Files
MeanField/libmeanfield/interface/operators/prepared_pressure_force.cppm
Emily Boudreaux 0f3ca8050b feat(field-support): added field support system, mid migration
currently the barotope and the pressure force operator are migrated to the new support system
2026-08-23 10:13:53 -04:00

304 lines
9.2 KiB
C++

module;
#include <compare>
#include <cstddef>
#include <cstdint>
#include <optional>
#include <vector>
#include <mfem.hpp>
export module mean_field:operators.prepared_pressure_force;
export import :eos.polytrope;
export import :fem;
export import :field.mfem;
export import :mapping.domain_mapper;
export import :operators.context.pressure_force;
export import :utils.blocks;
export namespace mean_field::operators {
struct PreparedPressureForceReport final {
context::pressure_force::PressureForcePreparationReport contextReport;
bool preparedEnthalpyJacobianData{false};
bool preparedDisplacementJacobianData{false};
bool preparedResidual{false};
[[nodiscard]]
bool DidAnyWork() const noexcept {
return contextReport.DidAnyWork() || preparedEnthalpyJacobianData || preparedDisplacementJacobianData ||
preparedResidual;
}
};
struct PreparedPressureForceEnthalpyJacobianStatistics final {
std::uint64_t preparations{0};
std::uint64_t applications{0};
constexpr auto operator<=>(const PreparedPressureForceEnthalpyJacobianStatistics &) const = default;
};
struct PreparedPressureForceDisplacementJacobianStatistics final {
std::uint64_t preparations{0};
std::uint64_t applications{0};
constexpr auto operator<=>(const PreparedPressureForceDisplacementJacobianStatistics &) const = default;
};
struct PreparedPressureForceCompleteJacobianStatistics final {
std::uint64_t applications{0};
constexpr auto operator<=>(const PreparedPressureForceCompleteJacobianStatistics &) const = default;
};
/*
* Prepared pressure contribution
*
* R_d^P(w)
* =
* - integral_{Omega_star(d)}
* P(h) div(w) dV.
*
* Public state and Jacobian directions are expressed in FieldDof
* coordinates.
*
* Current registry:
*
* h -> Stellar -> reduced
* d -> All -> identity/full
* R_d -> All -> identity/full
*
* Full MFEM true/local vectors are private implementation details.
*/
class PreparedPressureForceOperator final {
public:
PreparedPressureForceOperator(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const eos::Polytrope &equationOfState
);
PreparedPressureForceOperator(const PreparedPressureForceOperator &) = delete;
PreparedPressureForceOperator &operator=(const PreparedPressureForceOperator &) = delete;
PreparedPressureForceOperator(PreparedPressureForceOperator &&) = delete;
PreparedPressureForceOperator &operator=(PreparedPressureForceOperator &&) = delete;
PreparedPressureForceReport Prepare(
const context::pressure_force::PressureForceStateView &state,
const context::pressure_force::PressureForceDependencies &dependencies
);
void BuildResidual(mfem::Vector &residual) const;
void ApplyEnthalpyJacobianAction(
const mfem::Vector &enthalpyVariation,
mfem::Vector &action
) const;
void ApplyDisplacementJacobianAction(
const mfem::Vector &displacementVariation,
mfem::Vector &action
) const;
void ApplyCompleteJacobianAction(
const mfem::Vector &enthalpyVariation,
const mfem::Vector &displacementVariation,
mfem::Vector &action
) const;
[[nodiscard]]
bool IsPrepared() const noexcept;
[[nodiscard]]
int GetEnthalpySize() const noexcept;
[[nodiscard]]
int GetDisplacementSize() const noexcept;
[[nodiscard]]
const context::pressure_force::PressureForceLinearizationContext &GetContext() const noexcept;
[[nodiscard]]
const context::pressure_force::PressureForcePreparationStatistics &
GetContextPreparationStatistics() const noexcept;
[[nodiscard]]
std::uint64_t GetResidualPreparationCount() const noexcept;
[[nodiscard]]
std::uint64_t GetResidualApplicationCount() const noexcept;
[[nodiscard]]
const PreparedPressureForceEnthalpyJacobianStatistics &GetEnthalpyJacobianStatistics() const noexcept;
[[nodiscard]]
const PreparedPressureForceDisplacementJacobianStatistics &GetDisplacementJacobianStatistics() const noexcept;
[[nodiscard]]
const PreparedPressureForceCompleteJacobianStatistics &GetCompleteJacobianStatistics() const noexcept;
[[nodiscard]]
std::size_t GetStellarElementCount() const noexcept;
[[nodiscard]]
const fem::FEM &GetFEM() const noexcept;
private:
struct ConstructionData;
[[nodiscard]]
static ConstructionData MakeConstructionData(const fem::FEM &f);
PreparedPressureForceOperator(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const eos::Polytrope &equationOfState,
ConstructionData constructionData
);
struct ElementPAData final {
int elementId{-1};
mfem::Array<int> enthalpyDofs;
mfem::Array<int> displacementDofs;
mfem::Array<int> compactificationDofs;
mfem::DofTransformation *enthalpyDofTransformation{nullptr};
mfem::DofTransformation *displacementDofTransformation{nullptr};
mfem::DofTransformation *compactificationDofTransformation{nullptr};
const mfem::IntegrationRule *integrationRule{nullptr};
/*
* Rows are quadrature points and columns are enthalpy DOFs.
*/
mfem::DenseMatrix enthalpyBasis;
/*
* Each entry is:
*
* scalar displacement DOF
* x
* physical dimension.
*/
std::vector<mfem::DenseMatrix> referenceTestGradients;
std::vector<mfem::DenseMatrix> physicalTestGradients;
std::vector<mapping::VolumeMappingContext> baseMappingContexts;
std::optional<mapping::ElementDisplacementData> baseDisplacementData;
std::optional<mapping::ElementCompactificationData> compactificationData;
mfem::Vector quadratureWeights;
mfem::Vector pressure;
mfem::Vector pressureDerivative;
mfem::Vector elementResidual;
mfem::DenseMatrix enthalpyJacobian;
};
void PrepareStaticPlan();
void PrepareGeometry();
void PrepareMaterialState();
void FinalizeDisplacementJacobianPreparation();
void AssembleCachedResidual();
void VerifyPrepared() const;
const fem::FEM &m_fem;
const mapping::DomainMapperStateless &m_domainMapper;
const eos::Polytrope &m_equationOfState;
field::FieldDofMap m_enthalpyMap;
field::FieldDofMap m_displacementMap;
context::pressure_force::PressureForceLinearizationContext m_context;
std::vector<ElementPAData> m_elements;
/*
* Canonical full-MFEM expansion of the frozen FieldDof state.
*/
mfem::Vector m_baseEnthalpyTrue;
mfem::Vector m_baseDisplacementTrue;
/*
* Reusable Krylov work storage.
*/
mutable mfem::Vector m_enthalpyVariationTrue;
mutable mfem::Vector m_displacementVariationTrue;
mutable mfem::Vector m_fullDisplacementAction;
/*
* Solver-facing cached residual in Displacement FieldDof
* coordinates.
*/
mfem::Vector m_cachedResidual;
std::uint64_t m_residualPreparationCount{0};
mutable std::uint64_t m_residualApplicationCount{0};
mutable PreparedPressureForceEnthalpyJacobianStatistics m_enthalpyJacobianStatistics;
mutable PreparedPressureForceDisplacementJacobianStatistics m_displacementJacobianStatistics;
mutable PreparedPressureForceCompleteJacobianStatistics m_completeJacobianStatistics;
bool m_isPrepared{false};
};
using BarotropicEquilibriumLayout = utils::blocks::form_layout<utils::blocks::barotropic_equilibrium_form>;
/*
* Coupled-layout adapter around the modern prepared pressure-force
* Jacobian.
*
* Reads:
*
* delta d
* delta h
*
* Writes:
*
* R_d
*
* It deliberately imposes no raw-FES-size assumptions on unrelated
* coupled blocks.
*/
class PreparedPressureForceJacobianOperator final : public mfem::Operator {
public:
PreparedPressureForceJacobianOperator(
const BarotropicEquilibriumLayout &layout,
const PreparedPressureForceOperator &preparedOperator
);
void Mult(
const mfem::Vector &direction,
mfem::Vector &action
) const override;
[[nodiscard]]
const BarotropicEquilibriumLayout &GetLayout() const noexcept;
private:
BarotropicEquilibriumLayout m_layout;
const PreparedPressureForceOperator &m_preparedOperator;
};
} // namespace mean_field::operators