v0.14.0
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 ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "", "BcManager options", "none");
68 ierr = PetscOptionsEnd();
71}
72
74 const std::string problem_name, const std::string block_name,
75 const std::string field_name, int lo, int hi, bool get_low_dim_ents,
76 bool is_distributed_mesh) {
77 Interface &m_field = cOre;
78 auto prb_mng = m_field.getInterface<ProblemsManager>();
80
81 CHKERR pushMarkDOFsOnEntities(problem_name, block_name, field_name, lo, hi,
82 get_low_dim_ents);
83
84 auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
85 const int hi) {
86 if (is_distributed_mesh)
87 return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
88 hi);
89 else
90 return prb_mng->removeDofsOnEntitiesNotDistributed(
91 problem_name, field_name, ents, lo, hi);
92 };
93
94 for (auto m :
95 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
96
97 (boost::format("%s(.*)") % block_name).str()
98
99 ))
100
101 ) {
102 const std::string bc_id =
103 problem_name + "_" + field_name + "_" + m->getName();
104 CHKERR remove_dofs_on_ents(bcMapByBlockName.at(bc_id)->bcEnts, lo, hi);
105 bcMapByBlockName.at(bc_id)->bcMarkers = std::vector<unsigned char>();
106 }
107
109}
110
112 const std::string block_name,
113 const std::string field_name,
114 int lo, int hi,
115 bool get_low_dim_ents) {
116 Interface &m_field = cOre;
117 auto prb_mng = m_field.getInterface<ProblemsManager>();
119
120 // if(problem_name.size())
121 // MOFEM_LOG("BcMngWorld", Sev::warning)
122 // << "Argument problem_name has no effect";
123
124 auto fix_disp = [&]() {
126
127 auto mark_fix_dofs = [&](std::vector<unsigned char> &marked_field_dofs,
128 const auto lo, const auto hi) {
129 return prb_mng->modifyMarkDofs(problem_name, ROW, field_name, lo, hi,
131 marked_field_dofs);
132 };
133
134 auto iterate_meshsets = [&](auto &&meshset_vec_ptr) {
136 for (auto m : meshset_vec_ptr) {
137 auto bc = boost::make_shared<BCs>();
138 CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
139 bc->bcEnts, true);
140 CHKERR m->getAttributes(bc->bcAttributes);
141
142 if (problem_name.size())
143 CHKERR mark_fix_dofs(bc->bcMarkers, lo, hi);
144 MOFEM_LOG("BcMngWorld", Sev::verbose)
145 << "Found block " << m->getName() << " number of attributes "
146 << bc->bcAttributes.size();
147
148 if (get_low_dim_ents) {
149 auto low_dim_ents =
150 BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
151 bc->bcEnts.swap(low_dim_ents);
152 }
153
154 CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
155 bc->bcEnts);
156 if (problem_name.size())
157 CHKERR prb_mng->markDofs(problem_name, ROW, ProblemsManager::AND,
158 bc->bcEnts, bc->bcMarkers);
159
160 const std::string bc_id =
161 problem_name + "_" + field_name + "_" + m->getName();
162 bcMapByBlockName[bc_id] = bc;
163 }
165 };
166
167 CHKERR iterate_meshsets(
168
169 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
170
171 (boost::format("%s(.*)") % block_name).str()
172
173 ))
174
175 );
176
178 };
179
180 CHKERR fix_disp();
181
183}
184
185boost::shared_ptr<BcManager::BCs>
186BcManager::popMarkDOFsOnEntities(const std::string block_name) {
187 auto bc_it = bcMapByBlockName.find(block_name);
188 if (bc_it != bcMapByBlockName.end()) {
189 auto bc = bc_it->second;
190 bcMapByBlockName.erase(bc_it);
191 return bc;
192 }
193 return boost::shared_ptr<BCs>();
194}
195
196Range BcManager::getMergedBlocksRange(std::vector<std::regex> bc_regex_vec) {
197 Range ents;
198 if (bcMapByBlockName.size()) {
199 for (auto b : bcMapByBlockName) {
200 for (auto &reg_name : bc_regex_vec) {
201 if (std::regex_match(b.first, reg_name)) {
202 ents.merge(b.second->bcEnts);
203 }
204 }
205 }
206 }
207 return ents;
208}
209
211BcManager::getMergedBlocksMarker(std::vector<std::regex> bc_regex_vec) {
212 BcManager::BcMarkerPtr boundary_marker_ptr;
213 if (bcMapByBlockName.size()) {
214 for (auto b : bcMapByBlockName) {
215 for (auto &reg_name : bc_regex_vec) {
216 if (std::regex_match(b.first, reg_name)) {
217 if (!boundary_marker_ptr)
218 boundary_marker_ptr =
219 boost::make_shared<std::vector<char unsigned>>();
220 boundary_marker_ptr->resize(b.second->bcMarkers.size(), 0);
221 for (int i = 0; i != b.second->bcMarkers.size(); ++i) {
222 (*boundary_marker_ptr)[i] |= b.second->bcMarkers[i];
223 }
224 }
225 }
226 }
227 }
228 return boundary_marker_ptr;
229}
230
232 const std::vector<BcManager::BcMarkerPtr> &boundary_markers_ptr_vec) {
233 auto boundary_marker_ptr = boost::make_shared<std::vector<char unsigned>>();
234 for (auto &bcm : boundary_markers_ptr_vec) {
235 boundary_marker_ptr->resize(bcm->size(), 0);
236 for (int i = 0; i != bcm->size(); ++i)
237 (*boundary_marker_ptr)[i] |= (*bcm)[i];
238 }
239 return boundary_marker_ptr;
240}
241
242SmartPetscObj<IS> BcManager::getBlockIS(const std::string block_prefix,
243 const std::string block_name,
244 const std::string field_name,
245 const std::string problem_name, int lo,
246 int hi, SmartPetscObj<IS> is_expand) {
247 Interface &m_field = cOre;
248
249 const std::string bc_id =
250 block_prefix + "_" + field_name + "_" + block_name + "(.*)";
251
252 Range bc_ents;
253 for (auto bc : getBcMapByBlockName()) {
254 if (std::regex_match(bc.first, std::regex(bc_id))) {
255 bc_ents.merge(*(bc.second->getBcEntsPtr()));
256 MOFEM_LOG("BcMngWorld", Sev::verbose)
257 << "Get entities from block and add to IS. Block name " << bc.first;
258 }
259 }
260
261 SmartPetscObj<IS> is_bc;
262 auto get_is = [&]() {
264 CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(bc_ents);
265 CHKERR m_field.getInterface<ISManager>()->isCreateProblemFieldAndRank(
266 problem_name, ROW, field_name, lo, hi, is_bc, &bc_ents);
267 if (is_expand) {
268 IS is_tmp;
269 CHKERR ISExpand(is_bc, is_expand, &is_tmp);
270 is_bc = SmartPetscObj<IS>(is_tmp);
271 }
272 CHKERR ISSort(is_bc);
274 };
275
276 if (get_is())
277 CHK_THROW_MESSAGE(MOFEM_DATA_INCONSISTENCY, "IS is not created");
278
279 return is_bc;
280}
281
282SmartPetscObj<IS> BcManager::getBlockIS(const std::string problem_name,
283 const std::string block_name,
284 const std::string field_name, int lo,
285 int hi, SmartPetscObj<IS> is_expand) {
286 return getBlockIS(problem_name, block_name, field_name, problem_name, lo, hi,
287 is_expand);
288}
289
290template <>
292BcManager::removeBlockDOFsOnEntities<BcMeshsetType<DISPLACEMENTSET>>(
293 const std::string problem_name, const std::string field_name,
294 bool get_low_dim_ents, bool block_name_field_prefix,
295 bool is_distributed_mesh) {
296 Interface &m_field = cOre;
297 auto prb_mng = m_field.getInterface<ProblemsManager>();
299
300 CHKERR pushMarkDOFsOnEntities<BcMeshsetType<DISPLACEMENTSET>>(
301 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
302
303 std::array<Range, 3> ents_to_remove;
304
305 for (auto m :
306
309
310 const std::string bc_id =
311 problem_name + "_" + field_name + "_DISPLACEMENTSET" +
312 boost::lexical_cast<std::string>(m->getMeshsetId());
313
314 auto bc = bcMapByBlockName.at(bc_id);
315
316 if (bc->dispBcPtr) {
317 if (bc->dispBcPtr->data.flag1) {
318 ents_to_remove[0].merge(bc->bcEnts);
319 }
320 if (bc->dispBcPtr->data.flag2) {
321 ents_to_remove[1].merge(bc->bcEnts);
322 }
323 if (bc->dispBcPtr->data.flag3) {
324 ents_to_remove[2].merge(bc->bcEnts);
325 }
326 if (bc->dispBcPtr->data.flag4) {
327 ents_to_remove[1].merge(bc->bcEnts);
328 ents_to_remove[2].merge(bc->bcEnts);
329 }
330 if (bc->dispBcPtr->data.flag5) {
331 ents_to_remove[0].merge(bc->bcEnts);
332 ents_to_remove[2].merge(bc->bcEnts);
333 }
334 if (bc->dispBcPtr->data.flag6) {
335 ents_to_remove[0].merge(bc->bcEnts);
336 ents_to_remove[1].merge(bc->bcEnts);
337 }
338 }
339 bc->bcMarkers = std::vector<unsigned char>();
340 }
341
342 auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
343 const int hi) {
344 if (is_distributed_mesh)
345 return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
346 hi);
347 else
348 return prb_mng->removeDofsOnEntitiesNotDistributed(
349 problem_name, field_name, ents, lo, hi);
350 };
351
352 CHKERR remove_dofs_on_ents(ents_to_remove[0], 0, 0);
353 CHKERR remove_dofs_on_ents(ents_to_remove[1], 1, 1);
354 CHKERR remove_dofs_on_ents(ents_to_remove[2], 2, 2);
355
357}
358
359template <>
361BcManager::removeBlockDOFsOnEntities<BcMeshsetType<TEMPERATURESET>>(
362 const std::string problem_name, const std::string field_name,
363 bool get_low_dim_ents, bool block_name_field_prefix,
364 bool is_distributed_mesh) {
365 Interface &m_field = cOre;
366 auto prb_mng = m_field.getInterface<ProblemsManager>();
368
369 CHKERR pushMarkDOFsOnEntities<BcMeshsetType<TEMPERATURESET>>(
370 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
371
372 Range ents_to_remove;
373
374 for (auto m :
375
378
379 ) {
380 const std::string bc_id =
381 problem_name + "_" + field_name + "_TEMPERATURESET" +
382 boost::lexical_cast<std::string>(m->getMeshsetId());
383 auto bc = bcMapByBlockName.at(bc_id);
384 ents_to_remove.merge(bc->bcEnts);
385 bc->bcMarkers = std::vector<unsigned char>();
386 }
387
388 auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
389 const int hi) {
390 if (is_distributed_mesh)
391 return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
392 hi);
393 else
394 return prb_mng->removeDofsOnEntitiesNotDistributed(
395 problem_name, field_name, ents, lo, hi);
396 };
397
398 CHKERR remove_dofs_on_ents(ents_to_remove, 0, MAX_DOFS_ON_ENTITY);
399
401}
402
403template <>
404MoFEMErrorCode BcManager::removeBlockDOFsOnEntities<BcMeshsetType<HEATFLUXSET>>(
405 const std::string problem_name, const std::string field_name,
406 bool get_low_dim_ents, bool block_name_field_prefix,
407 bool is_distributed_mesh) {
408 Interface &m_field = cOre;
409 auto prb_mng = m_field.getInterface<ProblemsManager>();
411
412 CHKERR pushMarkDOFsOnEntities<BcMeshsetType<HEATFLUXSET>>(
413 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
414
415 Range ents_to_remove;
416
417 for (auto m :
418
421
422 ) {
423 const std::string bc_id =
424 problem_name + "_" + field_name + "_HEATFLUXSET" +
425 boost::lexical_cast<std::string>(m->getMeshsetId());
426 auto bc = bcMapByBlockName.at(bc_id);
427 ents_to_remove.merge(bc->bcEnts);
428 bc->bcMarkers = std::vector<unsigned char>();
429 }
430
431 auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
432 const int hi) {
433 if (is_distributed_mesh)
434 return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
435 hi);
436 else
437 return prb_mng->removeDofsOnEntitiesNotDistributed(
438 problem_name, field_name, ents, lo, hi);
439 };
440
441 CHKERR remove_dofs_on_ents(ents_to_remove, 0, MAX_DOFS_ON_ENTITY);
442
444}
445
446template <>
448BcManager::removeBlockDOFsOnEntities<BcDisplacementMeshsetType<BLOCKSET>>(
449 const std::string problem_name, const std::string field_name,
450 bool get_low_dim_ents, bool block_name_field_prefix,
451 bool is_distributed_mesh) {
452 Interface &m_field = cOre;
453 auto prb_mng = m_field.getInterface<ProblemsManager>();
455
456 CHKERR pushMarkDOFsOnEntities<BcDisplacementMeshsetType<BLOCKSET>>(
457 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
458
459 std::array<Range, 3> ents_to_remove;
460
461 for (auto m :
462
465
466 const auto block_name = m->getName();
467
468 std::string bc_id = problem_name + "_" + field_name + "_" + block_name;
469 std::string regex_str;
470 if (block_name_field_prefix) {
471 regex_str = (boost::format("%s_%s_%s_((FIX_(ALL|X|Y|Z))|("
472 "DISPLACEMENT|ROTATE))(.*)") %
473 problem_name % field_name % field_name)
474 .str();
475 } else {
476 regex_str = (boost::format("%s_%s_((FIX_(ALL|X|Y|Z))|("
477 "DISPLACEMENT|ROTATE))(.*)") %
478 problem_name % field_name)
479 .str();
480 }
481
482 if (std::regex_match(bc_id, std::regex(regex_str))) {
483
484 auto bc = bcMapByBlockName.at(bc_id);
485
486 if (auto disp_bc = bc->dispBcPtr) {
487 if (disp_bc->data.flag1) {
488 ents_to_remove[0].merge(bc->bcEnts);
489 }
490 if (disp_bc->data.flag2) {
491 ents_to_remove[1].merge(bc->bcEnts);
492 }
493 if (disp_bc->data.flag3) {
494 ents_to_remove[2].merge(bc->bcEnts);
495 }
496 if (disp_bc->data.flag4) {
497 ents_to_remove[1].merge(bc->bcEnts);
498 ents_to_remove[2].merge(bc->bcEnts);
499 }
500 if (disp_bc->data.flag5) {
501 ents_to_remove[0].merge(bc->bcEnts);
502 ents_to_remove[2].merge(bc->bcEnts);
503 }
504 if (disp_bc->data.flag6) {
505 ents_to_remove[0].merge(bc->bcEnts);
506 ents_to_remove[1].merge(bc->bcEnts);
507 }
508 } else {
509 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
510 "BC type not implemented");
511 }
512 }
513 }
514
515 auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
516 const int hi) {
517 if (is_distributed_mesh)
518 return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
519 hi);
520 else
521 return prb_mng->removeDofsOnEntitiesNotDistributed(
522 problem_name, field_name, ents, lo, hi);
523 };
524
525 CHKERR remove_dofs_on_ents(ents_to_remove[0], 0, 0);
526 CHKERR remove_dofs_on_ents(ents_to_remove[1], 1, 1);
527 CHKERR remove_dofs_on_ents(ents_to_remove[2], 2, 2);
528
530}
531
532template <>
534BcManager::removeBlockDOFsOnEntities<BcScalarMeshsetType<BLOCKSET>>(
535 const std::string problem_name, const std::string block_name,
536 const std::string field_name, bool get_low_dim_ents,
537 bool is_distributed_mesh) {
538 Interface &m_field = cOre;
539 auto prb_mng = m_field.getInterface<ProblemsManager>();
541
542 CHKERR pushMarkDOFsOnEntities<BcScalarMeshsetType<BLOCKSET>>(
543 problem_name, block_name, field_name, get_low_dim_ents);
544
545 Range ents_to_remove;
546
547 for (auto m :
548
551
552 std::string bc_id = problem_name + "_" + field_name + "_" + m->getName();
553
554 auto str = boost::format("%s_%s_%s(.*)")
555
556 % problem_name % field_name % block_name;
557
558 if (std::regex_match(bc_id, std::regex(str.str()))) {
559
560 auto bc = bcMapByBlockName.at(bc_id);
561
562 if (auto temp_bc = bc->tempBcPtr) {
563 if (temp_bc->data.flag1) {
564 ents_to_remove.merge(bc->bcEnts);
565 }
566 } else {
567 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
568 "BC type not implemented");
569 }
570 }
571 }
572
573 auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
574 const int hi) {
575 if (is_distributed_mesh)
576 return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
577 hi);
578 else
579 return prb_mng->removeDofsOnEntitiesNotDistributed(
580 problem_name, field_name, ents, lo, hi);
581 };
582
583 CHKERR remove_dofs_on_ents(ents_to_remove, 0, MAX_DOFS_ON_ENTITY);
584
586}
587
588template <>
590BcManager::pushMarkDOFsOnEntities<BcMeshsetType<DISPLACEMENTSET>>(
591 const std::string problem_name, const std::string field_name,
592 bool get_low_dim_ents, bool block_name_field_prefix) {
593 Interface &m_field = cOre;
594 auto prb_mng = m_field.getInterface<ProblemsManager>();
596
597 // if(problem_name.size()==0)
598 // MOFEM_LOG("BcMngWorld", Sev::warning)
599 // << "Argument problem_name has no effect";
600
601 if (block_name_field_prefix)
602 MOFEM_LOG("BcMngWorld", Sev::warning)
603 << "Argument block_name_field_prefix=true has no effect";
604
605 auto fix_disp = [&]() {
607
608 auto iterate_meshsets = [&](auto &&meshset_vec_ptr) {
610 for (auto m : meshset_vec_ptr) {
611 auto bc = boost::make_shared<BCs>();
612 CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
613 bc->bcEnts, true);
614 bc->dispBcPtr = boost::make_shared<DisplacementCubitBcData>();
615 CHKERR m->getBcDataStructure(*(bc->dispBcPtr));
616
617 MOFEM_LOG("BcMngWorld", Sev::verbose)
618 << "Found block DISPLACEMENTSET id = " << m->getMeshsetId();
619 MOFEM_LOG("BcMngWorld", Sev::verbose) << *bc->dispBcPtr;
620
621 MOFEM_LOG("BcMngSync", Sev::noisy)
622 << "Found block DISPLACEMENTSET id = " << m->getMeshsetId()
623 << " nb. of entities " << bc->bcEnts.size()
624 << " highest dim of entities "
625 << BcManagerImplTools::get_dim(bc->bcEnts);
626 MOFEM_LOG("BcMngSync", Sev::noisy) << *bc->dispBcPtr;
627 MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
628
629 if (problem_name.size()) {
630
631 if (bc->dispBcPtr->data.flag1)
632 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 0, 0,
634 bc->bcMarkers);
635 if (bc->dispBcPtr->data.flag2)
636 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 1, 1,
638 bc->bcMarkers);
639 if (bc->dispBcPtr->data.flag3)
640 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 2, 2,
642 bc->bcMarkers);
643 if (bc->dispBcPtr->data.flag4) {
644
645 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 1, 1,
647 bc->bcMarkers);
648 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 2, 2,
650 bc->bcMarkers);
651 }
652 if (bc->dispBcPtr->data.flag5) {
653
654 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 0, 0,
656 bc->bcMarkers);
657 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 2, 2,
659 bc->bcMarkers);
660 }
661 if (bc->dispBcPtr->data.flag6) {
662
663 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 0, 0,
665 bc->bcMarkers);
666 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 1, 1,
668 bc->bcMarkers);
669 }
670 }
671
672 if (get_low_dim_ents) {
673 auto low_dim_ents =
674 BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
675 bc->bcEnts.swap(low_dim_ents);
676 }
677
678 CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
679 bc->bcEnts);
680 if (problem_name.size())
681 CHKERR prb_mng->markDofs(problem_name, ROW, ProblemsManager::AND,
682 bc->bcEnts, bc->bcMarkers);
683
684 const std::string bc_id =
685 problem_name + "_" + field_name + "_DISPLACEMENTSET" +
686 boost::lexical_cast<std::string>(m->getMeshsetId());
687 bcMapByBlockName[bc_id] = bc;
688 }
690 };
691
692 CHKERR iterate_meshsets(
693
696
697 );
698
700 };
701
702 CHKERR fix_disp();
703
705}
706
707template <>
708MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<BcMeshsetType<TEMPERATURESET>>(
709 const std::string problem_name, const std::string field_name,
710 bool get_low_dim_ents, bool block_name_field_prefix) {
711 Interface &m_field = cOre;
712 auto prb_mng = m_field.getInterface<ProblemsManager>();
714
715 if (block_name_field_prefix)
716 MOFEM_LOG("BcMngWorld", Sev::warning)
717 << "Argument block_name_field_prefix=true has no effect";
718
719 auto fix_temp = [&]() {
721
722 auto iterate_meshsets = [&](auto &&meshset_vec_ptr) {
724 for (auto m : meshset_vec_ptr) {
725 auto bc = boost::make_shared<BCs>();
726 CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
727 bc->bcEnts, true);
728 bc->tempBcPtr = boost::make_shared<TemperatureCubitBcData>();
729 CHKERR m->getBcDataStructure(*(bc->tempBcPtr));
730
731 MOFEM_LOG("BcMngWorld", Sev::verbose)
732 << "Found block TEMPERATURESET id = " << m->getMeshsetId();
733 MOFEM_LOG("BcMngWorld", Sev::verbose) << *bc->tempBcPtr;
734
735 CHKERR prb_mng->modifyMarkDofs(
736 problem_name, ROW, field_name, 0, MAX_DOFS_ON_ENTITY,
737 ProblemsManager::MarkOP::OR, 1, bc->bcMarkers);
738
739 if (get_low_dim_ents) {
740 auto low_dim_ents =
741 BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
742 bc->bcEnts.swap(low_dim_ents);
743 }
744
745 CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
746 bc->bcEnts);
747 CHKERR prb_mng->markDofs(problem_name, ROW, ProblemsManager::AND,
748 bc->bcEnts, bc->bcMarkers);
749
750 const std::string bc_id =
751 problem_name + "_" + field_name + "_TEMPERATURESET" +
752 boost::lexical_cast<std::string>(m->getMeshsetId());
753 bcMapByBlockName[bc_id] = bc;
754 }
756 };
757
758 CHKERR iterate_meshsets(
759
762
763 );
764
766 };
767
768 CHKERR fix_temp();
769
771}
772
773template <>
774MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<BcMeshsetType<HEATFLUXSET>>(
775 const std::string problem_name, const std::string field_name,
776 bool get_low_dim_ents, bool block_name_field_prefix) {
777 Interface &m_field = cOre;
778 auto prb_mng = m_field.getInterface<ProblemsManager>();
780
781 if (block_name_field_prefix)
782 MOFEM_LOG("BcMngWorld", Sev::warning)
783 << "Argument block_name_field_prefix=true has no effect";
784
785 auto fix_disp = [&]() {
787
788 auto iterate_meshsets = [&](auto &&meshset_vec_ptr) {
790 for (auto m : meshset_vec_ptr) {
791 auto bc = boost::make_shared<BCs>();
792 CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
793 bc->bcEnts, true);
794 bc->heatFluxBcPtr = boost::make_shared<HeatFluxCubitBcData>();
795 CHKERR m->getBcDataStructure(*(bc->heatFluxBcPtr));
796
797 CHKERR prb_mng->modifyMarkDofs(
798 problem_name, ROW, field_name, 0, MAX_DOFS_ON_ENTITY,
799 ProblemsManager::MarkOP::OR, 1, bc->bcMarkers);
800
801 MOFEM_LOG("BcMngWorld", Sev::verbose)
802 << "Found block HEATFLUX id = " << m->getMeshsetId();
803 MOFEM_LOG("BcMngWorld", Sev::verbose) << *bc->heatFluxBcPtr;
804
805 if (get_low_dim_ents) {
806 auto low_dim_ents =
807 BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
808 bc->bcEnts.swap(low_dim_ents);
809 }
810
811 CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
812 bc->bcEnts);
813 CHKERR prb_mng->markDofs(problem_name, ROW, ProblemsManager::AND,
814 bc->bcEnts, bc->bcMarkers);
815
816 const std::string bc_id =
817 problem_name + "_" + field_name + "_HEATFLUXSET" +
818 boost::lexical_cast<std::string>(m->getMeshsetId());
819 bcMapByBlockName[bc_id] = bc;
820 }
822 };
823
824 CHKERR iterate_meshsets(
825
828
829 );
830
832 };
833
834 CHKERR fix_disp();
835
837}
838
839template <>
841BcManager::pushMarkDOFsOnEntities<BcDisplacementMeshsetType<BLOCKSET>>(
842 const std::string problem_name, const std::string field_name,
843 bool get_low_dim_ents, bool block_name_field_prefix) {
845
846 auto mark_dofs = [&](const string block_name, const int &idx_0,
847 const int &idx_1) {
849 if (block_name_field_prefix) {
850 const string field_block = field_name + "_" + block_name;
851 CHKERR pushMarkDOFsOnEntities(problem_name, field_block, field_name,
852 idx_0, idx_1, get_low_dim_ents);
853 } else {
854
855 CHKERR pushMarkDOFsOnEntities(problem_name, block_name, field_name, idx_0,
856 idx_1, get_low_dim_ents);
857 }
859 };
860
861 // displacement
862 CHKERR mark_dofs("FIX_X", 0, 0);
863 CHKERR mark_dofs("FIX_Y", 1, 1);
864 CHKERR mark_dofs("FIX_Z", 2, 2);
865 CHKERR mark_dofs("FIX_ALL", 0, MAX_DOFS_ON_ENTITY);
866
867 // rotation
868 CHKERR mark_dofs("ROTATE_X", 1, 1);
869 CHKERR mark_dofs("ROTATE_X", 2, 2);
870 CHKERR mark_dofs("ROTATE_Y", 0, 0);
871 CHKERR mark_dofs("ROTATE_Y", 2, 2);
872 CHKERR mark_dofs("ROTATE_Z", 0, 0);
873 CHKERR mark_dofs("ROTATE_Z", 1, 1);
874 CHKERR mark_dofs("ROTATE_ALL", 0, MAX_DOFS_ON_ENTITY);
875
876 std::string regex_str;
877 if (block_name_field_prefix) {
878 regex_str = (boost::format("%s_%s_%s_(.*)") % problem_name % field_name %
880 .str();
881 } else {
882 regex_str = (boost::format("%s_%s_(.*)") % problem_name % field_name).str();
883 }
884
885 for (auto &m : bcMapByBlockName) {
886 auto &bc_id = m.first;
887 if (std::regex_match(bc_id, std::regex(regex_str))) {
888 auto &bc = m.second;
889 if (std::regex_match(bc_id, std::regex("(.*)_FIX_X(.*)"))) {
890 bc->dispBcPtr = boost::make_shared<DisplacementCubitBcData>();
891 bc->dispBcPtr->data.flag1 = 1;
892 if (bc->bcAttributes.empty()) {
893 bc->dispBcPtr->data.value1 = 0;
894 MOFEM_LOG("BcMngWorld", Sev::warning)
895 << "Expected one attribute on block but have "
896 << bc->bcAttributes.size();
897 } else if (bc->bcAttributes.size() >= 1) {
898 bc->dispBcPtr->data.value1 = bc->bcAttributes[0];
899 }
900 MOFEM_LOG("BcMngWorld", Sev::inform) << "Add X " << bc_id;
901 MOFEM_LOG("BcMngWorld", Sev::inform) << *bc->dispBcPtr;
902 } else if (std::regex_match(bc_id, std::regex("(.*)_FIX_Y(.*)"))) {
903 bc->dispBcPtr = boost::make_shared<DisplacementCubitBcData>();
904 bc->dispBcPtr->data.flag2 = 1;
905 if (bc->bcAttributes.empty()) {
906 bc->dispBcPtr->data.value2 = 0;
907 MOFEM_LOG("BcMngWorld", Sev::warning)
908 << "Expected one attribute on block but have "
909 << bc->bcAttributes.size();
910 } else if (bc->bcAttributes.size() == 1) {
911 bc->dispBcPtr->data.value2 = bc->bcAttributes[0];
912 } else if (bc->bcAttributes.size() >= 2) {
913 bc->dispBcPtr->data.value2 = bc->bcAttributes[1];
914 }
915 MOFEM_LOG("BcMngWorld", Sev::inform) << "Add Y " << bc_id;
916 MOFEM_LOG("BcMngWorld", Sev::inform) << *(bc->dispBcPtr);
917 } else if (std::regex_match(bc_id, std::regex("(.*)_FIX_Z(.*)"))) {
918 bc->dispBcPtr = boost::make_shared<DisplacementCubitBcData>();
919 bc->dispBcPtr->data.flag3 = 1;
920 if (bc->bcAttributes.empty()) {
921 bc->dispBcPtr->data.value3 = 0;
922 MOFEM_LOG("BcMngWorld", Sev::warning)
923 << "Expected one attribute on block but have "
924 << bc->bcAttributes.size();
925 } else if (bc->bcAttributes.size() == 1) {
926 bc->dispBcPtr->data.value3 = bc->bcAttributes[0];
927 } else if (bc->bcAttributes.size() == 3) {
928 bc->dispBcPtr->data.value3 = bc->bcAttributes[2];
929 }
930 MOFEM_LOG("BcMngWorld", Sev::inform) << "Add Z " << bc_id;
931 MOFEM_LOG("BcMngWorld", Sev::inform) << *(bc->dispBcPtr);
932 } else if (std::regex_match(bc_id, std::regex("(.*)_FIX_ALL(.*)"))) {
933 bc->dispBcPtr = boost::make_shared<DisplacementCubitBcData>();
934 bc->dispBcPtr->data.flag1 = 1;
935 bc->dispBcPtr->data.flag2 = 1;
936 bc->dispBcPtr->data.flag3 = 1;
937 if (bc->bcAttributes.size() >= 1) {
938 bc->dispBcPtr->data.value1 = bc->bcAttributes[0];
939 }
940 if (bc->bcAttributes.size() >= 2) {
941 bc->dispBcPtr->data.value2 = bc->bcAttributes[1];
942 }
943 if (bc->bcAttributes.size() >= 3) {
944 bc->dispBcPtr->data.value3 = bc->bcAttributes[2];
945 }
946 MOFEM_LOG("BcMngWorld", Sev::inform) << "Add ALL " << bc_id;
947 MOFEM_LOG("BcMngWorld", Sev::inform) << *(bc->dispBcPtr);
948 } else if (std::regex_match(bc_id, std::regex("(.*)_ROTATE_X(.*)"))) {
949 bc->dispBcPtr =
950 boost::make_shared<DisplacementCubitBcDataWithRotation>();
951 bc->dispBcPtr->data.flag4 = 1;
952 bc->dispBcPtr->data.flag5 = 0;
953 bc->dispBcPtr->data.flag6 = 0;
954 // for the ROTATE_X block the angles can be specified with either one or
955 // three attributes, e.g. 1, coords or 1,0,0,coords
956 if (bc->bcAttributes.empty()) {
957 bc->dispBcPtr->data.value4 = 0;
958 MOFEM_LOG("BcMngWorld", Sev::warning)
959 << "Expected one attribute on block on block (angle (1 or 3), "
960 "center coords(3) but have "
961 << bc->bcAttributes.size();
962 } else if (bc->bcAttributes.size() >= 1) {
963 bc->dispBcPtr->data.value4 = bc->bcAttributes[0];
964 }
965 MOFEM_LOG("BcMngWorld", Sev::inform) << "Add X " << bc_id;
966 MOFEM_LOG("BcMngWorld", Sev::inform) << *bc->dispBcPtr;
967 if (bc->bcAttributes.size() == 4 || bc->bcAttributes.size() == 6) {
968 if (auto ext_disp_bc =
970 bc->dispBcPtr.get())) {
971 auto &o = ext_disp_bc->rotOffset;
972 for (int a = 0; a != 3; ++a)
973 o[a] = bc->bcAttributes[bc->bcAttributes.size() - 3 + a];
974 MOFEM_LOG("BcMngWorld", Sev::inform)
975 << "Add Rotate X Center: " << o[0] << " " << o[1] << " "
976 << o[2];
977 }
978 }
979 } else if (std::regex_match(bc_id, std::regex("(.*)_ROTATE_Y(.*)"))) {
980 bc->dispBcPtr =
981 boost::make_shared<DisplacementCubitBcDataWithRotation>();
982 bc->dispBcPtr->data.flag4 = 0;
983 bc->dispBcPtr->data.flag5 = 1;
984 bc->dispBcPtr->data.flag6 = 0;
985 // for the ROTATE_Y block the angles can be specified with either one or
986 // three attributes, e.g. 1, coords or 0,1,0,coords
987 if (bc->bcAttributes.empty()) {
988 bc->dispBcPtr->data.value5 = 0;
989 MOFEM_LOG("BcMngWorld", Sev::warning)
990 << "Expected one attribute on block on block (angle (1 or 3), "
991 "center coords(3) but have "
992 << bc->bcAttributes.size();
993 } else if (bc->bcAttributes.size() == 1 ||
994 bc->bcAttributes.size() == 4) {
995 bc->dispBcPtr->data.value5 = bc->bcAttributes[0];
996 } else if (bc->bcAttributes.size() == 6) {
997 bc->dispBcPtr->data.value5 = bc->bcAttributes[1];
998 }
999 MOFEM_LOG("BcMngWorld", Sev::inform) << "Add Y " << bc_id;
1000 MOFEM_LOG("BcMngWorld", Sev::inform) << *(bc->dispBcPtr);
1001 if (bc->bcAttributes.size() == 4 || bc->bcAttributes.size() == 6) {
1002 if (auto ext_disp_bc =
1004 bc->dispBcPtr.get())) {
1005 auto &o = ext_disp_bc->rotOffset;
1006 for (int a = 0; a != 3; ++a)
1007 o[a] = bc->bcAttributes[bc->bcAttributes.size() - 3 + a];
1008 MOFEM_LOG("BcMngWorld", Sev::inform)
1009 << "Add Rotate Y Center: " << o[0] << " " << o[1] << " "
1010 << o[2];
1011 }
1012 }
1013 } else if (std::regex_match(bc_id, std::regex("(.*)_ROTATE_Z(.*)"))) {
1014 bc->dispBcPtr =
1015 boost::make_shared<DisplacementCubitBcDataWithRotation>();
1016 bc->dispBcPtr->data.flag4 = 0;
1017 bc->dispBcPtr->data.flag5 = 0;
1018 bc->dispBcPtr->data.flag6 = 1;
1019 // for the ROTATE_Z block the angles can be specified with either one or
1020 // three attributes, e.g. 1, coords or 0,0,1,coords
1021 if (bc->bcAttributes.empty()) {
1022 bc->dispBcPtr->data.value6 = 0;
1023 MOFEM_LOG("BcMngWorld", Sev::warning)
1024 << "Expected one attribute on block (angle (1 or 3), center "
1025 "coords(3) but have "
1026 << bc->bcAttributes.size();
1027 } else if (bc->bcAttributes.size() == 1 ||
1028 bc->bcAttributes.size() == 4) {
1029 bc->dispBcPtr->data.value6 = bc->bcAttributes[0];
1030 } else if (bc->bcAttributes.size() == 3 ||
1031 bc->bcAttributes.size() == 6) {
1032 bc->dispBcPtr->data.value6 = bc->bcAttributes[2];
1033 }
1034 MOFEM_LOG("BcMngWorld", Sev::inform) << "Add Z " << bc_id;
1035 MOFEM_LOG("BcMngWorld", Sev::inform) << *(bc->dispBcPtr);
1036 if (bc->bcAttributes.size() == 4 || bc->bcAttributes.size() == 6) {
1037 if (auto ext_disp_bc =
1039 bc->dispBcPtr.get())) {
1040 auto &o = ext_disp_bc->rotOffset;
1041 for (int a = 0; a != 3; ++a)
1042 o[a] = bc->bcAttributes[bc->bcAttributes.size() - 3 + a];
1043 MOFEM_LOG("BcMngWorld", Sev::inform)
1044 << "Add Rotate Z Center: " << o[0] << " " << o[1] << " "
1045 << o[2];
1046 }
1047 }
1048 } else if (std::regex_match(bc_id, std::regex("(.*)_ROTATE_ALL(.*)"))) {
1049 bc->dispBcPtr =
1050 boost::make_shared<DisplacementCubitBcDataWithRotation>();
1051 bc->dispBcPtr->data.flag4 = 1;
1052 bc->dispBcPtr->data.flag5 = 1;
1053 bc->dispBcPtr->data.flag6 = 1;
1054 if (bc->bcAttributes.size() >= 1) {
1055 bc->dispBcPtr->data.value4 = bc->bcAttributes[0];
1056 }
1057 if (bc->bcAttributes.size() >= 2) {
1058 bc->dispBcPtr->data.value5 = bc->bcAttributes[1];
1059 }
1060 if (bc->bcAttributes.size() >= 3) {
1061 bc->dispBcPtr->data.value6 = bc->bcAttributes[2];
1062 }
1063 MOFEM_LOG("BcMngWorld", Sev::inform) << "Add ALL " << bc_id;
1064 MOFEM_LOG("BcMngWorld", Sev::inform) << *(bc->dispBcPtr);
1065 if (bc->bcAttributes.size() > 3) {
1066 if (auto ext_disp_bc =
1068 bc->dispBcPtr.get())) {
1069 auto &o = ext_disp_bc->rotOffset;
1070 for (int a = 0; a != 3; ++a)
1071 o[a] = bc->bcAttributes[3 + a];
1072 MOFEM_LOG("BcMngWorld", Sev::inform)
1073 << "Add Rotate ALL Center: " << o[0] << " " << o[1] << " "
1074 << o[2];
1075 }
1076 }
1077 }
1078 }
1079 }
1080
1082}
1083
1084template <>
1085MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<BcScalarMeshsetType<BLOCKSET>>(
1086 const std::string problem_name, const std::string block_name,
1087 const std::string field_name, bool get_low_dim_ents) {
1089
1090 CHKERR pushMarkDOFsOnEntities(problem_name, block_name, field_name, 0,
1091 MAX_DOFS_ON_ENTITY, get_low_dim_ents);
1092
1093 auto regex_str =
1094 (boost::format("%s_%s_%s(.*)") % problem_name % field_name % block_name)
1095 .str();
1096
1097 for (auto &m : bcMapByBlockName) {
1098
1099 auto &bc_id = m.first;
1100
1101 if (std::regex_match(bc_id, std::regex(regex_str))) {
1102
1103 auto &bc = m.second;
1104 bc->tempBcPtr = boost::make_shared<TemperatureCubitBcData>();
1105 bc->tempBcPtr->data.flag1 = 1;
1106 if (bc->bcAttributes.empty()) {
1107 bc->tempBcPtr->data.value1 = 0;
1108 MOFEM_LOG("BcMngWorld", Sev::warning)
1109 << "Expected one attribute on block but have "
1110 << bc->bcAttributes.size();
1111 } else if (bc->bcAttributes.size() >= 1) {
1112 bc->tempBcPtr->data.value1 = bc->bcAttributes[0];
1113 }
1114 }
1115 }
1116
1118}
1119
1120template <>
1121MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<DisplacementCubitBcData>(
1122 const std::string problem_name, const std::string field_name,
1123 bool get_low_dim_ents, bool block_name_field_prefix) {
1125 // that marks DOFs and create data when are set by cubit nodesets.
1126 CHKERR pushMarkDOFsOnEntities<BcMeshsetType<DISPLACEMENTSET>>(
1127 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1128 // that marks DOFs and create data when are set by blocsket.
1129 CHKERR pushMarkDOFsOnEntities<BcDisplacementMeshsetType<BLOCKSET>>(
1130 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1132}
1133
1134template <>
1135MoFEMErrorCode BcManager::removeBlockDOFsOnEntities<DisplacementCubitBcData>(
1136 const std::string problem_name, const std::string field_name,
1137 bool get_low_dim_ents, bool block_name_field_prefix,
1138 bool is_distributed_mesh) {
1140 // that remove DOFs when are set by cubit nodesets.
1141 CHKERR removeBlockDOFsOnEntities<BcMeshsetType<DISPLACEMENTSET>>(
1142 problem_name, field_name, get_low_dim_ents, block_name_field_prefix,
1143 is_distributed_mesh);
1144 // that remove DOFs when are by blocksets
1145 CHKERR removeBlockDOFsOnEntities<BcDisplacementMeshsetType<BLOCKSET>>(
1146 problem_name, field_name, get_low_dim_ents, block_name_field_prefix,
1147 is_distributed_mesh);
1148 // add more ways to remove bcs when appropiate
1150}
1151
1152template <>
1153MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<TemperatureCubitBcData>(
1154 const std::string problem_name, const std::string field_name,
1155 bool get_low_dim_ents, bool block_name_field_prefix) {
1157 CHKERR pushMarkDOFsOnEntities<BcMeshsetType<TEMPERATURESET>>(
1158 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1159
1160 auto get_block_name = [&]() {
1161 if (block_name_field_prefix)
1162 return (boost::format("%s_FIX_SCALAR") % field_name).str();
1163 else
1164 return field_name;
1165 };
1166
1167 CHKERR pushMarkDOFsOnEntities<BcScalarMeshsetType<BLOCKSET>>(
1168 problem_name, get_block_name(), field_name, get_low_dim_ents);
1170}
1171
1172template <>
1173MoFEMErrorCode BcManager::removeBlockDOFsOnEntities<TemperatureCubitBcData>(
1174 const std::string problem_name, const std::string field_name,
1175 bool get_low_dim_ents, bool block_name_field_prefix,
1176 bool is_distributed_mesh) {
1178 CHKERR removeBlockDOFsOnEntities<BcMeshsetType<TEMPERATURESET>>(
1179 problem_name, field_name, get_low_dim_ents, block_name_field_prefix,
1180 is_distributed_mesh);
1181
1182 auto get_block_name = [&]() {
1183 if (block_name_field_prefix)
1184 return (boost::format("%s_FIX_SCALAR") % field_name).str();
1185 else
1186 return field_name;
1187 };
1188
1189 CHKERR removeBlockDOFsOnEntities<BcScalarMeshsetType<BLOCKSET>>(
1190 problem_name, get_block_name(), field_name, get_low_dim_ents,
1191 is_distributed_mesh);
1193}
1194
1195template <>
1196MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<HeatFluxCubitBcData>(
1197 const std::string problem_name, const std::string field_name,
1198 bool get_low_dim_ents, bool block_name_field_prefix) {
1200 CHKERR pushMarkDOFsOnEntities<BcMeshsetType<HEATFLUXSET>>(
1201 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1203}
1204
1205template <>
1206MoFEMErrorCode BcManager::removeBlockDOFsOnEntities<HeatFluxCubitBcData>(
1207 const std::string problem_name, const std::string field_name,
1208 bool get_low_dim_ents, bool block_name_field_prefix,
1209 bool is_distributed_mesh) {
1211 CHKERR removeBlockDOFsOnEntities<BcMeshsetType<HEATFLUXSET>>(
1212 problem_name, field_name, get_low_dim_ents, block_name_field_prefix,
1213 is_distributed_mesh);
1215}
1216
1217std::pair<std::string, std::string>
1218BcManager::extractStringFromBlockId(const std::string block_id,
1219 const std::string prb_name) {
1220
1221 // Assumes that field name is consist with letters and numbers.
1222 // No special characters.
1223 auto field_rgx_str =
1224 (boost::format("%s_([a-zA-Z0-9]*)_(.*)") % prb_name).str();
1225 std::regex field_rgx(field_rgx_str);
1226 std::smatch match_field_name;
1227 std::string field_name;
1228 std::string block_name;
1229
1230 if (std::regex_search(block_id, match_field_name, field_rgx)) {
1231 field_name = match_field_name[1];
1232 block_name = match_field_name[2];
1233 } else {
1235 "Field name and block name can not be resolved");
1236 }
1237
1238 return std::make_pair(field_name, block_name);
1239}
1240
1241template <>
1242MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<BcMeshsetType<FORCESET>>(
1243 const std::string problem_name, const std::string field_name,
1244 bool get_low_dim_ents, bool block_name_field_prefix) {
1245 Interface &m_field = cOre;
1246 auto prb_mng = m_field.getInterface<ProblemsManager>();
1248
1249 if (problem_name.empty())
1250 MOFEM_LOG("BcMngWorld", Sev::warning) << "Argument problem_name is empty";
1251
1252 if (block_name_field_prefix)
1253 MOFEM_LOG("BcMngWorld", Sev::warning)
1254 << "Argument block_name_field_prefix=true has no effect";
1255
1256 auto fix_force = [&]() {
1258
1259 auto iterate_meshsets = [&](auto &&meshset_vec_ptr) {
1261 for (auto m : meshset_vec_ptr) {
1262 auto bc = boost::make_shared<BCs>();
1263 CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
1264 bc->bcEnts, true);
1265 bc->forceBcPtr = boost::make_shared<ForceCubitBcData>();
1266 CHKERR m->getBcDataStructure(*(bc->forceBcPtr));
1267
1268 MOFEM_LOG("BcMngWorld", Sev::verbose)
1269 << "Found block FORCESET id = " << m->getMeshsetId();
1270 MOFEM_LOG("BcMngWorld", Sev::verbose) << *bc->forceBcPtr;
1271
1272 MOFEM_LOG("BcMngSync", Sev::noisy)
1273 << "Found block FORCESET id = " << m->getMeshsetId()
1274 << " nb. of entities " << bc->bcEnts.size()
1275 << " highest dim of entities "
1276 << BcManagerImplTools::get_dim(bc->bcEnts);
1277 MOFEM_LOG("BcMngSync", Sev::noisy) << *bc->forceBcPtr;
1278 MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
1279
1280 if (problem_name.size()) {
1281
1282 if (bc->forceBcPtr->data.value2 > 0)
1283 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 0, 0,
1285 bc->bcMarkers);
1286 if (bc->forceBcPtr->data.value3 > 0)
1287 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 1, 1,
1289 bc->bcMarkers);
1290 if (bc->forceBcPtr->data.value4 > 0)
1291 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 2, 2,
1293 bc->bcMarkers);
1294
1295 if (bc->forceBcPtr->data.value5 > 0) {
1296
1297 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 1, 1,
1299 bc->bcMarkers);
1300 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 2, 2,
1302 bc->bcMarkers);
1303 }
1304 if (bc->forceBcPtr->data.value5) {
1305
1306 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 0, 0,
1308 bc->bcMarkers);
1309 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 2, 2,
1311 bc->bcMarkers);
1312 }
1313 if (bc->forceBcPtr->data.value6) {
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, 1, 1,
1320 bc->bcMarkers);
1321 }
1322 }
1323
1324 if (get_low_dim_ents) {
1325 auto low_dim_ents =
1326 BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
1327 bc->bcEnts.swap(low_dim_ents);
1328 }
1329
1330 CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
1331 bc->bcEnts);
1332 if (problem_name.size())
1333 CHKERR prb_mng->markDofs(problem_name, ROW, ProblemsManager::AND,
1334 bc->bcEnts, bc->bcMarkers);
1335
1336 const std::string bc_id =
1337 problem_name + "_" + field_name + "_FORCESET" +
1338 boost::lexical_cast<std::string>(m->getMeshsetId());
1339 bcMapByBlockName[bc_id] = bc;
1340 }
1342 };
1343
1344 CHKERR iterate_meshsets(
1345
1347 FORCESET)
1348
1349 );
1350
1352 };
1353
1354 CHKERR fix_force();
1355
1357}
1358
1359template <>
1360MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<BcForceMeshsetType<BLOCKSET>>(
1361 const std::string problem_name, const std::string field_name,
1362 bool get_low_dim_ents, bool block_name_field_prefix) {
1363 Interface &m_field = cOre;
1364 auto prb_mng = m_field.getInterface<ProblemsManager>();
1366
1367 if (problem_name.size() == 0)
1368 MOFEM_LOG("BcMngWorld", Sev::warning) << "Argument problem_name is empty";
1369
1370 auto get_force_block = [&](auto block_name) {
1372
1373 for (auto m :
1374 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
1375
1376 (boost::format("%s(.*)") % block_name).str()
1377
1378 ))
1379
1380 ) {
1381
1382 const auto block_name = m->getName();
1383
1384 MOFEM_LOG("BcMngWorld", Sev::inform)
1385 << "Found force block " << block_name;
1386
1387 auto bc = boost::make_shared<BCs>();
1388 CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
1389 bc->bcEnts, true);
1390
1391 CHKERR m->getAttributes(bc->bcAttributes);
1392 if (bc->bcAttributes.size() != 3) {
1393 SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
1394 "Expect three block attributes for force block");
1395 }
1396
1397 bc->forceBcPtr = boost::make_shared<ForceCubitBcData>();
1398 // For details look at ForceCubitBcData in mofem/src/multi_indices/BCData.hpp
1399 bc->forceBcPtr->data.value1 = 1;
1400 bc->forceBcPtr->data.value3 = bc->bcAttributes[0];
1401 bc->forceBcPtr->data.value4 = bc->bcAttributes[1];
1402 bc->forceBcPtr->data.value5 = bc->bcAttributes[2];
1403
1404 MOFEM_LOG("BcMngWorld", Sev::inform) << *bc->forceBcPtr;
1405 MOFEM_LOG("BcMngSync", Sev::noisy)
1406 << "Found block FORCESET id = " << m->getMeshsetId()
1407 << " nb. of entities " << bc->bcEnts.size()
1408 << " highest dim of entities "
1409 << BcManagerImplTools::get_dim(bc->bcEnts);
1410 MOFEM_LOG("BcMngSync", Sev::noisy) << *bc->forceBcPtr;
1411 MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
1412
1413 if (problem_name.size()) {
1414
1415 if (bc->forceBcPtr->data.value2 > 0)
1416 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 0, 0,
1418 bc->bcMarkers);
1419 if (bc->forceBcPtr->data.value3 > 0)
1420 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 1, 1,
1422 bc->bcMarkers);
1423 if (bc->forceBcPtr->data.value4 > 0)
1424 CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 2, 2,
1426 bc->bcMarkers);
1427 }
1428
1429 if (get_low_dim_ents) {
1430 auto low_dim_ents =
1431 BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
1432 bc->bcEnts.swap(low_dim_ents);
1433 }
1434
1435 CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
1436 bc->bcEnts);
1437 if (problem_name.size())
1438 CHKERR prb_mng->markDofs(problem_name, ROW, ProblemsManager::AND,
1439 bc->bcEnts, bc->bcMarkers);
1440
1441 const std::string bc_id =
1442 problem_name + "_" + field_name + "_" + block_name;
1443 bcMapByBlockName[bc_id] = bc;
1444 }
1446 };
1447
1448 CHKERR get_force_block("FORCE");
1449
1451}
1452
1453template <>
1454MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<ForceCubitBcData>(
1455 const std::string problem_name, const std::string field_name,
1456 bool get_low_dim_ents, bool block_name_field_prefix) {
1458
1459 CHKERR pushMarkDOFsOnEntities<BcMeshsetType<FORCESET>>(
1460 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1461
1462 CHKERR pushMarkDOFsOnEntities<BcForceMeshsetType<BLOCKSET>>(
1463 problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1464
1466}
1467
1468template <>
1469MoFEMErrorCode BcManager::removeBlockDOFsOnEntities<BcMeshsetType<FORCESET>>(
1470 const std::string problem_name, const std::string field_name,
1471 bool get_low_dim_ents, bool block_name_field_prefix,
1472 bool is_distributed_mesh) {
1473 Interface &m_field = cOre;
1474 auto prb_mng = m_field.getInterface<ProblemsManager>();
1476
1477 CHKERR pushMarkDOFsOnEntities<BcMeshsetType<FORCESET>>(
1478 problem_name, field_name, get_low_dim_ents);
1479
1480 std::array<Range, 3> ents_to_remove;
1481
1482 for (auto m :
1483
1485 FORCESET)) {
1486
1487 const auto block_name = m->getName();
1488 std::string bc_id = problem_name + "_" + field_name + "_" + block_name;
1489
1490 auto str = boost::format("%s_%s_%s(.*)")
1491
1492 % problem_name % field_name % block_name;
1493
1494 if (std::regex_match(bc_id, std::regex(str.str()))) {
1495
1496 auto bc = bcMapByBlockName.at(bc_id);
1497
1498 if (auto force_bc = bc->forceBcPtr) {
1499 if (force_bc->data.value3 > 0) {
1500 ents_to_remove[0].merge(bc->bcEnts);
1501 }
1502 if (force_bc->data.value4 > 0) {
1503 ents_to_remove[1].merge(bc->bcEnts);
1504 }
1505 if (force_bc->data.value5 > 0) {
1506 ents_to_remove[2].merge(bc->bcEnts);
1507 }
1508 } else {
1509 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1510 "BC type not implemented");
1511 }
1512 }
1513 }
1514
1515 auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
1516 const int hi) {
1517 if (is_distributed_mesh)
1518 return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
1519 hi);
1520 else
1521 return prb_mng->removeDofsOnEntitiesNotDistributed(
1522 problem_name, field_name, ents, lo, hi);
1523 };
1524
1525 CHKERR remove_dofs_on_ents(ents_to_remove[0], 0, 0);
1526 CHKERR remove_dofs_on_ents(ents_to_remove[1], 1, 1);
1527 CHKERR remove_dofs_on_ents(ents_to_remove[2], 2, 2);
1528
1530}
1531
1532template <>
1534BcManager::removeBlockDOFsOnEntities<BcForceMeshsetType<BLOCKSET>>(
1535 const std::string problem_name, const std::string field_name,
1536 bool get_low_dim_ents, bool block_name_field_prefix,
1537 bool is_distributed_mesh) {
1538 Interface &m_field = cOre;
1539 auto prb_mng = m_field.getInterface<ProblemsManager>();
1541
1542 CHKERR pushMarkDOFsOnEntities<BcForceMeshsetType<BLOCKSET>>(
1543 problem_name, field_name, get_low_dim_ents);
1544
1545 std::array<Range, 3> ents_to_remove;
1546
1547 for (auto m :
1548
1550 BLOCKSET | UNKNOWNNAME)) {
1551
1552 const auto block_name = m->getName();
1553 std::string bc_id = problem_name + "_" + field_name + "_" + block_name;
1554
1555 auto str = boost::format("%s_%s_%s(.*)")
1556
1557 % problem_name % field_name % block_name;
1558
1559 if (std::regex_match(bc_id, std::regex(str.str()))) {
1560
1561 auto bc = bcMapByBlockName.at(bc_id);
1562
1563 if (auto force_bc = bc->forceBcPtr) {
1564 if (force_bc->data.value3 > 0) {
1565 ents_to_remove[0].merge(bc->bcEnts);
1566 }
1567 if (force_bc->data.value4 > 0) {
1568 ents_to_remove[1].merge(bc->bcEnts);
1569 }
1570 if (force_bc->data.value5 > 0) {
1571 ents_to_remove[2].merge(bc->bcEnts);
1572 }
1573 } else {
1574 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1575 "BC type not implemented");
1576 }
1577 }
1578 }
1579
1580 auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
1581 const int hi) {
1582 if (is_distributed_mesh)
1583 return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
1584 hi);
1585 else
1586 return prb_mng->removeDofsOnEntitiesNotDistributed(
1587 problem_name, field_name, ents, lo, hi);
1588 };
1589
1590 CHKERR remove_dofs_on_ents(ents_to_remove[0], 0, 0);
1591 CHKERR remove_dofs_on_ents(ents_to_remove[1], 1, 1);
1592 CHKERR remove_dofs_on_ents(ents_to_remove[2], 2, 2);
1593
1595}
1596
1597template <>
1598MoFEMErrorCode BcManager::removeBlockDOFsOnEntities<ForceCubitBcData>(
1599 const std::string problem_name, const std::string field_name,
1600 bool get_low_dim_ents, bool block_name_field_prefix,
1601 bool is_distributed_mesh) {
1603
1604 CHKERR removeBlockDOFsOnEntities<BcMeshsetType<FORCESET>>(
1605 problem_name, field_name, get_low_dim_ents, block_name_field_prefix,
1606 is_distributed_mesh);
1607
1608 CHKERR removeBlockDOFsOnEntities<BcForceMeshsetType<BLOCKSET>>(
1609 problem_name, field_name, get_low_dim_ents, block_name_field_prefix,
1610 is_distributed_mesh);
1611
1613};
1614
1615} // namespace MoFEM
static Index< 'o', 3 > o
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
Definition: LogManager.hpp:352
constexpr double a
@ ROW
Definition: definitions.h:123
#define MAX_DOFS_ON_ENTITY
Maximal number of DOFs on entity.
Definition: definitions.h:236
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
Definition: definitions.h:595
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:447
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:346
#define CHKERRG(n)
Check error code of MoFEM/MOAB/PETSc function.
Definition: definitions.h:483
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
Definition: definitions.h:576
@ TEMPERATURESET
Definition: definitions.h:155
@ FORCESET
Definition: definitions.h:151
@ HEATFLUXSET
Definition: definitions.h:156
@ NODESET
Definition: definitions.h:146
@ SIDESET
Definition: definitions.h:147
@ UNKNOWNNAME
Definition: definitions.h:158
@ DISPLACEMENTSET
Definition: definitions.h:150
@ BLOCKSET
Definition: definitions.h:148
@ MOFEM_DATA_INCONSISTENCY
Definition: definitions.h:31
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:416
#define CHKERR
Inline error check.
Definition: definitions.h:535
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:440
const int dim
FTensor::Index< 'm', SPACE_DIM > m
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
Definition: LogManager.cpp:389
#define MOFEM_LOG(channel, severity)
Log.
Definition: LogManager.hpp:308
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
Definition: LogManager.hpp:339
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
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
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
Definition: Exceptions.hpp:76
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:10
constexpr auto field_name
Simple interface for fast problem set-up.
Definition: BcManager.hpp:25
Range getMergedBlocksRange(std::vector< std::regex > bc_regex_vec)
Merge block ranges.
Definition: BcManager.cpp:196
boost::shared_ptr< std::vector< char unsigned > > BcMarkerPtr
Definition: BcManager.hpp:184
MoFEMErrorCode getOptions()
get options
Definition: BcManager.cpp:65
BcMarkerPtr getMergedBlocksMarker(std::vector< std::regex > bc_regex_vec)
Get the Merged Boundary Marker object.
Definition: BcManager.cpp:211
static std::pair< std::string, std::string > extractStringFromBlockId(const std::string block_id, const std::string prb_name)
Extract block name and block name form block id.
Definition: BcManager.cpp:1218
MoFEM::Core & cOre
Definition: BcManager.hpp:325
BcMapByBlockName bcMapByBlockName
Definition: BcManager.hpp:327
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 >())
Get block IS.
Definition: BcManager.cpp:242
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.
Definition: BcManager.cpp:73
BcManager(const MoFEM::Core &core)
Definition: BcManager.cpp:41
MoFEMErrorCode query_interface(boost::typeindex::type_index type_index, UnknownInterface **iface) const
Definition: BcManager.cpp:34
boost::shared_ptr< BCs > popMarkDOFsOnEntities(const std::string block_name)
Get bc data and remove element.
Definition: BcManager.cpp:186
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 block DOFs.
Definition: BcManager.cpp:111
BcMapByBlockName & getBcMapByBlockName()
Get the bc map.
Definition: BcManager.hpp:200
Managing BitRefLevels.
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =0
Core (interface) class.
Definition: Core.hpp:82
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.
Definition: LogManager.cpp:298
static boost::shared_ptr< std::ostream > getStrmWorld()
Get the strm world object.
Definition: LogManager.cpp:344
static boost::shared_ptr< std::ostream > getStrmSync()
Get the strm sync object.
Definition: LogManager.cpp:348
static bool checkIfChannelExist(const std::string channel)
Check if channel exist.
Definition: LogManager.cpp:399
static boost::shared_ptr< std::ostream > getStrmSelf()
Get the strm self object.
Definition: LogManager.cpp:340
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 refernce to pointer of interface.