module; #include #include export module mean_field:equilibrium.stellar_discretization; export import :fem; export import :mapping.domain_mapper; export namespace mean_field::equilibrium { /* * An explicit, non-owning view of the numerical discretization used by a * stellar equilibrium problem. The referenced FEM and mapper must outlive * every problem and structure that uses this view. * * Ownership cannot move here yet because FEM currently also contains * mutable field workspaces. Separating those workspaces is a prerequisite * for shared discretization ownership by solved Structure objects. */ class StellarDiscretization final { public: explicit StellarDiscretization(fem::FEM &finiteElementModel) : StellarDiscretization( finiteElementModel, RequireDomainMapper(finiteElementModel) ) { } StellarDiscretization( fem::FEM &finiteElementModel, const mapping::DomainMapper &domainMapper ) : m_finiteElementModel(std::addressof(finiteElementModel)), m_domainMapper(std::addressof(domainMapper)) { if (!finiteElementModel.okay()) { throw std::invalid_argument("A stellar discretization requires a complete finite-element model."); } } [[nodiscard]] fem::FEM &finiteElementModel() const noexcept { return *m_finiteElementModel; } [[nodiscard]] const mapping::DomainMapper &domainMapper() const noexcept { return *m_domainMapper; } [[nodiscard]] bool isCurrent() const noexcept { return m_finiteElementModel != nullptr && m_domainMapper != nullptr && m_finiteElementModel->okay(); } private: [[nodiscard]] static const mapping::DomainMapper &RequireDomainMapper(const fem::FEM &finiteElementModel) { if (finiteElementModel.domainMapperStateless == nullptr) { throw std::invalid_argument("A stellar discretization requires a domain mapper."); } return *finiteElementModel.domainMapperStateless; } fem::FEM *m_finiteElementModel; const mapping::DomainMapper *m_domainMapper; }; } // namespace mean_field::equilibrium