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

@@ -450,8 +450,8 @@ namespace mean_field::operators {
m_displacementMap.scatter(m_context.GetDisplacement(), m_baseDisplacementTrue);
m_isPrepared = false;
m_elements.clear();
m_elements.reserve(m_fem.mesh->GetNE());
std::size_t preparedElementCount{0};
mfem::Vector baseDensityLocal;
mfem::Vector baseEnthalpyLocal;
@@ -462,6 +462,7 @@ namespace mean_field::operators {
true_to_local(*m_fem.displacementFes, m_baseDisplacementTrue, displacementLocal);
mapping::DomainMapper::Workspace workspace(m_fem.mesh->Dimension());
mapping::VolumeMappingContext mappingContext;
mfem::Array<int> compactificationDofs;
@@ -485,8 +486,10 @@ namespace mean_field::operators {
continue;
}
m_elements.emplace_back();
ElementPAData &data = m_elements.back();
if (preparedElementCount == m_elements.size()) {
m_elements.emplace_back();
}
ElementPAData &data = m_elements[preparedElementCount++];
data.elementId = elementId;
data.densityDofTransformation = m_fem.densityFes->GetElementDofs(elementId, data.densityDofs);
@@ -533,13 +536,15 @@ namespace mean_field::operators {
const mfem::IntegrationRule &integrationRule =
get_eos_rule(m_fem, m_equationOfState, densityElement, enthalpyElement, *transformation);
data.integrationRule = &integrationRule;
const int quadraturePointCount = integrationRule.GetNPoints();
const int densityDofCount = densityElement.GetDof();
const int enthalpyDofCount = enthalpyElement.GetDof();
data.densityBasis.SetSize(quadraturePointCount, densityDofCount);
data.enthalpyBasis.SetSize(quadraturePointCount, enthalpyDofCount);
data.densityBasis = m_fem.GetReferenceTables().GetScalarTable(densityElement, integrationRule);
data.enthalpyBasis = m_fem.GetReferenceTables().GetScalarTable(enthalpyElement, integrationRule);
data.displacementBasis = m_fem.GetReferenceTables().GetScalarTable(displacementElement, integrationRule);
data.inverseElementJacobians.SetSize(
quadraturePointCount, m_fem.mesh->Dimension() * m_fem.mesh->Dimension()
);
@@ -555,8 +560,6 @@ namespace mean_field::operators {
transformation->SetIntPoint(&integrationPoint);
mapping::VolumeMappingContext mappingContext;
const mapping::MappingStatus mappingStatus = m_domainMapper.EvaluateVolume(
mappingData, *transformation, integrationPoint, workspace, mappingContext
);
@@ -585,8 +588,8 @@ namespace mean_field::operators {
}
}
densityElement.CalcShape(integrationPoint, densityShape);
enthalpyElement.CalcShape(integrationPoint, enthalpyShape);
data.densityBasis->GetValues().GetRow(quadraturePoint, densityShape);
data.enthalpyBasis->GetValues().GetRow(quadraturePoint, enthalpyShape);
if (!vector_is_finite(densityShape) || !vector_is_finite(enthalpyShape)) {
retain_higher_priority_rejection(
@@ -595,13 +598,6 @@ namespace mean_field::operators {
continue;
}
for (int densityDof = 0; densityDof < densityDofCount; ++densityDof) {
data.densityBasis(quadraturePoint, densityDof) = densityShape(densityDof);
}
for (int enthalpyDof = 0; enthalpyDof < enthalpyDofCount; ++enthalpyDof) {
data.enthalpyBasis(quadraturePoint, enthalpyDof) = enthalpyShape(enthalpyDof);
}
const double density = elementBaseDensity * densityShape;
const double enthalpy = elementBaseEnthalpy * enthalpyShape;
const double quadratureWeight = mappingContext.quadrature.weight;
@@ -665,6 +661,7 @@ namespace mean_field::operators {
data.weightedEnthalpyDerivative(quadraturePoint) = weightedEnthalpyDerivative;
}
}
m_elements.resize(preparedElementCount);
if (auto globalRejection = synchronize_rejection(localRejection, m_fem.densityFes->GetComm());
globalRejection.has_value()) {
@@ -689,7 +686,7 @@ namespace mean_field::operators {
for (const ElementPAData &data : m_elements) {
elementResidual.SetSize(data.densityDofs.Size());
data.densityBasis.MultTranspose(data.weightedResidual, elementResidual);
data.densityBasis->GetValues().MultTranspose(data.weightedResidual, elementResidual);
if (data.densityDofTransformation != nullptr) {
data.densityDofTransformation->TransformDual(elementResidual);
@@ -719,7 +716,7 @@ namespace mean_field::operators {
elementDiagonal = 0.0;
for (int trialDof = 0; trialDof < data.densityDofs.Size(); ++trialDof) {
for (int quadraturePoint = 0; quadraturePoint < data.quadratureWeights.Size(); ++quadraturePoint) {
const double basis = data.densityBasis(quadraturePoint, trialDof);
const double basis = data.densityBasis->GetValues()(quadraturePoint, trialDof);
elementDiagonal(trialDof) += data.quadratureWeights(quadraturePoint) * basis * basis;
}
}
@@ -842,8 +839,8 @@ namespace mean_field::operators {
quadratureEnthalpyVariation.SetSize(data.quadratureWeights.Size());
quadratureAction.SetSize(data.quadratureWeights.Size());
data.densityBasis.Mult(elementDensityVariation, quadratureDensityVariation);
data.enthalpyBasis.Mult(elementEnthalpyVariation, quadratureEnthalpyVariation);
data.densityBasis->GetValues().Mult(elementDensityVariation, quadratureDensityVariation);
data.enthalpyBasis->GetValues().Mult(elementEnthalpyVariation, quadratureEnthalpyVariation);
for (int quadraturePoint = 0; quadraturePoint < quadratureAction.Size(); ++quadraturePoint) {
quadratureAction(quadraturePoint) =
@@ -852,7 +849,7 @@ namespace mean_field::operators {
}
elementAction.SetSize(data.densityDofs.Size());
data.densityBasis.MultTranspose(quadratureAction, elementAction);
data.densityBasis->GetValues().MultTranspose(quadratureAction, elementAction);
if (data.densityDofTransformation != nullptr) {
data.densityDofTransformation->TransformDual(elementAction);
@@ -906,14 +903,14 @@ namespace mean_field::operators {
"Prepared barotropic closure inverse-Jacobian data has an incompatible size."
);
m_referenceDShape.SetSize(displacementElement.GetDof(), dimension);
m_referenceDisplacementJacobian.SetSize(dimension, dimension);
m_quadratureDisplacementAction.SetSize(integrationRule.GetNPoints());
for (int quadraturePoint = 0; quadraturePoint < integrationRule.GetNPoints(); ++quadraturePoint) {
const mfem::IntegrationPoint &integrationPoint = integrationRule.IntPoint(quadraturePoint);
displacementElement.CalcDShape(integrationPoint, m_referenceDShape);
mfem::MultAtB(directionDofs, m_referenceDShape, m_referenceDisplacementJacobian);
mfem::MultAtB(
directionDofs, data.displacementBasis->GetGradients(quadraturePoint),
m_referenceDisplacementJacobian
);
double logarithmicJacobianVariation{0.0};
for (int row = 0; row < dimension; ++row) {
@@ -933,7 +930,7 @@ namespace mean_field::operators {
}
m_elementDisplacementAction.SetSize(data.densityDofs.Size());
data.densityBasis.MultTranspose(m_quadratureDisplacementAction, m_elementDisplacementAction);
data.densityBasis->GetValues().MultTranspose(m_quadratureDisplacementAction, m_elementDisplacementAction);
if (data.densityDofTransformation != nullptr) {
data.densityDofTransformation->TransformDual(m_elementDisplacementAction);