Files
MeanField_SERiF/tests/sandbox/polytropic_model.hpp
Emily Boudreaux cb20faeb3d test(tests): added test suite
The test suite is extensive. Note that LLMs were used to aid in the development of the test suite. All LLM generated code was manually reviewed.
2026-11-09 13:53:17 -05:00

45 lines
2.9 KiB
C++

#pragma once
#include <numbers>
#include <stdexcept>
#include "serif/eos/models/polytropic.hpp"
#include "serif/equations/angular_momentum.hpp"
#include "serif/equations/barotropic_density.hpp"
#include "serif/equations/mass_normalization.hpp"
#include "serif/equations/primal_gravity.hpp"
#include "serif/equations/surface_potential.hpp"
#include "serif/geometry/surface/isobaric.hpp"
#include "serif/model/eos_reference.hpp"
#include "serif/model/stellar_model.hpp"
#include "serif/model/specifications/fixed_total_mass.hpp"
#include "serif/model/specifications/fixed_angular_momentum.hpp"
#include "serif/utils/error/errors.hpp"
namespace serif::examples {
/** @brief Solve density mechanics, primal gravity and the isobar shape at fixed mass, EOS and angular momentum. */
[[nodiscard]] inline auto make_polytropic_model(double n = 1.0, double K = 2.0 / std::numbers::pi, double mass = 1.0, double angular_momentum = 0.0, double G = 1.0, double surface_pressure = 0.0) {
const auto equations = [G, surface_pressure](const auto& physics) {
const auto eos = model::borrow_eos(physics.equation_of_state());
const double index = physics.equation_of_state().polytropic_index();
const auto& rotation = physics.template specification<model::FixedAngularMomentum>();
// Resolve physical compatibility with the deferred equation definition, without restricting the EOS itself.
utils::errors::serif_ensure<utils::errors::SERiFErrorCode::INVALID_ARGUMENT, std::invalid_argument>(
!(index == 3.0 && rotation.target().value() == 0.0 && surface_pressure == 0.0),
"Fixed K and M do not determine a unique nonrotating n=3 vacuum equilibrium: compatible mass leaves radius free, and incompatible mass has no solution.");
return model::EquilibriumEquations{
.interior_equations = serif::equations::EquationRegistry{
serif::equations::BarotropicDensityBalance{eos, dimensions::PressureValue{surface_pressure}, rotation.axis(), rotation.center()},
serif::equations::PrimalPoissonBalance{4.0 * std::numbers::pi * G},
serif::equations::MassNormalization{physics.template specification<model::FixedTotalMass>().target().value()},
serif::equations::AngularMomentumConstraint{rotation.target().value(), rotation.axis(), rotation.center()}
},
.shape_force = serif::equations::SurfacePotentialBalance{rotation.axis(), rotation.center()},
.surface_condition = geometry::surface::Isobaric{dimensions::PressureValue{surface_pressure}}
};
};
return model::make_stellar_model(eos::models::Polytrope{n, K}, equations,
model::FixedTotalMass{dimensions::MassValue{mass}}, model::FixedAngularMomentum{dimensions::AngularMomentumValue{angular_momentum}});
}
}