module; #include #include #include #include #include export module mean_field:model.stellar; export import :deformation.domain_deformation; 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 SurfaceCondition = surface::ConstantPressureSurfaceType && surface::PressureSurfaceCompilable>; template < StructurePrescription Structure, deformation::SurfaceDeformationPrescription SurfaceDeformation = deformation::NodalRadialSurface, deformation::InteriorDeformationExtension StellarInteriorDeformation = deformation::PowerLawRadialInteriorExtension, deformation::VacuumDeformationExtension VacuumDeformation = deformation::FixedInfinityRadialVacuumExtension> requires SurfaceCondition> class StellarModel final { public: using StructurePrescriptionType = Structure; using SurfaceConditionType = surface::ConstantPressureSurface; using SurfaceDeformationPrescriptionType = SurfaceDeformation; using StellarInteriorDeformationExtensionType = StellarInteriorDeformation; using VacuumDeformationExtensionType = VacuumDeformation; using EquationOfStateType = StructureEquationOfStateT; using SurfaceConstraintType = surface::CompiledPressureSurfaceConstraintT; template requires std::same_as< std::remove_cvref_t, Structure> explicit StellarModel( StructureArgument &&structurePrescription, const surface::ConstantPressureSurface surfaceCondition ) : StellarModel( std::forward(structurePrescription), surfaceCondition, deformation::NodalRadialSurface{defaultReferenceCenter()}, deformation::PowerLawRadialInteriorExtension{}, deformation::FixedInfinityRadialVacuumExtension{} ) { } template < typename StructureArgument, typename SurfaceDeformationArgument, typename StellarInteriorDeformationArgument, typename VacuumDeformationArgument> requires std::same_as< std::remove_cvref_t, Structure> && std::same_as< std::remove_cvref_t, SurfaceDeformation> && std::same_as< std::remove_cvref_t, StellarInteriorDeformation> && std::same_as< std::remove_cvref_t, VacuumDeformation> explicit StellarModel( StructureArgument &&structurePrescription, const surface::ConstantPressureSurface surfaceCondition, SurfaceDeformationArgument &&surfaceDeformation, StellarInteriorDeformationArgument &&stellarInteriorDeformation, VacuumDeformationArgument &&vacuumDeformation ) : m_structurePrescription( std::make_unique(std::forward(structurePrescription)) ), m_surfaceCondition(std::make_unique(surfaceCondition)), m_surfaceDeformation( std::make_unique(std::forward(surfaceDeformation)) ), m_stellarInteriorDeformation( std::make_unique( std::forward(stellarInteriorDeformation) ) ), m_vacuumDeformation( std::make_unique(std::forward(vacuumDeformation)) ), m_compiledSurfaceConstraint(std::make_unique(validateAndCompileConfiguration())) { } ~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 &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; } [[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; } [[nodiscard]] auto compileDomainDeformation(fem::FEM &finiteElementModel) const { return deformation::compileDomainDeformation( surfaceDeformationPrescription(), stellarInteriorDeformationExtension(), vacuumDeformationExtension(), finiteElementModel ); } private: [[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(); return surface::compilePressureSurfaceConstraint( *m_surfaceCondition, m_structurePrescription->equationOfState() ); } std::unique_ptr m_structurePrescription; std::unique_ptr m_surfaceCondition; std::unique_ptr m_surfaceDeformation; std::unique_ptr m_stellarInteriorDeformation; std::unique_ptr m_vacuumDeformation; std::unique_ptr m_compiledSurfaceConstraint; }; template StellarModel( Structure &&, surface::ConstantPressureSurface ) -> StellarModel< std::remove_cvref_t, 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, std::remove_cvref_t, std::remove_cvref_t, std::remove_cvref_t>; namespace detail { template struct IsStellarModel : std::false_type { }; template < typename Structure, typename SurfaceDeformation, typename StellarInteriorDeformation, typename VacuumDeformation> struct IsStellarModel< StellarModel> : 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()), m_surfaceDeformation(model.surfaceDeformationPrescription().descriptor()), m_stellarInteriorDeformation(model.stellarInteriorDeformationExtension().descriptor()), m_vacuumDeformation(model.vacuumDeformationExtension().descriptor()) { } [[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; } [[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; } 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; deformation::SurfaceDeformationDescriptor m_surfaceDeformation; deformation::InteriorDeformationExtensionDescriptor m_stellarInteriorDeformation; deformation::VacuumDeformationExtensionDescriptor m_vacuumDeformation; }; } // namespace mean_field::models