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

@@ -11,6 +11,7 @@ module;
#include <mfem.hpp>
#include <mpi.h>
#include "interior_displacement_contractions.hpp"
module mean_field;
@@ -228,6 +229,7 @@ namespace mean_field::operators {
const bool updateAngularVelocity = !m_isPrepared || dependencies.rotation != m_preparedDependencies.rotation ||
angularVelocity != m_angularVelocity;
if (refreshGeometry || refreshDensity) m_jacobianRowsReady = false;
m_isPrepared = false;
if (synchronize_non_finite_failure(
!std::isfinite(angularVelocity), m_fem.mesh->GetComm(), "angular-velocity validity"
@@ -466,8 +468,99 @@ namespace mean_field::operators {
++m_residualApplicationCount;
}
bool PreparedAngularMomentumOperator::PrepareJacobianRows() const {
VerifyPrepared();
if (m_jacobianRowsReady) return m_jacobianRowsSupported;
m_jacobianRowsSupported = false;
for (const ElementPAData &data : m_elements) {
const auto &element = *m_fem.displacementFes->GetFE(data.elementId);
if (element.GetMapType() != mfem::FiniteElement::VALUE ||
element.GetDerivType() != mfem::FiniteElement::GRAD ||
m_domainMapper.IsCompactifiedElement(*m_fem.mesh->GetElementTransformation(data.elementId))) {
m_jacobianRowsReady = true;
return false;
}
}
m_densityJacobianLocal.SetSize(m_fem.densityFes->GetVSize());
m_displacementJacobianLocal.SetSize(m_fem.displacementFes->GetVSize());
m_densityJacobianLocal = 0.0;
m_displacementJacobianLocal = 0.0;
mfem::Vector densityRow, displacementRow, weightedRadius;
mapping::VolumeMappingContext mappingContext;
const auto &axis = m_constraint.specification().axis();
const auto &center = m_constraint.specification().center();
for (const ElementPAData &data : m_elements) {
const int nq = data.integrationRule->GetNPoints();
weightedRadius.SetSize(nq);
for (int q = 0; q < nq; ++q)
weightedRadius(q) = data.quadratureWeights(q) * data.cylindricalRadiusSquared(q);
densityRow.SetSize(data.densityDofs.Size());
data.densityBasis->GetValues().MultTranspose(weightedRadius, densityRow);
displacementRow.SetSize(data.displacementDofs.Size());
displacementRow = 0.0;
const auto basis = m_fem.GetReferenceTables().GetScalarTable(
*m_fem.displacementFes->GetFE(data.elementId), *data.integrationRule);
for (int q = 0; q < nq; ++q) {
data.mappingContexts.Load(q, mappingContext);
double relative[3], positionCoefficient[3], axialPosition = 0.0;
for (int c = 0; c < 3; ++c) {
relative[c] = mappingContext.mapping.physical_position(c) - center[c];
axialPosition += axis[c] * relative[c];
}
for (int c = 0; c < 3; ++c)
positionCoefficient[c] = 2.0 * data.density(q) * data.quadratureWeights(q) *
(relative[c] - axis[c] * axialPosition);
add_interior_functional_row(
basis->GetGradients(q), basis->GetValues(), q, mappingContext.quadrature.J_inv,
data.density(q) * weightedRadius(q), positionCoefficient, displacementRow);
}
if (data.densityDofTransformation) data.densityDofTransformation->TransformDual(densityRow);
if (data.displacementDofTransformation) data.displacementDofTransformation->TransformDual(displacementRow);
m_densityJacobianLocal.AddElementVector(data.densityDofs, densityRow);
m_displacementJacobianLocal.AddElementVector(data.displacementDofs, displacementRow);
}
verify_finite_vector(m_densityJacobianLocal, "Prepared angular-momentum density row is non-finite.");
verify_finite_vector(m_displacementJacobianLocal, "Prepared angular-momentum displacement row is non-finite.");
m_jacobianRowsSupported = true;
m_jacobianRowsReady = true;
++m_jacobianRowPreparationCount;
return true;
}
std::uint64_t PreparedAngularMomentumOperator::GetJacobianRowPreparationCount() const noexcept {
return m_jacobianRowPreparationCount;
}
double PreparedAngularMomentumOperator::EvaluateDensityMomentActionLocal(const mfem::Vector &direction) const {
if (!PrepareJacobianRows()) return EvaluateDensityMomentActionLocalReference(direction);
true_to_local(*m_fem.densityFes, direction, m_densityVariationLocal);
return m_densityJacobianLocal * m_densityVariationLocal;
}
double PreparedAngularMomentumOperator::EvaluateDisplacementMomentActionLocal(const mfem::Vector &direction) const {
if (!PrepareJacobianRows()) return EvaluateDisplacementMomentActionLocalReference(direction);
true_to_local(*m_fem.displacementFes, direction, m_displacementVariationLocal);
return m_displacementJacobianLocal * m_displacementVariationLocal;
}
void PreparedAngularMomentumOperator::ApplyCompleteJacobianActionReference(
const mfem::Vector &densityVariation, const mfem::Vector &displacementVariation,
const double angularVelocityVariation, mfem::Vector &action
) const {
VerifyPrepared();
verify_finite_vector(densityVariation, "Angular-momentum density direction is non-finite.");
verify_finite_vector(displacementVariation, "Angular-momentum displacement direction is non-finite.");
MFEM_VERIFY(std::isfinite(angularVelocityVariation), "Angular-velocity direction is non-finite.");
m_gravityContext.GetDensityMap().scatter(densityVariation, m_densityVariationTrue);
m_gravityContext.GetDisplacementMap().scatter(displacementVariation, m_displacementVariationTrue);
action.SetSize(1);
action(0) = m_angularVelocity * GlobalSum(EvaluateDensityMomentActionLocalReference(m_densityVariationTrue) +
EvaluateDisplacementMomentActionLocalReference(m_displacementVariationTrue)) +
m_momentOfInertia * angularVelocityVariation;
}
double
PreparedAngularMomentumOperator::EvaluateDensityMomentActionLocal(const mfem::Vector &densityVariation) const {
PreparedAngularMomentumOperator::EvaluateDensityMomentActionLocalReference(const mfem::Vector &densityVariation) const {
MFEM_VERIFY(
densityVariation.Size() == m_fem.densityFes->GetTrueVSize(),
"Angular-momentum density action has the wrong true-vector size."
@@ -490,7 +583,7 @@ namespace mean_field::operators {
return localAction;
}
double PreparedAngularMomentumOperator::EvaluateDisplacementMomentActionLocal(
double PreparedAngularMomentumOperator::EvaluateDisplacementMomentActionLocalReference(
const mfem::Vector &displacementVariation
) const {
MFEM_VERIFY(