MFEM  v4.6.0
Finite element discretization library
submesh.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2023, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-806117.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability visit https://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #include "submesh.hpp"
13 #include "submesh_utils.hpp"
14 #include "../../fem/gridfunc.hpp"
15 
16 namespace mfem
17 {
18 
20  Array<int> domain_attributes)
21 {
22  return SubMesh(parent, From::Domain, domain_attributes);
23 }
24 
26  Array<int> boundary_attributes)
27 {
28  return SubMesh(parent, From::Boundary, boundary_attributes);
29 }
30 
31 SubMesh::SubMesh(const Mesh &parent, From from,
32  Array<int> attributes) : parent_(parent), from_(from), attributes_(attributes)
33 {
34  if (Nonconforming())
35  {
36  MFEM_ABORT("SubMesh does not support non-conforming meshes");
37  }
38 
39  if (from == From::Domain)
40  {
41  InitMesh(parent.Dimension(), parent.SpaceDimension(), 0, 0, 0);
42 
43  std::tie(parent_vertex_ids_,
44  parent_element_ids_) = SubMeshUtils::AddElementsToMesh(parent_, *this,
45  attributes_);
46  }
47  else if (from == From::Boundary)
48  {
49  InitMesh(parent.Dimension() - 1, parent.SpaceDimension(), 0, 0, 0);
50 
51  std::tie(parent_vertex_ids_,
52  parent_element_ids_) = SubMeshUtils::AddElementsToMesh(parent_, *this,
53  attributes_, true);
54  }
55 
56  FinalizeTopology(true);
57 
58  if (Dim == 3)
59  {
60  parent_face_ids_ = SubMeshUtils::BuildFaceMap(parent, *this,
61  parent_element_ids_);
62 
63  Array<int> parent_face_to_be = parent.GetFaceToBdrElMap();
64  int max_bdr_attr = parent.bdr_attributes.Max();
65 
66  for (int i = 0; i < NumOfBdrElements; i++)
67  {
68  int pbeid = parent_face_to_be[parent_face_ids_[GetBdrFace(i)]];
69  if (pbeid != -1)
70  {
71  int attr = parent.GetBdrElement(pbeid)->GetAttribute();
72  GetBdrElement(i)->SetAttribute(attr);
73  }
74  else
75  {
76  // This case happens when a domain is extracted, but the root parent
77  // mesh didn't have a boundary element on the surface that defined
78  // it's boundary. It still creates a valid mesh, so we allow it.
79  GetBdrElement(i)->SetAttribute(max_bdr_attr + 1);
80  }
81  }
82 
83  parent_face_ori_.SetSize(NumOfFaces);
84 
85  for (int i = 0; i < NumOfFaces; i++)
86  {
87  Array<int> sub_vert;
88  GetFaceVertices(i, sub_vert);
89 
90  Array<int> sub_par_vert(sub_vert.Size());
91  for (int j = 0; j < sub_vert.Size(); j++)
92  {
93  sub_par_vert[j] = parent_vertex_ids_[sub_vert[j]];
94  }
95 
96  Array<int> par_vert;
97  parent.GetFaceVertices(parent_face_ids_[i], par_vert);
98 
99  if (par_vert.Size() == 3)
100  {
101  parent_face_ori_[i] = GetTriOrientation(par_vert, sub_par_vert);
102  }
103  else
104  {
105  parent_face_ori_[i] = GetQuadOrientation(par_vert, sub_par_vert);
106  }
107  }
108  }
109  else if (Dim == 2)
110  {
111  if (from == From::Domain)
112  {
113  parent_edge_ids_ = SubMeshUtils::BuildFaceMap(parent, *this,
114  parent_element_ids_);
115  Array<int> parent_face_to_be = parent.GetFaceToBdrElMap();
116  int max_bdr_attr = parent.bdr_attributes.Max();
117 
118  for (int i = 0; i < NumOfBdrElements; i++)
119  {
120  int pbeid = parent_face_to_be[parent_edge_ids_[GetBdrFace(i)]];
121  if (pbeid != -1)
122  {
123  int attr = parent.GetBdrElement(pbeid)->GetAttribute();
124  GetBdrElement(i)->SetAttribute(attr);
125  }
126  else
127  {
128  // This case happens when a domain is extracted, but the root parent
129  // mesh didn't have a boundary element on the surface that defined
130  // it's boundary. It still creates a valid mesh, so we allow it.
131  GetBdrElement(i)->SetAttribute(max_bdr_attr + 1);
132  }
133  }
134  }
135 
136  parent_face_ori_.SetSize(NumOfElements);
137 
138  for (int i = 0; i < NumOfElements; i++)
139  {
140  Array<int> sub_vert;
141  GetElementVertices(i, sub_vert);
142 
143  Array<int> sub_par_vert(sub_vert.Size());
144  for (int j = 0; j < sub_vert.Size(); j++)
145  {
146  sub_par_vert[j] = parent_vertex_ids_[sub_vert[j]];
147  }
148 
149  Array<int> par_vert;
150  int be_ori = 0;
151  if (from == From::Boundary)
152  {
153  parent.GetBdrElementVertices(parent_element_ids_[i], par_vert);
154 
155  int f = -1;
156  parent.GetBdrElementFace(parent_element_ids_[i], &f, &be_ori);
157  }
158  else
159  {
160  parent.GetElementVertices(parent_element_ids_[i], par_vert);
161  }
162 
163  if (par_vert.Size() == 3)
164  {
165  int se_ori = GetTriOrientation(par_vert, sub_par_vert);
166  parent_face_ori_[i] = ComposeTriOrientations(be_ori, se_ori);
167  }
168  else
169  {
170  parent_face_ori_[i] = GetQuadOrientation(par_vert, sub_par_vert);
171  }
172  }
173  }
174 
175  // If the parent Mesh has nodes and therefore is defined on a higher order
176  // geometry, we define this SubMesh as a curved Mesh and transfer the
177  // GridFunction from the parent Mesh to the SubMesh.
178  const GridFunction *parent_nodes = parent.GetNodes();
179  if (parent_nodes)
180  {
181  const FiniteElementSpace *parent_fes = parent_nodes->FESpace();
182 
183  SetCurvature(
184  parent_fes->FEColl()->GetOrder(),
185  parent_fes->IsDGSpace(),
186  spaceDim,
187  parent_fes->GetOrdering());
188 
189  Transfer(*parent.GetNodes(), *GetNodes());
190  }
191 
192  SetAttributes();
193  Finalize();
194 }
195 
197 
199 {
200  TransferMap map(src, dst);
201  map.Transfer(src, dst);
202 }
203 
205  const GridFunction &dst)
206 {
207  return TransferMap(src, dst);
208 }
209 
210 } // namespace mfem
Array< int > GetFaceToBdrElMap() const
Definition: mesh.cpp:1445
Class for grid function - Vector with associated FE space.
Definition: gridfunc.hpp:30
int Dimension() const
Dimension of the reference space used within the elements.
Definition: mesh.hpp:1020
static SubMesh CreateFromDomain(const Mesh &parent, Array< int > domain_attributes)
Create a domain SubMesh from its parent.
Definition: submesh.cpp:19
void Transfer(const GridFunction &src, GridFunction &dst) const
Transfer the source GridFunction to the destination GridFunction.
int GetAttribute() const
Return element&#39;s attribute.
Definition: element.hpp:55
bool Nonconforming() const
Definition: mesh.hpp:1969
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
Definition: array.cpp:68
int NumOfElements
Definition: mesh.hpp:69
void GetBdrElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of boundary element i.
Definition: mesh.hpp:1297
static int GetQuadOrientation(const int *base, const int *test)
Returns the orientation of "test" relative to "base".
Definition: mesh.cpp:5951
std::function< double(const Vector &)> f(double mass_coeff)
Definition: lor_mms.hpp:30
void GetBdrElementFace(int i, int *f, int *o) const
Return the index and the orientation of the face of bdr element i. (3D)
Definition: mesh.cpp:6565
virtual void SetAttributes()
Determine the sets of unique attribute values in domain and boundary elements.
Definition: mesh.cpp:1572
TransferMap represents a mapping of degrees of freedom from a source GridFunction to a destination Gr...
Definition: transfermap.hpp:31
virtual void SetCurvature(int order, bool discont=false, int space_dim=-1, int ordering=1)
Set the curvature of the mesh nodes using the given polynomial degree.
Definition: mesh.cpp:5635
void GetFaceVertices(int i, Array< int > &vert) const
Returns the indices of the vertices of face i.
Definition: mesh.hpp:1311
void GetElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of element i.
Definition: mesh.hpp:1293
int NumOfBdrElements
Definition: mesh.hpp:69
int GetBdrFace(int BdrElemNo) const
Return the local face index for the given boundary face.
Definition: mesh.cpp:1120
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
Definition: mesh.hpp:275
std::tuple< Array< int >, Array< int > > AddElementsToMesh(const Mesh &parent, Mesh &mesh, const Array< int > &attributes, bool from_boundary)
Given a Mesh parent and another Mesh mesh using the list of attributes in attributes, this function adds matching elements with those attributes from parent to mesh.
void FinalizeTopology(bool generate_bdr=true)
Finalize the construction of the secondary topology (connectivity) data of a Mesh.
Definition: mesh.cpp:2945
GridFunction * GetNodes()
Return a pointer to the internal node GridFunction (may be NULL).
Definition: mesh.hpp:1853
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition: array.hpp:687
Array< int > BuildFaceMap(const Mesh &pm, const Mesh &sm, const Array< int > &parent_element_ids)
Given two meshes that have a parent to SubMesh relationship create a face map, using a SubMesh to par...
void InitMesh(int Dim_, int spaceDim_, int NVert, int NElem, int NBdrElem)
Begin construction of a mesh.
Definition: mesh.cpp:1603
int SpaceDimension() const
Dimension of the physical space containing the mesh.
Definition: mesh.hpp:1023
virtual void Finalize(bool refine=false, bool fix_orientation=false)
Finalize the construction of a general Mesh.
Definition: mesh.cpp:3042
static void Transfer(const GridFunction &src, GridFunction &dst)
Transfer the dofs of a GridFunction.
Definition: submesh.cpp:198
static TransferMap CreateTransferMap(const GridFunction &src, const GridFunction &dst)
Create a Transfer Map object.
Definition: submesh.cpp:204
Subdomain representation of a topological parent in another Mesh.
Definition: submesh.hpp:42
void SetAttribute(const int attr)
Set element&#39;s attribute.
Definition: element.hpp:58
static SubMesh CreateFromBoundary(const Mesh &parent, Array< int > boundary_attributes)
Create a surface SubMesh from its parent.
Definition: submesh.cpp:25
int Dim
Definition: mesh.hpp:66
static int GetTriOrientation(const int *base, const int *test)
Returns the orientation of "test" relative to "base".
Definition: mesh.cpp:5862
void GetNodes(Vector &node_coord) const
Definition: mesh.cpp:8302
int spaceDim
Definition: mesh.hpp:67
const Element * GetBdrElement(int i) const
Return pointer to the i&#39;th boundary element object.
Definition: mesh.hpp:1158
SubMesh()=delete
static int ComposeTriOrientations(int ori_a_b, int ori_b_c)
Definition: mesh.cpp:5922
int NumOfFaces
Definition: mesh.hpp:70