feat(field-support): added field support system, mid migration
currently the barotope and the pressure force operator are migrated to the new support system
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
module;
|
||||
|
||||
#include <compare>
|
||||
#include <cstdint>
|
||||
|
||||
#include <mfem.hpp>
|
||||
@@ -7,18 +8,66 @@ module;
|
||||
export module mean_field:operators.context.barotropic_closure_linearization;
|
||||
|
||||
export import :fem;
|
||||
export import :field.mfem;
|
||||
export import :mapping.domain_mapper;
|
||||
export import :operators.prepared_barotropic_closure;
|
||||
export import :physics.barotrope;
|
||||
|
||||
export namespace mean_field::operators::context::barotropic {
|
||||
struct BarotropicClosureRevisions final {
|
||||
std::uint64_t density = 0;
|
||||
std::uint64_t enthalpy = 0;
|
||||
std::uint64_t displacement = 0;
|
||||
template <typename Tag> struct DependencyStamp {
|
||||
std::uint64_t identity{0};
|
||||
std::uint64_t revision{0};
|
||||
|
||||
[[nodiscard]] bool
|
||||
operator==(const BarotropicClosureRevisions &) const noexcept = default;
|
||||
[[nodiscard]] constexpr bool CanFollow(const DependencyStamp &prepared) const noexcept {
|
||||
return identity != prepared.identity || revision >= prepared.revision;
|
||||
}
|
||||
|
||||
constexpr auto operator<=>(const DependencyStamp &) const = default;
|
||||
};
|
||||
|
||||
struct DiscretizationDependencyTag { };
|
||||
struct DensityDependencyTag { };
|
||||
struct EnthalpyDependencyTag { };
|
||||
struct DisplacementDependencyTag { };
|
||||
|
||||
using DiscretizationDependency = DependencyStamp<DiscretizationDependencyTag>;
|
||||
using DensityDependency = DependencyStamp<DensityDependencyTag>;
|
||||
using EnthalpyDependency = DependencyStamp<EnthalpyDependencyTag>;
|
||||
using DisplacementDependency = DependencyStamp<DisplacementDependencyTag>;
|
||||
|
||||
struct BarotropicClosureDependencies final {
|
||||
DiscretizationDependency discretization;
|
||||
DensityDependency density;
|
||||
EnthalpyDependency enthalpy;
|
||||
DisplacementDependency displacement;
|
||||
|
||||
constexpr auto operator<=>(const BarotropicClosureDependencies &) const = default;
|
||||
};
|
||||
|
||||
struct BarotropicClosureStateView final {
|
||||
const mfem::Vector &density;
|
||||
const mfem::Vector &enthalpy;
|
||||
const mfem::Vector &displacement;
|
||||
};
|
||||
|
||||
struct BarotropicClosurePreparationReport final {
|
||||
bool preparedStaticDependencies{false};
|
||||
bool preparedGeometryState{false};
|
||||
bool preparedBaseState{false};
|
||||
|
||||
bool updatedDensity{false};
|
||||
bool updatedEnthalpy{false};
|
||||
bool updatedDisplacement{false};
|
||||
|
||||
[[nodiscard]] bool DidAnyWork() const noexcept {
|
||||
return preparedStaticDependencies || preparedGeometryState || preparedBaseState;
|
||||
}
|
||||
};
|
||||
|
||||
struct BarotropicClosurePreparationStatistics final {
|
||||
std::uint64_t staticPreparations{0};
|
||||
std::uint64_t geometryPreparations{0};
|
||||
std::uint64_t baseStatePreparations{0};
|
||||
|
||||
constexpr auto operator<=>(const BarotropicClosurePreparationStatistics &) const = default;
|
||||
};
|
||||
|
||||
class BarotropicClosureLinearizationContext final {
|
||||
@@ -26,51 +75,46 @@ export namespace mean_field::operators::context::barotropic {
|
||||
BarotropicClosureLinearizationContext(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const physics::PolytropicBarotrope &barotrope
|
||||
const field::FieldDofMap &densityMap,
|
||||
const field::FieldDofMap &enthalpyMap,
|
||||
const field::FieldDofMap &displacementMap
|
||||
);
|
||||
|
||||
void Prepare(
|
||||
const mfem::Vector &baseDensityTrue,
|
||||
const mfem::Vector &baseEnthalpyTrue,
|
||||
const mfem::Vector &displacementTrue,
|
||||
const BarotropicClosureRevisions &revisions
|
||||
BarotropicClosureLinearizationContext(const BarotropicClosureLinearizationContext &) = delete;
|
||||
BarotropicClosureLinearizationContext &operator=(const BarotropicClosureLinearizationContext &) = delete;
|
||||
BarotropicClosureLinearizationContext(BarotropicClosureLinearizationContext &&) = delete;
|
||||
BarotropicClosureLinearizationContext &operator=(BarotropicClosureLinearizationContext &&) = delete;
|
||||
|
||||
BarotropicClosurePreparationReport Prepare(
|
||||
const BarotropicClosureStateView &state,
|
||||
const BarotropicClosureDependencies &dependencies
|
||||
);
|
||||
|
||||
[[nodiscard]] bool IsPrepared() const noexcept;
|
||||
[[nodiscard]] bool MatchesDependencies(const BarotropicClosureDependencies &dependencies) const noexcept;
|
||||
[[nodiscard]] const BarotropicClosureDependencies &GetDependencies() const;
|
||||
[[nodiscard]] const BarotropicClosurePreparationStatistics &GetPreparationStatistics() const noexcept;
|
||||
|
||||
[[nodiscard]] bool MatchesRevisions(
|
||||
const BarotropicClosureRevisions &revisions
|
||||
) const noexcept;
|
||||
|
||||
[[nodiscard]] std::uint64_t GetPreparationCount() const noexcept;
|
||||
|
||||
[[nodiscard]] const BarotropicClosureRevisions &GetRevisions() const;
|
||||
|
||||
[[nodiscard]] const mfem::Vector &GetBaseDensityTrue() const;
|
||||
|
||||
[[nodiscard]] const mfem::Vector &GetBaseEnthalpyTrue() const;
|
||||
|
||||
[[nodiscard]] const mfem::Vector &GetDisplacementTrue() const;
|
||||
|
||||
[[nodiscard]]
|
||||
const PreparedBarotropicClosureOperator &GetOperator() const noexcept;
|
||||
|
||||
void BuildResidual(mfem::Vector &residual) const;
|
||||
[[nodiscard]] const mfem::Vector &GetBaseDensity() const;
|
||||
[[nodiscard]] const mfem::Vector &GetBaseEnthalpy() const;
|
||||
[[nodiscard]] const mfem::Vector &GetDisplacement() const;
|
||||
|
||||
private:
|
||||
void VerifyPrepared() const;
|
||||
|
||||
const fem::FEM &m_f;
|
||||
const mapping::DomainMapperStateless &m_domainMapper;
|
||||
|
||||
PreparedBarotropicClosureOperator m_operator;
|
||||
int m_densitySize{0};
|
||||
int m_enthalpySize{0};
|
||||
int m_displacementSize{0};
|
||||
|
||||
mfem::Vector m_baseDensityTrue;
|
||||
mfem::Vector m_baseEnthalpyTrue;
|
||||
mfem::Vector m_displacementTrue;
|
||||
mfem::Vector m_baseDensity;
|
||||
mfem::Vector m_baseEnthalpy;
|
||||
mfem::Vector m_displacement;
|
||||
|
||||
BarotropicClosureRevisions m_revisions;
|
||||
|
||||
std::uint64_t m_preparationCount = 0;
|
||||
bool m_isPrepared = false;
|
||||
BarotropicClosureDependencies m_dependencies;
|
||||
BarotropicClosurePreparationStatistics m_statistics;
|
||||
bool m_isPrepared{false};
|
||||
};
|
||||
} // namespace mean_field::operators::context::barotropic
|
||||
} // namespace mean_field::operators::context::barotropic
|
||||
|
||||
@@ -51,8 +51,8 @@ export namespace mean_field::operators::context::gravity_field {
|
||||
bool refreshed_variation_state{false};
|
||||
|
||||
[[nodiscard]] bool DidAnyWork() const noexcept {
|
||||
return reconstructed_operators || rebuilt_mass_operator ||
|
||||
rebuilt_source_operator || refreshed_variation_state;
|
||||
return reconstructed_operators || rebuilt_mass_operator || rebuilt_source_operator ||
|
||||
refreshed_variation_state;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -63,13 +63,10 @@ export namespace mean_field::operators::context::gravity_field {
|
||||
const mapping::DomainMapperStateless &domain_mapper
|
||||
);
|
||||
|
||||
GravityFieldGeometryContext(const GravityFieldGeometryContext &) =
|
||||
delete;
|
||||
GravityFieldGeometryContext &
|
||||
operator=(const GravityFieldGeometryContext &) = delete;
|
||||
GravityFieldGeometryContext(GravityFieldGeometryContext &&) = delete;
|
||||
GravityFieldGeometryContext &
|
||||
operator=(GravityFieldGeometryContext &&) = delete;
|
||||
GravityFieldGeometryContext(const GravityFieldGeometryContext &) = delete;
|
||||
GravityFieldGeometryContext &operator=(const GravityFieldGeometryContext &) = delete;
|
||||
GravityFieldGeometryContext(GravityFieldGeometryContext &&) = delete;
|
||||
GravityFieldGeometryContext &operator=(GravityFieldGeometryContext &&) = delete;
|
||||
|
||||
GravityFieldGeometryPreparation Prepare(
|
||||
const mfem::Vector &displacement_true,
|
||||
@@ -77,15 +74,11 @@ export namespace mean_field::operators::context::gravity_field {
|
||||
DisplacementRevision displacement_revision
|
||||
);
|
||||
|
||||
[[nodiscard]] const PreparedMappedHDivMassOperator &
|
||||
GetMassOperator() const;
|
||||
[[nodiscard]] const PreparedMappedGravitySourceOperator &
|
||||
GetSourceOperator() const;
|
||||
[[nodiscard]] const PreparedMappedHDivMassOperator &GetMassOperator() const;
|
||||
[[nodiscard]] const PreparedMappedGravitySourceOperator &GetSourceOperator() const;
|
||||
[[nodiscard]] const mfem::Vector &GetDisplacement() const;
|
||||
[[nodiscard]] DiscretizationRevision
|
||||
GetDiscretizationRevision() const noexcept;
|
||||
[[nodiscard]] DisplacementRevision
|
||||
GetDisplacementRevision() const noexcept;
|
||||
[[nodiscard]] DiscretizationRevision GetDiscretizationRevision() const noexcept;
|
||||
[[nodiscard]] DisplacementRevision GetDisplacementRevision() const noexcept;
|
||||
[[nodiscard]] bool IsPrepared() const noexcept;
|
||||
|
||||
private:
|
||||
@@ -109,8 +102,7 @@ export namespace mean_field::operators::context::gravity_field {
|
||||
bool updated_gravity_gradient{false};
|
||||
|
||||
[[nodiscard]] bool DidAnyWork() const noexcept {
|
||||
return geometry.DidAnyWork() || updated_density ||
|
||||
updated_gravity_gradient;
|
||||
return geometry.DidAnyWork() || updated_density || updated_gravity_gradient;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -121,23 +113,17 @@ export namespace mean_field::operators::context::gravity_field {
|
||||
const mapping::DomainMapperStateless &domain_mapper
|
||||
);
|
||||
|
||||
GravityFieldLinearizationContext(
|
||||
const GravityFieldLinearizationContext &
|
||||
) = delete;
|
||||
GravityFieldLinearizationContext &
|
||||
operator=(const GravityFieldLinearizationContext &) = delete;
|
||||
GravityFieldLinearizationContext(GravityFieldLinearizationContext &&) =
|
||||
delete;
|
||||
GravityFieldLinearizationContext &
|
||||
operator=(GravityFieldLinearizationContext &&) = delete;
|
||||
GravityFieldLinearizationContext(const GravityFieldLinearizationContext &) = delete;
|
||||
GravityFieldLinearizationContext &operator=(const GravityFieldLinearizationContext &) = delete;
|
||||
GravityFieldLinearizationContext(GravityFieldLinearizationContext &&) = delete;
|
||||
GravityFieldLinearizationContext &operator=(GravityFieldLinearizationContext &&) = delete;
|
||||
|
||||
GravityFieldPreparationReport Prepare(
|
||||
const GravityFieldStateView &state,
|
||||
const GravityFieldRevisions &revisions
|
||||
);
|
||||
|
||||
[[nodiscard]] const GravityFieldGeometryContext &
|
||||
GetGeometryContext() const;
|
||||
[[nodiscard]] const GravityFieldGeometryContext &GetGeometryContext() const;
|
||||
[[nodiscard]] const mfem::Vector &GetDensity() const;
|
||||
[[nodiscard]] const mfem::Vector &GetGravityGradient() const;
|
||||
[[nodiscard]] const GravityFieldRevisions &GetRevisions() const;
|
||||
|
||||
@@ -15,10 +15,8 @@ export namespace mean_field::operators::context::hydrostatic {
|
||||
std::uint64_t identity{0};
|
||||
std::uint64_t revision{0};
|
||||
|
||||
[[nodiscard]] constexpr bool
|
||||
CanFollow(const DependencyStamp &prepared) const noexcept {
|
||||
return identity != prepared.identity ||
|
||||
revision >= prepared.revision;
|
||||
[[nodiscard]] constexpr bool CanFollow(const DependencyStamp &prepared) const noexcept {
|
||||
return identity != prepared.identity || revision >= prepared.revision;
|
||||
}
|
||||
|
||||
constexpr auto operator<=>(const DependencyStamp &) const = default;
|
||||
@@ -31,20 +29,17 @@ export namespace mean_field::operators::context::hydrostatic {
|
||||
struct RotationDependencyTag { };
|
||||
struct BernoulliConstantDependencyTag { };
|
||||
|
||||
using DiscretizationDependency =
|
||||
DependencyStamp<DiscretizationDependencyTag>;
|
||||
using DiscretizationDependency = DependencyStamp<DiscretizationDependencyTag>;
|
||||
|
||||
using EnthalpyDependency = DependencyStamp<EnthalpyDependencyTag>;
|
||||
using EnthalpyDependency = DependencyStamp<EnthalpyDependencyTag>;
|
||||
|
||||
using GravityPotentialDependency =
|
||||
DependencyStamp<GravityPotentialDependencyTag>;
|
||||
using GravityPotentialDependency = DependencyStamp<GravityPotentialDependencyTag>;
|
||||
|
||||
using DisplacementDependency = DependencyStamp<DisplacementDependencyTag>;
|
||||
using DisplacementDependency = DependencyStamp<DisplacementDependencyTag>;
|
||||
|
||||
using RotationDependency = DependencyStamp<RotationDependencyTag>;
|
||||
using RotationDependency = DependencyStamp<RotationDependencyTag>;
|
||||
|
||||
using BernoulliConstantDependency =
|
||||
DependencyStamp<BernoulliConstantDependencyTag>;
|
||||
using BernoulliConstantDependency = DependencyStamp<BernoulliConstantDependencyTag>;
|
||||
|
||||
struct HydrostaticEquilibriumDependencies {
|
||||
DiscretizationDependency discretization;
|
||||
@@ -54,8 +49,7 @@ export namespace mean_field::operators::context::hydrostatic {
|
||||
RotationDependency rotation;
|
||||
BernoulliConstantDependency bernoulliConstant;
|
||||
|
||||
constexpr auto
|
||||
operator<=>(const HydrostaticEquilibriumDependencies &) const = default;
|
||||
constexpr auto operator<=>(const HydrostaticEquilibriumDependencies &) const = default;
|
||||
};
|
||||
|
||||
struct HydrostaticEquilibriumStateView {
|
||||
@@ -77,8 +71,8 @@ export namespace mean_field::operators::context::hydrostatic {
|
||||
bool updatedBernoulliConstant{false};
|
||||
|
||||
[[nodiscard]] bool DidAnyWork() const noexcept {
|
||||
return preparedStaticDependencies || preparedGeometryState ||
|
||||
preparedRotationDependencies || preparedBaseState;
|
||||
return preparedStaticDependencies || preparedGeometryState || preparedRotationDependencies ||
|
||||
preparedBaseState;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -88,8 +82,7 @@ export namespace mean_field::operators::context::hydrostatic {
|
||||
std::uint64_t rotationPreparations{0};
|
||||
std::uint64_t baseStatePreparations{0};
|
||||
|
||||
constexpr auto
|
||||
operator<=>(const HydrostaticPreparationStatistics &) const = default;
|
||||
constexpr auto operator<=>(const HydrostaticPreparationStatistics &) const = default;
|
||||
};
|
||||
|
||||
class HydrostaticEquilibriumContext {
|
||||
@@ -99,17 +92,13 @@ export namespace mean_field::operators::context::hydrostatic {
|
||||
const mapping::DomainMapperStateless &domainMapper
|
||||
);
|
||||
|
||||
HydrostaticEquilibriumContext(const HydrostaticEquilibriumContext &) =
|
||||
delete;
|
||||
HydrostaticEquilibriumContext(const HydrostaticEquilibriumContext &) = delete;
|
||||
|
||||
HydrostaticEquilibriumContext &
|
||||
operator=(const HydrostaticEquilibriumContext &) = delete;
|
||||
HydrostaticEquilibriumContext &operator=(const HydrostaticEquilibriumContext &) = delete;
|
||||
|
||||
HydrostaticEquilibriumContext(HydrostaticEquilibriumContext &&) =
|
||||
delete;
|
||||
HydrostaticEquilibriumContext(HydrostaticEquilibriumContext &&) = delete;
|
||||
|
||||
HydrostaticEquilibriumContext &
|
||||
operator=(HydrostaticEquilibriumContext &&) = delete;
|
||||
HydrostaticEquilibriumContext &operator=(HydrostaticEquilibriumContext &&) = delete;
|
||||
|
||||
HydrostaticPreparationReport Prepare(
|
||||
const HydrostaticEquilibriumStateView &state,
|
||||
@@ -118,15 +107,11 @@ export namespace mean_field::operators::context::hydrostatic {
|
||||
|
||||
[[nodiscard]] bool IsPrepared() const noexcept;
|
||||
|
||||
[[nodiscard]] bool MatchesDependencies(
|
||||
const HydrostaticEquilibriumDependencies &dependencies
|
||||
) const noexcept;
|
||||
[[nodiscard]] bool MatchesDependencies(const HydrostaticEquilibriumDependencies &dependencies) const noexcept;
|
||||
|
||||
[[nodiscard]] const HydrostaticEquilibriumDependencies &
|
||||
GetDependencies() const;
|
||||
[[nodiscard]] const HydrostaticEquilibriumDependencies &GetDependencies() const;
|
||||
|
||||
[[nodiscard]] const HydrostaticPreparationStatistics &
|
||||
GetPreparationStatistics() const noexcept;
|
||||
[[nodiscard]] const HydrostaticPreparationStatistics &GetPreparationStatistics() const noexcept;
|
||||
|
||||
[[nodiscard]] const mfem::Vector &GetBaseEnthalpyTrue() const;
|
||||
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
module;
|
||||
|
||||
#include <compare>
|
||||
#include <cstdint>
|
||||
|
||||
#include <mfem.hpp>
|
||||
|
||||
export module mean_field:operators.context.pressure_force;
|
||||
|
||||
export import :fem;
|
||||
export import :field.mfem;
|
||||
export import :mapping.domain_mapper;
|
||||
|
||||
export namespace mean_field::operators::context::pressure_force {
|
||||
template <typename Tag> struct DependencyStamp final {
|
||||
std::uint64_t identity{0};
|
||||
std::uint64_t revision{0};
|
||||
|
||||
[[nodiscard]] constexpr bool CanFollow(const DependencyStamp &prepared) const noexcept {
|
||||
return identity != prepared.identity || revision >= prepared.revision;
|
||||
}
|
||||
|
||||
constexpr auto operator<=>(const DependencyStamp &) const = default;
|
||||
};
|
||||
|
||||
struct DiscretizationDependencyTag final { };
|
||||
struct EnthalpyDependencyTag final { };
|
||||
struct DisplacementDependencyTag final { };
|
||||
|
||||
using DiscretizationDependency = DependencyStamp<DiscretizationDependencyTag>;
|
||||
|
||||
using EnthalpyDependency = DependencyStamp<EnthalpyDependencyTag>;
|
||||
|
||||
using DisplacementDependency = DependencyStamp<DisplacementDependencyTag>;
|
||||
|
||||
struct PressureForceDependencies final {
|
||||
DiscretizationDependency discretization;
|
||||
EnthalpyDependency enthalpy;
|
||||
DisplacementDependency displacement;
|
||||
|
||||
constexpr auto operator<=>(const PressureForceDependencies &) const = default;
|
||||
};
|
||||
|
||||
/*
|
||||
* Frozen solver-facing state.
|
||||
*
|
||||
* Both vectors use their registered FieldDof coordinates.
|
||||
*
|
||||
* Under the current registry:
|
||||
*
|
||||
* enthalpy -> Stellar -> reduced
|
||||
* displacement -> All -> identity/full
|
||||
*/
|
||||
struct PressureForceStateView final {
|
||||
const mfem::Vector &enthalpy;
|
||||
const mfem::Vector &displacement;
|
||||
};
|
||||
|
||||
struct PressureForcePreparationReport final {
|
||||
bool preparedStaticDependencies{false};
|
||||
bool preparedGeometryState{false};
|
||||
bool preparedMaterialState{false};
|
||||
|
||||
bool updatedEnthalpy{false};
|
||||
bool updatedDisplacement{false};
|
||||
|
||||
[[nodiscard]] bool DidAnyWork() const noexcept {
|
||||
return preparedStaticDependencies || preparedGeometryState || preparedMaterialState;
|
||||
}
|
||||
};
|
||||
|
||||
struct PressureForcePreparationStatistics final {
|
||||
std::uint64_t staticPreparations{0};
|
||||
std::uint64_t geometryPreparations{0};
|
||||
std::uint64_t materialPreparations{0};
|
||||
|
||||
constexpr auto operator<=>(const PressureForcePreparationStatistics &) const = default;
|
||||
};
|
||||
|
||||
class PressureForceLinearizationContext final {
|
||||
public:
|
||||
PressureForceLinearizationContext(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const field::FieldDofMap &enthalpyMap,
|
||||
const field::FieldDofMap &displacementMap
|
||||
);
|
||||
|
||||
PressureForceLinearizationContext(const PressureForceLinearizationContext &) = delete;
|
||||
|
||||
PressureForceLinearizationContext &operator=(const PressureForceLinearizationContext &) = delete;
|
||||
|
||||
PressureForceLinearizationContext(PressureForceLinearizationContext &&) = delete;
|
||||
|
||||
PressureForceLinearizationContext &operator=(PressureForceLinearizationContext &&) = delete;
|
||||
|
||||
PressureForcePreparationReport Prepare(
|
||||
const PressureForceStateView &state,
|
||||
const PressureForceDependencies &dependencies
|
||||
);
|
||||
|
||||
[[nodiscard]] bool IsPrepared() const noexcept;
|
||||
|
||||
[[nodiscard]] bool MatchesDependencies(const PressureForceDependencies &dependencies) const noexcept;
|
||||
|
||||
[[nodiscard]] const PressureForceDependencies &GetDependencies() const;
|
||||
|
||||
[[nodiscard]] const PressureForcePreparationStatistics &GetPreparationStatistics() const noexcept;
|
||||
|
||||
[[nodiscard]] const mfem::Vector &GetBaseEnthalpy() const;
|
||||
|
||||
[[nodiscard]] const mfem::Vector &GetDisplacement() const;
|
||||
|
||||
private:
|
||||
void VerifyPrepared() const;
|
||||
|
||||
int m_enthalpySize{0};
|
||||
int m_displacementSize{0};
|
||||
|
||||
mfem::Vector m_baseEnthalpy;
|
||||
mfem::Vector m_displacement;
|
||||
|
||||
PressureForcePreparationStatistics m_statistics;
|
||||
PressureForceDependencies m_dependencies;
|
||||
|
||||
bool m_isPrepared{false};
|
||||
};
|
||||
} // namespace mean_field::operators::context::pressure_force
|
||||
@@ -0,0 +1,124 @@
|
||||
module;
|
||||
|
||||
#include <compare>
|
||||
#include <cstdint>
|
||||
|
||||
#include <mfem.hpp>
|
||||
|
||||
export module mean_field:operators.context.rotational_displacement_force;
|
||||
|
||||
export import :fem;
|
||||
export import :mapping.domain_mapper;
|
||||
|
||||
export namespace mean_field::operators::context::rotational_displacement_force {
|
||||
template <typename Tag> struct DependencyStamp final {
|
||||
std::uint64_t identity{0};
|
||||
std::uint64_t revision{0};
|
||||
|
||||
[[nodiscard]] constexpr bool CanFollow(const DependencyStamp &prepared) const noexcept {
|
||||
return identity != prepared.identity || revision >= prepared.revision;
|
||||
}
|
||||
|
||||
constexpr auto operator<=>(const DependencyStamp &) const = default;
|
||||
};
|
||||
|
||||
struct DiscretizationDependencyTag final { };
|
||||
struct DensityDependencyTag final { };
|
||||
struct DisplacementDependencyTag final { };
|
||||
struct RotationDependencyTag final { };
|
||||
|
||||
using DiscretizationDependency = DependencyStamp<DiscretizationDependencyTag>;
|
||||
|
||||
using DensityDependency = DependencyStamp<DensityDependencyTag>;
|
||||
|
||||
using DisplacementDependency = DependencyStamp<DisplacementDependencyTag>;
|
||||
|
||||
using RotationDependency = DependencyStamp<RotationDependencyTag>;
|
||||
|
||||
struct RotationalDisplacementForceDependencies final {
|
||||
DiscretizationDependency discretization;
|
||||
DensityDependency density;
|
||||
DisplacementDependency displacement;
|
||||
RotationDependency rotation;
|
||||
|
||||
constexpr auto operator<=>(const RotationalDisplacementForceDependencies &) const = default;
|
||||
};
|
||||
|
||||
struct RotationalDisplacementForceStateView final {
|
||||
const mfem::Vector &density;
|
||||
const mfem::Vector &displacement;
|
||||
};
|
||||
|
||||
struct RotationalDisplacementForcePreparationReport final {
|
||||
bool preparedStaticDependencies{false};
|
||||
bool preparedGeometryState{false};
|
||||
bool preparedRotationDependencies{false};
|
||||
bool preparedBaseState{false};
|
||||
|
||||
bool updatedDensity{false};
|
||||
bool updatedDisplacement{false};
|
||||
|
||||
[[nodiscard]] bool DidAnyWork() const noexcept {
|
||||
return preparedStaticDependencies || preparedGeometryState || preparedRotationDependencies ||
|
||||
preparedBaseState;
|
||||
}
|
||||
};
|
||||
|
||||
struct RotationalDisplacementForcePreparationStatistics final {
|
||||
std::uint64_t staticPreparations{0};
|
||||
std::uint64_t geometryPreparations{0};
|
||||
std::uint64_t rotationPreparations{0};
|
||||
std::uint64_t baseStatePreparations{0};
|
||||
|
||||
constexpr auto operator<=>(const RotationalDisplacementForcePreparationStatistics &) const = default;
|
||||
};
|
||||
|
||||
class RotationalDisplacementForceLinearizationContext final {
|
||||
public:
|
||||
RotationalDisplacementForceLinearizationContext(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper
|
||||
);
|
||||
|
||||
RotationalDisplacementForceLinearizationContext(const RotationalDisplacementForceLinearizationContext &) =
|
||||
delete;
|
||||
|
||||
RotationalDisplacementForceLinearizationContext &
|
||||
operator=(const RotationalDisplacementForceLinearizationContext &) = delete;
|
||||
|
||||
RotationalDisplacementForceLinearizationContext(RotationalDisplacementForceLinearizationContext &&) = delete;
|
||||
|
||||
RotationalDisplacementForceLinearizationContext &
|
||||
operator=(RotationalDisplacementForceLinearizationContext &&) = delete;
|
||||
|
||||
RotationalDisplacementForcePreparationReport Prepare(
|
||||
const RotationalDisplacementForceStateView &state,
|
||||
const RotationalDisplacementForceDependencies &dependencies
|
||||
);
|
||||
|
||||
[[nodiscard]] bool IsPrepared() const noexcept;
|
||||
|
||||
[[nodiscard]] bool
|
||||
MatchesDependencies(const RotationalDisplacementForceDependencies &dependencies) const noexcept;
|
||||
|
||||
[[nodiscard]] const RotationalDisplacementForceDependencies &GetDependencies() const;
|
||||
|
||||
[[nodiscard]] const RotationalDisplacementForcePreparationStatistics &GetPreparationStatistics() const noexcept;
|
||||
|
||||
[[nodiscard]] const mfem::Vector &GetBaseDensityTrue() const;
|
||||
|
||||
[[nodiscard]] const mfem::Vector &GetDisplacementTrue() const;
|
||||
|
||||
private:
|
||||
void VerifyPrepared() const;
|
||||
|
||||
const fem::FEM &m_f;
|
||||
|
||||
mfem::Vector m_baseDensityTrue;
|
||||
mfem::Vector m_displacementTrue;
|
||||
|
||||
RotationalDisplacementForceDependencies m_dependencies;
|
||||
RotationalDisplacementForcePreparationStatistics m_statistics;
|
||||
bool m_isPrepared{false};
|
||||
};
|
||||
} // namespace mean_field::operators::context::rotational_displacement_force
|
||||
@@ -10,27 +10,20 @@ export import :operators.gravity_field_jacobian;
|
||||
export import :operators.context.gravity_field;
|
||||
|
||||
export namespace mean_field::operators {
|
||||
enum class GravityResidualBlock : std::uint8_t {
|
||||
gradient_equation = 0,
|
||||
poisson_equation = 1,
|
||||
count = 2
|
||||
};
|
||||
enum class GravityResidualBlock : std::uint8_t { gradient_equation = 0, poisson_equation = 1, count = 2 };
|
||||
|
||||
constexpr int
|
||||
gravity_residual_block_index(const GravityResidualBlock block) noexcept {
|
||||
constexpr int gravity_residual_block_index(const GravityResidualBlock block) noexcept {
|
||||
return static_cast<int>(block);
|
||||
}
|
||||
|
||||
inline constexpr int gravity_residual_block_count =
|
||||
gravity_residual_block_index(GravityResidualBlock::count);
|
||||
inline constexpr int gravity_residual_block_count = gravity_residual_block_index(GravityResidualBlock::count);
|
||||
|
||||
class GravityFieldOperator final : public mfem::Operator {
|
||||
public:
|
||||
GravityFieldOperator(
|
||||
fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domain_mapper,
|
||||
context::gravity_field::GravityFieldLinearizationContext
|
||||
&linearization_context,
|
||||
context::gravity_field::GravityFieldLinearizationContext &linearization_context,
|
||||
const mfem::Array<int> &state_true_offsets,
|
||||
GravityFieldJacobianOperator &jacobian
|
||||
);
|
||||
@@ -47,39 +40,32 @@ export namespace mean_field::operators {
|
||||
|
||||
Operator &GetGradient(const mfem::Vector &state) const override;
|
||||
|
||||
[[nodiscard]] const mfem::Array<int> &
|
||||
GetStateTrueOffsets() const noexcept;
|
||||
[[nodiscard]] const mfem::Array<int> &GetStateTrueOffsets() const noexcept;
|
||||
|
||||
[[nodiscard]] const mfem::Array<int> &
|
||||
GetResidualTrueOffsets() const noexcept;
|
||||
[[nodiscard]] const mfem::Array<int> &GetResidualTrueOffsets() const noexcept;
|
||||
|
||||
[[nodiscard]] context::gravity_field::GravityFieldLinearizationContext &
|
||||
GetLinearizationContext() noexcept;
|
||||
[[nodiscard]] context::gravity_field::GravityFieldLinearizationContext &GetLinearizationContext() noexcept;
|
||||
|
||||
[[nodiscard]] const context::gravity_field::
|
||||
GravityFieldLinearizationContext &
|
||||
GetLinearizationContext() const noexcept;
|
||||
[[nodiscard]] const context::gravity_field::GravityFieldLinearizationContext &
|
||||
GetLinearizationContext() const noexcept;
|
||||
|
||||
void ApplyGravityUnknowns(
|
||||
const mfem::Vector &gravity_gradient,
|
||||
const mfem::Vector &gravity_potential,
|
||||
const context::gravity_field::GravityFieldGeometryContext
|
||||
&geometry_context,
|
||||
const context::gravity_field::GravityFieldGeometryContext &geometry_context,
|
||||
mfem::Vector &action
|
||||
) const;
|
||||
|
||||
void ApplyDensitySource(
|
||||
const mfem::Vector &density,
|
||||
const context::gravity_field::GravityFieldGeometryContext
|
||||
&geometry_context,
|
||||
const context::gravity_field::GravityFieldGeometryContext &geometry_context,
|
||||
mfem::Vector &action
|
||||
) const;
|
||||
|
||||
private:
|
||||
fem::FEM &m_fem;
|
||||
const mapping::DomainMapperStateless &m_domain_mapper;
|
||||
context::gravity_field::GravityFieldLinearizationContext
|
||||
&m_linearization_context;
|
||||
context::gravity_field::GravityFieldLinearizationContext &m_linearization_context;
|
||||
mfem::Array<int> m_state_true_offsets;
|
||||
mfem::Array<int> m_residual_true_offsets;
|
||||
GravityFieldJacobianOperator &m_jacobian;
|
||||
@@ -89,18 +75,14 @@ export namespace mean_field::operators {
|
||||
public:
|
||||
ReducedGravityFieldOperator(
|
||||
GravityFieldOperator &gravity_field_operator,
|
||||
context::gravity_field::GravityFieldGeometryContext
|
||||
&gravity_field_geometry_context,
|
||||
context::gravity_field::GravityFieldGeometryContext &gravity_field_geometry_context,
|
||||
const mfem::Vector &displacement
|
||||
);
|
||||
|
||||
ReducedGravityFieldOperator(const ReducedGravityFieldOperator &) =
|
||||
delete;
|
||||
ReducedGravityFieldOperator &
|
||||
operator=(const ReducedGravityFieldOperator &) = delete;
|
||||
ReducedGravityFieldOperator(ReducedGravityFieldOperator &&) = delete;
|
||||
ReducedGravityFieldOperator &
|
||||
operator=(ReducedGravityFieldOperator &&) = delete;
|
||||
ReducedGravityFieldOperator(const ReducedGravityFieldOperator &) = delete;
|
||||
ReducedGravityFieldOperator &operator=(const ReducedGravityFieldOperator &) = delete;
|
||||
ReducedGravityFieldOperator(ReducedGravityFieldOperator &&) = delete;
|
||||
ReducedGravityFieldOperator &operator=(ReducedGravityFieldOperator &&) = delete;
|
||||
|
||||
void SetDisplacement(const mfem::Vector &displacement);
|
||||
|
||||
@@ -118,18 +100,13 @@ export namespace mean_field::operators {
|
||||
|
||||
[[nodiscard]] GravityFieldOperator &GetGravityFieldOperator() noexcept;
|
||||
|
||||
[[nodiscard]] const GravityFieldOperator &
|
||||
GetGravityFieldOperator() const noexcept;
|
||||
[[nodiscard]] const GravityFieldOperator &GetGravityFieldOperator() const noexcept;
|
||||
|
||||
[[nodiscard]] context::gravity_field::GravityFieldGeometryContext &
|
||||
GetGeometryContext() noexcept;
|
||||
[[nodiscard]] context::gravity_field::GravityFieldGeometryContext &GetGeometryContext() noexcept;
|
||||
|
||||
[[nodiscard]] const context::gravity_field::
|
||||
GravityFieldGeometryContext &
|
||||
GetGeometryContext() const noexcept;
|
||||
[[nodiscard]] const context::gravity_field::GravityFieldGeometryContext &GetGeometryContext() const noexcept;
|
||||
|
||||
[[nodiscard]] const mfem::Array<int> &
|
||||
GetGravityTrueOffsets() const noexcept;
|
||||
[[nodiscard]] const mfem::Array<int> &GetGravityTrueOffsets() const noexcept;
|
||||
|
||||
private:
|
||||
void ValidateDisplacement(const mfem::Vector &displacement) const;
|
||||
@@ -141,7 +118,6 @@ export namespace mean_field::operators {
|
||||
private:
|
||||
GravityFieldOperator &m_gravity_field_operator;
|
||||
mfem::Array<int> m_gravity_true_offsets;
|
||||
context::gravity_field::GravityFieldGeometryContext
|
||||
&m_gravity_field_geometry_context;
|
||||
context::gravity_field::GravityFieldGeometryContext &m_gravity_field_geometry_context;
|
||||
};
|
||||
} // namespace mean_field::operators
|
||||
@@ -12,8 +12,7 @@ export namespace mean_field::operators {
|
||||
GravityFieldJacobianOperator(
|
||||
fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domain_mapper,
|
||||
const context::gravity_field::GravityFieldLinearizationContext
|
||||
&linearization_context,
|
||||
const context::gravity_field::GravityFieldLinearizationContext &linearization_context,
|
||||
const mfem::Array<int> &state_true_offsets,
|
||||
const mfem::Array<int> &residual_true_offsets
|
||||
);
|
||||
@@ -23,15 +22,13 @@ export namespace mean_field::operators {
|
||||
mfem::Vector &action
|
||||
) const override;
|
||||
|
||||
[[nodiscard]] const context::gravity_field::
|
||||
GravityFieldLinearizationContext &
|
||||
GetLinearizationContext() const noexcept;
|
||||
[[nodiscard]] const context::gravity_field::GravityFieldLinearizationContext &
|
||||
GetLinearizationContext() const noexcept;
|
||||
|
||||
private:
|
||||
fem::FEM &m_fem;
|
||||
const mapping::DomainMapperStateless &m_domain_mapper;
|
||||
const context::gravity_field::GravityFieldLinearizationContext
|
||||
&m_linearization_context;
|
||||
const context::gravity_field::GravityFieldLinearizationContext &m_linearization_context;
|
||||
mfem::Array<int> m_state_true_offsets;
|
||||
mfem::Array<int> m_residual_true_offsets;
|
||||
};
|
||||
|
||||
@@ -4,15 +4,26 @@ module;
|
||||
|
||||
export module mean_field:operators.kernels.barotropic_closure;
|
||||
|
||||
export import :eos.polytrope;
|
||||
export import :fem;
|
||||
export import :mapping.domain_mapper;
|
||||
export import :physics.barotrope;
|
||||
|
||||
export namespace mean_field::operators::kernels {
|
||||
/*
|
||||
* Stateless full-MFEM reference kernels for
|
||||
*
|
||||
* R_rho = \int_{Omega_star} (rho - rho_EOS(h)) q_rho dV.
|
||||
*
|
||||
* These functions intentionally remain expressed in complete MFEM true
|
||||
* vectors. Solver/prepared-facing support reduction belongs to
|
||||
* PreparedBarotropicClosureOperator through FieldDofMap. Keeping this
|
||||
* layer full-space preserves an independent reference implementation for
|
||||
* R K P tests of the reduced prepared operator.
|
||||
*/
|
||||
void apply_barotropic_closure(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const physics::PolytropicBarotrope &barotrope,
|
||||
const eos::Polytrope &equationOfState,
|
||||
const mfem::Vector &densityTrue,
|
||||
const mfem::Vector &enthalpyTrue,
|
||||
const mfem::Vector &displacementTrue,
|
||||
@@ -22,7 +33,7 @@ export namespace mean_field::operators::kernels {
|
||||
void apply_barotropic_closure_density_action(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const physics::PolytropicBarotrope &barotrope,
|
||||
const eos::Polytrope &equationOfState,
|
||||
const mfem::Vector &densityVariationTrue,
|
||||
const mfem::Vector &displacementTrue,
|
||||
mfem::Vector &action
|
||||
@@ -31,7 +42,7 @@ export namespace mean_field::operators::kernels {
|
||||
void apply_barotropic_closure_enthalpy_action(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const physics::PolytropicBarotrope &barotrope,
|
||||
const eos::Polytrope &equationOfState,
|
||||
const mfem::Vector &baseEnthalpyTrue,
|
||||
const mfem::Vector &enthalpyVariationTrue,
|
||||
const mfem::Vector &displacementTrue,
|
||||
@@ -41,11 +52,11 @@ export namespace mean_field::operators::kernels {
|
||||
void apply_barotropic_closure_displacement_action(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const physics::PolytropicBarotrope &barotrope,
|
||||
const eos::Polytrope &equationOfState,
|
||||
const mfem::Vector &baseDensityTrue,
|
||||
const mfem::Vector &baseEnthalpyTrue,
|
||||
const mfem::Vector &displacementTrue,
|
||||
const mfem::Vector &displacementVariationTrue,
|
||||
mfem::Vector &action
|
||||
);
|
||||
} // namespace mean_field::operators::kernels
|
||||
} // namespace mean_field::operators::kernels
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
module;
|
||||
|
||||
#include <mfem.hpp>
|
||||
|
||||
export module mean_field:operators.kernels.gravity_displacement_force;
|
||||
|
||||
export import :fem;
|
||||
export import :mapping.domain_mapper;
|
||||
|
||||
export namespace mean_field::operators::kernels {
|
||||
void apply_gravity_displacement_force_residual(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const mfem::Vector &densityTrue,
|
||||
const mfem::Vector &gravityGradientTrue,
|
||||
const mfem::Vector &displacementTrue,
|
||||
mfem::Vector &residualTrue
|
||||
);
|
||||
|
||||
void apply_gravity_displacement_force_density_action(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const mfem::Vector &densityVariationTrue,
|
||||
const mfem::Vector &baseGravityGradientTrue,
|
||||
const mfem::Vector &displacementTrue,
|
||||
mfem::Vector &actionTrue
|
||||
);
|
||||
|
||||
void apply_gravity_displacement_force_gradient_action(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const mfem::Vector &baseDensityTrue,
|
||||
const mfem::Vector &gravityGradientVariationTrue,
|
||||
const mfem::Vector &displacementTrue,
|
||||
mfem::Vector &actionTrue
|
||||
);
|
||||
|
||||
void apply_gravity_displacement_force_displacement_action(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const mfem::Vector &baseDensityTrue,
|
||||
const mfem::Vector &baseGravityGradientTrue,
|
||||
const mfem::Vector &displacementVariationTrue,
|
||||
const mfem::Vector &displacementTrue,
|
||||
mfem::Vector &actionTrue
|
||||
);
|
||||
|
||||
void apply_gravity_displacement_force_complete_action(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const mfem::Vector &baseDensityTrue,
|
||||
const mfem::Vector &densityVariationTrue,
|
||||
const mfem::Vector &baseGravityGradientTrue,
|
||||
const mfem::Vector &gravityGradientVariationTrue,
|
||||
const mfem::Vector &displacementVariationTrue,
|
||||
const mfem::Vector &displacementTrue,
|
||||
mfem::Vector &actionTrue
|
||||
);
|
||||
} // namespace mean_field::operators::kernels
|
||||
@@ -6,15 +6,35 @@ export module mean_field:operators.kernels.pressure_force;
|
||||
|
||||
export import :fem;
|
||||
export import :mapping.domain_mapper;
|
||||
export import :physics.barotrope;
|
||||
export import :eos.polytrope;
|
||||
|
||||
export namespace mean_field::operators::kernels {
|
||||
void apply_pressure_force_residual(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const physics::PolytropicBarotrope &barotrope,
|
||||
const eos::Polytrope &barotrope,
|
||||
const mfem::Vector &enthalpyTrue,
|
||||
const mfem::Vector &displacementTrue,
|
||||
mfem::Vector &residualTrue
|
||||
);
|
||||
|
||||
void apply_pressure_force_enthalpy_action(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const eos::Polytrope &barotrope,
|
||||
const mfem::Vector &baseEnthalpyTrue,
|
||||
const mfem::Vector &enthalpyVariationTrue,
|
||||
const mfem::Vector &displacementTrue,
|
||||
mfem::Vector &actionTrue
|
||||
);
|
||||
|
||||
void apply_pressure_force_displacement_action(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const eos::Polytrope &barotrope,
|
||||
const mfem::Vector &baseEnthalpyTrue,
|
||||
const mfem::Vector &displacementVariationTrue,
|
||||
const mfem::Vector &displacementTrue,
|
||||
mfem::Vector &actionTrue
|
||||
);
|
||||
} // namespace mean_field::operators::kernels
|
||||
@@ -0,0 +1,64 @@
|
||||
module;
|
||||
|
||||
#include <mfem.hpp>
|
||||
|
||||
export module mean_field:operators.kernels.rotational_displacement_force;
|
||||
|
||||
export import :fem;
|
||||
export import :mapping.domain_mapper;
|
||||
export import :physics.rigid_rotation;
|
||||
|
||||
export namespace mean_field::operators::kernels {
|
||||
/*
|
||||
* Rotational contribution to the displacement row:
|
||||
*
|
||||
* R_d^rotation(w)
|
||||
* = -int_{Omega_star} rho grad(Psi_rotation) . w dV
|
||||
* = int_{Omega_star}
|
||||
* rho [Omega x (Omega x (x - x_0))] . w dV.
|
||||
*
|
||||
* RigidRotation stores the positive potential
|
||||
*
|
||||
* Psi_rotation = 0.5 |Omega x (x - x_0)|^2.
|
||||
*
|
||||
* Vacuum elements are excluded exactly.
|
||||
*/
|
||||
void apply_rotational_displacement_force_residual(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const physics::RigidRotation &rotation,
|
||||
const mfem::Vector &densityTrue,
|
||||
const mfem::Vector &displacementTrue,
|
||||
mfem::Vector &residualTrue
|
||||
);
|
||||
|
||||
void apply_rotational_displacement_force_density_action(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const physics::RigidRotation &rotation,
|
||||
const mfem::Vector &densityVariationTrue,
|
||||
const mfem::Vector &displacementTrue,
|
||||
mfem::Vector &actionTrue
|
||||
);
|
||||
|
||||
void apply_rotational_displacement_force_displacement_action(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const physics::RigidRotation &rotation,
|
||||
const mfem::Vector &baseDensityTrue,
|
||||
const mfem::Vector &displacementVariationTrue,
|
||||
const mfem::Vector &displacementTrue,
|
||||
mfem::Vector &actionTrue
|
||||
);
|
||||
|
||||
void apply_rotational_displacement_force_complete_action(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const physics::RigidRotation &rotation,
|
||||
const mfem::Vector &baseDensityTrue,
|
||||
const mfem::Vector &densityVariationTrue,
|
||||
const mfem::Vector &displacementVariationTrue,
|
||||
const mfem::Vector &displacementTrue,
|
||||
mfem::Vector &actionTrue
|
||||
);
|
||||
} // namespace mean_field::operators::kernels
|
||||
@@ -6,29 +6,44 @@ module;
|
||||
|
||||
export module mean_field:operators.prepared_barotropic_closure;
|
||||
|
||||
export import :eos.polytrope;
|
||||
export import :fem;
|
||||
export import :field.mfem;
|
||||
export import :mapping.domain_mapper;
|
||||
export import :physics.barotrope;
|
||||
export import :operators.context.barotropic_closure_linearization;
|
||||
|
||||
export namespace mean_field::operators {
|
||||
struct PreparedBarotropicClosureReport final {
|
||||
context::barotropic::BarotropicClosurePreparationReport contextReport;
|
||||
bool preparedElementData{false};
|
||||
|
||||
[[nodiscard]] bool DidAnyWork() const noexcept {
|
||||
return contextReport.DidAnyWork() || preparedElementData;
|
||||
}
|
||||
};
|
||||
|
||||
class PreparedBarotropicClosureOperator final : public mfem::Operator {
|
||||
public:
|
||||
PreparedBarotropicClosureOperator(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const physics::PolytropicBarotrope &barotrope
|
||||
const eos::Polytrope &equationOfState
|
||||
);
|
||||
|
||||
void Prepare(
|
||||
const mfem::Vector &baseDensityTrue,
|
||||
const mfem::Vector &baseEnthalpyTrue,
|
||||
const mfem::Vector &displacementTrue
|
||||
PreparedBarotropicClosureOperator(const PreparedBarotropicClosureOperator &) = delete;
|
||||
PreparedBarotropicClosureOperator &operator=(const PreparedBarotropicClosureOperator &) = delete;
|
||||
PreparedBarotropicClosureOperator(PreparedBarotropicClosureOperator &&) = delete;
|
||||
PreparedBarotropicClosureOperator &operator=(PreparedBarotropicClosureOperator &&) = delete;
|
||||
|
||||
PreparedBarotropicClosureReport Prepare(
|
||||
const context::barotropic::BarotropicClosureStateView &state,
|
||||
const context::barotropic::BarotropicClosureDependencies &dependencies
|
||||
);
|
||||
|
||||
void Mult(
|
||||
const mfem::Vector &densityVariationTrue,
|
||||
const mfem::Vector &enthalpyVariationTrue,
|
||||
const mfem::Vector &displacementVariationTrue,
|
||||
const mfem::Vector &densityVariation,
|
||||
const mfem::Vector &enthalpyVariation,
|
||||
const mfem::Vector &displacementVariation,
|
||||
mfem::Vector &action
|
||||
) const;
|
||||
|
||||
@@ -40,20 +55,33 @@ export namespace mean_field::operators {
|
||||
void BuildResidual(mfem::Vector &residual) const;
|
||||
|
||||
[[nodiscard]] bool IsPrepared() const noexcept;
|
||||
|
||||
[[nodiscard]] std::uint64_t GetPreparationCount() const noexcept;
|
||||
|
||||
[[nodiscard]] int GetDensitySize() const noexcept;
|
||||
|
||||
[[nodiscard]] int GetEnthalpySize() const noexcept;
|
||||
[[nodiscard]] int GetDisplacementSize() const noexcept;
|
||||
|
||||
[[nodiscard]] const context::barotropic::BarotropicClosureLinearizationContext &GetContext() const noexcept;
|
||||
[[nodiscard]] const context::barotropic::BarotropicClosurePreparationStatistics &
|
||||
GetContextPreparationStatistics() const noexcept;
|
||||
|
||||
private:
|
||||
struct ConstructionData;
|
||||
|
||||
[[nodiscard]] static ConstructionData MakeConstructionData(const fem::FEM &f);
|
||||
|
||||
PreparedBarotropicClosureOperator(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const eos::Polytrope &equationOfState,
|
||||
ConstructionData constructionData
|
||||
);
|
||||
|
||||
void VerifyPrepared() const;
|
||||
|
||||
void Mult(
|
||||
void ApplyThermodynamicActionFull(
|
||||
const mfem::Vector &densityVariationTrue,
|
||||
const mfem::Vector &enthalpyVariationTrue,
|
||||
mfem::Vector &action
|
||||
mfem::Vector &actionTrue
|
||||
) const;
|
||||
|
||||
struct ElementPAData {
|
||||
@@ -73,7 +101,13 @@ export namespace mean_field::operators {
|
||||
|
||||
const fem::FEM &m_fem;
|
||||
const mapping::DomainMapperStateless &m_domainMapper;
|
||||
const physics::PolytropicBarotrope &m_barotrope;
|
||||
const eos::Polytrope &m_equationOfState;
|
||||
|
||||
field::FieldDofMap m_densityMap;
|
||||
field::FieldDofMap m_enthalpyMap;
|
||||
field::FieldDofMap m_displacementMap;
|
||||
|
||||
context::barotropic::BarotropicClosureLinearizationContext m_context;
|
||||
|
||||
std::vector<ElementPAData> m_elements;
|
||||
|
||||
@@ -81,8 +115,12 @@ export namespace mean_field::operators {
|
||||
mfem::Vector m_baseEnthalpyTrue;
|
||||
mfem::Vector m_baseDisplacementTrue;
|
||||
|
||||
int m_densitySize{0};
|
||||
int m_enthalpySize{0};
|
||||
mutable mfem::Vector m_densityVariationTrue;
|
||||
mutable mfem::Vector m_enthalpyVariationTrue;
|
||||
mutable mfem::Vector m_displacementVariationTrue;
|
||||
mutable mfem::Vector m_fullThermodynamicAction;
|
||||
mutable mfem::Vector m_fullDisplacementAction;
|
||||
mutable mfem::Vector m_fullResidual;
|
||||
|
||||
std::uint64_t m_preparationCount{0};
|
||||
bool m_isPrepared{false};
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
module;
|
||||
|
||||
#include <compare>
|
||||
#include <cstdint>
|
||||
|
||||
#include <mfem.hpp>
|
||||
|
||||
export module mean_field:operators.prepared_displacement_residual;
|
||||
|
||||
export import :fem;
|
||||
export import :mapping.domain_mapper;
|
||||
export import :operators.context.gravity_field;
|
||||
export import :operators.prepared_gravity_displacement_force;
|
||||
export import :operators.prepared_pressure_force;
|
||||
export import :operators.prepared_rotational_displacement_force;
|
||||
export import :eos.polytrope;
|
||||
export import :physics.rigid_rotation;
|
||||
export import :utils.blocks;
|
||||
|
||||
export namespace mean_field::operators {
|
||||
struct DisplacementResidualDependencyStamp final {
|
||||
std::uint64_t identity{0};
|
||||
std::uint64_t revision{0};
|
||||
|
||||
constexpr auto operator<=>(const DisplacementResidualDependencyStamp &) const = default;
|
||||
};
|
||||
|
||||
struct DisplacementResidualDependencies final {
|
||||
DisplacementResidualDependencyStamp discretization;
|
||||
DisplacementResidualDependencyStamp density;
|
||||
DisplacementResidualDependencyStamp displacement;
|
||||
DisplacementResidualDependencyStamp gravityGradient;
|
||||
DisplacementResidualDependencyStamp enthalpy;
|
||||
DisplacementResidualDependencyStamp rotation;
|
||||
|
||||
constexpr auto operator<=>(const DisplacementResidualDependencies &) const = default;
|
||||
};
|
||||
|
||||
/*
|
||||
* Density, displacement, and gravity gradient deliberately do not appear
|
||||
* here. They are obtained from the shared, already-prepared gravity-field
|
||||
* linearization context so every mechanical-force contribution consumes
|
||||
* the same frozen density and geometry as the gravity equations.
|
||||
*/
|
||||
struct DisplacementResidualStateView final {
|
||||
const mfem::Vector &enthalpy;
|
||||
};
|
||||
|
||||
struct PreparedDisplacementResidualReport final {
|
||||
PreparedPressureForceReport pressure;
|
||||
PreparedGravityDisplacementForceReport gravity;
|
||||
PreparedRotationalDisplacementForceReport rotation;
|
||||
|
||||
bool assembledResidual{false};
|
||||
|
||||
[[nodiscard]] bool DidAnyChildWork() const noexcept {
|
||||
return pressure.DidAnyWork() || gravity.DidAnyWork() || rotation.DidAnyWork();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool DidAnyWork() const noexcept {
|
||||
return DidAnyChildWork() || assembledResidual;
|
||||
}
|
||||
};
|
||||
|
||||
struct PreparedDisplacementResidualActionStatistics final {
|
||||
std::uint64_t densityApplications{0};
|
||||
std::uint64_t displacementApplications{0};
|
||||
std::uint64_t gravityGradientApplications{0};
|
||||
std::uint64_t enthalpyApplications{0};
|
||||
std::uint64_t completeApplications{0};
|
||||
|
||||
constexpr auto operator<=>(const PreparedDisplacementResidualActionStatistics &) const = default;
|
||||
};
|
||||
|
||||
/*
|
||||
* Row-level composer for
|
||||
*
|
||||
* R_d = R_d^pressure + R_d^gravity + R_d^rotation.
|
||||
*
|
||||
* This class owns the three prepared contributors and only orchestrates
|
||||
* their existing residual and Jacobian APIs. It contains no force kernel
|
||||
* and no independent copy of the gravity linearization context.
|
||||
*/
|
||||
class PreparedDisplacementResidualOperator final {
|
||||
public:
|
||||
PreparedDisplacementResidualOperator(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const eos::Polytrope &barotrope,
|
||||
const context::gravity_field::GravityFieldLinearizationContext &gravityContext
|
||||
);
|
||||
|
||||
PreparedDisplacementResidualOperator(const PreparedDisplacementResidualOperator &) = delete;
|
||||
|
||||
PreparedDisplacementResidualOperator &operator=(const PreparedDisplacementResidualOperator &) = delete;
|
||||
|
||||
PreparedDisplacementResidualOperator(PreparedDisplacementResidualOperator &&) = delete;
|
||||
|
||||
PreparedDisplacementResidualOperator &operator=(PreparedDisplacementResidualOperator &&) = delete;
|
||||
|
||||
PreparedDisplacementResidualReport Prepare(
|
||||
const DisplacementResidualStateView &state,
|
||||
const DisplacementResidualDependencies &dependencies,
|
||||
const physics::RigidRotation &rotation
|
||||
);
|
||||
|
||||
void BuildResidual(mfem::Vector &residual) const;
|
||||
|
||||
void ApplyDensityJacobianAction(
|
||||
const mfem::Vector &densityVariation,
|
||||
mfem::Vector &action
|
||||
) const;
|
||||
|
||||
void ApplyDisplacementJacobianAction(
|
||||
const mfem::Vector &displacementVariation,
|
||||
mfem::Vector &action
|
||||
) const;
|
||||
|
||||
void ApplyGravityGradientJacobianAction(
|
||||
const mfem::Vector &gravityGradientVariation,
|
||||
mfem::Vector &action
|
||||
) const;
|
||||
|
||||
void ApplyEnthalpyJacobianAction(
|
||||
const mfem::Vector &enthalpyVariation,
|
||||
mfem::Vector &action
|
||||
) const;
|
||||
|
||||
void ApplyCompleteJacobianAction(
|
||||
const mfem::Vector &densityVariation,
|
||||
const mfem::Vector &displacementVariation,
|
||||
const mfem::Vector &gravityGradientVariation,
|
||||
const mfem::Vector &enthalpyVariation,
|
||||
mfem::Vector &action
|
||||
) const;
|
||||
|
||||
[[nodiscard]] bool IsPrepared() const noexcept;
|
||||
|
||||
[[nodiscard]] std::uint64_t GetResidualPreparationCount() const noexcept;
|
||||
|
||||
[[nodiscard]] std::uint64_t GetResidualApplicationCount() const noexcept;
|
||||
|
||||
[[nodiscard]] const PreparedDisplacementResidualActionStatistics &GetActionStatistics() const noexcept;
|
||||
|
||||
[[nodiscard]] const PreparedPressureForceOperator &GetPressureOperator() const noexcept;
|
||||
|
||||
[[nodiscard]] const PreparedGravityDisplacementForceOperator &GetGravityOperator() const noexcept;
|
||||
|
||||
[[nodiscard]] const PreparedRotationalDisplacementForceOperator &GetRotationalOperator() const noexcept;
|
||||
|
||||
[[nodiscard]] const fem::FEM &GetFEM() const noexcept;
|
||||
|
||||
[[nodiscard]] const context::gravity_field::GravityFieldLinearizationContext &
|
||||
GetGravityContext() const noexcept;
|
||||
|
||||
private:
|
||||
void AssembleResidual();
|
||||
void VerifyPrepared() const;
|
||||
|
||||
const fem::FEM &m_fem;
|
||||
const mapping::DomainMapperStateless &m_domainMapper;
|
||||
const context::gravity_field::GravityFieldLinearizationContext &m_gravityContext;
|
||||
|
||||
PreparedPressureForceOperator m_pressureOperator;
|
||||
PreparedGravityDisplacementForceOperator m_gravityOperator;
|
||||
PreparedRotationalDisplacementForceOperator m_rotationalOperator;
|
||||
|
||||
DisplacementResidualDependencies m_preparedDependencies;
|
||||
mfem::Vector m_cachedResidual;
|
||||
|
||||
std::uint64_t m_residualPreparationCount{0};
|
||||
mutable std::uint64_t m_residualApplicationCount{0};
|
||||
mutable PreparedDisplacementResidualActionStatistics m_actionStatistics;
|
||||
|
||||
bool m_isPrepared{false};
|
||||
};
|
||||
|
||||
using DisplacementResidualLayout = utils::blocks::form_layout<utils::blocks::barotropic_equilibrium_form>;
|
||||
|
||||
class PreparedDisplacementResidualJacobianOperator final : public mfem::Operator {
|
||||
public:
|
||||
PreparedDisplacementResidualJacobianOperator(
|
||||
const DisplacementResidualLayout &layout,
|
||||
const PreparedDisplacementResidualOperator &preparedOperator
|
||||
);
|
||||
|
||||
void Mult(
|
||||
const mfem::Vector &direction,
|
||||
mfem::Vector &action
|
||||
) const override;
|
||||
|
||||
[[nodiscard]] const DisplacementResidualLayout &GetLayout() const noexcept;
|
||||
|
||||
private:
|
||||
DisplacementResidualLayout m_layout;
|
||||
const PreparedDisplacementResidualOperator &m_preparedOperator;
|
||||
};
|
||||
} // namespace mean_field::operators
|
||||
@@ -0,0 +1,150 @@
|
||||
module;
|
||||
|
||||
#include <compare>
|
||||
#include <cstdint>
|
||||
|
||||
#include <mfem.hpp>
|
||||
|
||||
export module mean_field:operators.prepared_gravity_displacement_force;
|
||||
|
||||
export import :fem;
|
||||
export import :mapping.domain_mapper;
|
||||
export import :operators.context.gravity_field;
|
||||
export import :utils.blocks;
|
||||
|
||||
export namespace mean_field::operators {
|
||||
struct PreparedGravityDisplacementForceReport final {
|
||||
bool preparedResidual{false};
|
||||
|
||||
[[nodiscard]] bool DidAnyWork() const noexcept {
|
||||
return preparedResidual;
|
||||
}
|
||||
};
|
||||
|
||||
struct PreparedGravityDisplacementForceColumnStatistics final {
|
||||
std::uint64_t applications{0};
|
||||
|
||||
constexpr auto operator<=>(const PreparedGravityDisplacementForceColumnStatistics &) const = default;
|
||||
};
|
||||
|
||||
struct PreparedGravityDisplacementForceCompleteStatistics final {
|
||||
std::uint64_t applications{0};
|
||||
|
||||
constexpr auto operator<=>(const PreparedGravityDisplacementForceCompleteStatistics &) const = default;
|
||||
};
|
||||
|
||||
class PreparedGravityDisplacementForceOperator final {
|
||||
public:
|
||||
PreparedGravityDisplacementForceOperator(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const context::gravity_field::GravityFieldLinearizationContext &gravityContext
|
||||
);
|
||||
|
||||
PreparedGravityDisplacementForceOperator(const PreparedGravityDisplacementForceOperator &) = delete;
|
||||
|
||||
PreparedGravityDisplacementForceOperator &operator=(const PreparedGravityDisplacementForceOperator &) = delete;
|
||||
|
||||
PreparedGravityDisplacementForceOperator(PreparedGravityDisplacementForceOperator &&) = delete;
|
||||
|
||||
PreparedGravityDisplacementForceOperator &operator=(PreparedGravityDisplacementForceOperator &&) = delete;
|
||||
|
||||
/*
|
||||
* Freeze the already-prepared shared gravity context. The caller must
|
||||
* first prepare GravityFieldLinearizationContext for the desired
|
||||
* state. Repeated calls with unchanged revisions do no work.
|
||||
*/
|
||||
PreparedGravityDisplacementForceReport Prepare();
|
||||
|
||||
void BuildResidual(mfem::Vector &residual) const;
|
||||
|
||||
void ApplyDensityJacobianAction(
|
||||
const mfem::Vector &densityVariation,
|
||||
mfem::Vector &action
|
||||
) const;
|
||||
|
||||
void ApplyGravityGradientJacobianAction(
|
||||
const mfem::Vector &gravityGradientVariation,
|
||||
mfem::Vector &action
|
||||
) const;
|
||||
|
||||
void ApplyDisplacementJacobianAction(
|
||||
const mfem::Vector &displacementVariation,
|
||||
mfem::Vector &action
|
||||
) const;
|
||||
|
||||
void ApplyCompleteJacobianAction(
|
||||
const mfem::Vector &densityVariation,
|
||||
const mfem::Vector &displacementVariation,
|
||||
const mfem::Vector &gravityGradientVariation,
|
||||
mfem::Vector &action
|
||||
) const;
|
||||
|
||||
[[nodiscard]] bool IsPrepared() const noexcept;
|
||||
|
||||
[[nodiscard]] std::uint64_t GetResidualPreparationCount() const noexcept;
|
||||
|
||||
[[nodiscard]] std::uint64_t GetResidualApplicationCount() const noexcept;
|
||||
|
||||
[[nodiscard]] const PreparedGravityDisplacementForceColumnStatistics &
|
||||
GetDensityJacobianStatistics() const noexcept;
|
||||
|
||||
[[nodiscard]] const PreparedGravityDisplacementForceColumnStatistics &
|
||||
GetGravityGradientJacobianStatistics() const noexcept;
|
||||
|
||||
[[nodiscard]] const PreparedGravityDisplacementForceColumnStatistics &
|
||||
GetDisplacementJacobianStatistics() const noexcept;
|
||||
|
||||
[[nodiscard]] const PreparedGravityDisplacementForceCompleteStatistics &
|
||||
GetCompleteJacobianStatistics() const noexcept;
|
||||
|
||||
[[nodiscard]] const fem::FEM &GetFEM() const noexcept;
|
||||
|
||||
[[nodiscard]] const context::gravity_field::GravityFieldLinearizationContext &
|
||||
GetGravityContext() const noexcept;
|
||||
|
||||
private:
|
||||
void VerifyPrepared() const;
|
||||
|
||||
const fem::FEM &m_fem;
|
||||
const mapping::DomainMapperStateless &m_domainMapper;
|
||||
const context::gravity_field::GravityFieldLinearizationContext &m_gravityContext;
|
||||
|
||||
context::gravity_field::GravityFieldRevisions m_preparedRevisions;
|
||||
mfem::Vector m_cachedResidual;
|
||||
|
||||
std::uint64_t m_residualPreparationCount{0};
|
||||
mutable std::uint64_t m_residualApplicationCount{0};
|
||||
|
||||
mutable PreparedGravityDisplacementForceColumnStatistics m_densityJacobianStatistics;
|
||||
|
||||
mutable PreparedGravityDisplacementForceColumnStatistics m_gravityGradientJacobianStatistics;
|
||||
|
||||
mutable PreparedGravityDisplacementForceColumnStatistics m_displacementJacobianStatistics;
|
||||
|
||||
mutable PreparedGravityDisplacementForceCompleteStatistics m_completeJacobianStatistics;
|
||||
|
||||
bool m_isPrepared{false};
|
||||
};
|
||||
|
||||
using GravityDisplacementForceLayout = utils::blocks::form_layout<utils::blocks::barotropic_equilibrium_form>;
|
||||
|
||||
class PreparedGravityDisplacementForceJacobianOperator final : public mfem::Operator {
|
||||
public:
|
||||
PreparedGravityDisplacementForceJacobianOperator(
|
||||
const GravityDisplacementForceLayout &layout,
|
||||
const PreparedGravityDisplacementForceOperator &preparedOperator
|
||||
);
|
||||
|
||||
void Mult(
|
||||
const mfem::Vector &direction,
|
||||
mfem::Vector &action
|
||||
) const override;
|
||||
|
||||
[[nodiscard]] const GravityDisplacementForceLayout &GetLayout() const noexcept;
|
||||
|
||||
private:
|
||||
GravityDisplacementForceLayout m_layout;
|
||||
const PreparedGravityDisplacementForceOperator &m_preparedOperator;
|
||||
};
|
||||
} // namespace mean_field::operators
|
||||
@@ -25,8 +25,7 @@ export namespace mean_field::operators {
|
||||
bool preparedResidual{false};
|
||||
|
||||
[[nodiscard]] bool DidAnyWork() const noexcept {
|
||||
return contextReport.DidAnyWork() || updatedRotation ||
|
||||
preparedAlgebraicJacobianBlocks ||
|
||||
return contextReport.DidAnyWork() || updatedRotation || preparedAlgebraicJacobianBlocks ||
|
||||
preparedDisplacementJacobianData || preparedResidual;
|
||||
}
|
||||
};
|
||||
@@ -38,26 +37,20 @@ export namespace mean_field::operators {
|
||||
std::uint64_t bernoulliConstantApplications{0};
|
||||
std::uint64_t combinedApplications{0};
|
||||
|
||||
constexpr auto operator<=>(
|
||||
const PreparedHydrostaticAlgebraicJacobianStatistics &
|
||||
) const = default;
|
||||
constexpr auto operator<=>(const PreparedHydrostaticAlgebraicJacobianStatistics &) const = default;
|
||||
};
|
||||
|
||||
struct PreparedHydrostaticDisplacementJacobianStatistics {
|
||||
std::uint64_t preparations{0};
|
||||
std::uint64_t applications{0};
|
||||
|
||||
constexpr auto operator<=>(
|
||||
const PreparedHydrostaticDisplacementJacobianStatistics &
|
||||
) const = default;
|
||||
constexpr auto operator<=>(const PreparedHydrostaticDisplacementJacobianStatistics &) const = default;
|
||||
};
|
||||
|
||||
struct PreparedHydrostaticCompleteJacobianStatistics {
|
||||
std::uint64_t applications{0};
|
||||
|
||||
constexpr auto operator<=>(
|
||||
const PreparedHydrostaticCompleteJacobianStatistics &
|
||||
) const = default;
|
||||
constexpr auto operator<=>(const PreparedHydrostaticCompleteJacobianStatistics &) const = default;
|
||||
};
|
||||
|
||||
enum class HydrostaticJacobianInputBlock : int {
|
||||
@@ -94,24 +87,17 @@ export namespace mean_field::operators {
|
||||
const mapping::DomainMapperStateless &domainMapper
|
||||
);
|
||||
|
||||
PreparedHydrostaticEquilibriumOperator(
|
||||
const PreparedHydrostaticEquilibriumOperator &
|
||||
) = delete;
|
||||
PreparedHydrostaticEquilibriumOperator(const PreparedHydrostaticEquilibriumOperator &) = delete;
|
||||
|
||||
PreparedHydrostaticEquilibriumOperator &
|
||||
operator=(const PreparedHydrostaticEquilibriumOperator &) = delete;
|
||||
PreparedHydrostaticEquilibriumOperator &operator=(const PreparedHydrostaticEquilibriumOperator &) = delete;
|
||||
|
||||
PreparedHydrostaticEquilibriumOperator(
|
||||
PreparedHydrostaticEquilibriumOperator &&
|
||||
) = delete;
|
||||
PreparedHydrostaticEquilibriumOperator(PreparedHydrostaticEquilibriumOperator &&) = delete;
|
||||
|
||||
PreparedHydrostaticEquilibriumOperator &
|
||||
operator=(PreparedHydrostaticEquilibriumOperator &&) = delete;
|
||||
PreparedHydrostaticEquilibriumOperator &operator=(PreparedHydrostaticEquilibriumOperator &&) = delete;
|
||||
|
||||
PreparedHydrostaticEquilibriumReport Prepare(
|
||||
const context::hydrostatic::HydrostaticEquilibriumStateView &state,
|
||||
const context::hydrostatic::HydrostaticEquilibriumDependencies
|
||||
&dependencies,
|
||||
const context::hydrostatic::HydrostaticEquilibriumDependencies &dependencies,
|
||||
const physics::RigidRotation &rotation
|
||||
);
|
||||
|
||||
@@ -154,15 +140,12 @@ export namespace mean_field::operators {
|
||||
|
||||
[[nodiscard]] bool IsPrepared() const noexcept;
|
||||
|
||||
[[nodiscard]] const context::hydrostatic::
|
||||
HydrostaticPreparationStatistics &
|
||||
GetContextPreparationStatistics() const noexcept;
|
||||
[[nodiscard]] const context::hydrostatic::HydrostaticPreparationStatistics &
|
||||
GetContextPreparationStatistics() const noexcept;
|
||||
|
||||
[[nodiscard]] std::uint64_t
|
||||
GetResidualPreparationCount() const noexcept;
|
||||
[[nodiscard]] std::uint64_t GetResidualPreparationCount() const noexcept;
|
||||
|
||||
[[nodiscard]] std::uint64_t
|
||||
GetResidualApplicationCount() const noexcept;
|
||||
[[nodiscard]] std::uint64_t GetResidualApplicationCount() const noexcept;
|
||||
|
||||
[[nodiscard]] const PreparedHydrostaticAlgebraicJacobianStatistics &
|
||||
GetAlgebraicJacobianStatistics() const noexcept;
|
||||
@@ -203,11 +186,9 @@ export namespace mean_field::operators {
|
||||
mfem::Vector quadratureWeights;
|
||||
std::vector<mapping::VolumeMappingContext> baseMappingContexts;
|
||||
|
||||
std::optional<mapping::ElementDisplacementData>
|
||||
baseDisplacementData;
|
||||
std::optional<mapping::ElementDisplacementData> baseDisplacementData;
|
||||
|
||||
std::optional<mapping::ElementCompactificationData>
|
||||
compactificationData;
|
||||
std::optional<mapping::ElementCompactificationData> compactificationData;
|
||||
|
||||
mfem::Vector rotationPotential;
|
||||
mfem::DenseMatrix rotationGradient;
|
||||
@@ -242,20 +223,16 @@ export namespace mean_field::operators {
|
||||
|
||||
mutable std::uint64_t m_residualApplicationCount{0};
|
||||
|
||||
mutable PreparedHydrostaticAlgebraicJacobianStatistics
|
||||
m_algebraicJacobianStatistics;
|
||||
mutable PreparedHydrostaticAlgebraicJacobianStatistics m_algebraicJacobianStatistics;
|
||||
|
||||
mutable PreparedHydrostaticDisplacementJacobianStatistics
|
||||
m_displacementJacobianStatistics;
|
||||
mutable PreparedHydrostaticDisplacementJacobianStatistics m_displacementJacobianStatistics;
|
||||
|
||||
mutable PreparedHydrostaticCompleteJacobianStatistics
|
||||
m_completeJacobianStatistics;
|
||||
mutable PreparedHydrostaticCompleteJacobianStatistics m_completeJacobianStatistics;
|
||||
|
||||
bool m_isPrepared{false};
|
||||
};
|
||||
|
||||
class PreparedHydrostaticEquilibriumJacobianOperator final
|
||||
: public mfem::Operator {
|
||||
class PreparedHydrostaticEquilibriumJacobianOperator final : public mfem::Operator {
|
||||
public:
|
||||
PreparedHydrostaticEquilibriumJacobianOperator(
|
||||
const fem::FEM &f,
|
||||
@@ -267,8 +244,7 @@ export namespace mean_field::operators {
|
||||
mfem::Vector &action
|
||||
) const override;
|
||||
|
||||
[[nodiscard]] const HydrostaticJacobianBlockLayout &
|
||||
GetLayout() const noexcept;
|
||||
[[nodiscard]] const HydrostaticJacobianBlockLayout &GetLayout() const noexcept;
|
||||
|
||||
private:
|
||||
HydrostaticJacobianBlockLayout m_layout;
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
module;
|
||||
|
||||
#include <compare>
|
||||
#include <cstdint>
|
||||
#include <mfem.hpp>
|
||||
#include <vector>
|
||||
|
||||
export module mean_field:operators.prepared_mass_normalization;
|
||||
|
||||
export import :fem;
|
||||
export import :mapping.domain_mapper;
|
||||
export import :operators.context.gravity_field;
|
||||
export import :utils.blocks;
|
||||
|
||||
export namespace mean_field::operators {
|
||||
struct MassNormalizationDependencyStamp final {
|
||||
std::uint64_t identity{0};
|
||||
std::uint64_t revision{0};
|
||||
|
||||
constexpr auto operator<=>(const MassNormalizationDependencyStamp &) const = default;
|
||||
};
|
||||
|
||||
struct MassNormalizationDependencies final {
|
||||
MassNormalizationDependencyStamp discretization;
|
||||
MassNormalizationDependencyStamp density;
|
||||
MassNormalizationDependencyStamp displacement;
|
||||
MassNormalizationDependencyStamp targetMass;
|
||||
|
||||
constexpr auto operator<=>(const MassNormalizationDependencies &) const = default;
|
||||
};
|
||||
|
||||
struct MassNormalizationStateView final {
|
||||
double targetMass{0.0};
|
||||
};
|
||||
|
||||
struct PreparedMassNormalizationReport final {
|
||||
bool rebuiltStaticPlan{false};
|
||||
bool refreshedGeometry{false};
|
||||
bool refreshedDensity{false};
|
||||
bool updatedTargetMass{false};
|
||||
bool assembledResidual{false};
|
||||
|
||||
[[nodiscard]] bool DidAnyWork() const noexcept {
|
||||
return rebuiltStaticPlan || refreshedGeometry || refreshedDensity || updatedTargetMass || assembledResidual;
|
||||
}
|
||||
};
|
||||
|
||||
struct PreparedMassNormalizationActionStatistics final {
|
||||
std::uint64_t densityApplications{0};
|
||||
std::uint64_t displacementApplications{0};
|
||||
std::uint64_t completeApplications{0};
|
||||
|
||||
constexpr auto operator<=>(const PreparedMassNormalizationActionStatistics &) const = default;
|
||||
};
|
||||
|
||||
/*
|
||||
* Prepared scalar row
|
||||
*
|
||||
* R_M(rho, d) = integral_{Omega_star(d)} rho dV - M_target.
|
||||
*
|
||||
* Density and displacement are borrowed from the shared gravity-field
|
||||
* linearization context. This keeps the mass row on exactly the same
|
||||
* frozen state and geometry as the gravity and mechanical rows.
|
||||
*/
|
||||
class PreparedMassNormalizationOperator final {
|
||||
public:
|
||||
PreparedMassNormalizationOperator(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const context::gravity_field::GravityFieldLinearizationContext &gravityContext
|
||||
);
|
||||
|
||||
PreparedMassNormalizationOperator(const PreparedMassNormalizationOperator &) = delete;
|
||||
PreparedMassNormalizationOperator &operator=(const PreparedMassNormalizationOperator &) = delete;
|
||||
PreparedMassNormalizationOperator(PreparedMassNormalizationOperator &&) = delete;
|
||||
PreparedMassNormalizationOperator &operator=(PreparedMassNormalizationOperator &&) = delete;
|
||||
|
||||
PreparedMassNormalizationReport Prepare(
|
||||
const MassNormalizationStateView &state,
|
||||
const MassNormalizationDependencies &dependencies
|
||||
);
|
||||
|
||||
void BuildResidual(mfem::Vector &residual) const;
|
||||
|
||||
void ApplyDensityJacobianAction(
|
||||
const mfem::Vector &densityVariation,
|
||||
mfem::Vector &action
|
||||
) const;
|
||||
|
||||
void ApplyDisplacementJacobianAction(
|
||||
const mfem::Vector &displacementVariation,
|
||||
mfem::Vector &action
|
||||
) const;
|
||||
|
||||
void ApplyCompleteJacobianAction(
|
||||
const mfem::Vector &densityVariation,
|
||||
const mfem::Vector &displacementVariation,
|
||||
mfem::Vector &action
|
||||
) const;
|
||||
|
||||
[[nodiscard]] bool IsPrepared() const noexcept;
|
||||
[[nodiscard]] double GetCurrentMass() const;
|
||||
[[nodiscard]] double GetTargetMass() const;
|
||||
[[nodiscard]] std::uint64_t GetPreparationCount() const noexcept;
|
||||
[[nodiscard]] std::uint64_t GetResidualApplicationCount() const noexcept;
|
||||
[[nodiscard]] const PreparedMassNormalizationActionStatistics &GetActionStatistics() const noexcept;
|
||||
[[nodiscard]] const fem::FEM &GetFEM() const noexcept;
|
||||
[[nodiscard]] const context::gravity_field::GravityFieldLinearizationContext &
|
||||
GetGravityContext() const noexcept;
|
||||
|
||||
private:
|
||||
struct QuadraturePointData final {
|
||||
mfem::IntegrationPoint integrationPoint;
|
||||
mfem::Vector densityShape;
|
||||
mapping::VolumeMappingContext mappingContext;
|
||||
double density{0.0};
|
||||
};
|
||||
|
||||
struct ElementPAData final {
|
||||
int elementId{-1};
|
||||
|
||||
mfem::Array<int> densityDofs;
|
||||
mfem::Array<int> displacementDofs;
|
||||
mfem::Array<int> compactificationDofs;
|
||||
|
||||
mfem::DofTransformation *densityDofTransformation{nullptr};
|
||||
mfem::DofTransformation *displacementDofTransformation{nullptr};
|
||||
mfem::DofTransformation *compactificationDofTransformation{nullptr};
|
||||
|
||||
mfem::Vector baseDisplacement;
|
||||
mfem::Vector compactification;
|
||||
|
||||
std::vector<QuadraturePointData> quadraturePoints;
|
||||
};
|
||||
|
||||
void BuildStaticPlan();
|
||||
void RefreshGeometry(const mfem::Vector &displacement);
|
||||
void RefreshDensity(const mfem::Vector &density);
|
||||
void AssembleResidual();
|
||||
void VerifyPrepared() const;
|
||||
|
||||
[[nodiscard]] double EvaluateDensityActionLocal(const mfem::Vector &densityVariation) const;
|
||||
|
||||
[[nodiscard]] double EvaluateDisplacementActionLocal(const mfem::Vector &displacementVariation) const;
|
||||
|
||||
[[nodiscard]] double GlobalSum(double localValue) const;
|
||||
|
||||
const fem::FEM &m_fem;
|
||||
const mapping::DomainMapperStateless &m_domainMapper;
|
||||
const context::gravity_field::GravityFieldLinearizationContext &m_gravityContext;
|
||||
|
||||
std::vector<ElementPAData> m_elements;
|
||||
MassNormalizationDependencies m_preparedDependencies;
|
||||
mfem::Vector m_cachedResidual;
|
||||
|
||||
double m_currentMass{0.0};
|
||||
double m_targetMass{0.0};
|
||||
|
||||
std::uint64_t m_preparationCount{0};
|
||||
mutable std::uint64_t m_residualApplicationCount{0};
|
||||
mutable PreparedMassNormalizationActionStatistics m_actionStatistics;
|
||||
bool m_isPrepared{false};
|
||||
};
|
||||
|
||||
using MassNormalizationLayout = utils::blocks::form_layout<utils::blocks::barotropic_equilibrium_form>;
|
||||
|
||||
class PreparedMassNormalizationJacobianOperator final : public mfem::Operator {
|
||||
public:
|
||||
PreparedMassNormalizationJacobianOperator(
|
||||
const MassNormalizationLayout &layout,
|
||||
const PreparedMassNormalizationOperator &preparedOperator
|
||||
);
|
||||
|
||||
void Mult(
|
||||
const mfem::Vector &direction,
|
||||
mfem::Vector &action
|
||||
) const override;
|
||||
|
||||
[[nodiscard]] const MassNormalizationLayout &GetLayout() const noexcept;
|
||||
|
||||
private:
|
||||
MassNormalizationLayout m_layout;
|
||||
const PreparedMassNormalizationOperator &m_preparedOperator;
|
||||
};
|
||||
} // namespace mean_field::operators
|
||||
304
libmeanfield/interface/operators/prepared_pressure_force.cppm
Normal file
304
libmeanfield/interface/operators/prepared_pressure_force.cppm
Normal file
@@ -0,0 +1,304 @@
|
||||
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
|
||||
@@ -0,0 +1,149 @@
|
||||
module;
|
||||
|
||||
#include <compare>
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
||||
#include <mfem.hpp>
|
||||
|
||||
export module mean_field:operators.prepared_rotational_displacement_force;
|
||||
|
||||
export import :fem;
|
||||
export import :mapping.domain_mapper;
|
||||
export import :operators.context.rotational_displacement_force;
|
||||
export import :physics.rigid_rotation;
|
||||
export import :utils.blocks;
|
||||
|
||||
export namespace mean_field::operators {
|
||||
struct PreparedRotationalDisplacementForceReport final {
|
||||
context::rotational_displacement_force::RotationalDisplacementForcePreparationReport contextReport;
|
||||
|
||||
bool updatedRotation{false};
|
||||
bool preparedResidual{false};
|
||||
|
||||
[[nodiscard]] bool DidAnyWork() const noexcept {
|
||||
return contextReport.DidAnyWork() || updatedRotation || preparedResidual;
|
||||
}
|
||||
};
|
||||
|
||||
struct PreparedRotationalDisplacementForceColumnStatistics final {
|
||||
std::uint64_t applications{0};
|
||||
|
||||
constexpr auto operator<=>(const PreparedRotationalDisplacementForceColumnStatistics &) const = default;
|
||||
};
|
||||
|
||||
struct PreparedRotationalDisplacementForceCompleteStatistics final {
|
||||
std::uint64_t applications{0};
|
||||
|
||||
constexpr auto operator<=>(const PreparedRotationalDisplacementForceCompleteStatistics &) const = default;
|
||||
};
|
||||
|
||||
class PreparedRotationalDisplacementForceOperator final {
|
||||
public:
|
||||
PreparedRotationalDisplacementForceOperator(
|
||||
const fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper
|
||||
);
|
||||
|
||||
PreparedRotationalDisplacementForceOperator(const PreparedRotationalDisplacementForceOperator &) = delete;
|
||||
|
||||
PreparedRotationalDisplacementForceOperator &
|
||||
operator=(const PreparedRotationalDisplacementForceOperator &) = delete;
|
||||
|
||||
PreparedRotationalDisplacementForceOperator(PreparedRotationalDisplacementForceOperator &&) = delete;
|
||||
|
||||
PreparedRotationalDisplacementForceOperator &operator=(PreparedRotationalDisplacementForceOperator &&) = delete;
|
||||
|
||||
PreparedRotationalDisplacementForceReport Prepare(
|
||||
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(
|
||||
const mfem::Vector &densityVariation,
|
||||
mfem::Vector &action
|
||||
) const;
|
||||
|
||||
void ApplyDisplacementJacobianAction(
|
||||
const mfem::Vector &displacementVariation,
|
||||
mfem::Vector &action
|
||||
) const;
|
||||
|
||||
void ApplyCompleteJacobianAction(
|
||||
const mfem::Vector &densityVariation,
|
||||
const mfem::Vector &displacementVariation,
|
||||
mfem::Vector &action
|
||||
) const;
|
||||
|
||||
[[nodiscard]] bool IsPrepared() const noexcept;
|
||||
|
||||
[[nodiscard]] const context::rotational_displacement_force::RotationalDisplacementForcePreparationStatistics &
|
||||
GetContextPreparationStatistics() const noexcept;
|
||||
|
||||
[[nodiscard]] std::uint64_t GetResidualPreparationCount() const noexcept;
|
||||
|
||||
[[nodiscard]] std::uint64_t GetResidualApplicationCount() const noexcept;
|
||||
|
||||
[[nodiscard]] const PreparedRotationalDisplacementForceColumnStatistics &
|
||||
GetDensityJacobianStatistics() const noexcept;
|
||||
|
||||
[[nodiscard]] const PreparedRotationalDisplacementForceColumnStatistics &
|
||||
GetDisplacementJacobianStatistics() const noexcept;
|
||||
|
||||
[[nodiscard]] const PreparedRotationalDisplacementForceCompleteStatistics &
|
||||
GetCompleteJacobianStatistics() const noexcept;
|
||||
|
||||
[[nodiscard]] const fem::FEM &GetFEM() const noexcept;
|
||||
|
||||
[[nodiscard]] const context::rotational_displacement_force::RotationalDisplacementForceLinearizationContext &
|
||||
GetContext() const noexcept;
|
||||
|
||||
private:
|
||||
void VerifyPrepared() const;
|
||||
|
||||
const fem::FEM &m_fem;
|
||||
const mapping::DomainMapperStateless &m_domainMapper;
|
||||
|
||||
context::rotational_displacement_force::RotationalDisplacementForceLinearizationContext m_context;
|
||||
|
||||
std::optional<physics::RigidRotation> m_rotation;
|
||||
mfem::Vector m_cachedResidual;
|
||||
|
||||
context::rotational_displacement_force::RotationalDisplacementForceDependencies m_preparedDependencies;
|
||||
|
||||
std::uint64_t m_residualPreparationCount{0};
|
||||
mutable std::uint64_t m_residualApplicationCount{0};
|
||||
|
||||
mutable PreparedRotationalDisplacementForceColumnStatistics m_densityJacobianStatistics;
|
||||
|
||||
mutable PreparedRotationalDisplacementForceColumnStatistics m_displacementJacobianStatistics;
|
||||
|
||||
mutable PreparedRotationalDisplacementForceCompleteStatistics m_completeJacobianStatistics;
|
||||
|
||||
bool m_isPrepared{false};
|
||||
};
|
||||
|
||||
using RotationalDisplacementForceLayout = utils::blocks::form_layout<utils::blocks::barotropic_equilibrium_form>;
|
||||
|
||||
class PreparedRotationalDisplacementForceJacobianOperator final : public mfem::Operator {
|
||||
public:
|
||||
PreparedRotationalDisplacementForceJacobianOperator(
|
||||
const RotationalDisplacementForceLayout &layout,
|
||||
const PreparedRotationalDisplacementForceOperator &preparedOperator
|
||||
);
|
||||
|
||||
void Mult(
|
||||
const mfem::Vector &direction,
|
||||
mfem::Vector &action
|
||||
) const override;
|
||||
|
||||
[[nodiscard]] const RotationalDisplacementForceLayout &GetLayout() const noexcept;
|
||||
|
||||
private:
|
||||
RotationalDisplacementForceLayout m_layout;
|
||||
const PreparedRotationalDisplacementForceOperator &m_preparedOperator;
|
||||
};
|
||||
} // namespace mean_field::operators
|
||||
@@ -0,0 +1,177 @@
|
||||
module;
|
||||
|
||||
#include <compare>
|
||||
#include <cstdint>
|
||||
|
||||
#include <mfem.hpp>
|
||||
|
||||
export module mean_field:operators.prepared_stellar_equilibrium;
|
||||
|
||||
export import :eos.polytrope;
|
||||
export import :fem;
|
||||
export import :field.mfem;
|
||||
export import :mapping.domain_mapper;
|
||||
export import :model.stellar;
|
||||
export import :operators.context.gravity_field;
|
||||
export import :operators.gravity_field;
|
||||
export import :operators.gravity_field_jacobian;
|
||||
export import :operators.prepared_barotropic_closure;
|
||||
export import :operators.prepared_displacement_residual;
|
||||
export import :operators.prepared_hydrostatic_equilibrium;
|
||||
export import :operators.prepared_mass_normalization;
|
||||
export import :physics.rigid_rotation;
|
||||
export import :utils.blocks;
|
||||
|
||||
export namespace mean_field::operators {
|
||||
struct StellarEquilibriumDependencyStamp final {
|
||||
std::uint64_t identity{0};
|
||||
std::uint64_t revision{0};
|
||||
|
||||
constexpr auto operator<=>(const StellarEquilibriumDependencyStamp &) const = default;
|
||||
};
|
||||
|
||||
struct StellarEquilibriumDependencies final {
|
||||
StellarEquilibriumDependencyStamp discretization;
|
||||
StellarEquilibriumDependencyStamp density;
|
||||
StellarEquilibriumDependencyStamp displacement;
|
||||
StellarEquilibriumDependencyStamp gravityGradient;
|
||||
StellarEquilibriumDependencyStamp gravityPotential;
|
||||
StellarEquilibriumDependencyStamp enthalpy;
|
||||
StellarEquilibriumDependencyStamp bernoulliConstant;
|
||||
StellarEquilibriumDependencyStamp rotation;
|
||||
StellarEquilibriumDependencyStamp targetMass;
|
||||
|
||||
constexpr auto operator<=>(const StellarEquilibriumDependencies &) const = default;
|
||||
};
|
||||
|
||||
struct PreparedStellarEquilibriumReport final {
|
||||
context::gravity_field::GravityFieldPreparationReport gravity;
|
||||
PreparedBarotropicClosureReport barotropicClosure;
|
||||
PreparedHydrostaticEquilibriumReport hydrostatic;
|
||||
PreparedDisplacementResidualReport displacement;
|
||||
PreparedMassNormalizationReport massNormalization;
|
||||
bool assembledResidual{false};
|
||||
|
||||
[[nodiscard]] bool DidAnyChildWork() const noexcept {
|
||||
return gravity.DidAnyWork() || barotropicClosure.DidAnyWork() || hydrostatic.DidAnyWork() ||
|
||||
displacement.DidAnyWork() || massNormalization.DidAnyWork();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool DidAnyWork() const noexcept {
|
||||
return DidAnyChildWork() || assembledResidual;
|
||||
}
|
||||
};
|
||||
|
||||
struct PreparedStellarEquilibriumStatistics final {
|
||||
std::uint64_t residualAssemblies{0};
|
||||
std::uint64_t residualApplications{0};
|
||||
std::uint64_t jacobianApplications{0};
|
||||
|
||||
constexpr auto operator<=>(const PreparedStellarEquilibriumStatistics &) const = default;
|
||||
};
|
||||
|
||||
using StellarEquilibriumLayout = utils::blocks::form_layout<utils::blocks::barotropic_equilibrium_form>;
|
||||
|
||||
class PreparedStellarEquilibriumOperator final : public mfem::Operator {
|
||||
public:
|
||||
PreparedStellarEquilibriumOperator(
|
||||
fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const eos::Polytrope &equationOfState,
|
||||
double targetMass
|
||||
);
|
||||
|
||||
PreparedStellarEquilibriumOperator(
|
||||
fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const eos::Polytrope &equationOfState,
|
||||
const models::StellarModel &stellarModel
|
||||
);
|
||||
|
||||
PreparedStellarEquilibriumOperator(const PreparedStellarEquilibriumOperator &) = delete;
|
||||
PreparedStellarEquilibriumOperator &operator=(const PreparedStellarEquilibriumOperator &) = delete;
|
||||
PreparedStellarEquilibriumOperator(PreparedStellarEquilibriumOperator &&) = delete;
|
||||
PreparedStellarEquilibriumOperator &operator=(PreparedStellarEquilibriumOperator &&) = delete;
|
||||
|
||||
PreparedStellarEquilibriumReport Prepare(
|
||||
const mfem::Vector &state,
|
||||
const StellarEquilibriumDependencies &dependencies,
|
||||
const physics::RigidRotation &rotation
|
||||
);
|
||||
|
||||
void BuildResidual(mfem::Vector &residual) const;
|
||||
|
||||
void Mult(
|
||||
const mfem::Vector &direction,
|
||||
mfem::Vector &action
|
||||
) const override;
|
||||
|
||||
[[nodiscard]] bool IsPrepared() const noexcept;
|
||||
[[nodiscard]] double GetTargetMass() const noexcept;
|
||||
[[nodiscard]] const StellarEquilibriumLayout &GetLayout() const noexcept;
|
||||
[[nodiscard]] const StellarEquilibriumDependencies &GetDependencies() const;
|
||||
[[nodiscard]] const PreparedStellarEquilibriumStatistics &GetStatistics() const noexcept;
|
||||
|
||||
[[nodiscard]] const context::gravity_field::GravityFieldLinearizationContext &
|
||||
GetGravityContext() const noexcept;
|
||||
[[nodiscard]] const GravityFieldOperator &GetGravityOperator() const noexcept;
|
||||
[[nodiscard]] const GravityFieldJacobianOperator &GetGravityJacobianOperator() const noexcept;
|
||||
[[nodiscard]] const PreparedBarotropicClosureOperator &GetBarotropicClosureOperator() const noexcept;
|
||||
[[nodiscard]] const context::barotropic::BarotropicClosureLinearizationContext &
|
||||
GetBarotropicClosureContext() const noexcept;
|
||||
[[nodiscard]] const PreparedHydrostaticEquilibriumOperator &GetHydrostaticOperator() const noexcept;
|
||||
[[nodiscard]] const PreparedDisplacementResidualOperator &GetDisplacementOperator() const noexcept;
|
||||
[[nodiscard]] const PreparedMassNormalizationOperator &GetMassNormalizationOperator() const noexcept;
|
||||
|
||||
private:
|
||||
struct ConstructionData;
|
||||
|
||||
static ConstructionData MakeConstructionData(fem::FEM &f);
|
||||
|
||||
PreparedStellarEquilibriumOperator(
|
||||
fem::FEM &f,
|
||||
const mapping::DomainMapperStateless &domainMapper,
|
||||
const eos::Polytrope &equationOfState,
|
||||
double targetMass,
|
||||
ConstructionData constructionData
|
||||
);
|
||||
|
||||
void AssembleResidual();
|
||||
void VerifyPrepared() const;
|
||||
|
||||
StellarEquilibriumLayout m_layout;
|
||||
mfem::Array<int> m_gravityStateOffsets;
|
||||
|
||||
context::gravity_field::GravityFieldLinearizationContext m_gravityContext;
|
||||
GravityFieldJacobianOperator m_gravityJacobianOperator;
|
||||
GravityFieldOperator m_gravityOperator;
|
||||
|
||||
PreparedBarotropicClosureOperator m_barotropicClosureOperator;
|
||||
PreparedHydrostaticEquilibriumOperator m_hydrostaticOperator;
|
||||
PreparedDisplacementResidualOperator m_displacementOperator;
|
||||
PreparedMassNormalizationOperator m_massNormalizationOperator;
|
||||
|
||||
StellarEquilibriumDependencies m_preparedDependencies;
|
||||
mfem::Vector m_cachedResidual;
|
||||
double m_targetMass{0.0};
|
||||
|
||||
mutable PreparedStellarEquilibriumStatistics m_statistics;
|
||||
bool m_isPrepared{false};
|
||||
|
||||
field::FieldDofMap m_densityMap;
|
||||
field::FieldDofMap m_displacementMap;
|
||||
field::FieldDofMap m_gravityFluxMap;
|
||||
field::FieldDofMap m_gravityPotentialMap;
|
||||
field::FieldDofMap m_enthalpyMap;
|
||||
|
||||
mfem::Vector m_fullDensity;
|
||||
mfem::Vector m_fullEnthalpy;
|
||||
mfem::Vector m_fullGravityState;
|
||||
|
||||
mutable mfem::Vector m_fullDensityVariation;
|
||||
mutable mfem::Vector m_fullEnthalpyVariation;
|
||||
mutable mfem::Vector m_fullGravityDirection;
|
||||
|
||||
mutable mfem::Vector m_fullEnthalpyAction;
|
||||
};
|
||||
} // namespace mean_field::operators
|
||||
Reference in New Issue
Block a user