//! Shared helpers for the `entropyk-solver` Phase-0 integration tests. //! //! Provides the three reference emergent-pressure R134a cycles used as the //! Phase-0 golden safety net. The construction mirrors `benches/common.rs` //! so benchmarks and regression tests stay aligned. use std::sync::Arc; use entropyk_components::{Condenser, Evaporator, IsenthalpicExpansionValve, IsentropicCompressor}; use entropyk_fluids::{CoolPropBackend, FluidBackend}; use entropyk_solver::system::System; use entropyk_solver::{ConvergedState, FallbackConfig, FallbackSolver, NewtonConfig, Solver}; fn coolprop_backend() -> Arc { Arc::new(CoolPropBackend::new()) } fn build_emergent_cycle( cond_sec_temp_k: f64, evap_sec_temp_k: f64, ua_cond: f64, ua_evap: f64, ) -> System { use entropyk_components::isentropic_compressor::VolumetricEfficiency; let backend = coolprop_backend(); let fluid = "R134a"; let comp = Box::new( IsentropicCompressor::new(0.70, 318.15, 278.15, 5.0) .with_refrigerant(fluid) .with_fluid_backend(backend.clone()) .with_displacement(6.5e-5, 50.0, VolumetricEfficiency::Constant(0.92)), ); let cond = Box::new( Condenser::new(ua_cond) .with_refrigerant(fluid) .with_fluid_backend(backend.clone()) .with_secondary_stream(cond_sec_temp_k, 1500.0) .with_emergent_pressure(5.0), ); let exv = Box::new( IsenthalpicExpansionValve::new(278.15) .with_refrigerant(fluid) .with_fluid_backend(backend.clone()) .with_emergent_pressure(), ); let evap = Box::new( Evaporator::new(ua_evap) .with_refrigerant(fluid) .with_fluid_backend(backend.clone()) .with_secondary_stream(evap_sec_temp_k, 2000.0) .with_emergent_pressure(), ); let mut system = System::new(); let n_comp = system.add_component(comp); let n_cond = system.add_component(cond); let n_exv = system.add_component(exv); let n_evap = system.add_component(evap); system.add_edge(n_comp, n_cond).unwrap(); system.add_edge(n_cond, n_exv).unwrap(); system.add_edge(n_exv, n_evap).unwrap(); system.add_edge(n_evap, n_comp).unwrap(); system.finalize().unwrap(); system } pub fn build_reference_cycle_a() -> System { build_emergent_cycle(303.15, 285.15, 766.0, 1468.0) } pub fn build_reference_cycle_b() -> System { build_emergent_cycle(313.15, 283.15, 900.0, 1600.0) } pub fn build_reference_cycle_c() -> System { build_emergent_cycle(308.15, 291.15, 850.0, 1800.0) } fn newton_config_for_reference() -> NewtonConfig { let initial_state = vec![ 0.05, // shared mass flow [kg/s] 11.6e5, // comp->cond pressure [Pa] 445e3, // comp->cond enthalpy [J/kg] 11.6e5, // cond->exv pressure [Pa] 262e3, // cond->exv enthalpy [J/kg] 3.5e5, // exv->evap pressure [Pa] 262e3, // exv->evap enthalpy [J/kg] 3.5e5, // evap->comp pressure [Pa] 405e3, // evap->comp enthalpy [J/kg] ]; NewtonConfig { max_iterations: 200, tolerance: 1e-6, initial_state: Some(initial_state), ..NewtonConfig::default() } } /// Solves a reference cycle and returns the converged state vector. pub fn solve_reference_system_with_state(system: &mut System) -> ConvergedState { let newton = newton_config_for_reference(); let mut solver = FallbackSolver::new(FallbackConfig::default()).with_newton_config(newton); solver.solve(system).expect("reference cycle must converge") }