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