Snapshot optimized solver and audit diagnostics before numerical experiments

This commit is contained in:
2026-09-16 14:34:06 -04:00
parent 75cc638739
commit 80cc3d83d7
64 changed files with 11969 additions and 267 deletions

View File

@@ -156,6 +156,16 @@ export namespace mean_field::operators {
void BuildResidual(mfem::Vector &residual) const;
// Rows differentiate I_axis; changing Omega alone reuses both rows.
[[nodiscard]] bool PrepareJacobianRows() const;
[[nodiscard]] std::uint64_t GetJacobianRowPreparationCount() const noexcept;
void ApplyCompleteJacobianActionReference(
const mfem::Vector &densityVariation,
const mfem::Vector &displacementVariation,
double angularVelocityVariation,
mfem::Vector &action
) const;
void ApplyDensityJacobianAction(
const mfem::Vector &densityVariation,
mfem::Vector &action
@@ -223,6 +233,8 @@ export namespace mean_field::operators {
[[nodiscard]] double EvaluateDensityMomentActionLocal(const mfem::Vector &densityVariation) const;
[[nodiscard]] double EvaluateDisplacementMomentActionLocal(const mfem::Vector &displacementVariation) const;
[[nodiscard]] double EvaluateDensityMomentActionLocalReference(const mfem::Vector &densityVariation) const;
[[nodiscard]] double EvaluateDisplacementMomentActionLocalReference(const mfem::Vector &displacementVariation) const;
[[nodiscard]] double CylindricalRadiusSquared(const mfem::Vector &physicalPosition) const noexcept;
[[nodiscard]] double CylindricalRadiusSquaredVariation(
const mfem::Vector &physicalPosition,
@@ -238,6 +250,11 @@ export namespace mean_field::operators {
std::vector<ElementPAData> m_elements;
AngularMomentumDependencies m_preparedDependencies;
mfem::Vector m_cachedResidual;
mutable mfem::Vector m_densityJacobianLocal;
mutable mfem::Vector m_displacementJacobianLocal;
mutable bool m_jacobianRowsReady{false};
mutable bool m_jacobianRowsSupported{false};
mutable std::uint64_t m_jacobianRowPreparationCount{0};
mutable mfem::Vector m_densityVariationTrue;
mutable mfem::Vector m_displacementVariationTrue;
mutable mfem::Vector m_densityVariationLocal;

View File

@@ -82,6 +82,20 @@ export namespace mean_field::operators {
mfem::Vector &action
) const override;
// Supported-coordinate coupling actions; omit identically absent blocks.
void ApplyEnthalpyJacobianAction(const mfem::Vector &enthalpyVariation, mfem::Vector &action,
bool useTensorPath = true) const;
void ApplyDisplacementJacobianAction(const mfem::Vector &displacementVariation, mfem::Vector &action,
bool useTensorPath = true) const;
// Retained complete action for isolation/reference comparisons.
void MultReference(const mfem::Vector &densityVariation, const mfem::Vector &enthalpyVariation,
const mfem::Vector &displacementVariation, mfem::Vector &action) const;
// Previous optimized pointwise actions, sharing exactly the same state.
void MultCachedReference(const mfem::Vector &densityVariation, const mfem::Vector &enthalpyVariation,
const mfem::Vector &displacementVariation, mfem::Vector &action) const;
[[nodiscard]] int GetTensorElementCount() const noexcept;
void BuildResidual(mfem::Vector &residual) const;
// Exact diagonal of the prepared density-to-closure block, expressed
@@ -118,15 +132,19 @@ export namespace mean_field::operators {
void VerifyPrepared() const;
void MultImpl(const mfem::Vector &densityVariation, const mfem::Vector &enthalpyVariation,
const mfem::Vector &displacementVariation, mfem::Vector &action, bool useFastPath, bool useTensorPath) const;
void ApplyThermodynamicActionFull(
const mfem::Vector &densityVariationTrue,
const mfem::Vector *densityVariationTrue,
const mfem::Vector &enthalpyVariationTrue,
mfem::Vector &actionTrue
mfem::Vector &actionTrue, bool useTensorPath = true
) const;
void ApplyDisplacementActionFull(
const mfem::Vector &displacementVariationTrue,
mfem::Vector &actionTrue
mfem::Vector &actionTrue,
bool useFastPath = true, bool useTensorPath = true
) const;
struct ElementPAData {
@@ -180,6 +198,8 @@ export namespace mean_field::operators {
mutable mfem::Vector m_quadratureDisplacementAction;
mutable mfem::Vector m_elementDisplacementAction;
mutable mfem::DenseMatrix m_referenceDisplacementJacobian;
mutable mfem::DenseMatrix m_tensorDisplacement;
mutable mfem::Vector m_tensorWorkspace;
std::uint64_t m_preparationCount{0};
bool m_isPrepared{false};

View File

@@ -66,6 +66,9 @@ export namespace mean_field::operators {
kernels::GravityDisplacementForceRejection>
TryPrepare();
// Retained two-pass preparation for isolation benchmarks and validation.
PreparedGravityDisplacementForceReport PrepareReference();
void BuildResidual(mfem::Vector &residual) const;
void ApplyDensityJacobianAction(
@@ -90,6 +93,31 @@ export namespace mean_field::operators {
mfem::Vector &action
) const;
void ApplyCompleteJacobianActionReference(
const mfem::Vector &densityVariation,
const mfem::Vector &displacementVariation,
const mfem::Vector &gravityGradientVariation,
mfem::Vector &action
) const;
void ApplyCompleteJacobianActionCachedReference(
const mfem::Vector &densityVariation, const mfem::Vector &displacementVariation,
const mfem::Vector &gravityGradientVariation, mfem::Vector &action
) const;
[[nodiscard]] int GetTensorElementCount() const noexcept {
int count = 0;
for (const auto &data : m_elements)
if (data.fastApplication && data.displacementReferenceTable->HasTensorEvaluation3D() &&
data.gravityReferenceTable && data.gravityReferenceTable->HasTensorEvaluation3D()) ++count;
return count;
}
[[nodiscard]] int GetFastElementCount() const noexcept {
int count = 0;
for (const auto &data : m_elements) count += data.fastApplication;
return count;
}
[[nodiscard]] bool IsPrepared() const noexcept;
[[nodiscard]] std::uint64_t GetResidualPreparationCount() const noexcept;
@@ -124,16 +152,20 @@ export namespace mean_field::operators {
[[nodiscard]] std::expected<
void,
kernels::GravityDisplacementForceRejection>
TryPrepareElementData();
TryPrepareElementData(bool assembleResidual);
[[nodiscard]] std::expected<PreparedGravityDisplacementForceReport, kernels::GravityDisplacementForceRejection>
TryPrepareImpl(bool useFastPreparation);
void ApplyPreparedCompleteJacobianActionTrue(
const mfem::Vector &densityVariationTrue,
const mfem::Vector &displacementVariationTrue,
const mfem::Vector &gravityGradientVariationTrue,
mfem::Vector &actionTrue
mfem::Vector &actionTrue,
bool useFastPath = true, bool useTensorPath = true
) const;
struct ElementPAData {
int elementId{-1};
bool fastApplication{false};
mfem::Array<int> densityDofs;
mfem::Array<int> gravityGradientDofs;
mfem::Array<int> displacementDofs;
@@ -168,6 +200,8 @@ export namespace mean_field::operators {
mutable mfem::Vector m_gravityGradientVariationLocal;
mutable mfem::Vector m_displacementVariationLocal;
mutable mfem::Vector m_localAction;
mutable mfem::Vector m_quadratureDensityVariation;
mutable mfem::DenseMatrix m_quadratureForce;
mutable mfem::Vector m_elementDensityVariation;
mutable mfem::Vector m_elementGravityGradientVariation;
mutable mfem::Vector m_elementDisplacementVariation;
@@ -199,6 +233,9 @@ export namespace mean_field::operators {
mutable PreparedGravityDisplacementForceCompleteStatistics m_completeJacobianStatistics;
mutable mfem::DenseMatrix m_tensorDisplacement, m_tensorGravity, m_tensorElementDual;
mutable mfem::Vector m_tensorWorkspace;
bool m_preparedWithFastResidual{true};
bool m_isPrepared{false};
};

View File

@@ -38,6 +38,8 @@ export namespace mean_field::operators {
void Prepare(const mfem::Vector &displacement);
void PreparePrimal(const mfem::Vector &displacement);
// Previous weight-recomputation path for isolated preparation comparisons.
void PrepareReference(const mfem::Vector &displacement);
[[nodiscard]] GravitySourcePreparationResult TryPrepare(const mfem::Vector &displacement);
[[nodiscard]] GravitySourcePreparationResult TryPreparePrimal(const mfem::Vector &displacement);
void Mult(
@@ -64,6 +66,11 @@ export namespace mean_field::operators {
}
}
void MultDisplacementVariationTrueReference(
const mfem::Vector &densityTrue, const mfem::Vector &displacementVariationTrue,
mfem::Vector &actionVariationTrue) const;
[[nodiscard]] int GetTensorVariationElementCount() const noexcept;
void MultTranspose(
const mfem::Vector &potential,
mfem::Vector &action
@@ -109,7 +116,7 @@ export namespace mean_field::operators {
[[nodiscard]] GravitySourcePreparationResult TryPrepareImpl(
const mfem::Vector &displacement,
PreparationMode mode
PreparationMode mode, bool useCachedMeshWeight = true
);
const fem::FEM &m_fem;
@@ -137,6 +144,11 @@ export namespace mean_field::operators {
mutable mfem::Vector m_element_displacement_variation;
mutable mfem::Vector m_quadrature_variation_action;
mutable mfem::Vector m_element_variation_action;
void MultDisplacementVariationTrueImpl(const mfem::Vector &densityTrue,
const mfem::Vector &displacementVariationTrue, mfem::Vector &actionVariationTrue,
bool useTensorPath) const;
mutable mfem::DenseMatrix m_tensorSamples;
mutable mfem::Vector m_tensorWorkspace;
mutable mfem::DenseMatrix m_reference_displacement_jacobian;
mfem::Vector m_displacement_true;

View File

@@ -44,11 +44,29 @@ export namespace mean_field::operators {
const mfem::Vector &gravity_gradient,
mfem::Vector &action
) const override;
// Unmodified MFEM partial-assembly application on the same prepared data.
void MultReference(const mfem::Vector &gravityGradient, mfem::Vector &action) const;
[[nodiscard]] int GetFastMassElementCount() const noexcept { return m_fastMassElements; }
void MultDisplacementVariationTrue(
const mfem::Vector &gravityGradientTrue,
const mfem::Vector &displacementVariationTrue,
mfem::Vector &actionVariationTrue
) const;
// Retained prepared implementation for isolated A/B validation and
// profiling. Uses the same prepared state, quadrature and DOF maps.
void MultDisplacementVariationTrueReference(
const mfem::Vector &gravityGradientTrue,
const mfem::Vector &displacementVariationTrue,
mfem::Vector &actionVariationTrue
) const;
// Previous optimized pointwise path, excluding the new tensor contractions.
void MultDisplacementVariationTrueCachedReference(
const mfem::Vector &gravityGradientTrue, const mfem::Vector &displacementVariationTrue,
mfem::Vector &actionVariationTrue
) const;
[[nodiscard]] int GetFastVariationElementCount() const noexcept;
[[nodiscard]] int GetTensorVariationElementCount() const noexcept;
void AssembleDiagonal(mfem::Vector &diagonal) const override;
void AssembleTrueDiagonal(mfem::Vector &diagonal) const;
@@ -79,6 +97,11 @@ export namespace mean_field::operators {
mfem::Vector compactification;
const mfem::IntegrationRule *integrationRule{nullptr};
std::shared_ptr<const fem::VectorReferenceTable> gravityReferenceTable;
std::shared_ptr<const fem::ScalarReferenceTable> displacementReferenceTable;
// One contiguous column per quadrature point: scale*J_mesh^-1
// (row-major, nine entries), followed by grad(scale). 3D VALUE
// displacement with an interior or Kelvin map; empty otherwise.
mfem::DenseMatrix tangentFactors;
// Fixed computational-mesh Piola factor, separate from J_map.
mfem::DenseMatrix meshPiolaJacobians;
mfem::Vector referenceWeights;
@@ -86,6 +109,13 @@ export namespace mean_field::operators {
};
[[nodiscard]] mapping::MappingStatus PrepareVariationData();
void MultDisplacementVariationTrueImpl(
const mfem::Vector &gravityGradientTrue,
const mfem::Vector &displacementVariationTrue,
mfem::Vector &actionVariationTrue,
bool useFastPath, bool useTensorPath
) const;
void AddFastElementVariation(const ElementVariationData &data, bool useTensorPath) const;
[[nodiscard]] HDivMassPreparationResult TryPrepareImpl(
const mfem::Vector &displacement,
PreparationMode mode
@@ -129,9 +159,12 @@ export namespace mean_field::operators {
mutable mfem::DenseMatrix m_meshPiolaJacobian;
mutable mfem::DenseMatrix m_gravityGradientShape;
mutable mfem::DenseMatrix m_massTensorVariation;
mutable mfem::DenseMatrix m_tensorDisplacement, m_tensorGravity, m_tensorDual;
mutable mfem::Vector m_tensorWorkspace;
std::uint64_t m_preparation_count{0};
bool m_is_prepared{false};
bool m_has_variation_data{false};
bool m_single_rank{true};
int m_fastMassElements{0};
};
} // namespace mean_field::operators

View File

@@ -142,6 +142,14 @@ export namespace mean_field::operators {
const physics::RigidRotation &rotation
);
HydrostaticEquilibriumPreparationResult TryPrepareReference(
const context::hydrostatic::HydrostaticEquilibriumStateView &state,
const context::hydrostatic::HydrostaticEquilibriumDependencies &dependencies,
const physics::RigidRotation &rotation);
PreparedHydrostaticEquilibriumReport PrepareReference(
const context::hydrostatic::HydrostaticEquilibriumStateView &state,
const context::hydrostatic::HydrostaticEquilibriumDependencies &dependencies,
const physics::RigidRotation &rotation);
void BuildResidual(mfem::Vector &residual) const;
void ApplyEnthalpyJacobianAction(
@@ -179,6 +187,18 @@ export namespace mean_field::operators {
mfem::Vector &action
) const;
void ApplyDisplacementJacobianActionReference(
const mfem::Vector &displacementVariation,
mfem::Vector &action
) const;
// Previous cached pointwise implementation, retained for benchmarking
// the tensor change separately from the older general mapping path.
void ApplyDisplacementJacobianActionCachedReference(
const mfem::Vector &displacementVariation, mfem::Vector &action
) const;
[[nodiscard]] int GetFastDisplacementElementCount() const noexcept;
[[nodiscard]] int GetTensorDisplacementElementCount() const noexcept;
void ApplyCompleteJacobianAction(
const mfem::Vector &enthalpyVariation,
const mfem::Vector &gravityPotentialVariation,
@@ -244,6 +264,10 @@ export namespace mean_field::operators {
// Immutable reference values and gradients are shared by FE/rule.
std::shared_ptr<const fem::ScalarReferenceTable> enthalpyReferenceTable;
std::shared_ptr<const fem::ScalarReferenceTable> gravityPotentialReferenceTable;
std::shared_ptr<const fem::ScalarReferenceTable> displacementReferenceTable;
// Columns are quadrature points; each holds a column-major inverse
// deformed element Jacobian. Empty for the general mapping path.
mfem::DenseMatrix displacementInverseJacobians;
[[nodiscard]] const mfem::DenseMatrix &GetEnthalpyBasis() const {
return enthalpyReferenceTable->GetValues();
@@ -274,14 +298,24 @@ export namespace mean_field::operators {
mfem::Vector bernoulliConstantJacobian;
};
HydrostaticEquilibriumPreparationResult TryPrepareImpl(
const context::hydrostatic::HydrostaticEquilibriumStateView &state,
const context::hydrostatic::HydrostaticEquilibriumDependencies &dependencies,
const physics::RigidRotation &rotation, bool useTensorPreparation);
void PrepareStaticPlan();
[[nodiscard]] std::optional<mapping::MappingStatus> PrepareGeometry();
[[nodiscard]] bool PrepareAlgebraicJacobianBlocks();
[[nodiscard]] std::optional<mapping::MappingStatus> PrepareGeometry(bool useTensorPreparation);
[[nodiscard]] bool PrepareAlgebraicJacobianBlocks(bool useTensorPreparation);
[[nodiscard]] bool PrepareRotation();
[[nodiscard]] bool PrepareBaseState();
[[nodiscard]] bool PrepareBaseState(bool useTensorPreparation);
void FinalizeDisplacementJacobianPreparation();
[[nodiscard]] bool AssembleCachedResidual();
void VerifyPrepared() const;
void ApplyDisplacementJacobianActionImpl(
const mfem::Vector &displacementVariation, mfem::Vector &action, bool useFastPath, bool useTensorPath
) const;
mutable mfem::DenseMatrix m_tensorDisplacementValuesAndGradients;
mutable mfem::Vector m_tensorDisplacementWorkspace;
const fem::FEM &m_fem;
const mapping::DomainMapper &m_domainMapper;
@@ -307,6 +341,7 @@ export namespace mean_field::operators {
mutable PreparedHydrostaticCompleteJacobianStatistics m_completeJacobianStatistics;
bool m_preparedWithTensorPreparation{true};
bool m_isPrepared{false};
};

View File

@@ -147,6 +147,16 @@ export namespace mean_field::operators {
void BuildResidual(mfem::Vector &residual) const;
// Lazy, local-dual row assembly. Invalidated only by density/geometry.
// Returns false when this discretization uses the general fallback.
[[nodiscard]] bool PrepareJacobianRows() const;
[[nodiscard]] std::uint64_t GetJacobianRowPreparationCount() const noexcept;
void ApplyCompleteJacobianActionReference(
const mfem::Vector &densityVariation,
const mfem::Vector &displacementVariation,
mfem::Vector &action
) const;
void ApplyDensityJacobianAction(
const mfem::Vector &densityVariation,
mfem::Vector &action
@@ -230,6 +240,9 @@ export namespace mean_field::operators {
[[nodiscard]] double EvaluateDisplacementActionLocal(const mfem::Vector &displacementVariation) const;
[[nodiscard]] double EvaluateDensityActionLocalReference(const mfem::Vector &densityVariation) const;
[[nodiscard]] double EvaluateDisplacementActionLocalReference(const mfem::Vector &displacementVariation) const;
void AssembleDensityTransposeAction(
double residualDual,
mfem::Vector &densityDual
@@ -250,8 +263,16 @@ export namespace mean_field::operators {
MassNormalizationDependencies m_preparedDependencies;
mfem::Vector m_cachedResidual;
mutable mfem::Vector m_densityJacobianLocal;
mutable mfem::Vector m_displacementJacobianLocal;
mutable bool m_jacobianRowsReady{false};
mutable bool m_jacobianRowsSupported{false};
mutable std::uint64_t m_jacobianRowPreparationCount{0};
mutable mfem::Vector m_densityVariationTrue;
mutable mfem::Vector m_displacementVariationTrue;
mutable mfem::Vector m_densityVariationLocal;
mutable mfem::Vector m_displacementVariationLocal;
double m_currentMass{0.0};
double m_targetMass{0.0};

View File

@@ -116,6 +116,20 @@ export namespace mean_field::operators {
const context::pressure_force::PressureForceDependencies &dependencies
);
// Original quadrature-by-quadrature matrix assembly for validation.
PreparedPressureForceReport PrepareReference(
const context::pressure_force::PressureForceStateView &state,
const context::pressure_force::PressureForceDependencies &dependencies
);
// Previous blocked matrix preparation and pointwise field evaluation.
PreparedPressureForceReport PrepareCachedReference(
const context::pressure_force::PressureForceStateView &state,
const context::pressure_force::PressureForceDependencies &dependencies);
void ApplyDisplacementJacobianActionCachedReference(
const mfem::Vector &displacementVariation, mfem::Vector &action) const;
[[nodiscard]] int GetTensorElementCount() const noexcept;
void BuildResidual(mfem::Vector &residual) const;
void ApplyEnthalpyJacobianAction(
@@ -128,6 +142,10 @@ export namespace mean_field::operators {
mfem::Vector &action
) const;
void ApplyDisplacementJacobianActionReference(
const mfem::Vector &displacementVariation, mfem::Vector &action
) const;
void ApplyCompleteJacobianAction(
const mfem::Vector &enthalpyVariation,
const mfem::Vector &displacementVariation,
@@ -178,6 +196,8 @@ export namespace mean_field::operators {
}
private:
void ApplyDisplacementJacobianActionImpl(const mfem::Vector &displacementVariation,
mfem::Vector &action, bool useFastPath, bool useTensorPath = true) const;
struct ConstructionData;
[[nodiscard]]
@@ -237,8 +257,14 @@ export namespace mean_field::operators {
};
void PrepareStaticPlan();
[[nodiscard]] std::optional<PressureForcePreparationRejection> PrepareGeometry();
[[nodiscard]] std::optional<PressureForcePreparationRejection> PrepareMaterialState();
[[nodiscard]] std::optional<PressureForcePreparationRejection> PrepareGeometry(bool useTensorPreparation);
[[nodiscard]] std::optional<PressureForcePreparationRejection> PrepareMaterialState(bool useFastPreparation, bool useTensorPreparation);
[[nodiscard]] std::expected<PreparedPressureForceReport, PressureForcePreparationRejection>
TryPrepareImpl(
const context::pressure_force::PressureForceStateView &state,
const context::pressure_force::PressureForceDependencies &dependencies,
bool useFastPreparation, bool useTensorPreparation = true
);
void FinalizeDisplacementJacobianPreparation();
@@ -291,6 +317,10 @@ export namespace mean_field::operators {
mutable PreparedPressureForceCompleteJacobianStatistics m_completeJacobianStatistics;
mutable mfem::DenseMatrix m_tensorSamples, m_tensorDuals, m_tensorElement;
mutable mfem::Vector m_tensorWorkspace;
bool m_preparedWithTensorPreparation{true};
bool m_preparedWithFastMaterialAssembly{true};
bool m_isPrepared{false};
};

View File

@@ -4,6 +4,7 @@ module;
#include <cstdint>
#include <expected>
#include <optional>
#include <memory>
#include <vector>
#include <mfem.hpp>
@@ -11,6 +12,7 @@ module;
export module mean_field:operators.prepared_rotational_displacement_force;
export import :fem;
import :fem.reference_tables;
export import :mapping.domain_mapper;
export import :operators.context.rotational_displacement_force;
export import :operators.kernels.rotational_displacement_force;
@@ -72,6 +74,13 @@ export namespace mean_field::operators {
const physics::RigidRotation &rotation
);
// Retained two-pass preparation for isolation benchmarks and validation.
PreparedRotationalDisplacementForceReport PrepareReference(
const context::rotational_displacement_force::RotationalDisplacementForceStateView &state,
const context::rotational_displacement_force::RotationalDisplacementForceDependencies &dependencies,
const physics::RigidRotation &rotation
);
void BuildResidual(mfem::Vector &residual) const;
void ApplyDensityJacobianAction(
@@ -90,6 +99,23 @@ export namespace mean_field::operators {
mfem::Vector &action
) const;
void ApplyCompleteJacobianActionReference(
const mfem::Vector &densityVariation,
const mfem::Vector &displacementVariation,
mfem::Vector &action
) const;
void ApplyCompleteJacobianActionCachedReference(
const mfem::Vector &densityVariation, const mfem::Vector &displacementVariation, mfem::Vector &action
) const;
[[nodiscard]] int GetTensorElementCount() const noexcept;
[[nodiscard]] int GetFastElementCount() const noexcept {
int count = 0;
for (const auto &data : m_elements) count += data.fastApplication;
return count;
}
[[nodiscard]] bool IsPrepared() const noexcept;
[[nodiscard]] const context::rotational_displacement_force::RotationalDisplacementForcePreparationStatistics &
@@ -124,20 +150,31 @@ export namespace mean_field::operators {
[[nodiscard]] std::expected<
void,
kernels::RotationalDisplacementForceRejection>
TryPrepareElementData();
TryPrepareElementData(bool assembleResidual);
[[nodiscard]] std::expected<PreparedRotationalDisplacementForceReport, kernels::RotationalDisplacementForceRejection>
TryPrepareImpl(
const context::rotational_displacement_force::RotationalDisplacementForceStateView &state,
const context::rotational_displacement_force::RotationalDisplacementForceDependencies &dependencies,
const physics::RigidRotation &rotation,
bool useFastPreparation
);
void ApplyPreparedCompleteJacobianActionTrue(
const mfem::Vector &densityVariationTrue,
const mfem::Vector &displacementVariationTrue,
mfem::Vector &actionTrue
mfem::Vector &actionTrue,
bool useFastPath = true, bool useTensorPath = true
) const;
struct ElementPAData {
int elementId{-1};
bool fastApplication{false};
mfem::Array<int> densityDofs;
mfem::Array<int> displacementDofs;
mfem::DofTransformation *densityDofTransformation{nullptr};
mfem::DofTransformation *displacementDofTransformation{nullptr};
const mfem::IntegrationRule *integrationRule{nullptr};
std::shared_ptr<const fem::ScalarReferenceTable> densityReferenceTable;
std::shared_ptr<const fem::ScalarReferenceTable> displacementReferenceTable;
mfem::DenseMatrix inverseElementJacobians;
mfem::DenseMatrix centrifugalAccelerations;
mfem::Vector baseDensityValues;
@@ -150,6 +187,7 @@ export namespace mean_field::operators {
context::rotational_displacement_force::RotationalDisplacementForceLinearizationContext m_context;
std::optional<physics::RigidRotation> m_rotation;
mfem::DenseMatrix m_centrifugalJacobian;
mfem::Vector m_cachedResidual;
std::vector<ElementPAData> m_elements;
mutable mfem::Vector m_densityVariationTrue;
@@ -158,6 +196,11 @@ export namespace mean_field::operators {
mutable mfem::Vector m_densityVariationLocal;
mutable mfem::Vector m_displacementVariationLocal;
mutable mfem::Vector m_localAction;
mutable mfem::Vector m_quadratureDensityVariation;
mutable mfem::DenseMatrix m_quadratureForce;
mutable mfem::DenseMatrix m_quadraturePositionVariation;
mutable mfem::DenseMatrix m_tensorDisplacement, m_tensorElement;
mutable mfem::Vector m_tensorWorkspace;
mutable mfem::Vector m_elementDensityVariation;
mutable mfem::Vector m_elementDisplacementVariation;
mutable mfem::Vector m_elementAction;
@@ -181,6 +224,7 @@ export namespace mean_field::operators {
mutable PreparedRotationalDisplacementForceCompleteStatistics m_completeJacobianStatistics;
bool m_preparedWithFastResidual{true};
bool m_isPrepared{false};
};