Snapshot optimized solver and audit diagnostics before numerical experiments

This commit is contained in:
2026-09-16 14:34:06 -04:00
parent 75cc638739
commit 80cc3d83d7
64 changed files with 11969 additions and 267 deletions

View File

@@ -411,9 +411,27 @@ export namespace mean_field::preconditioning {
[[nodiscard]] std::unique_ptr<mfem::HypreParMatrix> assembleGravityDivergenceSurrogate(const fem::FEM &f);
// Fixed computational-mesh divergence, owned by one prepared block.
// FES/mesh/node sequences and policy identity invalidate it. Raw node edits
// require Mesh::NodesUpdated(). Clear explicitly if the policy changes in place.
class PreparedGravityDivergenceCache {
public:
[[nodiscard]] const mfem::HypreParMatrix &Get(const fem::FEM &f);
void Clear() noexcept { m_matrix.reset(); }
[[nodiscard]] std::uint64_t GetBuildCount() const noexcept { return m_builds; }
private:
std::unique_ptr<mfem::HypreParMatrix> m_matrix;
const mfem::Mesh *m_mesh{nullptr};
const mfem::ParFiniteElementSpace *m_flux{nullptr}, *m_potential{nullptr};
const quadrature::RuleFactory *m_policy{nullptr};
long m_meshSequence{-1}, m_nodesSequence{-1}, m_fluxSequence{-1}, m_potentialSequence{-1};
std::uint64_t m_builds{0};
};
[[nodiscard]] std::unique_ptr<mfem::HypreParMatrix> assembleGravityPotentialSchurSurrogate(
const fem::FEM &f,
const mfem::Vector &trueMassDiagonal
const mfem::Vector &trueMassDiagonal,
PreparedGravityDivergenceCache *divergenceCache = nullptr
);
struct GravityFieldBlockPreparationReport final {
@@ -548,6 +566,7 @@ export namespace mean_field::preconditioning {
RefreshMassInverse(geometryContext);
report.rebuiltMassInverse = true;
if (report.discretizationChanged) m_fixedDivergence.Clear();
auto potentialSchur = AssemblePotentialSchur(f, geometryContext);
m_potentialSchurInverse.Refresh(*potentialSchur);
m_potentialSchurSurrogate = std::move(potentialSchur);
@@ -586,6 +605,10 @@ export namespace mean_field::preconditioning {
return m_factorization;
}
[[nodiscard]] std::uint64_t GetDivergenceAssemblyCount() const noexcept {
return m_fixedDivergence.GetBuildCount();
}
[[nodiscard]] const PreparedGravityFieldBlockStatistics &GetStatistics() const noexcept {
return m_statistics;
}
@@ -632,13 +655,13 @@ export namespace mean_field::preconditioning {
}
}
[[nodiscard]] static std::unique_ptr<mfem::HypreParMatrix> AssemblePotentialSchur(
[[nodiscard]] std::unique_ptr<mfem::HypreParMatrix> AssemblePotentialSchur(
const fem::FEM &f,
const operators::context::gravity_field::GravityFieldGeometryContext &geometryContext
) {
mfem::Vector trueMassDiagonal;
geometryContext.GetMassOperator().AssembleTrueDiagonal(trueMassDiagonal);
return assembleGravityPotentialSchurSurrogate(f, trueMassDiagonal);
return assembleGravityPotentialSchurSurrogate(f, trueMassDiagonal, &m_fixedDivergence);
}
Block m_block;
@@ -647,6 +670,7 @@ export namespace mean_field::preconditioning {
field::FieldDofMap m_potentialMap;
ReducedGravityDivergenceOperator m_divergence;
PreparedMassInverse m_massInverse;
PreparedGravityDivergenceCache m_fixedDivergence;
std::unique_ptr<mfem::HypreParMatrix> m_potentialSchurSurrogate;
backend::PreparedHypreBoomerAMG<Mode> m_potentialSchurInverse;
ReducedFieldSolverAdapter m_reducedPotentialSchurInverse;