IOSS 2.0
Loading...
Searching...
No Matches
Ioss_StructuredBlock.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_BoundingBox.h"
10#include "Ioss_CodeTypes.h"
11#include "Ioss_EntityBlock.h"
12#include "Ioss_NodeBlock.h"
13#include "Ioss_Property.h"
15#include <array>
16#include <cassert>
17#include <fmt/core.h>
18#include <fmt/ostream.h>
19#include <iosfwd>
20#include <stddef.h>
21#include <stdint.h>
22#include <string>
23#include <vector>
24
25#include "Ioss_EntityType.h"
26#include "ioss_export.h"
27
28#if defined(SEACAS_HAVE_CGNS) && !defined(BUILT_IN_SIERRA)
29#include <cgnstypes.h>
30
31using IOSS_SB_INT = cgsize_t;
32#else
33// If this is not being built with CGNS, then default to using 32-bit integers.
34// Currently there is no way to input/output a structured mesh without CGNS,
35// so this block is simply to get things to compile and probably has no use.
36using IOSS_SB_INT = int;
37#endif
38
39namespace Ioss {
40 class Region;
41 class Field;
42
43 struct IOSS_EXPORT BoundaryCondition
44 {
45 BoundaryCondition(std::string name, std::string fam_name, Ioss::IJK_t range_beg,
46 Ioss::IJK_t range_end)
47 : m_bcName(std::move(name)), m_famName(std::move(fam_name)), m_rangeBeg(range_beg),
48 m_rangeEnd(range_end)
49 {
50 }
51
52 // Deprecated... Use the constructor above with both name and fam_name
53 BoundaryCondition(std::string name, Ioss::IJK_t range_beg, Ioss::IJK_t range_end)
54 : m_bcName(name), m_famName(std::move(name)), m_rangeBeg(range_beg), m_rangeEnd(range_end)
55 {
56 }
57
58 // cereal requires a default constructor when de-serializing vectors of objects. Because
59 // StructuredBlock contains a vector of BoundaryCondition objects, this default constructor is
60 // necessary.
61 BoundaryCondition() = default;
62
63 BoundaryCondition(const BoundaryCondition &copy_from) = default;
64 BoundaryCondition &operator=(const BoundaryCondition &copy_from) = default;
65
66 // Determine which "face" of the parent block this BC is applied to.
67 IOSS_NODISCARD int which_face() const;
68
69 // Does range specify a valid face
70 IOSS_NODISCARD bool is_valid() const;
71
72 // Return number of cell faces in the BC
73 IOSS_NODISCARD size_t get_face_count() const;
74
75 IOSS_NODISCARD bool operator==(const Ioss::BoundaryCondition &rhs) const;
77 IOSS_NODISCARD bool equal(const Ioss::BoundaryCondition &rhs) const;
78
79 std::string m_bcName{};
80 std::string m_famName{};
81
82 // These are potentially subsetted due to parallel decompositions...
83 Ioss::IJK_t m_rangeBeg{};
84 Ioss::IJK_t m_rangeEnd{};
85
86 mutable int m_face{-1};
87
88 template <class Archive> void serialize(Archive &archive)
89 {
90 archive(m_bcName, m_famName, m_rangeBeg, m_rangeEnd, m_face);
91 }
92
93 private:
94 bool equal_(const Ioss::BoundaryCondition &rhs, bool quiet) const;
95 };
96
97 IOSS_EXPORT std::ostream &operator<<(std::ostream &os, const BoundaryCondition &bc);
98
99 class DatabaseIO;
100
101 /** \brief A structured zone -- i,j,k
102 */
103 class IOSS_EXPORT StructuredBlock : public EntityBlock
104 {
105 public:
106 StructuredBlock(DatabaseIO *io_database, const std::string &my_name, int index_dim, int ni,
107 int nj, int nk, int off_i, int off_j, int off_k, int glo_ni, int glo_nj,
108 int glo_nk);
109 StructuredBlock(DatabaseIO *io_database, const std::string &my_name, int index_dim,
110 const Ioss::IJK_t &ordinal, const Ioss::IJK_t &offset,
111 const Ioss::IJK_t &global_ordinal);
112
113 // Useful for serial
114 StructuredBlock(DatabaseIO *io_database, const std::string &my_name, int index_dim, int ni,
115 int nj, int nk);
116 StructuredBlock(DatabaseIO *io_database, const std::string &my_name, int index_dim,
117 Ioss::IJK_t &ordinal);
118
119 StructuredBlock *clone(DatabaseIO *database) const;
120
121 IOSS_NODISCARD std::string type_string() const override { return "StructuredBlock"; }
122 IOSS_NODISCARD std::string short_type_string() const override { return "structuredblock"; }
123 IOSS_NODISCARD std::string contains_string() const override { return "Cell"; }
124 IOSS_NODISCARD EntityType type() const override { return STRUCTUREDBLOCK; }
125
126 IOSS_NODISCARD const Ioss::NodeBlock &get_node_block() const { return m_nodeBlock; }
128
129 /** \brief Does block contain any cells
130 */
131 IOSS_NODISCARD bool is_active() const { return m_ijk[0] * m_ijk[1] * m_ijk[2] > 0; }
132
133 // Handle implicit properties -- These are calculated from data stored
134 // in the grouping entity instead of having an explicit value assigned.
135 // An example would be 'element_block_count' for a region.
136 IOSS_NODISCARD Property get_implicit_property(const std::string &my_name) const override;
137
138 IOSS_NODISCARD AxisAlignedBoundingBox get_bounding_box() const;
139
140 /** \brief Set the 'offset' for the block.
141 *
142 * The 'offset' is used to map a cell or node location within a
143 * structured block to the model implicit cell or node location
144 * on a single processor. zero-based.
145 *
146 * The 'global' offsets do the same except for they apply over
147 * the entire model on all processors. zero-based.
148 *
149 * For example, the file descriptor (1-based) of
150 * the 37th cell in the 4th block is calculated by:
151 *
152 * file_descriptor = offset of block 4 + 37
153 *
154 * This can also be used to determine which structured block
155 * a cell with a file_descriptor maps into. An particular
156 * structured block contains all cells in the range:
157 *
158 * offset < file_descriptor <= offset+number_cells_per_block
159 *
160 * Note that for nodes, the nodeOffset does not take into account
161 * the nodes that are shared between blocks.
162 */
163 void set_node_offset(size_t offset) { m_nodeOffset = offset; }
164 void set_cell_offset(size_t offset) { m_cellOffset = offset; }
165 void set_node_global_offset(size_t offset) { m_nodeGlobalOffset = offset; }
166 void set_cell_global_offset(size_t offset) { m_cellGlobalOffset = offset; }
167
168 IOSS_NODISCARD size_t get_node_offset() const { return m_nodeOffset; }
169 IOSS_NODISCARD size_t get_cell_offset() const { return m_cellOffset; }
170 IOSS_NODISCARD size_t get_node_global_offset() const { return m_nodeGlobalOffset; }
171 IOSS_NODISCARD size_t get_cell_global_offset() const { return m_cellGlobalOffset; }
172
173 void set_ijk_offset(int axis, size_t offset);
174 void set_ijk_global(int axis, size_t global);
175
176 void set_ijk_offset(const IJK_t &offset);
177 void set_ijk_global(const IJK_t &global);
178
179 IOSS_NODISCARD IJK_t get_ijk_offset() const { return m_offset; }
180 IOSS_NODISCARD IJK_t get_ijk_local() const { return m_ijk; }
181 IOSS_NODISCARD IJK_t get_ijk_global() const { return m_ijkGlobal; }
182
183 // Get the global (over all processors) cell
184 // id at the specified i,j,k location (1 <= i,j,k <= ni,nj,nk). 1-based.
185 IOSS_NODISCARD size_t get_global_cell_id(int i, int j, int k) const
186 {
187 return m_cellGlobalOffset + static_cast<size_t>(k - 1) * m_ijkGlobal[0] * m_ijkGlobal[1] +
188 static_cast<size_t>(j - 1) * m_ijkGlobal[0] + i;
189 }
190
192 {
193 return get_global_cell_id(index[0], index[1], index[2]);
194 }
195
196 // Get the global (over all processors) node
197 // offset at the specified i,j,k location (1 <= i,j,k <= ni,nj,nk). 0-based, does not account
198 // for shared nodes.
199 IOSS_NODISCARD size_t get_global_node_offset(int i, int j, int k) const
200 {
201 return m_nodeGlobalOffset +
202 static_cast<size_t>(k - 1) * (m_ijkGlobal[0] + 1) * (m_ijkGlobal[1] + 1) +
203 static_cast<size_t>(j - 1) * (m_ijkGlobal[0] + 1) + i - 1;
204 }
205
207 {
208 return get_global_node_offset(index[0], index[1], index[2]);
209 }
210
211 // Get the local (relative to this block on this processor) node id at the specified
212 // i,j,k location (1 <= i,j,k <= ni+1,nj+1,nk+1). 0-based.
213 IOSS_NODISCARD size_t get_block_local_node_offset(int ii, int jj, int kk) const
214 {
215 auto i = ii - m_offset[0];
216 auto j = jj - m_offset[1];
217 auto k = kk - m_offset[2];
218 assert(i > 0 && i <= m_ijk[0] + 1 && j > 0 && j <= m_ijk[1] + 1 && k > 0 &&
219 k <= m_ijk[2] + 1);
220 return static_cast<size_t>(k - 1) * (m_ijk[0] + 1) * (m_ijk[1] + 1) +
221 static_cast<size_t>(j - 1) * (m_ijk[0] + 1) + i - 1;
222 }
223
225 {
226 return get_block_local_node_offset(index[0], index[1], index[2]);
227 }
228
229 // Get the local (on this processor) cell-node offset at the specified
230 // i,j,k location (1 <= i,j,k <= ni+1,nj+1,nk+1). 0-based.
231 IOSS_NODISCARD size_t get_local_node_offset(int i, int j, int k) const
232 {
233 return get_block_local_node_offset(i, j, k) + m_nodeOffset;
234 }
235
237 {
238 return get_local_node_offset(index[0], index[1], index[2]);
239 }
240
241 IOSS_NODISCARD std::vector<IOSS_SB_INT> get_cell_node_ids(bool add_offset) const
242 {
243 size_t node_count = get_property("node_count").get_int();
244 std::vector<IOSS_SB_INT> ids(node_count);
245 get_cell_node_ids(Data(ids), add_offset);
246 return ids;
247 }
248
249 template <typename INT_t> size_t get_cell_node_ids(INT_t *idata, bool add_offset) const
250 {
251 // Fill 'idata' with the cell node ids which are the
252 // 1-based location of each node in this zone
253 // The location is based on the "model" (all processors) zone.
254 // If this is a parallel decomposed model, then
255 // this block may be a subset of the "model" zone
256 //
257 // if 'add_offset' is true, then add the m_cellGlobalOffset
258 // which changes the location to be the location in the
259 // entire "mesh" instead of within a "zone" (all processors)
260
261 size_t index = 0;
262 size_t offset = add_offset ? m_nodeGlobalOffset : 0;
263
264 if (m_ijk[2] == 0 && m_ijk[1] == 0 && m_ijk[0] == 0) {
265 return index;
266 }
267
268 for (int kk = 0; kk < m_ijk[2] + 1; kk++) {
269 size_t k = m_offset[2] + kk;
270 for (int jj = 0; jj < m_ijk[1] + 1; jj++) {
271 size_t j = m_offset[1] + jj;
272 for (int ii = 0; ii < m_ijk[0] + 1; ii++) {
273 size_t i = m_offset[0] + ii;
274
275 size_t ind =
276 k * (m_ijkGlobal[0] + 1) * (m_ijkGlobal[1] + 1) + j * (m_ijkGlobal[0] + 1) + i;
277
278 idata[index++] = ind + offset + 1;
279 }
280 }
281 }
282
283 for (const auto &idx_id : m_globalIdMap) {
284 idata[idx_id.first] = idx_id.second;
285 }
286
287 return index;
288 }
289
290 template <typename INT_t> size_t get_cell_ids(INT_t *idata, bool add_offset) const
291 {
292 // Fill 'idata' with the cell ids which are the
293 // 1-based location of each cell in this zone
294 // The location is based on the "model" zone.
295 // If this is a parallel decomposed model, then
296 // this block may be a subset of the "model" zone
297 //
298 // if 'add_offset' is true, then add the m_cellGlobalOffset
299 // which changes the location to be the location in the
300 // entire "mesh" instead of within a "zone"
301
302 size_t index = 0;
303 size_t offset = add_offset ? m_cellGlobalOffset : 0;
304
305 if (m_ijk[2] == 0 && m_ijk[1] == 0 && m_ijk[0] == 0) {
306 return index;
307 }
308
309 for (int kk = 0; kk < m_ijk[2]; kk++) {
310 size_t k = m_offset[2] + kk;
311 for (int jj = 0; jj < m_ijk[1]; jj++) {
312 size_t j = m_offset[1] + jj;
313 for (int ii = 0; ii < m_ijk[0]; ii++) {
314 size_t i = m_offset[0] + ii;
315
316 size_t ind = k * m_ijkGlobal[0] * m_ijkGlobal[1] + j * m_ijkGlobal[0] + i;
317
318 idata[index++] = ind + offset + 1;
319 }
320 }
321 }
322 return index;
323 }
324
325 IOSS_NODISCARD bool contains_node(size_t global_offset) const
326 {
327 return (global_offset >= m_nodeOffset &&
328 global_offset < m_nodeOffset + get_property("node_count").get_int());
329 }
330
331 /* COMPARE two StructuredBlocks */
332 IOSS_NODISCARD bool operator==(const Ioss::StructuredBlock &rhs) const;
333 IOSS_NODISCARD bool operator!=(const Ioss::StructuredBlock &rhs) const;
334 IOSS_NODISCARD bool equal(const Ioss::StructuredBlock &rhs) const;
335
336 protected:
337 int64_t internal_get_field_data(const Field &field, void *data,
338 size_t data_size) const override;
339
340 int64_t internal_put_field_data(const Field &field, void *data,
341 size_t data_size) const override;
342
343 int64_t internal_get_zc_field_data(const Field &field, void **data,
344 size_t *data_size) const override;
345
346 private:
347 bool equal_(const Ioss::StructuredBlock &rhs, bool quiet) const;
349 IJK_t m_offset; // Valid 'i' ordinal runs from m_offset[i]+1 to m_offset[i]+m_ijk[i]
350 IJK_t m_ijkGlobal; // The ni,nj,nk of the master block this is a subset of.
351
352 size_t m_nodeOffset{};
353 size_t m_cellOffset{};
354
355 size_t m_nodeGlobalOffset{};
356 size_t m_cellGlobalOffset{};
357
359
360 public:
361 std::vector<ZoneConnectivity> m_zoneConnectivity;
362 std::vector<BoundaryCondition> m_boundaryConditions;
363 std::vector<size_t> m_blockLocalNodeIndex;
364 std::vector<std::pair<size_t, size_t>> m_globalIdMap;
365
366 template <class Archive> void serialize(Archive &archive)
367 {
368 archive(m_zoneConnectivity, m_boundaryConditions, m_blockLocalNodeIndex, m_globalIdMap);
369 }
370 };
371} // namespace Ioss
372
373#if FMT_VERSION >= 90000
374namespace fmt {
375 template <> struct formatter<Ioss::BoundaryCondition> : ostream_formatter
376 {
377 };
378} // namespace fmt
379#endif
#define IOSS_NODISCARD
Definition Ioss_CodeTypes.h:54
int IOSS_SB_INT
Definition Ioss_StructuredBlock.h:36
IOSS_NODISCARD constexpr T * Data(std::vector< T > &vec)
Definition Ioss_Utils.h:56
An input or output Database.
Definition Ioss_DatabaseIO.h:63
Base class for all 'block'-type grouping entities, which means all members of the block are similar o...
Definition Ioss_EntityBlock.h:38
Holds metadata for bulk data associated with a GroupingEntity.
Definition Ioss_Field.h:25
A collection of all nodes in the region.
Definition Ioss_NodeBlock.h:33
A named value that has a known type.
Definition Ioss_Property.h:27
A structured zone – i,j,k.
Definition Ioss_StructuredBlock.h:104
IOSS_NODISCARD bool is_active() const
Does block contain any cells.
Definition Ioss_StructuredBlock.h:131
void serialize(Archive &archive)
Definition Ioss_StructuredBlock.h:366
IOSS_NODISCARD size_t get_cell_offset() const
Definition Ioss_StructuredBlock.h:169
void set_node_global_offset(size_t offset)
Definition Ioss_StructuredBlock.h:165
IOSS_NODISCARD std::string type_string() const override
Get the name of the particular type of entity.
Definition Ioss_StructuredBlock.h:121
std::vector< ZoneConnectivity > m_zoneConnectivity
Definition Ioss_StructuredBlock.h:361
std::vector< std::pair< size_t, size_t > > m_globalIdMap
Definition Ioss_StructuredBlock.h:364
IOSS_NODISCARD Ioss::NodeBlock & get_node_block()
Definition Ioss_StructuredBlock.h:127
IOSS_NODISCARD size_t get_global_node_offset(int i, int j, int k) const
Definition Ioss_StructuredBlock.h:199
IOSS_NODISCARD size_t get_block_local_node_offset(IJK_t index) const
Definition Ioss_StructuredBlock.h:224
IOSS_NODISCARD std::vector< IOSS_SB_INT > get_cell_node_ids(bool add_offset) const
Definition Ioss_StructuredBlock.h:241
IOSS_NODISCARD std::string short_type_string() const override
Get a short name of the particular type of entity.
Definition Ioss_StructuredBlock.h:122
IOSS_NODISCARD bool contains_node(size_t global_offset) const
Definition Ioss_StructuredBlock.h:325
IOSS_NODISCARD size_t get_node_offset() const
Definition Ioss_StructuredBlock.h:168
IOSS_NODISCARD std::string contains_string() const override
What does this entity contain.
Definition Ioss_StructuredBlock.h:123
void set_cell_offset(size_t offset)
Definition Ioss_StructuredBlock.h:164
IOSS_NODISCARD size_t get_global_cell_id(int i, int j, int k) const
Definition Ioss_StructuredBlock.h:185
IOSS_NODISCARD const Ioss::NodeBlock & get_node_block() const
Definition Ioss_StructuredBlock.h:126
size_t get_cell_node_ids(INT_t *idata, bool add_offset) const
Definition Ioss_StructuredBlock.h:249
std::vector< size_t > m_blockLocalNodeIndex
Definition Ioss_StructuredBlock.h:363
IOSS_NODISCARD size_t get_global_cell_id(IJK_t index) const
Definition Ioss_StructuredBlock.h:191
IOSS_NODISCARD EntityType type() const override
Get the EntityType, which indicates the particular type of GroupingEntity this is.
Definition Ioss_StructuredBlock.h:124
IOSS_NODISCARD size_t get_node_global_offset() const
Definition Ioss_StructuredBlock.h:170
IJK_t m_ijk
Definition Ioss_StructuredBlock.h:348
size_t get_cell_ids(INT_t *idata, bool add_offset) const
Definition Ioss_StructuredBlock.h:290
IOSS_NODISCARD IJK_t get_ijk_local() const
Definition Ioss_StructuredBlock.h:180
Ioss::NodeBlock m_nodeBlock
Definition Ioss_StructuredBlock.h:358
void set_cell_global_offset(size_t offset)
Definition Ioss_StructuredBlock.h:166
IOSS_NODISCARD IJK_t get_ijk_offset() const
Definition Ioss_StructuredBlock.h:179
IOSS_NODISCARD size_t get_block_local_node_offset(int ii, int jj, int kk) const
Definition Ioss_StructuredBlock.h:213
IJK_t m_offset
Definition Ioss_StructuredBlock.h:349
IOSS_NODISCARD size_t get_local_node_offset(int i, int j, int k) const
Definition Ioss_StructuredBlock.h:231
IOSS_NODISCARD size_t get_local_node_offset(IJK_t index) const
Definition Ioss_StructuredBlock.h:236
IOSS_NODISCARD IJK_t get_ijk_global() const
Definition Ioss_StructuredBlock.h:181
IOSS_NODISCARD size_t get_global_node_offset(IJK_t index) const
Definition Ioss_StructuredBlock.h:206
IJK_t m_ijkGlobal
Definition Ioss_StructuredBlock.h:350
void set_node_offset(size_t offset)
Set the 'offset' for the block.
Definition Ioss_StructuredBlock.h:163
std::vector< BoundaryCondition > m_boundaryConditions
Definition Ioss_StructuredBlock.h:362
IOSS_NODISCARD size_t get_cell_global_offset() const
Definition Ioss_StructuredBlock.h:171
The main namespace for the Ioss library.
Definition Ioad_DatabaseIO.C:40
std::ostream & operator<<(std::ostream &os, const BoundaryCondition &bc)
Definition Ioss_StructuredBlock.C:382
std::array< int, 3 > IJK_t
Definition Ioss_CodeTypes.h:24
EntityType
The particular type of GroupingEntity.
Definition Ioss_EntityType.h:12
@ STRUCTUREDBLOCK
Definition Ioss_EntityType.h:27
Definition Ioss_BoundingBox.h:13
Definition Ioss_StructuredBlock.h:44
void serialize(Archive &archive)
Definition Ioss_StructuredBlock.h:88
BoundaryCondition(std::string name, Ioss::IJK_t range_beg, Ioss::IJK_t range_end)
Definition Ioss_StructuredBlock.h:53
BoundaryCondition(std::string name, std::string fam_name, Ioss::IJK_t range_beg, Ioss::IJK_t range_end)
Definition Ioss_StructuredBlock.h:45
BoundaryCondition & operator=(const BoundaryCondition &copy_from)=default
BoundaryCondition(const BoundaryCondition &copy_from)=default
IOSS_NODISCARD bool operator!=(const Ioss::BoundaryCondition &rhs) const