v0.9.1
ProblemsCore.cpp
Go to the documentation of this file.
1 /** \file ProblemsCore.cpp
2  * \brief Managing complexities for problem
3  */
4 
5 /* MoFEM is free software: you can redistribute it and/or modify it under
6  * the terms of the GNU Lesser General Public License as published by the
7  * Free Software Foundation, either version 3 of the License, or (at your
8  * option) any later version.
9  *
10  * MoFEM is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
13  * License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with MoFEM. If not, see <http://www.gnu.org/licenses/>
17  */
18 
19 namespace MoFEM {
20 
21 bool Core::check_problem(const string name) {
22  Problem_multiIndex::index<Problem_mi_tag>::type::iterator pit;
23  pit = pRoblems.get<Problem_mi_tag>().find(name);
24  if (pit == pRoblems.get<Problem_mi_tag>().end()) {
25  return false;
26  }
27  return true;
28 }
29 
30 MoFEMErrorCode Core::addProblem(const BitProblemId id, const std::string &name,
31  int verb) {
33  if (verb == -1)
34  verb = verbose;
35  EntityHandle meshset;
36  CHKERR get_moab().create_meshset(MESHSET_SET | MESHSET_TRACK_OWNER, meshset);
37  CHKERR get_moab().tag_set_data(th_ProblemId, &meshset, 1, &id);
38 
39  // Add problem meshset to partion meshset. In case of no elements
40  // on processor part, when mesh file is read, finite element meshset is
41  // prevented from deletion by moab reader.
42  auto add_meshset_to_partition = [&](auto meshset) {
44  const void *tag_vals[] = {&rAnk};
45  ParallelComm *pcomm = ParallelComm::get_pcomm(
46  &get_moab(), get_basic_entity_data_ptr()->pcommID);
47  Tag part_tag = pcomm->part_tag();
48  Range tagged_sets;
49  CHKERR get_moab().get_entities_by_type_and_tag(0, MBENTITYSET, &part_tag,
50  tag_vals, 1, tagged_sets,
51  moab::Interface::UNION);
52  for (auto s : tagged_sets)
53  CHKERR get_moab().add_entities(s, &meshset, 1);
55  };
56  CHKERR add_meshset_to_partition(meshset);
57 
58  void const *tag_data[] = {name.c_str()};
59  int tag_sizes[1];
60  tag_sizes[0] = name.size();
61  CHKERR get_moab().tag_set_by_ptr(th_ProblemName, &meshset, 1, tag_data,
62  tag_sizes);
63  // create entry
64  std::pair<Problem_multiIndex::iterator, bool> p =
65  pRoblems.insert(Problem(moab, meshset));
66  NOT_USED(p);
67  assert(p.second);
68  if (verb > 0) {
69  std::ostringstream ss;
70  ss << "add problem: " << name << std::endl;
71  PetscPrintf(cOmm, ss.str().c_str());
72  }
74 }
75 
76 MoFEMErrorCode Core::add_problem(const std::string &name, enum MoFEMTypes bh,
77  int verb) {
79  if (verb == -1)
80  verb = verbose;
81  auto miit = pRoblems.get<Problem_mi_tag>().find(name);
82  if (miit == pRoblems.get<Problem_mi_tag>().end()) {
84  CHKERR addProblem(id, name, verb);
85  } else if (bh == MF_EXCL) {
86  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "problem is in database %s",
87  name.c_str());
88  }
90 }
91 
92 MoFEMErrorCode Core::delete_problem(const std::string name) {
94  auto p_miit = pRoblems.get<Problem_mi_tag>().find(name);
95  if (p_miit == pRoblems.get<Problem_mi_tag>().end()) {
96  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "no such problem like < %s >",
97  name.c_str());
98  }
99  const EntityHandle meshset = p_miit->meshset;
100  pRoblems.get<Problem_mi_tag>().erase(p_miit);
101  CHKERR get_moab().delete_entities(&meshset, 1);
103 }
104 
105 BitProblemId Core::getBitProblemId(const std::string &name) const {
106  auto p_miit = pRoblems.get<Problem_mi_tag>().find(name);
107  if (p_miit == pRoblems.get<Problem_mi_tag>().end()) {
108  THROW_MESSAGE("no such problem like " + name + " >");
109  }
110  return p_miit->getId();
111 }
112 
116  const ProblemById &set_id = pRoblems.get<BitProblemId_mi_tag>();
117  ProblemById::iterator miit = set_id.begin();
118  for (; miit != set_id.end(); miit++) {
119  std::ostringstream ss;
120  ss << *miit << std::endl;
121  PetscPrintf(cOmm, ss.str().c_str());
122  }
124 }
125 
127 Core::modify_problem_add_finite_element(const std::string &name_problem,
128  const std::string &fe_name) {
131  ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
132  ProblemsByName::iterator miit = set.find(name_problem);
133  if (miit == set.end()) {
134  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "this problem <%s> is not there",
135  name_problem.c_str());
136  }
137  BitFEId f_id = getBitFEId(fe_name);
138  bool success = set.modify(miit, ProblemFiniteElementChangeBitAdd(f_id));
139  if (!success)
140  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
141  "modification unsuccessful");
143 }
144 
146 Core::modify_problem_unset_finite_element(const std::string &name_problem,
147  const std::string &fe_name) {
150  ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
151  ProblemsByName::iterator miit = set.find(name_problem);
152  if (miit == set.end()) {
153  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "this problem <%s> is not there",
154  name_problem.c_str());
155  }
156  BitFEId f_id = getBitFEId(fe_name);
157  bool success = set.modify(miit, ProblemFiniteElementChangeBitUnSet(f_id));
158  if (!success)
159  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
160  "modification unsuccessful");
162 }
163 
165 Core::modify_problem_ref_level_add_bit(const std::string &name_problem,
166  const BitRefLevel &bit) {
169  ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
170  ProblemsByName::iterator miit = set.find(name_problem);
171  std::ostringstream ss;
172  ss << name_problem;
173  if (miit == set.end())
174  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "this problem <%s> is there",
175  ss.str().c_str());
176  bool success = set.modify(miit, ProblemChangeRefLevelBitAdd(bit));
177  if (!success)
178  SETERRQ(PETSC_COMM_SELF, 1, "modification unsuccessful");
180 }
181 
183 Core::modify_problem_ref_level_set_bit(const std::string &name_problem,
184  const BitRefLevel &bit) {
187  ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
188  ProblemsByName::iterator miit = set.find(name_problem);
189  std::ostringstream ss;
190  ss << name_problem;
191  if (miit == set.end())
192  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "this problem <%s> is there",
193  ss.str().c_str());
194  bool success = set.modify(miit, ProblemChangeRefLevelBitSet(bit));
195  if (!success)
196  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
197  "modification unsuccessful");
199 }
200 
202 Core::modify_problem_mask_ref_level_add_bit(const std::string &name_problem,
203  const BitRefLevel &bit) {
206  ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
207  ProblemsByName::iterator miit = set.find(name_problem);
208  if (miit == set.end()) {
209  std::ostringstream ss;
210  ss << name_problem;
211  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "this problem <%s> is there",
212  ss.str().c_str());
213  }
214  bool success = set.modify(miit, ProblemChangeRefLevelBitDofMaskAdd(bit));
215  if (!success)
216  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
217  "modification unsuccessful");
219 }
220 
222 Core::modify_problem_mask_ref_level_set_bit(const std::string &name_problem,
223  const BitRefLevel &bit) {
226  ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
227  ProblemsByName::iterator miit = set.find(name_problem);
228  if (miit == set.end()) {
229  std::ostringstream ss;
230  ss << name_problem;
231  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "this problem <%s> is there",
232  ss.str().c_str());
233  }
234  bool success = set.modify(miit, ProblemChangeRefLevelBitDofMaskSet(bit));
235  if (!success)
236  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
237  "modification unsuccessful");
239 }
240 
243  if (verb == -1)
244  verb = verbose;
245  Problem_multiIndex::iterator p_miit = pRoblems.begin();
246  for (; p_miit != pRoblems.end(); p_miit++) {
247  CHKERR getInterface<ProblemsManager>()->buildProblemOnDistributedMesh(
248  const_cast<Problem *>(&*p_miit), verb);
249  }
251 }
252 
253 MoFEMErrorCode Core::clear_problem(const std::string problem_name, int verb) {
255  if (verb == -1)
256  verb = verbose;
258  ProblemsByName &prob_by_name = pRoblems.get<Problem_mi_tag>();
259  ProblemsByName::iterator p_miit = prob_by_name.find(problem_name);
260  if (p_miit == prob_by_name.end()) {
261  SETERRQ1(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
262  "problem < %s > not found, (top tip: check spelling)",
263  problem_name.c_str());
264  }
265  // zero rows
266  bool success = prob_by_name.modify(p_miit, ProblemZeroNbRowsChange());
267  if (!success)
268  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
269  "modification unsuccessful");
270  // zero cols
271  success = prob_by_name.modify(p_miit, ProblemZeroNbColsChange());
272  if (!success)
273  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
274  "modification unsuccessful");
275  // clear finite elements
276  success =
277  prob_by_name.modify(p_miit, ProblemClearNumeredFiniteElementsChange());
278  if (!success)
279  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
280  "modification unsuccessful");
281  // clear data structures
282  success = prob_by_name.modify(p_miit, ProblemClearSubProblemData());
283  if (!success)
284  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
285  "modification unsuccessful");
286  success = prob_by_name.modify(p_miit, ProblemClearComposedProblemData());
287  if (!success)
288  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
289  "modification unsuccessful");
290  if (p_miit->getRowDofsSequence())
291  p_miit->getRowDofsSequence()->clear();
292  if (p_miit->getColDofsSequence())
293  p_miit->getColDofsSequence()->clear();
294  if (p_miit->getSubData())
295  p_miit->getSubData().reset();
296  if (p_miit->getComposedProblemsData())
297  p_miit->getComposedProblemsData().reset();
299 }
300 
303  if (verb == -1)
304  verb = verbose;
305  if (!((*buildMoFEM) & BUILD_FIELD))
306  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "fields not build");
307  if (!((*buildMoFEM) & BUILD_FE))
308  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "FEs not build");
309  if (!((*buildMoFEM) & BUILD_ADJ))
310  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "adjacencies not build");
311  // iterate problems
312  Problem_multiIndex::iterator p_miit = pRoblems.begin();
313  for (; p_miit != pRoblems.end(); p_miit++) {
314  Problem *problem_ptr = const_cast<Problem *>(&*p_miit);
315  CHKERR getInterface<ProblemsManager>()->buildProblem(problem_ptr, false,
316  verb);
317  }
320 }
321 
324  if (verb == -1)
325  verb = verbose;
326  // iterate problems
327  for (auto p_miit = pRoblems.begin(); p_miit != pRoblems.end(); p_miit++)
328  CHKERR clear_problem(p_miit->getName(), verb);
330 }
331 
332 #define SET_BASIC_METHOD(METHOD, PROBLEM_PTR) \
333  { \
334  METHOD.rAnk = rAnk; \
335  METHOD.sIze = sIze; \
336  METHOD.problemPtr = PROBLEM_PTR; \
337  METHOD.fieldsPtr = &fIelds; \
338  METHOD.refinedEntitiesPtr = &refinedEntities; \
339  METHOD.entitiesPtr = &entsFields; \
340  METHOD.dofsPtr = &dofsField; \
341  METHOD.refinedFiniteElementsPtr = &refinedFiniteElements; \
342  METHOD.finiteElementsPtr = &finiteElements; \
343  METHOD.finiteElementsEntitiesPtr = &entsFiniteElements; \
344  METHOD.adjacenciesPtr = &entFEAdjacencies; \
345  }
346 
348  BasicMethod &method,
349  int verb) {
351  if (verb == -1)
352  verb = verbose;
353  // finite element
354  SET_BASIC_METHOD(method, problem_ptr)
355  PetscLogEventBegin(MOFEM_EVENT_preProcess, 0, 0, 0, 0);
356  CHKERR method.preProcess();
357  PetscLogEventEnd(MOFEM_EVENT_preProcess, 0, 0, 0, 0);
359 }
360 
362 Core::problem_basic_method_preProcess(const std::string &problem_name,
363  BasicMethod &method, int verb) {
365  if (verb == -1)
366  verb = verbose;
368  // find p_miit
369  ProblemsByName &pRoblems_set = pRoblems.get<Problem_mi_tag>();
370  ProblemsByName::iterator p_miit = pRoblems_set.find(problem_name);
371  if (p_miit == pRoblems_set.end())
372  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "problem is not in database %s",
373  problem_name.c_str());
374  CHKERR problem_basic_method_preProcess(&*p_miit, method, verb);
376 }
377 
380  BasicMethod &method, int verb) {
382  SET_BASIC_METHOD(method, problem_ptr)
383 
384  PetscLogEventBegin(MOFEM_EVENT_postProcess, 0, 0, 0, 0);
385  CHKERR method.postProcess();
386  PetscLogEventEnd(MOFEM_EVENT_postProcess, 0, 0, 0, 0);
387 
389 }
390 
392 Core::problem_basic_method_postProcess(const std::string &problem_name,
393  BasicMethod &method, int verb) {
395  if (verb == -1)
396  verb = verbose;
398 
399  // find p_miit
400  ProblemsByName &pRoblems_set = pRoblems.get<Problem_mi_tag>();
401  ProblemsByName::iterator p_miit = pRoblems_set.find(problem_name);
402  if (p_miit == pRoblems_set.end())
403  SETERRQ1(cOmm, 1, "problem is not in database %s", problem_name.c_str());
404 
405  CHKERR problem_basic_method_postProcess(&*p_miit, method, verb);
406 
408 }
409 
411  const Problem *problem_ptr, const std::string &fe_name, FEMethod &method,
412  int lower_rank, int upper_rank,
413  boost::shared_ptr<NumeredEntFiniteElement_multiIndex> fe_ptr, MoFEMTypes bh,
414  int verb) {
416  if (verb == DEFAULT_VERBOSITY)
417  verb = verbose;
418 
419  method.feName = fe_name;
420  SET_BASIC_METHOD(method, &*problem_ptr)
421  PetscLogEventBegin(MOFEM_EVENT_preProcess, 0, 0, 0, 0);
422  CHKERR method.preProcess();
423  PetscLogEventEnd(MOFEM_EVENT_preProcess, 0, 0, 0, 0);
424 
425  if (!fe_ptr)
426  fe_ptr = problem_ptr->numeredFiniteElements;
427 
428  auto miit = fe_ptr->get<Composite_Name_And_Part_mi_tag>().lower_bound(
429  boost::make_tuple(fe_name, lower_rank));
430  auto hi_miit = fe_ptr->get<Composite_Name_And_Part_mi_tag>().upper_bound(
431  boost::make_tuple(fe_name, upper_rank));
432 
433  if (miit == hi_miit && (bh & MF_EXIST)) {
434  if (!check_finite_element(fe_name)) {
435  SETERRQ1(cOmm, MOFEM_NOT_FOUND, "finite element < %s > not found",
436  fe_name.c_str());
437  }
438  }
439 
440  method.loopSize = std::distance(miit, hi_miit);
441  for (int nn = 0; miit != hi_miit; miit++, nn++) {
442 
443  method.nInTheLoop = nn;
444  method.numeredEntFiniteElementPtr = *miit;
445  method.dataFieldEntsPtr = (*miit)->sPtr->data_field_ents_view;
446  method.rowFieldEntsPtr = (*miit)->sPtr->row_field_ents_view;
447  method.colFieldEntsPtr = (*miit)->sPtr->col_field_ents_view;
448  method.dataPtr = (*miit)->sPtr->data_dofs;
449  method.rowPtr = (*miit)->rows_dofs;
450  method.colPtr = (*miit)->cols_dofs;
451 
452  PetscLogEventBegin(MOFEM_EVENT_operator, 0, 0, 0, 0);
453  CHKERR method();
454  PetscLogEventEnd(MOFEM_EVENT_operator, 0, 0, 0, 0);
455  }
456 
457  PetscLogEventBegin(MOFEM_EVENT_postProcess, 0, 0, 0, 0);
458  CHKERR method.postProcess();
459  PetscLogEventEnd(MOFEM_EVENT_postProcess, 0, 0, 0, 0);
460 
462 }
463 
465  const std::string &problem_name, const std::string &fe_name,
466  FEMethod &method,
467  boost::shared_ptr<NumeredEntFiniteElement_multiIndex> fe_ptr, MoFEMTypes bh,
468  int verb) {
470  if (verb == DEFAULT_VERBOSITY)
471  verb = verbose;
472 
473  CHKERR loop_finite_elements(problem_name, fe_name, method, rAnk, rAnk, fe_ptr,
474  bh, verb);
475 
477 }
478 
480  const std::string &problem_name, const std::string &fe_name,
481  FEMethod &method, int lower_rank, int upper_rank,
482  boost::shared_ptr<NumeredEntFiniteElement_multiIndex> fe_ptr, MoFEMTypes bh,
483  int verb) {
485  if (verb == DEFAULT_VERBOSITY)
486  verb = verbose;
487 
488  auto &prb_by_name = pRoblems.get<Problem_mi_tag>();
489  auto p_miit = prb_by_name.find(problem_name);
490  if (p_miit == prb_by_name.end())
491  SETERRQ1(cOmm, MOFEM_INVALID_DATA, "Problem <%s> is not in database",
492  problem_name.c_str());
493 
494  CHKERR loop_finite_elements(&*p_miit, fe_name, method, lower_rank, upper_rank,
495  fe_ptr, bh, verb);
496 
498 }
499 
501  const std::string &field_name, RowColData rc,
502  DofMethod &method, int lower_rank,
503  int upper_rank, int verb) {
505  SET_BASIC_METHOD(method, &*problem_ptr);
506  typedef NumeredDofEntity_multiIndex::index<
507  Composite_Name_And_Part_mi_tag>::type NumeredDofsByNameAndPart;
508  NumeredDofsByNameAndPart *dofs;
509  switch (rc) {
510  case ROW:
511  dofs = &problem_ptr->numeredDofsRows->get<Composite_Name_And_Part_mi_tag>();
512  break;
513  case COL:
514  dofs = &problem_ptr->numeredDofsCols->get<Composite_Name_And_Part_mi_tag>();
515  break;
516  default:
517  SETERRQ(cOmm, MOFEM_DATA_INCONSISTENCY, "not implemented");
518  }
519  NumeredDofsByNameAndPart::iterator miit =
520  dofs->lower_bound(boost::make_tuple(field_name, lower_rank));
521  NumeredDofsByNameAndPart::iterator hi_miit =
522  dofs->upper_bound(boost::make_tuple(field_name, upper_rank));
523  if (miit != hi_miit) {
524  method.fieldPtr = miit->get()->getFieldPtr();
525  } else {
526  Field_multiIndex::index<FieldName_mi_tag>::type::iterator field_it =
527  fIelds.get<FieldName_mi_tag>().find(field_name);
528  if (field_it != fIelds.get<FieldName_mi_tag>().end()) {
529  method.fieldPtr = *field_it;
530  }
531  }
532  CHKERR method.preProcess();
533  for (; miit != hi_miit; miit++) {
534  method.dofPtr = miit->get()->getDofEntityPtr();
535  method.dofNumeredPtr = *miit;
536  CHKERR method();
537  }
538  CHKERR method.postProcess();
540 }
541 
543  const std::string &problem_name, const std::string &field_name,
544  RowColData rc, // ROW or COL
545  DofMethod &method, // Finite element instance processed on each DOF
546  int lower_rank, // Only DOFs on processor higher or equal to this are
547  // processed
548  int upper_rank, // Only DOFs lowest or higher to this are processed
549  int verb // verbosity level
550 ) {
552  if (verb == DEFAULT_VERBOSITY)
553  verb = verbose;
555  // find p_miit
556  ProblemsByName &pRoblems_set = pRoblems.get<Problem_mi_tag>();
557  ProblemsByName::iterator p_miit = pRoblems_set.find(problem_name);
558  if (p_miit == pRoblems_set.end())
559  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "problem not in database %s",
560  problem_name.c_str());
561  CHKERR loop_dofs(&*p_miit, field_name, rc, method, lower_rank, upper_rank,
562  verb);
564 }
565 
566 MoFEMErrorCode Core::loop_dofs(const std::string &problem_name,
567  const std::string &field_name, RowColData rc,
568  DofMethod &method, int verb) {
570  if (verb == DEFAULT_VERBOSITY)
571  verb = verbose;
572  CHKERR loop_dofs(problem_name, field_name, rc, method, 0, sIze, verb);
574 }
575 
576 MoFEMErrorCode Core::loop_dofs(const std::string &field_name, DofMethod &method,
577  int verb) {
579  if (verb == DEFAULT_VERBOSITY)
580  verb = verbose;
581  SET_BASIC_METHOD(method, nullptr);
582  auto miit = dofsField.get<FieldName_mi_tag>().lower_bound(field_name);
583  auto hi_miit = dofsField.get<FieldName_mi_tag>().upper_bound(field_name);
584  if (miit != hi_miit) {
585  method.fieldPtr = miit->get()->getFieldPtr();
586  } else {
587  auto field_it = fIelds.get<FieldName_mi_tag>().find(field_name);
588  if (field_it != fIelds.get<FieldName_mi_tag>().end()) {
589  method.fieldPtr = *field_it;
590  }
591  }
592  method.loopSize = std::distance(miit, hi_miit);
593  CHKERR method.preProcess();
594  for (int nn = 0; miit != hi_miit; miit++, nn++) {
595  method.nInTheLoop = nn;
596  method.dofPtr = *miit;
597  CHKERR method();
598  }
599  CHKERR method.postProcess();
601 }
602 
604  const std::string field_name, RowColData rc,
605  EntityMethod &method, int lower_rank,
606  int upper_rank, int verb) {
608  if (verb == DEFAULT_VERBOSITY)
609  verb = verbose;
610  decltype(problem_ptr->numeredDofsRows) dofs;
611  switch (rc) {
612  case ROW:
613  dofs = problem_ptr->numeredDofsRows;
614  break;
615  case COL:
616  dofs = problem_ptr->numeredDofsCols;
617  break;
618  default:
620  "It works only with rows or columns");
621  }
622  auto miit = dofs->get<Composite_Name_And_Part_mi_tag>().lower_bound(
623  boost::make_tuple(field_name, lower_rank));
624  auto hi_miit = dofs->get<Composite_Name_And_Part_mi_tag>().upper_bound(
625  boost::make_tuple(field_name, upper_rank));
626  if (miit != hi_miit) {
627  method.fieldPtr = miit->get()->getFieldPtr();
628  } else {
629  Field_multiIndex::index<FieldName_mi_tag>::type::iterator field_it =
630  fIelds.get<FieldName_mi_tag>().find(field_name);
631  if (field_it != fIelds.get<FieldName_mi_tag>().end()) {
632  method.fieldPtr = *field_it;
633  }
634  }
635 
636  typedef multi_index_container<
637  boost::shared_ptr<FieldEntity>,
638  indexed_by<ordered_unique<
639  tag<Ent_mi_tag>,
640  const_mem_fun<FieldEntity, EntityHandle, &FieldEntity::getEnt>>>>
641  FieldEntity_view_multiIndex;
642  FieldEntity_view_multiIndex ents_view;
643  auto hint = ents_view.begin();
644  for (; miit != hi_miit; ++miit)
645  ents_view.emplace_hint(hint, (*miit)->getFieldEntityPtr());
646 
647  method.loopSize = ents_view.size();
648  SET_BASIC_METHOD(method, problem_ptr);
649  CHKERR method.preProcess();
650  method.nInTheLoop = 0;
651  for (auto &field_ent : ents_view) {
652  method.entPtr = field_ent;
653  CHKERR method();
654  ++method.nInTheLoop;
655  }
656  CHKERR method.postProcess();
658 }
659 
660 MoFEMErrorCode Core::loop_entities(const std::string problem_name,
661  const std::string field_name, RowColData rc,
662  EntityMethod &method, int lower_rank,
663  int upper_rank, int verb) {
665  if (verb == DEFAULT_VERBOSITY)
666  verb = verbose;
668  // find p_miit
669  ProblemsByName &pRoblems_set = pRoblems.get<Problem_mi_tag>();
670  ProblemsByName::iterator p_miit = pRoblems_set.find(problem_name);
671  if (p_miit == pRoblems_set.end())
672  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "problem not in database %s",
673  problem_name.c_str());
674  CHKERR loop_entities(&*p_miit, field_name, rc, method, lower_rank, upper_rank,
675  verb);
677 }
678 
679 MoFEMErrorCode Core::loop_entities(const std::string problem_name,
680  const std::string field_name, RowColData rc,
681  EntityMethod &method, int verb) {
682  return loop_entities(problem_name, field_name, rc, method, rAnk, rAnk, verb);
683 }
684 
685 MoFEMErrorCode Core::loop_entities(const std::string field_name,
686  EntityMethod &method,
687  Range const *const ents, int verb) {
689  if (verb == DEFAULT_VERBOSITY)
690  verb = verbose;
691  SET_BASIC_METHOD(method, nullptr);
692  auto r = entsFields.get<FieldName_mi_tag>().equal_range(field_name);
693  if (r.first != r.second) {
694  method.fieldPtr = (*r.first)->getFieldPtr();
695  } else {
696  auto field_it = fIelds.get<FieldName_mi_tag>().find(field_name);
697  if (field_it != fIelds.get<FieldName_mi_tag>().end()) {
698  method.fieldPtr = *field_it;
699  }
700  }
701 
702  typedef multi_index_container<
703  boost::shared_ptr<FieldEntity>,
704  indexed_by<
705  ordered_unique<tag<Ent_mi_tag>,
706  const_mem_fun<FieldEntity::interface_RefEntity,
708  FieldEntity_view_multiIndex;
709 
710  FieldEntity_view_multiIndex ents_view;
711  ents_view.insert(r.first, r.second);
712 
713  method.loopSize = ents_view.size();
714  CHKERR method.preProcess();
715  method.nInTheLoop = 0;
716 
717  if (ents)
718  for (auto p = ents->const_pair_begin(); p != ents->const_pair_end(); ++p)
719  for (auto feit = ents_view.lower_bound(p->first);
720  feit != ents_view.upper_bound(p->second); ++feit) {
721  method.entPtr = *feit;
722  CHKERR method();
723  ++method.nInTheLoop;
724  }
725  else
726  for (auto &field_ent : ents_view) {
727  method.entPtr = field_ent;
728  CHKERR method();
729  ++method.nInTheLoop;
730  }
731 
732  CHKERR method.postProcess();
734 }
735 } // namespace MoFEM
MoFEMErrorCode modify_problem_mask_ref_level_add_bit(const std::string &name_problem, const BitRefLevel &bit)
set dof mask ref level for problem
boost::shared_ptr< DofEntity > dofPtr
Clear sub-problem data structure.
DofEntity_multiIndex dofsField
dofs on fields
Definition: Core.hpp:249
structure for User Loop Methods on finite elementsIt can be used to calculate stiffness matrices,...
boost::shared_ptr< Field > fieldPtr
int sIze
MoFEM communicator size.
Definition: Core.hpp:849
PetscLogEvent MOFEM_EVENT_postProcess
Event for postProcess finite element.
Definition: Core.hpp:837
MPI_Comm cOmm
MoFEM communicator.
Definition: Core.hpp:846
FieldEntity_multiIndex entsFields
entities on fields
Definition: Core.hpp:248
int loopSize
local number oe methods to process
moab::Interface & get_moab()
Definition: Core.hpp:266
Data structure to exchange data between mofem and User Loop Methods on entities.It allows to exchange...
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:506
PetscLogEvent MOFEM_EVENT_operator
Event for evaluating operator of finite element.
Definition: Core.hpp:835
boost::shared_ptr< const FieldEntity_vector_view > colFieldEntsPtr
Pointer to finite element field entities column view.
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:482
MoFEMErrorCode loop_dofs(const Problem *problem_ptr, const std::string &field_name, RowColData rc, DofMethod &method, int lower_rank, int upper_rank, int verb=DEFAULT_VERBOSITY)
Make a loop over dofs.
MoFEMErrorCode clear_problem(const std::string name, int verb=DEFAULT_VERBOSITY)
clear problem
DEPRECATED MoFEMErrorCode build_problem_on_distributed_mesh(int verb=DEFAULT_VERBOSITY)
build problem data structures, assuming that mesh is distributed (collective)
std::string feName
Name of finite element.
BitProblemId getBitProblemId(const std::string &name) const
boost::shared_ptr< Field > fieldPtr
#define THROW_MESSAGE(a)
Throw MoFEM exception.
Definition: definitions.h:625
std::bitset< BITPROBLEMID_SIZE > BitProblemId
Problem Id.
Definition: Types.hpp:55
boost::shared_ptr< const FieldEntity_vector_view > rowFieldEntsPtr
Pointer to finite element field entities row view.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:513
Data structure to exchange data between mofem and User Loop Methods on entities.It allows to exchange...
BitProblemId getProblemShift()
Return unique problem Id.
Definition: Core.cpp:243
std::reference_wrapper< moab::Interface > moab
moab database
Definition: Core.hpp:265
keeps basic data about problemThis is low level structure with information about problem,...
virtual MoFEMErrorCode preProcess()
function is run at the beginning of loop
PetscLogEvent MOFEM_EVENT_preProcess
Event for preProcess finite element.
Definition: Core.hpp:833
#define SET_BASIC_METHOD(METHOD, PROBLEM_PTR)
RowColData
RowColData.
Definition: definitions.h:191
boost::shared_ptr< const FEDofEntity_multiIndex > dataPtr
Pointer to finite element data dofs.
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:21
boost::shared_ptr< const NumeredEntFiniteElement > numeredEntFiniteElementPtr
BitFEId getBitFEId(const std::string &name) const
Get field Id.
Definition: FECore.cpp:246
std::bitset< BITFEID_SIZE > BitFEId
Finite element Id.
Definition: Types.hpp:54
Tag th_ProblemName
Definition: Core.hpp:208
virtual MoFEMErrorCode postProcess()
function is run at the end of loop
Tag th_ProblemId
Definition: Core.hpp:208
int rAnk
MOFEM communicator rank.
Definition: Core.hpp:850
remove finite element from problem
DEPRECATED MoFEMErrorCode build_problems(int verb=DEFAULT_VERBOSITY)
build problem data structures
bool check_finite_element(const std::string &name) const
Check if finite element is in database.
Definition: FECore.cpp:35
int * buildMoFEM
keeps flags/semaphores for different stages
Definition: Core.hpp:896
MoFEMErrorCode modify_problem_add_finite_element(const std::string &name_problem, const std::string &MoFEMFiniteElement_name)
add finite element to problem, this add entities assigned to finite element to a particular problem
interface_RefEntity(const boost::shared_ptr< RefEntity > &sptr)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:66
MoFEMErrorCode loop_entities(const Problem *problem_ptr, const std::string field_name, RowColData rc, EntityMethod &method, int lower_rank, int upper_rank, int verb=DEFAULT_VERBOSITY)
Loop over field entities in the problem.
MoFEMErrorCode addProblem(const BitProblemId id, const std::string &name, int verb=DEFAULT_VERBOSITY)
add problem
boost::shared_ptr< NumeredDofEntity_multiIndex > numeredDofsRows
store DOFs on rows for this problem
Problem_multiIndex pRoblems
problems multi-index
Definition: Core.hpp:257
MoFEMErrorCode list_problem() const
list problems
#define CHKERR
Inline error check.
Definition: definitions.h:601
Field_multiIndex fIelds
fields
Definition: Core.hpp:247
int nInTheLoop
number currently of processed method
boost::shared_ptr< NumeredDofEntity > dofNumeredPtr
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
Definition: Types.hpp:51
boost::shared_ptr< FieldEntity > entPtr
MultiIndex Tag for field name.
int verbose
Verbosity level.
Definition: Core.hpp:885
boost::shared_ptr< const FieldEntity_multiIndex_spaceType_view > dataFieldEntsPtr
Pointer to finite element field entities data view.
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:412
MoFEMErrorCode problem_basic_method_postProcess(const Problem *problem_ptr, BasicMethod &method, int verb=DEFAULT_VERBOSITY)
Set data for BasicMethodThis function set data about problem, adjacencies and other multi-indices in ...
MoFEMErrorCode add_problem(const std::string &name, enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)
Add problem.
Clear composed problem data structure.
boost::shared_ptr< NumeredEntFiniteElement_multiIndex > numeredFiniteElements
store finite elements
boost::shared_ptr< BasicEntityData > & get_basic_entity_data_ptr()
Get pointer to basic entity data.
Definition: Core.hpp:234
MoFEMErrorCode modify_problem_mask_ref_level_set_bit(const std::string &name_problem, const BitRefLevel &bit)
set dof mask ref level for problem
boost::shared_ptr< const FENumeredDofEntity_multiIndex > colPtr
Pointer to finite element columns dofs view.
boost::shared_ptr< NumeredDofEntity_multiIndex > numeredDofsCols
store DOFs on columns for this problem
MoFEMErrorCode clear_problems(int verb=DEFAULT_VERBOSITY)
clear problems
#define NOT_USED(x)
Definition: definitions.h:308
MoFEMErrorCode modify_problem_unset_finite_element(const std::string &name_problem, const std::string &MoFEMFiniteElement_name)
unset finite element from problem, this remove entities assigned to finite element to a particular pr...
Data structure to exchange data between mofem and User Loop Methods.It allows to exchange data betwee...
MoFEMErrorCode modify_problem_ref_level_add_bit(const std::string &name_problem, const BitRefLevel &bit)
add ref level to problem
MoFEMErrorCode delete_problem(const std::string name)
Delete problem.
MoFEMTypes
Those types control how functions respond on arguments, f.e. error handling.
Definition: definitions.h:188
MoFEMErrorCode problem_basic_method_preProcess(const Problem *problem_ptr, BasicMethod &method, int verb=DEFAULT_VERBOSITY)
Set data for BasicMethod.
MoFEMErrorCode modify_problem_ref_level_set_bit(const std::string &name_problem, const BitRefLevel &bit)
set ref level for problem
boost::shared_ptr< const FENumeredDofEntity_multiIndex > rowPtr
Pointer to finite element rows dofs view.
MoFEMErrorCode loop_finite_elements(const Problem *problem_ptr, const std::string &fe_name, FEMethod &method, int lower_rank, int upper_rank, boost::shared_ptr< NumeredEntFiniteElement_multiIndex > fe_ptr=nullptr, MoFEMTypes bh=MF_EXIST, int verb=DEFAULT_VERBOSITY)
Make a loop over finite elements on partitions from upper to lower rank.
bool check_problem(const std::string name)
check if problem exist