interior.hpp memory optional tuple utility serif/backend/mfem/model/system.hpp serif/backend/mfem/model/volume_actions.hpp serif/backend/mfem/model/volume.hpp serif/backend/mfem/model/computations/shape_derivatives.hpp serif/backend/mfem/model/computations/scalar_row.hpp serif/backend/mfem/operators/volume_computations.hpp serif/backend/mfem/operators/volume_field_block.hpp src/include/serif/backend/mfem/model/computations/potential_infinity.hpp src/include/serif/backend/mfem/model/computations/pressure_boundary.hpp src/include/serif/backend/mfem/model/computations/surface_potential.hpp src/include/serif/backend/mfem/model/graph.hpp serif::model::computations::InteriorContribution serif::model::computations::Contributions serif serif::model serif::model::computations #pragmaonce #include<memory> #include<optional> #include<tuple> #include<utility> #include"serif/backend/mfem/model/system.hpp" #include"serif/backend/mfem/model/volume_actions.hpp" #include"serif/backend/mfem/model/volume.hpp" #include"serif/backend/mfem/model/computations/shape_derivatives.hpp" #include"serif/backend/mfem/model/computations/scalar_row.hpp" #include"serif/backend/mfem/operators/volume_computations.hpp" #include"serif/backend/mfem/operators/volume_field_block.hpp" namespaceserif::model::computations{ template<typenameRow> structInteriorContribution{ }; structContributionsfinal{ std::vector<backend::mfem::ResidualContribution>residual; std::vector<backend::mfem::JacobianContribution>jacobian; std::vector<backend::mfem::RowReplacement>replacements; std::optional<std::vector<backend::mfem::JacobianContribution>>actions; }; template<typenameEquation,typenameSchema,typenameLayout> [[nodiscard]]Contributionsvolume_contribution(std::shared_ptr<constoperators::backend::mfem::VolumeData<Equation, Schema>>accepted, constLayout&layout,std::optional<backend::mfem::ColumnContribution>geometry={}){ usingnamespaceutils::dependencies; usingnamespacediscretization::blocks; namespaceexecution=operators::backend::mfem; usingRow=typenameEquation::Test; constintrow_offset=static_cast<int>(layout.templateoffset<RepresentedValueKind::residual,Row>()); Contributionsresult; result.residual.push_back({row_offset,std::vector<double>(accepted->residual.GetData(),accepted->residual.GetData()+accepted->residual.Size())}); operators::EquationPlan<Equation>::for_each_column([&]<typenameColumn>(Column,std::size_t){ usingField=typenameColumn::term_type; ifconstexpr(ContainsKey<Field,typenameLayout::Values>){ result.jacobian.push_back({row_offset,static_cast<int>(layout.templateoffset<RepresentedValueKind::value,Field>()),execution::volume_field_block<Field>(accepted)}); } }); if(geometry){ result.jacobian.push_back({row_offset,geometry->column_offset,serif::operators::backend::mfem::compose_blocks(backend::mfem::volume_geometry_block(accepted),geometry->block)}); } result.actions=std::vector<backend::mfem::JacobianContribution>{{row_offset,0,backend::mfem::volume_row_action(accepted,layout,geometry)}}; returnresult; } template<typenameEquation,typenameLayout> [[nodiscard]]autointerior_contribution(Layoutlayout){ usingnamespaceutils::dependencies; usingnamespacediscretization::blocks; namespaceexecution=operators::backend::mfem; usingRow=typenameEquation::Test; usingVolume=typenameexecution::volume_keys::Scoped<Row>::Linearization; ifconstexpr(GlobalScalarTerm<Row>){ returnmake_owning_computation<InteriorContribution<Row>,InputList<Volume,ScalarResidualRow<Row>>>([layout](constauto&volume,constauto&row){ constintoffset=static_cast<int>(layout.templateoffset<RepresentedValueKind::residual,Row>()); returnContributions{ .residual={{offset,std::vector<double>(volume->residual.GetData(),volume->residual.GetData()+volume->residual.Size())}}, .jacobian={{offset,0,*row}} }; }); }elseifconstexpr(ContainsKey<surface_deformation::coefficients,typenameLayout::Values>){ returnmake_owning_computation<InteriorContribution<Row>,InputList<Volume,ShapeDerivatives>>([layout](constauto&volume,constauto&shape){ returnvolume_contribution(volume,layout,backend::mfem::ColumnContribution{ static_cast<int>(layout.templateoffset<RepresentedValueKind::value,surface_deformation::coefficients>()),shape->tangent}); }); } else{ returnmake_owning_computation<InteriorContribution<Row>,InputList<Volume>>([layout](constauto&volume){ returnvolume_contribution(volume,layout); }); } } template<typenameEquation,typenameLayout> [[nodiscard]]autointerior_computations(constLayout&layout){ ifconstexpr(discretization::blocks::GlobalScalarTerm<typenameEquation::Test>){ returnstd::tuple{scalar_residual_row<Equation>(layout),interior_contribution<Equation>(layout)}; }else{ returnstd::tuple{interior_contribution<Equation>(layout)}; } } }//namespaceserif::model::computations