dof_selection.hpp serif/backend/mfem/discretization/term_binding.hpp serif/backend/mfem/discretization/dof_map.hpp src/include/serif/backend/mfem/discretization/boundary_trace.hpp src/include/serif/backend/mfem/model/computations/potential_infinity.hpp src/include/serif/backend/mfem/model/normalization/computations.hpp src/include/serif/backend/mfem/solver/seed/state.hpp serif::discretization::backend::mfem::DofSelection serif serif::discretization serif::discretization::backend serif::discretization::backend::mfem This file contains the DofSelection which allows for the selection of a subset of DOFs from a term binding, with boundary attribute information. Emily M. Boudreaux #pragmaonce #include"serif/backend/mfem/discretization/term_binding.hpp" #include"serif/backend/mfem/discretization/dof_map.hpp" namespaceserif::discretization::backend::mfem{ classDofSelectionfinal{ public: DofSelection( constDofMap&binding, const::mfem::Array<int>&reduced_dofs, constbooltrack_coordinates=false ): m_binding(binding), m_dofs(reduced_dofs), m_boundary_attributes(binding.mesh().GetNBE()), m_nodes_sequence(track_coordinates?binding.mesh().GetNodesSequence():-1){ usingnamespaceutils::errors; binding.validate(); intprevious=-1; for(constintdof:m_dofs){ serif_ensure<SERiFErrorCode::INVALID_DOF_COUNT,std::invalid_argument>(dof>previous&&dof<binding.size(),"SelectedDOFsmustbesorted,unique,andinsidethetermbinding."); previous=dof; } for(intboundary=0;boundary<m_boundary_attributes.Size();++boundary){ m_boundary_attributes[boundary]=binding.mesh().GetBdrAttribute(boundary); } } [[nodiscard]]constDofMap&binding()constnoexcept{returnm_binding;} [[nodiscard]]const::mfem::Array<int>&reduced_dofs()constnoexcept{returnm_dofs;} [[nodiscard]]intsize()constnoexcept{returnm_dofs.Size();} [[nodiscard]]const::mfem::Array<int>&boundary_attributes()constnoexcept{returnm_boundary_attributes;} [[nodiscard]]booltracks_coordinates()constnoexcept{returnm_nodes_sequence>=0;} voidvalidate()const{ usingnamespaceutils::errors; m_binding.validate(); constauto&mesh=m_binding.mesh(); serif_ensure<SERiFErrorCode::CACHE_FE_BINDING_ERROR,std::logic_error>(m_nodes_sequence<0||mesh.GetNodesSequence()==m_nodes_sequence,"Rebuildpointselectionsafterfixed-meshcoordinatechanges."); serif_ensure<SERiFErrorCode::CACHE_FE_BINDING_ERROR,std::logic_error>(mesh.GetNBE()==m_boundary_attributes.Size(),"RebuildDOFselectionsafterboundarychanges."); for(intboundary=0;boundary<m_boundary_attributes.Size();++boundary){ serif_ensure<SERiFErrorCode::CACHE_FE_BINDING_ERROR,std::logic_error>(mesh.GetBdrAttribute(boundary)==m_boundary_attributes[boundary],"RebuildDOFselectionsafterboundaryattributeschange."); } } private: constDofMap&m_binding; ::mfem::Array<int>m_dofs; ::mfem::Array<int>m_boundary_attributes; longm_nodes_sequence; }; template<domain::IsBoundaryBoundaryT,blocks::SpatialTermTermT,domain::schema::IsSchemaSchemaT> [[nodiscard]]DofSelectionselect_boundary_dofs( constTermBinding<TermT, SchemaT>&binding ){ usingnamespaceutils::errors; static_assert(SchemaT::templatecontains_boundary<BoundaryT>(),"Theboundarymustberegisteredinthedomainschema."); binding.validate(); ::mfem::Array<int>marker(binding.size()); marker=0; ::mfem::Array<int>dofs; ::mfem::Array<int>selected; auto&space=binding.space(); constauto&mesh=binding.mesh(); for(intboundary=0;boundary<mesh.GetNBE();++boundary){ if(!SchemaT::templateboundary_id_matches<BoundaryT>(mesh.GetBdrAttribute(boundary))){ continue; } space.GetBdrElementVDofs(boundary,dofs); for(constintencoded:dofs){ boolsupported=false; binding.for_each_coefficient(::mfem::FiniteElementSpace::DecodeDof(encoded),[&](constintindex,constdouble){ marker[index]=1; supported=true; }); serif_ensure<SERiFErrorCode::INVALID_DOMAIN_ERROR,std::invalid_argument>(supported,"AselectedboundaryDOFliesoutsidetheterm'ssupport."); } } ::mfem::FiniteElementSpace::MarkerToList(marker,selected); serif_ensure<SERiFErrorCode::INVALID_DOMAIN_ERROR,std::invalid_argument>(selected.Size()>0,"TherequestedboundaryhasnoDOFsonthisserialmesh."); returnDofSelection(binding,selected); } }//namespaceserif::discretization::backend::mfem