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

@@ -231,10 +231,90 @@ export namespace mean_field::preconditioning {
template <typename Candidate>
concept MaterialSurfaceDescriptor = detail::IsMaterialSurfaceDescriptor<std::remove_cvref_t<Candidate>>::value;
/*
* Capability boundary for EOS-specific material/surface surrogate
* assembly. The current kernels remain polytropic, but selection no
* longer embeds that closed-world type test in the descriptor concept.
*/
template <typename EquationOfState>
struct MaterialSurfaceEquationOfStateBackend {
static constexpr bool registered = false;
};
template <>
struct MaterialSurfaceEquationOfStateBackend<eos::Polytrope> {
static constexpr bool registered = true;
using CoreType = operators::PreparedStellarEquilibriumOperator;
};
template <typename EquationOfState>
concept ImplementedMaterialSurfaceEquationOfState = requires {
{
MaterialSurfaceEquationOfStateBackend<std::remove_cvref_t<EquationOfState>>::registered
} -> std::convertible_to<bool>;
requires MaterialSurfaceEquationOfStateBackend<
std::remove_cvref_t<EquationOfState>>::registered;
typename MaterialSurfaceEquationOfStateBackend<std::remove_cvref_t<EquationOfState>>::CoreType;
};
/*
* Registering an EOS-to-core association is intentionally not enough to
* claim that the material/surface preconditioner can execute it. Every
* implementation listed here must have matching prepared operators and
* prepare(...) overloads below. A future backend should add its pair only
* after those executable pieces exist; this keeps capability queries
* truthful while the current kernels still consume the legacy physical
* core directly.
*/
template <typename EquationOfState, typename PhysicalCore>
struct MaterialSurfaceExecutableRuntime {
static constexpr bool available = false;
};
template <>
struct MaterialSurfaceExecutableRuntime<eos::Polytrope, operators::PreparedStellarEquilibriumOperator> {
static constexpr bool available = true;
};
template <typename EquationOfState, typename PhysicalCore>
concept ExecutableMaterialSurfaceRuntimeFor = requires {
{
MaterialSurfaceExecutableRuntime<
std::remove_cvref_t<EquationOfState>,
std::remove_cvref_t<PhysicalCore>>::available
} -> std::convertible_to<bool>;
requires MaterialSurfaceExecutableRuntime<
std::remove_cvref_t<EquationOfState>,
std::remove_cvref_t<PhysicalCore>>::available;
};
template <typename Descriptor>
concept ImplementedMaterialSurfaceDescriptor =
MaterialSurfaceDescriptor<Descriptor> &&
std::same_as<typename Descriptor::ThermodynamicEquations::EquationOfStateType, eos::Polytrope>;
ImplementedMaterialSurfaceEquationOfState<
typename Descriptor::ThermodynamicEquations::EquationOfStateType>;
template <typename Descriptor, typename PhysicalCore>
concept MaterialSurfaceRuntimeFor =
ImplementedMaterialSurfaceDescriptor<Descriptor> && requires {
typename MaterialSurfaceEquationOfStateBackend<
typename std::remove_cvref_t<Descriptor>::ThermodynamicEquations::EquationOfStateType>::CoreType;
requires std::same_as<
std::remove_cvref_t<PhysicalCore>,
typename MaterialSurfaceEquationOfStateBackend<
typename std::remove_cvref_t<Descriptor>::ThermodynamicEquations::EquationOfStateType>::CoreType>;
requires ExecutableMaterialSurfaceRuntimeFor<
typename std::remove_cvref_t<Descriptor>::ThermodynamicEquations::EquationOfStateType,
PhysicalCore>;
};
template <typename Candidate>
concept MaterialSurfacePreconditionerProblem =
equilibrium::DiscretizedStellarEquilibriumProblem<Candidate> && requires {
requires MaterialSurfaceRuntimeFor<
MaterialSurfaceDescriptorFor<std::remove_cvref_t<Candidate>>,
typename std::remove_cvref_t<Candidate>::PhysicalCoreType>;
};
using DensityMassDiagonalCharacteristics = OperatorCharacteristics<
OperatorCategory::mass_like,
@@ -605,7 +685,7 @@ export namespace mean_field::preconditioning {
};
template <
equilibrium::DiscretizedStellarEquilibriumProblem Problem,
MaterialSurfacePreconditionerProblem Problem,
backend::Registered MaterialBackend = backend::Diagonal,
backend::Registered SurfaceBackend = backend::Diagonal,
MaterialSurfaceFactorizationPolicy Policy = SurfaceThenMaterialTriangular>
@@ -623,7 +703,7 @@ export namespace mean_field::preconditioning {
}
template <
equilibrium::DiscretizedStellarEquilibriumProblem Problem,
MaterialSurfacePreconditionerProblem Problem,
backend::Registered MaterialBackend,
backend::Registered SurfaceBackend,
MaterialSurfaceFactorizationPolicy Policy,
@@ -688,7 +768,7 @@ export namespace mean_field::preconditioning {
// direct coupling actions and does not pay for a full Jacobian
// application.
m_fullDirection = 0.0;
const auto fullDirectionView = m_operation->GetRootManifest().directionView(m_fullDirection);
const auto fullDirectionView = m_operation->GetRootManifest().stateView(m_fullDirection);
mfem::Vector fullDensityDirection = fullDirectionView.block(utils::blocks::density_field.mass_term);
mfem::Vector fullSurfaceDirection =
fullDirectionView.block(utils::blocks::surface_deformation_field.parameters_term);
@@ -699,10 +779,10 @@ export namespace mean_field::preconditioning {
m_operation->Mult(m_fullDirection, m_fullAction);
const auto fullActionView = m_operation->GetRootManifest().residualView(m_fullAction);
const mfem::Vector fullDensityAction = fullActionView.block(utils::blocks::density_field.mass_term);
const mfem::Vector fullSurfaceAction =
const auto fullDensityAction = fullActionView.block(utils::blocks::density_field.mass_term);
const auto fullSurfaceAction =
fullActionView.block(utils::blocks::surface_deformation_field.shape_equilibrium_term);
const mfem::Vector fullEnthalpyAction = fullActionView.block(utils::blocks::enthalpy_field.specific_term);
const auto fullEnthalpyAction = fullActionView.block(utils::blocks::enthalpy_field.specific_term);
densityAction = fullDensityAction;
surfaceAction = fullSurfaceAction;
enthalpyAction = fullEnthalpyAction;
@@ -1108,7 +1188,8 @@ export namespace mean_field::preconditioning {
std::uint64_t surfaceH1Assemblies{0};
};
template <ImplementedMaterialSurfaceDescriptor Descriptor, MaterialSurfaceFactorizationPolicy Policy>
template <MaterialSurfaceDescriptor Descriptor, MaterialSurfaceFactorizationPolicy Policy>
requires MaterialSurfaceRuntimeFor<Descriptor, operators::PreparedStellarEquilibriumOperator>
class PreparedMaterialSurfaceBlock final : public mfem::Solver {
public:
using Block = MaterialSurfaceBlock<Descriptor, backend::Diagonal, backend::Diagonal, Policy>;
@@ -1562,9 +1643,10 @@ export namespace mean_field::preconditioning {
};
template <
ImplementedMaterialSurfaceDescriptor Descriptor,
MaterialSurfaceDescriptor Descriptor,
MaterialSurfaceFactorizationPolicy Policy,
backend::ApplicationMode Mode>
requires MaterialSurfaceRuntimeFor<Descriptor, operators::PreparedStellarEquilibriumOperator>
class PreparedH1MaterialSurfaceBlock final : public mfem::Solver {
public:
using SurfaceBackend = backend::HypreBoomerAMG<Mode>;
@@ -2027,8 +2109,9 @@ export namespace mean_field::preconditioning {
};
template <
ImplementedMaterialSurfaceDescriptor Descriptor,
MaterialSurfaceDescriptor Descriptor,
MaterialSurfaceFactorizationPolicy Policy>
requires MaterialSurfaceRuntimeFor<Descriptor, operators::PreparedStellarEquilibriumOperator>
[[nodiscard]] auto prepare(
const operators::PreparedStellarEquilibriumOperator &operation,
MaterialSurfaceBlock<
@@ -2042,26 +2125,26 @@ export namespace mean_field::preconditioning {
template <
equilibrium::StellarEquilibriumModel Model,
equilibrium::StellarDiscretizationType Discretization,
MaterialSurfaceFactorizationPolicy Policy>
requires MaterialSurfacePreconditionerProblem<
equilibrium::StellarEquilibriumProblem<Model, Discretization>>
[[nodiscard]] auto prepare(
const equilibrium::StellarEquilibriumProblem<Model> &problem,
const equilibrium::StellarEquilibriumProblem<Model, Discretization> &problem,
MaterialSurfaceBlock<
MaterialSurfaceDescriptorFor<equilibrium::StellarEquilibriumProblem<Model>>,
MaterialSurfaceDescriptorFor<equilibrium::StellarEquilibriumProblem<Model, Discretization>>,
backend::Diagonal,
backend::Diagonal,
Policy> block
) {
if constexpr (equilibrium::StellarEquilibriumProblem<Model>::hasFixedCentralDensity) {
return prepare(problem.GetPreparedOperator().GetPhysicalOperator(), std::move(block));
} else {
return prepare(problem.GetPreparedOperator(), std::move(block));
}
return prepare(problem.GetPhysicalOperator(), std::move(block));
}
template <
ImplementedMaterialSurfaceDescriptor Descriptor,
MaterialSurfaceDescriptor Descriptor,
MaterialSurfaceFactorizationPolicy Policy,
backend::ApplicationMode Mode>
requires MaterialSurfaceRuntimeFor<Descriptor, operators::PreparedStellarEquilibriumOperator>
[[nodiscard]] auto prepare(
const operators::PreparedStellarEquilibriumOperator &operation,
MaterialSurfaceBlock<
@@ -2076,21 +2159,20 @@ export namespace mean_field::preconditioning {
template <
equilibrium::StellarEquilibriumModel Model,
equilibrium::StellarDiscretizationType Discretization,
MaterialSurfaceFactorizationPolicy Policy,
backend::ApplicationMode Mode>
requires MaterialSurfacePreconditionerProblem<
equilibrium::StellarEquilibriumProblem<Model, Discretization>>
[[nodiscard]] auto prepare(
const equilibrium::StellarEquilibriumProblem<Model> &problem,
const equilibrium::StellarEquilibriumProblem<Model, Discretization> &problem,
MaterialSurfaceBlock<
MaterialSurfaceDescriptorFor<equilibrium::StellarEquilibriumProblem<Model>>,
MaterialSurfaceDescriptorFor<equilibrium::StellarEquilibriumProblem<Model, Discretization>>,
backend::Diagonal,
backend::HypreBoomerAMG<Mode>,
Policy,
SurfaceH1MassStiffness> block
) {
if constexpr (equilibrium::StellarEquilibriumProblem<Model>::hasFixedCentralDensity) {
return prepare(problem.GetPreparedOperator().GetPhysicalOperator(), std::move(block));
} else {
return prepare(problem.GetPreparedOperator(), std::move(block));
}
return prepare(problem.GetPhysicalOperator(), std::move(block));
}
} // namespace mean_field::preconditioning