v0.8.14
FieldMultiIndices.hpp
Go to the documentation of this file.
1 /** \file FieldMultiIndices.hpp
2  * \brief Field data structure storing information about space, approximation
3  * base, coordinate systems, etc.
4  *
5  * Also, it stores data needed for book keeping, like tags to data on the
6  * mesh.
7  *
8  * Each filed has unique ID and name. This data structure is shared between
9  * entities on which is spanning and DOFs on those entities.
10  */
11 
12 /*
13  * MoFEM is free software: you can redistribute it and/or modify it under
14  * the terms of the GNU Lesser General Public License as published by the
15  * Free Software Foundation, either version 3 of the License, or (at your
16  * option) any later version.
17  *
18  * MoFEM is distributed in the hope that it will be useful, but WITHOUT
19  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
21  * License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public
24  * License along with MoFEM. If not, see <http://www.gnu.org/licenses/>
25  */
26 
27 #ifndef __FIELDMULTIINDICES_HPP__
28 #define __FIELDMULTIINDICES_HPP__
29 
30 namespace MoFEM {
31 
32 /** \brief user adjacency function
33  * \ingroup fe_multi_indices
34  */
35 typedef boost::function<int(const int order)> FieldOrderFunct;
36 
37 /** \brief user adjacency function table
38  * \ingroup dof_multi_indices
39  */
40 typedef FieldOrderFunct FieldOrderTable[MBMAXTYPE];
41 
42 struct FieldEntity;
43 struct DofEntity;
44 
45 /**
46  * \brief Provide data structure for (tensor) field approximation.
47  * \ingroup dof_multi_indices
48  *
49  * The Field is intended to provide support for fields, with a strong bias
50  * towards supporting first and best the capabilities required for scientific
51  * computing applications. Since we work with discrete spaces, data structure
52  * has to carry information about type of approximation space, its regularity.
53  *
54  *
55  * Field data structure storing information about space, approximation base,
56  * coordinate systems, etc. It stores additional data needed for book keeping,
57  * like tags to data on the mesh.
58  *
59  * Each filed has unique ID and name. This
60  * data structure is shared between entities on which is spanning and DOFs on
61  * those entities.
62  *
63  */
64 struct Field {
65 
66  typedef multi_index_container<boost::weak_ptr<std::vector<FieldEntity>>,
67  indexed_by<sequenced<>>>
69 
70  typedef multi_index_container<boost::weak_ptr<std::vector<DofEntity>>,
71  indexed_by<sequenced<>>>
73 
74  moab::Interface &moab;
75 
76  EntityHandle meshSet; ///< keeps entities for this meshset
77  boost::shared_ptr<CoordSys>
78  coordSysPtr; ///< Pointer to field coordinate system data structure
79 
80  Tag th_FieldData; ///< Tag storing field values on entity in the field
81  Tag th_AppOrder; ///< Tag storing approximation order on entity
82 
83  BitFieldId *tagId; ///< tag keeps field id
84  FieldSpace *tagSpaceData; ///< tag keeps field space
85  FieldApproximationBase *tagBaseData; ///< tag keeps field base
86 
87  /// tag keeps field rank (dimension, f.e. Temperature field has rank 1,
88  /// displacements field in 3d has rank 3)
90  const void *tagName; ///< tag keeps name of the field
91  int tagNameSize; ///< number of bits necessary to keep field name
92  const void *tagNamePrefixData; ///< tag keeps name prefix of the field
93  int tagNamePrefixSize; ///< number of bits necessary to keep field name
94  ///< prefix
95  FieldOrderTable forderTable; ///< nb. DOFs table for entities
96 
97  /**
98  * @brief Get the Field Order Table
99  *
100  * @return FieldOrderTable&
101  */
103 
104  /**
105  * Field Id is bit set. Each field has only one bit on, bitNumber stores
106  * number of set bit
107  */
108  unsigned int bitNumber;
109 
110  /**
111  * \brief constructor for moab field
112  *
113  * \param meshset which keeps entities for this field
114  */
115  Field(const Interface &moab, const EntityHandle meshset,
116  const boost::shared_ptr<CoordSys> coord_sys_ptr);
117 
118  /**
119  * \brief Get field meshset
120  *
121 
122  * To meshsets entity are attached Tags which keeps basic information about
123  * field. Those information is field name, approximation base, approximation
124  * space, id, etc.
125 
126  * In meshset contains entities on which given filed is sparing. Type of
127  entities
128  * depended on approximations space.
129 
130  * @return EntityHandle
131  */
132  inline EntityHandle getMeshset() const { return meshSet; }
133 
134  /**
135  * \brief Get dimension of general two-point tensor \ref
136  MoFEM::CoordSys::getDim
137 
138  See details here \ref MoFEM::CoordSys::getDim
139 
140  */
141  inline int getCoordSysDim(const int d = 0) const {
142  return coordSysPtr->getDim(d);
143  }
144 
145  /**
146  * \brief Get reference base vectors
147  * @param Array where coefficients (covariant) are returned
148  * @return Error code
149  */
150  inline MoFEMErrorCode get_E_Base(const double m[]) const {
152  MoFEMFunctionReturnHot(coordSysPtr->get_E_Base(m));
153  }
154 
155  /**
156  * \brief Get reference dual base vectors
157  * @param Array where coefficients (contravariant) are returned
158  * @return Error code
159  */
160  inline MoFEMErrorCode get_E_DualBase(const double m[]) const {
162  MoFEMFunctionReturnHot(coordSysPtr->get_E_DualBase(m));
163  }
164 
165  /**
166  * \brief Get current dual base vectors
167  * @param Array where coefficients (covariant) are returned
168  * @return Error code
169  */
170  inline MoFEMErrorCode get_e_Base(const double m[]) const {
172  MoFEMFunctionReturnHot(coordSysPtr->get_e_Base(m));
173  }
174 
175  /**
176  * \brief Get current dual base vectors
177  * @param Array where coefficients (covariant) are returned
178  * @return Error code
179  */
180  inline MoFEMErrorCode get_e_DualBase(const double m[]) const {
182  MoFEMFunctionReturnHot(coordSysPtr->get_e_DualBase(m));
183  }
184 
185  /**
186  * \brief Returns meshset on which Tags defining coordinate system are stored
187  * @return Coordinate system EntityHandle
188  */
190  return coordSysPtr->getMeshset();
191  }
192 
193  /**
194  * \brief Get coordinate system name
195  * @return Coordinate system name
196  */
197  inline std::string getCoordSysName() const { return coordSysPtr->getName(); }
198 
199  /**
200  * \brief Get coordinate system name
201  * @return Return string_ref with name.
202  */
203  inline boost::string_ref getCoordSysNameRef() const {
204  return coordSysPtr->getNameRef();
205  }
206 
207  /**
208  * \brief Get unique field id.
209  * @return Filed ID
210  */
211  inline const BitFieldId &getId() const { return *((BitFieldId *)tagId); }
212 
213  /**
214  * \brief Get string reference to field name
215  * @return Field name
216  */
217  inline boost::string_ref getNameRef() const {
218  return boost::string_ref((char *)tagName, tagNameSize);
219  }
220 
221  /**
222  * \brief Get field name
223  * @return Field name
224  */
225  inline std::string getName() const {
226  return std::string((char *)tagName, tagNameSize);
227  }
228 
229  /**
230  * \brief Get field approximation space
231  * @return approximation space
232  */
233  inline FieldSpace getSpace() const { return *tagSpaceData; }
234 
235  /**
236  * \brief Get approximation base
237  * @return Approximation base
238  */
240 
241  /** \brief Get number of field coefficients
242  *
243 
244  * Scalar field has only one coefficient, vector field in 3D has three. In
245  * general number determine space needed to keep data on entities. What
246  coefficient
247  * means depend on interpretation and associated coordinate system. For
248  example
249  * 3 coefficient means could be covariant or contravariant, or mean three
250  temperatures
251  * for mixture of solid, air and water, etc.
252 
253 
254  */
256  return *tagNbCoeffData;
257  };
258 
259  /**
260  * \brief Get number of set bit in Field ID.
261  * Each field has uid, get getBitNumber get number of bit set for given field.
262  * Field ID has only one bit set for each field.
263  */
264  inline unsigned int getBitNumber() const { return bitNumber; }
265 
266  /**
267  * \brief Calculate number of set bit in Field ID.
268  * Each field has uid, get getBitNumber get number of bit set for given field.
269  * Field ID has only one bit set for each field.
270  */
271  inline unsigned int getBitNumberCalculate() const {
272  int b = ffsl(((BitFieldId *)tagId)->to_ulong());
273  if (b != 0)
274  return b;
275  for (int ll = 1; ll < BITFIELDID_SIZE / 32; ll++) {
276  BitFieldId id;
277  id = (*tagId) >> ll * 32;
278  b = ll * 32 + ffsl(id.to_ulong());
279  if (b != 0)
280  return b;
281  }
282  return 0;
283  }
284 
285  friend std::ostream &operator<<(std::ostream &os, const Field &e);
286 
287  /**
288  * \brief Get reference to sequence data container
289  *
290  * In sequence data container data are physically stored. The purpose of this
291  * is to allocate MoFEMEntities data in bulk, having only one allocation
292  * instead each time entity is inserted. That makes code efficient.
293  *
294  * The vector in sequence is destroyed if last entity inside that vector is
295  * destroyed. All MoFEM::MoFEMEntities have aliased shared_ptr which points to
296  * the vector.
297  *
298  * @return MoFEM::Field::SequenceEntContainer
299  */
300  inline boost::shared_ptr<SequenceEntContainer> &
302  return sequenceEntContainer;
303  }
304 
305  /**
306  * \brief Get reference to sequence data container
307  *
308  * In sequence data container data are physically stored. The purpose of this
309  * is to allocate DofEntity data in bulk, having only one allocation instead
310  * each time entity is inserted. That makes code efficient.
311  *
312  * The vector in sequence is destroyed if last entity inside that vector is
313  * destroyed. All MoFEM::MoFEMEntities have aliased shared_ptr which points to
314  the vector.
315 
316  * Not all DOFs are starred in this way, currently such cases are considered;
317  * - DOFs on vertices. That is exploited that for H1 space, there is some
318  * fixed number of DOFs on each vertex
319 
320  * For other cases, DOFs are stored locally in each MoFEM::MoFEMEntities.
321 
322  * @return MoFEM::Field::SequenceDofContainer
323  */
324  inline boost::shared_ptr<SequenceDofContainer> &
326  return sequenceDofContainer;
327  }
328 
329  /**
330  * \brief get hash-map relating dof index on entity with its order
331  *
332  * Dofs of given field are indexed on entity
333  * of the same type, same space, approximation base and number of
334  * coefficients, are sorted in the way.
335  *
336  */
337  inline std::vector<ApproximationOrder> &
338  getDofOrderMap(const EntityType type) const {
339  return dofOrderMap[type];
340  }
341 
342 private:
343  mutable boost::shared_ptr<SequenceEntContainer> sequenceEntContainer;
344  mutable boost::shared_ptr<SequenceDofContainer> sequenceDofContainer;
345 
346  mutable std::map<EntityType, std::vector<int>> dofOrderMap;
347 };
348 
349 /**
350  * \brief Pointer interface for MoFEM::Field
351  *
352  * MoFEM::Field class is keeps data and methods. This class is interface to that
353  * class, and all other classes, like MoFEMEntities, DofEntity and derived form
354  * them inherits pointer interface, not MoFEM::Field class directly.
355  *
356  * \ingroup dof_multi_indices
357  */
358 template <typename T> struct interface_Field {
359 
360  mutable boost::shared_ptr<T> sFieldPtr;
361 
362  interface_Field(const boost::shared_ptr<T> &field_ptr)
363  : sFieldPtr(field_ptr) {}
364 
366  : sFieldPtr(interface.getFieldPtr()) {}
367 
368  virtual ~interface_Field() {}
369 
370  inline EntityHandle getMeshset() const {
371  return this->sFieldPtr->getMeshset();
372  }
373 
374  inline int getCoordSysId() const { return this->sFieldPtr->getCoordSysId(); }
375 
376  /**
377  * \brief Get dimension of general two-point tensor \ref
378  MoFEM::CoordSys::getDim
379 
380  See details here \ref MoFEM::CoordSys::getDim
381 
382  */
383  inline int getCoordSysDim(const int d = 0) const {
384  return this->sFieldPtr->getCoordSysDim(d);
385  }
386 
387  inline MoFEMErrorCode get_E_Base(const double m[]) const {
389  MoFEMFunctionReturnHot(this->sFieldPtr->get_E_Base(m));
390  }
391  inline MoFEMErrorCode get_E_DualBase(const double m[]) const {
393  MoFEMFunctionReturnHot(this->sFieldPtr->get_E_DualBase(m));
394  }
395  inline MoFEMErrorCode get_e_Base(const double m[]) const {
397  MoFEMFunctionReturnHot(this->sFieldPtr->get_e_Base(m));
398  }
399 
400  inline MoFEMErrorCode get_e_DualBase(const double m[]) const {
402  MoFEMFunctionReturnHot(this->sFieldPtr->get_e_DualBase(m));
403  }
404 
405  /// @return return meshset for coordinate system
407  return this->sFieldPtr->getCoordSysMeshSet();
408  }
409 
410  /// @return return coordinate system name for field
411  inline std::string getCoordSysName() const {
412  return this->sFieldPtr->getCoordSysName();
413  }
414 
415  /// @return return coordinate system name for field
416  inline boost::string_ref getCoordSysNameRef() const {
417  return this->sFieldPtr->getCoordSysNameRef();
418  }
419 
420  /// @return get field Id
421  inline const BitFieldId &getId() const { return this->sFieldPtr->getId(); }
422 
423  /// @return get field name
424  inline boost::string_ref getNameRef() const {
425  return this->sFieldPtr->getNameRef();
426  }
427 
428  /// @return get field name
429  inline std::string getName() const { return this->sFieldPtr->getName(); }
430 
431  /// @return get approximation space
432  inline FieldSpace getSpace() const { return this->sFieldPtr->getSpace(); }
433 
434  /// @return get approximation base
436  return this->sFieldPtr->getApproxBase();
437  }
438 
439  /// @return get number of coefficients for DOF
441  return this->sFieldPtr->getNbOfCoeffs();
442  }
443 
444  /// @return get bit number if filed Id
445  inline unsigned int getBitNumber() const {
446  return this->sFieldPtr->getBitNumber();
447  }
448 
449  /// @return get pointer to the field data structure
450  inline boost::shared_ptr<T> &getFieldPtr() const { return this->sFieldPtr; }
451 
452  /**
453  * \brief get hash-map relating dof index on entity with its order
454  *
455  * Dofs of given field are indexed on entity
456  * of the same type, same space, approximation base and number of
457  * coefficients, are sorted in the way.
458  *
459  */
460  inline std::vector<ApproximationOrder> &
461  getDofOrderMap(const EntityType type) const {
462  return this->sFieldPtr->getDofOrderMap(type);
463  }
464 };
465 
466 /**
467  * @relates multi_index_container
468  * \brief Field_multiIndex for Field
469  *
470  */
471 typedef multi_index_container<
472  boost::shared_ptr<Field>,
473  indexed_by<
474  hashed_unique<tag<BitFieldId_mi_tag>,
475  const_mem_fun<Field, const BitFieldId &, &Field::getId>,
476  HashBit<BitFieldId>, EqBit<BitFieldId>>,
477  ordered_unique<tag<Meshset_mi_tag>,
478  member<Field, EntityHandle, &Field::meshSet>>,
479  ordered_unique<
480  tag<FieldName_mi_tag>,
481  const_mem_fun<Field, boost::string_ref, &Field::getNameRef>>,
482  ordered_non_unique<tag<BitFieldId_space_mi_tag>,
483  const_mem_fun<Field, FieldSpace, &Field::getSpace>>>>
485 
486 typedef multi_index_container<
487  boost::shared_ptr<Field>,
488  indexed_by<
489  ordered_unique<tag<BitFieldId_mi_tag>,
490  const_mem_fun<Field, const BitFieldId &, &Field::getId>,
491  LtBit<BitFieldId>>>>
493 
494 /** \brief Set field coordinate system
495  * \ingroup ent_multi_indices
496  */
498  boost::shared_ptr<CoordSys> csPtr;
499  FieldChangeCoordinateSystem(const boost::shared_ptr<CoordSys> &cs_ptr)
500  : csPtr(cs_ptr) {}
501  void operator()(boost::shared_ptr<Field> &e) { e->coordSysPtr = csPtr; }
502 };
503 
504 } // namespace MoFEM
505 
506 #endif // __FIELDMULTIINDICES_HPP__
unsigned int getBitNumber() const
std::vector< ApproximationOrder > & getDofOrderMap(const EntityType type) const
get hash-map relating dof index on entity with its order
Tag th_AppOrder
Tag storing approximation order on entity.
std::string getName() const
Get field name.
interface_Field(const interface_Field< T > &interface)
const void * tagName
tag keeps name of the field
MoFEMErrorCode get_E_Base(const double m[]) const
MoFEMErrorCode get_E_DualBase(const double m[]) const
Get reference dual base vectors.
int getCoordSysDim(const int d=0) const
Get dimension of general two-point tensor MoFEM::CoordSys::getDim.
FieldChangeCoordinateSystem(const boost::shared_ptr< CoordSys > &cs_ptr)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Common.hpp:60
EntityHandle getCoordSysMeshSet() const
std::vector< ApproximationOrder > & getDofOrderMap(const EntityType type) const
get hash-map relating dof index on entity with its order
Provide data structure for (tensor) field approximation.The Field is intended to provide support for ...
keeps information about DOF on the entity
friend std::ostream & operator<<(std::ostream &os, const Field &e)
const void * tagNamePrefixData
tag keeps name prefix of the field
void operator()(boost::shared_ptr< Field > &e)
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:483
interface_Field(const boost::shared_ptr< T > &field_ptr)
const Tensor1_Expr< const dTensor0< T, Dim, i >, typename promote< T, double >::V, Dim, i > d(const Tensor0< T *> &a, const Index< i, Dim > index, const Tensor1< int, Dim > &d_ijk, const Tensor1< double, Dim > &d_xyz)
Definition: dTensor0.hpp:27
EntityHandle meshSet
keeps entities for this meshset
FieldCoefficientsNumber getNbOfCoeffs() const
multi_index_container< boost::shared_ptr< Field >, indexed_by< hashed_unique< tag< BitFieldId_mi_tag >, const_mem_fun< Field, const BitFieldId &, &Field::getId >, HashBit< BitFieldId >, EqBit< BitFieldId > >, ordered_unique< tag< Meshset_mi_tag >, member< Field, EntityHandle, &Field::meshSet > >, ordered_unique< tag< FieldName_mi_tag >, const_mem_fun< Field, boost::string_ref, &Field::getNameRef > >, ordered_non_unique< tag< BitFieldId_space_mi_tag >, const_mem_fun< Field, FieldSpace, &Field::getSpace > > > > Field_multiIndex
Field_multiIndex for Field.
boost::shared_ptr< SequenceEntContainer > & getEntSequenceContainer() const
Get reference to sequence data container.
boost::string_ref getCoordSysNameRef() const
boost::function< int(const int order)> FieldOrderFunct
user adjacency function
FieldOrderFunct FieldOrderTable[MBMAXTYPE]
user adjacency function table
FieldCoefficientsNumber getNbOfCoeffs() const
Get number of field coefficients.
MoFEMErrorCode get_e_DualBase(const double m[]) const
Get current dual base vectors.
boost::string_ref getNameRef() const
Get string reference to field name.
std::bitset< BITFIELDID_SIZE > BitFieldId
Definition: Common.hpp:149
Struct keeps handle to entity in the field.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return() ...
Definition: definitions.h:490
MoFEMErrorCode get_E_DualBase(const double m[]) const
Pointer interface for MoFEM::Field.
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:21
FieldSpace getSpace() const
Get field approximation space.
boost::string_ref getNameRef() const
EntityHandle getMeshset() const
FieldOrderTable forderTable
nb. DOFs table for entities
std::string getName() const
std::string getCoordSysName() const
Get coordinate system name.
FieldSpace * tagSpaceData
tag keeps field space
EntityHandle getCoordSysMeshSet() const
Returns meshset on which Tags defining coordinate system are stored.
FieldSpace getSpace() const
FieldApproximationBase
approximation base
Definition: definitions.h:140
FieldCoefficientsNumber * tagNbCoeffData
boost::string_ref getCoordSysNameRef() const
Get coordinate system name.
#define BITFIELDID_SIZE
max number of fields
Definition: definitions.h:277
int getCoordSysDim(const int d=0) const
Get dimension of general two-point tensor MoFEM::CoordSys::getDim.
const BitFieldId & getId() const
Get unique field id.
boost::shared_ptr< CoordSys > coordSysPtr
Pointer to field coordinate system data structure.
multi_index_container< boost::shared_ptr< Field >, indexed_by< ordered_unique< tag< BitFieldId_mi_tag >, const_mem_fun< Field, const BitFieldId &, &Field::getId >, LtBit< BitFieldId > > > > Field_multiIndex_view
FieldApproximationBase getApproxBase() const
Get approximation base.
FieldApproximationBase getApproxBase() const
const BitFieldId & getId() const
multi_index_container< boost::weak_ptr< std::vector< DofEntity > >, indexed_by< sequenced<> > > SequenceDofContainer
FieldSpace
approximation spaces
Definition: definitions.h:165
boost::shared_ptr< SequenceEntContainer > sequenceEntContainer
FieldOrderTable & getFieldOrderTable()
Get the Field Order Table.
FieldApproximationBase * tagBaseData
tag keeps field base
unsigned int getBitNumberCalculate() const
Calculate number of set bit in Field ID. Each field has uid, get getBitNumber get number of bit set f...
unsigned int getBitNumber() const
Get number of set bit in Field ID. Each field has uid, get getBitNumber get number of bit set for giv...
MoFEMErrorCode get_e_Base(const double m[]) const
Get current dual base vectors.
boost::shared_ptr< T > & getFieldPtr() const
multi_index_container< boost::weak_ptr< std::vector< FieldEntity > >, indexed_by< sequenced<> > > SequenceEntContainer
boost::shared_ptr< SequenceDofContainer > sequenceDofContainer
int tagNameSize
number of bits necessary to keep field name
MoFEMErrorCode get_e_Base(const double m[]) const
MoFEMErrorCode get_E_Base(const double m[]) const
Get reference base vectors.
moab::Interface & moab
EntityHandle getMeshset() const
Get field meshset.
Field(const Interface &moab, const EntityHandle meshset, const boost::shared_ptr< CoordSys > coord_sys_ptr)
constructor for moab field
boost::shared_ptr< SequenceDofContainer > & getDofSequenceContainer() const
Get reference to sequence data container.
std::string getCoordSysName() const
std::map< EntityType, std::vector< int > > dofOrderMap
Set field coordinate system.
unsigned int bitNumber
boost::shared_ptr< T > sFieldPtr
Tag th_FieldData
Tag storing field values on entity in the field.
boost::shared_ptr< CoordSys > csPtr
BitFieldId * tagId
tag keeps field id
MoFEMErrorCode get_e_DualBase(const double m[]) const