v0.14.0
ProblemsManager.cpp
Go to the documentation of this file.
1 /** \file ProblemsManager.cpp
2  * \brief Managing complexities for problem
3  * \ingroup mofem_problems_manager
4  */
5 
6 namespace MoFEM {
7 
8 #define ProblemManagerFunctionBegin \
9  MoFEMFunctionBegin; \
10  MOFEM_LOG_CHANNEL("WORLD"); \
11  MOFEM_LOG_CHANNEL("SYNC"); \
12  MOFEM_LOG_FUNCTION(); \
13  MOFEM_LOG_TAG("SYNC", "ProblemsManager"); \
14  MOFEM_LOG_TAG("WORLD", "ProblemsManager")
15 
16 struct IdxDataType {
17  IdxDataType(const UId uid, const int dof) {
18  bcopy(&uid, dAta, 4 * sizeof(int));
19  dAta[4] = dof;
20  }
21 
22 private:
23  int dAta[5];
24 };
25 
27  IdxDataTypePtr(const int *ptr) : pTr(ptr) {}
28  inline int getDofIdx() const {
29  int global_dof = pTr[4];
30  return global_dof;
31  }
32  inline UId getUId() const {
33  unsigned int b0, b1, b2, b3;
34  bcopy(&pTr[0], &b0, sizeof(int));
35  bcopy(&pTr[1], &b1, sizeof(int));
36  bcopy(&pTr[2], &b2, sizeof(int));
37  bcopy(&pTr[3], &b3, sizeof(int));
38  UId uid = static_cast<UId>(b0) | static_cast<UId>(b1) << 8 * sizeof(int) |
39  static_cast<UId>(b2) << 16 * sizeof(int) |
40  static_cast<UId>(b3) << 24 * sizeof(int);
41  return uid;
42  }
43 
44 private:
45  const int *pTr;
46 };
47 
49 ProblemsManager::query_interface(boost::typeindex::type_index type_index,
50  UnknownInterface **iface) const {
51  *iface = const_cast<ProblemsManager *>(this);
52  return 0;
53 }
54 
56  : cOre(const_cast<MoFEM::Core &>(core)),
57  buildProblemFromFields(PETSC_FALSE),
58  synchroniseProblemEntities(PETSC_FALSE) {
59  PetscLogEventRegister("ProblemsManager", 0, &MOFEM_EVENT_ProblemsManager);
60 }
61 
63  MoFEM::Interface &m_field = cOre;
65  CHKERR PetscOptionsBegin(m_field.get_comm(), "", "Problem manager", "none");
66  {
67  CHKERR PetscOptionsBool(
68  "-problem_build_from_fields",
69  "Add DOFs to problem directly from fields not through DOFs on elements",
71  }
72  ierr = PetscOptionsEnd();
73  CHKERRG(ierr);
75 }
76 
78  const Range &ents, const int dim, const int adj_dim, const int n_parts,
79  Tag *th_vertex_weights, Tag *th_edge_weights, Tag *th_part_weights,
80  int verb, const bool debug) {
81  return static_cast<MoFEM::Interface &>(cOre)
82  .getInterface<CommInterface>()
83  ->partitionMesh(ents, dim, adj_dim, n_parts, th_vertex_weights,
84  th_edge_weights, th_part_weights, verb, debug);
85 }
86 
88  const bool square_matrix,
89  int verb) {
90 
91  MoFEM::Interface &m_field = cOre;
93  if (!(cOre.getBuildMoFEM() & (1 << 0)))
94  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "fields not build");
95  if (!(cOre.getBuildMoFEM() & (1 << 1)))
96  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "FEs not build");
97  if (!(cOre.getBuildMoFEM() & (1 << 2)))
98  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "adjacencies not build");
99  const Problem *problem_ptr;
100  CHKERR m_field.get_problem(name, &problem_ptr);
101  CHKERR buildProblem(const_cast<Problem *>(problem_ptr), square_matrix, verb);
102  cOre.getBuildMoFEM() |= 1 << 3; // It is assumed that user who uses this
103  // function knows what he is doing
105 }
106 
108  const bool square_matrix,
109  int verb) {
110  MoFEM::Interface &m_field = cOre;
111  auto dofs_field_ptr = m_field.get_dofs();
112  auto ents_field_ptr = m_field.get_field_ents();
113  auto adjacencies_ptr = m_field.get_ents_elements_adjacency();
115  PetscLogEventBegin(MOFEM_EVENT_ProblemsManager, 0, 0, 0, 0);
116 
117  // Note: Only allowed changes on problem_ptr structure which not influence
118  // multi-index.
119 
120  if (problem_ptr->getBitRefLevel().none()) {
121  SETERRQ1(PETSC_COMM_SELF, 1, "problem <%s> refinement level not set",
122  problem_ptr->getName().c_str());
123  }
124  CHKERR m_field.clear_problem(problem_ptr->getName());
125 
126  // zero finite elements
127  problem_ptr->numeredFiniteElementsPtr->clear();
128 
129  DofEntity_multiIndex_active_view dofs_rows, dofs_cols;
130  auto make_rows_and_cols_view = [&](auto &dofs_rows, auto &dofs_cols) {
132  for (auto it = ents_field_ptr->begin(); it != ents_field_ptr->end(); ++it) {
133 
134  const auto uid = (*it)->getLocalUniqueId();
135 
136  auto r = adjacencies_ptr->get<Unique_mi_tag>().equal_range(uid);
137  for (auto lo = r.first; lo != r.second; ++lo) {
138 
139  if ((lo->getBitFEId() & problem_ptr->getBitFEId()).any()) {
140  std::array<bool, 2> row_col = {false, false};
141 
142  const BitRefLevel &prb_bit = problem_ptr->getBitRefLevel();
143  const BitRefLevel &prb_mask = problem_ptr->getBitRefLevelMask();
144  const BitRefLevel &fe_bit = lo->entFePtr->getBitRefLevel();
145 
146  // if entity is not problem refinement level
147  if ((fe_bit & prb_mask) != fe_bit)
148  continue;
149  if ((fe_bit & prb_bit).none())
150  continue;
151 
152  auto add_to_view = [&](auto &nb_dofs, auto &view, auto rc) {
153  auto dit = nb_dofs->lower_bound(uid);
154  decltype(dit) hi_dit;
155  if (dit != nb_dofs->end()) {
156  hi_dit = nb_dofs->upper_bound(
157  uid | static_cast<UId>(MAX_DOFS_ON_ENTITY - 1));
158  view.insert(dit, hi_dit);
159  row_col[rc] = true;
160  }
161  };
162 
163  if ((lo->entFePtr->getBitFieldIdRow() & (*it)->getId()).any())
164  add_to_view(dofs_field_ptr, dofs_rows, ROW);
165 
166  if (!square_matrix)
167  if ((lo->entFePtr->getBitFieldIdCol() & (*it)->getId()).any())
168  add_to_view(dofs_field_ptr, dofs_cols, COL);
169 
170  if (square_matrix && row_col[ROW])
171  break;
172  else if (row_col[ROW] && row_col[COL])
173  break;
174  }
175  }
176  }
178  };
179 
180  CHKERR make_rows_and_cols_view(dofs_rows, dofs_cols);
181 
182  // Add row dofs to problem
183  {
184  // zero rows
185  problem_ptr->nbDofsRow = 0;
186  problem_ptr->nbLocDofsRow = 0;
187  problem_ptr->nbGhostDofsRow = 0;
188 
189  // add dofs for rows
190  DofEntity_multiIndex_active_view::nth_index<0>::type::iterator miit,
191  hi_miit;
192  hi_miit = dofs_rows.get<0>().end();
193 
194  int count_dofs = dofs_rows.get<1>().count(true);
195  boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array =
196  boost::shared_ptr<std::vector<NumeredDofEntity>>(
197  new std::vector<NumeredDofEntity>());
198  problem_ptr->getRowDofsSequence()->push_back(dofs_array);
199  dofs_array->reserve(count_dofs);
200  miit = dofs_rows.get<0>().begin();
201  for (; miit != hi_miit; miit++) {
202  if ((*miit)->getActive()) {
203  dofs_array->emplace_back(*miit);
204  dofs_array->back().dofIdx = (problem_ptr->nbDofsRow)++;
205  }
206  }
207  auto hint = problem_ptr->numeredRowDofsPtr->end();
208  for (auto &v : *dofs_array) {
209  hint = problem_ptr->numeredRowDofsPtr->emplace_hint(hint, dofs_array, &v);
210  }
211  }
212 
213  // Add col dofs to problem
214  if (!square_matrix) {
215  // zero cols
216  problem_ptr->nbDofsCol = 0;
217  problem_ptr->nbLocDofsCol = 0;
218  problem_ptr->nbGhostDofsCol = 0;
219 
220  // add dofs for cols
221  DofEntity_multiIndex_active_view::nth_index<0>::type::iterator miit,
222  hi_miit;
223  hi_miit = dofs_cols.get<0>().end();
224 
225  int count_dofs = 0;
226  miit = dofs_cols.get<0>().begin();
227  for (; miit != hi_miit; miit++) {
228  if (!(*miit)->getActive()) {
229  continue;
230  }
231  count_dofs++;
232  }
233 
234  boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array =
235  boost::shared_ptr<std::vector<NumeredDofEntity>>(
236  new std::vector<NumeredDofEntity>());
237  problem_ptr->getColDofsSequence()->push_back(dofs_array);
238  dofs_array->reserve(count_dofs);
239  miit = dofs_cols.get<0>().begin();
240  for (; miit != hi_miit; miit++) {
241  if (!(*miit)->getActive()) {
242  continue;
243  }
244  dofs_array->emplace_back(*miit);
245  dofs_array->back().dofIdx = problem_ptr->nbDofsCol++;
246  }
247  auto hint = problem_ptr->numeredColDofsPtr->end();
248  for (auto &v : *dofs_array) {
249  hint = problem_ptr->numeredColDofsPtr->emplace_hint(hint, dofs_array, &v);
250  }
251  } else {
252  problem_ptr->numeredColDofsPtr = problem_ptr->numeredRowDofsPtr;
253  problem_ptr->nbLocDofsCol = problem_ptr->nbLocDofsRow;
254  problem_ptr->nbDofsCol = problem_ptr->nbDofsRow;
255  }
256 
257  // job done, some debugging and postprocessing
258  if (verb >= VERBOSE) {
259  MOFEM_LOG("SYNC", Sev::verbose)
260  << problem_ptr->getName() << " Nb. local dofs "
261  << problem_ptr->numeredRowDofsPtr->size() << " by "
262  << problem_ptr->numeredColDofsPtr->size();
263  MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::verbose);
264  }
265 
266  if (verb >= NOISY) {
267  MOFEM_LOG("SYNC", Sev::noisy)
268  << "FEs row dofs " << *problem_ptr << " Nb. row dof "
269  << problem_ptr->getNbDofsRow();
270  for (auto &miit : *problem_ptr->numeredRowDofsPtr)
271  MOFEM_LOG("SYNC", Sev::noisy) << *miit;
272 
273  MOFEM_LOG("SYNC", Sev::noisy)
274  << "FEs col dofs " << *problem_ptr << " Nb. col dof "
275  << problem_ptr->getNbDofsCol();
276  for (auto &miit : *problem_ptr->numeredColDofsPtr)
277  MOFEM_LOG("SYNC", Sev::noisy) << *miit;
278  MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
279  }
280 
281  cOre.getBuildMoFEM() |= Core::BUILD_PROBLEM; // It is assumed that user who
282  // uses this function knows
283  // what he is doing
284 
285  PetscLogEventEnd(MOFEM_EVENT_ProblemsManager, 0, 0, 0, 0);
286 
288 }
289 
291  const std::string name, const bool square_matrix, int verb) {
292  MoFEM::Interface &m_field = cOre;
294 
295  if (!((cOre.getBuildMoFEM()) & Core::BUILD_FIELD))
296  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "fields not build");
297  if (!((cOre.getBuildMoFEM()) & Core::BUILD_FE))
298  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "FEs not build");
299  if (!((cOre.getBuildMoFEM()) & Core::BUILD_ADJ))
300  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "adjacencies not build");
301 
302  const Problem *problem_ptr;
303  CHKERR m_field.get_problem(name, &problem_ptr);
304  CHKERR buildProblemOnDistributedMesh(const_cast<Problem *>(problem_ptr),
305  square_matrix, verb);
306 
309 
311 }
312 
314  Problem *problem_ptr, const bool square_matrix, int verb) {
315  MoFEM::Interface &m_field = cOre;
316  auto fields_ptr = m_field.get_fields();
317  auto fe_ptr = m_field.get_finite_elements();
318  auto dofs_field_ptr = m_field.get_dofs();
320  PetscLogEventBegin(MOFEM_EVENT_ProblemsManager, 0, 0, 0, 0);
321 
322  // clear data structures
323  CHKERR m_field.clear_problem(problem_ptr->getName());
324 
325  CHKERR getOptions();
326 
327  if (problem_ptr->getBitRefLevel().none())
328  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND,
329  "problem <%s> refinement level not set",
330  problem_ptr->getName().c_str());
331 
332  int loop_size = 2;
333  if (square_matrix) {
334  loop_size = 1;
335  problem_ptr->numeredColDofsPtr = problem_ptr->numeredRowDofsPtr;
336  } else if (problem_ptr->numeredColDofsPtr == problem_ptr->numeredRowDofsPtr) {
337  problem_ptr->numeredColDofsPtr =
338  boost::shared_ptr<NumeredDofEntity_multiIndex>(
340  }
341 
342  const BitRefLevel &prb_bit = problem_ptr->getBitRefLevel();
343  const BitRefLevel &prb_mask = problem_ptr->getBitRefLevelMask();
344 
345  // // get rows and cols dofs view based on data on elements
346  DofEntity_multiIndex_active_view dofs_rows, dofs_cols;
347 
348  // Add DOFs to problem by visiting all elements and adding DOFs from
349  // elements to the problem
350  if (buildProblemFromFields == PETSC_FALSE) {
351 
352  auto make_rows_and_cols_view = [&](auto &dofs_rows, auto &dofs_cols) {
353  auto ents_field_ptr = m_field.get_field_ents();
354  auto adjacencies_ptr = m_field.get_ents_elements_adjacency();
356  for (auto it = ents_field_ptr->begin(); it != ents_field_ptr->end();
357  ++it) {
358 
359  const auto uid = (*it)->getLocalUniqueId();
360 
361  auto r = adjacencies_ptr->get<Unique_mi_tag>().equal_range(uid);
362  for (auto lo = r.first; lo != r.second; ++lo) {
363 
364  if ((lo->getBitFEId() & problem_ptr->getBitFEId()).any()) {
365  std::array<bool, 2> row_col = {false, false};
366 
367  const BitRefLevel &fe_bit = lo->entFePtr->getBitRefLevel();
368 
369  // if entity is not problem refinement level
370  if ((fe_bit & prb_bit).any() && (fe_bit & prb_mask) == fe_bit) {
371 
372  auto add_to_view = [&](auto dofs, auto &view, auto rc) {
373  auto dit = dofs->lower_bound(uid);
374  decltype(dit) hi_dit;
375  if (dit != dofs->end()) {
376  hi_dit = dofs->upper_bound(
377  uid | static_cast<UId>(MAX_DOFS_ON_ENTITY - 1));
378  view.insert(dit, hi_dit);
379  row_col[rc] = true;
380  }
381  };
382 
383  if ((lo->entFePtr->getBitFieldIdRow() & (*it)->getId()).any())
384  add_to_view(dofs_field_ptr, dofs_rows, ROW);
385 
386  if (!square_matrix)
387  if ((lo->entFePtr->getBitFieldIdCol() & (*it)->getId()).any())
388  add_to_view(dofs_field_ptr, dofs_cols, COL);
389 
390  if (square_matrix && row_col[ROW])
391  break;
392  else if (row_col[ROW] && row_col[COL])
393  break;
394  }
395  }
396  }
397  }
399  };
400 
401  CHKERR make_rows_and_cols_view(dofs_rows, dofs_cols);
402  }
403 
404  // Add DOFS to the problem by searching all the filedes, and adding to
405  // problem owned or shared DOFs
406  if (buildProblemFromFields == PETSC_TRUE) {
407  // Get fields IDs on elements
408  BitFieldId fields_ids_row, fields_ids_col;
409  for (auto fit = fe_ptr->begin(); fit != fe_ptr->end(); fit++) {
410  if ((fit->get()->getId() & problem_ptr->getBitFEId()).any()) {
411  fields_ids_row |= fit->get()->getBitFieldIdRow();
412  fields_ids_col |= fit->get()->getBitFieldIdCol();
413  }
414  }
415  // Get fields DOFs
416  for (auto fit = fields_ptr->begin(); fit != fields_ptr->end(); fit++) {
417  if ((fit->get()->getId() & (fields_ids_row | fields_ids_col)).any()) {
418 
419  auto dit = dofs_field_ptr->get<Unique_mi_tag>().lower_bound(
420  FieldEntity::getLoBitNumberUId((*fit)->getBitNumber()));
421  auto hi_dit = dofs_field_ptr->get<Unique_mi_tag>().upper_bound(
422  FieldEntity::getHiBitNumberUId((*fit)->getBitNumber()));
423 
424  for (; dit != hi_dit; dit++) {
425 
426  const int owner_proc = dit->get()->getOwnerProc();
427  if (owner_proc != m_field.get_comm_rank()) {
428  const unsigned char pstatus = dit->get()->getPStatus();
429  if (pstatus == 0) {
430  continue;
431  }
432  }
433 
434  const auto &dof_bit = (*dit)->getBitRefLevel();
435  // if entity is not problem refinement level
436  if ((dof_bit & prb_bit).any() && (dof_bit & prb_mask) == dof_bit) {
437 
438  if ((fit->get()->getId() & fields_ids_row).any()) {
439  dofs_rows.insert(*dit);
440  }
441  if (!square_matrix) {
442  if ((fit->get()->getId() & fields_ids_col).any()) {
443  dofs_cols.insert(*dit);
444  }
445  }
446  }
447  }
448  }
449  }
450  }
451 
453  // Get fields IDs on elements
454  BitFieldId fields_ids_row, fields_ids_col;
455  BitFieldId *fields_ids[2] = {&fields_ids_row, &fields_ids_col};
456  for (FiniteElement_multiIndex::iterator fit = fe_ptr->begin();
457  fit != fe_ptr->end(); fit++) {
458  if ((fit->get()->getId() & problem_ptr->getBitFEId()).any()) {
459  fields_ids_row |= fit->get()->getBitFieldIdRow();
460  fields_ids_col |= fit->get()->getBitFieldIdCol();
461  }
462  }
463 
464  DofEntity_multiIndex_active_view *dofs_ptr[] = {&dofs_rows, &dofs_cols};
465  for (int ss = 0; ss != ((square_matrix) ? 1 : 2); ++ss) {
466  DofEntity_multiIndex_active_view::nth_index<1>::type::iterator miit,
467  hi_miit;
468  miit = dofs_ptr[ss]->get<1>().lower_bound(1);
469  hi_miit = dofs_ptr[ss]->get<1>().upper_bound(1);
470  Range ents_to_synchronise;
471  for (; miit != hi_miit; ++miit) {
472  if (miit->get()->getEntDofIdx() != 0)
473  continue;
474  ents_to_synchronise.insert(miit->get()->getEnt());
475  }
476  Range tmp_ents = ents_to_synchronise;
477  CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
478  ents_to_synchronise, nullptr, verb);
479  ents_to_synchronise = subtract(ents_to_synchronise, tmp_ents);
480  for (auto fit = fields_ptr->begin(); fit != fields_ptr->end(); fit++) {
481  if ((fit->get()->getId() & *fields_ids[ss]).any()) {
482  const auto bit_number = (*fit)->getBitNumber();
483  for (Range::pair_iterator pit = ents_to_synchronise.pair_begin();
484  pit != ents_to_synchronise.pair_end(); ++pit) {
485  const auto f = pit->first;
486  const auto s = pit->second;
487  const auto lo_uid =
489  const auto hi_uid =
491 
492  auto dit = dofs_field_ptr->get<Unique_mi_tag>().lower_bound(lo_uid);
493  auto hi_dit =
494  dofs_field_ptr->get<Unique_mi_tag>().upper_bound(hi_uid);
495 
496  dofs_ptr[ss]->insert(dit, hi_dit);
497  }
498  }
499  }
500  }
501  }
502 
503  // add dofs for rows and cols and set ownership
504  DofEntity_multiIndex_active_view *dofs_ptr[] = {&dofs_rows, &dofs_cols};
505  boost::shared_ptr<NumeredDofEntity_multiIndex> numered_dofs_ptr[] = {
506  problem_ptr->numeredRowDofsPtr, problem_ptr->numeredColDofsPtr};
507  int *nbdof_ptr[] = {&problem_ptr->nbDofsRow, &problem_ptr->nbDofsCol};
508  int *local_nbdof_ptr[] = {&problem_ptr->nbLocDofsRow,
509  &problem_ptr->nbLocDofsCol};
510  int *ghost_nbdof_ptr[] = {&problem_ptr->nbGhostDofsRow,
511  &problem_ptr->nbGhostDofsCol};
512  for (int ss = 0; ss < 2; ss++) {
513  *(nbdof_ptr[ss]) = 0;
514  *(local_nbdof_ptr[ss]) = 0;
515  *(ghost_nbdof_ptr[ss]) = 0;
516  }
517 
518  // Loop over dofs on rows and columns and add to multi-indices in dofs
519  // problem structure, set partition for each dof
520  int nb_local_dofs[] = {0, 0};
521  for (int ss = 0; ss < loop_size; ss++) {
522  DofEntity_multiIndex_active_view::nth_index<1>::type::iterator miit,
523  hi_miit;
524  miit = dofs_ptr[ss]->get<1>().lower_bound(1);
525  hi_miit = dofs_ptr[ss]->get<1>().upper_bound(1);
526  for (; miit != hi_miit; miit++) {
527  int owner_proc = (*miit)->getOwnerProc();
528  if (owner_proc == m_field.get_comm_rank()) {
529  nb_local_dofs[ss]++;
530  }
531  }
532  }
533 
534  // get layout
535  int start_ranges[2], end_ranges[2];
536  for (int ss = 0; ss != loop_size; ss++) {
537  PetscLayout layout;
538  CHKERR PetscLayoutCreate(m_field.get_comm(), &layout);
539  CHKERR PetscLayoutSetBlockSize(layout, 1);
540  CHKERR PetscLayoutSetLocalSize(layout, nb_local_dofs[ss]);
541  CHKERR PetscLayoutSetUp(layout);
542  CHKERR PetscLayoutGetSize(layout, &*nbdof_ptr[ss]);
543  CHKERR PetscLayoutGetRange(layout, &start_ranges[ss], &end_ranges[ss]);
544  CHKERR PetscLayoutDestroy(&layout);
545  }
546  if (square_matrix) {
547  nbdof_ptr[1] = nbdof_ptr[0];
548  nb_local_dofs[1] = nb_local_dofs[0];
549  start_ranges[1] = start_ranges[0];
550  end_ranges[1] = end_ranges[0];
551  }
552 
553  // if(sizeof(UId) != SIZEOFUID) {
554  // SETERRQ2(
555  // PETSC_COMM_SELF,MOFEM_DATA_INCONSISTENCY,
556  // "check size of UId, size of UId is %u != %u",
557  // sizeof(UId),SIZEOFUID
558  // );
559  // }
560 
561  // set local and global indices on own dofs
562  const size_t idx_data_type_size = sizeof(IdxDataType);
563  const size_t data_block_size = idx_data_type_size / sizeof(int);
564 
565  if (sizeof(IdxDataType) % sizeof(int)) {
566  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
567  }
568  std::vector<std::vector<IdxDataType>> ids_data_packed_rows(
569  m_field.get_comm_size()),
570  ids_data_packed_cols(m_field.get_comm_size());
571 
572  // Loop over dofs on this processor and prepare those dofs to send on
573  // another proc
574  for (int ss = 0; ss != loop_size; ++ss) {
575 
576  DofEntity_multiIndex_active_view::nth_index<0>::type::iterator miit,
577  hi_miit;
578  hi_miit = dofs_ptr[ss]->get<0>().end();
579 
580  boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array =
581  boost::shared_ptr<std::vector<NumeredDofEntity>>(
582  new std::vector<NumeredDofEntity>());
583  int nb_dofs_to_add = 0;
584  miit = dofs_ptr[ss]->get<0>().begin();
585  for (; miit != hi_miit; ++miit) {
586  // Only set global idx for dofs on this processor part
587  if (!(miit->get()->getActive()))
588  continue;
589  ++nb_dofs_to_add;
590  }
591  dofs_array->reserve(nb_dofs_to_add);
592  if (ss == 0) {
593  problem_ptr->getRowDofsSequence()->push_back(dofs_array);
594  } else {
595  problem_ptr->getColDofsSequence()->push_back(dofs_array);
596  }
597 
598  int &local_idx = *local_nbdof_ptr[ss];
599  miit = dofs_ptr[ss]->get<0>().begin();
600  for (; miit != hi_miit; ++miit) {
601 
602  // Only set global idx for dofs on this processor part
603  if (!(miit->get()->getActive()))
604  continue;
605 
606  dofs_array->emplace_back(*miit);
607 
608  int owner_proc = dofs_array->back().getOwnerProc();
609  if (owner_proc < 0) {
610  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
611  "data inconsistency");
612  }
613 
614  if (owner_proc != m_field.get_comm_rank()) {
615  dofs_array->back().pArt = owner_proc;
616  dofs_array->back().dofIdx = -1;
617  dofs_array->back().petscGloablDofIdx = -1;
618  dofs_array->back().petscLocalDofIdx = -1;
619  } else {
620 
621  // Set part and indexes
622  int glob_idx = start_ranges[ss] + local_idx;
623  dofs_array->back().pArt = owner_proc;
624  dofs_array->back().dofIdx = glob_idx;
625  dofs_array->back().petscGloablDofIdx = glob_idx;
626  dofs_array->back().petscLocalDofIdx = local_idx;
627  local_idx++;
628 
629  unsigned char pstatus = dofs_array->back().getPStatus();
630  // check id dof is shared, if that is a case global idx added to data
631  // structure and is sended to other processors
632  if (pstatus > 0) {
633 
634  for (int proc = 0;
635  proc < MAX_SHARING_PROCS &&
636  -1 != dofs_array->back().getSharingProcsPtr()[proc];
637  proc++) {
638  // make it different for rows and columns when needed
639  if (ss == 0) {
640  ids_data_packed_rows[dofs_array->back()
641  .getSharingProcsPtr()[proc]]
642  .emplace_back(dofs_array->back().getGlobalUniqueId(),
643  glob_idx);
644  } else {
645  ids_data_packed_cols[dofs_array->back()
646  .getSharingProcsPtr()[proc]]
647  .emplace_back(dofs_array->back().getGlobalUniqueId(),
648  glob_idx);
649  }
650  if (!(pstatus & PSTATUS_MULTISHARED)) {
651  break;
652  }
653  }
654  }
655  }
656  }
657 
658  auto hint = numered_dofs_ptr[ss]->end();
659  for (auto &v : *dofs_array)
660  hint = numered_dofs_ptr[ss]->emplace_hint(hint, dofs_array, &v);
661  }
662  if (square_matrix) {
663  local_nbdof_ptr[1] = local_nbdof_ptr[0];
664  }
665 
666  int nsends_rows = 0, nsends_cols = 0;
667  // Non zero lengths[i] represent a message to i of length lengths[i].
668  std::vector<int> lengths_rows(m_field.get_comm_size()),
669  lengths_cols(m_field.get_comm_size());
670  lengths_rows.clear();
671  lengths_cols.clear();
672  for (int proc = 0; proc < m_field.get_comm_size(); proc++) {
673  lengths_rows[proc] = ids_data_packed_rows[proc].size() * data_block_size;
674  lengths_cols[proc] = ids_data_packed_cols[proc].size() * data_block_size;
675  if (!ids_data_packed_rows[proc].empty())
676  nsends_rows++;
677  if (!ids_data_packed_cols[proc].empty())
678  nsends_cols++;
679  }
680 
681  MPI_Status *status;
682  CHKERR PetscMalloc1(m_field.get_comm_size(), &status);
683 
684  // Do rows
685  int nrecvs_rows; // number of messages received
686  int *onodes_rows; // list of node-ids from which messages are expected
687  int *olengths_rows; // corresponding message lengths
688  int **rbuf_row; // must bee freed by user
689 
690  // make sure it is a PETSc comm
691  MPI_Comm comm;
692  CHKERR PetscCommDuplicate(m_field.get_comm(), &comm, NULL);
693 
694  {
695 
696  // rows
697 
698  // Computes the number of messages a node expects to receive
699  CHKERR PetscGatherNumberOfMessages(comm, NULL, &lengths_rows[0],
700  &nrecvs_rows);
701  // std::cerr << nrecvs_rows << std::endl;
702 
703  // Computes info about messages that a MPI-node will receive, including
704  // (from-id,length) pairs for each message.
705  CHKERR PetscGatherMessageLengths(comm, nsends_rows, nrecvs_rows,
706  &lengths_rows[0], &onodes_rows,
707  &olengths_rows);
708 
709  // Gets a unique new tag from a PETSc communicator. All processors that
710  // share the communicator MUST call this routine EXACTLY the same number
711  // of times. This tag should only be used with the current objects
712  // communicator; do NOT use it with any other MPI communicator.
713  int tag_row;
714  CHKERR PetscCommGetNewTag(comm, &tag_row);
715 
716  // Allocate a buffer sufficient to hold messages of size specified in
717  // olengths. And post Irecvs on these buffers using node info from onodes
718  MPI_Request *r_waits_row; // must bee freed by user
719  // rbuf has a pointers to messeges. It has size of of nrecvs (number of
720  // messages) +1. In the first index a block is allocated,
721  // such that rbuf[i] = rbuf[i-1]+olengths[i-1].
722 
723  CHKERR PetscPostIrecvInt(comm, tag_row, nrecvs_rows, onodes_rows,
724  olengths_rows, &rbuf_row, &r_waits_row);
725  CHKERR PetscFree(onodes_rows);
726 
727  MPI_Request *s_waits_row; // status of sens messages
728  CHKERR PetscMalloc1(nsends_rows, &s_waits_row);
729 
730  // Send messeges
731  for (int proc = 0, kk = 0; proc < m_field.get_comm_size(); proc++) {
732  if (!lengths_rows[proc])
733  continue; // no message to send to this proc
734  CHKERR MPI_Isend(&(ids_data_packed_rows[proc])[0], // buffer to send
735  lengths_rows[proc], // message length
736  MPIU_INT, proc, // to proc
737  tag_row, comm, s_waits_row + kk);
738  kk++;
739  }
740 
741  if (nrecvs_rows) {
742  CHKERR MPI_Waitall(nrecvs_rows, r_waits_row, status);
743  }
744  if (nsends_rows) {
745  CHKERR MPI_Waitall(nsends_rows, s_waits_row, status);
746  }
747 
748  CHKERR PetscFree(r_waits_row);
749  CHKERR PetscFree(s_waits_row);
750  }
751 
752  // cols
753  int nrecvs_cols = nrecvs_rows;
754  int *olengths_cols = olengths_rows;
755  PetscInt **rbuf_col = rbuf_row;
756  if (!square_matrix) {
757 
758  // Computes the number of messages a node expects to receive
759  CHKERR PetscGatherNumberOfMessages(comm, NULL, &lengths_cols[0],
760  &nrecvs_cols);
761 
762  // Computes info about messages that a MPI-node will receive, including
763  // (from-id,length) pairs for each message.
764  int *onodes_cols;
765  CHKERR PetscGatherMessageLengths(comm, nsends_cols, nrecvs_cols,
766  &lengths_cols[0], &onodes_cols,
767  &olengths_cols);
768 
769  // Gets a unique new tag from a PETSc communicator.
770  int tag_col;
771  CHKERR PetscCommGetNewTag(comm, &tag_col);
772 
773  // Allocate a buffer sufficient to hold messages of size specified in
774  // olengths. And post Irecvs on these buffers using node info from onodes
775  MPI_Request *r_waits_col; // must bee freed by user
776  CHKERR PetscPostIrecvInt(comm, tag_col, nrecvs_cols, onodes_cols,
777  olengths_cols, &rbuf_col, &r_waits_col);
778  CHKERR PetscFree(onodes_cols);
779 
780  MPI_Request *s_waits_col; // status of sens messages
781  CHKERR PetscMalloc1(nsends_cols, &s_waits_col);
782 
783  // Send messages
784  for (int proc = 0, kk = 0; proc < m_field.get_comm_size(); proc++) {
785  if (!lengths_cols[proc])
786  continue; // no message to send to this proc
787  CHKERR MPI_Isend(&(ids_data_packed_cols[proc])[0], // buffer to send
788  lengths_cols[proc], // message length
789  MPIU_INT, proc, // to proc
790  tag_col, comm, s_waits_col + kk);
791  kk++;
792  }
793 
794  if (nrecvs_cols) {
795  CHKERR MPI_Waitall(nrecvs_cols, r_waits_col, status);
796  }
797  if (nsends_cols) {
798  CHKERR MPI_Waitall(nsends_cols, s_waits_col, status);
799  }
800 
801  CHKERR PetscFree(r_waits_col);
802  CHKERR PetscFree(s_waits_col);
803  }
804 
805  CHKERR PetscCommDestroy(&comm);
806  CHKERR PetscFree(status);
807 
808  DofEntity_multiIndex_global_uid_view dofs_glob_uid_view;
809  auto hint = dofs_glob_uid_view.begin();
810  for (auto dof : *m_field.get_dofs())
811  dofs_glob_uid_view.emplace_hint(hint, dof);
812 
813  // set values received from other processors
814  for (int ss = 0; ss != loop_size; ++ss) {
815 
816  int nrecvs;
817  int *olengths;
818  int **data_procs;
819  if (ss == 0) {
820  nrecvs = nrecvs_rows;
821  olengths = olengths_rows;
822  data_procs = rbuf_row;
823  } else {
824  nrecvs = nrecvs_cols;
825  olengths = olengths_cols;
826  data_procs = rbuf_col;
827  }
828 
829  UId uid;
830  for (int kk = 0; kk != nrecvs; ++kk) {
831  int len = olengths[kk];
832  int *data_from_proc = data_procs[kk];
833  for (int dd = 0; dd < len; dd += data_block_size) {
834  uid = IdxDataTypePtr(&data_from_proc[dd]).getUId();
835  auto ddit = dofs_glob_uid_view.find(uid);
836  const auto owner_proc = FieldEntity::getOwnerFromUniqueId(uid);
837 
838  if (owner_proc == m_field.get_comm_rank() &&
839  PetscUnlikely(ddit == dofs_glob_uid_view.end())) {
840 
841 #ifndef NDEBUG
842  auto ents_field_ptr = m_field.get_field_ents();
843  MOFEM_LOG("SELF", Sev::error)
844  << "DOF is shared or multishared between processors. For example "
845  "if order of field on given entity is set in inconsistently, "
846  "has different value on two processor, error such as this is "
847  "triggered";
848 
849  MOFEM_LOG("SELF", Sev::error) << "UId " << uid << " is not found";
850  MOFEM_LOG("SELF", Sev::error)
851  << "Problematic UId owner proc is " << owner_proc;
852  const auto uid_handle = FieldEntity::getHandleFromUniqueId(uid);
853  MOFEM_LOG("SELF", Sev::error)
854  << "Problematic UId entity owning processor handle is "
855  << uid_handle << " entity type "
856  << moab::CN::EntityTypeName(type_from_handle(uid_handle));
857  const auto uid_bit_number =
859  MOFEM_LOG("SELF", Sev::error)
860  << "Problematic UId field is "
861  << m_field.get_field_name(
862  field_bit_from_bit_number(uid_bit_number));
863 
865  field_view.insert(ents_field_ptr->begin(), ents_field_ptr->end());
866  auto fe_it = field_view.find(FieldEntity::getGlobalUniqueIdCalculate(
867  owner_proc, uid_bit_number, uid_handle));
868  if (fe_it == field_view.end()) {
869  MOFEM_LOG("SELF", Sev::error)
870  << "Also, no field entity in database for given global UId";
871  } else {
872  MOFEM_LOG("SELF", Sev::error) << "Field entity in databse exist "
873  "(but have no DOF wih give UId";
874  MOFEM_LOG("SELF", Sev::error) << **fe_it;
875 
876  // Save file with missing entity
877  auto error_file_name =
878  "error_with_missing_entity_" +
879  boost::lexical_cast<std::string>(m_field.get_comm_rank()) +
880  ".vtk";
881  MOFEM_LOG("SELF", Sev::error)
882  << "Look to file < " << error_file_name
883  << " > it contains entity with missing DOF.";
884 
885  auto tmp_msh = get_temp_meshset_ptr(m_field.get_moab());
886  const auto local_fe_ent = (*fe_it)->getEnt();
887  CHKERR m_field.get_moab().add_entities(*tmp_msh, &local_fe_ent, 1);
888  CHKERR m_field.get_moab().write_file(error_file_name.c_str(), "VTK",
889  "", tmp_msh->get_ptr(), 1);
890  }
891 #endif
892 
893  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
894  "DOF with global UId not found (Compile code in Debug to "
895  "learn more about problem");
896  }
897 
898  if (PetscUnlikely(ddit == dofs_glob_uid_view.end())) {
899  continue;
900  }
901 
902  auto dit = numered_dofs_ptr[ss]->find((*ddit)->getLocalUniqueId());
903 
904  if (dit != numered_dofs_ptr[ss]->end()) {
905 
906  int global_idx = IdxDataTypePtr(&data_from_proc[dd]).getDofIdx();
907 #ifndef NDEBUG
908  if (PetscUnlikely(global_idx < 0))
909  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
910  "received negative dof");
911 #endif
912  bool success;
913  success = numered_dofs_ptr[ss]->modify(
914  dit, NumeredDofEntity_mofem_index_change(global_idx));
915 
916 #ifndef NDEBUG
917  if (PetscUnlikely(!success))
918  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
919  "modification unsuccessful");
920 #endif
921  success = numered_dofs_ptr[ss]->modify(
922  dit, NumeredDofEntity_part_and_glob_idx_change((*dit)->getPart(),
923  global_idx));
924 #ifndef NDEBUG
925  if (PetscUnlikely(!success))
926  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
927  "modification unsuccessful");
928 #endif
929  };
930 
931 #ifndef NDEBUG
932  if (PetscUnlikely(ddit->get()->getPStatus() == 0)) {
933 
934  // Dof is shared on this processor, however there is no element
935  // which have this dof. If DOF is not shared and received from other
936  // processor, but not marked as a shared on other that means that is
937  // data inconstancy and error should be thrown.
938 
939  std::ostringstream zz;
940  zz << **ddit << std::endl;
941  SETERRQ1(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
942  "data inconsistency, dofs is not shared, but received "
943  "from other proc\n"
944  "%s",
945  zz.str().c_str());
946  }
947 #endif
948  }
949  }
950  }
951 
952  if (square_matrix) {
953  (problem_ptr->nbDofsCol) = (problem_ptr->nbDofsRow);
954  (problem_ptr->nbLocDofsCol) = (problem_ptr->nbLocDofsRow);
955  }
956 
957  CHKERR PetscFree(olengths_rows);
958  CHKERR PetscFree(rbuf_row[0]);
959  CHKERR PetscFree(rbuf_row);
960  if (!square_matrix) {
961  CHKERR PetscFree(olengths_cols);
962  CHKERR PetscFree(rbuf_col[0]);
963  CHKERR PetscFree(rbuf_col);
964  }
965 
966  if (square_matrix) {
967  if (numered_dofs_ptr[0]->size() != numered_dofs_ptr[1]->size()) {
968  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
969  "data inconsistency for square_matrix %d!=%d",
970  numered_dofs_ptr[0]->size(), numered_dofs_ptr[1]->size());
971  }
972  if (problem_ptr->numeredRowDofsPtr != problem_ptr->numeredColDofsPtr) {
973  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
974  "data inconsistency for square_matrix");
975  }
976  }
977 
978  CHKERR printPartitionedProblem(problem_ptr, verb);
979  CHKERR debugPartitionedProblem(problem_ptr, verb);
980 
981  PetscLogEventEnd(MOFEM_EVENT_ProblemsManager, 0, 0, 0, 0);
982 
984 }
985 
987  const std::string out_name,
988 
989  const std::vector<std::string> &fields_row,
990  const std::vector<std::string> &fields_col,
991 
992  const std::string main_problem, const bool square_matrix,
993 
994  const map<std::string, boost::shared_ptr<Range>> *entityMapRow,
995  const map<std::string, boost::shared_ptr<Range>> *entityMapCol,
996 
997  int verb) {
998  MoFEM::Interface &m_field = cOre;
999  auto problems_ptr = m_field.get_problems();
1001 
1002  CHKERR m_field.clear_problem(out_name);
1003 
1004  // get reference to all problems
1005  using ProblemByName = decltype(problems_ptr->get<Problem_mi_tag>());
1006  auto &problems_by_name =
1007  const_cast<ProblemByName &>(problems_ptr->get<Problem_mi_tag>());
1008 
1009  // get iterators to out problem, i.e. build problem
1010  auto out_problem_it = problems_by_name.find(out_name);
1011  if (out_problem_it == problems_by_name.end()) {
1012  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1013  "subproblem with name < %s > not defined (top tip check spelling)",
1014  out_name.c_str());
1015  }
1016  // get iterator to main problem, i.e. out problem is subproblem of main
1017  // problem
1018  auto main_problem_it = problems_by_name.find(main_problem);
1019  if (main_problem_it == problems_by_name.end()) {
1020  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1021  "problem of subproblem with name < %s > not defined (top tip "
1022  "check spelling)",
1023  main_problem.c_str());
1024  }
1025 
1026  // get dofs for row & columns for out problem,
1027  boost::shared_ptr<NumeredDofEntity_multiIndex> out_problem_dofs[] = {
1028  out_problem_it->numeredRowDofsPtr, out_problem_it->numeredColDofsPtr};
1029  // get dofs for row & columns for main problem
1030  boost::shared_ptr<NumeredDofEntity_multiIndex> main_problem_dofs[] = {
1031  main_problem_it->numeredRowDofsPtr, main_problem_it->numeredColDofsPtr};
1032  // get local indices counter
1033  int *nb_local_dofs[] = {&out_problem_it->nbLocDofsRow,
1034  &out_problem_it->nbLocDofsCol};
1035  // get global indices counter
1036  int *nb_dofs[] = {&out_problem_it->nbDofsRow, &out_problem_it->nbDofsCol};
1037 
1038  // set number of ghost nodes to zero
1039  {
1040  out_problem_it->nbGhostDofsRow = 0;
1041  out_problem_it->nbGhostDofsCol = 0;
1042  }
1043 
1044  // put rows & columns field names in array
1045  std::vector<std::string> fields[] = {fields_row, fields_col};
1046  const map<std::string, boost::shared_ptr<Range>> *entityMap[] = {
1047  entityMapRow, entityMapCol};
1048 
1049  // make data structure fos sub-problem data
1050  out_problem_it->subProblemData =
1051  boost::make_shared<Problem::SubProblemData>();
1052 
1053  // Loop over rows and columns
1054  for (int ss = 0; ss != (square_matrix ? 1 : 2); ++ss) {
1055 
1056  // reset dofs and columns counters
1057  (*nb_local_dofs[ss]) = 0;
1058  (*nb_dofs[ss]) = 0;
1059  // clear arrays
1060  out_problem_dofs[ss]->clear();
1061 
1062  // If DOFs are cleared clear finite elements too.
1063  out_problem_it->numeredFiniteElementsPtr->clear();
1064 
1065  // get dofs by field name and insert them in out problem multi-indices
1066  for (auto field : fields[ss]) {
1067 
1068  // Following reserve memory in sequences, only two allocations are here,
1069  // once for array of objects, next for array of shared pointers
1070 
1071  // aliased sequence of pointer is killed with element
1072  boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array =
1073  boost::make_shared<std::vector<NumeredDofEntity>>();
1074  // reserve memory for field dofs
1075  if (!ss)
1076  out_problem_it->getRowDofsSequence()->emplace_back(dofs_array);
1077  else
1078  out_problem_it->getColDofsSequence()->emplace_back(dofs_array);
1079 
1080  // create elements objects
1081  auto bit_number = m_field.get_field_bit_number(field);
1082 
1083  auto add_dit_to_dofs_array = [&](auto &dit) {
1084  if (dit->get()->getPetscGlobalDofIdx() >= 0)
1085  dofs_array->emplace_back(
1086  dit->get()->getDofEntityPtr(), dit->get()->getPetscGlobalDofIdx(),
1087  dit->get()->getPetscGlobalDofIdx(),
1088  dit->get()->getPetscLocalDofIdx(), dit->get()->getPart());
1089  };
1090 
1091  auto get_dafult_dof_range = [&]() {
1092  auto dit = main_problem_dofs[ss]->get<Unique_mi_tag>().lower_bound(
1093  FieldEntity::getLoBitNumberUId(bit_number));
1094  auto hi_dit = main_problem_dofs[ss]->get<Unique_mi_tag>().upper_bound(
1095  FieldEntity::getHiBitNumberUId(bit_number));
1096  return std::make_pair(dit, hi_dit);
1097  };
1098 
1099  auto check = [&](auto &field) -> boost::shared_ptr<Range> {
1100  if (entityMap[ss]) {
1101  auto mit = entityMap[ss]->find(field);
1102  if (mit != entityMap[ss]->end()) {
1103  return mit->second;
1104  } else {
1105  return nullptr;
1106  }
1107  } else {
1108  return nullptr;
1109  }
1110  };
1111 
1112  if (auto r_ptr = check(field)) {
1113  for (auto p = r_ptr->pair_begin(); p != r_ptr->pair_end(); ++p) {
1114  const auto lo_ent = p->first;
1115  const auto hi_ent = p->second;
1116  auto dit = main_problem_dofs[ss]->get<Unique_mi_tag>().lower_bound(
1117  DofEntity::getLoFieldEntityUId(bit_number, lo_ent));
1118  auto hi_dit = main_problem_dofs[ss]->get<Unique_mi_tag>().upper_bound(
1119  DofEntity::getHiFieldEntityUId(bit_number, hi_ent));
1120  dofs_array->reserve(std::distance(dit, hi_dit));
1121  for (; dit != hi_dit; dit++) {
1122  add_dit_to_dofs_array(dit);
1123  }
1124  }
1125  } else {
1126  auto [dit, hi_dit] = get_dafult_dof_range();
1127  dofs_array->reserve(std::distance(dit, hi_dit));
1128  for (; dit != hi_dit; dit++)
1129  add_dit_to_dofs_array(dit);
1130  }
1131 
1132  // fill multi-index
1133  auto hint = out_problem_dofs[ss]->end();
1134  for (auto &v : *dofs_array)
1135  hint = out_problem_dofs[ss]->emplace_hint(hint, dofs_array, &v);
1136  }
1137  // Set local indexes
1138  {
1139  auto dit = out_problem_dofs[ss]->get<Idx_mi_tag>().begin();
1140  auto hi_dit = out_problem_dofs[ss]->get<Idx_mi_tag>().end();
1141  for (; dit != hi_dit; dit++) {
1142  int idx = -1; // if dof is not part of partition, set local index to -1
1143  if (dit->get()->getPart() == (unsigned int)m_field.get_comm_rank()) {
1144  idx = (*nb_local_dofs[ss])++;
1145  }
1146  bool success = out_problem_dofs[ss]->modify(
1147  out_problem_dofs[ss]->project<0>(dit),
1149  if (!success) {
1150  SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1151  "operation unsuccessful");
1152  }
1153  };
1154  }
1155  // Set global indexes, compress global indices
1156  {
1157  auto dit =
1158  out_problem_dofs[ss]->get<PetscLocalIdx_mi_tag>().lower_bound(0);
1159  auto hi_dit =
1160  out_problem_dofs[ss]->get<PetscLocalIdx_mi_tag>().upper_bound(
1161  out_problem_dofs[ss]->size());
1162  const int nb = std::distance(dit, hi_dit);
1163  // get main problem global indices
1164  std::vector<int> main_indices(nb);
1165  for (auto it = main_indices.begin(); dit != hi_dit; dit++, it++) {
1166  *it = dit->get()->getPetscGlobalDofIdx();
1167  }
1168  // create is with global dofs
1169  IS is;
1170  CHKERR ISCreateGeneral(m_field.get_comm(), nb, &*main_indices.begin(),
1171  PETSC_USE_POINTER, &is);
1172  // create map form main problem global indices to out problem global
1173  // indices
1174  AO ao;
1175  CHKERR AOCreateMappingIS(is, PETSC_NULL, &ao);
1176  if (ss == 0) {
1177  IS is_dup;
1178  CHKERR ISDuplicate(is, &is_dup);
1179  out_problem_it->getSubData()->rowIs = SmartPetscObj<IS>(is_dup, false);
1180  out_problem_it->getSubData()->rowMap = SmartPetscObj<AO>(ao, true);
1181  } else {
1182  IS is_dup;
1183  CHKERR ISDuplicate(is, &is_dup);
1184  out_problem_it->getSubData()->colIs = SmartPetscObj<IS>(is_dup, false);
1185  out_problem_it->getSubData()->colMap = SmartPetscObj<AO>(ao, true);
1186  }
1187  CHKERR AOApplicationToPetscIS(ao, is);
1188  // set global number of DOFs
1189  CHKERR ISGetSize(is, nb_dofs[ss]);
1190  CHKERR ISDestroy(&is);
1191  // set out problem global indices after applying map
1192  dit = out_problem_dofs[ss]->get<PetscLocalIdx_mi_tag>().lower_bound(0);
1193  for (std::vector<int>::iterator it = main_indices.begin(); dit != hi_dit;
1194  dit++, it++) {
1195  bool success = out_problem_dofs[ss]->modify(
1196  out_problem_dofs[ss]->project<0>(dit),
1198  dit->get()->getPart(), *it, *it,
1199  dit->get()->getPetscLocalDofIdx()));
1200  if (!success) {
1201  SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1202  "operation unsuccessful");
1203  }
1204  }
1205  // set global indices to nodes not on this part
1206  {
1207  NumeredDofEntityByLocalIdx::iterator dit =
1208  out_problem_dofs[ss]->get<PetscLocalIdx_mi_tag>().lower_bound(-1);
1209  NumeredDofEntityByLocalIdx::iterator hi_dit =
1210  out_problem_dofs[ss]->get<PetscLocalIdx_mi_tag>().upper_bound(-1);
1211  const int nb = std::distance(dit, hi_dit);
1212  std::vector<int> main_indices_non_local(nb);
1213  for (auto it = main_indices_non_local.begin(); dit != hi_dit;
1214  dit++, it++) {
1215  *it = dit->get()->getPetscGlobalDofIdx();
1216  }
1217  IS is;
1218  CHKERR ISCreateGeneral(m_field.get_comm(), nb,
1219  &*main_indices_non_local.begin(),
1220  PETSC_USE_POINTER, &is);
1221  CHKERR AOApplicationToPetscIS(ao, is);
1222  CHKERR ISDestroy(&is);
1223  dit = out_problem_dofs[ss]->get<PetscLocalIdx_mi_tag>().lower_bound(-1);
1224  for (auto it = main_indices_non_local.begin(); dit != hi_dit;
1225  dit++, it++) {
1226  bool success = out_problem_dofs[ss]->modify(
1227  out_problem_dofs[ss]->project<0>(dit),
1229  dit->get()->getPart(), dit->get()->getDofIdx(), *it,
1230  dit->get()->getPetscLocalDofIdx()));
1231  if (!success) {
1232  SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1233  "operation unsuccessful");
1234  }
1235  }
1236  }
1237  CHKERR AODestroy(&ao);
1238  }
1239  }
1240 
1241  if (square_matrix) {
1242  out_problem_it->numeredColDofsPtr = out_problem_it->numeredRowDofsPtr;
1243  out_problem_it->nbLocDofsCol = out_problem_it->nbLocDofsRow;
1244  out_problem_it->nbDofsCol = out_problem_it->nbDofsRow;
1245  out_problem_it->getSubData()->colIs = out_problem_it->getSubData()->rowIs;
1246  out_problem_it->getSubData()->colMap = out_problem_it->getSubData()->rowMap;
1247  }
1248 
1249  CHKERR printPartitionedProblem(&*out_problem_it, verb);
1250  CHKERR debugPartitionedProblem(&*out_problem_it, verb);
1251 
1253 }
1254 
1256  const std::string out_name, const std::vector<std::string> add_row_problems,
1257  const std::vector<std::string> add_col_problems, const bool square_matrix,
1258  int verb) {
1260  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "fields not build");
1261  if (!(cOre.getBuildMoFEM() & Core::BUILD_FE))
1262  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "FEs not build");
1263  if (!(cOre.getBuildMoFEM() & Core::BUILD_ADJ))
1264  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "adjacencies not build");
1265  MoFEM::Interface &m_field = cOre;
1266  auto problems_ptr = m_field.get_problems();
1268 
1269  CHKERR m_field.clear_problem(out_name);
1270  // get reference to all problems
1272  ProblemByName &problems_by_name =
1273  const_cast<ProblemByName &>(problems_ptr->get<Problem_mi_tag>());
1274 
1275  // Get iterators to out problem, i.e. build problem
1276  ProblemByName::iterator out_problem_it = problems_by_name.find(out_name);
1277  if (out_problem_it == problems_by_name.end()) {
1278  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1279  "problem with name < %s > not defined (top tip check spelling)",
1280  out_name.c_str());
1281  }
1282  // Make data structure for composed-problem data
1283  out_problem_it->composedProblemsData =
1284  boost::make_shared<ComposedProblemsData>();
1285  boost::shared_ptr<ComposedProblemsData> cmp_prb_data =
1286  out_problem_it->getComposedProblemsData();
1287 
1288  const std::vector<std::string> *add_prb[] = {&add_row_problems,
1289  &add_col_problems};
1290  std::vector<const Problem *> *add_prb_ptr[] = {&cmp_prb_data->rowProblemsAdd,
1291  &cmp_prb_data->colProblemsAdd};
1292  std::vector<SmartPetscObj<IS>> *add_prb_is[] = {&cmp_prb_data->rowIs,
1293  &cmp_prb_data->colIs};
1294 
1295  // Get local indices counter
1296  int *nb_local_dofs[] = {&out_problem_it->nbLocDofsRow,
1297  &out_problem_it->nbLocDofsCol};
1298  // Get global indices counter
1299  int *nb_dofs[] = {&out_problem_it->nbDofsRow, &out_problem_it->nbDofsCol};
1300 
1301  // Set number of ghost nodes to zero
1302  {
1303  out_problem_it->nbDofsRow = 0;
1304  out_problem_it->nbDofsCol = 0;
1305  out_problem_it->nbLocDofsRow = 0;
1306  out_problem_it->nbLocDofsCol = 0;
1307  out_problem_it->nbGhostDofsRow = 0;
1308  out_problem_it->nbGhostDofsCol = 0;
1309  }
1310  int nb_dofs_reserve[] = {0, 0};
1311 
1312  // Loop over rows and columns in the main problem and sub-problems
1313  for (int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1314  add_prb_ptr[ss]->reserve(add_prb[ss]->size());
1315  add_prb_is[ss]->reserve(add_prb[ss]->size());
1316  for (std::vector<std::string>::const_iterator vit = add_prb[ss]->begin();
1317  vit != add_prb[ss]->end(); vit++) {
1318  ProblemByName::iterator prb_it = problems_by_name.find(*vit);
1319  if (prb_it == problems_by_name.end()) {
1320  SETERRQ1(
1321  PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1322  "problem with name < %s > not defined (top tip check spelling)",
1323  vit->c_str());
1324  }
1325  add_prb_ptr[ss]->push_back(&*prb_it);
1326  // set number of dofs on rows and columns
1327  if (ss == 0) {
1328  // row
1329  *nb_dofs[ss] += add_prb_ptr[ss]->back()->getNbDofsRow();
1330  *nb_local_dofs[ss] += add_prb_ptr[ss]->back()->getNbLocalDofsRow();
1331  nb_dofs_reserve[ss] +=
1332  add_prb_ptr[ss]->back()->numeredRowDofsPtr->size();
1333  } else {
1334  // column
1335  *nb_dofs[ss] += add_prb_ptr[ss]->back()->getNbDofsCol();
1336  *nb_local_dofs[ss] += add_prb_ptr[ss]->back()->getNbLocalDofsCol();
1337  nb_dofs_reserve[ss] +=
1338  add_prb_ptr[ss]->back()->numeredColDofsPtr->size();
1339  }
1340  }
1341  }
1342  // if squre problem, rows and columns are the same
1343  if (square_matrix) {
1344  add_prb_ptr[1]->reserve(add_prb_ptr[0]->size());
1345  add_prb_is[1]->reserve(add_prb_ptr[0]->size());
1346  out_problem_it->numeredColDofsPtr = out_problem_it->numeredRowDofsPtr;
1347  *nb_dofs[1] = *nb_dofs[0];
1348  *nb_local_dofs[1] = *nb_local_dofs[0];
1349  }
1350 
1351  // reserve memory for dofs
1352  boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array[2];
1353  // Reserve memory
1354  for (int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1355  dofs_array[ss] = boost::make_shared<std::vector<NumeredDofEntity>>();
1356  dofs_array[ss]->reserve(nb_dofs_reserve[ss]);
1357  if (!ss)
1358  out_problem_it->getRowDofsSequence()->emplace_back(dofs_array[ss]);
1359  else
1360  out_problem_it->getColDofsSequence()->emplace_back(dofs_array[ss]);
1361  }
1362 
1363  // Push back DOFs
1364  for (int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1365  NumeredDofEntity_multiIndex::index<PetscGlobalIdx_mi_tag>::type::iterator
1366  dit,
1367  hi_dit;
1368  int shift_glob = 0;
1369  int shift_loc = 0;
1370  for (unsigned int pp = 0; pp != add_prb_ptr[ss]->size(); pp++) {
1371  PetscInt *dofs_out_idx_ptr;
1372  int nb_local_dofs = (*add_prb_ptr[ss])[pp]->getNbLocalDofsRow();
1373  CHKERR PetscMalloc(nb_local_dofs * sizeof(int), &dofs_out_idx_ptr);
1374  if (ss == 0) {
1375  dit = (*add_prb_ptr[ss])[pp]
1376  ->numeredRowDofsPtr->get<PetscGlobalIdx_mi_tag>()
1377  .begin();
1378  hi_dit = (*add_prb_ptr[ss])[pp]
1379  ->numeredRowDofsPtr->get<PetscGlobalIdx_mi_tag>()
1380  .end();
1381  } else {
1382  dit = (*add_prb_ptr[ss])[pp]
1383  ->numeredColDofsPtr->get<PetscGlobalIdx_mi_tag>()
1384  .begin();
1385  hi_dit = (*add_prb_ptr[ss])[pp]
1386  ->numeredColDofsPtr->get<PetscGlobalIdx_mi_tag>()
1387  .end();
1388  }
1389  int is_nb = 0;
1390  for (; dit != hi_dit; dit++) {
1391  const BitRefLevel &prb_bit = out_problem_it->getBitRefLevel();
1392  const BitRefLevel &prb_mask = out_problem_it->getBitRefLevelMask();
1393  const BitRefLevel &dof_bit = dit->get()->getBitRefLevel();
1394  if ((dof_bit & prb_bit).none() || ((dof_bit & prb_mask) != dof_bit))
1395  continue;
1396  const int rank = m_field.get_comm_rank();
1397  const int part = dit->get()->getPart();
1398  const int glob_idx = shift_glob + dit->get()->getPetscGlobalDofIdx();
1399  const int loc_idx =
1400  (part == rank) ? (shift_loc + dit->get()->getPetscLocalDofIdx())
1401  : -1;
1402  dofs_array[ss]->emplace_back(dit->get()->getDofEntityPtr(), glob_idx,
1403  glob_idx, loc_idx, part);
1404  if (part == rank) {
1405  dofs_out_idx_ptr[is_nb++] = glob_idx;
1406  }
1407  }
1408  if (is_nb > nb_local_dofs) {
1409  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
1410  "Data inconsistency");
1411  }
1412  IS is;
1413  CHKERR ISCreateGeneral(m_field.get_comm(), is_nb, dofs_out_idx_ptr,
1414  PETSC_OWN_POINTER, &is);
1415  auto smart_is = SmartPetscObj<IS>(is);
1416  (*add_prb_is[ss]).push_back(smart_is);
1417  if (ss == 0) {
1418  shift_glob += (*add_prb_ptr[ss])[pp]->getNbDofsRow();
1419  shift_loc += (*add_prb_ptr[ss])[pp]->getNbLocalDofsRow();
1420  } else {
1421  shift_glob += (*add_prb_ptr[ss])[pp]->getNbDofsCol();
1422  shift_loc += (*add_prb_ptr[ss])[pp]->getNbLocalDofsCol();
1423  }
1424  if (square_matrix) {
1425  (*add_prb_ptr[1]).push_back((*add_prb_ptr[0])[pp]);
1426  (*add_prb_is[1]).push_back(smart_is);
1427  }
1428  }
1429  }
1430 
1431  if ((*add_prb_is[1]).size() != (*add_prb_is[0]).size()) {
1432  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY, "Data inconsistency");
1433  }
1434 
1435  // Insert DOFs to problem multi-index
1436  for (int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1437  auto hint = (ss == 0) ? out_problem_it->numeredRowDofsPtr->end()
1438  : out_problem_it->numeredColDofsPtr->end();
1439  for (auto &v : *dofs_array[ss])
1440  hint = (ss == 0) ? out_problem_it->numeredRowDofsPtr->emplace_hint(
1441  hint, dofs_array[ss], &v)
1442  : out_problem_it->numeredColDofsPtr->emplace_hint(
1443  hint, dofs_array[ss], &v);
1444  }
1445 
1446  // Compress DOFs
1447  *nb_dofs[0] = 0;
1448  *nb_dofs[1] = 0;
1449  *nb_local_dofs[0] = 0;
1450  *nb_local_dofs[1] = 0;
1451  for (int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1452 
1453  boost::shared_ptr<NumeredDofEntity_multiIndex> dofs_ptr;
1454  if (ss == 0) {
1455  dofs_ptr = out_problem_it->numeredRowDofsPtr;
1456  } else {
1457  dofs_ptr = out_problem_it->numeredColDofsPtr;
1458  }
1459  NumeredDofEntityByUId::iterator dit, hi_dit;
1460  dit = dofs_ptr->get<Unique_mi_tag>().begin();
1461  hi_dit = dofs_ptr->get<Unique_mi_tag>().end();
1462  std::vector<int> idx;
1463  idx.reserve(std::distance(dit, hi_dit));
1464  // set dofs in order entity and dof number on entity
1465  for (; dit != hi_dit; dit++) {
1466  if (dit->get()->getPart() == (unsigned int)m_field.get_comm_rank()) {
1467  bool success = dofs_ptr->get<Unique_mi_tag>().modify(
1468  dit, NumeredDofEntity_local_idx_change((*nb_local_dofs[ss])++));
1469  if (!success) {
1470  SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
1471  "modification unsuccessful");
1472  }
1473  idx.push_back(dit->get()->getPetscGlobalDofIdx());
1474  } else {
1475  if (dit->get()->getPetscLocalDofIdx() != -1) {
1476  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
1477  "local index should be negative");
1478  }
1479  }
1480  }
1481  if (square_matrix) {
1482  *nb_local_dofs[1] = *nb_local_dofs[0];
1483  }
1484 
1485  // set new dofs mapping
1486  IS is;
1487  CHKERR ISCreateGeneral(m_field.get_comm(), idx.size(), &*idx.begin(),
1488  PETSC_USE_POINTER, &is);
1489  CHKERR ISGetSize(is, nb_dofs[ss]);
1490  if (square_matrix) {
1491  *nb_dofs[1] = *nb_dofs[0];
1492  }
1493 
1494  AO ao;
1495  CHKERR AOCreateMappingIS(is, PETSC_NULL, &ao);
1496  for (unsigned int pp = 0; pp != (*add_prb_is[ss]).size(); pp++)
1497  CHKERR AOApplicationToPetscIS(ao, (*add_prb_is[ss])[pp]);
1498 
1499  // Set DOFs numeration
1500  {
1501  std::vector<int> idx_new;
1502  idx_new.reserve(dofs_ptr->size());
1503  for (NumeredDofEntityByUId::iterator dit =
1504  dofs_ptr->get<Unique_mi_tag>().begin();
1505  dit != dofs_ptr->get<Unique_mi_tag>().end(); dit++) {
1506  idx_new.push_back(dit->get()->getPetscGlobalDofIdx());
1507  }
1508  // set new global dofs numeration
1509  IS is_new;
1510  CHKERR ISCreateGeneral(m_field.get_comm(), idx_new.size(),
1511  &*idx_new.begin(), PETSC_USE_POINTER, &is_new);
1512  CHKERR AOApplicationToPetscIS(ao, is_new);
1513  // set global indices to multi-index
1514  std::vector<int>::iterator vit = idx_new.begin();
1515  for (NumeredDofEntityByUId::iterator dit =
1516  dofs_ptr->get<Unique_mi_tag>().begin();
1517  dit != dofs_ptr->get<Unique_mi_tag>().end(); dit++) {
1518  bool success =
1519  dofs_ptr->modify(dit, NumeredDofEntity_part_and_glob_idx_change(
1520  dit->get()->getPart(), *(vit++)));
1521  if (!success) {
1522  SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
1523  "modification unsuccessful");
1524  }
1525  }
1526  CHKERR ISDestroy(&is_new);
1527  }
1528  CHKERR ISDestroy(&is);
1529  CHKERR AODestroy(&ao);
1530  }
1531 
1532  CHKERR printPartitionedProblem(&*out_problem_it, verb);
1533  CHKERR debugPartitionedProblem(&*out_problem_it, verb);
1534 
1535  // Inidcate that porble has been build
1538 
1540 }
1541 
1543  int verb) {
1544 
1545  MoFEM::Interface &m_field = cOre;
1546  auto problems_ptr = m_field.get_problems();
1548 
1550  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "fields not build");
1551  if (!(cOre.getBuildMoFEM() & Core::BUILD_FE))
1552  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "FEs not build");
1553  if (!(cOre.getBuildMoFEM() & Core::BUILD_ADJ))
1554  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "adjacencies not build");
1556  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "adjacencies not build");
1557  MOFEM_LOG("WORLD", Sev::verbose) << "Simple partition problem " << name;
1558 
1559  // find p_miit
1561  ProblemByName &problems_set =
1562  const_cast<ProblemByName &>(problems_ptr->get<Problem_mi_tag>());
1563  ProblemByName::iterator p_miit = problems_set.find(name);
1564  if (p_miit == problems_set.end()) {
1565  SETERRQ1(PETSC_COMM_SELF, 1,
1566  "problem < %s > is not found (top tip: check spelling)",
1567  name.c_str());
1568  }
1569  typedef boost::multi_index::index<NumeredDofEntity_multiIndex,
1570  Idx_mi_tag>::type NumeredDofEntitysByIdx;
1571  NumeredDofEntitysByIdx &dofs_row_by_idx =
1572  p_miit->numeredRowDofsPtr->get<Idx_mi_tag>();
1573  NumeredDofEntitysByIdx &dofs_col_by_idx =
1574  p_miit->numeredColDofsPtr->get<Idx_mi_tag>();
1575  boost::multi_index::index<NumeredDofEntity_multiIndex,
1576  Idx_mi_tag>::type::iterator miit_row,
1577  hi_miit_row;
1578  boost::multi_index::index<NumeredDofEntity_multiIndex,
1579  Idx_mi_tag>::type::iterator miit_col,
1580  hi_miit_col;
1581  DofIdx &nb_row_local_dofs = p_miit->nbLocDofsRow;
1582  DofIdx &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
1583  nb_row_local_dofs = 0;
1584  nb_row_ghost_dofs = 0;
1585  DofIdx &nb_col_local_dofs = p_miit->nbLocDofsCol;
1586  DofIdx &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
1587  nb_col_local_dofs = 0;
1588  nb_col_ghost_dofs = 0;
1589 
1590  bool square_matrix = false;
1591  if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr) {
1592  square_matrix = true;
1593  }
1594 
1595  // get row range of local indices
1596  PetscLayout layout_row;
1597  const int *ranges_row;
1598 
1599  DofIdx nb_dofs_row = dofs_row_by_idx.size();
1600  CHKERR PetscLayoutCreate(m_field.get_comm(), &layout_row);
1601  CHKERR PetscLayoutSetBlockSize(layout_row, 1);
1602  CHKERR PetscLayoutSetSize(layout_row, nb_dofs_row);
1603  CHKERR PetscLayoutSetUp(layout_row);
1604  CHKERR PetscLayoutGetRanges(layout_row, &ranges_row);
1605  // get col range of local indices
1606  PetscLayout layout_col;
1607  const int *ranges_col;
1608  if (!square_matrix) {
1609  DofIdx nb_dofs_col = dofs_col_by_idx.size();
1610  CHKERR PetscLayoutCreate(m_field.get_comm(), &layout_col);
1611  CHKERR PetscLayoutSetBlockSize(layout_col, 1);
1612  CHKERR PetscLayoutSetSize(layout_col, nb_dofs_col);
1613  CHKERR PetscLayoutSetUp(layout_col);
1614  CHKERR PetscLayoutGetRanges(layout_col, &ranges_col);
1615  }
1616  for (unsigned int part = 0; part < (unsigned int)m_field.get_comm_size();
1617  part++) {
1618  miit_row = dofs_row_by_idx.lower_bound(ranges_row[part]);
1619  hi_miit_row = dofs_row_by_idx.lower_bound(ranges_row[part + 1]);
1620  if (std::distance(miit_row, hi_miit_row) !=
1621  ranges_row[part + 1] - ranges_row[part]) {
1622  SETERRQ4(
1623  PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1624  "data inconsistency, std::distance(miit_row,hi_miit_row) != rend - "
1625  "rstart (%d != %d - %d = %d) ",
1626  std::distance(miit_row, hi_miit_row), ranges_row[part + 1],
1627  ranges_row[part], ranges_row[part + 1] - ranges_row[part]);
1628  }
1629  // loop rows
1630  for (; miit_row != hi_miit_row; miit_row++) {
1631  bool success = dofs_row_by_idx.modify(
1632  miit_row,
1633  NumeredDofEntity_part_and_glob_idx_change(part, (*miit_row)->dofIdx));
1634  if (!success)
1635  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
1636  "modification unsuccessful");
1637  if (part == (unsigned int)m_field.get_comm_rank()) {
1638  success = dofs_row_by_idx.modify(
1639  miit_row, NumeredDofEntity_local_idx_change(nb_row_local_dofs++));
1640  if (!success)
1641  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
1642  "modification unsuccessful");
1643  }
1644  }
1645  if (!square_matrix) {
1646  miit_col = dofs_col_by_idx.lower_bound(ranges_col[part]);
1647  hi_miit_col = dofs_col_by_idx.lower_bound(ranges_col[part + 1]);
1648  if (std::distance(miit_col, hi_miit_col) !=
1649  ranges_col[part + 1] - ranges_col[part]) {
1650  SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1651  "data inconsistency, std::distance(miit_col,hi_miit_col) != "
1652  "rend - "
1653  "rstart (%d != %d - %d = %d) ",
1654  std::distance(miit_col, hi_miit_col), ranges_col[part + 1],
1655  ranges_col[part], ranges_col[part + 1] - ranges_col[part]);
1656  }
1657  // loop cols
1658  for (; miit_col != hi_miit_col; miit_col++) {
1659  bool success = dofs_col_by_idx.modify(
1661  part, (*miit_col)->dofIdx));
1662  if (!success)
1663  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
1664  "modification unsuccessful");
1665  if (part == (unsigned int)m_field.get_comm_rank()) {
1666  success = dofs_col_by_idx.modify(
1667  miit_col, NumeredDofEntity_local_idx_change(nb_col_local_dofs++));
1668  if (!success)
1669  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
1670  "modification unsuccessful");
1671  }
1672  }
1673  }
1674  }
1675  CHKERR PetscLayoutDestroy(&layout_row);
1676  if (!square_matrix) {
1677  CHKERR PetscLayoutDestroy(&layout_col);
1678  }
1679  if (square_matrix) {
1680  nb_col_local_dofs = nb_row_local_dofs;
1681  nb_col_ghost_dofs = nb_row_ghost_dofs;
1682  }
1683  CHKERR printPartitionedProblem(&*p_miit, verb);
1686 }
1687 
1689  int verb) {
1690  MoFEM::Interface &m_field = cOre;
1691  auto problems_ptr = m_field.get_problems();
1693 
1694  MOFEM_LOG("WORLD", Sev::noisy) << "Partition problem " << name;
1695 
1696  using NumeredDofEntitysByIdx =
1698  using ProblemsByName = Problem_multiIndex::index<Problem_mi_tag>::type;
1699 
1700  // Find problem pointer by name
1701  auto &problems_set =
1702  const_cast<ProblemsByName &>(problems_ptr->get<Problem_mi_tag>());
1703  auto p_miit = problems_set.find(name);
1704  if (p_miit == problems_set.end()) {
1705  SETERRQ1(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
1706  "problem with name %s not defined (top tip check spelling)",
1707  name.c_str());
1708  }
1709  int nb_dofs_row = p_miit->getNbDofsRow();
1710 
1711  if (m_field.get_comm_size() != 1) {
1712 
1713  if (!(cOre.getBuildMoFEM() & (1 << 0)))
1714  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "fields not build");
1715  if (!(cOre.getBuildMoFEM() & (1 << 1)))
1716  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "FEs not build");
1717  if (!(cOre.getBuildMoFEM() & (1 << 2)))
1718  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1719  "entFEAdjacencies not build");
1720  if (!(cOre.getBuildMoFEM() & (1 << 3)))
1721  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "Problems not build");
1722 
1723  Mat Adj;
1724  CHKERR m_field.getInterface<MatrixManager>()
1725  ->createMPIAdjWithArrays<Idx_mi_tag>(name, &Adj, verb);
1726 
1727  int m, n;
1728  CHKERR MatGetSize(Adj, &m, &n);
1729  if (verb > VERY_VERBOSE)
1730  MatView(Adj, PETSC_VIEWER_STDOUT_WORLD);
1731 
1732  // partitioning
1733  MatPartitioning part;
1734  IS is;
1735  CHKERR MatPartitioningCreate(m_field.get_comm(), &part);
1736  CHKERR MatPartitioningSetAdjacency(part, Adj);
1737  CHKERR MatPartitioningSetFromOptions(part);
1738  CHKERR MatPartitioningSetNParts(part, m_field.get_comm_size());
1739  CHKERR MatPartitioningApply(part, &is);
1740  if (verb > VERY_VERBOSE)
1741  ISView(is, PETSC_VIEWER_STDOUT_WORLD);
1742 
1743  // gather
1744  IS is_gather, is_num, is_gather_num;
1745  CHKERR ISAllGather(is, &is_gather);
1746  CHKERR ISPartitioningToNumbering(is, &is_num);
1747  CHKERR ISAllGather(is_num, &is_gather_num);
1748  const int *part_number, *petsc_idx;
1749  CHKERR ISGetIndices(is_gather, &part_number);
1750  CHKERR ISGetIndices(is_gather_num, &petsc_idx);
1751  int size_is_num, size_is_gather;
1752  CHKERR ISGetSize(is_gather, &size_is_gather);
1753  if (size_is_gather != (int)nb_dofs_row)
1754  SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1755  "data inconsistency %d != %d", size_is_gather, nb_dofs_row);
1756 
1757  CHKERR ISGetSize(is_num, &size_is_num);
1758  if (size_is_num != (int)nb_dofs_row)
1759  SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1760  "data inconsistency %d != %d", size_is_num, nb_dofs_row);
1761 
1762  bool square_matrix = false;
1763  if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr)
1764  square_matrix = true;
1765 
1766  // if (!square_matrix) {
1767  // // FIXME: This is for back compatibility, if deprecate interface
1768  // function
1769  // // build interfaces is removed, this part of the code will be obsolete
1770  // auto mit_row = p_miit->numeredRowDofsPtr->get<Idx_mi_tag>().begin();
1771  // auto hi_mit_row = p_miit->numeredRowDofsPtr->get<Idx_mi_tag>().end();
1772  // auto mit_col = p_miit->numeredColDofsPtr->get<Idx_mi_tag>().begin();
1773  // auto hi_mit_col = p_miit->numeredColDofsPtr->get<Idx_mi_tag>().end();
1774  // for (; mit_row != hi_mit_row; mit_row++, mit_col++) {
1775  // if (mit_col == hi_mit_col) {
1776  // SETERRQ(
1777  // PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1778  // "check finite element definition, nb. of rows is not equal to "
1779  // "number for columns");
1780  // }
1781  // if (mit_row->get()->getLocalUniqueId() !=
1782  // mit_col->get()->getLocalUniqueId()) {
1783  // SETERRQ(
1784  // PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1785  // "check finite element definition, nb. of rows is not equal to "
1786  // "number for columns");
1787  // }
1788  // }
1789  // }
1790 
1791  auto number_dofs = [&](auto &dofs_idx, auto &counter) {
1793  for (auto miit_dofs_row = dofs_idx.begin();
1794  miit_dofs_row != dofs_idx.end(); miit_dofs_row++) {
1795  const int part = part_number[(*miit_dofs_row)->dofIdx];
1796  if (part == (unsigned int)m_field.get_comm_rank()) {
1797  const bool success = dofs_idx.modify(
1798  miit_dofs_row,
1800  part, petsc_idx[(*miit_dofs_row)->dofIdx], counter++));
1801  if (!success) {
1802  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
1803  "modification unsuccessful");
1804  }
1805  } else {
1806  const bool success = dofs_idx.modify(
1808  part, petsc_idx[(*miit_dofs_row)->dofIdx]));
1809  if (!success) {
1810  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
1811  "modification unsuccessful");
1812  }
1813  }
1814  }
1816  };
1817 
1818  // Set petsc global indices
1819  auto &dofs_row_by_idx_no_const = const_cast<NumeredDofEntitysByIdx &>(
1820  p_miit->numeredRowDofsPtr->get<Idx_mi_tag>());
1821  int &nb_row_local_dofs = p_miit->nbLocDofsRow;
1822  int &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
1823  nb_row_local_dofs = 0;
1824  nb_row_ghost_dofs = 0;
1825 
1826  CHKERR number_dofs(dofs_row_by_idx_no_const, nb_row_local_dofs);
1827 
1828  int &nb_col_local_dofs = p_miit->nbLocDofsCol;
1829  int &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
1830  if (square_matrix) {
1831  nb_col_local_dofs = nb_row_local_dofs;
1832  nb_col_ghost_dofs = nb_row_ghost_dofs;
1833  } else {
1834  NumeredDofEntitysByIdx &dofs_col_by_idx_no_const =
1835  const_cast<NumeredDofEntitysByIdx &>(
1836  p_miit->numeredColDofsPtr->get<Idx_mi_tag>());
1837  nb_col_local_dofs = 0;
1838  nb_col_ghost_dofs = 0;
1839  CHKERR number_dofs(dofs_col_by_idx_no_const, nb_col_local_dofs);
1840  }
1841 
1842  CHKERR ISRestoreIndices(is_gather, &part_number);
1843  CHKERR ISRestoreIndices(is_gather_num, &petsc_idx);
1844  CHKERR ISDestroy(&is_num);
1845  CHKERR ISDestroy(&is_gather_num);
1846  CHKERR ISDestroy(&is_gather);
1847  CHKERR ISDestroy(&is);
1848  CHKERR MatPartitioningDestroy(&part);
1849  CHKERR MatDestroy(&Adj);
1850  CHKERR printPartitionedProblem(&*p_miit, verb);
1851  } else {
1852 
1853  auto number_dofs = [&](auto &dof_idx, auto &counter) {
1855  for (auto miit_dofs_row = dof_idx.begin(); miit_dofs_row != dof_idx.end();
1856  miit_dofs_row++) {
1857  const bool success = dof_idx.modify(
1858  miit_dofs_row,
1859  NumeredDofEntity_part_and_indices_change(0, counter, counter));
1860  ++counter;
1861  if (!success) {
1862  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
1863  "modification unsuccessful");
1864  }
1865  }
1867  };
1868 
1869  auto &dofs_row_by_idx_no_const = const_cast<NumeredDofEntitysByIdx &>(
1870  p_miit->numeredRowDofsPtr->get<Idx_mi_tag>());
1871  int &nb_row_local_dofs = p_miit->nbLocDofsRow;
1872  int &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
1873  nb_row_local_dofs = 0;
1874  nb_row_ghost_dofs = 0;
1875 
1876  CHKERR number_dofs(dofs_row_by_idx_no_const, nb_row_local_dofs);
1877 
1878  bool square_matrix = false;
1879  if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr)
1880  square_matrix = true;
1881 
1882  int &nb_col_local_dofs = p_miit->nbLocDofsCol;
1883  int &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
1884  if (square_matrix) {
1885  nb_col_local_dofs = nb_row_local_dofs;
1886  nb_col_ghost_dofs = nb_row_ghost_dofs;
1887  } else {
1888  NumeredDofEntitysByIdx &dofs_col_by_idx_no_const =
1889  const_cast<NumeredDofEntitysByIdx &>(
1890  p_miit->numeredColDofsPtr->get<Idx_mi_tag>());
1891  nb_col_local_dofs = 0;
1892  nb_col_ghost_dofs = 0;
1893  CHKERR number_dofs(dofs_col_by_idx_no_const, nb_col_local_dofs);
1894  }
1895  }
1896 
1897  cOre.getBuildMoFEM() |= 1 << 4;
1899 }
1900 
1902  const std::string name, const std::string problem_for_rows, bool copy_rows,
1903  const std::string problem_for_cols, bool copy_cols, int verb) {
1904  MoFEM::Interface &m_field = cOre;
1905  auto problems_ptr = m_field.get_problems();
1907 
1909  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY, "pRoblems not build");
1910 
1912 
1913  // find p_miit
1914  ProblemByName &problems_by_name =
1915  const_cast<ProblemByName &>(problems_ptr->get<Problem_mi_tag>());
1916  ProblemByName::iterator p_miit = problems_by_name.find(name);
1917  if (p_miit == problems_by_name.end()) {
1918  SETERRQ1(m_field.get_comm(), MOFEM_NOT_FOUND,
1919  "problem with name < %s > not defined (top tip check spelling)",
1920  name.c_str());
1921  }
1922  if (verb > QUIET)
1923  MOFEM_LOG("WORLD", Sev::inform)
1924  << p_miit->getName() << " from rows of " << problem_for_rows
1925  << " and columns of " << problem_for_cols;
1926 
1927  // find p_miit_row
1928  ProblemByName::iterator p_miit_row = problems_by_name.find(problem_for_rows);
1929  if (p_miit_row == problems_by_name.end()) {
1930  SETERRQ1(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
1931  "problem with name < %s > not defined (top tip check spelling)",
1932  problem_for_rows.c_str());
1933  }
1934  const boost::shared_ptr<NumeredDofEntity_multiIndex> dofs_row =
1935  p_miit_row->numeredRowDofsPtr;
1936 
1937  // find p_mit_col
1938  ProblemByName::iterator p_miit_col = problems_by_name.find(problem_for_cols);
1939  if (p_miit_col == problems_by_name.end()) {
1940  SETERRQ1(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
1941  "problem with name < %s > not defined (top tip check spelling)",
1942  problem_for_cols.c_str());
1943  }
1944  boost::shared_ptr<NumeredDofEntity_multiIndex> dofs_col =
1945  p_miit_col->numeredColDofsPtr;
1946 
1947  bool copy[] = {copy_rows, copy_cols};
1948  boost::shared_ptr<NumeredDofEntity_multiIndex> composed_dofs[] = {
1949  p_miit->numeredRowDofsPtr, p_miit->numeredColDofsPtr};
1950 
1951  int *nb_local_dofs[] = {&p_miit->nbLocDofsRow, &p_miit->nbLocDofsCol};
1952  int *nb_dofs[] = {&p_miit->nbDofsRow, &p_miit->nbDofsCol};
1953  boost::shared_ptr<NumeredDofEntity_multiIndex> copied_dofs[] = {dofs_row,
1954  dofs_col};
1955 
1956  for (int ss = 0; ss < 2; ss++) {
1957 
1958  // build indices
1959  *nb_local_dofs[ss] = 0;
1960  if (!copy[ss]) {
1961 
1962  // only copy indices which are belong to some elements if this problem
1963  std::vector<int> is_local, is_new;
1964 
1965  NumeredDofEntityByUId &dofs_by_uid =
1966  copied_dofs[ss]->get<Unique_mi_tag>();
1967  for (NumeredDofEntity_multiIndex::iterator dit =
1968  composed_dofs[ss]->begin();
1969  dit != composed_dofs[ss]->end(); dit++) {
1970  NumeredDofEntityByUId::iterator diit =
1971  dofs_by_uid.find((*dit)->getLocalUniqueId());
1972  if (diit == dofs_by_uid.end()) {
1973  SETERRQ(
1975  "data inconsistency, could not find dof in composite problem");
1976  }
1977  int part_number = (*diit)->getPart(); // get part number
1978  int petsc_global_dof = (*diit)->getPetscGlobalDofIdx();
1979  bool success;
1980  success = composed_dofs[ss]->modify(
1982  petsc_global_dof));
1983  if (!success) {
1984  SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
1985  "modification unsuccessful");
1986  }
1987  if ((*dit)->getPart() == (unsigned int)m_field.get_comm_rank()) {
1988  success = composed_dofs[ss]->modify(
1989  dit, NumeredDofEntity_local_idx_change((*nb_local_dofs[ss])++));
1990  if (!success) {
1991  SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
1992  "modification unsuccessful");
1993  }
1994  is_local.push_back(petsc_global_dof);
1995  }
1996  }
1997 
1998  AO ao;
1999  CHKERR AOCreateMapping(m_field.get_comm(), is_local.size(), &is_local[0],
2000  NULL, &ao);
2001 
2002  // apply local to global mapping
2003  is_local.resize(0);
2004  for (NumeredDofEntity_multiIndex::iterator dit =
2005  composed_dofs[ss]->begin();
2006  dit != composed_dofs[ss]->end(); dit++) {
2007  is_local.push_back((*dit)->getPetscGlobalDofIdx());
2008  }
2009  CHKERR AOPetscToApplication(ao, is_local.size(), &is_local[0]);
2010  int idx2 = 0;
2011  for (NumeredDofEntity_multiIndex::iterator dit =
2012  composed_dofs[ss]->begin();
2013  dit != composed_dofs[ss]->end(); dit++) {
2014  int part_number = (*dit)->getPart(); // get part number
2015  int petsc_global_dof = is_local[idx2++];
2016  bool success;
2017  success = composed_dofs[ss]->modify(
2019  petsc_global_dof));
2020  if (!success) {
2021  SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
2022  "modification unsuccessful");
2023  }
2024  }
2025 
2026  CHKERR AODestroy(&ao);
2027 
2028  } else {
2029 
2030  for (NumeredDofEntity_multiIndex::iterator dit = copied_dofs[ss]->begin();
2031  dit != copied_dofs[ss]->end(); dit++) {
2032  std::pair<NumeredDofEntity_multiIndex::iterator, bool> p;
2033  p = composed_dofs[ss]->insert(boost::shared_ptr<NumeredDofEntity>(
2034  new NumeredDofEntity((*dit)->getDofEntityPtr())));
2035  if (p.second) {
2036  (*nb_dofs[ss])++;
2037  }
2038  int dof_idx = (*dit)->getDofIdx();
2039  int part_number = (*dit)->getPart(); // get part number
2040  int petsc_global_dof = (*dit)->getPetscGlobalDofIdx();
2041  if (part_number == (unsigned int)m_field.get_comm_rank()) {
2042  const bool success = composed_dofs[ss]->modify(
2044  part_number, dof_idx, petsc_global_dof,
2045  (*nb_local_dofs[ss])++));
2046  if (!success) {
2047  SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
2048  "modification unsuccessful");
2049  }
2050  } else {
2051  const bool success = composed_dofs[ss]->modify(
2053  part_number, dof_idx, petsc_global_dof));
2054  if (!success) {
2055  SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
2056  "modification unsuccessful");
2057  }
2058  }
2059  }
2060  }
2061  }
2062 
2063  CHKERR printPartitionedProblem(&*p_miit, verb);
2064  CHKERR debugPartitionedProblem(&*p_miit, verb);
2065 
2067 }
2068 
2070 ProblemsManager::printPartitionedProblem(const Problem *problem_ptr, int verb) {
2071  MoFEM::Interface &m_field = cOre;
2073 
2074  if (verb > QUIET) {
2075 
2076  MOFEM_LOG("SYNC", Sev::inform)
2077  << problem_ptr->getName() << " Nb. local dof "
2078  << problem_ptr->getNbLocalDofsRow() << " by "
2079  << problem_ptr->getNbLocalDofsCol() << " nb global dofs "
2080  << problem_ptr->getNbDofsRow() << " by " << problem_ptr->getNbDofsCol();
2081 
2082  MOFEM_LOG_SYNCHRONISE(m_field.get_comm())
2083  }
2084 
2086 }
2087 
2089 ProblemsManager::debugPartitionedProblem(const Problem *problem_ptr, int verb) {
2090  MoFEM::Interface &m_field = cOre;
2092 
2093  auto save_ent = [](moab::Interface &moab, const std::string name,
2094  const EntityHandle ent) {
2096  EntityHandle out_meshset;
2097  CHKERR moab.create_meshset(MESHSET_SET, out_meshset);
2098  CHKERR moab.add_entities(out_meshset, &ent, 1);
2099  CHKERR moab.write_file(name.c_str(), "VTK", "", &out_meshset, 1);
2100  CHKERR moab.delete_entities(&out_meshset, 1);
2102  };
2103 
2104  if (debug > 0) {
2105 
2107  NumeredDofEntitysByIdx;
2108  NumeredDofEntitysByIdx::iterator dit, hi_dit;
2109  const NumeredDofEntitysByIdx *numered_dofs_ptr[] = {
2110  &(problem_ptr->numeredRowDofsPtr->get<Idx_mi_tag>()),
2111  &(problem_ptr->numeredColDofsPtr->get<Idx_mi_tag>())};
2112 
2113  int *nbdof_ptr[] = {&problem_ptr->nbDofsRow, &problem_ptr->nbDofsCol};
2114  int *local_nbdof_ptr[] = {&problem_ptr->nbLocDofsRow,
2115  &problem_ptr->nbLocDofsCol};
2116 
2117  for (int ss = 0; ss < 2; ss++) {
2118 
2119  dit = numered_dofs_ptr[ss]->begin();
2120  hi_dit = numered_dofs_ptr[ss]->end();
2121  for (; dit != hi_dit; dit++) {
2122  if ((*dit)->getPart() == (unsigned int)m_field.get_comm_rank()) {
2123  if ((*dit)->getPetscLocalDofIdx() < 0) {
2124  std::ostringstream zz;
2125  zz << "rank " << m_field.get_comm_rank() << " " << **dit;
2126  SETERRQ2(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE,
2127  "local dof index for %d (0-row, 1-col) not set, i.e. has "
2128  "negative value\n %s",
2129  ss, zz.str().c_str());
2130  }
2131  if ((*dit)->getPetscLocalDofIdx() >= *local_nbdof_ptr[ss]) {
2132  std::ostringstream zz;
2133  zz << "rank " << m_field.get_comm_rank() << " " << **dit;
2134  SETERRQ2(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE,
2135  "local dofs for %d (0-row, 1-col) out of range\n %s", ss,
2136  zz.str().c_str());
2137  }
2138  } else {
2139  if ((*dit)->getPetscGlobalDofIdx() < 0) {
2140 
2141  const EntityHandle ent = (*dit)->getEnt();
2142  CHKERR save_ent(
2143  m_field.get_moab(),
2144  "debug_part" +
2145  boost::lexical_cast<std::string>(m_field.get_comm_rank()) +
2146  "_negative_global_index.vtk",
2147  ent);
2148 
2149  std::ostringstream zz;
2150  zz << "rank " << m_field.get_comm_rank() << " "
2151  << dit->get()->getBitRefLevel() << " " << **dit;
2152  SETERRQ2(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE,
2153  "global dof index for %d (0-row, 1-col) row not set, i.e. "
2154  "has negative value\n %s",
2155  ss, zz.str().c_str());
2156  }
2157  if ((*dit)->getPetscGlobalDofIdx() >= *nbdof_ptr[ss]) {
2158  std::ostringstream zz;
2159  zz << "rank " << m_field.get_comm_rank() << " nb_dofs "
2160  << *nbdof_ptr[ss] << " " << **dit;
2161  SETERRQ2(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE,
2162  "global dofs for %d (0-row, 1-col) out of range\n %s", ss,
2163  zz.str().c_str());
2164  }
2165  }
2166  }
2167  }
2168  }
2170 }
2171 
2173  bool part_from_moab,
2174  int low_proc,
2175  int hi_proc, int verb) {
2176  MoFEM::Interface &m_field = cOre;
2177  auto problems_ptr = m_field.get_problems();
2178  auto fe_ent_ptr = m_field.get_ents_finite_elements();
2180 
2182  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY, "fields not build");
2183 
2184  if (!(cOre.getBuildMoFEM() & Core::BUILD_FE))
2185  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY, "FEs not build");
2186 
2187  if (!(cOre.getBuildMoFEM() & Core::BUILD_ADJ))
2188  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2189  "adjacencies not build");
2190 
2192  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY, "problem not build");
2193 
2195  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2196  "problem not partitioned");
2197 
2198  if (low_proc == -1)
2199  low_proc = m_field.get_comm_rank();
2200  if (hi_proc == -1)
2201  hi_proc = m_field.get_comm_rank();
2202 
2203  // Find pointer to problem of given name
2205  auto &problems =
2206  const_cast<ProblemByName &>(problems_ptr->get<Problem_mi_tag>());
2207  ProblemByName::iterator p_miit = problems.find(name);
2208  if (p_miit == problems.end()) {
2209  SETERRQ1(m_field.get_comm(), MOFEM_NOT_FOUND,
2210  "problem < %s > not found (top tip: check spelling)",
2211  name.c_str());
2212  }
2213 
2214  // Get reference on finite elements multi-index on the problem
2215  NumeredEntFiniteElement_multiIndex &problem_finite_elements =
2216  *p_miit->numeredFiniteElementsPtr;
2217 
2218  // Clear all elements and data, build it again
2219  problem_finite_elements.clear();
2220 
2221  // Check if dofs and columns are the same, i.e. structurally symmetric
2222  // problem
2223  bool do_cols_prob = true;
2224  if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr) {
2225  do_cols_prob = false;
2226  }
2227 
2228  auto get_good_elems = [&]() {
2229  auto good_elems = std::vector<decltype(fe_ent_ptr->begin())>();
2230  good_elems.reserve(fe_ent_ptr->size());
2231 
2232  const auto prb_bit = p_miit->getBitRefLevel();
2233  const auto prb_mask = p_miit->getBitRefLevelMask();
2234 
2235  // Loop over all elements in database and if right element is there add it
2236  // to problem finite element multi-index
2237  for (auto efit = fe_ent_ptr->begin(); efit != fe_ent_ptr->end(); ++efit) {
2238 
2239  // if element is not part of problem
2240  if (((*efit)->getId() & p_miit->getBitFEId()).any()) {
2241 
2242  const auto &fe_bit = (*efit)->getBitRefLevel();
2243 
2244  // if entity is not problem refinement level
2245  if ((fe_bit & prb_mask) == fe_bit && (fe_bit & prb_bit).any())
2246  good_elems.emplace_back(efit);
2247  }
2248  }
2249 
2250  return good_elems;
2251  };
2252 
2253  auto good_elems = get_good_elems();
2254 
2255  auto numbered_good_elems_ptr =
2256  boost::make_shared<std::vector<NumeredEntFiniteElement>>();
2257  numbered_good_elems_ptr->reserve(good_elems.size());
2258  for (auto &efit : good_elems)
2259  numbered_good_elems_ptr->emplace_back(NumeredEntFiniteElement(*efit));
2260 
2261  if (!do_cols_prob) {
2262  for (auto &fe : *numbered_good_elems_ptr) {
2263  if (fe.sPtr->getRowFieldEntsPtr() == fe.sPtr->getColFieldEntsPtr()) {
2264  fe.getColFieldEntsPtr() = fe.getRowFieldEntsPtr();
2265  }
2266  }
2267  }
2268 
2269  if (part_from_moab) {
2270  for (auto &fe : *numbered_good_elems_ptr) {
2271  if (fe.getEntType() == MBENTITYSET) {
2272  fe.part = m_field.get_comm_rank();
2273  } else {
2274  // if partition is taken from moab partition
2275  int proc = fe.getPartProc();
2276  if (proc == -1 && fe.getEntType() == MBVERTEX)
2277  proc = fe.getOwnerProc();
2278  fe.part = proc;
2279  }
2280  }
2281  }
2282 
2283  for (auto &fe : *numbered_good_elems_ptr) {
2284 
2286  CHKERR fe.sPtr->getRowDofView(*(p_miit->numeredRowDofsPtr), rows_view);
2287 
2288  if (!part_from_moab) {
2289  if (fe.getEntType() == MBENTITYSET) {
2290  fe.part = m_field.get_comm_rank();
2291  } else {
2292  std::vector<int> parts(m_field.get_comm_size(), 0);
2293  for (auto &dof_ptr : rows_view)
2294  parts[dof_ptr->pArt]++;
2295  std::vector<int>::iterator pos =
2296  max_element(parts.begin(), parts.end());
2297  const auto max_part = std::distance(parts.begin(), pos);
2298  fe.part = max_part;
2299  }
2300  }
2301  }
2302 
2303  for (auto &fe : *numbered_good_elems_ptr) {
2304 
2305  auto check_fields_and_dofs = [&]() {
2306  if (!part_from_moab) {
2307  if (fe.getBitFieldIdRow().none() && m_field.get_comm_size() == 0) {
2308  MOFEM_LOG("WORLD", Sev::warning)
2309  << "At least one field has to be added to element row to "
2310  "determine partition of finite element. Check element " +
2311  boost::lexical_cast<std::string>(fe.getName());
2312  }
2313  }
2314 
2315  return true;
2316  };
2317 
2318  if (check_fields_and_dofs()) {
2319  // Add element to the problem
2320  auto p = problem_finite_elements.insert(
2321  boost::shared_ptr<NumeredEntFiniteElement>(numbered_good_elems_ptr,
2322  &fe));
2323  if (!p.second)
2324  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "element is there");
2325  }
2326  }
2327 
2328  if (verb >= VERBOSE) {
2329  auto elements_on_rank =
2330  problem_finite_elements.get<Part_mi_tag>().equal_range(
2331  m_field.get_comm_rank());
2332  MOFEM_LOG("SYNC", Sev::verbose)
2333  << p_miit->getName() << " nb. elems "
2334  << std::distance(elements_on_rank.first, elements_on_rank.second);
2335  auto fe_ptr = m_field.get_finite_elements();
2336  for (auto &fe : *fe_ptr) {
2337  auto e_range =
2338  problem_finite_elements.get<Composite_Name_And_Part_mi_tag>()
2339  .equal_range(
2340  boost::make_tuple(fe->getName(), m_field.get_comm_rank()));
2341  MOFEM_LOG("SYNC", Sev::noisy)
2342  << "Element " << fe->getName() << " nb. elems "
2343  << std::distance(e_range.first, e_range.second);
2344  }
2345 
2346  MOFEM_LOG_SYNCHRONISE(m_field.get_comm());
2347  }
2348 
2351 }
2352 
2354  int verb) {
2355  MoFEM::Interface &m_field = cOre;
2356  auto problems_ptr = m_field.get_problems();
2358 
2360  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2361  "partition of problem not build");
2363  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2364  "partitions finite elements not build");
2365 
2366  // get problem pointer
2367  auto p_miit = problems_ptr->get<Problem_mi_tag>().find(name);
2368  if (p_miit == problems_ptr->get<Problem_mi_tag>().end())
2369  SETERRQ1(PETSC_COMM_SELF, MOFEM_INVALID_DATA, "Problem %s not fond",
2370  name.c_str());
2371 
2372  // get reference to number of ghost dofs
2373  int &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
2374  int &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
2375  nb_row_ghost_dofs = 0;
2376  nb_col_ghost_dofs = 0;
2377 
2378  // do work if more than one processor
2379  if (m_field.get_comm_size() > 1) {
2380 
2382  ghost_idx_col_view;
2383 
2384  // get elements on this partition
2385  auto fe_range =
2386  p_miit->numeredFiniteElementsPtr->get<Part_mi_tag>().equal_range(
2387  m_field.get_comm_rank());
2388 
2389  // get dofs on elements which are not part of this partition
2390 
2391  struct Inserter {
2392  using Vec = std::vector<boost::shared_ptr<NumeredDofEntity>>;
2393  using It = Vec::iterator;
2394  It operator()(Vec &dofs_view, It &hint,
2395  boost::shared_ptr<NumeredDofEntity> &&dof) {
2396  dofs_view.emplace_back(dof);
2397  return dofs_view.end();
2398  }
2399  };
2400 
2401  // rows
2402  std::vector<boost::shared_ptr<NumeredDofEntity>> fe_vec_view;
2403  auto hint_r = ghost_idx_row_view.begin();
2404  for (auto fe_ptr = fe_range.first; fe_ptr != fe_range.second; ++fe_ptr) {
2405 
2406  fe_vec_view.clear();
2407  CHKERR EntFiniteElement::getDofView((*fe_ptr)->getRowFieldEnts(),
2408  *(p_miit->getNumeredRowDofsPtr()),
2409  fe_vec_view, Inserter());
2410 
2411  for (auto &dof_ptr : fe_vec_view) {
2412  if (dof_ptr->getPart() != (unsigned int)m_field.get_comm_rank()) {
2413  hint_r = ghost_idx_row_view.emplace_hint(hint_r, dof_ptr);
2414  }
2415  }
2416  }
2417 
2418  // columns
2419  if (p_miit->numeredColDofsPtr == p_miit->numeredRowDofsPtr) {
2420 
2421  auto hint_c = ghost_idx_col_view.begin();
2422  for (auto fe_ptr = fe_range.first; fe_ptr != fe_range.second; ++fe_ptr) {
2423 
2424  fe_vec_view.clear();
2425  CHKERR EntFiniteElement::getDofView((*fe_ptr)->getColFieldEnts(),
2426  *(p_miit->getNumeredColDofsPtr()),
2427  fe_vec_view, Inserter());
2428 
2429  for (auto &dof_ptr : fe_vec_view) {
2430  if (dof_ptr->getPart() != (unsigned int)m_field.get_comm_rank()) {
2431  hint_c = ghost_idx_col_view.emplace_hint(hint_c, dof_ptr);
2432  }
2433  }
2434  }
2435  }
2436 
2437  int *nb_ghost_dofs[2] = {&nb_row_ghost_dofs, &nb_col_ghost_dofs};
2438  int nb_local_dofs[2] = {p_miit->nbLocDofsRow, p_miit->nbLocDofsCol};
2439 
2440  NumeredDofEntity_multiIndex_uid_view_ordered *ghost_idx_view[2] = {
2441  &ghost_idx_row_view, &ghost_idx_col_view};
2442  NumeredDofEntityByUId *dof_by_uid_no_const[2] = {
2443  &p_miit->numeredRowDofsPtr->get<Unique_mi_tag>(),
2444  &p_miit->numeredColDofsPtr->get<Unique_mi_tag>()};
2445 
2446  int loop_size = 2;
2447  if (p_miit->numeredColDofsPtr == p_miit->numeredRowDofsPtr) {
2448  loop_size = 1;
2449  }
2450 
2451  // set local ghost dofs indices
2452  for (int ss = 0; ss != loop_size; ++ss) {
2453  for (auto &gid : *ghost_idx_view[ss]) {
2454  NumeredDofEntityByUId::iterator dof =
2455  dof_by_uid_no_const[ss]->find(gid->getLocalUniqueId());
2456  if (PetscUnlikely((*dof)->petscLocalDofIdx != (DofIdx)-1))
2457  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2458  "inconsistent data, ghost dof already set");
2459  bool success = dof_by_uid_no_const[ss]->modify(
2460  dof, NumeredDofEntity_local_idx_change(nb_local_dofs[ss]++));
2461  if (PetscUnlikely(!success))
2462  SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
2463  "modification unsuccessful");
2464  (*nb_ghost_dofs[ss])++;
2465  }
2466  }
2467  if (loop_size == 1) {
2468  (*nb_ghost_dofs[1]) = (*nb_ghost_dofs[0]);
2469  }
2470  }
2471 
2472  if (verb > QUIET) {
2473  MOFEM_LOG("SYNC", Sev::inform)
2474  << " FEs ghost dofs on problem " << p_miit->getName()
2475  << " Nb. ghost dof " << p_miit->getNbGhostDofsRow() << " by "
2476  << p_miit->getNbGhostDofsCol() << " Nb. local dof "
2477  << p_miit->getNbLocalDofsCol() << " by " << p_miit->getNbLocalDofsCol();
2478 
2479  MOFEM_LOG_SYNCHRONISE(m_field.get_comm())
2480  }
2481 
2484 }
2485 
2488  int verb) {
2489  MoFEM::Interface &m_field = cOre;
2490  auto problems_ptr = m_field.get_problems();
2492 
2494  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2495  "partition of problem not build");
2497  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2498  "partitions finite elements not build");
2499 
2500  // get problem pointer
2501  typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
2502  // find p_miit
2503  ProblemsByName &problems_set =
2504  const_cast<ProblemsByName &>(problems_ptr->get<Problem_mi_tag>());
2505  ProblemsByName::iterator p_miit = problems_set.find(name);
2506 
2507  // get reference to number of ghost dofs
2508  // get number of local dofs
2509  DofIdx *nb_ghost_dofs[2] = {&(p_miit->nbGhostDofsRow),
2510  &(p_miit->nbGhostDofsCol)};
2511  DofIdx nb_local_dofs[2] = {p_miit->nbLocDofsRow, p_miit->nbLocDofsCol};
2512  for (int ss = 0; ss != 2; ++ss) {
2513  (*nb_ghost_dofs[ss]) = 0;
2514  }
2515 
2516  // do work if more than one processor
2517  if (m_field.get_comm_size() > 1) {
2518  // determine if rows on columns are different from dofs on rows
2519  int loop_size = 2;
2520  if (p_miit->numeredColDofsPtr == p_miit->numeredRowDofsPtr) {
2521  loop_size = 1;
2522  }
2523 
2524  typedef decltype(p_miit->numeredRowDofsPtr) NumbDofTypeSharedPtr;
2525  NumbDofTypeSharedPtr numered_dofs[] = {p_miit->numeredRowDofsPtr,
2526  p_miit->numeredColDofsPtr};
2527 
2528  // iterate over dofs on rows and dofs on columns
2529  for (int ss = 0; ss != loop_size; ++ss) {
2530 
2531  // create dofs view by uid
2532  auto r = numered_dofs[ss]->get<PetscLocalIdx_mi_tag>().equal_range(-1);
2533 
2534  std::vector<NumeredDofEntity_multiIndex::iterator> ghost_idx_view;
2535  ghost_idx_view.reserve(std::distance(r.first, r.second));
2536  for (; r.first != r.second; ++r.first)
2537  ghost_idx_view.emplace_back(numered_dofs[ss]->project<0>(r.first));
2538 
2539  auto cmp = [](auto a, auto b) {
2540  return (*a)->getLocalUniqueId() < (*b)->getLocalUniqueId();
2541  };
2542  sort(ghost_idx_view.begin(), ghost_idx_view.end(), cmp);
2543 
2544  // iterate over dofs which have negative local index
2545  for (auto gid_it : ghost_idx_view) {
2546  bool success = numered_dofs[ss]->modify(
2547  gid_it, NumeredDofEntity_local_idx_change((nb_local_dofs[ss])++));
2548  if (!success)
2549  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
2550  "modification unsuccessful");
2551  ++(*nb_ghost_dofs[ss]);
2552  }
2553  }
2554  if (loop_size == 1) {
2555  (*nb_ghost_dofs[1]) = (*nb_ghost_dofs[0]);
2556  }
2557  }
2558 
2559  if (verb > QUIET) {
2560  MOFEM_LOG("SYNC", Sev::inform)
2561  << " FEs ghost dofs on problem " << p_miit->getName()
2562  << " Nb. ghost dof " << p_miit->getNbGhostDofsRow() << " by "
2563  << p_miit->getNbGhostDofsCol() << " Nb. local dof "
2564  << p_miit->getNbLocalDofsCol() << " by " << p_miit->getNbLocalDofsCol();
2565 
2566  MOFEM_LOG_SYNCHRONISE(m_field.get_comm())
2567  }
2568 
2571 }
2572 
2574  const std::string &fe_name,
2575  EntityHandle *meshset) const {
2576  MoFEM::Interface &m_field = cOre;
2577  const Problem *problem_ptr;
2578  const FiniteElement_multiIndex *fes_ptr;
2580 
2581  CHKERR m_field.get_moab().create_meshset(MESHSET_SET, *meshset);
2582  CHKERR m_field.get_problem(prb_name, &problem_ptr);
2583  CHKERR m_field.get_finite_elements(&fes_ptr);
2584 
2585  auto fe_miit = fes_ptr->get<FiniteElement_name_mi_tag>().find(fe_name);
2586  if (fe_miit != fes_ptr->get<FiniteElement_name_mi_tag>().end()) {
2587  auto fit =
2588  problem_ptr->numeredFiniteElementsPtr->get<Unique_mi_tag>().lower_bound(
2590  0, (*fe_miit)->getFEUId()));
2591  auto hi_fe_it =
2592  problem_ptr->numeredFiniteElementsPtr->get<Unique_mi_tag>().upper_bound(
2594  get_id_for_max_type<MBENTITYSET>(), (*fe_miit)->getFEUId()));
2595  std::vector<EntityHandle> fe_vec;
2596  fe_vec.reserve(std::distance(fit, hi_fe_it));
2597  for (; fit != hi_fe_it; fit++)
2598  fe_vec.push_back(fit->get()->getEnt());
2599  CHKERR m_field.get_moab().add_entities(*meshset, &*fe_vec.begin(),
2600  fe_vec.size());
2601  }
2602 
2604 }
2605 
2608  const std::string &fe_name,
2609  PetscLayout *layout) const {
2610  MoFEM::Interface &m_field = cOre;
2611  const Problem *problem_ptr;
2613  CHKERR m_field.get_problem(name, &problem_ptr);
2614  CHKERR problem_ptr->getNumberOfElementsByNameAndPart(PETSC_COMM_WORLD,
2615  fe_name, layout);
2617 }
2618 
2620 
2621  std::vector<boost::weak_ptr<NumeredDofEntity>> &vec_dof_view,
2622 
2623  const std::string problem_name, RowColData rc, const std::string field_name,
2624  const Range ents, int bridge_dim, const int lo_coeff, const int hi_coeff,
2625  const int lo_order, const int hi_order, int verb, const bool debug
2626 
2627 ) const {
2628  MoFEM::Interface &m_field = cOre;
2630 
2631  switch (rc) {
2632  case ROW:
2633  case COL:
2634  break;
2635  default:
2636  SETERRQ(m_field.get_comm(), MOFEM_INVALID_DATA, "invalid RowColData");
2637  break;
2638  }
2639 
2640  const Problem *prb_ptr;
2641  CHKERR m_field.get_problem(problem_name, &prb_ptr);
2642 
2643  decltype(prb_ptr->numeredRowDofsPtr) numered_dofs[2] = {
2644  prb_ptr->numeredRowDofsPtr, nullptr};
2645  if (prb_ptr->numeredRowDofsPtr != prb_ptr->numeredColDofsPtr)
2646  numered_dofs[1] = prb_ptr->numeredColDofsPtr;
2647 
2648  Range bridge_ents;
2649  CHKERR m_field.get_moab().get_adjacencies(
2650  ents, bridge_dim, false, bridge_ents, moab::Interface::UNION);
2651 
2652  auto &moab = m_field.get_moab();
2653  const auto bit_number = m_field.get_field_bit_number(field_name);
2654  const auto nb_coeffs =
2656  const auto &side_dof_map = m_field.get_field_structure(field_name)
2657  ->getDofSideMap();
2658 
2659  using NumeredDofEntity_it_view_multiIndex = multi_index_container<
2660 
2661  NumeredDofEntity_multiIndex::iterator, indexed_by<sequenced<>>
2662 
2663  >;
2664  NumeredDofEntity_it_view_multiIndex dofs_it_view;
2665 
2666  for (auto pit = bridge_ents.const_pair_begin();
2667  pit != bridge_ents.const_pair_end(); ++pit) {
2668  auto lo = numered_dofs[rc]->get<Unique_mi_tag>().lower_bound(
2669  DofEntity::getLoFieldEntityUId(bit_number, pit->first));
2670  auto hi = numered_dofs[rc]->get<Unique_mi_tag>().upper_bound(
2671  DofEntity::getHiFieldEntityUId(bit_number, pit->second));
2672 
2673  auto bride_type = moab.type_from_handle(pit->first);
2674 
2675  for (; lo != hi; ++lo) {
2676  if ((*lo)->getDofCoeffIdx() >= lo_coeff &&
2677  (*lo)->getDofCoeffIdx() <= hi_coeff &&
2678  (*lo)->getDofOrder() >= lo_order &&
2679  (*lo)->getDofOrder() <= hi_order) {
2680  auto ent_dof_index = (*lo)->getEntDofIdx();
2681  auto side_it = side_dof_map.at(bride_type)
2682  .get<EntDofIdx_mi_tag>()
2683  .find(std::floor(static_cast<double>(ent_dof_index) /
2684  nb_coeffs));
2685  if (side_it !=
2686  side_dof_map.at(bride_type).get<EntDofIdx_mi_tag>().end()) {
2687  auto bridge_ent = (*lo)->getEnt();
2688  auto type = side_it->type;
2689  auto side = side_it->side;
2690  auto dim = CN::Dimension(type);
2691  EntityHandle side_ent = 0;
2692  CHKERR moab.side_element(bridge_ent, dim, side, side_ent);
2693  if (ents.find(side_ent) != ents.end()) {
2694  dofs_it_view.emplace_back(numered_dofs[rc]->project<0>(lo));
2695  }
2696  } else {
2697 #ifndef NDEBUG
2698  MOFEM_LOG("SELF", Sev::error)
2699  << *m_field.get_field_structure(field_name);
2700  MOFEM_LOG("SELF", Sev::error)
2701  << "side not found for entity " << CN::EntityTypeName(bride_type);
2702  MOFEM_LOG("SELF", Sev::error)
2703  << "ent_dof_index / nb_coeffs "
2704  << std::floor(static_cast<double>(ent_dof_index) / nb_coeffs);
2705  MOFEM_LOG("SELF", Sev::error)
2706  << "side_dof_map.size() " << side_dof_map.size();
2707 #endif // NDEBUG
2708  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2709  "side not found - you will get more information in debug");
2710  }
2711  }
2712  }
2713  }
2714 
2715  if (verb > QUIET) {
2716  for (auto &dof : dofs_it_view)
2717  MOFEM_LOG("SYNC", Sev::noisy) << **dof;
2718  MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
2719  }
2720 
2721  vec_dof_view.reserve(vec_dof_view.size() + dofs_it_view.size());
2722  for (auto dit : dofs_it_view)
2723  vec_dof_view.push_back(*dit);
2724 
2726 }
2727 
2729  const std::string problem_name, RowColData rc,
2730  std::vector<boost::weak_ptr<NumeredDofEntity>> &vec_dof_view, int verb,
2731  const bool debug) {
2732 
2733  MoFEM::Interface &m_field = cOre;
2735 
2736  switch (rc) {
2737  case ROW:
2738  case COL:
2739  break;
2740  default:
2741  SETERRQ(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE, "Should be row or column");
2742  }
2743 
2744  const Problem *prb_ptr;
2745  CHKERR m_field.get_problem(problem_name, &prb_ptr);
2746 
2747  decltype(prb_ptr->numeredRowDofsPtr) numered_dofs[2] = {
2748  prb_ptr->numeredRowDofsPtr, nullptr};
2749  if (prb_ptr->numeredRowDofsPtr != prb_ptr->numeredColDofsPtr)
2750  numered_dofs[1] = prb_ptr->numeredColDofsPtr;
2751 
2752  int *nbdof_ptr[] = {&prb_ptr->nbDofsRow, &prb_ptr->nbDofsCol};
2753  int *local_nbdof_ptr[] = {&prb_ptr->nbLocDofsRow, &prb_ptr->nbLocDofsCol};
2754  int *ghost_nbdof_ptr[] = {&prb_ptr->nbGhostDofsRow, &prb_ptr->nbGhostDofsCol};
2755 
2756  const int nb_init_row_dofs = prb_ptr->getNbDofsRow();
2757  const int nb_init_col_dofs = prb_ptr->getNbDofsCol();
2758  const int nb_init_loc_row_dofs = prb_ptr->getNbLocalDofsRow();
2759  const int nb_init_ghost_row_dofs = prb_ptr->getNbGhostDofsRow();
2760  const int nb_init_ghost_col_dofs = prb_ptr->getNbGhostDofsCol();
2761 
2762  if (numered_dofs[rc]) {
2763 
2764  if (verb >= NOISY)
2765  MOFEM_LOG_C("SYNC", Sev::noisy,
2766  "Number of DOFs in multi-index %d and to delete %d\n",
2767  numered_dofs[rc]->size(), vec_dof_view.size());
2768 
2769  // erase dofs from problem
2770  for (auto weak_dit : vec_dof_view)
2771  if (auto dit = weak_dit.lock()) {
2772  numered_dofs[rc]->erase(dit->getLocalUniqueId());
2773  }
2774 
2775  if (verb >= NOISY)
2776  MOFEM_LOG_C("SYNC", Sev::noisy,
2777  "Number of DOFs in multi-index after delete %d\n",
2778  numered_dofs[rc]->size());
2779 
2780  // get current number of ghost dofs
2781  int nb_local_dofs = 0;
2782  int nb_ghost_dofs = 0;
2783  for (auto dit = numered_dofs[rc]->get<PetscLocalIdx_mi_tag>().begin();
2784  dit != numered_dofs[rc]->get<PetscLocalIdx_mi_tag>().end(); ++dit) {
2785  if ((*dit)->getPetscLocalDofIdx() >= 0 &&
2786  (*dit)->getPetscLocalDofIdx() < *(local_nbdof_ptr[rc]))
2787  ++nb_local_dofs;
2788  else if ((*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[rc]))
2789  ++nb_ghost_dofs;
2790  else
2791  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2792  "Impossible case. You could run problem on no distributed "
2793  "mesh. That is not implemented. Dof local index is %d",
2794  (*dit)->getPetscLocalDofIdx());
2795  }
2796 
2797  // get indices
2798  auto get_indices_by_tag = [&](auto tag, auto &indices, bool only_local) {
2799  const int nb_dofs = numered_dofs[rc]->size();
2800  indices.clear();
2801  indices.reserve(nb_dofs);
2802  for (auto dit = numered_dofs[rc]->get<decltype(tag)>().begin();
2803  dit != numered_dofs[rc]->get<decltype(tag)>().end(); ++dit) {
2804  bool add = true;
2805  if (only_local) {
2806  if ((*dit)->getPetscLocalDofIdx() < 0 ||
2807  (*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[rc])) {
2808  add = false;
2809  }
2810  }
2811  if (add)
2812  indices.push_back(decltype(tag)::get_index(dit));
2813  }
2814  };
2815 
2816  auto get_indices_by_uid = [&](auto tag, auto &indices) {
2817  const int nb_dofs = numered_dofs[rc]->size();
2818  indices.clear();
2819  indices.reserve(nb_dofs);
2820  for (auto dit = numered_dofs[rc]->begin(); dit != numered_dofs[rc]->end();
2821  ++dit)
2822  indices.push_back(decltype(tag)::get_index(dit));
2823  };
2824 
2825  auto get_sub_ao = [&](auto sub_data) {
2826  if (rc == 0) {
2827  return sub_data->getSmartRowMap();
2828  } else {
2829  return sub_data->getSmartColMap();
2830  }
2831  };
2832 
2833  auto set_sub_is_and_ao = [&rc, &prb_ptr](auto sub_data, auto is, auto ao) {
2834  if (rc == ROW) {
2835  sub_data->rowIs = is;
2836  sub_data->rowMap = ao;
2837  sub_data->colIs = is; // if square problem col is equal to row
2838  sub_data->colMap = ao;
2839  } else {
2840  sub_data->colIs = is;
2841  sub_data->colMap = ao;
2842  }
2843  };
2844 
2845  auto apply_symmetry = [&rc, &prb_ptr](auto sub_data) {
2846  if (rc == ROW) {
2847  if (prb_ptr->numeredRowDofsPtr == prb_ptr->numeredColDofsPtr) {
2848  sub_data->colIs = sub_data->getSmartRowIs();
2849  sub_data->colMap = sub_data->getSmartRowMap();
2850  }
2851  }
2852  };
2853 
2854  auto concatenate_dofs = [&](auto tag, auto &indices,
2855  const auto local_only) {
2857  get_indices_by_tag(tag, indices, local_only);
2858 
2859  SmartPetscObj<AO> ao;
2860  // Create AO from app indices (i.e. old), to pestc indices (new after
2861  // remove)
2862  if (local_only)
2863  ao = createAOMapping(m_field.get_comm(), indices.size(),
2864  &*indices.begin(), PETSC_NULL);
2865  else
2866  ao = createAOMapping(PETSC_COMM_SELF, indices.size(), &*indices.begin(),
2867  PETSC_NULL);
2868 
2869  // Set mapping to sub dm data
2870  if (local_only) {
2871  if (auto sub_data = prb_ptr->getSubData()) {
2872  // create is and then map it to main problem of sub-problem
2873  auto sub_is = createISGeneral(m_field.get_comm(), indices.size(),
2874  &*indices.begin(), PETSC_COPY_VALUES);
2875  // get old app, i.e. oroginal befor sub indices, and ao, from app,
2876  // to petsc sub indices.
2877  auto sub_ao = get_sub_ao(sub_data);
2878  CHKERR AOPetscToApplicationIS(sub_ao, sub_is);
2879  sub_ao = createAOMappingIS(sub_is, PETSC_NULL);
2880  // set new sub ao
2881  set_sub_is_and_ao(sub_data, sub_is, sub_ao);
2882  apply_symmetry(sub_data);
2883  } else {
2884  // create sub data
2885  prb_ptr->getSubData() = boost::make_shared<Problem::SubProblemData>();
2886  auto sub_is = createISGeneral(m_field.get_comm(), indices.size(),
2887  &*indices.begin(), PETSC_COPY_VALUES);
2888  // set sub is ao
2889  set_sub_is_and_ao(prb_ptr->getSubData(), sub_is, ao);
2890  apply_symmetry(prb_ptr->getSubData());
2891  }
2892  }
2893 
2894  get_indices_by_uid(tag, indices);
2895  CHKERR AOApplicationToPetsc(ao, indices.size(), &*indices.begin());
2896 
2898  };
2899 
2900  // set indices index
2901  auto set_concatenated_indices = [&]() {
2902  std::vector<int> global_indices;
2903  std::vector<int> local_indices;
2905  CHKERR concatenate_dofs(PetscGlobalIdx_mi_tag(), global_indices, true);
2906  CHKERR concatenate_dofs(PetscLocalIdx_mi_tag(), local_indices, false);
2907  auto gi = global_indices.begin();
2908  auto li = local_indices.begin();
2909  for (auto dit = numered_dofs[rc]->begin(); dit != numered_dofs[rc]->end();
2910  ++dit) {
2912  (*dit)->getPart(), (*dit)->getDofIdx(), *gi, *li);
2913  bool success = numered_dofs[rc]->modify(dit, mod);
2914  if (!success)
2915  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
2916  "can not set negative indices");
2917  ++gi;
2918  ++li;
2919  }
2921  };
2922  CHKERR set_concatenated_indices();
2923 
2924  MPI_Allreduce(&nb_local_dofs, nbdof_ptr[rc], 1, MPI_INT, MPI_SUM,
2925  m_field.get_comm());
2926  *(local_nbdof_ptr[rc]) = nb_local_dofs;
2927  *(ghost_nbdof_ptr[rc]) = nb_ghost_dofs;
2928 
2929  if (debug)
2930  for (auto dof : (*numered_dofs[rc])) {
2931  if (dof->getPetscGlobalDofIdx() < 0) {
2932  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2933  "Negative global idx");
2934  }
2935  if (dof->getPetscLocalDofIdx() < 0) {
2936  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2937  "Negative local idx");
2938  }
2939  }
2940 
2941  } else {
2942 
2943  *(nbdof_ptr[1]) = *(nbdof_ptr[0]);
2944  *(local_nbdof_ptr[1]) = *(local_nbdof_ptr[0]);
2945  *(ghost_nbdof_ptr[1]) = *(ghost_nbdof_ptr[0]);
2946  }
2947 
2948  if (verb > QUIET) {
2949  MOFEM_LOG_C(
2950  "WORLD", Sev::inform,
2951  "Removed DOFs from problem %s dofs [%d / %d (before %d / %d) global]",
2952  prb_ptr->getName().c_str(), prb_ptr->getNbDofsRow(),
2953  prb_ptr->getNbDofsCol(), nb_init_row_dofs, nb_init_col_dofs);
2954  MOFEM_LOG_C("SYNC", Sev::verbose,
2955  "Removed DOFs from problem %s dofs [ %d / %d "
2956  "(before %d / %d) local, %d / %d (before %d / %d)]",
2957  prb_ptr->getName().c_str(), prb_ptr->getNbLocalDofsRow(),
2958  prb_ptr->getNbLocalDofsCol(), nb_init_loc_row_dofs,
2959  nb_init_loc_row_dofs, prb_ptr->getNbGhostDofsRow(),
2960  prb_ptr->getNbGhostDofsCol(), nb_init_ghost_row_dofs,
2961  nb_init_ghost_col_dofs);
2962  MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::verbose);
2963  }
2964 
2966 }
2967 
2969  const std::string problem_name, const std::string field_name,
2970  const Range ents, const int lo_coeff, const int hi_coeff,
2971  const int lo_order, const int hi_order, int verb, const bool debug) {
2972 
2973  MoFEM::Interface &m_field = cOre;
2975 
2976  const Problem *prb_ptr;
2977  CHKERR m_field.get_problem(problem_name, &prb_ptr);
2978 
2979  decltype(prb_ptr->numeredRowDofsPtr) numered_dofs[2] = {
2980  prb_ptr->numeredRowDofsPtr, nullptr};
2981  if (prb_ptr->numeredRowDofsPtr != prb_ptr->numeredColDofsPtr)
2982  numered_dofs[1] = prb_ptr->numeredColDofsPtr;
2983 
2984  int *nbdof_ptr[] = {&prb_ptr->nbDofsRow, &prb_ptr->nbDofsCol};
2985  int *local_nbdof_ptr[] = {&prb_ptr->nbLocDofsRow, &prb_ptr->nbLocDofsCol};
2986  int *ghost_nbdof_ptr[] = {&prb_ptr->nbGhostDofsRow, &prb_ptr->nbGhostDofsCol};
2987 
2988  const int nb_init_row_dofs = prb_ptr->getNbDofsRow();
2989  const int nb_init_col_dofs = prb_ptr->getNbDofsCol();
2990  const int nb_init_loc_row_dofs = prb_ptr->getNbLocalDofsRow();
2991  // const int nb_init_loc_col_dofs = prb_ptr->getNbLocalDofsCol();
2992  const int nb_init_ghost_row_dofs = prb_ptr->getNbGhostDofsRow();
2993  const int nb_init_ghost_col_dofs = prb_ptr->getNbGhostDofsCol();
2994 
2995  for (int s = 0; s != 2; ++s)
2996  if (numered_dofs[s]) {
2997 
2998  using NumeredDofEntity_it_view_multiIndex = multi_index_container<
2999 
3000  NumeredDofEntity_multiIndex::iterator, indexed_by<sequenced<>>
3001 
3002  >;
3003 
3004  const auto bit_number = m_field.get_field_bit_number(field_name);
3005  NumeredDofEntity_it_view_multiIndex dofs_it_view;
3006 
3007  // Set -1 to global and local dofs indices
3008  for (auto pit = ents.const_pair_begin(); pit != ents.const_pair_end();
3009  ++pit) {
3010  auto lo = numered_dofs[s]->get<Unique_mi_tag>().lower_bound(
3011  DofEntity::getLoFieldEntityUId(bit_number, pit->first));
3012  auto hi = numered_dofs[s]->get<Unique_mi_tag>().upper_bound(
3013  DofEntity::getHiFieldEntityUId(bit_number, pit->second));
3014 
3015  for (; lo != hi; ++lo)
3016  if ((*lo)->getDofCoeffIdx() >= lo_coeff &&
3017  (*lo)->getDofCoeffIdx() <= hi_coeff &&
3018  (*lo)->getDofOrder() >= lo_order &&
3019  (*lo)->getDofOrder() <= hi_order)
3020  dofs_it_view.emplace_back(numered_dofs[s]->project<0>(lo));
3021  }
3022 
3023  if (verb > QUIET) {
3024  for (auto &dof : dofs_it_view)
3025  MOFEM_LOG("SYNC", Sev::noisy) << **dof;
3026  MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
3027  }
3028 
3029  // create weak view
3030  std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_weak_view;
3031  dofs_weak_view.reserve(dofs_it_view.size());
3032  for (auto dit : dofs_it_view)
3033  dofs_weak_view.push_back(*dit);
3034 
3035  if (verb >= NOISY)
3036  MOFEM_LOG_C("SYNC", Sev::noisy,
3037  "Number of DOFs in multi-index %d and to delete %d\n",
3038  numered_dofs[s]->size(), dofs_it_view.size());
3039 
3040  // erase dofs from problem
3041  for (auto weak_dit : dofs_weak_view)
3042  if (auto dit = weak_dit.lock()) {
3043  numered_dofs[s]->erase(dit->getLocalUniqueId());
3044  }
3045 
3046  if (verb >= NOISY)
3047  MOFEM_LOG_C("SYNC", Sev::noisy,
3048  "Number of DOFs in multi-index after delete %d\n",
3049  numered_dofs[s]->size());
3050 
3051  // get current number of ghost dofs
3052  int nb_local_dofs = 0;
3053  int nb_ghost_dofs = 0;
3054  for (auto dit = numered_dofs[s]->get<PetscLocalIdx_mi_tag>().begin();
3055  dit != numered_dofs[s]->get<PetscLocalIdx_mi_tag>().end(); ++dit) {
3056  if ((*dit)->getPetscLocalDofIdx() >= 0 &&
3057  (*dit)->getPetscLocalDofIdx() < *(local_nbdof_ptr[s]))
3058  ++nb_local_dofs;
3059  else if ((*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[s]))
3060  ++nb_ghost_dofs;
3061  else
3062  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
3063  "Impossible case. You could run problem on no distributed "
3064  "mesh. That is not implemented. Dof local index is %d",
3065  (*dit)->getPetscLocalDofIdx());
3066  }
3067 
3068  // get indices
3069  auto get_indices_by_tag = [&](auto tag, auto &indices, bool only_local) {
3070  const int nb_dofs = numered_dofs[s]->size();
3071  indices.clear();
3072  indices.reserve(nb_dofs);
3073  for (auto dit = numered_dofs[s]->get<decltype(tag)>().begin();
3074  dit != numered_dofs[s]->get<decltype(tag)>().end(); ++dit) {
3075  bool add = true;
3076  if (only_local) {
3077  if ((*dit)->getPetscLocalDofIdx() < 0 ||
3078  (*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[s])) {
3079  add = false;
3080  }
3081  }
3082  if (add)
3083  indices.push_back(decltype(tag)::get_index(dit));
3084  }
3085  };
3086 
3087  auto get_indices_by_uid = [&](auto tag, auto &indices) {
3088  const int nb_dofs = numered_dofs[s]->size();
3089  indices.clear();
3090  indices.reserve(nb_dofs);
3091  for (auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3092  ++dit)
3093  indices.push_back(decltype(tag)::get_index(dit));
3094  };
3095 
3096  auto get_sub_ao = [&](auto sub_data) {
3097  if (s == 0) {
3098  return sub_data->getSmartRowMap();
3099  } else {
3100  return sub_data->getSmartColMap();
3101  }
3102  };
3103 
3104  auto set_sub_is_and_ao = [&s, &prb_ptr](auto sub_data, auto is, auto ao) {
3105  if (s == 0) {
3106  sub_data->rowIs = is;
3107  sub_data->rowMap = ao;
3108  sub_data->colIs = is; // if square problem col is equal to row
3109  sub_data->colMap = ao;
3110  } else {
3111  sub_data->colIs = is;
3112  sub_data->colMap = ao;
3113  }
3114  };
3115 
3116  auto apply_symmetry = [&s, &prb_ptr](auto sub_data) {
3117  if (s == 0) {
3118  if (prb_ptr->numeredRowDofsPtr == prb_ptr->numeredColDofsPtr) {
3119  sub_data->colIs = sub_data->getSmartRowIs();
3120  sub_data->colMap = sub_data->getSmartRowMap();
3121  }
3122  }
3123  };
3124 
3125  auto concatenate_dofs = [&](auto tag, auto &indices,
3126  const auto local_only) {
3128  get_indices_by_tag(tag, indices, local_only);
3129 
3130  SmartPetscObj<AO> ao;
3131  // Create AO from app indices (i.e. old), to pestc indices (new after
3132  // remove)
3133  if (local_only)
3134  ao = createAOMapping(m_field.get_comm(), indices.size(),
3135  &*indices.begin(), PETSC_NULL);
3136  else
3137  ao = createAOMapping(PETSC_COMM_SELF, indices.size(),
3138  &*indices.begin(), PETSC_NULL);
3139 
3140  // Set mapping to sub dm data
3141  if (local_only) {
3142  if (auto sub_data = prb_ptr->getSubData()) {
3143  // create is and then map it to main problem of sub-problem
3144  auto sub_is = createISGeneral(m_field.get_comm(), indices.size(),
3145  &*indices.begin(), PETSC_COPY_VALUES);
3146  // get old app, i.e. oroginal befor sub indices, and ao, from app,
3147  // to petsc sub indices.
3148  auto sub_ao = get_sub_ao(sub_data);
3149  CHKERR AOPetscToApplicationIS(sub_ao, sub_is);
3150  sub_ao = createAOMappingIS(sub_is, PETSC_NULL);
3151  // set new sub ao
3152  set_sub_is_and_ao(sub_data, sub_is, sub_ao);
3153  apply_symmetry(sub_data);
3154  } else {
3155  // create sub data
3156  prb_ptr->getSubData() =
3157  boost::make_shared<Problem::SubProblemData>();
3158  auto sub_is = createISGeneral(m_field.get_comm(), indices.size(),
3159  &*indices.begin(), PETSC_COPY_VALUES);
3160  // set sub is ao
3161  set_sub_is_and_ao(prb_ptr->getSubData(), sub_is, ao);
3162  apply_symmetry(prb_ptr->getSubData());
3163  }
3164  }
3165 
3166  get_indices_by_uid(tag, indices);
3167  CHKERR AOApplicationToPetsc(ao, indices.size(), &*indices.begin());
3168 
3170  };
3171 
3172  // set indices index
3173  auto set_concatenated_indices = [&]() {
3174  std::vector<int> global_indices;
3175  std::vector<int> local_indices;
3177  CHKERR concatenate_dofs(PetscGlobalIdx_mi_tag(), global_indices, true);
3178  CHKERR concatenate_dofs(PetscLocalIdx_mi_tag(), local_indices, false);
3179  auto gi = global_indices.begin();
3180  auto li = local_indices.begin();
3181  for (auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3182  ++dit) {
3184  (*dit)->getPart(), (*dit)->getDofIdx(), *gi, *li);
3185  bool success = numered_dofs[s]->modify(dit, mod);
3186  if (!success)
3187  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
3188  "can not set negative indices");
3189  ++gi;
3190  ++li;
3191  }
3193  };
3194  CHKERR set_concatenated_indices();
3195 
3196  MPI_Allreduce(&nb_local_dofs, nbdof_ptr[s], 1, MPI_INT, MPI_SUM,
3197  m_field.get_comm());
3198  *(local_nbdof_ptr[s]) = nb_local_dofs;
3199  *(ghost_nbdof_ptr[s]) = nb_ghost_dofs;
3200 
3201  if (debug)
3202  for (auto dof : (*numered_dofs[s])) {
3203  if (dof->getPetscGlobalDofIdx() < 0) {
3204  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
3205  "Negative global idx");
3206  }
3207  if (dof->getPetscLocalDofIdx() < 0) {
3208  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
3209  "Negative local idx");
3210  }
3211  }
3212 
3213  } else {
3214 
3215  *(nbdof_ptr[1]) = *(nbdof_ptr[0]);
3216  *(local_nbdof_ptr[1]) = *(local_nbdof_ptr[0]);
3217  *(ghost_nbdof_ptr[1]) = *(ghost_nbdof_ptr[0]);
3218  }
3219 
3220  if (verb > QUIET) {
3221  MOFEM_LOG_C(
3222  "WORLD", Sev::inform,
3223  "Removed DOFs from problem %s dofs [%d / %d (before %d / %d) global]",
3224  prb_ptr->getName().c_str(), prb_ptr->getNbDofsRow(),
3225  prb_ptr->getNbDofsCol(), nb_init_row_dofs, nb_init_col_dofs);
3226  MOFEM_LOG_C("SYNC", Sev::verbose,
3227  "Removed DOFs from problem %s dofs [ %d / %d "
3228  "(before %d / %d) local, %d / %d (before %d / %d)]",
3229  prb_ptr->getName().c_str(), prb_ptr->getNbLocalDofsRow(),
3230  prb_ptr->getNbLocalDofsCol(), nb_init_loc_row_dofs,
3231  nb_init_loc_row_dofs, prb_ptr->getNbGhostDofsRow(),
3232  prb_ptr->getNbGhostDofsCol(), nb_init_ghost_row_dofs,
3233  nb_init_ghost_col_dofs);
3234  MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::verbose);
3235  }
3236 
3238 }
3239 
3241  const std::string problem_name, const std::string field_name,
3242  const Range ents, const int lo_coeff, const int hi_coeff,
3243  const int lo_order, const int hi_order, int verb, const bool debug) {
3244 
3245  MoFEM::Interface &m_field = cOre;
3247 
3248  const Problem *prb_ptr;
3249  CHKERR m_field.get_problem(problem_name, &prb_ptr);
3250 
3251  decltype(prb_ptr->numeredRowDofsPtr) numered_dofs[2] = {
3252  prb_ptr->numeredRowDofsPtr, nullptr};
3253  if (prb_ptr->numeredRowDofsPtr != prb_ptr->numeredColDofsPtr)
3254  numered_dofs[1] = prb_ptr->numeredColDofsPtr;
3255 
3256  int *nbdof_ptr[] = {&prb_ptr->nbDofsRow, &prb_ptr->nbDofsCol};
3257  int *local_nbdof_ptr[] = {&prb_ptr->nbLocDofsRow, &prb_ptr->nbLocDofsCol};
3258  int *ghost_nbdof_ptr[] = {&prb_ptr->nbGhostDofsRow, &prb_ptr->nbGhostDofsCol};
3259 
3260  const int nb_init_row_dofs = prb_ptr->getNbDofsRow();
3261  const int nb_init_col_dofs = prb_ptr->getNbDofsCol();
3262  const int nb_init_loc_row_dofs = prb_ptr->getNbLocalDofsRow();
3263  // const int nb_init_loc_col_dofs = prb_ptr->getNbLocalDofsCol();
3264  const int nb_init_ghost_row_dofs = prb_ptr->getNbGhostDofsRow();
3265  const int nb_init_ghost_col_dofs = prb_ptr->getNbGhostDofsCol();
3266 
3267  const std::array<int, 2> nb_init_dofs = {nb_init_row_dofs, nb_init_col_dofs};
3268 
3269  for (int s = 0; s != 2; ++s)
3270  if (numered_dofs[s]) {
3271 
3272  typedef multi_index_container<
3273 
3274  NumeredDofEntity_multiIndex::iterator, indexed_by<sequenced<>>
3275 
3276  >
3277  NumeredDofEntity_it_view_multiIndex;
3278 
3279  const auto bit_number = m_field.get_field_bit_number(field_name);
3280  NumeredDofEntity_it_view_multiIndex dofs_it_view;
3281 
3282  // Set -1 to global and local dofs indices
3283  for (auto pit = ents.const_pair_begin(); pit != ents.const_pair_end();
3284  ++pit) {
3285  auto lo = numered_dofs[s]->get<Unique_mi_tag>().lower_bound(
3286  DofEntity::getLoFieldEntityUId(bit_number, pit->first));
3287  auto hi = numered_dofs[s]->get<Unique_mi_tag>().upper_bound(
3288  DofEntity::getHiFieldEntityUId(bit_number, pit->second));
3289 
3290  for (; lo != hi; ++lo)
3291  if ((*lo)->getDofCoeffIdx() >= lo_coeff &&
3292  (*lo)->getDofCoeffIdx() <= hi_coeff &&
3293  (*lo)->getDofOrder() >= lo_order &&
3294  (*lo)->getDofOrder() <= hi_order)
3295  dofs_it_view.emplace_back(numered_dofs[s]->project<0>(lo));
3296  }
3297 
3298  if (verb > QUIET) {
3299  for (auto &dof : dofs_it_view)
3300  MOFEM_LOG("SYNC", Sev::noisy) << **dof;
3301  }
3302 
3303  // set negative index
3304  auto mod = NumeredDofEntity_part_and_all_indices_change(-1, -1, -1, -1);
3305  for (auto dit : dofs_it_view) {
3306  bool success = numered_dofs[s]->modify(dit, mod);
3307  if (!success)
3308  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
3309  "can not set negative indices");
3310  }
3311 
3312  // create weak view
3313  std::vector<boost::weak_ptr<NumeredDofEntity>> dosf_weak_view;
3314  dosf_weak_view.reserve(dofs_it_view.size());
3315  for (auto dit : dofs_it_view)
3316  dosf_weak_view.push_back(*dit);
3317 
3318  if (verb >= NOISY)
3319  MOFEM_LOG_C("SYNC", Sev::noisy,
3320  "Number of DOFs in multi-index %d and to delete %d\n",
3321  numered_dofs[s]->size(), dofs_it_view.size());
3322 
3323  // erase dofs from problem
3324  for (auto weak_dit : dosf_weak_view)
3325  if (auto dit = weak_dit.lock()) {
3326  numered_dofs[s]->erase(dit->getLocalUniqueId());
3327  }
3328 
3329  if (verb >= NOISY)
3330  MOFEM_LOG_C("SYNC", Sev::noisy,
3331  "Number of DOFs in multi-index after delete %d\n",
3332  numered_dofs[s]->size());
3333 
3334  // get current number of ghost dofs
3335  int nb_global_dof = 0;
3336  int nb_local_dofs = 0;
3337  int nb_ghost_dofs = 0;
3338 
3339  for (auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3340  ++dit) {
3341 
3342  if ((*dit)->getDofIdx() >= 0) {
3343 
3344  if ((*dit)->getPetscLocalDofIdx() >= 0 &&
3345  (*dit)->getPetscLocalDofIdx() < *(local_nbdof_ptr[s]))
3346  ++nb_local_dofs;
3347  else if ((*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[s]))
3348  ++nb_ghost_dofs;
3349 
3350  ++nb_global_dof;
3351  }
3352  }
3353 
3354  if (debug) {
3355  MPI_Allreduce(&nb_local_dofs, nbdof_ptr[s], 1, MPI_INT, MPI_SUM,
3356  m_field.get_comm());
3357  if (*(nbdof_ptr[s]) != nb_global_dof)
3358  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
3359  "Number of local DOFs do not add up %d != %d",
3360  *(nbdof_ptr[s]), nb_global_dof);
3361  }
3362 
3363  *(nbdof_ptr[s]) = nb_global_dof;
3364  *(local_nbdof_ptr[s]) = nb_local_dofs;
3365  *(ghost_nbdof_ptr[s]) = nb_ghost_dofs;
3366 
3367  // get indices
3368  auto get_indices_by_tag = [&](auto tag) {
3369  std::vector<int> indices;
3370  indices.resize(nb_init_dofs[s], -1);
3371  for (auto dit = numered_dofs[s]->get<Idx_mi_tag>().lower_bound(0);
3372  dit != numered_dofs[s]->get<Idx_mi_tag>().end(); ++dit) {
3373  indices[(*dit)->getDofIdx()] = decltype(tag)::get_index(dit);
3374  }
3375  return indices;
3376  };
3377 
3378  auto renumber = [&](auto tag, auto &indices) {
3380  int idx = 0;
3381  for (auto dit = numered_dofs[s]->get<decltype(tag)>().lower_bound(0);
3382  dit != numered_dofs[s]->get<decltype(tag)>().end(); ++dit) {
3383  indices[(*dit)->getDofIdx()] = idx++;
3384  }
3386  };
3387 
3388  auto get_sub_ao = [&](auto sub_data) {
3389  if (s == 0) {
3390  return sub_data->getSmartRowMap();
3391  } else {
3392  return sub_data->getSmartColMap();
3393  }
3394  };
3395 
3396  auto set_sub_is_and_ao = [&s, &prb_ptr](auto sub_data, auto is, auto ao) {
3397  if (s == 0) {
3398  sub_data->rowIs = is;
3399  sub_data->rowMap = ao;
3400  sub_data->colIs = is;
3401  sub_data->colMap = ao;
3402  } else {
3403  sub_data->colIs = is;
3404  sub_data->colMap = ao;
3405  }
3406  };
3407 
3408  auto apply_symmetry = [&s, &prb_ptr](auto sub_data) {
3409  if (s == 0) {
3410  if (prb_ptr->numeredRowDofsPtr == prb_ptr->numeredColDofsPtr) {
3411  sub_data->colIs = sub_data->getSmartRowIs();
3412  sub_data->colMap = sub_data->getSmartRowMap();
3413  }
3414  }
3415  };
3416 
3417  auto set_sub_data = [&](auto &indices) {
3419  if (auto sub_data = prb_ptr->getSubData()) {
3420  // create is and then map it to main problem of sub-problem
3421  auto sub_is = createISGeneral(m_field.get_comm(), indices.size(),
3422  &*indices.begin(), PETSC_COPY_VALUES);
3423  // get old app, i.e. oroginal befor sub indices, and ao, from
3424  // app, to petsc sub indices.
3425  auto sub_ao = get_sub_ao(sub_data);
3426  CHKERR AOPetscToApplicationIS(sub_ao, sub_is);
3427  sub_ao = createAOMappingIS(sub_is, PETSC_NULL);
3428  // set new sub ao
3429  set_sub_is_and_ao(sub_data, sub_is, sub_ao);
3430  apply_symmetry(sub_data);
3431  } else {
3432  prb_ptr->getSubData() = boost::make_shared<Problem::SubProblemData>();
3433  auto sub_is = createISGeneral(m_field.get_comm(), indices.size(),
3434  &*indices.begin(), PETSC_COPY_VALUES);
3435  auto sub_ao = createAOMappingIS(sub_is, PETSC_NULL);
3436  // set sub is ao
3437  set_sub_is_and_ao(prb_ptr->getSubData(), sub_is, sub_ao);
3438  apply_symmetry(prb_ptr->getSubData());
3439  }
3441  };
3442 
3443  auto global_indices = get_indices_by_tag(PetscGlobalIdx_mi_tag());
3444  auto local_indices = get_indices_by_tag(PetscLocalIdx_mi_tag());
3445  CHKERR set_sub_data(global_indices);
3446  CHKERR renumber(PetscGlobalIdx_mi_tag(), global_indices);
3447  CHKERR renumber(PetscLocalIdx_mi_tag(), local_indices);
3448 
3449  int i = 0;
3450  for (auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3451  ++dit) {
3452  auto idx = (*dit)->getDofIdx();
3453  if (idx >= 0) {
3455  (*dit)->getPart(), i++, global_indices[idx], local_indices[idx]);
3456  bool success = numered_dofs[s]->modify(dit, mod);
3457  if (!success)
3458  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
3459  "can not set negative indices");
3460  } else {
3462  (*dit)->getPart(), -1, -1, -1);
3463  bool success = numered_dofs[s]->modify(dit, mod);
3464  if (!success)
3465  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
3466  "can not set negative indices");
3467  }
3468  };
3469 
3470  if (debug) {
3471  for (auto dof : (*numered_dofs[s])) {
3472  if (dof->getDofIdx() >= 0 && dof->getPetscGlobalDofIdx() < 0) {
3473  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
3474  "Negative global idx");
3475  }
3476  }
3477  }
3478 
3479  } else {
3480 
3481  *(nbdof_ptr[1]) = *(nbdof_ptr[0]);
3482  *(local_nbdof_ptr[1]) = *(local_nbdof_ptr[0]);
3483  *(ghost_nbdof_ptr[1]) = *(ghost_nbdof_ptr[0]);
3484  }
3485 
3486  if (verb >= NOISY)
3487  MOFEM_LOG_SYNCHRONISE(m_field.get_comm());
3488 
3489  if (verb > QUIET) {
3490  MOFEM_LOG_C(
3491  "WORLD", Sev::inform,
3492  "Removed DOFs from problem %s dofs [%d / %d (before %d / %d) global]",
3493  prb_ptr->getName().c_str(), prb_ptr->getNbDofsRow(),
3494  prb_ptr->getNbDofsCol(), nb_init_row_dofs, nb_init_col_dofs);
3495  MOFEM_LOG_C("SYNC", Sev::verbose,
3496  "Removed DOFs from problem %s dofs [ %d / %d "
3497  "(before %d / %d) local, %d / %d (before %d / %d)]",
3498  prb_ptr->getName().c_str(), prb_ptr->getNbLocalDofsRow(),
3499  prb_ptr->getNbLocalDofsCol(), nb_init_loc_row_dofs,
3500  nb_init_loc_row_dofs, prb_ptr->getNbGhostDofsRow(),
3501  prb_ptr->getNbGhostDofsCol(), nb_init_ghost_row_dofs,
3502  nb_init_ghost_col_dofs);
3503  MOFEM_LOG_SYNCHRONISE(m_field.get_comm());
3504  }
3506 }
3507 
3509  const std::string problem_name, const std::string field_name,
3510  const BitRefLevel bit_ref_level, const BitRefLevel bit_ref_mask,
3511  Range *ents_ptr, const int lo_coeff, const int hi_coeff, const int lo_order,
3512  const int hi_order, int verb, const bool debug) {
3513  MoFEM::Interface &m_field = cOre;
3515 
3516  auto bit_manager = m_field.getInterface<BitRefManager>();
3517 
3518  Range ents;
3519  if (ents_ptr) {
3520  ents = *ents_ptr;
3521  CHKERR bit_manager->filterEntitiesByRefLevel(bit_ref_level, bit_ref_mask,
3522  ents, verb);
3523  } else {
3524  CHKERR bit_manager->getEntitiesByRefLevel(bit_ref_level, bit_ref_mask, ents,
3525  verb);
3526  }
3527 
3528  CHKERR removeDofsOnEntities(problem_name, field_name, ents, lo_coeff,
3529  hi_coeff, lo_order, hi_order, verb, debug);
3530 
3532 }
3533 
3535  const std::string problem_name, const std::string field_name,
3536  const BitRefLevel bit_ref_level, const BitRefLevel bit_ref_mask,
3537  Range *ents_ptr, const int lo_coeff, const int hi_coeff, const int lo_order,
3538  const int hi_order, int verb, const bool debug) {
3539  MoFEM::Interface &m_field = cOre;
3541 
3542  auto bit_manager = m_field.getInterface<BitRefManager>();
3543 
3544  Range ents;
3545  if (ents_ptr) {
3546  ents = *ents_ptr;
3547  CHKERR bit_manager->filterEntitiesByRefLevel(bit_ref_level, bit_ref_mask,
3548  ents, verb);
3549  } else {
3550  CHKERR bit_manager->getEntitiesByRefLevel(bit_ref_level, bit_ref_mask, ents,
3551  verb);
3552  }
3553 
3555  lo_coeff, hi_coeff, lo_order,
3556  hi_order, verb, debug);
3557 
3559 }
3560 
3562 ProblemsManager::markDofs(const std::string problem_name, RowColData rc,
3563  const enum MarkOP op, const Range ents,
3564  std::vector<unsigned char> &marker) const {
3565 
3566  Interface &m_field = cOre;
3567  const Problem *problem_ptr;
3569  CHKERR m_field.get_problem(problem_name, &problem_ptr);
3570  boost::shared_ptr<NumeredDofEntity_multiIndex> dofs;
3571  switch (rc) {
3572  case ROW:
3573  dofs = problem_ptr->getNumeredRowDofsPtr();
3574  break;
3575  case COL:
3576  dofs = problem_ptr->getNumeredColDofsPtr();
3577  default:
3578  SETERRQ(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE, "Should be row or column");
3579  }
3580  marker.resize(dofs->size(), 0);
3581  std::vector<unsigned char> marker_tmp;
3582 
3583  switch (op) {
3584  case MarkOP::OR:
3585  for (auto p = ents.pair_begin(); p != ents.pair_end(); ++p) {
3586  auto lo = dofs->get<Ent_mi_tag>().lower_bound(p->first);
3587  auto hi = dofs->get<Ent_mi_tag>().upper_bound(p->second);
3588  for (; lo != hi; ++lo)
3589  marker[(*lo)->getPetscLocalDofIdx()] |= 1;
3590  }
3591  break;
3592  case MarkOP::AND:
3593  marker_tmp.resize(dofs->size(), 0);
3594  for (auto p = ents.pair_begin(); p != ents.pair_end(); ++p) {
3595  auto lo = dofs->get<Ent_mi_tag>().lower_bound(p->first);
3596  auto hi = dofs->get<Ent_mi_tag>().upper_bound(p->second);
3597  for (; lo != hi; ++lo)
3598  marker_tmp[(*lo)->getPetscLocalDofIdx()] = 1;
3599  }
3600  for (int i = 0; i != marker.size(); ++i) {
3601  marker[i] &= marker_tmp[i];
3602  }
3603  break;
3604  }
3605 
3607 }
3608 
3610  const std::string problem_name, RowColData rc, const std::string field_name,
3611  const int lo, const int hi, const enum ProblemsManager::MarkOP op,
3612  const unsigned char c, std::vector<unsigned char> &marker) const {
3613 
3614  Interface &m_field = cOre;
3615  const Problem *problem_ptr;
3617  CHKERR m_field.get_problem(problem_name, &problem_ptr);
3618  boost::shared_ptr<NumeredDofEntity_multiIndex> dofs;
3619  switch (rc) {
3620  case ROW:
3621  dofs = problem_ptr->getNumeredRowDofsPtr();
3622  break;
3623  case COL:
3624  dofs = problem_ptr->getNumeredColDofsPtr();
3625  default:
3626  SETERRQ(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE, "Should be row or column");
3627  }
3628  marker.resize(dofs->size(), 0);
3629 
3630  auto dof_lo = dofs->get<Unique_mi_tag>().lower_bound(
3632  auto dof_hi = dofs->get<Unique_mi_tag>().upper_bound(
3634 
3635  auto marker_ref = [marker](auto &it) -> unsigned int & {
3636  return marker[(*it)->getPetscLocalDofIdx()];
3637  };
3638 
3639  switch (op) {
3640  case MarkOP::OR:
3641  for (; dof_lo != dof_hi; ++dof_lo)
3642  if ((*dof_lo)->getDofCoeffIdx() >= lo &&
3643  (*dof_lo)->getDofCoeffIdx() <= hi)
3644  marker[(*dof_lo)->getPetscLocalDofIdx()] |= c;
3645  break;
3646  case MarkOP::AND:
3647  for (; dof_lo != dof_hi; ++dof_lo)
3648  if ((*dof_lo)->getDofCoeffIdx() >= lo &&
3649  (*dof_lo)->getDofCoeffIdx() <= hi)
3650  marker[(*dof_lo)->getPetscLocalDofIdx()] &= c;
3651  break;
3652  }
3653 
3655 }
3656 
3658 
3659  const std::string problem_name, RowColData rc,
3660  std::vector<boost::weak_ptr<NumeredDofEntity>> &vec_dof_view,
3661  const enum MarkOP op, std::vector<unsigned char> &marker
3662 
3663 ) const {
3664  Interface &m_field = cOre;
3666 
3667  const Problem *problem_ptr;
3668  CHKERR m_field.get_problem(problem_name, &problem_ptr);
3669  boost::shared_ptr<NumeredDofEntity_multiIndex> dofs;
3670  switch (rc) {
3671  case ROW:
3672  dofs = problem_ptr->getNumeredRowDofsPtr();
3673  break;
3674  case COL:
3675  dofs = problem_ptr->getNumeredColDofsPtr();
3676  break;
3677  default:
3678  SETERRQ(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE, "Should be row or column");
3679  }
3680  marker.resize(dofs->size(), 0);
3681 
3682  for (auto &dof : vec_dof_view) {
3683  if (auto dof_ptr = dof.lock()) {
3684  if (op == MarkOP::OR)
3685  marker[dof_ptr->getPetscLocalDofIdx()] |= 1;
3686  else
3687  marker[dof_ptr->getPetscLocalDofIdx()] &= 1;
3688  }
3689  }
3690 
3692 }
3693 
3695 ProblemsManager::addFieldToEmptyFieldBlocks(const std::string problem_name,
3696  const std::string row_field,
3697  const std::string col_field) const {
3698 
3699  Interface &m_field = cOre;
3701 
3702  const auto problem_ptr = m_field.get_problem(problem_name);
3703  auto get_field_id = [&](const std::string field_name) {
3704  return m_field.get_field_structure(field_name)->getId();
3705  };
3706  const auto row_id = get_field_id(row_field);
3707  const auto col_id = get_field_id(col_field);
3708 
3709  problem_ptr->addFieldToEmptyFieldBlocks(BlockFieldPair(row_id, col_id));
3710 
3712 }
3713 
3714 } // namespace MoFEM
MoFEMFunctionReturnHot
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:460
MoFEM::UnknownInterface::getInterface
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Definition: UnknownInterface.hpp:93
MoFEM::createAOMappingIS
auto createAOMappingIS(IS isapp, IS ispetsc)
Creates an application mapping using two index sets.
Definition: PetscSmartObj.hpp:318
MoFEM::ProblemsManager::buildProblemFromFields
PetscBool buildProblemFromFields
Definition: ProblemsManager.hpp:30
MoFEM::IdxDataTypePtr::getUId
UId getUId() const
Definition: ProblemsManager.cpp:32
MoFEM::CoreInterface::get_field_name
virtual std::string get_field_name(const BitFieldId id) const =0
get field name from id
MoFEM::FieldEntity::getGlobalUniqueIdCalculate
UId getGlobalUniqueIdCalculate() const
Calculate global UId.
Definition: FieldEntsMultiIndices.hpp:216
MoFEM::CoreInterface::get_ents_finite_elements
virtual const EntFiniteElement_multiIndex * get_ents_finite_elements() const =0
Get the ents finite elements object.
MoFEM::Ent_mi_tag
Definition: TagMultiIndices.hpp:21
MoFEM::Problem::nbGhostDofsRow
DofIdx nbGhostDofsRow
Number of ghost DOFs in row.
Definition: ProblemsMultiIndices.hpp:69
MoFEM::Field::getNbOfCoeffs
FieldCoefficientsNumber getNbOfCoeffs() const
Get number of field coefficients.
Definition: FieldMultiIndices.hpp:202
MoFEM::debug
const static bool debug
Definition: ConstrainMatrixCtx.cpp:9
MoFEM::ProblemsManager::buildProblem
MoFEMErrorCode buildProblem(const std::string name, const bool square_matrix, int verb=VERBOSE)
build problem data structures
Definition: ProblemsManager.cpp:87
MoFEM::ProblemsManager::MarkOP
MarkOP
Definition: ProblemsManager.hpp:416
MoFEM::CoreTmp< 0 >
Core (interface) class.
Definition: Core.hpp:82
ProblemManagerFunctionBegin
#define ProblemManagerFunctionBegin
Definition: ProblemsManager.cpp:8
MoFEM::NumeredDofEntity_part_and_mofem_glob_idx_change
Definition: DofsMultiIndices.hpp:549
MoFEM::field_bit_from_bit_number
auto field_bit_from_bit_number(const int bit_number)
get field bit id from bit number
Definition: Templates.hpp:1930
MOFEM_LOG_SEVERITY_SYNC
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
Definition: LogManager.hpp:352
MoFEM::createISGeneral
auto createISGeneral(MPI_Comm comm, PetscInt n, const PetscInt idx[], PetscCopyMode mode)
Creates a data structure for an index set containing a list of integers.
Definition: PetscSmartObj.hpp:287
MoFEM::Problem::getNumberOfElementsByNameAndPart
MoFEMErrorCode getNumberOfElementsByNameAndPart(MPI_Comm comm, const std::string name, PetscLayout *layout) const
Get number of finite elements by name on processors.
Definition: ProblemsMultiIndices.cpp:98
EntityHandle
MoFEM::ProblemsManager
Problem manager is used to build and partition problems.
Definition: ProblemsManager.hpp:21
MoFEM::Problem::getNbDofsCol
DofIdx getNbDofsCol() const
Definition: ProblemsMultiIndices.hpp:377
NOISY
@ NOISY
Definition: definitions.h:224
MoFEM::IdxDataTypePtr::getDofIdx
int getDofIdx() const
Definition: ProblemsManager.cpp:28
MoFEM::Problem_mi_tag
Definition: TagMultiIndices.hpp:70
MoFEM::ProblemsManager::partitionMesh
DEPRECATED MoFEMErrorCode partitionMesh(const Range &ents, const int dim, const int adj_dim, const int n_parts, Tag *th_vertex_weights=nullptr, Tag *th_edge_weights=nullptr, Tag *th_part_weights=nullptr, int verb=VERBOSE, const bool debug=false)
Set partition tag to each finite element in the problem.
Definition: ProblemsManager.cpp:77
MoFEM::ProblemsManager::inheritPartition
MoFEMErrorCode inheritPartition(const std::string name, const std::string problem_for_rows, bool copy_rows, const std::string problem_for_cols, bool copy_cols, int verb=VERBOSE)
build indexing and partition problem inheriting indexing and partitioning from two other problems
Definition: ProblemsManager.cpp:1901
MoFEM::CoreInterface::get_comm
virtual MPI_Comm & get_comm() const =0
MoFEM::CoreInterface::get_field_structure
virtual const Field * get_field_structure(const std::string &name, enum MoFEMTypes bh=MF_EXIST) const =0
get field structure
MoFEM::NumeredDofEntity_part_and_indices_change
Definition: DofsMultiIndices.hpp:564
MoFEM::Exceptions::MoFEMErrorCode
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
MoFEM::NumeredDofEntity_part_and_glob_idx_change
Definition: DofsMultiIndices.hpp:537
MoFEM::CoreInterface::get_field_bit_number
virtual FieldBitNumber get_field_bit_number(const std::string name) const =0
get field bit number
MoFEM::PetscLocalIdx_mi_tag
Definition: TagMultiIndices.hpp:45
MoFEM::CoreInterface::get_comm_rank
virtual int get_comm_rank() const =0
MoFEM::NumeredDofEntity_part_and_all_indices_change
Definition: DofsMultiIndices.hpp:610
MoFEM::Types::BitFieldId
std::bitset< BITFIELDID_SIZE > BitFieldId
Field Id.
Definition: Types.hpp:42
MoFEM::CoreInterface::get_problem
virtual const Problem * get_problem(const std::string problem_name) const =0
Get the problem object.
MoFEM::Composite_Name_And_Part_mi_tag
Definition: TagMultiIndices.hpp:87
MoFEM::Problem::getBitFEId
BitFEId getBitFEId() const
Get the BitFEIDs in problem
Definition: ProblemsMultiIndices.cpp:45
MoFEM::CoreTmp< 0 >::BUILD_ADJ
@ BUILD_ADJ
Definition: Core.hpp:214
MoFEM::Problem::getRowDofsSequence
auto & getRowDofsSequence() const
Get reference to sequence data numbered dof container.
Definition: ProblemsMultiIndices.hpp:510
MoFEM::CoreInterface::get_finite_elements
virtual const FiniteElement_multiIndex * get_finite_elements() const =0
Get the finite elements object.
MoFEM::Problem::getNbGhostDofsCol
DofIdx getNbGhostDofsCol() const
Definition: ProblemsMultiIndices.hpp:381
MoFEM::Problem::getNbGhostDofsRow
DofIdx getNbGhostDofsRow() const
Definition: ProblemsMultiIndices.hpp:380
MoFEM::ProblemsManager::printPartitionedProblem
MoFEMErrorCode printPartitionedProblem(const Problem *problem_ptr, int verb=VERBOSE)
Definition: ProblemsManager.cpp:2070
MOFEM_IMPOSSIBLE_CASE
@ MOFEM_IMPOSSIBLE_CASE
Definition: definitions.h:35
MoFEM::ProblemsManager::debugPartitionedProblem
MoFEMErrorCode debugPartitionedProblem(const Problem *problem_ptr, int verb=VERBOSE)
Definition: ProblemsManager.cpp:2089
MoFEM::ProblemsManager::query_interface
MoFEMErrorCode query_interface(boost::typeindex::type_index type_index, UnknownInterface **iface) const
Definition: ProblemsManager.cpp:49
MoFEM::DofEntity_multiIndex_active_view
multi_index_container< boost::shared_ptr< DofEntity >, indexed_by< ordered_unique< const_mem_fun< DofEntity, UId, &DofEntity::getLocalUniqueId > >, ordered_non_unique< const_mem_fun< DofEntity, char, &DofEntity::getActive > > > > DofEntity_multiIndex_active_view
multi-index view on DofEntity activity
Definition: DofsMultiIndices.hpp:370
sdf.r
int r
Definition: sdf.py:8
MoFEM::Field::getDofSideMap
std::map< int, BaseFunction::DofsSideMap > & getDofSideMap() const
Get the dofs side map.
Definition: FieldMultiIndices.hpp:292
MoFEM::EntDofIdx_mi_tag
Definition: TagMultiIndices.hpp:28
MoFEM::DeprecatedCoreInterface
Deprecated interface functions.
Definition: DeprecatedCoreInterface.hpp:16
ROW
@ ROW
Definition: definitions.h:136
MoFEM::CoreInterface::get_dofs
virtual const DofEntity_multiIndex * get_dofs() const =0
Get the dofs object.
MoFEM::Interface
DeprecatedCoreInterface Interface
Definition: Interface.hpp:2010
NumeredDofEntity_multiIndex
multi_index_container< boost::shared_ptr< NumeredDofEntity >, indexed_by< ordered_unique< tag< Unique_mi_tag >, const_mem_fun< NumeredDofEntity::interface_type_DofEntity, UId, &NumeredDofEntity::getLocalUniqueId > >, ordered_non_unique< tag< Part_mi_tag >, member< NumeredDofEntity, unsigned int, &NumeredDofEntity::pArt > >, ordered_non_unique< tag< Idx_mi_tag >, member< NumeredDofEntity, DofIdx, &NumeredDofEntity::dofIdx > >, ordered_non_unique< tag< PetscGlobalIdx_mi_tag >, member< NumeredDofEntity, DofIdx, &NumeredDofEntity::petscGloablDofIdx > >, ordered_non_unique< tag< PetscLocalIdx_mi_tag >, member< NumeredDofEntity, DofIdx, &NumeredDofEntity::petscLocalDofIdx > >, ordered_non_unique< tag< Ent_mi_tag >, const_mem_fun< NumeredDofEntity::interface_type_DofEntity, EntityHandle, &NumeredDofEntity::getEnt > > > > NumeredDofEntity_multiIndex
MultiIndex container keeps NumeredDofEntity.
Definition: DofsMultiIndices.hpp:469
c
const double c
speed of light (cm/ns)
Definition: initial_diffusion.cpp:39
MoFEM::NumeredDofEntityByUId
NumeredDofEntity_multiIndex::index< Unique_mi_tag >::type NumeredDofEntityByUId
Numbered DoF multi-index by UId.
Definition: DofsMultiIndices.hpp:476
MoFEM::IdxDataTypePtr::pTr
const int * pTr
Definition: ProblemsManager.cpp:45
MoFEM::Field::getId
const BitFieldId & getId() const
Get unique field id.
Definition: FieldMultiIndices.hpp:129
VERBOSE
@ VERBOSE
Definition: definitions.h:222
MoFEM::createAOMapping
auto createAOMapping(MPI_Comm comm, PetscInt napp, const PetscInt myapp[], const PetscInt mypetsc[])
Creates an application mapping using two integer arrays.
Definition: PetscSmartObj.hpp:338
CHKERR
#define CHKERR
Inline error check.
Definition: definitions.h:548
MoFEM::CoreInterface::get_moab
virtual moab::Interface & get_moab()=0
MoFEM::ProblemsManager::cOre
MoFEM::Core & cOre
Definition: ProblemsManager.hpp:26
MoFEM::ProblemsManager::removeDofsOnEntitiesNotDistributed
MoFEMErrorCode removeDofsOnEntitiesNotDistributed(const std::string problem_name, const std::string field_name, const Range ents, const int lo_coeff=0, const int hi_coeff=MAX_DOFS_ON_ENTITY, const int lo_order=0, const int hi_order=100, int verb=VERBOSE, const bool debug=false)
Remove DOFs from problem.
Definition: ProblemsManager.cpp:3240
MoFEM::NumeredDofEntity
keeps information about indexed dofs for the problem
Definition: DofsMultiIndices.hpp:226
MoFEM::NumeredDofEntity_local_idx_change
Definition: DofsMultiIndices.hpp:584
MoFEM
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:10
MoFEM::Part_mi_tag
Definition: TagMultiIndices.hpp:53
a
constexpr double a
Definition: approx_sphere.cpp:30
MoFEM::ProblemsManager::partitionGhostDofsOnDistributedMesh
MoFEMErrorCode partitionGhostDofsOnDistributedMesh(const std::string name, int verb=VERBOSE)
determine ghost nodes on distributed meshes
Definition: ProblemsManager.cpp:2487
MoFEM::Problem::numeredColDofsPtr
boost::shared_ptr< NumeredDofEntity_multiIndex > numeredColDofsPtr
store DOFs on columns for this problem
Definition: ProblemsMultiIndices.hpp:75
MOFEM_LOG_C
#define MOFEM_LOG_C(channel, severity, format,...)
Definition: LogManager.hpp:311
MoFEM::FieldEntity::getHandleFromUniqueId
static auto getHandleFromUniqueId(const UId uid)
Get the Handle From Unique Id.
Definition: FieldEntsMultiIndices.hpp:192
MoFEM::Types::UId
uint128_t UId
Unique Id.
Definition: Types.hpp:31
MoFEM::get_temp_meshset_ptr
auto get_temp_meshset_ptr(moab::Interface &moab)
Create smart pointer to temporary meshset.
Definition: Templates.hpp:1886
RowColData
RowColData
RowColData.
Definition: definitions.h:136
MoFEM::ProblemsManager::removeDofsOnEntities
MoFEMErrorCode removeDofsOnEntities(const std::string problem_name, const std::string field_name, const Range ents, const int lo_coeff=0, const int hi_coeff=MAX_DOFS_ON_ENTITY, const int lo_order=0, const int hi_order=100, int verb=VERBOSE, const bool debug=false)
Remove DOFs from problem.
Definition: ProblemsManager.cpp:2968
convert.type
type
Definition: convert.py:64
MoFEM::Problem::getNbDofsRow
DofIdx getNbDofsRow() const
Definition: ProblemsMultiIndices.hpp:376
MoFEM::FieldEntity::getLocalUniqueIdCalculate
UId getLocalUniqueIdCalculate()
Get the Local Unique Id Calculate object.
Definition: FieldEntsMultiIndices.hpp:136
MoFEM::EntFiniteElement::getLocalUniqueIdCalculate
UId getLocalUniqueIdCalculate() const
Generate UId for finite element entity.
Definition: FEMultiIndices.hpp:528
MoFEM::CoreTmp< 0 >::BUILD_FIELD
@ BUILD_FIELD
Definition: Core.hpp:212
MoFEM::IdxDataType
Definition: ProblemsManager.cpp:16
MOFEM_LOG_SYNCHRONISE
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
Definition: LogManager.hpp:345
MoFEM::Problem::getSubData
boost::shared_ptr< SubProblemData > & getSubData() const
Get main problem of sub-problem is.
Definition: ProblemsMultiIndices.hpp:119
MoFEM::FieldEntity::getLoBitNumberUId
static UId getLoBitNumberUId(const FieldBitNumber bit_number)
Definition: FieldEntsMultiIndices.hpp:222
COL
@ COL
Definition: definitions.h:136
MoFEM::Problem::nbDofsCol
DofIdx nbDofsCol
Global number of DOFs in col.
Definition: ProblemsMultiIndices.hpp:66
MoFEM::ProblemsManager::addFieldToEmptyFieldBlocks
MoFEMErrorCode addFieldToEmptyFieldBlocks(const std::string problem_name, const std::string row_field, const std::string col_field) const
add empty block to problem
Definition: ProblemsManager.cpp:3695
MoFEM::NumeredDofEntity_multiIndex_uid_view_ordered
multi_index_container< boost::shared_ptr< NumeredDofEntity >, indexed_by< ordered_unique< const_mem_fun< NumeredDofEntity::interface_type_DofEntity, UId, &NumeredDofEntity::getLocalUniqueId > > > > NumeredDofEntity_multiIndex_uid_view_ordered
Definition: DofsMultiIndices.hpp:503
MoFEM::Problem::getNumeredRowDofsPtr
auto & getNumeredRowDofsPtr() const
get access to numeredRowDofsPtr storing DOFs on rows
Definition: ProblemsMultiIndices.hpp:82
MoFEM::CoreInterface::get_comm_size
virtual int get_comm_size() const =0
MoFEM::ProblemsManager::getOptions
MoFEMErrorCode getOptions()
Definition: ProblemsManager.cpp:62
MoFEM::ProblemsManager::markDofs
MoFEMErrorCode markDofs(const std::string problem_name, RowColData rc, const enum MarkOP op, const Range ents, std::vector< unsigned char > &marker) const
Create vector with marked indices.
Definition: ProblemsManager.cpp:3562
MoFEM::CoreInterface::get_field_ents
virtual const FieldEntity_multiIndex * get_field_ents() const =0
Get the field ents object.
MoFEM::NumeredDofEntity_mofem_index_change
Definition: DofsMultiIndices.hpp:597
MoFEM::CoreTmp< 0 >::BUILD_PROBLEM
@ BUILD_PROBLEM
Definition: Core.hpp:215
MoFEM::Problem::getColDofsSequence
auto & getColDofsSequence() const
Get reference to sequence data numbered dof container.
Definition: ProblemsMultiIndices.hpp:526
MoFEM::BlockFieldPair
Problem::BlockFieldPair BlockFieldPair
Definition: ProblemsMultiIndices.hpp:566
MoFEM::Problem::nbLocDofsRow
DofIdx nbLocDofsRow
Local number of DOFs in row.
Definition: ProblemsMultiIndices.hpp:67
MoFEM::IdxDataTypePtr
Definition: ProblemsManager.cpp:26
MoFEM::CoreTmp< 0 >::PARTITION_PROBLEM
@ PARTITION_PROBLEM
Definition: Core.hpp:216
MoFEM::ProblemsManager::getProblemElementsLayout
MoFEMErrorCode getProblemElementsLayout(const std::string name, const std::string &fe_name, PetscLayout *layout) const
Get layout of elements in the problem.
Definition: ProblemsManager.cpp:2607
MOFEM_OPERATION_UNSUCCESSFUL
@ MOFEM_OPERATION_UNSUCCESSFUL
Definition: definitions.h:34
MoFEM::type_from_handle
auto type_from_handle(const EntityHandle h)
get type from entity handle
Definition: Templates.hpp:1898
MoFEM::PetscGlobalIdx_mi_tag
Definition: TagMultiIndices.hpp:38
MoFEM::FieldEntity_multiIndex_global_uid_view
multi_index_container< boost::shared_ptr< FieldEntity >, indexed_by< ordered_unique< tag< Unique_mi_tag >, const_mem_fun< FieldEntity, UId, &FieldEntity::getGlobalUniqueId > > > > FieldEntity_multiIndex_global_uid_view
multi-index view on DofEntity by uid
Definition: FieldEntsMultiIndices.hpp:444
MoFEM::Problem::getNbLocalDofsRow
DofIdx getNbLocalDofsRow() const
Definition: ProblemsMultiIndices.hpp:378
MoFEM::CoreInterface::get_problems
virtual const Problem_multiIndex * get_problems() const =0
Get the problems object.
i
FTensor::Index< 'i', SPACE_DIM > i
Definition: hcurl_divergence_operator_2d.cpp:27
MoFEM::ProblemsManager::partitionFiniteElements
MoFEMErrorCode partitionFiniteElements(const std::string name, bool part_from_moab=false, int low_proc=-1, int hi_proc=-1, int verb=VERBOSE)
partition finite elements
Definition: ProblemsManager.cpp:2172
MoFEM::Problem::numeredFiniteElementsPtr
boost::shared_ptr< NumeredEntFiniteElement_multiIndex > numeredFiniteElementsPtr
store finite elements
Definition: ProblemsMultiIndices.hpp:77
MoFEM::DofEntity_multiIndex_global_uid_view
multi_index_container< boost::shared_ptr< DofEntity >, indexed_by< ordered_unique< const_mem_fun< DofEntity, UId, &DofEntity::getGlobalUniqueId > > > > DofEntity_multiIndex_global_uid_view
multi-index view on DofEntity by uid
Definition: DofsMultiIndices.hpp:349
MoFEM::DofEntity::getLoFieldEntityUId
static UId getLoFieldEntityUId(const FieldBitNumber bit, const EntityHandle ent)
Definition: DofsMultiIndices.hpp:69
MOFEM_NOT_FOUND
@ MOFEM_NOT_FOUND
Definition: definitions.h:33
NumeredEntFiniteElement_multiIndex
multi_index_container< boost::shared_ptr< NumeredEntFiniteElement >, indexed_by< ordered_unique< tag< Unique_mi_tag >, const_mem_fun< NumeredEntFiniteElement::interface_type_EntFiniteElement, UId, &NumeredEntFiniteElement::getLocalUniqueId > >, ordered_non_unique< tag< Part_mi_tag >, member< NumeredEntFiniteElement, unsigned int, &NumeredEntFiniteElement::part > >, ordered_non_unique< tag< Ent_mi_tag >, const_mem_fun< NumeredEntFiniteElement::interface_type_RefEntity, EntityHandle, &NumeredEntFiniteElement::getEnt > >, ordered_non_unique< tag< Composite_Name_And_Part_mi_tag >, composite_key< NumeredEntFiniteElement, const_mem_fun< NumeredEntFiniteElement::interface_type_FiniteElement, boost::string_ref, &NumeredEntFiniteElement::getNameRef >, member< NumeredEntFiniteElement, unsigned int, &NumeredEntFiniteElement::part > >> >> NumeredEntFiniteElement_multiIndex
MultiIndex for entities for NumeredEntFiniteElement.
Definition: FEMultiIndices.hpp:830
MoFEM::IdxDataTypePtr::IdxDataTypePtr
IdxDataTypePtr(const int *ptr)
Definition: ProblemsManager.cpp:27
MoFEM::ProblemsManager::buildComposedProblem
MoFEMErrorCode buildComposedProblem(const std::string out_name, const std::vector< std::string > add_row_problems, const std::vector< std::string > add_col_problems, const bool square_matrix=true, int verb=1)
build composite problem
Definition: ProblemsManager.cpp:1255
MoFEM::Problem::nbGhostDofsCol
DofIdx nbGhostDofsCol
Number of ghost DOFs in col.
Definition: ProblemsMultiIndices.hpp:70
field_name
constexpr auto field_name
Definition: poisson_2d_homogeneous.cpp:13
MoFEM::MatrixManager
Matrix manager is used to build and partition problems.
Definition: MatrixManager.hpp:21
convert.n
n
Definition: convert.py:82
MoFEM::ProblemsManager::removeDofs
MoFEMErrorCode removeDofs(const std::string problem_name, RowColData rc, std::vector< boost::weak_ptr< NumeredDofEntity >> &vec_dof_view, int verb=VERBOSE, const bool debug=false)
Remove DOFs from problem on broken space.
Definition: ProblemsManager.cpp:2728
MoFEM::CoreInterface::get_fields
virtual const Field_multiIndex * get_fields() const =0
Get the fields object.
MoFEM::Problem::numeredRowDofsPtr
boost::shared_ptr< NumeredDofEntity_multiIndex > numeredRowDofsPtr
store DOFs on rows for this problem
Definition: ProblemsMultiIndices.hpp:73
MoFEM::UnknownInterface
base class for all interface classes
Definition: UnknownInterface.hpp:34
MAX_DOFS_ON_ENTITY
#define MAX_DOFS_ON_ENTITY
Maximal number of DOFs on entity.
Definition: definitions.h:249
v
const double v
phase velocity of light in medium (cm/ns)
Definition: initial_diffusion.cpp:40
MoFEM::CoreTmp< 0 >::PARTITION_FE
@ PARTITION_FE
Definition: Core.hpp:217
Range
MoFEM::CoreTmp< 0 >::getBuildMoFEM
int & getBuildMoFEM() const
Get flags/semaphores for different stages.
Definition: Core.hpp:225
MoFEM::IdxDataType::IdxDataType
IdxDataType(const UId uid, const int dof)
Definition: ProblemsManager.cpp:17
MoFEM::Problem::nbLocDofsCol
DofIdx nbLocDofsCol
Local number of DOFs in colIs.
Definition: ProblemsMultiIndices.hpp:68
MoFEM::ProblemsManager::MOFEM_EVENT_ProblemsManager
PetscLogEvent MOFEM_EVENT_ProblemsManager
Definition: ProblemsManager.hpp:495
FTensor::dd
const Tensor2_symmetric_Expr< const ddTensor0< T, Dim, i, j >, typename promote< T, double >::V, Dim, i, j > dd(const Tensor0< T * > &a, const Index< i, Dim > index1, const Index< j, Dim > index2, const Tensor1< int, Dim > &d_ijk, const Tensor1< double, Dim > &d_xyz)
Definition: ddTensor0.hpp:33
MOFEM_LOG
#define MOFEM_LOG(channel, severity)
Log.
Definition: LogManager.hpp:308
MoFEM::IdxDataType::dAta
int dAta[5]
Definition: ProblemsManager.cpp:23
MoFEM::EntFiniteElement::getDofView
static MoFEMErrorCode getDofView(const FE_ENTS &fe_ents_view, const MOFEM_DOFS &mofem_dofs, MOFEM_DOFS_VIEW &dofs_view, INSERTER &&inserter)
Definition: FEMultiIndices.hpp:583
MoFEM::CommInterface
Managing BitRefLevels.
Definition: CommInterface.hpp:21
MoFEM::DofEntity::getHiFieldEntityUId
static UId getHiFieldEntityUId(const FieldBitNumber bit, const EntityHandle ent)
Definition: DofsMultiIndices.hpp:75
MoFEM::ProblemsManager::partitionSimpleProblem
MoFEMErrorCode partitionSimpleProblem(const std::string name, int verb=VERBOSE)
partition problem dofs
Definition: ProblemsManager.cpp:1542
MoFEM::ProblemsManager::synchroniseProblemEntities
PetscBool synchroniseProblemEntities
DOFs in fields, not from DOFs on elements.
Definition: ProblemsManager.hpp:33
HenckyOps::f
auto f
Definition: HenckyOps.hpp:15
MoFEM::FiniteElement_name_mi_tag
Definition: TagMultiIndices.hpp:26
MoFEM::CoreInterface::get_ents_elements_adjacency
virtual MoFEMErrorCode get_ents_elements_adjacency(const FieldEntityEntFiniteElementAdjacencyMap_multiIndex **dofs_elements_adjacency) const =0
Get the dofs elements adjacency object.
MoFEM::Exceptions::ierr
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
Definition: Exceptions.hpp:76
MoFEM::Problem::nbDofsRow
DofIdx nbDofsRow
Global number of DOFs in row.
Definition: ProblemsMultiIndices.hpp:65
EigenMatrix::Vec
const FTensor::Tensor2< T, Dim, Dim > Vec
Definition: MatrixFunction.hpp:64
MOFEM_DATA_INCONSISTENCY
@ MOFEM_DATA_INCONSISTENCY
Definition: definitions.h:31
MoFEM::ProblemsManager::buildProblemOnDistributedMesh
MoFEMErrorCode buildProblemOnDistributedMesh(const std::string name, const bool square_matrix, int verb=VERBOSE)
build problem data structures, assuming that mesh is distributed (collective)
Definition: ProblemsManager.cpp:290
MoFEM::Idx_mi_tag
Definition: TagMultiIndices.hpp:31
MoFEM::CoreInterface::clear_problem
virtual MoFEMErrorCode clear_problem(const std::string name, int verb=DEFAULT_VERBOSITY)=0
clear problem
MoFEM::Problem::getBitRefLevelMask
BitRefLevel getBitRefLevelMask() const
Definition: ProblemsMultiIndices.hpp:384
MoFEM::ProblemsManager::ProblemsManager
ProblemsManager(const MoFEM::Core &core)
Definition: ProblemsManager.cpp:55
MoFEM::Problem::getBitRefLevel
BitRefLevel getBitRefLevel() const
Definition: ProblemsMultiIndices.hpp:383
MoFEM::FieldEntity::getHiBitNumberUId
static UId getHiBitNumberUId(const FieldBitNumber bit_number)
Definition: FieldEntsMultiIndices.hpp:228
MoFEM::Problem::getNbLocalDofsCol
DofIdx getNbLocalDofsCol() const
Definition: ProblemsMultiIndices.hpp:379
MoFEM::CoreTmp< 0 >::BUILD_FE
@ BUILD_FE
Definition: Core.hpp:213
MoFEM::Problem::getNumeredColDofsPtr
auto & getNumeredColDofsPtr() const
get access to numeredColDofsPtr storing DOFs on cols
Definition: ProblemsMultiIndices.hpp:87
FiniteElement_multiIndex
multi_index_container< boost::shared_ptr< FiniteElement >, indexed_by< hashed_unique< tag< FiniteElement_Meshset_mi_tag >, member< FiniteElement, EntityHandle, &FiniteElement::meshset > >, hashed_unique< tag< BitFEId_mi_tag >, const_mem_fun< FiniteElement, BitFEId, &FiniteElement::getId >, HashBit< BitFEId >, EqBit< BitFEId > >, ordered_unique< tag< FiniteElement_name_mi_tag >, const_mem_fun< FiniteElement, boost::string_ref, &FiniteElement::getNameRef > > > > FiniteElement_multiIndex
MultiIndex for entities for FiniteElement.
Definition: FEMultiIndices.hpp:849
MoFEM::NumeredEntFiniteElement
Partitioned (Indexed) Finite Element in Problem.
Definition: FEMultiIndices.hpp:728
m
FTensor::Index< 'm', 3 > m
Definition: shallow_wave.cpp:80
MoFEM::BitRefManager
Managing BitRefLevels.
Definition: BitRefManager.hpp:21
MoFEM::Types::BitRefLevel
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
Definition: Types.hpp:40
MOFEM_ATOM_TEST_INVALID
@ MOFEM_ATOM_TEST_INVALID
Definition: definitions.h:40
MoFEM::ProblemsManager::getFEMeshset
MoFEMErrorCode getFEMeshset(const std::string prb_name, const std::string &fe_name, EntityHandle *meshset) const
create add entities of finite element in the problem
Definition: ProblemsManager.cpp:2573
marker
auto marker
set bit to marker
Definition: hanging_node_approx.cpp:82
MoFEMFunctionBeginHot
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:453
QUIET
@ QUIET
Definition: definitions.h:221
MoFEM::Unique_mi_tag
Definition: TagMultiIndices.hpp:18
MoFEM::Problem
keeps basic data about problem
Definition: ProblemsMultiIndices.hpp:54
MoFEM::CoreTmp< 0 >::PARTITION_GHOST_DOFS
@ PARTITION_GHOST_DOFS
Definition: Core.hpp:218
MoFEM::SmartPetscObj< IS >
MoFEM::ProblemsManager::partitionGhostDofs
MoFEMErrorCode partitionGhostDofs(const std::string name, int verb=VERBOSE)
determine ghost nodes
Definition: ProblemsManager.cpp:2353
MoFEM::Problem::getName
auto getName() const
Definition: ProblemsMultiIndices.hpp:372
MoFEM::ProblemsManager::modifyMarkDofs
MoFEMErrorCode modifyMarkDofs(const std::string problem_name, RowColData rc, const std::string field_name, const int lo, const int hi, const enum MarkOP op, const unsigned char c, std::vector< unsigned char > &marker) const
Mark DOFs.
Definition: ProblemsManager.cpp:3609
MoFEM::ProblemsManager::getSideDofsOnBrokenSpaceEntities
MoFEMErrorCode getSideDofsOnBrokenSpaceEntities(std::vector< boost::weak_ptr< NumeredDofEntity >> &vec_dof_view, const std::string problem_name, RowColData rc, const std::string field_name, const Range ents, int bridge_dim, const int lo_coeff=0, const int hi_coeff=MAX_DOFS_ON_ENTITY, const int lo_order=0, const int hi_order=100, int verb=VERBOSE, const bool debug=false) const
Get DOFs on side entities for broke space.
Definition: ProblemsManager.cpp:2619
MoFEM::FieldEntity::getFieldBitNumberFromUniqueId
static auto getFieldBitNumberFromUniqueId(const UId uid)
Get the Field Bit Number From Unique Id.
Definition: FieldEntsMultiIndices.hpp:205
convert.int
int
Definition: convert.py:64
MoFEMFunctionReturn
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:429
CHKERRG
#define CHKERRG(n)
Check error code of MoFEM/MOAB/PETSc function.
Definition: definitions.h:496
VERY_VERBOSE
@ VERY_VERBOSE
Definition: definitions.h:223
MoFEMFunctionBegin
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:359
MOFEM_INVALID_DATA
@ MOFEM_INVALID_DATA
Definition: definitions.h:36
MoFEM::ProblemsManager::partitionProblem
MoFEMErrorCode partitionProblem(const std::string name, int verb=VERBOSE)
partition problem dofs (collective)
Definition: ProblemsManager.cpp:1688
MoFEM::ProblemsManager::buildSubProblem
MoFEMErrorCode buildSubProblem(const std::string out_name, const std::vector< std::string > &fields_row, const std::vector< std::string > &fields_col, const std::string main_problem, const bool square_matrix=true, const map< std::string, boost::shared_ptr< Range >> *entityMapRow=nullptr, const map< std::string, boost::shared_ptr< Range >> *entityMapCol=nullptr, int verb=VERBOSE)
build sub problem
Definition: ProblemsManager.cpp:986
MoFEM::Types::DofIdx
int DofIdx
Index of DOF.
Definition: Types.hpp:18
MoFEM::FieldEntity::getOwnerFromUniqueId
static auto getOwnerFromUniqueId(const UId uid)
Definition: FieldEntsMultiIndices.hpp:177