v0.9.1
FEMultiIndices.cpp
Go to the documentation of this file.
1 /** \file FEMultiIndices.cpp
2  * \brief Multi-index containers for finite elements
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, const EntFiniteElement &fe,
513  Range &adjacency) {
515  switch (field.getSpace()) {
516  case H1:
517  adjacency.insert(fe.getEnt());
518  break;
519  case NOFIELD: {
520  Range ents;
521  CHKERR moab.get_entities_by_handle(field.getMeshset(), ents, false);
522  adjacency.merge(ents);
523  for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
524  const_cast<SideNumber_multiIndex &>(fe.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.getSideNumberPtr(*eit);
536  }
538 }
539 
541  const Field &field,
542  const EntFiniteElement &fe,
543  Range &adjacency) {
545  EntityHandle fe_ent = fe.getEnt();
546  // Range nodes;
547  switch (field.getSpace()) {
548  case H1:
549  CHKERR moab.get_connectivity(&fe_ent, 1, adjacency, true);
550  case L2:
551  case HCURL:
552  adjacency.insert(fe_ent);
553  break;
554  case NOFIELD: {
555  Range ents;
556  CHKERR moab.get_entities_by_handle(field.getMeshset(), ents, false);
557  adjacency.merge(ents);
558  for (auto e : ents) {
559  const_cast<SideNumber_multiIndex &>(fe.getSideNumberTable())
560  .insert(boost::shared_ptr<SideNumber>(new SideNumber(e, -1, 0, 0)));
561  }
562  } break;
563  default:
564  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
565  "this field is not implemented for EDGE finite element");
566  }
567  // build side table
568  for (auto e : adjacency)
569  fe.getSideNumberPtr(e);
571 }
572 
574  const Field &field,
575  const EntFiniteElement &fe,
576  Range &adjacency) {
578  // Range nodes,edges;
579  const EntityHandle fe_ent = fe.getEnt();
580  switch (field.getSpace()) {
581  case H1:
582  CHKERR moab.get_connectivity(&fe_ent, 1, adjacency, true);
583  case HCURL:
584  CHKERR moab.get_adjacencies(&fe_ent, 1, 1, false, adjacency,
585  moab::Interface::UNION);
586  case HDIV:
587  adjacency.insert(fe_ent);
588  break;
589  case NOFIELD: {
590  Range ents;
591  CHKERR moab.get_entities_by_handle(field.getMeshset(), ents, false);
592  adjacency.merge(ents);
593  for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
594  const_cast<SideNumber_multiIndex &>(fe.getSideNumberTable())
595  .insert(
596  boost::shared_ptr<SideNumber>(new SideNumber(*eit, -1, 0, 0)));
597  }
598  } break;
599  case L2:
600  adjacency.insert(fe_ent); // add this just in case, if L2 is on skeleton
601  break;
602  default:
603  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
604  "this field is not implemented for TRI finite element");
605  }
606  // build side table
607  for (Range::iterator eit = adjacency.begin(); eit != adjacency.end(); eit++)
608  fe.getSideNumberPtr(*eit);
610 }
611 
613  const Field &field,
614  const EntFiniteElement &fe,
615  Range &adjacency) {
617  EntityHandle fe_ent = fe.getEnt();
618  switch (field.getSpace()) {
619  case H1:
620  CHKERR moab.get_connectivity(&fe_ent, 1, adjacency, true);
621  case HCURL:
622  CHKERR moab.get_adjacencies(&fe_ent, 1, 1, false, adjacency,
623  moab::Interface::UNION);
624  case HDIV:
625  CHKERR moab.get_adjacencies(&fe_ent, 1, 2, false, adjacency,
626  moab::Interface::UNION);
627  case L2:
628  adjacency.insert(fe_ent);
629  break;
630  case NOFIELD: {
631  Range ents;
632  CHKERR moab.get_entities_by_handle(field.getMeshset(), ents, false);
633  adjacency.merge(ents);
634  for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
635  const_cast<SideNumber_multiIndex &>(fe.getSideNumberTable())
636  .insert(
637  boost::shared_ptr<SideNumber>(new SideNumber(*eit, -1, 0, 0)));
638  }
639  } break;
640  default:
641  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
642  "this field is not implemented for TRI finite element");
643  }
644  // build side table
645  for (Range::iterator eit = adjacency.begin(); eit != adjacency.end(); eit++)
646  fe.getSideNumberPtr(*eit);
648 }
649 
651  const Field &field,
652  const EntFiniteElement &fe,
653  Range &adjacency) {
655  const EntityHandle prism = fe.getEnt();
656  Range nodes;
657  // initialize side sets
658  fe.getRefElement()->getSideNumberPtr(prism);
659  EntityHandle face_side3, face_side4;
660  CHKERR moab.side_element(prism, 2, 3, face_side3);
661  CHKERR moab.side_element(prism, 2, 4, face_side4);
662  fe.getRefElement()->getSideNumberPtr(face_side3);
663  fe.getRefElement()->getSideNumberPtr(face_side4);
664  for (int qq = 0; qq < 3; qq++) {
665  EntityHandle quad = 0;
666  rval = moab.side_element(prism, 2, qq, quad);
667  if (rval != MB_SUCCESS || quad == 0)
668  continue;
669  int side_number, sense, offset;
670  rval = moab.side_number(prism, quad, side_number, sense, offset);
671  if (side_number == -1 || rval != MB_SUCCESS)
672  continue;
673  const_cast<SideNumber_multiIndex &>(fe.getSideNumberTable())
674  .insert(boost::shared_ptr<SideNumber>(
675  new SideNumber(quad, side_number, sense, offset)));
676  }
677  int ee = 0;
678  for (; ee < 3; ee++) {
679  EntityHandle edge = 0;
680  CHKERR moab.side_element(prism, 1, ee, edge);
681  boost::shared_ptr<SideNumber> side_ptr =
682  fe.getRefElement()->getSideNumberPtr(edge);
683  if (side_ptr->side_number != ee) {
684  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
685  "data inconsistency for edge %d while in FE datastructure is "
686  "numbered %d.",
687  ee, side_ptr->side_number);
688  }
689  CHKERR moab.side_element(prism, 1, 6 + ee, edge);
690  side_ptr = fe.getRefElement()->getSideNumberPtr(edge);
691  if (side_ptr->side_number != ee + 6) {
692  if (side_ptr->side_number != ee) {
693  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
694  "data inconsistency for edge %d while in FE datastructure "
695  "is numbered %d.",
696  ee, side_ptr->side_number);
697  } else {
698  side_ptr->brother_side_number = ee + 6;
699  }
700  }
701  }
702  for (; ee < 6; ee++) {
703  EntityHandle edge = 0;
704  rval = moab.side_element(prism, 1, ee, edge);
705  if (rval != MB_SUCCESS || edge == 0)
706  continue;
707  int side_number, sense, offset;
708  rval = moab.side_number(prism, edge, side_number, sense, offset);
709  if (side_number == -1 || rval != MB_SUCCESS)
710  continue;
711  const_cast<SideNumber_multiIndex &>(fe.getSideNumberTable())
712  .insert(boost::shared_ptr<SideNumber>(
713  new SideNumber(edge, side_number, sense, offset)));
714  }
715  int nn = 0;
716  for (; nn < 3; nn++) {
717  EntityHandle node;
718  CHKERR moab.side_element(prism, 0, nn, node);
719  boost::shared_ptr<SideNumber> side_ptr =
720  fe.getRefElement()->getSideNumberPtr(node);
721  if (side_ptr->side_number != nn) {
722  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
723  "data inconsistency for node %d while in FE datastructure is "
724  "numbered %d.",
725  nn, side_ptr->side_number);
726  }
727  CHKERR moab.side_element(prism, 0, nn + 3, node);
728  side_ptr = fe.getRefElement()->getSideNumberPtr(node);
729  if (side_ptr->side_number != nn + 3) {
730  if (side_ptr->side_number != nn) {
731  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
732  "data inconsistency for node %d while in FE datastructure is "
733  "numbered %d.",
734  nn, side_ptr->side_number);
735  } else {
736  side_ptr->brother_side_number = nn + 3;
737  }
738  }
739  }
740 
741  // get adjacencies
742  SideNumber_multiIndex &side_table = fe.getRefElement()->getSideNumberTable();
743  switch (field.getSpace()) {
744  case H1:
745  // moab.get_connectivity(&prism,1,nodes,true);
746  // use get adjacencies, this will allow take in account adjacencies set user
747  CHKERR moab.get_adjacencies(&prism, 1, 0, false, nodes,
748  moab::Interface::UNION);
749  {
750  Range topo_nodes;
751  CHKERR moab.get_connectivity(&prism, 1, topo_nodes, true);
752  Range mid_nodes;
753  CHKERR moab.get_connectivity(&prism, 1, mid_nodes, false);
754  mid_nodes = subtract(mid_nodes, topo_nodes);
755  nodes = subtract(nodes, mid_nodes);
756  }
757  adjacency.insert(nodes.begin(), nodes.end());
758  case HCURL: {
759  SideNumber_multiIndex::nth_index<2>::type::iterator siit, hi_siit;
760  siit = side_table.get<2>().lower_bound(MBEDGE);
761  hi_siit = side_table.get<2>().upper_bound(MBEDGE);
762  for (; siit != hi_siit; siit++)
763  adjacency.insert(siit->get()->ent);
764  }
765  case HDIV: {
766  SideNumber_multiIndex::nth_index<2>::type::iterator siit, hi_siit;
767  siit = side_table.get<2>().lower_bound(MBTRI);
768  hi_siit = side_table.get<2>().upper_bound(MBTRI);
769  for (; siit != hi_siit; siit++)
770  adjacency.insert(siit->get()->ent);
771  siit = side_table.get<2>().lower_bound(MBQUAD);
772  hi_siit = side_table.get<2>().upper_bound(MBQUAD);
773  for (; siit != hi_siit; siit++)
774  adjacency.insert(siit->get()->ent);
775  }
776  case L2:
777  adjacency.insert(prism);
778  break;
779  case NOFIELD: {
780  Range ents;
781  CHKERR moab.get_entities_by_handle(field.getMeshset(), ents, false);
782  adjacency.merge(ents);
783  for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
784  const_cast<SideNumber_multiIndex &>(fe.getSideNumberTable())
785  .insert(
786  boost::shared_ptr<SideNumber>(new SideNumber(*eit, -1, 0, 0)));
787  }
788  } break;
789  default:
790  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
791  "this field is not implemented for TRI finite element");
792  }
794 }
795 
797  moab::Interface &moab, const Field &field, const EntFiniteElement &fe,
798  Range &adjacency) {
800  EntityHandle fe_ent = fe.getEnt();
801  // get all meshsets in finite element meshset
802  Range ent_ents_meshset;
803  CHKERR moab.get_entities_by_type(fe_ent, MBENTITYSET, ent_ents_meshset,
804  false);
805  // resolve recursively all ents in the meshset
806  Range ent_ents;
807  CHKERR moab.get_entities_by_handle(fe_ent, ent_ents, true);
808  switch (field.getSpace()) {
809  case H1:
810  adjacency.merge(ent_ents.subset_by_type(MBVERTEX));
811  case HCURL:
812  adjacency.merge(ent_ents.subset_by_type(MBEDGE));
813  case HDIV:
814  adjacency.merge(ent_ents.subset_by_type(MBTRI));
815  case L2:
816  adjacency.merge(ent_ents.subset_by_type(MBTET));
817  break;
818  case NOFIELD: {
819  Range ents;
820  CHKERR moab.get_entities_by_handle(field.getMeshset(), ents, false);
821  adjacency.merge(ents);
822  for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
823  const_cast<SideNumber_multiIndex &>(fe.getSideNumberTable())
824  .insert(
825  boost::shared_ptr<SideNumber>(new SideNumber(*eit, -1, 0, 0)));
826  }
827  } break;
828  default:
829  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
830  }
832 }
833 
834 // FiniteElement
836  : meshset(_meshset) {
837  Tag th_FEId;
838  rval = moab.tag_get_handle("_FEId", th_FEId);
839  MOAB_THROW(rval);
840  rval = moab.tag_get_by_ptr(th_FEId, &meshset, 1, (const void **)&tagId);
841  MOAB_THROW(rval);
842  Tag th_FEName;
843  rval = moab.tag_get_handle("_FEName", th_FEName);
844  MOAB_THROW(rval);
845  rval = moab.tag_get_by_ptr(th_FEName, &meshset, 1, (const void **)&tagName,
846  &tagNameSize);
847  MOAB_THROW(rval);
848  Tag th_FEIdCol, th_FEIdRow, th_FEIdData;
849  rval = moab.tag_get_handle("_FEIdCol", th_FEIdCol);
850  MOAB_THROW(rval);
851  rval = moab.tag_get_by_ptr(th_FEIdCol, &meshset, 1,
852  (const void **)&tag_BitFieldId_col_data);
853  MOAB_THROW(rval);
854  rval = moab.tag_get_handle("_FEIdRow", th_FEIdRow);
855  MOAB_THROW(rval);
856  rval = moab.tag_get_by_ptr(th_FEIdRow, &meshset, 1,
857  (const void **)&tag_BitFieldId_row_data);
858  MOAB_THROW(rval);
859  rval = moab.tag_get_handle("_FEIdData", th_FEIdData);
860  MOAB_THROW(rval);
861  rval = moab.tag_get_by_ptr(th_FEIdData, &meshset, 1,
862  (const void **)&tag_BitFieldId_data);
863  MOAB_THROW(rval);
864 
872 }
873 
874 std::ostream &operator<<(std::ostream &os, const FiniteElement &e) {
875  os << e.getNameRef() << " fe_id " << e.getId().to_ulong() << " f_id_row "
876  << e.getBitFieldIdRow() << " f_id_col " << e.getBitFieldIdCol()
877  << " BitFEId_data " << e.getBitFieldIdData();
878  return os;
879 }
880 
882 operator()(boost::shared_ptr<FiniteElement> &fe) {
883  *static_cast<BitFieldId *>(fe->tag_BitFieldId_col_data) |= fIdCol;
884 }
885 
887 operator()(boost::shared_ptr<FiniteElement> &fe) {
888  *static_cast<BitFieldId *>(fe->tag_BitFieldId_row_data) |= fIdRow;
889 }
890 
892 operator()(boost::shared_ptr<FiniteElement> &fe) {
893  *static_cast<BitFieldId *>(fe->tag_BitFieldId_data) |= fIdData;
894 }
895 
897 operator()(boost::shared_ptr<FiniteElement> &fe) {
898  *static_cast<BitFieldId *>(fe->tag_BitFieldId_col_data) &= fIdCol.flip();
899 }
900 
902 operator()(boost::shared_ptr<FiniteElement> &fe) {
903  *static_cast<BitFieldId *>(fe->tag_BitFieldId_row_data) &= fIdRow.flip();
904 }
905 
907 operator()(boost::shared_ptr<FiniteElement> &fe) {
908  *static_cast<BitFieldId *>(fe->tag_BitFieldId_data) &= fIdData.flip();
909 }
910 
912 operator()(boost::shared_ptr<FiniteElement> &fe) {
913  static_cast<BitFieldId *>(fe->tag_BitFieldId_col_data)->reset();
914 }
915 
917 operator()(boost::shared_ptr<FiniteElement> &fe) {
918  static_cast<BitFieldId *>(fe->tag_BitFieldId_row_data)->reset();
919 }
920 
922 operator()(boost::shared_ptr<FiniteElement> &fe) {
923  static_cast<BitFieldId *>(fe->tag_BitFieldId_data)->reset();
924 }
925 
926 // FiniteElement data
928  const boost::shared_ptr<RefElement> &ref_finite_element,
929  const boost::shared_ptr<FiniteElement> &fe_ptr)
931  interface_RefElement<RefElement>(ref_finite_element),
932  data_dofs(new FEDofEntity_multiIndex()),
933  row_field_ents_view(new FieldEntity_vector_view()),
934  col_field_ents_view(new FieldEntity_vector_view()),
935  data_field_ents_view(new FieldEntity_multiIndex_spaceType_view()) {
936  // get finite element entity
938 }
939 
940 std::ostream &operator<<(std::ostream &os, const EntFiniteElement &e) {
941  os << *e.sFePtr << std::endl;
942  os << *e.sPtr << std::endl;
943  os << "data dof_uids ";
944  for (auto &dit : *e.data_dofs) {
945  if (!dit) {
946  os << "null ptr";
947  } else {
948  if (!dit->getDofEntityPtr()) {
949  os << "( null ptr to dof ) ";
950  } else {
951  if (!dit->getFieldEntityPtr()) {
952  os << "(( null ptr to field entity )) ";
953  } else {
954  os << dit->getGlobalUniqueId() << " ";
955  }
956  }
957  }
958  }
959  return os;
960 }
961 
963 EntFiniteElement::getElementAdjacency(const boost::shared_ptr<Field> field_ptr,
964  Range &adjacency) {
965  moab::Interface &moab = getRefEntityPtr()->basicDataPtr->moab;
967  const EntFiniteElement *this_fe_ptr = this;
968  if (get_MoFEMFiniteElementPtr()->elementAdjacencyTable[getEntType()] ==
969  NULL) {
970  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
971  }
972  CHKERR get_MoFEMFiniteElementPtr()->elementAdjacencyTable[getEntType()](
973  moab, *field_ptr, *this_fe_ptr, adjacency);
975 }
976 
977 boost::weak_ptr<FENumeredDofEntity>
979  auto comp = [idx](const auto &a) { return a->getPetscGlobalDofIdx() == idx; };
980  auto dit = std::find_if(rows_dofs->begin(), rows_dofs->end(), comp);
981  if (dit != rows_dofs->end())
982  return *dit;
983  else
984  return boost::weak_ptr<FENumeredDofEntity>();
985 }
986 
987 boost::weak_ptr<FENumeredDofEntity>
989  auto comp = [idx](const auto &a) { return a->getPetscGlobalDofIdx() == idx; };
990  auto dit = std::find_if(cols_dofs->begin(), cols_dofs->end(), comp);
991  if (dit != cols_dofs->end())
992  return *dit;
993  else
994  return boost::weak_ptr<FENumeredDofEntity>();
995 }
996 
997 } // 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:179
RefElement_EDGE(const boost::shared_ptr< RefEntity > &ref_ent_ptr)
static MoFEMErrorCode defaultMeshset(Interface &moab, const Field &field, const EntFiniteElement &fe, Range &adjacency)
const BitRefEdges & getBitRefEdges() const
std::array< ElementAdjacencyFunct, MBMAXTYPE > elementAdjacencyTable
Table of functions retrieving adjacencies for finite element User can alter and change default behavi...
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
SideNumber_multiIndex side_number_table
scalar or vector of scalars describe (no true field)
Definition: definitions.h:176
static MoFEMErrorCode defaultFace(Interface &moab, const Field &field, const EntFiniteElement &fe, Range &adjacency)
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:483
BitFieldId getBitFieldIdRow() const
Get field ids on rows.
static MoFEMErrorCode defaultPrism(Interface &moab, const Field &field, const EntFiniteElement &fe, Range &adjacency)
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:626
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:608
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
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
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
void operator()(boost::shared_ptr< FiniteElement > &fe)
boost::shared_ptr< T > sFePtr
boost::shared_ptr< FENumeredDofEntity_multiIndex > rows_dofs
indexed dofs on rows
void operator()(boost::shared_ptr< FiniteElement > &fe)
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.
field with continuous tangents
Definition: definitions.h:178
keeps data about abstract TET finite element
static MoFEMErrorCode defaultVertex(Interface &moab, const Field &field, const EntFiniteElement &fe, Range &adjacency)
intrface to RefElement
Finite element data for entity.
#define CHKERR
Inline error check.
Definition: definitions.h:602
static MoFEMErrorCode defaultEdge(Interface &moab, const Field &field, const EntFiniteElement &fe, Range &adjacency)
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)
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
DeprecatedCoreInterface Interface
Definition: Interface.hpp:1788
static MoFEMErrorCode defaultTet(Interface &moab, const Field &field, const EntFiniteElement &fe, Range &adjacency)
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:413
void * tagName
ptr to tag storing FE name
continuous field
Definition: definitions.h:177
EntityHandle getMeshset() const
Get field meshset.
void operator()(boost::shared_ptr< FiniteElement > &fe)
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:309
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:180