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.
45 lines
2.9 KiB
C++
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}});
|
|
}
|
|
|
|
}
|