1 // Copyright(C) 1999-2020 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 #ifndef IOSS_Ioss_Region_h
8 #define IOSS_Ioss_Region_h
9
10 #include "vtk_ioss_mangle.h"
11
12 #include <Ioss_CoordinateFrame.h> // for CoordinateFrame
13 #include <Ioss_DatabaseIO.h> // for DatabaseIO
14 #include <Ioss_EntityType.h> // for EntityType, etc
15 #include <Ioss_GroupingEntity.h> // for GroupingEntity
16 #include <Ioss_MeshType.h>
17 #include <Ioss_Property.h> // for Property
18 #include <Ioss_State.h> // for State
19 #include <cstddef> // for size_t, nullptr
20 #include <cstdint> // for int64_t
21 #include <functional> // for less
22 #include <iosfwd> // for ostream
23 #include <map> // for map, map<>::value_compare
24 #include <string> // for string, operator<
25 #include <utility> // for pair
26 #include <vector> // for vector
27 namespace Ioss {
28 class Assembly;
29 class Blob;
30 class CommSet;
31 class EdgeBlock;
32 class EdgeSet;
33 class ElementBlock;
34 class ElementSet;
35 class FaceBlock;
36 class FaceSet;
37 class Field;
38 class NodeBlock;
39 class NodeSet;
40 class SideBlock;
41 class SideSet;
42 class StructuredBlock;
43 } // namespace Ioss
44 // Needed for node_global_to_local inline function.
45
46 namespace Ioss {
47
48 class CoordinateFrame;
49
50 using AssemblyContainer = std::vector<Ioss::Assembly *>;
51 using BlobContainer = std::vector<Ioss::Blob *>;
52
53 using NodeBlockContainer = std::vector<NodeBlock *>;
54 using EdgeBlockContainer = std::vector<EdgeBlock *>;
55 using FaceBlockContainer = std::vector<FaceBlock *>;
56 using ElementBlockContainer = std::vector<ElementBlock *>;
57
58 using NodeSetContainer = std::vector<NodeSet *>;
59 using EdgeSetContainer = std::vector<EdgeSet *>;
60 using FaceSetContainer = std::vector<FaceSet *>;
61 using ElementSetContainer = std::vector<ElementSet *>;
62
63 using SideSetContainer = std::vector<SideSet *>;
64 using StructuredBlockContainer = std::vector<StructuredBlock *>;
65 using CommSetContainer = std::vector<CommSet *>;
66 using StateTimeContainer = std::vector<double>;
67
68 using CoordinateFrameContainer = std::vector<CoordinateFrame>;
69
70 using AliasMap = std::map<std::string, std::string, std::less<std::string>>;
71
72 /** \brief A grouping entity that contains other grouping entities.
73 *
74 * Maintains a list of NodeBlocks, ElementBlocks, NodeLists, CommLists and Surfaces.
75 * [Similar to the "Composite Pattern" in Design Patterns] All interface to
76 * GroupingEntities is through the Region class; clients of the IO subsystem have no direct
77 * access to the underlying GroupingEntities (other than the Region).
78 */
79 class Region : public GroupingEntity
80 {
81 public:
82 explicit Region(DatabaseIO *iodatabase = nullptr, const std::string &my_name = "");
83
84 ~Region() override;
85
type_string()86 std::string type_string() const override { return "Region"; }
short_type_string()87 std::string short_type_string() const override { return "region"; }
contains_string()88 std::string contains_string() const override { return "Entities"; }
type()89 EntityType type() const override { return REGION; }
90
91 MeshType mesh_type() const;
92 const std::string mesh_type_string() const;
93 bool node_major() const;
94
95 void output_summary(std::ostream &strm, bool do_transient = true) const;
96
97 bool supports_field_type(Ioss::EntityType fld_type) const;
98
99 // Helper function...
100 int64_t node_global_to_local(int64_t global, bool must_exist = true) const;
101
102 bool begin_mode(State new_state);
103 bool end_mode(State current_state);
104
105 // Add a new state at this time, return state number
add_state(double time)106 virtual int add_state(double time)
107 {
108 IOSS_FUNC_ENTER(m_);
109 return add_state__(time);
110 }
111 virtual int add_state__(double time);
112
113 // Get time corresponding to specified state
114
115 virtual double get_state_time(int state = -1) const;
116 int get_current_state() const;
117 double begin_state(int state);
118 double end_state(int state);
119
120 /** \brief Determine whether the metadata defining the model (nontransient,
121 * geometry, and toploloty) has been set.
122 *
123 * \returns True if the metadata defining the model has been set.
124 */
model_defined()125 bool model_defined() const { return modelDefined; }
126
127 /** \brief Determine whether the metadata related to the transient
128 * data has been set.
129 *
130 * \returns True if the metadata related to the transient data has been set.
131 */
transient_defined()132 bool transient_defined() const { return transientDefined; }
133
134 // Return a pair consisting of the step (1-based) corresponding to
135 // the maximum time on the database and the corresponding maximum
136 // time value. Note that this may not necessarily be the last step
137 // on the database if cycle and overlay are being used.
138 std::pair<int, double> get_max_time() const;
139
140 // Return a pair consisting of the step (1-based) corresponding to
141 // the minimum time on the database and the corresponding minimum
142 // time value. Note that this may not necessarily be the first step
143 // on the database if cycle and overlay are being used.
144 std::pair<int, double> get_min_time() const;
145
146 // Functions for an output region...
147 bool add(NodeBlock *node_block);
148 bool add(EdgeBlock *edge_block);
149 bool add(FaceBlock *face_block);
150 bool add(ElementBlock *element_block);
151 bool add(SideSet *sideset);
152 bool add(NodeSet *nodeset);
153 bool add(EdgeSet *edgeset);
154 bool add(FaceSet *faceset);
155 bool add(ElementSet *elementset);
156 bool add(CommSet *commset);
157 bool add(StructuredBlock *structured_block);
158 bool add(Assembly *assembly);
159 bool add(Blob *blob);
160 bool add(const CoordinateFrame &frame);
161
162 // Special purpose...
163 bool remove(Assembly *removal);
164
165 const NodeBlockContainer & get_node_blocks() const;
166 const EdgeBlockContainer & get_edge_blocks() const;
167 const FaceBlockContainer & get_face_blocks() const;
168 const ElementBlockContainer & get_element_blocks() const;
169 const SideSetContainer & get_sidesets() const;
170 const NodeSetContainer & get_nodesets() const;
171 const EdgeSetContainer & get_edgesets() const;
172 const FaceSetContainer & get_facesets() const;
173 const ElementSetContainer & get_elementsets() const;
174 const CommSetContainer & get_commsets() const;
175 const StructuredBlockContainer &get_structured_blocks() const;
176 const AssemblyContainer & get_assemblies() const;
177 const BlobContainer & get_blobs() const;
178 const CoordinateFrameContainer &get_coordinate_frames() const;
179
180 // Retrieve the Grouping Entity with the specified name.
181 // Returns nullptr if the entity does not exist
182 GroupingEntity * get_entity(const std::string &my_name, EntityType io_type) const;
183 GroupingEntity * get_entity(const std::string &my_name) const;
184 NodeBlock * get_node_block(const std::string &my_name) const;
185 EdgeBlock * get_edge_block(const std::string &my_name) const;
186 FaceBlock * get_face_block(const std::string &my_name) const;
187 ElementBlock * get_element_block(const std::string &my_name) const;
188 SideSet * get_sideset(const std::string &my_name) const;
189 SideBlock * get_sideblock(const std::string &my_name) const;
190 NodeSet * get_nodeset(const std::string &my_name) const;
191 EdgeSet * get_edgeset(const std::string &my_name) const;
192 FaceSet * get_faceset(const std::string &my_name) const;
193 ElementSet * get_elementset(const std::string &my_name) const;
194 CommSet * get_commset(const std::string &my_name) const;
195 StructuredBlock *get_structured_block(const std::string &my_name) const;
196 Assembly * get_assembly(const std::string &my_name) const;
197 Blob * get_blob(const std::string &my_name) const;
198
199 // Not guaranteed to be efficient...
200 // Note that not all GroupingEntity's are guaranteed to have an 'id'...
201 GroupingEntity *get_entity(const int64_t id, EntityType io_type) const;
202
203 const CoordinateFrame &get_coordinate_frame(int64_t id) const;
204
205 // Add the name 'alias' as an alias for the database entity with the
206 // name 'db_name'. Returns true if alias added; false if problems
207 // adding alias.
208 bool add_alias(const std::string &db_name, const std::string &alias);
209 bool add_alias(const GroupingEntity *ge);
210 std::string get_alias(const std::string &alias) const;
211 std::string get_alias__(const std::string &alias) const; // Not locked by mutex
212
213 const AliasMap &get_alias_map() const;
214
215 /// Get a map containing all aliases defined for the entity with basename 'name'
216 int get_aliases(const std::string &my_name, std::vector<std::string> &aliases) const;
217
218 // This routine transfers all relevant aliases from the 'this'
219 // region and applies them to the 'to' file.
220 void transfer_mesh_aliases(Region *to) const;
221
222 // Ensure that the 'this' region has the same ids and names as the 'from' region.
223 void synchronize_id_and_name(const Region *from, bool sync_attribute_field_names = false);
224
225 // Returns true if the passed in name refers to a known Entity
226 // defined on this region. If true, then 'type' (if non-nullptr) is
227 // filled in with the type of the entity; if false, then type (if
228 // non-nullptr) is set to 'INVALID' This function is defined to
229 // consolidate several distinct implementations of this code in
230 // client code. Because of this, the 'type' used in the client
231 // code is repeated here instead of something more generic.
232 bool is_valid_io_entity(const std::string &my_name, unsigned int io_type,
233 std::string *my_type = nullptr) const;
234
235 // Retrieve the element block that contains the specified element
236 // The 'local_id' is the local database id (1-based), not the global id.
237 // returns nullptr if no element block contains this element (local_id <= 0
238 // or greater than number of elements in database)
239 ElementBlock *get_element_block(size_t local_id) const;
240
241 // Retrieve the structured block that contains the specified node
242 // The 'global_offset' is the global offset (0-based)
243 // returns nullptr if no structured block contains this node (local_id <= 0
244 // or greater than number of cell-nodes in database)
245 StructuredBlock *get_structured_block(size_t global_offset) const;
246
247 // Handle implicit properties -- These are calcuated from data stored
248 // in the grouping entity instead of having an explicit value assigned.
249 // An example would be 'element_block_count' for a region.
250 Property get_implicit_property(const std::string &my_name) const override;
251
252 const std::vector<std::string> &get_information_records() const;
253 void add_information_records(const std::vector<std::string> &info);
254 void add_information_record(const std::string &info);
255
256 const std::vector<std::string> &get_qa_records() const;
257 void add_qa_record(const std::string &code, const std::string &code_qa,
258 const std::string &date = "", const std::string &time = "");
259
260 protected:
261 int64_t internal_get_field_data(const Field &field, void *data,
262 size_t data_size = 0) const override;
263
264 int64_t internal_put_field_data(const Field &field, void *data,
265 size_t data_size = 0) const override;
266
267 private:
268 // Add the name 'alias' as an alias for the database entity with the
269 // name 'db_name'. Returns true if alias added; false if problems
270 // adding alias. Not protected by mutex -- call internally only.
271 bool add_alias__(const std::string &db_name, const std::string &alias);
272 bool add_alias__(const GroupingEntity *ge);
273
274 bool begin_mode__(State new_state);
275 bool end_mode__(State current_state);
276
277 void delete_database() override;
278
279 AliasMap aliases_; ///< Stores alias mappings
280
281 // Containers for all grouping entities
282 NodeBlockContainer nodeBlocks;
283 EdgeBlockContainer edgeBlocks;
284 FaceBlockContainer faceBlocks;
285 ElementBlockContainer elementBlocks;
286
287 NodeSetContainer nodeSets;
288 EdgeSetContainer edgeSets;
289 FaceSetContainer faceSets;
290 ElementSetContainer elementSets;
291
292 SideSetContainer sideSets;
293 CommSetContainer commSets;
294 CoordinateFrameContainer coordinateFrames;
295 StructuredBlockContainer structuredBlocks;
296 AssemblyContainer assemblies;
297 BlobContainer blobs;
298 mutable StateTimeContainer stateTimes;
299
300 int currentState{-1};
301 mutable int stateCount{0};
302 bool modelDefined{false};
303 bool transientDefined{false};
304 };
305 } // namespace Ioss
306
307 /** \brief Get the index (1-based) of the currently-active state.
308 *
309 * \returns The index.
310 */
get_current_state()311 inline int Ioss::Region::get_current_state() const { return currentState; }
312
supports_field_type(Ioss::EntityType fld_type)313 inline bool Ioss::Region::supports_field_type(Ioss::EntityType fld_type) const
314 {
315 return static_cast<unsigned int>((get_database()->entity_field_support() & fld_type) != 0u) != 0u;
316 }
317
node_global_to_local(int64_t global,bool must_exist)318 inline int64_t Ioss::Region::node_global_to_local(int64_t global, bool must_exist) const
319 {
320 return get_database()->node_global_to_local(global, must_exist);
321 }
322
323 /** \brief Get all information records (informative strings) for the region's database.
324 *
325 * \returns The informative strings.
326 */
get_information_records()327 inline const std::vector<std::string> &Ioss::Region::get_information_records() const
328 {
329 IOSS_FUNC_ENTER(m_);
330 return get_database()->get_information_records();
331 }
332
333 /** \brief Add multiple information records (informative strings) to the region's database.
334 *
335 * \param[in] info The strings to add.
336 */
add_information_records(const std::vector<std::string> & info)337 inline void Ioss::Region::add_information_records(const std::vector<std::string> &info)
338 {
339 IOSS_FUNC_ENTER(m_);
340 return get_database()->add_information_records(info);
341 }
342
343 /** \brief Add an information record (an informative string) to the region's database.
344 *
345 * \param[in] info The string to add.
346 */
add_information_record(const std::string & info)347 inline void Ioss::Region::add_information_record(const std::string &info)
348 {
349 IOSS_FUNC_ENTER(m_);
350 return get_database()->add_information_record(info);
351 }
352
353 /** \brief Add a QA record, which consists of 4 strings, to the region's database
354 *
355 * The 4 function parameters correspond to the 4 QA record strings.
356 *
357 * \param[in] code A descriptive code name, such as the application that modified the database.
358 * \param[in] code_qa A descriptive string, such as the version of the application that modified
359 * the database.
360 * \param[in] date A relevant date, such as the date the database was modified.
361 * \param[in] time A relevant time, such as the time the database was modified.
362 */
add_qa_record(const std::string & code,const std::string & code_qa,const std::string & date,const std::string & time)363 inline void Ioss::Region::add_qa_record(const std::string &code, const std::string &code_qa,
364 const std::string &date, const std::string &time)
365 {
366 IOSS_FUNC_ENTER(m_);
367 return get_database()->add_qa_record(code, code_qa, date, time);
368 }
369
370 /** \brief Get all QA records, each of which consists of 4 strings, from the region's database.
371 *
372 * The 4 strings that make up a database QA record are:
373 *
374 * 1. A descriptive code name, such as the application that modified the database.
375 *
376 * 2. A descriptive string, such as the version of the application that modified the database.
377 *
378 * 3. A relevant date, such as the date the database was modified.
379 *
380 * 4. A relevant time, such as the time the database was modified.
381 *
382 * \returns All QA records in a single vector. Every 4 consecutive elements of the
383 * vector make up a single QA record.
384 */
get_qa_records()385 inline const std::vector<std::string> &Ioss::Region::get_qa_records() const
386 {
387 IOSS_FUNC_ENTER(m_);
388 return get_database()->get_qa_records();
389 }
390
391 #endif
392