feat(preconditioner): major work on preconditioner system

first preconditioner MVP
This commit is contained in:
2026-09-04 07:54:10 -04:00
parent 25510008dd
commit 71423d543f
61 changed files with 15920 additions and 422 deletions

View File

@@ -76,6 +76,12 @@ export namespace mean_field::operators::context::gravity_field {
DisplacementRevision displacement_revision
);
GravityFieldGeometryPreparation PreparePrimal(
const mfem::Vector &displacement,
DiscretizationRevision discretization_revision,
DisplacementRevision displacement_revision
);
[[nodiscard]] const PreparedMappedHDivMassOperator &GetMassOperator() const;
[[nodiscard]] const PreparedMappedGravitySourceOperator &GetSourceOperator() const;
[[nodiscard]] const mfem::Operator &GetDivergenceOperator() const;
@@ -87,12 +93,21 @@ export namespace mean_field::operators::context::gravity_field {
[[nodiscard]] bool IsPrepared() const noexcept;
private:
enum class PreparationMode : std::uint8_t { primal, linearization };
GravityFieldGeometryPreparation PrepareImpl(
const mfem::Vector &displacement,
DiscretizationRevision discretization_revision,
DisplacementRevision displacement_revision,
PreparationMode mode
);
const fem::FEM &m_fem;
const mapping::DomainMapper &m_domain_mapper;
std::unique_ptr<PreparedMappedHDivMassOperator> m_mass_operator;
std::unique_ptr<PreparedMappedGravitySourceOperator> m_source_operator;
std::unique_ptr<mfem::ParMixedBilinearForm> m_divergence_operator;
std::unique_ptr<mfem::Operator> m_divergence_operator;
std::unique_ptr<mfem::TransposeOperator> m_transpose_divergence_operator;
field::FieldDofMap m_displacement_map;
@@ -102,6 +117,7 @@ export namespace mean_field::operators::context::gravity_field {
DisplacementRevision m_displacement_revision;
bool m_is_prepared{false};
bool m_variation_state_prepared{false};
};
struct GravityFieldPreparationReport {

View File

@@ -60,6 +60,12 @@ export namespace mean_field::operators {
mfem::Array<int> m_state_offsets;
mfem::Array<int> m_residual_offsets;
GravityFieldJacobianOperator &m_jacobian;
mutable mfem::Vector m_potential_true;
mutable mfem::Vector m_transpose_divergence_action_true;
mutable mfem::Vector m_transpose_divergence_action;
mutable mfem::Vector m_gradient_true;
mutable mfem::Vector m_divergence_action_true;
};
class ReducedGravityFieldOperator final : public mfem::Operator {

View File

@@ -54,6 +54,10 @@ export namespace mean_field::operators {
void BuildResidual(mfem::Vector &residual) const;
// Exact diagonal of the prepared density-to-closure block, expressed
// in the reduced density coordinates used by the root operator.
void AssembleDensityJacobianDiagonal(mfem::Vector &diagonal) const;
[[nodiscard]] bool IsPrepared() const noexcept;
[[nodiscard]] std::uint64_t GetPreparationCount() const noexcept;
[[nodiscard]] int GetDensitySize() const noexcept;

View File

@@ -18,6 +18,7 @@ export namespace mean_field::operators {
);
void Prepare(const mfem::Vector &displacement);
void PreparePrimal(const mfem::Vector &displacement);
void Mult(
const mfem::Vector &density,
mfem::Vector &action
@@ -29,6 +30,7 @@ export namespace mean_field::operators {
) const;
[[nodiscard]] bool IsPrepared() const noexcept;
[[nodiscard]] bool HasVariationData() const noexcept;
[[nodiscard]] std::uint64_t GetPreparationCount() const noexcept;
[[nodiscard]] const field::FieldDofMap &GetDensityMap() const noexcept;
@@ -41,6 +43,8 @@ export namespace mean_field::operators {
) const override;
private:
enum class PreparationMode : std::uint8_t { primal, linearization };
struct ElementPAData {
int element_id{-1};
@@ -64,6 +68,11 @@ export namespace mean_field::operators {
mfem::Vector quadrature_data;
};
void PrepareImpl(
const mfem::Vector &displacement,
PreparationMode mode
);
const fem::FEM &m_fem;
const mapping::DomainMapper &m_domain_mapper;
@@ -77,6 +86,11 @@ export namespace mean_field::operators {
mutable mfem::Vector m_density_true;
mutable mfem::Vector m_potential_true;
mutable mfem::Vector m_action_true;
mutable mfem::Vector m_potential_local;
mutable mfem::Vector m_local_action;
mutable mfem::Vector m_element_input;
mutable mfem::Vector m_quadrature_action;
mutable mfem::Vector m_element_action;
mutable mfem::Vector m_density_local;
mutable mfem::Vector m_displacement_variation_local;
mutable mfem::Vector m_local_variation_action;
@@ -90,5 +104,6 @@ export namespace mean_field::operators {
std::uint64_t m_preparation_count{0};
bool m_is_prepared{false};
bool m_has_variation_data{false};
};
} // namespace mean_field::operators

View File

@@ -18,6 +18,7 @@ export namespace mean_field::operators {
);
void Prepare(const mfem::Vector &displacement);
void PreparePrimal(const mfem::Vector &displacement);
void Mult(
const mfem::Vector &gravity_gradient,
mfem::Vector &action
@@ -31,12 +32,15 @@ export namespace mean_field::operators {
void AssembleTrueDiagonal(mfem::Vector &diagonal) const;
[[nodiscard]] bool IsPrepared() const noexcept;
[[nodiscard]] bool HasVariationData() const noexcept;
[[nodiscard]] std::uint64_t GetPreparationCount() const noexcept;
[[nodiscard]] const field::FieldDofMap &GetFluxMap() const noexcept;
[[nodiscard]] const field::FieldDofMap &GetDisplacementMap() const noexcept;
private:
enum class PreparationMode : std::uint8_t { primal, linearization };
struct ElementVariationData {
int elementId{-1};
mfem::Array<int> gravityGradientDofs;
@@ -51,6 +55,10 @@ export namespace mean_field::operators {
};
void PrepareVariationData();
void PrepareImpl(
const mfem::Vector &displacement,
PreparationMode mode
);
const fem::FEM &m_fem;
const mapping::DomainMapper &m_domain_mapper;
@@ -68,6 +76,9 @@ export namespace mean_field::operators {
mutable mfem::Vector m_flux_true;
mutable mfem::Vector m_action_true;
mutable mfem::Vector m_domain_action_true;
mutable mfem::Vector m_flux_local;
mutable mfem::Vector m_action_local;
mutable mfem::Vector m_domain_action_local;
mfem::Vector m_displacement_true;
std::vector<ElementVariationData> m_variationElements;
@@ -86,5 +97,7 @@ export namespace mean_field::operators {
mutable mfem::DenseMatrix m_massTensorVariation;
std::uint64_t m_preparation_count{0};
bool m_is_prepared{false};
bool m_has_variation_data{false};
bool m_single_rank{true};
};
} // namespace mean_field::operators

View File

@@ -138,6 +138,10 @@ export namespace mean_field::operators {
mfem::Vector &action
) const;
// Exact diagonal of the volume enthalpy-to-hydrostatic block. Surface
// boundary-row replacement is deliberately applied by its owner.
void AssembleEnthalpyJacobianDiagonal(mfem::Vector &diagonal) const;
[[nodiscard]] bool IsPrepared() const noexcept;
[[nodiscard]] const context::hydrostatic::HydrostaticPreparationStatistics &

View File

@@ -11,6 +11,7 @@ export module mean_field:operators.stellar_equilibrium_problem;
export import :deformation.domain_deformation;
export import :equilibrium.stellar_discretization;
export import :material.thermodynamic_equations;
export import :model.typed_stellar;
export import :operators.prepared_central_density_stellar_equilibrium;
export import :surface.compiler;
@@ -39,8 +40,25 @@ export namespace mean_field::equilibrium {
hasFixedCentralDensity,
operators::PreparedCentralDensityStellarEquilibriumOperator,
operators::PreparedStellarEquilibriumOperator>;
using CompiledSurfaceConstraintType =
surface::CompiledPressureSurfaceConstraintT<surface::BarotropicSurfaceFormulation, eos::Polytrope>;
using FormType = std::conditional_t<
hasFixedCentralDensity,
operators::CentralDensityStellarEquilibriumForm,
utils::blocks::surface_deformed_stellar_equilibrium_form>;
using JacobianFormType = std::conditional_t<
hasFixedCentralDensity,
operators::CentralDensityStellarEquilibriumJacobianForm,
utils::blocks::surface_deformed_stellar_equilibrium_jacobian_form>;
using ManifestType = std::conditional_t<
hasFixedCentralDensity,
operators::CentralDensityStellarEquilibriumSystemManifest,
operators::StellarEquilibriumSystemManifest>;
using EquationOfStateType = eos::Polytrope;
using AvailableThermodynamicEquations = material::StellarEquilibriumThermodynamicEquations;
using ThermodynamicEquationsType =
material::CompiledThermodynamicEquationsT<EquationOfStateType, FormType, AvailableThermodynamicEquations>;
using CompiledSurfaceConstraintType = surface::CompiledPressureSurfaceConstraintT<
typename ThermodynamicEquationsType::PressureSurfaceFormulation,
EquationOfStateType>;
StellarEquilibriumProblem(
ModelType stellarModel,
@@ -113,6 +131,26 @@ export namespace mean_field::equilibrium {
return m_preparedOperator.GetRootManifest();
}
[[nodiscard]] bool IsPrepared() const noexcept {
return m_preparedOperator.IsPrepared();
}
[[nodiscard]] const operators::StellarEquilibriumDependencies &GetLinearizationDependencies() const {
if constexpr (hasFixedCentralDensity) {
return m_preparedOperator.GetPhysicalOperator().GetDependencies();
} else {
return m_preparedOperator.GetDependencies();
}
}
[[nodiscard]] const operators::StellarEquilibriumDependencyStamp &GetGeometryDependency() const {
if constexpr (hasFixedCentralDensity) {
return m_preparedOperator.GetPhysicalOperator().GetGeneratedDisplacementDependency();
} else {
return m_preparedOperator.GetGeneratedDisplacementDependency();
}
}
[[nodiscard]] const field::FieldBoundaryDofMap &GetPressureSurfaceRows() const noexcept {
if constexpr (hasFixedCentralDensity) {
return m_preparedOperator.GetPhysicalOperator().GetSurfaceConstraintOperator().GetSurfaceRows();
@@ -154,9 +192,10 @@ export namespace mean_field::equilibrium {
private:
[[nodiscard]] static CompiledSurfaceConstraintType CompileSurfaceConstraint(const ModelType &stellarModel) {
return surface::compilePressureSurfaceConstraint<surface::BarotropicSurfaceFormulation>(
return surface::compilePressureSurfaceConstraint<
typename ThermodynamicEquationsType::PressureSurfaceFormulation>(
stellarModel.template specification<surface::Isobaric>(),
stellarModel.template specification<eos::Polytrope>()
stellarModel.template specification<EquationOfStateType>()
);
}
@@ -207,4 +246,12 @@ export namespace mean_field::equilibrium {
) {
return discretize(std::forward<Model>(stellarModel), StellarDiscretization{finiteElementModel});
}
template <typename Candidate> struct IsStellarEquilibriumProblem : std::false_type { };
template <StellarEquilibriumModel Model>
struct IsStellarEquilibriumProblem<StellarEquilibriumProblem<Model>> : std::true_type { };
template <typename Candidate>
concept DiscretizedStellarEquilibriumProblem = IsStellarEquilibriumProblem<std::remove_cvref_t<Candidate>>::value;
} // namespace mean_field::equilibrium