physical_blocks.hpp expected serif/backend/mfem/operators/linearized_block.hpp serif/solver/preconditioner/failure.hpp serif/solver/preconditioner/keys.hpp serif/utils/dependencies/computation.hpp src/include/serif/backend/mfem/solver/preconditioner/computations/inverse.hpp serif serif::solver serif::solver::preconditioner serif::solver::preconditioner::computations #pragmaonce #include<expected> #include"serif/backend/mfem/operators/linearized_block.hpp" #include"serif/solver/preconditioner/failure.hpp" #include"serif/solver/preconditioner/keys.hpp" #include"serif/utils/dependencies/computation.hpp" namespaceserif::solver::preconditioner::computations { template<typenameRows,typenameValues> [[nodiscard]]autophysical_diagonal() { usingnamespaceutils::dependencies; returnmake_computation<keys::Diagonal<Rows,Values>,InputList<keys::Block<Rows,Values>>>( [](constoperators::backend::mfem::LinearizedBlock&block)->std::expected<std::vector<double>,Failure> { if(!block.has_diagonal()||block.action()->Height()!=block.action()->Width()) { returnstd::unexpected(Failure{utils::errors::SERiFErrorCode::PRECONDITIONER_INCOMPATIBLE_STRATEGY, "Thisinverseneedsasquarephysicalblockwithanefficientdiagonalextractor.Supplythematchingfieldblock."}); } std::vector<double>diagonal=block.diagonal(); if(diagonal.size()!=static_cast<std::size_t>(block.action()->Height())) { returnstd::unexpected(Failure{utils::errors::SERiFErrorCode::PRECONDITIONER_SIZE_MISMATCH, "Thephysicaldiagonaldoesnotmatchitsacceptedoperator.Correcttheselectedblockextractor."}); } returndiagonal; }); } template<typenameRows,typenameValues> [[nodiscard]]autophysical_matrix() { usingnamespaceutils::dependencies; returnmake_computation<keys::Matrix<Rows,Values>,InputList<keys::Block<Rows,Values>>>( [](constoperators::backend::mfem::LinearizedBlock&block)->std::expected<std::shared_ptr<const::mfem::SparseMatrix>,Failure> { if(!block.has_assembly()) { returnstd::unexpected(Failure{utils::errors::SERiFErrorCode::PRECONDITIONER_INCOMPATIBLE_STRATEGY, "Thisinverseneedsaselectedsparsematrix.Supplythephysicalblock'sassemblerorchooseamatrix-freeinverse."}); } automatrix=block.assemble(); if(!matrix||matrix->Height()!=block.action()->Height()||matrix->Width()!=block.action()->Width()) { returnstd::unexpected(Failure{utils::errors::SERiFErrorCode::PRECONDITIONER_SIZE_MISMATCH, "Selectedsparseassemblydoesnotmatchitsacceptedaction.Correcttheblockassembler."}); } returnmatrix; }); } }//namespaceserif::solver::preconditioner::computations namespaceserif::solver::preconditioner{ template<typenameRow,typenameField> [[nodiscard]]autophysical_block(operators::backend::mfem::LinearizedBlockblock) { usingnamespaceutils::dependencies; returnown<keys::Block<KeyList<Row>,KeyList<Field>>>(std::move(block)); } }