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

@@ -489,7 +489,8 @@ namespace mean_field::mapping {
mfem::ElementTransformation &transformation,
const mfem::IntegrationPoint &integration_point,
Workspace &workspace,
CompactificationPointData &point_data
CompactificationPointData &point_data,
const mfem::DenseMatrix *inverse_mesh_jacobian
) const {
const mfem::FiniteElement &element = compactification.GetElement();
const mfem::Vector &dofs = compactification.GetDofs();
@@ -509,13 +510,17 @@ namespace mean_field::mapping {
return MappingStatus::non_finite_input;
}
transformation.SetIntPoint(&integration_point);
workspace.m_compactification_shape.SetSize(dof_count);
workspace.m_compactification_dshape.SetSize(dof_count, m_options.dimension);
element.CalcShape(integration_point, workspace.m_compactification_shape);
element.CalcPhysDShape(transformation, workspace.m_compactification_dshape);
if (inverse_mesh_jacobian != nullptr) {
workspace.m_reference_dshape.SetSize(dof_count, m_options.dimension);
element.CalcDShape(integration_point, workspace.m_reference_dshape);
mfem::Mult(workspace.m_reference_dshape, *inverse_mesh_jacobian, workspace.m_compactification_dshape);
} else {
element.CalcPhysDShape(transformation, workspace.m_compactification_dshape);
}
point_data.coordinate = dofs * workspace.m_compactification_shape;
point_data.coordinate_gradient.SetSize(m_options.dimension);
@@ -539,10 +544,9 @@ namespace mean_field::mapping {
const mfem::IntegrationPoint &integration_point,
Workspace &workspace,
mfem::Vector &value,
mfem::DenseMatrix &jacobian
mfem::DenseMatrix &jacobian,
const mfem::DenseMatrix *inverse_mesh_jacobian
) const {
transformation.SetIntPoint(&integration_point);
const mfem::FiniteElement &element = field.GetElement();
const mfem::DenseMatrix &dof_matrix = field.GetDofMatrix();
@@ -550,7 +554,13 @@ namespace mean_field::mapping {
workspace.m_mesh_dshape.SetSize(element.GetDof(), m_options.dimension);
element.CalcShape(integration_point, workspace.m_shape);
element.CalcPhysDShape(transformation, workspace.m_mesh_dshape);
if (inverse_mesh_jacobian != nullptr) {
workspace.m_reference_dshape.SetSize(element.GetDof(), m_options.dimension);
element.CalcDShape(integration_point, workspace.m_reference_dshape);
mfem::Mult(workspace.m_reference_dshape, *inverse_mesh_jacobian, workspace.m_mesh_dshape);
} else {
element.CalcPhysDShape(transformation, workspace.m_mesh_dshape);
}
value.SetSize(m_options.dimension);
dof_matrix.MultTranspose(workspace.m_shape, value);
@@ -586,7 +596,7 @@ namespace mean_field::mapping {
EvaluateField(
element_data.displacement, transformation, integration_point, workspace, workspace.m_field_value,
workspace.m_field_jacobian
workspace.m_field_jacobian, nullptr
);
if (!vector_is_finite(context.reference_position) || !vector_is_finite(workspace.m_field_value) ||
@@ -608,7 +618,7 @@ namespace mean_field::mapping {
if (context.compactified) {
const MappingStatus coordinate_status = EvaluateCompactificationCoordinate(
element_data.compactification, transformation, integration_point, workspace,
workspace.m_compactification_point
workspace.m_compactification_point, nullptr
);
if (coordinate_status != MappingStatus::valid)
@@ -663,7 +673,6 @@ namespace mean_field::mapping {
if (point_status != MappingStatus::valid)
return point_status;
transformation.SetIntPoint(&integration_point);
mfem::Mult(context.mapping.mapping_jacobian, transformation.Jacobian(), workspace.m_full_element_jacobian);
context.quadrature.J_inv.SetSize(m_options.dimension, m_options.dimension);
@@ -766,6 +775,21 @@ namespace mean_field::mapping {
const MappingPointContext &base_context,
Workspace &workspace,
MappingPointVariation &variation
) const {
return EvaluatePointVariationImpl(
element_data, direction, transformation, integration_point, base_context, workspace, variation, nullptr
);
}
MappingStatus DomainMapper::EvaluatePointVariationImpl(
const ElementMappingData &element_data,
const ElementDisplacementData &direction,
mfem::ElementTransformation &transformation,
const mfem::IntegrationPoint &integration_point,
const MappingPointContext &base_context,
Workspace &workspace,
MappingPointVariation &variation,
const mfem::DenseMatrix *inverse_mesh_jacobian
) const {
ValidateElementData(element_data);
const ElementMappingData direction_data{
@@ -786,8 +810,13 @@ namespace mean_field::mapping {
"domain."
);
if (inverse_mesh_jacobian == nullptr) {
transformation.SetIntPoint(&integration_point);
}
EvaluateField(
direction, transformation, integration_point, workspace, workspace.m_field_value, workspace.m_field_jacobian
direction, transformation, integration_point, workspace, workspace.m_field_value,
workspace.m_field_jacobian, inverse_mesh_jacobian
);
if (!vector_is_finite(workspace.m_field_value) || !matrix_is_finite(workspace.m_field_jacobian))
@@ -799,7 +828,7 @@ namespace mean_field::mapping {
if (base_context.compactified) {
const MappingStatus coordinate_status = EvaluateCompactificationCoordinate(
element_data.compactification, transformation, integration_point, workspace,
workspace.m_compactification_point
workspace.m_compactification_point, inverse_mesh_jacobian
);
if (coordinate_status != MappingStatus::valid)
@@ -872,27 +901,28 @@ namespace mean_field::mapping {
Workspace &workspace,
VolumeMappingVariation &variation
) const {
const MappingStatus point_status = EvaluatePointVariation(
mfem::Mult(base_context.quadrature.J_inv, base_context.mapping.mapping_jacobian, workspace.m_matrix_temp_2);
const MappingStatus point_status = EvaluatePointVariationImpl(
element_data, direction, transformation, integration_point, base_context.mapping, workspace,
variation.mapping
variation.mapping, &workspace.m_matrix_temp_2
);
if (point_status != MappingStatus::valid)
return point_status;
transformation.SetIntPoint(&integration_point);
mfem::Mult(
variation.mapping.mapping_jacobian_variation, transformation.Jacobian(), workspace.m_full_element_jacobian
base_context.quadrature.J_inv, variation.mapping.mapping_jacobian_variation, workspace.m_matrix_temp_1
);
mfem::Mult(base_context.quadrature.J_inv, workspace.m_full_element_jacobian, workspace.m_matrix_temp_1);
variation.inverse_element_jacobian_variation.SetSize(m_options.dimension, m_options.dimension);
mfem::Mult(
workspace.m_matrix_temp_1, base_context.quadrature.J_inv, variation.inverse_element_jacobian_variation
workspace.m_matrix_temp_1, base_context.mapping.inverse_mapping_jacobian,
variation.inverse_element_jacobian_variation
);
variation.inverse_element_jacobian_variation *= -1.0;
variation.weight_variation =
integration_point.weight * transformation.Weight() * variation.mapping.mapping_determinant_variation;
variation.weight_variation = base_context.quadrature.weight / base_context.mapping.mapping_determinant *
variation.mapping.mapping_determinant_variation;
if (!matrix_is_finite(variation.inverse_element_jacobian_variation) ||
!std::isfinite(variation.weight_variation))

View File

@@ -217,16 +217,22 @@ namespace mean_field::mapping {
);
MFEM_VERIFY(std::isfinite(determinant_variation), "The mapping determinant variation must be finite.");
mfem::DenseMatrix determinant_correction(dimension, dimension);
ComputeHDivMassTensor(context, determinant_correction);
determinant_correction *= determinant_variation / determinant;
const mfem::DenseMatrix &jacobian = context.mapping_jacobian;
const mfem::DenseMatrix &jacobianVariation = variation.mapping_jacobian_variation;
const double inverseDeterminant = 1.0 / determinant;
const double determinantScale = determinant_variation * inverseDeterminant;
mfem::DenseMatrix right_jacobian_variation(dimension, dimension);
mfem::MultAtB(context.mapping_jacobian, variation.mapping_jacobian_variation, right_jacobian_variation);
mfem::MultAtB(variation.mapping_jacobian_variation, context.mapping_jacobian, mass_tensor_variation);
mass_tensor_variation += right_jacobian_variation;
mass_tensor_variation *= 1 / determinant;
mass_tensor_variation -= determinant_correction;
for (int row = 0; row < dimension; ++row) {
for (int column = 0; column < dimension; ++column) {
double gram{0.0};
double gramVariation{0.0};
for (int inner = 0; inner < dimension; ++inner) {
gram += jacobian(inner, row) * jacobian(inner, column);
gramVariation += jacobian(inner, row) * jacobianVariation(inner, column) +
jacobianVariation(inner, row) * jacobian(inner, column);
}
mass_tensor_variation(row, column) = inverseDeterminant * (gramVariation - determinantScale * gram);
}
}
}
} // namespace mean_field::mapping
} // namespace mean_field::mapping