IOSS 2.0
Loading...
Searching...
No Matches
Iogn_GeneratedMesh.h
Go to the documentation of this file.
1// Copyright(C) 1999-2024 National Technology & Engineering Solutions
2// of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
3// NTESS, the U.S. Government retains certain rights in this software.
4//
5// See packages/seacas/LICENSE for details
6
7#pragma once
8
9#include "Ioss_CodeTypes.h"
10#include "Ioss_EntityType.h" // for EntityType
11#include <array>
12#include <cstddef> // for size_t
13#include <cstdint> // for int64_t
14#include <map> // for map, etc
15#include <string> // for string
16#include <utility> // for pair
17#include <vector> // for vector
18
19#include "iogn_export.h"
20
21namespace Iogn {
22 class IOGN_EXPORT GeneratedMesh
23 {
24 public:
25 enum ShellLocation { MX = 0, PX = 1, MY = 2, PY = 3, MZ = 4, PZ = 5 };
26
27 /**
28 Generate a cube mesh of size `num_x` by `num_y` by `num_z` elements.
29 By default, the mesh is generated on a single processor. If `proc_count` is
30 greater than 1, then the mesh will be distributed over `proc_count` processors
31 and this process will get the portion of the mesh for `my_proc`.
32 The mesh will be decomposed along the `Z` axis so `num_z` must be greater than
33 or equal to `proc_count` and for even distribution of the hexes `num_z` mod `proc_count`
34 should be zero.
35
36 The mesh can optionally include shell elements along each face of the cube mesh.
37 These are specified via the `add_shell_block` function.
38
39 The mesh can optionally include nodesets/sidesets along each
40 face of the cube mesh. These are specified via the
41 `add_nodesets` and `add_sidesets` functions.
42
43 If the `parameters` string constructor is used, the string
44 is parsed to determine the intervals in each direction and,
45 optionally, additional information. The form of the string
46 is "IxJxK" where I, J, and K are the number of intervals
47 in the X, Y, and Z directions respectively and the "x" are
48 literal `x` characters. For example, the constructor
49 GeneratedMesh("10x12x14") will create the same mesh as
50 GeneratedMesh(10,12,14)
51
52 Additional valid options are:
53 - `help` -- no argument, shows valid options
54 - `show` -- no argument, prints out a summary of the
55 GeneratedMesh() parameters. The output will look similar
56 to:
57 ```
58 10x12x8|shell:xX|bbox:-10,-10,-10,10,10,10|nodeset:xyz|sideset:XYZ|show
59
60 Mesh Parameters:
61 Intervals: 10 by 12 by 8
62 X = 2 * (0..10) + -10 Range: -10 <= X <= 10
63 Y = 1.66667 * (0..12) + -10 Range: -10 <= Y <= 10
64 Z = 2.5 * (0..8) + -10 Range: -10 <= Z <= 10
65 Node Count (total) = 1287
66 Element Count (total) = 1152
67 Block Count = 3
68 NodeSet Count = 3
69 SideSet Count = 3
70 ```
71
72 - `tets` -- no argument - specifies that each hex should be
73 split into 6 tetrahedral elements. Cannot currently be used with
74 shells or sidesets.
75
76 - `pyramids` -- no argument - specifies that each hex should be
77 split into 6 pyramidal elements.
78
79 - `shell` -- argument = xXyYzZ which specifies whether there is a shell
80 block at that location. `x` is minimum x face, `X` is maximum x face,
81 similarly for y and z. Note that the argument string is a single
82 multicharacter string. You can add multiple shell blocks to a face,
83 for example, shell:xxx would add three layered shell blocks on the
84 minimum x face. An error is output if a non xXyYzZ character is
85 found, but execution continues.
86
87 - `nodeset` -- argument = xXyYzZ which specifies whether there is
88 a nodeset at that location. `x` is minimum x face, `X` is
89 maximum x face, similarly for y and z. Note that the argument
90 string is a single multicharacter string. You can add multiple
91 nodesets to a face, for example, nodeset:xxx would add three
92 nodesets on the minimum x face. An error is output if a non
93 xXyYzZ character is found, but execution continues.
94
95 - `sideset` -- argument = xXyYzZ which specifies whether there is
96 a sideset at that location. `x` is minimum x face, `X` is
97 maximum x face, similarly for y and z. Note that the argument
98 string is a single multicharacter string. You can add multiple
99 sidesets to a face, for example, sideset:xxx would add three
100 sidesets on the minimum x face. An error is output if a non
101 xXyYzZ character is found, but execution continues. If there
102 is a shell block specified on that face, then the sideset will
103 be on the shell elements; else the sideset will be on the hex
104 elements.
105
106 - `zdecomp` -- argument = n0, n1, n2, ..., n#proc-1 which are the number
107 of intervals in the z direction for each processor in a pallel run.
108 If this option is specified, then the total number of intervals in the
109 z direction is the sum of the n0, n1, ... An interval count must be
110 specified for each processor. If this option is not specified, then
111 the number of intervals on each processor in the z direction is
112 numZ/numProc with the extras added to the lower numbered processors.
113
114 - `scale` -- argument = xs, ys, zs which are the scale factors in the x,
115 y, and z directions. All three must be specified if this option is
116 present.
117
118 - `offset` -- argument = xoff, yoff, zoff which are the offsets in the
119 x, y, and z directions. All three must be specified if this option
120 is present.
121
122 - `bbox` -- argument = xmin, ymin, zmin, xmax, ymax, zmax
123 which specify the lower left and upper right corners of
124 the bounding box for the generated mesh. This will
125 calculate the scale and offset which will fit the mesh in
126 the specified box. All calculations are based on the currently
127 active interval settings. If scale or offset or zdecomp
128 specified later in the option list, you may not get the
129 desired bounding box.
130
131 - `rotate` -- argument = axis,angle,axis,angle,...
132 where axis is `x`, `y`, or `z` and angle is the rotation angle in
133 degrees. Multiple rotations are cumulative. The composite rotation
134 matrix is applied at the time the coordinates are retrieved after
135 scaling and offset are applied.
136
137 The unrotated coordinate of a node at grid location i,j,k is:
138 \code
139 x = x_scale * i + x_off,
140 y = z_scale * j + y_off,
141 z = z_scale * k + z_off,
142 \endcode
143
144 The extent of the unrotated mesh will be:
145 \code
146 x_off <= x <= x_scale * numX + x_off
147 y_off <= y <= y_scale * numY + y_off
148 z_off <= z <= z_scale * numZ + z_off
149 \endcode
150
151 If an unrecognized option is specified, an error message will be
152 output and execution will continue.
153
154 An example of valid input is:
155 `"10x20x40|scale:1,0.5,0.25|offset:-5,-5,-5|shell:xX"`
156
157 This would create a mesh with 10 intervals in x, 20 in y, 40 in z
158 The mesh would be centered on 0,0,0 with a range of 10 in each
159 direction. There would be a shell layer on the min and max
160 x faces.
161
162 NOTE: All options are processed in the order they appear in
163 the parameters string (except rotate which is applied at the
164 time the coordinates are generated/retrieved)
165 */
166 explicit GeneratedMesh(const std::string &parameters, int proc_count = 1, int my_proc = 0);
167 GeneratedMesh(int64_t num_x, int64_t num_y, int64_t num_z, int proc_count = 1, int my_proc = 0);
169 GeneratedMesh(const GeneratedMesh &) = delete;
171 virtual ~GeneratedMesh() = default;
172
173 /**
174 * Split each hexahedral element into 6 tetrahedral elements.
175 * Cannot currently be used with sidesets or shells.
176 */
177 void create_tets(bool yesno);
178
179 /**
180 * Split each hexahedral element into 6 pyramidal elements.
181 * Cannot currently be used with sidesets or shells.
182 */
183 void create_pyramids(bool yesno);
184
185 /**
186 * Add a shell block along the specified face of the hex mesh.
187 * The shell blocks will maintain the order of definition. The
188 * first shell block defined will be block 2; the hex block has id
189 * 1. The loc options are:
190 * - MX = add shell layer on the face with minimum X
191 * - PX = add shell layer on the face with maximum X
192 * - MY = add shell layer on the face with minimum Y
193 * - PY = add shell layer on the face with maximum Y
194 * - MZ = add shell layer on the face with minimum Z
195 * - PZ = add shell layer on the face with maximum Z
196 *
197 */
198 int64_t add_shell_block(ShellLocation loc);
199
200 /**
201 * Add a nodeset along the specified face of the hex mesh.
202 * The nodesets will maintain the order of definition. The
203 * first nodeset defined will be nodeset 1.
204 * The loc options are:
205 * - MX = add nodeset on the face with minimum X
206 * - PX = add nodeset on the face with maximum X
207 * - MY = add nodeset on the face with minimum Y
208 * - PY = add nodeset on the face with maximum Y
209 * - MZ = add nodeset on the face with minimum Z
210 * - PZ = add nodeset on the face with maximum Z
211 *
212 */
213 int64_t add_nodeset(ShellLocation loc);
214
215 /**
216 * Add a sideset along the specified face of the hex mesh.
217 * The sidesets will maintain the order of definition. The
218 * first sideset defined will be sideset 1. If there is a shell
219 * block specified on that face, then the sideset will be on the
220 * shell elements; otherwise the sideset will be on the hex
221 * elements.
222 * The loc options are:
223 * - MX = add sideset on the face with minimum X
224 * - PX = add sideset on the face with maximum X
225 * - MY = add sideset on the face with minimum Y
226 * - PY = add sideset on the face with maximum Y
227 * - MZ = add sideset on the face with minimum Z
228 * - PZ = add sideset on the face with maximum Z
229 *
230 */
231 int64_t add_sideset(ShellLocation loc);
232
233 /**
234 * Specify the coordinate scaling and offset in all three
235 * spatial dimensions.
236 *
237 * node location of node at (i,j,k) is
238 * \code
239 * X = scale X * i + offset X
240 * Y = scale Y * i + offset Y
241 * Z = scale Z * i + offset Z
242 * \endcode
243 *
244 * WARNING: Should be called before retrieving node
245 * coordinates.
246 */
247 void set_scale(double scl_x, double scl_y, double scl_z);
248 void set_offset(double off_x, double off_y, double off_z);
249 void set_bbox(double xmin, double ymin, double zmin, double xmax, double ymax, double zmax);
250
251 /**
252 * Set rotation. Multiple calls are cumulative.
253 * Rotate `angle_degrees` degrees about the axis `axis`
254 * Center of rotation is about the origin and operates
255 * on the scaled/offset coordinates of the mesh.
256 */
257 void set_rotation(const std::string &axis, double angle_degrees);
258
259 /**
260 * Return number of nodes in the entire model.
261 */
262 IOSS_NODISCARD virtual int64_t node_count() const;
263
264 /**
265 * Return number of nodes on this processor.
266 */
267 IOSS_NODISCARD virtual int64_t node_count_proc() const;
268
269 /**
270 * Return number of element blocks in the entire model.
271 */
272 IOSS_NODISCARD virtual int block_count() const;
273
274 /**
275 * Return number of nodesets in the entire model.
276 */
277 IOSS_NODISCARD virtual int nodeset_count() const;
278
279 /**
280 * Return number of nodeset nodes on nodeset `id`
281 */
282 IOSS_NODISCARD int64_t nodeset_node_count(int64_t id) const;
283
284 /**
285 * Return number of nodeset nodes on nodeset `id` on the current processor
286 */
287 IOSS_NODISCARD virtual int64_t nodeset_node_count_proc(int64_t id) const;
288
289 /**
290 * Return string (quad4 or tri3) giving face topology of sidesets in model
291 */
292 IOSS_NODISCARD virtual std::string get_sideset_topology() const;
293
294 /**
295 * Return number of sidesets in the entire model.
296 */
297 IOSS_NODISCARD virtual int sideset_count() const;
298
299 /**
300 * Return number of sideset `sides` on sideset `id`
301 */
302 IOSS_NODISCARD int64_t sideset_side_count(int64_t id) const;
303
304 /**
305 * Return number of sideset `sides` on sideset `id` on the current
306 * processor.
307 */
308 IOSS_NODISCARD virtual int64_t sideset_side_count_proc(int64_t id) const;
309
310 /**
311 * Return number of elements in all element blocks in the model.
312 */
313 IOSS_NODISCARD virtual int64_t element_count() const;
314
315 /**
316 * Return number of shell elements in all element blocks in the model.
317 */
318 IOSS_NODISCARD int64_t shell_element_count(ShellLocation /*loc*/) const;
319
320 /**
321 * Return number of elements in all element blocks on this processor.
322 */
323 IOSS_NODISCARD virtual int64_t element_count_proc() const;
324
325 /**
326 * Return number of shell elements in all element blocks on this processor.
327 */
328 IOSS_NODISCARD int64_t shell_element_count_proc(ShellLocation /*loc*/) const;
329
330 IOSS_NODISCARD int timestep_count() const { return timestepCount; }
331 /**
332 * Return number of elements in the element block with id
333 * `block_number`. The `block_number` ranges from `1` to
334 * `block_count()`.
335 */
336 IOSS_NODISCARD virtual int64_t element_count(int64_t block_number) const;
337
338 /**
339 * Return number of elements on this processor in the element
340 * block with id `block_number`. The `block_number` ranges from
341 * `1` to `block_count()`.
342 */
343 IOSS_NODISCARD virtual int64_t element_count_proc(int64_t block_number) const;
344
345 /**
346 * Returns pair containing "topology type string" and "number of
347 * nodes / element". The topology type string will be "hex8" for
348 * the hex element block and "shell4" for the shell element blocks.
349 */
350 IOSS_NODISCARD virtual std::pair<std::string, int> topology_type(int64_t block_number) const;
351
352 void build_node_map(Ioss::Int64Vector &map, std::vector<int> &proc, int64_t slab,
353 size_t slabOffset, size_t adjacentProc, size_t index);
354 IOSS_NODISCARD virtual int64_t communication_node_count_proc() const;
355 virtual void node_communication_map(Ioss::Int64Vector &map, std::vector<int> &proc);
356 virtual void owning_processor(int *owner, int64_t num_node);
357
358 /**
359 * Fill the passed in `map` argument with the node map
360 * "map[local_position] = global_id" for the nodes on this
361 * processor.
362 */
363 virtual void node_map(Ioss::Int64Vector &map) const;
364 virtual void node_map(Ioss::IntVector &map) const;
365
366 /**
367 * Fill the passed in `map` argument with the element map
368 * "map[local_position] = global_id" for the elements on this
369 * processor in block "block_number".
370 */
371 virtual void element_map(int64_t block_number, Ioss::Int64Vector &map) const;
372 virtual void element_map(int64_t block_number, Ioss::IntVector &map) const;
373
374 /**
375 * Fill the passed in `map` argument with the element map
376 * "map[local_position] = global_id" for all elements on this
377 * processor
378 */
379 virtual void element_map(Ioss::Int64Vector &map) const;
380 virtual void element_map(Ioss::IntVector &map) const;
381
382 /**
383 * Fill the passed in `map` argument with the element map pair
384 * "map[local_position] = element global_id" and
385 * "map[local_position+1] = element local face id (0-based)" for
386 * all elements on the current processor having a face on the
387 * surface defined by ShellLocation.
388 */
389 void element_surface_map(ShellLocation loc, Ioss::Int64Vector &map) const;
390
391 /**
392 * Return the connectivity for the elements on this processor in
393 * the block with id `block_number`. If the elements in this block
394 * have `npe` nodes per element, then the first `npe` entries in
395 * the `conn` vector will be the nodal connectivity for the first
396 * element; the next `npe` entries are the nodal connectivity for
397 * the second element. The `connect` vector will be resized to the
398 * size required to contain the nodal connectivity for the
399 * specified block; all information in `connect` will be overwritten.
400 */
401 void connectivity(int64_t block_number, Ioss::Int64Vector &connect) const;
402 void connectivity(int64_t block_number, Ioss::IntVector &connect) const;
403 void connectivity(int64_t block_number, int64_t *connect) const;
404 virtual void connectivity(int64_t block_number, int *connect) const;
405
406 /**
407 * Return the coordinates for all nodes on this processor. The
408 * first 3 entries in the `coord` vector are the x, y, and z
409 * coordinates of the first node, etc. The `coord` vector will be
410 * resized to the size required to contain the nodal coordinates;
411 * all information in `coord` will be overwritten.
412 */
413 virtual void coordinates(std::vector<double> &coord) const;
414 virtual void coordinates(double *coord) const;
415
416 /**
417 * Return the coordinates for all nodes on this processor in
418 * separate vectors. The vectors will be resized to the size
419 * required to contain the nodal coordinates; all information in
420 * the vectors will be overwritten.
421 */
422 virtual void coordinates(std::vector<double> &x, std::vector<double> &y,
423 std::vector<double> &z) const;
424
425 /**
426 * Return the coordinates for component `comp` (1=x, 2=y, 3=z)
427 * for all nodes on this processor. The
428 * vector will be resized to the size required to contain the
429 * nodal coordinates; all information in the vector will be
430 * overwritten.
431 * It is an error to request the coordinates via this function
432 * if a rotation is defined.
433 */
434 virtual void coordinates(int component, std::vector<double> &xyz) const;
435 virtual void coordinates(int component, double *xyz) const;
436
437 /**
438 * Return the list of nodes in nodeset `id` on this processor.
439 * The `nodes` vector will be resized to the size required to
440 * contain the node list. The ids are global ids.
441 */
442 virtual void nodeset_nodes(int64_t id, Ioss::Int64Vector &nodes) const;
443
444 /**
445 * Return the list of the face/ordinal pairs
446 * "elem_sides[local_position] = element global_id" and
447 * "elem_sides[local_position+1] = element local face id (0-based)"
448 * for the faces in sideset `id` on this
449 * processor. The `elem_sides` vector will be resized to the size
450 * required to contain the list. The element ids are global ids,
451 * the side ordinal is 0-based.
452 */
453 virtual void sideset_elem_sides(int64_t id, Ioss::Int64Vector &elem_sides) const;
454
455 virtual Ioss::NameList sideset_touching_blocks(int64_t set_id) const;
456
457 IOSS_NODISCARD int64_t get_num_x() const { return numX; }
458 IOSS_NODISCARD int64_t get_num_y() const { return numY; }
459 IOSS_NODISCARD int64_t get_num_z() const { return numZ; }
460
462 {
463 return variableCount.find(type) != variableCount.end() ? variableCount.find(type)->second : 0;
464 }
465
466 private:
467 template <typename INT> void raw_element_map(int64_t block_number, std::vector<INT> &map) const;
468 template <typename INT> void raw_element_map(std::vector<INT> &map) const;
469 template <typename INT> void raw_connectivity(int64_t block_number, INT *connect) const;
470
471 void set_variable_count(const std::string &type, size_t count);
472 void parse_options(const Ioss::NameList &groups);
473 void show_parameters() const;
474 void initialize();
475
476 std::vector<ShellLocation> shellBlocks;
477 std::vector<ShellLocation> nodesets;
478 std::vector<ShellLocation> sidesets;
479 std::array<std::array<double, 3>, 3> rotmat;
480 int64_t numX{0}, numY{0}, numZ{0};
481 int64_t myNumZ{0}, myStartZ{0};
482
483 int processorCount{0};
484 int myProcessor{0};
485
486 int timestepCount{0};
487 std::map<Ioss::EntityType, size_t> variableCount;
488
489 double offX{0}, offY{0}, offZ{0}; /** Offsets in X, Y, and Z directions */
490 double sclX{1}, sclY{1}, sclZ{1}; /** Scale in X, Y, and Z directions
491 * location of node at (i,j,k)
492 * position is (sclX*i+offX,
493 * sclY*i+offY, sclZ*i+offZ) */
494 bool doRotation{false};
495 bool createTets{false};
496 bool createPyramids{false};
497 };
498} // namespace Iogn
#define IOSS_NODISCARD
Definition Ioss_CodeTypes.h:55
Definition Iogn_GeneratedMesh.h:23
virtual ~GeneratedMesh()=default
std::vector< ShellLocation > nodesets
Definition Iogn_GeneratedMesh.h:477
IOSS_NODISCARD int64_t get_num_y() const
Definition Iogn_GeneratedMesh.h:458
std::map< Ioss::EntityType, size_t > variableCount
Definition Iogn_GeneratedMesh.h:487
std::vector< ShellLocation > shellBlocks
Definition Iogn_GeneratedMesh.h:476
IOSS_NODISCARD int64_t get_num_x() const
Definition Iogn_GeneratedMesh.h:457
ShellLocation
Definition Iogn_GeneratedMesh.h:25
GeneratedMesh(const GeneratedMesh &)=delete
IOSS_NODISCARD int64_t get_num_z() const
Definition Iogn_GeneratedMesh.h:459
std::vector< ShellLocation > sidesets
Definition Iogn_GeneratedMesh.h:478
GeneratedMesh & operator=(const GeneratedMesh &)=delete
IOSS_NODISCARD int timestep_count() const
Definition Iogn_GeneratedMesh.h:330
IOSS_NODISCARD size_t get_variable_count(Ioss::EntityType type) const
Definition Iogn_GeneratedMesh.h:461
std::array< std::array< double, 3 >, 3 > rotmat
Definition Iogn_GeneratedMesh.h:479
A namespace for the generated database format.
Definition Iogn_DashSurfaceMesh.C:12
std::vector< int64_t > Int64Vector
Definition Ioss_CodeTypes.h:22
Ioss::NameList NameList
Definition Ioss_ChangeSetFactory.h:25
std::vector< int > IntVector
Definition Ioss_CodeTypes.h:21
EntityType
The particular type of GroupingEntity.
Definition Ioss_EntityType.h:12