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:
2026-09-10 06:50:56 -04:00
parent b3c04d507a
commit 75cc638739
66 changed files with 207183 additions and 99552 deletions

View File

@@ -0,0 +1,82 @@
module;
#include <cstdint>
#include <limits>
#include <span>
#include <mfem.hpp>
export module mean_field:deformation.safe_newton_step;
export import :mapping.domain_mapper;
export namespace mean_field::deformation {
/*
* One element-local quadrature rule at which a downstream operator will
* evaluate the mapped geometry. A caller may provide several entries for
* one element when several operators use different, non-nested rules.
* The integration-rule object must outlive the call.
*/
struct NewtonStepGeometryRule final {
int element{-1};
const mfem::IntegrationRule *integrationRule{nullptr};
};
struct LargestSafeNewtonStepSizeOptions final {
double maximumStepSize{1.0};
double determinantFloor{0.0};
double fractionToBoundarySafety{0.9};
void Validate() const;
};
/*
* The estimated boundary is the first alpha in [0, maximumStepSize] at
* which any sampled mapping determinant reaches determinantFloor. When
* no such point exists, boundaryStepSize equals maximumStepSize and
* limitedByGeometry is false. stepSize is the boundary multiplied by the
* safety fraction only when geometry is limiting.
*
* Element and rule indices are local to limitingRank. limitingRule is an
* index into that rank's input span.
*/
struct LargestSafeNewtonStepSizeEstimate final {
double stepSize{0.0};
double boundaryStepSize{0.0};
double minimumDeterminantAtAcceptedState{std::numeric_limits<double>::quiet_NaN()};
double minimumDeterminantAtMaximumStepSize{std::numeric_limits<double>::quiet_NaN()};
double limitingPointDeterminantAtStepSize{std::numeric_limits<double>::quiet_NaN()};
std::uint64_t sampledQuadraturePointCount{0};
bool limitedByGeometry{false};
int limitingRank{-1};
int limitingElement{-1};
int limitingRule{-1};
int limitingQuadraturePoint{-1};
};
/*
* Estimate the largest safe alpha for
*
* displacement(alpha) = acceptedVolumeDisplacement
* + alpha * volumeNewtonDirection.
*
* Both vectors use the displacement space's true-DOF layout. The
* compactification coordinate is held fixed. The result is collective on
* displacementSpace.GetComm() and is identical on every rank.
*
* The calculation is exact for the current domain mapper: its mapping
* Jacobian is affine along a displacement direction, so each sampled
* determinant is a polynomial of degree at most the spatial dimension.
* Compactified elements require an exterior map that explicitly advertises
* the same affine contract.
*/
[[nodiscard]] LargestSafeNewtonStepSizeEstimate estimate_largest_safe_newton_step_size(
const mapping::DomainMapper &domainMapper,
const mfem::ParFiniteElementSpace &displacementSpace,
const mfem::ParGridFunction &compactificationCoordinate,
const mfem::Vector &acceptedVolumeDisplacement,
const mfem::Vector &volumeNewtonDirection,
std::span<const NewtonStepGeometryRule> geometryRules,
const LargestSafeNewtonStepSizeOptions &options = {}
);
} // namespace mean_field::deformation