v0.9.2
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 #define ProblemCoreFunctionBegin \
20  MoFEMFunctionBegin; \
21  MOFEM_LOG_CHANNEL("WORLD"); \
22  MOFEM_LOG_CHANNEL("SYNC"); \
23  MOFEM_LOG_FUNCTION(); \
24  MOFEM_LOG_TAG("SYNC", "ProblemCore"); \
25  MOFEM_LOG_TAG("WORLD", "ProblemCore")
26 
27 namespace MoFEM {
28 
29 bool Core::check_problem(const string name) {
30  Problem_multiIndex::index<Problem_mi_tag>::type::iterator pit;
31  pit = pRoblems.get<Problem_mi_tag>().find(name);
32  if (pit == pRoblems.get<Problem_mi_tag>().end()) {
33  return false;
34  }
35  return true;
36 }
37 
38 MoFEMErrorCode Core::addProblem(const BitProblemId id, const std::string &name,
39  int verb) {
41 
42  if (verb == -1)
43  verb = verbose;
44  EntityHandle meshset;
45  CHKERR get_moab().create_meshset(MESHSET_SET, meshset);
46  CHKERR get_moab().tag_set_data(th_ProblemId, &meshset, 1, &id);
47 
48  // Add problem meshset to partion meshset. In case of no elements
49  // on processor part, when mesh file is read, finite element meshset is
50  // prevented from deletion by moab reader.
51  auto add_meshset_to_partition = [&](auto meshset) {
53  const void *tag_vals[] = {&rAnk};
54  ParallelComm *pcomm = ParallelComm::get_pcomm(
55  &get_moab(), get_basic_entity_data_ptr()->pcommID);
56  Tag part_tag = pcomm->part_tag();
57  Range tagged_sets;
58  CHKERR get_moab().get_entities_by_type_and_tag(0, MBENTITYSET, &part_tag,
59  tag_vals, 1, tagged_sets,
60  moab::Interface::UNION);
61  for (auto s : tagged_sets)
62  CHKERR get_moab().add_entities(s, &meshset, 1);
64  };
65  CHKERR add_meshset_to_partition(meshset);
66 
67  void const *tag_data[] = {name.c_str()};
68  int tag_sizes[1];
69  tag_sizes[0] = name.size();
70  CHKERR get_moab().tag_set_by_ptr(th_ProblemName, &meshset, 1, tag_data,
71  tag_sizes);
72  // create entry
73  auto p = pRoblems.insert(Problem(moab, meshset));
74  if (!p.second)
75  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "Problem not added");
76 
77  MOFEM_LOG("WORLD", Sev::inform) << "Add problem " << name;
78 
80 }
81 
82 MoFEMErrorCode Core::add_problem(const std::string &name, enum MoFEMTypes bh,
83  int verb) {
85  if (verb == -1)
86  verb = verbose;
87  auto miit = pRoblems.get<Problem_mi_tag>().find(name);
88  if (miit == pRoblems.get<Problem_mi_tag>().end()) {
90  CHKERR addProblem(id, name, verb);
91  } else if (bh == MF_EXCL) {
92  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "problem is in database %s",
93  name.c_str());
94  }
96 }
97 
98 MoFEMErrorCode Core::delete_problem(const std::string name) {
100  auto p_miit = pRoblems.get<Problem_mi_tag>().find(name);
101  if (p_miit == pRoblems.get<Problem_mi_tag>().end()) {
102  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "no such problem like < %s >",
103  name.c_str());
104  }
105  const EntityHandle meshset = p_miit->meshset;
106  pRoblems.get<Problem_mi_tag>().erase(p_miit);
107  CHKERR get_moab().delete_entities(&meshset, 1);
109 }
110 
111 BitProblemId Core::getBitProblemId(const std::string &name) const {
112  auto p_miit = pRoblems.get<Problem_mi_tag>().find(name);
113  if (p_miit == pRoblems.get<Problem_mi_tag>().end()) {
114  THROW_MESSAGE("no such problem like " + name + " >");
115  }
116  return p_miit->getId();
117 }
118 
122  const ProblemById &set_id = pRoblems.get<BitProblemId_mi_tag>();
123  ProblemById::iterator miit = set_id.begin();
124  for (; miit != set_id.end(); miit++) {
125  std::ostringstream ss;
126  ss << *miit << std::endl;
127  PetscPrintf(cOmm, ss.str().c_str());
128  }
130 }
131 
133 Core::modify_problem_add_finite_element(const std::string &name_problem,
134  const std::string &fe_name) {
137  ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
138  ProblemsByName::iterator miit = set.find(name_problem);
139  if (miit == set.end()) {
140  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "this problem <%s> is not there",
141  name_problem.c_str());
142  }
143  BitFEId f_id = getBitFEId(fe_name);
144  bool success = set.modify(miit, ProblemFiniteElementChangeBitAdd(f_id));
145  if (!success)
146  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
147  "modification unsuccessful");
149 }
150 
152 Core::modify_problem_unset_finite_element(const std::string &name_problem,
153  const std::string &fe_name) {
156  ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
157  ProblemsByName::iterator miit = set.find(name_problem);
158  if (miit == set.end()) {
159  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "this problem <%s> is not there",
160  name_problem.c_str());
161  }
162  BitFEId f_id = getBitFEId(fe_name);
163  bool success = set.modify(miit, ProblemFiniteElementChangeBitUnSet(f_id));
164  if (!success)
165  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
166  "modification unsuccessful");
168 }
169 
171 Core::modify_problem_ref_level_add_bit(const std::string &name_problem,
172  const BitRefLevel &bit) {
175  ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
176  ProblemsByName::iterator miit = set.find(name_problem);
177  std::ostringstream ss;
178  ss << name_problem;
179  if (miit == set.end())
180  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "this problem <%s> is there",
181  ss.str().c_str());
182  bool success = set.modify(miit, ProblemChangeRefLevelBitAdd(bit));
183  if (!success)
184  SETERRQ(PETSC_COMM_SELF, 1, "modification unsuccessful");
186 }
187 
189 Core::modify_problem_ref_level_set_bit(const std::string &name_problem,
190  const BitRefLevel &bit) {
193  ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
194  ProblemsByName::iterator miit = set.find(name_problem);
195  std::ostringstream ss;
196  ss << name_problem;
197  if (miit == set.end())
198  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "this problem <%s> is there",
199  ss.str().c_str());
200  bool success = set.modify(miit, ProblemChangeRefLevelBitSet(bit));
201  if (!success)
202  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
203  "modification unsuccessful");
205 }
206 
208 Core::modify_problem_mask_ref_level_add_bit(const std::string &name_problem,
209  const BitRefLevel &bit) {
212  ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
213  ProblemsByName::iterator miit = set.find(name_problem);
214  if (miit == set.end()) {
215  std::ostringstream ss;
216  ss << name_problem;
217  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "this problem <%s> is there",
218  ss.str().c_str());
219  }
220  bool success = set.modify(miit, ProblemChangeRefLevelBitDofMaskAdd(bit));
221  if (!success)
222  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
223  "modification unsuccessful");
225 }
226 
228 Core::modify_problem_mask_ref_level_set_bit(const std::string &name_problem,
229  const BitRefLevel &bit) {
231  ProblemsByName;
232  ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
233  ProblemsByName::iterator miit = set.find(name_problem);
234  if (miit == set.end()) {
235  std::ostringstream ss;
236  ss << name_problem;
237  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "this problem <%s> is there",
238  ss.str().c_str());
239  }
240  bool success = set.modify(miit, ProblemChangeRefLevelBitDofMaskSet(bit));
241  if (!success)
242  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
243  "modification unsuccessful");
245 }
246 
249  if (verb == -1)
250  verb = verbose;
251  Problem_multiIndex::iterator p_miit = pRoblems.begin();
252  for (; p_miit != pRoblems.end(); p_miit++) {
253  CHKERR getInterface<ProblemsManager>()->buildProblemOnDistributedMesh(
254  const_cast<Problem *>(&*p_miit), verb);
255  }
257 }
258 
259 MoFEMErrorCode Core::clear_problem(const std::string problem_name, int verb) {
261  if (verb == -1)
262  verb = verbose;
264  ProblemsByName &prob_by_name = pRoblems.get<Problem_mi_tag>();
265  ProblemsByName::iterator p_miit = prob_by_name.find(problem_name);
266  if (p_miit == prob_by_name.end()) {
267  SETERRQ1(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
268  "problem < %s > not found, (top tip: check spelling)",
269  problem_name.c_str());
270  }
271  // zero rows
272  bool success = prob_by_name.modify(p_miit, ProblemZeroNbRowsChange());
273  if (!success)
274  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
275  "modification unsuccessful");
276  // zero cols
277  success = prob_by_name.modify(p_miit, ProblemZeroNbColsChange());
278  if (!success)
279  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
280  "modification unsuccessful");
281  // clear finite elements
282  success =
283  prob_by_name.modify(p_miit, ProblemClearNumeredFiniteElementsChange());
284  if (!success)
285  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
286  "modification unsuccessful");
287  // clear data structures
288  success = prob_by_name.modify(p_miit, ProblemClearSubProblemData());
289  if (!success)
290  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
291  "modification unsuccessful");
292  success = prob_by_name.modify(p_miit, ProblemClearComposedProblemData());
293  if (!success)
294  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
295  "modification unsuccessful");
296  if (p_miit->getRowDofsSequence())
297  p_miit->getRowDofsSequence()->clear();
298  if (p_miit->getColDofsSequence())
299  p_miit->getColDofsSequence()->clear();
300  if (p_miit->getSubData())
301  p_miit->getSubData().reset();
302  if (p_miit->getComposedProblemsData())
303  p_miit->getComposedProblemsData().reset();
305 }
306 
309  if (verb == -1)
310  verb = verbose;
311  if (!((*buildMoFEM) & BUILD_FIELD))
312  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "fields not build");
313  if (!((*buildMoFEM) & BUILD_FE))
314  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "FEs not build");
315  if (!((*buildMoFEM) & BUILD_ADJ))
316  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "adjacencies not build");
317  // iterate problems
318  Problem_multiIndex::iterator p_miit = pRoblems.begin();
319  for (; p_miit != pRoblems.end(); p_miit++) {
320  Problem *problem_ptr = const_cast<Problem *>(&*p_miit);
321  CHKERR getInterface<ProblemsManager>()->buildProblem(problem_ptr, false,
322  verb);
323  }
326 }
327 
330  if (verb == -1)
331  verb = verbose;
332  // iterate problems
333  for (auto p_miit = pRoblems.begin(); p_miit != pRoblems.end(); p_miit++)
334  CHKERR clear_problem(p_miit->getName(), verb);
336 }
337 
338 #define SET_BASIC_METHOD(METHOD, PROBLEM_PTR) \
339  { \
340  METHOD.rAnk = rAnk; \
341  METHOD.sIze = sIze; \
342  METHOD.problemPtr = PROBLEM_PTR; \
343  METHOD.fieldsPtr = &fIelds; \
344  METHOD.refinedEntitiesPtr = &refinedEntities; \
345  METHOD.entitiesPtr = &entsFields; \
346  METHOD.dofsPtr = &dofsField; \
347  METHOD.refinedFiniteElementsPtr = &refinedFiniteElements; \
348  METHOD.finiteElementsPtr = &finiteElements; \
349  METHOD.finiteElementsEntitiesPtr = &entsFiniteElements; \
350  METHOD.adjacenciesPtr = &entFEAdjacencies; \
351  }
352 
354  BasicMethod &method,
355  int verb) {
357  if (verb == -1)
358  verb = verbose;
359  // finite element
360  SET_BASIC_METHOD(method, problem_ptr)
361  PetscLogEventBegin(MOFEM_EVENT_preProcess, 0, 0, 0, 0);
362  CHKERR method.preProcess();
363  PetscLogEventEnd(MOFEM_EVENT_preProcess, 0, 0, 0, 0);
365 }
366 
368 Core::problem_basic_method_preProcess(const std::string &problem_name,
369  BasicMethod &method, int verb) {
371  if (verb == -1)
372  verb = verbose;
374  // find p_miit
375  ProblemsByName &pRoblems_set = pRoblems.get<Problem_mi_tag>();
376  ProblemsByName::iterator p_miit = pRoblems_set.find(problem_name);
377  if (p_miit == pRoblems_set.end())
378  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "problem is not in database %s",
379  problem_name.c_str());
380  CHKERR problem_basic_method_preProcess(&*p_miit, method, verb);
382 }
383 
386  BasicMethod &method, int verb) {
388  SET_BASIC_METHOD(method, problem_ptr)
389 
390  PetscLogEventBegin(MOFEM_EVENT_postProcess, 0, 0, 0, 0);
391  CHKERR method.postProcess();
392  PetscLogEventEnd(MOFEM_EVENT_postProcess, 0, 0, 0, 0);
393 
395 }
396 
398 Core::problem_basic_method_postProcess(const std::string &problem_name,
399  BasicMethod &method, int verb) {
401  if (verb == -1)
402  verb = verbose;
404 
405  // find p_miit
406  ProblemsByName &pRoblems_set = pRoblems.get<Problem_mi_tag>();
407  ProblemsByName::iterator p_miit = pRoblems_set.find(problem_name);
408  if (p_miit == pRoblems_set.end())
409  SETERRQ1(cOmm, 1, "problem is not in database %s", problem_name.c_str());
410 
411  CHKERR problem_basic_method_postProcess(&*p_miit, method, verb);
412 
414 }
415 
417  const Problem *problem_ptr, const std::string &fe_name, FEMethod &method,
418  int lower_rank, int upper_rank,
419  boost::shared_ptr<NumeredEntFiniteElement_multiIndex> fe_ptr, MoFEMTypes bh,
420  int verb) {
422  if (verb == DEFAULT_VERBOSITY)
423  verb = verbose;
424 
425  method.feName = fe_name;
426  SET_BASIC_METHOD(method, &*problem_ptr)
427  PetscLogEventBegin(MOFEM_EVENT_preProcess, 0, 0, 0, 0);
428  CHKERR method.preProcess();
429  PetscLogEventEnd(MOFEM_EVENT_preProcess, 0, 0, 0, 0);
430 
431  if (!fe_ptr)
432  fe_ptr = problem_ptr->numeredFiniteElements;
433 
434  auto miit = fe_ptr->get<Composite_Name_And_Part_mi_tag>().lower_bound(
435  boost::make_tuple(fe_name, lower_rank));
436  auto hi_miit = fe_ptr->get<Composite_Name_And_Part_mi_tag>().upper_bound(
437  boost::make_tuple(fe_name, upper_rank));
438 
439  if (miit == hi_miit && (bh & MF_EXIST)) {
440  if (!check_finite_element(fe_name)) {
441  SETERRQ1(cOmm, MOFEM_NOT_FOUND, "finite element < %s > not found",
442  fe_name.c_str());
443  }
444  }
445 
446  method.loopSize = std::distance(miit, hi_miit);
447  for (int nn = 0; miit != hi_miit; miit++, nn++) {
448 
449  method.nInTheLoop = nn;
450  method.numeredEntFiniteElementPtr = *miit;
451  method.dataFieldEntsPtr = (*miit)->sPtr->data_field_ents_view;
452  method.rowFieldEntsPtr = (*miit)->sPtr->row_field_ents_view;
453  method.colFieldEntsPtr = (*miit)->sPtr->col_field_ents_view;
454  method.dataPtr = (*miit)->sPtr->data_dofs;
455  method.rowPtr = (*miit)->rows_dofs;
456  method.colPtr = (*miit)->cols_dofs;
457 
458  PetscLogEventBegin(MOFEM_EVENT_operator, 0, 0, 0, 0);
459  CHKERR method();
460  PetscLogEventEnd(MOFEM_EVENT_operator, 0, 0, 0, 0);
461  }
462 
463  PetscLogEventBegin(MOFEM_EVENT_postProcess, 0, 0, 0, 0);
464  CHKERR method.postProcess();
465  PetscLogEventEnd(MOFEM_EVENT_postProcess, 0, 0, 0, 0);
466 
468 }
469 
471  const std::string &problem_name, const std::string &fe_name,
472  FEMethod &method,
473  boost::shared_ptr<NumeredEntFiniteElement_multiIndex> fe_ptr, MoFEMTypes bh,
474  int verb) {
476  if (verb == DEFAULT_VERBOSITY)
477  verb = verbose;
478 
479  CHKERR loop_finite_elements(problem_name, fe_name, method, rAnk, rAnk, fe_ptr,
480  bh, verb);
481 
483 }
484 
486  const std::string &problem_name, const std::string &fe_name,
487  FEMethod &method, int lower_rank, int upper_rank,
488  boost::shared_ptr<NumeredEntFiniteElement_multiIndex> fe_ptr, MoFEMTypes bh,
489  int verb) {
491  if (verb == DEFAULT_VERBOSITY)
492  verb = verbose;
493 
494  auto &prb_by_name = pRoblems.get<Problem_mi_tag>();
495  auto p_miit = prb_by_name.find(problem_name);
496  if (p_miit == prb_by_name.end())
497  SETERRQ1(cOmm, MOFEM_INVALID_DATA, "Problem <%s> is not in database",
498  problem_name.c_str());
499 
500  CHKERR loop_finite_elements(&*p_miit, fe_name, method, lower_rank, upper_rank,
501  fe_ptr, bh, verb);
502 
504 }
505 
507  const std::string &field_name, RowColData rc,
508  DofMethod &method, int lower_rank,
509  int upper_rank, int verb) {
511  SET_BASIC_METHOD(method, &*problem_ptr);
512  typedef NumeredDofEntity_multiIndex::index<
513  Composite_Name_And_Part_mi_tag>::type NumeredDofsByNameAndPart;
514  NumeredDofsByNameAndPart *dofs;
515  switch (rc) {
516  case ROW:
517  dofs = &problem_ptr->numeredDofsRows->get<Composite_Name_And_Part_mi_tag>();
518  break;
519  case COL:
520  dofs = &problem_ptr->numeredDofsCols->get<Composite_Name_And_Part_mi_tag>();
521  break;
522  default:
523  SETERRQ(cOmm, MOFEM_DATA_INCONSISTENCY, "not implemented");
524  }
525  NumeredDofsByNameAndPart::iterator miit =
526  dofs->lower_bound(boost::make_tuple(field_name, lower_rank));
527  NumeredDofsByNameAndPart::iterator hi_miit =
528  dofs->upper_bound(boost::make_tuple(field_name, upper_rank));
529  if (miit != hi_miit) {
530  method.fieldPtr = miit->get()->getFieldPtr();
531  } else {
532  Field_multiIndex::index<FieldName_mi_tag>::type::iterator field_it =
533  fIelds.get<FieldName_mi_tag>().find(field_name);
534  if (field_it != fIelds.get<FieldName_mi_tag>().end()) {
535  method.fieldPtr = *field_it;
536  }
537  }
538  CHKERR method.preProcess();
539  for (; miit != hi_miit; miit++) {
540  method.dofPtr = miit->get()->getDofEntityPtr();
541  method.dofNumeredPtr = *miit;
542  CHKERR method();
543  }
544  CHKERR method.postProcess();
546 }
547 
549  const std::string &problem_name, const std::string &field_name,
550  RowColData rc, // ROW or COL
551  DofMethod &method, // Finite element instance processed on each DOF
552  int lower_rank, // Only DOFs on processor higher or equal to this are
553  // processed
554  int upper_rank, // Only DOFs lowest or higher to this are processed
555  int verb // verbosity level
556 ) {
558  if (verb == DEFAULT_VERBOSITY)
559  verb = verbose;
561  // find p_miit
562  ProblemsByName &pRoblems_set = pRoblems.get<Problem_mi_tag>();
563  ProblemsByName::iterator p_miit = pRoblems_set.find(problem_name);
564  if (p_miit == pRoblems_set.end())
565  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "problem not in database %s",
566  problem_name.c_str());
567  CHKERR loop_dofs(&*p_miit, field_name, rc, method, lower_rank, upper_rank,
568  verb);
570 }
571 
572 MoFEMErrorCode Core::loop_dofs(const std::string &problem_name,
573  const std::string &field_name, RowColData rc,
574  DofMethod &method, int verb) {
576  if (verb == DEFAULT_VERBOSITY)
577  verb = verbose;
578  CHKERR loop_dofs(problem_name, field_name, rc, method, 0, sIze, verb);
580 }
581 
582 MoFEMErrorCode Core::loop_dofs(const std::string &field_name, DofMethod &method,
583  int verb) {
585  if (verb == DEFAULT_VERBOSITY)
586  verb = verbose;
587  SET_BASIC_METHOD(method, nullptr);
588  auto miit = dofsField.get<FieldName_mi_tag>().lower_bound(field_name);
589  auto hi_miit = dofsField.get<FieldName_mi_tag>().upper_bound(field_name);
590  if (miit != hi_miit) {
591  method.fieldPtr = miit->get()->getFieldPtr();
592  } else {
593  auto field_it = fIelds.get<FieldName_mi_tag>().find(field_name);
594  if (field_it != fIelds.get<FieldName_mi_tag>().end()) {
595  method.fieldPtr = *field_it;
596  }
597  }
598  method.loopSize = std::distance(miit, hi_miit);
599  CHKERR method.preProcess();
600  for (int nn = 0; miit != hi_miit; miit++, nn++) {
601  method.nInTheLoop = nn;
602  method.dofPtr = *miit;
603  CHKERR method();
604  }
605  CHKERR method.postProcess();
607 }
608 
610  const std::string field_name, RowColData rc,
611  EntityMethod &method, int lower_rank,
612  int upper_rank, int verb) {
614  if (verb == DEFAULT_VERBOSITY)
615  verb = verbose;
616  decltype(problem_ptr->numeredDofsRows) dofs;
617  switch (rc) {
618  case ROW:
619  dofs = problem_ptr->numeredDofsRows;
620  break;
621  case COL:
622  dofs = problem_ptr->numeredDofsCols;
623  break;
624  default:
626  "It works only with rows or columns");
627  }
628  auto miit = dofs->get<Composite_Name_And_Part_mi_tag>().lower_bound(
629  boost::make_tuple(field_name, lower_rank));
630  auto hi_miit = dofs->get<Composite_Name_And_Part_mi_tag>().upper_bound(
631  boost::make_tuple(field_name, upper_rank));
632  if (miit != hi_miit) {
633  method.fieldPtr = miit->get()->getFieldPtr();
634  } else {
635  Field_multiIndex::index<FieldName_mi_tag>::type::iterator field_it =
636  fIelds.get<FieldName_mi_tag>().find(field_name);
637  if (field_it != fIelds.get<FieldName_mi_tag>().end()) {
638  method.fieldPtr = *field_it;
639  }
640  }
641 
642  typedef multi_index_container<
643  boost::shared_ptr<FieldEntity>,
644  indexed_by<ordered_unique<
645  tag<Ent_mi_tag>,
646  const_mem_fun<FieldEntity, EntityHandle, &FieldEntity::getEnt>>>>
647  FieldEntity_view_multiIndex;
648  FieldEntity_view_multiIndex ents_view;
649  auto hint = ents_view.begin();
650  for (; miit != hi_miit; ++miit)
651  ents_view.emplace_hint(hint, (*miit)->getFieldEntityPtr());
652 
653  method.loopSize = ents_view.size();
654  SET_BASIC_METHOD(method, problem_ptr);
655  CHKERR method.preProcess();
656  method.nInTheLoop = 0;
657  for (auto &field_ent : ents_view) {
658  method.entPtr = field_ent;
659  CHKERR method();
660  ++method.nInTheLoop;
661  }
662  CHKERR method.postProcess();
664 }
665 
666 MoFEMErrorCode Core::loop_entities(const std::string problem_name,
667  const std::string field_name, RowColData rc,
668  EntityMethod &method, int lower_rank,
669  int upper_rank, int verb) {
671  if (verb == DEFAULT_VERBOSITY)
672  verb = verbose;
674  // find p_miit
675  ProblemsByName &pRoblems_set = pRoblems.get<Problem_mi_tag>();
676  ProblemsByName::iterator p_miit = pRoblems_set.find(problem_name);
677  if (p_miit == pRoblems_set.end())
678  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "problem not in database %s",
679  problem_name.c_str());
680  CHKERR loop_entities(&*p_miit, field_name, rc, method, lower_rank, upper_rank,
681  verb);
683 }
684 
685 MoFEMErrorCode Core::loop_entities(const std::string problem_name,
686  const std::string field_name, RowColData rc,
687  EntityMethod &method, int verb) {
688  return loop_entities(problem_name, field_name, rc, method, rAnk, rAnk, verb);
689 }
690 
691 MoFEMErrorCode Core::loop_entities(const std::string field_name,
692  EntityMethod &method,
693  Range const *const ents, int verb) {
695  if (verb == DEFAULT_VERBOSITY)
696  verb = verbose;
697  SET_BASIC_METHOD(method, nullptr);
698  auto r = entsFields.get<FieldName_mi_tag>().equal_range(field_name);
699  if (r.first != r.second) {
700  method.fieldPtr = (*r.first)->getFieldPtr();
701  } else {
702  auto field_it = fIelds.get<FieldName_mi_tag>().find(field_name);
703  if (field_it != fIelds.get<FieldName_mi_tag>().end()) {
704  method.fieldPtr = *field_it;
705  }
706  }
707 
708  typedef multi_index_container<
709  boost::shared_ptr<FieldEntity>,
710  indexed_by<
711  ordered_unique<tag<Ent_mi_tag>,
712  const_mem_fun<FieldEntity::interface_RefEntity,
714  FieldEntity_view_multiIndex;
715 
716  FieldEntity_view_multiIndex ents_view;
717  ents_view.insert(r.first, r.second);
718 
719  method.loopSize = ents_view.size();
720  CHKERR method.preProcess();
721  method.nInTheLoop = 0;
722 
723  if (ents)
724  for (auto p = ents->const_pair_begin(); p != ents->const_pair_end(); ++p)
725  for (auto feit = ents_view.lower_bound(p->first);
726  feit != ents_view.upper_bound(p->second); ++feit) {
727  method.entPtr = *feit;
728  CHKERR method();
729  ++method.nInTheLoop;
730  }
731  else
732  for (auto &field_ent : ents_view) {
733  method.entPtr = field_ent;
734  CHKERR method();
735  ++method.nInTheLoop;
736  }
737 
738  CHKERR method.postProcess();
740 }
741 } // 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:859
PetscLogEvent MOFEM_EVENT_postProcess
Event for postProcess finite element.
Definition: Core.hpp:847
MPI_Comm cOmm
MoFEM communicator.
Definition: Core.hpp:856
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:507
PetscLogEvent MOFEM_EVENT_operator
Event for evaluating operator of finite element.
Definition: Core.hpp:845
#define MOFEM_LOG(channel, severity)
Log.
Definition: LogManager.hpp:303
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:483
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:626
std::bitset< BITPROBLEMID_SIZE > BitProblemId
Problem Id.
Definition: Types.hpp:54
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:514
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:265
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:843
#define SET_BASIC_METHOD(METHOD, PROBLEM_PTR)
RowColData
RowColData.
Definition: definitions.h:192
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:239
std::bitset< BITFEID_SIZE > BitFEId
Finite element Id.
Definition: Types.hpp:53
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:860
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:29
int * buildMoFEM
keeps flags/semaphores for different stages
Definition: Core.hpp:906
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:67
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.
#define ProblemCoreFunctionBegin
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:602
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:50
boost::shared_ptr< FieldEntity > entPtr
MultiIndex Tag for field name.
int verbose
Verbosity level.
Definition: Core.hpp:895
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:413
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
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:189
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