/* *********************************************************************** // // Copyright (C) 2025 -- The 4D-STAR Collaboration // File Author: Emily Boudreaux // Last Modified: April 21, 2025 // // 4DSSE is free software; you can use it and/or modify // it under the terms and restrictions the GNU General Library Public // License version 3 (GPLv3) as published by the Free Software Foundation. // // 4DSSE is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU Library General Public License for more details. // // You should have received a copy of the GNU Library General Public License // along with this software; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // *********************************************************************** */ #pragma once #include "mfem.hpp" #include "4DSTARTypes.h" #include #include "probe.h" class PolytropeOperator final : public mfem::Operator { public: PolytropeOperator( std::unique_ptr M, std::unique_ptr Q, std::unique_ptr D, std::unique_ptr f, const mfem::Array &blockOffsets); ~PolytropeOperator() override = default; void Mult(const mfem::Vector &x, mfem::Vector &y) const override; mfem::Operator& GetGradient(const mfem::Vector &x) const override; void SetEssentialTrueDofs(const SSE::MFEMArrayPair& theta_ess_tdofs, const SSE::MFEMArrayPair& phi_ess_tdofs); void SetEssentialTrueDofs(const SSE::MFEMArrayPairSet& ess_tdof_pair_set); SSE::MFEMArrayPairSet GetEssentialTrueDofs() const; bool isFinalized() const { return m_isFinalized; } void finalize(const mfem::Vector &initTheta); const mfem::Array& GetBlockOffsets() const { return m_blockOffsets; } const mfem::BlockOperator &GetJacobianOperator() const; mfem::BlockDiagonalPreconditioner &GetPreconditioner() const; private: Probe::LogManager& m_logManager = Probe::LogManager::getInstance(); quill::Logger* m_logger = m_logManager.getLogger("log"); std::unique_ptr m_M; std::unique_ptr m_Q; std::unique_ptr m_D; std::unique_ptr m_f; const mfem::Array m_blockOffsets; SSE::MFEMArrayPair m_theta_ess_tdofs; SSE::MFEMArrayPair m_phi_ess_tdofs; std::unique_ptr m_Mmat, m_Qmat, m_Dmat; std::unique_ptr m_negM_op; std::unique_ptr m_negQ_op; mutable std::unique_ptr m_jacobian; mutable std::unique_ptr m_invSchurCompliment; mutable std::unique_ptr m_invNonlinearJacobian; /* * The schur preconditioner has the form * * ⎡ḟ(θ)^-1 0 ⎤ * ⎣ 0 S^-1 ⎦ * * Where S is the Schur compliment of the system * */ mutable std::unique_ptr m_schurPreconditioner; bool m_isFinalized = false; private: void updateInverseNonlinearJacobian(const mfem::Operator &grad) const; void updateInverseSchurCompliment() const; void updatePreconditioner(const mfem::Operator &grad) const; };