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:
@@ -13,6 +13,8 @@ module;
|
||||
#include <mpi.h>
|
||||
|
||||
module mean_field;
|
||||
|
||||
import :fem.reference_tables;
|
||||
import :operators.prepared_hdiv_mass;
|
||||
|
||||
namespace {
|
||||
@@ -551,6 +553,15 @@ namespace mean_field::operators {
|
||||
);
|
||||
|
||||
data.integrationRule = &get_hdiv_mass_rule(m_fem, m_domain_mapper, gravityGradientElement, *transformation);
|
||||
const int dimension = m_domain_mapper.GetDimension();
|
||||
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);
|
||||
data.referenceWeights.SetSize(data.integrationRule->GetNPoints());
|
||||
}
|
||||
data.frozenMappingData.SetSize(
|
||||
data.integrationRule->GetNPoints(), frozen_mapping_width(m_domain_mapper.GetDimension())
|
||||
);
|
||||
@@ -573,6 +584,25 @@ namespace mean_field::operators {
|
||||
return status;
|
||||
}
|
||||
freeze_mapping_context(mappingContext, quadraturePoint, data.frozenMappingData);
|
||||
if (data.gravityReferenceTable != nullptr) {
|
||||
// CalcVShape_RT = reference_shape * J_mesh^T / Weight.
|
||||
// Cache only this small factor, never the mapped basis.
|
||||
const double meshWeight = transformation->Weight();
|
||||
const mfem::DenseMatrix &meshJacobian = transformation->Jacobian();
|
||||
const double inverseMeshWeight = 1.0 / meshWeight;
|
||||
data.referenceWeights(quadraturePoint) = integrationPoint.weight * meshWeight;
|
||||
for (int row = 0; row < dimension; ++row) {
|
||||
for (int column = 0; column < dimension; ++column) {
|
||||
const double entry = inverseMeshWeight * meshJacobian(row, column);
|
||||
if (!std::isfinite(entry))
|
||||
return mapping::MappingStatus::non_finite_result;
|
||||
data.meshPiolaJacobians(quadraturePoint, row * dimension + column) = entry;
|
||||
}
|
||||
}
|
||||
if (!std::isfinite(data.referenceWeights(quadraturePoint))) {
|
||||
return mapping::MappingStatus::non_finite_result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return mapping::MappingStatus::valid;
|
||||
@@ -830,7 +860,10 @@ namespace mean_field::operators {
|
||||
m_elementVariationAction.SetSize(gravityGradientElement.GetDof());
|
||||
m_elementVariationAction = 0.0;
|
||||
m_gravityGradientValue.SetSize(dimension);
|
||||
m_gravityReferenceCellValue.SetSize(dimension);
|
||||
m_referenceCellDual.SetSize(dimension);
|
||||
m_massTensorVariationAction.SetSize(dimension);
|
||||
m_meshPiolaJacobian.SetSize(dimension, dimension);
|
||||
m_gravityGradientShape.SetSize(gravityGradientElement.GetDof(), dimension);
|
||||
m_massTensorVariation.SetSize(dimension, dimension);
|
||||
|
||||
@@ -853,12 +886,33 @@ namespace mean_field::operators {
|
||||
m_baseMappingContext.mapping, m_mappingVariation.mapping, m_massTensorVariation
|
||||
);
|
||||
|
||||
transformation->SetIntPoint(&integrationPoint);
|
||||
gravityGradientElement.CalcVShape(*transformation, m_gravityGradientShape);
|
||||
m_gravityGradientShape.MultTranspose(m_elementGravityGradient, m_gravityGradientValue);
|
||||
m_massTensorVariation.Mult(m_gravityGradientValue, m_massTensorVariationAction);
|
||||
const double referenceWeight = integrationPoint.weight * transformation->Weight();
|
||||
m_gravityGradientShape.AddMult(m_massTensorVariationAction, m_elementVariationAction, referenceWeight);
|
||||
if (data.gravityReferenceTable != nullptr) {
|
||||
const mfem::DenseMatrix &referenceShape = data.gravityReferenceTable->GetValues(quadraturePoint);
|
||||
referenceShape.MultTranspose(m_elementGravityGradient, m_gravityReferenceCellValue);
|
||||
for (int row = 0; row < dimension; ++row) {
|
||||
for (int column = 0; column < dimension; ++column) {
|
||||
m_meshPiolaJacobian(row, column) =
|
||||
data.meshPiolaJacobians(quadraturePoint, row * dimension + column);
|
||||
}
|
||||
}
|
||||
m_meshPiolaJacobian.Mult(m_gravityReferenceCellValue, m_gravityGradientValue);
|
||||
m_massTensorVariation.Mult(m_gravityGradientValue, m_massTensorVariationAction);
|
||||
// Move the test-side Piola transform onto the three-vector
|
||||
// dual before applying the reference basis transpose.
|
||||
m_meshPiolaJacobian.MultTranspose(m_massTensorVariationAction, m_referenceCellDual);
|
||||
referenceShape.AddMult(
|
||||
m_referenceCellDual, m_elementVariationAction, data.referenceWeights(quadraturePoint)
|
||||
);
|
||||
} else {
|
||||
transformation->SetIntPoint(&integrationPoint);
|
||||
gravityGradientElement.CalcVShape(*transformation, m_gravityGradientShape);
|
||||
m_gravityGradientShape.MultTranspose(m_elementGravityGradient, m_gravityGradientValue);
|
||||
m_massTensorVariation.Mult(m_gravityGradientValue, m_massTensorVariationAction);
|
||||
const double referenceWeight = integrationPoint.weight * transformation->Weight();
|
||||
m_gravityGradientShape.AddMult(
|
||||
m_massTensorVariationAction, m_elementVariationAction, referenceWeight
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (data.gravityGradientDofTransformation != nullptr) {
|
||||
|
||||
Reference in New Issue
Block a user