deformation.hpp limits span utility serif/geometry/deformation/linearization.hpp serif/model/backend/mfem/actions.hpp serif/utils/error/errors.hpp src/include/serif/model/computations/shape.hpp src/include/serif/model/computations/shape_derivatives.hpp src/lib/serif/model/backend/mfem/deformation.cpp serif::model::backend::mfem::ShapeDerivatives serif serif::discretization serif::discretization::backend serif::discretization::backend::mfem serif::model serif::model::backend serif::model::backend::mfem serif::model::backend::mfem::detail #pragmaonce #include<limits> #include<span> #include<utility> #include"serif/geometry/deformation/linearization.hpp" #include"serif/model/backend/mfem/actions.hpp" #include"serif/utils/error/errors.hpp" namespaceserif::discretization::backend::mfem { classDofMap; } namespaceserif::model::backend::mfem { [[nodiscard]]LinearizedBlockdisplacement_projection(constdiscretization::backend::mfem::DofMap&binding); template<typenameDeformation> structShapeDerivatives { std::shared_ptr<constDeformation>deformation; LinearizedBlockprojection; LinearizedBlocktangent; }; namespacedetail { template<geometry::deformation::DeformationMapMap> voidvalidate_deformation(conststd::shared_ptr<constgeometry::deformation::DeformationLinearization<Map>>&state) { usingnamespaceutils::errors; serif_ensure<SERiFErrorCode::INVALID_ARGUMENT>(state&&state->map,"Amodelshapeactionrequiresanaccepteddeformationmap."); serif_ensure<SERiFErrorCode::INVALID_DOF_COUNT>(state->map->input_size()<=static_cast<std::size_t>(std::numeric_limits<int>::max())&&state->map->output_size()<=static_cast<std::size_t>(std::numeric_limits<int>::max()),"DeformationcoordinatecountsexceedtheMFEMintegerrange."); serif_ensure<SERiFErrorCode::INVALID_DOF_COUNT>(state->parameters.size()==state->map->input_size(),"Theaccepteddeformationmustcontaineveryshapecoordinate."); } voidrequire_deformation_action(constgeometry::deformation::DeformationStatus&status); }//namespacedetail template<geometry::deformation::DeformationMapMap> [[nodiscard]]LinearizedBlockdeformation_tangent(std::shared_ptr<constgeometry::deformation::DeformationLinearization<Map>>state) { detail::validate_deformation(state); constintrows=static_cast<int>(state->map->output_size()); constintcolumns=static_cast<int>(state->map->input_size()); returnlinearized_action(rows,columns,[state,workspace=std::make_shared<geometry::deformation::DeformationWorkspace<Map>>(geometry::deformation::make_deformation_workspace(*state->map))](const::mfem::Vector&input,::mfem::Vector&output)mutable { detail::require_deformation_action(geometry::deformation::apply_jacobian(*state,std::span<constdouble>(input.GetData(),input.Size()),std::span<double>(output.GetData(),output.Size()),*workspace)); },[state,workspace=std::make_shared<geometry::deformation::DeformationWorkspace<Map>>(geometry::deformation::make_deformation_workspace(*state->map))](const::mfem::Vector&input,::mfem::Vector&output)mutable { detail::require_deformation_action(geometry::deformation::apply_jacobian_transpose(*state,std::span<constdouble>(input.GetData(),input.Size()),std::span<double>(output.GetData(),output.Size()),*workspace)); }); } template<geometry::deformation::DeformationMapMap> [[nodiscard]]LinearizedBlockdeformation_curvature(std::shared_ptr<constgeometry::deformation::DeformationLinearization<Map>>state,std::vector<double>force) { usingnamespaceutils::errors; detail::validate_deformation(state); serif_ensure<SERiFErrorCode::INVALID_DOF_COUNT>(force.size()==state->map->output_size(),"Ashapepullbackrequiresoneforcecoefficientperdisplacementcoordinate."); constintsize=static_cast<int>(state->map->input_size()); autoaction=[state,force=std::move(force),workspace=std::make_shared<geometry::deformation::DeformationWorkspace<Map>>(geometry::deformation::make_deformation_workspace(*state->map))](const::mfem::Vector&input,::mfem::Vector&output)mutable { detail::require_deformation_action(geometry::deformation::apply_pullback_derivative(*state,std::span<constdouble>(input.GetData(),input.Size()),force,std::span<double>(output.GetData(),output.Size()),*workspace)); }; returnlinearized_action(size,size,action,action); } }//namespaceserif::model::backend::mfem