IOSS 2.0
Loading...
Searching...
No Matches
Iogs_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 "iogs_export.h"
20
21namespace Iogs {
22 class IOGS_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 gen_struc 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 sidesets along each
37 face of the cube mesh. These are specified via the
38 'add_sidesets' function.
39
40 If the 'parameters' string constructor is used, the string
41 is parsed to determine the intervals in each direction and,
42 optionally, additional information. The form of the string
43 is "IxJxK" where I, J, and K are the number of intervals
44 in the X, Y, and Z directions respectively and the "x" are
45 literal 'x' characters. For example, the constructor
46 GeneratedMesh("10x12x14") will create the same mesh as
47 GeneratedMesh(10,12,14)
48
49 Additional valid options are:
50 - help -- no argument, shows valid options
51 - show -- no argument, prints out a summary of the
52 GeneratedMesh() parameters. The output will look similar
53 to:
54 \code
55 "10x12x8|bbox:-10,-10,-10,10,10,10|sideset:XYZ|show"
56
57 Mesh Parameters:
58 Intervals: 10 by 12 by 8
59 X = 2 * (0..10) + -10 Range: -10 <= X <= 10
60 Y = 1.66667 * (0..12) + -10 Range: -10 <= Y <= 10
61 Z = 2.5 * (0..8) + -10 Range: -10 <= Z <= 10
62 Node Count (total) = 1287
63 Element Count (total) = 1152
64 Block Count = 3
65 SideSet Count = 3
66 \endcode
67
68 - sideset -- argument = xXyYzZ which specifies whether there is
69 a sideset at that location. 'x' is minimum x face, 'X' is
70 maximum x face, similarly for y and z. Note that the argument
71 string is a single multicharacter string. You can add multiple
72 sidesets to a face, for example, sideset:xxx would add three
73 sidesets on the minimum x face. An error is output if a non
74 xXyYzZ character is found, but execution continues.
75
76 - zdecomp -- argument = n0, n1, n2, ..., n#proc-1 which are the number
77 of intervals in the z direction for each processor in a pallel run.
78 If this option is specified, then the total number of intervals in the
79 z direction is the sum of the n0, n1, ... An interval count must be
80 specified for each processor. If this option is not specified, then
81 the number of intervals on each processor in the z direction is
82 numZ/numProc with the extras added to the lower numbered processors.
83
84 - scale -- argument = xs, ys, zs which are the scale factors in the x,
85 y, and z directions. All three must be specified if this option is
86 present.
87
88 - offset -- argument = xoff, yoff, zoff which are the offsets in the
89 x, y, and z directions. All three must be specified if this option
90 is present.
91
92 - bbox -- argument = xmin, ymin, zmin, xmax, ymax, zmax
93 which specify the lower left and upper right corners of
94 the bounding box for the gen_struc mesh. This will
95 calculate the scale and offset which will fit the mesh in
96 the specified box. All calculations are based on the currently
97 active interval settings. If scale or offset or zdecomp
98 specified later in the option list, you may not get the
99 desired bounding box.
100
101 - rotate -- argument = axis,angle,axis,angle,...
102 where axis is 'x', 'y', or 'z' and angle is the rotation angle in
103 degrees. Multiple rotations are cumulative. The composite rotation
104 matrix is applied at the time the coordinates are retrieved after
105 scaling and offset are applied.
106
107 The unrotated coordinate of a node at grid location i,j,k is:
108 \code
109 x = x_scale * i + x_off,
110 y = z_scale * j + y_off,
111 z = z_scale * k + z_off,
112 \endcode
113
114 The extent of the unrotated mesh will be:
115 \code
116 x_off <= x <= x_scale * numX + x_off
117 y_off <= y <= y_scale * numY + y_off
118 z_off <= z <= z_scale * numZ + z_off
119 \endcode
120
121 If an unrecognized option is specified, an error message will be
122 output and execution will continue.
123
124 An example of valid input is:
125 \code
126 "10x20x40|scale:1,0.5,0.25|offset:-5,-5,-5"
127 \endcode
128
129 This would create a mesh with 10 intervals in x, 20 in y, 40 in z
130 The mesh would be centered on 0,0,0 with a range of 10 in each
131 direction.
132
133 NOTE: All options are processed in the order they appear in
134 the parameters string (except rotate which is applied at the
135 time the coordinates are gen_struc/retrieved)
136 */
137 explicit GeneratedMesh(const std::string &parameters, int proc_count = 1, int my_proc = 0);
138 GeneratedMesh(int64_t num_x, int64_t num_y, int64_t num_z, int proc_count = 1, int my_proc = 0);
140 virtual ~GeneratedMesh() = default;
141
142 /**
143 * Add a sideset along the specified face of the hex mesh.
144 * The sidesets will maintain the order of definition. The
145 * first sideset defined will be sideset 1.
146 * The loc options are:
147 * - MX = add sideset on the face with minimum X
148 * - PX = add sideset on the face with maximum X
149 * - MY = add sideset on the face with minimum Y
150 * - PY = add sideset on the face with maximum Y
151 * - MZ = add sideset on the face with minimum Z
152 * - PZ = add sideset on the face with maximum Z
153 *
154 */
155 int64_t add_sideset(ShellLocation loc);
156
157 /**
158 * Specify the coordinate scaling and offset in all three
159 * spatial dimensions.
160 *
161 * node location of node at (i,j,k) is
162 * \code
163 * X = scale X * i + offset X
164 * Y = scale Y * i + offset Y
165 * Z = scale Z * i + offset Z
166 * \endcode
167 *
168 * WARNING: Should be called before retrieving node
169 * coordinates.
170 */
171 void set_scale(double scl_x, double scl_y, double scl_z);
172 void set_offset(double off_x, double off_y, double off_z);
173 void set_bbox(double xmin, double ymin, double zmin, double xmax, double ymax, double zmax);
174
175 /**
176 * Set rotation. Multiple calls are cumulative.
177 * Rotate 'angle_degrees' degrees about the axis 'axis'
178 * Center of rotation is about the origin and operates
179 * on the scaled/offset coordinates of the mesh.
180 */
181 void set_rotation(const std::string &axis, double angle_degrees);
182
183 /**
184 * Return number of nodes in the entire model.
185 */
186 IOSS_NODISCARD virtual int64_t node_count() const;
187
188 /**
189 * Return number of nodes on this processor.
190 */
191 IOSS_NODISCARD virtual int64_t node_count_proc() const;
192
193 /**
194 * Return number of structured blocks in the entire model.
195 */
196 IOSS_NODISCARD virtual int64_t structured_block_count() const;
197
198 /**
199 * Return number of sidesets in the entire model.
200 */
201 IOSS_NODISCARD virtual int64_t sideset_count() const;
202
203 /**
204 * Return number of sideset 'sides' on sideset 'id'
205 */
206 IOSS_NODISCARD int64_t sideset_side_count(int64_t id) const;
207
208 /**
209 * Return number of sideset 'sides' on sideset 'id' on the current
210 * processor.
211 */
212 IOSS_NODISCARD virtual int64_t sideset_side_count_proc(int64_t id) const;
213
214 IOSS_NODISCARD Ioss::IJK_t block_range(int64_t /* id */) const
215 {
216 return Ioss::IJK_t{{(int)numX, (int)numY, (int)numZ}};
217 }
220
221 /**
222 * Return number of elements in all structured blocks in the model.
223 */
224 IOSS_NODISCARD virtual int64_t element_count() const;
225
226 /**
227 * Return number of elements in all structured blocks on this processor.
228 */
229 IOSS_NODISCARD int64_t element_count_proc() const;
230
231 IOSS_NODISCARD int64_t timestep_count() const { return timestepCount; }
232 /**
233 * Return number of elements in the structured block with id
234 * 'block_number'. The 'block_number' ranges from '1' to
235 * 'block_count()'.
236 */
237 IOSS_NODISCARD virtual int64_t element_count(int64_t block_number) const;
238
239 /**
240 * Return number of elements on this processor in the structured
241 * block with id 'block_number'. The 'block_number' ranges from
242 * '1' to 'block_count()'.
243 */
244 IOSS_NODISCARD int64_t element_count_proc(int64_t block_number) const;
245
246 /**
247 * Returns pair containing "topology type string" and "number of
248 * nodes / element". The topology type string will be "hex8" for
249 * the hex element block
250 */
251 IOSS_NODISCARD virtual std::pair<std::string, int> topology_type(int64_t block_number) const;
252
253 void build_node_map(Ioss::Int64Vector &map, std::vector<int> &proc, int64_t slab,
254 size_t slabOffset, size_t adjacentProc, size_t index);
255 IOSS_NODISCARD virtual int64_t communication_node_count_proc() const;
256 virtual void node_communication_map(Ioss::Int64Vector &map, std::vector<int> &proc);
257 virtual void owning_processor(int *owner, int64_t num_node);
258
259 /**
260 * Fill the passed in 'map' argument with the node map
261 * "map[local_position] = global_id" for the nodes on this
262 * processor.
263 */
264 virtual void node_map(Ioss::Int64Vector &map) const;
265 virtual void node_map(Ioss::IntVector &map) const;
266
267 /**
268 * Fill the passed in 'map' argument with the element map
269 * "map[local_position] = global_id" for the elements on this
270 * processor in block "block_number".
271 */
272 virtual void element_map(int64_t block_number, Ioss::Int64Vector &map) const;
273 virtual void element_map(int64_t block_number, Ioss::IntVector &map) const;
274
275 /**
276 * Fill the passed in 'map' argument with the element map
277 * "map[local_position] = global_id" for all elements on this
278 * processor
279 */
280 virtual void element_map(Ioss::Int64Vector &map) const;
281 virtual void element_map(Ioss::IntVector &map) const;
282
283 /**
284 * Fill the passed in 'map' argument with the element map pair
285 * "map[local_position] = element global_id" and
286 * "map[local_position+1] = element local face id (0-based)" for
287 * all elements on the current processor having a face on the
288 * surface defined by ShellLocation.
289 */
290 void element_surface_map(ShellLocation loc, Ioss::Int64Vector &map) const;
291
292 /**
293 * Return the connectivity for the elements on this processor in
294 * the block with id 'block_number'. If the elements in this block
295 * have 'npe' nodes per element, then the first 'npe' entries in
296 * the 'conn' vector will be the nodal connectivity for the first
297 * element; the next 'npe' entries are the nodal connectivity for
298 * the second element. The 'connect' vector will be resized to the
299 * size required to contain the nodal connectivity for the
300 * specified block; all information in 'connect' will be overwritten.
301 */
302 void connectivity(int64_t block_number, Ioss::Int64Vector &connect) const;
303 void connectivity(int64_t block_number, Ioss::IntVector &connect) const;
304 void connectivity(int64_t block_number, int64_t *connect) const;
305 virtual void connectivity(int64_t block_number, int *connect) const;
306
307 /**
308 * Return the coordinates for all nodes on this processor. The
309 * first 3 entries in the 'coord' vector are the x, y, and z
310 * coordinates of the first node, etc. The 'coord' vector will be
311 * resized to the size required to contain the nodal coordinates;
312 * all information in 'coord' will be overwritten.
313 */
314 virtual void coordinates(std::vector<double> &coord) const;
315 virtual void coordinates(double *coord) const;
316
317 /**
318 * Return the coordinates for all nodes on this processor in
319 * separate vectors. The vectors will be resized to the size
320 * required to contain the nodal coordinates; all information in
321 * the vectors will be overwritten.
322 */
323 virtual void coordinates(std::vector<double> &x, std::vector<double> &y,
324 std::vector<double> &z) const;
325
326 /**
327 * Return the coordinates for component 'comp' (1=x, 2=y, 3=z)
328 * for all nodes on this processor. The
329 * vector will be resized to the size required to contain the
330 * nodal coordinates; all information in the vector will be
331 * overwritten.
332 * It is an error to request the coordinates via this function
333 * if a rotation is defined.
334 */
335 virtual void coordinates(int component, std::vector<double> &xyz) const;
336
337 /**
338 * Return the coordinates for component 'comp' (1=x, 2=y, 3=z, 0=all)
339 * for all nodes in zone `zone` on this processor. The
340 * vector will be resized to the size required to contain the
341 * nodal coordinates; all information in the vector will be
342 * overwritten.
343 * It is an error to request the coordinates via this function
344 * if a rotation is defined.
345 */
346 void coordinates(int component, int zone, double *coord) const;
347
348 /**
349 * Return the list of the face/ordinal pairs
350 * "elem_sides[local_position] = element global_id" and
351 * "elem_sides[local_position+1] = element local face id (0-based)"
352 * for the faces in sideset 'id' on this
353 * processor. The 'elem_sides' vector will be resized to the size
354 * required to contain the list. The element ids are global ids,
355 * the side ordinal is 0-based.
356 */
357 virtual void sideset_elem_sides(int64_t id, Ioss::Int64Vector &elem_sides) const;
358
359 IOSS_NODISCARD virtual std::vector<std::string> sideset_touching_blocks(int64_t set_id) const;
360
361 IOSS_NODISCARD int64_t get_num_x() const { return numX; }
362 IOSS_NODISCARD int64_t get_num_y() const { return numY; }
363 IOSS_NODISCARD int64_t get_num_z() const { return numZ; }
364
366 {
367 return variableCount.find(type) != variableCount.end() ? variableCount.find(type)->second : 0;
368 }
369
370 private:
371 template <typename INT> void raw_element_map(int64_t block_number, std::vector<INT> &map) const;
372 template <typename INT> void raw_element_map(std::vector<INT> &map) const;
373 template <typename INT> void raw_connectivity(int64_t block_number, INT *connect) const;
374
377
378 void set_variable_count(const std::string &type, size_t count);
379 void parse_options(const std::vector<std::string> &groups);
380 void show_parameters() const;
381 void initialize();
382
383 std::vector<ShellLocation> sidesets{};
384 std::array<std::array<double, 3>, 3> rotmat;
385 size_t numX{0}, numY{0}, numZ{0};
386 size_t myNumZ{0}, myStartZ{0};
387
388 size_t processorCount{1};
389 size_t myProcessor{0};
390
391 size_t timestepCount{0};
392 std::map<Ioss::EntityType, size_t> variableCount{};
393
394 double offX{0}, offY{0}, offZ{0}; /** Offsets in X, Y, and Z directions */
395 double sclX{1}, sclY{1}, sclZ{1}; /** Scale in X, Y, and Z directions
396 * location of node at (i,j,k)
397 * position is (sclX*i+offX,
398 * sclY*i+offY, sclZ*i+offZ) */
399 bool doRotation{false};
400 };
401} // namespace Iogs
#define IOSS_NODISCARD
Definition Ioss_CodeTypes.h:54
Definition Iogs_GeneratedMesh.h:23
GeneratedMesh & operator=(const GeneratedMesh &)
ShellLocation
Definition Iogs_GeneratedMesh.h:25
IOSS_NODISCARD int64_t get_num_z() const
Definition Iogs_GeneratedMesh.h:363
IOSS_NODISCARD int64_t get_num_x() const
Definition Iogs_GeneratedMesh.h:361
GeneratedMesh(const GeneratedMesh &)
IOSS_NODISCARD Ioss::IJK_t block_offset_proc(int64_t id) const
IOSS_NODISCARD Ioss::IJK_t block_range(int64_t) const
Definition Iogs_GeneratedMesh.h:214
IOSS_NODISCARD int64_t get_num_y() const
Definition Iogs_GeneratedMesh.h:362
virtual ~GeneratedMesh()=default
IOSS_NODISCARD Ioss::IJK_t block_range_proc(int64_t id) const
IOSS_NODISCARD size_t get_variable_count(Ioss::EntityType type) const
Definition Iogs_GeneratedMesh.h:365
std::array< std::array< double, 3 >, 3 > rotmat
Definition Iogs_GeneratedMesh.h:384
IOSS_NODISCARD int64_t timestep_count() const
Definition Iogs_GeneratedMesh.h:231
A namespace for the gen_struc database format.
Definition Iogs_DatabaseIO.C:87
std::vector< int64_t > Int64Vector
Definition Ioss_CodeTypes.h:22
std::vector< int > IntVector
Definition Ioss_CodeTypes.h:21
std::array< int, 3 > IJK_t
Definition Ioss_CodeTypes.h:24
EntityType
The particular type of GroupingEntity.
Definition Ioss_EntityType.h:12