v0.16.0
Loading...
Searching...
No Matches
JsonConfigManagerMeshsets.cpp
Go to the documentation of this file.
1int canonicalAttributeOrder(const std::string &lower_key) {
2 const auto &ordering = JsonConfigManager::canonical_attributes_ordering;
3 const auto it = std::find_if(
4 ordering.begin(), ordering.end(), [&](const std::string &name) {
5 return toLowerCopy(name) == lower_key;
6 });
7 if (it == ordering.end()) {
8 return -1;
9 }
10 return static_cast<int>(std::distance(ordering.begin(), it));
11}
12
13double requireBlockAttributeValue(const JsonValue &value,
14 const std::string &file_name,
15 const std::string &context) {
16 if (value.is_bool())
17 return value.as_bool() ? 1.0 : 0.0;
18
19 return requireNumber(value, file_name, context);
20}
21
22MoFEMErrorCode applyBlockAttributes(MeshsetsManager &meshsets_manager, int id,
23 const JsonObject &props,
24 const std::string &file_name,
25 const std::string &context,
26 const std::string &blockset_name) {
28 std::map<int, double> ordered_values;
29
30 for (const auto &item : props) {
31 if (item.value().is_string()) {
32 continue;
33 }
34
35 const auto key = toStdString(item.key());
36 const auto lower_key = toLowerCopy(key);
37 const auto order = canonicalAttributeOrder(lower_key);
38 if (order < 0) {
39 continue;
40 }
41 ordered_values[order] = requireBlockAttributeValue(
42 item.value(), file_name, makeContext(context, key));
43 }
44
45 if (ordered_values.size() > MAX_MESHSET_ATTRIBUTES) {
46 CHKERR failConfig(
47 file_name, context,
48 "BLOCKSET attributes exceed maximum supported direct attribute count " +
49 boost::lexical_cast<std::string>(MAX_MESHSET_ATTRIBUTES));
50 }
51
52 std::vector<double> values;
53 values.reserve(ordered_values.size());
54 for (const auto &attribute : ordered_values) {
55 values.push_back(attribute.second);
56 }
57
58 CHKERR meshsets_manager.setAttributes(BLOCKSET, id, values, blockset_name);
60}
61
62std::string meshsetContext(const std::string &mesh_context,
63 const size_t meshset_index) {
64 return mesh_context + ".meshsets[" +
65 boost::lexical_cast<std::string>(meshset_index) + "]";
66}
67
69 int meshsetId = -1;
71 std::string meshsetName;
72 std::string sourceMeshsetName;
73 std::string typeName;
74 JsonObject attributes;
75 std::string context;
76};
77
78using BlocksetParamKey = std::pair<std::string, int>;
79using BlocksetParams = std::map<std::string, double>;
80using BlocksetParamsByKey = std::map<BlocksetParamKey, BlocksetParams>;
81using BlocksetStringParams = std::map<std::string, std::string>;
83 std::map<BlocksetParamKey, BlocksetStringParams>;
84
86 return makeContext(entry.context, "attributes");
87}
88
89std::string appliedBlocksetName(const ParsedMeshsetEntry &entry) {
90 const auto id = boost::lexical_cast<std::string>(entry.appliedMeshsetId);
91 const auto max_name_size = NAME_TAG_SIZE - 1;
92 const auto type_id_name = entry.typeName + "_" + id;
93
94 if (type_id_name.size() > max_name_size) {
95 std::ostringstream ss;
96 ss << "JSON " << entry.context << ": generated BLOCKSET name '"
97 << type_id_name << "' is too long (" << type_id_name.size()
98 << " characters); cannot fit type and id into " << max_name_size
99 << " characters";
101 }
102
103 const auto &meshset_name = entry.meshsetName.empty() ? entry.sourceMeshsetName
104 : entry.meshsetName;
105 if (meshset_name.empty() || meshset_name == entry.typeName) {
106 return type_id_name;
107 }
108
109 const auto full_name = entry.typeName + "_" + meshset_name + "_" + id;
110 if (full_name.size() <= max_name_size) {
111 return full_name;
112 }
113
114 MOFEM_LOG("WORLD", Sev::warning)
115 << "JSON " << entry.context << ": generated BLOCKSET name '"
116 << full_name << "' is too long (" << full_name.size()
117 << " characters); removed meshset_name and using '" << type_id_name
118 << "'";
119 return type_id_name;
120}
121
122MoFEMErrorCode getUniqueBlocksetByName(MeshsetsManager &meshsets_manager,
123 const std::string &meshset_name,
124 const std::string &file_name,
125 const std::string &context,
126 const CubitMeshSets **blockset_ptr) {
128 *blockset_ptr = nullptr;
129 int number_of_meshsets = 0;
130
131 for (auto it = meshsets_manager.getBegin(); it != meshsets_manager.getEnd();
132 ++it) {
133 if ((it->getBcType() & CubitBCType(BLOCKSET)).none() ||
134 it->getName() != meshset_name) {
135 continue;
136 }
137 *blockset_ptr = &*it;
138 ++number_of_meshsets;
139 }
140
141 if (number_of_meshsets == 0) {
142 CHKERR failConfig(file_name, makeContext(context, "meshset_name"),
143 "failed to resolve BLOCKSET meshset_name '" +
144 meshset_name + "'");
145 }
146 if (number_of_meshsets != 1) {
147 CHKERR failConfig(file_name, makeContext(context, "meshset_name"),
148 "BLOCKSET meshset_name '" + meshset_name +
149 "' is not unique; resolve by explicit id");
150 }
151
153}
154
155MoFEMErrorCode getBlocksetById(MeshsetsManager &meshsets_manager,
156 const int meshset_id,
157 const std::string &file_name,
158 const std::string &context,
159 const CubitMeshSets **blockset_ptr) {
161 if (!meshsets_manager.checkMeshset(meshset_id, BLOCKSET)) {
162 CHKERR failConfig(file_name, makeContext(context, "id"),
163 "failed to resolve BLOCKSET id '" +
164 boost::lexical_cast<std::string>(meshset_id) + "'");
165 }
166 CHKERR meshsets_manager.getCubitMeshsetPtr(meshset_id, BLOCKSET,
167 blockset_ptr);
169}
170
171MoFEMErrorCode resolveMeshsetIdAndName(MeshsetsManager &meshsets_manager,
172 const bool has_meshset_id,
173 const int requested_meshset_id,
174 const std::string &lookup_meshset_name,
175 const std::string &file_name,
176 const std::string &context,
177 int &meshset_id,
178 std::string &meshset_name) {
180 const CubitMeshSets *blockset_by_id = nullptr;
181
182 if (has_meshset_id) {
183 CHKERR getBlocksetById(meshsets_manager, requested_meshset_id, file_name,
184 context, &blockset_by_id);
185 meshset_id = blockset_by_id->getMeshsetId();
186 meshset_name = blockset_by_id->getName();
187 if (!lookup_meshset_name.empty() && meshset_name != lookup_meshset_name) {
188 CHKERR failConfig(
189 file_name, context,
190 "meshset id '" + boost::lexical_cast<std::string>(meshset_id) +
191 "' does not match meshset_name '" + lookup_meshset_name + "'");
192 }
193 } else if (!lookup_meshset_name.empty()) {
194 const CubitMeshSets *blockset_by_name = nullptr;
195 CHKERR getUniqueBlocksetByName(meshsets_manager, lookup_meshset_name,
196 file_name, context, &blockset_by_name);
197 meshset_id = blockset_by_name->getMeshsetId();
198 meshset_name = blockset_by_name->getName();
199 }
200
202}
203
204MoFEMErrorCode parseMeshsetEntry(const JsonObject &meshset_object,
205 const std::string &file_name,
206 const std::string &context,
207 MeshsetsManager *meshsets_manager_ptr,
208 ParsedMeshsetEntry &entry) {
210 entry = ParsedMeshsetEntry{};
211 entry.context = context;
212
213 bool has_meshset_id = false;
214
215 for (const auto &item : meshset_object) {
216 const auto key = toStdString(item.key());
217 if (key == "id") {
218 entry.meshsetId =
219 requireInt(item.value(), file_name, makeContext(context, key));
220 has_meshset_id = true;
221 continue;
222 }
223 if (key == "meshset_name") {
224 entry.meshsetName =
225 requireString(item.value(), file_name, makeContext(context, key));
226 continue;
227 }
228 if (key == "type") {
229 entry.typeName =
230 requireString(item.value(), file_name, makeContext(context, key));
231 continue;
232 }
233 if (key == "attributes") {
234 entry.attributes =
235 requireObject(item.value(), file_name, makeContext(context, key));
236 continue;
237 }
238 CHKERR failConfig(file_name, makeContext(context, key), "unknown meshset key");
239 }
240
241 if (entry.typeName.empty()) {
242 CHKERR failConfig(file_name, makeContext(context, "type"),
243 "missing meshset type");
244 }
245 if (!has_meshset_id && entry.meshsetName.empty()) {
246 CHKERR failConfig(file_name, context,
247 "meshset requires either 'id' or 'meshset_name'");
248 }
249
250 if (meshsets_manager_ptr) {
251 int resolved_meshset_id = -1;
252 std::string resolved_meshset_name;
254 *meshsets_manager_ptr, has_meshset_id, entry.meshsetId,
255 entry.meshsetName, file_name, context, resolved_meshset_id,
256 resolved_meshset_name);
257 entry.meshsetId = resolved_meshset_id;
258 entry.appliedMeshsetId = resolved_meshset_id;
259 entry.sourceMeshsetName = resolved_meshset_name;
260 }
262}
263
264MoFEMErrorCode parseMeshsets(const JsonArray &meshsets,
265 const std::string &mesh_context,
266 const std::string &file_name,
267 MeshsetsManager *meshsets_manager_ptr,
268 std::vector<ParsedMeshsetEntry> &parsed_meshsets) {
270 parsed_meshsets.clear();
271 parsed_meshsets.reserve(meshsets.size());
272
273 for (size_t meshset_index = 0; meshset_index != meshsets.size();
274 ++meshset_index) {
275 const auto current_meshset_context =
276 meshsetContext(mesh_context, meshset_index);
277 const auto &meshset_object =
278 requireObject(meshsets[meshset_index], file_name, current_meshset_context);
279
280 ParsedMeshsetEntry entry;
281 CHKERR parseMeshsetEntry(meshset_object, file_name, current_meshset_context,
282 meshsets_manager_ptr, entry);
283 parsed_meshsets.push_back(std::move(entry));
284 }
286}
287
288MoFEMErrorCode validateMeshsets(const JsonArray &meshsets,
289 const std::string &mesh_context,
290 const std::string &file_name) {
292 std::vector<ParsedMeshsetEntry> ignored_meshsets;
293 CHKERR parseMeshsets(meshsets, mesh_context, file_name, nullptr,
294 ignored_meshsets);
296}
297
299 const std::string &file_name) {
300 BlocksetParams params;
301 for (const auto &item : entry.attributes) {
302 if (item.value().is_string()) {
303 continue;
304 }
305
306 const auto key = toStdString(item.key());
307 params[toLowerCopy(key)] = requireBlockAttributeValue(
308 item.value(), file_name, makeContext(meshsetAttributesContext(entry), key));
309 }
310 return params;
311}
312
314 const std::string &file_name) {
316 for (const auto &item : entry.attributes) {
317 if (!item.value().is_string()) {
318 continue;
319 }
320
321 const auto key = toStdString(item.key());
322 params[toLowerCopy(key)] = requireString(
323 item.value(), file_name, makeContext(meshsetAttributesContext(entry), key));
324 }
325 return params;
326}
327
329 const int meshset_id) {
330 return {toLowerCopy(entry.typeName), meshset_id};
331}
332
334 const std::vector<ParsedMeshsetEntry> &parsed_meshsets,
335 const std::string &file_name, BlocksetParamsByKey &params_by_key,
336 BlocksetStringParamsByKey &string_params_by_key,
337 std::set<int> &used_blockset_ids) {
339 params_by_key.clear();
340 string_params_by_key.clear();
341 used_blockset_ids.clear();
342
343 for (const auto &entry : parsed_meshsets) {
344 used_blockset_ids.insert(entry.meshsetId);
345
346 const auto param_key = getBlocksetParamKey(entry, entry.meshsetId);
347 if (params_by_key.count(param_key) || string_params_by_key.count(param_key)) {
348 CHKERR failConfig(
349 file_name, entry.context,
350 "duplicate JSON meshset entry for type '" + entry.typeName +
351 "' and id '" +
352 boost::lexical_cast<std::string>(entry.meshsetId) + "'");
353 }
354 params_by_key[param_key] = getBlocksetParams(entry, file_name);
355 string_params_by_key[param_key] = getBlocksetStringParams(entry, file_name);
356 }
358}
359
361 const std::vector<ParsedMeshsetEntry> &parsed_meshsets,
362 const std::string &file_name, BlocksetParamsByKey &params_by_key,
363 BlocksetStringParamsByKey &string_params_by_key) {
365 for (const auto &entry : parsed_meshsets) {
366 if (entry.appliedMeshsetId != entry.meshsetId) {
367 params_by_key[getBlocksetParamKey(entry, entry.appliedMeshsetId)] =
368 getBlocksetParams(entry, file_name);
369 string_params_by_key[getBlocksetParamKey(entry, entry.appliedMeshsetId)] =
370 getBlocksetStringParams(entry, file_name);
371 }
372 }
374}
375
376int firstGeneratedBlocksetId(MeshsetsManager &meshsets_manager) {
377 int next_id = 1;
378 for (auto it = meshsets_manager.getBegin(); it != meshsets_manager.getEnd();
379 ++it) {
380 if ((it->getBcType() & CubitBCType(BLOCKSET)).any()) {
381 next_id = std::max(next_id, it->getMeshsetId() + 1);
382 }
383 }
384 return next_id;
385}
386
387int takeNextFreeBlocksetId(MeshsetsManager &meshsets_manager, int &next_id) {
388 while (meshsets_manager.checkMeshset(next_id, BLOCKSET)) {
389 ++next_id;
390 }
391 return next_id++;
392}
393
394MoFEMErrorCode createBlocksetCopy(MeshsetsManager &meshsets_manager,
395 const int source_id, const int new_id,
396 const std::string &name) {
398 const CubitMeshSets *source_meshset = nullptr;
399 CHKERR meshsets_manager.getCubitMeshsetPtr(source_id, BLOCKSET,
400 &source_meshset);
401
402 Interface &m_field = meshsets_manager.cOre;
403 Range entities;
404 CHKERR m_field.get_moab().get_entities_by_handle(source_meshset->getMeshset(),
405 entities, true);
406
407 CHKERR meshsets_manager.addMeshset(BLOCKSET, new_id, name);
408 if (!entities.empty()) {
409 CHKERR meshsets_manager.addEntitiesToMeshset(BLOCKSET, new_id, entities);
410 }
412}
413
414MoFEMErrorCode applyParsedMeshsets(
415 MeshsetsManager &meshsets_manager,
416 std::vector<ParsedMeshsetEntry> &parsed_meshsets,
417 const std::string &file_name) {
419
420 std::map<int, int> applied_entries_by_source_id;
421 int next_blockset_id = firstGeneratedBlocksetId(meshsets_manager);
422
423 for (auto &entry : parsed_meshsets) {
424 CHKERR ensureBlocksetExists(meshsets_manager, entry.meshsetId, file_name,
425 entry.context);
426
427 entry.appliedMeshsetId = entry.meshsetId;
428 auto &applied_entries = applied_entries_by_source_id[entry.meshsetId];
429 const bool make_copy = applied_entries > 0;
430 if (make_copy) {
431 entry.appliedMeshsetId =
432 takeNextFreeBlocksetId(meshsets_manager, next_blockset_id);
433 }
434
435 const auto blockset_name = appliedBlocksetName(entry);
436
437 if (make_copy) {
438 // Reuse the source entities, but do not overwrite the previous type/name.
439 CHKERR createBlocksetCopy(meshsets_manager, entry.meshsetId,
440 entry.appliedMeshsetId, blockset_name);
441 }
442 ++applied_entries;
443
444 CHKERR applyBlockAttributes(meshsets_manager, entry.appliedMeshsetId,
445 entry.attributes, file_name,
446 meshsetAttributesContext(entry), blockset_name);
447 }
448
450}
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 cacheAppliedBlocksetParams(const std::vector< ParsedMeshsetEntry > &parsed_meshsets, const std::string &file_name, BlocksetParamsByKey &params_by_key, BlocksetStringParamsByKey &string_params_by_key)
MoFEMErrorCode applyParsedMeshsets(MeshsetsManager &meshsets_manager, std::vector< ParsedMeshsetEntry > &parsed_meshsets, const std::string &file_name)
std::map< std::string, double > BlocksetParams
std::map< std::string, std::string > BlocksetStringParams
std::string meshsetAttributesContext(const ParsedMeshsetEntry &entry)
int canonicalAttributeOrder(const std::string &lower_key)
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)
int firstGeneratedBlocksetId(MeshsetsManager &meshsets_manager)
MoFEMErrorCode cacheResolvedBlocksetParams(const std::vector< ParsedMeshsetEntry > &parsed_meshsets, const std::string &file_name, BlocksetParamsByKey &params_by_key, BlocksetStringParamsByKey &string_params_by_key, std::set< int > &used_blockset_ids)
std::string meshsetContext(const std::string &mesh_context, const size_t meshset_index)
BlocksetStringParams getBlocksetStringParams(const ParsedMeshsetEntry &entry, const std::string &file_name)
MoFEMErrorCode createBlocksetCopy(MeshsetsManager &meshsets_manager, const int source_id, const int new_id, const std::string &name)
int takeNextFreeBlocksetId(MeshsetsManager &meshsets_manager, int &next_id)
MoFEMErrorCode parseMeshsets(const JsonArray &meshsets, const std::string &mesh_context, const std::string &file_name, MeshsetsManager *meshsets_manager_ptr, std::vector< ParsedMeshsetEntry > &parsed_meshsets)
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)
MoFEMErrorCode applyBlockAttributes(MeshsetsManager &meshsets_manager, int id, const JsonObject &props, const std::string &file_name, const std::string &context, const std::string &blockset_name)
std::map< BlocksetParamKey, BlocksetParams > BlocksetParamsByKey
std::map< BlocksetParamKey, BlocksetStringParams > BlocksetStringParamsByKey
std::string key
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ BLOCKSET
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
constexpr int order
#define MOFEM_LOG(channel, severity)
Log.