NEMoSys  0.63.0
A modular, extensible resource with robust automated mesh generation, mesh quality analysis, adaptive mesh refinement, and data transfer between arbitrary meshes.
exoGeoMesh.H
Go to the documentation of this file.
1 /*******************************************************************************
2 * Promesh *
3 * Copyright (C) 2022, IllinoisRocstar LLC. All rights reserved. *
4 * *
5 * Promesh is the property of IllinoisRocstar LLC. *
6 * *
7 * IllinoisRocstar LLC *
8 * Champaign, IL *
9 * www.illinoisrocstar.com *
10 * promesh@illinoisrocstar.com *
11 *******************************************************************************/
12 /*******************************************************************************
13 * This file is part of Promesh *
14 * *
15 * This version of Promesh is free software: you can redistribute it and/or *
16 * modify it under the terms of the GNU Lesser General Public License as *
17 * published by the Free Software Foundation, either version 3 of the License, *
18 * or (at your option) any later version. *
19 * *
20 * Promesh is distributed in the hope that it will be useful, but WITHOUT ANY *
21 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more *
23 * details. *
24 * *
25 * You should have received a copy of the GNU Lesser General Public License *
26 * along with this program. If not, see <https://www.gnu.org/licenses/>. *
27 * *
28 *******************************************************************************/
29 #ifndef NEMOSYS_EXOGEOMESH_H_
30 #define NEMOSYS_EXOGEOMESH_H_
31 
32 #include "nemosys_export.h"
33 #include "Mesh/geoMeshBase.H"
34 
35 #include <map>
36 #include <set>
37 #include <string>
38 #include <utility>
39 #include <vector>
40 
41 #include <vtkExodusIIReader.h>
42 
43 namespace NEM {
44 namespace MSH {
45 
46 /**
47  * @class exoGeoMesh
48  * @brief A concrete implementation of @c geoMeshBase representing an Exodus II
49  * mesh
50  * @details Note that only the title, dimension, element blocks, element block
51  * properties, element block variables, node variables, global variables, node
52  * sets, and side sets (and the names of each of these fields) are read and
53  * stored in an exoGeoMesh class. Side set sides are ignored if the source
54  * element does not have the same dimensionality as the mesh.
55  */
56 class NEMOSYS_EXPORT exoGeoMesh : public geoMeshBase {
57  public:
58  vtkSmartPointer<vtkPolyData> getSS() { return getGeoMesh().sideSet.sides; }
59  public:
60  static exoGeoMesh *New();
61  vtkTypeMacro(exoGeoMesh, geoMeshBase)
62 
63  public:
64  /**
65  * Reads an EXODUS II file into an exoGeoMesh object.
66  * @param fileName Name of file to read. Empty string interpreted as creating
67  * new exoGeoMesh with empty mesh
68  * @param timeStep Time step (using EXODUS II indexing) to read
69  * @return Pointer to a new exoGeoMesh object
70  */
71  static exoGeoMesh *Read(const std::string &fileName, int timeStep = 1);
72 
73  public:
74  exoGeoMesh();
75 
76  /**
77  * @brief exoGeoMesh constructor from file.
78  * @param fileName Name of EXODUS II file to read
79  * @param timeStep Time step (using EXODUS II indexing) to read
80  */
81  explicit exoGeoMesh(const std::string &fileName, int timeStep = 1);
82 
83  ~exoGeoMesh() override;
84 
85  protected:
86  /**
87  * @brief exoGeoMesh constructor from vtkExodusIIReader
88  * @details Note that side set side indices in the reader's output are ignored
89  * and are read from @c reader->GetFileName() instead. Element block
90  * properties are also read from the file separately.
91  * @param reader Existing vtkExodusIIReader from which to create exoGeoMesh
92  * object. Update() should already have been called.
93  */
94  explicit exoGeoMesh(const vtkSmartPointer<vtkExodusIIReader> &reader);
95 
96  public:
97  /**
98  * @brief Write exoGeoMesh out to a file.
99  * @details If @p fileName already exists, it is overwritten. If there are
100  * more than 900 side sets, they are concatenated, with a side set variable
101  * named @c "NEM_SIDE_SET_ID" added that contains the id of the side in this
102  * exoGeoMesh.
103  * @param fileName Name of file. Must end in ".exo", ".e", ".gen", or ".g"
104  */
105  void write(const std::string &fileName) override;
106  /**
107  * Write a summary of this exoGeoMesh to @p out.
108  * @param out Stream to write summary to.
109  */
110  void report(std::ostream &out) const override;
111  /**
112  * @copydoc geoMeshBase::reconstructGeo()
113  * If @c physGrpName is not empty, then physical groups are set based on the
114  * property @c physGrpName for each element block. Otherwise, each element
115  * block represents its own physical group.
116  */
117  void reconstructGeo() override;
118  void takeGeoMesh(geoMeshBase *otherGeoMesh) override;
119 
120  /**
121  * Get the title of the exoGeoMesh (used for writing out to EXODUS II file)
122  * @return reference to title
123  */
124  const std::string &getTitle() const;
125  /**
126  * Set the title of the exoGeoMesh (used for writing out to EXODUS II file)
127  * @param title new title to set
128  */
129  void setTitle(const std::string &title);
130  /**
131  * Get number of element blocks
132  * @return number of element blocks
133  */
134  int getNumElemBlocks() const;
135  /**
136  * Get all element block names
137  * @return element block names, indexed by ID
138  */
139  std::map<int, std::string> getElemBlockNames() const;
140  /**
141  * Get the name of an element block (used for writing out to EXODUS II file)
142  * @param id ID of the element block
143  * @return reference to block name
144  */
145  const std::string &getElemBlockName(int id) const;
146  /**
147  * Set the name of an element block (used for writing out to EXODUS II file)
148  * @param id ID of the element block
149  * @param name new name of the element block
150  */
151  void setElemBlockName(int id, const std::string &name);
152  /**
153  * Get all element block IDs.
154  * @return All element block IDs.
155  */
156  std::vector<int> getElemBlockIds() const;
157  /**
158  * Get the element block ID of a cell
159  * @param cellIdx 0-based index of a cell
160  * @return block ID that the cell belongs to; -1 if not found
161  */
162  int getElemBlockId(vtkIdType cellIdx) const;
163  /**
164  * Get (0-based) indices of the cells that are in a specific element block
165  * @param blockId ID of an element block
166  * @return Indices of all cells that belong to @p blockID
167  */
168  std::vector<vtkIdType> getElemBlock(int blockId) const;
169  /**
170  * Add a new element block to the mesh. Invalidates geometry, if any.
171  * PointData and CellData arrays are intersected.
172  * @param elements vtkUnstructuredGrid of cells to add to the mesh. All
173  * cells should be of same cell type.
174  * @param name Name of new element block
175  * @param tol Tolerance for merging points
176  * @return The ID of the new element block.
177  */
178  int addElemBlock(vtkUnstructuredGrid *elements, const std::string &name = "",
179  float tol = 1e-15f);
180  /**
181  * Add cells to an existing element block. Invalidates geometry, if any.
182  * PointData and CellData arrays are intersected.
183  * @param elements vtkUnstructuredGrid of cells to add to the mesh. All
184  * cells should be of the same type as cells in the block given by @p blockId.
185  * @param blockId ID of existing element block
186  * @param tol Tolerance for merging points
187  */
188  void addCellsToBlock(vtkUnstructuredGrid *elements, int blockId,
189  float tol = 1e-15f);
190  /**
191  * @brief Reassign cells to a different element block
192  * @details Cells must all have same cell type. May result in empty blocks.
193  * Invalidates geometry, if any.
194  * @param cells vector of cell indices
195  * @param blockId id of block to assign to; if not an existing block, one is
196  * created (if @p blockId is positive, the new block will have that ID;
197  * otherwise, one is chosen)
198  * @param elemBlockName if blockId is not an existing block, the name of the
199  * new block
200  * @return element block that the cells were assigned to
201  */
202  int reassignCells(const std::vector<vtkIdType> &cells, int blockId = -1,
203  const std::string &elemBlockName = {});
204  /**
205  * Add a property to element blocks (with default value 0 on all element
206  * blocks)
207  * @param propName Name of new property
208  * @return Whether or not new property was added
209  */
210  bool addElemBlockProperty(const std::string &propName);
211  /**
212  * Get the names of all block properties
213  * @return Names of all element block properties
214  */
215  std::vector<std::string> getElemBlockPropertyNames() const;
216  /**
217  * Get the value of an element block property on a block
218  * @param propName Name of an element block property
219  * @param blockId ID of an element block
220  * @return Value of a property on an element block
221  */
222  int getElemBlockProperty(const std::string &propName, int blockId) const;
223  /**
224  * Set the value of an element block property on a block
225  * @param propName Name of an element block property
226  * @param blockId ID of an element block
227  * @param value Value of a property on an element block
228  */
229  void setElemBlockProperty(const std::string &propName, int blockId,
230  int value);
231  /**
232  * Get number of side sets
233  * @return number of side sets
234  */
235  int getNumSideSets() const;
236  /**
237  * Get all side set names
238  * @return side set names, indexed by ID
239  */
240  const std::map<int, std::string> &getSideSetNames() const;
241  /**
242  * Get the name of a side set (used for writing out to EXODUS II file)
243  * @param id ID of a side set
244  * @return Reference to the name of a side set
245  */
246  const std::string &getSideSetName(int id) const;
247  /**
248  * Set the name of a side set (used for writing out to EXODUS II file)
249  * @param id ID of a side set
250  * @param name New name of the side set
251  */
252  void setSideSetName(int id, const std::string &name);
253  /**
254  * Get all side set IDs.
255  * @return All side set IDs.
256  */
257  std::vector<int> getSideSetIds() const;
258  /**
259  * Get sides in a side set
260  * @param sideSetId ID of a side set
261  * @return Pair of vectors, first of which contains the (0-based) index
262  * of the cell the side belongs to and the second contains the side (according
263  * to VTK face/edge ordering)
264  */
265  std::pair<std::vector<vtkIdType>, std::vector<int>> getSideSet(
266  int sideSetId) const;
267  /**
268  * Add a new side set
269  * @param elements The (0-based) index of the cells that each side comes from
270  * @param sides The index of the face/edge that of the side (according to VTK
271  * face/edge ordering)
272  * @param name Name of new side set
273  * @return ID of new side set
274  */
275  int addSideSet(const std::vector<vtkIdType> &elements,
276  const std::vector<int> &sides, const std::string &name = "");
277  /**
278  * Get number of node sets
279  * @return number of node sets
280  */
281  int getNumNodeSets() const;
282  /**
283  * Get all node set names
284  * @return node set names, indexed by ID
285  */
286  std::map<int, std::string> getNodeSetNames() const;
287  /**
288  * Get the name of a node set (used for writing out to EXODUS II file)
289  * @param id ID of a node set
290  * @return Reference to the name of a node set
291  */
292  const std::string &getNodeSetName(int id) const;
293  /**
294  * Set the name of a node set (used for writing out to EXODUS II file)
295  * @param id ID of a node set
296  * @param name New name of the node set
297  */
298  void setNodeSetName(int id, const std::string &name);
299  /**
300  * Get the IDs of all node sets
301  * @return All node set IDs
302  */
303  std::vector<int> getNodeSetIds() const;
304  /**
305  * Get the nodes of a node set.
306  * @param nodeSetId ID of a node set
307  * @return Vector of (0-based) node indices of the nodes in the node set.
308  */
309  const std::vector<vtkIdType> &getNodeSet(int nodeSetId) const;
310  /**
311  * Add a new node set
312  * @param nodes Node indices that should belong on the new node set (0-based
313  * indexing)
314  * @param name Name of new node set
315  * @return ID of new node set
316  */
317  int addNodeSet(const std::vector<vtkIdType> &nodes,
318  const std::string &name = "");
319  /**
320  * Get the name of the element block property that maps element blocks to
321  * physical groups (if empty, each element block represents its own physical
322  * group)
323  * @return Name of element block property mapping element blocks to physical
324  * groups (or empty string if not set)
325  */
326  const std::string &getPhysGrpPropertyName() const;
327  /**
328  * Sets the name of the element block property that maps element blocks to
329  * physical groups (if empty, each element block represents its own physical
330  * group)
331  * @param physGrpName Name of element block property mapping element blocks to
332  * physical groups (use empty string to unset). Must be an existing element
333  * block property name.
334  */
335  void setPhysGrpPropertyName(const std::string &physGrpName);
336  /**
337  * Stitch another exoGeoMesh object onto this one. PointData and CellData
338  * arrays are intersected. Adds side sets and node sets if available. Element
339  * block properties from @p otherGM are copied if property also defined in
340  * this exoGeoMesh.
341  * @param otherGM Other exoGeoMesh to addd to this one
342  * @param tol Tolerance for merging points
343  */
344  void stitch(const exoGeoMesh &otherGM, float tol = 1e-15f);
345  /**
346  * Scale point locations. Does not change point data.
347  * @param scale Multiplicative factor for point locations
348  */
349  void scaleNodes(double scale);
350 
351  private:
352  static vtkSmartPointer<vtkExodusIIReader> getExoReader(
353  const std::string &fileName, int timeStep = 1);
354  static GeoMesh exoReader2GM(vtkSmartPointer<vtkExodusIIReader> reader);
355  static const char *getExoIdArrName();
356  /**
357  * Clears element block names, element block properties.
358  * Creates element blocks and sets the dimension based on the @c GeoMesh.
359  */
360  void resetElemBlocks();
361  /**
362  * Renumbers the nodes in all node sets based on @p nodeMap if provided.
363  * Removes duplicate node ids within a node set.
364  * @param nodeMap map from old to new node indices (can be many-to-one)
365  */
366  void resetNodeSetPoints(vtkIdTypeArray *nodeMap = nullptr);
367  /**
368  * Sets the (Exodus) side set IDs of each cell in the @c GeoMesh.sideSet by
369  * creating a side set for each pair (side entity, parent entity).
370  */
371  void setSideSetObjId();
372 
373  void resetNative() override;
374 
375  protected:
376  struct NEMOSYS_NO_EXPORT elemBlock {
377  std::string name;
378  VTKCellType cellType;
379  std::map<std::string, int> properties; // missing values treated as 0
380  };
381  struct NEMOSYS_NO_EXPORT nodeSet {
382  std::string name;
383  std::vector<vtkIdType> nodes; // correspond to indices in the _geoMesh.mesh
384  };
385 
386  private:
387  std::string _title;
388  std::map<int, elemBlock> _elemBlocks;
389  std::map<int, std::string> _sideSetNames;
390  std::map<int, nodeSet> _nodeSets;
391  std::set<std::string> _elemBlockPropNames;
392  std::string _physGrpName; // Should correspond to a property
393 };
394 
395 } // namespace MSH
396 } // namespace NEM
397 
398 #endif // NEMOSYS_EXOGEOMESH_H_
std::string _title
Definition: exoGeoMesh.H:387
std::set< std::string > _elemBlockPropNames
Definition: exoGeoMesh.H:391
std::vector< std::pair< vtkIdType, std::vector< double > > > nodes
Each entry stores (node ID in .inp file, coordinates)
Definition: inpGeoMesh.C:139
geoMeshBase * Read(const std::string &fileName)
Read a mesh from file.
std::map< int, std::string > _sideSetNames
Definition: exoGeoMesh.H:389
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
std::map< int, elemBlock > _elemBlocks
Definition: exoGeoMesh.H:388
std::map< int, nodeSet > _nodeSets
Definition: exoGeoMesh.H:390
vtkSmartPointer< vtkPolyData > getSS()
Definition: exoGeoMesh.H:58
std::array< int, 2 > sides
A concrete implementation of geoMeshBase representing an Exodus II mesh.
Definition: exoGeoMesh.H:56
std::vector< vtkIdType > nodes
Definition: exoGeoMesh.H:383
std::string _physGrpName
Definition: exoGeoMesh.H:392
std::map< std::string, int > properties
Definition: exoGeoMesh.H:379
abstract class to specify geometry and mesh data
Definition: geoMeshBase.H:102