feat(newton): first newton solver implementation

This commit is contained in:
2026-09-08 06:36:39 -04:00
parent 76818f2f82
commit b3c04d507a
98 changed files with 20397 additions and 11040 deletions

View File

@@ -4,6 +4,7 @@
#include <numbers>
#include <stdexcept>
#include <type_traits>
#include <utility>
#include <catch2/catch_approx.hpp>
#include <catch2/catch_test_macros.hpp>
@@ -14,8 +15,8 @@ import test_helpers;
namespace {
template <typename... Specifications>
using ProjectionModelWith = mean_field::model::StellarModel<
mean_field::models::SpecificationSet<Specifications...>>;
using ProjectionModelWith =
mean_field::model::StellarModel<mean_field::models::SpecificationSet<Specifications...>>;
class UnregisteredProjectionConstraint final {
public:
@@ -45,11 +46,10 @@ namespace {
};
struct IncompleteProjectionPhysics final {
static constexpr bool registered = true;
static constexpr bool providesRadialMass = false;
static constexpr bool registered = true;
static constexpr bool providesRadialMass = false;
template <typename Model>
static constexpr bool supports = true;
template <typename Model> static constexpr bool supports = true;
};
class IncompleteProjectionConstraint final {
@@ -69,9 +69,8 @@ namespace {
class UnregisteredProjectionEquationOfState final {
public:
struct Parameters final { };
using ModelDefinition = mean_field::eos::ConstitutiveLaw<
UnregisteredProjectionEquationOfState,
"UnregisteredProjectionEquationOfState">;
using ModelDefinition = mean_field::eos::
ConstitutiveLaw<UnregisteredProjectionEquationOfState, "UnregisteredProjectionEquationOfState">;
explicit constexpr UnregisteredProjectionEquationOfState(Parameters) noexcept {
}
@@ -80,27 +79,27 @@ namespace {
class UnregisteredProjectionSurface final {
public:
struct Parameters final { };
using ModelDefinition = mean_field::surface::BoundaryCondition<
UnregisteredProjectionSurface,
"UnregisteredProjectionSurface">;
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;
static constexpr bool registered = true;
static constexpr bool providesRadialMass = true;
template <typename Model>
static constexpr bool supports = 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>
template <
typename Specification,
typename Model>
static void validate(
const Specification &,
const Model &,
@@ -109,7 +108,9 @@ namespace {
) noexcept {
}
template <typename Specification, typename Model>
template <
typename Specification,
typename Model>
static void initialize(
const Specification &,
const Model &,
@@ -128,9 +129,8 @@ namespace {
struct Parameters final {
mean_field::dimensions::MassValue mass;
};
using ModelDefinition = mean_field::integral::FixedWithMultiplier<
SecondRadialMassConstraint,
"SecondRadialMassConstraint">;
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) {
@@ -178,46 +178,24 @@ TEST_CASE(
tags::stellar_seed_projection_type_contract
) {
using namespace mean_field;
using BaseModel = ProjectionModelWith<eos::Polytrope, surface::Isobaric, integral::FixedTotalMass>;
using BaseModel = ProjectionModelWith<eos::Polytrope, surface::Isobaric, integral::FixedTotalMass>;
using CentralModel = ProjectionModelWith<
eos::Polytrope,
surface::Isobaric,
integral::FixedTotalMass,
constraint::FixedCentralDensity>;
eos::Polytrope, surface::Isobaric, integral::FixedTotalMass, constraint::FixedCentralDensity>;
using AngularModel = ProjectionModelWith<
eos::Polytrope,
surface::Isobaric,
integral::FixedTotalMass,
integral::FixedAngularMomentum>;
eos::Polytrope, surface::Isobaric, integral::FixedTotalMass, integral::FixedAngularMomentum>;
using ExplicitExtensionModel = ProjectionModelWith<
eos::Polytrope,
surface::Isobaric,
integral::FixedTotalMass,
ExplicitNoChangeProjectionConstraint>;
eos::Polytrope, surface::Isobaric, integral::FixedTotalMass, ExplicitNoChangeProjectionConstraint>;
using MissingConstraintRuleModel = ProjectionModelWith<
eos::Polytrope,
surface::Isobaric,
integral::FixedTotalMass,
UnregisteredProjectionConstraint>;
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>;
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>;
using AmbiguousMassProviderModel =
ProjectionModelWith<eos::Polytrope, surface::Isobaric, integral::FixedTotalMass, SecondRadialMassConstraint>;
STATIC_CHECK(seed::RadialProfileProjectableModel<BaseModel>);
STATIC_CHECK(seed::RadialProfileProjectableModel<CentralModel>);
@@ -272,7 +250,7 @@ TEST_CASE(
integral::FixedTotalMass({.Mtotal = dimensions::MassValue{targetMass}}),
constraint::FixedCentralDensity({.RhoC = dimensions::DensityValue{centralDensity}})
);
auto problem = equilibrium::discretize(stellarModel, finiteElementModel);
auto problem = equilibrium::discretize(stellarModel, std::move(finiteElementModel));
STATIC_CHECK(seed::RadialSeedStrategyFor<seed::LaneEmden, decltype(stellarModel)>);
STATIC_CHECK(
@@ -346,7 +324,7 @@ TEST_CASE(
integral::FixedTotalMass({.Mtotal = dimensions::MassValue{1.0}}),
constraint::FixedCentralDensity({.RhoC = dimensions::DensityValue{1.0}})
);
auto problem = equilibrium::discretize(stellarModel, finiteElementModel);
auto problem = equilibrium::discretize(stellarModel, std::move(finiteElementModel));
const seed::RadialProfile mismatchedProfile =
seed::generateRadialProfile(problem.GetStellarModel(), seed::LaneEmden({.radialSampleCount = 64}));
@@ -371,7 +349,7 @@ TEST_CASE(
integral::FixedTotalMass({.Mtotal = dimensions::MassValue{1.0}}),
constraint::FixedCentralDensity({.RhoC = dimensions::DensityValue{centralDensity}})
);
auto problem = equilibrium::discretize(stellarModel, finiteElementModel);
auto problem = equilibrium::discretize(stellarModel, std::move(finiteElementModel));
const seed::RadialProfile profile =
seed::generateRadialProfile(problem.GetStellarModel(), seed::LaneEmden({.radialSampleCount = 64}));