perf(allocations): reduced overall allocations by 95%, increaseed jacobian applicatin by 2x

This commit uses global pre allocated work space to dramatically reduce memory usage and allocation time
This commit is contained in:
2026-09-10 06:50:56 -04:00
parent b3c04d507a
commit 75cc638739
66 changed files with 207183 additions and 99552 deletions

View File

@@ -488,9 +488,6 @@ namespace mean_field::operators {
m_elements.clear();
m_elements.reserve(m_fem.mesh->GetNE());
mfem::Vector enthalpyShape;
mfem::Vector gravityPotentialShape;
for (int elementId = 0; elementId < m_fem.mesh->GetNE(); ++elementId) {
mfem::ElementTransformation *transformation = m_fem.mesh->GetElementTransformation(elementId);
@@ -528,34 +525,10 @@ namespace mean_field::operators {
data.integrationRule =
&get_hydrostatic_rule(m_fem, enthalpyElement, gravityPotentialElement, *transformation);
const int quadraturePointCount = data.integrationRule->GetNPoints();
const int enthalpyDofCount = enthalpyElement.GetDof();
const int gravityPotentialDofCount = gravityPotentialElement.GetDof();
data.enthalpyBasis.SetSize(quadraturePointCount, enthalpyDofCount);
data.gravityPotentialBasis.SetSize(quadraturePointCount, gravityPotentialDofCount);
enthalpyShape.SetSize(enthalpyDofCount);
gravityPotentialShape.SetSize(gravityPotentialDofCount);
for (int quadraturePoint = 0; quadraturePoint < quadraturePointCount; ++quadraturePoint) {
const mfem::IntegrationPoint &integrationPoint = data.integrationRule->IntPoint(quadraturePoint);
enthalpyElement.CalcShape(integrationPoint, enthalpyShape);
gravityPotentialElement.CalcShape(integrationPoint, gravityPotentialShape);
for (int dof = 0; dof < enthalpyDofCount; ++dof) {
data.enthalpyBasis(quadraturePoint, dof) = enthalpyShape(dof);
}
for (int dof = 0; dof < gravityPotentialDofCount; ++dof) {
data.gravityPotentialBasis(quadraturePoint, dof) = gravityPotentialShape(dof);
}
}
const fem::ReferenceTableCache &referenceTables = m_fem.GetReferenceTables();
data.enthalpyReferenceTable = referenceTables.GetScalarTable(enthalpyElement, *data.integrationRule);
data.gravityPotentialReferenceTable =
referenceTables.GetScalarTable(gravityPotentialElement, *data.integrationRule);
}
}
@@ -565,6 +538,7 @@ namespace mean_field::operators {
true_to_local(*m_fem.displacementFes, m_context.GetDisplacementTrue(), displacementLocal);
mapping::DomainMapper::Workspace workspace(m_fem.mesh->Dimension());
mapping::VolumeMappingContext mappingContext;
mfem::Array<int> compactificationDofs;
@@ -615,16 +589,14 @@ namespace mean_field::operators {
data.quadratureWeights.SetSize(quadraturePointCount);
data.baseMappingContexts.resize(quadraturePointCount);
data.baseMappingContexts.SetSize(quadraturePointCount, m_fem.mesh->Dimension());
for (int quadraturePoint = 0; quadraturePoint < quadraturePointCount; ++quadraturePoint) {
const mfem::IntegrationPoint &integrationPoint = data.integrationRule->IntPoint(quadraturePoint);
transformation->SetIntPoint(&integrationPoint);
mapping::VolumeMappingContext &mappingContext = data.baseMappingContexts[quadraturePoint];
const mapping::MappingStatus mappingStatus = m_domainMapper.EvaluateVolume(
const mapping::MappingStatus mappingStatus = m_domainMapper.EvaluateVolume(
mappingData, *transformation, integrationPoint, workspace, mappingContext
);
@@ -641,6 +613,7 @@ namespace mean_field::operators {
return mapping::MappingStatus::non_positive_determinant;
}
data.baseMappingContexts.Store(quadraturePoint, mappingContext);
data.quadratureWeights(quadraturePoint) = quadratureWeight;
for (int component = 0; component < m_fem.mesh->Dimension(); ++component) {
@@ -660,15 +633,17 @@ namespace mean_field::operators {
bool PreparedHydrostaticEquilibriumOperator::PrepareAlgebraicJacobianBlocks() {
for (ElementPAData &data : m_elements) {
const int quadraturePointCount = data.quadratureWeights.Size();
const mfem::DenseMatrix &enthalpyBasis = data.GetEnthalpyBasis();
const mfem::DenseMatrix &gravityPotentialBasis = data.GetGravityPotentialBasis();
const int quadraturePointCount = data.quadratureWeights.Size();
const int enthalpyDofCount = data.enthalpyBasis.Width();
const int enthalpyDofCount = enthalpyBasis.Width();
const int gravityPotentialDofCount = data.gravityPotentialBasis.Width();
const int gravityPotentialDofCount = gravityPotentialBasis.Width();
MFEM_VERIFY(
data.enthalpyBasis.Height() == quadraturePointCount &&
data.gravityPotentialBasis.Height() == quadraturePointCount,
enthalpyBasis.Height() == quadraturePointCount &&
gravityPotentialBasis.Height() == quadraturePointCount,
"Prepared hydrostatic algebraic Jacobian has "
"inconsistent quadrature data."
);
@@ -687,18 +662,18 @@ namespace mean_field::operators {
const double quadratureWeight = data.quadratureWeights(quadraturePoint);
for (int testDof = 0; testDof < enthalpyDofCount; ++testDof) {
const double weightedTestBasis = quadratureWeight * data.enthalpyBasis(quadraturePoint, testDof);
const double weightedTestBasis = quadratureWeight * enthalpyBasis(quadraturePoint, testDof);
data.bernoulliConstantJacobian(testDof) -= weightedTestBasis;
for (int trialDof = 0; trialDof < enthalpyDofCount; ++trialDof) {
data.enthalpyJacobian(testDof, trialDof) +=
weightedTestBasis * data.enthalpyBasis(quadraturePoint, trialDof);
weightedTestBasis * enthalpyBasis(quadraturePoint, trialDof);
}
for (int trialDof = 0; trialDof < gravityPotentialDofCount; ++trialDof) {
data.gravityPotentialJacobian(testDof, trialDof) +=
weightedTestBasis * data.gravityPotentialBasis(quadraturePoint, trialDof);
weightedTestBasis * gravityPotentialBasis(quadraturePoint, trialDof);
}
}
}
@@ -795,9 +770,9 @@ namespace mean_field::operators {
quadratureGravityPotential.SetSize(quadraturePointCount);
data.enthalpyBasis.Mult(elementEnthalpy, quadratureEnthalpy);
data.GetEnthalpyBasis().Mult(elementEnthalpy, quadratureEnthalpy);
data.gravityPotentialBasis.Mult(elementGravityPotential, quadratureGravityPotential);
data.GetGravityPotentialBasis().Mult(elementGravityPotential, quadratureGravityPotential);
MFEM_VERIFY(
data.rotationPotential.Size() == quadraturePointCount, "Prepared hydrostatic base state has stale "
@@ -836,7 +811,8 @@ namespace mean_field::operators {
MFEM_VERIFY(
data.baseDisplacementData.has_value() && data.compactificationData.has_value() &&
static_cast<int>(data.baseMappingContexts.size()) == quadraturePointCount &&
data.baseMappingContexts.GetPointCount() == quadraturePointCount &&
data.baseMappingContexts.GetDimension() == dimension &&
data.rotationGradient.Height() == quadraturePointCount &&
data.rotationGradient.Width() == dimension &&
data.hydrostaticImbalance.Size() == quadraturePointCount,
@@ -855,7 +831,7 @@ namespace mean_field::operators {
for (const ElementPAData &data : m_elements) {
elementResidual.SetSize(data.enthalpyDofs.Size());
data.enthalpyBasis.MultTranspose(data.weightedResidual, elementResidual);
data.GetEnthalpyBasis().MultTranspose(data.weightedResidual, elementResidual);
if (data.enthalpyDofTransformation != nullptr) {
data.enthalpyDofTransformation->TransformDual(elementResidual);
@@ -1072,7 +1048,7 @@ namespace mean_field::operators {
data.rotationPotential(quadraturePoint);
}
elementAction.SetSize(data.enthalpyDofs.Size());
data.enthalpyBasis.MultTranspose(weightedVariation, elementAction);
data.GetEnthalpyBasis().MultTranspose(weightedVariation, elementAction);
if (data.enthalpyDofTransformation != nullptr) {
data.enthalpyDofTransformation->TransformDual(elementAction);
}
@@ -1204,6 +1180,7 @@ namespace mean_field::operators {
mfem::Vector elementDisplacementVariation;
mfem::Vector weightedQuadratureVariation;
mfem::Vector elementAction;
mapping::VolumeMappingContext mappingContext;
mapping::VolumeMappingVariation variation;
for (const ElementPAData &data : m_elements) {
@@ -1239,7 +1216,7 @@ namespace mean_field::operators {
const int quadraturePointCount = data.integrationRule->GetNPoints();
MFEM_VERIFY(
static_cast<int>(data.baseMappingContexts.size()) == quadraturePointCount &&
data.baseMappingContexts.GetPointCount() == quadraturePointCount &&
data.quadratureWeights.Size() == quadraturePointCount &&
data.hydrostaticImbalance.Size() == quadraturePointCount &&
data.rotationGradient.Height() == quadraturePointCount &&
@@ -1252,10 +1229,10 @@ namespace mean_field::operators {
for (int quadraturePoint = 0; quadraturePoint < quadraturePointCount; ++quadraturePoint) {
const mfem::IntegrationPoint &integrationPoint = data.integrationRule->IntPoint(quadraturePoint);
data.baseMappingContexts.Load(quadraturePoint, mappingContext);
const mapping::MappingStatus mappingStatus = m_domainMapper.EvaluateVolumeVariation(
mappingData, directionData, *transformation, integrationPoint,
data.baseMappingContexts[quadraturePoint], workspace, variation
const mapping::MappingStatus mappingStatus = m_domainMapper.EvaluateVolumeVariation(
mappingData, directionData, *transformation, integrationPoint, mappingContext, workspace, variation
);
MFEM_VERIFY(
@@ -1288,7 +1265,7 @@ namespace mean_field::operators {
elementAction.SetSize(data.enthalpyDofs.Size());
data.enthalpyBasis.MultTranspose(weightedQuadratureVariation, elementAction);
data.GetEnthalpyBasis().MultTranspose(weightedQuadratureVariation, elementAction);
if (data.enthalpyDofTransformation != nullptr) {
data.enthalpyDofTransformation->TransformDual(elementAction);