operators.hpp cstddef cstdint span mfem/linalg/operator.hpp mfem/linalg/vector.hpp serif/solver/normalization/diagonal.hpp src/compile_time_checks/serif/solver/normalization/algebra.cpp src/include/serif/backend/mfem/model/normalized_system.hpp src/lib/serif/backend/mfem/solver/normalization/operators.cpp serif::solver::normalization::backend::mfem::detail::ScaledOperator serif::solver::normalization::backend::mfem::ScaledPreconditionerStatistics serif::solver::normalization::backend::mfem::ScaledPreconditioner serif serif::solver serif::solver::normalization serif::solver::normalization::backend serif::solver::normalization::backend::mfem serif::solver::normalization::backend::mfem::detail #pragmaonce #include<cstddef> #include<cstdint> #include<span> #include"mfem/linalg/operator.hpp" #include"mfem/linalg/vector.hpp" #include"serif/solver/normalization/diagonal.hpp" namespaceserif::solver::normalization::backend::mfem { namespacedetail { [[nodiscard]]intmfem_size(std::size_tsize); voidscale_vector(std::span<constdouble>factors,const::mfem::Vector&input,::mfem::Vector&output,boolinverse); template<boolInverse> classScaledOperatorfinal:public::mfem::Operator { public: ScaledOperator(const::mfem::Operator&physical_operator,DiagonalNormalizationnormalization); ScaledOperator(::mfem::Operator&&,DiagonalNormalization)=delete; ScaledOperator(const::mfem::Operator&&,DiagonalNormalization)=delete; voidMult(const::mfem::Vector&input,::mfem::Vector&output)constoverride; voidMultTranspose(const::mfem::Vector&input,::mfem::Vector&output)constoverride; [[nodiscard]]const::mfem::Operator&physical_operator()constnoexcept { return*m_physical_operator; } [[nodiscard]]constDiagonalNormalization&normalization()constnoexcept { returnm_normalization; } private: [[nodiscard]]std::span<constdouble>input_factors()constnoexcept { returnInverse?m_normalization.residual_factors():m_normalization.state_factors(); } [[nodiscard]]std::span<constdouble>output_factors()constnoexcept { returnInverse?m_normalization.state_factors():m_normalization.residual_factors(); } const::mfem::Operator*constm_physical_operator; constDiagonalNormalizationm_normalization; mutable::mfem::Vectorm_physical_input; mutable::mfem::Vectorm_physical_output; }; externtemplateclassScaledOperator<false>; externtemplateclassScaledOperator<true>; } usingScaledJacobianOperator=detail::ScaledOperator<false>; usingScaledInverseOperator=detail::ScaledOperator<true>; structScaledPreconditionerStatisticsfinal { std::uint64_toperator_bindings{0}; std::uint64_tapplications{0}; }; classScaledPreconditionerfinal:public::mfem::Solver { public: ScaledPreconditioner(::mfem::Solver&physical_inverse,constScaledJacobianOperator&normalized_jacobian); ScaledPreconditioner(::mfem::Solver&,ScaledJacobianOperator&&)=delete; ScaledPreconditioner(::mfem::Solver&,constScaledJacobianOperator&&)=delete; voidSetOperator(const::mfem::Operator&normalized_jacobian)override; voidMult(const::mfem::Vector&input,::mfem::Vector&output)constoverride; voidMultTranspose(const::mfem::Vector&input,::mfem::Vector&output)constoverride; [[nodiscard]]constScaledPreconditionerStatistics&statistics()constnoexcept { returnm_statistics; } private: static::mfem::Solver&bind_physical_inverse(::mfem::Solver&inverse,constScaledJacobianOperator&jacobian); ::mfem::Solver*m_physical_inverse; constScaledJacobianOperator*m_normalized_jacobian; ScaledInverseOperatorm_scaled_inverse; mutableScaledPreconditionerStatisticsm_statistics; }; }