computations.hpp concepts memory tuple type_traits utility serif/backend/mfem/model/preconditioned_system.hpp serif/backend/mfem/model/computations/physical_blocks.hpp serif/backend/mfem/model/computations/solver_layout.hpp serif/backend/mfem/geometry/deformation/computations.hpp serif/backend/mfem/solver/preconditioner/graph.hpp src/include/serif/backend/mfem/model/equilibrium_evaluator.hpp serif::model::preconditioning::PreparedSystem serif serif::model serif::model::preconditioning serif::model::preconditioning::detail #pragmaonce #include<concepts> #include<memory> #include<tuple> #include<type_traits> #include<utility> #include"serif/backend/mfem/model/preconditioned_system.hpp" #include"serif/backend/mfem/model/computations/physical_blocks.hpp" #include"serif/backend/mfem/model/computations/solver_layout.hpp" #include"serif/backend/mfem/geometry/deformation/computations.hpp" #include"serif/backend/mfem/solver/preconditioner/graph.hpp" namespaceserif::model::preconditioning{ structPreparedSystemfinal{}; namespacedetail{ template<typenameComputation,typename...Existing> [[nodiscard]]automissing_computation(Computationcomputation,conststd::tuple<Existing...>&){ ifconstexpr((std::same_as<typenameComputation::Key,typenameExisting::Key>||...)){ returnstd::tuple{}; }else{ returnstd::tuple{std::move(computation)}; } } } template<typenameResultKey,typenameRecipe,typenameLayout,typename...Existing> [[nodiscard]]automake_computations(constRecipe&recipe,constLayout&layout,conststd::tuple<Existing...>&existing){ usingnamespaceutils::dependencies; namespacenumerical=solver::preconditioner; constautoinverse=numerical::make_preconditioner_computations(recipe,layout); usingGraph=decltype(std::apply([](auto...computations){ returnmake_computation_graph(std::move(computations)...); },inverse)); usingPhysicalKeys=typenamenumerical::computations::detail::PhysicalSources<typenameGraph::Inputs>::Type; constautoshared_layout=std::apply([&](autocomputation){ returndetail::missing_computation(std::move(computation),existing); },computations::make_solver_layout_computations(layout)); constautoprepared=make_computation<PreparedSystem,InputList<ResultKey,numerical::keys::Preconditioner>>( [](constauto&system,constnumerical::backend::mfem::Inverse&inverse){ usingSystem=std::remove_const_t<typenamestd::remove_cvref_t<decltype(system)>::element_type>; returnstd::make_shared<constbackend::mfem::PreconditionedSystem<System>>(system,inverse); }); returnstd::tuple_cat(inverse,shared_layout, computations::make_physical_block_computations(layout,PhysicalKeys{}),std::tuple{prepared}); } }