feat(surface): major work on implementing surface constraints in a presciption agnostic manner

This commit is contained in:
2026-08-30 16:41:14 -04:00
parent 36adfa1174
commit 0a7f18c5c7
95 changed files with 30144 additions and 25766 deletions

View File

@@ -7,62 +7,84 @@ module;
export module mean_field:model.stellar;
export import :eos.base;
export import :eos.runtime;
export import :model.structure.base;
export import :surface.base;
export import :surface.compiler;
export namespace mean_field::models {
template <typename Candidate>
concept StructurePrescription =
std::derived_from<std::remove_cvref_t<Candidate>, mean_field::models::structure::StructureBase>;
namespace detail {
template <typename Candidate>
concept ConstEquationOfStateReference =
std::is_lvalue_reference_v<Candidate> && std::is_const_v<std::remove_reference_t<Candidate>> &&
eos::EquationOfStateModel<std::remove_cvref_t<Candidate>>;
} // namespace detail
template <typename Candidate>
concept SurfacePrescription = std::derived_from<std::remove_cvref_t<Candidate>, mean_field::surface::SurfaceBase>;
concept StructurePrescription = requires(
const std::remove_cvref_t<Candidate> &structurePrescription,
const structure::StructureSeedRequest &seedRequest
) {
{ structurePrescription.equationOfState() } noexcept -> detail::ConstEquationOfStateReference;
{ structurePrescription.targetMass() } noexcept -> std::same_as<double>;
{ structurePrescription.makeInitialSeed(seedRequest) } -> std::same_as<structure::StructureSeed>;
{ structurePrescription.validate() } -> std::same_as<void>;
};
/*
* Public ownership facade for a physical structure prescription and its
* stellar-surface prescription.
*
* The concrete prescriptions are allocated once at construction. Their
* stable addresses allow future prepared operators and contexts to borrow
* references without making ownership part of the user-facing API.
*/
template <StructurePrescription Candidate>
using StructureEquationOfStateT =
std::remove_cvref_t<decltype(std::declval<const std::remove_cvref_t<Candidate> &>().equationOfState())>;
template <typename Candidate, typename EquationOfState>
concept SurfacePrescription =
surface::ConstantPressureSurfaceType<Candidate> &&
surface::PressureSurfaceCompilable<surface::BarotropicSurfaceFormulation, std::remove_cvref_t<EquationOfState>>;
template <StructurePrescription Structure>
requires SurfacePrescription<surface::ConstantPressureSurface, StructureEquationOfStateT<Structure>>
class StellarModel final {
public:
template <
StructurePrescription StructureType,
SurfacePrescription SurfaceType>
using StructurePrescriptionType = Structure;
using SurfacePrescriptionType = surface::ConstantPressureSurface;
using EquationOfStateType = StructureEquationOfStateT<Structure>;
using SurfaceConstraintType =
surface::CompiledPressureSurfaceConstraintT<surface::BarotropicSurfaceFormulation, EquationOfStateType>;
template <typename StructureArgument>
requires std::same_as<
std::remove_cvref_t<StructureArgument>,
Structure>
explicit StellarModel(
StructureType &&structurePrescription,
SurfaceType &&surfacePrescription
StructureArgument &&structurePrescription,
const surface::ConstantPressureSurface surfacePrescription
)
: StellarModel(
std::make_unique<std::remove_cvref_t<StructureType>>(
std::forward<StructureType>(structurePrescription)
),
std::make_unique<std::remove_cvref_t<SurfaceType>>(std::forward<SurfaceType>(surfacePrescription))
: m_structurePrescription(
std::make_unique<Structure>(std::forward<StructureArgument>(structurePrescription))
),
m_surfacePrescription(std::make_unique<surface::ConstantPressureSurface>(surfacePrescription)),
m_compiledSurfaceConstraint(
std::make_unique<SurfaceConstraintType>(validateAndCompileSurface(
*m_structurePrescription,
*m_surfacePrescription
))
) {
}
~StellarModel() = default;
StellarModel(const StellarModel &) = delete;
StellarModel &operator=(const StellarModel &) = delete;
StellarModel(StellarModel &&) noexcept = default;
StellarModel &operator=(StellarModel &&) noexcept = default;
[[nodiscard]] const mean_field::models::structure::StructureBase &structurePrescription() const noexcept {
[[nodiscard]] const Structure &structurePrescription() const noexcept {
return *m_structurePrescription;
}
[[nodiscard]] const mean_field::surface::SurfaceBase &surfacePrescription() const noexcept {
[[nodiscard]] const surface::ConstantPressureSurface &surfacePrescription() const noexcept {
return *m_surfacePrescription;
}
[[nodiscard]] const mean_field::eos::EquationOfState &equationOfState() const noexcept {
[[nodiscard]] const EquationOfStateType &equationOfState() const noexcept {
return m_structurePrescription->equationOfState();
}
@@ -70,45 +92,99 @@ export namespace mean_field::models {
return m_structurePrescription->targetMass();
}
[[nodiscard]] mean_field::models::structure::StructureSeed
makeInitialSeed(const mean_field::models::structure::StructureSeedRequest &request) const {
[[nodiscard]] structure::StructureSeed makeInitialSeed(const structure::StructureSeedRequest &request) const {
return m_structurePrescription->makeInitialSeed(request);
}
[[nodiscard]] const mean_field::surface::ResolvedSurfaceCondition &resolvedSurfaceCondition() const noexcept {
return m_resolvedSurfaceCondition;
[[nodiscard]] const SurfaceConstraintType &compiledSurfaceConstraint() const noexcept {
return *m_compiledSurfaceConstraint;
}
private:
explicit StellarModel(
std::unique_ptr<mean_field::models::structure::StructureBase> structurePrescription,
std::unique_ptr<mean_field::surface::SurfaceBase> surfacePrescription
)
: m_structurePrescription(std::move(structurePrescription)),
m_surfacePrescription(std::move(surfacePrescription)),
m_resolvedSurfaceCondition(validateAndResolve(
*m_structurePrescription,
*m_surfacePrescription
)) {
}
[[nodiscard]] static mean_field::surface::ResolvedSurfaceCondition validateAndResolve(
const mean_field::models::structure::StructureBase &structurePrescription,
const mean_field::surface::SurfaceBase &surfacePrescription
[[nodiscard]] static SurfaceConstraintType validateAndCompileSurface(
const Structure &structurePrescription,
const surface::ConstantPressureSurface &surfacePrescription
) {
structurePrescription.validate();
const mean_field::eos::EquationOfState &equationOfState = structurePrescription.equationOfState();
surfacePrescription.validate(equationOfState);
return surfacePrescription.resolve(equationOfState);
return surface::compilePressureSurfaceConstraint<surface::BarotropicSurfaceFormulation>(
surfacePrescription, structurePrescription.equationOfState()
);
}
std::unique_ptr<mean_field::models::structure::StructureBase> m_structurePrescription;
std::unique_ptr<Structure> m_structurePrescription;
std::unique_ptr<surface::ConstantPressureSurface> m_surfacePrescription;
std::unique_ptr<SurfaceConstraintType> m_compiledSurfaceConstraint;
};
std::unique_ptr<mean_field::surface::SurfaceBase> m_surfacePrescription;
template <typename Structure>
StellarModel(
Structure &&,
surface::ConstantPressureSurface
) -> StellarModel<std::remove_cvref_t<Structure>>;
mean_field::surface::ResolvedSurfaceCondition m_resolvedSurfaceCondition;
namespace detail {
template <typename Candidate> struct IsStellarModel : std::false_type { };
template <typename Structure> struct IsStellarModel<StellarModel<Structure>> : std::true_type { };
} // namespace detail
template <typename Candidate>
concept StellarModelType = detail::IsStellarModel<std::remove_cvref_t<Candidate>>::value;
class StellarModelView final {
public:
template <typename Model>
requires StellarModelType<Model> &&
eos::RuntimeEquationOfStateModel<typename std::remove_cvref_t<Model>::EquationOfStateType>
explicit StellarModelView(Model &model) noexcept
: m_equationOfState(model.equationOfState()),
m_structurePrescription(std::addressof(model.structurePrescription())),
m_makeInitialSeed(&makeInitialSeedFor<typename std::remove_cvref_t<Model>::StructurePrescriptionType>),
m_targetMass(model.targetMass()),
m_surfaceCondition(model.compiledSurfaceConstraint().descriptor()),
m_surfaceDependencies(model.compiledSurfaceConstraint().runtimeDependencies()) {
}
[[nodiscard]] eos::EquationOfStateView equationOfState() const noexcept {
return m_equationOfState;
}
[[nodiscard]] double targetMass() const noexcept {
return m_targetMass;
}
[[nodiscard]] structure::StructureSeed makeInitialSeed(const structure::StructureSeedRequest &request) const {
return m_makeInitialSeed(m_structurePrescription, request);
}
[[nodiscard]] surface::PressureSurfaceDescriptor surfaceCondition() const noexcept {
return m_surfaceCondition;
}
[[nodiscard]] surface::RuntimeSurfaceConstraintDependencies surfaceDependencies() const noexcept {
return m_surfaceDependencies;
}
private:
using MakeInitialSeedFunction = structure::StructureSeed (*)(
const void *,
const structure::StructureSeedRequest &
);
template <StructurePrescription Structure>
[[nodiscard]] static structure::StructureSeed makeInitialSeedFor(
const void *structurePrescription,
const structure::StructureSeedRequest &request
) {
return static_cast<const Structure *>(structurePrescription)->makeInitialSeed(request);
}
eos::EquationOfStateView m_equationOfState;
const void *m_structurePrescription;
MakeInitialSeedFunction m_makeInitialSeed;
double m_targetMass;
surface::PressureSurfaceDescriptor m_surfaceCondition;
surface::RuntimeSurfaceConstraintDependencies m_surfaceDependencies;
};
} // namespace mean_field::models