Chi-Tech
mesh_orthomacros_02_unpartitioned.cc
Go to the documentation of this file.
1#include "mesh/chi_mesh.h"
2
6
8
9#include "chi_runtime.h"
10#include "chi_log.h"
11
12//###################################################################
13/**Creates a 1D slab mesh from a set of vertices.*/
14size_t chi_mesh::CreateUnpartitioned1DOrthoMesh(std::vector<double>& vertices)
15{
16 ChiLogicalErrorIf(vertices.empty(), "Empty vertex list.");
17
18 //======================================== Get current mesh handler
19 auto& handler = chi_mesh::GetCurrentHandler();
20
21 //======================================== Reorient 1D verts along z
22 std::vector<Vertex> zverts;
23 zverts.reserve(vertices.size());
24 for (double z_coord : vertices)
25 zverts.emplace_back(0.0,0.0,z_coord);
26
27 //======================================== Create unpartitioned mesh
28 auto umesh = std::make_shared<chi_mesh::UnpartitionedMesh>();
29
30 umesh->GetMeshAttributes() = DIMENSION_1 | ORTHOGONAL;
31
32 //======================================== Create vertices
33 size_t Nz = vertices.size();
34
35 umesh->GetMeshOptions().ortho_Nx = 1;
36 umesh->GetMeshOptions().ortho_Ny = 1;
37 umesh->GetMeshOptions().ortho_Nz = Nz-1;
38 umesh->GetMeshOptions().boundary_id_map[4] = "ZMAX";
39 umesh->GetMeshOptions().boundary_id_map[5] = "ZMIN";
40
41 umesh->GetVertices().reserve(Nz);
42 for (auto& vertex : zverts)
43 umesh->GetVertices().push_back(vertex);
44
45 //======================================== Create cells
46 for (size_t c=0; c<(zverts.size()-1); ++c)
47 {
48 auto cell = new UnpartitionedMesh::LightWeightCell(CellType::SLAB,
49 CellType::SLAB);
50
51 cell->vertex_ids = {c,c+1};
52
55
56 left_face.vertex_ids = {c};
57 rite_face.vertex_ids = {c+1};
58
59 if (c == 0) left_face.neighbor = 5/*ZMIN*/;
60 if (c == (zverts.size()-2)) rite_face.neighbor = 4/*ZMAX*/;
61
62 cell->faces.push_back(left_face);
63 cell->faces.push_back(rite_face);
64
65 umesh->AddCell(cell);
66 }
67
68 umesh->ComputeCentroidsAndCheckQuality();
69 umesh->BuildMeshConnectivity();
70
71 Chi::unpartitionedmesh_stack.push_back(umesh);
72
73 //======================================== Create meshers
74 handler.SetSurfaceMesher(std::make_shared<chi_mesh::SurfaceMesherPredefined>());
75 handler.SetVolumeMesher(std::make_shared<
77
78// handler.GetVolumeMesher().Execute();
79
80 return Chi::unpartitionedmesh_stack.size()-1;
81}
82
83//###################################################################
84/**Creates a 2D orthogonal mesh from a set of vertices in x and y.
85 * The vertices along a dimension merely represents the divisions. They
86 * are not the complete vertices defining a cell. For example:
87\code
88std::vector<chi_mesh::Vertex> vertices_x = {0.0,1.0,2.0};
89std::vector<chi_mesh::Vertex> vertices_y = {0.0,1.0,2.0};
90chi_mesh::CreateUnpartitioned2DOrthoMesh(vertices_x,vertices_y);
91\endcode
92
93This code will create a 2x2 mesh with \f$ \vec{x} \in [0,2]^2 \f$.
94
95 */
97 std::vector<double>& vertices_1d_x,
98 std::vector<double>& vertices_1d_y)
99{
100 ChiLogicalErrorIf(vertices_1d_x.empty() or vertices_1d_y.empty(),
101 "Empty vertex list.");
102
103 //======================================== Get current mesh handler
104 auto& handler = chi_mesh::GetCurrentHandler();
105
106 //======================================== Create unpartitioned mesh
107 auto umesh = std::make_shared<chi_mesh::UnpartitionedMesh>();
108
109 umesh->GetMeshAttributes() = DIMENSION_2 | ORTHOGONAL;
110
111 //======================================== Create vertices
112 size_t Nx = vertices_1d_x.size();
113 size_t Ny = vertices_1d_y.size();
114
115 umesh->GetMeshOptions().ortho_Nx = Nx-1;
116 umesh->GetMeshOptions().ortho_Ny = Ny-1;
117 umesh->GetMeshOptions().ortho_Nz = 1;
118 umesh->GetMeshOptions().boundary_id_map[0] = "XMAX";
119 umesh->GetMeshOptions().boundary_id_map[1] = "XMIN";
120 umesh->GetMeshOptions().boundary_id_map[2] = "YMAX";
121 umesh->GetMeshOptions().boundary_id_map[3] = "YMIN";
122
123 typedef std::vector<uint64_t> VecIDs;
124 std::vector<VecIDs> vertex_ij_to_i_map(Ny,VecIDs(Nx));
125 umesh->GetVertices().reserve(Nx * Ny);
126 uint64_t k=0;
127 for (size_t i=0; i<Ny; ++i)
128 {
129 for (size_t j=0; j<Nx; ++j)
130 {
131 vertex_ij_to_i_map[i][j] = k++;
132 umesh->GetVertices().emplace_back(vertices_1d_x[j],
133 vertices_1d_y[i],
134 0.0);
135 }//for j
136 }//for i
137
138 //======================================== Create cells
139 auto& vmap = vertex_ij_to_i_map;
140 for (size_t i=0; i<(Ny-1); ++i)
141 {
142 for (size_t j=0; j<(Nx-1); ++j)
143 {
144 auto cell =
145 new UnpartitionedMesh::LightWeightCell(CellType::POLYGON,
146 CellType::QUADRILATERAL);
147
148 // vertex ids: face ids:
149 // 2
150 // 3---2 x---x
151 // | | 3| |1
152 // 0---1 x---x
153 // 0
154
155 cell->vertex_ids = {vmap[i][j],vmap[i][j+1],vmap[i+1][j+1],vmap[i+1][j]};
156
157 for (int v=0; v<4; ++v)
158 {
160
161 if (v<3)
162 face.vertex_ids = std::vector<uint64_t>{cell->vertex_ids[v],
163 cell->vertex_ids[v+1]};
164 else
165 face.vertex_ids = std::vector<uint64_t>{cell->vertex_ids[v],
166 cell->vertex_ids[0]};
167
168 //boundary logic
169 if (j == (Nx-2) and v == 1) face.neighbor = 0/*XMAX*/;
170 if (j == 0 and v == 3) face.neighbor = 1/*XMIN*/;
171 if (i == (Ny-2) and v == 2) face.neighbor = 2/*YMAX*/;
172 if (i == 0 and v == 0) face.neighbor = 3/*YMIN*/;
173
174 cell->faces.push_back(face);
175 }
176
177 umesh->AddCell(cell);
178 }//for j
179 }//for i
180
181 umesh->ComputeCentroidsAndCheckQuality();
182 umesh->BuildMeshConnectivity();
183
184 Chi::unpartitionedmesh_stack.push_back(umesh);
185
186 //======================================== Create meshers
187 handler.SetSurfaceMesher(std::make_shared<chi_mesh::SurfaceMesherPredefined>());
188 handler.SetVolumeMesher(std::make_shared<
190
191 handler.GetSurfaceMesher().Execute();
192
193 return Chi::unpartitionedmesh_stack.size()-1;
194}
195
196//###################################################################
197/**Creates a 3D orthogonal mesh from a set of vertices in x,y,z.
198 * The vertices along a dimension merely represents the divisions. They
199 * are not the complete vertices defining a cell. For example:
200\code
201std::vector<chi_mesh::Vertex> vertices_x = {0.0,1.0,2.0};
202std::vector<chi_mesh::Vertex> vertices_y = {0.0,1.0,2.0};
203std::vector<chi_mesh::Vertex> vertices_z = {0.0,1.0,2.0};
204chi_mesh::CreateUnpartitioned3DOrthoMesh(vertices_x,vertices_y,vertices_z);
205\endcode
206
207This code will create a 2x2 mesh with \f$ \vec{x} \in [0,2]^2 \f$.
208
209 */
211 std::vector<double>& vertices_1d_x,
212 std::vector<double>& vertices_1d_y,
213 std::vector<double>& vertices_1d_z)
214{
215 ChiLogicalErrorIf(vertices_1d_x.empty() or
216 vertices_1d_y.empty() or
217 vertices_1d_z.empty(), "Empty vertex list.");
218
219 //======================================== Get current mesh handler
220 auto& handler = chi_mesh::GetCurrentHandler();
221
222 //======================================== Create unpartitioned mesh
223 auto umesh = std::make_shared<chi_mesh::UnpartitionedMesh>();
224
225 umesh->GetMeshAttributes() = DIMENSION_3 | ORTHOGONAL;
226
227 //======================================== Create vertices
228 size_t Nx = vertices_1d_x.size();
229 size_t Ny = vertices_1d_y.size();
230 size_t Nz = vertices_1d_z.size();
231
232 umesh->GetMeshOptions().ortho_Nx = Nx-1;
233 umesh->GetMeshOptions().ortho_Ny = Ny-1;
234 umesh->GetMeshOptions().ortho_Nz = Nz-1;
235 umesh->GetMeshOptions().boundary_id_map[0] = "XMAX";
236 umesh->GetMeshOptions().boundary_id_map[1] = "XMIN";
237 umesh->GetMeshOptions().boundary_id_map[2] = "YMAX";
238 umesh->GetMeshOptions().boundary_id_map[3] = "YMIN";
239 umesh->GetMeshOptions().boundary_id_map[4] = "ZMAX";
240 umesh->GetMeshOptions().boundary_id_map[5] = "ZMIN";
241
242 // i is j, and j is i, MADNESS explanation:
243 // In math convention the i-index refers to the ith row
244 // and the j-index refers to the jth row. We try to follow
245 // the same logic here.
246
247 typedef std::vector<uint64_t> VecIDs;
248 typedef std::vector<VecIDs> VecVecIDs;
249 std::vector<VecVecIDs> vertex_ijk_to_i_map(Ny);
250 for (auto& vec : vertex_ijk_to_i_map)
251 vec.resize(Nx,VecIDs(Nz));
252
253 umesh->GetVertices().reserve(Nx * Ny * Nz);
254 uint64_t c=0;
255 for (size_t i=0; i<Ny; ++i)
256 {
257 for (size_t j=0; j<Nx; ++j)
258 {
259 for (size_t k=0; k<Nz; ++k)
260 {
261 vertex_ijk_to_i_map[i][j][k] = c++;
262 umesh->GetVertices().emplace_back(vertices_1d_x[j],
263 vertices_1d_y[i],
264 vertices_1d_z[k]);
265 }//for k
266 }//for j
267 }//for i
268
269 //======================================== Create cells
270 auto& vmap = vertex_ijk_to_i_map;
271 for (size_t i=0; i<(Ny-1); ++i)
272 {
273 for (size_t j=0; j<(Nx-1); ++j)
274 {
275 for (size_t k=0; k<(Nz-1); ++k)
276 {
277 auto cell =
278 new UnpartitionedMesh::LightWeightCell(CellType::POLYHEDRON,
279 CellType::HEXAHEDRON);
280
281 cell->vertex_ids = std::vector<uint64_t>
282 {vmap[i ][j ][k],
283 vmap[i ][j+1][k],
284 vmap[i+1][j+1][k],
285 vmap[i+1][j ][k],
286
287 vmap[i ][j ][k+1],
288 vmap[i ][j+1][k+1],
289 vmap[i+1][j+1][k+1],
290 vmap[i+1][j ][k+1]};
291
292 //East face
293 {
295
296 face.vertex_ids = std::vector<uint64_t>
297 {vmap[i ][j+1][k],
298 vmap[i+1][j+1][k],
299 vmap[i+1][j+1][k+1],
300 vmap[i ][j+1][k+1]};
301 face.neighbor = 0/*XMAX*/;
302 cell->faces.push_back(face);
303 }
304 //West face
305 {
307
308 face.vertex_ids = std::vector<uint64_t>
309 {vmap[i ][j ][k],
310 vmap[i ][j ][k+1],
311 vmap[i+1][j ][k+1],
312 vmap[i+1][j ][k]};
313 face.neighbor = 1/*XMIN*/;
314 cell->faces.push_back(face);
315 }
316 //North face
317 {
319
320 face.vertex_ids = std::vector<uint64_t>
321 {vmap[i+1][j ][k],
322 vmap[i+1][j ][k+1],
323 vmap[i+1][j+1][k+1],
324 vmap[i+1][j+1][k]};
325 face.neighbor = 2/*YMAX*/;
326 cell->faces.push_back(face);
327 }
328 //South face
329 {
331
332 face.vertex_ids = std::vector<uint64_t>
333 {vmap[i ][j ][k],
334 vmap[i ][j+1][k],
335 vmap[i ][j+1][k+1],
336 vmap[i ][j ][k+1]};
337 face.neighbor = 3/*YMIN*/;
338 cell->faces.push_back(face);
339 }
340 //Top face
341 {
343
344 face.vertex_ids = std::vector<uint64_t>
345 {vmap[i ][j ][k+1],
346 vmap[i ][j+1][k+1],
347 vmap[i+1][j+1][k+1],
348 vmap[i+1][j ][k+1]};
349 face.neighbor = 4/*ZMAX*/;
350 cell->faces.push_back(face);
351 }
352 //Bottom face
353 {
355
356 face.vertex_ids = std::vector<uint64_t>
357 {vmap[i ][j ][k],
358 vmap[i+1][j ][k],
359 vmap[i+1][j+1][k],
360 vmap[i ][j+1][k]};
361 face.neighbor = 5/*ZMIN*/;
362 cell->faces.push_back(face);
363 }
364
365 umesh->AddCell(cell);
366 }//for k
367 }//for j
368 }//for i
369
370 umesh->ComputeCentroidsAndCheckQuality();
371 umesh->BuildMeshConnectivity();
372
373 Chi::unpartitionedmesh_stack.push_back(umesh);
374
375 //======================================== Create meshers
376 handler.SetSurfaceMesher(std::make_shared<chi_mesh::SurfaceMesherPredefined>());
377 handler.SetVolumeMesher(std::make_shared<
379
380 handler.GetSurfaceMesher().Execute();
381
382 return Chi::unpartitionedmesh_stack.size()-1;
383}
#define ChiLogicalErrorIf(condition, message)
static std::vector< chi_mesh::UnpartMeshPtr > unpartitionedmesh_stack
Definition: chi_runtime.h:88
size_t CreateUnpartitioned3DOrthoMesh(std::vector< double > &vertices_1d_x, std::vector< double > &vertices_1d_y, std::vector< double > &vertices_1d_z)
size_t CreateUnpartitioned1DOrthoMesh(std::vector< double > &vertices_1d)
@ DIMENSION_1
Definition: chi_mesh.h:72
@ DIMENSION_2
Definition: chi_mesh.h:73
@ ORTHOGONAL
Definition: chi_mesh.h:75
@ DIMENSION_3
Definition: chi_mesh.h:74
MeshHandler & GetCurrentHandler()
size_t CreateUnpartitioned2DOrthoMesh(std::vector< double > &vertices_1d_x, std::vector< double > &vertices_1d_y)