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

@@ -345,6 +345,11 @@ namespace mean_field::operators {
}
}
void PreparedMappedGravitySourceOperator::PrepareReference(const mfem::Vector &displacement) {
auto result = TryPrepareImpl(displacement, PreparationMode::linearization, false);
if (!result.has_value()) throwGravitySourcePreparationRejection(result.error());
}
void PreparedMappedGravitySourceOperator::PreparePrimal(const mfem::Vector &displacement) {
MEAN_FIELD_PROFILE_SCOPE_WARMUP("PreparedMappedGravitySourceOperator::Prepare primal", 0);
auto result = TryPrepareImpl(displacement, PreparationMode::primal);
@@ -366,7 +371,7 @@ namespace mean_field::operators {
GravitySourcePreparationResult PreparedMappedGravitySourceOperator::TryPrepareImpl(
const mfem::Vector &displacement,
const PreparationMode mode
const PreparationMode mode, const bool useCachedMeshWeight
) {
MFEM_VERIFY(
displacement.Size() == m_displacement_map.reduced_size(),
@@ -513,7 +518,12 @@ namespace mean_field::operators {
transformation.SetIntPoint(&integration_point);
const double quadrature_value = integration_point.weight * transformation.Weight() * coefficient_value;
// EvaluateVolume already cached the computational mesh geometry.
// Resetting IntPoint above invalidates MFEM's local weight cache.
const auto *fixed = useCachedMeshWeight ?
m_domain_mapper.GetFixedMeshGeometry(transformation, integration_point) : nullptr;
const double meshWeight = fixed ? fixed->weight : transformation.Weight();
const double quadrature_value = integration_point.weight * meshWeight * coefficient_value;
if (!std::isfinite(quadrature_value) || quadrature_value <= 0.0) {
localNonFiniteQuadrature = true;
@@ -608,9 +618,27 @@ namespace mean_field::operators {
}
void PreparedMappedGravitySourceOperator::MultDisplacementVariationTrue(
const mfem::Vector &densityTrue,
const mfem::Vector &displacementVariationTrue,
const mfem::Vector &densityTrue, const mfem::Vector &displacementVariationTrue,
mfem::Vector &actionVariationTrue
) const {
MultDisplacementVariationTrueImpl(densityTrue, displacementVariationTrue, actionVariationTrue, true);
}
void PreparedMappedGravitySourceOperator::MultDisplacementVariationTrueReference(
const mfem::Vector &densityTrue, const mfem::Vector &displacementVariationTrue,
mfem::Vector &actionVariationTrue
) const {
MultDisplacementVariationTrueImpl(densityTrue, displacementVariationTrue, actionVariationTrue, false);
}
int PreparedMappedGravitySourceOperator::GetTensorVariationElementCount() const noexcept {
int count = 0;
for (const auto &data : m_elements)
count += data.displacement_reference && data.displacement_reference->HasTensorEvaluation3D();
return count;
}
void PreparedMappedGravitySourceOperator::MultDisplacementVariationTrueImpl(
const mfem::Vector &densityTrue, const mfem::Vector &displacementVariationTrue,
mfem::Vector &actionVariationTrue, const bool useTensorPath
) const {
MFEM_VERIFY(
m_is_prepared,
@@ -667,10 +695,15 @@ namespace mean_field::operators {
m_reference_displacement_jacobian.SetSize(dimension, dimension);
m_quadrature_variation_action.SetSize(data.integration_rule->GetNPoints());
data.GetDensityBasis().Mult(m_element_density, m_quadrature_variation_action);
if (useTensorPath && data.density_reference && data.density_reference->HasTensorEvaluation3D())
data.density_reference->EvaluateValuesTensor3D(m_element_density, m_quadrature_variation_action, m_tensorWorkspace);
else data.GetDensityBasis().Mult(m_element_density, m_quadrature_variation_action);
const bool tensor = useTensorPath && data.displacement_reference &&
data.displacement_reference->HasTensorEvaluation3D();
if (tensor) data.displacement_reference->EvaluateTensor3D(direction_dofs, m_tensorSamples, m_tensorWorkspace);
for (int quadrature_point = 0; quadrature_point < data.integration_rule->GetNPoints(); ++quadrature_point) {
mfem::MultAtB(
if (!tensor) mfem::MultAtB(
direction_dofs, data.displacement_reference->GetGradients(quadrature_point),
m_reference_displacement_jacobian
);
@@ -680,7 +713,8 @@ namespace mean_field::operators {
for (int column = 0; column < dimension; ++column) {
logarithmic_jacobian_variation +=
data.inverse_element_jacobians(quadrature_point, row * dimension + column) *
m_reference_displacement_jacobian(column, row);
(tensor ? m_tensorSamples(quadrature_point, 4*column+row+1) :
m_reference_displacement_jacobian(column, row));
}
}
@@ -693,7 +727,9 @@ namespace mean_field::operators {
}
m_element_variation_action.SetSize(data.potential_dofs.Size());
data.GetPotentialBasis().MultTranspose(m_quadrature_variation_action, m_element_variation_action);
if (useTensorPath && data.potential_reference && data.potential_reference->HasTensorEvaluation3D())
data.potential_reference->ApplyTransposeTensor3D(m_quadrature_variation_action, m_element_variation_action, m_tensorWorkspace);
else data.GetPotentialBasis().MultTranspose(m_quadrature_variation_action, m_element_variation_action);
if (data.potential_dof_transformation != nullptr) {
data.potential_dof_transformation->TransformDual(m_element_variation_action);