point_constraints.hpp limits memory tuple type_traits utility vector serif/discretization/blocks/system_layout.hpp serif/model/computations/interior.hpp serif/operators/backend/mfem/linearized_block.hpp serif/operators/backend/mfem/nodal_computations.hpp serif/operators/backend/mfem/point_border.hpp src/include/serif/model/backend/mfem/binding.hpp src/include/serif/model/graph.hpp serif::model::computations::PointConstraintContribution serif serif::model serif::model::computations #pragmaonce #include<limits> #include<memory> #include<tuple> #include<type_traits> #include<utility> #include<vector> #include"serif/discretization/blocks/system_layout.hpp" #include"serif/model/computations/interior.hpp" #include"serif/operators/backend/mfem/linearized_block.hpp" #include"serif/operators/backend/mfem/nodal_computations.hpp" #include"serif/operators/backend/mfem/point_border.hpp" namespaceserif::model::computations { template<typenameScope> structPointConstraintContribution { }; template<operators::backend::mfem::AffinePointEquationEquation,typenameDiscretization> [[nodiscard]]autopoint_constraint_discretization(constEquation&,constDiscretization&discretization) { returnoperators::backend::mfem::make_point_border_discretization<Equation>(discretization.templatebinding<typenameEquation::Test>(),discretization.templatebinding<typenameEquation::Border>()); } template<typenameScope,typenameEquation,typenameSchema,discretization::blocks::SystemLayoutTypeLayout> [[nodiscard]]autopoint_constraint_contribution(Layoutlayout) { usingnamespaceutils::dependencies; usingnamespacediscretization::blocks; namespaceexecution=operators::backend::mfem; usingCarrier=typenameEquation::Test; usingBorder=typenameEquation::Border; usingInput=typenameexecution::nodal_keys::Scoped<Scope>::BorderLinearization; returnmake_computation<PointConstraintContribution<Scope>,InputList<Input>>([layout](constexecution::PointBorderData<Equation,Schema>&data) { usingnamespaceutils::errors; constintcarrier_size=data.nodal.discretization.residual_binding.size(); serif_ensure<SERiFErrorCode::INVALID_DOF_COUNT>(layout.templatesize<RepresentedValueKind::value,Carrier>()==static_cast<std::size_t>(carrier_size)&& layout.templatesize<RepresentedValueKind::residual,Carrier>()==static_cast<std::size_t>(carrier_size)&&layout.templatesize<RepresentedValueKind::value,Border>()==1&& layout.templatesize<RepresentedValueKind::residual,Border>()==1,"Themodellayoutmustmatchthepointconstraint'scarriersize{}andonescalarborderoneachside.",carrier_size); serif_ensure<SERiFErrorCode::INVALID_DOF_COUNT>(layout.templatetotal_size<RepresentedValueKind::value>()<=std::numeric_limits<int>::max()&& layout.templatetotal_size<RepresentedValueKind::residual>()<=std::numeric_limits<int>::max(),"Thepointconstraintlayoutexceedsthebackend'ssupportedintegercoefficientcount."); ::mfem::Vectorcarrier(carrier_size),phase(1); carrier=0.0; execution::add_point_border_residual(data,carrier,phase); constintpoint=data.nodal.discretization.selected_rows->reduced_dofs()[0]; constdoublederivative=data.nodal.derivative(0,0); autoforce=std::make_shared<::mfem::SparseMatrix>(carrier_size,1); autoconstraint=std::make_shared<::mfem::SparseMatrix>(1,carrier_size); force->Add(point,0,derivative); constraint->Add(0,point,derivative); force->Finalize(); constraint->Finalize(); constintcarrier_row=static_cast<int>(layout.templateoffset<RepresentedValueKind::residual,Carrier>()); constintborder_row=static_cast<int>(layout.templateoffset<RepresentedValueKind::residual,Border>()); constintcarrier_column=static_cast<int>(layout.templateoffset<RepresentedValueKind::value,Carrier>()); constintborder_column=static_cast<int>(layout.templateoffset<RepresentedValueKind::value,Border>()); returnContributions { .residual={{carrier_row,std::vector<double>(carrier.GetData(),carrier.GetData()+carrier_size)},{border_row,{phase[0]}}}, .jacobian={{carrier_row,border_column,execution::linearized_block(std::shared_ptr<const::mfem::SparseMatrix>{std::move(force)})}, {border_row,carrier_column,execution::linearized_block(std::shared_ptr<const::mfem::SparseMatrix>{std::move(constraint)})}}, .replacements={} }; }); } template<typenameScope=void,operators::backend::mfem::AffinePointEquationEquation,typenameSchema,discretization::blocks::SystemLayoutTypeLayout> requiresutils::dependencies::ContainsKey<typenameEquation::Test,typenameLayout::Values>&& utils::dependencies::ContainsKey<typenameEquation::Test,typenameLayout::Residuals>&& utils::dependencies::ContainsKey<typenameEquation::Border,typenameLayout::Values>&& utils::dependencies::ContainsKey<typenameEquation::Border,typenameLayout::Residuals> [[nodiscard]]automake_point_constraint_computations(Equationequation,constoperators::backend::mfem::PointBorderDiscretization<Equation,Schema>&discretization,Layoutlayout) { usingPointScope=std::conditional_t<std::same_as<Scope,void>,typenameEquation::Border,Scope>; returnstd::tuple_cat(operators::backend::mfem::make_point_border_computations<PointScope>(std::move(equation),discretization), std::tuple{point_constraint_contribution<PointScope, Equation, Schema>(std::move(layout))}); } }//namespaceserif::model::computations