module; #include #include #include #include module mean_field; import :model.structure.polytropic; namespace mean_field::models::structure { PolytropicStructure::PolytropicStructure( eos::Polytrope equationOfState, const double targetMass ) : m_equationOfState(std::move(equationOfState)), m_targetMass(targetMass) { validate(); } const eos::Polytrope &PolytropicStructure::equationOfState() const noexcept { return m_equationOfState; } double PolytropicStructure::targetMass() const noexcept { return m_targetMass; } StructureSeed PolytropicStructure::makeInitialSeed(const StructureSeedRequest &request) const { const seed::RadialProfile profile = seed::generateLaneEmdenProfile( m_equationOfState, dimensions::DensityValue{request.centralDensity}, request.radialSampleCount ); return { .radius = profile.radius, .density = profile.density, .enthalpy = profile.specificEnthalpy, .stellarRadius = profile.stellarRadius.value(), .centralDensity = profile.centralDensity.value(), .centralEnthalpy = profile.centralSpecificEnthalpy.value() }; } void PolytropicStructure::validate() const { const double polytropicIndex = m_equationOfState.polytropic_index(); if (!std::isfinite(polytropicIndex) || polytropicIndex < 1.0 || polytropicIndex >= 5.0) { throw std::invalid_argument( std::format( "PolytropicStructure requires a finite-radius polytrope with 1 <= n < 5. Instead n = {} was " "provided.", polytropicIndex ) ); } if (!std::isfinite(m_targetMass) || m_targetMass <= 0.0) { throw std::invalid_argument( std::format( "The target stellar mass must be finite and positive. Instead a value of {} was provided.", m_targetMass ) ); } } } // namespace mean_field::models::structure