Snapshot optimized solver and audit diagnostics before numerical experiments
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user