MFEM v4.7.0
Finite element discretization library
Loading...
Searching...
No Matches
submesh.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2024, 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"
15
16namespace 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
31SubMesh::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_[GetBdrElementFaceIndex(i)]];
69 if (pbeid != -1)
70 {
71 int attr = parent.GetBdrElement(pbeid)->GetAttribute();
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_[GetBdrElementFaceIndex(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
184 parent_fes->FEColl()->GetOrder(),
185 parent_fes->IsDGSpace(),
186 spaceDim,
187 parent_fes->GetOrdering());
188
189 Transfer(*parent.GetNodes(), *GetNodes());
190 }
191
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
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
Definition array.cpp:68
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition array.hpp:697
void SetAttribute(const int attr)
Set element's attribute.
Definition element.hpp:58
int GetAttribute() const
Return element's attribute.
Definition element.hpp:55
Class for grid function - Vector with associated FE space.
Definition gridfunc.hpp:31
Mesh data type.
Definition mesh.hpp:56
void GetBdrElementFace(int i, int *f, int *o) const
Definition mesh.cpp:7252
void InitMesh(int Dim_, int spaceDim_, int NVert, int NElem, int NBdrElem)
Begin construction of a mesh.
Definition mesh.cpp:1635
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
Definition mesh.hpp:282
static int GetQuadOrientation(const int *base, const int *test)
Returns the orientation of "test" relative to "base".
Definition mesh.cpp:6533
int NumOfBdrElements
Definition mesh.hpp:71
void GetBdrElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of boundary element i.
Definition mesh.hpp:1442
void GetElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of element i.
Definition mesh.hpp:1438
Array< int > GetFaceToBdrElMap() const
Definition mesh.cpp:1477
int Dim
Definition mesh.hpp:68
bool Nonconforming() const
Definition mesh.hpp:2229
int GetBdrElementFaceIndex(int be_idx) const
Return the local face (codimension-1) index for the given boundary element index.
Definition mesh.hpp:1518
static int GetTriOrientation(const int *base, const int *test)
Returns the orientation of "test" relative to "base".
Definition mesh.cpp:6444
void FinalizeTopology(bool generate_bdr=true)
Finalize the construction of the secondary topology (connectivity) data of a Mesh.
Definition mesh.cpp:3135
int Dimension() const
Dimension of the reference space used within the elements.
Definition mesh.hpp:1160
const Element * GetBdrElement(int i) const
Return pointer to the i'th boundary element object.
Definition mesh.hpp:1298
int SpaceDimension() const
Dimension of the physical space containing the mesh.
Definition mesh.hpp:1163
void GetNodes(Vector &node_coord) const
Definition mesh.cpp:8973
static int ComposeTriOrientations(int ori_a_b, int ori_b_c)
Definition mesh.cpp:6504
int NumOfElements
Definition mesh.hpp:71
void GetFaceVertices(int i, Array< int > &vert) const
Returns the indices of the vertices of face i.
Definition mesh.hpp:1456
int NumOfFaces
Definition mesh.hpp:72
int spaceDim
Definition mesh.hpp:69
virtual void Finalize(bool refine=false, bool fix_orientation=false)
Finalize the construction of a general Mesh.
Definition mesh.cpp:3241
GridFunction * GetNodes()
Return a pointer to the internal node GridFunction (may be NULL).
Definition mesh.hpp:2093
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:6211
virtual void SetAttributes()
Determine the sets of unique attribute values in domain and boundary elements.
Definition mesh.cpp:1604
Subdomain representation of a topological parent in another Mesh.
Definition submesh.hpp:43
static SubMesh CreateFromBoundary(const Mesh &parent, Array< int > boundary_attributes)
Create a surface SubMesh from its parent.
Definition submesh.cpp:25
static void Transfer(const GridFunction &src, GridFunction &dst)
Transfer the dofs of a GridFunction.
Definition submesh.cpp:198
static SubMesh CreateFromDomain(const Mesh &parent, Array< int > domain_attributes)
Create a domain SubMesh from its parent.
Definition submesh.cpp:19
static TransferMap CreateTransferMap(const GridFunction &src, const GridFunction &dst)
Create a Transfer Map object.
Definition submesh.cpp:204
SubMesh()=delete
TransferMap represents a mapping of degrees of freedom from a source GridFunction to a destination Gr...
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,...
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...
std::function< real_t(const Vector &)> f(real_t mass_coeff)
Definition lor_mms.hpp:30