topology.cpp serif/discretization/domain/mesh/topology.hpp mfem.hpp serif serif::discretization serif::discretization::domain serif::discretization::domain::mesh #include"serif/discretization/domain/mesh/topology.hpp" #include<mfem.hpp> namespaceserif::discretization::domain::mesh{ conststd::vector<int>MeshTopology::s_noElements{}; namespace{ [[nodiscard]]std::size_tas_index(constintid)noexcept{ returnstatic_cast<std::size_t>(id); } [[nodiscard]]boolin_range(constintid,conststd::size_tsize)noexcept{ returnid>=0&&as_index(id)<size; } } MeshTopology::MeshTopology(constmfem::Mesh&mesh) :m_elementDomainIDs(as_index(mesh.GetNE()),0), m_faceElements(as_index(mesh.GetNumFaces())), m_elementNeighbors(as_index(mesh.GetNE())), m_boundaryElementBoundaryIDs(as_index(mesh.GetNBE()),0), m_boundaryElementFaceIDs(as_index(mesh.GetNBE()),-1), m_boundaryElementsByFace(as_index(mesh.GetNumFaces())){ //Whichdomaineachvolumeelementclaimstobelongto. for(intelementID=0;elementID<mesh.GetNE();++elementID){ m_elementDomainIDs[as_index(elementID)]=mesh.GetAttribute(elementID); } //Faceconnectivity. for(intfaceID=0;faceID<mesh.GetNumFaces();++faceID){ intfirstElementID=-1; intsecondElementID=-1; mesh.GetFaceElements(faceID,&firstElementID,&secondElementID); m_faceElements[as_index(faceID)]=FaceElements{ .firstElementID=firstElementID, .secondElementID=secondElementID }; if(firstElementID<0||secondElementID<0){ continue; } m_elementNeighbors[as_index(firstElementID)].push_back(secondElementID); m_elementNeighbors[as_index(secondElementID)].push_back(firstElementID); } //Boundaryelements for(intboundaryElementID=0;boundaryElementID<mesh.GetNBE();++boundaryElementID){ m_boundaryElementBoundaryIDs[as_index(boundaryElementID)]=mesh.GetBdrAttribute(boundaryElementID); constintfaceID=mesh.GetBdrElementFaceIndex(boundaryElementID); m_boundaryElementFaceIDs[as_index(boundaryElementID)]=faceID; if(in_range(faceID,m_boundaryElementsByFace.size())){ m_boundaryElementsByFace[as_index(faceID)].push_back(boundaryElementID); } } } intMeshTopology::element_count()constnoexcept{ returnstatic_cast<int>(m_elementDomainIDs.size()); } intMeshTopology::face_count()constnoexcept{ returnstatic_cast<int>(m_faceElements.size()); } intMeshTopology::boundary_element_count()constnoexcept{ returnstatic_cast<int>(m_boundaryElementBoundaryIDs.size()); } intMeshTopology::element_domain_id(constintelementID)const{ if(!in_range(elementID,m_elementDomainIDs.size())){ return0; } returnm_elementDomainIDs[as_index(elementID)]; } intMeshTopology::boundary_element_boundary_id(constintboundaryElementID)const{ if(!in_range(boundaryElementID,m_boundaryElementBoundaryIDs.size())){ return0; } returnm_boundaryElementBoundaryIDs[as_index(boundaryElementID)]; } FaceElementsMeshTopology::face_elements(constintfaceID)const{ if(!in_range(faceID,m_faceElements.size())){ returnFaceElements{}; } returnm_faceElements[as_index(faceID)]; } conststd::vector<int>&MeshTopology::element_neighbors(constintelementID)const{ if(!in_range(elementID,m_elementNeighbors.size())){ returns_noElements; } returnm_elementNeighbors[as_index(elementID)]; } intMeshTopology::boundary_element_face(constintboundaryElementID)const{ if(!in_range(boundaryElementID,m_boundaryElementFaceIDs.size())){ return-1; } returnm_boundaryElementFaceIDs[as_index(boundaryElementID)]; } conststd::vector<int>&MeshTopology::boundary_elements_on_face(constintfaceID)const{ if(!in_range(faceID,m_boundaryElementsByFace.size())){ returns_noElements; } returnm_boundaryElementsByFace[as_index(faceID)]; } }