v0.16.0
Loading...
Searching...
No Matches
JsonConfigManagerMeshsets.cpp
Go to the documentation of this file.
1int centerAttributeSlot(const std::string &lower_key, const int first_slot) {
2 if (lower_key == "center_x" || lower_key == "x0")
3 return first_slot;
4 if (lower_key == "center_y" || lower_key == "y0")
5 return first_slot + 1;
6 if (lower_key == "center_z" || lower_key == "z0")
7 return first_slot + 2;
8 return 0;
9}
10
11int positionalBlockAttributeSlot(const std::string &lower_type,
12 const std::string &lower_key) {
13 if (lower_type == "fix_x" && lower_key == "x")
14 return 1;
15 if (lower_type == "fix_y" && lower_key == "y")
16 return 2;
17 if (lower_type == "fix_z" && lower_key == "z")
18 return 3;
19 if (lower_type == "fix_all") {
20 if (lower_key == "x")
21 return 1;
22 if (lower_key == "y")
23 return 2;
24 if (lower_key == "z")
25 return 3;
26 }
27
28 if (lower_type == "rotate_x") {
29 if (lower_key == "rx")
30 return 1;
31 return centerAttributeSlot(lower_key, 2);
32 }
33 if (lower_type == "rotate_y") {
34 if (lower_key == "ry")
35 return 1;
36 return centerAttributeSlot(lower_key, 2);
37 }
38 if (lower_type == "rotate_z") {
39 if (lower_key == "rz")
40 return 1;
41 return centerAttributeSlot(lower_key, 2);
42 }
43 if (lower_type == "rotate_all") {
44 if (lower_key == "rx")
45 return 1;
46 if (lower_key == "ry")
47 return 2;
48 if (lower_key == "rz")
49 return 3;
50 return centerAttributeSlot(lower_key, 4);
51 }
52
53 if (lower_type.rfind("boundary_condition", 0) == 0 &&
54 (lower_key == "value" || lower_key == "potential"))
55 return 1;
56 if (lower_type == "hencky" || lower_type.rfind("mat_elastic", 0) == 0) {
57 if (lower_key == "young" || lower_key == "young_modulus")
58 return 1;
59 if (lower_key == "poisson" || lower_key == "poisson_ratio")
60 return 2;
61 }
62
63 return 0;
64}
65
66int parseGenericBlockUserIndex(const std::string &lower_key) {
67 if (lower_key.size() < 5 || lower_key.compare(0, 4, "user") != 0) {
68 return 0;
69 }
70
71 try {
72 return boost::lexical_cast<int>(lower_key.substr(4));
73 } catch (...) {
74 return 0;
75 }
76}
77
78double requireBlockAttributeValue(const JsonValue &value,
79 const std::string &file_name,
80 const std::string &context) {
81 if (value.is_bool())
82 return value.as_bool() ? 1.0 : 0.0;
83
84 return requireNumber(value, file_name, context);
85}
86
87MoFEMErrorCode applyBlockAttributes(MeshsetsManager &meshsets_manager, int id,
88 const JsonObject &props,
89 const std::string &file_name,
90 const std::string &context,
91 const std::string &type_name,
92 const std::string &blockset_name) {
94 std::vector<double> values(MAX_MESHSET_ATTRIBUTES, 0);
95 int max_index = 0;
96 const auto lower_type = toLowerCopy(type_name);
97 std::array<bool, MAX_MESHSET_ATTRIBUTES> used_indices{};
98 std::vector<const JsonObject::value_type *> fallback_items;
99
100 auto set_value = [&](const JsonObject::value_type &item, const int index) {
101 const auto key = toStdString(item.key());
102 if (index < 1 || index > MAX_MESHSET_ATTRIBUTES) {
103 CHKERR failConfig(
104 file_name, makeContext(context, key),
105 "User index must be between 1 and " +
106 boost::lexical_cast<std::string>(MAX_MESHSET_ATTRIBUTES));
107 }
108 values[index - 1] = requireBlockAttributeValue(
109 item.value(), file_name, makeContext(context, key));
110 used_indices[index - 1] = true;
111 max_index = std::max(max_index, index);
112 return 0;
113 };
114
115 for (const auto &item : props) {
116 const auto key = toStdString(item.key());
117 const auto lower_key = toLowerCopy(key);
118 int index = positionalBlockAttributeSlot(lower_type, lower_key);
119 if (!index) {
120 index = parseGenericBlockUserIndex(lower_key);
121 }
122 if (!index) {
123 fallback_items.push_back(&item);
124 continue;
125 }
126 CHKERR set_value(item, index);
127 }
128
129 for (const auto *item_ptr : fallback_items) {
130 int fallback_index = 0;
131 for (int index = 1; index <= MAX_MESHSET_ATTRIBUTES; ++index) {
132 if (!used_indices[index - 1]) {
133 fallback_index = index;
134 break;
135 }
136 }
137 if (!fallback_index) {
138 CHKERR failConfig(
139 file_name, context,
140 "generic BLOCKSET custom attributes exhausted available User slots");
141 }
142 CHKERR set_value(*item_ptr, fallback_index);
143 }
144
145 values.resize(max_index);
146 CHKERR meshsets_manager.setAttributes(BLOCKSET, id, values, blockset_name);
148}
149
150std::string meshsetContext(const std::string &mesh_context,
151 const size_t meshset_index) {
152 return mesh_context + ".meshsets[" +
153 boost::lexical_cast<std::string>(meshset_index) + "]";
154}
155
157 int meshsetId = -1;
159 std::string meshsetName;
160 std::string sourceMeshsetName;
161 std::string typeName;
162 JsonObject attributes;
163 std::string context;
164};
165
166using BlocksetParamKey = std::pair<std::string, int>;
167using BlocksetParams = std::map<std::string, double>;
168using BlocksetParamsByKey = std::map<BlocksetParamKey, BlocksetParams>;
169
171 return makeContext(entry.context, "attributes");
172}
173
174std::string appliedBlocksetName(const ParsedMeshsetEntry &entry) {
175 const auto &name = entry.meshsetName.empty() ? entry.sourceMeshsetName
176 : entry.meshsetName;
177 if (name.empty()) {
178 return entry.typeName + "_" +
179 boost::lexical_cast<std::string>(entry.appliedMeshsetId);
180 }
181
182 return entry.typeName + "_" + name + "_" +
183 boost::lexical_cast<std::string>(entry.appliedMeshsetId);
184}
185
186MoFEMErrorCode getUniqueBlocksetByName(MeshsetsManager &meshsets_manager,
187 const std::string &meshset_name,
188 const std::string &file_name,
189 const std::string &context,
190 const CubitMeshSets **blockset_ptr) {
192 *blockset_ptr = nullptr;
193 int number_of_meshsets = 0;
194
195 for (auto it = meshsets_manager.getBegin(); it != meshsets_manager.getEnd();
196 ++it) {
197 if ((it->getBcType() & CubitBCType(BLOCKSET)).none() ||
198 it->getName() != meshset_name) {
199 continue;
200 }
201 *blockset_ptr = &*it;
202 ++number_of_meshsets;
203 }
204
205 if (number_of_meshsets == 0) {
206 CHKERR failConfig(file_name, makeContext(context, "meshset_name"),
207 "failed to resolve BLOCKSET meshset_name '" +
208 meshset_name + "'");
209 }
210 if (number_of_meshsets != 1) {
211 CHKERR failConfig(file_name, makeContext(context, "meshset_name"),
212 "BLOCKSET meshset_name '" + meshset_name +
213 "' is not unique; resolve by explicit id");
214 }
215
217}
218
219MoFEMErrorCode getBlocksetById(MeshsetsManager &meshsets_manager,
220 const int meshset_id,
221 const std::string &file_name,
222 const std::string &context,
223 const CubitMeshSets **blockset_ptr) {
225 if (!meshsets_manager.checkMeshset(meshset_id, BLOCKSET)) {
226 CHKERR failConfig(file_name, makeContext(context, "id"),
227 "failed to resolve BLOCKSET id '" +
228 boost::lexical_cast<std::string>(meshset_id) + "'");
229 }
230 CHKERR meshsets_manager.getCubitMeshsetPtr(meshset_id, BLOCKSET,
231 blockset_ptr);
233}
234
235MoFEMErrorCode resolveMeshsetIdAndName(MeshsetsManager &meshsets_manager,
236 const bool has_meshset_id,
237 const int requested_meshset_id,
238 const std::string &lookup_meshset_name,
239 const std::string &file_name,
240 const std::string &context,
241 int &meshset_id,
242 std::string &meshset_name) {
244 const CubitMeshSets *blockset_by_id = nullptr;
245
246 if (has_meshset_id) {
247 CHKERR getBlocksetById(meshsets_manager, requested_meshset_id, file_name,
248 context, &blockset_by_id);
249 meshset_id = blockset_by_id->getMeshsetId();
250 meshset_name = blockset_by_id->getName();
251 if (!lookup_meshset_name.empty() && meshset_name != lookup_meshset_name) {
252 CHKERR failConfig(
253 file_name, context,
254 "meshset id '" + boost::lexical_cast<std::string>(meshset_id) +
255 "' does not match meshset_name '" + lookup_meshset_name + "'");
256 }
257 } else if (!lookup_meshset_name.empty()) {
258 const CubitMeshSets *blockset_by_name = nullptr;
259 CHKERR getUniqueBlocksetByName(meshsets_manager, lookup_meshset_name,
260 file_name, context, &blockset_by_name);
261 meshset_id = blockset_by_name->getMeshsetId();
262 meshset_name = blockset_by_name->getName();
263 }
264
266}
267
268MoFEMErrorCode parseMeshsetEntry(const JsonObject &meshset_object,
269 const std::string &file_name,
270 const std::string &context,
271 MeshsetsManager *meshsets_manager_ptr,
272 ParsedMeshsetEntry &entry) {
274 entry = ParsedMeshsetEntry{};
275 entry.context = context;
276
277 bool has_meshset_id = false;
278
279 for (const auto &item : meshset_object) {
280 const auto key = toStdString(item.key());
281 if (key == "id") {
282 entry.meshsetId =
283 requireInt(item.value(), file_name, makeContext(context, key));
284 has_meshset_id = true;
285 continue;
286 }
287 if (key == "meshset_name") {
288 entry.meshsetName =
289 requireString(item.value(), file_name, makeContext(context, key));
290 continue;
291 }
292 if (key == "type") {
293 entry.typeName =
294 requireString(item.value(), file_name, makeContext(context, key));
295 continue;
296 }
297 if (key == "attributes") {
298 entry.attributes =
299 requireObject(item.value(), file_name, makeContext(context, key));
300 continue;
301 }
302 CHKERR failConfig(file_name, makeContext(context, key), "unknown meshset key");
303 }
304
305 if (entry.typeName.empty()) {
306 CHKERR failConfig(file_name, makeContext(context, "type"),
307 "missing meshset type");
308 }
309 if (!has_meshset_id && entry.meshsetName.empty()) {
310 CHKERR failConfig(file_name, context,
311 "meshset requires either 'id' or 'meshset_name'");
312 }
313
314 if (meshsets_manager_ptr) {
315 int resolved_meshset_id = -1;
316 std::string resolved_meshset_name;
318 *meshsets_manager_ptr, has_meshset_id, entry.meshsetId,
319 entry.meshsetName, file_name, context, resolved_meshset_id,
320 resolved_meshset_name);
321 entry.meshsetId = resolved_meshset_id;
322 entry.appliedMeshsetId = resolved_meshset_id;
323 entry.sourceMeshsetName = resolved_meshset_name;
324 }
326}
327
328MoFEMErrorCode parseMeshsets(const JsonArray &meshsets,
329 const std::string &mesh_context,
330 const std::string &file_name,
331 MeshsetsManager *meshsets_manager_ptr,
332 std::vector<ParsedMeshsetEntry> &parsed_meshsets) {
334 parsed_meshsets.clear();
335 parsed_meshsets.reserve(meshsets.size());
336
337 for (size_t meshset_index = 0; meshset_index != meshsets.size();
338 ++meshset_index) {
339 const auto current_meshset_context =
340 meshsetContext(mesh_context, meshset_index);
341 const auto &meshset_object =
342 requireObject(meshsets[meshset_index], file_name, current_meshset_context);
343
344 ParsedMeshsetEntry entry;
345 CHKERR parseMeshsetEntry(meshset_object, file_name, current_meshset_context,
346 meshsets_manager_ptr, entry);
347 parsed_meshsets.push_back(std::move(entry));
348 }
350}
351
352MoFEMErrorCode validateMeshsets(const JsonArray &meshsets,
353 const std::string &mesh_context,
354 const std::string &file_name) {
356 std::vector<ParsedMeshsetEntry> ignored_meshsets;
357 CHKERR parseMeshsets(meshsets, mesh_context, file_name, nullptr,
358 ignored_meshsets);
360}
361
363 const std::string &file_name) {
364 BlocksetParams params;
365 for (const auto &item : entry.attributes) {
366 const auto key = toStdString(item.key());
367 params[toLowerCopy(key)] = requireBlockAttributeValue(
368 item.value(), file_name, makeContext(meshsetAttributesContext(entry), key));
369 }
370 return params;
371}
372
374 const int meshset_id) {
375 return {toLowerCopy(entry.typeName), meshset_id};
376}
377
379 const std::vector<ParsedMeshsetEntry> &parsed_meshsets,
380 const std::string &file_name, BlocksetParamsByKey &params_by_key,
381 std::set<int> &used_blockset_ids) {
383 params_by_key.clear();
384 used_blockset_ids.clear();
385
386 for (const auto &entry : parsed_meshsets) {
387 used_blockset_ids.insert(entry.meshsetId);
388
389 if (!params_by_key
390 .emplace(getBlocksetParamKey(entry, entry.meshsetId),
391 getBlocksetParams(entry, file_name))
392 .second) {
393 CHKERR failConfig(
394 file_name, entry.context,
395 "duplicate JSON meshset entry for type '" + entry.typeName +
396 "' and id '" +
397 boost::lexical_cast<std::string>(entry.meshsetId) + "'");
398 }
399 }
401}
402
404 const std::vector<ParsedMeshsetEntry> &parsed_meshsets,
405 const std::string &file_name, BlocksetParamsByKey &params_by_key) {
407 for (const auto &entry : parsed_meshsets) {
408 if (entry.appliedMeshsetId != entry.meshsetId) {
409 params_by_key[getBlocksetParamKey(entry, entry.appliedMeshsetId)] =
410 getBlocksetParams(entry, file_name);
411 }
412 }
414}
415
416int firstGeneratedBlocksetId(MeshsetsManager &meshsets_manager) {
417 int next_id = 1;
418 for (auto it = meshsets_manager.getBegin(); it != meshsets_manager.getEnd();
419 ++it) {
420 if ((it->getBcType() & CubitBCType(BLOCKSET)).any()) {
421 next_id = std::max(next_id, it->getMeshsetId() + 1);
422 }
423 }
424 return next_id;
425}
426
427int takeNextFreeBlocksetId(MeshsetsManager &meshsets_manager, int &next_id) {
428 while (meshsets_manager.checkMeshset(next_id, BLOCKSET)) {
429 ++next_id;
430 }
431 return next_id++;
432}
433
434MoFEMErrorCode createBlocksetCopy(MeshsetsManager &meshsets_manager,
435 const int source_id, const int new_id,
436 const std::string &name) {
438 const CubitMeshSets *source_meshset = nullptr;
439 CHKERR meshsets_manager.getCubitMeshsetPtr(source_id, BLOCKSET,
440 &source_meshset);
441
442 Interface &m_field = meshsets_manager.cOre;
443 Range entities;
444 CHKERR m_field.get_moab().get_entities_by_handle(source_meshset->getMeshset(),
445 entities, true);
446
447 CHKERR meshsets_manager.addMeshset(BLOCKSET, new_id, name);
448 if (!entities.empty()) {
449 CHKERR meshsets_manager.addEntitiesToMeshset(BLOCKSET, new_id, entities);
450 }
452}
453
454MoFEMErrorCode applyParsedMeshsets(
455 MeshsetsManager &meshsets_manager,
456 std::vector<ParsedMeshsetEntry> &parsed_meshsets,
457 const std::string &file_name) {
459
460 std::map<int, int> applied_entries_by_source_id;
461 int next_blockset_id = firstGeneratedBlocksetId(meshsets_manager);
462
463 for (auto &entry : parsed_meshsets) {
464 CHKERR ensureBlocksetExists(meshsets_manager, entry.meshsetId, file_name,
465 entry.context);
466
467 entry.appliedMeshsetId = entry.meshsetId;
468 auto &applied_entries = applied_entries_by_source_id[entry.meshsetId];
469 if (applied_entries > 0) {
470 // Reuse the source entities, but do not overwrite the previous type/name.
471 entry.appliedMeshsetId =
472 takeNextFreeBlocksetId(meshsets_manager, next_blockset_id);
473 CHKERR createBlocksetCopy(meshsets_manager, entry.meshsetId,
474 entry.appliedMeshsetId,
475 appliedBlocksetName(entry));
476 }
477 ++applied_entries;
478
479 CHKERR applyBlockAttributes(meshsets_manager, entry.appliedMeshsetId,
480 entry.attributes, file_name,
482 entry.typeName, appliedBlocksetName(entry));
483 }
484
486}
MoFEMErrorCode validateMeshsets(const JsonArray &meshsets, const std::string &mesh_context, const std::string &file_name)
MoFEMErrorCode getUniqueBlocksetByName(MeshsetsManager &meshsets_manager, const std::string &meshset_name, const std::string &file_name, const std::string &context, const CubitMeshSets **blockset_ptr)
MoFEMErrorCode applyParsedMeshsets(MeshsetsManager &meshsets_manager, std::vector< ParsedMeshsetEntry > &parsed_meshsets, const std::string &file_name)
std::map< std::string, double > BlocksetParams
std::string meshsetAttributesContext(const ParsedMeshsetEntry &entry)
MoFEMErrorCode parseMeshsetEntry(const JsonObject &meshset_object, const std::string &file_name, const std::string &context, MeshsetsManager *meshsets_manager_ptr, ParsedMeshsetEntry &entry)
BlocksetParams getBlocksetParams(const ParsedMeshsetEntry &entry, const std::string &file_name)
std::pair< std::string, int > BlocksetParamKey
std::string appliedBlocksetName(const ParsedMeshsetEntry &entry)
MoFEMErrorCode getBlocksetById(MeshsetsManager &meshsets_manager, const int meshset_id, const std::string &file_name, const std::string &context, const CubitMeshSets **blockset_ptr)
double requireBlockAttributeValue(const JsonValue &value, const std::string &file_name, const std::string &context)
MoFEMErrorCode cacheResolvedBlocksetParams(const std::vector< ParsedMeshsetEntry > &parsed_meshsets, const std::string &file_name, BlocksetParamsByKey &params_by_key, std::set< int > &used_blockset_ids)
int firstGeneratedBlocksetId(MeshsetsManager &meshsets_manager)
MoFEMErrorCode applyBlockAttributes(MeshsetsManager &meshsets_manager, int id, const JsonObject &props, const std::string &file_name, const std::string &context, const std::string &type_name, const std::string &blockset_name)
std::string meshsetContext(const std::string &mesh_context, const size_t meshset_index)
MoFEMErrorCode createBlocksetCopy(MeshsetsManager &meshsets_manager, const int source_id, const int new_id, const std::string &name)
int centerAttributeSlot(const std::string &lower_key, const int first_slot)
int takeNextFreeBlocksetId(MeshsetsManager &meshsets_manager, int &next_id)
int parseGenericBlockUserIndex(const std::string &lower_key)
MoFEMErrorCode parseMeshsets(const JsonArray &meshsets, const std::string &mesh_context, const std::string &file_name, MeshsetsManager *meshsets_manager_ptr, std::vector< ParsedMeshsetEntry > &parsed_meshsets)
MoFEMErrorCode cacheAppliedBlocksetParams(const std::vector< ParsedMeshsetEntry > &parsed_meshsets, const std::string &file_name, BlocksetParamsByKey &params_by_key)
int positionalBlockAttributeSlot(const std::string &lower_type, const std::string &lower_key)
BlocksetParamKey getBlocksetParamKey(const ParsedMeshsetEntry &entry, const int meshset_id)
MoFEMErrorCode resolveMeshsetIdAndName(MeshsetsManager &meshsets_manager, const bool has_meshset_id, const int requested_meshset_id, const std::string &lookup_meshset_name, const std::string &file_name, const std::string &context, int &meshset_id, std::string &meshset_name)
std::map< BlocksetParamKey, BlocksetParams > BlocksetParamsByKey
std::string key
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ BLOCKSET
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.