IOSS 2.0
Loading...
Searching...
No Matches
Iotm_TextMeshSidesetSplitter.h
Go to the documentation of this file.
1// Copyright(C) 1999-2020, 2022, 2023 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// ####################### Start Clang Header Tool Managed Headers ########################
8// clang-format off
9#include <ctype.h> // for toupper
10#include <stddef.h> // for size_t
11#include <algorithm> // for remove, etc
12#include <iterator> // for insert_iterator
13#include <map>
14#include <set> // for set
15#include <sstream> // for operator<<, etc
16#include <string> // for basic_string, etc
17#include <utility> // for pair
18#include <vector> // for vector
19#include <unordered_map>
20#include <sstream> // for ostringstream
21#include <iostream>
22#include <functional>
23#include <stdexcept>
24#include <numeric>
25#include <strings.h>
26
27#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
39 {
40 std::string name{};
41 std::string parentName{};
42 std::string sideTopology{};
43 std::string elementTopology{};
44 std::string touchingBlock{};
45 std::vector<size_t> sideIndex{};
46 unsigned numNodesPerSide{0};
47 };
48
50
51 inline std::ostream &operator<<(std::ostream &out, const SplitType &t)
52 {
53 switch (t) {
54 case SplitType::TOPOLOGY: return out << "TOPOLOGY"; break;
55 case SplitType::ELEMENT_BLOCK: return out << "ELEMENT_BLOCK"; break;
56 case SplitType::NO_SPLIT: return out << "NO_SPLIT"; break;
57 default: return out << "INVALID"; break;
58 }
59 return out << "INVALID[" << (unsigned)t << "]";
60 }
61
62 template <typename EntityId> using SidesetDataType = std::pair<EntityId, int>;
63
64 template <typename EntityId, typename Topology> struct SidesetData;
65
66 template <typename EntityId, typename Topology> class SidesetSplitter
67 {
68 public:
69 explicit SidesetSplitter(SplitType splitType) : m_splitType(splitType)
70 {
71 ErrorHandler errorHandler = [](const std::ostringstream &errmsg) {
73 };
74 set_error_handler(errorHandler);
75 }
76
78 {
79 ErrorHandler errorHandler = [](const std::ostringstream &errmsg) {
81 };
82 set_error_handler(errorHandler);
83 }
84
85 void set_error_handler(ErrorHandler errorHandler) { m_errorHandler = errorHandler; }
86
88 const std::vector<ElementData<EntityId, Topology>> &elementData)
89 {
90 m_splitMap.clear();
91 m_sidesetName = sideset.name;
92
93 if (get_split_type() == SplitType::TOPOLOGY) {
94 split_by_topology(sideset, elementData);
95 }
96 else if (get_split_type() == SplitType::ELEMENT_BLOCK) {
97 split_by_element_block(sideset, elementData);
98 }
99 else if (get_split_type() == SplitType::NO_SPLIT) {
100 split_by_no_split(sideset, elementData);
101 }
102 else {
103 std::ostringstream errmsg;
104 errmsg << "Invalid split type: " << get_split_type();
105 m_errorHandler(errmsg);
106 }
107
108 build_index_proc_map(sideset, elementData);
109 }
110
111 std::vector<SideBlockInfo> get_side_block_info() const
112 {
113 std::vector<SideBlockInfo> infoVec;
114 infoVec.reserve(m_splitMap.size());
115
116 for (auto iter = m_splitMap.begin(); iter != m_splitMap.end(); iter++) {
117 const std::string &sideBlockName = iter->first;
118 SideBlockInfo info = get_side_block_info(sideBlockName);
119 infoVec.push_back(info);
120 }
121 return infoVec;
122 }
123
124 std::vector<size_t> get_indices_local_to_proc(const std::vector<size_t> &index,
125 int proc) const
126 {
127 std::vector<size_t> indexForProc;
128 indexForProc.reserve(index.size());
129
130 for (size_t elemPairIndex : index) {
131 if (is_index_local_to_proc(elemPairIndex, proc)) {
132 indexForProc.push_back(elemPairIndex);
133 }
134 }
135
136 indexForProc.resize(indexForProc.size());
137 return indexForProc;
138 }
139
140 SideBlockInfo get_side_block_info(const std::string &name) const
141 {
142 SideBlockInfo info;
143
144 auto iter = m_splitMap.find(name);
145 if (iter != m_splitMap.end()) {
146 const SplitData &splitData = iter->second;
147
148 info.name = name;
149 info.parentName = splitData.sidesetName;
150 info.sideTopology = splitData.sideTopology;
151 info.elementTopology = splitData.elemTopology;
152 info.numNodesPerSide = splitData.sideNodeCount;
153 info.touchingBlock = splitData.touchingBlock;
154 info.sideIndex = splitData.index;
155 }
156 return info;
157 }
158
160 void set_split_type(SplitType inputSplitType) { m_splitType = inputSplitType; }
161
162 private:
164 const std::vector<ElementData<EntityId, Topology>> &elementData)
165 {
166 for (size_t i = 0; i < sideset.data.size(); ++i) {
167 const SidesetDataType<EntityId> &elemSidePair = sideset.data[i];
168 EntityId elemId = elemSidePair.first;
169
170 auto iter = bound_search(elementData.begin(), elementData.end(), elemId,
172 if (iter == elementData.end()) {
173 std::ostringstream errmsg;
174 errmsg << "Error! Sideset with id: " << sideset.id << " and name: " << sideset.name
175 << " has reference to invalid element '" << elemId << "'.";
176 m_errorHandler(errmsg);
177 }
178
179 m_indexProcMap[i] = iter->proc;
180 }
181 }
182
183 bool is_index_local_to_proc(size_t elemPairIndex, int proc) const
184 {
185 auto iter = m_indexProcMap.find(elemPairIndex);
186
187 if (iter == m_indexProcMap.end()) {
188 std::ostringstream errmsg;
189 errmsg << "Sideset with name: " << m_sidesetName << " is referencing an invalid index "
190 << elemPairIndex;
191 m_errorHandler(errmsg);
192 }
193
194 return iter->second == proc;
195 }
196
198 {
199 bool metaDataSet{false};
200 std::string sidesetName{};
201 std::string touchingBlock{};
202 std::string elemTopology{};
203 std::string sideTopology{};
205 std::vector<size_t> index{};
206
208 };
209
210 void fill_split_data(std::string key, size_t index,
211 const ElementData<EntityId, Topology> &elemData, int side)
212 {
214
215 SplitData &splitData = m_splitMap[key];
216
217 splitData.index.push_back(index);
218
219 if (!splitData.metaDataSet) {
220 splitData.sidesetName = m_sidesetName;
221 splitData.elemTopology = elemData.topology.name();
222 splitData.sideTopology = elemData.topology.side_topology_name(side);
223 splitData.sideNodeCount = elemData.topology.side_topology_num_nodes(side);
224
225 if (get_split_type() == ELEMENT_BLOCK) {
226 splitData.touchingBlock = elemData.partName;
227 }
228
229 splitData.metaDataSet = true;
230 }
231 }
232
233 using Criterion =
234 std::function<std::string(const SidesetData<EntityId, Topology> &sideset,
235 const ElementData<EntityId, Topology> &elemData, int side)>;
236
238 const std::vector<ElementData<EntityId, Topology>> &elementData,
239 Criterion criterion)
240 {
241 for (size_t index = 0; index < sideset.data.size(); ++index) {
242 const SidesetDataType<EntityId> &elemSidePair = sideset.data[index];
243 EntityId elemId = elemSidePair.first;
244 int side = elemSidePair.second;
245
246 auto iter = bound_search(elementData.begin(), elementData.end(), elemId,
248 if (iter == elementData.end()) {
249 std::ostringstream errmsg;
250 errmsg << "Error! Sideset with id: " << sideset.id << " and name: " << sideset.name
251 << " has reference to invalid element '" << elemId << "'.";
252 m_errorHandler(errmsg);
253 }
254
255 std::string key = criterion(sideset, *iter, side);
256 fill_split_data(key, index, *iter, side);
257 }
258 }
259
261 const std::vector<ElementData<EntityId, Topology>> &elementData)
262 {
263 Criterion criterion = [](const SidesetData<EntityId, Topology> &sideSet,
264 const ElementData<EntityId, Topology> &elemData, int side) {
265 if (sideSet.has_default_exodus_name()) {
266 return "SURFACE_" + elemData.topology.name() + "_" +
267 elemData.topology.side_topology_name(side) + "_" + std::to_string(sideSet.id);
268 }
269 return sideSet.name + "_" + elemData.topology.name() + "_" +
270 elemData.topology.side_topology_name(side);
271 };
272
273 split_by_criterion(sideset, elementData, criterion);
274 }
275
277 const std::vector<ElementData<EntityId, Topology>> &elementData)
278 {
279 Criterion criterion = [](const SidesetData<EntityId, Topology> &sideSet,
280 const ElementData<EntityId, Topology> &elemData, int side) {
281 if (sideSet.has_default_exodus_name()) {
282 return "SURFACE_" + elemData.partName + "_" +
283 elemData.topology.side_topology_name(side) + "_" + std::to_string(sideSet.id);
284 }
285 return sideSet.name + "_" + elemData.partName + "_" +
286 elemData.topology.side_topology_name(side);
287 };
288
289 split_by_criterion(sideset, elementData, criterion);
290 }
291
293 const std::vector<ElementData<EntityId, Topology>> & /* elementData */)
294 {
295 std::vector<size_t> splitIndex(sideset.data.size());
296 std::iota(std::begin(splitIndex), std::end(splitIndex), 0);
297 SplitData &splitData = m_splitMap[sideset.name];
298
299 splitData.index = splitIndex;
300 splitData.sidesetName = m_sidesetName;
301 splitData.elemTopology = "unknown";
302 splitData.sideTopology = "unknown";
303 splitData.sideNodeCount = -1;
304 splitData.metaDataSet = true;
305 }
306
308 std::string m_sidesetName{};
309
310 std::unordered_map<size_t, int> m_indexProcMap;
311 std::unordered_map<std::string, SplitData> m_splitMap;
313 };
314
315 } // namespace text_mesh
316} // namespace Iotm
unsigned side_topology_num_nodes(unsigned side) const
Definition Iotm_TextMeshTopologyMapping.h:121
const std::string name() const
Definition Iotm_TextMeshTopologyMapping.h:72
std::string side_topology_name(unsigned side) const
Definition Iotm_TextMeshTopologyMapping.h:105
Definition Iotm_TextMeshSidesetSplitter.h:67
void split_by_no_split(const SidesetData< EntityId, Topology > &sideset, const std::vector< ElementData< EntityId, Topology > > &)
Definition Iotm_TextMeshSidesetSplitter.h:292
std::string m_sidesetName
Definition Iotm_TextMeshSidesetSplitter.h:308
SideBlockInfo get_side_block_info(const std::string &name) const
Definition Iotm_TextMeshSidesetSplitter.h:140
void split(const SidesetData< EntityId, Topology > &sideset, const std::vector< ElementData< EntityId, Topology > > &elementData)
Definition Iotm_TextMeshSidesetSplitter.h:87
SplitType m_splitType
Definition Iotm_TextMeshSidesetSplitter.h:307
SplitType get_split_type() const
Definition Iotm_TextMeshSidesetSplitter.h:159
std::function< std::string(const SidesetData< EntityId, Topology > &sideset, const ElementData< EntityId, Topology > &elemData, int side)> Criterion
Definition Iotm_TextMeshSidesetSplitter.h:233
SidesetSplitter()
Definition Iotm_TextMeshSidesetSplitter.h:77
SidesetSplitter(SplitType splitType)
Definition Iotm_TextMeshSidesetSplitter.h:69
bool is_index_local_to_proc(size_t elemPairIndex, int proc) const
Definition Iotm_TextMeshSidesetSplitter.h:183
ErrorHandler m_errorHandler
Definition Iotm_TextMeshSidesetSplitter.h:312
void set_split_type(SplitType inputSplitType)
Definition Iotm_TextMeshSidesetSplitter.h:160
void split_by_criterion(const SidesetData< EntityId, Topology > &sideset, const std::vector< ElementData< EntityId, Topology > > &elementData, Criterion criterion)
Definition Iotm_TextMeshSidesetSplitter.h:237
void split_by_topology(const SidesetData< EntityId, Topology > &sideset, const std::vector< ElementData< EntityId, Topology > > &elementData)
Definition Iotm_TextMeshSidesetSplitter.h:260
std::vector< size_t > get_indices_local_to_proc(const std::vector< size_t > &index, int proc) const
Definition Iotm_TextMeshSidesetSplitter.h:124
void split_by_element_block(const SidesetData< EntityId, Topology > &sideset, const std::vector< ElementData< EntityId, Topology > > &elementData)
Definition Iotm_TextMeshSidesetSplitter.h:276
std::vector< SideBlockInfo > get_side_block_info() const
Definition Iotm_TextMeshSidesetSplitter.h:111
void build_index_proc_map(const SidesetData< EntityId, Topology > &sideset, const std::vector< ElementData< EntityId, Topology > > &elementData)
Definition Iotm_TextMeshSidesetSplitter.h:163
void set_error_handler(ErrorHandler errorHandler)
Definition Iotm_TextMeshSidesetSplitter.h:85
std::unordered_map< size_t, int > m_indexProcMap
Definition Iotm_TextMeshSidesetSplitter.h:310
std::unordered_map< std::string, SplitData > m_splitMap
Definition Iotm_TextMeshSidesetSplitter.h:311
void fill_split_data(std::string key, size_t index, const ElementData< EntityId, Topology > &elemData, int side)
Definition Iotm_TextMeshSidesetSplitter.h:210
ForwardIt bound_search(ForwardIt first, ForwardIt last, const T &value)
Definition Iotm_TextMeshFuncs.h:38
void convert_to_upper_case(std::string &str)
Definition Iotm_TextMeshFuncs.h:88
std::function< void(const std::ostringstream &)> ErrorHandler
Definition Iotm_TextMeshAdjacencyGraph.h:35
std::ostream & operator<<(std::ostream &out, const AssemblyType &t)
Definition Iotm_TextMeshAssembly.h:41
std::pair< EntityId, int > SidesetDataType
Definition Iotm_TextMeshSideset.h:40
void default_error_handler(const std::ostringstream &message)
Definition Iotm_TextMeshFuncs.h:32
SplitType
Definition Iotm_TextMeshSidesetSplitter.h:49
@ INVALID_SPLIT
Definition Iotm_TextMeshSidesetSplitter.h:49
@ TOPOLOGY
Definition Iotm_TextMeshSidesetSplitter.h:49
@ NO_SPLIT
Definition Iotm_TextMeshSidesetSplitter.h:49
@ ELEMENT_BLOCK
Definition Iotm_TextMeshSidesetSplitter.h:49
A namespace for the generated database format.
Definition Iotm_DatabaseIO.C:95
int64_t EntityId
Definition Iotm_TextMesh.h:33
Definition Iotm_TextMeshDataTypes.h:288
Definition Iotm_TextMeshDataTypes.h:277
Topology topology
Definition Iotm_TextMeshDataTypes.h:280
std::string partName
Definition Iotm_TextMeshDataTypes.h:282
std::string name
Definition Iotm_TextMeshEntityGroup.h:43
unsigned id
Definition Iotm_TextMeshEntityGroup.h:42
std::vector< DataType > data
Definition Iotm_TextMeshEntityGroup.h:45
Definition Iotm_TextMeshSidesetSplitter.h:39
unsigned numNodesPerSide
Definition Iotm_TextMeshSidesetSplitter.h:46
std::string elementTopology
Definition Iotm_TextMeshSidesetSplitter.h:43
std::string parentName
Definition Iotm_TextMeshSidesetSplitter.h:41
std::vector< size_t > sideIndex
Definition Iotm_TextMeshSidesetSplitter.h:45
std::string sideTopology
Definition Iotm_TextMeshSidesetSplitter.h:42
std::string touchingBlock
Definition Iotm_TextMeshSidesetSplitter.h:44
std::string name
Definition Iotm_TextMeshSidesetSplitter.h:40
Definition Iotm_TextMeshSideset.h:44
bool has_default_exodus_name() const
Definition Iotm_TextMeshSideset.h:88
Definition Iotm_TextMeshSidesetSplitter.h:198
std::string touchingBlock
Definition Iotm_TextMeshSidesetSplitter.h:201
SplitData()
Definition Iotm_TextMeshSidesetSplitter.h:207
int sideNodeCount
Definition Iotm_TextMeshSidesetSplitter.h:204
std::string sideTopology
Definition Iotm_TextMeshSidesetSplitter.h:203
std::string sidesetName
Definition Iotm_TextMeshSidesetSplitter.h:200
bool metaDataSet
Definition Iotm_TextMeshSidesetSplitter.h:199
std::vector< size_t > index
Definition Iotm_TextMeshSidesetSplitter.h:205
std::string elemTopology
Definition Iotm_TextMeshSidesetSplitter.h:202