v0.16.3
Loading...
Searching...
No Matches
BcManager.cpp
Go to the documentation of this file.
1/** \file BcManager.cpp
2 * \brief Manages boundary conditions
3 * \ingroup bc_manager
4 */
5
6namespace MoFEM {
7
8namespace BcManagerImplTools {
9
10auto get_dim(const Range &ents) {
11 for (auto d : {3, 2, 1})
12 if (ents.num_of_dimension(d))
13 return d;
14 return 0;
15};
16
17auto get_adj_ents(moab::Interface &moab, const Range &ents) {
18 Range verts;
19 CHK_MOAB_THROW(moab.get_connectivity(ents, verts, true), "get verts");
20 const auto dim = get_dim(ents);
21 for (size_t d = 1; d < dim; ++d) {
22 for (auto dd = d + 1; dd <= dim; ++dd) {
23 CHK_MOAB_THROW(moab.get_adjacencies(ents.subset_by_dimension(dd), d,
24 false, verts, moab::Interface::UNION),
25 "get adj");
26 }
27 }
28 verts.merge(ents);
29 return verts;
30}
31} // namespace BcManagerImplTools
32
34BcManager::query_interface(boost::typeindex::type_index type_index,
35 UnknownInterface **iface) const {
37 *iface = const_cast<BcManager *>(this);
39}
40
41BcManager::BcManager(const Core &core) : cOre(const_cast<Core &>(core)) {
42
43 if (!LogManager::checkIfChannelExist("BcMngWorld")) {
44 auto core_log = logging::core::get();
45
46 core_log->add_sink(
48 core_log->add_sink(
50 core_log->add_sink(
52
53 LogManager::setLog("BcMngWorld");
54 LogManager::setLog("BcMngSync");
55 LogManager::setLog("BcMngSelf");
56
57 MOFEM_LOG_TAG("BcMngWorld", "BcMng");
58 MOFEM_LOG_TAG("BcMngSync", "BcMng");
59 MOFEM_LOG_TAG("BcMngSelf", "BcMng");
60 }
61
62 MOFEM_LOG("BcMngWorld", Sev::noisy) << "BC manager created";
63}
64
67 PetscOptionsBegin(PETSC_COMM_WORLD, "", "BcManager options", "none");
68 PetscOptionsEnd();
70}
71
73 const std::string problem_name, const std::string block_name,
74 const std::string field_name, int lo, int hi, bool get_low_dim_ents,
75 bool is_distributed_mesh) {
76 Interface &m_field = cOre;
77 auto prb_mng = m_field.getInterface<ProblemsManager>();
79
80 CHKERR pushMarkDOFsOnEntities(problem_name, block_name, field_name, lo, hi,
81 get_low_dim_ents);
82
83 auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
84 const int hi) {
85 if (is_distributed_mesh)
86 return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
87 hi);
88 else
89 return prb_mng->removeDofsOnEntitiesNotDistributed(
90 problem_name, field_name, ents, lo, hi);
91 };
92
93 for (auto m :
94 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
95
96 (boost::format("%s(.*)") % block_name).str()
97
98 ))
99
100 ) {
101 const std::string bc_id =
102 problem_name + "_" + field_name + "_" + m->getName();
103 CHKERR remove_dofs_on_ents(bcMapByBlockName.at(bc_id)->bcEnts, lo, hi);
104 bcMapByBlockName.at(bc_id)->bcMarkers = std::vector<unsigned char>();
105 }
106
108}
109
111 const std::string block_name,
112 const std::string field_name,
113 int lo, int hi,
114 bool get_low_dim_ents) {
115 Interface &m_field = cOre;
116 auto prb_mng = m_field.getInterface<ProblemsManager>();
118
119 // if(problem_name.size())
120 // MOFEM_LOG("BcMngWorld", Sev::warning)
121 // << "Argument problem_name has no effect";
122
123 auto fix_disp = [&]() {
125
126 auto mark_fix_dofs = [&](std::vector<unsigned char> &marked_field_dofs,
127 const auto lo, const auto hi) {
128 return prb_mng->modifyMarkDofs(problem_name, ROW, field_name, lo, hi,
130 marked_field_dofs);
131 };
132
133 auto iterate_meshsets = [&](auto &&meshset_vec_ptr) {
135 for (auto m : meshset_vec_ptr) {
136 auto bc = boost::make_shared<BCs>();
137 CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
138 bc->bcEnts, true);
139 CHKERR m->getAttributes(bc->bcAttributes);
140
141 if (problem_name.size())
142 CHKERR mark_fix_dofs(bc->bcMarkers, lo, hi);
143 MOFEM_LOG("BcMngWorld", Sev::verbose)
144 << "Found block " << m->getName() << " number of attributes "
145 << bc->bcAttributes.size();
146
147 if (get_low_dim_ents) {
148 auto low_dim_ents =
149 BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
150 bc->bcEnts.swap(low_dim_ents);
151 }
152
153 CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
154 bc->bcEnts);
155 if (problem_name.size())
156 CHKERR prb_mng->markDofs(problem_name, ROW, ProblemsManager::AND,
157 bc->bcEnts, bc->bcMarkers);
158
159 const std::string bc_id =
160 problem_name + "_" + field_name + "_" + m->getName();
161 bcMapByBlockName[bc_id] = bc;
162 }
164 };
165
166 CHKERR iterate_meshsets(
167
168 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
169
170 (boost::format("%s(.*)") % block_name).str()
171
172 ))
173
174 );
175
177 };
178
179 CHKERR fix_disp();
180
182}
183
184boost::shared_ptr<BcManager::BCs>
185BcManager::popMarkDOFsOnEntities(const std::string block_name) {
186 auto bc_it = bcMapByBlockName.find(block_name);
187 if (bc_it != bcMapByBlockName.end()) {
188 auto bc = bc_it->second;
189 bcMapByBlockName.erase(bc_it);
190 return bc;
191 }
192 return boost::shared_ptr<BCs>();
193}
194
195Range BcManager::getMergedBlocksRange(std::vector<std::regex> bc_regex_vec) {
196 Range ents;
197 if (bcMapByBlockName.size()) {
198 for (auto b : bcMapByBlockName) {
199 for (auto &reg_name : bc_regex_vec) {
200 if (std::regex_match(b.first, reg_name)) {
201 ents.merge(b.second->bcEnts);
202 }
203 }
204 }
205 }
206 return ents;
207}
208
210BcManager::getMergedBlocksMarker(std::vector<std::regex> bc_regex_vec) {
211 BcManager::BcMarkerPtr boundary_marker_ptr;
212 if (bcMapByBlockName.size()) {
213 for (auto b : bcMapByBlockName) {
214 for (auto &reg_name : bc_regex_vec) {
215 if (std::regex_match(b.first, reg_name)) {
216 if (!boundary_marker_ptr)
217 boundary_marker_ptr =
218 boost::make_shared<std::vector<char unsigned>>();
219 boundary_marker_ptr->resize(b.second->bcMarkers.size(), 0);
220 for (int i = 0; i != b.second->bcMarkers.size(); ++i) {
221 (*boundary_marker_ptr)[i] |= b.second->bcMarkers[i];
222 }
223 }
224 }
225 }
226 }
227 return boundary_marker_ptr;
228}
229
231 const std::vector<BcManager::BcMarkerPtr> &boundary_markers_ptr_vec) {
232 auto boundary_marker_ptr = boost::make_shared<std::vector<char unsigned>>();
233 for (auto &bcm : boundary_markers_ptr_vec) {
234 boundary_marker_ptr->resize(bcm->size(), 0);
235 for (int i = 0; i != bcm->size(); ++i)
236 (*boundary_marker_ptr)[i] |= (*bcm)[i];
237 }
238 return boundary_marker_ptr;
239}
240
241SmartPetscObj<IS> BcManager::getBlockIS(const std::string block_prefix,
242 const std::string block_name,
243 const std::string field_name,
244 const std::string problem_name, int lo,
245 int hi, SmartPetscObj<IS> is_expand) {
246 Interface &m_field = cOre;
247
248 const std::string bc_id =
249 block_prefix + "_" + field_name + "_" + block_name + "(.*)";
250
251 Range bc_ents;
252 for (auto bc : getBcMapByBlockName()) {
253 if (std::regex_match(bc.first, std::regex(bc_id))) {
254 bc_ents.merge(*(bc.second->getBcEntsPtr()));
255 MOFEM_LOG("BcMngWorld", Sev::verbose)
256 << "Get entities from block and add to IS. Block name " << bc.first;
257 }
258 }
259
260 SmartPetscObj<IS> is_bc;
261 auto get_is = [&]() {
263 CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(bc_ents);
264 CHKERR m_field.getInterface<ISManager>()->isCreateProblemFieldAndRank(
265 problem_name, ROW, field_name, lo, hi, is_bc, &bc_ents);
266 if (is_expand) {
267 IS is_tmp;
268 CHKERR ISExpand(is_bc, is_expand, &is_tmp);
269 is_bc = SmartPetscObj<IS>(is_tmp);
270 }
271 CHKERR ISSort(is_bc);
273 };
274
275 if (get_is())
276 CHK_THROW_MESSAGE(MOFEM_DATA_INCONSISTENCY, "IS is not created");
277
278 return is_bc;
279}
280
281SmartPetscObj<IS> BcManager::getBlockIS(const std::string problem_name,
282 const std::string block_name,
283 const std::string field_name, int lo,
284 int hi, SmartPetscObj<IS> is_expand) {
285 return getBlockIS(problem_name, block_name, field_name, problem_name, lo, hi,
286 is_expand);
287}
288
289template <>
291BcManager::removeBlockDOFsOnEntities<BcMeshsetType<DISPLACEMENTSET>>(
292 const std::string problem_name, const std::string field_name,
293 bool get_low_dim_ents, bool block_name_field_prefix,
294 bool is_distributed_mesh) {
295 Interface &m_field = cOre;
296 auto prb_mng = m_field.getInterface<ProblemsManager>();
298
299 CHKERR pushMarkDOFsOnEntities<BcMeshsetType<DISPLACEMENTSET>>(
300 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
301
302 std::array<Range, 3> ents_to_remove;
303
304 for (auto m :
305
306 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
308
309 const std::string bc_id =
310 problem_name + "_" + field_name + "_DISPLACEMENTSET" +
311 boost::lexical_cast<std::string>(m->getMeshsetId());
312
313 auto bc = bcMapByBlockName.at(bc_id);
314
315 if (bc->dispBcPtr) {
316 if (bc->dispBcPtr->data.flag1) {
317 ents_to_remove[0].merge(bc->bcEnts);
318 }
319 if (bc->dispBcPtr->data.flag2) {
320 ents_to_remove[1].merge(bc->bcEnts);
321 }
322 if (bc->dispBcPtr->data.flag3) {
323 ents_to_remove[2].merge(bc->bcEnts);
324 }
325 if (bc->dispBcPtr->data.flag4) {
326 ents_to_remove[1].merge(bc->bcEnts);
327 ents_to_remove[2].merge(bc->bcEnts);
328 }
329 if (bc->dispBcPtr->data.flag5) {
330 ents_to_remove[0].merge(bc->bcEnts);
331 ents_to_remove[2].merge(bc->bcEnts);
332 }
333 if (bc->dispBcPtr->data.flag6) {
334 ents_to_remove[0].merge(bc->bcEnts);
335 ents_to_remove[1].merge(bc->bcEnts);
336 }
337 }
338 bc->bcMarkers = std::vector<unsigned char>();
339 }
340
341 auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
342 const int hi) {
343 if (is_distributed_mesh)
344 return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
345 hi);
346 else
347 return prb_mng->removeDofsOnEntitiesNotDistributed(
348 problem_name, field_name, ents, lo, hi);
349 };
350
351 CHKERR remove_dofs_on_ents(ents_to_remove[0], 0, 0);
352 CHKERR remove_dofs_on_ents(ents_to_remove[1], 1, 1);
353 CHKERR remove_dofs_on_ents(ents_to_remove[2], 2, 2);
354
356}
357
358template <>
360BcManager::removeBlockDOFsOnEntities<BcMeshsetType<TEMPERATURESET>>(
361 const std::string problem_name, const std::string field_name,
362 bool get_low_dim_ents, bool block_name_field_prefix,
363 bool is_distributed_mesh) {
364 Interface &m_field = cOre;
365 auto prb_mng = m_field.getInterface<ProblemsManager>();
367
368 CHKERR pushMarkDOFsOnEntities<BcMeshsetType<TEMPERATURESET>>(
369 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
370
371 Range ents_to_remove;
372
373 for (auto m :
374
375 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
377
378 ) {
379 const std::string bc_id =
380 problem_name + "_" + field_name + "_TEMPERATURESET" +
381 boost::lexical_cast<std::string>(m->getMeshsetId());
382 auto bc = bcMapByBlockName.at(bc_id);
383 ents_to_remove.merge(bc->bcEnts);
384 bc->bcMarkers = std::vector<unsigned char>();
385 }
386
387 auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
388 const int hi) {
389 if (is_distributed_mesh)
390 return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
391 hi);
392 else
393 return prb_mng->removeDofsOnEntitiesNotDistributed(
394 problem_name, field_name, ents, lo, hi);
395 };
396
397 CHKERR remove_dofs_on_ents(ents_to_remove, 0, MAX_DOFS_ON_ENTITY);
398
400}
401
402template <>
403MoFEMErrorCode BcManager::removeBlockDOFsOnEntities<BcMeshsetType<HEATFLUXSET>>(
404 const std::string problem_name, const std::string field_name,
405 bool get_low_dim_ents, bool block_name_field_prefix,
406 bool is_distributed_mesh) {
407 Interface &m_field = cOre;
408 auto prb_mng = m_field.getInterface<ProblemsManager>();
410
411 CHKERR pushMarkDOFsOnEntities<BcMeshsetType<HEATFLUXSET>>(
412 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
413
414 Range ents_to_remove;
415
416 for (auto m :
417
418 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(NODESET |
420
421 ) {
422 const std::string bc_id =
423 problem_name + "_" + field_name + "_HEATFLUXSET" +
424 boost::lexical_cast<std::string>(m->getMeshsetId());
425 auto bc = bcMapByBlockName.at(bc_id);
426 ents_to_remove.merge(bc->bcEnts);
427 bc->bcMarkers = std::vector<unsigned char>();
428 }
429
430 auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
431 const int hi) {
432 if (is_distributed_mesh)
433 return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
434 hi);
435 else
436 return prb_mng->removeDofsOnEntitiesNotDistributed(
437 problem_name, field_name, ents, lo, hi);
438 };
439
440 CHKERR remove_dofs_on_ents(ents_to_remove, 0, MAX_DOFS_ON_ENTITY);
441
443}
444
445template <>
447BcManager::removeBlockDOFsOnEntities<BcDisplacementMeshsetType<BLOCKSET>>(
448 const std::string problem_name, const std::string field_name,
449 bool get_low_dim_ents, bool block_name_field_prefix,
450 bool is_distributed_mesh) {
451 Interface &m_field = cOre;
452 auto prb_mng = m_field.getInterface<ProblemsManager>();
454
455 CHKERR pushMarkDOFsOnEntities<BcDisplacementMeshsetType<BLOCKSET>>(
456 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
457
458 std::array<Range, 3> ents_to_remove;
459
460 for (auto m :
461
462 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
464
465 const auto block_name = m->getName();
466
467 std::string bc_id = problem_name + "_" + field_name + "_" + block_name;
468 std::string regex_str;
469 if (block_name_field_prefix) {
470 regex_str = (boost::format("%s_%s_%s_((FIX_(ALL|X|Y|Z))|("
471 "DISPLACEMENT|ROTATE))(.*)") %
472 problem_name % field_name % field_name)
473 .str();
474 } else {
475 regex_str = (boost::format("%s_%s_((FIX_(ALL|X|Y|Z))|("
476 "DISPLACEMENT|ROTATE))(.*)") %
477 problem_name % field_name)
478 .str();
479 }
480
481 if (std::regex_match(bc_id, std::regex(regex_str))) {
482
483 auto bc = bcMapByBlockName.at(bc_id);
484
485 if (auto disp_bc = bc->dispBcPtr) {
486 if (disp_bc->data.flag1) {
487 ents_to_remove[0].merge(bc->bcEnts);
488 }
489 if (disp_bc->data.flag2) {
490 ents_to_remove[1].merge(bc->bcEnts);
491 }
492 if (disp_bc->data.flag3) {
493 ents_to_remove[2].merge(bc->bcEnts);
494 }
495 if (disp_bc->data.flag4) {
496 ents_to_remove[1].merge(bc->bcEnts);
497 ents_to_remove[2].merge(bc->bcEnts);
498 }
499 if (disp_bc->data.flag5) {
500 ents_to_remove[0].merge(bc->bcEnts);
501 ents_to_remove[2].merge(bc->bcEnts);
502 }
503 if (disp_bc->data.flag6) {
504 ents_to_remove[0].merge(bc->bcEnts);
505 ents_to_remove[1].merge(bc->bcEnts);
506 }
507 } else {
508 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
509 "BC type not implemented");
510 }
511 }
512 }
513
514 auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
515 const int hi) {
516 if (is_distributed_mesh)
517 return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
518 hi);
519 else
520 return prb_mng->removeDofsOnEntitiesNotDistributed(
521 problem_name, field_name, ents, lo, hi);
522 };
523
524 CHKERR remove_dofs_on_ents(ents_to_remove[0], 0, 0);
525 CHKERR remove_dofs_on_ents(ents_to_remove[1], 1, 1);
526 CHKERR remove_dofs_on_ents(ents_to_remove[2], 2, 2);
527
529}
530
531template <>
533BcManager::removeBlockDOFsOnEntities<BcScalarMeshsetType<BLOCKSET>>(
534 const std::string problem_name, const std::string block_name,
535 const std::string field_name, bool get_low_dim_ents,
536 bool is_distributed_mesh) {
537 Interface &m_field = cOre;
538 auto prb_mng = m_field.getInterface<ProblemsManager>();
540
541 CHKERR pushMarkDOFsOnEntities<BcScalarMeshsetType<BLOCKSET>>(
542 problem_name, block_name, field_name, get_low_dim_ents);
543
544 Range ents_to_remove;
545
546 for (auto m :
547
548 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
550
551 std::string bc_id = problem_name + "_" + field_name + "_" + m->getName();
552
553 auto str = boost::format("%s_%s_%s(.*)")
554
555 % problem_name % field_name % block_name;
556
557 if (std::regex_match(bc_id, std::regex(str.str()))) {
558
559 auto bc = bcMapByBlockName.at(bc_id);
560
561 if (auto temp_bc = bc->tempBcPtr) {
562 if (temp_bc->data.flag1) {
563 ents_to_remove.merge(bc->bcEnts);
564 }
565 } else {
566 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
567 "BC type not implemented");
568 }
569 }
570 }
571
572 auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
573 const int hi) {
574 if (is_distributed_mesh)
575 return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
576 hi);
577 else
578 return prb_mng->removeDofsOnEntitiesNotDistributed(
579 problem_name, field_name, ents, lo, hi);
580 };
581
582 CHKERR remove_dofs_on_ents(ents_to_remove, 0, MAX_DOFS_ON_ENTITY);
583
585}
586
587template <>
589BcManager::pushMarkDOFsOnEntities<BcMeshsetType<DISPLACEMENTSET>>(
590 const std::string problem_name, const std::string field_name,
591 bool get_low_dim_ents, bool block_name_field_prefix) {
592 Interface &m_field = cOre;
593 auto prb_mng = m_field.getInterface<ProblemsManager>();
595
596 // if(problem_name.size()==0)
597 // MOFEM_LOG("BcMngWorld", Sev::warning)
598 // << "Argument problem_name has no effect";
599
600 if (block_name_field_prefix)
601 MOFEM_LOG("BcMngWorld", Sev::warning)
602 << "Argument block_name_field_prefix=true has no effect";
603
604 auto fix_disp = [&]() {
606
607 auto iterate_meshsets = [&](auto &&meshset_vec_ptr) {
609 for (auto m : meshset_vec_ptr) {
610 auto bc = boost::make_shared<BCs>();
611 CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
612 bc->bcEnts, true);
613 bc->dispBcPtr = boost::make_shared<DisplacementCubitBcData>();
614 CHKERR m->getBcDataStructure(*(bc->dispBcPtr));
615
616 MOFEM_LOG("BcMngWorld", Sev::verbose)
617 << "Found block DISPLACEMENTSET id = " << m->getMeshsetId();
618 MOFEM_LOG("BcMngWorld", Sev::verbose) << *bc->dispBcPtr;
619
620 MOFEM_LOG("BcMngSync", Sev::noisy)
621 << "Found block DISPLACEMENTSET id = " << m->getMeshsetId()
622 << " nb. of entities " << bc->bcEnts.size()
623 << " highest dim of entities "
624 << BcManagerImplTools::get_dim(bc->bcEnts);
625 MOFEM_LOG("BcMngSync", Sev::noisy) << *bc->dispBcPtr;
626 MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
627
628 if (problem_name.size()) {
629
630 if (bc->dispBcPtr->data.flag1)
631 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 0, 0,
633 bc->bcMarkers);
634 if (bc->dispBcPtr->data.flag2)
635 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 1, 1,
637 bc->bcMarkers);
638 if (bc->dispBcPtr->data.flag3)
639 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 2, 2,
641 bc->bcMarkers);
642 if (bc->dispBcPtr->data.flag4) {
643
644 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 1, 1,
646 bc->bcMarkers);
647 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 2, 2,
649 bc->bcMarkers);
650 }
651 if (bc->dispBcPtr->data.flag5) {
652
653 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 0, 0,
655 bc->bcMarkers);
656 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 2, 2,
658 bc->bcMarkers);
659 }
660 if (bc->dispBcPtr->data.flag6) {
661
662 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 0, 0,
664 bc->bcMarkers);
665 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 1, 1,
667 bc->bcMarkers);
668 }
669 }
670
671 if (get_low_dim_ents) {
672 auto low_dim_ents =
673 BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
674 bc->bcEnts.swap(low_dim_ents);
675 }
676
677 CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
678 bc->bcEnts);
679 if (problem_name.size())
680 CHKERR prb_mng->markDofs(problem_name, ROW, ProblemsManager::AND,
681 bc->bcEnts, bc->bcMarkers);
682
683 const std::string bc_id =
684 problem_name + "_" + field_name + "_DISPLACEMENTSET" +
685 boost::lexical_cast<std::string>(m->getMeshsetId());
686 bcMapByBlockName[bc_id] = bc;
687 }
689 };
690
691 CHKERR iterate_meshsets(
692
695
696 );
697
699 };
700
701 CHKERR fix_disp();
702
704}
705
706template <>
707MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<BcMeshsetType<TEMPERATURESET>>(
708 const std::string problem_name, const std::string field_name,
709 bool get_low_dim_ents, bool block_name_field_prefix) {
710 Interface &m_field = cOre;
711 auto prb_mng = m_field.getInterface<ProblemsManager>();
713
714 if (block_name_field_prefix)
715 MOFEM_LOG("BcMngWorld", Sev::warning)
716 << "Argument block_name_field_prefix=true has no effect";
717
718 auto fix_temp = [&]() {
720
721 auto iterate_meshsets = [&](auto &&meshset_vec_ptr) {
723 for (auto m : meshset_vec_ptr) {
724 auto bc = boost::make_shared<BCs>();
725 CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
726 bc->bcEnts, true);
727 bc->tempBcPtr = boost::make_shared<TemperatureCubitBcData>();
728 CHKERR m->getBcDataStructure(*(bc->tempBcPtr));
729
730 MOFEM_LOG("BcMngWorld", Sev::verbose)
731 << "Found block TEMPERATURESET id = " << m->getMeshsetId();
732 MOFEM_LOG("BcMngWorld", Sev::verbose) << *bc->tempBcPtr;
733
734 CHKERR prb_mng->modifyMarkDofs(
735 problem_name, ROW, field_name, 0, MAX_DOFS_ON_ENTITY,
736 ProblemsManager::MarkOP::OR, 1, bc->bcMarkers);
737
738 if (get_low_dim_ents) {
739 auto low_dim_ents =
740 BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
741 bc->bcEnts.swap(low_dim_ents);
742 }
743
744 CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
745 bc->bcEnts);
746 CHKERR prb_mng->markDofs(problem_name, ROW, ProblemsManager::AND,
747 bc->bcEnts, bc->bcMarkers);
748
749 const std::string bc_id =
750 problem_name + "_" + field_name + "_TEMPERATURESET" +
751 boost::lexical_cast<std::string>(m->getMeshsetId());
752 bcMapByBlockName[bc_id] = bc;
753 }
755 };
756
757 CHKERR iterate_meshsets(
758
761
762 );
763
765 };
766
767 CHKERR fix_temp();
768
770}
771
772template <>
773MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<BcMeshsetType<HEATFLUXSET>>(
774 const std::string problem_name, const std::string field_name,
775 bool get_low_dim_ents, bool block_name_field_prefix) {
776 Interface &m_field = cOre;
777 auto prb_mng = m_field.getInterface<ProblemsManager>();
779
780 if (block_name_field_prefix)
781 MOFEM_LOG("BcMngWorld", Sev::warning)
782 << "Argument block_name_field_prefix=true has no effect";
783
784 auto fix_disp = [&]() {
786
787 auto iterate_meshsets = [&](auto &&meshset_vec_ptr) {
789 for (auto m : meshset_vec_ptr) {
790 auto bc = boost::make_shared<BCs>();
791 CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
792 bc->bcEnts, true);
793 bc->heatFluxBcPtr = boost::make_shared<HeatFluxCubitBcData>();
794 CHKERR m->getBcDataStructure(*(bc->heatFluxBcPtr));
795
796 CHKERR prb_mng->modifyMarkDofs(
797 problem_name, ROW, field_name, 0, MAX_DOFS_ON_ENTITY,
798 ProblemsManager::MarkOP::OR, 1, bc->bcMarkers);
799
800 MOFEM_LOG("BcMngWorld", Sev::inform)
801 << "Found block HEATFLUX id = " << m->getMeshsetId();
802 MOFEM_LOG("BcMngWorld", Sev::inform) << *bc->heatFluxBcPtr;
803
804 if (get_low_dim_ents) {
805 auto low_dim_ents =
806 BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
807 bc->bcEnts.swap(low_dim_ents);
808 }
809
810 CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
811 bc->bcEnts);
812 CHKERR prb_mng->markDofs(problem_name, ROW, ProblemsManager::AND,
813 bc->bcEnts, bc->bcMarkers);
814
815 const std::string bc_id =
816 problem_name + "_" + field_name + "_HEATFLUXSET" +
817 boost::lexical_cast<std::string>(m->getMeshsetId());
818 bcMapByBlockName[bc_id] = bc;
819 }
821 };
822
823 CHKERR iterate_meshsets(
824
827
828 );
829
831 };
832
833 CHKERR fix_disp();
834
836}
837
838template <>
840BcManager::pushMarkDOFsOnEntities<BcDisplacementMeshsetType<BLOCKSET>>(
841 const std::string problem_name, const std::string field_name,
842 bool get_low_dim_ents, bool block_name_field_prefix) {
844
845 auto mark_dofs = [&](const string block_name, const int &idx_0,
846 const int &idx_1) {
848 if (block_name_field_prefix) {
849 const string field_block = field_name + "_" + block_name;
850 CHKERR pushMarkDOFsOnEntities(problem_name, field_block, field_name,
851 idx_0, idx_1, get_low_dim_ents);
852 } else {
853
854 CHKERR pushMarkDOFsOnEntities(problem_name, block_name, field_name, idx_0,
855 idx_1, get_low_dim_ents);
856 }
858 };
859
860 // displacement
861 CHKERR mark_dofs("FIX_X", 0, 0);
862 CHKERR mark_dofs("FIX_Y", 1, 1);
863 CHKERR mark_dofs("FIX_Z", 2, 2);
864 CHKERR mark_dofs("FIX_ALL", 0, MAX_DOFS_ON_ENTITY);
865
866 // rotation
867 CHKERR mark_dofs("ROTATE_X", 1, 1);
868 CHKERR mark_dofs("ROTATE_X", 2, 2);
869 CHKERR mark_dofs("ROTATE_Y", 0, 0);
870 CHKERR mark_dofs("ROTATE_Y", 2, 2);
871 CHKERR mark_dofs("ROTATE_Z", 0, 0);
872 CHKERR mark_dofs("ROTATE_Z", 1, 1);
873 CHKERR mark_dofs("ROTATE_ALL", 0, MAX_DOFS_ON_ENTITY);
874
875 std::string regex_str;
876 if (block_name_field_prefix) {
877 regex_str = (boost::format("%s_%s_%s_(.*)") % problem_name % field_name %
879 .str();
880 } else {
881 regex_str = (boost::format("%s_%s_(.*)") % problem_name % field_name).str();
882 }
883
884 for (auto &m : bcMapByBlockName) {
885 auto &bc_id = m.first;
886 std::smatch bc_match;
887 if (std::regex_match(bc_id, bc_match, std::regex(regex_str))) {
888 // JSON names start with the BC type, followed by the source meshset name.
889 // Match that type, not a later token such as FIX_Z in FIX_ALL_FIX_Z_5.
890 const auto block_name = bc_match[1].str();
891 auto &bc = m.second;
892 if (std::regex_match(block_name, std::regex("FIX_X(.*)"))) {
893 bc->dispBcPtr = boost::make_shared<DisplacementCubitBcData>();
894 bc->dispBcPtr->data.flag1 = 1;
895 if (bc->bcAttributes.empty()) {
896 bc->dispBcPtr->data.value1 = 0;
897 MOFEM_LOG("BcMngWorld", Sev::warning)
898 << "Expected one attribute on block but have "
899 << bc->bcAttributes.size();
900 } else if (bc->bcAttributes.size() >= 1) {
901 bc->dispBcPtr->data.value1 = bc->bcAttributes[0];
902 }
903 MOFEM_LOG("BcMngWorld", Sev::inform) << "Add X " << bc_id;
904 MOFEM_LOG("BcMngWorld", Sev::inform) << *bc->dispBcPtr;
905 } else if (std::regex_match(block_name, std::regex("FIX_Y(.*)"))) {
906 bc->dispBcPtr = boost::make_shared<DisplacementCubitBcData>();
907 bc->dispBcPtr->data.flag2 = 1;
908 if (bc->bcAttributes.empty()) {
909 bc->dispBcPtr->data.value2 = 0;
910 MOFEM_LOG("BcMngWorld", Sev::warning)
911 << "Expected one attribute on block but have "
912 << bc->bcAttributes.size();
913 } else if (bc->bcAttributes.size() == 1) {
914 bc->dispBcPtr->data.value2 = bc->bcAttributes[0];
915 } else if (bc->bcAttributes.size() >= 2) {
916 bc->dispBcPtr->data.value2 = bc->bcAttributes[1];
917 }
918 MOFEM_LOG("BcMngWorld", Sev::inform) << "Add Y " << bc_id;
919 MOFEM_LOG("BcMngWorld", Sev::inform) << *(bc->dispBcPtr);
920 } else if (std::regex_match(block_name, std::regex("FIX_Z(.*)"))) {
921 bc->dispBcPtr = boost::make_shared<DisplacementCubitBcData>();
922 bc->dispBcPtr->data.flag3 = 1;
923 if (bc->bcAttributes.empty()) {
924 bc->dispBcPtr->data.value3 = 0;
925 MOFEM_LOG("BcMngWorld", Sev::warning)
926 << "Expected one attribute on block but have "
927 << bc->bcAttributes.size();
928 } else if (bc->bcAttributes.size() == 1) {
929 bc->dispBcPtr->data.value3 = bc->bcAttributes[0];
930 } else if (bc->bcAttributes.size() == 3) {
931 bc->dispBcPtr->data.value3 = bc->bcAttributes[2];
932 }
933 MOFEM_LOG("BcMngWorld", Sev::inform) << "Add Z " << bc_id;
934 MOFEM_LOG("BcMngWorld", Sev::inform) << *(bc->dispBcPtr);
935 } else if (std::regex_match(block_name, std::regex("FIX_ALL(.*)"))) {
936 bc->dispBcPtr = boost::make_shared<DisplacementCubitBcData>();
937 bc->dispBcPtr->data.flag1 = 1;
938 bc->dispBcPtr->data.flag2 = 1;
939 bc->dispBcPtr->data.flag3 = 1;
940 if (bc->bcAttributes.size() >= 1) {
941 bc->dispBcPtr->data.value1 = bc->bcAttributes[0];
942 }
943 if (bc->bcAttributes.size() >= 2) {
944 bc->dispBcPtr->data.value2 = bc->bcAttributes[1];
945 }
946 if (bc->bcAttributes.size() >= 3) {
947 bc->dispBcPtr->data.value3 = bc->bcAttributes[2];
948 }
949 MOFEM_LOG("BcMngWorld", Sev::inform) << "Add ALL " << bc_id;
950 MOFEM_LOG("BcMngWorld", Sev::inform) << *(bc->dispBcPtr);
951 } else if (std::regex_match(block_name, std::regex("ROTATE_X(.*)"))) {
952 bc->dispBcPtr =
953 boost::make_shared<DisplacementCubitBcDataWithRotation>();
954 bc->dispBcPtr->data.flag4 = 1;
955 bc->dispBcPtr->data.flag5 = 0;
956 bc->dispBcPtr->data.flag6 = 0;
957 // for the ROTATE_X block the angles can be specified with either one or
958 // three attributes, e.g. 1, coords or 1,0,0,coords
959 if (bc->bcAttributes.empty()) {
960 bc->dispBcPtr->data.value4 = 0;
961 MOFEM_LOG("BcMngWorld", Sev::warning)
962 << "Expected one attribute on block on block (angle (1 or 3), "
963 "center coords(3) but have "
964 << bc->bcAttributes.size();
965 } else if (bc->bcAttributes.size() >= 1) {
966 bc->dispBcPtr->data.value4 = bc->bcAttributes[0];
967 }
968 MOFEM_LOG("BcMngWorld", Sev::inform) << "Add X " << bc_id;
969 MOFEM_LOG("BcMngWorld", Sev::inform) << *bc->dispBcPtr;
970 if (bc->bcAttributes.size() == 4 || bc->bcAttributes.size() == 6) {
971 if (auto ext_disp_bc =
973 bc->dispBcPtr.get())) {
974 auto &o = ext_disp_bc->rotOffset;
975 for (int a = 0; a != 3; ++a)
976 o[a] = bc->bcAttributes[bc->bcAttributes.size() - 3 + a];
977 MOFEM_LOG("BcMngWorld", Sev::inform)
978 << "Add Rotate X Center: " << o[0] << " " << o[1] << " "
979 << o[2];
980 }
981 }
982 } else if (std::regex_match(block_name, std::regex("ROTATE_Y(.*)"))) {
983 bc->dispBcPtr =
984 boost::make_shared<DisplacementCubitBcDataWithRotation>();
985 bc->dispBcPtr->data.flag4 = 0;
986 bc->dispBcPtr->data.flag5 = 1;
987 bc->dispBcPtr->data.flag6 = 0;
988 // for the ROTATE_Y block the angles can be specified with either one or
989 // three attributes, e.g. 1, coords or 0,1,0,coords
990 if (bc->bcAttributes.empty()) {
991 bc->dispBcPtr->data.value5 = 0;
992 MOFEM_LOG("BcMngWorld", Sev::warning)
993 << "Expected one attribute on block on block (angle (1 or 3), "
994 "center coords(3) but have "
995 << bc->bcAttributes.size();
996 } else if (bc->bcAttributes.size() == 1 ||
997 bc->bcAttributes.size() == 4) {
998 bc->dispBcPtr->data.value5 = bc->bcAttributes[0];
999 } else if (bc->bcAttributes.size() == 6) {
1000 bc->dispBcPtr->data.value5 = bc->bcAttributes[1];
1001 }
1002 MOFEM_LOG("BcMngWorld", Sev::inform) << "Add Y " << bc_id;
1003 MOFEM_LOG("BcMngWorld", Sev::inform) << *(bc->dispBcPtr);
1004 if (bc->bcAttributes.size() == 4 || bc->bcAttributes.size() == 6) {
1005 if (auto ext_disp_bc =
1007 bc->dispBcPtr.get())) {
1008 auto &o = ext_disp_bc->rotOffset;
1009 for (int a = 0; a != 3; ++a)
1010 o[a] = bc->bcAttributes[bc->bcAttributes.size() - 3 + a];
1011 MOFEM_LOG("BcMngWorld", Sev::inform)
1012 << "Add Rotate Y Center: " << o[0] << " " << o[1] << " "
1013 << o[2];
1014 }
1015 }
1016 } else if (std::regex_match(block_name, std::regex("ROTATE_Z(.*)"))) {
1017 bc->dispBcPtr =
1018 boost::make_shared<DisplacementCubitBcDataWithRotation>();
1019 bc->dispBcPtr->data.flag4 = 0;
1020 bc->dispBcPtr->data.flag5 = 0;
1021 bc->dispBcPtr->data.flag6 = 1;
1022 // for the ROTATE_Z block the angles can be specified with either one or
1023 // three attributes, e.g. 1, coords or 0,0,1,coords
1024 if (bc->bcAttributes.empty()) {
1025 bc->dispBcPtr->data.value6 = 0;
1026 MOFEM_LOG("BcMngWorld", Sev::warning)
1027 << "Expected one attribute on block (angle (1 or 3), center "
1028 "coords(3) but have "
1029 << bc->bcAttributes.size();
1030 } else if (bc->bcAttributes.size() == 1 ||
1031 bc->bcAttributes.size() == 4) {
1032 bc->dispBcPtr->data.value6 = bc->bcAttributes[0];
1033 } else if (bc->bcAttributes.size() == 3 ||
1034 bc->bcAttributes.size() == 6) {
1035 bc->dispBcPtr->data.value6 = bc->bcAttributes[2];
1036 }
1037 MOFEM_LOG("BcMngWorld", Sev::inform) << "Add Z " << bc_id;
1038 MOFEM_LOG("BcMngWorld", Sev::inform) << *(bc->dispBcPtr);
1039 if (bc->bcAttributes.size() == 4 || bc->bcAttributes.size() == 6) {
1040 if (auto ext_disp_bc =
1042 bc->dispBcPtr.get())) {
1043 auto &o = ext_disp_bc->rotOffset;
1044 for (int a = 0; a != 3; ++a)
1045 o[a] = bc->bcAttributes[bc->bcAttributes.size() - 3 + a];
1046 MOFEM_LOG("BcMngWorld", Sev::inform)
1047 << "Add Rotate Z Center: " << o[0] << " " << o[1] << " "
1048 << o[2];
1049 }
1050 }
1051 } else if (std::regex_match(block_name, std::regex("ROTATE_ALL(.*)"))) {
1052 bc->dispBcPtr =
1053 boost::make_shared<DisplacementCubitBcDataWithRotation>();
1054 bc->dispBcPtr->data.flag4 = 1;
1055 bc->dispBcPtr->data.flag5 = 1;
1056 bc->dispBcPtr->data.flag6 = 1;
1057 if (bc->bcAttributes.size() >= 1) {
1058 bc->dispBcPtr->data.value4 = bc->bcAttributes[0];
1059 }
1060 if (bc->bcAttributes.size() >= 2) {
1061 bc->dispBcPtr->data.value5 = bc->bcAttributes[1];
1062 }
1063 if (bc->bcAttributes.size() >= 3) {
1064 bc->dispBcPtr->data.value6 = bc->bcAttributes[2];
1065 }
1066 MOFEM_LOG("BcMngWorld", Sev::inform) << "Add ALL " << bc_id;
1067 MOFEM_LOG("BcMngWorld", Sev::inform) << *(bc->dispBcPtr);
1068 if (bc->bcAttributes.size() > 3) {
1069 if (auto ext_disp_bc =
1071 bc->dispBcPtr.get())) {
1072 auto &o = ext_disp_bc->rotOffset;
1073 for (int a = 0; a != 3; ++a)
1074 o[a] = bc->bcAttributes[3 + a];
1075 MOFEM_LOG("BcMngWorld", Sev::inform)
1076 << "Add Rotate ALL Center: " << o[0] << " " << o[1] << " "
1077 << o[2];
1078 }
1079 }
1080 }
1081 }
1082 }
1083
1085}
1086
1087template <>
1088MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<BcScalarMeshsetType<BLOCKSET>>(
1089 const std::string problem_name, const std::string block_name,
1090 const std::string field_name, bool get_low_dim_ents) {
1092
1093 CHKERR pushMarkDOFsOnEntities(problem_name, block_name, field_name, 0,
1094 MAX_DOFS_ON_ENTITY, get_low_dim_ents);
1095
1096 auto regex_str =
1097 (boost::format("%s_%s_%s(.*)") % problem_name % field_name % block_name)
1098 .str();
1099
1100 for (auto &m : bcMapByBlockName) {
1101
1102 auto &bc_id = m.first;
1103
1104 if (std::regex_match(bc_id, std::regex(regex_str))) {
1105
1106 auto &bc = m.second;
1107 bc->tempBcPtr = boost::make_shared<TemperatureCubitBcData>();
1108 bc->tempBcPtr->data.flag1 = 1;
1109 if (bc->bcAttributes.empty()) {
1110 bc->tempBcPtr->data.value1 = 0;
1111 MOFEM_LOG("BcMngWorld", Sev::warning)
1112 << "Expected one attribute on block but have "
1113 << bc->bcAttributes.size();
1114 } else if (bc->bcAttributes.size() >= 1) {
1115 bc->tempBcPtr->data.value1 = bc->bcAttributes[0];
1116 }
1117 }
1118 }
1119
1121}
1122
1123template <>
1124MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<DisplacementCubitBcData>(
1125 const std::string problem_name, const std::string field_name,
1126 bool get_low_dim_ents, bool block_name_field_prefix) {
1128 // that marks DOFs and create data when are set by cubit nodesets.
1129 CHKERR pushMarkDOFsOnEntities<BcMeshsetType<DISPLACEMENTSET>>(
1130 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1131 // that marks DOFs and create data when are set by blocsket.
1132 CHKERR pushMarkDOFsOnEntities<BcDisplacementMeshsetType<BLOCKSET>>(
1133 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1134 // get normal displacements boundary conditions.
1135 CHKERR pushMarkDOFsOnEntities<BcNormalDisplacementMeshsetType<BLOCKSET>>(
1136 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1137 // get analytical displacements boundary conditions.
1138 CHKERR pushMarkDOFsOnEntities<BcAnalyticalDisplacementMeshsetType<BLOCKSET>>(
1139 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1141}
1142
1143template <>
1144MoFEMErrorCode BcManager::removeBlockDOFsOnEntities<DisplacementCubitBcData>(
1145 const std::string problem_name, const std::string field_name,
1146 bool get_low_dim_ents, bool block_name_field_prefix,
1147 bool is_distributed_mesh) {
1149 // that remove DOFs when are set by cubit nodesets.
1150 CHKERR removeBlockDOFsOnEntities<BcMeshsetType<DISPLACEMENTSET>>(
1151 problem_name, field_name, get_low_dim_ents, block_name_field_prefix,
1152 is_distributed_mesh);
1153 // that remove DOFs when are by blocksets
1154 CHKERR removeBlockDOFsOnEntities<BcDisplacementMeshsetType<BLOCKSET>>(
1155 problem_name, field_name, get_low_dim_ents, block_name_field_prefix,
1156 is_distributed_mesh);
1157 // add more ways to remove bcs when appropiate
1159}
1160
1161template <>
1162MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<TemperatureCubitBcData>(
1163 const std::string problem_name, const std::string field_name,
1164 bool get_low_dim_ents, bool block_name_field_prefix) {
1166 CHKERR pushMarkDOFsOnEntities<BcMeshsetType<TEMPERATURESET>>(
1167 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1168
1169 auto get_block_name = [&]() {
1170 if (block_name_field_prefix)
1171 return (boost::format("%s_FIX_SCALAR") % field_name).str();
1172 else
1173 return field_name;
1174 };
1175
1176 CHKERR pushMarkDOFsOnEntities<BcScalarMeshsetType<BLOCKSET>>(
1177 problem_name, get_block_name(), field_name, get_low_dim_ents);
1179}
1180
1181template <>
1182MoFEMErrorCode BcManager::removeBlockDOFsOnEntities<TemperatureCubitBcData>(
1183 const std::string problem_name, const std::string field_name,
1184 bool get_low_dim_ents, bool block_name_field_prefix,
1185 bool is_distributed_mesh) {
1187 CHKERR removeBlockDOFsOnEntities<BcMeshsetType<TEMPERATURESET>>(
1188 problem_name, field_name, get_low_dim_ents, block_name_field_prefix,
1189 is_distributed_mesh);
1190
1191 auto get_block_name = [&]() {
1192 if (block_name_field_prefix)
1193 return (boost::format("%s_FIX_SCALAR") % field_name).str();
1194 else
1195 return field_name;
1196 };
1197
1198 CHKERR removeBlockDOFsOnEntities<BcScalarMeshsetType<BLOCKSET>>(
1199 problem_name, get_block_name(), field_name, get_low_dim_ents,
1200 is_distributed_mesh);
1202}
1203
1204template <>
1205MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<HeatFluxCubitBcData>(
1206 const std::string problem_name, const std::string field_name,
1207 bool get_low_dim_ents, bool block_name_field_prefix) {
1209 CHKERR pushMarkDOFsOnEntities<BcMeshsetType<HEATFLUXSET>>(
1210 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1212}
1213
1214template <>
1215MoFEMErrorCode BcManager::removeBlockDOFsOnEntities<HeatFluxCubitBcData>(
1216 const std::string problem_name, const std::string field_name,
1217 bool get_low_dim_ents, bool block_name_field_prefix,
1218 bool is_distributed_mesh) {
1220 CHKERR removeBlockDOFsOnEntities<BcMeshsetType<HEATFLUXSET>>(
1221 problem_name, field_name, get_low_dim_ents, block_name_field_prefix,
1222 is_distributed_mesh);
1224}
1225
1226std::pair<std::string, std::string>
1227BcManager::extractStringFromBlockId(const std::string block_id,
1228 const std::string prb_name) {
1229
1230 // Assumes that field name is consist with letters and numbers.
1231 // No special characters.
1232 auto field_rgx_str =
1233 (boost::format("%s_([a-zA-Z0-9]*)_(.*)") % prb_name).str();
1234 std::regex field_rgx(field_rgx_str);
1235 std::smatch match_field_name;
1236 std::string field_name;
1237 std::string block_name;
1238
1239 if (std::regex_search(block_id, match_field_name, field_rgx)) {
1240 field_name = match_field_name[1];
1241 block_name = match_field_name[2];
1242 } else {
1244 "Field name and block name can not be resolved");
1245 }
1246
1247 return std::make_pair(field_name, block_name);
1248}
1249
1250template <>
1251MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<BcMeshsetType<FORCESET>>(
1252 const std::string problem_name, const std::string field_name,
1253 bool get_low_dim_ents, bool block_name_field_prefix) {
1254 Interface &m_field = cOre;
1255 auto prb_mng = m_field.getInterface<ProblemsManager>();
1257
1258 if (problem_name.empty())
1259 MOFEM_LOG("BcMngWorld", Sev::warning) << "Argument problem_name is empty";
1260
1261 if (block_name_field_prefix)
1262 MOFEM_LOG("BcMngWorld", Sev::warning)
1263 << "Argument block_name_field_prefix=true has no effect";
1264
1265 auto fix_force = [&]() {
1267
1268 auto iterate_meshsets = [&](auto &&meshset_vec_ptr) {
1270 for (auto m : meshset_vec_ptr) {
1271 auto bc = boost::make_shared<BCs>();
1272 CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
1273 bc->bcEnts, true);
1274 bc->forceBcPtr = boost::make_shared<ForceCubitBcData>();
1275 CHKERR m->getBcDataStructure(*(bc->forceBcPtr));
1276
1277 MOFEM_LOG("BcMngWorld", Sev::verbose)
1278 << "Found block FORCESET id = " << m->getMeshsetId();
1279 MOFEM_LOG("BcMngWorld", Sev::verbose) << *bc->forceBcPtr;
1280
1281 MOFEM_LOG("BcMngSync", Sev::noisy)
1282 << "Found block FORCESET id = " << m->getMeshsetId()
1283 << " nb. of entities " << bc->bcEnts.size()
1284 << " highest dim of entities "
1285 << BcManagerImplTools::get_dim(bc->bcEnts);
1286 MOFEM_LOG("BcMngSync", Sev::noisy) << *bc->forceBcPtr;
1287 MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
1288
1289 if (problem_name.size()) {
1290
1291 if (bc->forceBcPtr->data.value2 > 0)
1292 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 0, 0,
1294 bc->bcMarkers);
1295 if (bc->forceBcPtr->data.value3 > 0)
1296 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 1, 1,
1298 bc->bcMarkers);
1299 if (bc->forceBcPtr->data.value4 > 0)
1300 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 2, 2,
1302 bc->bcMarkers);
1303
1304 if (bc->forceBcPtr->data.value5 > 0) {
1305
1306 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 1, 1,
1308 bc->bcMarkers);
1309 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 2, 2,
1311 bc->bcMarkers);
1312 }
1313 if (bc->forceBcPtr->data.value5) {
1314
1315 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 0, 0,
1317 bc->bcMarkers);
1318 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 2, 2,
1320 bc->bcMarkers);
1321 }
1322 if (bc->forceBcPtr->data.value6) {
1323
1324 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 0, 0,
1326 bc->bcMarkers);
1327 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 1, 1,
1329 bc->bcMarkers);
1330 }
1331 }
1332
1333 if (get_low_dim_ents) {
1334 auto low_dim_ents =
1335 BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
1336 bc->bcEnts.swap(low_dim_ents);
1337 }
1338
1339 CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
1340 bc->bcEnts);
1341 if (problem_name.size())
1342 CHKERR prb_mng->markDofs(problem_name, ROW, ProblemsManager::AND,
1343 bc->bcEnts, bc->bcMarkers);
1344
1345 const std::string bc_id =
1346 problem_name + "_" + field_name + "_FORCESET" +
1347 boost::lexical_cast<std::string>(m->getMeshsetId());
1348 bcMapByBlockName[bc_id] = bc;
1349 }
1351 };
1352
1353 CHKERR iterate_meshsets(
1354
1356 FORCESET)
1357
1358 );
1359
1361 };
1362
1363 CHKERR fix_force();
1364
1366}
1367
1368template <>
1369MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<BcForceMeshsetType<BLOCKSET>>(
1370 const std::string problem_name, const std::string field_name,
1371 bool get_low_dim_ents, bool block_name_field_prefix) {
1372 Interface &m_field = cOre;
1373 auto prb_mng = m_field.getInterface<ProblemsManager>();
1375
1376 if (problem_name.size() == 0)
1377 MOFEM_LOG("BcMngWorld", Sev::warning) << "Argument problem_name is empty";
1378
1379 auto get_force_block = [&](auto block_name) {
1381
1382 for (auto m :
1383 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
1384
1385 (boost::format("%s(.*)") % block_name).str()
1386
1387 ))
1388
1389 ) {
1390
1391 const auto block_name = m->getName();
1392
1393 MOFEM_LOG("BcMngWorld", Sev::inform)
1394 << "Found force block " << block_name;
1395
1396 auto bc = boost::make_shared<BCs>();
1397 CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
1398 bc->bcEnts, true);
1399
1400 CHKERR m->getAttributes(bc->bcAttributes);
1401 if (bc->bcAttributes.size() < 3) {
1402 SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
1403 "At least three block attributes for force block are expected");
1404 }
1405
1406 bc->forceBcPtr = boost::make_shared<ForceCubitBcData>();
1407 // For details look at ForceCubitBcData in
1408 // mofem/src/multi_indices/BCData.hpp
1409 bc->forceBcPtr->data.value1 = 1;
1410 bc->forceBcPtr->data.value3 = bc->bcAttributes[0];
1411 bc->forceBcPtr->data.value4 = bc->bcAttributes[1];
1412 bc->forceBcPtr->data.value5 = bc->bcAttributes[2];
1413
1414 MOFEM_LOG("BcMngWorld", Sev::inform) << *bc->forceBcPtr;
1415 MOFEM_LOG("BcMngSync", Sev::noisy)
1416 << "Found block FORCESET id = " << m->getMeshsetId()
1417 << " nb. of entities " << bc->bcEnts.size()
1418 << " highest dim of entities "
1419 << BcManagerImplTools::get_dim(bc->bcEnts);
1420 MOFEM_LOG("BcMngSync", Sev::noisy) << *bc->forceBcPtr;
1421 MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
1422
1423 if (problem_name.size()) {
1424
1425 if (bc->forceBcPtr->data.value2 > 0)
1426 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 0, 0,
1428 bc->bcMarkers);
1429 if (bc->forceBcPtr->data.value3 > 0)
1430 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 1, 1,
1432 bc->bcMarkers);
1433 if (bc->forceBcPtr->data.value4 > 0)
1434 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 2, 2,
1436 bc->bcMarkers);
1437 }
1438
1439 if (get_low_dim_ents) {
1440 auto low_dim_ents =
1441 BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
1442 bc->bcEnts.swap(low_dim_ents);
1443 }
1444
1445 CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
1446 bc->bcEnts);
1447 if (problem_name.size())
1448 CHKERR prb_mng->markDofs(problem_name, ROW, ProblemsManager::AND,
1449 bc->bcEnts, bc->bcMarkers);
1450
1451 const std::string bc_id =
1452 problem_name + "_" + field_name + "_" + block_name;
1453 bcMapByBlockName[bc_id] = bc;
1454 }
1456 };
1457
1458 CHKERR get_force_block("FORCE");
1459
1461}
1462
1463template <>
1464MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<ForceCubitBcData>(
1465 const std::string problem_name, const std::string field_name,
1466 bool get_low_dim_ents, bool block_name_field_prefix) {
1468
1469 CHKERR pushMarkDOFsOnEntities<BcMeshsetType<FORCESET>>(
1470 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1471
1472 CHKERR pushMarkDOFsOnEntities<BcForceMeshsetType<BLOCKSET>>(
1473 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1474
1475 CHKERR pushMarkDOFsOnEntities<BcMeshsetType<PRESSURESET>>(
1476 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1477
1478 CHKERR pushMarkDOFsOnEntities<BcPressureMeshsetType<BLOCKSET>>(
1479 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1480
1481 CHKERR pushMarkDOFsOnEntities<BcAnalyticalTractionMeshsetType<BLOCKSET>>(
1482 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1483
1485}
1486
1487template <>
1488MoFEMErrorCode BcManager::removeBlockDOFsOnEntities<BcMeshsetType<FORCESET>>(
1489 const std::string problem_name, const std::string field_name,
1490 bool get_low_dim_ents, bool block_name_field_prefix,
1491 bool is_distributed_mesh) {
1492 Interface &m_field = cOre;
1493 auto prb_mng = m_field.getInterface<ProblemsManager>();
1495
1496 CHKERR pushMarkDOFsOnEntities<BcMeshsetType<FORCESET>>(
1497 problem_name, field_name, get_low_dim_ents);
1498
1499 std::array<Range, 3> ents_to_remove;
1500
1501 for (auto m :
1502
1503 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(NODESET |
1504 FORCESET)) {
1505
1506 const auto block_name = m->getName();
1507 std::string bc_id = problem_name + "_" + field_name + "_" + block_name;
1508
1509 auto str = boost::format("%s_%s_%s(.*)")
1510
1511 % problem_name % field_name % block_name;
1512
1513 if (std::regex_match(bc_id, std::regex(str.str()))) {
1514
1515 auto bc = bcMapByBlockName.at(bc_id);
1516
1517 if (auto force_bc = bc->forceBcPtr) {
1518 if (force_bc->data.value3 > 0) {
1519 ents_to_remove[0].merge(bc->bcEnts);
1520 }
1521 if (force_bc->data.value4 > 0) {
1522 ents_to_remove[1].merge(bc->bcEnts);
1523 }
1524 if (force_bc->data.value5 > 0) {
1525 ents_to_remove[2].merge(bc->bcEnts);
1526 }
1527 } else {
1528 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1529 "BC type not implemented");
1530 }
1531 }
1532 }
1533
1534 auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
1535 const int hi) {
1536 if (is_distributed_mesh)
1537 return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
1538 hi);
1539 else
1540 return prb_mng->removeDofsOnEntitiesNotDistributed(
1541 problem_name, field_name, ents, lo, hi);
1542 };
1543
1544 CHKERR remove_dofs_on_ents(ents_to_remove[0], 0, 0);
1545 CHKERR remove_dofs_on_ents(ents_to_remove[1], 1, 1);
1546 CHKERR remove_dofs_on_ents(ents_to_remove[2], 2, 2);
1547
1549}
1550
1551template <>
1553BcManager::removeBlockDOFsOnEntities<BcForceMeshsetType<BLOCKSET>>(
1554 const std::string problem_name, const std::string field_name,
1555 bool get_low_dim_ents, bool block_name_field_prefix,
1556 bool is_distributed_mesh) {
1557 Interface &m_field = cOre;
1558 auto prb_mng = m_field.getInterface<ProblemsManager>();
1560
1561 CHKERR pushMarkDOFsOnEntities<BcForceMeshsetType<BLOCKSET>>(
1562 problem_name, field_name, get_low_dim_ents);
1563
1564 std::array<Range, 3> ents_to_remove;
1565
1566 for (auto m :
1567
1568 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
1569 BLOCKSET | UNKNOWNNAME)) {
1570
1571 const auto block_name = m->getName();
1572 std::string bc_id = problem_name + "_" + field_name + "_" + block_name;
1573
1574 auto str = boost::format("%s_%s_%s(.*)")
1575
1576 % problem_name % field_name % block_name;
1577
1578 if (std::regex_match(bc_id, std::regex(str.str()))) {
1579
1580 auto bc = bcMapByBlockName.at(bc_id);
1581
1582 if (auto force_bc = bc->forceBcPtr) {
1583 if (force_bc->data.value3 > 0) {
1584 ents_to_remove[0].merge(bc->bcEnts);
1585 }
1586 if (force_bc->data.value4 > 0) {
1587 ents_to_remove[1].merge(bc->bcEnts);
1588 }
1589 if (force_bc->data.value5 > 0) {
1590 ents_to_remove[2].merge(bc->bcEnts);
1591 }
1592 } else {
1593 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1594 "BC type not implemented");
1595 }
1596 }
1597 }
1598
1599 auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
1600 const int hi) {
1601 if (is_distributed_mesh)
1602 return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
1603 hi);
1604 else
1605 return prb_mng->removeDofsOnEntitiesNotDistributed(
1606 problem_name, field_name, ents, lo, hi);
1607 };
1608
1609 CHKERR remove_dofs_on_ents(ents_to_remove[0], 0, 0);
1610 CHKERR remove_dofs_on_ents(ents_to_remove[1], 1, 1);
1611 CHKERR remove_dofs_on_ents(ents_to_remove[2], 2, 2);
1612
1614}
1615
1616template <>
1617MoFEMErrorCode BcManager::removeBlockDOFsOnEntities<ForceCubitBcData>(
1618 const std::string problem_name, const std::string field_name,
1619 bool get_low_dim_ents, bool block_name_field_prefix,
1620 bool is_distributed_mesh) {
1622
1623 CHKERR removeBlockDOFsOnEntities<BcMeshsetType<FORCESET>>(
1624 problem_name, field_name, get_low_dim_ents, block_name_field_prefix,
1625 is_distributed_mesh);
1626
1627 CHKERR removeBlockDOFsOnEntities<BcForceMeshsetType<BLOCKSET>>(
1628 problem_name, field_name, get_low_dim_ents, block_name_field_prefix,
1629 is_distributed_mesh);
1630
1632};
1633
1635
1636 const std::string problem_name, const std::string block_name,
1637 const std::string field_name, int bridge_dim, int lo, int hi
1638
1639) {
1640 Interface &m_field = cOre;
1642
1643 if (problem_name.empty())
1645
1646 auto iterate_meshsets = [&](auto &&meshset_vec_ptr) {
1647 auto prb_mng = m_field.getInterface<ProblemsManager>();
1649 for (auto m : meshset_vec_ptr) {
1650 auto bc = boost::make_shared<BCs>();
1651 CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
1652 bc->bcEnts, true);
1653 CHKERR m->getAttributes(bc->bcAttributes);
1654
1655 bc->dofsViewPtr = boost::make_shared<BCs::DofsView>();
1656
1657 CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
1658 bc->bcEnts);
1659 CHKERR prb_mng->getSideDofsOnBrokenSpaceEntities(
1660 *(bc->dofsViewPtr), problem_name, ROW, field_name, bc->bcEnts,
1661 bridge_dim, lo, hi);
1662 CHKERR prb_mng->markDofs(problem_name, ROW, *(bc->dofsViewPtr),
1663 ProblemsManager::OR, bc->bcMarkers);
1664
1665 MOFEM_LOG("BcMngWorld", Sev::inform)
1666 << "Found block " << m->getName() << " number of attributes "
1667 << bc->bcAttributes.size() << " number of entities "
1668 << bc->bcEnts.size();
1669
1670 const std::string bc_id =
1671 problem_name + "_" + field_name + "_" + m->getName();
1672 bcMapByBlockName[bc_id] = bc;
1673 }
1675 };
1676
1677 CHKERR iterate_meshsets(
1678
1679 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
1680
1681 (boost::format("%s(.*)") % block_name).str()
1682
1683 ))
1684
1685 );
1686
1688}
1689
1690MoFEMErrorCode BcManager::removeSideDOFs(const std::string problem_name,
1691 const std::string block_name,
1692 const std::string field_name,
1693 int bridge_dim, int lo, int hi,
1694 bool is_distributed_mesh) {
1695 Interface &m_field = cOre;
1697
1698 CHKERR pushMarkSideDofs(problem_name, block_name, field_name, bridge_dim, lo,
1699 hi);
1700
1701 auto iterate_meshsets = [&](auto &&meshset_vec_ptr) {
1703 auto prb_mng = m_field.getInterface<ProblemsManager>();
1704 for (auto m : meshset_vec_ptr) {
1705 const std::string bc_id =
1706 problem_name + "_" + field_name + "_" + m->getName();
1707 auto &bc = bcMapByBlockName.at(bc_id);
1708 CHKERR prb_mng->removeDofs(problem_name, ROW, *(bc->dofsViewPtr), lo, hi);
1709 CHKERR prb_mng->removeDofs(problem_name, COL, *(bc->dofsViewPtr), lo, hi);
1710 }
1712 };
1713
1714 if (is_distributed_mesh) {
1715
1716 CHKERR iterate_meshsets(
1717
1718 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
1719
1720 (boost::format("%s(.*)") % block_name).str()
1721
1722 ))
1723
1724 );
1725 } else {
1726 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "Not implemented");
1727 }
1728
1730}
1731
1732template <>
1734BcManager::pushMarkDOFsOnEntities<BcNormalDisplacementMeshsetType<BLOCKSET>>(
1735 const std::string problem_name, const std::string field_name,
1736 bool get_low_dim_ents, bool block_name_field_prefix) {
1737 Interface &m_field = cOre;
1739
1740 if (problem_name.size() == 0)
1741 MOFEM_LOG("BcMngWorld", Sev::warning) << "Argument problem_name is empty";
1742
1743 auto get_normal_disp_block = [&](auto block_name) {
1745
1746 for (auto m :
1747 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
1748
1749 (boost::format("%s(.*)") % block_name).str()
1750
1751 ))
1752
1753 ) {
1754
1755 std::string bc_id =
1756 problem_name + "_" + field_name + "_" + m->getName();
1757 std::string regex_str;
1758 if (block_name_field_prefix) {
1759 regex_str = (boost::format("%s_%s_%s_%s(.*)") % problem_name %
1760 field_name % field_name % block_name)
1761 .str();
1762 } else {
1763 regex_str = (boost::format("%s_%s_%s(.*)") % problem_name % field_name %
1764 block_name)
1765 .str();
1766 }
1767
1768 if (std::regex_match(bc_id, std::regex(regex_str))) {
1769
1770 MOFEM_LOG("BcMngWorld", Sev::inform)
1771 << "Normal displacement block " << m->getName();
1772
1773 auto bc = boost::make_shared<BCs>();
1774 CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
1775 bc->bcEnts, true);
1776
1777 CHKERR m->getAttributes(bc->bcAttributes);
1778 if (bc->bcAttributes.size() < 1) {
1779 SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
1780 "At least one block attribute expected");
1781 }
1782
1783 // normal is applied in the current configuration
1784 auto current_normal =
1785 bc->bcAttributes.size() <= 1 ? false : bc->bcAttributes[1];
1786
1787 MOFEM_LOG("BcMngSync", Sev::noisy)
1788 << "Found block NATURAL_DISPLACEMENT id = " << m->getMeshsetId()
1789 << " nb. of entities " << bc->bcEnts.size()
1790 << " highest dim of entities "
1791 << BcManagerImplTools::get_dim(bc->bcEnts) << " value "
1792 << bc->bcAttributes[0] << " current normal " << current_normal;
1793 MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
1794
1795 if (get_low_dim_ents) {
1796 auto low_dim_ents =
1797 BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
1798 bc->bcEnts.swap(low_dim_ents);
1799 }
1800
1801 CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
1802 bc->bcEnts);
1803 bcMapByBlockName[bc_id] = bc;
1804 }
1805 }
1807 };
1808
1809 CHKERR get_normal_disp_block("NORMAL_DISPLACEMENT");
1810
1812}
1813
1814template <>
1817 const std::string problem_name, const std::string field_name,
1818 bool get_low_dim_ents, bool block_name_field_prefix) {
1819 Interface &m_field = cOre;
1821
1822 if (problem_name.size() == 0)
1823 MOFEM_LOG("BcMngWorld", Sev::warning) << "Argument problem_name is empty";
1824
1825 auto get_analytical_disp_block = [&](auto block_name) {
1827
1828 for (auto m :
1829 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
1830
1831 (boost::format("%s(.*)") % block_name).str()
1832
1833 ))
1834
1835 ) {
1836
1837 std::string bc_id = problem_name + "_" + field_name + "_" + m->getName();
1838 std::string regex_str;
1839 if (block_name_field_prefix) {
1840 regex_str = (boost::format("%s_%s_%s_%s(.*)") % problem_name %
1841 field_name % field_name % block_name)
1842 .str();
1843 } else {
1844 regex_str = (boost::format("%s_%s_%s(.*)") % problem_name % field_name %
1845 block_name)
1846 .str();
1847 }
1848
1849 if (std::regex_match(bc_id, std::regex(regex_str))) {
1850
1851 MOFEM_LOG("BcMngWorld", Sev::inform)
1852 << "Found analytical displacement block " << m->getName();
1853
1854 auto bc = boost::make_shared<BCs>();
1855 CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
1856 bc->bcEnts, true);
1857
1858 CHKERR m->getAttributes(bc->bcAttributes);
1859 if (bc->bcAttributes.size() < 3) {
1860 SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
1861 "At least three block attribute expected");
1862 }
1863
1864 MOFEM_LOG("BcMngSync", Sev::noisy)
1865 << "Found block ANALYTICAL_DISPLACEMENT id = " << m->getMeshsetId()
1866 << " nb. of entities " << bc->bcEnts.size()
1867 << " highest dim of entities "
1868 << BcManagerImplTools::get_dim(bc->bcEnts) << " value "
1869 << bc->bcAttributes[0] << bc->bcAttributes[1] << bc->bcAttributes[2];
1870 MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
1871
1872 if (get_low_dim_ents) {
1873 auto low_dim_ents =
1874 BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
1875 bc->bcEnts.swap(low_dim_ents);
1876 }
1877
1878 CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
1879 bc->bcEnts);
1880 bcMapByBlockName[bc_id] = bc;
1881 }
1882 }
1884 };
1885
1886 CHKERR get_analytical_disp_block("ANALYTICAL_DISPLACEMENT");
1887
1889}
1890
1891template <>
1892MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<BcMeshsetType<PRESSURESET>>(
1893 const std::string problem_name, const std::string field_name,
1894 bool get_low_dim_ents, bool block_name_field_prefix) {
1895 Interface &m_field = cOre;
1897
1898 if (block_name_field_prefix)
1899 MOFEM_LOG("BcMngWorld", Sev::warning)
1900 << "Argument block_name_field_prefix=true has no effect";
1901
1902 auto fix_pressure = [&]() {
1904
1905 auto iterate_meshsets = [&](auto &&meshset_vec_ptr) {
1907 for (auto m : meshset_vec_ptr) {
1908 auto bc = boost::make_shared<BCs>();
1909 CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
1910 bc->bcEnts, true);
1911 bc->pressureBcPtr = boost::make_shared<PressureCubitBcData>();
1912 CHKERR m->getBcDataStructure(*(bc->pressureBcPtr));
1913
1914 MOFEM_LOG("BcMngWorld", Sev::verbose)
1915 << "Found block FORCESET id = " << m->getMeshsetId();
1916 MOFEM_LOG("BcMngWorld", Sev::verbose) << *bc->pressureBcPtr;
1917
1918 MOFEM_LOG("BcMngSync", Sev::noisy)
1919 << "Found block FORCESET id = " << m->getMeshsetId()
1920 << " nb. of entities " << bc->bcEnts.size()
1921 << " highest dim of entities "
1922 << BcManagerImplTools::get_dim(bc->bcEnts);
1923 MOFEM_LOG("BcMngSync", Sev::noisy) << *bc->forceBcPtr;
1924 MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
1925
1926 if (get_low_dim_ents) {
1927 auto low_dim_ents =
1928 BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
1929 bc->bcEnts.swap(low_dim_ents);
1930 }
1931
1932 CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
1933 bc->bcEnts);
1934 const std::string bc_id =
1935 problem_name + "_" + field_name + "_FORCESET" +
1936 boost::lexical_cast<std::string>(m->getMeshsetId());
1937 bcMapByBlockName[bc_id] = bc;
1938 }
1940 };
1941
1942 CHKERR iterate_meshsets(
1943
1945 FORCESET)
1946
1947 );
1948
1950 };
1951
1952 CHKERR fix_pressure();
1953
1955}
1956
1957template <>
1959BcManager::pushMarkDOFsOnEntities<BcPressureMeshsetType<BLOCKSET>>(
1960 const std::string problem_name, const std::string field_name,
1961 bool get_low_dim_ents, bool block_name_field_prefix) {
1962 Interface &m_field = cOre;
1964
1965 auto get_pressure_block = [&](auto block_name) {
1967
1968 for (auto m :
1969 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
1970
1971 (boost::format("%s(.*)") % block_name).str()
1972
1973 ))
1974
1975 ) {
1976
1977 std::string bc_id = problem_name + "_" + field_name + "_" + m->getName();
1978 std::string regex_str;
1979 if (block_name_field_prefix) {
1980 regex_str = (boost::format("%s_%s_%s_%s(.*)") % problem_name %
1981 field_name % field_name % block_name)
1982 .str();
1983 } else {
1984 regex_str = (boost::format("%s_%s_%s(.*)") % problem_name % field_name %
1985 block_name)
1986 .str();
1987 }
1988
1989 if (std::regex_match(bc_id, std::regex(regex_str))) {
1990
1991 MOFEM_LOG("BcMngWorld", Sev::inform)
1992 << "Found force block " << block_name;
1993
1994 auto bc = boost::make_shared<BCs>();
1995 CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
1996 bc->bcEnts, true);
1997
1998 CHKERR m->getAttributes(bc->bcAttributes);
1999 if (bc->bcAttributes.size() < 1) {
2000 SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2001 "At least one block attribute expected");
2002 }
2003
2004 bc->pressureBcPtr = boost::make_shared<PressureCubitBcData>();
2005 bc->pressureBcPtr->data.value1 = 1;
2006
2007 MOFEM_LOG("BcMngWorld", Sev::verbose)
2008 << "Found block PRESSURE id = " << m->getMeshsetId();
2009 MOFEM_LOG("BcMngWorld", Sev::verbose) << *bc->pressureBcPtr;
2010
2011 MOFEM_LOG("BcMngSync", Sev::noisy)
2012 << "Found block PRESSURE id = " << m->getMeshsetId()
2013 << " nb. of entities " << bc->bcEnts.size()
2014 << " highest dim of entities "
2015 << BcManagerImplTools::get_dim(bc->bcEnts) << " value "
2016 << bc->bcAttributes[0];
2017 MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
2018
2019 if (get_low_dim_ents) {
2020 auto low_dim_ents =
2021 BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
2022 bc->bcEnts.swap(low_dim_ents);
2023 }
2024
2025 CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
2026 bc->bcEnts);
2027 const std::string bc_id =
2028 problem_name + "_" + field_name + "_" + block_name;
2029 bcMapByBlockName[bc_id] = bc;
2030 }
2031 }
2033 };
2034
2035 CHKERR get_pressure_block("PRESSURE");
2036
2038}
2039
2040template <>
2042BcManager::pushMarkDOFsOnEntities<BcAnalyticalTractionMeshsetType<BLOCKSET>>(
2043 const std::string problem_name, const std::string field_name,
2044 bool get_low_dim_ents, bool block_name_field_prefix) {
2045 Interface &m_field = cOre;
2047
2048 auto get_analytical_traction_block = [&](auto block_name) {
2050
2051 for (auto m :
2052 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
2053
2054 (boost::format("%s(.*)") % block_name).str()
2055
2056 ))
2057
2058 ) {
2059
2060 std::string bc_id = problem_name + "_" + field_name + "_" + m->getName();
2061 std::string regex_str;
2062 if (block_name_field_prefix) {
2063 regex_str = (boost::format("%s_%s_%s_%s(.*)") % problem_name %
2064 field_name % field_name % block_name)
2065 .str();
2066 } else {
2067 regex_str = (boost::format("%s_%s_%s(.*)") % problem_name % field_name %
2068 block_name)
2069 .str();
2070 }
2071
2072 if (std::regex_match(bc_id, std::regex(regex_str))) {
2073
2074 MOFEM_LOG("BcMngWorld", Sev::inform)
2075 << "Found analytical traction block " << m->getName();
2076
2077 auto bc = boost::make_shared<BCs>();
2078 CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
2079 bc->bcEnts, true);
2080
2081 CHKERR m->getAttributes(bc->bcAttributes);
2082 if (bc->bcAttributes.size() < 3) {
2083 SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2084 "At least one block attribute expected");
2085 }
2086
2087 MOFEM_LOG("BcMngSync", Sev::noisy)
2088 << "Found block ANALTICAL_TRACTION id = " << m->getMeshsetId()
2089 << " nb. of entities " << bc->bcEnts.size()
2090 << " highest dim of entities "
2091 << BcManagerImplTools::get_dim(bc->bcEnts) << " values "
2092 << bc->bcAttributes[0] << bc->bcAttributes[1] << bc->bcAttributes[2];
2093 MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
2094
2095 if (get_low_dim_ents) {
2096 auto low_dim_ents =
2097 BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
2098 bc->bcEnts.swap(low_dim_ents);
2099 }
2100 CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
2101 bc->bcEnts);
2102 bcMapByBlockName[bc_id] = bc;
2103 }
2104 }
2106 };
2107 CHKERR get_analytical_traction_block("ANALYTICAL_TRACTION");
2108
2110}
2111
2112} // namespace MoFEM
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
Core & cOre
constexpr double a
@ COL
@ ROW
#define MAX_DOFS_ON_ENTITY
Maximal number of DOFs on entity.
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
@ TEMPERATURESET
@ FORCESET
@ HEATFLUXSET
@ NODESET
@ SIDESET
@ UNKNOWNNAME
@ DISPLACEMENTSET
@ 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.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
MoFEMErrorCode modifyMarkDofs(const std::string problem_name, RowColData rc, const std::string field_name, const int lo, const int hi, const enum MarkOP op, const unsigned char c, std::vector< unsigned char > &marker) const
Modify DOF markers for specific field and coefficient range.
MoFEMErrorCode removeDofs(const std::string problem_name, RowColData rc, std::vector< boost::weak_ptr< NumeredDofEntity > > &vec_dof_view, int verb=VERBOSE, const bool debug=false)
Remove DOFs from problem on broken space.
Range getMergedBlocksRange(std::vector< std::regex > bc_regex_vec)
Merge entity ranges from multiple boundary condition blocks.
MoFEMErrorCode getOptions()
Get command line options for BcManager.
Definition BcManager.cpp:65
BcMarkerPtr getMergedBlocksMarker(std::vector< std::regex > bc_regex_vec)
Merge DOF markers from multiple boundary condition blocks.
MoFEMErrorCode removeSideDOFs(const std::string problem_name, const std::string block_name, const std::string field_name, int bridge_dim, int lo, int hi, bool is_distributed_mesh=true)
Remove DOFs on side entities from problem.
SmartPetscObj< IS > getBlockIS(const std::string block_prefix, const std::string block_name, const std::string field_name, const std::string problem_name, int lo, int hi, SmartPetscObj< IS > is_expand=SmartPetscObj< IS >())
Create PETSc Index Set for boundary condition block.
MoFEMErrorCode removeBlockDOFsOnEntities(const std::string problem_name, const std::string block_name, const std::string field_name, int lo, int hi, bool get_low_dim_ents=true, bool is_distributed_mesh=true)
Remove DOFs from problem based on block entities.
Definition BcManager.cpp:72
MoFEMErrorCode pushMarkSideDofs(const std::string problem_name, const std::string block_name, const std::string field_name, int bridge_dim, int lo, int hi)
Mark DOFs on side entities for boundary conditions.
boost::shared_ptr< BCs > popMarkDOFsOnEntities(const std::string block_name)
Retrieve and remove boundary condition data.
MoFEMErrorCode pushMarkDOFsOnEntities(const std::string problem_name, const std::string block_name, const std::string field_name, int lo, int hi, bool get_low_dim_ents=true)
Mark DOFs on block entities for boundary conditions.
BcMapByBlockName & getBcMapByBlockName()
Get the boundary condition map.
FTensor::Index< 'i', SPACE_DIM > i
auto get_dim(const Range &ents)
Definition BcManager.cpp:10
auto get_adj_ents(moab::Interface &moab, const Range &ents)
Definition BcManager.cpp:17
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
constexpr auto field_name
FTensor::Index< 'm', 3 > m
Template specialization for analytical displacement functions.
Boundary condition manager for finite element problem setup.
boost::shared_ptr< std::vector< char unsigned > > BcMarkerPtr
Shared pointer to marker vector.
static std::pair< std::string, std::string > extractStringFromBlockId(const std::string block_id, const std::string prb_name)
Extract block name and block name from block id.
MoFEM::Core & cOre
BcMapByBlockName bcMapByBlockName
BcManager(const MoFEM::Core &core)
Constructor for BcManager.
Definition BcManager.cpp:41
MoFEMErrorCode query_interface(boost::typeindex::type_index type_index, UnknownInterface **iface) const
Query interface for BcManager.
Definition BcManager.cpp:34
Managing BitRefLevels.
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =0
Core (interface) class.
Definition Core.hpp:83
Deprecated interface functions.
A specialized version of DisplacementCubitBcData that includes an additional rotation offset.
Section manager is used to create indexes and sections.
Definition ISManager.hpp:23
static boost::shared_ptr< SinkType > createSink(boost::shared_ptr< std::ostream > stream_ptr, std::string comm_filter)
Create a sink object.
static boost::shared_ptr< std::ostream > getStrmWorld()
Get the strm world object.
static boost::shared_ptr< std::ostream > getStrmSync()
Get the strm sync object.
static bool checkIfChannelExist(const std::string channel)
Check if channel exist.
static boost::shared_ptr< std::ostream > getStrmSelf()
Get the strm self object.
Interface for managing meshsets containing materials and boundary conditions.
Problem manager is used to build and partition problems.
intrusive_ptr for managing petsc objects
base class for all interface classes
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.