evaluation.hpp cmath expected serif/eos/evaluation.hpp serif/geometry/surface/linearization.hpp src/include/serif/geometry/surface/detail/batches.hpp src/include/serif/geometry/surface/evaluation.hpp serif serif::geometry serif::geometry::surface serif::geometry::surface::detail #pragmaonce #include<cmath> #include<expected> #include"serif/eos/evaluation.hpp" #include"serif/geometry/surface/linearization.hpp" namespaceserif::geometry::surface::detail { template<typenameQuantity,PressureSurfaceFormulationTypeFormulation> [[nodiscard]]dimensions::QuantityValue<Quantity>state_value(constSurfacePoint<Formulation>&point) { usingTerm=utils::dependencies::bound_type_t<typename Formulation::StateBindings, Quantity>; returndimensions::QuantityValue<Quantity>{point.fields.templateget<Term>()}; } template<typenameQuantity,PressureSurfaceFormulationTypeFormulation> [[nodiscard]]dimensions::QuantityValue<Quantity>relation_input(constdimensions::PressureValuepressure,constSurfacePoint<Formulation>&point) { ifconstexpr(Formulation::resolves_carrier&&std::same_as<Quantity,dimensions::Pressure>) { returnpressure; } else { returnstate_value<Quantity, Formulation>(point); } } template<PressureSurfaceFormulationTypeFormulation,typename...Quantities> [[nodiscard]]boolfinite_state(constSurfacePoint<Formulation>&point,utils::dependencies::KeyList<Quantities...>) { return(std::isfinite(state_value<Quantities, Formulation>(point).value())&&...); } template<typenameQuantity,PressureSurfaceFormulationTypeFormulation,typename...Inputs> voidaccumulate_partial(consttypenameFormulation::EquationOfState&equation_of_state,constdimensions::PressureValuepressure,constSurfacePoint<Formulation>&point,SurfaceEOSResponse<Formulation>&response,dimensions::QuantityList<Inputs...>) { usingOutput=typenameFormulation::Relation::OutputQuantity; usingTerm=utils::dependencies::bound_type_t<typename Formulation::StateBindings, Quantity>; constdimensions::PartialDerivative<Output,Quantity>derivative=eos::partial_derivative<Output, Quantity>(equation_of_state,relation_input<Inputs, Formulation>(pressure,point)...); response.field_derivatives.templateget<Term>()+=derivative.value(); } template<PressureSurfaceFormulationTypeFormulation,typename...Inputs,typename...StateQuantities> [[nodiscard]]SurfaceEOSResponse<Formulation>evaluate_relation(consttypenameFormulation::EquationOfState&equation_of_state,constdimensions::PressureValuepressure,constSurfacePoint<Formulation>&point,dimensions::QuantityList<Inputs...>inputs,utils::dependencies::KeyList<StateQuantities...>) { usingOutput=typenameFormulation::Relation::OutputQuantity; SurfaceEOSResponse<Formulation>response{}; response.value=eos::evaluate<Output>(equation_of_state,relation_input<Inputs, Formulation>(pressure,point)...); (accumulate_partial<StateQuantities, Formulation>(equation_of_state,pressure,point,response,inputs),...); returnresponse; } template<PressureSurfaceFormulationTypeFormulation> [[nodiscard]]std::expected<SurfaceEOSResponse<Formulation>,SurfaceFailure>evaluate_surface_response(consttypenameFormulation::EquationOfState&equation_of_state,constdimensions::PressureValuepressure,constSurfacePoint<Formulation>&point) { ifconstexpr(!Formulation::uses_eos) { //Apressureunknownusestheprescribedpressureitselfasitstarget,withoutanEOSrelation. returnSurfaceEOSResponse<Formulation>{.value=pressure}; } else { if(!finite_state<Formulation>(point,typenameFormulation::EOSStateQuantities{})) { returnstd::unexpected(SurfaceFailure{.reason=SurfaceFailureReason::non_finite_state,.message="ThesurfaceEOSinputsmustbefinite;supplyanadmissibleboundarystate."}); } constSurfaceEOSResponse<Formulation>response=evaluate_relation<Formulation>(equation_of_state,pressure,point,typenameFormulation::Relation::InputQuantities{},typenameFormulation::EOSStateQuantities{}); boolfinite=std::isfinite(response.value.value()); for(constdoublederivative:response.field_derivatives.values) { finite=finite&&std::isfinite(derivative); } if(!finite) { returnstd::unexpected(SurfaceFailure{.reason=SurfaceFailureReason::non_finite_eos_response,.message="ThesurfaceEOSreturnedanon-finitevalueorpartialderivative;checkitsthermodynamicdomain."}); } returnresponse; } } template<PressureSurfaceFormulationTypeFormulation> [[nodiscard]]SurfaceLinearization<Formulation>linearize_surface(constdimensions::PressureValuepressure,constSurfacePoint<Formulation>&point,constSurfaceEOSResponse<Formulation>&response) { SurfaceLinearization<Formulation>result{}; result.field_derivatives=response.field_derivatives; ifconstexpr(Formulation::resolves_carrier) { result.residual=state_value<typename Formulation::CarrierQuantity, Formulation>(point).value()-response.value.value(); for(double&derivative:result.field_derivatives.values) { derivative=-derivative; } result.field_derivatives.templateget<typenameFormulation::CarrierTerm>()+=1.0; } else { result.residual=response.value.value()-pressure.value(); } returnresult; } template<PressureSurfaceFormulationTypeFormulation> [[nodiscard]]std::expected<SurfaceLinearization<Formulation>,SurfaceFailure>checked_linearization(constdimensions::PressureValuepressure,constSurfacePoint<Formulation>&point,constSurfaceEOSResponse<Formulation>&response) { constSurfaceLinearization<Formulation>result=linearize_surface<Formulation>(pressure,point,response); boolfinite=std::isfinite(result.residual); for(constdoublederivative:result.field_derivatives.values) { finite=finite&&std::isfinite(derivative); } if(!finite) { returnstd::unexpected(SurfaceFailure{.reason=SurfaceFailureReason::non_finite_linearization,.message="Thesurfaceresidualorderivativeisnon-finite;reducethetrialstatebeforeusingthislinearization."}); } returnresult; } }