v0.9.0
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  void const *tag_data[] = {name.c_str()};
39  int tag_sizes[1];
40  tag_sizes[0] = name.size();
41  CHKERR get_moab().tag_set_by_ptr(th_ProblemName, &meshset, 1, tag_data,
42  tag_sizes);
43  // create entry
44  std::pair<Problem_multiIndex::iterator, bool> p =
45  pRoblems.insert(Problem(moab, meshset));
46  NOT_USED(p);
47  assert(p.second);
48  if (verb > 0) {
49  std::ostringstream ss;
50  ss << "add problem: " << name << std::endl;
51  PetscPrintf(cOmm, ss.str().c_str());
52  }
54 }
55 
56 MoFEMErrorCode Core::add_problem(const std::string &name, enum MoFEMTypes bh,
57  int verb) {
59  if (verb == -1)
60  verb = verbose;
61  auto miit = pRoblems.get<Problem_mi_tag>().find(name);
62  if (miit == pRoblems.get<Problem_mi_tag>().end()) {
64  CHKERR addProblem(id, name, verb);
65  } else if (bh == MF_EXCL) {
66  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "problem is in database %s",
67  name.c_str());
68  }
70 }
71 
72 MoFEMErrorCode Core::delete_problem(const std::string name) {
74  auto p_miit = pRoblems.get<Problem_mi_tag>().find(name);
75  if (p_miit == pRoblems.get<Problem_mi_tag>().end()) {
76  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "no such problem like < %s >",
77  name.c_str());
78  }
79  const EntityHandle meshset = p_miit->meshset;
80  pRoblems.get<Problem_mi_tag>().erase(p_miit);
81  CHKERR get_moab().delete_entities(&meshset, 1);
83 }
84 
85 BitProblemId Core::getBitProblemId(const std::string &name) const {
86  auto p_miit = pRoblems.get<Problem_mi_tag>().find(name);
87  if (p_miit == pRoblems.get<Problem_mi_tag>().end()) {
88  THROW_MESSAGE("no such problem like " + name + " >");
89  }
90  return p_miit->getId();
91 }
92 
95  typedef Problem_multiIndex::index<BitProblemId_mi_tag>::type ProblemById;
96  const ProblemById &set_id = pRoblems.get<BitProblemId_mi_tag>();
97  ProblemById::iterator miit = set_id.begin();
98  for (; miit != set_id.end(); miit++) {
99  std::ostringstream ss;
100  ss << *miit << std::endl;
101  PetscPrintf(cOmm, ss.str().c_str());
102  }
104 }
105 
107 Core::modify_problem_add_finite_element(const std::string &name_problem,
108  const std::string &fe_name) {
110  try {
111  typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
112  ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
113  ProblemsByName::iterator miit = set.find(name_problem);
114  if (miit == set.end()) {
115  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND,
116  "this problem <%s> is not there", name_problem.c_str());
117  }
118  BitFEId f_id = getBitFEId(fe_name);
119  bool success = set.modify(miit, ProblemFiniteElementChangeBitAdd(f_id));
120  if (!success)
121  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
122  "modification unsuccessful");
123  } catch (MoFEMException const &e) {
124  SETERRQ(PETSC_COMM_SELF, e.errorCode, e.errorMessage);
125  }
127 }
128 
130 Core::modify_problem_unset_finite_element(const std::string &name_problem,
131  const std::string &fe_name) {
133  try {
134  typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
135  ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
136  ProblemsByName::iterator miit = set.find(name_problem);
137  if (miit == set.end()) {
138  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND,
139  "this problem <%s> is not there", name_problem.c_str());
140  }
141  BitFEId f_id = getBitFEId(fe_name);
142  bool success = set.modify(miit, ProblemFiniteElementChangeBitUnSet(f_id));
143  if (!success)
144  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
145  "modification unsuccessful");
146  } catch (MoFEMException const &e) {
147  SETERRQ(PETSC_COMM_SELF, e.errorCode, e.errorMessage);
148  }
150 }
151 
153 Core::modify_problem_ref_level_add_bit(const std::string &name_problem,
154  const BitRefLevel &bit) {
156  typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
157  ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
158  ProblemsByName::iterator miit = set.find(name_problem);
159  std::ostringstream ss;
160  ss << name_problem;
161  if (miit == set.end())
162  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "this problem <%s> is there",
163  ss.str().c_str());
164  bool success = set.modify(miit, ProblemChangeRefLevelBitAdd(bit));
165  if (!success)
166  SETERRQ(PETSC_COMM_SELF, 1, "modification unsuccessful");
168 }
169 
171 Core::modify_problem_ref_level_set_bit(const std::string &name_problem,
172  const BitRefLevel &bit) {
174  typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
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, ProblemChangeRefLevelBitSet(bit));
183  if (!success)
184  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
185  "modification unsuccessful");
187 }
188 
190 Core::modify_problem_mask_ref_level_add_bit(const std::string &name_problem,
191  const BitRefLevel &bit) {
193  typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
194  ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
195  ProblemsByName::iterator miit = set.find(name_problem);
196  if (miit == set.end()) {
197  std::ostringstream ss;
198  ss << name_problem;
199  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "this problem <%s> is there",
200  ss.str().c_str());
201  }
202  bool success = set.modify(miit, ProblemChangeRefLevelBitDofMaskAdd(bit));
203  if (!success)
204  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
205  "modification unsuccessful");
207 }
208 
210 Core::modify_problem_mask_ref_level_set_bit(const std::string &name_problem,
211  const BitRefLevel &bit) {
213  typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
214  ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
215  ProblemsByName::iterator miit = set.find(name_problem);
216  if (miit == set.end()) {
217  std::ostringstream ss;
218  ss << name_problem;
219  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "this problem <%s> is there",
220  ss.str().c_str());
221  }
222  bool success = set.modify(miit, ProblemChangeRefLevelBitDofMaskSet(bit));
223  if (!success)
224  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
225  "modification unsuccessful");
227 }
228 
231  if (verb == -1)
232  verb = verbose;
233  Problem_multiIndex::iterator p_miit = pRoblems.begin();
234  for (; p_miit != pRoblems.end(); p_miit++) {
235  CHKERR getInterface<ProblemsManager>()->buildProblemOnDistributedMesh(
236  const_cast<Problem *>(&*p_miit), verb);
237  }
239 }
240 
241 MoFEMErrorCode Core::clear_problem(const std::string problem_name, int verb) {
243  if (verb == -1)
244  verb = verbose;
245  typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
246  ProblemsByName &prob_by_name = pRoblems.get<Problem_mi_tag>();
247  ProblemsByName::iterator p_miit = prob_by_name.find(problem_name);
248  if (p_miit == prob_by_name.end()) {
249  SETERRQ1(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
250  "problem < %s > not found, (top tip: check spelling)",
251  problem_name.c_str());
252  }
253  // zero rows
254  bool success = prob_by_name.modify(p_miit, ProblemZeroNbRowsChange());
255  if (!success)
256  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
257  "modification unsuccessful");
258  // zero cols
259  success = prob_by_name.modify(p_miit, ProblemZeroNbColsChange());
260  if (!success)
261  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
262  "modification unsuccessful");
263  // clear finite elements
264  success =
265  prob_by_name.modify(p_miit, ProblemClearNumeredFiniteElementsChange());
266  if (!success)
267  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
268  "modification unsuccessful");
269  // clear data structures
270  success = prob_by_name.modify(p_miit, ProblemClearSubProblemData());
271  if (!success)
272  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
273  "modification unsuccessful");
274  success = prob_by_name.modify(p_miit, ProblemClearComposedProblemData());
275  if (!success)
276  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
277  "modification unsuccessful");
278  if (p_miit->getRowDofsSequence())
279  p_miit->getRowDofsSequence()->clear();
280  if (p_miit->getColDofsSequence())
281  p_miit->getColDofsSequence()->clear();
282  if (p_miit->getSubData())
283  p_miit->getSubData().reset();
284  if (p_miit->getComposedProblemsData())
285  p_miit->getComposedProblemsData().reset();
287 }
288 
291  if (verb == -1)
292  verb = verbose;
293  if (!((*buildMoFEM) & BUILD_FIELD))
294  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "fields not build");
295  if (!((*buildMoFEM) & BUILD_FE))
296  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "FEs not build");
297  if (!((*buildMoFEM) & BUILD_ADJ))
298  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "adjacencies not build");
299  // iterate problems
300  Problem_multiIndex::iterator p_miit = pRoblems.begin();
301  for (; p_miit != pRoblems.end(); p_miit++) {
302  Problem *problem_ptr = const_cast<Problem *>(&*p_miit);
303  CHKERR getInterface<ProblemsManager>()->buildProblem(problem_ptr, false,
304  verb);
305  }
308 }
309 
312  if (verb == -1)
313  verb = verbose;
314  // iterate problems
315  for (Problem_multiIndex::iterator p_miit = pRoblems.begin();
316  p_miit != pRoblems.end(); p_miit++) {
317  ierr = clear_problem(p_miit->getName(), verb);
318  CHKERRG(ierr);
319  }
321 }
322 
323 #define SET_BASIC_METHOD(METHOD, PROBLEM_PTR) \
324  { \
325  METHOD.rAnk = rAnk; \
326  METHOD.sIze = sIze; \
327  METHOD.problemPtr = PROBLEM_PTR; \
328  METHOD.fieldsPtr = &fIelds; \
329  METHOD.refinedEntitiesPtr = &refinedEntities; \
330  METHOD.entitiesPtr = &entsFields; \
331  METHOD.dofsPtr = &dofsField; \
332  METHOD.refinedFiniteElementsPtr = &refinedFiniteElements; \
333  METHOD.finiteElementsPtr = &finiteElements; \
334  METHOD.finiteElementsEntitiesPtr = &entsFiniteElements; \
335  METHOD.adjacenciesPtr = &entFEAdjacencies; \
336  }
337 
339  BasicMethod &method,
340  int verb) {
342  if (verb == -1)
343  verb = verbose;
344  // finite element
345  SET_BASIC_METHOD(method, problem_ptr)
346  PetscLogEventBegin(MOFEM_EVENT_preProcess, 0, 0, 0, 0);
347  CHKERR method.preProcess();
348  PetscLogEventEnd(MOFEM_EVENT_preProcess, 0, 0, 0, 0);
350 }
351 
353 Core::problem_basic_method_preProcess(const std::string &problem_name,
354  BasicMethod &method, int verb) {
356  if (verb == -1)
357  verb = verbose;
358  typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
359  // find p_miit
360  ProblemsByName &pRoblems_set = pRoblems.get<Problem_mi_tag>();
361  ProblemsByName::iterator p_miit = pRoblems_set.find(problem_name);
362  if (p_miit == pRoblems_set.end())
363  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "problem is not in database %s",
364  problem_name.c_str());
365  CHKERR problem_basic_method_preProcess(&*p_miit, method, verb);
367 }
368 
371  BasicMethod &method, int verb) {
373  SET_BASIC_METHOD(method, problem_ptr)
374 
375  PetscLogEventBegin(MOFEM_EVENT_postProcess, 0, 0, 0, 0);
376  CHKERR method.postProcess();
377  PetscLogEventEnd(MOFEM_EVENT_postProcess, 0, 0, 0, 0);
378 
380 }
381 
383 Core::problem_basic_method_postProcess(const std::string &problem_name,
384  BasicMethod &method, int verb) {
386  if (verb == -1)
387  verb = verbose;
388  typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
389 
390  // find p_miit
391  ProblemsByName &pRoblems_set = pRoblems.get<Problem_mi_tag>();
392  ProblemsByName::iterator p_miit = pRoblems_set.find(problem_name);
393  if (p_miit == pRoblems_set.end())
394  SETERRQ1(cOmm, 1, "problem is not in database %s", problem_name.c_str());
395 
396  CHKERR problem_basic_method_postProcess(&*p_miit, method, verb);
397 
399 }
400 
402  const Problem *problem_ptr, const std::string &fe_name, FEMethod &method,
403  int lower_rank, int upper_rank,
404  boost::shared_ptr<NumeredEntFiniteElement_multiIndex> fe_ptr, MoFEMTypes bh,
405  int verb) {
407  if (verb == DEFAULT_VERBOSITY)
408  verb = verbose;
409 
410  method.feName = fe_name;
411  SET_BASIC_METHOD(method, &*problem_ptr)
412  PetscLogEventBegin(MOFEM_EVENT_preProcess, 0, 0, 0, 0);
413  CHKERR method.preProcess();
414  PetscLogEventEnd(MOFEM_EVENT_preProcess, 0, 0, 0, 0);
415 
416  if (!fe_ptr)
417  fe_ptr = problem_ptr->numeredFiniteElements;
418 
419  auto miit = fe_ptr->get<Composite_Name_And_Part_mi_tag>().lower_bound(
420  boost::make_tuple(fe_name, lower_rank));
421  auto hi_miit = fe_ptr->get<Composite_Name_And_Part_mi_tag>().upper_bound(
422  boost::make_tuple(fe_name, upper_rank));
423 
424  if (miit == hi_miit && (bh & MF_EXIST)) {
425  if (!check_finite_element(fe_name)) {
426  SETERRQ1(cOmm, MOFEM_NOT_FOUND, "finite element < %s > not found",
427  fe_name.c_str());
428  }
429  }
430 
431  method.loopSize = std::distance(miit, hi_miit);
432  for (int nn = 0; miit != hi_miit; miit++, nn++) {
433 
434  method.nInTheLoop = nn;
435  method.numeredEntFiniteElementPtr = *miit;
436  method.dataFieldEntsPtr = (*miit)->sPtr->data_field_ents_view;
437  method.rowFieldEntsPtr = (*miit)->sPtr->row_field_ents_view;
438  method.colFieldEntsPtr = (*miit)->sPtr->col_field_ents_view;
439  method.dataPtr = (*miit)->sPtr->data_dofs;
440  method.rowPtr = (*miit)->rows_dofs;
441  method.colPtr = (*miit)->cols_dofs;
442 
443  PetscLogEventBegin(MOFEM_EVENT_operator, 0, 0, 0, 0);
444  CHKERR method();
445  PetscLogEventEnd(MOFEM_EVENT_operator, 0, 0, 0, 0);
446  }
447 
448  PetscLogEventBegin(MOFEM_EVENT_postProcess, 0, 0, 0, 0);
449  CHKERR method.postProcess();
450  PetscLogEventEnd(MOFEM_EVENT_postProcess, 0, 0, 0, 0);
451 
453 }
454 
456  const std::string &problem_name, const std::string &fe_name,
457  FEMethod &method,
458  boost::shared_ptr<NumeredEntFiniteElement_multiIndex> fe_ptr, MoFEMTypes bh,
459  int verb) {
461  if (verb == DEFAULT_VERBOSITY)
462  verb = verbose;
463 
464  CHKERR loop_finite_elements(problem_name, fe_name, method, rAnk, rAnk, fe_ptr,
465  bh, verb);
466 
468 }
469 
471  const std::string &problem_name, const std::string &fe_name,
472  FEMethod &method, int lower_rank, int upper_rank,
473  boost::shared_ptr<NumeredEntFiniteElement_multiIndex> fe_ptr, MoFEMTypes bh,
474  int verb) {
476  if (verb == DEFAULT_VERBOSITY)
477  verb = verbose;
478 
479  auto &prb_by_name = pRoblems.get<Problem_mi_tag>();
480  auto p_miit = prb_by_name.find(problem_name);
481  if (p_miit == prb_by_name.end())
482  SETERRQ1(cOmm, MOFEM_INVALID_DATA, "Problem <%s> is not in database",
483  problem_name.c_str());
484 
485  CHKERR loop_finite_elements(&*p_miit, fe_name, method, lower_rank, upper_rank,
486  fe_ptr, bh, verb);
487 
489 }
490 
492  const std::string &field_name, RowColData rc,
493  DofMethod &method, int lower_rank,
494  int upper_rank, int verb) {
496  SET_BASIC_METHOD(method, &*problem_ptr);
497  typedef NumeredDofEntity_multiIndex::index<
498  Composite_Name_And_Part_mi_tag>::type NumeredDofsByNameAndPart;
499  NumeredDofsByNameAndPart *dofs;
500  switch (rc) {
501  case ROW:
502  dofs = &problem_ptr->numeredDofsRows->get<Composite_Name_And_Part_mi_tag>();
503  break;
504  case COL:
505  dofs = &problem_ptr->numeredDofsCols->get<Composite_Name_And_Part_mi_tag>();
506  break;
507  default:
508  SETERRQ(cOmm, MOFEM_DATA_INCONSISTENCY, "not implemented");
509  }
510  NumeredDofsByNameAndPart::iterator miit =
511  dofs->lower_bound(boost::make_tuple(field_name, lower_rank));
512  NumeredDofsByNameAndPart::iterator hi_miit =
513  dofs->upper_bound(boost::make_tuple(field_name, upper_rank));
514  if (miit != hi_miit) {
515  method.fieldPtr = miit->get()->getFieldPtr();
516  } else {
517  Field_multiIndex::index<FieldName_mi_tag>::type::iterator field_it =
518  fIelds.get<FieldName_mi_tag>().find(field_name);
519  if (field_it != fIelds.get<FieldName_mi_tag>().end()) {
520  method.fieldPtr = *field_it;
521  }
522  }
523  CHKERR method.preProcess();
524  for (; miit != hi_miit; miit++) {
525  method.dofPtr = miit->get()->getDofEntityPtr();
526  method.dofNumeredPtr = *miit;
527  CHKERR method();
528  }
529  CHKERR method.postProcess();
531 }
532 
534  const std::string &problem_name, const std::string &field_name,
535  RowColData rc, // ROW or COL
536  DofMethod &method, // Finite element instance processed on each DOF
537  int lower_rank, // Only DOFs on processor higher or equal to this are
538  // processed
539  int upper_rank, // Only DOFs lowest or higher to this are processed
540  int verb // verbosity level
541 ) {
543  if (verb == DEFAULT_VERBOSITY)
544  verb = verbose;
545  typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
546  // find p_miit
547  ProblemsByName &pRoblems_set = pRoblems.get<Problem_mi_tag>();
548  ProblemsByName::iterator p_miit = pRoblems_set.find(problem_name);
549  if (p_miit == pRoblems_set.end())
550  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "problem not in database %s",
551  problem_name.c_str());
552  CHKERR loop_dofs(&*p_miit, field_name, rc, method, lower_rank, upper_rank,
553  verb);
555 }
556 
557 MoFEMErrorCode Core::loop_dofs(const std::string &problem_name,
558  const std::string &field_name, RowColData rc,
559  DofMethod &method, int verb) {
561  if (verb == DEFAULT_VERBOSITY)
562  verb = verbose;
563  CHKERR loop_dofs(problem_name, field_name, rc, method, 0, sIze, verb);
565 }
566 
567 MoFEMErrorCode Core::loop_dofs(const std::string &field_name, DofMethod &method,
568  int verb) {
570  if (verb == DEFAULT_VERBOSITY)
571  verb = verbose;
572  SET_BASIC_METHOD(method, nullptr);
573  auto miit = dofsField.get<FieldName_mi_tag>().lower_bound(field_name);
574  auto hi_miit = dofsField.get<FieldName_mi_tag>().upper_bound(field_name);
575  if (miit != hi_miit) {
576  method.fieldPtr = miit->get()->getFieldPtr();
577  } else {
578  auto field_it = fIelds.get<FieldName_mi_tag>().find(field_name);
579  if (field_it != fIelds.get<FieldName_mi_tag>().end()) {
580  method.fieldPtr = *field_it;
581  }
582  }
583  method.loopSize = std::distance(miit, hi_miit);
584  CHKERR method.preProcess();
585  for (int nn = 0; miit != hi_miit; miit++, nn++) {
586  method.nInTheLoop = nn;
587  method.dofPtr = *miit;
588  CHKERR method();
589  }
590  CHKERR method.postProcess();
592 }
593 
595  const std::string field_name, RowColData rc,
596  EntityMethod &method, int lower_rank,
597  int upper_rank, int verb) {
599  if (verb == DEFAULT_VERBOSITY)
600  verb = verbose;
601  decltype(problem_ptr->numeredDofsRows) dofs;
602  switch (rc) {
603  case ROW:
604  dofs = problem_ptr->numeredDofsRows;
605  break;
606  case COL:
607  dofs = problem_ptr->numeredDofsCols;
608  break;
609  default:
611  "It works only with rows or columns");
612  }
613  auto miit = dofs->get<Composite_Name_And_Part_mi_tag>().lower_bound(
614  boost::make_tuple(field_name, lower_rank));
615  auto hi_miit = dofs->get<Composite_Name_And_Part_mi_tag>().upper_bound(
616  boost::make_tuple(field_name, upper_rank));
617  if (miit != hi_miit) {
618  method.fieldPtr = miit->get()->getFieldPtr();
619  } else {
620  Field_multiIndex::index<FieldName_mi_tag>::type::iterator field_it =
621  fIelds.get<FieldName_mi_tag>().find(field_name);
622  if (field_it != fIelds.get<FieldName_mi_tag>().end()) {
623  method.fieldPtr = *field_it;
624  }
625  }
626 
627  typedef multi_index_container<
628  boost::shared_ptr<FieldEntity>,
629  indexed_by<ordered_unique<
630  tag<Ent_mi_tag>,
631  const_mem_fun<FieldEntity, EntityHandle, &FieldEntity::getEnt>>>>
632  FieldEntity_view_multiIndex;
633  FieldEntity_view_multiIndex ents_view;
634  auto hint = ents_view.begin();
635  for (; miit != hi_miit; ++miit)
636  ents_view.emplace_hint(hint, (*miit)->getFieldEntityPtr());
637 
638  method.loopSize = ents_view.size();
639  SET_BASIC_METHOD(method, problem_ptr);
640  CHKERR method.preProcess();
641  method.nInTheLoop = 0;
642  for (auto &field_ent : ents_view) {
643  method.entPtr = field_ent;
644  CHKERR method();
645  ++method.nInTheLoop;
646  }
647  CHKERR method.postProcess();
649 }
650 
651 MoFEMErrorCode Core::loop_entities(const std::string problem_name,
652  const std::string field_name, RowColData rc,
653  EntityMethod &method, int lower_rank,
654  int upper_rank, int verb) {
656  if (verb == DEFAULT_VERBOSITY)
657  verb = verbose;
658  typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
659  // find p_miit
660  ProblemsByName &pRoblems_set = pRoblems.get<Problem_mi_tag>();
661  ProblemsByName::iterator p_miit = pRoblems_set.find(problem_name);
662  if (p_miit == pRoblems_set.end())
663  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "problem not in database %s",
664  problem_name.c_str());
665  CHKERR loop_entities(&*p_miit, field_name, rc, method, lower_rank, upper_rank,
666  verb);
668 }
669 
670 MoFEMErrorCode Core::loop_entities(const std::string problem_name,
671  const std::string field_name, RowColData rc,
672  EntityMethod &method, int verb) {
673  return loop_entities(problem_name, field_name, rc, method, rAnk, rAnk, verb);
674 }
675 
676 MoFEMErrorCode Core::loop_entities(const std::string field_name,
677  EntityMethod &method,
678  Range const *const ents, int verb) {
680  if (verb == DEFAULT_VERBOSITY)
681  verb = verbose;
682  SET_BASIC_METHOD(method, nullptr);
683  auto r = entsFields.get<FieldName_mi_tag>().equal_range(field_name);
684  if (r.first != r.second) {
685  method.fieldPtr = (*r.first)->getFieldPtr();
686  } else {
687  auto field_it = fIelds.get<FieldName_mi_tag>().find(field_name);
688  if (field_it != fIelds.get<FieldName_mi_tag>().end()) {
689  method.fieldPtr = *field_it;
690  }
691  }
692 
693  typedef multi_index_container<
694  boost::shared_ptr<FieldEntity>,
695  indexed_by<
696  ordered_unique<tag<Ent_mi_tag>,
697  const_mem_fun<FieldEntity::interface_RefEntity,
699  FieldEntity_view_multiIndex;
700 
701  FieldEntity_view_multiIndex ents_view;
702  ents_view.insert(r.first, r.second);
703 
704  method.loopSize = ents_view.size();
705  CHKERR method.preProcess();
706  method.nInTheLoop = 0;
707 
708  if (ents)
709  for (auto p = ents->const_pair_begin(); p != ents->const_pair_end(); ++p)
710  for (auto feit = ents_view.lower_bound(p->first);
711  feit != ents_view.upper_bound(p->second); ++feit) {
712  method.entPtr = *feit;
713  CHKERR method();
714  ++method.nInTheLoop;
715  }
716  else
717  for (auto &field_ent : ents_view) {
718  method.entPtr = field_ent;
719  CHKERR method();
720  ++method.nInTheLoop;
721  }
722 
723  CHKERR method.postProcess();
725 }
726 } // 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:501
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:477
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)
#define CHKERRG(n)
Check error code of MoFEM/MOAB/PETSc function.
Definition: definitions.h:544
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:620
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:508
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:242
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:186
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:240
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:596
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:407
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
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:303
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:183
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