68 lines
2.2 KiB
C++
68 lines
2.2 KiB
C++
module;
|
|
|
|
#include <cmath>
|
|
#include <format>
|
|
#include <stdexcept>
|
|
#include <utility>
|
|
|
|
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
|