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

@@ -141,55 +141,50 @@ TEST_CASE(
tags::model_specification_type_contract
) {
using namespace mean_field;
using Request = models::FixedAngularMomentumLayoutRequest;
using Form = operators::CompiledStellarEquilibriumForm<AngularMomentumPolytropicMassModel>;
using Jacobian = operators::CompiledStellarEquilibriumJacobianForm<AngularMomentumPolytropicMassModel>;
using AngularValue = utils::blocks::fixed_angular_momentum::angular_velocity::value;
using Request = models::FixedAngularMomentumLayoutRequest;
using Form = operators::CompiledStellarEquilibriumForm<AngularMomentumPolytropicMassModel>;
using Jacobian = operators::CompiledStellarEquilibriumJacobianForm<AngularMomentumPolytropicMassModel>;
using AngularValue = utils::blocks::fixed_angular_momentum::angular_velocity::value;
using AngularResidual = utils::blocks::fixed_angular_momentum::angular_velocity::residual;
STATIC_CHECK(models::ConstraintLayoutRequestType<Request>);
STATIC_CHECK(models::CompiledConstraint<models::CompiledFixedAngularMomentum>);
STATIC_CHECK(std::same_as<
typename Request::GeneratedValueType,
models::PhysicalCoordinateFor<models::FixedAngularMomentum>>);
STATIC_CHECK(std::same_as<
typename AngularValue::GeneratedType,
models::PhysicalCoordinateFor<models::FixedAngularMomentum>>);
STATIC_CHECK(std::same_as<
typename models::CompiledFixedAngularMomentum::AngularVelocityField,
field::AngularVelocity>);
STATIC_CHECK(
std::same_as<typename Request::GeneratedValueType, models::PhysicalCoordinateFor<models::FixedAngularMomentum>>
);
STATIC_CHECK(
std::same_as<typename AngularValue::GeneratedType, models::PhysicalCoordinateFor<models::FixedAngularMomentum>>
);
STATIC_CHECK(
std::same_as<typename models::CompiledFixedAngularMomentum::AngularVelocityField, field::AngularVelocity>
);
STATIC_CHECK(Form::value_block_count == 7);
STATIC_CHECK(Form::residual_block_count == 7);
STATIC_CHECK(Request::valueBlock<Form>().index == 6);
STATIC_CHECK(Request::residualBlock<Form>().index == 6);
STATIC_CHECK(utils::blocks::valid_jacobian_form<Form, Jacobian>);
STATIC_CHECK(utils::blocks::has_jacobian_coupling_v<
AngularResidual,
utils::blocks::density::mass::value,
Jacobian>);
STATIC_CHECK(utils::blocks::has_jacobian_coupling_v<
AngularResidual,
utils::blocks::surface_deformation::parameters::value,
Jacobian>);
STATIC_CHECK(
utils::blocks::has_jacobian_coupling_v<AngularResidual, utils::blocks::density::mass::value, Jacobian>
);
STATIC_CHECK(
utils::blocks::has_jacobian_coupling_v<
AngularResidual, utils::blocks::surface_deformation::parameters::value, Jacobian>
);
STATIC_CHECK(utils::blocks::has_jacobian_coupling_v<AngularResidual, AngularValue, Jacobian>);
STATIC_CHECK(utils::blocks::has_jacobian_coupling_v<
utils::blocks::surface_deformation::shape_equilibrium::residual,
AngularValue,
Jacobian>);
STATIC_CHECK(utils::blocks::has_jacobian_coupling_v<
utils::blocks::enthalpy::specific::residual,
AngularValue,
Jacobian>);
STATIC_CHECK_FALSE(utils::blocks::has_jacobian_coupling_v<
utils::blocks::gravity::poisson::residual,
AngularValue,
Jacobian>);
STATIC_CHECK(
utils::blocks::has_jacobian_coupling_v<
utils::blocks::surface_deformation::shape_equilibrium::residual, AngularValue, Jacobian>
);
STATIC_CHECK(
utils::blocks::has_jacobian_coupling_v<utils::blocks::enthalpy::specific::residual, AngularValue, Jacobian>
);
STATIC_CHECK_FALSE(
utils::blocks::has_jacobian_coupling_v<utils::blocks::gravity::poisson::residual, AngularValue, Jacobian>
);
const integral::FixedAngularMomentum specification({
.Jtotal = dimensions::AngularMomentumValue{2.75},
.axis = {0.0, 3.0, 4.0},
.center = {0.25, -0.5, 0.75}
});
const integral::FixedAngularMomentum specification(
{.Jtotal = dimensions::AngularMomentumValue{2.75}, .axis = {0.0, 3.0, 4.0}, .center = {0.25, -0.5, 0.75}}
);
const models::CompiledFixedAngularMomentum compiled = models::compileConstraint(specification);
CHECK(compiled.targetAngularMomentum() == dimensions::AngularMomentumValue{2.75});
CHECK(std::abs(compiled.specification().axis()[0]) < 1.0e-15);
@@ -281,9 +276,7 @@ TEST_CASE(
) {
const mean_field::models::FixedTotalMass mass{mean_field::dimensions::MassValue{1.25}};
const mean_field::models::FixedCentralDensity centralDensity{mean_field::eos::DensityValue{2.5}};
const mean_field::models::FixedAngularMomentum angularMomentum{
mean_field::dimensions::AngularMomentumValue{0.75}
};
const mean_field::models::FixedAngularMomentum angularMomentum{mean_field::dimensions::AngularMomentumValue{0.75}};
CHECK(mass.targetMass() == mean_field::dimensions::MassValue{1.25});
CHECK(centralDensity.targetDensity() == mean_field::eos::DensityValue{2.5});
@@ -308,18 +301,17 @@ TEST_CASE(
std::invalid_argument
);
CHECK_THROWS_AS(
mean_field::models::FixedAngularMomentum({
.Jtotal = mean_field::dimensions::AngularMomentumValue{1.0},
.axis = {0.0, 0.0, 0.0}
}),
mean_field::models::FixedAngularMomentum(
{.Jtotal = mean_field::dimensions::AngularMomentumValue{1.0}, .axis = {0.0, 0.0, 0.0}}
),
std::invalid_argument
);
CHECK_THROWS_AS(
mean_field::models::FixedAngularMomentum({
.Jtotal = mean_field::dimensions::AngularMomentumValue{1.0},
.axis = {0.0, 0.0, 1.0},
.center = {0.0, std::numeric_limits<double>::quiet_NaN(), 0.0}
}),
mean_field::models::FixedAngularMomentum(
{.Jtotal = mean_field::dimensions::AngularMomentumValue{1.0},
.axis = {0.0, 0.0, 1.0},
.center = {0.0, std::numeric_limits<double>::quiet_NaN(), 0.0}}
),
std::invalid_argument
);

File diff suppressed because it is too large Load Diff

View File

@@ -27,16 +27,15 @@ namespace {
int marker;
};
using ModelDefinition =
mean_field::eos::ConstitutiveLaw<MoveOnlyEquationOfState, "MoveOnlyEquationOfState">;
using ModelDefinition = mean_field::eos::ConstitutiveLaw<MoveOnlyEquationOfState, "MoveOnlyEquationOfState">;
explicit MoveOnlyEquationOfState(const Parameters parameters)
: m_marker(std::make_unique<int>(parameters.marker)) {
}
MoveOnlyEquationOfState(const MoveOnlyEquationOfState &) = delete;
MoveOnlyEquationOfState &operator=(const MoveOnlyEquationOfState &) = delete;
MoveOnlyEquationOfState(MoveOnlyEquationOfState &&) noexcept = default;
MoveOnlyEquationOfState(const MoveOnlyEquationOfState &) = delete;
MoveOnlyEquationOfState &operator=(const MoveOnlyEquationOfState &) = delete;
MoveOnlyEquationOfState(MoveOnlyEquationOfState &&) noexcept = default;
MoveOnlyEquationOfState &operator=(MoveOnlyEquationOfState &&) noexcept = default;
[[nodiscard]] const std::unique_ptr<int> &marker() const noexcept {
@@ -60,9 +59,9 @@ namespace {
: m_marker(std::make_unique<int>(parameters.marker)) {
}
MoveOnlySurfaceCondition(const MoveOnlySurfaceCondition &) = delete;
MoveOnlySurfaceCondition &operator=(const MoveOnlySurfaceCondition &) = delete;
MoveOnlySurfaceCondition(MoveOnlySurfaceCondition &&) noexcept = default;
MoveOnlySurfaceCondition(const MoveOnlySurfaceCondition &) = delete;
MoveOnlySurfaceCondition &operator=(const MoveOnlySurfaceCondition &) = delete;
MoveOnlySurfaceCondition(MoveOnlySurfaceCondition &&) noexcept = default;
MoveOnlySurfaceCondition &operator=(MoveOnlySurfaceCondition &&) noexcept = default;
[[nodiscard]] const std::unique_ptr<int> &marker() const noexcept {
@@ -87,7 +86,7 @@ namespace {
"C_move",
"move_only_integral.residual",
"R_move">;
using TargetValue = typename ScalarDescription::TargetValue;
using TargetValue = typename ScalarDescription::TargetValue;
using ModelDefinition = mean_field::integral::FixedScalarWithMultiplier<
MoveOnlyIntegralConstraint,
"MoveOnlyIntegralConstraint",
@@ -99,9 +98,9 @@ namespace {
: m_marker(std::make_unique<int>(parameters.marker)) {
}
MoveOnlyIntegralConstraint(const MoveOnlyIntegralConstraint &) = delete;
MoveOnlyIntegralConstraint &operator=(const MoveOnlyIntegralConstraint &) = delete;
MoveOnlyIntegralConstraint(MoveOnlyIntegralConstraint &&) noexcept = default;
MoveOnlyIntegralConstraint(const MoveOnlyIntegralConstraint &) = delete;
MoveOnlyIntegralConstraint &operator=(const MoveOnlyIntegralConstraint &) = delete;
MoveOnlyIntegralConstraint(MoveOnlyIntegralConstraint &&) noexcept = default;
MoveOnlyIntegralConstraint &operator=(MoveOnlyIntegralConstraint &&) noexcept = default;
[[nodiscard]] const std::unique_ptr<int> &marker() const noexcept {
@@ -167,20 +166,15 @@ TEST_CASE(
tags::stellar_model_specification_api
) {
using namespace mean_field;
using Qualified = models::SpecificationSet<
const eos::Polytrope &,
volatile surface::Isobaric &&,
const integral::FixedTotalMass>;
using Plain = models::SpecificationSet<
eos::Polytrope,
surface::Isobaric,
integral::FixedTotalMass>;
using Qualified =
models::SpecificationSet<const eos::Polytrope &, volatile surface::Isobaric &&, const integral::FixedTotalMass>;
using Plain = models::SpecificationSet<eos::Polytrope, surface::Isobaric, integral::FixedTotalMass>;
STATIC_CHECK(std::same_as<Qualified, Plain>);
STATIC_CHECK(models::ValidModelSpecificationPack<
const eos::Polytrope &,
volatile surface::Isobaric &&,
const integral::FixedTotalMass>);
STATIC_CHECK(
models::ValidModelSpecificationPack<
const eos::Polytrope &, volatile surface::Isobaric &&, const integral::FixedTotalMass>
);
STATIC_CHECK(model::StellarModelType<model::StellarModel<Qualified>>);
}
@@ -226,23 +220,20 @@ TEST_CASE(
using namespace mean_field;
auto stellarModel = model::StellarModel(
MoveOnlyIntegralConstraint({.marker = 307}),
MoveOnlySurfaceCondition({.marker = 211}),
MoveOnlyIntegralConstraint({.marker = 307}), MoveOnlySurfaceCondition({.marker = 211}),
MoveOnlyEquationOfState({.marker = 101})
);
using Model = std::remove_cvref_t<decltype(stellarModel)>;
using Expected = model::StellarModel<models::SpecificationSet<
MoveOnlyEquationOfState,
MoveOnlySurfaceCondition,
MoveOnlyIntegralConstraint>>;
using Model = std::remove_cvref_t<decltype(stellarModel)>;
using Expected = model::StellarModel<
models::SpecificationSet<MoveOnlyEquationOfState, MoveOnlySurfaceCondition, MoveOnlyIntegralConstraint>>;
STATIC_CHECK(std::same_as<Model, Expected>);
STATIC_CHECK_FALSE(std::copy_constructible<MoveOnlyEquationOfState>);
STATIC_CHECK_FALSE(std::copy_constructible<MoveOnlySurfaceCondition>);
STATIC_CHECK_FALSE(std::copy_constructible<MoveOnlyIntegralConstraint>);
const auto &equationOfState = stellarModel.specification<MoveOnlyEquationOfState>();
const auto &surfaceCondition = stellarModel.specification<MoveOnlySurfaceCondition>();
const auto &equationOfState = stellarModel.specification<MoveOnlyEquationOfState>();
const auto &surfaceCondition = stellarModel.specification<MoveOnlySurfaceCondition>();
const auto &integralConstraint = stellarModel.specification<MoveOnlyIntegralConstraint>();
REQUIRE(equationOfState.marker() != nullptr);