physical_blocks.hpp array limits tuple serif/backend/mfem/model/system.hpp serif/model/keys.hpp serif/operators/linearized_system_view.hpp serif/utils/dependencies/computation.hpp src/include/serif/backend/mfem/model/preconditioning/computations.hpp serif serif::model serif::model::computations serif::model::computations::detail #pragmaonce #include<array> #include<limits> #include<tuple> #include"serif/backend/mfem/model/system.hpp" #include"serif/model/keys.hpp" #include"serif/operators/linearized_system_view.hpp" #include"serif/utils/dependencies/computation.hpp" namespaceserif::model::computations{ namespacedetail{ template<typenameLayout,typename...Rows,typename...Fields> [[nodiscard]]autophysical_block(constbackend::mfem::PhysicalSystem&system,constLayout&layout, utils::dependencies::KeyList<Rows...>,utils::dependencies::KeyList<Fields...>){ usingKind=discretization::blocks::RepresentedValueKind; static_assert(sizeof...(Rows)>0&&sizeof...(Fields)>0,"Selectatleastoneequationandonephysicalcoordinateforasolverblock."); conststd::arrayrows{backend::mfem::CoordinateRange{static_cast<int>(layout.templateoffset<Kind::residual,Rows>()),static_cast<int>(layout.templatesize<Kind::residual,Rows>())}...}; conststd::arraycolumns{backend::mfem::CoordinateRange{static_cast<int>(layout.templateoffset<Kind::value,Fields>()),static_cast<int>(layout.templatesize<Kind::value,Fields>())}...}; returnsystem.block(rows,columns); } } template<typenameBlock,discretization::blocks::SystemLayoutTypeLayout> [[nodiscard]]autophysical_block(constLayout&layout){ usingnamespaceutils::dependencies; usingnamespaceutils::errors; usingKind=discretization::blocks::RepresentedValueKind; serif_ensure<SERiFErrorCode::INVALID_DOF_COUNT>(layout.templatetotal_size<Kind::residual>()<=std::numeric_limits<int>::max()&& layout.templatetotal_size<Kind::value>()<=std::numeric_limits<int>::max(),"PhysicalsolverblockcoordinatesexceedMFEM'sintegerindexrange.Supplyarepresentablesystemlayout."); returnmake_computation<Block,InputList<keys::PhysicalSystem>>([layout](conststd::shared_ptr<constbackend::mfem::PhysicalSystem>&system){ serif_ensure<SERiFErrorCode::INVALID_ARGUMENT>(system!=nullptr,"Physicalsolverblocksrequireanevaluatedstellarsystem."); serif_ensure<SERiFErrorCode::MATRIX_SHAPE_ERROR>(layout.templatetotal_size<Kind::residual>()==static_cast<std::size_t>(system->jacobian().action()->Height())&& layout.templatetotal_size<Kind::value>()==static_cast<std::size_t>(system->jacobian().action()->Width()),"Therequestedsolverblocklayoutdoesnotmatchitsfrozenphysicalsystem.Usethatsystem'scoordinatedescription."); returndetail::physical_block(*system,layout,typenameBlock::Rows{},typenameBlock::Values{}); }); } template<discretization::blocks::SystemLayoutTypeLayout,typename...Blocks> [[nodiscard]]automake_physical_block_computations(constLayout&layout,utils::dependencies::KeyList<Blocks...>){ returnstd::tuple{physical_block<Blocks>(layout)...}; } }