preconditioned_system.hpp concepts memory utility serif/backend/mfem/model/normalized_system.hpp serif/backend/mfem/solver/preconditioner/solver.hpp src/include/serif/backend/mfem/model/preconditioning/computations.hpp serif::model::backend::mfem::PreconditionedSystem serif serif::model serif::model::backend serif::model::backend::mfem #pragmaonce #include<concepts> #include<memory> #include<utility> #include"serif/backend/mfem/model/normalized_system.hpp" #include"serif/backend/mfem/solver/preconditioner/solver.hpp" namespaceserif::model::backend::mfem{ template<typenameSystem> requires(std::same_as<System,PhysicalSystem>||std::same_as<System,NormalizedSystem>) classPreconditionedSystemfinal{ public: PreconditionedSystem(std::shared_ptr<constSystem>system,solver::preconditioner::backend::mfem::Inverseinverse): m_system(checked_system(std::move(system))), m_physical_inverse(std::make_shared<solver::preconditioner::backend::mfem::Solver>(std::move(inverse),physical_jacobian())), m_inverse(make_solver()){ } [[nodiscard]]conststd::shared_ptr<constSystem>&system()constnoexcept{ returnm_system; } [[nodiscard]]::mfem::Solver&preconditioner()constnoexcept{ return*m_inverse; } [[nodiscard]]constsolver::preconditioner::backend::mfem::Solver&physical_preconditioner()constnoexcept{ return*m_physical_inverse; } [[nodiscard]]solver::preconditioner::ApplicationContractcontract()constnoexcept{ returnm_physical_inverse->contract(); } private: [[nodiscard]]staticstd::shared_ptr<constSystem>checked_system(std::shared_ptr<constSystem>system){ usingnamespaceutils::errors; serif_ensure<SERiFErrorCode::INVALID_ARGUMENT>(system!=nullptr, "Apreconditionedstellarsystemrequiresanevaluatedstar.PreparethematchingresidualandJacobianbeforebindingitsinverse."); returnsystem; } [[nodiscard]]autophysical_jacobian()const{ ifconstexpr(std::same_as<System,NormalizedSystem>){ returnm_system->physical()->jacobian().action(); }else{ returnm_system->jacobian().action(); } } [[nodiscard]]std::shared_ptr<::mfem::Solver>make_solver()const{ ifconstexpr(std::same_as<System,NormalizedSystem>){ returnstd::make_shared<solver::normalization::backend::mfem::ScaledPreconditioner>(*m_physical_inverse,m_system->jacobian()); }else{ returnm_physical_inverse; } } std::shared_ptr<constSystem>m_system; std::shared_ptr<solver::preconditioner::backend::mfem::Solver>m_physical_inverse; std::shared_ptr<::mfem::Solver>m_inverse; }; }