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

@@ -13,6 +13,7 @@ module mean_field;
import :operators.kernels.gravity_displacement_force;
import :operators.prepared_gravity_displacement_force;
import :fem.reference_tables;
namespace {
using DomainSchema = mean_field::utils::domain::CoreEnvelopeVacuumDomainSchema;
@@ -249,6 +250,17 @@ namespace mean_field::operators {
const mfem::FiniteElement &displacementElement = *m_fem.displacementFes->GetFE(elementId);
const mfem::FiniteElement &compactificationElement = *m_fem.compactificationFes->GetFE(elementId);
data.integrationRule = &get_gravity_force_rule(m_fem, *transformation);
data.densityReferenceTable =
m_fem.GetReferenceTables().GetScalarTable(densityElement, *data.integrationRule);
data.displacementReferenceTable =
m_fem.GetReferenceTables().GetScalarTable(displacementElement, *data.integrationRule);
if (gravityGradientElement.GetMapType() == mfem::FiniteElement::H_DIV &&
gravityGradientElement.GetDim() == dimension && gravityGradientElement.GetRangeDim() == dimension &&
transformation->GetSpaceDim() == dimension) {
data.gravityReferenceTable =
m_fem.GetReferenceTables().GetVectorTable(gravityGradientElement, *data.integrationRule);
data.meshPiolaJacobians.SetSize(data.integrationRule->GetNPoints(), dimension * dimension);
}
const mapping::ElementDisplacementData displacementData =
mapping::ElementDisplacementDataFromElementVDofs(displacementElement, elementBaseDisplacement);
@@ -282,13 +294,17 @@ namespace mean_field::operators {
"Prepared gravity force encountered compactification on a stellar element."
);
densityElement.CalcShape(integrationPoint, densityShape);
for (int dof = 0; dof < densityElement.GetDof(); ++dof) {
densityShape(dof) = data.densityReferenceTable->GetValues()(quadraturePoint, dof);
}
gravityGradientElement.CalcVShape(*transformation, gravityGradientShape);
gravityGradientShape.MultTranspose(elementBaseGravityGradient, baseGravityReferenceValue);
data.baseDensityValues(quadraturePoint) = elementBaseDensity * densityShape;
data.referenceWeights(quadraturePoint) = integrationPoint.weight * transformation->Weight();
const mfem::DenseMatrix &inverseMeshJacobian = transformation->InverseJacobian();
const mfem::DenseMatrix &meshJacobian = transformation->Jacobian();
const double inverseMeshWeight = 1.0 / transformation->Weight();
for (int row = 0; row < dimension; ++row) {
data.baseGravityReferenceValues(quadraturePoint, row) = baseGravityReferenceValue(row);
for (int column = 0; column < dimension; ++column) {
@@ -296,6 +312,10 @@ namespace mean_field::operators {
data.mappingJacobians(quadraturePoint, entry) =
mappingContext.mapping.mapping_jacobian(row, column);
data.inverseMeshJacobians(quadraturePoint, entry) = inverseMeshJacobian(row, column);
if (data.gravityReferenceTable != nullptr) {
data.meshPiolaJacobians(quadraturePoint, entry) =
inverseMeshWeight * meshJacobian(row, column);
}
}
}
@@ -308,7 +328,9 @@ namespace mean_field::operators {
for (int column = 0; column < dimension; ++column) {
const int entry = row * dimension + column;
if (!std::isfinite(data.mappingJacobians(quadraturePoint, entry)) ||
!std::isfinite(data.inverseMeshJacobians(quadraturePoint, entry))) {
!std::isfinite(data.inverseMeshJacobians(quadraturePoint, entry)) ||
(data.gravityReferenceTable != nullptr &&
!std::isfinite(data.meshPiolaJacobians(quadraturePoint, entry)))) {
return std::unexpected(non_finite_rejection());
}
}
@@ -462,6 +484,10 @@ namespace mean_field::operators {
for (const ElementPAData &data : m_elements) {
MFEM_VERIFY(data.integrationRule != nullptr, "Prepared gravity force has no integration rule.");
MFEM_VERIFY(
data.densityReferenceTable != nullptr && data.displacementReferenceTable != nullptr,
"Prepared gravity force has no reference basis tables."
);
m_densityVariationLocal.GetSubVector(data.densityDofs, m_elementDensityVariation);
m_gravityGradientVariationLocal.GetSubVector(data.gravityGradientDofs, m_elementGravityGradientVariation);
@@ -490,13 +516,14 @@ namespace mean_field::operators {
m_densityShape.SetSize(densityElement.GetDof());
m_displacementShape.SetSize(scalarDisplacementDofCount);
m_gravityGradientShape.SetSize(gravityGradientElement.GetDof(), dimension);
m_referenceDisplacementDShape.SetSize(scalarDisplacementDofCount, dimension);
m_referenceDisplacementJacobian.SetSize(dimension, dimension);
m_displacementJacobianVariation.SetSize(dimension, dimension);
m_mappingJacobian.SetSize(dimension, dimension);
m_inverseMeshJacobian.SetSize(dimension, dimension);
m_meshPiolaJacobian.SetSize(dimension, dimension);
m_baseGravityReferenceValue.SetSize(dimension);
m_gravityVariationReferenceValue.SetSize(dimension);
m_gravityVariationReferenceCellValue.SetSize(dimension);
m_mappedBaseGravity.SetSize(dimension);
m_mappedGravityVariation.SetSize(dimension);
m_mappedGeometryVariation.SetSize(dimension);
@@ -506,16 +533,28 @@ namespace mean_field::operators {
for (int quadraturePoint = 0; quadraturePoint < data.integrationRule->GetNPoints(); ++quadraturePoint) {
const mfem::IntegrationPoint &integrationPoint = data.integrationRule->IntPoint(quadraturePoint);
densityElement.CalcShape(integrationPoint, m_densityShape);
displacementElement.CalcShape(integrationPoint, m_displacementShape);
displacementElement.CalcDShape(integrationPoint, m_referenceDisplacementDShape);
mfem::MultAtB(directionDofs, m_referenceDisplacementDShape, m_referenceDisplacementJacobian);
const mfem::DenseMatrix &referenceDisplacementDShape =
data.displacementReferenceTable->GetGradients(quadraturePoint);
mfem::MultAtB(directionDofs, referenceDisplacementDShape, m_referenceDisplacementJacobian);
const mfem::DenseMatrix &densityValues = data.densityReferenceTable->GetValues();
const mfem::DenseMatrix &displacementValues = data.displacementReferenceTable->GetValues();
for (int dof = 0; dof < densityElement.GetDof(); ++dof) {
m_densityShape(dof) = densityValues(quadraturePoint, dof);
}
for (int dof = 0; dof < scalarDisplacementDofCount; ++dof) {
m_displacementShape(dof) = displacementValues(quadraturePoint, dof);
}
transformation->SetIntPoint(&integrationPoint);
gravityGradientElement.CalcVShape(*transformation, m_gravityGradientShape);
m_gravityGradientShape.MultTranspose(
m_elementGravityGradientVariation, m_gravityVariationReferenceValue
);
if (data.gravityReferenceTable != nullptr) {
data.gravityReferenceTable->GetValues(quadraturePoint)
.MultTranspose(m_elementGravityGradientVariation, m_gravityVariationReferenceCellValue);
} else {
transformation->SetIntPoint(&integrationPoint);
gravityGradientElement.CalcVShape(*transformation, m_gravityGradientShape);
m_gravityGradientShape.MultTranspose(
m_elementGravityGradientVariation, m_gravityVariationReferenceValue
);
}
for (int row = 0; row < dimension; ++row) {
m_baseGravityReferenceValue(row) = data.baseGravityReferenceValues(quadraturePoint, row);
@@ -523,8 +562,14 @@ namespace mean_field::operators {
const int entry = row * dimension + column;
m_mappingJacobian(row, column) = data.mappingJacobians(quadraturePoint, entry);
m_inverseMeshJacobian(row, column) = data.inverseMeshJacobians(quadraturePoint, entry);
if (data.gravityReferenceTable != nullptr) {
m_meshPiolaJacobian(row, column) = data.meshPiolaJacobians(quadraturePoint, entry);
}
}
}
if (data.gravityReferenceTable != nullptr) {
m_meshPiolaJacobian.Mult(m_gravityVariationReferenceCellValue, m_gravityVariationReferenceValue);
}
mfem::Mult(m_referenceDisplacementJacobian, m_inverseMeshJacobian, m_displacementJacobianVariation);
m_mappingJacobian.Mult(m_baseGravityReferenceValue, m_mappedBaseGravity);
m_mappingJacobian.Mult(m_gravityVariationReferenceValue, m_mappedGravityVariation);