feat(libmeanfield): variadic refactor

also added normaliztion operator
This commit is contained in:
2026-09-06 10:15:00 -04:00
parent 71423d543f
commit 76818f2f82
63 changed files with 28794 additions and 1119 deletions

View File

@@ -13,6 +13,137 @@ import mean_field;
import test_helpers;
namespace {
template <typename... Specifications>
using ProjectionModelWith = mean_field::model::StellarModel<
mean_field::models::SpecificationSet<Specifications...>>;
class UnregisteredProjectionConstraint final {
public:
struct Parameters final { };
using ModelDefinition = mean_field::constraint::PhaseCondition<
UnregisteredProjectionConstraint,
"UnregisteredProjectionConstraint",
mean_field::models::DependsOn<mean_field::models::stellar::state::SpecificEnthalpy>,
mean_field::models::Affects<mean_field::models::stellar::equation::HydrostaticBalance>>;
explicit constexpr UnregisteredProjectionConstraint(Parameters) noexcept {
}
};
class ExplicitNoChangeProjectionConstraint final {
public:
struct Parameters final { };
using ModelDefinition = mean_field::constraint::PhaseCondition<
ExplicitNoChangeProjectionConstraint,
"ExplicitNoChangeProjectionConstraint",
mean_field::models::DependsOn<mean_field::models::stellar::state::SpecificEnthalpy>,
mean_field::models::Affects<mean_field::models::stellar::equation::HydrostaticBalance>>;
using RadialProjection = mean_field::seed::projection::Use<mean_field::seed::projection::NoStateChange>;
explicit constexpr ExplicitNoChangeProjectionConstraint(Parameters) noexcept {
}
};
struct IncompleteProjectionPhysics final {
static constexpr bool registered = true;
static constexpr bool providesRadialMass = false;
template <typename Model>
static constexpr bool supports = true;
};
class IncompleteProjectionConstraint final {
public:
struct Parameters final { };
using ModelDefinition = mean_field::constraint::PhaseCondition<
IncompleteProjectionConstraint,
"IncompleteProjectionConstraint",
mean_field::models::DependsOn<mean_field::models::stellar::state::SpecificEnthalpy>,
mean_field::models::Affects<mean_field::models::stellar::equation::HydrostaticBalance>>;
using RadialProjection = mean_field::seed::projection::Use<IncompleteProjectionPhysics>;
explicit constexpr IncompleteProjectionConstraint(Parameters) noexcept {
}
};
class UnregisteredProjectionEquationOfState final {
public:
struct Parameters final { };
using ModelDefinition = mean_field::eos::ConstitutiveLaw<
UnregisteredProjectionEquationOfState,
"UnregisteredProjectionEquationOfState">;
explicit constexpr UnregisteredProjectionEquationOfState(Parameters) noexcept {
}
};
class UnregisteredProjectionSurface final {
public:
struct Parameters final { };
using ModelDefinition = mean_field::surface::BoundaryCondition<
UnregisteredProjectionSurface,
"UnregisteredProjectionSurface">;
explicit constexpr UnregisteredProjectionSurface(Parameters) noexcept {
}
};
struct SecondRadialMassProjectionPhysics final {
static constexpr bool registered = true;
static constexpr bool providesRadialMass = true;
template <typename Model>
static constexpr bool supports = true;
template <typename Specification>
[[nodiscard]] static mean_field::dimensions::MassValue targetMass(const Specification &specification) {
return specification.targetMass();
}
template <typename Specification, typename Model>
static void validate(
const Specification &,
const Model &,
const mean_field::seed::RadialProfile &,
const mean_field::seed::StellarEquilibriumProjectionOptions &
) noexcept {
}
template <typename Specification, typename Model>
static void initialize(
const Specification &,
const Model &,
const mean_field::seed::RadialProjectionScales &,
mean_field::seed::RadialProjectionState &,
mfem::Vector coordinate
) {
if (coordinate.Size() == 1) {
coordinate(0) = 0.0;
}
}
};
class SecondRadialMassConstraint final {
public:
struct Parameters final {
mean_field::dimensions::MassValue mass;
};
using ModelDefinition = mean_field::integral::FixedWithMultiplier<
SecondRadialMassConstraint,
"SecondRadialMassConstraint">;
using RadialProjection = mean_field::seed::projection::Use<SecondRadialMassProjectionPhysics>;
explicit constexpr SecondRadialMassConstraint(Parameters parameters) noexcept : m_mass(parameters.mass) {
}
[[nodiscard]] constexpr mean_field::dimensions::MassValue targetMass() const noexcept {
return m_mass;
}
private:
mean_field::dimensions::MassValue m_mass;
};
[[nodiscard]] mean_field::operators::StellarEquilibriumDependencies make_dependencies() {
return {
.discretization = {.identity = 7001, .revision = 1},
@@ -42,6 +173,65 @@ namespace {
}
} // namespace
TEST_CASE(
"Radial Projection Capabilities Are Inferred From Every Model Specification",
tags::stellar_seed_projection_type_contract
) {
using namespace mean_field;
using BaseModel = ProjectionModelWith<eos::Polytrope, surface::Isobaric, integral::FixedTotalMass>;
using CentralModel = ProjectionModelWith<
eos::Polytrope,
surface::Isobaric,
integral::FixedTotalMass,
constraint::FixedCentralDensity>;
using AngularModel = ProjectionModelWith<
eos::Polytrope,
surface::Isobaric,
integral::FixedTotalMass,
integral::FixedAngularMomentum>;
using ExplicitExtensionModel = ProjectionModelWith<
eos::Polytrope,
surface::Isobaric,
integral::FixedTotalMass,
ExplicitNoChangeProjectionConstraint>;
using MissingConstraintRuleModel = ProjectionModelWith<
eos::Polytrope,
surface::Isobaric,
integral::FixedTotalMass,
UnregisteredProjectionConstraint>;
using IncompleteConstraintRuleModel = ProjectionModelWith<
eos::Polytrope,
surface::Isobaric,
integral::FixedTotalMass,
IncompleteProjectionConstraint>;
using MissingEquationOfStateRuleModel = ProjectionModelWith<
UnregisteredProjectionEquationOfState,
surface::Isobaric,
integral::FixedTotalMass>;
using MissingSurfaceRuleModel = ProjectionModelWith<
eos::Polytrope,
UnregisteredProjectionSurface,
integral::FixedTotalMass>;
using MissingMassProviderModel = ProjectionModelWith<eos::Polytrope, surface::Isobaric>;
using AmbiguousMassProviderModel = ProjectionModelWith<
eos::Polytrope,
surface::Isobaric,
integral::FixedTotalMass,
SecondRadialMassConstraint>;
STATIC_CHECK(seed::RadialProfileProjectableModel<BaseModel>);
STATIC_CHECK(seed::RadialProfileProjectableModel<CentralModel>);
STATIC_CHECK(seed::RadialProfileProjectableModel<AngularModel>);
STATIC_CHECK(seed::RadialProfileProjectableModel<ExplicitExtensionModel>);
STATIC_CHECK_FALSE(seed::RadialProfileProjectableModel<MissingConstraintRuleModel>);
STATIC_CHECK_FALSE(seed::RadialProfileProjectableModel<IncompleteConstraintRuleModel>);
STATIC_CHECK_FALSE(seed::RadialProfileProjectableModel<MissingEquationOfStateRuleModel>);
STATIC_CHECK_FALSE(seed::RadialProfileProjectableModel<MissingSurfaceRuleModel>);
STATIC_CHECK_FALSE(seed::RadialProfileProjectableModel<MissingMassProviderModel>);
STATIC_CHECK_FALSE(seed::RadialProfileProjectableModel<AmbiguousMassProviderModel>);
STATIC_CHECK_FALSE(seed::RadialProfileProjectableModel<int>);
}
TEST_CASE(
"Projected Equilibrium States Preserve Their Compiled Stellar Model Type",
tags::stellar_seed_projection_type_contract
@@ -116,9 +306,9 @@ TEST_CASE(
REQUIRE(centralDensityBorder.Size() == 1);
CHECK(centralDensityBorder(0) == 0.0);
const operators::PreparedCentralDensityStellarEquilibriumReport preparation =
problem.Prepare(projected.values, make_dependencies(), make_zero_rotation());
const auto preparation = problem.Prepare(projected.values, make_dependencies(), make_zero_rotation());
CHECK(preparation.assembledResidual);
CHECK(preparation.template specification<models::FixedCentralDensity>().constraint.DidAnyWork());
mfem::Vector residual;
problem.BuildResidual(residual);