feat(libmeanfield): variadic refactor
also added normaliztion operator
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <concepts>
|
||||
#include <memory>
|
||||
#include <numbers>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
@@ -13,6 +14,130 @@
|
||||
import mean_field;
|
||||
import test_helpers;
|
||||
|
||||
namespace material_surface_runtime_contract_test {
|
||||
struct RegisteredAlternateEquationOfState final {
|
||||
struct Parameters final { };
|
||||
|
||||
using ModelDefinition = mean_field::models::ConstitutiveLaw<
|
||||
RegisteredAlternateEquationOfState,
|
||||
"RegisteredAlternateMaterialSurfaceEquationOfState">;
|
||||
using Relations = mean_field::eos::RelationCatalog<mean_field::eos::SpecificEnthalpyFromPressure>;
|
||||
|
||||
explicit RegisteredAlternateEquationOfState(Parameters) noexcept { }
|
||||
|
||||
[[nodiscard]] mean_field::dimensions::SpecificEnthalpyValue evaluate(
|
||||
mean_field::eos::SpecificEnthalpyFromPressure,
|
||||
mean_field::dimensions::PressureValue
|
||||
) const;
|
||||
};
|
||||
|
||||
class AlternatePhysicalCore final : public mfem::Operator {
|
||||
public:
|
||||
using BackendSpecifications = mean_field::models::ModelTypeList<
|
||||
RegisteredAlternateEquationOfState,
|
||||
mean_field::surface::Isobaric,
|
||||
mean_field::models::FixedTotalMass>;
|
||||
|
||||
using mfem::Operator::Operator;
|
||||
|
||||
void Mult(const mfem::Vector &, mfem::Vector &) const override;
|
||||
|
||||
[[nodiscard]] const mean_field::operators::StellarEquilibriumLayout &GetLayout() const noexcept;
|
||||
[[nodiscard]] mean_field::operators::PreparedStellarEquilibriumReport Prepare(
|
||||
const mfem::Vector &,
|
||||
const mean_field::operators::StellarEquilibriumDependencies &,
|
||||
const mean_field::physics::RigidRotation &
|
||||
);
|
||||
void BuildResidual(mfem::Vector &) const;
|
||||
[[nodiscard]] bool IsPrepared() const noexcept;
|
||||
[[nodiscard]] mean_field::operators::RootConstraintReport GetFixedMassReport() const;
|
||||
[[nodiscard]] const mean_field::operators::StellarEquilibriumDependencies &GetDependencies() const;
|
||||
[[nodiscard]] const mean_field::operators::StellarEquilibriumDependencyStamp &
|
||||
GetGeneratedDisplacementDependency() const;
|
||||
[[nodiscard]] const mean_field::operators::PreparedPressureSurfaceConstraint &
|
||||
GetSurfaceConstraintOperator() const;
|
||||
};
|
||||
|
||||
template <mean_field::model::StellarModelType Model>
|
||||
class AlternateEquationOfStateRuntime final {
|
||||
public:
|
||||
using Report = mean_field::operators::EmptySpecificationPreparationReport;
|
||||
|
||||
AlternateEquationOfStateRuntime(
|
||||
mean_field::fem::FEM &,
|
||||
const mean_field::mapping::DomainMapper &,
|
||||
AlternatePhysicalCore &,
|
||||
const Model &
|
||||
) noexcept { }
|
||||
|
||||
template <typename StateView, typename Controls>
|
||||
void ReadPhysicalControls(const StateView &, Controls &) noexcept { }
|
||||
|
||||
template <typename StateView>
|
||||
[[nodiscard]] Report PrepareAfterPhysical(
|
||||
const StateView &,
|
||||
const mean_field::operators::StellarEquilibriumDependencies &,
|
||||
const AlternatePhysicalCore &
|
||||
) noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename ResidualView>
|
||||
void AddResidual(const ResidualView &) const noexcept { }
|
||||
|
||||
template <typename DirectionView, typename ActionView>
|
||||
void AddJacobianAction(
|
||||
const DirectionView &,
|
||||
const ActionView &,
|
||||
const AlternatePhysicalCore &
|
||||
) const noexcept { }
|
||||
|
||||
[[nodiscard]] constexpr bool IsPrepared() const noexcept {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
} // namespace material_surface_runtime_contract_test
|
||||
|
||||
namespace mean_field::operators {
|
||||
template <>
|
||||
struct StellarEquilibriumCoreRuntime<
|
||||
material_surface_runtime_contract_test::RegisteredAlternateEquationOfState> {
|
||||
static constexpr bool registered = true;
|
||||
using CoreType = material_surface_runtime_contract_test::AlternatePhysicalCore;
|
||||
|
||||
[[nodiscard]] static std::unique_ptr<CoreType> Make(
|
||||
fem::FEM &,
|
||||
const mapping::DomainMapper &,
|
||||
const material_surface_runtime_contract_test::RegisteredAlternateEquationOfState &,
|
||||
const models::CompiledFixedMass &,
|
||||
PressureSurfaceConstraintView,
|
||||
deformation::PreparedDomainDeformationRuntime
|
||||
);
|
||||
|
||||
[[nodiscard]] static int SurfaceEquationCount(const CoreType &) noexcept;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct StellarEquilibriumRuntimeContribution<
|
||||
material_surface_runtime_contract_test::RegisteredAlternateEquationOfState>
|
||||
: PreparedStellarEquilibriumContribution<
|
||||
material_surface_runtime_contract_test::AlternateEquationOfStateRuntime> { };
|
||||
} // namespace mean_field::operators
|
||||
|
||||
namespace mean_field::preconditioning {
|
||||
/*
|
||||
* This registration deliberately advertises a distinct core without an
|
||||
* executable material/surface implementation. Registration alone must
|
||||
* therefore remain insufficient for MaterialSurfaceRuntimeFor.
|
||||
*/
|
||||
template <>
|
||||
struct MaterialSurfaceEquationOfStateBackend<
|
||||
material_surface_runtime_contract_test::RegisteredAlternateEquationOfState> {
|
||||
static constexpr bool registered = true;
|
||||
using CoreType = material_surface_runtime_contract_test::AlternatePhysicalCore;
|
||||
};
|
||||
} // namespace mean_field::preconditioning
|
||||
|
||||
namespace {
|
||||
namespace backend = mean_field::preconditioning::backend;
|
||||
namespace blocks = mean_field::utils::blocks;
|
||||
@@ -25,6 +150,11 @@ 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<
|
||||
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<
|
||||
PolytropicMaterialSurfaceDescriptor,
|
||||
backend::Diagonal,
|
||||
@@ -44,6 +174,30 @@ namespace {
|
||||
PolytropicMaterialSurfaceDescriptor,
|
||||
preconditioning::ApproximateMaterialSurfaceLDU,
|
||||
backend::FixedCycles>;
|
||||
using RegisteredAlternateGravityComponent = preconditioning::GravityFieldBlock<
|
||||
backend::Diagonal,
|
||||
FixedCycleAMG,
|
||||
preconditioning::GravityApproximateLDU>;
|
||||
|
||||
using RegisteredAlternateMaterialSurfaceDescriptor =
|
||||
preconditioning::MaterialSurfaceDescriptorFor<RegisteredAlternateProblem>;
|
||||
|
||||
struct DistinctPhysicalCore final { };
|
||||
|
||||
template <typename Problem>
|
||||
concept CanMakeDefaultMaterialSurface = requires(const Problem &problem) {
|
||||
preconditioning::materialSurfaceBlock(problem);
|
||||
};
|
||||
|
||||
template <typename Problem>
|
||||
concept CanPrepareDefaultMaterialSurface = requires(const Problem &problem) {
|
||||
preconditioning::prepare(problem, preconditioning::materialSurfaceBlock(problem));
|
||||
};
|
||||
|
||||
template <typename Problem>
|
||||
concept CanMakeDefaultStellarStructure = requires(const Problem &problem) {
|
||||
preconditioning::stellarStructureBlock(problem);
|
||||
};
|
||||
|
||||
class KnownCouplings final {
|
||||
public:
|
||||
@@ -161,6 +315,53 @@ 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_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>);
|
||||
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(preconditioning::MaterialSurfacePreconditionerProblem<PolytropicProblem>);
|
||||
STATIC_CHECK_FALSE(preconditioning::MaterialSurfacePreconditionerProblem<RegisteredAlternateProblem>);
|
||||
STATIC_CHECK(CanMakeDefaultMaterialSurface<PolytropicProblem>);
|
||||
STATIC_CHECK_FALSE(CanMakeDefaultMaterialSurface<RegisteredAlternateProblem>);
|
||||
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(CanMakeDefaultStellarStructure<RegisteredAlternateProblem>);
|
||||
STATIC_CHECK(
|
||||
mean_field::material::CompiledThermodynamicEquations<typename PolytropicProblem::ThermodynamicEquationsType>
|
||||
);
|
||||
@@ -171,7 +372,7 @@ TEST_CASE(
|
||||
);
|
||||
STATIC_CHECK(MaterialSurfaceDiagonal::CorrectionBlocks::size == 3);
|
||||
STATIC_CHECK(MaterialSurfaceDiagonal::ResidualBlocks::size == 3);
|
||||
STATIC_CHECK(MaterialSurfaceDiagonal::RequiredCouplings::size == 8);
|
||||
STATIC_CHECK(MaterialSurfaceDiagonal::RequiredCouplings::size == 9);
|
||||
STATIC_CHECK(preconditioning::CompletePreconditionerFor<Plan, Form>);
|
||||
STATIC_CHECK(preconditioning::CompatiblePreconditionerFor<Plan, Form, JacobianForm>);
|
||||
STATIC_CHECK(preconditioning::backend::ArnoldiAdmissible<typename MaterialSurfaceDiagonal::BackendType>);
|
||||
@@ -409,7 +610,7 @@ TEST_CASE(
|
||||
|
||||
mfem::Vector fullDirection(physical.Width());
|
||||
fullDirection = 0.0;
|
||||
const auto fullDirectionView = physical.GetRootManifest().directionView(fullDirection);
|
||||
const auto fullDirectionView = physical.GetRootManifest().stateView(fullDirection);
|
||||
const auto &offsets = restricted.GetOffsets();
|
||||
const mfem::Vector densityDirection(restrictedDirection.GetData(), offsets[1]);
|
||||
const mfem::Vector surfaceDirection(restrictedDirection.GetData() + offsets[1], offsets[2] - offsets[1]);
|
||||
|
||||
Reference in New Issue
Block a user