v0.13.1
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
14#ifndef __FIELDMULTIINDICES_HPP__
15#define __FIELDMULTIINDICES_HPP__
16
17namespace MoFEM {
18
19template <typename T> struct interface_RefEntity;
20struct DofEntity;
21
22/** \brief user adjacency function
23 * \ingroup fe_multi_indices
24 */
25typedef boost::function<int(const int order)> FieldOrderFunct;
26
27/** \brief user adjacency function table
28 * \ingroup dof_multi_indices
29 */
31
32/**
33 * \brief Provide data structure for (tensor) field approximation.
34 * \ingroup dof_multi_indices
35 *
36 * The Field is intended to provide support for fields, with a strong bias
37 * towards supporting first and best the capabilities required for scientific
38 * computing applications. Since we work with discrete spaces, data structure
39 * has to carry information about type of approximation space, its regularity.
40 *
41 *
42 * Field data structure storing information about space, approximation base,
43 * coordinate systems, etc. It stores additional data needed for book keeping,
44 * like tags to data on the mesh.
45 *
46 * Each filed has unique ID and name. This
47 * data structure is shared between entities on which is spanning and DOFs on
48 * those entities.
49 *
50 */
51struct Field {
52
53 /**
54 * \brief constructor for moab field
55 *
56 * \param meshset which keeps entities for this field
57 */
58 Field(moab::Interface &moab, const EntityHandle meshset);
59
60 virtual ~Field() = default;
61
62 using SequenceDofContainer = multi_index_container<
63
64 boost::weak_ptr<std::vector<DofEntity>>,
65
66 indexed_by<sequenced<>>>;
67
68 typedef std::array<std::array<int, MAX_DOFS_ON_ENTITY>, MBMAXTYPE>
70
72
73 EntityHandle meshSet; ///< keeps entities for this meshset
74
75 TagType tagFieldDataVertsType; // Tag type for storing data on vertices
76 Tag th_FieldDataVerts; ///< Tag storing field values on vertices in the field
77 Tag th_FieldData; ///< Tag storing field values on entity in the field
78 Tag th_AppOrder; ///< Tag storing approximation order on entity
79 Tag th_FieldRank; /// Tag field rank
80
81 BitFieldId *tagId; ///< tag keeps field id
82 FieldSpace *tagSpaceData; ///< tag keeps field space
83 FieldApproximationBase *tagBaseData; ///< tag keeps field base
84
85 /// tag keeps field rank (dimension, f.e. Temperature field has rank 1,
86 /// displacements field in 3d has rank 3)
88 const void *tagName; ///< tag keeps name of the field
89 int tagNameSize; ///< number of bits necessary to keep field name
90 const void *tagNamePrefixData; ///< tag keeps name prefix of the field
91 int tagNamePrefixSize; ///< number of bits necessary to keep field name
92 ///< prefix
93 FieldOrderTable forderTable; ///< nb. DOFs table for entities
94
95 /**
96 * @brief Get the Field Order Table
97 *
98 * @return FieldOrderTable&
99 */
101
102 /**
103 * Field Id is bit set. Each field has only one bit on, bitNumber stores
104 * number of set bit
105 */
106 unsigned int bitNumber;
107
108 static UId generateGlobalUniqueIdForTypeLo(const char bit_number,
109 const EntityType type,
110 const int owner_proc) {
111 constexpr int ent_shift = 8 * sizeof(EntityHandle);
112 return (static_cast<UId>(type) << MB_ID_WIDTH |
113 static_cast<UId>(bit_number) << 8 * sizeof(EntityHandle) |
114 static_cast<UId>(owner_proc) << 5 + ent_shift)
115 << 9;
116 }
117
119 const int owner_proc) const {
121 }
122
123 static UId generateGlobalUniqueIdForTypeHi(const char bit_number,
124 const EntityType type,
125 const int owner_proc) {
126 constexpr int ent_shift = 8 * sizeof(EntityHandle);
127 return (static_cast<UId>(type) << MB_ID_WIDTH |
128 static_cast<UId>(bit_number) << ent_shift |
129 static_cast<UId>(owner_proc) << 5 + ent_shift)
130 << 9;
131 }
132
134 const int owner_proc) const {
136 }
137
138 /**
139 * \brief Get field meshset
140 *
141
142 * To meshsets entity are attached Tags which keeps basic information about
143 * field. Those information is field name, approximation base, approximation
144 * space, id, etc.
145
146 * In meshset contains entities on which given filed is sparing. Type of
147 entities
148 * depended on approximations space.
149
150 * @return EntityHandle
151 */
152 inline EntityHandle getMeshset() const { return meshSet; }
153
154 /**
155 * \brief Get unique field id.
156 * @return Filed ID
157 */
158 inline const BitFieldId &getId() const { return *((BitFieldId *)tagId); }
159
160 /**
161 * \brief Get string reference to field name
162 * @return Field name
163 */
164 inline boost::string_ref getNameRef() const {
165 return boost::string_ref((char *)tagName, tagNameSize);
166 }
167
168 /**
169 * \brief Get field name
170 * @return Field name
171 */
172 inline std::string getName() const {
173 return std::string((char *)tagName, tagNameSize);
174 }
175
176 /**
177 * \brief Get field approximation space
178 * @return approximation space
179 */
180 inline FieldSpace getSpace() const { return *tagSpaceData; }
181
182 /**
183 * \brief Get field approximation space
184 * @return approximation space name
185 */
186 inline auto getSpaceName() const {
187 return std::string(FieldSpaceNames[getSpace()]);
188 }
189
190 /**
191 * \brief Get approximation base
192 * @return Approximation base
193 */
195
196 /**
197 * \brief Get approximation base
198 * @return Approximation base name
199 */
200 inline auto getApproxBaseName() const {
201 return std::string(ApproximationBaseNames[getApproxBase()]);
202 }
203
204 /** \brief Get number of field coefficients
205 *
206
207 * Scalar field has only one coefficient, vector field in 3D has three. In
208 * general number determine space needed to keep data on entities. What
209 coefficient
210 * means depend on interpretation and associated coordinate system. For
211 example
212 * 3 coefficient means could be covariant or contravariant, or mean three
213 temperatures
214 * for mixture of solid, air and water, etc.
215
216
217 */
219 return *tagNbCoeffData;
220 };
221
222 /**
223 * \brief Get number of set bit in Field ID.
224 * Each field has uid, get getBitNumber get number of bit set for given field.
225 * Field ID has only one bit set for each field.
226 */
227 inline FieldBitNumber getBitNumber() const { return bitNumber; }
228
229 /**
230 * \brief Calculate number of set bit in Field ID.
231 * Each field has uid, get getBitNumber get number of bit set for given field.
232 * Field ID has only one bit set for each field.
233 */
235 static_assert(BITFIELDID_SIZE >= 32,
236 "Too many fields allowed, can be more but ...");
237 FieldBitNumber b = ffsl(id.to_ulong());
238 if (b != 0)
239 return b;
240 return 0;
241 }
242
243 /**
244 * \brief Calculate number of set bit in Field ID.
245 * Each field has uid, get getBitNumber get number of bit set for given field.
246 * Field ID has only one bit set for each field.
247 */
249 return getBitNumberCalculate(static_cast<BitFieldId &>(*tagId));
250 }
251
252 /**
253 * \brief Get reference to sequence data container
254 *
255 * In sequence data container data are physically stored. The purpose of this
256 * is to allocate DofEntity data in bulk, having only one allocation instead
257 * each time entity is inserted. That makes code efficient.
258 *
259 * The vector in sequence is destroyed if last entity inside that vector is
260 * destroyed. All MoFEM::MoFEMEntities have aliased shared_ptr which points to
261 the vector.
262
263 * Not all DOFs are starred in this way, currently such cases are considered;
264 * - DOFs on vertices. That is exploited that for H1 space, there is some
265 * fixed number of DOFs on each vertex
266
267 * For other cases, DOFs are stored locally in each MoFEM::MoFEMEntities.
268
269 * @return MoFEM::Field::SequenceDofContainer
270 */
273 }
274
275 /**
276 * \brief get hash-map relating dof index on entity with its order
277 *
278 * Dofs of given field are indexed on entity
279 * of the same type, same space, approximation base and number of
280 * coefficients, are sorted in the way.
281 *
282 */
283 inline const std::array<ApproximationOrder, MAX_DOFS_ON_ENTITY> &
285 return dofOrderMap[type];
286 }
287
288 /**
289 * \brief get hash-map relating dof index on entity with its order
290 *
291 * Dofs of given field are indexed on entity
292 * of the same type, same space, approximation base and number of
293 * coefficients, are sorted in the way.
294 *
295 */
296 inline const DofsOrderMap &getDofOrderMap() const { return dofOrderMap; }
297
299
300 friend std::ostream &operator<<(std::ostream &os, const Field &e);
301
302 inline const Field *getFieldRawPtr() const { return this; };
303
304private:
307};
308
309/**
310 * \brief Pointer interface for MoFEM::Field
311 *
312 * MoFEM::Field class is keeps data and methods. This class is interface to
313 * that class, and all other classes, like MoFEMEntities, DofEntity and
314 * derived form them inherits pointer interface, not MoFEM::Field class
315 * directly.
316 *
317 * \ingroup dof_multi_indices
318 */
319template <typename FIELD, typename REFENT>
321
323
324 interface_FieldImpl(const boost::shared_ptr<FIELD> &field_ptr,
325 const boost::shared_ptr<REFENT> &ref_ents_ptr)
326 : interface_RefEntity<REFENT>(ref_ents_ptr) {}
327 virtual ~interface_FieldImpl() = default;
328};
329
330template <typename FIELD, typename REFENT>
331struct interface_Field : public interface_FieldImpl<FIELD, REFENT> {
332
333 interface_Field(const boost::shared_ptr<FIELD> &field_ptr,
334 const boost::shared_ptr<REFENT> &ref_ents_ptr)
335 : interface_FieldImpl<FIELD, REFENT>(field_ptr, ref_ents_ptr),
336 sFieldPtr(field_ptr) {}
337
338 inline EntityHandle getMeshset() const {
339 return getFieldRawPtr()->getMeshset();
340 }
341
342 inline int getCoordSysDim(const int d = 0) const {
343 return getFieldRawPtr()->getCoordSysDim(d);
344 }
345
346 /// @return get field Id
347 inline const BitFieldId &getId() const {
348 return getFieldRawPtr()->getId();
349 }
350
351 /// @return get field name
352 inline boost::string_ref getNameRef() const {
353 return getFieldRawPtr()->getNameRef();
354 }
355
356 /// @return get field name
357 inline std::string getName() const {
358 return getFieldRawPtr()->getName();
359 }
360
361 /// @return get approximation space
362 inline FieldSpace getSpace() const {
363 return getFieldRawPtr()->getSpace();
364 }
365
366 /// @return get approximation base
368 return getFieldRawPtr()->getApproxBase();
369 }
370
371 /// @return get number of coefficients for DOF
373 return getFieldRawPtr()->getNbOfCoeffs();
374 }
375
376 /// @return get bit number if filed Id
378 return getFieldRawPtr()->getBitNumber();
379 }
380
381 /**
382 * \brief get hash-map relating dof index on entity with its order
383 *
384 * Dofs of given field are indexed on entity
385 * of the same type, same space, approximation base and number of
386 * coefficients, are sorted in the way.
387 *
388 */
389 inline std::array<ApproximationOrder, MAX_DOFS_ON_ENTITY> &
392 }
393
394 inline const Field *getFieldRawPtr() const {
395 return sFieldPtr->getFieldRawPtr();
396 };
397
399 return sFieldPtr->getFieldOrderTable();
400 };
401
402private:
403 mutable boost::shared_ptr<FIELD> sFieldPtr;
404};
405
406template <typename T>
407struct interface_Field<T, T> : public interface_FieldImpl<T, T> {
408 interface_Field(const boost::shared_ptr<T> &ptr)
409 : interface_FieldImpl<T, T>(ptr, ptr) {}
410
412
413 inline EntityHandle getMeshset() const {
414 return getFieldRawPtr()->getMeshset();
415 }
416
417 /// @return get field Id
418 inline const BitFieldId &getId() const {
419 return getFieldRawPtr()->getId();
420 }
421
422 /// @return get field name
423 inline boost::string_ref getNameRef() const {
424 return getFieldRawPtr()->getNameRef();
425 }
426
427 /// @return get field name
428 inline std::string getName() const {
429 return getFieldRawPtr()->getName();
430 }
431
432 /// @return get approximation space
433 inline FieldSpace getSpace() const {
434 return getFieldRawPtr()->getSpace();
435 }
436
437 /// @return get approximation base
438 inline auto getSpaceName() const { return getFieldRawPtr()->getSpaceName(); }
439
440 /// @return get approximation base
442 return getFieldRawPtr()->getApproxBase();
443 }
444
445 /// @return get approximation base
446 inline auto getApproxBaseName() const {
448 }
449
450 /// @return get number of coefficients for DOF
452 return getFieldRawPtr()->getNbOfCoeffs();
453 }
454
455 /// @return get bit number if filed Id
457 return getFieldRawPtr()->getBitNumber();
458 }
459
460 /**
461 * \brief get hash-map relating dof index on entity with its order
462 *
463 * Dofs of given field are indexed on entity
464 * of the same type, same space, approximation base and number of
465 * coefficients, are sorted in the way.
466 *
467 */
468 inline std::array<ApproximationOrder, MAX_DOFS_ON_ENTITY> &
471 }
472
473 inline const Field *getFieldRawPtr() const {
474 return boost::static_pointer_cast<T>(this->getRefEntityPtr())
475 ->getFieldRawPtr();
476 };
477};
478
479/**
480 * @relates multi_index_container
481 * \brief Field_multiIndex for Field
482 *
483 */
484typedef multi_index_container<
485 boost::shared_ptr<Field>,
486 indexed_by<
487 hashed_unique<tag<BitFieldId_mi_tag>,
488 const_mem_fun<Field, const BitFieldId &, &Field::getId>,
489 HashBit<BitFieldId>, EqBit<BitFieldId>>,
490 ordered_unique<tag<Meshset_mi_tag>,
491 member<Field, EntityHandle, &Field::meshSet>>,
492 ordered_unique<
493 tag<FieldName_mi_tag>,
494 const_mem_fun<Field, boost::string_ref, &Field::getNameRef>>,
495 ordered_non_unique<tag<BitFieldId_space_mi_tag>,
496 const_mem_fun<Field, FieldSpace, &Field::getSpace>>>>
498
499typedef multi_index_container<
500 boost::shared_ptr<Field>,
501 indexed_by<
502 ordered_unique<tag<BitFieldId_mi_tag>,
503 const_mem_fun<Field, const BitFieldId &, &Field::getId>,
504 LtBit<BitFieldId>>>>
506
507} // namespace MoFEM
508
509#endif // __FIELDMULTIINDICES_HPP__
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.
FieldApproximationBase
approximation base
Definition: definitions.h:58
FieldSpace
approximation spaces
Definition: definitions.h:82
#define MB_ID_WIDTH
Definition: definitions.h:227
static const char *const FieldSpaceNames[]
Definition: definitions.h:92
#define BITFIELDID_SIZE
max number of fields
Definition: definitions.h:220
static const char *const ApproximationBaseNames[]
Definition: definitions.h:72
FieldOrderFunct FieldOrderTable[MBMAXTYPE]
user adjacency function table
boost::function< int(const int order)> FieldOrderFunct
user adjacency function
const double T
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
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
std::bitset< BITFIELDID_SIZE > BitFieldId
Field Id.
Definition: Types.hpp:42
uint128_t UId
Unique Id.
Definition: Types.hpp:31
int FieldCoefficientsNumber
Number of field coefficients.
Definition: Types.hpp:27
char FieldBitNumber
Field bit number.
Definition: Types.hpp:28
implementation of Data Operators for Forces and Sources
Definition: MoFEM.hpp:24
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
DeprecatedCoreInterface Interface
Definition: Interface.hpp:1955
Provide data structure for (tensor) field approximation.
FieldCoefficientsNumber getNbOfCoeffs() const
Get number of field coefficients.
const void * tagNamePrefixData
tag keeps name prefix of the field
FieldOrderTable forderTable
nb. DOFs table for entities
const void * tagName
tag keeps name of the field
int tagNameSize
number of bits necessary to keep field name
std::string getName() const
Get field name.
auto getSpaceName() const
Get field approximation space.
DofsOrderMap dofOrderMap
static UId generateGlobalUniqueIdForTypeHi(const char bit_number, const EntityType type, const int owner_proc)
FieldApproximationBase getApproxBase() const
Get approximation base.
friend std::ostream & operator<<(std::ostream &os, const Field &e)
unsigned int bitNumber
EntityHandle getMeshset() const
Get field meshset.
EntityHandle meshSet
keeps entities for this meshset
std::array< std::array< int, MAX_DOFS_ON_ENTITY >, MBMAXTYPE > DofsOrderMap
static UId generateGlobalUniqueIdForTypeLo(const char bit_number, const EntityType type, const int owner_proc)
FieldSpace * tagSpaceData
tag keeps field space
FieldBitNumber getBitNumberCalculate() const
Calculate number of set bit in Field ID. Each field has uid, get getBitNumber get number of bit set f...
auto getApproxBaseName() const
Get approximation base.
const std::array< ApproximationOrder, MAX_DOFS_ON_ENTITY > & getDofOrderMap(const EntityType type) const
get hash-map relating dof index on entity with its order
UId generateGlobalUniqueIdForTypeLo(const EntityType type, const int owner_proc) const
static FieldBitNumber getBitNumberCalculate(const BitFieldId &id)
Calculate number of set bit in Field ID. Each field has uid, get getBitNumber get number of bit set f...
Tag th_FieldData
Tag storing field values on entity in the field.
const DofsOrderMap & getDofOrderMap() const
get hash-map relating dof index on entity with its order
FieldOrderTable & getFieldOrderTable()
Get the Field Order Table.
MoFEMErrorCode rebuildDofsOrderMap()
FieldCoefficientsNumber * tagNbCoeffData
BitFieldId * tagId
Tag field rank.
FieldSpace getSpace() const
Get field approximation space.
Field(moab::Interface &moab, const EntityHandle meshset)
constructor for moab field
Tag th_FieldDataVerts
Tag storing field values on vertices in the field.
SequenceDofContainer sequenceDofContainer
FieldApproximationBase * tagBaseData
tag keeps field base
SequenceDofContainer & getDofSequenceContainer() const
Get reference to sequence data container.
UId generateGlobalUniqueIdForTypeHi(const EntityType type, const int owner_proc) const
const Field * getFieldRawPtr() const
TagType tagFieldDataVertsType
multi_index_container< boost::weak_ptr< std::vector< DofEntity > >, indexed_by< sequenced<> > > SequenceDofContainer
Tag th_AppOrder
Tag storing approximation order on entity.
moab::Interface & moab
boost::string_ref getNameRef() const
Get string reference to field name.
virtual ~Field()=default
FieldBitNumber getBitNumber() const
Get number of set bit in Field ID. Each field has uid, get getBitNumber get number of bit set for giv...
const BitFieldId & getId() const
Get unique field id.
const BitFieldId & getId() const
FieldBitNumber getBitNumber() const
interface_Field(const boost::shared_ptr< T > &ptr)
FieldApproximationBase getApproxBase() const
FieldCoefficientsNumber getNbOfCoeffs() const
const Field * getFieldRawPtr() const
std::array< ApproximationOrder, MAX_DOFS_ON_ENTITY > & getDofOrderMap(const EntityType type) const
get hash-map relating dof index on entity with its order
boost::string_ref getNameRef() const
FieldBitNumber getBitNumber() const
FieldCoefficientsNumber getNbOfCoeffs() const
boost::string_ref getNameRef() const
FieldApproximationBase getApproxBase() const
std::string getName() const
std::array< ApproximationOrder, MAX_DOFS_ON_ENTITY > & getDofOrderMap(const EntityType type) const
get hash-map relating dof index on entity with its order
EntityHandle getMeshset() const
const Field * getFieldRawPtr() const
FieldSpace getSpace() const
const BitFieldId & getId() const
interface_Field(const boost::shared_ptr< FIELD > &field_ptr, const boost::shared_ptr< REFENT > &ref_ents_ptr)
FieldOrderTable & getFieldOrderTable()
boost::shared_ptr< FIELD > sFieldPtr
int getCoordSysDim(const int d=0) const
Pointer interface for MoFEM::Field.
interface_FieldImpl(const boost::shared_ptr< FIELD > &field_ptr, const boost::shared_ptr< REFENT > &ref_ents_ptr)
virtual ~interface_FieldImpl()=default
boost::shared_ptr< REFENT > & getRefEntityPtr() const