perf(jacobian-action): major updates to jacobian action application by removing redudant quadrature work. ~5x increase in speed

This commit is contained in:
2026-09-02 17:01:50 -04:00
parent 85500fef3b
commit 25510008dd
74 changed files with 8967 additions and 814 deletions

View File

@@ -619,7 +619,7 @@ namespace mean_field::operators {
for (int quadraturePoint = 0; quadraturePoint < quadraturePointCount; ++quadraturePoint) {
const double enthalpy = quadratureEnthalpy(quadraturePoint);
const eos::SpecificEnthalpyValue specificEnthalpy{enthalpy};
const dimensions::SpecificEnthalpyValue specificEnthalpy{enthalpy};
const double pressure =
eos::evaluate<eos::quantity::Pressure>(m_equationOfState, specificEnthalpy).value();
@@ -813,11 +813,13 @@ namespace mean_field::operators {
localAction = 0.0;
mapping::DomainMapper::Workspace workspace(m_fem.mesh->Dimension());
mfem::Vector elementDisplacementVariation;
mfem::Vector elementAction;
mfem::DenseMatrix referenceDisplacementDShape;
mfem::DenseMatrix referenceDisplacementJacobian;
mfem::DenseMatrix inverseElementJacobianVariation;
mfem::DenseMatrix matrixTemporary;
mfem::DenseMatrix physicalTestGradientVariation;
const int dimension = m_fem.mesh->Dimension();
@@ -850,13 +852,11 @@ namespace mean_field::operators {
const mapping::ElementDisplacementData directionData =
mapping::ElementDisplacementDataFromElementVDofs(displacementElement, elementDisplacementVariation);
const mapping::ElementMappingData mappingData{
.displacement = *data.baseDisplacementData, .compactification = *data.compactificationData
};
const int quadraturePointCount = data.integrationRule->GetNPoints();
const int quadraturePointCount = data.integrationRule->GetNPoints();
const int scalarDisplacementDofCount = displacementElement.GetDof();
const int scalarDisplacementDofCount = displacementElement.GetDof();
const mfem::DenseMatrix &directionDofs = directionData.GetDofMatrix();
MFEM_VERIFY(
static_cast<int>(data.baseMappingContexts.size()) == quadraturePointCount &&
@@ -869,31 +869,32 @@ namespace mean_field::operators {
elementAction = 0.0;
referenceDisplacementDShape.SetSize(scalarDisplacementDofCount, dimension);
referenceDisplacementJacobian.SetSize(dimension, dimension);
inverseElementJacobianVariation.SetSize(dimension, dimension);
matrixTemporary.SetSize(dimension, dimension);
physicalTestGradientVariation.SetSize(scalarDisplacementDofCount, dimension);
for (int quadraturePoint = 0; quadraturePoint < quadraturePointCount; ++quadraturePoint) {
const mfem::IntegrationPoint &integrationPoint = data.integrationRule->IntPoint(quadraturePoint);
transformation->SetIntPoint(&integrationPoint);
displacementElement.CalcDShape(integrationPoint, referenceDisplacementDShape);
mfem::MultAtB(directionDofs, referenceDisplacementDShape, referenceDisplacementJacobian);
mapping::VolumeMappingVariation variation;
const mfem::DenseMatrix &inverseElementJacobian =
data.baseMappingContexts[quadraturePoint].quadrature.J_inv;
mfem::Mult(inverseElementJacobian, referenceDisplacementJacobian, matrixTemporary);
const mapping::MappingStatus mappingStatus = m_domainMapper.EvaluateVolumeVariation(
mappingData, directionData, *transformation, integrationPoint,
data.baseMappingContexts[quadraturePoint], workspace, variation
);
double logarithmicJacobianVariation{0.0};
for (int component = 0; component < dimension; ++component) {
logarithmicJacobianVariation += matrixTemporary(component, component);
}
MFEM_VERIFY(
mappingStatus == mapping::MappingStatus::valid,
"Stateless mapping variation failed while applying "
"the prepared pressure-force displacement Jacobian. "
"Element: "
<< data.elementId << ", attribute: " << transformation->Attribute
<< ", quadrature point: " << quadraturePoint << ", status: " << static_cast<int>(mappingStatus)
);
mfem::Mult(matrixTemporary, inverseElementJacobian, inverseElementJacobianVariation);
inverseElementJacobianVariation *= -1.0;
mfem::Mult(
data.referenceTestGradients[quadraturePoint], variation.inverse_element_jacobian_variation,
data.referenceTestGradients[quadraturePoint], inverseElementJacobianVariation,
physicalTestGradientVariation
);
@@ -905,12 +906,13 @@ namespace mean_field::operators {
displacementOrdering, scalarDof, component, scalarDisplacementDofCount, dimension
);
const double gradientWeightVariation =
data.quadratureWeights(quadraturePoint) *
physicalTestGradientVariation(scalarDof, component) +
variation.weight_variation * physicalTestGradient(scalarDof, component);
const double gradientWeightVariation = data.quadratureWeights(quadraturePoint) *
physicalTestGradientVariation(scalarDof, component) +
data.quadratureWeights(quadraturePoint) *
logarithmicJacobianVariation *
physicalTestGradient(scalarDof, component);
const double contribution = data.pressure(quadraturePoint) * gradientWeightVariation;
const double contribution = data.pressure(quadraturePoint) * gradientWeightVariation;
MFEM_VERIFY(
std::isfinite(gradientWeightVariation) && std::isfinite(contribution),