coupling.hpp serif/backend/mfem/operators/linearized_block.hpp serif/solver/preconditioner/recipes/coupled.hpp serif/solver/preconditioner/recipes/bordered.hpp serif/backend/mfem/solver/preconditioner/coupling.hpp serif/backend/mfem/solver/preconditioner/border.hpp serif/utils/dependencies/computation.hpp src/include/serif/backend/mfem/solver/preconditioner/graph.hpp serif serif::solver serif::solver::preconditioner serif::solver::preconditioner::computations #pragmaonce #include"serif/backend/mfem/operators/linearized_block.hpp" #include"serif/solver/preconditioner/recipes/coupled.hpp" #include"serif/solver/preconditioner/recipes/bordered.hpp" #include"serif/backend/mfem/solver/preconditioner/coupling.hpp" #include"serif/backend/mfem/solver/preconditioner/border.hpp" #include"serif/utils/dependencies/computation.hpp" namespaceserif::solver::preconditioner::computations { template<typenameFirst,typenameSecond,typenamePolicy> [[nodiscard]]autocoupling(constCoupledPreconditioner<First, Second, Policy>&) { usingnamespaceutils::dependencies; usingRecipe=CoupledPreconditioner<First, Second, Policy>; usingInverse=backend::mfem::Inverse; usingBlock=operators::backend::mfem::LinearizedBlock; static_assert(Policy::order==strategies::coupling::CouplingOrder::second_then_first,"Recipescouplesubsystemssecond-then-first."); returnmake_computation<typenameRecipe::Result,InputList<typenameFirst::Result,typenameSecond::Result,keys::Block<typenameFirst::Rows,typenameSecond::Values>>>( [](constInverse&first,constInverse&second,constBlock&first_from_second) { returnbackend::mfem::try_coupled_inverse(first,second,{first_from_second.action(),nullptr},Policy::order); }); } template<typenameFields,typenameConstraints> [[nodiscard]]autoborder(constBorderedPreconditioner<Fields, Constraints>&choice) { usingnamespaceutils::dependencies; usingRecipe=BorderedPreconditioner<Fields, Constraints>; usingBlock=operators::backend::mfem::LinearizedBlock; returnmake_computation<typenameRecipe::Result,InputList<typenameFields::Result,keys::Block<typenameFields::Rows,typenameConstraints::Values>,keys::Block<typename Constraints::Rows, typename Fields::Values>,keys::Block<typename Constraints::Rows, typename Constraints::Values>>>( [options=choice.constraint_inverse](constbackend::mfem::Inverse&fields,constBlock&columns,constBlock&rows,constBlock&diagonal) { returnbackend::mfem::try_bordered_inverse(fields,{columns.action(),rows.action()},diagonal.action(),options); }); } }//namespaceserif::solver::preconditioner::computations