v0.8.23
ProblemsMultiIndices.hpp
Go to the documentation of this file.
1 /** \file ProblemsMultiIndices.hpp
2  * \brief Multi-index containers, data structures for problems and other
3  * low-level functions
4  */
5 
6 /* MoFEM is free software: you can redistribute it and/or modify it under
7  * the terms of the GNU Lesser General Public License as published by the
8  * Free Software Foundation, either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * MoFEM is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14  * License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with MoFEM. If not, see <http://www.gnu.org/licenses/>
18  */
19 
20 #ifndef __PROBLEMSMULTIINDICES_HPP__
21 #define __PROBLEMSMULTIINDICES_HPP__
22 
23 namespace MoFEM {
24 
25 struct Problem;
26 
27 /**
28  * Data structure created when composite problem is created
29  */
31 
32  std::vector<const Problem *> rowProblemsAdd;
33  std::vector<const Problem *> colProblemsAdd;
34 
35  std::vector<IS> rowIs;
36  std::vector<IS> colIs;
37 
38  inline MoFEMErrorCode getRowIs(IS *is, const unsigned int pp) const {
40  PetscObjectReference((PetscObject)rowIs[pp]);
41  if (pp <= rowIs.size()) {
42  SETERRQ1(PETSC_COMM_WORLD, MOFEM_INVALID_DATA,
43  "Exceed size of array pp<%d", rowIs.size());
44  }
45  *is = rowIs[pp];
47  }
48 
49  inline MoFEMErrorCode getColIs(IS *is, const unsigned int pp) const {
51  PetscObjectReference((PetscObject)colIs[pp]);
52  if (pp <= colIs.size()) {
53  SETERRQ1(PETSC_COMM_WORLD, MOFEM_INVALID_DATA,
54  "Exceed size of array pp<%d", colIs.size());
55  }
56  *is = colIs[pp];
58  }
59 
61  for (unsigned int ii = 0; ii != rowIs.size(); ii++) {
62  ISDestroy(&rowIs[ii]);
63  }
64  for (unsigned int jj = 0; jj != colIs.size(); jj++) {
65  ISDestroy(&colIs[jj]);
66  }
67  }
68 };
69 
70 /** \brief keeps basic data about problem
71  * \ingroup problems_multi_indices
72  *
73  * This is low level structure with information about problem, what elements
74  * compose problem and what DOFs are on rows and columns.
75  *
76  * \todo fix names following name convention
77  *
78  */
79 struct Problem {
80 
81  EntityHandle meshset; ///< Problem meshset (on tag of this meshset all data
82  ///< related to problem are stored)
83  BitProblemId *tagId; ///< Unique problem ID
84  const char *tagName; ///< Problem name
85  int tagNameSize; ///< Size of problem name
86  BitFEId *tagBitFEId; ///< IDs of finite elements in problem
87  BitRefLevel *tagBitRefLevel; ///< BitRef level of finite elements in problem
88  BitRefLevel *tagMaskBitRefLevel; ///< BItRefMask of elements in problem
89 
90  mutable DofIdx nbDofsRow; ///< Global number of DOFs in row
91  mutable DofIdx nbDofsCol; ///< Global number of DOFs in col
92  mutable DofIdx nbLocDofsRow; ///< Local number of DOFs in row
93  mutable DofIdx nbLocDofsCol; ///< Local number of DOFs in colIs
94  mutable DofIdx nbGhostDofsRow; ///< Number of ghost DOFs in row
95  mutable DofIdx nbGhostDofsCol; ///< Number of ghost DOFs in col
96 
97  mutable boost::shared_ptr<NumeredDofEntity_multiIndex>
98  numeredDofsRows; ///< store DOFs on rows for this problem
99  mutable boost::shared_ptr<NumeredDofEntity_multiIndex>
100  numeredDofsCols; ///< store DOFs on columns for this problem
101  mutable boost::shared_ptr<NumeredEntFiniteElement_multiIndex>
102  numeredFiniteElements; ///< store finite elements
103 
104  /**
105  * \brief get access to numeredDofsRows storing DOFs on rows
106  */
107  const boost::shared_ptr<NumeredDofEntity_multiIndex> &
109  return numeredDofsRows;
110  }
111 
112  /**
113  * \brief get access to numeredDofsCols storing DOFs on cols
114  */
115  const boost::shared_ptr<NumeredDofEntity_multiIndex> &
117  return numeredDofsCols;
118  }
119 
120  /**
121  * \brief get access to reference for multi-index storing finite elements
122  */
123  const boost::shared_ptr<NumeredEntFiniteElement_multiIndex> &
125  return numeredFiniteElements;
126  }
127 
128  /**
129  * \brief Subproblem problem data
130  */
131  struct SubProblemData {
132 
133  IS rowIs; ///< indices of main problem of which sub problem is this
134  IS colIs; ///< indices of main problem of which sub problem is this
135  AO rowMap; ///< mapping form main problem indices to sub-problem indices
136  AO colMap;
137 
138  /**
139  * get row Is for sub problem
140  * @param is create is
141  * @return error code
142  */
143  inline MoFEMErrorCode getRowIs(IS *is) {
145  PetscObjectReference((PetscObject)rowIs);
146  *is = rowIs;
148  }
149 
150  /**
151  * get col Is for sub problem
152  * @param is create is
153  * @return error code
154  */
155  inline MoFEMErrorCode getColIs(IS *is) {
157  PetscObjectReference((PetscObject)colIs);
158  *is = colIs;
160  };
161 
162  /**
163  * get row AO mapping for sub problem
164  * @param ao get mapping
165  * @return error code
166  */
167  inline MoFEMErrorCode getRowMap(AO *ao) {
169  PetscObjectReference((PetscObject)rowMap);
170  *ao = rowMap;
172  }
173 
174  /**
175  * get col AO mapping for sub problem
176  * @param ao get mapping
177  * @return error code
178  */
179  inline MoFEMErrorCode getColMap(AO *ao) {
181  PetscObjectReference((PetscObject)colMap);
182  *ao = colMap;
184  }
185 
187  : rowIs(PETSC_NULL), colIs(PETSC_NULL), rowMap(PETSC_NULL),
188  colMap(PETSC_NULL) {}
189  virtual ~SubProblemData() {
190  // int flg;
191  // MPI_Finalized(&flg);
192  // if(!flg) {
193  ISDestroy(&rowIs);
194  ISDestroy(&colIs);
195  AODestroy(&rowMap);
196  AODestroy(&colMap);
197  // }
198  }
199  };
200 
201  /**
202  * Pointer to data structure. This pointer has allocated data only for
203  * sub problems.
204  */
205  mutable boost::shared_ptr<SubProblemData> subProblemData;
206 
207  /**
208  * \brief Get main problem of sub-problem is
209  * @return sub problem data structure
210  */
211  inline boost::shared_ptr<SubProblemData> &getSubData() const {
212  return subProblemData;
213  }
214 
215  /**
216  * Pointer to data structure from which this problem is composed
217  */
218  mutable boost::shared_ptr<ComposedProblemsData> composedProblemsData;
219 
220  /**
221  * \brief Het composed problems data structure
222  */
223  inline boost::shared_ptr<ComposedProblemsData> &
225  return composedProblemsData;
226  }
227 
228  /**
229  * \brief get DOFs from problem
230  *
231  * Note that \e ent_dof_idx is not coefficient number, is local number of DOFs
232  * on the entity. The coefficient number and local index of DOFs or entity are
233  * the same on vertices and H1 approximation.
234  *
235  * @param name field name
236  * @param ent entity handle
237  * @param ent_dof_idx index of DOFs on entity
238  * @param row_or_col ROW or COL
239  * @param dof_ptr shared pointer to DOFs if found
240  * @return error code
241  */
243  const string name, const EntityHandle ent, const int ent_dof_idx,
244  const RowColData row_or_col,
245  boost::shared_ptr<NumeredDofEntity> &dof_ptr) const;
246 
247 /**
248  * use with loops to iterate problem fes
249  * \ingroup problems_multi_indices
250  *
251  * for(_IT_NUMEREDFE_BY_NAME_FOR_LOOP_(PROBLEMPTR,NAME,IT)) {
252  * ...
253  * }
254  *
255  */
256 #define _IT_NUMEREDFE_BY_NAME_FOR_LOOP_(PROBLEMPTR, NAME, IT) \
257  NumeredEntFiniteElementbyName::iterator IT = \
258  PROBLEMPTR->getNumeredFEsBegin(NAME); \
259  IT != PROBLEMPTR->getNumeredFEsEnd(NAME); \
260  IT++
261 
262  NumeredEntFiniteElementbyName::iterator
263  getNumeredFEsBegin(std::string fe_name) const {
264  return numeredFiniteElements->get<FiniteElement_name_mi_tag>().lower_bound(
265  fe_name);
266  }
267 
268  NumeredEntFiniteElementbyName::iterator
269  getNumeredFEsEnd(std::string fe_name) const {
270  return numeredFiniteElements->get<FiniteElement_name_mi_tag>().upper_bound(
271  fe_name);
272  }
273 
274 /**
275  * \brief use with loops to iterate row DOFs
276  * \ingroup problems_multi_indices
277  *
278  * \code
279  * for(_IT_NUMEREDDOF_ROW_FOR_LOOP_(PROBLEMPTR,IT)) {
280  * ...
281  * }
282  * \endcode
283  *
284  */
285 #define _IT_NUMEREDDOF_ROW_FOR_LOOP_(PROBLEMPTR, IT) \
286  NumeredDofEntity_multiIndex::iterator IT = \
287  PROBLEMPTR->getNumeredDofsRowsBegin(); \
288  IT != PROBLEMPTR->getNumeredDofsRowsEnd(); \
289  IT++
290 
291 /**
292  * use with loops to iterate col DOFs
293  * \ingroup problems_multi_indices
294  *
295  * \code
296  * for(_IT_NUMEREDDOF_COL_FOR_LOOP_(PROBLEMPTR,IT)) {
297  * ...
298  * }
299  * \endcode
300  *
301  */
302 #define _IT_NUMEREDDOF_COL_FOR_LOOP_(PROBLEMPTR, IT) \
303  NumeredDofEntity_multiIndex::iterator IT = \
304  PROBLEMPTR->getNumeredDofsColsBegin(); \
305  IT != PROBLEMPTR->getNumeredDofsColsEnd(); \
306  IT++
307 
308  /// get begin iterator for numeredDofsRows (insted you can use
309  /// #_IT_NUMEREDDOFMOFEMENTITY_ROW_FOR_LOOP_ for loops)
310  NumeredDofEntity_multiIndex::iterator getNumeredDofsRowsBegin() const {
311  return numeredDofsRows->begin();
312  }
313 
314  /// get end iterator for numeredDofsRows (insted you can use
315  /// #_IT_NUMEREDDOFMOFEMENTITY_ROW_FOR_LOOP_ for loops)
316  NumeredDofEntity_multiIndex::iterator getNumeredDofsRowsEnd() const {
317  return numeredDofsRows->end();
318  }
319 
320  /// get begin iterator for numeredDofsCols (insted you can use
321  /// #_IT_NUMEREDDOFMOFEMENTITY_COL_FOR_LOOP_ for loops)
322  NumeredDofEntity_multiIndex::iterator getNumeredDofsColsBegin() const {
323  return numeredDofsCols->begin();
324  }
325 
326  /// get end iterator for numeredDofsCols (insted you can use
327  /// #_IT_NUMEREDDOFMOFEMENTITY_COL_FOR_LOOP_ for loops)
328  NumeredDofEntity_multiIndex::iterator getNumeredDofsColsEnd() const {
329  return numeredDofsCols->end();
330  }
331 
332 /**
333  * \brief use with loops to iterate row DOFs
334  * \ingroup problems_multi_indices
335  *
336  * \code
337  * for(_IT_NUMEREDDOF_ROW_BY_LOCIDX_FOR_LOOP_(PROBLEMPTR,IT)) {
338  * ...
339  * }
340  * \endcode
341  *
342  */
343 #define _IT_NUMEREDDOF_ROW_BY_LOCIDX_FOR_LOOP_(PROBLEMPTR, IT) \
344  NumeredDofEntityByLocalIdx::iterator IT = \
345  PROBLEMPTR->getNumeredDofsRowsByLocIdxBegin(0); \
346  IT != PROBLEMPTR->getNumeredDofsRowsByLocIdxEnd( \
347  PROBLEMPTR->getNbLocalDofsRow() - 1); \
348  IT++
349 
350 /**
351  * \brief use with loops to iterate col DOFs
352  *
353  * \code
354  * for(_IT_NUMEREDDOF_COL_BY_LOCIDX_FOR_LOOP_(PROBLEMPTR,IT)) {
355  * ...
356  * }
357  * \endcode
358  *
359  */
360 #define _IT_NUMEREDDOF_COL_BY_LOCIDX_FOR_LOOP_(PROBLEMPTR, IT) \
361  NumeredDofEntityByUId::iterator IT = \
362  PROBLEMPTR->getNumeredDofsColsByLocIdxBegin(0); \
363  IT != PROBLEMPTR->getNumeredDofsColsByLocIdxEnd( \
364  PROBLEMPTR->getNbLocalDofsRow() - 1); \
365  IT++
366 
367  /// get begin iterator for numeredDofsRows (insted you can use
368  /// #_IT_NUMEREDDOF_ROW_FOR_LOOP_ for loops)
369  NumeredDofEntityByLocalIdx::iterator
371  return numeredDofsRows->get<PetscLocalIdx_mi_tag>().lower_bound(locidx);
372  }
373 
374  /// get end iterator for numeredDofsRows (insted you can use
375  /// #_IT_NUMEREDDOF_ROW_FOR_LOOP_ for loops)
376  NumeredDofEntityByLocalIdx::iterator
377  getNumeredDofsRowsByLocIdxEnd(const DofIdx locidx) const {
378  return numeredDofsRows->get<PetscLocalIdx_mi_tag>().upper_bound(locidx);
379  }
380 
381  /// get begin iterator for numeredDofsCols (insted you can use
382  /// #_IT_NUMEREDDOF_COL_FOR_LOOP_ for loops)
383  NumeredDofEntityByLocalIdx::iterator
385  return numeredDofsCols->get<PetscLocalIdx_mi_tag>().lower_bound(locidx);
386  }
387 
388  /// get end iterator for numeredDofsCols (insted you can use
389  /// #_IT_NUMEREDDOF_COL_FOR_LOOP_ for loops)
390  NumeredDofEntityByLocalIdx::iterator
391  getNumeredDofsColsByLocIdxEnd(const DofIdx locidx) const {
392  return numeredDofsCols->get<PetscLocalIdx_mi_tag>().upper_bound(locidx);
393  }
394 
395 /**
396  * \brief use with loops to iterate row DOFs
397  * \ingroup problems_multi_indices
398  *
399  * \code
400  * for(_IT_NUMEREDDOF_BY_ENT_ROW_FOR_LOOP_(PROBLEMPTR,ENT,IT)) {
401  * ...
402  * }
403  * \endcode
404  *
405  */
406 #define _IT_NUMEREDDOF_ROW_BY_ENT_FOR_LOOP_(PROBLEMPTR, ENT, IT) \
407  NumeredDofEntityByEnt::iterator IT = \
408  PROBLEMPTR->getNumeredDofsRowsByEntBegin(ENT); \
409  IT != PROBLEMPTR->getNumeredDofsRowsByEntEnd(ENT); \
410  IT++
411 
412 /**
413  * \brief use with loops to iterate col DOFs
414  * \ingroup problems_multi_indices
415  *
416  * \code
417  * for(_IT_NUMEREDDOF_COL_BY_ENT_FOR_LOOP_(PROBLEMPTR,ENT,IT)) {
418  * ...
419  * }
420  * \endcode
421  *
422  */
423 #define _IT_NUMEREDDOF_COL_BY_ENT_FOR_LOOP_(PROBLEMPTR, ENT, IT) \
424  NumeredDofEntityByEnt::iterator IT = \
425  PROBLEMPTR->getNumeredDofsColsByEntBegin(ENT); \
426  IT != PROBLEMPTR->getNumeredDofsColsByEntEnd(ENT); \
427  IT++
428 
429  /// get begin iterator for numeredDofsRows (insted you can use
430  /// #_IT_NUMEREDDOF_ROW_BY_ENT_FOR_LOOP_ for loops)
431  NumeredDofEntityByEnt::iterator
433  return numeredDofsRows->get<Ent_mi_tag>().lower_bound(ent);
434  }
435 
436  /// get end iterator for numeredDofsRows (insted you can use
437  /// #_IT_NUMEREDDOF_ROW_BY_ENT_FOR_LOOP_ for loops)
438  NumeredDofEntityByEnt::iterator
440  return numeredDofsRows->get<Ent_mi_tag>().upper_bound(ent);
441  }
442 
443  /// get begin iterator for numeredDofsCols (insted you can use
444  /// #_IT_NUMEREDDOF_COL_BY_ENT_FOR_LOOP_ for loops)
445  NumeredDofEntityByEnt::iterator
447  return numeredDofsCols->get<Ent_mi_tag>().lower_bound(ent);
448  }
449 
450  /// get end iterator for numeredDofsCols (insted you can use
451  /// #_IT_NUMEREDDOF_COL_BY_ENT_FOR_LOOP_ for loops)
452  NumeredDofEntityByEnt::iterator
454  return numeredDofsCols->get<Ent_mi_tag>().upper_bound(ent);
455  }
456 
457 /**
458  * use with loops to iterate row DOFs
459  * \ingroup problems_multi_indices
460  *
461  * \code
462  * for(_IT_NUMEREDDOF_BY_NAME_ROW_FOR_LOOP_(PROBLEMPTR,NAME,IT)) {
463  * ...
464  * }
465  * \endcode
466  *
467  */
468 #define _IT_NUMEREDDOF_ROW_BY_NAME_FOR_LOOP_(PROBLEMPTR, NAME, IT) \
469  NumeredDofEntityByFieldName::iterator IT = \
470  PROBLEMPTR->getNumeredDofsRowsBegin(NAME); \
471  IT != PROBLEMPTR->getNumeredDofsRowsEnd(NAME); \
472  IT++
473 
474 /**
475  * \brief use with loops to iterate col DOFs
476  * \ingroup problems_multi_indices
477  *
478  * \code
479  * for(_IT_NUMEREDDOF_COL_BY_NAME_FOR_LOOP_(PROBLEMPTR,NAME,IT)) {
480  * ...
481  * }
482  * \endcode
483  *
484  */
485 #define _IT_NUMEREDDOF_COL_BY_NAME_FOR_LOOP_(PROBLEMPTR, NAME, IT) \
486  NumeredDofEntityByFieldName::iterator IT = \
487  PROBLEMPTR->getNumeredDofsColsBegin(NAME); \
488  IT != PROBLEMPTR->getNumeredDofsColsEnd(NAME); \
489  IT++
490 
491  /// get begin iterator for numeredDofsRows (insted you can use
492  /// #_IT_NUMEREDDOF_ROW_BY_NAME_FOR_LOOP_ for loops)
493  NumeredDofEntityByFieldName::iterator
494  getNumeredDofsRowsBegin(const std::string &name) const {
495  return numeredDofsRows->get<FieldName_mi_tag>().lower_bound(name);
496  }
497 
498  /// get end iterator for numeredDofsRows (insted you can use
499  /// #_IT_NUMEREDDOF_ROW_BY_NAME_FOR_LOOP_ for loops)
500  NumeredDofEntityByFieldName::iterator
501  getNumeredDofsRowsEnd(const std::string &name) const {
502  return numeredDofsRows->get<FieldName_mi_tag>().upper_bound(name);
503  }
504 
505  /// get begin iterator for numeredDofsCols (insted you can use
506  /// #_IT_NUMEREDDOF_COL_BY_NAME_FOR_LOOP_ for loops)
507  NumeredDofEntityByFieldName::iterator
508  getNumeredDofsColsBegin(const std::string &name) const {
509  return numeredDofsCols->get<FieldName_mi_tag>().lower_bound(name);
510  }
511 
512  /// get end iterator for numeredDofsCols (insted you can use
513  /// #_IT_NUMEREDDOF_COL_BY_NAME_FOR_LOOP_ for loops)
514  NumeredDofEntityByFieldName::iterator
515  getNumeredDofsColsEnd(const std::string &name) const {
516  return numeredDofsCols->get<FieldName_mi_tag>().upper_bound(name);
517  }
518 
519 /**
520  * \brief use with loops to iterate row DOFs
521  * \ingroup problems_multi_indices
522  *
523  * \code
524  * for(_IT_NUMEREDDOF_ROW_BY_NAME_ENT_PART_FOR_LOOP_(PROBLEMPTR,NAME,ENT,PART,IT))
525  * {
526  * ...
527  * }
528  * \endcode
529  *
530  */
531 #define _IT_NUMEREDDOF_ROW_BY_NAME_ENT_PART_FOR_LOOP_(PROBLEMPTR, NAME, ENT, \
532  PART, IT) \
533  NumeredDofEntityByNameEntAndPart::iterator IT = \
534  PROBLEMPTR->getNumeredDofsRowsBegin(NAME, ENT, PART); \
535  IT != PROBLEMPTR->getNumeredDofsRowsEnd(NAME, ENT, PART); \
536  IT++
537 
538 /**
539  * use with loops to iterate col DOFs
540  * \ingroup problems_multi_indices
541  *
542  * \code
543  * for(_IT_NUMEREDDOF_COL_BY_NAME_ENT_PART_FOR_LOOP_(PROBLEMPTR,NAME,ENT,PART,IT))
544  * {
545  * ...
546  * }
547  * \endcode
548  *
549  */
550 #define _IT_NUMEREDDOF_COL_BY_NAME_ENT_PART_FOR_LOOP_(PROBLEMPTR, NAME, ENT, \
551  PART, IT) \
552  NumeredDofEntityByNameEntAndPart::iterator IT = \
553  PROBLEMPTR->getNumeredDofsColsBegin(NAME, ENT, PART); \
554  IT != PROBLEMPTR->getNumeredDofsColsEnd(NAME, ENT, PART); \
555  IT++
556 
557  /// get begin iterator for numeredDofsRows (insted you can use
558  /// #_IT_NUMEREDDOF_ROW_BY_NAME_ENT_PART_FOR_LOOP_ for loops)
559  NumeredDofEntityByNameEntAndPart::iterator
560  getNumeredDofsRowsBegin(const std::string &name, const EntityHandle ent,
561  const int part) const {
563  .lower_bound(boost::make_tuple(name, ent, part));
564  }
565 
566  /// get end iterator for numeredDofsRows (insted you can use
567  /// #_IT_NUMEREDDOF_ROW_BY_NAME_ENT_PART_FOR_LOOP_ for loops)
568  NumeredDofEntityByNameEntAndPart::iterator
569  getNumeredDofsRowsEnd(const std::string &name, const EntityHandle ent,
570  const int part) const {
572  .upper_bound(boost::make_tuple(name, ent, part));
573  }
574 
575  /// get begin iterator for numeredDofsCols (insted you can use
576  /// #_IT_NUMEREDDOF_COL_BY_NAME_ENT_PART_FOR_LOOP_ for loops)
577  NumeredDofEntityByNameEntAndPart::iterator
578  getNumeredDofsColsBegin(const std::string &name, const EntityHandle ent,
579  const int part) const {
581  .lower_bound(boost::make_tuple(name, ent, part));
582  }
583 
584  /// get end iterator for numeredDofsCols (insted you can use
585  /// #_IT_NUMEREDDOF_COL_BY_NAME_ENT_PART_FOR_LOOP_ for loops)
586  NumeredDofEntityByNameEntAndPart::iterator
587  getNumeredDofsColsEnd(const std::string &name, const EntityHandle ent,
588  const int part) const {
590  .upper_bound(boost::make_tuple(name, ent, part));
591  }
592 
593 /**
594  * \brief Loop over problem DOFs in row by part
595  * @param PROBLEMPTR problem pointer
596  * @param PART partition number
597  * @param IT iterator
598  * @return error code
599  * \ingroup problems_multi_indices
600  *
601  * \code
602  * for(_IT_NUMEREDDOF_ROW_BY_OWNPROC_FOR_LOOP_(PART,IT)) {
603  * ...
604  * }
605  * \endcode
606  */
607 #define _IT_NUMEREDDOF_ROW_BY_OWNPROC_FOR_LOOP_(PROBLEMPTR, PART, IT) \
608  NumeredDofEntity_multiIndex::iterator IT = \
609  PROBLEMPTR->getNumeredDofsRowsBegin(PART); \
610  IT != PROBLEMPTR->getNumeredDofsRowsEnd(PART); \
611  IT++
612 
613  /// get begin iterator for numeredDofsRows (insted you can use
614  /// #_IT_NUMEREDDOF_ROW_BY_OWNPROC_FOR_LOOP_ for loops)
615  NumeredDofEntity_multiIndex::iterator
616  getNumeredDofsRowsBegin(const int part) const {
617  return numeredDofsRows->get<Unique_mi_tag>().lower_bound(
619  }
620 
621  /// get end iterator for numeredDofsRows (insted you can use
622  /// #_IT_NUMEREDDOF_ROW_BY_OWNPROC_FOR_LOOP_ for loops)
623  NumeredDofEntity_multiIndex::iterator
624  getNumeredDofsRowsEnd(const int part) const {
625  return numeredDofsRows->get<Unique_mi_tag>().upper_bound(
627  }
628 
629 /**
630  * \brief Loop over problem DOFs in col by part
631  * @param PROBLEMPTR problem pointer
632  * @param PART partition number
633  * @param IT iterator
634  * @return error code
635  * \ingroup problems_multi_indices
636  *
637  * \code
638  * for(_IT_NUMEREDDOF_COL_BY_PART_FOR_LOOP_(PART,IT)) {
639  * ...
640  * }
641  * \endcode
642  *
643  */
644 #define _IT_NUMEREDDOF_COL_BY_PART_FOR_LOOP_(PROBLEMPTR, PART, IT) \
645  NumeredDofEntity_multiIndex::iterator IT = \
646  PROBLEMPTR->getNumeredDofsColsBegin(PART); \
647  IT != PROBLEMPTR->getNumeredDofsColsEnd(PART); \
648  IT++
649 
650  /// get begin iterator for numeredDofsRows (insted you can use
651  /// #_IT_NUMEREDDOF_COL_BY_PART_FOR_LOOP_ for loops)
652  NumeredDofEntity_multiIndex::iterator
653  getNumeredDofsColsBegin(const int part) const {
654  return numeredDofsRows->get<Unique_mi_tag>().lower_bound(
656  }
657 
658  /// get end iterator for numeredDofsRows (insted you can use
659  /// #_IT_NUMEREDDOF_COL_BY_PART_FOR_LOOP_ for loops)
660  NumeredDofEntity_multiIndex::iterator
661  getNumeredDofsColsEnd(const int part) const {
662  return numeredDofsRows->get<Unique_mi_tag>().upper_bound(
664  }
665 
666  Problem(Interface &moab, const EntityHandle meshset);
667 
668  virtual ~Problem();
669 
670  inline BitProblemId getId() const { return *((BitProblemId *)tagId); }
671 
672  inline std::string getName() const {
673  return std::string((char *)tagName, tagNameSize);
674  }
675 
676  inline DofIdx getNbDofsRow() const { return nbDofsRow; }
677  inline DofIdx getNbDofsCol() const { return nbDofsCol; }
678  inline DofIdx getNbLocalDofsRow() const { return nbLocDofsRow; }
679  inline DofIdx getNbLocalDofsCol() const { return nbLocDofsCol; }
680  inline DofIdx getNbGhostDofsRow() const { return nbGhostDofsRow; }
681  inline DofIdx getNbGhostDofsCol() const { return nbGhostDofsCol; }
682 
683  inline BitRefLevel getBitRefLevel() const { return *tagBitRefLevel; }
685 
688  const NumeredDofEntity **dof_ptr) const;
691  const NumeredDofEntity **dof_ptr) const;
692 
693  BitFEId getBitFEId() const;
694 
695  friend std::ostream &operator<<(std::ostream &os, const Problem &e);
696 
697  /**
698  * \brief Get number of finite elements by name on processors
699  *
700  * Size retuned IS is equal to size of processors.
701  *
702  * What PetscLayout see,
703  <http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/IS/index.html>
704  *
705  * Example of usage for layout
706  * \code
707 
708  PetscInt rstart, rend;
709  ierr = PetscLayoutGetRange(layout, &rstart, &rend); CHKERRG(ierr);
710  int global_size;
711  ierr = PetscLayoutGetSize(layout,&global_size); CHKERRG(ierr);
712 
713  \endcode
714  *
715  * @param comm Communicator
716  * @param name Finite element name
717  * @param layout Get number of elements on each processor
718  * @return error code
719  */
721  const std::string name,
722  PetscLayout *layout) const;
723 
724  /**
725  * \brief Get number of finite elements on processors
726  *
727  * Size retuned IS is equal to size of processors.
728  *
729  * What PetscLayout see,
730  <http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/IS/index.html>
731  *
732  * Example of usage for layout
733  * \code
734 
735  PetscInt rstart, rend;
736  ierr = PetscLayoutGetRange(layout, &rstart, &rend); CHKERRG(ierr);
737  int global_size;
738  ierr = PetscLayoutGetSize(layout,&global_size); CHKERRG(ierr);
739 
740  \endcode
741  *
742  * @param comm Communicator
743  * @param layout Get number of elements on each processor
744  * @return error code
745  */
747  PetscLayout *layout) const;
748 
749  typedef multi_index_container<boost::weak_ptr<std::vector<NumeredDofEntity> >,
750  indexed_by<sequenced<> > >
752 
753  /**
754  * \brief Get reference to sequence data numbered dof container
755  *
756  * In sequence data container data are physically stored. The purpose of this
757  * is to allocate NumeredDofEntity data in bulk, having only one allocation
758  instead
759  * each time entity is inserted. That makes code efficient.
760  *
761  * The vector in sequence is destroyed if last entity inside that vector is
762  * destroyed. All MoFEM::NumeredDofEntity have aliased shared_ptr which points
763  to the vector.
764 
765  * @return MoFEM::Problem::SequenceDofContainer
766  */
767  inline boost::shared_ptr<SequenceDofContainer> &getRowDofsSequence() const {
769  }
770 
771  /**
772  * \brief Get reference to sequence data numbered dof container
773  *
774  * In sequence data container data are physically stored. The purpose of this
775  * is to allocate NumeredDofEntity data in bulk, having only one allocation
776  instead
777  * each time entity is inserted. That makes code efficient.
778  *
779  * The vector in sequence is destroyed if last entity inside that vector is
780  * destroyed. All MoFEM::NumeredDofEntity have aliased shared_ptr which points
781  to the vector.
782 
783  * @return MoFEM::Problem::SequenceDofContainer
784  */
785  inline boost::shared_ptr<SequenceDofContainer> &getColDofsSequence() const {
787  }
788 
789 private:
790  // Keep vector of DoFS on entity
791  mutable boost::shared_ptr<SequenceDofContainer> sequenceRowDofContainer;
792  mutable boost::shared_ptr<SequenceDofContainer> sequenceColDofContainer;
793 };
794 
795 /// \deprecated use just Problem
797 
798 /**
799  * @relates multi_index_container
800  * \brief MultiIndex for entities for Problem
801  * \ingroup fe_multi_indices
802  */
803 typedef multi_index_container<
804  Problem,
805  indexed_by<
806  ordered_unique<tag<Meshset_mi_tag>,
807  member<Problem, EntityHandle, &Problem::meshset> >,
808  hashed_unique<tag<BitProblemId_mi_tag>,
809  const_mem_fun<Problem, BitProblemId, &Problem::getId>,
811  hashed_unique<
812  tag<Problem_mi_tag>,
813  const_mem_fun<Problem, std::string, &Problem::getName> > > >
815 
816 /** \brief add ref level to problem
817  * \ingroup problems_multi_indices
818  */
822  void operator()(Problem &p) { *(p.tagBitRefLevel) |= bit; };
823 };
824 
825 /** \brief set ref level to problem
826  * \ingroup problems_multi_indices
827  */
831  void operator()(Problem &p) { *(p.tagBitRefLevel) = bit; };
832 };
833 
834 /** \brief set prof dof bit ref mask
835  * \ingroup problems_multi_indices
836  */
840  void operator()(Problem &p) { *(p.tagMaskBitRefLevel) = bit; };
841 };
842 
843 /** \brief add finite element to problem
844  * \ingroup problems_multi_indices
845  */
849  void operator()(Problem &p);
850 };
851 
852 /** \brief set prof dof bit ref mask
853  * \ingroup problems_multi_indices
854  */
858  void operator()(Problem &p) { *(p.tagMaskBitRefLevel) |= bit; };
859 };
860 
861 /** \brief remove finite element from problem
862  * \ingroup problems_multi_indices
863  */
867  void operator()(Problem &p);
868 };
869 
870 /** \brief zero nb. of DOFs in row
871  * \ingroup problems_multi_indices
872  */
874  void operator()(Problem &e);
875 };
876 
877 /** \brief zero nb. of DOFs in col
878  * \ingroup problems_multi_indices
879  */
881  void operator()(Problem &e);
882 };
883 
884 /** \brief clear problem finite elements
885  * \ingroup problems_multi_indices
886  */
888  void operator()(Problem &e);
889 };
890 
891 /**
892  * \brief Clear sub-problem data structure
893  */
895  void operator()(Problem &e) { e.subProblemData.reset(); }
896 };
897 
898 /**
899  * \brief Clear composed problem data structure
900  */
902  void operator()(Problem &e) { e.composedProblemsData.reset(); }
903 };
904 
905 } // namespace MoFEM
906 
907 #endif //__PROBLEMSMULTIINDICES_HPP__
908 
909 /**
910  * \defgroup problems_multi_indices Problems structures and multi-indices
911  * \ingroup mofem
912  ******************************************************************************/
NumeredDofEntityByFieldName::iterator getNumeredDofsColsBegin(const std::string &name) const
const boost::shared_ptr< NumeredEntFiniteElement_multiIndex > & getNumeredFiniteElements() const
get access to reference for multi-index storing finite elements
Clear sub-problem data structure.
DofIdx getNbDofsRow() const
ProblemChangeRefLevelBitSet(const BitRefLevel _bit)
Problem(Interface &moab, const EntityHandle meshset)
NumeredDofEntityByLocalIdx::iterator getNumeredDofsRowsByLocIdxEnd(const DofIdx locidx) const
BitFEId getBitFEId() const
ProblemChangeRefLevelBitDofMaskSet(const BitRefLevel _bit)
DofIdx nbLocDofsCol
Local number of DOFs in colIs.
DofIdx getNbGhostDofsCol() const
boost::shared_ptr< SubProblemData > & getSubData() const
Get main problem of sub-problem is.
MoFEMErrorCode getRowIs(IS *is, const unsigned int pp) const
NumeredDofEntity_multiIndex::iterator getNumeredDofsRowsBegin() const
std::vector< const Problem * > rowProblemsAdd
MoFEMErrorCode getRowDofsByPetscGlobalDofIdx(DofIdx idx, const NumeredDofEntity **dof_ptr) const
int tagNameSize
Size of problem name.
DofIdx nbDofsCol
Global number of DOFs in col.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:501
IS rowIs
indices of main problem of which sub problem is this
boost::shared_ptr< SubProblemData > subProblemData
DofIdx nbGhostDofsCol
Number of ghost DOFs in col.
BitProblemId * tagId
Unique problem ID.
NumeredDofEntityByFieldName::iterator getNumeredDofsRowsBegin(const std::string &name) const
AO rowMap
mapping form main problem indices to sub-problem indices
MoFEMErrorCode getColDofsByPetscGlobalDofIdx(DofIdx idx, const NumeredDofEntity **dof_ptr) const
NumeredDofEntity_multiIndex::iterator getNumeredDofsRowsEnd() const
DofIdx getNbLocalDofsRow() const
IS colIs
indices of main problem of which sub problem is this
NumeredDofEntity_multiIndex::iterator getNumeredDofsRowsEnd(const int part) const
static UId getGlobalUniqueIdCalculate_Hi_Proc(const int owner_proc)
std::bitset< BITPROBLEMID_SIZE > BitProblemId
Problem Id.
Definition: Types.hpp:55
const char * tagName
Problem name.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:508
keeps basic data about problemThis is low level structure with information about problem,...
DofIdx getNbGhostDofsRow() const
NumeredDofEntity_multiIndex::iterator getNumeredDofsColsEnd(const int part) const
RowColData
RowColData.
Definition: definitions.h:186
BitFEId * tagBitFEId
IDs of finite elements in problem.
NumeredDofEntity_multiIndex::iterator getNumeredDofsColsBegin(const int part) const
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:21
const boost::shared_ptr< NumeredDofEntity_multiIndex > & getNumeredDofsCols() const
get access to numeredDofsCols storing DOFs on cols
NumeredDofEntityByLocalIdx::iterator getNumeredDofsColsByLocIdxEnd(const DofIdx locidx) const
NumeredDofEntityByLocalIdx::iterator getNumeredDofsRowsByLocIdxBegin(const DofIdx locidx) const
MoFEMErrorCode getDofByNameEntAndEntDofIdx(const string name, const EntityHandle ent, const int ent_dof_idx, const RowColData row_or_col, boost::shared_ptr< NumeredDofEntity > &dof_ptr) const
get DOFs from problem
NumeredDofEntityByEnt::iterator getNumeredDofsColsByEntEnd(const EntityHandle ent) const
DofIdx nbGhostDofsRow
Number of ghost DOFs in row.
std::bitset< BITFEID_SIZE > BitFEId
Finite element Id.
Definition: Types.hpp:54
DofIdx nbLocDofsRow
Local number of DOFs in row.
boost::shared_ptr< ComposedProblemsData > composedProblemsData
NumeredDofEntityByFieldName::iterator getNumeredDofsRowsEnd(const std::string &name) const
remove finite element from problem
BitRefLevel * tagMaskBitRefLevel
BItRefMask of elements in problem.
BitRefLevel * tagBitRefLevel
BitRef level of finite elements in problem.
NumeredDofEntityByFieldName::iterator getNumeredDofsColsEnd(const std::string &name) const
std::vector< const Problem * > colProblemsAdd
MoFEMErrorCode getNumberOfElementsByPart(MPI_Comm comm, PetscLayout *layout) const
Get number of finite elements on processors.
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:66
boost::shared_ptr< SequenceDofContainer > & getColDofsSequence() const
Get reference to sequence data numbered dof container.
NumeredDofEntity_multiIndex::iterator getNumeredDofsColsEnd() const
boost::shared_ptr< NumeredDofEntity_multiIndex > numeredDofsRows
store DOFs on rows for this problem
NumeredDofEntityByEnt::iterator getNumeredDofsRowsByEntEnd(const EntityHandle ent) const
friend std::ostream & operator<<(std::ostream &os, const Problem &e)
MoFEMErrorCode getColIs(IS *is, const unsigned int pp) const
multi_index_container< Problem, indexed_by< ordered_unique< tag< Meshset_mi_tag >, member< Problem, EntityHandle, &Problem::meshset > >, hashed_unique< tag< BitProblemId_mi_tag >, const_mem_fun< Problem, BitProblemId, &Problem::getId >, HashBit< BitProblemId >, EqBit< BitProblemId > >, hashed_unique< tag< Problem_mi_tag >, const_mem_fun< Problem, std::string, &Problem::getName > > > > Problem_multiIndex
MultiIndex for entities for Problem.
NumeredDofEntityByLocalIdx::iterator getNumeredDofsColsByLocIdxBegin(const DofIdx locidx) const
DofIdx nbDofsRow
Global number of DOFs in row.
NumeredDofEntity_multiIndex::iterator getNumeredDofsRowsBegin(const int part) const
BitRefLevel getMaskBitRefLevel() const
NumeredEntFiniteElementbyName::iterator getNumeredFEsBegin(std::string fe_name) const
boost::shared_ptr< SequenceDofContainer > sequenceColDofContainer
NumeredDofEntityByNameEntAndPart::iterator getNumeredDofsColsBegin(const std::string &name, const EntityHandle ent, const int part) const
DofIdx getNbDofsCol() const
ProblemChangeRefLevelBitDofMaskAdd(const BitRefLevel _bit)
BitRefLevel getBitRefLevel() const
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
Definition: Types.hpp:51
#define DEPRECATED
Definition: definitions.h:29
MultiIndex Tag for field name.
NumeredDofEntityByNameEntAndPart::iterator getNumeredDofsRowsEnd(const std::string &name, const EntityHandle ent, const int part) const
boost::shared_ptr< SequenceDofContainer > sequenceRowDofContainer
boost::shared_ptr< SequenceDofContainer > & getRowDofsSequence() const
Get reference to sequence data numbered dof container.
NumeredDofEntityByEnt::iterator getNumeredDofsRowsByEntBegin(const EntityHandle ent) const
NumeredEntFiniteElementbyName::iterator getNumeredFEsEnd(std::string fe_name) const
NumeredDofEntityByEnt::iterator getNumeredDofsColsByEntBegin(const EntityHandle ent) const
keeps information about indexed dofs for the problemFIXME: Is too many iterator, this has to be manag...
NumeredDofEntityByNameEntAndPart::iterator getNumeredDofsColsEnd(const std::string &name, const EntityHandle ent, const int part) const
ProblemChangeRefLevelBitAdd(const BitRefLevel _bit)
boost::shared_ptr< ComposedProblemsData > & getComposedProblemsData() const
Het composed problems data structure.
std::string getName() const
Clear composed problem data structure.
boost::shared_ptr< NumeredEntFiniteElement_multiIndex > numeredFiniteElements
store finite elements
DEPRECATED typedef Problem MoFEMProblem
NumeredDofEntity_multiIndex::iterator getNumeredDofsColsBegin() const
DofIdx getNbLocalDofsCol() const
MoFEMErrorCode getNumberOfElementsByNameAndPart(MPI_Comm comm, const std::string name, PetscLayout *layout) const
Get number of finite elements by name on processors.
boost::shared_ptr< NumeredDofEntity_multiIndex > numeredDofsCols
store DOFs on columns for this problem
NumeredDofEntityByNameEntAndPart::iterator getNumeredDofsRowsBegin(const std::string &name, const EntityHandle ent, const int part) const
multi_index_container< boost::weak_ptr< std::vector< NumeredDofEntity > >, indexed_by< sequenced<> > > SequenceDofContainer
const boost::shared_ptr< NumeredDofEntity_multiIndex > & getNumeredDofsRows() const
get access to numeredDofsRows storing DOFs on rows
static UId getGlobalUniqueIdCalculate_Low_Proc(const int owner_proc)
BitProblemId getId() const