2026-08-23 10:13:53 -04:00
|
|
|
module;
|
|
|
|
|
|
|
|
|
|
#include <concepts>
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include <type_traits>
|
|
|
|
|
#include <utility>
|
|
|
|
|
|
2026-09-01 11:50:13 -04:00
|
|
|
#include <mfem.hpp>
|
|
|
|
|
|
2026-08-23 10:13:53 -04:00
|
|
|
export module mean_field:model.stellar;
|
|
|
|
|
|
2026-09-01 11:50:13 -04:00
|
|
|
export import :deformation.domain_deformation;
|
2026-08-30 16:41:14 -04:00
|
|
|
export import :eos.runtime;
|
2026-08-23 10:13:53 -04:00
|
|
|
export import :model.structure.base;
|
2026-08-30 16:41:14 -04:00
|
|
|
export import :surface.compiler;
|
2026-08-23 10:13:53 -04:00
|
|
|
|
|
|
|
|
export namespace mean_field::models {
|
2026-08-30 16:41:14 -04:00
|
|
|
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
|
2026-08-23 10:13:53 -04:00
|
|
|
|
|
|
|
|
template <typename Candidate>
|
2026-08-30 16:41:14 -04:00
|
|
|
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>;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <StructurePrescription Candidate>
|
|
|
|
|
using StructureEquationOfStateT =
|
|
|
|
|
std::remove_cvref_t<decltype(std::declval<const std::remove_cvref_t<Candidate> &>().equationOfState())>;
|
|
|
|
|
|
|
|
|
|
template <typename Candidate, typename EquationOfState>
|
2026-09-01 11:50:13 -04:00
|
|
|
concept SurfaceCondition =
|
2026-08-30 16:41:14 -04:00
|
|
|
surface::ConstantPressureSurfaceType<Candidate> &&
|
|
|
|
|
surface::PressureSurfaceCompilable<surface::BarotropicSurfaceFormulation, std::remove_cvref_t<EquationOfState>>;
|
|
|
|
|
|
2026-09-01 11:50:13 -04:00
|
|
|
template <
|
|
|
|
|
StructurePrescription Structure,
|
|
|
|
|
deformation::SurfaceDeformationPrescription SurfaceDeformation = deformation::NodalRadialSurface,
|
|
|
|
|
deformation::InteriorDeformationExtension StellarInteriorDeformation =
|
|
|
|
|
deformation::PowerLawRadialInteriorExtension,
|
|
|
|
|
deformation::VacuumDeformationExtension VacuumDeformation = deformation::FixedInfinityRadialVacuumExtension>
|
|
|
|
|
requires SurfaceCondition<surface::ConstantPressureSurface, StructureEquationOfStateT<Structure>>
|
2026-08-23 10:13:53 -04:00
|
|
|
class StellarModel final {
|
|
|
|
|
public:
|
2026-09-01 11:50:13 -04:00
|
|
|
using StructurePrescriptionType = Structure;
|
|
|
|
|
using SurfaceConditionType = surface::ConstantPressureSurface;
|
|
|
|
|
using SurfaceDeformationPrescriptionType = SurfaceDeformation;
|
|
|
|
|
using StellarInteriorDeformationExtensionType = StellarInteriorDeformation;
|
|
|
|
|
using VacuumDeformationExtensionType = VacuumDeformation;
|
|
|
|
|
using EquationOfStateType = StructureEquationOfStateT<Structure>;
|
2026-08-30 16:41:14 -04:00
|
|
|
using SurfaceConstraintType =
|
|
|
|
|
surface::CompiledPressureSurfaceConstraintT<surface::BarotropicSurfaceFormulation, EquationOfStateType>;
|
|
|
|
|
|
|
|
|
|
template <typename StructureArgument>
|
2026-09-01 11:50:13 -04:00
|
|
|
requires std::same_as<
|
|
|
|
|
std::remove_cvref_t<StructureArgument>,
|
|
|
|
|
Structure>
|
|
|
|
|
explicit StellarModel(
|
|
|
|
|
StructureArgument &&structurePrescription,
|
|
|
|
|
const surface::ConstantPressureSurface surfaceCondition
|
|
|
|
|
)
|
|
|
|
|
: StellarModel(
|
|
|
|
|
std::forward<StructureArgument>(structurePrescription),
|
|
|
|
|
surfaceCondition,
|
|
|
|
|
deformation::NodalRadialSurface{defaultReferenceCenter()},
|
|
|
|
|
deformation::PowerLawRadialInteriorExtension{},
|
|
|
|
|
deformation::FixedInfinityRadialVacuumExtension{}
|
|
|
|
|
) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <
|
|
|
|
|
typename StructureArgument,
|
|
|
|
|
typename SurfaceDeformationArgument,
|
|
|
|
|
typename StellarInteriorDeformationArgument,
|
|
|
|
|
typename VacuumDeformationArgument>
|
2026-08-30 16:41:14 -04:00
|
|
|
requires std::same_as<
|
|
|
|
|
std::remove_cvref_t<StructureArgument>,
|
2026-09-01 11:50:13 -04:00
|
|
|
Structure> &&
|
|
|
|
|
std::same_as<
|
|
|
|
|
std::remove_cvref_t<SurfaceDeformationArgument>,
|
|
|
|
|
SurfaceDeformation> &&
|
|
|
|
|
std::same_as<
|
|
|
|
|
std::remove_cvref_t<StellarInteriorDeformationArgument>,
|
|
|
|
|
StellarInteriorDeformation> &&
|
|
|
|
|
std::same_as<
|
|
|
|
|
std::remove_cvref_t<VacuumDeformationArgument>,
|
|
|
|
|
VacuumDeformation>
|
2026-08-23 10:13:53 -04:00
|
|
|
explicit StellarModel(
|
2026-08-30 16:41:14 -04:00
|
|
|
StructureArgument &&structurePrescription,
|
2026-09-01 11:50:13 -04:00
|
|
|
const surface::ConstantPressureSurface surfaceCondition,
|
|
|
|
|
SurfaceDeformationArgument &&surfaceDeformation,
|
|
|
|
|
StellarInteriorDeformationArgument &&stellarInteriorDeformation,
|
|
|
|
|
VacuumDeformationArgument &&vacuumDeformation
|
2026-08-23 10:13:53 -04:00
|
|
|
)
|
2026-08-30 16:41:14 -04:00
|
|
|
: m_structurePrescription(
|
|
|
|
|
std::make_unique<Structure>(std::forward<StructureArgument>(structurePrescription))
|
|
|
|
|
),
|
2026-09-01 11:50:13 -04:00
|
|
|
m_surfaceCondition(std::make_unique<surface::ConstantPressureSurface>(surfaceCondition)),
|
|
|
|
|
m_surfaceDeformation(
|
|
|
|
|
std::make_unique<SurfaceDeformation>(std::forward<SurfaceDeformationArgument>(surfaceDeformation))
|
|
|
|
|
),
|
|
|
|
|
m_stellarInteriorDeformation(
|
|
|
|
|
std::make_unique<StellarInteriorDeformation>(
|
|
|
|
|
std::forward<StellarInteriorDeformationArgument>(stellarInteriorDeformation)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
m_vacuumDeformation(
|
|
|
|
|
std::make_unique<VacuumDeformation>(std::forward<VacuumDeformationArgument>(vacuumDeformation))
|
|
|
|
|
),
|
|
|
|
|
m_compiledSurfaceConstraint(std::make_unique<SurfaceConstraintType>(validateAndCompileConfiguration())) {
|
2026-08-23 10:13:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~StellarModel() = default;
|
|
|
|
|
|
|
|
|
|
StellarModel(const StellarModel &) = delete;
|
|
|
|
|
StellarModel &operator=(const StellarModel &) = delete;
|
|
|
|
|
StellarModel(StellarModel &&) noexcept = default;
|
|
|
|
|
StellarModel &operator=(StellarModel &&) noexcept = default;
|
|
|
|
|
|
2026-08-30 16:41:14 -04:00
|
|
|
[[nodiscard]] const Structure &structurePrescription() const noexcept {
|
2026-08-23 10:13:53 -04:00
|
|
|
return *m_structurePrescription;
|
|
|
|
|
}
|
|
|
|
|
|
2026-09-01 11:50:13 -04:00
|
|
|
[[nodiscard]] const surface::ConstantPressureSurface &surfaceCondition() const noexcept {
|
|
|
|
|
return *m_surfaceCondition;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] const SurfaceDeformation &surfaceDeformationPrescription() const noexcept {
|
|
|
|
|
return *m_surfaceDeformation;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] const StellarInteriorDeformation &stellarInteriorDeformationExtension() const noexcept {
|
|
|
|
|
return *m_stellarInteriorDeformation;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] const VacuumDeformation &vacuumDeformationExtension() const noexcept {
|
|
|
|
|
return *m_vacuumDeformation;
|
2026-08-23 10:13:53 -04:00
|
|
|
}
|
|
|
|
|
|
2026-08-30 16:41:14 -04:00
|
|
|
[[nodiscard]] const EquationOfStateType &equationOfState() const noexcept {
|
2026-08-23 10:13:53 -04:00
|
|
|
return m_structurePrescription->equationOfState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] double targetMass() const noexcept {
|
|
|
|
|
return m_structurePrescription->targetMass();
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-30 16:41:14 -04:00
|
|
|
[[nodiscard]] structure::StructureSeed makeInitialSeed(const structure::StructureSeedRequest &request) const {
|
2026-08-23 10:13:53 -04:00
|
|
|
return m_structurePrescription->makeInitialSeed(request);
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-30 16:41:14 -04:00
|
|
|
[[nodiscard]] const SurfaceConstraintType &compiledSurfaceConstraint() const noexcept {
|
|
|
|
|
return *m_compiledSurfaceConstraint;
|
2026-08-23 10:13:53 -04:00
|
|
|
}
|
|
|
|
|
|
2026-09-01 11:50:13 -04:00
|
|
|
[[nodiscard]] auto compileDomainDeformation(fem::FEM &finiteElementModel) const {
|
|
|
|
|
return deformation::compileDomainDeformation(
|
|
|
|
|
surfaceDeformationPrescription(), stellarInteriorDeformationExtension(), vacuumDeformationExtension(),
|
|
|
|
|
finiteElementModel
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-23 10:13:53 -04:00
|
|
|
private:
|
2026-09-01 11:50:13 -04:00
|
|
|
[[nodiscard]] static mfem::Vector defaultReferenceCenter() {
|
|
|
|
|
mfem::Vector center(3);
|
|
|
|
|
center = 0.0;
|
|
|
|
|
return center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] SurfaceConstraintType validateAndCompileConfiguration() const {
|
|
|
|
|
m_structurePrescription->validate();
|
|
|
|
|
m_surfaceDeformation->validate();
|
|
|
|
|
m_stellarInteriorDeformation->validate();
|
|
|
|
|
m_vacuumDeformation->validate();
|
2026-08-23 10:13:53 -04:00
|
|
|
|
2026-08-30 16:41:14 -04:00
|
|
|
return surface::compilePressureSurfaceConstraint<surface::BarotropicSurfaceFormulation>(
|
2026-09-01 11:50:13 -04:00
|
|
|
*m_surfaceCondition, m_structurePrescription->equationOfState()
|
2026-08-30 16:41:14 -04:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<Structure> m_structurePrescription;
|
2026-09-01 11:50:13 -04:00
|
|
|
std::unique_ptr<surface::ConstantPressureSurface> m_surfaceCondition;
|
|
|
|
|
std::unique_ptr<SurfaceDeformation> m_surfaceDeformation;
|
|
|
|
|
std::unique_ptr<StellarInteriorDeformation> m_stellarInteriorDeformation;
|
|
|
|
|
std::unique_ptr<VacuumDeformation> m_vacuumDeformation;
|
2026-08-30 16:41:14 -04:00
|
|
|
std::unique_ptr<SurfaceConstraintType> m_compiledSurfaceConstraint;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename Structure>
|
|
|
|
|
StellarModel(
|
|
|
|
|
Structure &&,
|
|
|
|
|
surface::ConstantPressureSurface
|
2026-09-01 11:50:13 -04:00
|
|
|
)
|
|
|
|
|
-> StellarModel<
|
|
|
|
|
std::remove_cvref_t<Structure>,
|
|
|
|
|
deformation::NodalRadialSurface,
|
|
|
|
|
deformation::PowerLawRadialInteriorExtension,
|
|
|
|
|
deformation::FixedInfinityRadialVacuumExtension>;
|
|
|
|
|
|
|
|
|
|
template <
|
|
|
|
|
typename Structure,
|
|
|
|
|
typename SurfaceDeformation,
|
|
|
|
|
typename StellarInteriorDeformation,
|
|
|
|
|
typename VacuumDeformation>
|
|
|
|
|
StellarModel(
|
|
|
|
|
Structure &&,
|
|
|
|
|
surface::ConstantPressureSurface,
|
|
|
|
|
SurfaceDeformation &&,
|
|
|
|
|
StellarInteriorDeformation &&,
|
|
|
|
|
VacuumDeformation &&
|
|
|
|
|
)
|
|
|
|
|
-> StellarModel<
|
|
|
|
|
std::remove_cvref_t<Structure>,
|
|
|
|
|
std::remove_cvref_t<SurfaceDeformation>,
|
|
|
|
|
std::remove_cvref_t<StellarInteriorDeformation>,
|
|
|
|
|
std::remove_cvref_t<VacuumDeformation>>;
|
2026-08-30 16:41:14 -04:00
|
|
|
|
|
|
|
|
namespace detail {
|
|
|
|
|
template <typename Candidate> struct IsStellarModel : std::false_type { };
|
2026-08-23 10:13:53 -04:00
|
|
|
|
2026-09-01 11:50:13 -04:00
|
|
|
template <
|
|
|
|
|
typename Structure,
|
|
|
|
|
typename SurfaceDeformation,
|
|
|
|
|
typename StellarInteriorDeformation,
|
|
|
|
|
typename VacuumDeformation>
|
|
|
|
|
struct IsStellarModel<
|
|
|
|
|
StellarModel<Structure, SurfaceDeformation, StellarInteriorDeformation, VacuumDeformation>>
|
|
|
|
|
: std::true_type { };
|
2026-08-30 16:41:14 -04:00
|
|
|
} // namespace detail
|
2026-08-23 10:13:53 -04:00
|
|
|
|
2026-08-30 16:41:14 -04:00
|
|
|
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()),
|
2026-09-01 11:50:13 -04:00
|
|
|
m_surfaceDependencies(model.compiledSurfaceConstraint().runtimeDependencies()),
|
|
|
|
|
m_surfaceDeformation(model.surfaceDeformationPrescription().descriptor()),
|
|
|
|
|
m_stellarInteriorDeformation(model.stellarInteriorDeformationExtension().descriptor()),
|
|
|
|
|
m_vacuumDeformation(model.vacuumDeformationExtension().descriptor()) {
|
2026-08-30 16:41:14 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] eos::EquationOfStateView equationOfState() const noexcept {
|
|
|
|
|
return m_equationOfState;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] double targetMass() const noexcept {
|
|
|
|
|
return m_targetMass;
|
2026-08-23 10:13:53 -04:00
|
|
|
}
|
|
|
|
|
|
2026-08-30 16:41:14 -04:00
|
|
|
[[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;
|
|
|
|
|
}
|
2026-08-23 10:13:53 -04:00
|
|
|
|
2026-09-01 11:50:13 -04:00
|
|
|
[[nodiscard]] deformation::SurfaceDeformationDescriptor surfaceDeformation() const noexcept {
|
|
|
|
|
return m_surfaceDeformation;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] deformation::InteriorDeformationExtensionDescriptor stellarInteriorDeformation() const noexcept {
|
|
|
|
|
return m_stellarInteriorDeformation;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] deformation::VacuumDeformationExtensionDescriptor vacuumDeformation() const noexcept {
|
|
|
|
|
return m_vacuumDeformation;
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-30 16:41:14 -04:00
|
|
|
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);
|
|
|
|
|
}
|
2026-08-23 10:13:53 -04:00
|
|
|
|
2026-08-30 16:41:14 -04:00
|
|
|
eos::EquationOfStateView m_equationOfState;
|
|
|
|
|
const void *m_structurePrescription;
|
|
|
|
|
MakeInitialSeedFunction m_makeInitialSeed;
|
|
|
|
|
double m_targetMass;
|
|
|
|
|
surface::PressureSurfaceDescriptor m_surfaceCondition;
|
|
|
|
|
surface::RuntimeSurfaceConstraintDependencies m_surfaceDependencies;
|
2026-09-01 11:50:13 -04:00
|
|
|
deformation::SurfaceDeformationDescriptor m_surfaceDeformation;
|
|
|
|
|
deformation::InteriorDeformationExtensionDescriptor m_stellarInteriorDeformation;
|
|
|
|
|
deformation::VacuumDeformationExtensionDescriptor m_vacuumDeformation;
|
2026-08-23 10:13:53 -04:00
|
|
|
};
|
|
|
|
|
} // namespace mean_field::models
|