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,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);
|
||||
|
||||
Reference in New Issue
Block a user