v0.13.0
FieldEntsMultiIndices.cpp
Go to the documentation of this file.
1 /** \file FieldEntsMultiIndices.cpp
2  * \brief Multi-index containers for entities
3  */
4 
5 /* MoFEM is free software: you can redistribute it and/or modify it under
6  * the terms of the GNU Lesser General Public License as published by the
7  * Free Software Foundation, either version 3 of the License, or (at your
8  * option) any later version.
9  *
10  * MoFEM is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
13  * License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with MoFEM. If not, see <http://www.gnu.org/licenses/>
17  */
18 
19 #define IS_BUILDING_MB
20 #include <moab/Error.hpp>
21 
22 namespace MoFEM {
23 
24 constexpr int FieldEntity::dof_shift; // Maximal number of DOFs on entity
25 constexpr int FieldEntity::ent_shift; // EntityHandle size
26 constexpr int FieldEntity::proc_shift; // Maximal number of 1024 processors
27 
29  const boost::shared_ptr<Field> field_ptr,
30  const boost::shared_ptr<RefEntity> ref_ents_ptr,
31  boost::shared_ptr<double *const> field_data_adaptor_ptr,
32  boost::shared_ptr<const int> t_max_order_ptr)
33  : interface_Field<Field, RefEntity>(field_ptr, ref_ents_ptr),
34  tagMaxOrderPtr(t_max_order_ptr),
35  fieldDataAdaptorPtr(field_data_adaptor_ptr) {
36 
37  localUId = getLocalUniqueIdCalculate(field_ptr->getBitNumber(),
38  ref_ents_ptr->getEnt());
39 #ifndef NDEBUG
40  if (PetscUnlikely(!fieldDataAdaptorPtr))
41  THROW_MESSAGE("Pointer to field data adaptor not set");
42 
43  if (PetscUnlikely(!tagMaxOrderPtr))
44  THROW_MESSAGE("Pointer to max order not set");
45 #endif
46 }
47 
48 boost::shared_ptr<FieldData *const> FieldEntity::makeSharedFieldDataAdaptorPtr(
49  const boost::shared_ptr<Field> &field_ptr,
50  const boost::shared_ptr<RefEntity> &ref_ents_ptr) {
51  int size;
52  FieldData *ptr;
53  switch (ref_ents_ptr->getEntType()) {
54  case MBVERTEX:
55  size = field_ptr->getNbOfCoeffs();
56  ptr = static_cast<FieldData *>(
57  MoFEM::get_tag_ptr(field_ptr->moab, field_ptr->th_FieldDataVerts,
58  ref_ents_ptr->ent, &size));
59  break;
60  default:
61  ptr = static_cast<FieldData *>(MoFEM::get_tag_ptr(
62  field_ptr->moab, field_ptr->th_FieldData, ref_ents_ptr->ent, &size));
63  }
64  return boost::make_shared<FieldData *const>(ptr);
65 }
66 
67 std::ostream &operator<<(std::ostream &os, const FieldEntity &e) {
68  os << "ent_global_uid " << e.getLocalUniqueId() << " entity " << e.getEnt()
69  << " type " << e.getEntTypeName() << " pstatus "
70  << std::bitset<8>(e.getPStatus()) << " owner handle " << e.getOwnerEnt()
71  << " owner proc " << e.getOwnerProc() << " order " << e.getMaxOrder()
72  << " " << *e.getFieldRawPtr();
73  return os;
74 }
75 
77 
78  moab::Interface &moab = e->sPtr->getBasicDataPtr()->moab;
79  const EntityHandle ent = e->getEnt();
80  *const_cast<ApproximationOrder *>(e->getMaxOrderPtr()) = order;
81  std::size_t nb_dofs = e->getOrderNbDofs(order) * e->getNbOfCoeffs();
82 
83  double *tag_field_data = nullptr;
84  int tag_field_data_size = 0;
85 
86  auto set_verts = [&]() {
87  if (e->getFieldRawPtr()->tagFieldDataVertsType == MB_TAG_SPARSE) {
88  // Get pointer and size of field values tag
89  rval = moab.tag_get_by_ptr(e->getFieldRawPtr()->th_FieldDataVerts, &ent,
90  1, (const void **)&tag_field_data,
91  &tag_field_data_size);
92  if (nb_dofs) {
93  if (nb_dofs != tag_field_data_size) {
94  rval = moab.tag_set_data(e->getFieldRawPtr()->th_FieldDataVerts, &ent,
95  1, &*data.begin());
97  }
98  } else if (rval == MB_SUCCESS) {
99  rval = moab.tag_delete_data(e->getFieldRawPtr()->th_FieldDataVerts,
100  &ent, 1);
101  MOAB_THROW(rval);
102  }
103  } else {
104  rval = moab.tag_get_by_ptr(e->getFieldRawPtr()->th_FieldDataVerts, &ent,
105  1, (const void **)&tag_field_data);
106  MOAB_THROW(rval);
107  rval = moab.tag_set_data(e->getFieldRawPtr()->th_FieldDataVerts, &ent, 1,
108  tag_field_data);
109  MOAB_THROW(rval);
110  }
111  };
112 
113  auto set_default = [&]() {
114  if (reduceTagSize || nb_dofs) {
115 
116  // Get pointer and size of field values tag
117  rval = moab.tag_get_by_ptr(e->getFieldRawPtr()->th_FieldData, &ent, 1,
118  (const void **)&tag_field_data,
119  &tag_field_data_size);
120 
121  if ((reduceTagSize && nb_dofs != tag_field_data_size) ||
122  nb_dofs > tag_field_data_size) {
123 
124  // Tag exist and are some data on it
125  if (rval == MB_SUCCESS) {
126  // Size of tag is different than new size, so copy data to new
127  // container
128  data.resize(tag_field_data_size);
129  FieldData *ptr_begin = static_cast<FieldData *>(tag_field_data);
130  FieldData *ptr_end =
131  static_cast<FieldData *>(tag_field_data) + tag_field_data_size;
132  std::copy(ptr_begin, ptr_end, data.begin());
133  }
134 
135  if (rval != MB_SUCCESS || nb_dofs) {
136 
137  // Set field dof data
138  data.resize(nb_dofs, 0);
139  int tag_size[1];
140  tag_size[0] = data.size();
141  void const *tag_data[] = {&data[0]};
142  rval = moab.tag_set_by_ptr(e->getFieldRawPtr()->th_FieldData, &ent, 1,
143  tag_data, tag_size);
144  MOAB_THROW(rval);
145  rval = moab.tag_get_by_ptr(e->getFieldRawPtr()->th_FieldData, &ent, 1,
146  (const void **)&tag_field_data,
147  &tag_field_data_size);
148  MOAB_THROW(rval);
149 
150  } else {
151 
152  rval =
153  moab.tag_delete_data(e->getFieldRawPtr()->th_FieldData, &ent, 1);
154  MOAB_THROW(rval);
155  }
156  }
157  }
158  };
159 
160  switch (e->getEntType()) {
161  case MBVERTEX:
162  set_verts();
163  break;
164  default:
165  set_default();
166  }
167 
168  if (nb_dofs)
169  const_cast<double *&>(*(e->getEntFieldDataPtr())) = tag_field_data;
170  else
171  const_cast<double *&>(*(e->getEntFieldDataPtr())) = nullptr;
172 }
173 
174 } // namespace MoFEM
#define MOAB_THROW(err)
Check error code of MoAB function and throw MoFEM exception.
Definition: definitions.h:554
#define THROW_MESSAGE(msg)
Throw MoFEM exception.
Definition: definitions.h:574
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
Definition: Exceptions.hpp:85
double FieldData
Field data type.
Definition: Types.hpp:36
int ApproximationOrder
Approximation on the entity.
Definition: Types.hpp:37
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:21
void * get_tag_ptr(moab::Interface &moab, Tag th, EntityHandle ent, int *tag_size)
Get the tag ptr object.
DeprecatedCoreInterface Interface
Definition: Interface.hpp:1965
std::ostream & operator<<(std::ostream &os, const EntitiesFieldData::EntData &e)
void operator()(boost::shared_ptr< FieldEntity > &e)
Struct keeps handle to entity in the field.
static constexpr int dof_shift
const UId & getLocalUniqueId() const
Get global unique id.
UId getLocalUniqueIdCalculate()
Get the Local Unique Id Calculate object.
boost::shared_ptr< FieldData *const > fieldDataAdaptorPtr
static constexpr int proc_shift
FieldEntity(const boost::shared_ptr< Field > field_ptr, const boost::shared_ptr< RefEntity > ref_ents_ptr, boost::shared_ptr< double *const > field_data_adaptor_ptr, boost::shared_ptr< const int > t_max_order_ptr)
ApproximationOrder getMaxOrder() const
Get order set to the entity (Allocated tag size for such number)
static boost::shared_ptr< FieldData *const > makeSharedFieldDataAdaptorPtr(const boost::shared_ptr< Field > &field_ptr, const boost::shared_ptr< RefEntity > &ref_ents_ptr)
Return shared pointer to entity field data vector adaptor.
UId localUId
Global unique id for this entity.
const ApproximationOrder * getMaxOrderPtr() const
Get pinter to Tag keeping approximation order.
boost::shared_ptr< FieldData *const > & getEntFieldDataPtr() const
Get shared ptr to vector adaptor pointing to the field tag data on entity.
static constexpr int ent_shift
int getOrderNbDofs(ApproximationOrder order) const
Get number of DOFs on entity for given order of approximation.
boost::shared_ptr< const ApproximationOrder > tagMaxOrderPtr
Provide data structure for (tensor) field approximation.
Tag th_FieldData
Tag storing field values on entity in the field.
Tag th_FieldDataVerts
Tag storing field values on vertices in the field.
TagType tagFieldDataVertsType
Struct keeps handle to refined handle.
FieldCoefficientsNumber getNbOfCoeffs() const
const Field * getFieldRawPtr() const
EntityHandle getOwnerEnt() const
const char * getEntTypeName() const
Get the Ent Type Name.
EntityType getEntType() const
Get entity type.
unsigned char getPStatus() const
EntityHandle getEnt() const
Get the entity handle.