IOSS 2.0
Loading...
Searching...
No Matches
Iotm_TextMeshDataTypes.h
Go to the documentation of this file.
1// Copyright(C) 1999-2020, 2022 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#pragma once
6
7#include "iotm_export.h"
8
9// ####################### Start Clang Header Tool Managed Headers ########################
10// clang-format off
11#include <ctype.h> // for toupper
12#include <stddef.h> // for size_t
13#include <algorithm> // for remove, etc
14#include <iterator> // for insert_iterator
15#include <map>
16#include <set> // for set
17#include <sstream> // for operator<<, etc
18#include <string> // for basic_string, etc
19#include <utility> // for pair
20#include <vector> // for vector
21#include <unordered_map>
22#include <sstream> // for ostringstream
23#include <iostream>
24#include <functional>
25#include <stdexcept>
26#include <numeric>
27#include <strings.h>
28
29#include "Iotm_TextMeshFuncs.h"
30
31// clang-format on
32// ####################### End Clang Header Tool Managed Headers ########################
33namespace Iotm {
34 namespace text_mesh {
35
36 using ErrorHandler = std::function<void(const std::ostringstream &)>;
37
38 template <typename T> class TopologyMapping
39 {
40 public:
41 using Topology = T;
42
43 virtual ~TopologyMapping() {}
44
45 Topology topology(const std::string &textMeshName) const
46 {
47 const auto &it = m_nameToTopology.find(textMeshName);
48 return (it != m_nameToTopology.end() ? it->second : invalid_topology());
49 }
50
51 virtual Topology invalid_topology() const = 0;
52 virtual void initialize_topology_map() = 0;
53
54 protected:
55 std::unordered_map<std::string, Topology> m_nameToTopology;
56 };
57
58 class IOTM_EXPORT PartIdMapping
59 {
60 public:
61 PartIdMapping() : m_idsAssigned(false)
62 {
63 set_error_handler([](const std::ostringstream &errmsg) { default_error_handler(errmsg); });
64 }
65
66 void register_part_name(const std::string &name)
67 {
68 m_partNames.push_back(name);
69 handle_block_part(name);
70 }
71
72 void register_part_name_with_id(const std::string &name, unsigned id)
73 {
74 register_part_name(name);
75 assign(name, id);
76 }
77
78 unsigned get(const std::string &name) const
79 {
80 if (!m_idsAssigned)
81 assign_ids();
82 return get_part_id(name);
83 }
84
85 std::string get(unsigned id) const
86 {
87 if (!m_idsAssigned)
88 assign_ids();
89 return get_part_name(id);
90 }
91
92 unsigned size() const
93 {
94 if (!m_idsAssigned)
95 assign_ids();
96 return m_ids.size();
97 }
98
99 std::vector<std::string> get_part_names_sorted_by_id() const
100 {
101 if (!m_idsAssigned)
102 assign_ids();
103
104 std::vector<std::string> names;
105 names.reserve(m_parts.size());
106
107 for (const auto &iter : m_parts) {
108 names.push_back(iter.second);
109 }
110
111 return names;
112 }
113
114 bool is_registered(const std::string &name) const { return m_ids.count(name) > 0; }
115
116 const std::vector<std::string> &get_part_names() const { return m_partNames; }
117
118 void set_error_handler(ErrorHandler errorHandler) { m_errorHandler = errorHandler; }
119
120 const std::string get_group_type() const { return "element block"; }
121
123 {
124 if (!m_idsAssigned)
125 assign_ids();
126 }
127
128 private:
129 void handle_block_part(const std::string &name)
130 {
131 auto result = get_id_from_part_name(name, "BLOCK_");
132
133 if (!result.second)
134 return;
135
136 assign(name, result.first);
137 }
138
139 void assign_ids() const
140 {
141 unsigned nextPartId = 1;
142 for (const std::string &name : m_partNames) {
143 if (m_ids.find(name) == m_ids.end()) {
144 while (is_assigned(nextPartId))
145 nextPartId++;
146
147 assign(name, nextPartId);
148 }
149 }
150
151 m_idsAssigned = true;
152 }
153
154 void assign(const std::string &name, unsigned id) const
155 {
156 validate_name_and_id(name, id);
157 m_ids[name] = id;
158 m_parts[id] = name;
159 }
160
161 void validate_name_and_id(const std::string &name, unsigned id) const
162 {
163 if (is_registered(name)) {
164 if (m_ids[name] != id) {
165 std::ostringstream errmsg;
166 errmsg << "Cannot assign part '" << name << "' two different ids: " << m_ids[name]
167 << " and " << id;
168 m_errorHandler(errmsg);
169 }
170 }
171 else {
172 if (is_assigned(id)) {
173 std::ostringstream errmsg;
174 errmsg << "Part id " << id << " has already been assigned, cannot assign it to part '"
175 << name << "'";
176 m_errorHandler(errmsg);
177 }
178 }
179 }
180
181 bool is_assigned(unsigned id) const { return m_parts.count(id) > 0; }
182
183 unsigned get_part_id(const std::string &name) const
184 {
185 auto it = m_ids.find(name);
186 if (it == m_ids.end()) {
187 std::ostringstream errmsg;
188 errmsg << "PartIdMapping has no ID for invalid part name " << name;
189 m_errorHandler(errmsg);
190 }
191 return it->second;
192 }
193
194 std::string get_part_name(unsigned id) const
195 {
196 auto it = m_parts.find(id);
197 if (it == m_parts.end()) {
198 std::ostringstream errmsg;
199 errmsg << "PartIdMapping has no part name for invalid id " << id;
200 m_errorHandler(errmsg);
201 }
202 return it->second;
203 }
204
205 std::vector<std::string> m_partNames{};
206 mutable std::unordered_map<std::string, unsigned> m_ids;
207 mutable std::map<unsigned, std::string> m_parts;
208 mutable bool m_idsAssigned{false};
209
211 };
212
213 template <typename EntityId> class Coordinates
214 {
215 public:
217 {
218 set_error_handler([](const std::ostringstream &errmsg) { default_error_handler(errmsg); });
219 }
220
221 const std::vector<double> &operator[](const EntityId nodeId) const
222 {
223 auto it = m_nodalCoords.find(nodeId);
224
225 if (it == m_nodalCoords.end()) {
226 std::ostringstream errmsg;
227 errmsg << "Could not find node id " << nodeId;
228 m_errorHandler(errmsg);
229 }
230
231 return it->second;
232 }
233
234 void set_coordinate_data(const unsigned spatialDim, const std::set<EntityId> &nodeIds,
235 const std::vector<double> &coordinates)
236 {
237 if (!coordinates.empty()) {
238 validate_num_coordinates(spatialDim, nodeIds, coordinates);
239 fill_coordinate_map(spatialDim, nodeIds, coordinates);
240 m_hasCoordinateData = true;
241 }
242 }
243
244 void set_error_handler(ErrorHandler errorHandler) { m_errorHandler = errorHandler; }
245
247
248 private:
249 void validate_num_coordinates(const unsigned spatialDim, const std::set<EntityId> &nodeIds,
250 const std::vector<double> &coordinates)
251 {
252 if (coordinates.size() != nodeIds.size() * spatialDim) {
253 std::ostringstream errmsg;
254 errmsg << "Number of coordinates: " << coordinates.size()
255 << ", Number of nodes: " << nodeIds.size()
256 << ", Spatial dimension: " << spatialDim;
257 m_errorHandler(errmsg);
258 }
259 }
260
261 void fill_coordinate_map(const unsigned spatialDim, const std::set<EntityId> &nodeIds,
262 const std::vector<double> &coordinates)
263 {
264 std::vector<double>::const_iterator coordIter = coordinates.begin();
265 for (const EntityId &nodeId : nodeIds) {
266 m_nodalCoords[nodeId] = std::vector<double>(coordIter, coordIter + spatialDim);
267 coordIter += spatialDim;
268 }
269 }
270
272 std::unordered_map<EntityId, std::vector<double>> m_nodalCoords;
274 };
275
276 template <typename EntityId, typename Topology> struct ElementData
277 {
278 int proc;
281 std::vector<EntityId> nodeIds{};
282 std::string partName = "";
283
284 operator EntityId() const { return identifier; }
285 };
286
287 template <typename EntityId, typename Topology> struct ElementDataLess
288 {
291 {
292 return lhs.identifier < rhs.identifier;
293 };
294
296 {
297 return lhs.identifier < rhs;
298 };
299
301 {
302 return lhs < rhs.identifier;
303 };
304
305 bool operator()(const EntityId lhs, const EntityId rhs) { return lhs < rhs; };
306 };
307
308 template <typename EntityId, typename Topology> class Sidesets;
309
310 template <typename EntityId> class Nodesets;
311
312 template <typename EntityId> class Assemblies;
313
314 template <typename EntityId, typename Topology> struct TextMeshData
315 {
316 unsigned spatialDim{0};
317 std::vector<ElementData<EntityId, Topology>> elementDataVec{};
319 std::set<EntityId> nodeIds{};
324
326
328 {
329 elementDataVec.push_back(elem);
330 for (const EntityId &nodeId : elem.nodeIds) {
331 nodeIds.insert(nodeId);
332 associate_node_with_proc(nodeId, elem.proc);
333 }
334 }
335
336 const std::set<EntityId> &nodes_on_proc(int proc) const
337 {
338 auto it = m_nodesOnProc.find(proc);
339 return it != m_nodesOnProc.end() ? it->second : m_emptyNodes;
340 }
341
342 unsigned num_nodes_on_proc(int proc) const
343 {
344 auto it = m_nodesOnProc.find(proc);
345 return it != m_nodesOnProc.end() ? it->second.size() : 0;
346 }
347
348 const std::set<int> &procs_for_node(const EntityId nodeId) const
349 {
350 auto it = m_procsForNode.find(nodeId);
351 return it != m_procsForNode.end() ? it->second : m_emptyProcs;
352 }
353
354 private:
355 void associate_node_with_proc(const EntityId nodeId, int proc)
356 {
357 m_procsForNode[nodeId].insert(proc);
358 m_nodesOnProc[proc].insert(nodeId);
359 }
360
361 std::unordered_map<EntityId, std::set<int>> m_procsForNode;
362 std::unordered_map<int, std::set<EntityId>> m_nodesOnProc;
363
364 std::set<int> m_emptyProcs{};
365 std::set<EntityId> m_emptyNodes{};
366 };
367
368 } // namespace text_mesh
369} // namespace Iotm
Definition Iotm_TextMeshTopologyMapping.h:33
Definition Iotm_TextMeshDataTypes.h:312
Definition Iotm_TextMeshDataTypes.h:214
void set_coordinate_data(const unsigned spatialDim, const std::set< EntityId > &nodeIds, const std::vector< double > &coordinates)
Definition Iotm_TextMeshDataTypes.h:234
std::unordered_map< EntityId, std::vector< double > > m_nodalCoords
Definition Iotm_TextMeshDataTypes.h:272
void validate_num_coordinates(const unsigned spatialDim, const std::set< EntityId > &nodeIds, const std::vector< double > &coordinates)
Definition Iotm_TextMeshDataTypes.h:249
ErrorHandler m_errorHandler
Definition Iotm_TextMeshDataTypes.h:273
void fill_coordinate_map(const unsigned spatialDim, const std::set< EntityId > &nodeIds, const std::vector< double > &coordinates)
Definition Iotm_TextMeshDataTypes.h:261
void set_error_handler(ErrorHandler errorHandler)
Definition Iotm_TextMeshDataTypes.h:244
bool m_hasCoordinateData
Definition Iotm_TextMeshDataTypes.h:271
const std::vector< double > & operator[](const EntityId nodeId) const
Definition Iotm_TextMeshDataTypes.h:221
bool has_coordinate_data() const
Definition Iotm_TextMeshDataTypes.h:246
Coordinates()
Definition Iotm_TextMeshDataTypes.h:216
Definition Iotm_TextMeshNodeset.h:46
Definition Iotm_TextMeshDataTypes.h:59
unsigned get_part_id(const std::string &name) const
Definition Iotm_TextMeshDataTypes.h:183
void assign_ids() const
Definition Iotm_TextMeshDataTypes.h:139
ErrorHandler m_errorHandler
Definition Iotm_TextMeshDataTypes.h:210
bool is_registered(const std::string &name) const
Definition Iotm_TextMeshDataTypes.h:114
void assign(const std::string &name, unsigned id) const
Definition Iotm_TextMeshDataTypes.h:154
unsigned get(const std::string &name) const
Definition Iotm_TextMeshDataTypes.h:78
void register_part_name(const std::string &name)
Definition Iotm_TextMeshDataTypes.h:66
void validate_name_and_id(const std::string &name, unsigned id) const
Definition Iotm_TextMeshDataTypes.h:161
const std::string get_group_type() const
Definition Iotm_TextMeshDataTypes.h:120
std::string get(unsigned id) const
Definition Iotm_TextMeshDataTypes.h:85
void handle_block_part(const std::string &name)
Definition Iotm_TextMeshDataTypes.h:129
unsigned size() const
Definition Iotm_TextMeshDataTypes.h:92
std::string get_part_name(unsigned id) const
Definition Iotm_TextMeshDataTypes.h:194
std::map< unsigned, std::string > m_parts
Definition Iotm_TextMeshDataTypes.h:207
std::unordered_map< std::string, unsigned > m_ids
Definition Iotm_TextMeshDataTypes.h:206
PartIdMapping()
Definition Iotm_TextMeshDataTypes.h:61
void finalize_parse()
Definition Iotm_TextMeshDataTypes.h:122
void set_error_handler(ErrorHandler errorHandler)
Definition Iotm_TextMeshDataTypes.h:118
void register_part_name_with_id(const std::string &name, unsigned id)
Definition Iotm_TextMeshDataTypes.h:72
const std::vector< std::string > & get_part_names() const
Definition Iotm_TextMeshDataTypes.h:116
std::vector< std::string > get_part_names_sorted_by_id() const
Definition Iotm_TextMeshDataTypes.h:99
bool is_assigned(unsigned id) const
Definition Iotm_TextMeshDataTypes.h:181
Definition Iotm_TextMeshSideset.h:104
Definition Iotm_TextMeshDataTypes.h:39
T Topology
Definition Iotm_TextMeshDataTypes.h:41
std::unordered_map< std::string, Topology > m_nameToTopology
Definition Iotm_TextMeshDataTypes.h:55
virtual ~TopologyMapping()
Definition Iotm_TextMeshDataTypes.h:43
virtual void initialize_topology_map()=0
virtual Topology invalid_topology() const =0
Topology topology(const std::string &textMeshName) const
Definition Iotm_TextMeshDataTypes.h:45
std::function< void(const std::ostringstream &)> ErrorHandler
Definition Iotm_TextMeshAdjacencyGraph.h:35
void default_error_handler(const std::ostringstream &message)
Definition Iotm_TextMeshFuncs.h:32
std::pair< unsigned, bool > get_id_from_part_name(const std::string &name, const std::string &prefix)
Definition Iotm_TextMeshFuncs.h:118
A namespace for the textmesh database format.
Definition Iotm_DatabaseIO.C:95
int64_t EntityId
Definition Iotm_TextMesh.h:33
Definition Iotm_TextMeshDataTypes.h:288
bool operator()(const EntityId lhs, const EntityId rhs)
Definition Iotm_TextMeshDataTypes.h:305
bool operator()(const ElementData< EntityId, Topology > &lhs, const EntityId rhs)
Definition Iotm_TextMeshDataTypes.h:295
bool operator()(const EntityId lhs, const ElementData< EntityId, Topology > &rhs)
Definition Iotm_TextMeshDataTypes.h:300
bool operator()(const ElementData< EntityId, Topology > &lhs, const ElementData< EntityId, Topology > &rhs)
Definition Iotm_TextMeshDataTypes.h:289
Definition Iotm_TextMeshDataTypes.h:277
Topology topology
Definition Iotm_TextMeshDataTypes.h:280
std::string partName
Definition Iotm_TextMeshDataTypes.h:282
int proc
Definition Iotm_TextMeshDataTypes.h:278
EntityId identifier
Definition Iotm_TextMeshDataTypes.h:279
std::vector< EntityId > nodeIds
Definition Iotm_TextMeshDataTypes.h:281
Definition Iotm_TextMeshDataTypes.h:315
std::set< int > m_emptyProcs
Definition Iotm_TextMeshDataTypes.h:364
std::set< EntityId > nodeIds
Definition Iotm_TextMeshDataTypes.h:319
Assemblies< EntityId > assemblies
Definition Iotm_TextMeshDataTypes.h:323
Nodesets< EntityId > nodesets
Definition Iotm_TextMeshDataTypes.h:322
std::vector< ElementData< EntityId, Topology > > elementDataVec
Definition Iotm_TextMeshDataTypes.h:317
const std::set< int > & procs_for_node(const EntityId nodeId) const
Definition Iotm_TextMeshDataTypes.h:348
std::set< EntityId > m_emptyNodes
Definition Iotm_TextMeshDataTypes.h:365
PartIdMapping partIds
Definition Iotm_TextMeshDataTypes.h:318
void associate_node_with_proc(const EntityId nodeId, int proc)
Definition Iotm_TextMeshDataTypes.h:355
unsigned spatialDim
Definition Iotm_TextMeshDataTypes.h:316
Coordinates< EntityId > coords
Definition Iotm_TextMeshDataTypes.h:320
TextMeshData()
Definition Iotm_TextMeshDataTypes.h:325
void add_element(const ElementData< EntityId, Topology > &elem)
Definition Iotm_TextMeshDataTypes.h:327
std::unordered_map< int, std::set< EntityId > > m_nodesOnProc
Definition Iotm_TextMeshDataTypes.h:362
std::unordered_map< EntityId, std::set< int > > m_procsForNode
Definition Iotm_TextMeshDataTypes.h:361
unsigned num_nodes_on_proc(int proc) const
Definition Iotm_TextMeshDataTypes.h:342
const std::set< EntityId > & nodes_on_proc(int proc) const
Definition Iotm_TextMeshDataTypes.h:336
Sidesets< EntityId, Topology > sidesets
Definition Iotm_TextMeshDataTypes.h:321