barotropic_closure.hpp algorithm cmath limits string_view utility serif/discretization/blocks/fields.hpp serif/eos/evaluation.hpp serif/eos/exceptions.hpp serif/eos/models/polytropic.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/model/validation.cpp src/compile_time_checks/serif/operators/computation_owners.cpp src/compile_time_checks/serif/operators/plan.cpp src/include/serif/equations/equations.hpp serif::equations::BarotropicClosure serif serif::equations File containing the barotropic closure equation. Emily M. Boudreaux #pragmaonce #include<algorithm> #include<cmath> #include<limits> #include<string_view> #include<utility> #include"serif/discretization/blocks/fields.hpp" #include"serif/eos/evaluation.hpp" #include"serif/eos/exceptions.hpp" #include"serif/eos/models/polytropic.hpp" #include"serif/equations/point.hpp" #include"serif/utils/error/errors.hpp" namespaceserif::equations{ //Onstellardomains:integral[rho-rho_EOS(h)]q_rhodV=0. template<eos::models::BarotropicClosureEOSEOST> classBarotropicClosurefinal{ public: usingTest=discretization::blocks::density::mass; usingResidualQuantity=dimensions::MassDensity; usingEnthalpy=discretization::blocks::enthalpy::specific; usingOperands=utils::types::TypeList<discretization::forms::Operand<Test>,discretization::forms::Operand<Enthalpy>>; staticconstexprstd::string_viewname="barotropicclosure"; explicitBarotropicClosure( EOSTequation_of_state, constdoubleenthalpy_power ): m_eos(std::move(equation_of_state)),m_enthalpy_power(enthalpy_power){ usingnamespaceutils::errors; serif_ensure<SERiFErrorCode::INVALID_QUADRATURE_ORDER,std::invalid_argument>(std::isfinite(enthalpy_power)&&enthalpy_power>0.0,"Thedensityquadraturepowermustbepositiveandfinite."); } explicitBarotropicClosure( EOSTequation_of_state ) requiresstd::same_as<EOST,eos::models::Polytrope> :BarotropicClosure(equation_of_state,equation_of_state.polytropic_index()){} [[nodiscard]]PointLinearization<Operands>evaluate( constEquationPoint<Operands>&point )const{ usingnamespaceutils::errors; constdoubledensity=point.fields.templateget<Test>(); constdoubleenthalpy=point.fields.templateget<Enthalpy>(); serif_ensure<SERiFErrorCode::EOS_NONFINITE_INPUT,eos::EOSEvaluationError>(std::isfinite(density)&&std::isfinite(enthalpy),"Closurerequiresfinitedensityandenthalpy."); serif_ensure<SERiFErrorCode::EOS_OUTSIDE_DOMAIN,eos::EOSEvaluationError>(enthalpy>=0.0,"Stellarclosurerequiresnon-negativeenthalpy."); constdimensions::SpecificEnthalpyValueinput{enthalpy}; constdoubleeos_density=eos::evaluate<dimensions::MassDensity>(m_eos,input).value(); constdoubledensity_derivative=eos::partial_derivative<dimensions::MassDensity, dimensions::SpecificEnthalpy>(m_eos,input).value(); serif_ensure<SERiFErrorCode::EOS_NONFINITE_RESULT,eos::EOSEvaluationError>(std::isfinite(eos_density)&&std::isfinite(density_derivative),"Barotropicclosurereceivedanon-finiteEOSresult."); PointLinearization<Operands>result; result.residual=density-eos_density; result.field_derivatives.templateget<Test>()=1.0; result.field_derivatives.templateget<Enthalpy>()=-density_derivative; returnresult; } template<typenameOperandT> [[nodiscard]]intadditional_order(OperandT/*operand*/,int/*position_order*/)const{ usingnamespaceutils::errors; ifconstexpr(std::same_as<typenameOperandT::term_type,Enthalpy>){ constdoubleextra=std::ceil(std::max(0.0,m_enthalpy_power-1.0)*Enthalpy::FunctionalSpace::order); serif_ensure<SERiFErrorCode::INVALID_QUADRATURE_ORDER,std::invalid_argument>(extra<=std::numeric_limits<int>::max(),"TheEOSquadratureorderexceedsthesupportedrange."); returnstatic_cast<int>(extra); } return0; } private: EOSTm_eos; doublem_enthalpy_power; }; }//namespaceserif::equations