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