module; #include #include #include #include export module mean_field:model.stellar; export import :eos.runtime; export import :model.structure.base; export import :surface.compiler; export namespace mean_field::models { namespace detail { template concept ConstEquationOfStateReference = std::is_lvalue_reference_v && std::is_const_v> && eos::EquationOfStateModel>; } // namespace detail template concept StructurePrescription = requires( const std::remove_cvref_t &structurePrescription, const structure::StructureSeedRequest &seedRequest ) { { structurePrescription.equationOfState() } noexcept -> detail::ConstEquationOfStateReference; { structurePrescription.targetMass() } noexcept -> std::same_as; { structurePrescription.makeInitialSeed(seedRequest) } -> std::same_as; { structurePrescription.validate() } -> std::same_as; }; template using StructureEquationOfStateT = std::remove_cvref_t &>().equationOfState())>; template concept SurfacePrescription = surface::ConstantPressureSurfaceType && surface::PressureSurfaceCompilable>; template requires SurfacePrescription> class StellarModel final { public: using StructurePrescriptionType = Structure; using SurfacePrescriptionType = surface::ConstantPressureSurface; using EquationOfStateType = StructureEquationOfStateT; using SurfaceConstraintType = surface::CompiledPressureSurfaceConstraintT; template requires std::same_as< std::remove_cvref_t, Structure> explicit StellarModel( StructureArgument &&structurePrescription, const surface::ConstantPressureSurface surfacePrescription ) : m_structurePrescription( std::make_unique(std::forward(structurePrescription)) ), m_surfacePrescription(std::make_unique(surfacePrescription)), m_compiledSurfaceConstraint( std::make_unique(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 Structure &structurePrescription() const noexcept { return *m_structurePrescription; } [[nodiscard]] const surface::ConstantPressureSurface &surfacePrescription() const noexcept { return *m_surfacePrescription; } [[nodiscard]] const EquationOfStateType &equationOfState() const noexcept { return m_structurePrescription->equationOfState(); } [[nodiscard]] double targetMass() const noexcept { return m_structurePrescription->targetMass(); } [[nodiscard]] structure::StructureSeed makeInitialSeed(const structure::StructureSeedRequest &request) const { return m_structurePrescription->makeInitialSeed(request); } [[nodiscard]] const SurfaceConstraintType &compiledSurfaceConstraint() const noexcept { return *m_compiledSurfaceConstraint; } private: [[nodiscard]] static SurfaceConstraintType validateAndCompileSurface( const Structure &structurePrescription, const surface::ConstantPressureSurface &surfacePrescription ) { structurePrescription.validate(); return surface::compilePressureSurfaceConstraint( surfacePrescription, structurePrescription.equationOfState() ); } std::unique_ptr m_structurePrescription; std::unique_ptr m_surfacePrescription; std::unique_ptr m_compiledSurfaceConstraint; }; template StellarModel( Structure &&, surface::ConstantPressureSurface ) -> StellarModel>; namespace detail { template struct IsStellarModel : std::false_type { }; template struct IsStellarModel> : std::true_type { }; } // namespace detail template concept StellarModelType = detail::IsStellarModel>::value; class StellarModelView final { public: template requires StellarModelType && eos::RuntimeEquationOfStateModel::EquationOfStateType> explicit StellarModelView(Model &model) noexcept : m_equationOfState(model.equationOfState()), m_structurePrescription(std::addressof(model.structurePrescription())), m_makeInitialSeed(&makeInitialSeedFor::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 [[nodiscard]] static structure::StructureSeed makeInitialSeedFor( const void *structurePrescription, const structure::StructureSeedRequest &request ) { return static_cast(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