v0.14.0
BcManager.cpp
Go to the documentation of this file.
1 /** \file BcManager.cpp
2  * \brief Manages boundary conditions
3  * \ingroup bc_manager
4  */
5 
6 namespace MoFEM {
7 
8 namespace BcManagerImplTools {
9 
10 auto 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 
17 auto 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 
34 BcManager::query_interface(boost::typeindex::type_index type_index,
35  UnknownInterface **iface) const {
37  *iface = const_cast<BcManager *>(this);
39 }
40 
41 BcManager::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();
69  CHKERRG(ierr);
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 
111 MoFEMErrorCode BcManager::pushMarkDOFsOnEntities(const std::string problem_name,
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,
130  ProblemsManager::MarkOP::OR, 1,
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 
185 MoFEMErrorCode BcManager::addBlockDOFsToMPCs(const std::string problem_name,
186  const std::string field_name,
187  bool get_low_dim_ents,
188  bool block_name_field_prefix,
189  bool is_distributed_mesh) {
190  Interface &m_field = cOre;
191  auto prb_mng = m_field.getInterface<ProblemsManager>();
193 
194  if (block_name_field_prefix)
195  MOFEM_LOG("BcMngWorld", Sev::warning)
196  << "Argument block_name_field_prefix=true has no effect";
197  if (is_distributed_mesh)
198  MOFEM_LOG("BcMngWorld", Sev::warning)
199  << "Argument is_distributed_mesh=true has no effect";
200  if (get_low_dim_ents)
201  MOFEM_LOG("BcMngWorld", Sev::warning)
202  << "Argument get_low_dim_ents=true has no effect";
203 
204  auto get_dim = [&](const Range &ents) {
205  for (auto d : {3, 2, 1})
206  if (ents.num_of_dimension(d))
207  return d;
208  return 0;
209  };
210 
211  auto mark_fix_dofs = [&](std::vector<unsigned char> &marked_field_dofs,
212  const auto lo, const auto hi) {
213  return prb_mng->modifyMarkDofs(problem_name, ROW, field_name, lo, hi,
214  ProblemsManager::MarkOP::OR, 1,
215  marked_field_dofs);
216  };
217 
218  auto iterate_mpc_meshsets = [&]() {
220 
221  auto mpc_meshset_ptr =
222  m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
223  std::regex((boost::format("%s(.*)") % "MPC_(.*)").str()));
224 
225  for (auto m : mpc_meshset_ptr) {
226 
227  if (std::regex_match(m->getName(),
228  std::regex("(.*)COUPLING_LINKS(.*)"))) {
229 
230  auto bc = boost::make_shared<BCs>();
231  bc->mpcPtr = boost::make_shared<MPCsType>();
232  bc->mpcPtr->mpcType = MPC::COUPLING;
233 
234  std::string const corresponding_master_ms =
235  std::regex_replace(m->getName(), std::regex("LINKS"), "MASTER");
236 
237  Range links_ents;
238  CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
239  links_ents, true);
240 
241  Range master_nodes;
242  if (m_field.getInterface<MeshsetsManager>()->checkMeshset(
243  corresponding_master_ms)) {
244  const CubitMeshSets *l;
245  CHKERR m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
246  corresponding_master_ms, &l);
247  bc->mpcPtr->isReprocitical = false;
248 
249  // std::cout << "master meshset is: " << master_nodes << "\n";
250  CHKERR m_field.get_moab().get_entities_by_handle(
251  l->getMeshset(), master_nodes, true);
252  // std::cout << "master meshset is: " << master_nodes << "\n";
253  // if (master_nodes.subset_by_dimension(0).size() < links_ents.subset_by_dimension(1))
254  {
255  auto low_dim_ents = BcManagerImplTools::get_adj_ents(
256  m_field.get_moab(), master_nodes);
257  // std::cout << "lower_dim meshset is: " << low_dim_ents << "\n";
258  low_dim_ents = low_dim_ents.subset_by_dimension(0);
259  master_nodes.swap(low_dim_ents);
260  // std::cout << "master meshset 2 is: " << master_nodes << "\n";
261  }
262 
263  MOFEM_LOG("BcMngWorld", Sev::verbose)
264  << "Found block MASTER LINKS block: " << l->getName()
265  << " Entities size: " << master_nodes.size();
266 
267  } else {
268  MOFEM_LOG("BcMngWorld", Sev::warning)
269  << "MASTER LINKS block not found: " << corresponding_master_ms
270  << " setting reprocitical constraint. ("
271  << bc->mpcPtr->isReprocitical << ").";
272  }
273 
274  // if (std::regex_match(bc_id, std::regex("(.*)TIE(.*)")))
275  // bc->mpcPtr->mpcType = MPC::TIE;
276  // if (std::regex_match(bc_id, std::regex("(.*)RIGID_BODY(.*)")))
277  // bc->mpcPtr->mpcType = MPC::RIGID_BODY;
278 
279  // std::cout << "links_ents range is: " << links_ents << "\n";
280  for (auto &link : links_ents.subset_by_dimension(1)) {
281  Range verts;
282  CHKERR m_field.get_moab().get_connectivity(&link, 1, verts, true);
283  // std::cout << "verts range is: " << verts << "\n";
284  if (bc->mpcPtr->isReprocitical) {
285  bc->mpcPtr->mpcMasterEnts.insert(verts[0]);
286  bc->mpcPtr->mpcSlaveEnts.insert(verts[1]);
287  } else {
288  for (auto &m_node : verts)
289  if (master_nodes.find(m_node) != master_nodes.end()) {
290  // std::cout << "found ent: " << m_node << "\n";
291  bc->mpcPtr->mpcMasterEnts.insert(m_node);
292  bc->mpcPtr->mpcSlaveEnts.merge(subtract(verts, Range(m_node, m_node)));
293  break;
294  }
295  }
296  }
297 
298  MOFEM_LOG("BcMngWorld", Sev::verbose)
299  << "Found block MPC LINKS block: " << m->getName()
300  << " Entities size (edges): " << links_ents.size()
301  << " Entities size (nodes): " << bc->mpcPtr->mpcMasterEnts.size() + bc->mpcPtr->mpcSlaveEnts.size()
302  << " (" << bc->mpcPtr->mpcMasterEnts.size() << " " << bc->mpcPtr->mpcSlaveEnts.size() << ")";
303 
304  MOFEM_LOG("BcMngSync", Sev::noisy) << *bc->mpcPtr;
305  MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
306 
307  // CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
308  // bc->mpcPtr->mpcMasterEnts);
309  // CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
310  // bc->mpcPtr->mpcSlaveEnts);
311  vector<double> mAttributes;
312  CHKERR m->getAttributes(mAttributes);
313 
314  auto setFlags = [&](const auto &flags) {
315  auto &d = bc->mpcPtr->data;
316  if (flags.empty()) {
317  d.flag1 = d.flag2 = d.flag3 = d.flag4 = d.flag5 = d.flag6 =
318  true;
319  return;
320  }
321  for (size_t i = 0; i < std::min(flags.size(), size_t(6)); ++i)
322  (&d.flag1)[i] = flags[i] > 0.0;
323  };
324 
325  setFlags(mAttributes);
326 
327  MOFEM_LOG("BcMngWorld", Sev::verbose)
328  << "Found block " << m->getName() << " number of entities "
329  << bc->mpcPtr->mpcMasterEnts.size() << " number of attributes "
330  << mAttributes.size() << " highest dim of entities "
331  << get_dim(bc->mpcPtr->mpcMasterEnts);
332 
333  // NOTE: we are not using markers at the moment
334  // for (int i = 0; i != mAttributes.size(); ++i) {
335  // if (mAttributes[i] > 0.0)
336  // CHKERR mark_fix_dofs(bc->mpcPtr->bcMasterMarkers, i, i);
337  // }
338 
339  // if (mAttributes.empty())
340  // CHKERR mark_fix_dofs(bc->mpcPtr->bcMasterMarkers, 0,
341  // MAX_DOFS_ON_ENTITY);
342 
343  const std::string bc_id =
344  problem_name + "_" + field_name + "_" + m->getName();
345  bcMapByBlockName[bc_id] = bc;
346  }
347  }
349  };
350 
351  CHKERR iterate_mpc_meshsets();
352 
354 }
355 
356 boost::shared_ptr<BcManager::BCs>
357 BcManager::popMarkDOFsOnEntities(const std::string block_name) {
358  auto bc_it = bcMapByBlockName.find(block_name);
359  if (bc_it != bcMapByBlockName.end()) {
360  auto bc = bc_it->second;
361  bcMapByBlockName.erase(bc_it);
362  return bc;
363  }
364  return boost::shared_ptr<BCs>();
365 }
366 
367 Range BcManager::getMergedBlocksRange(std::vector<std::regex> bc_regex_vec) {
368  Range ents;
369  if (bcMapByBlockName.size()) {
370  for (auto b : bcMapByBlockName) {
371  for (auto &reg_name : bc_regex_vec) {
372  if (std::regex_match(b.first, reg_name)) {
373  ents.merge(b.second->bcEnts);
374  }
375  }
376  }
377  }
378  return ents;
379 }
380 
382 BcManager::getMergedBlocksMarker(std::vector<std::regex> bc_regex_vec) {
383  BcManager::BcMarkerPtr boundary_marker_ptr;
384  if (bcMapByBlockName.size()) {
385  for (auto b : bcMapByBlockName) {
386  for (auto &reg_name : bc_regex_vec) {
387  if (std::regex_match(b.first, reg_name)) {
388  if (!boundary_marker_ptr)
389  boundary_marker_ptr =
390  boost::make_shared<std::vector<char unsigned>>();
391  boundary_marker_ptr->resize(b.second->bcMarkers.size(), 0);
392  for (int i = 0; i != b.second->bcMarkers.size(); ++i) {
393  (*boundary_marker_ptr)[i] |= b.second->bcMarkers[i];
394  }
395  }
396  }
397  }
398  }
399  return boundary_marker_ptr;
400 }
401 
403  const std::vector<BcManager::BcMarkerPtr> &boundary_markers_ptr_vec) {
404  auto boundary_marker_ptr = boost::make_shared<std::vector<char unsigned>>();
405  for (auto &bcm : boundary_markers_ptr_vec) {
406  boundary_marker_ptr->resize(bcm->size(), 0);
407  for (int i = 0; i != bcm->size(); ++i)
408  (*boundary_marker_ptr)[i] |= (*bcm)[i];
409  }
410  return boundary_marker_ptr;
411 }
412 
413 SmartPetscObj<IS> BcManager::getBlockIS(const std::string block_prefix,
414  const std::string block_name,
415  const std::string field_name,
416  const std::string problem_name, int lo,
417  int hi, SmartPetscObj<IS> is_expand) {
418  Interface &m_field = cOre;
419 
420  const std::string bc_id =
421  block_prefix + "_" + field_name + "_" + block_name + "(.*)";
422 
423  Range bc_ents;
424  for (auto bc : getBcMapByBlockName()) {
425  if (std::regex_match(bc.first, std::regex(bc_id))) {
426  bc_ents.merge(*(bc.second->getBcEntsPtr()));
427  MOFEM_LOG("BcMngWorld", Sev::verbose)
428  << "Get entities from block and add to IS. Block name " << bc.first;
429  }
430  }
431 
432  SmartPetscObj<IS> is_bc;
433  auto get_is = [&]() {
435  CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(bc_ents);
436  CHKERR m_field.getInterface<ISManager>()->isCreateProblemFieldAndRank(
437  problem_name, ROW, field_name, lo, hi, is_bc, &bc_ents);
438  if (is_expand) {
439  IS is_tmp;
440  CHKERR ISExpand(is_bc, is_expand, &is_tmp);
441  is_bc = SmartPetscObj<IS>(is_tmp);
442  }
443  CHKERR ISSort(is_bc);
445  };
446 
447  if (get_is())
448  CHK_THROW_MESSAGE(MOFEM_DATA_INCONSISTENCY, "IS is not created");
449 
450  return is_bc;
451 }
452 
453 SmartPetscObj<IS> BcManager::getBlockIS(const std::string problem_name,
454  const std::string block_name,
455  const std::string field_name, int lo,
456  int hi, SmartPetscObj<IS> is_expand) {
457  return getBlockIS(problem_name, block_name, field_name, problem_name, lo, hi,
458  is_expand);
459 }
460 
461 template <>
463 BcManager::removeBlockDOFsOnEntities<BcMeshsetType<DISPLACEMENTSET>>(
464  const std::string problem_name, const std::string field_name,
465  bool get_low_dim_ents, bool block_name_field_prefix,
466  bool is_distributed_mesh) {
467  Interface &m_field = cOre;
468  auto prb_mng = m_field.getInterface<ProblemsManager>();
470 
471  CHKERR pushMarkDOFsOnEntities<BcMeshsetType<DISPLACEMENTSET>>(
472  problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
473 
474  std::array<Range, 3> ents_to_remove;
475 
476  for (auto m :
477 
480 
481  const std::string bc_id =
482  problem_name + "_" + field_name + "_DISPLACEMENTSET" +
483  boost::lexical_cast<std::string>(m->getMeshsetId());
484 
485  auto bc = bcMapByBlockName.at(bc_id);
486 
487  if (bc->dispBcPtr) {
488  if (bc->dispBcPtr->data.flag1) {
489  ents_to_remove[0].merge(bc->bcEnts);
490  }
491  if (bc->dispBcPtr->data.flag2) {
492  ents_to_remove[1].merge(bc->bcEnts);
493  }
494  if (bc->dispBcPtr->data.flag3) {
495  ents_to_remove[2].merge(bc->bcEnts);
496  }
497  if (bc->dispBcPtr->data.flag4) {
498  ents_to_remove[1].merge(bc->bcEnts);
499  ents_to_remove[2].merge(bc->bcEnts);
500  }
501  if (bc->dispBcPtr->data.flag5) {
502  ents_to_remove[0].merge(bc->bcEnts);
503  ents_to_remove[2].merge(bc->bcEnts);
504  }
505  if (bc->dispBcPtr->data.flag6) {
506  ents_to_remove[0].merge(bc->bcEnts);
507  ents_to_remove[1].merge(bc->bcEnts);
508  }
509  }
510  bc->bcMarkers = std::vector<unsigned char>();
511  }
512 
513  auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
514  const int hi) {
515  if (is_distributed_mesh)
516  return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
517  hi);
518  else
519  return prb_mng->removeDofsOnEntitiesNotDistributed(
520  problem_name, field_name, ents, lo, hi);
521  };
522 
523  CHKERR remove_dofs_on_ents(ents_to_remove[0], 0, 0);
524  CHKERR remove_dofs_on_ents(ents_to_remove[1], 1, 1);
525  CHKERR remove_dofs_on_ents(ents_to_remove[2], 2, 2);
526 
528 }
529 
530 template <>
532 BcManager::removeBlockDOFsOnEntities<BcMeshsetType<TEMPERATURESET>>(
533  const std::string problem_name, const std::string field_name,
534  bool get_low_dim_ents, bool block_name_field_prefix,
535  bool is_distributed_mesh) {
536  Interface &m_field = cOre;
537  auto prb_mng = m_field.getInterface<ProblemsManager>();
539 
540  CHKERR pushMarkDOFsOnEntities<BcMeshsetType<TEMPERATURESET>>(
541  problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
542 
543  Range ents_to_remove;
544 
545  for (auto m :
546 
549 
550  ) {
551  const std::string bc_id =
552  problem_name + "_" + field_name + "_TEMPERATURESET" +
553  boost::lexical_cast<std::string>(m->getMeshsetId());
554  auto bc = bcMapByBlockName.at(bc_id);
555  ents_to_remove.merge(bc->bcEnts);
556  bc->bcMarkers = std::vector<unsigned char>();
557  }
558 
559  auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
560  const int hi) {
561  if (is_distributed_mesh)
562  return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
563  hi);
564  else
565  return prb_mng->removeDofsOnEntitiesNotDistributed(
566  problem_name, field_name, ents, lo, hi);
567  };
568 
569  CHKERR remove_dofs_on_ents(ents_to_remove, 0, MAX_DOFS_ON_ENTITY);
570 
572 }
573 
574 template <>
575 MoFEMErrorCode BcManager::removeBlockDOFsOnEntities<BcMeshsetType<HEATFLUXSET>>(
576  const std::string problem_name, const std::string field_name,
577  bool get_low_dim_ents, bool block_name_field_prefix,
578  bool is_distributed_mesh) {
579  Interface &m_field = cOre;
580  auto prb_mng = m_field.getInterface<ProblemsManager>();
582 
583  CHKERR pushMarkDOFsOnEntities<BcMeshsetType<HEATFLUXSET>>(
584  problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
585 
586  Range ents_to_remove;
587 
588  for (auto m :
589 
591  HEATFLUXSET)
592 
593  ) {
594  const std::string bc_id =
595  problem_name + "_" + field_name + "_HEATFLUXSET" +
596  boost::lexical_cast<std::string>(m->getMeshsetId());
597  auto bc = bcMapByBlockName.at(bc_id);
598  ents_to_remove.merge(bc->bcEnts);
599  bc->bcMarkers = std::vector<unsigned char>();
600  }
601 
602  auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
603  const int hi) {
604  if (is_distributed_mesh)
605  return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
606  hi);
607  else
608  return prb_mng->removeDofsOnEntitiesNotDistributed(
609  problem_name, field_name, ents, lo, hi);
610  };
611 
612  CHKERR remove_dofs_on_ents(ents_to_remove, 0, MAX_DOFS_ON_ENTITY);
613 
615 }
616 
617 template <>
619 BcManager::removeBlockDOFsOnEntities<BcDisplacementMeshsetType<BLOCKSET>>(
620  const std::string problem_name, const std::string field_name,
621  bool get_low_dim_ents, bool block_name_field_prefix,
622  bool is_distributed_mesh) {
623  Interface &m_field = cOre;
624  auto prb_mng = m_field.getInterface<ProblemsManager>();
626 
627  CHKERR pushMarkDOFsOnEntities<BcDisplacementMeshsetType<BLOCKSET>>(
628  problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
629 
630  std::array<Range, 3> ents_to_remove;
631 
632  for (auto m :
633 
635  BLOCKSET | UNKNOWNNAME)) {
636 
637  const auto block_name = m->getName();
638 
639  std::string bc_id = problem_name + "_" + field_name + "_" + block_name;
640  std::string regex_str;
641  if (block_name_field_prefix) {
642  regex_str = (boost::format("%s_%s_%s_((FIX_(ALL|X|Y|Z))|("
643  "DISPLACEMENT|ROTATE))(.*)") %
644  problem_name % field_name % field_name)
645  .str();
646  } else {
647  regex_str = (boost::format("%s_%s_((FIX_(ALL|X|Y|Z))|("
648  "DISPLACEMENT|ROTATE))(.*)") %
649  problem_name % field_name)
650  .str();
651  }
652 
653  if (std::regex_match(bc_id, std::regex(regex_str))) {
654 
655  auto bc = bcMapByBlockName.at(bc_id);
656 
657  if (auto disp_bc = bc->dispBcPtr) {
658  if (disp_bc->data.flag1) {
659  ents_to_remove[0].merge(bc->bcEnts);
660  }
661  if (disp_bc->data.flag2) {
662  ents_to_remove[1].merge(bc->bcEnts);
663  }
664  if (disp_bc->data.flag3) {
665  ents_to_remove[2].merge(bc->bcEnts);
666  }
667  if (disp_bc->data.flag4) {
668  ents_to_remove[1].merge(bc->bcEnts);
669  ents_to_remove[2].merge(bc->bcEnts);
670  }
671  if (disp_bc->data.flag5) {
672  ents_to_remove[0].merge(bc->bcEnts);
673  ents_to_remove[2].merge(bc->bcEnts);
674  }
675  if (disp_bc->data.flag6) {
676  ents_to_remove[0].merge(bc->bcEnts);
677  ents_to_remove[1].merge(bc->bcEnts);
678  }
679  } else {
680  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
681  "BC type not implemented");
682  }
683  }
684  }
685 
686  auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
687  const int hi) {
688  if (is_distributed_mesh)
689  return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
690  hi);
691  else
692  return prb_mng->removeDofsOnEntitiesNotDistributed(
693  problem_name, field_name, ents, lo, hi);
694  };
695 
696  CHKERR remove_dofs_on_ents(ents_to_remove[0], 0, 0);
697  CHKERR remove_dofs_on_ents(ents_to_remove[1], 1, 1);
698  CHKERR remove_dofs_on_ents(ents_to_remove[2], 2, 2);
699 
701 }
702 
703 template <>
705 BcManager::removeBlockDOFsOnEntities<BcScalarMeshsetType<BLOCKSET>>(
706  const std::string problem_name, const std::string block_name,
707  const std::string field_name, bool get_low_dim_ents,
708  bool is_distributed_mesh) {
709  Interface &m_field = cOre;
710  auto prb_mng = m_field.getInterface<ProblemsManager>();
712 
713  CHKERR pushMarkDOFsOnEntities<BcScalarMeshsetType<BLOCKSET>>(
714  problem_name, block_name, field_name, get_low_dim_ents);
715 
716  Range ents_to_remove;
717 
718  for (auto m :
719 
721  BLOCKSET | UNKNOWNNAME)) {
722 
723  std::string bc_id = problem_name + "_" + field_name + "_" + m->getName();
724 
725  auto str = boost::format("%s_%s_%s(.*)")
726 
727  % problem_name % field_name % block_name;
728 
729  if (std::regex_match(bc_id, std::regex(str.str()))) {
730 
731  auto bc = bcMapByBlockName.at(bc_id);
732 
733  if (auto temp_bc = bc->tempBcPtr) {
734  if (temp_bc->data.flag1) {
735  ents_to_remove.merge(bc->bcEnts);
736  }
737  } else {
738  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
739  "BC type not implemented");
740  }
741  }
742  }
743 
744  auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
745  const int hi) {
746  if (is_distributed_mesh)
747  return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
748  hi);
749  else
750  return prb_mng->removeDofsOnEntitiesNotDistributed(
751  problem_name, field_name, ents, lo, hi);
752  };
753 
754  CHKERR remove_dofs_on_ents(ents_to_remove, 0, MAX_DOFS_ON_ENTITY);
755 
757 }
758 
759 template <>
761 BcManager::pushMarkDOFsOnEntities<BcMeshsetType<DISPLACEMENTSET>>(
762  const std::string problem_name, const std::string field_name,
763  bool get_low_dim_ents, bool block_name_field_prefix) {
764  Interface &m_field = cOre;
765  auto prb_mng = m_field.getInterface<ProblemsManager>();
767 
768  // if(problem_name.size()==0)
769  // MOFEM_LOG("BcMngWorld", Sev::warning)
770  // << "Argument problem_name has no effect";
771 
772  if (block_name_field_prefix)
773  MOFEM_LOG("BcMngWorld", Sev::warning)
774  << "Argument block_name_field_prefix=true has no effect";
775 
776  auto fix_disp = [&]() {
778 
779  auto iterate_meshsets = [&](auto &&meshset_vec_ptr) {
781  for (auto m : meshset_vec_ptr) {
782  auto bc = boost::make_shared<BCs>();
783  CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
784  bc->bcEnts, true);
785  bc->dispBcPtr = boost::make_shared<DisplacementCubitBcData>();
786  CHKERR m->getBcDataStructure(*(bc->dispBcPtr));
787 
788  MOFEM_LOG("BcMngWorld", Sev::verbose)
789  << "Found block DISPLACEMENTSET id = " << m->getMeshsetId();
790  MOFEM_LOG("BcMngWorld", Sev::verbose) << *bc->dispBcPtr;
791 
792  MOFEM_LOG("BcMngSync", Sev::noisy)
793  << "Found block DISPLACEMENTSET id = " << m->getMeshsetId()
794  << " nb. of entities " << bc->bcEnts.size()
795  << " highest dim of entities "
796  << BcManagerImplTools::get_dim(bc->bcEnts);
797  MOFEM_LOG("BcMngSync", Sev::noisy) << *bc->dispBcPtr;
798  MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
799 
800  if (problem_name.size()) {
801 
802  if (bc->dispBcPtr->data.flag1)
803  CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 0, 0,
804  ProblemsManager::MarkOP::OR, 1,
805  bc->bcMarkers);
806  if (bc->dispBcPtr->data.flag2)
807  CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 1, 1,
808  ProblemsManager::MarkOP::OR, 1,
809  bc->bcMarkers);
810  if (bc->dispBcPtr->data.flag3)
811  CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 2, 2,
812  ProblemsManager::MarkOP::OR, 1,
813  bc->bcMarkers);
814  if (bc->dispBcPtr->data.flag4) {
815 
816  CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 1, 1,
817  ProblemsManager::MarkOP::OR, 1,
818  bc->bcMarkers);
819  CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 2, 2,
820  ProblemsManager::MarkOP::OR, 1,
821  bc->bcMarkers);
822  }
823  if (bc->dispBcPtr->data.flag5) {
824 
825  CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 0, 0,
826  ProblemsManager::MarkOP::OR, 1,
827  bc->bcMarkers);
828  CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 2, 2,
829  ProblemsManager::MarkOP::OR, 1,
830  bc->bcMarkers);
831  }
832  if (bc->dispBcPtr->data.flag6) {
833 
834  CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 0, 0,
835  ProblemsManager::MarkOP::OR, 1,
836  bc->bcMarkers);
837  CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 1, 1,
838  ProblemsManager::MarkOP::OR, 1,
839  bc->bcMarkers);
840  }
841  }
842 
843  if (get_low_dim_ents) {
844  auto low_dim_ents =
845  BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
846  bc->bcEnts.swap(low_dim_ents);
847  }
848 
849  CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
850  bc->bcEnts);
851  if (problem_name.size())
852  CHKERR prb_mng->markDofs(problem_name, ROW, ProblemsManager::AND,
853  bc->bcEnts, bc->bcMarkers);
854 
855  const std::string bc_id =
856  problem_name + "_" + field_name + "_DISPLACEMENTSET" +
857  boost::lexical_cast<std::string>(m->getMeshsetId());
858  bcMapByBlockName[bc_id] = bc;
859  }
861  };
862 
863  CHKERR iterate_meshsets(
864 
867 
868  );
869 
871  };
872 
873  CHKERR fix_disp();
874 
876 }
877 
878 template <>
879 MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<BcMeshsetType<TEMPERATURESET>>(
880  const std::string problem_name, const std::string field_name,
881  bool get_low_dim_ents, bool block_name_field_prefix) {
882  Interface &m_field = cOre;
883  auto prb_mng = m_field.getInterface<ProblemsManager>();
885 
886  if (block_name_field_prefix)
887  MOFEM_LOG("BcMngWorld", Sev::warning)
888  << "Argument block_name_field_prefix=true has no effect";
889 
890  auto fix_temp = [&]() {
892 
893  auto iterate_meshsets = [&](auto &&meshset_vec_ptr) {
895  for (auto m : meshset_vec_ptr) {
896  auto bc = boost::make_shared<BCs>();
897  CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
898  bc->bcEnts, true);
899  bc->tempBcPtr = boost::make_shared<TemperatureCubitBcData>();
900  CHKERR m->getBcDataStructure(*(bc->tempBcPtr));
901 
902  MOFEM_LOG("BcMngWorld", Sev::verbose)
903  << "Found block TEMPERATURESET id = " << m->getMeshsetId();
904  MOFEM_LOG("BcMngWorld", Sev::verbose) << *bc->tempBcPtr;
905 
906  CHKERR prb_mng->modifyMarkDofs(
907  problem_name, ROW, field_name, 0, MAX_DOFS_ON_ENTITY,
908  ProblemsManager::MarkOP::OR, 1, bc->bcMarkers);
909 
910  if (get_low_dim_ents) {
911  auto low_dim_ents =
912  BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
913  bc->bcEnts.swap(low_dim_ents);
914  }
915 
916  CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
917  bc->bcEnts);
918  CHKERR prb_mng->markDofs(problem_name, ROW, ProblemsManager::AND,
919  bc->bcEnts, bc->bcMarkers);
920 
921  const std::string bc_id =
922  problem_name + "_" + field_name + "_TEMPERATURESET" +
923  boost::lexical_cast<std::string>(m->getMeshsetId());
924  bcMapByBlockName[bc_id] = bc;
925  }
927  };
928 
929  CHKERR iterate_meshsets(
930 
933 
934  );
935 
937  };
938 
939  CHKERR fix_temp();
940 
942 }
943 
944 template <>
945 MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<BcMeshsetType<HEATFLUXSET>>(
946  const std::string problem_name, const std::string field_name,
947  bool get_low_dim_ents, bool block_name_field_prefix) {
948  Interface &m_field = cOre;
949  auto prb_mng = m_field.getInterface<ProblemsManager>();
951 
952  if (block_name_field_prefix)
953  MOFEM_LOG("BcMngWorld", Sev::warning)
954  << "Argument block_name_field_prefix=true has no effect";
955 
956  auto fix_disp = [&]() {
958 
959  auto iterate_meshsets = [&](auto &&meshset_vec_ptr) {
961  for (auto m : meshset_vec_ptr) {
962  auto bc = boost::make_shared<BCs>();
963  CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
964  bc->bcEnts, true);
965  bc->heatFluxBcPtr = boost::make_shared<HeatFluxCubitBcData>();
966  CHKERR m->getBcDataStructure(*(bc->heatFluxBcPtr));
967 
968  CHKERR prb_mng->modifyMarkDofs(
969  problem_name, ROW, field_name, 0, MAX_DOFS_ON_ENTITY,
970  ProblemsManager::MarkOP::OR, 1, bc->bcMarkers);
971 
972  MOFEM_LOG("BcMngWorld", Sev::verbose)
973  << "Found block HEATFLUX id = " << m->getMeshsetId();
974  MOFEM_LOG("BcMngWorld", Sev::verbose) << *bc->heatFluxBcPtr;
975 
976  if (get_low_dim_ents) {
977  auto low_dim_ents =
978  BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
979  bc->bcEnts.swap(low_dim_ents);
980  }
981 
982  CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
983  bc->bcEnts);
984  CHKERR prb_mng->markDofs(problem_name, ROW, ProblemsManager::AND,
985  bc->bcEnts, bc->bcMarkers);
986 
987  const std::string bc_id =
988  problem_name + "_" + field_name + "_HEATFLUXSET" +
989  boost::lexical_cast<std::string>(m->getMeshsetId());
990  bcMapByBlockName[bc_id] = bc;
991  }
993  };
994 
995  CHKERR iterate_meshsets(
996 
998  HEATFLUXSET)
999 
1000  );
1001 
1003  };
1004 
1005  CHKERR fix_disp();
1006 
1008 }
1009 
1010 template <>
1012 BcManager::pushMarkDOFsOnEntities<BcDisplacementMeshsetType<BLOCKSET>>(
1013  const std::string problem_name, const std::string field_name,
1014  bool get_low_dim_ents, bool block_name_field_prefix) {
1016 
1017  auto mark_dofs = [&](const string block_name, const int &idx_0,
1018  const int &idx_1) {
1020  if (block_name_field_prefix) {
1021  const string field_block = field_name + "_" + block_name;
1022  CHKERR pushMarkDOFsOnEntities(problem_name, field_block, field_name,
1023  idx_0, idx_1, get_low_dim_ents);
1024  } else {
1025 
1026  CHKERR pushMarkDOFsOnEntities(problem_name, block_name, field_name, idx_0,
1027  idx_1, get_low_dim_ents);
1028  }
1030  };
1031 
1032  // displacement
1033  CHKERR mark_dofs("FIX_X", 0, 0);
1034  CHKERR mark_dofs("FIX_Y", 1, 1);
1035  CHKERR mark_dofs("FIX_Z", 2, 2);
1036  CHKERR mark_dofs("FIX_ALL", 0, MAX_DOFS_ON_ENTITY);
1037 
1038  // rotation
1039  CHKERR mark_dofs("ROTATE_X", 1, 1);
1040  CHKERR mark_dofs("ROTATE_X", 2, 2);
1041  CHKERR mark_dofs("ROTATE_Y", 0, 0);
1042  CHKERR mark_dofs("ROTATE_Y", 2, 2);
1043  CHKERR mark_dofs("ROTATE_Z", 0, 0);
1044  CHKERR mark_dofs("ROTATE_Z", 1, 1);
1045  CHKERR mark_dofs("ROTATE_ALL", 0, MAX_DOFS_ON_ENTITY);
1046 
1047  std::string regex_str;
1048  if (block_name_field_prefix) {
1049  regex_str = (boost::format("%s_%s_%s_(.*)") % problem_name % field_name %
1050  field_name)
1051  .str();
1052  } else {
1053  regex_str = (boost::format("%s_%s_(.*)") % problem_name % field_name).str();
1054  }
1055 
1056  for (auto &m : bcMapByBlockName) {
1057  auto &bc_id = m.first;
1058  if (std::regex_match(bc_id, std::regex(regex_str))) {
1059  auto &bc = m.second;
1060  if (std::regex_match(bc_id, std::regex("(.*)_FIX_X(.*)"))) {
1061  bc->dispBcPtr = boost::make_shared<DisplacementCubitBcData>();
1062  bc->dispBcPtr->data.flag1 = 1;
1063  if (bc->bcAttributes.empty()) {
1064  bc->dispBcPtr->data.value1 = 0;
1065  MOFEM_LOG("BcMngWorld", Sev::warning)
1066  << "Expected one attribute on block but have "
1067  << bc->bcAttributes.size();
1068  } else if (bc->bcAttributes.size() >= 1) {
1069  bc->dispBcPtr->data.value1 = bc->bcAttributes[0];
1070  }
1071  MOFEM_LOG("BcMngWorld", Sev::inform) << "Add X " << bc_id;
1072  MOFEM_LOG("BcMngWorld", Sev::inform) << *bc->dispBcPtr;
1073  } else if (std::regex_match(bc_id, std::regex("(.*)_FIX_Y(.*)"))) {
1074  bc->dispBcPtr = boost::make_shared<DisplacementCubitBcData>();
1075  bc->dispBcPtr->data.flag2 = 1;
1076  if (bc->bcAttributes.empty()) {
1077  bc->dispBcPtr->data.value2 = 0;
1078  MOFEM_LOG("BcMngWorld", Sev::warning)
1079  << "Expected one attribute on block but have "
1080  << bc->bcAttributes.size();
1081  } else if (bc->bcAttributes.size() == 1) {
1082  bc->dispBcPtr->data.value2 = bc->bcAttributes[0];
1083  } else if (bc->bcAttributes.size() >= 2) {
1084  bc->dispBcPtr->data.value2 = bc->bcAttributes[1];
1085  }
1086  MOFEM_LOG("BcMngWorld", Sev::inform) << "Add Y " << bc_id;
1087  MOFEM_LOG("BcMngWorld", Sev::inform) << *(bc->dispBcPtr);
1088  } else if (std::regex_match(bc_id, std::regex("(.*)_FIX_Z(.*)"))) {
1089  bc->dispBcPtr = boost::make_shared<DisplacementCubitBcData>();
1090  bc->dispBcPtr->data.flag3 = 1;
1091  if (bc->bcAttributes.empty()) {
1092  bc->dispBcPtr->data.value3 = 0;
1093  MOFEM_LOG("BcMngWorld", Sev::warning)
1094  << "Expected one attribute on block but have "
1095  << bc->bcAttributes.size();
1096  } else if (bc->bcAttributes.size() == 1) {
1097  bc->dispBcPtr->data.value3 = bc->bcAttributes[0];
1098  } else if (bc->bcAttributes.size() == 3) {
1099  bc->dispBcPtr->data.value3 = bc->bcAttributes[2];
1100  }
1101  MOFEM_LOG("BcMngWorld", Sev::inform) << "Add Z " << bc_id;
1102  MOFEM_LOG("BcMngWorld", Sev::inform) << *(bc->dispBcPtr);
1103  } else if (std::regex_match(bc_id, std::regex("(.*)_FIX_ALL(.*)"))) {
1104  bc->dispBcPtr = boost::make_shared<DisplacementCubitBcData>();
1105  bc->dispBcPtr->data.flag1 = 1;
1106  bc->dispBcPtr->data.flag2 = 1;
1107  bc->dispBcPtr->data.flag3 = 1;
1108  if (bc->bcAttributes.size() >= 1) {
1109  bc->dispBcPtr->data.value1 = bc->bcAttributes[0];
1110  }
1111  if (bc->bcAttributes.size() >= 2) {
1112  bc->dispBcPtr->data.value2 = bc->bcAttributes[1];
1113  }
1114  if (bc->bcAttributes.size() >= 3) {
1115  bc->dispBcPtr->data.value3 = bc->bcAttributes[2];
1116  }
1117  MOFEM_LOG("BcMngWorld", Sev::inform) << "Add ALL " << bc_id;
1118  MOFEM_LOG("BcMngWorld", Sev::inform) << *(bc->dispBcPtr);
1119  } else if (std::regex_match(bc_id, std::regex("(.*)_ROTATE_X(.*)"))) {
1120  bc->dispBcPtr =
1121  boost::make_shared<DisplacementCubitBcDataWithRotation>();
1122  bc->dispBcPtr->data.flag4 = 1;
1123  bc->dispBcPtr->data.flag5 = 0;
1124  bc->dispBcPtr->data.flag6 = 0;
1125  // for the ROTATE_X block the angles can be specified with either one or
1126  // three attributes, e.g. 1, coords or 1,0,0,coords
1127  if (bc->bcAttributes.empty()) {
1128  bc->dispBcPtr->data.value4 = 0;
1129  MOFEM_LOG("BcMngWorld", Sev::warning)
1130  << "Expected one attribute on block on block (angle (1 or 3), "
1131  "center coords(3) but have "
1132  << bc->bcAttributes.size();
1133  } else if (bc->bcAttributes.size() >= 1) {
1134  bc->dispBcPtr->data.value4 = bc->bcAttributes[0];
1135  }
1136  MOFEM_LOG("BcMngWorld", Sev::inform) << "Add X " << bc_id;
1137  MOFEM_LOG("BcMngWorld", Sev::inform) << *bc->dispBcPtr;
1138  if (bc->bcAttributes.size() == 4 || bc->bcAttributes.size() == 6) {
1139  if (auto ext_disp_bc =
1140  dynamic_cast<DisplacementCubitBcDataWithRotation *>(
1141  bc->dispBcPtr.get())) {
1142  auto &o = ext_disp_bc->rotOffset;
1143  for (int a = 0; a != 3; ++a)
1144  o[a] = bc->bcAttributes[bc->bcAttributes.size() - 3 + a];
1145  MOFEM_LOG("BcMngWorld", Sev::inform)
1146  << "Add Rotate X Center: " << o[0] << " " << o[1] << " "
1147  << o[2];
1148  }
1149  }
1150  } else if (std::regex_match(bc_id, std::regex("(.*)_ROTATE_Y(.*)"))) {
1151  bc->dispBcPtr =
1152  boost::make_shared<DisplacementCubitBcDataWithRotation>();
1153  bc->dispBcPtr->data.flag4 = 0;
1154  bc->dispBcPtr->data.flag5 = 1;
1155  bc->dispBcPtr->data.flag6 = 0;
1156  // for the ROTATE_Y block the angles can be specified with either one or
1157  // three attributes, e.g. 1, coords or 0,1,0,coords
1158  if (bc->bcAttributes.empty()) {
1159  bc->dispBcPtr->data.value5 = 0;
1160  MOFEM_LOG("BcMngWorld", Sev::warning)
1161  << "Expected one attribute on block on block (angle (1 or 3), "
1162  "center coords(3) but have "
1163  << bc->bcAttributes.size();
1164  } else if (bc->bcAttributes.size() == 1 ||
1165  bc->bcAttributes.size() == 4) {
1166  bc->dispBcPtr->data.value5 = bc->bcAttributes[0];
1167  } else if (bc->bcAttributes.size() == 6) {
1168  bc->dispBcPtr->data.value5 = bc->bcAttributes[1];
1169  }
1170  MOFEM_LOG("BcMngWorld", Sev::inform) << "Add Y " << bc_id;
1171  MOFEM_LOG("BcMngWorld", Sev::inform) << *(bc->dispBcPtr);
1172  if (bc->bcAttributes.size() == 4 || bc->bcAttributes.size() == 6) {
1173  if (auto ext_disp_bc =
1174  dynamic_cast<DisplacementCubitBcDataWithRotation *>(
1175  bc->dispBcPtr.get())) {
1176  auto &o = ext_disp_bc->rotOffset;
1177  for (int a = 0; a != 3; ++a)
1178  o[a] = bc->bcAttributes[bc->bcAttributes.size() - 3 + a];
1179  MOFEM_LOG("BcMngWorld", Sev::inform)
1180  << "Add Rotate Y Center: " << o[0] << " " << o[1] << " "
1181  << o[2];
1182  }
1183  }
1184  } else if (std::regex_match(bc_id, std::regex("(.*)_ROTATE_Z(.*)"))) {
1185  bc->dispBcPtr =
1186  boost::make_shared<DisplacementCubitBcDataWithRotation>();
1187  bc->dispBcPtr->data.flag4 = 0;
1188  bc->dispBcPtr->data.flag5 = 0;
1189  bc->dispBcPtr->data.flag6 = 1;
1190  // for the ROTATE_Z block the angles can be specified with either one or
1191  // three attributes, e.g. 1, coords or 0,0,1,coords
1192  if (bc->bcAttributes.empty()) {
1193  bc->dispBcPtr->data.value6 = 0;
1194  MOFEM_LOG("BcMngWorld", Sev::warning)
1195  << "Expected one attribute on block (angle (1 or 3), center "
1196  "coords(3) but have "
1197  << bc->bcAttributes.size();
1198  } else if (bc->bcAttributes.size() == 1 ||
1199  bc->bcAttributes.size() == 4) {
1200  bc->dispBcPtr->data.value6 = bc->bcAttributes[0];
1201  } else if (bc->bcAttributes.size() == 3 ||
1202  bc->bcAttributes.size() == 6) {
1203  bc->dispBcPtr->data.value6 = bc->bcAttributes[2];
1204  }
1205  MOFEM_LOG("BcMngWorld", Sev::inform) << "Add Z " << bc_id;
1206  MOFEM_LOG("BcMngWorld", Sev::inform) << *(bc->dispBcPtr);
1207  if (bc->bcAttributes.size() == 4 || bc->bcAttributes.size() == 6) {
1208  if (auto ext_disp_bc =
1209  dynamic_cast<DisplacementCubitBcDataWithRotation *>(
1210  bc->dispBcPtr.get())) {
1211  auto &o = ext_disp_bc->rotOffset;
1212  for (int a = 0; a != 3; ++a)
1213  o[a] = bc->bcAttributes[bc->bcAttributes.size() - 3 + a];
1214  MOFEM_LOG("BcMngWorld", Sev::inform)
1215  << "Add Rotate Z Center: " << o[0] << " " << o[1] << " "
1216  << o[2];
1217  }
1218  }
1219  } else if (std::regex_match(bc_id, std::regex("(.*)_ROTATE_ALL(.*)"))) {
1220  bc->dispBcPtr =
1221  boost::make_shared<DisplacementCubitBcDataWithRotation>();
1222  bc->dispBcPtr->data.flag4 = 1;
1223  bc->dispBcPtr->data.flag5 = 1;
1224  bc->dispBcPtr->data.flag6 = 1;
1225  if (bc->bcAttributes.size() >= 1) {
1226  bc->dispBcPtr->data.value4 = bc->bcAttributes[0];
1227  }
1228  if (bc->bcAttributes.size() >= 2) {
1229  bc->dispBcPtr->data.value5 = bc->bcAttributes[1];
1230  }
1231  if (bc->bcAttributes.size() >= 3) {
1232  bc->dispBcPtr->data.value6 = bc->bcAttributes[2];
1233  }
1234  MOFEM_LOG("BcMngWorld", Sev::inform) << "Add ALL " << bc_id;
1235  MOFEM_LOG("BcMngWorld", Sev::inform) << *(bc->dispBcPtr);
1236  if (bc->bcAttributes.size() > 3) {
1237  if (auto ext_disp_bc =
1238  dynamic_cast<DisplacementCubitBcDataWithRotation *>(
1239  bc->dispBcPtr.get())) {
1240  auto &o = ext_disp_bc->rotOffset;
1241  for (int a = 0; a != 3; ++a)
1242  o[a] = bc->bcAttributes[3 + a];
1243  MOFEM_LOG("BcMngWorld", Sev::inform)
1244  << "Add Rotate ALL Center: " << o[0] << " " << o[1] << " "
1245  << o[2];
1246  }
1247  }
1248  }
1249  }
1250  }
1251 
1253 }
1254 
1255 template <>
1256 MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<BcScalarMeshsetType<BLOCKSET>>(
1257  const std::string problem_name, const std::string block_name,
1258  const std::string field_name, bool get_low_dim_ents) {
1260 
1261  CHKERR pushMarkDOFsOnEntities(problem_name, block_name, field_name, 0,
1262  MAX_DOFS_ON_ENTITY, get_low_dim_ents);
1263 
1264  auto regex_str =
1265  (boost::format("%s_%s_%s(.*)") % problem_name % field_name % block_name)
1266  .str();
1267 
1268  for (auto &m : bcMapByBlockName) {
1269 
1270  auto &bc_id = m.first;
1271 
1272  if (std::regex_match(bc_id, std::regex(regex_str))) {
1273 
1274  auto &bc = m.second;
1275  bc->tempBcPtr = boost::make_shared<TemperatureCubitBcData>();
1276  bc->tempBcPtr->data.flag1 = 1;
1277  if (bc->bcAttributes.empty()) {
1278  bc->tempBcPtr->data.value1 = 0;
1279  MOFEM_LOG("BcMngWorld", Sev::warning)
1280  << "Expected one attribute on block but have "
1281  << bc->bcAttributes.size();
1282  } else if (bc->bcAttributes.size() >= 1) {
1283  bc->tempBcPtr->data.value1 = bc->bcAttributes[0];
1284  }
1285  }
1286  }
1287 
1289 }
1290 
1291 template <>
1292 MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<DisplacementCubitBcData>(
1293  const std::string problem_name, const std::string field_name,
1294  bool get_low_dim_ents, bool block_name_field_prefix) {
1296  // that marks DOFs and create data when are set by cubit nodesets.
1297  CHKERR pushMarkDOFsOnEntities<BcMeshsetType<DISPLACEMENTSET>>(
1298  problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1299  // that marks DOFs and create data when are set by blocsket.
1300  CHKERR pushMarkDOFsOnEntities<BcDisplacementMeshsetType<BLOCKSET>>(
1301  problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1303 }
1304 
1305 template <>
1306 MoFEMErrorCode BcManager::removeBlockDOFsOnEntities<DisplacementCubitBcData>(
1307  const std::string problem_name, const std::string field_name,
1308  bool get_low_dim_ents, bool block_name_field_prefix,
1309  bool is_distributed_mesh) {
1311  // that remove DOFs when are set by cubit nodesets.
1312  CHKERR removeBlockDOFsOnEntities<BcMeshsetType<DISPLACEMENTSET>>(
1313  problem_name, field_name, get_low_dim_ents, block_name_field_prefix,
1314  is_distributed_mesh);
1315  // that remove DOFs when are by blocksets
1316  CHKERR removeBlockDOFsOnEntities<BcDisplacementMeshsetType<BLOCKSET>>(
1317  problem_name, field_name, get_low_dim_ents, block_name_field_prefix,
1318  is_distributed_mesh);
1319  // add more ways to remove bcs when appropiate
1321 }
1322 
1323 template <>
1324 MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<TemperatureCubitBcData>(
1325  const std::string problem_name, const std::string field_name,
1326  bool get_low_dim_ents, bool block_name_field_prefix) {
1328  CHKERR pushMarkDOFsOnEntities<BcMeshsetType<TEMPERATURESET>>(
1329  problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1330 
1331  auto get_block_name = [&]() {
1332  if (block_name_field_prefix)
1333  return (boost::format("%s_FIX_SCALAR") % field_name).str();
1334  else
1335  return field_name;
1336  };
1337 
1338  CHKERR pushMarkDOFsOnEntities<BcScalarMeshsetType<BLOCKSET>>(
1339  problem_name, get_block_name(), field_name, get_low_dim_ents);
1341 }
1342 
1343 template <>
1344 MoFEMErrorCode BcManager::removeBlockDOFsOnEntities<TemperatureCubitBcData>(
1345  const std::string problem_name, const std::string field_name,
1346  bool get_low_dim_ents, bool block_name_field_prefix,
1347  bool is_distributed_mesh) {
1349  CHKERR removeBlockDOFsOnEntities<BcMeshsetType<TEMPERATURESET>>(
1350  problem_name, field_name, get_low_dim_ents, block_name_field_prefix,
1351  is_distributed_mesh);
1352 
1353  auto get_block_name = [&]() {
1354  if (block_name_field_prefix)
1355  return (boost::format("%s_FIX_SCALAR") % field_name).str();
1356  else
1357  return field_name;
1358  };
1359 
1360  CHKERR removeBlockDOFsOnEntities<BcScalarMeshsetType<BLOCKSET>>(
1361  problem_name, get_block_name(), field_name, get_low_dim_ents,
1362  is_distributed_mesh);
1364 }
1365 
1366 template <>
1367 MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<HeatFluxCubitBcData>(
1368  const std::string problem_name, const std::string field_name,
1369  bool get_low_dim_ents, bool block_name_field_prefix) {
1371  CHKERR pushMarkDOFsOnEntities<BcMeshsetType<HEATFLUXSET>>(
1372  problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1374 }
1375 
1376 template <>
1377 MoFEMErrorCode BcManager::removeBlockDOFsOnEntities<HeatFluxCubitBcData>(
1378  const std::string problem_name, const std::string field_name,
1379  bool get_low_dim_ents, bool block_name_field_prefix,
1380  bool is_distributed_mesh) {
1382  CHKERR removeBlockDOFsOnEntities<BcMeshsetType<HEATFLUXSET>>(
1383  problem_name, field_name, get_low_dim_ents, block_name_field_prefix,
1384  is_distributed_mesh);
1386 }
1387 
1388 std::pair<std::string, std::string>
1389 BcManager::extractStringFromBlockId(const std::string block_id,
1390  const std::string prb_name) {
1391 
1392  // Assumes that field name is consist with letters and numbers.
1393  // No special characters.
1394  auto field_rgx_str =
1395  (boost::format("%s_([a-zA-Z0-9]*)_(.*)") % prb_name).str();
1396  std::regex field_rgx(field_rgx_str);
1397  std::smatch match_field_name;
1398  std::string field_name;
1399  std::string block_name;
1400 
1401  if (std::regex_search(block_id, match_field_name, field_rgx)) {
1402  field_name = match_field_name[1];
1403  block_name = match_field_name[2];
1404  } else {
1406  "Field name and block name can not be resolved");
1407  }
1408 
1409  return std::make_pair(field_name, block_name);
1410 }
1411 
1412 template <>
1413 MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<BcMeshsetType<FORCESET>>(
1414  const std::string problem_name, const std::string field_name,
1415  bool get_low_dim_ents, bool block_name_field_prefix) {
1416  Interface &m_field = cOre;
1417  auto prb_mng = m_field.getInterface<ProblemsManager>();
1419 
1420  if (problem_name.empty())
1421  MOFEM_LOG("BcMngWorld", Sev::warning) << "Argument problem_name is empty";
1422 
1423  if (block_name_field_prefix)
1424  MOFEM_LOG("BcMngWorld", Sev::warning)
1425  << "Argument block_name_field_prefix=true has no effect";
1426 
1427  auto fix_force = [&]() {
1429 
1430  auto iterate_meshsets = [&](auto &&meshset_vec_ptr) {
1432  for (auto m : meshset_vec_ptr) {
1433  auto bc = boost::make_shared<BCs>();
1434  CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
1435  bc->bcEnts, true);
1436  bc->forceBcPtr = boost::make_shared<ForceCubitBcData>();
1437  CHKERR m->getBcDataStructure(*(bc->forceBcPtr));
1438 
1439  MOFEM_LOG("BcMngWorld", Sev::verbose)
1440  << "Found block FORCESET id = " << m->getMeshsetId();
1441  MOFEM_LOG("BcMngWorld", Sev::verbose) << *bc->forceBcPtr;
1442 
1443  MOFEM_LOG("BcMngSync", Sev::noisy)
1444  << "Found block FORCESET id = " << m->getMeshsetId()
1445  << " nb. of entities " << bc->bcEnts.size()
1446  << " highest dim of entities "
1447  << BcManagerImplTools::get_dim(bc->bcEnts);
1448  MOFEM_LOG("BcMngSync", Sev::noisy) << *bc->forceBcPtr;
1449  MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
1450 
1451  if (problem_name.size()) {
1452 
1453  if (bc->forceBcPtr->data.value2 > 0)
1454  CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 0, 0,
1455  ProblemsManager::MarkOP::OR, 1,
1456  bc->bcMarkers);
1457  if (bc->forceBcPtr->data.value3 > 0)
1458  CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 1, 1,
1459  ProblemsManager::MarkOP::OR, 1,
1460  bc->bcMarkers);
1461  if (bc->forceBcPtr->data.value4 > 0)
1462  CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 2, 2,
1463  ProblemsManager::MarkOP::OR, 1,
1464  bc->bcMarkers);
1465 
1466  if (bc->forceBcPtr->data.value5 > 0) {
1467 
1468  CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 1, 1,
1469  ProblemsManager::MarkOP::OR, 1,
1470  bc->bcMarkers);
1471  CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 2, 2,
1472  ProblemsManager::MarkOP::OR, 1,
1473  bc->bcMarkers);
1474  }
1475  if (bc->forceBcPtr->data.value5) {
1476 
1477  CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 0, 0,
1478  ProblemsManager::MarkOP::OR, 1,
1479  bc->bcMarkers);
1480  CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 2, 2,
1481  ProblemsManager::MarkOP::OR, 1,
1482  bc->bcMarkers);
1483  }
1484  if (bc->forceBcPtr->data.value6) {
1485 
1486  CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 0, 0,
1487  ProblemsManager::MarkOP::OR, 1,
1488  bc->bcMarkers);
1489  CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 1, 1,
1490  ProblemsManager::MarkOP::OR, 1,
1491  bc->bcMarkers);
1492  }
1493  }
1494 
1495  if (get_low_dim_ents) {
1496  auto low_dim_ents =
1497  BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
1498  bc->bcEnts.swap(low_dim_ents);
1499  }
1500 
1501  CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
1502  bc->bcEnts);
1503  if (problem_name.size())
1504  CHKERR prb_mng->markDofs(problem_name, ROW, ProblemsManager::AND,
1505  bc->bcEnts, bc->bcMarkers);
1506 
1507  const std::string bc_id =
1508  problem_name + "_" + field_name + "_FORCESET" +
1509  boost::lexical_cast<std::string>(m->getMeshsetId());
1510  bcMapByBlockName[bc_id] = bc;
1511  }
1513  };
1514 
1515  CHKERR iterate_meshsets(
1516 
1518  FORCESET)
1519 
1520  );
1521 
1523  };
1524 
1525  CHKERR fix_force();
1526 
1528 }
1529 
1530 template <>
1531 MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<BcForceMeshsetType<BLOCKSET>>(
1532  const std::string problem_name, const std::string field_name,
1533  bool get_low_dim_ents, bool block_name_field_prefix) {
1534  Interface &m_field = cOre;
1535  auto prb_mng = m_field.getInterface<ProblemsManager>();
1537 
1538  if (problem_name.size() == 0)
1539  MOFEM_LOG("BcMngWorld", Sev::warning) << "Argument problem_name is empty";
1540 
1541  auto get_force_block = [&](auto block_name) {
1543 
1544  for (auto m :
1545  m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
1546 
1547  (boost::format("%s(.*)") % block_name).str()
1548 
1549  ))
1550 
1551  ) {
1552 
1553  const auto block_name = m->getName();
1554 
1555  MOFEM_LOG("BcMngWorld", Sev::inform)
1556  << "Found force block " << block_name;
1557 
1558  auto bc = boost::make_shared<BCs>();
1559  CHKERR m_field.get_moab().get_entities_by_handle(m->getMeshset(),
1560  bc->bcEnts, true);
1561 
1562  CHKERR m->getAttributes(bc->bcAttributes);
1563  if (bc->bcAttributes.size() != 3) {
1564  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
1565  "Expect three block attributes for force block");
1566  }
1567 
1568  bc->forceBcPtr = boost::make_shared<ForceCubitBcData>();
1569  // For details look at ForceCubitBcData in mofem/src/multi_indices/BCData.hpp
1570  bc->forceBcPtr->data.value1 = 1;
1571  bc->forceBcPtr->data.value3 = bc->bcAttributes[0];
1572  bc->forceBcPtr->data.value4 = bc->bcAttributes[1];
1573  bc->forceBcPtr->data.value5 = bc->bcAttributes[2];
1574 
1575  MOFEM_LOG("BcMngWorld", Sev::inform) << *bc->forceBcPtr;
1576  MOFEM_LOG("BcMngSync", Sev::noisy)
1577  << "Found block FORCESET id = " << m->getMeshsetId()
1578  << " nb. of entities " << bc->bcEnts.size()
1579  << " highest dim of entities "
1580  << BcManagerImplTools::get_dim(bc->bcEnts);
1581  MOFEM_LOG("BcMngSync", Sev::noisy) << *bc->forceBcPtr;
1582  MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
1583 
1584  if (problem_name.size()) {
1585 
1586  if (bc->forceBcPtr->data.value2 > 0)
1587  CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 0, 0,
1588  ProblemsManager::MarkOP::OR, 1,
1589  bc->bcMarkers);
1590  if (bc->forceBcPtr->data.value3 > 0)
1591  CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 1, 1,
1592  ProblemsManager::MarkOP::OR, 1,
1593  bc->bcMarkers);
1594  if (bc->forceBcPtr->data.value4 > 0)
1595  CHKERR prb_mng->modifyMarkDofs(problem_name, ROW, field_name, 2, 2,
1596  ProblemsManager::MarkOP::OR, 1,
1597  bc->bcMarkers);
1598  }
1599 
1600  if (get_low_dim_ents) {
1601  auto low_dim_ents =
1602  BcManagerImplTools::get_adj_ents(m_field.get_moab(), bc->bcEnts);
1603  bc->bcEnts.swap(low_dim_ents);
1604  }
1605 
1606  CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
1607  bc->bcEnts);
1608  if (problem_name.size())
1609  CHKERR prb_mng->markDofs(problem_name, ROW, ProblemsManager::AND,
1610  bc->bcEnts, bc->bcMarkers);
1611 
1612  const std::string bc_id =
1613  problem_name + "_" + field_name + "_" + block_name;
1614  bcMapByBlockName[bc_id] = bc;
1615  }
1617  };
1618 
1619  CHKERR get_force_block("FORCE");
1620 
1622 }
1623 
1624 template <>
1625 MoFEMErrorCode BcManager::pushMarkDOFsOnEntities<ForceCubitBcData>(
1626  const std::string problem_name, const std::string field_name,
1627  bool get_low_dim_ents, bool block_name_field_prefix) {
1629 
1630  CHKERR pushMarkDOFsOnEntities<BcMeshsetType<FORCESET>>(
1631  problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1632 
1633  CHKERR pushMarkDOFsOnEntities<BcForceMeshsetType<BLOCKSET>>(
1634  problem_name, field_name, get_low_dim_ents, block_name_field_prefix);
1635 
1637 }
1638 
1639 template <>
1640 MoFEMErrorCode BcManager::removeBlockDOFsOnEntities<BcMeshsetType<FORCESET>>(
1641  const std::string problem_name, const std::string field_name,
1642  bool get_low_dim_ents, bool block_name_field_prefix,
1643  bool is_distributed_mesh) {
1644  Interface &m_field = cOre;
1645  auto prb_mng = m_field.getInterface<ProblemsManager>();
1647 
1648  CHKERR pushMarkDOFsOnEntities<BcMeshsetType<FORCESET>>(
1649  problem_name, field_name, get_low_dim_ents);
1650 
1651  std::array<Range, 3> ents_to_remove;
1652 
1653  for (auto m :
1654 
1656  FORCESET)) {
1657 
1658  const auto block_name = m->getName();
1659  std::string bc_id = problem_name + "_" + field_name + "_" + block_name;
1660 
1661  auto str = boost::format("%s_%s_%s(.*)")
1662 
1663  % problem_name % field_name % block_name;
1664 
1665  if (std::regex_match(bc_id, std::regex(str.str()))) {
1666 
1667  auto bc = bcMapByBlockName.at(bc_id);
1668 
1669  if (auto force_bc = bc->forceBcPtr) {
1670  if (force_bc->data.value3 > 0) {
1671  ents_to_remove[0].merge(bc->bcEnts);
1672  }
1673  if (force_bc->data.value4 > 0) {
1674  ents_to_remove[1].merge(bc->bcEnts);
1675  }
1676  if (force_bc->data.value5 > 0) {
1677  ents_to_remove[2].merge(bc->bcEnts);
1678  }
1679  } else {
1680  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1681  "BC type not implemented");
1682  }
1683  }
1684  }
1685 
1686  auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
1687  const int hi) {
1688  if (is_distributed_mesh)
1689  return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
1690  hi);
1691  else
1692  return prb_mng->removeDofsOnEntitiesNotDistributed(
1693  problem_name, field_name, ents, lo, hi);
1694  };
1695 
1696  CHKERR remove_dofs_on_ents(ents_to_remove[0], 0, 0);
1697  CHKERR remove_dofs_on_ents(ents_to_remove[1], 1, 1);
1698  CHKERR remove_dofs_on_ents(ents_to_remove[2], 2, 2);
1699 
1701 }
1702 
1703 template <>
1705 BcManager::removeBlockDOFsOnEntities<BcForceMeshsetType<BLOCKSET>>(
1706  const std::string problem_name, const std::string field_name,
1707  bool get_low_dim_ents, bool block_name_field_prefix,
1708  bool is_distributed_mesh) {
1709  Interface &m_field = cOre;
1710  auto prb_mng = m_field.getInterface<ProblemsManager>();
1712 
1713  CHKERR pushMarkDOFsOnEntities<BcForceMeshsetType<BLOCKSET>>(
1714  problem_name, field_name, get_low_dim_ents);
1715 
1716  std::array<Range, 3> ents_to_remove;
1717 
1718  for (auto m :
1719 
1721  BLOCKSET | UNKNOWNNAME)) {
1722 
1723  const auto block_name = m->getName();
1724  std::string bc_id = problem_name + "_" + field_name + "_" + block_name;
1725 
1726  auto str = boost::format("%s_%s_%s(.*)")
1727 
1728  % problem_name % field_name % block_name;
1729 
1730  if (std::regex_match(bc_id, std::regex(str.str()))) {
1731 
1732  auto bc = bcMapByBlockName.at(bc_id);
1733 
1734  if (auto force_bc = bc->forceBcPtr) {
1735  if (force_bc->data.value3 > 0) {
1736  ents_to_remove[0].merge(bc->bcEnts);
1737  }
1738  if (force_bc->data.value4 > 0) {
1739  ents_to_remove[1].merge(bc->bcEnts);
1740  }
1741  if (force_bc->data.value5 > 0) {
1742  ents_to_remove[2].merge(bc->bcEnts);
1743  }
1744  } else {
1745  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1746  "BC type not implemented");
1747  }
1748  }
1749  }
1750 
1751  auto remove_dofs_on_ents = [&](const Range &ents, const int lo,
1752  const int hi) {
1753  if (is_distributed_mesh)
1754  return prb_mng->removeDofsOnEntities(problem_name, field_name, ents, lo,
1755  hi);
1756  else
1757  return prb_mng->removeDofsOnEntitiesNotDistributed(
1758  problem_name, field_name, ents, lo, hi);
1759  };
1760 
1761  CHKERR remove_dofs_on_ents(ents_to_remove[0], 0, 0);
1762  CHKERR remove_dofs_on_ents(ents_to_remove[1], 1, 1);
1763  CHKERR remove_dofs_on_ents(ents_to_remove[2], 2, 2);
1764 
1766 }
1767 
1768 template <>
1769 MoFEMErrorCode BcManager::removeBlockDOFsOnEntities<ForceCubitBcData>(
1770  const std::string problem_name, const std::string field_name,
1771  bool get_low_dim_ents, bool block_name_field_prefix,
1772  bool is_distributed_mesh) {
1774 
1775  CHKERR removeBlockDOFsOnEntities<BcMeshsetType<FORCESET>>(
1776  problem_name, field_name, get_low_dim_ents, block_name_field_prefix,
1777  is_distributed_mesh);
1778 
1779  CHKERR removeBlockDOFsOnEntities<BcForceMeshsetType<BLOCKSET>>(
1780  problem_name, field_name, get_low_dim_ents, block_name_field_prefix,
1781  is_distributed_mesh);
1782 
1784 };
1785 
1786 } // namespace MoFEM
MoFEMFunctionReturnHot
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:447
MoFEM::UnknownInterface::getInterface
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface refernce to pointer of interface.
Definition: UnknownInterface.hpp:93
CHK_MOAB_THROW
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
Definition: definitions.h:576
MoFEM::BcManager::extractStringFromBlockId
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:1389
SIDESET
@ SIDESET
Definition: definitions.h:147
MoFEM::LogManager::checkIfChannelExist
static bool checkIfChannelExist(const std::string channel)
Check if channel exist.
Definition: LogManager.cpp:404
MoFEM::CoreTmp< 0 >
Core (interface) class.
Definition: Core.hpp:82
MoFEM::BcManager::popMarkDOFsOnEntities
boost::shared_ptr< BCs > popMarkDOFsOnEntities(const std::string block_name)
Get bc data and remove element.
Definition: BcManager.cpp:357
MOFEM_LOG_SEVERITY_SYNC
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
Definition: LogManager.hpp:352
sdf_hertz.d
float d
Definition: sdf_hertz.py:5
MoFEM::BcManager::query_interface
MoFEMErrorCode query_interface(boost::typeindex::type_index type_index, UnknownInterface **iface) const
Definition: BcManager.cpp:34
MoFEM::ProblemsManager
Problem manager is used to build and partition problems.
Definition: ProblemsManager.hpp:21
MoFEM::BcManager::BcManager
BcManager(const MoFEM::Core &core)
Definition: BcManager.cpp:41
MoFEM::CoreInterface::get_comm
virtual MPI_Comm & get_comm() const =0
MoFEM::BcManager::cOre
MoFEM::Core & cOre
Definition: BcManager.hpp:332
CHK_THROW_MESSAGE
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
Definition: definitions.h:596
MoFEM::Exceptions::MoFEMErrorCode
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
MoFEM::CubitMeshSets
this struct keeps basic methods for moab meshset about material and boundary conditions
Definition: BCMultiIndices.hpp:19
MoFEM::BcManager::getOptions
MoFEMErrorCode getOptions()
get options
Definition: BcManager.cpp:65
MoFEM::BcManager::removeBlockDOFsOnEntities
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
MoFEM::BcManager::getMergedBlocksMarker
BcMarkerPtr getMergedBlocksMarker(std::vector< std::regex > bc_regex_vec)
Get the Merged Boundary Marker object.
Definition: BcManager.cpp:382
MoFEM::LogManager::createSink
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
MoFEM::DeprecatedCoreInterface
Deprecated interface functions.
Definition: DeprecatedCoreInterface.hpp:16
UNKNOWNNAME
@ UNKNOWNNAME
Definition: definitions.h:158
ROW
@ ROW
Definition: definitions.h:123
MoFEM::Interface
DeprecatedCoreInterface Interface
Definition: Interface.hpp:1975
MoFEM::BcManager::pushMarkDOFsOnEntities
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
NODESET
@ NODESET
Definition: definitions.h:146
CHKERR
#define CHKERR
Inline error check.
Definition: definitions.h:535
MoFEM::CoreInterface::get_moab
virtual moab::Interface & get_moab()=0
MoFEM
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:10
MoFEM::ISManager
Section manager is used to create indexes and sections.
Definition: ISManager.hpp:23
a
constexpr double a
Definition: approx_sphere.cpp:30
MoFEM::BcManager
Simple interface for fast problem set-up.
Definition: BcManager.hpp:25
FORCESET
@ FORCESET
Definition: definitions.h:151
MoFEM::BcManagerImplTools::get_dim
auto get_dim(const Range &ents)
Definition: BcManager.cpp:10
MoFEM::BcManager::getBcMapByBlockName
BcMapByBlockName & getBcMapByBlockName()
Get the bc map.
Definition: BcManager.hpp:207
DISPLACEMENTSET
@ DISPLACEMENTSET
Definition: definitions.h:150
MoFEM::LogManager::getStrmSync
static boost::shared_ptr< std::ostream > getStrmSync()
Get the strm sync object.
Definition: LogManager.cpp:348
MoFEM::BcManager::getBlockIS
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:413
MoFEM::LogManager::getStrmWorld
static boost::shared_ptr< std::ostream > getStrmWorld()
Get the strm world object.
Definition: LogManager.cpp:344
MoFEM::LogManager::getStrmSelf
static boost::shared_ptr< std::ostream > getStrmSelf()
Get the strm self object.
Definition: LogManager.cpp:340
MoFEM::BcManager::getMergedBlocksRange
Range getMergedBlocksRange(std::vector< std::regex > bc_regex_vec)
Merge block ranges.
Definition: BcManager.cpp:367
MoFEM::BcManager::BcMarkerPtr
boost::shared_ptr< std::vector< char unsigned > > BcMarkerPtr
Definition: BcManager.hpp:191
MOFEM_LOG_TAG
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
Definition: LogManager.hpp:339
i
FTensor::Index< 'i', SPACE_DIM > i
Definition: hcurl_divergence_operator_2d.cpp:27
field_name
constexpr auto field_name
Definition: poisson_2d_homogeneous.cpp:13
MoFEM::ProblemsManager::AND
@ AND
Definition: ProblemsManager.hpp:365
MoFEM::BcManager::addBlockDOFsToMPCs
MoFEMErrorCode addBlockDOFsToMPCs(const std::string problem_name, const std::string field_name, bool get_low_dim_ents=false, bool block_name_field_prefix=false, bool is_distributed_mesh=false)
Definition: BcManager.cpp:185
MoFEM::UnknownInterface
base class for all interface classes
Definition: UnknownInterface.hpp:34
MAX_DOFS_ON_ENTITY
#define MAX_DOFS_ON_ENTITY
Maximal number of DOFs on entity.
Definition: definitions.h:236
Range
FTensor::dd
const Tensor2_symmetric_Expr< const ddTensor0< T, Dim, i, j >, typename promote< T, double >::V, Dim, i, j > dd(const Tensor0< T * > &a, const Index< i, Dim > index1, const Index< j, Dim > index2, const Tensor1< int, Dim > &d_ijk, const Tensor1< double, Dim > &d_xyz)
Definition: ddTensor0.hpp:33
MOFEM_LOG
#define MOFEM_LOG(channel, severity)
Log.
Definition: LogManager.hpp:308
MoFEM::CommInterface
Managing BitRefLevels.
Definition: CommInterface.hpp:21
BLOCKSET
@ BLOCKSET
Definition: definitions.h:148
MoFEM::BcManager::bcMapByBlockName
BcMapByBlockName bcMapByBlockName
Definition: BcManager.hpp:334
MoFEM::Exceptions::ierr
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
Definition: Exceptions.hpp:76
MOFEM_DATA_INCONSISTENCY
@ MOFEM_DATA_INCONSISTENCY
Definition: definitions.h:31
TEMPERATURESET
@ TEMPERATURESET
Definition: definitions.h:155
MoFEM::MeshsetsManager
Interface for managing meshsets containing materials and boundary conditions.
Definition: MeshsetsManager.hpp:104
m
FTensor::Index< 'm', 3 > m
Definition: shallow_wave.cpp:80
MoFEMFunctionBeginHot
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:440
HEATFLUXSET
@ HEATFLUXSET
Definition: definitions.h:156
MoFEM::DisplacementCubitBcDataWithRotation
A specialized version of DisplacementCubitBcData that includes an additional rotation offset.
Definition: EssentialDisplacementCubitBcData.hpp:24
MoFEM::MeshsetsManager::getCubitMeshsetPtr
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
Definition: MeshsetsManager.cpp:575
MoFEM::LogManager::setLog
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
Definition: LogManager.cpp:389
MoFEM::SmartPetscObj< IS >
MoFEM::MeshsetsManager::checkMeshset
bool checkMeshset(const int ms_id, const CubitBCType cubit_bc_type) const
check for CUBIT Id and CUBIT type
Definition: MeshsetsManager.cpp:357
MoFEMFunctionReturn
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:416
CHKERRG
#define CHKERRG(n)
Check error code of MoFEM/MOAB/PETSc function.
Definition: definitions.h:483
MoFEMFunctionBegin
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:346
l
FTensor::Index< 'l', 3 > l
Definition: matrix_function.cpp:21
MoFEM::BcManagerImplTools::get_adj_ents
auto get_adj_ents(moab::Interface &moab, const Range &ents)
Definition: BcManager.cpp:17
MoFEM::MPC::COUPLING
@ COUPLING