IOSS  2.0
Ioss_StructuredBlock.h
Go to the documentation of this file.
1 // Copyright(C) 1999-2017 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 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //
12 // * Redistributions in binary form must reproduce the above
13 // copyright notice, this list of conditions and the following
14 // disclaimer in the documentation and/or other materials provided
15 // with the distribution.
16 //
17 // * Neither the name of NTESS nor the names of its
18 // contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 
33 #ifndef IOSS_Ioss_StructuredBlock_h
34 #define IOSS_Ioss_StructuredBlock_h
35 
36 #include <Ioss_BoundingBox.h>
37 #include <Ioss_CodeTypes.h>
38 #include <Ioss_EntityBlock.h>
39 #include <Ioss_NodeBlock.h>
40 #include <Ioss_Property.h>
41 #include <Ioss_ZoneConnectivity.h>
42 #include <array>
43 #include <cassert>
44 #include <string>
45 
46 #if defined(SEACAS_HAVE_CGNS) && !defined(SIERRA_PARALLEL_MPI)
47 #include <cgnstypes.h>
48 using INT = cgsize_t;
49 #else
50 // If this is not being built with CGNS, then default to using 32-bit integers.
51 // Currently there is no way to input/output a structured mesh without CGNS,
52 // so this block is simply to get things to compile and probably has no use.
53 using INT = int;
54 #endif
55 
56 namespace Ioss {
57  class Region;
58 
60  {
61  BoundaryCondition(const std::string name, const std::string fam_name,
62  const Ioss::IJK_t range_beg, const Ioss::IJK_t range_end)
63  : m_bcName(std::move(name)), m_famName(std::move(fam_name)),
64  m_rangeBeg(std::move(range_beg)), m_rangeEnd(std::move(range_end))
65  {
66  }
67 
68  // Deprecated... Use the constructor above with both name and fam_name
69  BoundaryCondition(const std::string name, const Ioss::IJK_t range_beg,
70  const Ioss::IJK_t range_end)
71  : m_bcName(name), m_famName(std::move(name)), m_rangeBeg(std::move(range_beg)),
72  m_rangeEnd(std::move(range_end))
73  {
74  }
75 
76  BoundaryCondition(const BoundaryCondition &copy_from) = default;
77 
78  // Determine which "face" of the parent block this BC is applied to.
79  int which_parent_face() const;
80 
81  // Return number of cell faces in the BC
82  size_t get_face_count() const;
83 
84  std::string m_bcName;
85  std::string m_famName;
86 
87  // These are potentially subsetted due to parallel decompositions...
90 
91  friend std::ostream &operator<<(std::ostream &os, const BoundaryCondition &bc);
92  };
93 
94  class DatabaseIO;
95 
96  /** \brief A structured zone -- i,j,k
97  */
99  {
100  public:
101  StructuredBlock(DatabaseIO *io_database, const std::string &my_name, int index_dim, int ni,
102  int nj, int nk, int off_i, int off_j, int off_k, int glo_ni, int glo_nj,
103  int glo_nk);
104  StructuredBlock(DatabaseIO *io_database, const std::string &my_name, int index_dim,
105  Ioss::IJK_t &ordinal, Ioss::IJK_t &offset, Ioss::IJK_t &global_ordinal);
106 
107  // Useful for serial
108  StructuredBlock(DatabaseIO *io_database, const std::string &my_name, int index_dim, int ni,
109  int nj, int nk);
110  StructuredBlock(DatabaseIO *io_database, const std::string &my_name, int index_dim,
111  Ioss::IJK_t &ordinal);
112 
113  StructuredBlock *clone(DatabaseIO *database) const;
114 
115  ~StructuredBlock() override;
116 
117  std::string type_string() const override { return "StructuredBlock"; }
118  std::string short_type_string() const override { return "structuredblock"; }
119  EntityType type() const override { return STRUCTUREDBLOCK; }
120 
121  const Ioss::NodeBlock &get_node_block() const { return m_nodeBlock; }
122 
123  /** \brief Does block contain any cells
124  */
125  bool is_active() const
126  {
127  return m_ni * m_nj * m_nk > 0;
128  }
129 
130  // Handle implicit properties -- These are calcuated from data stored
131  // in the grouping entity instead of having an explicit value assigned.
132  // An example would be 'element_block_count' for a region.
133  Property get_implicit_property(const std::string &my_name) const override;
134 
135  AxisAlignedBoundingBox get_bounding_box() const;
136 
137  /** \brief Set the 'offset' for the block.
138  *
139  * The 'offset' is used to map a cell or node location within a
140  * structured block to the model implicit cell or node location
141  * on a single processor. zero-based.
142  *
143  * The 'global' offsets do the same except for they apply over
144  * the entire model on all processors. zero-based.
145  *
146  * For example, the file descriptor (1-based) of
147  * the 37th cell in the 4th block is calculated by:
148  *
149  * file_descriptor = offset of block 4 + 37
150  *
151  * This can also be used to determine which structured block
152  * a cell with a file_descriptor maps into. An particular
153  * structured block contains all cells in the range:
154  *
155  * offset < file_descriptor <= offset+number_cells_per_block
156  *
157  * Note that for nodes, the nodeOffset does not take into account
158  * the nodes that are shared between blocks.
159  */
160  void set_node_offset(size_t offset) { m_nodeOffset = offset; }
161  void set_cell_offset(size_t offset) { m_cellOffset = offset; }
162  void set_node_global_offset(size_t offset) { m_nodeGlobalOffset = offset; }
163  void set_cell_global_offset(size_t offset) { m_cellGlobalOffset = offset; }
164 
165  size_t get_node_offset() const { return m_nodeOffset; }
166  size_t get_cell_offset() const { return m_cellOffset; }
167  size_t get_node_global_offset() const { return m_nodeGlobalOffset; }
168  size_t get_cell_global_offset() const { return m_cellGlobalOffset; }
169 
170  // Get the global (over all processors) cell
171  // id at the specified i,j,k location (1 <= i,j,k <= ni,nj,nk). 1-based.
172  size_t get_global_cell_id(int i, int j, int k) const
173  {
174  return m_cellGlobalOffset + static_cast<size_t>(k - 1) * m_niGlobal * m_njGlobal +
175  static_cast<size_t>(j - 1) * m_niGlobal + i;
176  }
177 
178  size_t get_global_cell_id(IJK_t index) const
179  {
180  return get_global_cell_id(index[0], index[1], index[2]);
181  }
182 
183  // Get the global (over all processors) node
184  // offset at the specified i,j,k location (1 <= i,j,k <= ni,nj,nk). 0-based, does not account
185  // for shared nodes.
186  size_t get_global_node_offset(int i, int j, int k) const
187  {
188  return m_nodeGlobalOffset + static_cast<size_t>(k - 1) * (m_niGlobal + 1) * (m_njGlobal + 1) +
189  static_cast<size_t>(j - 1) * (m_niGlobal + 1) + i - 1;
190  }
191 
192  size_t get_global_node_offset(IJK_t index) const
193  {
194  return get_global_node_offset(index[0], index[1], index[2]);
195  }
196 
197  // Get the local (relative to this block on this processor) node id at the specified
198  // i,j,k location (1 <= i,j,k <= ni+1,nj+1,nk+1). 0-based.
199  size_t get_block_local_node_offset(int ii, int jj, int kk) const
200  {
201  auto i = ii - m_offsetI;
202  auto j = jj - m_offsetJ;
203  auto k = kk - m_offsetK;
204  assert(i > 0 && i <= m_ni + 1 && j > 0 && j <= m_nj + 1 && k > 0 && k <= m_nk + 1);
205  return static_cast<size_t>(k - 1) * (m_ni + 1) * (m_nj + 1) +
206  static_cast<size_t>(j - 1) * (m_ni + 1) + i - 1;
207  }
208 
209  size_t get_block_local_node_offset(IJK_t index) const
210  {
211  return get_block_local_node_offset(index[0], index[1], index[2]);
212  }
213 
214  // Get the local (on this processor) cell-node offset at the specified
215  // i,j,k location (1 <= i,j,k <= ni+1,nj+1,nk+1). 0-based.
216  size_t get_local_node_offset(int i, int j, int k) const
217  {
218  return get_block_local_node_offset(i, j, k) + m_nodeOffset;
219  }
220 
221  size_t get_local_node_offset(IJK_t index) const
222  {
223  return get_local_node_offset(index[0], index[1], index[2]);
224  }
225 
226  std::vector<INT> get_cell_node_ids(bool add_offset) const
227  {
228  size_t node_count = get_property("node_count").get_int();
229  std::vector<INT> ids(node_count);
230  get_cell_node_ids(ids.data(), add_offset);
231  return ids;
232  }
233 
234  template <typename INT_t> size_t get_cell_node_ids(INT_t *idata, bool add_offset) const
235  {
236  // Fill 'idata' with the cell node ids which are the
237  // 1-based location of each node in this zone
238  // The location is based on the "model" (all processors) zone.
239  // If this is a parallel decomposed model, then
240  // this block may be a subset of the "model" zone
241  //
242  // if 'add_offset' is true, then add the m_cellGlobalOffset
243  // which changes the location to be the location in the
244  // entire "mesh" instead of within a "zone" (all processors)
245 
246  size_t index = 0;
247  size_t offset = add_offset ? m_nodeGlobalOffset : 0;
248 
249  if (m_nk == 0 && m_nj == 0 && m_ni == 0) {
250  return index;
251  }
252 
253  for (int kk = 0; kk < m_nk + 1; kk++) {
254  size_t k = m_offsetK + kk;
255  for (int jj = 0; jj < m_nj + 1; jj++) {
256  size_t j = m_offsetJ + jj;
257  for (int ii = 0; ii < m_ni + 1; ii++) {
258  size_t i = m_offsetI + ii;
259 
260  size_t ind = k * (m_niGlobal + 1) * (m_njGlobal + 1) + j * (m_niGlobal + 1) + i;
261 
262  idata[index++] = ind + offset + 1;
263  }
264  }
265  }
266 
267  for (auto idx_id : m_globalIdMap) {
268  idata[idx_id.first] = idx_id.second;
269  }
270 
271  return index;
272  }
273 
274  template <typename INT_t> size_t get_cell_ids(INT_t *idata, bool add_offset) const
275  {
276  // Fill 'idata' with the cell ids which are the
277  // 1-based location of each cell in this zone
278  // The location is based on the "model" zone.
279  // If this is a parallel decomposed model, then
280  // this block may be a subset of the "model" zone
281  //
282  // if 'add_offset' is true, then add the m_cellGlobalOffset
283  // which changes the location to be the location in the
284  // entire "mesh" instead of within a "zone"
285 
286  size_t index = 0;
287  size_t offset = add_offset ? m_cellGlobalOffset : 0;
288 
289  if (m_nk == 0 && m_nj == 0 && m_ni == 0) {
290  return index;
291  }
292 
293  for (int kk = 0; kk < m_nk; kk++) {
294  size_t k = m_offsetK + kk;
295  for (int jj = 0; jj < m_nj; jj++) {
296  size_t j = m_offsetJ + jj;
297  for (int ii = 0; ii < m_ni; ii++) {
298  size_t i = m_offsetI + ii;
299 
300  size_t ind = k * m_niGlobal * m_njGlobal + j * m_niGlobal + i;
301 
302  idata[index++] = ind + offset + 1;
303  }
304  }
305  }
306  return index;
307  }
308 
309  bool contains(size_t global_offset) const
310  {
311  return (global_offset >= m_nodeOffset &&
312  global_offset < m_nodeOffset + get_property("node_count").get_int());
313  }
314 
315  protected:
316  int64_t internal_get_field_data(const Field &field, void *data,
317  size_t data_size) const override;
318 
319  int64_t internal_put_field_data(const Field &field, void *data,
320  size_t data_size) const override;
321 
322  private:
323  int m_ni{};
324  int m_nj{};
325  int m_nk{};
326 
327  int m_offsetI{}; // Valid 'i' ordinal runs from m_offsetI+1 to m_offsetI+m_ni
328  int m_offsetJ{};
329  int m_offsetK{};
330 
331  int m_niGlobal{}; // The ni,nj,nk of the master block this is a subset of.
332  int m_njGlobal{};
333  int m_nkGlobal{};
334 
335  size_t m_nodeOffset{};
336  size_t m_cellOffset{};
337 
338  size_t m_nodeGlobalOffset{};
339  size_t m_cellGlobalOffset{};
340 
342 
343  public:
344  std::vector<ZoneConnectivity> m_zoneConnectivity;
345  std::vector<BoundaryCondition> m_boundaryConditions;
346  std::vector<size_t> m_blockLocalNodeIndex;
347  std::vector<std::pair<size_t, size_t>> m_globalIdMap;
348  };
349 } // namespace Ioss
350 #endif
bool contains(size_t global_offset) const
Definition: Ioss_StructuredBlock.h:309
A named value that has a known type.
Definition: Ioss_Property.h:47
The main namespace for the Ioss library.
Definition: Iocgns_DatabaseIO.h:50
An input or output Database.
Definition: Ioss_DatabaseIO.h:80
friend std::ostream & operator<<(std::ostream &os, const BoundaryCondition &bc)
Definition: Ioss_StructuredBlock.C:263
Definition: Ioss_BoundingBox.h:37
Ioss::NodeBlock m_nodeBlock
Definition: Ioss_StructuredBlock.h:341
size_t get_local_node_offset(IJK_t index) const
Definition: Ioss_StructuredBlock.h:221
Definition: json.h:1157
const Ioss::NodeBlock & get_node_block() const
Definition: Ioss_StructuredBlock.h:121
size_t get_cell_node_ids(INT_t *idata, bool add_offset) const
Definition: Ioss_StructuredBlock.h:234
std::vector< size_t > m_blockLocalNodeIndex
Definition: Ioss_StructuredBlock.h:346
size_t get_global_cell_id(int i, int j, int k) const
Definition: Ioss_StructuredBlock.h:172
size_t get_face_count() const
Definition: Ioss_StructuredBlock.C:227
void set_node_offset(size_t offset)
Set the &#39;offset&#39; for the block.
Definition: Ioss_StructuredBlock.h:160
A structured zone – i,j,k.
Definition: Ioss_StructuredBlock.h:98
std::string type_string() const override
Get the name of the particular type of entity.
Definition: Ioss_StructuredBlock.h:117
Base class for all &#39;block&#39;-type grouping entities, which means all members of the block are similar o...
Definition: Ioss_EntityBlock.h:61
Ioss::IJK_t m_rangeEnd
Definition: Ioss_StructuredBlock.h:89
int which_parent_face() const
Definition: Ioss_StructuredBlock.C:250
size_t get_global_node_offset(int i, int j, int k) const
Definition: Ioss_StructuredBlock.h:186
std::array< int, 3 > IJK_t
Definition: Ioss_CodeTypes.h:45
std::string m_bcName
Definition: Ioss_StructuredBlock.h:84
Definition: Ioss_StructuredBlock.h:59
size_t get_cell_global_offset() const
Definition: Ioss_StructuredBlock.h:168
void set_node_global_offset(size_t offset)
Definition: Ioss_StructuredBlock.h:162
size_t get_block_local_node_offset(IJK_t index) const
Definition: Ioss_StructuredBlock.h:209
void set_cell_global_offset(size_t offset)
Definition: Ioss_StructuredBlock.h:163
A collection of all nodes in the region.
Definition: Ioss_NodeBlock.h:53
bool is_active() const
Does block contain any cells.
Definition: Ioss_StructuredBlock.h:125
std::vector< INT > get_cell_node_ids(bool add_offset) const
Definition: Ioss_StructuredBlock.h:226
Ioss::IJK_t m_rangeBeg
Definition: Ioss_StructuredBlock.h:88
std::vector< BoundaryCondition > m_boundaryConditions
Definition: Ioss_StructuredBlock.h:345
int INT
Definition: Ioss_StructuredBlock.h:53
std::string short_type_string() const override
Get a short name of the particular type of entity.
Definition: Ioss_StructuredBlock.h:118
size_t get_node_offset() const
Definition: Ioss_StructuredBlock.h:165
void set_cell_offset(size_t offset)
Definition: Ioss_StructuredBlock.h:161
size_t get_cell_offset() const
Definition: Ioss_StructuredBlock.h:166
Definition: Ioss_EntityType.h:54
std::string m_famName
Definition: Ioss_StructuredBlock.h:85
size_t get_node_global_offset() const
Definition: Ioss_StructuredBlock.h:167
size_t get_global_cell_id(IJK_t index) const
Definition: Ioss_StructuredBlock.h:178
std::string name(Ioss::GroupingEntity *entity)
Definition: io_info.C:71
size_t get_global_node_offset(IJK_t index) const
Definition: Ioss_StructuredBlock.h:192
Holds metadata for bulk data associated with a GroupingEntity.
Definition: Ioss_Field.h:47
std::vector< ZoneConnectivity > m_zoneConnectivity
Definition: Ioss_StructuredBlock.h:344
EntityType type() const override
Get the EntityType, which indicates the particular type of GroupingEntity this is.
Definition: Ioss_StructuredBlock.h:119
EntityType
The particular type of GroupingEntity.
Definition: Ioss_EntityType.h:39
std::vector< std::pair< size_t, size_t > > m_globalIdMap
Definition: Ioss_StructuredBlock.h:347
size_t get_local_node_offset(int i, int j, int k) const
Definition: Ioss_StructuredBlock.h:216
size_t get_block_local_node_offset(int ii, int jj, int kk) const
Definition: Ioss_StructuredBlock.h:199
BoundaryCondition(const std::string name, const std::string fam_name, const Ioss::IJK_t range_beg, const Ioss::IJK_t range_end)
Definition: Ioss_StructuredBlock.h:61
BoundaryCondition(const std::string name, const Ioss::IJK_t range_beg, const Ioss::IJK_t range_end)
Definition: Ioss_StructuredBlock.h:69
std::vector< char > data
Definition: Ioss_Utils.C:78
size_t get_cell_ids(INT_t *idata, bool add_offset) const
Definition: Ioss_StructuredBlock.h:274