v0.9.0
FEMultiIndices.cpp
Go to the documentation of this file.
1 /** \file CoreDataStructures.cpp
2  * \brief Mylti-index contains data structures and other low-level functions
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 namespace MoFEM {
20 
21 const boost::shared_ptr<SideNumber> RefElement::nullSideNumber =
22  boost::shared_ptr<SideNumber>();
23 
24 // ref moab FiniteElement
25 RefElement::RefElement(const boost::shared_ptr<RefEntity> &ref_ent_ptr)
26  : interface_RefEntity<RefEntity>(ref_ent_ptr) {}
27 
28 std::ostream &operator<<(std::ostream &os, const RefElement &e) {
29  os << " ref egdes " << e.getBitRefEdges();
30  os << " " << *(e.sPtr);
31  return os;
32 }
33 
35  const boost::shared_ptr<RefEntity> &ref_ent_ptr)
36  : RefElement(ref_ent_ptr) {
37  switch (ref_ent_ptr->getEntType()) {
38  case MBENTITYSET:
39  break;
40  default:
41  THROW_MESSAGE("this work only for MESHSETs");
42  }
43 }
44 const boost::shared_ptr<SideNumber> &
46  NOT_USED(ent);
47  SideNumber_multiIndex::iterator miit;
48  miit =
49  const_cast<SideNumber_multiIndex &>(side_number_table)
50  .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, 0, 0, 0)))
51  .first;
52  return *miit;
53 }
55  const boost::shared_ptr<RefEntity> &ref_ent_ptr)
56  : RefElement(ref_ent_ptr) {
57  Tag th_RefBitEdge;
58  moab::Interface &moab = getRefEntityPtr()->basicDataPtr->moab;
59  rval = moab.tag_get_handle("_RefBitEdge", th_RefBitEdge);
61  rval = moab.tag_get_by_ptr(th_RefBitEdge, &ref_ent_ptr->ent, 1,
62  (const void **)&tag_BitRefEdges);
64  switch (ref_ent_ptr->getEntType()) {
65  case MBPRISM:
66  break;
67  default:
68  THROW_MESSAGE("this work only for PRISMs");
69  }
70  EntityHandle prism = getRefEnt();
71  int num_nodes;
72  const EntityHandle *conn;
73  rval = moab.get_connectivity(prism, conn, num_nodes, true);
75  assert(num_nodes == 6);
76  for (int nn = 0; nn != 6; ++nn) {
77  const_cast<SideNumber_multiIndex &>(side_number_table)
78  .insert(
79  boost::shared_ptr<SideNumber>(new SideNumber(conn[nn], nn, 0, -1)));
80  }
81  // Range face_side3, face_side4;
82  // CHKERR moab.get_adjacencies(conn, 3, 2, true, face_side3);
83  // CHKERR moab.get_adjacencies(&conn[3], 3, 2, true, face_side4);
84  // if (face_side3.size() != 1)
85  // THROW_MESSAGE("prism don't have side face 3");
86  // if (face_side4.size() != 1)
87  // THROW_MESSAGE("prims don't have side face 4");
88  // getSideNumberPtr(*face_side3.begin());
89  // getSideNumberPtr(*face_side4.begin());
90 }
91 const boost::shared_ptr<SideNumber> &
93 
94  moab::Interface &moab = getRefEntityPtr()->basicDataPtr->moab;
95 
96  SideNumber_multiIndex::iterator miit = side_number_table.find(ent);
97  // this int is in table then return pointer
98  if (miit != side_number_table.end())
99  return *miit;
100 
101  // if ent is a this prism
102  if (sPtr->ent == ent) {
103  miit =
104  const_cast<SideNumber_multiIndex &>(side_number_table)
105  .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, 0, 0, 0)))
106  .first;
107  return *miit;
108  }
109 
110  // if ent is meshset
111  if (moab.type_from_handle(ent) == MBENTITYSET) {
112  miit =
113  const_cast<SideNumber_multiIndex &>(side_number_table)
114  .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, 0, 0, 0)))
115  .first;
116  return *miit;
117  }
118 
119  // use moab to get sense, side and offset
120 
121  int side_number, sense, offset;
122  rval = moab.side_number(sPtr->ent, ent, side_number, sense, offset);
123 
124  // it has to be degenerated prism, get sense from nodes topology
125  if (side_number == -1 || rval != MB_SUCCESS) {
126 
127  if (moab.type_from_handle(ent) == MBVERTEX) {
128  THROW_MESSAGE("Huston we have problem, vertex (specified by ent) is not "
129  "part of prism, that is impossible (top tip: check your "
130  "prisms)");
131  }
132 
133  // get prism connectivity
134  int num_nodes;
135  const EntityHandle *conn;
136  rval = moab.get_connectivity(sPtr->ent, conn, num_nodes, true);
137  MOAB_THROW(rval);
138  assert(num_nodes == 6);
139  // get ent connectivity
140  const EntityHandle *conn_ent;
141  rval = moab.get_connectivity(ent, conn_ent, num_nodes, true);
142  MOAB_THROW(rval);
143 
144  // for(int nn = 0; nn<6;nn++) {
145  // std::cerr << conn[nn] << " ";
146  // };
147  // std::cerr << std::endl;
148  // for(int nn = 0; nn<num_nodes;nn++) {
149  // std::cerr << conn_ent[nn] << " ";
150  // }
151  // std::cerr << std::endl;
152 
153  // bottom face
154  EntityHandle face3[3] = {conn[0], conn[1], conn[2]};
155  // top face
156  EntityHandle face4[3] = {conn[3], conn[4], conn[5]};
157  if (num_nodes == 3) {
158  int sense_p1_map[3][3] = {{0, 1, 2}, {1, 2, 0}, {2, 0, 1}};
159  int sense_m1_map[3][3] = {{0, 2, 1}, {1, 0, 2}, {2, 1, 0}};
160  EntityHandle *conn0_3_ptr = std::find(face3, &face3[3], conn_ent[0]);
161  if (conn0_3_ptr != &face3[3]) {
162  offset = std::distance(face3, conn0_3_ptr);
163  if (face3[sense_p1_map[offset][0]] == conn_ent[0] &&
164  face3[sense_p1_map[offset][1]] == conn_ent[1] &&
165  face3[sense_p1_map[offset][2]] == conn_ent[2]) {
166  miit = const_cast<SideNumber_multiIndex &>(side_number_table)
167  .insert(boost::shared_ptr<SideNumber>(
168  new SideNumber(ent, 3, 1, offset)))
169  .first;
170  return *miit;
171  } else if (face3[sense_m1_map[offset][0]] == conn_ent[0] &&
172  face3[sense_m1_map[offset][1]] == conn_ent[1] &&
173  face3[sense_m1_map[offset][2]] == conn_ent[2]) {
174  miit = const_cast<SideNumber_multiIndex &>(side_number_table)
175  .insert(boost::shared_ptr<SideNumber>(
176  new SideNumber(ent, 3, -1, offset)))
177  .first;
178  return *miit;
179  }
180  }
181  EntityHandle *conn0_4_ptr = std::find(face4, &face4[3], conn_ent[0]);
182  if (conn0_4_ptr != &face4[3]) {
183  offset = std::distance(face4, conn0_4_ptr);
184  if (face4[sense_p1_map[offset][0]] == conn_ent[0] &&
185  face4[sense_p1_map[offset][1]] == conn_ent[1] &&
186  face4[sense_p1_map[offset][2]] == conn_ent[2]) {
187  miit = const_cast<SideNumber_multiIndex &>(side_number_table)
188  .insert(boost::shared_ptr<SideNumber>(
189  new SideNumber(ent, 4, 1, 3 + offset)))
190  .first;
191  return *miit;
192  } else if (face4[sense_m1_map[offset][0]] == conn_ent[0] &&
193  face4[sense_m1_map[offset][1]] == conn_ent[1] &&
194  face4[sense_m1_map[offset][2]] == conn_ent[2]) {
195  miit = const_cast<SideNumber_multiIndex &>(side_number_table)
196  .insert(boost::shared_ptr<SideNumber>(
197  new SideNumber(ent, 4, -1, 3 + offset)))
198  .first;
199  return *miit;
200  } else {
201  std::cerr << conn_ent[0] << " " << conn_ent[1] << " " << conn_ent[2]
202  << std::endl;
203  std::cerr << face3[0] << " " << face3[1] << " " << face3[2]
204  << std::endl;
205  std::cerr << face4[0] << " " << face4[1] << " " << face4[2]
206  << std::endl;
207  std::cerr << offset << std::endl;
208  THROW_MESSAGE("Huston we have problem");
209  }
210  }
211  THROW_MESSAGE("Huston we have problem");
212  }
213 
214  if (num_nodes == 2) {
215  {
216  // Triangle edges
217  EntityHandle edges[6][2] = {
218  {conn[0], conn[1]} /*0*/, {conn[1], conn[2]} /*1*/,
219  {conn[2], conn[0]} /*2*/, {conn[3], conn[4]} /*3+3*/,
220  {conn[4], conn[5]} /*3+4*/, {conn[5], conn[3]} /*3+5*/
221  };
222  for (int ee = 0; ee < 6; ee++) {
223  if (((conn_ent[0] == edges[ee][0]) &&
224  (conn_ent[1] == edges[ee][1])) ||
225  ((conn_ent[0] == edges[ee][1]) &&
226  (conn_ent[1] == edges[ee][0]))) {
227  side_number = ee;
228  if (ee >= 3) {
229  side_number += 3;
230  EntityHandle *conn0_4_ptr =
231  std::find(face4, &face4[3], conn_ent[0]);
232  offset = std::distance(face4, conn0_4_ptr) + 3;
233  } else {
234  EntityHandle *conn0_3_ptr =
235  std::find(face3, &face3[3], conn_ent[0]);
236  offset = std::distance(face3, conn0_3_ptr);
237  }
238  sense = 1;
239  if ((conn_ent[0] == edges[ee][1]) && (conn_ent[1] == edges[ee][0]))
240  sense = -1;
241  miit = const_cast<SideNumber_multiIndex &>(side_number_table)
242  .insert(boost::shared_ptr<SideNumber>(
243  new SideNumber(ent, side_number, sense, offset)))
244  .first;
245  return *miit;
246  }
247  }
248  }
249  // {
250  // // Edges through thickness
251  // EntityHandle edges[3][2] = {
252  // { conn[0], conn[3] }, { conn[1], conn[4] }, { conn[2], conn[5] }
253  // };
254  // for(int ee = 0;ee<3;ee++) {
255  // if(
256  // (( conn_ent[0] == edges[ee][0] )&&( conn_ent[1] == edges[ee][1]
257  // ))||
258  // (( conn_ent[0] == edges[ee][1] )&&( conn_ent[1] == edges[ee][0]
259  // ))
260  // ) {
261  // side_number = 3+ee;
262  // offset = std::distance(conn,find(conn,&conn[6],conn_ent[0]));
263  // sense = 1;
264  // if(( conn_ent[0] == edges[ee][1] )&&( conn_ent[1] == edges[ee][0]
265  // )) sense = -1; miit =
266  // const_cast<SideNumber_multiIndex&>(side_number_table).insert(SideNumber(ent,side_number,sense,offset)).first;
267  // return const_cast<SideNumber*>(&*miit);
268  // }
269  // }
270  // }
271  // for(int nn = 0; nn<6;nn++) {
272  // std::cerr << conn[nn] << " ";
273  // };
274  // std::cerr << std::endl;
275  // std::cerr << conn_ent[0] << " " << conn_ent[1] << std::endl;
276  THROW_MESSAGE("Huston we have problem");
277  }
278  std::ostringstream sss;
279  sss << "this not working: " << ent
280  << " type: " << moab.type_from_handle(ent) << " " << MBEDGE << " "
281  << MBTRI << std::endl;
282  THROW_MESSAGE(sss.str().c_str());
283  }
284  miit = const_cast<SideNumber_multiIndex &>(side_number_table)
285  .insert(boost::shared_ptr<SideNumber>(
286  new SideNumber(ent, side_number, sense, offset)))
287  .first;
288  return *miit;
289  THROW_MESSAGE("not implemented");
290  return nullSideNumber;
291 }
292 
293 RefElement_TET::RefElement_TET(const boost::shared_ptr<RefEntity> &ref_ent_ptr)
294  : RefElement(ref_ent_ptr), tag_BitRefEdges(NULL) {
295  Tag th_RefBitEdge;
296  moab::Interface &moab = getRefEntityPtr()->basicDataPtr->moab;
297  rval = moab.tag_get_handle("_RefBitEdge", th_RefBitEdge);
298  MOAB_THROW(rval);
299  rval = moab.tag_get_by_ptr(th_RefBitEdge, &ref_ent_ptr->ent, 1,
300  (const void **)&tag_BitRefEdges);
301  MOAB_THROW(rval);
302  switch (ref_ent_ptr->getEntType()) {
303  case MBTET:
304  break;
305  default:
306  THROW_MESSAGE("this work only for TETs");
307  }
308  const_cast<SideNumber_multiIndex &>(side_number_table)
309  .insert(
310  boost::shared_ptr<SideNumber>(new SideNumber(sPtr->ent, 0, 0, 0)));
311 }
312 
313 const boost::shared_ptr<SideNumber> &
315  moab::Interface &moab = getRefEntityPtr()->basicDataPtr->moab;
316  SideNumber_multiIndex::iterator miit = side_number_table.find(ent);
317  if (miit != side_number_table.end())
318  return *miit;
319  if (sPtr->ent == ent) {
320  miit =
321  const_cast<SideNumber_multiIndex &>(side_number_table)
322  .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, 0, 0, 0)))
323  .first;
324  return *miit;
325  }
326  if (moab.type_from_handle(ent) == MBENTITYSET) {
327  miit =
328  const_cast<SideNumber_multiIndex &>(side_number_table)
329  .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, 0, 0, 0)))
330  .first;
331  return *miit;
332  }
333  int side_number, sense, offset;
334  rval = moab.side_number(sPtr->ent, ent, side_number, sense, offset);
335  MOAB_THROW(rval);
336  std::pair<SideNumber_multiIndex::iterator, bool> p_miit;
337  p_miit = const_cast<SideNumber_multiIndex &>(side_number_table)
338  .insert(boost::shared_ptr<SideNumber>(
339  new SideNumber(ent, side_number, sense, offset)));
340  miit = p_miit.first;
341  if (miit->get()->ent != ent) {
342  THROW_MESSAGE("this not working");
343  }
344  // std::cerr << side_number << " " << sense << " " << offset << std::endl;
345  return *miit;
346 }
347 std::ostream &operator<<(std::ostream &os, const RefElement_TET &e) {
348  os << "ref type " << e.tag_type_data[0] << " ref sub type "
349  << e.tag_type_data[1];
350  os << " ref egdes " << e.getBitRefEdges();
351  os << " " << *e.sPtr;
352  return os;
353 }
354 
355 RefElementFace::RefElementFace(const boost::shared_ptr<RefEntity> &ref_ent_ptr)
356  : RefElement(ref_ent_ptr) {
357 
358  int nb_nodes = 0;
359  int nb_edges = 0;
360  switch (ref_ent_ptr->getEntType()) {
361  case MBTRI:
362  nb_nodes = nb_edges = 3;
363  break;
364  case MBQUAD:
365  nb_nodes = nb_edges = 4;
366  break;
367  default:
368  THROW_MESSAGE("this works only for TRIs and QUADs");
369  }
370  int side_number, sense, offset;
371  EntityHandle tri = getRefEnt();
372  int num_nodes;
373  const EntityHandle *conn;
374  moab::Interface &moab = getRefEntityPtr()->basicDataPtr->moab;
375  rval = moab.get_connectivity(tri, conn, num_nodes, true);
376  MOAB_THROW(rval);
377  for (int nn = 0; nn < nb_nodes; nn++) {
378  const_cast<SideNumber_multiIndex &>(side_number_table)
379  .insert(
380  boost::shared_ptr<SideNumber>(new SideNumber(conn[nn], nn, 0, 0)));
381  }
382  for (int ee = 0; ee < nb_edges; ee++) {
383  EntityHandle edge;
384  rval = moab.side_element(tri, 1, ee, edge);
385  MOAB_THROW(rval);
386  rval = moab.side_number(tri, edge, side_number, sense, offset);
387  MOAB_THROW(rval);
388  const_cast<SideNumber_multiIndex &>(side_number_table)
389  .insert(boost::shared_ptr<SideNumber>(
390  new SideNumber(edge, ee, sense, offset)));
391  }
392  const_cast<SideNumber_multiIndex &>(side_number_table)
393  .insert(boost::shared_ptr<SideNumber>(new SideNumber(tri, 0, 0, 0)));
394 }
395 const boost::shared_ptr<SideNumber> &
397  moab::Interface &moab = getRefEntityPtr()->basicDataPtr->moab;
398  SideNumber_multiIndex::iterator miit = side_number_table.find(ent);
399  if (miit != side_number_table.end())
400  return *miit;
401  if (sPtr->ent == ent) {
402  miit =
403  const_cast<SideNumber_multiIndex &>(side_number_table)
404  .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, 0, 0, 0)))
405  .first;
406  return *miit;
407  }
408  if (moab.type_from_handle(ent) == MBENTITYSET) {
409  miit =
410  const_cast<SideNumber_multiIndex &>(side_number_table)
411  .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, 0, 0, 0)))
412  .first;
413  return *miit;
414  }
415  int side_number, sense, offset;
416  rval = moab.side_number(sPtr->ent, ent, side_number, sense, offset);
417  MOAB_THROW(rval);
418  miit = const_cast<SideNumber_multiIndex &>(side_number_table)
419  .insert(boost::shared_ptr<SideNumber>(
420  new SideNumber(ent, side_number, sense, offset)))
421  .first;
422  // std::cerr << side_number << " " << sense << " " << offset << std::endl;
423  return *miit;
424 }
425 std::ostream &operator<<(std::ostream &os, const RefElementFace &e) {
426  os << *e.sPtr;
427  return os;
428 }
430  const boost::shared_ptr<RefEntity> &ref_ent_ptr)
431  : RefElement(ref_ent_ptr) {
432  switch (ref_ent_ptr->getEntType()) {
433  case MBEDGE:
434  break;
435  default:
436  THROW_MESSAGE("this work only for TRIs");
437  }
438 }
439 const boost::shared_ptr<SideNumber> &
441  moab::Interface &moab = getRefEntityPtr()->basicDataPtr->moab;
442  SideNumber_multiIndex::iterator miit = side_number_table.find(ent);
443  if (miit != side_number_table.end())
444  return *miit;
445  if (sPtr->ent == ent) {
446  miit =
447  const_cast<SideNumber_multiIndex &>(side_number_table)
448  .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, 0, 0, 0)))
449  .first;
450  return *miit;
451  }
452  if (moab.type_from_handle(ent) == MBENTITYSET) {
453  miit =
454  const_cast<SideNumber_multiIndex &>(side_number_table)
455  .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, 0, 0, 0)))
456  .first;
457  return *miit;
458  }
459  int side_number, sense, offset;
460  rval = moab.side_number(sPtr->ent, ent, side_number, sense, offset);
461  MOAB_THROW(rval);
462  miit = const_cast<SideNumber_multiIndex &>(side_number_table)
463  .insert(boost::shared_ptr<SideNumber>(
464  new SideNumber(ent, side_number, sense, offset)))
465  .first;
466  // std::cerr << side_number << " " << sense << " " << offset << std::endl;
467  return *miit;
468 }
469 std::ostream &operator<<(std::ostream &os, const RefElement_EDGE &e) {
470  os << *e.sPtr;
471  return os;
472 }
474  const boost::shared_ptr<RefEntity> &ref_ent_ptr)
475  : RefElement(ref_ent_ptr) {
476  switch (ref_ent_ptr->getEntType()) {
477  case MBVERTEX:
478  break;
479  default:
480  THROW_MESSAGE("this works only for TRIs");
481  }
482 }
483 const boost::shared_ptr<SideNumber> &
485  moab::Interface &moab = getRefEntityPtr()->basicDataPtr->moab;
486  SideNumber_multiIndex::iterator miit = side_number_table.find(ent);
487  if (miit != side_number_table.end())
488  return *miit;
489  if (sPtr->ent == ent) {
490  miit =
491  const_cast<SideNumber_multiIndex &>(side_number_table)
492  .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, 0, 0, 0)))
493  .first;
494  return *miit;
495  }
496  if (moab.type_from_handle(ent) == MBENTITYSET) {
497  miit =
498  const_cast<SideNumber_multiIndex &>(side_number_table)
499  .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, 0, 0, 0)))
500  .first;
501  return *miit;
502  }
503  THROW_MESSAGE("no side entity for vertex if its is not an vertex itself");
504  return nullSideNumber;
505 }
506 std::ostream &operator<<(std::ostream &os, const RefElement_VERTEX &e) {
507  os << *e.sPtr;
508  return os;
509 }
510 
512  moab::Interface &moab, const Field &field_ptr,
513  const EntFiniteElement &fe_ptr, Range &adjacency) {
515  switch (field_ptr.getSpace()) {
516  case H1:
517  adjacency.insert(fe_ptr.getEnt());
518  break;
519  case NOFIELD: {
520  Range ents;
521  CHKERR moab.get_entities_by_handle(field_ptr.getMeshset(), ents, false);
522  adjacency.merge(ents);
523  for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
524  const_cast<SideNumber_multiIndex &>(fe_ptr.getSideNumberTable())
525  .insert(
526  boost::shared_ptr<SideNumber>(new SideNumber(*eit, -1, 0, 0)));
527  }
528  } break;
529  default:
530  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
531  "this field is not implemented for VERTEX finite element");
532  }
533  // build side table
534  for (Range::iterator eit = adjacency.begin(); eit != adjacency.end(); eit++) {
535  fe_ptr.getSideNumberPtr(*eit);
536  }
538 }
540  moab::Interface &moab, const Field &field_ptr,
541  const EntFiniteElement &fe_ptr, Range &adjacency) {
543  EntityHandle fe_ent = fe_ptr.getEnt();
544  // Range nodes;
545  switch (field_ptr.getSpace()) {
546  case H1:
547  CHKERR moab.get_connectivity(&fe_ent, 1, adjacency, true);
548  case L2:
549  case HCURL:
550  adjacency.insert(fe_ent);
551  break;
552  case NOFIELD: {
553  Range ents;
554  CHKERR moab.get_entities_by_handle(field_ptr.getMeshset(), ents, false);
555  adjacency.merge(ents);
556  for (auto e : ents) {
557  const_cast<SideNumber_multiIndex &>(fe_ptr.getSideNumberTable())
558  .insert(boost::shared_ptr<SideNumber>(new SideNumber(e, -1, 0, 0)));
559  }
560  } break;
561  default:
562  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
563  "this field is not implemented for EDGE finite element");
564  }
565  // build side table
566  for (auto e : adjacency)
567  fe_ptr.getSideNumberPtr(e);
569 }
570 
572  moab::Interface &moab, const Field &field_ptr,
573  const EntFiniteElement &fe_ptr, Range &adjacency) {
575  // Range nodes,edges;
576  const EntityHandle fe_ent = fe_ptr.getEnt();
577  switch (field_ptr.getSpace()) {
578  case H1:
579  CHKERR moab.get_connectivity(&fe_ent, 1, adjacency, true);
580  case HCURL:
581  CHKERR moab.get_adjacencies(&fe_ent, 1, 1, false, adjacency,
582  moab::Interface::UNION);
583  case HDIV:
584  adjacency.insert(fe_ent);
585  break;
586  case NOFIELD: {
587  Range ents;
588  CHKERR moab.get_entities_by_handle(field_ptr.getMeshset(), ents, false);
589  adjacency.merge(ents);
590  for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
591  const_cast<SideNumber_multiIndex &>(fe_ptr.getSideNumberTable())
592  .insert(
593  boost::shared_ptr<SideNumber>(new SideNumber(*eit, -1, 0, 0)));
594  }
595  } break;
596  case L2:
597  adjacency.insert(fe_ent); // add this just in case, if L2 is on skeleton
598  break;
599  default:
600  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
601  "this field is not implemented for TRI finite element");
602  }
603  // build side table
604  for (Range::iterator eit = adjacency.begin(); eit != adjacency.end(); eit++)
605  fe_ptr.getSideNumberPtr(*eit);
607 }
609  moab::Interface &moab, const Field &field_ptr,
610  const EntFiniteElement &fe_ptr, Range &adjacency) {
612  EntityHandle fe_ent = fe_ptr.getEnt();
613  switch (field_ptr.getSpace()) {
614  case H1:
615  CHKERR moab.get_connectivity(&fe_ent, 1, adjacency, true);
616  case HCURL:
617  CHKERR moab.get_adjacencies(&fe_ent, 1, 1, false, adjacency,
618  moab::Interface::UNION);
619  case HDIV:
620  CHKERR moab.get_adjacencies(&fe_ent, 1, 2, false, adjacency,
621  moab::Interface::UNION);
622  case L2:
623  adjacency.insert(fe_ent);
624  break;
625  case NOFIELD: {
626  Range ents;
627  CHKERR moab.get_entities_by_handle(field_ptr.getMeshset(), ents, false);
628  adjacency.merge(ents);
629  for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
630  const_cast<SideNumber_multiIndex &>(fe_ptr.getSideNumberTable())
631  .insert(
632  boost::shared_ptr<SideNumber>(new SideNumber(*eit, -1, 0, 0)));
633  }
634  } break;
635  default:
636  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
637  "this field is not implemented for TRI finite element");
638  }
639  // build side table
640  for (Range::iterator eit = adjacency.begin(); eit != adjacency.end(); eit++)
641  fe_ptr.getSideNumberPtr(*eit);
643 }
644 
646  moab::Interface &moab, const Field &field_ptr,
647  const EntFiniteElement &fe_ptr, Range &adjacency) {
649  const EntityHandle prism = fe_ptr.getEnt();
650  Range nodes;
651  // initialize side sets
652  fe_ptr.getRefElement()->getSideNumberPtr(prism);
653  EntityHandle face_side3, face_side4;
654  CHKERR moab.side_element(prism, 2, 3, face_side3);
655  CHKERR moab.side_element(prism, 2, 4, face_side4);
656  fe_ptr.getRefElement()->getSideNumberPtr(face_side3);
657  fe_ptr.getRefElement()->getSideNumberPtr(face_side4);
658  for (int qq = 0; qq < 3; qq++) {
659  EntityHandle quad = 0;
660  rval = moab.side_element(prism, 2, qq, quad);
661  if (rval != MB_SUCCESS || quad == 0)
662  continue;
663  int side_number, sense, offset;
664  rval = moab.side_number(prism, quad, side_number, sense, offset);
665  if (side_number == -1 || rval != MB_SUCCESS)
666  continue;
667  const_cast<SideNumber_multiIndex &>(fe_ptr.getSideNumberTable())
668  .insert(boost::shared_ptr<SideNumber>(
669  new SideNumber(quad, side_number, sense, offset)));
670  }
671  int ee = 0;
672  for (; ee < 3; ee++) {
673  EntityHandle edge = 0;
674  CHKERR moab.side_element(prism, 1, ee, edge);
675  boost::shared_ptr<SideNumber> side_ptr =
676  fe_ptr.getRefElement()->getSideNumberPtr(edge);
677  if (side_ptr->side_number != ee) {
678  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
679  "data inconsistency for edge %d while in FE datastructure is "
680  "numbered %d.",
681  ee, side_ptr->side_number);
682  }
683  CHKERR moab.side_element(prism, 1, 6 + ee, edge);
684  side_ptr = fe_ptr.getRefElement()->getSideNumberPtr(edge);
685  if (side_ptr->side_number != ee + 6) {
686  if (side_ptr->side_number != ee) {
687  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
688  "data inconsistency for edge %d while in FE datastructure "
689  "is numbered %d.",
690  ee, side_ptr->side_number);
691  } else {
692  side_ptr->brother_side_number = ee + 6;
693  }
694  }
695  }
696  for (; ee < 6; ee++) {
697  EntityHandle edge = 0;
698  rval = moab.side_element(prism, 1, ee, edge);
699  if (rval != MB_SUCCESS || edge == 0)
700  continue;
701  int side_number, sense, offset;
702  rval = moab.side_number(prism, edge, side_number, sense, offset);
703  if (side_number == -1 || rval != MB_SUCCESS)
704  continue;
705  const_cast<SideNumber_multiIndex &>(fe_ptr.getSideNumberTable())
706  .insert(boost::shared_ptr<SideNumber>(
707  new SideNumber(edge, side_number, sense, offset)));
708  }
709  int nn = 0;
710  for (; nn < 3; nn++) {
711  EntityHandle node;
712  CHKERR moab.side_element(prism, 0, nn, node);
713  boost::shared_ptr<SideNumber> side_ptr =
714  fe_ptr.getRefElement()->getSideNumberPtr(node);
715  if (side_ptr->side_number != nn) {
716  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
717  "data inconsistency for node %d while in FE datastructure is "
718  "numbered %d.",
719  nn, side_ptr->side_number);
720  }
721  CHKERR moab.side_element(prism, 0, nn + 3, node);
722  side_ptr = fe_ptr.getRefElement()->getSideNumberPtr(node);
723  if (side_ptr->side_number != nn + 3) {
724  if (side_ptr->side_number != nn) {
725  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
726  "data inconsistency for node %d while in FE datastructure is "
727  "numbered %d.",
728  nn, side_ptr->side_number);
729  } else {
730  side_ptr->brother_side_number = nn + 3;
731  }
732  }
733  }
734 
735  // get adjacencies
736  SideNumber_multiIndex &side_table =
737  fe_ptr.getRefElement()->getSideNumberTable();
738  switch (field_ptr.getSpace()) {
739  case H1:
740  // moab.get_connectivity(&prism,1,nodes,true);
741  // use get adjacencies, this will allow take in account adjacencies set user
742  CHKERR moab.get_adjacencies(&prism, 1, 0, false, nodes,
743  moab::Interface::UNION);
744  {
745  Range topo_nodes;
746  CHKERR moab.get_connectivity(&prism, 1, topo_nodes, true);
747  Range mid_nodes;
748  CHKERR moab.get_connectivity(&prism, 1, mid_nodes, false);
749  mid_nodes = subtract(mid_nodes, topo_nodes);
750  nodes = subtract(nodes, mid_nodes);
751  }
752  adjacency.insert(nodes.begin(), nodes.end());
753  case HCURL: {
754  SideNumber_multiIndex::nth_index<2>::type::iterator siit, hi_siit;
755  siit = side_table.get<2>().lower_bound(MBEDGE);
756  hi_siit = side_table.get<2>().upper_bound(MBEDGE);
757  for (; siit != hi_siit; siit++)
758  adjacency.insert(siit->get()->ent);
759  }
760  case HDIV: {
761  SideNumber_multiIndex::nth_index<2>::type::iterator siit, hi_siit;
762  siit = side_table.get<2>().lower_bound(MBTRI);
763  hi_siit = side_table.get<2>().upper_bound(MBTRI);
764  for (; siit != hi_siit; siit++)
765  adjacency.insert(siit->get()->ent);
766  siit = side_table.get<2>().lower_bound(MBQUAD);
767  hi_siit = side_table.get<2>().upper_bound(MBQUAD);
768  for (; siit != hi_siit; siit++)
769  adjacency.insert(siit->get()->ent);
770  }
771  case L2:
772  adjacency.insert(prism);
773  break;
774  case NOFIELD: {
775  Range ents;
776  CHKERR moab.get_entities_by_handle(field_ptr.getMeshset(), ents, false);
777  adjacency.merge(ents);
778  for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
779  const_cast<SideNumber_multiIndex &>(fe_ptr.getSideNumberTable())
780  .insert(
781  boost::shared_ptr<SideNumber>(new SideNumber(*eit, -1, 0, 0)));
782  }
783  } break;
784  default:
785  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
786  "this field is not implemented for TRI finite element");
787  }
789 }
791  moab::Interface &moab, const Field &field_ptr,
792  const EntFiniteElement &fe_ptr, Range &adjacency) {
794  EntityHandle fe_ent = fe_ptr.getEnt();
795  // get all meshsets in finite element meshset
796  Range ent_ents_meshset;
797  CHKERR moab.get_entities_by_type(fe_ent, MBENTITYSET, ent_ents_meshset,
798  false);
799  // resolve recursively all ents in the meshset
800  Range ent_ents;
801  CHKERR moab.get_entities_by_handle(fe_ent, ent_ents, true);
802  switch (field_ptr.getSpace()) {
803  case H1:
804  adjacency.merge(ent_ents.subset_by_type(MBVERTEX));
805  case HCURL:
806  adjacency.merge(ent_ents.subset_by_type(MBEDGE));
807  case HDIV:
808  adjacency.merge(ent_ents.subset_by_type(MBTRI));
809  case L2:
810  adjacency.merge(ent_ents.subset_by_type(MBTET));
811  break;
812  case NOFIELD: {
813  Range ents;
814  CHKERR moab.get_entities_by_handle(field_ptr.getMeshset(), ents, false);
815  adjacency.merge(ents);
816  for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
817  const_cast<SideNumber_multiIndex &>(fe_ptr.getSideNumberTable())
818  .insert(
819  boost::shared_ptr<SideNumber>(new SideNumber(*eit, -1, 0, 0)));
820  }
821  } break;
822  default:
823  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
824  }
826 }
827 
828 // FiniteElement
829 FiniteElement::FiniteElement(moab::Interface &moab, const EntityHandle _meshset)
830  : meshset(_meshset) {
831  Tag th_FEId;
832  rval = moab.tag_get_handle("_FEId", th_FEId);
833  MOAB_THROW(rval);
834  rval = moab.tag_get_by_ptr(th_FEId, &meshset, 1, (const void **)&tagId);
835  MOAB_THROW(rval);
836  Tag th_FEName;
837  rval = moab.tag_get_handle("_FEName", th_FEName);
838  MOAB_THROW(rval);
839  rval = moab.tag_get_by_ptr(th_FEName, &meshset, 1, (const void **)&tagName,
840  &tagNameSize);
841  MOAB_THROW(rval);
842  Tag th_FEIdCol, th_FEIdRow, th_FEIdData;
843  rval = moab.tag_get_handle("_FEIdCol", th_FEIdCol);
844  MOAB_THROW(rval);
845  rval = moab.tag_get_by_ptr(th_FEIdCol, &meshset, 1,
846  (const void **)&tag_BitFieldId_col_data);
847  MOAB_THROW(rval);
848  rval = moab.tag_get_handle("_FEIdRow", th_FEIdRow);
849  MOAB_THROW(rval);
850  rval = moab.tag_get_by_ptr(th_FEIdRow, &meshset, 1,
851  (const void **)&tag_BitFieldId_row_data);
852  MOAB_THROW(rval);
853  rval = moab.tag_get_handle("_FEIdData", th_FEIdData);
854  MOAB_THROW(rval);
855  rval = moab.tag_get_by_ptr(th_FEIdData, &meshset, 1,
856  (const void **)&tag_BitFieldId_data);
857  MOAB_THROW(rval);
858 
866 }
867 
868 std::ostream &operator<<(std::ostream &os, const FiniteElement &e) {
869  os << "id " << e.getId() << " name " << e.getNameRef() << " f_id_row "
870  << e.getBitFieldIdRow() << " f_id_col " << e.getBitFieldIdCol()
871  << " BitFEId_data " << e.getBitFieldIdData();
872  return os;
873 }
874 
876 operator()(boost::shared_ptr<FiniteElement> &fe) {
877  *((BitFieldId *)(fe->tag_BitFieldId_col_data)) |= fIdCol;
878 }
879 
881 operator()(boost::shared_ptr<FiniteElement> &fe) {
882  *((BitFieldId *)(fe->tag_BitFieldId_row_data)) |= fIdRow;
883 }
884 
886 operator()(boost::shared_ptr<FiniteElement> &fe) {
887  *((BitFieldId *)(fe->tag_BitFieldId_data)) |= fIdData;
888 }
889 
891 operator()(boost::shared_ptr<FiniteElement> &fe) {
892  *((BitFieldId *)(fe->tag_BitFieldId_col_data)) &= fIdCol.flip();
893 }
894 
896 operator()(boost::shared_ptr<FiniteElement> &fe) {
897  *((BitFieldId *)(fe->tag_BitFieldId_row_data)) &= fIdRow.flip();
898 }
899 
901 operator()(boost::shared_ptr<FiniteElement> &fe) {
902  *((BitFieldId *)(fe->tag_BitFieldId_data)) &= fIdData.flip();
903 }
904 
905 // FiniteElement data
907  const boost::shared_ptr<RefElement> &ref_finite_element,
908  const boost::shared_ptr<FiniteElement> &fe_ptr)
910  interface_RefElement<RefElement>(ref_finite_element),
911  data_dofs(new FEDofEntity_multiIndex()),
912  row_field_ents_view(new FieldEntity_vector_view()),
913  col_field_ents_view(new FieldEntity_vector_view()),
914  data_field_ents_view(new FieldEntity_multiIndex_spaceType_view()) {
915  // get finite element entity
917 }
918 
919 std::ostream &operator<<(std::ostream &os, const EntFiniteElement &e) {
920  os << *e.sFePtr << std::endl;
921  os << *e.sPtr << std::endl;
922  os << "data dof_uids ";
923  FEDofEntity_multiIndex::iterator dit;
924  dit = e.data_dofs->begin();
925  for (; dit != e.data_dofs->end(); dit++) {
926  if (!(*dit)) {
927  os << "null ptr";
928  } else {
929  if (!(*dit)->getDofEntityPtr()) {
930  os << "( null ptr to dof ) ";
931  } else {
932  if (!(*dit)->getFieldEntityPtr()) {
933  os << "(( null ptr to field entity )) ";
934  } else {
935  os << (*dit)->getGlobalUniqueId() << " ";
936  }
937  }
938  }
939  }
940  return os;
941 }
942 
944 EntFiniteElement::getElementAdjacency(const boost::shared_ptr<Field> field_ptr,
945  Range &adjacency) {
946  moab::Interface &moab = getRefEntityPtr()->basicDataPtr->moab;
948  const EntFiniteElement *this_fe_ptr = this;
949  if (get_MoFEMFiniteElementPtr()->elementAdjacencyTable[getEntType()] ==
950  NULL) {
951  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
952  }
953  CHKERR get_MoFEMFiniteElementPtr()->elementAdjacencyTable[getEntType()](
954  moab, *field_ptr, *this_fe_ptr, adjacency);
956 }
957 
958 boost::weak_ptr<FENumeredDofEntity>
960  auto comp = [idx](const auto &a) { return a->getPetscGlobalDofIdx() == idx; };
961  auto dit = std::find_if(rows_dofs->begin(), rows_dofs->end(), comp);
962  if (dit != rows_dofs->end())
963  return *dit;
964  else
965  return boost::weak_ptr<FENumeredDofEntity>();
966 }
967 
968 boost::weak_ptr<FENumeredDofEntity>
970  auto comp = [idx](const auto &a) { return a->getPetscGlobalDofIdx() == idx; };
971  auto dit = std::find_if(cols_dofs->begin(), cols_dofs->end(), comp);
972  if (dit != cols_dofs->end())
973  return *dit;
974  else
975  return boost::weak_ptr<FENumeredDofEntity>();
976 }
977 
978 } // namespace MoFEM
keeps data about abstract VERTEX finite element
boost::shared_ptr< T > sPtr
boost::weak_ptr< FENumeredDofEntity > getColDofsByPetscGlobalDofIdx(const int idx) const
get FE dof by petsc index
RefElementFace(const boost::shared_ptr< RefEntity > &ref_ent_ptr)
void operator()(boost::shared_ptr< FiniteElement > &fe)
void operator()(boost::shared_ptr< FiniteElement > &fe)
RefElement_MESHSET(const boost::shared_ptr< RefEntity > &ref_ent_ptr)
field with continuous normal traction
Definition: definitions.h:173
RefElement_EDGE(const boost::shared_ptr< RefEntity > &ref_ent_ptr)
const BitRefEdges & getBitRefEdges() const
EntFiniteElement(const boost::shared_ptr< RefElement > &ref_finite_element, const boost::shared_ptr< FiniteElement > &fe_ptr)
Provide data structure for (tensor) field approximation.The Field is intended to provide support for ...
const boost::shared_ptr< SideNumber > & getSideNumberPtr(const EntityHandle ent) const
static MoFEMErrorCode defaultFace(Interface &moab, const Field &field_ptr, const EntFiniteElement &fe_ptr, Range &adjacency)
static MoFEMErrorCode defaultVertex(Interface &moab, const Field &field_ptr, const EntFiniteElement &fe_ptr, Range &adjacency)
SideNumber_multiIndex side_number_table
scalar or vector of scalars describe (no true field)
Definition: definitions.h:170
const boost::shared_ptr< FiniteElement > & get_MoFEMFiniteElementPtr()
std::vector< boost::weak_ptr< FieldEntity > > FieldEntity_vector_view
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:477
BitFieldId getBitFieldIdRow() const
Get field ids on rows.
virtual const BitRefEdges & getBitRefEdges() const
const boost::shared_ptr< SideNumber > & getSideNumberPtr(const EntityHandle ent) const
boost::shared_ptr< RefEntity > & getRefEntityPtr() const
UId getGlobalUniqueIdCalculate() const
Generate UId for finite element entity.
void operator()(boost::shared_ptr< FiniteElement > &fe)
#define THROW_MESSAGE(a)
Throw MoFEM exception.
Definition: definitions.h:620
BitFieldId * tag_BitFieldId_row_data
tag stores row id_id for fields
BitFieldId * tag_BitFieldId_data
tag stores data id_id for fields
EntityHandle getEnt() const
Get element entity.
#define MOAB_THROW(a)
Check error code of MoAB function and throw MoFEM exception.
Definition: definitions.h:602
Struct keeps handle to refined handle.
const boost::shared_ptr< SideNumber > & getSideNumberPtr(const EntityHandle ent) const
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:21
FieldSpace getSpace() const
Get field approximation space.
BitFieldId getBitFieldIdData() const
Get field ids on data.
const boost::shared_ptr< SideNumber > & getSideNumberPtr(const EntityHandle ent) const
keeps data about abstract refined finite element
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
Definition: Exceptions.hpp:84
std::ostream & operator<<(std::ostream &os, const DataForcesAndSourcesCore::EntData &e)
BitRefEdges * tag_BitRefEdges
void operator()(boost::shared_ptr< FiniteElement > &fe)
boost::weak_ptr< FENumeredDofEntity > getRowDofsByPetscGlobalDofIdx(const int idx) const
get FE dof by petsc index
multi_index_container< boost::shared_ptr< FieldEntity >, indexed_by< sequenced<>, ordered_non_unique< tag< Composite_EntType_and_Space_mi_tag >, composite_key< FieldEntity, const_mem_fun< FieldEntity::interface_type_RefEntity, EntityType, &FieldEntity::getEntType >, const_mem_fun< FieldEntity::interface_type_Field, FieldSpace, &FieldEntity::getSpace > > > > > FieldEntity_multiIndex_spaceType_view
RefElement(const boost::shared_ptr< RefEntity > &ref_ent_ptr)
keeps data about abstract TRI finite element
static MoFEMErrorCode defaultTet(Interface &moab, const Field &field_ptr, const EntFiniteElement &fe_ptr, Range &adjacency)
Finite element definition.
boost::shared_ptr< FEDofEntity_multiIndex > data_dofs
boost::shared_ptr< RefEntity > & getRefEntityPtr() const
Get pointer to RefEntity.
EntityHandle meshset
meshset stores FE ents
ElementAdjacencyFunct elementAdjacencyTable[MBMAXTYPE]
Table of functions retrieving adjacencies for finite element User can alter and change default behavi...
BitFEId * tagId
ptr to tag storing FE id
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:66
BitRefEdges * tag_BitRefEdges
void operator()(boost::shared_ptr< FiniteElement > &fe)
int tagNameSize
numer of characters in FE name
boost::shared_ptr< T > sFePtr
boost::shared_ptr< FENumeredDofEntity_multiIndex > rows_dofs
indexed dofs on rows
interface to RefEntity
RefElement_VERTEX(const boost::shared_ptr< RefEntity > &ref_ent_ptr)
boost::shared_ptr< FENumeredDofEntity_multiIndex > cols_dofs
indexed dofs on columns
BitFEId getId() const
Get finite element id.
static MoFEMErrorCode defaultEdge(Interface &moab, const Field &field_ptr, const EntFiniteElement &fe_ptr, Range &adjacency)
field with continuous tangents
Definition: definitions.h:172
keeps data about abstract TET finite element
intrface to RefElement
std::bitset< BITFIELDID_SIZE > BitFieldId
Field Id.
Definition: Types.hpp:53
Finite element data for entity.
#define CHKERR
Inline error check.
Definition: definitions.h:596
multi_index_container< boost::shared_ptr< FEDofEntity >, indexed_by< ordered_unique< tag< Unique_mi_tag >, const_mem_fun< FEDofEntity::interface_type_DofEntity, const UId &, &FEDofEntity::getGlobalUniqueId > >, ordered_non_unique< tag< Ent_mi_tag >, const_mem_fun< FEDofEntity::interface_type_DofEntity, EntityHandle, &FEDofEntity::getEnt > >, ordered_non_unique< tag< FieldName_mi_tag >, const_mem_fun< FEDofEntity::interface_type_Field, boost::string_ref, &FEDofEntity::getNameRef > >, ordered_non_unique< tag< EntType_mi_tag >, const_mem_fun< FEDofEntity::interface_type_RefEntity, EntityType, &FEDofEntity::getEntType > >, ordered_non_unique< tag< Composite_Name_And_Type_mi_tag >, composite_key< FEDofEntity, const_mem_fun< FEDofEntity::interface_type_Field, boost::string_ref, &FEDofEntity::getNameRef >, const_mem_fun< FEDofEntity::interface_type_RefEntity, EntityType, &FEDofEntity::getEntType > > >, ordered_non_unique< tag< Composite_Name_And_Ent_mi_tag >, composite_key< FEDofEntity, const_mem_fun< FEDofEntity::interface_type_Field, boost::string_ref, &FEDofEntity::getNameRef >, const_mem_fun< FEDofEntity::interface_type_DofEntity, EntityHandle, &FEDofEntity::getEnt > > >, ordered_non_unique< tag< Composite_Name_Type_And_Side_Number_mi_tag >, composite_key< FEDofEntity, const_mem_fun< FEDofEntity::interface_type_Field, boost::string_ref, &FEDofEntity::getNameRef >, const_mem_fun< FEDofEntity::interface_type_RefEntity, EntityType, &FEDofEntity::getEntType >, KeyFromKey< member< SideNumber, char, &SideNumber::side_number >, member< FEDofEntity::BaseFEEntity, boost::shared_ptr< SideNumber >, &FEDofEntity::sideNumberPtr > > > > > > FEDofEntity_multiIndex
MultiIndex container keeps FEDofEntity.
FiniteElement(Interface &moab, const EntityHandle _meshset)
SideNumber_multiIndex & getSideNumberTable() const
boost::shared_ptr< RefElement > & getRefElement() const
RefElement_PRISM(const boost::shared_ptr< RefEntity > &ref_ent_ptr)
static MoFEMErrorCode defaultPrism(Interface &moab, const Field &field_ptr, const EntFiniteElement &fe_ptr, Range &adjacency)
BitFieldId * tag_BitFieldId_col_data
tag stores col id_id for fields
MoFEMErrorCode getElementAdjacency(const boost::shared_ptr< Field > field_ptr, Range &adjacency)
BitFieldId getBitFieldIdCol() const
Get field ids on columns.
keeps data about abstract EDGE finite element
static MoFEMErrorCode defaultMeshset(Interface &moab, const Field &field_ptr, const EntFiniteElement &fe_ptr, Range &adjacency)
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:407
void * tagName
ptr to tag storing FE name
continuous field
Definition: definitions.h:171
EntityHandle getMeshset() const
Get field meshset.
const boost::shared_ptr< SideNumber > & getSideNumberPtr(const EntityHandle ent) const
multi_index_container< boost::shared_ptr< SideNumber >, indexed_by< hashed_unique< member< SideNumber, EntityHandle, &SideNumber::ent > >, ordered_non_unique< composite_key< SideNumber, const_mem_fun< SideNumber, EntityType, &SideNumber::getEntType >, member< SideNumber, char, &SideNumber::side_number > > >, ordered_non_unique< const_mem_fun< SideNumber, EntityType, &SideNumber::getEntType > > > > SideNumber_multiIndex
SideNumber_multiIndex for SideNumber.
RefElement_TET(const boost::shared_ptr< RefEntity > &ref_ent_ptr)
boost::string_ref getNameRef() const
Get finite element name.
#define NOT_USED(x)
Definition: definitions.h:303
const boost::shared_ptr< SideNumber > & getSideNumberPtr(const EntityHandle ent) const
static const boost::shared_ptr< SideNumber > nullSideNumber
void operator()(boost::shared_ptr< FiniteElement > &fe)
const boost::shared_ptr< SideNumber > & getSideNumberPtr(const EntityHandle ent) const
field with C-1 continuity
Definition: definitions.h:174