module; #include #include #include #include export module mean_field:operators.prepared_gravity_source; export import :fem; export import :field.mfem; export import :mapping.domain_mapper; export namespace mean_field::operators { class PreparedMappedGravitySourceOperator final : public mfem::Operator { public: PreparedMappedGravitySourceOperator( const fem::FEM &f, const mapping::DomainMapper &domain_mapper ); void Prepare(const mfem::Vector &displacement); void Mult( const mfem::Vector &density, mfem::Vector &action ) const override; [[nodiscard]] bool IsPrepared() const noexcept; [[nodiscard]] std::uint64_t GetPreparationCount() const noexcept; [[nodiscard]] const field::FieldDofMap &GetDensityMap() const noexcept; [[nodiscard]] const field::FieldDofMap &GetPotentialMap() const noexcept; [[nodiscard]] const field::FieldDofMap &GetDisplacementMap() const noexcept; void MultTranspose( const mfem::Vector &potential, mfem::Vector &action ) const override; private: struct ElementPAData { int element_id{-1}; mfem::Array density_dofs; mfem::Array potential_dofs; mfem::DofTransformation *density_dof_transformation{nullptr}; mfem::DofTransformation *potential_dof_transformation{nullptr}; // Rows are quadrature points; columns are element DOFs. mfem::DenseMatrix density_basis; mfem::DenseMatrix potential_basis; // Contains quadrature weight, mesh Jacobian, mapped Jacobian, // and 4*pi*G. mfem::Vector quadrature_data; }; const fem::FEM &m_fem; const mapping::DomainMapper &m_domain_mapper; field::FieldDofMap m_density_map; field::FieldDofMap m_potential_map; field::FieldDofMap m_displacement_map; mfem::Array m_stellar_marker; std::vector m_elements; mutable mfem::Vector m_density_true; mutable mfem::Vector m_potential_true; mutable mfem::Vector m_action_true; mfem::Vector m_displacement_true; std::uint64_t m_preparation_count{0}; bool m_is_prepared{false}; }; } // namespace mean_field::operators