v0.14.0
ForcesAndSourcesCore.cpp
Go to the documentation of this file.
1 /** \file ForcesAndSourcesCore.cpp
2 
3 \brief Implementation of Elements on Entities for Forces and Sources
4 */
5 
6 #ifdef __cplusplus
7 extern "C" {
8 #endif
9 #include <cblas.h>
10 #include <lapack_wrap.h>
11 // #include <gm_rule.h>
12 #ifdef __cplusplus
13 }
14 #endif
15 
16 namespace MoFEM {
17 
18 static auto cmp_uid_lo(const boost::weak_ptr<FieldEntity> &a, const UId &b) {
19  if (auto a_ptr = a.lock()) {
20  if (a_ptr->getLocalUniqueId() < b)
21  return true;
22  else
23  return false;
24  } else {
25  return false;
26  }
27 }
28 
29 static auto cmp_uid_hi(const UId &b, const boost::weak_ptr<FieldEntity> &a) {
30  if (auto a_ptr = a.lock()) {
31  if (b < a_ptr->getLocalUniqueId())
32  return true;
33  else
34  return false;
35  } else {
36  return true;
37  }
38 }
39 
41  :
42 
43  mField(m_field), getRuleHook(0), setRuleHook(0),
44  dataOnElement{
45 
46  boost::make_shared<EntitiesFieldData>(MBENTITYSET), // NOSPACE,
47  boost::make_shared<EntitiesFieldData>(MBENTITYSET), // NOFIELD
48  boost::make_shared<EntitiesFieldData>(MBENTITYSET), // H1
49  boost::make_shared<EntitiesFieldData>(MBENTITYSET), // HCURL
50  boost::make_shared<EntitiesFieldData>(MBENTITYSET), // HDIV
51  boost::make_shared<EntitiesFieldData>(MBENTITYSET) // L2
52 
53  },
54  derivedDataOnElement{
55 
56  nullptr,
57  boost::make_shared<DerivedEntitiesFieldData>(
58  dataOnElement[NOFIELD]), // NOFIELD
59  boost::make_shared<DerivedEntitiesFieldData>(dataOnElement[H1]), // H1
60  boost::make_shared<DerivedEntitiesFieldData>(
61  dataOnElement[HCURL]), // HCURL
62  boost::make_shared<DerivedEntitiesFieldData>(
63  dataOnElement[HDIV]), // HDIV
64  boost::make_shared<DerivedEntitiesFieldData>(dataOnElement[L2]) // L2
65 
66  },
67  dataNoField(*dataOnElement[NOFIELD].get()),
68  dataH1(*dataOnElement[H1].get()), dataHcurl(*dataOnElement[HCURL].get()),
69  dataHdiv(*dataOnElement[HDIV].get()), dataL2(*dataOnElement[L2].get()),
70  lastEvaluatedElementEntityType(MBMAXTYPE), sidePtrFE(nullptr),
71  refinePtrFE(nullptr) {
72 
73  dataOnElement[NOSPACE]->dataOnEntities[MBENTITYSET].push_back(
75 
76  dataOnElement[NOFIELD]->dataOnEntities[MBENTITYSET].push_back(
78  derivedDataOnElement[NOFIELD]->dataOnEntities[MBENTITYSET].push_back(
80 }
81 
82 // ** Sense **
83 
85  const EntityType type,
86  boost::ptr_vector<EntitiesFieldData::EntData> &data) const {
88 
89  auto &side_table = numeredEntFiniteElementPtr->getSideNumberTable().get<0>();
90  auto sit = side_table.lower_bound(get_id_for_min_type(type));
91  if (sit != side_table.end()) {
92  auto hi_sit = side_table.upper_bound(get_id_for_max_type(type));
93  for (; sit != hi_sit; ++sit) {
94  if (const auto side_number = (*sit)->side_number; side_number >= 0) {
95  const int brother_side_number = (*sit)->brother_side_number;
96  const int sense = (*sit)->sense;
97 
98  data[side_number].getSense() = sense;
99  if (brother_side_number != -1)
100  data[brother_side_number].getSense() = sense;
101  }
102  }
103  }
105 }
106 
107 // ** Order **
108 
109 template <typename ENTMULTIINDEX>
110 static inline int getMaxOrder(const ENTMULTIINDEX &multi_index) {
111  int max_order = 0;
112  for (auto ent_field_weak_ptr : multi_index)
113  if (auto e = ent_field_weak_ptr.lock()) {
114  const int order = e->getMaxOrder();
115  max_order = (max_order < order) ? order : max_order;
116  }
117  return max_order;
118 }
119 
121  int max_order = 0;
122  for (auto e : getDataFieldEnts()) {
123  if (auto ptr = e.lock()) {
124  const int order = ptr->getMaxOrder();
125  max_order = (max_order < order) ? order : max_order;
126  }
127  }
128  return max_order;
129 }
130 
132  return getMaxOrder(getRowFieldEnts());
133 }
134 
136  return getMaxOrder(getColFieldEnts());
137 }
138 
140  const EntityType type, const FieldSpace space,
141  boost::ptr_vector<EntitiesFieldData::EntData> &data) const {
143 
144  auto set_order = [&]() {
146  auto &side_table = numeredEntFiniteElementPtr->getSideNumberTable();
147 
148  for (unsigned int s = 0; s != data.size(); ++s)
149  data[s].getOrder() = 0;
150 
151  const FieldEntity_vector_view &data_field_ent = getDataFieldEnts();
152 
153  for (auto r = fieldsPtr->get<BitFieldId_space_mi_tag>().equal_range(space);
154  r.first != r.second; ++r.first) {
155 
156  const auto field_bit_number = (*r.first)->getBitNumber();
157  const auto lo_uid = FieldEntity::getLocalUniqueIdCalculate(
158  field_bit_number, get_id_for_min_type(type));
159  auto lo = std::lower_bound(data_field_ent.begin(), data_field_ent.end(),
160  lo_uid, cmp_uid_lo);
161  if (lo != data_field_ent.end()) {
162  const auto hi_uid = FieldEntity::getLocalUniqueIdCalculate(
163  field_bit_number, get_id_for_max_type(type));
164  auto hi =
165  std::upper_bound(lo, data_field_ent.end(), hi_uid, cmp_uid_hi);
166  for (; lo != hi; ++lo) {
167 
168  if (auto ptr = lo->lock()) {
169 
170  auto &e = *ptr;
171  auto sit = side_table.find(e.getEnt());
172  if (sit != side_table.end()) {
173  auto &side = *sit;
174  if (const auto side_number = side->side_number;
175  side_number >= 0) {
176  ApproximationOrder ent_order = e.getMaxOrder();
177  auto &dat = data[side_number];
178  dat.getOrder() =
179  dat.getOrder() > ent_order ? dat.getOrder() : ent_order;
180  }
181  } else
182  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
183  "Entity on side of the element not found");
184  }
185  }
186  }
187  }
188 
190  };
191 
192  auto set_order_on_brother = [&]() {
194  auto &side_table =
195  numeredEntFiniteElementPtr->getSideNumberTable().get<0>();
196  auto sit = side_table.lower_bound(get_id_for_min_type(type));
197  if (sit != side_table.end()) {
198  auto hi_sit = side_table.upper_bound(get_id_for_max_type(type));
199  for (; sit != hi_sit; ++sit) {
200  const int brother_side_number = (*sit)->brother_side_number;
201  if (brother_side_number != -1) {
202  const int side_number = (*sit)->side_number;
203  data[brother_side_number].getOrder() = data[side_number].getOrder();
204  }
205  }
206  }
208  };
209 
210  CHKERR set_order();
211  CHKERR set_order_on_brother();
212 
214 }
215 
216 // ** Indices **
217 
218 template <typename EXTRACTOR>
220  const int bit_number, FieldEntity_vector_view &ents_field,
221  VectorInt &nodes_indices, VectorInt &local_nodes_indices,
222  EXTRACTOR &&extractor) const {
224 
225  auto field_it = fieldsPtr->get<BitFieldId_mi_tag>().find(
226  BitFieldId().set(bit_number - 1));
227  if (field_it != fieldsPtr->get<BitFieldId_mi_tag>().end()) {
228 
229 #ifndef NDEBUG
230  if ((*field_it)->getBitNumber() != bit_number)
231  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "Wrong bit number");
232 #endif
233  const auto lo_uid = FieldEntity::getLocalUniqueIdCalculate(
234  bit_number, get_id_for_min_type<MBVERTEX>());
235  auto lo = std::lower_bound(ents_field.begin(), ents_field.end(), lo_uid,
236  cmp_uid_lo);
237  if (lo != ents_field.end()) {
238  const auto hi_uid = FieldEntity::getLocalUniqueIdCalculate(
239  bit_number, get_id_for_max_type<MBVERTEX>());
240  auto hi = std::upper_bound(lo, ents_field.end(), hi_uid, cmp_uid_hi);
241 
242  const int num_nodes = getNumberOfNodes();
243  const int nb_dofs_on_vert = (*field_it)->getNbOfCoeffs();
244  const int max_nb_dofs = nb_dofs_on_vert * num_nodes;
245 
246  int nb_dofs = 0;
247  for (auto it = lo; it != hi; ++it) {
248  if (auto e = it->lock()) {
249  if (auto cache = extractor(e).lock()) {
250  if (cache->loHi[0] != cache->loHi[1]) {
251  nb_dofs += std::distance(cache->loHi[0], cache->loHi[1]);
252  break;
253  }
254  }
255  }
256  }
257 
258  if (nb_dofs) {
259  nodes_indices.resize(max_nb_dofs, false);
260  local_nodes_indices.resize(max_nb_dofs, false);
261  } else {
262  nodes_indices.resize(0, false);
263  local_nodes_indices.resize(0, false);
264  }
265 
266  if (nb_dofs != max_nb_dofs) {
267  std::fill(nodes_indices.begin(), nodes_indices.end(), -1);
268  std::fill(local_nodes_indices.begin(), local_nodes_indices.end(), -1);
269  }
270 
271  for (auto it = lo; it != hi; ++it) {
272  if (auto e = it->lock()) {
273  auto side_ptr = e->getSideNumberPtr();
274  if (const auto side_number = side_ptr->side_number;
275  side_number >= 0) {
276  const auto brother_side_number = side_ptr->brother_side_number;
277  if (auto cache = extractor(e).lock()) {
278  for (auto dit = cache->loHi[0]; dit != cache->loHi[1]; ++dit) {
279  auto &dof = **dit;
280  const int idx = dof.getPetscGlobalDofIdx();
281  const int local_idx = dof.getPetscLocalDofIdx();
282  const int pos =
283  side_number * nb_dofs_on_vert + dof.getDofCoeffIdx();
284  nodes_indices[pos] = idx;
285  local_nodes_indices[pos] = local_idx;
286  if (brother_side_number != -1) {
287  const int elem_idx = brother_side_number * nb_dofs_on_vert +
288  (*dit)->getDofCoeffIdx();
289  nodes_indices[elem_idx] = idx;
290  local_nodes_indices[elem_idx] = local_idx;
291  }
292  }
293  }
294  }
295  }
296  }
297  } else {
298  nodes_indices.resize(0, false);
299  local_nodes_indices.resize(0, false);
300  }
301 
302  } else {
303  nodes_indices.resize(0, false);
304  local_nodes_indices.resize(0, false);
305  }
306 
308 }
309 
312  const int bit_number) const {
313 
314  struct Extractor {
315  boost::weak_ptr<EntityCacheNumeredDofs>
316  operator()(boost::shared_ptr<FieldEntity> &e) {
317  return e->entityCacheRowDofs;
318  }
319  };
320 
321  return getNodesIndices(bit_number, getRowFieldEnts(),
322  data.dataOnEntities[MBVERTEX][0].getIndices(),
323  data.dataOnEntities[MBVERTEX][0].getLocalIndices(),
324  Extractor());
325 }
326 
329  const int bit_number) const {
330 
331  struct Extractor {
332  boost::weak_ptr<EntityCacheNumeredDofs>
333  operator()(boost::shared_ptr<FieldEntity> &e) {
334  return e->entityCacheColDofs;
335  }
336  };
337 
338  return getNodesIndices(bit_number, getColFieldEnts(),
339  data.dataOnEntities[MBVERTEX][0].getIndices(),
340  data.dataOnEntities[MBVERTEX][0].getLocalIndices(),
341  Extractor());
342 }
343 
344 template <typename EXTRACTOR>
346  EntitiesFieldData &data, const int bit_number,
347  FieldEntity_vector_view &ents_field, const EntityType type_lo,
348  const EntityType type_hi, EXTRACTOR &&extractor) const {
350 
351  for (EntityType t = type_lo; t != type_hi; ++t) {
352  for (auto &dat : data.dataOnEntities[t]) {
353  dat.getIndices().resize(0, false);
354  dat.getLocalIndices().resize(0, false);
355  }
356  }
357 
358  const auto lo_uid = FieldEntity::getLocalUniqueIdCalculate(
359  bit_number, get_id_for_min_type(type_lo));
360  auto lo = std::lower_bound(ents_field.begin(), ents_field.end(), lo_uid,
361  cmp_uid_lo);
362  if (lo != ents_field.end()) {
363  const auto hi_uid = FieldEntity::getLocalUniqueIdCalculate(
364  bit_number, get_id_for_max_type(type_hi));
365  auto hi = std::upper_bound(lo, ents_field.end(), hi_uid, cmp_uid_hi);
366  if (lo != hi) {
367 
368  std::vector<boost::weak_ptr<FieldEntity>> brother_ents_vec;
369 
370  for (auto it = lo; it != hi; ++it)
371  if (auto e = it->lock()) {
372 
373  const EntityType type = e->getEntType();
374  auto side_ptr = e->getSideNumberPtr();
375  if (const auto side = side_ptr->side_number; side >= 0) {
376  const auto nb_dofs_on_ent = e->getNbDofsOnEnt();
377  const auto brother_side = side_ptr->brother_side_number;
378  auto &dat = data.dataOnEntities[type][side];
379  auto &ent_field_indices = dat.getIndices();
380  auto &ent_field_local_indices = dat.getLocalIndices();
381 
382  ent_field_indices.resize(nb_dofs_on_ent, false);
383  ent_field_local_indices.resize(nb_dofs_on_ent, false);
384  std::fill(ent_field_indices.data().begin(),
385  ent_field_indices.data().end(), -1);
386  std::fill(ent_field_local_indices.data().begin(),
387  ent_field_local_indices.data().end(), -1);
388 
389  if (auto cache = extractor(e).lock()) {
390  for (auto dit = cache->loHi[0]; dit != cache->loHi[1]; ++dit) {
391  const int idx = (*dit)->getEntDofIdx();
392  ent_field_indices[idx] = (*dit)->getPetscGlobalDofIdx();
393  ent_field_local_indices[idx] = (*dit)->getPetscLocalDofIdx();
394  }
395  }
396 
397  if (brother_side != -1) {
398  auto &dat_brother = data.dataOnEntities[type][brother_side];
399  dat_brother.getIndices().resize(nb_dofs_on_ent, false);
400  dat_brother.getLocalIndices().resize(nb_dofs_on_ent, false);
401  noalias(dat_brother.getIndices()) = dat.getIndices();
402  noalias(dat_brother.getLocalIndices()) = dat.getLocalIndices();
403  }
404  }
405  }
406  }
407  }
408 
410 }
411 
413  EntitiesFieldData &data, const int bit_number, const EntityType type_lo,
414  const EntityType type_hi) const {
415 
416  struct Extractor {
417  boost::weak_ptr<EntityCacheNumeredDofs>
418  operator()(boost::shared_ptr<FieldEntity> &e) {
419  return e->entityCacheRowDofs;
420  }
421  };
422 
423  return getEntityIndices(data, bit_number, getRowFieldEnts(), type_lo, type_hi,
424  Extractor());
425 }
426 
428  EntitiesFieldData &data, const int bit_number, const EntityType type_lo,
429  const EntityType type_hi) const {
430 
431  struct Extractor {
432  boost::weak_ptr<EntityCacheNumeredDofs>
433  operator()(boost::shared_ptr<FieldEntity> &e) {
434  return e->entityCacheColDofs;
435  }
436  };
437 
438  return getEntityIndices(data, bit_number, getColFieldEnts(), type_lo, type_hi,
439  Extractor());
440 }
441 
443  const int bit_number, boost::shared_ptr<FENumeredDofEntity_multiIndex> dofs,
444  VectorInt &indices) const {
446  auto dit = dofs->get<Unique_mi_tag>().lower_bound(
447  FieldEntity::getLoBitNumberUId(bit_number));
448  auto hi_dit = dofs->get<Unique_mi_tag>().upper_bound(
449  FieldEntity::getHiBitNumberUId(bit_number));
450  indices.resize(std::distance(dit, hi_dit));
451  for (; dit != hi_dit; dit++) {
452  int idx = (*dit)->getPetscGlobalDofIdx();
453  indices[(*dit)->getDofCoeffIdx()] = idx;
454  }
456 }
457 
460  const int bit_number) const {
462 #ifndef NDEBUG
463  if (data.dataOnEntities[MBENTITYSET].size() == 0) {
464  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
465  "data.dataOnEntities[MBENTITYSET] is empty");
466  }
467 #endif
468  CHKERR getNoFieldIndices(bit_number, getRowDofsPtr(),
469  data.dataOnEntities[MBENTITYSET][0].getIndices());
471 }
472 
475  const int bit_number) const {
477 #ifndef NDEBUG
478  if (data.dataOnEntities[MBENTITYSET].size() == 0) {
479  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
480  "data.dataOnEntities[MBENTITYSET] is empty");
481  }
482 #endif
483  CHKERR getNoFieldIndices(bit_number, getColDofsPtr(),
484  data.dataOnEntities[MBENTITYSET][0].getIndices());
486 }
487 
488 // ** Indices from problem **
489 
491  const std::string &field_name, const NumeredDofEntity_multiIndex &dofs,
492  VectorInt &nodes_indices) const {
494 
495  const Field *field_struture = mField.get_field_structure(field_name);
496  if (field_struture->getSpace() == H1) {
497 
498  const int num_nodes = getNumberOfNodes();
499  nodes_indices.resize(field_struture->getNbOfCoeffs() * num_nodes, false);
500  std::fill(nodes_indices.begin(), nodes_indices.end(), -1);
501 
502  auto &side_table = const_cast<SideNumber_multiIndex &>(
503  numeredEntFiniteElementPtr->getSideNumberTable());
504  auto siit = side_table.get<1>().lower_bound(boost::make_tuple(MBVERTEX, 0));
505  auto hi_siit =
506  side_table.get<1>().lower_bound(boost::make_tuple(MBVERTEX, 10000));
507 
508  int nn = 0;
509  for (; siit != hi_siit; siit++, nn++) {
510  if (siit->get()->side_number >= 0) {
511  auto bit_number = mField.get_field_bit_number(field_name);
512  const EntityHandle ent = siit->get()->ent;
513  auto dit = dofs.get<Unique_mi_tag>().lower_bound(
514  FieldEntity::getLoLocalEntityBitNumber(bit_number, ent));
515  auto hi_dit = dofs.get<Unique_mi_tag>().upper_bound(
516  FieldEntity::getHiLocalEntityBitNumber(bit_number, ent));
517  for (; dit != hi_dit; dit++) {
518  nodes_indices[siit->get()->side_number * (*dit)->getNbOfCoeffs() +
519  (*dit)->getDofCoeffIdx()] =
520  (*dit)->getPetscGlobalDofIdx();
521  }
522  }
523  }
524  } else {
525  nodes_indices.resize(0, false);
526  }
527 
529 }
530 
532  const std::string &field_name, const NumeredDofEntity_multiIndex &dofs,
533  EntityType type, int side_number, VectorInt &indices) const {
535 
536  indices.resize(0);
537 
538  auto &side_table = const_cast<SideNumber_multiIndex &>(
539  numeredEntFiniteElementPtr->getSideNumberTable());
540  auto siit =
541  side_table.get<1>().lower_bound(boost::make_tuple(type, side_number));
542  auto hi_siit =
543  side_table.get<1>().upper_bound(boost::make_tuple(type, side_number));
544 
545  for (; siit != hi_siit; siit++) {
546  if (siit->get()->side_number >= 0) {
547 
548  const EntityHandle ent = siit->get()->ent;
549  auto bit_number = mField.get_field_bit_number(field_name);
550  auto dit = dofs.get<Unique_mi_tag>().lower_bound(
551  FieldEntity::getLoLocalEntityBitNumber(bit_number, ent));
552  auto hi_dit = dofs.get<Unique_mi_tag>().upper_bound(
553  FieldEntity::getHiLocalEntityBitNumber(bit_number, ent));
554  indices.resize(std::distance(dit, hi_dit));
555  for (; dit != hi_dit; dit++) {
556 
557  indices[(*dit)->getEntDofIdx()] = (*dit)->getPetscGlobalDofIdx();
558  }
559  }
560  }
561 
563 }
564 
566  const std::string &field_name, VectorInt &nodes_indices) const {
568  nodes_indices);
569 }
570 
573  EntityType type, int side_number,
574  VectorInt &indices) const {
576  type, side_number, indices);
577 }
578 
580  const std::string &field_name, VectorInt &nodes_indices) const {
582  nodes_indices);
583 }
584 
587  EntityType type, int side_number,
588  VectorInt &indices) const {
590  type, side_number, indices);
591 }
592 
593 // ** Data **
594 
597 
598  for (auto &data : dataOnElement) {
599  if (data) {
600  for (auto &dat : data->dataOnEntities) {
601  for (auto &ent_dat : dat) {
602  ent_dat.getEntDataBitRefLevel().clear();
603  }
604  }
605  }
606  }
607 
608  auto &field_ents = getDataFieldEnts();
609  for (auto it : field_ents) {
610  if (auto e = it.lock()) {
611  const FieldSpace space = e->getSpace();
612  if (space > NOFIELD) {
613  const EntityType type = e->getEntType();
614  const signed char side = e->getSideNumberPtr()->side_number;
615  if (side >= 0) {
616  if (auto &data = dataOnElement[space]) {
617  if (type == MBVERTEX) {
618  auto &dat = data->dataOnEntities[type][0];
619  dat.getEntDataBitRefLevel().resize(getNumberOfNodes(), false);
620  dat.getEntDataBitRefLevel()[side] = e->getBitRefLevel();
621  } else {
622  auto &dat = data->dataOnEntities[type][side];
623  dat.getEntDataBitRefLevel().resize(1, false);
624  dat.getEntDataBitRefLevel()[0] = e->getBitRefLevel();
625  }
626  }
627  }
628  } else {
629  if (auto &data = dataOnElement[NOFIELD]) {
630  auto &dat = data->dataOnEntities[MBENTITYSET][0];
631  dat.getEntDataBitRefLevel().resize(1, false);
632  dat.getEntDataBitRefLevel()[0] = e->getBitRefLevel();
633  }
634  }
635  }
636  }
637 
639 };
640 
643  const int bit_number) const {
644 
645  auto get_nodes_field_data = [&](VectorDouble &nodes_data,
646  VectorFieldEntities &field_entities,
647  VectorDofs &nodes_dofs, FieldSpace &space,
649  VectorInt &bb_node_order) {
651 
652  nodes_data.resize(0, false);
653  nodes_dofs.resize(0, false);
654  field_entities.resize(0, false);
655 
656  auto field_it =
657  fieldsPtr->get<BitFieldId_mi_tag>().find(BitFEId().set(bit_number - 1));
658  if (field_it != fieldsPtr->get<BitFieldId_mi_tag>().end()) {
659 
660 #ifndef NDEBUG
661  if ((*field_it)->getBitNumber() != bit_number)
662  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "Wrong bit number");
663 #endif
664  const int nb_dofs_on_vert = (*field_it)->getNbOfCoeffs();
665  space = (*field_it)->getSpace();
666  base = (*field_it)->getApproxBase();
667 
668  auto &field_ents = getDataFieldEnts();
669  const auto lo_uid = FieldEntity::getLocalUniqueIdCalculate(
670  bit_number, get_id_for_min_type<MBVERTEX>());
671  auto lo = std::lower_bound(field_ents.begin(), field_ents.end(), lo_uid,
672  cmp_uid_lo);
673  if (lo != field_ents.end()) {
674  const auto hi_uid = FieldEntity::getLocalUniqueIdCalculate(
675  bit_number, get_id_for_max_type<MBVERTEX>());
676  auto hi = std::upper_bound(lo, field_ents.end(), hi_uid, cmp_uid_hi);
677  if (lo != hi) {
678 
679  int nb_dofs = 0;
680  for (auto it = lo; it != hi; ++it) {
681  if (auto e = it->lock()) {
682  if (auto cache = e->entityCacheDataDofs.lock()) {
683  if (cache->loHi[0] != cache->loHi[1]) {
684  nb_dofs += std::distance(cache->loHi[0], cache->loHi[1]);
685  break;
686  }
687  }
688  }
689  }
690 
691  if (nb_dofs) {
692 
693  const int num_nodes = getNumberOfNodes();
694  bb_node_order.resize(num_nodes, false);
695  bb_node_order.clear();
696  const int max_nb_dofs = nb_dofs_on_vert * num_nodes;
697  nodes_data.resize(max_nb_dofs, false);
698  nodes_dofs.resize(max_nb_dofs, false);
699  field_entities.resize(num_nodes, false);
700  std::fill(nodes_data.begin(), nodes_data.end(), 0);
701  std::fill(nodes_dofs.begin(), nodes_dofs.end(), nullptr);
702  std::fill(field_entities.begin(), field_entities.end(), nullptr);
703 
704  std::vector<boost::weak_ptr<FieldEntity>> brother_ents_vec;
705 
706  for (auto it = lo; it != hi; ++it) {
707  if (auto e = it->lock()) {
708  const auto &sn = e->getSideNumberPtr();
709  // Some field entities on skeleton can have negative side
710  // number
711  if (const auto side_number = sn->side_number;
712  side_number >= 0) {
713  const int brother_side_number = sn->brother_side_number;
714 
715  field_entities[side_number] = e.get();
716  if (brother_side_number != -1) {
717  brother_ents_vec.emplace_back(e);
718  field_entities[side_number] = field_entities[side_number];
719  }
720 
721  bb_node_order[side_number] = e->getMaxOrder();
722  int pos = side_number * nb_dofs_on_vert;
723  auto ent_filed_data_vec = e->getEntFieldData();
724  if (auto cache = e->entityCacheDataDofs.lock()) {
725  for (auto dit = cache->loHi[0]; dit != cache->loHi[1];
726  ++dit) {
727  const auto dof_idx = (*dit)->getEntDofIdx();
728  nodes_data[pos + dof_idx] = ent_filed_data_vec[dof_idx];
729  nodes_dofs[pos + dof_idx] =
730  reinterpret_cast<FEDofEntity *>((*dit).get());
731  }
732  }
733  }
734  }
735  }
736 
737  for (auto &it : brother_ents_vec) {
738  if (const auto e = it.lock()) {
739  const auto &sn = e->getSideNumberPtr();
740  const int side_number = sn->side_number;
741  const int brother_side_number = sn->brother_side_number;
742  bb_node_order[brother_side_number] = bb_node_order[side_number];
743  int pos = side_number * nb_dofs_on_vert;
744  int brother_pos = brother_side_number * nb_dofs_on_vert;
745  for (int ii = 0; ii != nb_dofs_on_vert; ++ii) {
746  nodes_data[brother_pos] = nodes_data[pos];
747  nodes_dofs[brother_pos] = nodes_dofs[pos];
748  ++pos;
749  ++brother_pos;
750  }
751  }
752  }
753  }
754  }
755  }
756  }
757 
759  };
760 
761  return get_nodes_field_data(
762  data.dataOnEntities[MBVERTEX][0].getFieldData(),
763  data.dataOnEntities[MBVERTEX][0].getFieldEntities(),
764  data.dataOnEntities[MBVERTEX][0].getFieldDofs(),
765  data.dataOnEntities[MBVERTEX][0].getSpace(),
766  data.dataOnEntities[MBVERTEX][0].getBase(),
767  data.dataOnEntities[MBVERTEX][0].getBBNodeOrder());
768 }
769 
771  EntitiesFieldData &data, const int bit_number, const EntityType type_lo,
772  const EntityType type_hi) const {
774  for (EntityType t = type_lo; t != type_hi; ++t) {
775  for (auto &dat : data.dataOnEntities[t]) {
776  dat.getOrder() = 0;
777  dat.getBase() = NOBASE;
778  dat.getSpace() = NOSPACE;
779  dat.getFieldData().resize(0, false);
780  dat.getFieldDofs().resize(0, false);
781  dat.getFieldEntities().resize(0, false);
782  }
783  }
784 
785  auto &field_ents = getDataFieldEnts();
786  const auto lo_uid = FieldEntity::getLocalUniqueIdCalculate(
787  bit_number, get_id_for_min_type(type_lo));
788  auto lo = std::lower_bound(field_ents.begin(), field_ents.end(), lo_uid,
789  cmp_uid_lo);
790  if (lo != field_ents.end()) {
791  const auto hi_uid = FieldEntity::getLocalUniqueIdCalculate(
792  bit_number, get_id_for_max_type(type_hi));
793  auto hi = std::upper_bound(lo, field_ents.end(), hi_uid, cmp_uid_hi);
794  if (lo != hi) {
795 
796  std::vector<boost::weak_ptr<FieldEntity>> brother_ents_vec;
797 
798  for (auto it = lo; it != hi; ++it)
799  if (auto e = it->lock()) {
800  auto side_ptr = e->getSideNumberPtr();
801  if (const auto side = side_ptr->side_number; side >= 0) {
802  const EntityType type = e->getEntType();
803  auto &dat = data.dataOnEntities[type][side];
804  auto &ent_field = dat.getFieldEntities();
805  auto &ent_field_dofs = dat.getFieldDofs();
806  auto &ent_field_data = dat.getFieldData();
807 
808  const int brother_side = side_ptr->brother_side_number;
809  if (brother_side != -1)
810  brother_ents_vec.emplace_back(e);
811 
812  dat.getBase() = e->getApproxBase();
813  dat.getSpace() = e->getSpace();
814  const int ent_order = e->getMaxOrder();
815  dat.getOrder() =
816  dat.getOrder() > ent_order ? dat.getOrder() : ent_order;
817 
818  auto ent_data = e->getEntFieldData();
819  ent_field_data.resize(ent_data.size(), false);
820  noalias(ent_field_data) = ent_data;
821  ent_field_dofs.resize(ent_data.size(), false);
822  std::fill(ent_field_dofs.begin(), ent_field_dofs.end(), nullptr);
823  ent_field.resize(1, false);
824  ent_field[0] = e.get();
825  if (auto cache = e->entityCacheDataDofs.lock()) {
826  for (auto dit = cache->loHi[0]; dit != cache->loHi[1]; ++dit) {
827  ent_field_dofs[(*dit)->getEntDofIdx()] =
828  reinterpret_cast<FEDofEntity *>((*dit).get());
829  }
830  }
831  }
832  }
833 
834  for (auto &it : brother_ents_vec) {
835  if (const auto e = it.lock()) {
836  const EntityType type = e->getEntType();
837  const int side = e->getSideNumberPtr()->side_number;
838  const int brother_side = e->getSideNumberPtr()->brother_side_number;
839  auto &dat = data.dataOnEntities[type][side];
840  auto &dat_brother = data.dataOnEntities[type][brother_side];
841  dat_brother.getBase() = dat.getBase();
842  dat_brother.getSpace() = dat.getSpace();
843  dat_brother.getOrder() = dat.getOrder();
844  dat_brother.getFieldData() = dat.getFieldData();
845  dat_brother.getFieldDofs() = dat.getFieldDofs();
846  dat_brother.getFieldEntities() = dat.getFieldEntities();
847  }
848  }
849  }
850  }
851 
853 }
854 
856  const int bit_number, VectorDouble &ent_field_data,
857  VectorDofs &ent_field_dofs, VectorFieldEntities &ent_field) const {
858 
860 
861  ent_field_data.resize(0, false);
862  ent_field_dofs.resize(0, false);
863  ent_field.resize(0, false);
864 
865  auto &field_ents = getDataFieldEnts();
866  const auto lo_uid = FieldEntity::getLocalUniqueIdCalculate(
867  bit_number, get_id_for_min_type<MBVERTEX>());
868  auto lo = std::lower_bound(field_ents.begin(), field_ents.end(), lo_uid,
869  cmp_uid_lo);
870  if (lo != field_ents.end()) {
871 
872  ent_field.resize(field_ents.size(), false);
873  std::fill(ent_field.begin(), ent_field.end(), nullptr);
874 
875  const auto hi_uid = FieldEntity::getLocalUniqueIdCalculate(
876  bit_number, get_id_for_max_type<MBENTITYSET>());
877  auto hi = std::upper_bound(lo, field_ents.end(), hi_uid, cmp_uid_hi);
878  if (lo != hi) {
879 
880  int side = 0;
881  for (auto it = lo; it != hi; ++it, ++side)
882  if (auto e = it->lock()) {
883 
884  const auto size = e->getNbDofsOnEnt();
885  ent_field_data.resize(size, false);
886  ent_field_dofs.resize(size, false);
887  ent_field[side] = e.get();
888  noalias(ent_field_data) = e->getEntFieldData();
889 
890  if (auto cache = e->entityCacheDataDofs.lock()) {
891  for (auto dit = cache->loHi[0]; dit != cache->loHi[1]; ++dit) {
892  ent_field_dofs[(*dit)->getEntDofIdx()] =
893  reinterpret_cast<FEDofEntity *>((*dit).get());
894  }
895  }
896  }
897  }
898  }
899 
901 }
902 
905  const int bit_number) const {
907  if (data.dataOnEntities[MBENTITYSET].size() == 0)
908  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
909  "No space to insert data");
910 
912  bit_number, data.dataOnEntities[MBENTITYSET][0].getFieldData(),
913  data.dataOnEntities[MBENTITYSET][0].getFieldDofs(),
914  data.dataOnEntities[MBENTITYSET][0].getFieldEntities());
916 }
917 
918 // ** Face **
919 
923  auto &face_nodes = data.facesNodes;
924  auto &face_nodes_order = data.facesNodesOrder;
925  auto &side_table = const_cast<SideNumber_multiIndex &>(
926  numeredEntFiniteElementPtr->getSideNumberTable());
927  const auto ent = numeredEntFiniteElementPtr->getEnt();
928  const auto type = numeredEntFiniteElementPtr->getEntType();
929  const auto nb_faces = CN::NumSubEntities(type, 2);
930  const EntityHandle *conn_ele;
931  int num_nodes_ele;
932  CHKERR mField.get_moab().get_connectivity(ent, conn_ele, num_nodes_ele, true);
933  auto side_ptr_it = side_table.get<1>().lower_bound(
934  boost::make_tuple(CN::TypeDimensionMap[2].first, 0));
935  auto hi_side_ptr_it = side_table.get<1>().upper_bound(
936  boost::make_tuple(CN::TypeDimensionMap[2].second, 100));
937 
938  for (; side_ptr_it != hi_side_ptr_it; ++side_ptr_it) {
939  const auto side = (*side_ptr_it)->side_number;
940  const auto sense = (*side_ptr_it)->sense;
941  const auto offset = (*side_ptr_it)->offset;
942 
943  EntityType face_type;
944  int nb_nodes_face;
945  auto face_indices =
946  CN::SubEntityVertexIndices(type, 2, side, face_type, nb_nodes_face);
947  face_nodes.resize(nb_faces, nb_nodes_face);
948  face_nodes_order.resize(nb_faces, nb_nodes_face);
949 
950  if (sense == 1)
951  for (int n = 0; n != nb_nodes_face; ++n)
952  face_nodes_order(side, n) = (n + offset) % nb_nodes_face;
953  else
954  for (int n = 0; n != nb_nodes_face; ++n)
955  face_nodes_order(side, n) =
956  (nb_nodes_face - (n - offset) % nb_nodes_face) % nb_nodes_face;
957 
958  for (int n = 0; n != nb_nodes_face; ++n)
959  face_nodes(side, n) = face_indices[face_nodes_order(side, n)];
960 
961 #ifndef NDEBUG
962  const auto face_ent = (*side_ptr_it)->ent;
963  auto check = [&]() {
965  const EntityHandle *conn_face;
966  // int nb_nodes_face;
967  CHKERR mField.get_moab().get_connectivity(face_ent, conn_face,
968  nb_nodes_face, true);
969  face_nodes.resize(nb_faces, nb_nodes_face);
970  for (int nn = 0; nn != nb_nodes_face; ++nn) {
971  if (face_nodes(side, nn) !=
972  std::distance(
973  conn_ele,
974  std::find(conn_ele, &conn_ele[num_nodes_ele], conn_face[nn]))) {
975  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
976  "Wrong face numeration");
977  }
978  }
980  };
981  CHKERR check();
982 #endif
983  }
984 
986 }
987 
988 // ** Space and Base **
989 
991  EntitiesFieldData &data) const {
993 
994  if (nInTheLoop == 0) {
995  data.bAse.reset();
996  for (EntityType t = MBVERTEX; t != MBMAXTYPE; ++t) {
997  data.spacesOnEntities[t].reset();
998  data.basesOnEntities[t].reset();
999  }
1000  for (int s = 0; s != LASTSPACE; ++s) {
1001  data.basesOnSpaces[s].reset();
1002  data.brokenBasesOnSpaces[s].reset();
1003  }
1004  }
1005 
1006  auto fe_type = numeredEntFiniteElementPtr->getEntType();
1007 
1008  if (getDataFieldEntsPtr())
1009  for (auto e : getDataFieldEnts()) {
1010  if (auto ptr = e.lock()) {
1011  // get data from entity
1012  const EntityType type = ptr->getEntType();
1014  const FieldSpace space = ptr->getSpace();
1015  const FieldContinuity continuity = ptr->getContinuity();
1016  const FieldApproximationBase approx = ptr->getApproxBase();
1017 
1018  // set data
1019  switch (continuity) {
1020  case CONTINUOUS:
1021  data.basesOnSpaces[space].set(approx);
1022  break;
1023  case DISCONTINUOUS:
1024  data.brokenBasesOnSpaces[space].set(approx);
1025  break;
1026  default:
1027  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1028  "Continuity not defined");
1029  }
1030 
1031  data.bAse.set(approx);
1032  data.spacesOnEntities[type].set(space);
1033  data.basesOnEntities[type].set(approx);
1034  }
1035  }
1036  }
1037  else
1038  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1039  "data fields ents not allocated on element");
1040 
1041  for (auto space = 0; space != LASTSPACE; ++space)
1042  if ((data.brokenBasesOnSpaces[space] & data.basesOnSpaces[space]).any())
1043  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1044  "Discontinuous and continuous bases on the same space");
1045 
1047 }
1048 
1050  const FieldApproximationBase b) {
1052  if (dataOnElement[H1]->bAse.test(b)) {
1053 
1054  switch (static_cast<FieldApproximationBase>(b)) {
1055  case NOBASE:
1057  // BERNSTEIN_BEZIER_BASE is not hierarchical base
1059  }
1060  default:
1061  break;
1062  }
1063 
1064  auto get_elem_base = [&](auto base) {
1065  if (b != USER_BASE) {
1066  if (!getElementPolynomialBase())
1069  "Functions generating approximation base not defined");
1070  return getElementPolynomialBase();
1071  } else {
1072  if (!getUserPolynomialBase())
1075  "Functions generating user approximation base not defined");
1076  return getUserPolynomialBase();
1077  }
1078  };
1079 
1080  auto get_ctx = [&](auto space, auto base, auto continuity) {
1081  return boost::make_shared<EntPolynomialBaseCtx>(
1082  *dataOnElement[space], static_cast<FieldSpace>(space), continuity,
1083  static_cast<FieldApproximationBase>(base), NOBASE);
1084  };
1085 
1086  auto get_value = [&](auto elem_base, auto &gaussPts, auto &&ctx) {
1087  return elem_base->getValue(gaussPts, ctx);
1088  };
1089 
1090  for (int space = H1; space != LASTSPACE; ++space) {
1091 
1092 #ifndef NDEBUG
1093  if (dataOnElement[H1]->basesOnSpaces[space].test(b) &&
1094  dataOnElement[H1]->brokenBasesOnSpaces[space].test(b)) {
1095  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1096  "Discontinuous and continuous bases on the same space");
1097  }
1098 #endif // NDEBUG
1099 
1100  if (dataOnElement[H1]->basesOnSpaces[space].test(b))
1101  CHKERR get_value(get_elem_base(b), gaussPts,
1102  get_ctx(space, b, CONTINUOUS));
1103  else if (dataOnElement[H1]->brokenBasesOnSpaces[space].test(b))
1104  CHKERR get_value(get_elem_base(b), gaussPts,
1105  get_ctx(space, b, DISCONTINUOUS));
1106  }
1107 
1108  }
1110 }
1111 
1114  /// Use the some node base. Node base is usually used for construction other
1115  /// bases.
1116  for (int space = HCURL; space != LASTSPACE; ++space) {
1117  dataOnElement[space]->dataOnEntities[MBVERTEX][0].getNSharedPtr(NOBASE) =
1118  dataOnElement[H1]->dataOnEntities[MBVERTEX][0].getNSharedPtr(NOBASE);
1119  dataOnElement[space]->dataOnEntities[MBVERTEX][0].getDiffNSharedPtr(
1120  NOBASE) =
1121  dataOnElement[H1]->dataOnEntities[MBVERTEX][0].getDiffNSharedPtr(
1122  NOBASE);
1123  }
1124  for (int b = AINSWORTH_LEGENDRE_BASE; b != LASTBASE; b++) {
1126  static_cast<FieldApproximationBase>(b));
1127  }
1129 }
1130 
1134 
1135  const auto ele_type = numeredEntFiniteElementPtr->getEntType();
1136 
1137  auto get_nodal_base_data = [&](EntitiesFieldData &data, auto field_ptr) {
1139  auto &space = data.dataOnEntities[MBVERTEX][0].getSpace();
1140  auto &base = data.dataOnEntities[MBVERTEX][0].getBase();
1141  auto &bb_node_order = data.dataOnEntities[MBVERTEX][0].getBBNodeOrder();
1142 
1143  auto &field_ents = getDataFieldEnts();
1144  auto bit_number = field_ptr->getBitNumber();
1145  const auto lo_uid = FieldEntity::getLocalUniqueIdCalculate(
1146  bit_number, get_id_for_min_type<MBVERTEX>());
1147  auto lo = std::lower_bound(field_ents.begin(), field_ents.end(), lo_uid,
1148  cmp_uid_lo);
1149  if (lo != field_ents.end()) {
1150  const auto hi_uid = FieldEntity::getLocalUniqueIdCalculate(
1151  bit_number, get_id_for_max_type<MBVERTEX>());
1152  auto hi = std::upper_bound(lo, field_ents.end(), hi_uid, cmp_uid_hi);
1153  if (lo != hi) {
1154 
1155  for (auto it = lo; it != hi; ++it)
1156  if (auto first_e = it->lock()) {
1157  space = first_e->getSpace();
1158  base = first_e->getApproxBase();
1159  const int num_nodes = getNumberOfNodes();
1160  bb_node_order.resize(num_nodes, false);
1161  bb_node_order.clear();
1162 
1163  std::vector<boost::weak_ptr<FieldEntity>> brother_ents_vec;
1164 
1165  for (; it != hi; ++it) {
1166  if (auto e = it->lock()) {
1167  const auto &sn = e->getSideNumberPtr();
1168  const int side_number = sn->side_number;
1169  const int brother_side_number = sn->brother_side_number;
1170  if (brother_side_number != -1)
1171  brother_ents_vec.emplace_back(e);
1172  bb_node_order[side_number] = e->getMaxOrder();
1173  }
1174  }
1175 
1176  for (auto &it : brother_ents_vec) {
1177  if (const auto e = it.lock()) {
1178  const auto &sn = e->getSideNumberPtr();
1179  const int side_number = sn->side_number;
1180  const int brother_side_number = sn->brother_side_number;
1181  bb_node_order[brother_side_number] = bb_node_order[side_number];
1182  }
1183  }
1184 
1185  break;
1186  }
1187  }
1188  }
1189 
1191  };
1192 
1193  auto get_entity_base_data = [&](EntitiesFieldData &data, auto field_ptr,
1194  const EntityType type_lo,
1195  const EntityType type_hi) {
1197  for (EntityType t = MBEDGE; t != MBPOLYHEDRON; ++t) {
1198  for (auto &dat : data.dataOnEntities[t]) {
1199  dat.getOrder() = 0;
1200  dat.getBase() = NOBASE;
1201  dat.getSpace() = NOSPACE;
1202  dat.getFieldData().resize(0, false);
1203  dat.getFieldDofs().resize(0, false);
1204  }
1205  }
1206 
1207  auto &field_ents = getDataFieldEnts();
1208  auto bit_number = field_ptr->getBitNumber();
1209  const auto lo_uid = FieldEntity::getLocalUniqueIdCalculate(
1210  bit_number, get_id_for_min_type(type_lo));
1211  auto lo = std::lower_bound(field_ents.begin(), field_ents.end(), lo_uid,
1212  cmp_uid_lo);
1213  if (lo != field_ents.end()) {
1214  const auto hi_uid = FieldEntity::getLocalUniqueIdCalculate(
1215  bit_number, get_id_for_max_type(type_hi));
1216  auto hi = std::upper_bound(lo, field_ents.end(), hi_uid, cmp_uid_hi);
1217 
1218  std::vector<boost::weak_ptr<FieldEntity>> brother_ents_vec;
1219  for (; lo != hi; ++lo) {
1220  if (auto e = lo->lock()) {
1221  if (auto cache = e->entityCacheDataDofs.lock()) {
1222  if (cache->loHi[0] != cache->loHi[1]) {
1223  if (const auto side = e->getSideNumberPtr()->side_number;
1224  side >= 0) {
1225  const EntityType type = e->getEntType();
1226  auto &dat = data.dataOnEntities[type][side];
1227  const int brother_side =
1228  e->getSideNumberPtr()->brother_side_number;
1229  if (brother_side != -1)
1230  brother_ents_vec.emplace_back(e);
1231  dat.getBase() = e->getApproxBase();
1232  dat.getSpace() = e->getSpace();
1233  const auto ent_order = e->getMaxOrder();
1234  dat.getOrder() =
1235  dat.getOrder() > ent_order ? dat.getOrder() : ent_order;
1236  }
1237  }
1238  }
1239  }
1240  }
1241 
1242  for (auto &ent_ptr : brother_ents_vec) {
1243  if (auto e = ent_ptr.lock()) {
1244  const EntityType type = e->getEntType();
1245  const int side = e->getSideNumberPtr()->side_number;
1246  const int brother_side = e->getSideNumberPtr()->brother_side_number;
1247  auto &dat = data.dataOnEntities[type][side];
1248  auto &dat_brother = data.dataOnEntities[type][brother_side];
1249  dat_brother.getBase() = dat.getBase();
1250  dat_brother.getSpace() = dat.getSpace();
1251  dat_brother.getOrder() = dat.getOrder();
1252  }
1253  }
1254  }
1256  };
1257 
1258  for (auto &e : getDataFieldEnts()) {
1259  if (auto ent_data_ptr = e.lock()) {
1260  if (ent_data_ptr->getApproxBase() == AINSWORTH_BERNSTEIN_BEZIER_BASE) {
1261  auto space = ent_data_ptr->getSpace();
1262  for (EntityType t = MBVERTEX; t != MBPOLYHEDRON; ++t) {
1263  for (auto &dat : (*dataOnElement[space]).dataOnEntities[t]) {
1264  for (auto &ptr : dat.getBBAlphaIndicesByOrderArray())
1265  ptr.reset();
1266  for (auto &ptr : dat.getBBNByOrderArray())
1267  ptr.reset();
1268  for (auto &ptr : dat.getBBDiffNByOrderArray())
1269  ptr.reset();
1270  }
1271  }
1272  }
1273  }
1274  }
1275 
1276  auto check_space = [&](const auto space) {
1277  switch (space) {
1278  case H1:
1279  for (auto t = MBVERTEX; t <= ele_type; ++t) {
1280  if (dataOnElement[H1]->spacesOnEntities[t].test(H1))
1281  return true;
1282  }
1283  return false;
1284  case HCURL:
1285  for (auto t = MBEDGE; t <= ele_type; ++t) {
1286  if (dataOnElement[HCURL]->spacesOnEntities[t].test(HCURL))
1287  return true;
1288  }
1289  return false;
1290  case HDIV:
1291  for (auto t = MBTRI; t <= ele_type; ++t) {
1292  if (dataOnElement[HDIV]->spacesOnEntities[t].test(HDIV))
1293  return true;
1294  }
1295  return false;
1296  case L2:
1297  return dataOnElement[L2]->spacesOnEntities[ele_type].test(L2);
1298  break;
1299  default:
1300  THROW_MESSAGE("Not implemented");
1301  }
1302  };
1303 
1304  std::set<string> fields_list;
1305  for (auto &e : getDataFieldEnts()) {
1306  if (auto ent_data_ptr = e.lock()) {
1307  if (ent_data_ptr->getApproxBase() == AINSWORTH_BERNSTEIN_BEZIER_BASE) {
1308  auto field_name = ent_data_ptr->getName();
1309  if (fields_list.find(field_name) == fields_list.end()) {
1310  auto field_ptr = ent_data_ptr->getFieldRawPtr();
1311  auto space = ent_data_ptr->getSpace();
1312  CHKERR get_nodal_base_data(*dataOnElement[space], field_ptr);
1313  CHKERR get_entity_base_data(*dataOnElement[space], field_ptr, MBEDGE,
1314  ele_type);
1315  if (check_space(space)) {
1316 #ifndef NDEBUG
1317  if (ent_data_ptr->getContinuity() != CONTINUOUS)
1318  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1319  "Broken space not implemented");
1320 #endif // NDEBUG
1322  -> getValue(gaussPts,
1323  boost::make_shared<EntPolynomialBaseCtx>(
1324  *dataOnElement[space], field_name,
1325  static_cast<FieldSpace>(space), CONTINUOUS,
1327  fields_list.insert(field_name);
1328  }
1329  }
1330  }
1331  }
1332  }
1333 
1335 };
1336 
1339 
1340  // Data on elements for proper spaces
1341  for (int space = H1; space != LASTSPACE; ++space) {
1342  dataOnElement[space]->setElementType(type);
1343  derivedDataOnElement[space]->setElementType(type);
1344  }
1345 
1347 }
1348 
1349 #define FUNCTION_NAME_WITH_OP_NAME(OP) \
1350  std::ostringstream ss; \
1351  ss << "(Calling user data operator " \
1352  << boost::typeindex::type_id_runtime(OP).pretty_name() << " rowField " \
1353  << (OP).rowFieldName << " colField " << (OP).colFieldName << ") "
1354 
1355 #define CATCH_OP_ERRORS(OP) \
1356  catch (MoFEMExceptionInitial const &ex) { \
1357  FUNCTION_NAME_WITH_OP_NAME(OP) << PETSC_FUNCTION_NAME; \
1358  return PetscError(PETSC_COMM_SELF, ex.lINE, ss.str().c_str(), __FILE__, \
1359  ex.errorCode, PETSC_ERROR_INITIAL, ex.what()); \
1360  } \
1361  catch (MoFEMExceptionRepeat const &ex) { \
1362  FUNCTION_NAME_WITH_OP_NAME(OP) << PETSC_FUNCTION_NAME; \
1363  return PetscError(PETSC_COMM_SELF, ex.lINE, ss.str().c_str(), __FILE__, \
1364  ex.errorCode, PETSC_ERROR_REPEAT, " "); \
1365  } \
1366  catch (MoFEMException const &ex) { \
1367  FUNCTION_NAME_WITH_OP_NAME(OP) << ex.errorMessage; \
1368  SETERRQ(PETSC_COMM_SELF, ex.errorCode, ss.str().c_str()); \
1369  } \
1370  catch (std::exception const &ex) { \
1371  std::string message("Error: " + std::string(ex.what()) + " at " + \
1372  boost::lexical_cast<std::string>(__LINE__) + " : " + \
1373  std::string(__FILE__) + " in " + \
1374  std::string(PETSC_FUNCTION_NAME)); \
1375  FUNCTION_NAME_WITH_OP_NAME(OP) << message; \
1376  SETERRQ(PETSC_COMM_SELF, MOFEM_STD_EXCEPTION_THROW, ss.str().c_str()); \
1377  }
1378 
1381 
1382  using UDO = UserDataOperator;
1383 
1384  std::array<std::string, 2> field_name;
1385  std::array<const Field *, 3> field_struture;
1386  std::array<int, 2>
1387  field_id; // note the this is field bit number (nor field bit)
1388  std::array<FieldSpace, 2> space;
1389  std::array<FieldApproximationBase, 2> base;
1390 
1391  constexpr std::array<UDO::OpType, 2> types = {UDO::OPROW, UDO::OPCOL};
1392  std::array<int, 2> last_eval_field_id = {0, 0};
1393 
1394  std::array<boost::shared_ptr<EntitiesFieldData>, 2> op_data;
1395 
1396  auto swap_bases = [&](auto &op) {
1398  for (size_t ss = 0; ss != 2; ++ss) {
1399  if (op.getOpType() & types[ss] || op.getOpType() & UDO::OPROWCOL) {
1400  switch (base[ss]) {
1402  CHKERR op_data[ss]->baseSwap(field_name[ss],
1404  default:
1405  break;
1406  }
1407  }
1408  }
1409 
1411  };
1412 
1413  const EntityType type = numeredEntFiniteElementPtr->getEntType();
1414 
1415  // evaluate entity data only, no field specific data provided or known
1416  auto evaluate_op_space = [&](auto &op) {
1418 
1419  // reseat all data which all field dependent
1420  dataOnElement[op.sPace]->resetFieldDependentData();
1421  std::fill(last_eval_field_id.begin(), last_eval_field_id.end(), 0);
1422 
1423  switch (op.sPace) {
1424  case NOSPACE:
1425  try {
1426  CHKERR op.doWork(
1427  0, MBENTITYSET,
1428  dataOnElement[NOSPACE]->dataOnEntities[MBENTITYSET][0]);
1429  }
1430  CATCH_OP_ERRORS(op);
1431  break;
1432  case NOFIELD:
1433  case H1:
1434  case HCURL:
1435  case HDIV:
1436  case L2:
1437  try {
1438 
1439  for (EntityType t = MBVERTEX; t != MBMAXTYPE; ++t) {
1440  for (auto &e : dataOnElement[op.sPace]->dataOnEntities[t]) {
1441  e.getSpace() = op.sPace;
1442  }
1443  }
1444 
1445  CHKERR op.opRhs(*dataOnElement[op.sPace], false);
1446  }
1447  CATCH_OP_ERRORS(op);
1448  break;
1449  default:
1450  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
1451  "Not implemented for this space", op.sPace);
1452  }
1453 
1455  };
1456 
1457  // set entity data
1458  auto set_op_entities_data = [&](auto ss, auto &op) {
1460 
1461 #ifndef NDEBUG
1462  if ((op.getNumeredEntFiniteElementPtr()->getBitFieldIdData() &
1464  .none()) {
1465  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1466  "no data field < %s > on finite element < %s >",
1467  field_name[ss].c_str(), getFEName().c_str());
1468  }
1469 #endif
1470 
1471  op_data[ss] =
1472  !ss ? dataOnElement[space[ss]] : derivedDataOnElement[space[ss]];
1473 
1474  for (auto &data : op_data[ss]->dataOnEntities[MBENTITYSET]) {
1475  CHKERR data.resetFieldDependentData();
1476  }
1477 
1478  auto get_data_for_nodes = [&]() {
1480  if (!ss)
1481  CHKERR getRowNodesIndices(*op_data[ss], field_id[ss]);
1482  else
1483  CHKERR getColNodesIndices(*op_data[ss], field_id[ss]);
1484  CHKERR getNodesFieldData(*op_data[ss], field_id[ss]);
1486  };
1487 
1488  // get data on entities but not nodes
1489  auto get_data_for_entities = [&]() {
1491  CHKERR getEntityFieldData(*op_data[ss], field_id[ss], MBEDGE);
1492  if (!ss)
1493  CHKERR getEntityRowIndices(*op_data[ss], field_id[ss], MBEDGE);
1494  else
1495  CHKERR getEntityColIndices(*op_data[ss], field_id[ss], MBEDGE);
1497  };
1498 
1499  auto get_data_for_meshset = [&]() {
1501  if (!ss) {
1502  CHKERR getNoFieldRowIndices(*op_data[ss], field_id[ss]);
1503  } else {
1504  CHKERR getNoFieldColIndices(*op_data[ss], field_id[ss]);
1505  }
1506  CHKERR getNoFieldFieldData(*op_data[ss], field_id[ss]);
1508  };
1509 
1510  switch (space[ss]) {
1511  case H1:
1512  CHKERR get_data_for_nodes();
1513  case HCURL:
1514  case HDIV:
1515  CHKERR get_data_for_entities();
1516  break;
1517  case L2:
1518  switch (type) {
1519  case MBVERTEX:
1520  CHKERR get_data_for_nodes();
1521  break;
1522  default:
1523  CHKERR get_data_for_entities();
1524  }
1525  break;
1526  case NOFIELD:
1527  // if (!getNinTheLoop()) {
1528  // NOFIELD data are the same for each element, can be
1529  // retrieved only once
1530  CHKERR get_data_for_meshset();
1531  // }
1532  break;
1533  default:
1534  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
1535  "not implemented for this space < %s >",
1536  FieldSpaceNames[space[ss]]);
1537  }
1539  };
1540 
1541  // evaluate operators with field data
1542  auto evaluate_op_for_fields = [&](auto &op) {
1544 
1545  if (op.getOpType() & UDO::OPROW) {
1546  try {
1547  CHKERR op.opRhs(*op_data[0], false);
1548  }
1549  CATCH_OP_ERRORS(op);
1550  }
1551 
1552  if (op.getOpType() & UDO::OPCOL) {
1553  try {
1554  CHKERR op.opRhs(*op_data[1], false);
1555  }
1556  CATCH_OP_ERRORS(op);
1557  }
1558 
1559  if (op.getOpType() & UDO::OPROWCOL) {
1560  try {
1561  CHKERR op.opLhs(*op_data[0], *op_data[1]);
1562  }
1563  CATCH_OP_ERRORS(op);
1564  }
1566  };
1567 
1568  // collect bit ref level on all entities, fields and spaces
1570 
1571  auto oit = opPtrVector.begin();
1572  auto hi_oit = opPtrVector.end();
1573 
1574  // iterate over all operators on element
1575  for (; oit != hi_oit; oit++) {
1576 
1577  try {
1578 
1579  CHKERR oit->setPtrFE(this);
1580 
1581  if ((oit->opType & UDO::OPSPACE) == UDO::OPSPACE) {
1582 
1583  // run operator for space but specific field
1584  CHKERR evaluate_op_space(*oit);
1585 
1586  } else if (
1587 
1588  (oit->opType & (UDO::OPROW | UDO::OPCOL | UDO::OPROWCOL)) ==
1589  oit->opType
1590 
1591  ) {
1592 
1593  field_name[0] = oit->rowFieldName;
1594  field_name[1] = oit->colFieldName;
1595 
1596  for (size_t ss = 0; ss != 2; ss++) {
1597 
1598 #ifndef NDEBUG
1599  if (field_name[ss].empty()) {
1600  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1601  "Not set Field name in operator %d (0-row, 1-column) in "
1602  "operator %s",
1603  ss,
1604  (boost::typeindex::type_id_runtime(*oit).pretty_name())
1605  .c_str());
1606  }
1607 #endif
1608 
1609  field_struture[ss] = mField.get_field_structure(field_name[ss]);
1610  field_id[ss] = field_struture[ss]->getBitNumber();
1611  space[ss] = field_struture[ss]->getSpace();
1612  base[ss] = field_struture[ss]->getApproxBase();
1613  }
1614 
1615  // not that if field name do not change between operators, entity field
1616  // data are nor rebuild
1617  for (size_t ss = 0; ss != 2; ss++) {
1618 
1619  if (oit->getOpType() & types[ss] ||
1620  oit->getOpType() & UDO::OPROWCOL) {
1621  if (last_eval_field_id[ss] != field_id[ss]) {
1622  CHKERR set_op_entities_data(ss, *oit);
1623  last_eval_field_id[ss] = field_id[ss];
1624  }
1625  }
1626  }
1627 
1628  CHKERR swap_bases(*oit);
1629 
1630  // run operator for given field or row, column or both
1631  CHKERR evaluate_op_for_fields(*oit);
1632 
1633  CHKERR swap_bases(*oit);
1634 
1635  } else {
1636 
1637  for (int i = 0; i != 5; ++i)
1638  if (oit->opType & (1 << i))
1639  MOFEM_LOG("SELF", Sev::error) << UDO::OpTypeNames[i];
1640  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1641  "Impossible operator type");
1642  }
1643  }
1644  CATCH_OP_ERRORS(*oit);
1645  }
1647 }
1648 
1650  "OPROW", " OPCOL", "OPROWCOL", "OPSPACE", "OPLAST"};
1651 
1653  const std::string field_name, const EntityType type, const int side,
1654  VectorInt &indices) const {
1656  if (ptrFE == NULL)
1657  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
1658 
1659  switch (type) {
1660  case MBVERTEX:
1662  break;
1663  default:
1665  }
1667 }
1668 
1670  const std::string field_name, const EntityType type, const int side,
1671  VectorInt &indices) const {
1673  if (ptrFE == NULL)
1674  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
1675 
1676  switch (type) {
1677  case MBVERTEX:
1678  CHKERR ptrFE->getProblemNodesColIndices(field_name, indices);
1679  break;
1680  default:
1681  CHKERR ptrFE->getProblemTypeColIndices(field_name, type, side, indices);
1682  }
1684 }
1685 
1689  sidePtrFE = const_cast<ForcesAndSourcesCore *>(side_fe_ptr);
1691 }
1692 
1694  const ForcesAndSourcesCore *refine_fe_ptr) {
1696  refinePtrFE = const_cast<ForcesAndSourcesCore *>(refine_fe_ptr);
1698 }
1699 
1701  const string &fe_name, ForcesAndSourcesCore *side_fe, const size_t side_dim,
1702  const EntityHandle ent_for_side, const int verb,
1703  const LogManager::SeverityLevel sev, AdjCache *adj_cache) {
1705 
1706  const auto *problem_ptr = getFEMethod()->problemPtr;
1707  auto &numered_fe =
1708  problem_ptr->numeredFiniteElementsPtr->get<Unique_mi_tag>();
1709 
1710  auto fe_miit = ptrFE->mField.get_finite_elements()
1711  ->get<FiniteElement_name_mi_tag>()
1712  .find(fe_name);
1713  if (fe_miit != ptrFE->mField.get_finite_elements()
1714  ->get<FiniteElement_name_mi_tag>()
1715  .end()) {
1716 
1717  const auto ent = ent_for_side ? ent_for_side : getFEEntityHandle();
1718 
1719  side_fe->feName = fe_name;
1720 
1721  CHKERR side_fe->setSideFEPtr(ptrFE);
1722  CHKERR side_fe->copyBasicMethod(*getFEMethod());
1723  CHKERR side_fe->copyPetscData(*getFEMethod());
1724  CHKERR side_fe->copyKsp(*getFEMethod());
1725  CHKERR side_fe->copySnes(*getFEMethod());
1726  CHKERR side_fe->copyTs(*getFEMethod());
1727 
1728  side_fe->cacheWeakPtr = getFEMethod()->cacheWeakPtr;
1729 
1730  CHKERR side_fe->preProcess();
1731 
1732  std::vector<boost::weak_ptr<NumeredEntFiniteElement>> fe_vec;
1733  auto get_numered_fe_ptr = [&](auto &fe_uid, Range &&adjacent_ents)
1734  -> std::vector<boost::weak_ptr<NumeredEntFiniteElement>> & {
1735  fe_vec.reserve(adjacent_ents.size());
1736  for (auto fe_ent : adjacent_ents) {
1737  auto miit = numered_fe.find(
1739  if (miit != numered_fe.end()) {
1740  fe_vec.emplace_back(*miit);
1741  }
1742  }
1743  return fe_vec;
1744  };
1745 
1746  auto get_bit_entity_adjacency = [&]() {
1747  Range adjacent_ents;
1748  CHKERR ptrFE->mField.getInterface<BitRefManager>()->getAdjacenciesAny(
1749  ent, side_dim, adjacent_ents);
1750  return adjacent_ents;
1751  };
1752 
1753  auto get_adj = [&](auto &fe_uid)
1754  -> std::vector<boost::weak_ptr<NumeredEntFiniteElement>> & {
1755  if (adj_cache) {
1756  try {
1757  return (*adj_cache).at(ent);
1758  } catch (const std::out_of_range &) {
1759  return (*adj_cache)[ent] =
1760  get_numered_fe_ptr(fe_uid, get_bit_entity_adjacency());
1761  }
1762  } else {
1763  return get_numered_fe_ptr(fe_uid, get_bit_entity_adjacency());
1764  }
1765  };
1766 
1767  auto adj = get_adj((*fe_miit)->getFEUId());
1768 
1769  int nn = 0;
1770  side_fe->loopSize = adj.size();
1771  for (auto fe_weak_ptr : adj) {
1772  if (auto fe_ptr = fe_weak_ptr.lock()) {
1773  if (verb >= VERBOSE)
1774  MOFEM_LOG("SELF", sev)
1775  << "Side finite element " << "(" << nn << "): " << *fe_ptr;
1776  side_fe->nInTheLoop = nn;
1777  side_fe->numeredEntFiniteElementPtr = fe_ptr;
1778  CHKERR (*side_fe)();
1779  }
1780  ++nn;
1781  }
1782 
1783  CHKERR side_fe->postProcess();
1784  }
1785 
1787 }
1788 
1790  const string &fe_name, ForcesAndSourcesCore *this_fe, const int verb,
1791  const LogManager::SeverityLevel sev) {
1793 
1794  if (verb >= VERBOSE)
1795  MOFEM_LOG("SELF", sev) << "This finite element: "
1796  << *getNumeredEntFiniteElementPtr();
1797 
1798  this_fe->feName = fe_name;
1799 
1800  CHKERR this_fe->setRefineFEPtr(ptrFE);
1801  CHKERR this_fe->copyBasicMethod(*getFEMethod());
1802  CHKERR this_fe->copyPetscData(*getFEMethod());
1803  CHKERR this_fe->copyKsp(*getFEMethod());
1804  CHKERR this_fe->copySnes(*getFEMethod());
1805  CHKERR this_fe->copyTs(*getFEMethod());
1806 
1807  this_fe->cacheWeakPtr = getFEMethod()->cacheWeakPtr;
1808 
1809  CHKERR this_fe->preProcess();
1810 
1811  this_fe->nInTheLoop = getNinTheLoop();
1812  this_fe->loopSize = getLoopSize();
1813  this_fe->numeredEntFiniteElementPtr = getNumeredEntFiniteElementPtr();
1814 
1815  CHKERR (*this_fe)();
1816 
1817  CHKERR this_fe->postProcess();
1818 
1820 }
1821 
1823  const string &fe_name, ForcesAndSourcesCore *parent_fe, const int verb,
1824  const LogManager::SeverityLevel sev) {
1826 
1827  auto &fes =
1828  ptrFE->mField.get_finite_elements()->get<FiniteElement_name_mi_tag>();
1829  auto fe_miit = fes.find(fe_name);
1830  if (fe_miit != fes.end()) {
1831 
1832  const auto *problem_ptr = getFEMethod()->problemPtr;
1833  auto &numered_fe =
1834  problem_ptr->numeredFiniteElementsPtr->get<Unique_mi_tag>();
1835 
1836  parent_fe->feName = fe_name;
1837  CHKERR parent_fe->setRefineFEPtr(ptrFE);
1838  CHKERR parent_fe->copyBasicMethod(*getFEMethod());
1839  CHKERR parent_fe->copyPetscData(*getFEMethod());
1840  CHKERR parent_fe->copyKsp(*getFEMethod());
1841  CHKERR parent_fe->copySnes(*getFEMethod());
1842  CHKERR parent_fe->copyTs(*getFEMethod());
1843 
1844  parent_fe->cacheWeakPtr = getFEMethod()->cacheWeakPtr;
1845 
1846  const auto parent_ent = getNumeredEntFiniteElementPtr()->getParentEnt();
1847  auto miit = numered_fe.find(EntFiniteElement::getLocalUniqueIdCalculate(
1848  parent_ent, (*fe_miit)->getFEUId()));
1849  if (miit != numered_fe.end()) {
1850  if (verb >= VERBOSE)
1851  MOFEM_LOG("SELF", sev) << "Parent finite element: " << **miit;
1852  parent_fe->loopSize = 1;
1853  parent_fe->nInTheLoop = 0;
1854  parent_fe->numeredEntFiniteElementPtr = *miit;
1855  CHKERR parent_fe->preProcess();
1856  CHKERR (*parent_fe)();
1857  CHKERR parent_fe->postProcess();
1858  } else {
1859  if (verb >= VERBOSE)
1860  MOFEM_LOG("SELF", sev) << "Parent finite element: no parent";
1861  parent_fe->loopSize = 0;
1862  parent_fe->nInTheLoop = 0;
1863  CHKERR parent_fe->preProcess();
1864  CHKERR parent_fe->postProcess();
1865  }
1866  }
1867 
1869 }
1870 
1872  const string &fe_name, ForcesAndSourcesCore *child_fe, const int verb,
1873  const LogManager::SeverityLevel sev) {
1875 
1876  auto fe_miit = ptrFE->mField.get_finite_elements()
1877  ->get<FiniteElement_name_mi_tag>()
1878  .find(fe_name);
1879  if (fe_miit != ptrFE->mField.get_finite_elements()
1880  ->get<FiniteElement_name_mi_tag>()
1881  .end()) {
1882 
1883  const auto *problem_ptr = getFEMethod()->problemPtr;
1884  auto &ref_ents = *getPtrFE()->mField.get_ref_ents();
1885  auto &numered_fe =
1886  problem_ptr->numeredFiniteElementsPtr->get<Unique_mi_tag>();
1887 
1888  const auto parent_ent = getNumeredEntFiniteElementPtr()->getEnt();
1889  const auto parent_type = getNumeredEntFiniteElementPtr()->getEntType();
1890  auto range =
1891  ref_ents.get<Composite_ParentEnt_And_EntType_mi_tag>().equal_range(
1892  boost::make_tuple(parent_type, parent_ent));
1893 
1894  if (auto size = std::distance(range.first, range.second)) {
1895 
1896  std::vector<EntityHandle> childs_vec;
1897  childs_vec.reserve(size);
1898  for (; range.first != range.second; ++range.first)
1899  childs_vec.emplace_back((*range.first)->getEnt());
1900 
1901  Range childs;
1902 
1903  if ((childs_vec.back() - childs_vec.front() + 1) == size)
1904  childs = Range(childs_vec.front(), childs_vec.back());
1905  else
1906  childs.insert_list(childs_vec.begin(), childs_vec.end());
1907 
1908  child_fe->feName = fe_name;
1909 
1910  CHKERR child_fe->setRefineFEPtr(ptrFE);
1911  CHKERR child_fe->copyBasicMethod(*getFEMethod());
1912  CHKERR child_fe->copyPetscData(*getFEMethod());
1913  CHKERR child_fe->copyKsp(*getFEMethod());
1914  CHKERR child_fe->copySnes(*getFEMethod());
1915  CHKERR child_fe->copyTs(*getFEMethod());
1916 
1917  child_fe->cacheWeakPtr = getFEMethod()->cacheWeakPtr;
1918 
1919  CHKERR child_fe->preProcess();
1920 
1921  int nn = 0;
1922  child_fe->loopSize = size;
1923 
1924  for (auto p = childs.pair_begin(); p != childs.pair_end(); ++p) {
1925 
1926  auto miit =
1927  numered_fe.lower_bound(EntFiniteElement::getLocalUniqueIdCalculate(
1928  p->first, (*fe_miit)->getFEUId()));
1929  auto hi_miit =
1930  numered_fe.upper_bound(EntFiniteElement::getLocalUniqueIdCalculate(
1931  p->second, (*fe_miit)->getFEUId()));
1932 
1933  for (; miit != hi_miit; ++miit) {
1934 
1935  if (verb >= VERBOSE)
1936  MOFEM_LOG("SELF", sev)
1937  << "Child finite element " << "(" << nn << "): " << **miit;
1938 
1939  child_fe->nInTheLoop = nn++;
1940  child_fe->numeredEntFiniteElementPtr = *miit;
1941  CHKERR (*child_fe)();
1942  }
1943  }
1944  }
1945 
1946  CHKERR child_fe->postProcess();
1947  }
1948 
1950 }
1951 
1952 int ForcesAndSourcesCore::getRule(int order_row, int order_col,
1953  int order_data) {
1954  return getRuleHook ? getRuleHook(order_row, order_col, order_data)
1955  : getRule(order_data);
1956 }
1957 
1959  int order_data) {
1960  return setRuleHook ? setRuleHook(this, order_row, order_col, order_data)
1961  : setGaussPts(order_data);
1962 }
1963 
1965 
1966 /** \deprecated setGaussPts(int row_order, int col_order, int data order);
1967  */
1970  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Sorry, not implemented");
1972 }
1973 
1975  const char type,
1976  const bool symm)
1977  : DataOperator(symm), opType(type), sPace(space), ptrFE(nullptr) {}
1978 
1980  const std::string field_name, const char type, const bool symm)
1981  : DataOperator(symm), opType(type), rowFieldName(field_name),
1982  colFieldName(field_name), sPace(LASTSPACE), ptrFE(nullptr) {}
1983 
1985  const std::string row_field_name, const std::string col_field_name,
1986  const char type, const bool symm)
1987  : DataOperator(symm), opType(type), rowFieldName(row_field_name),
1988  colFieldName(col_field_name), sPace(LASTSPACE), ptrFE(nullptr) {}
1989 
1992  if (preProcessHook) {
1993  ierr = preProcessHook();
1994  CHKERRG(ierr);
1995  }
1997 }
2000  if (operatorHook) {
2001  ierr = operatorHook();
2002  CHKERRG(ierr);
2003  } else {
2004 #ifndef NDEBUG
2005  MOFEM_LOG("SELF", Sev::warning)
2006  << "No method operator() overloaded on element entity on finite "
2007  "element <"
2008  << boost::typeindex::type_id_runtime(*this).pretty_name() << ">";
2009 #endif
2010  }
2012 }
2015  if (postProcessHook) {
2016  ierr = postProcessHook();
2017  CHKERRG(ierr);
2018  }
2020 }
2021 
2025  if (!(ptrFE = dynamic_cast<ForcesAndSourcesCore *>(ptr)))
2026  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2027  "User operator and finite element do not work together");
2029 }
2030 
2031 } // namespace MoFEM
NOSPACE
@ NOSPACE
Definition: definitions.h:83
MoFEMFunctionReturnHot
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:460
MoFEM::FEMethod::getRowFieldEnts
auto & getRowFieldEnts() const
Definition: LoopMethods.hpp:423
MoFEM::ForcesAndSourcesCore::getEntityRowIndices
MoFEMErrorCode getEntityRowIndices(EntitiesFieldData &data, const int bit_number, const EntityType type_lo=MBVERTEX, const EntityType type_hi=MBPOLYHEDRON) const
Definition: ForcesAndSourcesCore.cpp:412
MoFEM::BasicMethod::getNinTheLoop
int getNinTheLoop() const
get number of evaluated element in the loop
Definition: LoopMethods.hpp:207
MoFEM::ForcesAndSourcesCore::UserDataOperator::AdjCache
std::map< EntityHandle, std::vector< boost::weak_ptr< NumeredEntFiniteElement > >> AdjCache
Definition: ForcesAndSourcesCore.hpp:904
MoFEM::Field::getNbOfCoeffs
FieldCoefficientsNumber getNbOfCoeffs() const
Get number of field coefficients.
Definition: FieldMultiIndices.hpp:202
CATCH_OP_ERRORS
#define CATCH_OP_ERRORS(OP)
Definition: ForcesAndSourcesCore.cpp:1355
MoFEM::EntitiesFieldData::facesNodesOrder
MatrixInt facesNodesOrder
order of face nodes on element
Definition: EntitiesFieldData.hpp:46
H1
@ H1
continuous field
Definition: definitions.h:85
MoFEM::ForcesAndSourcesCore::getNoFieldFieldData
MoFEMErrorCode getNoFieldFieldData(const int bit_number, VectorDouble &ent_field_data, VectorDofs &ent_field_dofs, VectorFieldEntities &ent_field) const
Get field data on nodes.
Definition: ForcesAndSourcesCore.cpp:855
MoFEM::ForcesAndSourcesCore::calBernsteinBezierBaseFunctionsOnElement
MoFEMErrorCode calBernsteinBezierBaseFunctionsOnElement()
Calculate Bernstein-Bezier base.
Definition: ForcesAndSourcesCore.cpp:1132
MoFEM::DataOperator
base operator to do operations at Gauss Pt. level
Definition: DataOperators.hpp:24
MoFEM::BasicMethod::nInTheLoop
int nInTheLoop
number currently of processed method
Definition: LoopMethods.hpp:198
LASTBASE
@ LASTBASE
Definition: definitions.h:69
MoFEM::ForcesAndSourcesCore::getProblemNodesIndices
MoFEMErrorCode getProblemNodesIndices(const std::string &field_name, const NumeredDofEntity_multiIndex &dofs, VectorInt &nodes_indices) const
get indices of nodal indices which are declared for problem but not this particular element
Definition: ForcesAndSourcesCore.cpp:490
MoFEM::ForcesAndSourcesCore::getMaxRowOrder
int getMaxRowOrder() const
Get max order of approximation for field in rows.
Definition: ForcesAndSourcesCore.cpp:131
MoFEM::ForcesAndSourcesCore::UserDataOperator::getProblemColIndices
MoFEMErrorCode getProblemColIndices(const std::string filed_name, const EntityType type, const int side, VectorInt &indices) const
Get col indices.
Definition: ForcesAndSourcesCore.cpp:1669
EntityHandle
MoFEM::FEMethod::getColDofsPtr
auto getColDofsPtr() const
Definition: LoopMethods.hpp:443
MoFEM::ForcesAndSourcesCore::derivedDataOnElement
const std::array< boost::shared_ptr< EntitiesFieldData >, LASTSPACE > derivedDataOnElement
Entity data on element entity columns fields.
Definition: ForcesAndSourcesCore.hpp:468
MoFEM::EntitiesFieldData::basesOnEntities
std::array< std::bitset< LASTBASE >, MBMAXTYPE > basesOnEntities
bases on entity types
Definition: EntitiesFieldData.hpp:51
MoFEM::ForcesAndSourcesCore::UserDataOperator::OpTypeNames
static const char *const OpTypeNames[]
Definition: ForcesAndSourcesCore.hpp:574
MoFEM::ForcesAndSourcesCore::getFaceNodes
MoFEMErrorCode getFaceNodes(EntitiesFieldData &data) const
Get nodes on faces.
Definition: ForcesAndSourcesCore.cpp:921
MoFEM::ForcesAndSourcesCore::getBitRefLevelOnData
MoFEMErrorCode getBitRefLevelOnData()
Definition: ForcesAndSourcesCore.cpp:595
MoFEM::ForcesAndSourcesCore::getRuleHook
RuleHookFun getRuleHook
Hook to get rule.
Definition: ForcesAndSourcesCore.hpp:42
MoFEM::FEMethod::feName
std::string feName
Name of finite element.
Definition: LoopMethods.hpp:380
MoFEM::FieldEntity::getLoLocalEntityBitNumber
static UId getLoLocalEntityBitNumber(const char bit_number, const EntityHandle ent)
Definition: FieldEntsMultiIndices.hpp:247
MoFEM::cmp_uid_hi
static auto cmp_uid_hi(const UId &b, const boost::weak_ptr< FieldEntity > &a)
Definition: ForcesAndSourcesCore.cpp:29
NOBASE
@ NOBASE
Definition: definitions.h:59
MoFEM::PetscData::copyPetscData
MoFEMErrorCode copyPetscData(const PetscData &petsc_data)
Definition: LoopMethods.cpp:31
CHK_THROW_MESSAGE
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
Definition: definitions.h:609
L2
@ L2
field with C-1 continuity
Definition: definitions.h:88
MoFEM::CoreInterface::get_field_structure
virtual const Field * get_field_structure(const std::string &name, enum MoFEMTypes bh=MF_EXIST) const =0
get field structure
MoFEM::ForcesAndSourcesCore::setRefineFEPtr
MoFEMErrorCode setRefineFEPtr(const ForcesAndSourcesCore *refine_fe_ptr)
Set the pointer to face element refined.
Definition: ForcesAndSourcesCore.cpp:1693
MoFEM::Exceptions::MoFEMErrorCode
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
MoFEM::Field::getSpace
FieldSpace getSpace() const
Get field approximation space.
Definition: FieldMultiIndices.hpp:151
MoFEM::FieldEntity_vector_view
std::vector< boost::weak_ptr< FieldEntity > > FieldEntity_vector_view
Definition: FieldEntsMultiIndices.hpp:478
MoFEM::ForcesAndSourcesCore::setGaussPts
virtual MoFEMErrorCode setGaussPts(int order_row, int order_col, int order_data)
set user specific integration rule
Definition: ForcesAndSourcesCore.cpp:1958
MoFEM::CoreInterface::get_field_bit_number
virtual FieldBitNumber get_field_bit_number(const std::string name) const =0
get field bit number
MoFEM::FEMethod::getDataFieldEnts
const FieldEntity_vector_view & getDataFieldEnts() const
Definition: LoopMethods.hpp:412
MoFEM::ForcesAndSourcesCore::getMaxDataOrder
int getMaxDataOrder() const
Get max order of approximation for data fields.
Definition: ForcesAndSourcesCore.cpp:120
MoFEM::Types::BitFieldId
std::bitset< BITFIELDID_SIZE > BitFieldId
Field Id.
Definition: Types.hpp:42
MoFEM::ForcesAndSourcesCore::getEntityDataOrder
MoFEMErrorCode getEntityDataOrder(const EntityType type, const FieldSpace space, boost::ptr_vector< EntitiesFieldData::EntData > &data) const
Get the entity data order.
Definition: ForcesAndSourcesCore.cpp:139
MoFEM::BasicMethod::preProcessHook
boost::function< MoFEMErrorCode()> preProcessHook
Hook function for pre-processing.
Definition: LoopMethods.hpp:294
MoFEM::ForcesAndSourcesCore::sidePtrFE
ForcesAndSourcesCore * sidePtrFE
Element to integrate on the sides.
Definition: ForcesAndSourcesCore.hpp:507
MoFEM::ForcesAndSourcesCore::getElementPolynomialBase
auto & getElementPolynomialBase()
Get the Entity Polynomial Base object.
Definition: ForcesAndSourcesCore.hpp:90
MoFEM::ForcesAndSourcesCore::preProcess
virtual MoFEMErrorCode preProcess()
function is run at the beginning of loop
Definition: ForcesAndSourcesCore.cpp:1990
MoFEM::ForcesAndSourcesCore::getMaxColOrder
int getMaxColOrder() const
Get max order of approximation for field in columns.
Definition: ForcesAndSourcesCore.cpp:135
MoFEM::ForcesAndSourcesCore::calHierarchicalBaseFunctionsOnElement
MoFEMErrorCode calHierarchicalBaseFunctionsOnElement()
Calculate base functions.
Definition: ForcesAndSourcesCore.cpp:1112
MoFEM::ForcesAndSourcesCore::getNoFieldRowIndices
MoFEMErrorCode getNoFieldRowIndices(EntitiesFieldData &data, const int bit_number) const
get col NoField indices
Definition: ForcesAndSourcesCore.cpp:459
MoFEM::ForcesAndSourcesCore::getNoFieldIndices
MoFEMErrorCode getNoFieldIndices(const int bit_number, boost::shared_ptr< FENumeredDofEntity_multiIndex > dofs, VectorInt &nodes_indices) const
get NoField indices
Definition: ForcesAndSourcesCore.cpp:442
MoFEM::EntitiesFieldData::spacesOnEntities
std::array< std::bitset< LASTSPACE >, MBMAXTYPE > spacesOnEntities
spaces on entity types
Definition: EntitiesFieldData.hpp:49
MoFEM::Types::BitFEId
std::bitset< BITFEID_SIZE > BitFEId
Finite element Id.
Definition: Types.hpp:43
MoFEM::ForcesAndSourcesCore::getProblemTypeRowIndices
MoFEMErrorCode getProblemTypeRowIndices(const std::string &field_name, EntityType type, int side_number, VectorInt &indices) const
Definition: ForcesAndSourcesCore.cpp:572
THROW_MESSAGE
#define THROW_MESSAGE(msg)
Throw MoFEM exception.
Definition: definitions.h:574
MoFEM::ForcesAndSourcesCore::getProblemTypeColIndices
MoFEMErrorCode getProblemTypeColIndices(const std::string &field_name, EntityType type, int side_number, VectorInt &indices) const
Definition: ForcesAndSourcesCore.cpp:586
MoFEM::EntitiesFieldData::facesNodes
MatrixInt facesNodes
nodes on finite element faces
Definition: EntitiesFieldData.hpp:45
sdf.r
int r
Definition: sdf.py:8
MoFEM::Field
Provide data structure for (tensor) field approximation.
Definition: FieldMultiIndices.hpp:51
USER_BASE
@ USER_BASE
user implemented approximation base
Definition: definitions.h:68
order
constexpr int order
Definition: dg_projection.cpp:18
MoFEM::DeprecatedCoreInterface
Deprecated interface functions.
Definition: DeprecatedCoreInterface.hpp:16
MoFEM::ForcesAndSourcesCore::getEntityFieldData
MoFEMErrorCode getEntityFieldData(EntitiesFieldData &data, const int bit_number, const EntityType type_lo=MBVERTEX, const EntityType type_hi=MBPOLYHEDRON) const
Definition: ForcesAndSourcesCore.cpp:770
MoFEM::EntitiesFieldData::basesOnSpaces
std::array< std::bitset< LASTBASE >, LASTSPACE > basesOnSpaces
base on spaces
Definition: EntitiesFieldData.hpp:53
MoFEM::BasicMethod::fieldsPtr
const Field_multiIndex * fieldsPtr
raw pointer to fields container
Definition: LoopMethods.hpp:252
NumeredDofEntity_multiIndex
multi_index_container< boost::shared_ptr< NumeredDofEntity >, indexed_by< ordered_unique< tag< Unique_mi_tag >, const_mem_fun< NumeredDofEntity::interface_type_DofEntity, UId, &NumeredDofEntity::getLocalUniqueId > >, ordered_non_unique< tag< Part_mi_tag >, member< NumeredDofEntity, unsigned int, &NumeredDofEntity::pArt > >, ordered_non_unique< tag< Idx_mi_tag >, member< NumeredDofEntity, DofIdx, &NumeredDofEntity::dofIdx > >, ordered_non_unique< tag< PetscGlobalIdx_mi_tag >, member< NumeredDofEntity, DofIdx, &NumeredDofEntity::petscGloablDofIdx > >, ordered_non_unique< tag< PetscLocalIdx_mi_tag >, member< NumeredDofEntity, DofIdx, &NumeredDofEntity::petscLocalDofIdx > >, ordered_non_unique< tag< Ent_mi_tag >, const_mem_fun< NumeredDofEntity::interface_type_DofEntity, EntityHandle, &NumeredDofEntity::getEnt > > > > NumeredDofEntity_multiIndex
MultiIndex container keeps NumeredDofEntity.
Definition: DofsMultiIndices.hpp:469
FieldSpace
FieldSpace
approximation spaces
Definition: definitions.h:82
VERBOSE
@ VERBOSE
Definition: definitions.h:222
CHKERR
#define CHKERR
Inline error check.
Definition: definitions.h:548
MoFEM::ForcesAndSourcesCore::getNoFieldColIndices
MoFEMErrorCode getNoFieldColIndices(EntitiesFieldData &data, const int bit_number) const
get col NoField indices
Definition: ForcesAndSourcesCore.cpp:474
MoFEM::FEMethod::getRowDofsPtr
auto getRowDofsPtr() const
Definition: LoopMethods.hpp:439
MoFEM::CoreInterface::get_field_id
virtual BitFieldId get_field_id(const std::string &name) const =0
Get field Id.
MoFEM::CoreInterface::get_moab
virtual moab::Interface & get_moab()=0
MoFEM::ForcesAndSourcesCore::refinePtrFE
ForcesAndSourcesCore * refinePtrFE
Element to integrate parent or child.
Definition: ForcesAndSourcesCore.hpp:524
MoFEM::BasicMethod::getLoopSize
int getLoopSize() const
get loop size
Definition: LoopMethods.hpp:211
MoFEM::get_value
static MoFEMErrorCode get_value(MatrixDouble &pts_x, MatrixDouble &pts_t, TYPE *ctx)
Definition: JacobiPolynomial.cpp:25
MoFEM::ForcesAndSourcesCore::getUserPolynomialBase
auto & getUserPolynomialBase()
Get the User Polynomial Base object.
Definition: ForcesAndSourcesCore.hpp:97
MoFEM
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:10
a
constexpr double a
Definition: approx_sphere.cpp:30
MoFEM::ForcesAndSourcesCore::UserDataOperator::getProblemRowIndices
MoFEMErrorCode getProblemRowIndices(const std::string filed_name, const EntityType type, const int side, VectorInt &indices) const
Get row indices.
Definition: ForcesAndSourcesCore.cpp:1652
MoFEM::ForcesAndSourcesCore::getEntityIndices
MoFEMErrorCode getEntityIndices(EntitiesFieldData &data, const int bit_number, FieldEntity_vector_view &ents_field, const EntityType type_lo, const EntityType type_hi, EXTRACTOR &&extractor) const
Definition: ForcesAndSourcesCore.cpp:345
MoFEM::ForcesAndSourcesCore::getColNodesIndices
MoFEMErrorCode getColNodesIndices(EntitiesFieldData &data, const int bit_number) const
get col node indices from FENumeredDofEntity_multiIndex
Definition: ForcesAndSourcesCore.cpp:328
MoFEM::Problem::numeredColDofsPtr
boost::shared_ptr< NumeredDofEntity_multiIndex > numeredColDofsPtr
store DOFs on columns for this problem
Definition: ProblemsMultiIndices.hpp:75
FieldContinuity
FieldContinuity
Field continuity.
Definition: definitions.h:99
MoFEM::Types::UId
uint128_t UId
Unique Id.
Definition: Types.hpp:31
MoFEM::FEMethod::getNumberOfNodes
auto getNumberOfNodes() const
Definition: LoopMethods.hpp:456
convert.type
type
Definition: convert.py:64
MoFEM::FieldEntity::getLocalUniqueIdCalculate
UId getLocalUniqueIdCalculate()
Get the Local Unique Id Calculate object.
Definition: FieldEntsMultiIndices.hpp:136
SideNumber_multiIndex
multi_index_container< boost::shared_ptr< SideNumber >, indexed_by< ordered_unique< member< SideNumber, EntityHandle, &SideNumber::ent > >, ordered_non_unique< composite_key< SideNumber, const_mem_fun< SideNumber, EntityType, &SideNumber::getEntType >, member< SideNumber, signed char, &SideNumber::side_number > > > > > SideNumber_multiIndex
SideNumber_multiIndex for SideNumber.
Definition: RefEntsMultiIndices.hpp:101
MoFEM::EntFiniteElement::getLocalUniqueIdCalculate
UId getLocalUniqueIdCalculate() const
Generate UId for finite element entity.
Definition: FEMultiIndices.hpp:528
MoFEM::ForcesAndSourcesCore::opPtrVector
boost::ptr_deque< UserDataOperator > opPtrVector
Vector of finite element users data operators.
Definition: ForcesAndSourcesCore.hpp:480
MoFEM::ForcesAndSourcesCore::dataOnElement
const std::array< boost::shared_ptr< EntitiesFieldData >, LASTSPACE > dataOnElement
Entity data on element entity rows fields.
Definition: ForcesAndSourcesCore.hpp:461
MoFEM::SnesMethod::copySnes
MoFEMErrorCode copySnes(const SnesMethod &snes)
Copy snes data.
Definition: LoopMethods.cpp:75
MoFEM::ForcesAndSourcesCore::createDataOnElement
MoFEMErrorCode createDataOnElement(EntityType type)
Create a entity data on element object.
Definition: ForcesAndSourcesCore.cpp:1337
MoFEM::FieldEntity::getLoBitNumberUId
static UId getLoBitNumberUId(const FieldBitNumber bit_number)
Definition: FieldEntsMultiIndices.hpp:222
MoFEM::cmp_uid_lo
static auto cmp_uid_lo(const boost::weak_ptr< FieldEntity > &a, const UId &b)
Definition: ForcesAndSourcesCore.cpp:18
MoFEM::ForcesAndSourcesCore::UserDataOperator::setPtrFE
virtual MoFEMErrorCode setPtrFE(ForcesAndSourcesCore *ptr)
Definition: ForcesAndSourcesCore.cpp:2023
MoFEM::ForcesAndSourcesCore::ForcesAndSourcesCore
ForcesAndSourcesCore(Interface &m_field)
Definition: ForcesAndSourcesCore.cpp:40
MoFEM::VectorDofs
ublas::vector< FEDofEntity *, DofsAllocator > VectorDofs
Definition: EntitiesFieldData.hpp:23
lapack_wrap.h
MoFEM::BasicMethod::postProcessHook
boost::function< MoFEMErrorCode()> postProcessHook
Hook function for post-processing.
Definition: LoopMethods.hpp:299
LASTSPACE
@ LASTSPACE
FieldSpace in [ 0, LASTSPACE )
Definition: definitions.h:89
MoFEM::ForcesAndSourcesCore::getRule
virtual int getRule(int order_row, int order_col, int order_data)
another variant of getRule
Definition: ForcesAndSourcesCore.cpp:1952
MoFEM::get_id_for_max_type
EntityHandle get_id_for_max_type()
Definition: RefEntsMultiIndices.hpp:13
MoFEM::ForcesAndSourcesCore::getEntityColIndices
MoFEMErrorCode getEntityColIndices(EntitiesFieldData &data, const int bit_number, const EntityType type_lo=MBVERTEX, const EntityType type_hi=MBPOLYHEDRON) const
Definition: ForcesAndSourcesCore.cpp:427
MoFEM::ForcesAndSourcesCore::operator()
virtual MoFEMErrorCode operator()()
function is run for every finite element
Definition: ForcesAndSourcesCore.cpp:1998
MoFEM::FEMethod::getFEName
auto getFEName() const
get finite element name
Definition: LoopMethods.hpp:391
MoFEM::EntitiesFieldData::brokenBasesOnSpaces
std::array< std::bitset< LASTBASE >, LASTSPACE > brokenBasesOnSpaces
base on spaces
Definition: EntitiesFieldData.hpp:55
MoFEM::LogManager::SeverityLevel
SeverityLevel
Severity levels.
Definition: LogManager.hpp:33
MoFEM::BasicMethod::loopSize
int loopSize
local number oe methods to process
Definition: LoopMethods.hpp:203
t
constexpr double t
plate stiffness
Definition: plate.cpp:59
MoFEM::EntitiesFieldData::bAse
std::bitset< LASTBASE > bAse
bases on element
Definition: EntitiesFieldData.hpp:42
MoFEM::ForcesAndSourcesCore::UserDataOperator
friend class UserDataOperator
Definition: ForcesAndSourcesCore.hpp:482
i
FTensor::Index< 'i', SPACE_DIM > i
Definition: hcurl_divergence_operator_2d.cpp:27
MoFEM::ForcesAndSourcesCore::getProblemTypeIndices
MoFEMErrorCode getProblemTypeIndices(const std::string &field_name, const NumeredDofEntity_multiIndex &dofs, EntityType type, int side_number, VectorInt &indices) const
get indices by type (generic function) which are declared for problem but not this particular element
Definition: ForcesAndSourcesCore.cpp:531
MoFEM::ForcesAndSourcesCore::getSpacesAndBaseOnEntities
MoFEMErrorCode getSpacesAndBaseOnEntities(EntitiesFieldData &data) const
Get field approximation space and base on entities.
Definition: ForcesAndSourcesCore.cpp:990
EntData
EntitiesFieldData::EntData EntData
Definition: child_and_parent.cpp:37
field_name
constexpr auto field_name
Definition: poisson_2d_homogeneous.cpp:13
AINSWORTH_BERNSTEIN_BEZIER_BASE
@ AINSWORTH_BERNSTEIN_BEZIER_BASE
Definition: definitions.h:64
MoFEM::ForcesAndSourcesCore::setSideFEPtr
MoFEMErrorCode setSideFEPtr(const ForcesAndSourcesCore *side_fe_ptr)
Set the pointer to face element on the side.
Definition: ForcesAndSourcesCore.cpp:1687
convert.n
n
Definition: convert.py:82
MoFEM::ForcesAndSourcesCore::getRowNodesIndices
MoFEMErrorCode getRowNodesIndices(EntitiesFieldData &data, const int bit_number) const
get row node indices from FENumeredDofEntity_multiIndex
Definition: ForcesAndSourcesCore.cpp:311
MoFEM::interface_RefEntity::getSideNumberPtr
boost::shared_ptr< SideNumber > getSideNumberPtr() const
Get the Side number.
Definition: RefEntsMultiIndices.hpp:589
MoFEM::BasicMethod::copyBasicMethod
MoFEMErrorCode copyBasicMethod(const BasicMethod &basic)
Copy data from other base method to this base method.
Definition: LoopMethods.cpp:117
MoFEM::Problem::numeredRowDofsPtr
boost::shared_ptr< NumeredDofEntity_multiIndex > numeredRowDofsPtr
store DOFs on rows for this problem
Definition: ProblemsMultiIndices.hpp:73
MoFEM::ForcesAndSourcesCore
structure to get information form mofem into EntitiesFieldData
Definition: ForcesAndSourcesCore.hpp:22
Range
FieldSpaceNames
const static char *const FieldSpaceNames[]
Definition: definitions.h:92
MOFEM_LOG
#define MOFEM_LOG(channel, severity)
Log.
Definition: LogManager.hpp:308
MoFEM::BasicMethod::operatorHook
boost::function< MoFEMErrorCode()> operatorHook
Hook function for operator.
Definition: LoopMethods.hpp:304
MoFEM::Types::ApproximationOrder
int ApproximationOrder
Approximation on the entity.
Definition: Types.hpp:26
MoFEM::Field::getBitNumber
FieldBitNumber getBitNumber() const
Get number of set bit in Field ID. Each field has uid, get getBitNumber get number of bit set for giv...
Definition: FieldMultiIndices.hpp:211
MoFEM::BitFieldId_mi_tag
Definition: TagMultiIndices.hpp:17
MoFEM::ForcesAndSourcesCore::UserDataOperator::loopSide
MoFEMErrorCode loopSide(const string &fe_name, ForcesAndSourcesCore *side_fe, const size_t dim, const EntityHandle ent_for_side=0, const int verb=QUIET, const LogManager::SeverityLevel sev=Sev::noisy, AdjCache *adj_cache=nullptr)
User calls this function to loop over elements on the side of face. This function calls finite elemen...
Definition: ForcesAndSourcesCore.cpp:1700
MoFEM::ForcesAndSourcesCore::UserDataOperator::loopChildren
MoFEMErrorCode loopChildren(const string &fe_name, ForcesAndSourcesCore *child_fe, const int verb=QUIET, const LogManager::SeverityLevel sev=Sev::noisy)
User calls this function to loop over parent elements. This function calls finite element with its op...
Definition: ForcesAndSourcesCore.cpp:1871
MoFEM::FiniteElement_name_mi_tag
Definition: TagMultiIndices.hpp:26
MoFEM::Types::VectorInt
UBlasVector< int > VectorInt
Definition: Types.hpp:67
MoFEM::ForcesAndSourcesCore::getProblemNodesColIndices
MoFEMErrorCode getProblemNodesColIndices(const std::string &field_name, VectorInt &nodes_indices) const
Definition: ForcesAndSourcesCore.cpp:579
DISCONTINUOUS
@ DISCONTINUOUS
Broken continuity (No effect on L2 space)
Definition: definitions.h:101
MoFEM::TSMethod::copyTs
MoFEMErrorCode copyTs(const TSMethod &ts)
Copy TS solver data.
Definition: LoopMethods.cpp:96
UBlasVector< double >
MoFEM::Exceptions::ierr
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
Definition: Exceptions.hpp:76
AINSWORTH_LEGENDRE_BASE
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition: definitions.h:60
MoFEM::BasicMethod::cacheWeakPtr
boost::weak_ptr< CacheTuple > cacheWeakPtr
Definition: LoopMethods.hpp:351
MoFEM::getMaxOrder
static int getMaxOrder(const ENTMULTIINDEX &multi_index)
Definition: ForcesAndSourcesCore.cpp:110
MoFEM::KspMethod::copyKsp
MoFEMErrorCode copyKsp(const KspMethod &ksp)
copy data form another method
Definition: LoopMethods.cpp:55
HCURL
@ HCURL
field with continuous tangents
Definition: definitions.h:86
MoFEM::BitFieldId_space_mi_tag
Definition: TagMultiIndices.hpp:68
MOFEM_DATA_INCONSISTENCY
@ MOFEM_DATA_INCONSISTENCY
Definition: definitions.h:31
MoFEM::BasicMethod::problemPtr
const Problem * problemPtr
raw pointer to problem
Definition: LoopMethods.hpp:250
MoFEM::ForcesAndSourcesCore::gaussPts
MatrixDouble gaussPts
Matrix of integration points.
Definition: ForcesAndSourcesCore.hpp:109
MoFEM::Composite_ParentEnt_And_EntType_mi_tag
Definition: TagMultiIndices.hpp:78
MoFEM::FEMethod::getColFieldEnts
auto & getColFieldEnts() const
Definition: LoopMethods.hpp:431
FieldApproximationBase
FieldApproximationBase
approximation base
Definition: definitions.h:58
MoFEM::FieldEntity::getHiBitNumberUId
static UId getHiBitNumberUId(const FieldBitNumber bit_number)
Definition: FieldEntsMultiIndices.hpp:228
MoFEM::EntitiesFieldData::dataOnEntities
std::array< boost::ptr_vector< EntData >, MBMAXTYPE > dataOnEntities
Definition: EntitiesFieldData.hpp:57
MoFEM::FieldEntity::getHiLocalEntityBitNumber
static UId getHiLocalEntityBitNumber(const char bit_number, const EntityHandle ent)
Definition: FieldEntsMultiIndices.hpp:258
MoFEM::VectorFieldEntities
ublas::vector< FieldEntity *, FieldEntAllocator > VectorFieldEntities
Definition: EntitiesFieldData.hpp:31
MoFEM::ForcesAndSourcesCore::loopOverOperators
MoFEMErrorCode loopOverOperators()
Iterate user data operators.
Definition: ForcesAndSourcesCore.cpp:1379
MoFEM::BitRefManager
Managing BitRefLevels.
Definition: BitRefManager.hpp:21
MoFEM::FEMethod::getFEEntityHandle
EntityHandle getFEEntityHandle() const
Definition: LoopMethods.hpp:460
MoFEM::ForcesAndSourcesCore::setRuleHook
GaussHookFun setRuleHook
Set function to calculate integration rule.
Definition: ForcesAndSourcesCore.hpp:48
MoFEM::FEMethod::numeredEntFiniteElementPtr
boost::shared_ptr< const NumeredEntFiniteElement > numeredEntFiniteElementPtr
Definition: LoopMethods.hpp:383
MoFEMFunctionBeginHot
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:453
MoFEM::Unique_mi_tag
Definition: TagMultiIndices.hpp:18
MoFEM::ForcesAndSourcesCore::getNodesIndices
MoFEMErrorCode getNodesIndices(const int bit_number, FieldEntity_vector_view &ents_field, VectorInt &nodes_indices, VectorInt &local_nodes_indices, EXTRACTOR &&extractor) const
get node indices
Definition: ForcesAndSourcesCore.cpp:219
MoFEM::field_it
Field_multiIndex::index< FieldName_mi_tag >::type::iterator field_it
Definition: Projection10NodeCoordsOnField.cpp:123
MoFEM::ForcesAndSourcesCore::UserDataOperator::loopParent
MoFEMErrorCode loopParent(const string &fe_name, ForcesAndSourcesCore *parent_fe, const int verb=QUIET, const LogManager::SeverityLevel sev=Sev::noisy)
User calls this function to loop over parent elements. This function calls finite element with its op...
Definition: ForcesAndSourcesCore.cpp:1822
MoFEM::ForcesAndSourcesCore::getNodesFieldData
MoFEMErrorCode getNodesFieldData(EntitiesFieldData &data, const int bit_number) const
Get data on nodes.
Definition: ForcesAndSourcesCore.cpp:642
MoFEM::FEDofEntity
keeps information about indexed dofs for the finite element
Definition: DofsMultiIndices.hpp:267
MoFEM::EntitiesFieldData
data structure for finite element entity
Definition: EntitiesFieldData.hpp:40
MoFEM::FEMethod::getDataFieldEntsPtr
boost::shared_ptr< FieldEntity_vector_view > & getDataFieldEntsPtr() const
Definition: LoopMethods.hpp:417
MoFEM::ForcesAndSourcesCore::postProcess
virtual MoFEMErrorCode postProcess()
function is run at the end of loop
Definition: ForcesAndSourcesCore.cpp:2013
CONTINUOUS
@ CONTINUOUS
Regular field.
Definition: definitions.h:100
MoFEM::get_id_for_min_type
EntityHandle get_id_for_min_type()
Definition: RefEntsMultiIndices.hpp:18
MoFEMFunctionReturn
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:429
HDIV
@ HDIV
field with continuous normal traction
Definition: definitions.h:87
MOFEM_NOT_IMPLEMENTED
@ MOFEM_NOT_IMPLEMENTED
Definition: definitions.h:32
MoFEM::ForcesAndSourcesCore::UserDataOperator::loopThis
MoFEMErrorCode loopThis(const string &fe_name, ForcesAndSourcesCore *this_fe, const int verb=QUIET, const LogManager::SeverityLevel sev=Sev::noisy)
User calls this function to loop over the same element using a different set of integration points....
Definition: ForcesAndSourcesCore.cpp:1789
MoFEM::ForcesAndSourcesCore::getProblemNodesRowIndices
MoFEMErrorCode getProblemNodesRowIndices(const std::string &field_name, VectorInt &nodes_indices) const
Definition: ForcesAndSourcesCore.cpp:565
CHKERRG
#define CHKERRG(n)
Check error code of MoFEM/MOAB/PETSc function.
Definition: definitions.h:496
MoFEM::ForcesAndSourcesCore::UserDataOperator::ptrFE
ForcesAndSourcesCore * ptrFE
Definition: ForcesAndSourcesCore.hpp:985
MoFEMFunctionBegin
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:359
MoFEM::ForcesAndSourcesCore::mField
Interface & mField
Definition: ForcesAndSourcesCore.hpp:24
MoFEM::ForcesAndSourcesCore::getEntitySense
MoFEMErrorCode getEntitySense(const EntityType type, boost::ptr_vector< EntitiesFieldData::EntData > &data) const
get sense (orientation) of entity
Definition: ForcesAndSourcesCore.cpp:84
NOFIELD
@ NOFIELD
scalar or vector of scalars describe (no true field)
Definition: definitions.h:84
MoFEM::ForcesAndSourcesCore::UserDataOperator::UserDataOperator
UserDataOperator(const FieldSpace space, const char type=OPSPACE, const bool symm=true)
Definition: ForcesAndSourcesCore.cpp:1974
MoFEM::DefaultElementAdjacency::getDefTypeMap
static bool getDefTypeMap(const EntityType fe_type, const EntityType ent_type)
Definition: FEMultiIndices.hpp:304