feat(newton): first newton solver implementation
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include <numbers>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <catch2/catch_approx.hpp>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
@@ -18,12 +19,12 @@ namespace material_surface_runtime_contract_test {
|
||||
struct RegisteredAlternateEquationOfState final {
|
||||
struct Parameters final { };
|
||||
|
||||
using ModelDefinition = mean_field::models::ConstitutiveLaw<
|
||||
RegisteredAlternateEquationOfState,
|
||||
"RegisteredAlternateMaterialSurfaceEquationOfState">;
|
||||
using ModelDefinition = mean_field::models::
|
||||
ConstitutiveLaw<RegisteredAlternateEquationOfState, "RegisteredAlternateMaterialSurfaceEquationOfState">;
|
||||
using Relations = mean_field::eos::RelationCatalog<mean_field::eos::SpecificEnthalpyFromPressure>;
|
||||
|
||||
explicit RegisteredAlternateEquationOfState(Parameters) noexcept { }
|
||||
explicit RegisteredAlternateEquationOfState(Parameters) noexcept {
|
||||
}
|
||||
|
||||
[[nodiscard]] mean_field::dimensions::SpecificEnthalpyValue evaluate(
|
||||
mean_field::eos::SpecificEnthalpyFromPressure,
|
||||
@@ -40,7 +41,10 @@ namespace material_surface_runtime_contract_test {
|
||||
|
||||
using mfem::Operator::Operator;
|
||||
|
||||
void Mult(const mfem::Vector &, mfem::Vector &) const override;
|
||||
void Mult(
|
||||
const mfem::Vector &,
|
||||
mfem::Vector &
|
||||
) const override;
|
||||
|
||||
[[nodiscard]] const mean_field::operators::StellarEquilibriumLayout &GetLayout() const noexcept;
|
||||
[[nodiscard]] mean_field::operators::PreparedStellarEquilibriumReport Prepare(
|
||||
@@ -58,8 +62,7 @@ namespace material_surface_runtime_contract_test {
|
||||
GetSurfaceConstraintOperator() const;
|
||||
};
|
||||
|
||||
template <mean_field::model::StellarModelType Model>
|
||||
class AlternateEquationOfStateRuntime final {
|
||||
template <mean_field::model::StellarModelType Model> class AlternateEquationOfStateRuntime final {
|
||||
public:
|
||||
using Report = mean_field::operators::EmptySpecificationPreparationReport;
|
||||
|
||||
@@ -68,10 +71,17 @@ namespace material_surface_runtime_contract_test {
|
||||
const mean_field::mapping::DomainMapper &,
|
||||
AlternatePhysicalCore &,
|
||||
const Model &
|
||||
) noexcept { }
|
||||
) noexcept {
|
||||
}
|
||||
|
||||
template <typename StateView, typename Controls>
|
||||
void ReadPhysicalControls(const StateView &, Controls &) noexcept { }
|
||||
template <
|
||||
typename StateView,
|
||||
typename Controls>
|
||||
void ReadPhysicalControls(
|
||||
const StateView &,
|
||||
Controls &
|
||||
) noexcept {
|
||||
}
|
||||
|
||||
template <typename StateView>
|
||||
[[nodiscard]] Report PrepareAfterPhysical(
|
||||
@@ -82,15 +92,18 @@ namespace material_surface_runtime_contract_test {
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename ResidualView>
|
||||
void AddResidual(const ResidualView &) const noexcept { }
|
||||
template <typename ResidualView> void AddResidual(const ResidualView &) const noexcept {
|
||||
}
|
||||
|
||||
template <typename DirectionView, typename ActionView>
|
||||
template <
|
||||
typename DirectionView,
|
||||
typename ActionView>
|
||||
void AddJacobianAction(
|
||||
const DirectionView &,
|
||||
const ActionView &,
|
||||
const AlternatePhysicalCore &
|
||||
) const noexcept { }
|
||||
) const noexcept {
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr bool IsPrepared() const noexcept {
|
||||
return true;
|
||||
@@ -100,10 +113,9 @@ namespace material_surface_runtime_contract_test {
|
||||
|
||||
namespace mean_field::operators {
|
||||
template <>
|
||||
struct StellarEquilibriumCoreRuntime<
|
||||
material_surface_runtime_contract_test::RegisteredAlternateEquationOfState> {
|
||||
struct StellarEquilibriumCoreRuntime<material_surface_runtime_contract_test::RegisteredAlternateEquationOfState> {
|
||||
static constexpr bool registered = true;
|
||||
using CoreType = material_surface_runtime_contract_test::AlternatePhysicalCore;
|
||||
using CoreType = material_surface_runtime_contract_test::AlternatePhysicalCore;
|
||||
|
||||
[[nodiscard]] static std::unique_ptr<CoreType> Make(
|
||||
fem::FEM &,
|
||||
@@ -134,7 +146,7 @@ namespace mean_field::preconditioning {
|
||||
struct MaterialSurfaceEquationOfStateBackend<
|
||||
material_surface_runtime_contract_test::RegisteredAlternateEquationOfState> {
|
||||
static constexpr bool registered = true;
|
||||
using CoreType = material_surface_runtime_contract_test::AlternatePhysicalCore;
|
||||
using CoreType = material_surface_runtime_contract_test::AlternatePhysicalCore;
|
||||
};
|
||||
} // namespace mean_field::preconditioning
|
||||
|
||||
@@ -150,12 +162,12 @@ namespace {
|
||||
mean_field::constraint::FixedCentralDensity>>;
|
||||
using PolytropicProblem = mean_field::equilibrium::StellarEquilibriumProblem<PolytropicModel>;
|
||||
using PolytropicMaterialSurfaceDescriptor = preconditioning::MaterialSurfaceDescriptorFor<PolytropicProblem>;
|
||||
using RegisteredAlternateModel = mean_field::model::StellarModel<mean_field::models::SpecificationSet<
|
||||
using RegisteredAlternateModel = mean_field::model::StellarModel<mean_field::models::SpecificationSet<
|
||||
material_surface_runtime_contract_test::RegisteredAlternateEquationOfState,
|
||||
mean_field::surface::Isobaric,
|
||||
mean_field::integral::FixedTotalMass>>;
|
||||
using RegisteredAlternateProblem = mean_field::equilibrium::StellarEquilibriumProblem<RegisteredAlternateModel>;
|
||||
using MaterialSurfaceDiagonal = preconditioning::MaterialSurfaceBlock<
|
||||
using MaterialSurfaceDiagonal = preconditioning::MaterialSurfaceBlock<
|
||||
PolytropicMaterialSurfaceDescriptor,
|
||||
backend::Diagonal,
|
||||
backend::Diagonal,
|
||||
@@ -174,10 +186,8 @@ namespace {
|
||||
PolytropicMaterialSurfaceDescriptor,
|
||||
preconditioning::ApproximateMaterialSurfaceLDU,
|
||||
backend::FixedCycles>;
|
||||
using RegisteredAlternateGravityComponent = preconditioning::GravityFieldBlock<
|
||||
backend::Diagonal,
|
||||
FixedCycleAMG,
|
||||
preconditioning::GravityApproximateLDU>;
|
||||
using RegisteredAlternateGravityComponent =
|
||||
preconditioning::GravityFieldBlock<backend::Diagonal, FixedCycleAMG, preconditioning::GravityApproximateLDU>;
|
||||
|
||||
using RegisteredAlternateMaterialSurfaceDescriptor =
|
||||
preconditioning::MaterialSurfaceDescriptorFor<RegisteredAlternateProblem>;
|
||||
@@ -185,9 +195,8 @@ namespace {
|
||||
struct DistinctPhysicalCore final { };
|
||||
|
||||
template <typename Problem>
|
||||
concept CanMakeDefaultMaterialSurface = requires(const Problem &problem) {
|
||||
preconditioning::materialSurfaceBlock(problem);
|
||||
};
|
||||
concept CanMakeDefaultMaterialSurface =
|
||||
requires(const Problem &problem) { preconditioning::materialSurfaceBlock(problem); };
|
||||
|
||||
template <typename Problem>
|
||||
concept CanPrepareDefaultMaterialSurface = requires(const Problem &problem) {
|
||||
@@ -195,9 +204,8 @@ namespace {
|
||||
};
|
||||
|
||||
template <typename Problem>
|
||||
concept CanMakeDefaultStellarStructure = requires(const Problem &problem) {
|
||||
preconditioning::stellarStructureBlock(problem);
|
||||
};
|
||||
concept CanMakeDefaultStellarStructure =
|
||||
requires(const Problem &problem) { preconditioning::stellarStructureBlock(problem); };
|
||||
|
||||
class KnownCouplings final {
|
||||
public:
|
||||
@@ -315,41 +323,46 @@ TEST_CASE(
|
||||
STATIC_CHECK(preconditioning::PreconditionerComponent<MaterialSurfaceDiagonal>);
|
||||
STATIC_CHECK(preconditioning::PreconditionerComponent<MaterialSurfaceH1>);
|
||||
STATIC_CHECK(preconditioning::MaterialSurfaceDescriptor<PolytropicMaterialSurfaceDescriptor>);
|
||||
STATIC_CHECK(preconditioning::ImplementedMaterialSurfaceEquationOfState<
|
||||
mean_field::eos::Polytrope>);
|
||||
STATIC_CHECK(preconditioning::ImplementedMaterialSurfaceEquationOfState<mean_field::eos::Polytrope>);
|
||||
STATIC_CHECK_FALSE(preconditioning::ImplementedMaterialSurfaceEquationOfState<int>);
|
||||
STATIC_CHECK(preconditioning::ImplementedMaterialSurfaceDescriptor<PolytropicMaterialSurfaceDescriptor>);
|
||||
STATIC_CHECK(
|
||||
preconditioning::ExecutableMaterialSurfaceRuntimeFor<
|
||||
mean_field::eos::Polytrope, mean_field::operators::PreparedStellarEquilibriumOperator>
|
||||
);
|
||||
STATIC_CHECK(
|
||||
std::same_as<
|
||||
typename preconditioning::MaterialSurfaceEquationOfStateBackend<mean_field::eos::Polytrope>::CoreType,
|
||||
mean_field::operators::PreparedStellarEquilibriumOperator>
|
||||
);
|
||||
STATIC_CHECK(
|
||||
preconditioning::MaterialSurfaceRuntimeFor<
|
||||
PolytropicMaterialSurfaceDescriptor, mean_field::operators::PreparedStellarEquilibriumOperator>
|
||||
);
|
||||
STATIC_CHECK_FALSE(
|
||||
preconditioning::ImplementedMaterialSurfaceEquationOfState<int>);
|
||||
STATIC_CHECK(preconditioning::ImplementedMaterialSurfaceDescriptor<
|
||||
PolytropicMaterialSurfaceDescriptor>);
|
||||
STATIC_CHECK(preconditioning::ExecutableMaterialSurfaceRuntimeFor<
|
||||
mean_field::eos::Polytrope,
|
||||
mean_field::operators::PreparedStellarEquilibriumOperator>);
|
||||
STATIC_CHECK(std::same_as<
|
||||
typename preconditioning::MaterialSurfaceEquationOfStateBackend<
|
||||
mean_field::eos::Polytrope>::CoreType,
|
||||
mean_field::operators::PreparedStellarEquilibriumOperator>);
|
||||
STATIC_CHECK(preconditioning::MaterialSurfaceRuntimeFor<
|
||||
PolytropicMaterialSurfaceDescriptor,
|
||||
mean_field::operators::PreparedStellarEquilibriumOperator>);
|
||||
STATIC_CHECK_FALSE(preconditioning::MaterialSurfaceRuntimeFor<
|
||||
PolytropicMaterialSurfaceDescriptor,
|
||||
DistinctPhysicalCore>);
|
||||
STATIC_CHECK(preconditioning::MaterialSurfaceDescriptor<
|
||||
RegisteredAlternateMaterialSurfaceDescriptor>);
|
||||
preconditioning::MaterialSurfaceRuntimeFor<PolytropicMaterialSurfaceDescriptor, DistinctPhysicalCore>
|
||||
);
|
||||
STATIC_CHECK(preconditioning::MaterialSurfaceDescriptor<RegisteredAlternateMaterialSurfaceDescriptor>);
|
||||
STATIC_CHECK(mean_field::equilibrium::StellarEquilibriumModel<RegisteredAlternateModel>);
|
||||
STATIC_CHECK(std::same_as<
|
||||
typename RegisteredAlternateProblem::PhysicalCoreType,
|
||||
material_surface_runtime_contract_test::AlternatePhysicalCore>);
|
||||
STATIC_CHECK(preconditioning::ImplementedMaterialSurfaceEquationOfState<
|
||||
material_surface_runtime_contract_test::RegisteredAlternateEquationOfState>);
|
||||
STATIC_CHECK(preconditioning::ImplementedMaterialSurfaceDescriptor<
|
||||
RegisteredAlternateMaterialSurfaceDescriptor>);
|
||||
STATIC_CHECK_FALSE(preconditioning::ExecutableMaterialSurfaceRuntimeFor<
|
||||
material_surface_runtime_contract_test::RegisteredAlternateEquationOfState,
|
||||
material_surface_runtime_contract_test::AlternatePhysicalCore>);
|
||||
STATIC_CHECK_FALSE(preconditioning::MaterialSurfaceRuntimeFor<
|
||||
RegisteredAlternateMaterialSurfaceDescriptor,
|
||||
material_surface_runtime_contract_test::AlternatePhysicalCore>);
|
||||
STATIC_CHECK(
|
||||
std::same_as<
|
||||
typename RegisteredAlternateProblem::PhysicalCoreType,
|
||||
material_surface_runtime_contract_test::AlternatePhysicalCore>
|
||||
);
|
||||
STATIC_CHECK(
|
||||
preconditioning::ImplementedMaterialSurfaceEquationOfState<
|
||||
material_surface_runtime_contract_test::RegisteredAlternateEquationOfState>
|
||||
);
|
||||
STATIC_CHECK(preconditioning::ImplementedMaterialSurfaceDescriptor<RegisteredAlternateMaterialSurfaceDescriptor>);
|
||||
STATIC_CHECK_FALSE(
|
||||
preconditioning::ExecutableMaterialSurfaceRuntimeFor<
|
||||
material_surface_runtime_contract_test::RegisteredAlternateEquationOfState,
|
||||
material_surface_runtime_contract_test::AlternatePhysicalCore>
|
||||
);
|
||||
STATIC_CHECK_FALSE(
|
||||
preconditioning::MaterialSurfaceRuntimeFor<
|
||||
RegisteredAlternateMaterialSurfaceDescriptor, material_surface_runtime_contract_test::AlternatePhysicalCore>
|
||||
);
|
||||
STATIC_CHECK(preconditioning::MaterialSurfacePreconditionerProblem<PolytropicProblem>);
|
||||
STATIC_CHECK_FALSE(preconditioning::MaterialSurfacePreconditionerProblem<RegisteredAlternateProblem>);
|
||||
STATIC_CHECK(CanMakeDefaultMaterialSurface<PolytropicProblem>);
|
||||
@@ -357,10 +370,10 @@ TEST_CASE(
|
||||
STATIC_CHECK(CanPrepareDefaultMaterialSurface<PolytropicProblem>);
|
||||
STATIC_CHECK_FALSE(CanPrepareDefaultMaterialSurface<RegisteredAlternateProblem>);
|
||||
STATIC_CHECK_FALSE(preconditioning::StellarStructurePreconditionerProblem<RegisteredAlternateProblem>);
|
||||
STATIC_CHECK_FALSE(preconditioning::StellarStructurePreparableFor<
|
||||
RegisteredAlternateProblem,
|
||||
MaterialSurfaceDiagonal,
|
||||
RegisteredAlternateGravityComponent>);
|
||||
STATIC_CHECK_FALSE(
|
||||
preconditioning::StellarStructurePreparableFor<
|
||||
RegisteredAlternateProblem, MaterialSurfaceDiagonal, RegisteredAlternateGravityComponent>
|
||||
);
|
||||
STATIC_CHECK_FALSE(CanMakeDefaultStellarStructure<RegisteredAlternateProblem>);
|
||||
STATIC_CHECK(
|
||||
mean_field::material::CompiledThermodynamicEquations<typename PolytropicProblem::ThermodynamicEquationsType>
|
||||
@@ -572,9 +585,10 @@ TEST_CASE(
|
||||
const utils::Args arguments = test_utils::setup_args();
|
||||
fem::FEM finiteElements = fem::setup_fem(arguments.mesh_file, arguments, 0);
|
||||
REQUIRE(finiteElements.okay());
|
||||
const mfem::ParFiniteElementSpace *surfaceDeformationSpace = finiteElements.surfaceDeformationFes.get();
|
||||
|
||||
constexpr double radius = utils::RADIUS;
|
||||
constexpr double mass = utils::MASS;
|
||||
constexpr double radius = utils::RADIUS;
|
||||
constexpr double mass = utils::MASS;
|
||||
const double polytropicConstant = 2.0 * utils::G * radius * radius / std::numbers::pi_v<double>;
|
||||
const double centralDensity = std::numbers::pi_v<double> * mass / (4.0 * radius * radius * radius);
|
||||
const auto stellarModel = model::StellarModel(
|
||||
@@ -583,7 +597,7 @@ TEST_CASE(
|
||||
integral::FixedTotalMass({.Mtotal = dimensions::MassValue{mass}}),
|
||||
constraint::FixedCentralDensity({.RhoC = dimensions::DensityValue{centralDensity}})
|
||||
);
|
||||
auto problem = equilibrium::discretize(stellarModel, finiteElements);
|
||||
auto problem = equilibrium::discretize(stellarModel, std::move(finiteElements));
|
||||
auto projected = seed::makeProjectedEquilibriumState(problem, seed::LaneEmden({.radialSampleCount = 512}));
|
||||
const auto rotation = zeroRotation();
|
||||
problem.Prepare(projected.values, makeDependencies(), rotation);
|
||||
@@ -711,7 +725,7 @@ TEST_CASE(
|
||||
CHECK(surfaceFit.relativeGramDeterminant > 1.0e-12);
|
||||
CHECK(surfaceFit.normalEquations.targetTarget > 0.0);
|
||||
CHECK(frequencyAware.GetSurfaceInverse().Height() == physical.GetDomainDeformation().parameterCount());
|
||||
CHECK(frequencyAware.GetSurfaceSurrogateMatrix().Height() == finiteElements.surfaceDeformationFes->GetTrueVSize());
|
||||
CHECK(frequencyAware.GetSurfaceSurrogateMatrix().Height() == surfaceDeformationSpace->GetTrueVSize());
|
||||
CHECK(frequencyAware.GetSurfaceBackend().GetStatistics().setups == 1);
|
||||
CHECK(frequencyAware.GetStatistics().surfaceJacobianProbes == 4);
|
||||
CHECK(frequencyAware.GetStatistics().surfaceH1Assemblies == 3);
|
||||
|
||||
Reference in New Issue
Block a user