volume.hpp algorithm array serif/backend/mfem/operators/actions.hpp serif/backend/mfem/operators/volume_application.hpp src/include/serif/backend/mfem/model/computations/interior.hpp serif serif::model serif::model::backend serif::model::backend::mfem #pragmaonce #include<algorithm> #include<array> #include"serif/backend/mfem/operators/actions.hpp" #include"serif/backend/mfem/operators/volume_application.hpp" namespaceserif::model::backend::mfem{ usingoperators::backend::mfem::LinearizedBlock; template<operators::VolumeEquationEquation,typenameSchema> [[nodiscard]]std::vector<double>volume_residual_values(conststd::shared_ptr<constoperators::backend::mfem::VolumeData<Equation,Schema>>&data){ usingnamespaceutils::errors; serif_ensure<SERiFErrorCode::INVALID_ARGUMENT>(data!=nullptr,"Modelassemblyrequiresanacceptedvolumeequation."); operators::backend::mfem::validate_volume_data(*data); returnstd::vector<double>(data->residual.GetData(),data->residual.GetData()+data->residual.Size()); } template<operators::VolumeEquationEquation,typenameSchema> [[nodiscard]]LinearizedBlockvolume_geometry_block(std::shared_ptr<constoperators::backend::mfem::VolumeData<Equation,Schema>>data){ usingnamespaceutils::errors; namespacevolume=operators::backend::mfem; serif_ensure<SERiFErrorCode::INVALID_ARGUMENT>(data!=nullptr,"Amodelgeometryblockrequiresanacceptedvolumeequation."); constintrows=volume::volume_height(*data); constintcolumns=data->configuration->discretization.displacement_binding.size(); returnoperators::backend::mfem::linearized_action(rows,columns,[data,workspace=volume::Workspace{}](const::mfem::Vector&input,::mfem::Vector&output)mutable{ conststd::array<const::mfem::Vector*,operators::EquationPlan<Equation>::column_count>directions{}; volume::apply_volume_direction<false>(*data,directions,input,workspace,output); },[data,columns,workspace=volume::Workspace{},packed=::mfem::Vector{}](const::mfem::Vector&input,::mfem::Vector&output)mutable{ volume::apply_jacobian_transpose(*data,input,workspace,packed); std::copy_n(packed.GetData()+packed.Size()-columns,columns,output.GetData()); },[data](std::span<const::mfem::Vector*const>inputs,std::span<::mfem::Vector*const>outputs){ volume::apply_volume_displacements(*data,inputs,outputs); }); } }//namespaceserif::model::backend::mfem