pressure_force.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/contributions.hpp serif/equations/point.hpp serif/utils/error/errors.hpp src/compile_time_checks/serif/operators/plan.cpp src/include/serif/equations/displacement_force.hpp src/include/serif/equations/equations.hpp serif::equations::PressureForce serif serif::equations #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/contributions.hpp" #include"serif/equations/point.hpp" #include"serif/utils/error/errors.hpp" namespaceserif::equations{ template<eos::models::PressureForceEOSEOST> classPressureForcefinal:publicContribution< discretization::forms::Operand<discretization::blocks::displacement::vector,discretization::forms::Operation::Divergence>, discretization::domain::StellarDomains >{ public: usingEnthalpy=discretization::blocks::enthalpy::specific; usingEnthalpyValue=discretization::forms::Operand<Enthalpy>; usingOperands=utils::types::TypeList<EnthalpyValue>; staticconstexprstd::string_viewname="pressureforce"; explicitPressureForce( 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,"Thepressurequadraturepowermustbepositiveandfinite."); } explicitPressureForce( EOSTequation_of_state ) requiresstd::same_as<EOST,eos::models::Polytrope> :PressureForce(equation_of_state,equation_of_state.polytropic_index()+1.0){} [[nodiscard]]PointLinearization<Operands>evaluate( constEquationPoint<Operands>&point )const{ usingnamespaceutils::errors; constdoubleenthalpy=point.fields.templateget<Enthalpy>(); serif_ensure<SERiFErrorCode::EOS_NONFINITE_INPUT,eos::EOSEvaluationError>(std::isfinite(enthalpy),"Pressureforcerequiresfiniteenthalpy."); serif_ensure<SERiFErrorCode::EOS_OUTSIDE_DOMAIN,eos::EOSEvaluationError>(enthalpy>=0.0,"Stellarpressureforcerequiresnon-negativeenthalpy."); constdimensions::SpecificEnthalpyValueinput{enthalpy}; constdoublepressure=eos::evaluate<dimensions::Pressure>(m_eos,input).value(); constdoublepressure_derivative=eos::partial_derivative<dimensions::Pressure, dimensions::SpecificEnthalpy>(m_eos,input).value(); serif_ensure<SERiFErrorCode::EOS_NONFINITE_RESULT,eos::EOSEvaluationError>(std::isfinite(pressure)&&std::isfinite(pressure_derivative),"Pressureforcereceivedanon-finiteEOSresult."); PointLinearization<Operands>result; result.residual=-pressure; result.field_derivatives.templateget<Enthalpy>()=-pressure_derivative; returnresult; } [[nodiscard]]intadditional_order(EnthalpyValue,int/*position_order*/)const{ usingnamespaceutils::errors; 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(),"Thepressurequadratureorderexceedsthesupportedrange."); returnstatic_cast<int>(extra); } private: EOSTm_eos; doublem_enthalpy_power; }; }//namespaceserif::equations