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

@@ -1,5 +1,7 @@
module;
#include "interior_displacement_contractions.hpp"
#include <array>
#include <cmath>
#include <cstdint>
@@ -730,10 +732,66 @@ namespace mean_field::operators {
}
void PreparedBarotropicClosureOperator::Mult(
const mfem::Vector &densityVariation, const mfem::Vector &enthalpyVariation,
const mfem::Vector &displacementVariation, mfem::Vector &action
) const {
MultImpl(densityVariation, enthalpyVariation, displacementVariation, action, true, true);
}
void PreparedBarotropicClosureOperator::MultReference(
const mfem::Vector &densityVariation, const mfem::Vector &enthalpyVariation,
const mfem::Vector &displacementVariation, mfem::Vector &action
) const {
MultImpl(densityVariation, enthalpyVariation, displacementVariation, action, false, false);
}
void PreparedBarotropicClosureOperator::MultCachedReference(
const mfem::Vector &densityVariation, const mfem::Vector &enthalpyVariation,
const mfem::Vector &displacementVariation, mfem::Vector &action
) const {
MultImpl(densityVariation, enthalpyVariation, displacementVariation, action, true, false);
}
int PreparedBarotropicClosureOperator::GetTensorElementCount() const noexcept {
int count = 0;
for (const auto &data : m_elements)
count += data.densityBasis->HasTensorEvaluation3D() &&
data.enthalpyBasis->HasTensorEvaluation3D() && data.displacementBasis->HasTensorEvaluation3D();
return count;
}
void PreparedBarotropicClosureOperator::ApplyEnthalpyJacobianAction(
const mfem::Vector &enthalpyVariation, mfem::Vector &action, const bool useTensorPath
) const {
VerifyPrepared();
MFEM_VERIFY(enthalpyVariation.Size() == m_enthalpyMap.reduced_size(),
"The supported enthalpy variation has the wrong size.");
validate_finite_vector(enthalpyVariation, "The enthalpy variation contains a non-finite value.");
m_enthalpyMap.scatter(enthalpyVariation, m_enthalpyVariationTrue);
ApplyThermodynamicActionFull(nullptr, m_enthalpyVariationTrue, m_fullThermodynamicAction, useTensorPath);
action.SetSize(m_densityMap.reduced_size());
m_densityMap.gather(m_fullThermodynamicAction, action);
}
void PreparedBarotropicClosureOperator::ApplyDisplacementJacobianAction(
const mfem::Vector &displacementVariation, mfem::Vector &action, const bool useTensorPath
) const {
VerifyPrepared();
MFEM_VERIFY(displacementVariation.Size() == m_displacementMap.reduced_size(),
"The supported displacement variation has the wrong size.");
validate_finite_vector(displacementVariation, "The displacement variation contains a non-finite value.");
m_displacementMap.scatter(displacementVariation, m_displacementVariationTrue);
ApplyDisplacementActionFull(m_displacementVariationTrue, m_fullDisplacementAction, true, useTensorPath);
action.SetSize(m_densityMap.reduced_size());
m_densityMap.gather(m_fullDisplacementAction, action);
}
void PreparedBarotropicClosureOperator::MultImpl(
const mfem::Vector &densityVariation,
const mfem::Vector &enthalpyVariation,
const mfem::Vector &displacementVariation,
mfem::Vector &action
mfem::Vector &action,
const bool useFastPath, const bool useTensorPath
) const {
VerifyPrepared();
@@ -758,9 +816,9 @@ namespace mean_field::operators {
m_enthalpyMap.scatter(enthalpyVariation, m_enthalpyVariationTrue);
m_displacementMap.scatter(displacementVariation, m_displacementVariationTrue);
ApplyThermodynamicActionFull(m_densityVariationTrue, m_enthalpyVariationTrue, m_fullThermodynamicAction);
ApplyThermodynamicActionFull(&m_densityVariationTrue, m_enthalpyVariationTrue, m_fullThermodynamicAction, useTensorPath);
ApplyDisplacementActionFull(m_displacementVariationTrue, m_fullDisplacementAction);
ApplyDisplacementActionFull(m_displacementVariationTrue, m_fullDisplacementAction, useFastPath, useTensorPath);
MFEM_VERIFY(
m_fullThermodynamicAction.Size() == m_densityMap.full_size() &&
@@ -797,12 +855,13 @@ namespace mean_field::operators {
}
void PreparedBarotropicClosureOperator::ApplyThermodynamicActionFull(
const mfem::Vector &densityVariationTrue,
const mfem::Vector *densityVariationTrue,
const mfem::Vector &enthalpyVariationTrue,
mfem::Vector &actionTrue
mfem::Vector &actionTrue, const bool useTensorPath
) const {
MFEM_VERIFY(
densityVariationTrue.Size() == m_densityMap.full_size(), "The full density variation has the wrong size."
densityVariationTrue == nullptr || densityVariationTrue->Size() == m_densityMap.full_size(),
"The full density variation has the wrong size."
);
MFEM_VERIFY(
enthalpyVariationTrue.Size() == m_enthalpyMap.full_size(), "The full enthalpy variation has the wrong size."
@@ -811,7 +870,7 @@ namespace mean_field::operators {
mfem::Vector densityVariationLocal;
mfem::Vector enthalpyVariationLocal;
true_to_local(*m_fem.densityFes, densityVariationTrue, densityVariationLocal);
if (densityVariationTrue) true_to_local(*m_fem.densityFes, *densityVariationTrue, densityVariationLocal);
true_to_local(*m_fem.enthalpyFes, enthalpyVariationTrue, enthalpyVariationLocal);
mfem::Vector localAction(m_fem.densityFes->GetVSize());
@@ -825,10 +884,10 @@ namespace mean_field::operators {
mfem::Vector elementAction;
for (const ElementPAData &data : m_elements) {
densityVariationLocal.GetSubVector(data.densityDofs, elementDensityVariation);
if (densityVariationTrue) densityVariationLocal.GetSubVector(data.densityDofs, elementDensityVariation);
enthalpyVariationLocal.GetSubVector(data.enthalpyDofs, elementEnthalpyVariation);
if (data.densityDofTransformation != nullptr) {
if (densityVariationTrue && data.densityDofTransformation != nullptr) {
data.densityDofTransformation->InvTransformPrimal(elementDensityVariation);
}
if (data.enthalpyDofTransformation != nullptr) {
@@ -839,17 +898,25 @@ namespace mean_field::operators {
quadratureEnthalpyVariation.SetSize(data.quadratureWeights.Size());
quadratureAction.SetSize(data.quadratureWeights.Size());
data.densityBasis->GetValues().Mult(elementDensityVariation, quadratureDensityVariation);
data.enthalpyBasis->GetValues().Mult(elementEnthalpyVariation, quadratureEnthalpyVariation);
if (densityVariationTrue) {
if (useTensorPath && data.densityBasis->HasTensorEvaluation3D())
data.densityBasis->EvaluateValuesTensor3D(elementDensityVariation, quadratureDensityVariation, m_tensorWorkspace);
else data.densityBasis->GetValues().Mult(elementDensityVariation, quadratureDensityVariation);
}
if (useTensorPath && data.enthalpyBasis->HasTensorEvaluation3D())
data.enthalpyBasis->EvaluateValuesTensor3D(elementEnthalpyVariation, quadratureEnthalpyVariation, m_tensorWorkspace);
else data.enthalpyBasis->GetValues().Mult(elementEnthalpyVariation, quadratureEnthalpyVariation);
for (int quadraturePoint = 0; quadraturePoint < quadratureAction.Size(); ++quadraturePoint) {
quadratureAction(quadraturePoint) =
data.quadratureWeights(quadraturePoint) * quadratureDensityVariation(quadraturePoint) -
(densityVariationTrue ? data.quadratureWeights(quadraturePoint) * quadratureDensityVariation(quadraturePoint) : 0.0) -
data.weightedEnthalpyDerivative(quadraturePoint) * quadratureEnthalpyVariation(quadraturePoint);
}
elementAction.SetSize(data.densityDofs.Size());
data.densityBasis->GetValues().MultTranspose(quadratureAction, elementAction);
if (useTensorPath && data.densityBasis->HasTensorEvaluation3D())
data.densityBasis->ApplyTransposeTensor3D(quadratureAction, elementAction, m_tensorWorkspace);
else data.densityBasis->GetValues().MultTranspose(quadratureAction, elementAction);
if (data.densityDofTransformation != nullptr) {
data.densityDofTransformation->TransformDual(elementAction);
@@ -863,7 +930,8 @@ namespace mean_field::operators {
void PreparedBarotropicClosureOperator::ApplyDisplacementActionFull(
const mfem::Vector &displacementVariationTrue,
mfem::Vector &actionTrue
mfem::Vector &actionTrue,
const bool useFastPath, const bool useTensorPath
) const {
MFEM_VERIFY(
displacementVariationTrue.Size() == m_displacementMap.full_size(),
@@ -905,8 +973,29 @@ namespace mean_field::operators {
m_referenceDisplacementJacobian.SetSize(dimension, dimension);
m_quadratureDisplacementAction.SetSize(integrationRule.GetNPoints());
const bool tensor = useTensorPath && data.displacementBasis->HasTensorEvaluation3D();
if (tensor) data.displacementBasis->EvaluateTensor3D(directionDofs, m_tensorDisplacement, m_tensorWorkspace);
for (int quadraturePoint = 0; quadraturePoint < integrationRule.GetNPoints(); ++quadraturePoint) {
if (tensor) {
double trace = 0.0;
for (int row = 0; row < 3; ++row) for (int column = 0; column < 3; ++column)
trace += data.inverseElementJacobians(quadraturePoint, row * 3 + column) *
m_tensorDisplacement(quadraturePoint, 4 * column + row + 1);
m_quadratureDisplacementAction(quadraturePoint) = data.weightedResidual(quadraturePoint) * trace;
MFEM_VERIFY(std::isfinite(m_quadratureDisplacementAction(quadraturePoint)),
"Prepared barotropic closure displacement action encountered a non-finite quadrature value.");
continue;
}
if (useFastPath && dimension == 3) {
const double trace = displacement_trace_3d(
directionDofs, data.displacementBasis->GetGradients(quadraturePoint),
data.inverseElementJacobians, quadraturePoint);
m_quadratureDisplacementAction(quadraturePoint) = data.weightedResidual(quadraturePoint) * trace;
MFEM_VERIFY(std::isfinite(m_quadratureDisplacementAction(quadraturePoint)),
"Prepared barotropic closure displacement action encountered a non-finite quadrature value.");
continue;
}
mfem::MultAtB(
directionDofs, data.displacementBasis->GetGradients(quadraturePoint),
m_referenceDisplacementJacobian
@@ -930,7 +1019,9 @@ namespace mean_field::operators {
}
m_elementDisplacementAction.SetSize(data.densityDofs.Size());
data.densityBasis->GetValues().MultTranspose(m_quadratureDisplacementAction, m_elementDisplacementAction);
if (useTensorPath && data.densityBasis->HasTensorEvaluation3D())
data.densityBasis->ApplyTransposeTensor3D(m_quadratureDisplacementAction, m_elementDisplacementAction, m_tensorWorkspace);
else data.densityBasis->GetValues().MultTranspose(m_quadratureDisplacementAction, m_elementDisplacementAction);
if (data.densityDofTransformation != nullptr) {
data.densityDofTransformation->TransformDual(m_elementDisplacementAction);