central_density.hpp array cmath string_view utility serif/dimensions/type_alias.hpp serif/eos/evaluation.hpp serif/equations/contributions.hpp serif/equations/point.hpp serif/utils/error/errors.hpp src/compile_time_checks/serif/model/execution_validation.cpp src/compile_time_checks/serif/model/normalization.cpp src/compile_time_checks/serif/operators/serial_backend.cpp src/include/serif/equations/equations.hpp serif::equations::CentralDensityConstraint serif serif::equations Prescribe central density through the continuous enthalpy: h(0) - h_EOS(rho_c) = 0. Generally this is not needed; however, in the particular case of an n=3 polytrope with no rotation the central density becomes ill-defined and must be prescribed to avoid a singularity in the solution. Emily M. Boudreaux #pragmaonce #include<array> #include<cmath> #include<string_view> #include<utility> #include"serif/dimensions/type_alias.hpp" #include"serif/eos/evaluation.hpp" #include"serif/equations/contributions.hpp" #include"serif/equations/point.hpp" #include"serif/utils/error/errors.hpp" namespaceserif::equations{ template<eos::models::EOSModelEOST> requireseos::models::EOSSupportingRelation<EOST,eos::relations::SpecificEnthalpyFromDensity> classCentralDensityConstraintfinal:publicContribution<discretization::forms::Operand<discretization::blocks::enthalpy::specific>>{ public: usingOperands=utils::types::TypeList<TestOperand>; usingBorder=discretization::blocks::central_density::border; usingResidualQuantity=dimensions::SpecificEnthalpy; staticconstexprstd::string_viewname="centraldensityconstraint"; staticconstexprboolposition_independent=true; staticconstexprboolaffine=true; staticconstexprstd::array<double,3>reference_position{}; CentralDensityConstraint(EOSTequation_of_state,dimensions::DensityValuetarget_density): m_eos(std::move(equation_of_state)), m_target_density(target_density){ usingnamespaceutils::errors; serif_ensure<SERiFErrorCode::INVALID_ARGUMENT,std::invalid_argument>(std::isfinite(target_density.value())&&target_density.value()>0.0,"Centraldensitymustbefiniteandstrictlypositive."); m_target_enthalpy=eos::evaluate<dimensions::SpecificEnthalpy>(m_eos,target_density).value(); serif_ensure<SERiFErrorCode::NON_FINITE_VALUE_ERROR,std::domain_error>(std::isfinite(m_target_enthalpy),"TheEOSreturnedanon-finitecentralenthalpy."); } [[nodiscard]]PointLinearization<Operands>evaluate(constEquationPoint<Operands>&point)const{ PointLinearization<Operands>result; result.residual=point.fields.get<Test>()-m_target_enthalpy; result.field_derivatives.get<Test>()=1.0; returnresult; } [[nodiscard]]dimensions::DensityValuetarget_density()constnoexcept{ returnm_target_density; } [[nodiscard]]dimensions::SpecificEnthalpyValuetarget_enthalpy()constnoexcept{ returndimensions::SpecificEnthalpyValue{m_target_enthalpy}; } [[nodiscard]]dimensions::DensityValuedensity_from_enthalpy(dimensions::SpecificEnthalpyValueenthalpy)const requireseos::models::EOSSupportingRelation<EOST, eos::relations::DensityFromSpecificEnthalpy>{ returneos::evaluate<dimensions::MassDensity>(m_eos,enthalpy); } private: EOSTm_eos; dimensions::DensityValuem_target_density; doublem_target_enthalpy; }; }//namespaceserif::equations