v0.10.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 
25  const boost::shared_ptr<Field> field_ptr,
26  const boost::shared_ptr<RefEntity> ref_ents_ptr,
27  boost::shared_ptr<double *const> field_data_adaptor_ptr,
28  boost::shared_ptr<const int> t_max_order_ptr)
29  : interface_Field<Field, RefEntity>(field_ptr, ref_ents_ptr),
30  tagMaxOrderPtr(t_max_order_ptr),
31  fieldDataAdaptorPtr(field_data_adaptor_ptr) {
32 
33  localUId = getLocalUniqueIdCalculate(field_ptr->getBitNumber(),
34  ref_ents_ptr->getEnt());
35 
36  if (PetscUnlikely(!fieldDataAdaptorPtr))
37  THROW_MESSAGE("Pointer to field data adaptor not set");
38 
39  if (PetscUnlikely(!tagMaxOrderPtr))
40  THROW_MESSAGE("Pointer to max order not set");
41 }
42 
43 boost::shared_ptr<FieldData *const> FieldEntity::makeSharedFieldDataAdaptorPtr(
44  const boost::shared_ptr<Field> &field_ptr,
45  const boost::shared_ptr<RefEntity> &ref_ents_ptr) {
46  int size;
47  FieldData *ptr;
48  switch (ref_ents_ptr->getEntType()) {
49  case MBVERTEX:
50  size = field_ptr->getNbOfCoeffs();
51  ptr = static_cast<FieldData *>(
52  MoFEM::get_tag_ptr(field_ptr->moab, field_ptr->th_FieldDataVerts,
53  ref_ents_ptr->ent, &size));
54  break;
55  default:
56  ptr = static_cast<FieldData *>(MoFEM::get_tag_ptr(
57  field_ptr->moab, field_ptr->th_FieldData, ref_ents_ptr->ent, &size));
58  }
59  return boost::make_shared<FieldData *const>(ptr);
60 }
61 
62 std::ostream &operator<<(std::ostream &os, const FieldEntity &e) {
63  os << "ent_global_uid " << e.getLocalUniqueId() << " entity " << e.getEnt()
64  << " type " << e.getEntTypeName() << " pstatus "
65  << std::bitset<8>(e.getPStatus()) << " owner handle " << e.getOwnerEnt()
66  << " owner proc " << e.getOwnerProc() << " order " << e.getMaxOrder()
67  << " " << *e.getFieldRawPtr();
68  return os;
69 }
70 
72 
73  moab::Interface &moab = e->sPtr->getBasicDataPtr()->moab;
74  const EntityHandle ent = e->getEnt();
75  *const_cast<ApproximationOrder *>(e->getMaxOrderPtr()) = order;
76  std::size_t nb_dofs = e->getOrderNbDofs(order) * e->getNbOfCoeffs();
77 
78  double *tag_field_data = nullptr;
79  int tag_field_data_size = 0;
80 
81  auto set_verts = [&]() {
82  if (e->getFieldRawPtr()->th_FieldDataVertsType == MB_TAG_SPARSE) {
83  // Get pointer and size of field values tag
84  rval = moab.tag_get_by_ptr(e->getFieldRawPtr()->th_FieldDataVerts, &ent,
85  1, (const void **)&tag_field_data,
86  &tag_field_data_size);
87  if (nb_dofs) {
88  if (nb_dofs != tag_field_data_size) {
89  rval = moab.tag_set_data(e->getFieldRawPtr()->th_FieldDataVerts, &ent,
90  1, &*data.begin());
92  }
93  } else if (rval == MB_SUCCESS) {
94  rval = moab.tag_delete_data(e->getFieldRawPtr()->th_FieldDataVerts,
95  &ent, 1);
97  }
98  } else {
99  rval = moab.tag_get_by_ptr(e->getFieldRawPtr()->th_FieldDataVerts, &ent,
100  1, (const void **)&tag_field_data);
101  MOAB_THROW(rval);
102  rval = moab.tag_set_data(e->getFieldRawPtr()->th_FieldDataVerts, &ent, 1,
103  tag_field_data);
104  MOAB_THROW(rval);
105  }
106  };
107 
108  auto set_default = [&]() {
109  if (reduceTagSize || nb_dofs) {
110 
111  // Get pointer and size of field values tag
112  rval = moab.tag_get_by_ptr(e->getFieldRawPtr()->th_FieldData, &ent, 1,
113  (const void **)&tag_field_data,
114  &tag_field_data_size);
115 
116  if ((reduceTagSize && nb_dofs != tag_field_data_size) ||
117  nb_dofs > tag_field_data_size) {
118 
119  // Tag exist and are some data on it
120  if (rval == MB_SUCCESS) {
121  // Size of tag is different than new size, so copy data to new
122  // container
123  data.resize(tag_field_data_size);
124  FieldData *ptr_begin = static_cast<FieldData *>(tag_field_data);
125  FieldData *ptr_end =
126  static_cast<FieldData *>(tag_field_data) + tag_field_data_size;
127  std::copy(ptr_begin, ptr_end, data.begin());
128  }
129 
130  if (rval != MB_SUCCESS || nb_dofs) {
131 
132  // Set field dof data
133  data.resize(nb_dofs, 0);
134  int tag_size[1];
135  tag_size[0] = data.size();
136  void const *tag_data[] = {&data[0]};
137  rval = moab.tag_set_by_ptr(e->getFieldRawPtr()->th_FieldData, &ent, 1,
138  tag_data, tag_size);
139  MOAB_THROW(rval);
140  rval = moab.tag_get_by_ptr(e->getFieldRawPtr()->th_FieldData, &ent, 1,
141  (const void **)&tag_field_data,
142  &tag_field_data_size);
143  MOAB_THROW(rval);
144 
145  } else {
146 
147  rval =
148  moab.tag_delete_data(e->getFieldRawPtr()->th_FieldData, &ent, 1);
149  MOAB_THROW(rval);
150  }
151  }
152  }
153  };
154 
155  switch (e->getEntType()) {
156  case MBVERTEX:
157  set_verts();
158  break;
159  default:
160  set_default();
161  }
162 
163  if (nb_dofs)
164  const_cast<double *&>(*(e->getEntFieldDataPtr())) = tag_field_data;
165  else
166  const_cast<double *&>(*(e->getEntFieldDataPtr())) = nullptr;
167 }
168 
169 } // namespace MoFEM
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)
int getOrderNbDofs(ApproximationOrder order) const
Get number of DOFs on entity for given order of approximation.
EntityType getEntType() const
Get entity type.
Provide data structure for (tensor) field approximation.The Field is intended to provide support for ...
UId getLocalUniqueIdCalculate()
Get the Local Unique Id Calculate object.
TagType th_FieldDataVertsType
Struct keeps handle to refined handle.
FieldCoefficientsNumber getNbOfCoeffs() const
#define THROW_MESSAGE(a)
Throw MoFEM exception.
Definition: definitions.h:628
Struct keeps handle to entity in the field.
UId localUId
Global unique id for this entity.
#define MOAB_THROW(a)
Check error code of MoAB function and throw MoFEM exception.
Definition: definitions.h:610
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:21
EntityHandle getOwnerEnt() const
const Field * getFieldRawPtr() const
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
Definition: Exceptions.hpp:85
std::ostream & operator<<(std::ostream &os, const DataForcesAndSourcesCore::EntData &e)
const char * getEntTypeName() const
Get the Ent Type Name.
const ApproximationOrder * getMaxOrderPtr() const
Get pinter to Tag keeping approximation order.
ApproximationOrder getMaxOrder() const
Get order set to the entity (Allocated tag size for such number)
boost::shared_ptr< FieldData *const > & getEntFieldDataPtr() const
Get shared ptr to vector adaptor pointing to the field tag data on entity.
Tag th_FieldDataVerts
Tag storing field values on vertices in the field.
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.
unsigned char getPStatus() const
void operator()(boost::shared_ptr< FieldEntity > &e)
EntityHandle getEnt() const
Get the entity handle.
void * get_tag_ptr(moab::Interface &moab, Tag th, EntityHandle ent, int *tag_size)
Get the tag ptr object.
const UId & getLocalUniqueId() const
Get global unique id.
DeprecatedCoreInterface Interface
Definition: Interface.hpp:1943
boost::shared_ptr< FieldData *const > fieldDataAdaptorPtr
boost::shared_ptr< const ApproximationOrder > tagMaxOrderPtr
Tag th_FieldData
Tag storing field values on entity in the field.