boundary_faces.hpp vector mfem/mesh/mesh.hpp mfem/mesh/ncmesh.hpp serif/utils/error/errors.hpp src/lib/serif/backend/mfem/discretization/reconstruction.cpp serif serif::discretization serif::discretization::backend serif::discretization::backend::mfem #pragmaonce #include<vector> #include"mfem/mesh/mesh.hpp" #include"mfem/mesh/ncmesh.hpp" #include"serif/utils/error/errors.hpp" namespaceserif::discretization::backend::mfem{ [[nodiscard]]inlinestd::vector<int>boundary_leaf_faces(::mfem::Mesh&mesh,constintattribute){ usingnamespaceutils::errors; std::vector<int>labels(mesh.GetNumFaces(),0); for(intboundary=0;boundary<mesh.GetNBE();++boundary){ constintface=mesh.GetBdrElementFaceIndex(boundary); constintlabel=mesh.GetBdrAttribute(boundary); serif_ensure<SERiFErrorCode::INVALID_ARGUMENT>(labels[face]==0||labels[face]==label, "Aweakboundaryfacehasconflictingexplicitboundarylabels."); labels[face]=label; } std::vector<int>child_count(mesh.GetNumFaces(),0); if(mesh.ncmesh!=nullptr){ constauto&faces=mesh.ncmesh->GetFaceList(); for(constauto&slave:faces.slaves){ if(labels[slave.master]!=attribute){continue;} serif_ensure<SERiFErrorCode::INVALID_ARGUMENT>(labels[slave.index]==0||labels[slave.index]==attribute, "Aselectedcoarseboundarylabelconflictswithanexplicitleaflabel."); labels[slave.index]=attribute; ++child_count[slave.master]; } } std::vector<int>result; for(intface=0;face<mesh.GetNumFaces();++face){ if(labels[face]!=attribute){continue;} if(mesh.GetFaceInformation(face).tag==::mfem::Mesh::FaceInfoTag::MasterNonconforming){ serif_ensure<SERiFErrorCode::INVALID_ARGUMENT>(child_count[face]>0, "Aselectednonconformingmasterfacehasnophysicalleaffaces."); continue; } result.push_back(face); } returnresult; } }