pressure_field_block.hpp cmath memory utility vector serif/backend/mfem/geometry/surface/boundary_rows.hpp serif/backend/mfem/operators/replaced_rows.hpp serif/utils/dependencies/key_list_operations.hpp src/include/serif/backend/mfem/model/computations/pressure_boundary.hpp serif serif::geometry serif::geometry::surface serif::geometry::surface::backend serif::geometry::surface::backend::mfem #pragmaonce #include<cmath> #include<memory> #include<utility> #include<vector> #include"serif/backend/mfem/geometry/surface/boundary_rows.hpp" #include"serif/backend/mfem/operators/replaced_rows.hpp" #include"serif/utils/dependencies/key_list_operations.hpp" namespaceserif::geometry::surface::backend::mfem{ template<typenameField,PressureBoundaryFormulationFormulation,typenameTraces> requiresutils::dependencies::ContainsKey<Field,typenameFormulation::StateTerms> [[nodiscard]]std::shared_ptr<const::mfem::SparseMatrix>pressure_field_trace(constPressureBoundary<Formulation, Traces>&boundary,conststd::vector<SurfaceLinearization<Formulation>>&linearizations){ usingnamespaceutils::errors; boundary.validate(); detail::validate_boundary_samples(boundary,linearizations); autoresult=std::make_shared<::mfem::SparseMatrix>(boundary.traces.templateget<Field>().interpolation()); ::mfem::Vectorderivatives(boundary.selected_rows->size()); for(introw=0;row<derivatives.Size();++row){ derivatives[row]=linearizations[row].field_derivatives.templateget<Field>(); serif_ensure<SERiFErrorCode::NON_FINITE_VALUE_ERROR>(std::isfinite(derivatives[row]),"Pressure-boundaryderivative{}isnonfinite.Supplyanacceptedsurfacelinearization.",row); } result->ScaleRows(derivatives); returnresult; } template<typenameField,PressureBoundaryFormulationFormulation,typenameTraces> [[nodiscard]]operators::backend::mfem::LinearizedBlockpressure_field_block(operators::backend::mfem::LinearizedBlockvolume,constPressureBoundary<Formulation, Traces>&boundary,conststd::vector<SurfaceLinearization<Formulation>>&linearizations){ usingnamespaceutils::errors; boundary.validate(); detail::validate_boundary_samples(boundary,linearizations); serif_ensure<SERiFErrorCode::MATRIX_SHAPE_ERROR>(volume.action()->Height()==boundary.selected_rows->binding().size(),"Theselectedphysicalblockandpressureboundarymustusethesamefullresidualcoordinatecount."); std::shared_ptr<const::mfem::SparseMatrix>replacement; ifconstexpr(utils::dependencies::ContainsKey<Field,typenameFormulation::StateTerms>){ replacement=pressure_field_trace<Field>(boundary,linearizations); serif_ensure<SERiFErrorCode::MATRIX_SHAPE_ERROR>(replacement->Width()==volume.action()->Width(),"Theselectedphysicalfieldanditspressuretracehavedifferentcoefficientcounts."); } else{ autozero=std::make_shared<::mfem::SparseMatrix>(boundary.selected_rows->size(),volume.action()->Width()); zero->Finalize(); replacement=std::move(zero); } const::mfem::Array<int>&selected=boundary.selected_rows->reduced_dofs(); returnoperators::backend::mfem::replace_block_rows(std::move(volume),std::vector<int>(selected.begin(),selected.end()),std::move(replacement)); } }//namespaceserif::geometry::surface::backend::mfem