v0.9.2
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_ents_ptr)
26  : interface_RefEntity<RefEntity>(ref_ents_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_ents_ptr)
36  : RefElement(ref_ents_ptr) {
37  switch (ref_ents_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_ents_ptr)
56  : RefElement(ref_ents_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_ents_ptr->ent, 1,
62  (const void **)&tag_BitRefEdges);
64  switch (ref_ents_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_ents_ptr)
294  : RefElement(ref_ents_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_ents_ptr->ent, 1,
300  (const void **)&tag_BitRefEdges);
301  MOAB_THROW(rval);
302  switch (ref_ents_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(boost::make_shared<SideNumber>(sPtr->ent, 0, 0, 0));
310 }
311 
312 const boost::shared_ptr<SideNumber> &
314  moab::Interface &moab = getRefEntityPtr()->basicDataPtr->moab;
315  auto miit = side_number_table.find(ent);
316  if (miit != side_number_table.end())
317  return *miit;
318  if (sPtr->ent == ent) {
319  miit = const_cast<SideNumber_multiIndex &>(side_number_table)
320  .insert(boost::make_shared<SideNumber>(ent, 0, 0, 0))
321  .first;
322  return *miit;
323  }
324  if (moab.type_from_handle(ent) == MBENTITYSET) {
325  miit = const_cast<SideNumber_multiIndex &>(side_number_table)
326  .insert(boost::make_shared<SideNumber>(ent, 0, 0, 0))
327  .first;
328  return *miit;
329  }
330  int side_number, sense, offset;
331  rval = moab.side_number(sPtr->ent, ent, side_number, sense, offset);
332  MOAB_THROW(rval);
333  auto p_miit = const_cast<SideNumber_multiIndex &>(side_number_table)
334  .insert(boost::make_shared<SideNumber>(ent, side_number,
335  sense, offset));
336  miit = p_miit.first;
337  if (miit->get()->ent != ent)
338  THROW_MESSAGE("this not working");
339 
340  return *miit;
341 }
342 std::ostream &operator<<(std::ostream &os, const RefElement_TET &e) {
343  os << "ref type " << e.tag_type_data[0] << " ref sub type "
344  << e.tag_type_data[1];
345  os << " ref egdes " << e.getBitRefEdges();
346  os << " " << *e.sPtr;
347  return os;
348 }
349 
350 RefElementFace::RefElementFace(const boost::shared_ptr<RefEntity> &ref_ents_ptr)
351  : RefElement(ref_ents_ptr) {
352 
353  int nb_nodes = 0;
354  int nb_edges = 0;
355  switch (ref_ents_ptr->getEntType()) {
356  case MBTRI:
357  nb_nodes = nb_edges = 3;
358  break;
359  case MBQUAD:
360  nb_nodes = nb_edges = 4;
361  break;
362  default:
363  THROW_MESSAGE("this works only for TRIs and QUADs");
364  }
365  int side_number, sense, offset;
366  EntityHandle tri = getRefEnt();
367  int num_nodes;
368  const EntityHandle *conn;
369  moab::Interface &moab = getRefEntityPtr()->basicDataPtr->moab;
370  rval = moab.get_connectivity(tri, conn, num_nodes, true);
371  MOAB_THROW(rval);
372  for (int nn = 0; nn < nb_nodes; nn++) {
373  const_cast<SideNumber_multiIndex &>(side_number_table)
374  .insert(
375  boost::shared_ptr<SideNumber>(new SideNumber(conn[nn], nn, 0, 0)));
376  }
377  for (int ee = 0; ee < nb_edges; ee++) {
378  EntityHandle edge;
379  rval = moab.side_element(tri, 1, ee, edge);
380  MOAB_THROW(rval);
381  rval = moab.side_number(tri, edge, side_number, sense, offset);
382  MOAB_THROW(rval);
383  const_cast<SideNumber_multiIndex &>(side_number_table)
384  .insert(boost::shared_ptr<SideNumber>(
385  new SideNumber(edge, ee, sense, offset)));
386  }
387  const_cast<SideNumber_multiIndex &>(side_number_table)
388  .insert(boost::shared_ptr<SideNumber>(new SideNumber(tri, 0, 0, 0)));
389 }
390 const boost::shared_ptr<SideNumber> &
392  moab::Interface &moab = getRefEntityPtr()->basicDataPtr->moab;
393  SideNumber_multiIndex::iterator miit = side_number_table.find(ent);
394  if (miit != side_number_table.end())
395  return *miit;
396  if (sPtr->ent == ent) {
397  miit =
398  const_cast<SideNumber_multiIndex &>(side_number_table)
399  .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, 0, 0, 0)))
400  .first;
401  return *miit;
402  }
403  if (moab.type_from_handle(ent) == MBENTITYSET) {
404  miit =
405  const_cast<SideNumber_multiIndex &>(side_number_table)
406  .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, 0, 0, 0)))
407  .first;
408  return *miit;
409  }
410  int side_number, sense, offset;
411  rval = moab.side_number(sPtr->ent, ent, side_number, sense, offset);
412  MOAB_THROW(rval);
413  miit = const_cast<SideNumber_multiIndex &>(side_number_table)
414  .insert(boost::shared_ptr<SideNumber>(
415  new SideNumber(ent, side_number, sense, offset)))
416  .first;
417  // std::cerr << side_number << " " << sense << " " << offset << std::endl;
418  return *miit;
419 }
420 std::ostream &operator<<(std::ostream &os, const RefElementFace &e) {
421  os << *e.sPtr;
422  return os;
423 }
425  const boost::shared_ptr<RefEntity> &ref_ents_ptr)
426  : RefElement(ref_ents_ptr) {
427  switch (ref_ents_ptr->getEntType()) {
428  case MBEDGE:
429  break;
430  default:
431  THROW_MESSAGE("this work only for TRIs");
432  }
433 }
434 const boost::shared_ptr<SideNumber> &
436  moab::Interface &moab = getRefEntityPtr()->basicDataPtr->moab;
437  SideNumber_multiIndex::iterator miit = side_number_table.find(ent);
438  if (miit != side_number_table.end())
439  return *miit;
440  if (sPtr->ent == ent) {
441  miit =
442  const_cast<SideNumber_multiIndex &>(side_number_table)
443  .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, 0, 0, 0)))
444  .first;
445  return *miit;
446  }
447  if (moab.type_from_handle(ent) == MBENTITYSET) {
448  miit =
449  const_cast<SideNumber_multiIndex &>(side_number_table)
450  .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, 0, 0, 0)))
451  .first;
452  return *miit;
453  }
454  int side_number, sense, offset;
455  rval = moab.side_number(sPtr->ent, ent, side_number, sense, offset);
456  MOAB_THROW(rval);
457  miit = const_cast<SideNumber_multiIndex &>(side_number_table)
458  .insert(boost::shared_ptr<SideNumber>(
459  new SideNumber(ent, side_number, sense, offset)))
460  .first;
461  // std::cerr << side_number << " " << sense << " " << offset << std::endl;
462  return *miit;
463 }
464 std::ostream &operator<<(std::ostream &os, const RefElement_EDGE &e) {
465  os << *e.sPtr;
466  return os;
467 }
469  const boost::shared_ptr<RefEntity> &ref_ents_ptr)
470  : RefElement(ref_ents_ptr) {
471  switch (ref_ents_ptr->getEntType()) {
472  case MBVERTEX:
473  break;
474  default:
475  THROW_MESSAGE("this works only for TRIs");
476  }
477 }
478 const boost::shared_ptr<SideNumber> &
480  moab::Interface &moab = getRefEntityPtr()->basicDataPtr->moab;
481  SideNumber_multiIndex::iterator miit = side_number_table.find(ent);
482  if (miit != side_number_table.end())
483  return *miit;
484  if (sPtr->ent == ent) {
485  miit =
486  const_cast<SideNumber_multiIndex &>(side_number_table)
487  .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, 0, 0, 0)))
488  .first;
489  return *miit;
490  }
491  if (moab.type_from_handle(ent) == MBENTITYSET) {
492  miit =
493  const_cast<SideNumber_multiIndex &>(side_number_table)
494  .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, 0, 0, 0)))
495  .first;
496  return *miit;
497  }
498  THROW_MESSAGE("no side entity for vertex if its is not an vertex itself");
499  return nullSideNumber;
500 }
501 std::ostream &operator<<(std::ostream &os, const RefElement_VERTEX &e) {
502  os << *e.sPtr;
503  return os;
504 }
505 
507  moab::Interface &moab, const Field &field, const EntFiniteElement &fe,
508  Range &adjacency) {
510  switch (field.getSpace()) {
511  case H1:
512  adjacency.insert(fe.getEnt());
513  break;
514  case NOFIELD: {
515  Range ents;
516  CHKERR moab.get_entities_by_handle(field.getMeshset(), ents, false);
517  adjacency.merge(ents);
518  for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
519  const_cast<SideNumber_multiIndex &>(fe.getSideNumberTable())
520  .insert(
521  boost::shared_ptr<SideNumber>(new SideNumber(*eit, -1, 0, 0)));
522  }
523  } break;
524  default:
525  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
526  "this field is not implemented for VERTEX finite element");
527  }
528  // build side table
529  for (Range::iterator eit = adjacency.begin(); eit != adjacency.end(); eit++) {
530  fe.getSideNumberPtr(*eit);
531  }
533 }
534 
536  const Field &field,
537  const EntFiniteElement &fe,
538  Range &adjacency) {
540  EntityHandle fe_ent = fe.getEnt();
541  // Range nodes;
542  switch (field.getSpace()) {
543  case H1:
544  CHKERR moab.get_connectivity(&fe_ent, 1, adjacency, true);
545  case L2:
546  case HCURL:
547  adjacency.insert(fe_ent);
548  break;
549  case NOFIELD: {
550  Range ents;
551  CHKERR moab.get_entities_by_handle(field.getMeshset(), ents, false);
552  adjacency.merge(ents);
553  for (auto e : ents) {
554  const_cast<SideNumber_multiIndex &>(fe.getSideNumberTable())
555  .insert(boost::shared_ptr<SideNumber>(new SideNumber(e, -1, 0, 0)));
556  }
557  } break;
558  default:
559  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
560  "this field is not implemented for EDGE finite element");
561  }
562  // build side table
563  for (auto e : adjacency)
564  fe.getSideNumberPtr(e);
566 }
567 
569  const Field &field,
570  const EntFiniteElement &fe,
571  Range &adjacency) {
573  // Range nodes,edges;
574  const EntityHandle fe_ent = fe.getEnt();
575  switch (field.getSpace()) {
576  case H1:
577  CHKERR moab.get_connectivity(&fe_ent, 1, adjacency, true);
578  case HCURL:
579  CHKERR moab.get_adjacencies(&fe_ent, 1, 1, false, adjacency,
580  moab::Interface::UNION);
581  case HDIV:
582  adjacency.insert(fe_ent);
583  break;
584  case NOFIELD: {
585  Range ents;
586  CHKERR moab.get_entities_by_handle(field.getMeshset(), ents, false);
587  adjacency.merge(ents);
588  for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
589  const_cast<SideNumber_multiIndex &>(fe.getSideNumberTable())
590  .insert(
591  boost::shared_ptr<SideNumber>(new SideNumber(*eit, -1, 0, 0)));
592  }
593  } break;
594  case L2:
595  adjacency.insert(fe_ent); // add this just in case, if L2 is on skeleton
596  break;
597  default:
598  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
599  "this field is not implemented for TRI finite element");
600  }
601  // build side table
602  for (Range::iterator eit = adjacency.begin(); eit != adjacency.end(); eit++)
603  fe.getSideNumberPtr(*eit);
605 }
606 
608  const Field &field,
609  const EntFiniteElement &fe,
610  Range &adjacency) {
612  EntityHandle fe_ent = fe.getEnt();
613  switch (field.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.getMeshset(), ents, false);
628  adjacency.merge(ents);
629  for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
630  const_cast<SideNumber_multiIndex &>(fe.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.getSideNumberPtr(*eit);
643 }
644 
646  const Field &field,
647  const EntFiniteElement &fe,
648  Range &adjacency) {
650  const EntityHandle prism = fe.getEnt();
651  Range nodes;
652  // initialize side sets
653  fe.getRefElement()->getSideNumberPtr(prism);
654  EntityHandle face_side3, face_side4;
655  CHKERR moab.side_element(prism, 2, 3, face_side3);
656  CHKERR moab.side_element(prism, 2, 4, face_side4);
657  fe.getRefElement()->getSideNumberPtr(face_side3);
658  fe.getRefElement()->getSideNumberPtr(face_side4);
659  for (int qq = 0; qq < 3; qq++) {
660  EntityHandle quad = 0;
661  rval = moab.side_element(prism, 2, qq, quad);
662  if (rval != MB_SUCCESS || quad == 0)
663  continue;
664  int side_number, sense, offset;
665  rval = moab.side_number(prism, quad, side_number, sense, offset);
666  if (side_number == -1 || rval != MB_SUCCESS)
667  continue;
668  const_cast<SideNumber_multiIndex &>(fe.getSideNumberTable())
669  .insert(boost::shared_ptr<SideNumber>(
670  new SideNumber(quad, side_number, sense, offset)));
671  }
672  int ee = 0;
673  for (; ee < 3; ee++) {
674  EntityHandle edge = 0;
675  CHKERR moab.side_element(prism, 1, ee, edge);
676  boost::shared_ptr<SideNumber> side_ptr =
677  fe.getRefElement()->getSideNumberPtr(edge);
678  if (side_ptr->side_number != ee) {
679  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
680  "data inconsistency for edge %d while in FE datastructure is "
681  "numbered %d.",
682  ee, side_ptr->side_number);
683  }
684  CHKERR moab.side_element(prism, 1, 6 + ee, edge);
685  side_ptr = fe.getRefElement()->getSideNumberPtr(edge);
686  if (side_ptr->side_number != ee + 6) {
687  if (side_ptr->side_number != ee) {
688  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
689  "data inconsistency for edge %d while in FE datastructure "
690  "is numbered %d.",
691  ee, side_ptr->side_number);
692  } else {
693  side_ptr->brother_side_number = ee + 6;
694  }
695  }
696  }
697  for (; ee < 6; ee++) {
698  EntityHandle edge = 0;
699  rval = moab.side_element(prism, 1, ee, edge);
700  if (rval != MB_SUCCESS || edge == 0)
701  continue;
702  int side_number, sense, offset;
703  rval = moab.side_number(prism, edge, side_number, sense, offset);
704  if (side_number == -1 || rval != MB_SUCCESS)
705  continue;
706  const_cast<SideNumber_multiIndex &>(fe.getSideNumberTable())
707  .insert(boost::shared_ptr<SideNumber>(
708  new SideNumber(edge, side_number, sense, offset)));
709  }
710  int nn = 0;
711  for (; nn < 3; nn++) {
712  EntityHandle node;
713  CHKERR moab.side_element(prism, 0, nn, node);
714  boost::shared_ptr<SideNumber> side_ptr =
715  fe.getRefElement()->getSideNumberPtr(node);
716  if (side_ptr->side_number != nn) {
717  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
718  "data inconsistency for node %d while in FE datastructure is "
719  "numbered %d.",
720  nn, side_ptr->side_number);
721  }
722  CHKERR moab.side_element(prism, 0, nn + 3, node);
723  side_ptr = fe.getRefElement()->getSideNumberPtr(node);
724  if (side_ptr->side_number != nn + 3) {
725  if (side_ptr->side_number != nn) {
726  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
727  "data inconsistency for node %d while in FE datastructure is "
728  "numbered %d.",
729  nn, side_ptr->side_number);
730  } else {
731  side_ptr->brother_side_number = nn + 3;
732  }
733  }
734  }
735 
736  // get adjacencies
737  SideNumber_multiIndex &side_table = fe.getRefElement()->getSideNumberTable();
738  switch (field.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.getMeshset(), ents, false);
777  adjacency.merge(ents);
778  for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
779  const_cast<SideNumber_multiIndex &>(fe.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 }
790 
792  moab::Interface &moab, const Field &field, const EntFiniteElement &fe,
793  Range &adjacency) {
795  EntityHandle fe_ent = fe.getEnt();
796  // get all meshsets in finite element meshset
797  Range ent_ents_meshset;
798  CHKERR moab.get_entities_by_type(fe_ent, MBENTITYSET, ent_ents_meshset,
799  false);
800  // resolve recursively all ents in the meshset
801  Range ent_ents;
802  CHKERR moab.get_entities_by_handle(fe_ent, ent_ents, true);
803  switch (field.getSpace()) {
804  case H1:
805  adjacency.merge(ent_ents.subset_by_type(MBVERTEX));
806  case HCURL:
807  adjacency.merge(ent_ents.subset_by_type(MBEDGE));
808  case HDIV:
809  adjacency.merge(ent_ents.subset_by_type(MBTRI));
810  case L2:
811  adjacency.merge(ent_ents.subset_by_type(MBTET));
812  break;
813  case NOFIELD: {
814  Range ents;
815  CHKERR moab.get_entities_by_handle(field.getMeshset(), ents, false);
816  adjacency.merge(ents);
817  for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
818  const_cast<SideNumber_multiIndex &>(fe.getSideNumberTable())
819  .insert(
820  boost::shared_ptr<SideNumber>(new SideNumber(*eit, -1, 0, 0)));
821  }
822  } break;
823  default:
824  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
825  }
827 }
828 
829 // FiniteElement
831  : meshset(_meshset) {
832  Tag th_FEId;
833  rval = moab.tag_get_handle("_FEId", th_FEId);
834  MOAB_THROW(rval);
835  rval = moab.tag_get_by_ptr(th_FEId, &meshset, 1, (const void **)&tagId);
836  MOAB_THROW(rval);
837  Tag th_FEName;
838  rval = moab.tag_get_handle("_FEName", th_FEName);
839  MOAB_THROW(rval);
840  rval = moab.tag_get_by_ptr(th_FEName, &meshset, 1, (const void **)&tagName,
841  &tagNameSize);
842  MOAB_THROW(rval);
843  Tag th_FEIdCol, th_FEIdRow, th_FEIdData;
844  rval = moab.tag_get_handle("_FEIdCol", th_FEIdCol);
845  MOAB_THROW(rval);
846  rval = moab.tag_get_by_ptr(th_FEIdCol, &meshset, 1,
847  (const void **)&tag_BitFieldId_col_data);
848  MOAB_THROW(rval);
849  rval = moab.tag_get_handle("_FEIdRow", th_FEIdRow);
850  MOAB_THROW(rval);
851  rval = moab.tag_get_by_ptr(th_FEIdRow, &meshset, 1,
852  (const void **)&tag_BitFieldId_row_data);
853  MOAB_THROW(rval);
854  rval = moab.tag_get_handle("_FEIdData", th_FEIdData);
855  MOAB_THROW(rval);
856  rval = moab.tag_get_by_ptr(th_FEIdData, &meshset, 1,
857  (const void **)&tag_BitFieldId_data);
858  MOAB_THROW(rval);
859 
867 }
868 
869 std::ostream &operator<<(std::ostream &os, const FiniteElement &e) {
870  os << e.getNameRef() << " fe_id " << e.getId().to_ulong() << " f_id_row "
871  << e.getBitFieldIdRow() << " f_id_col " << e.getBitFieldIdCol()
872  << " BitFEId_data " << e.getBitFieldIdData();
873  return os;
874 }
875 
877 operator()(boost::shared_ptr<FiniteElement> &fe) {
878  *static_cast<BitFieldId *>(fe->tag_BitFieldId_col_data) |= fIdCol;
879 }
880 
882 operator()(boost::shared_ptr<FiniteElement> &fe) {
883  *static_cast<BitFieldId *>(fe->tag_BitFieldId_row_data) |= fIdRow;
884 }
885 
887 operator()(boost::shared_ptr<FiniteElement> &fe) {
888  *static_cast<BitFieldId *>(fe->tag_BitFieldId_data) |= fIdData;
889 }
890 
892 operator()(boost::shared_ptr<FiniteElement> &fe) {
893  *static_cast<BitFieldId *>(fe->tag_BitFieldId_col_data) &= fIdCol.flip();
894 }
895 
897 operator()(boost::shared_ptr<FiniteElement> &fe) {
898  *static_cast<BitFieldId *>(fe->tag_BitFieldId_row_data) &= fIdRow.flip();
899 }
900 
902 operator()(boost::shared_ptr<FiniteElement> &fe) {
903  *static_cast<BitFieldId *>(fe->tag_BitFieldId_data) &= fIdData.flip();
904 }
905 
907 operator()(boost::shared_ptr<FiniteElement> &fe) {
908  static_cast<BitFieldId *>(fe->tag_BitFieldId_col_data)->reset();
909 }
910 
912 operator()(boost::shared_ptr<FiniteElement> &fe) {
913  static_cast<BitFieldId *>(fe->tag_BitFieldId_row_data)->reset();
914 }
915 
917 operator()(boost::shared_ptr<FiniteElement> &fe) {
918  static_cast<BitFieldId *>(fe->tag_BitFieldId_data)->reset();
919 }
920 
921 // FiniteElement data
923  const boost::shared_ptr<RefElement> &ref_finite_element,
924  const boost::shared_ptr<FiniteElement> &fe_ptr)
926  interface_RefElement<RefElement>(ref_finite_element),
927  data_dofs(new FEDofEntity_multiIndex()),
928  row_field_ents_view(new FieldEntity_vector_view()),
929  col_field_ents_view(new FieldEntity_vector_view()),
930  data_field_ents_view(new FieldEntity_multiIndex_spaceType_view()) {
931  // get finite element entity
933 }
934 
935 std::ostream &operator<<(std::ostream &os, const EntFiniteElement &e) {
936  os << *e.sFePtr << std::endl;
937  os << *e.sPtr << std::endl;
938  os << "data dof_uids ";
939  for (auto &dit : *e.data_dofs) {
940  if (!dit) {
941  os << "null ptr";
942  } else {
943  if (!dit->getDofEntityPtr()) {
944  os << "( null ptr to dof ) ";
945  } else {
946  if (!dit->getFieldEntityPtr()) {
947  os << "(( null ptr to field entity )) ";
948  } else {
949  os << dit->getGlobalUniqueId() << " ";
950  }
951  }
952  }
953  }
954  return os;
955 }
956 
958 EntFiniteElement::getElementAdjacency(const boost::shared_ptr<Field> field_ptr,
959  Range &adjacency) {
960  moab::Interface &moab = getRefEntityPtr()->basicDataPtr->moab;
962  const EntFiniteElement *this_fe_ptr = this;
963  if (get_MoFEMFiniteElementPtr()->elementAdjacencyTable[getEntType()] ==
964  NULL) {
965  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
966  }
967  CHKERR get_MoFEMFiniteElementPtr()->elementAdjacencyTable[getEntType()](
968  moab, *field_ptr, *this_fe_ptr, adjacency);
970 }
971 
972 boost::weak_ptr<FENumeredDofEntity>
974  auto comp = [idx](const auto &a) { return a->getPetscGlobalDofIdx() == idx; };
975  auto dit = std::find_if(rows_dofs->begin(), rows_dofs->end(), comp);
976  if (dit != rows_dofs->end())
977  return *dit;
978  else
979  return boost::weak_ptr<FENumeredDofEntity>();
980 }
981 
982 boost::weak_ptr<FENumeredDofEntity>
984  auto comp = [idx](const auto &a) { return a->getPetscGlobalDofIdx() == idx; };
985  auto dit = std::find_if(cols_dofs->begin(), cols_dofs->end(), comp);
986  if (dit != cols_dofs->end())
987  return *dit;
988  else
989  return boost::weak_ptr<FENumeredDofEntity>();
990 }
991 
992 } // namespace MoFEM
keeps data about abstract VERTEX finite element
boost::shared_ptr< T > sPtr
RefElement(const boost::shared_ptr< RefEntity > &ref_ents_ptr)
boost::weak_ptr< FENumeredDofEntity > getColDofsByPetscGlobalDofIdx(const int idx) const
get FE dof by petsc index
void operator()(boost::shared_ptr< FiniteElement > &fe)
void operator()(boost::shared_ptr< FiniteElement > &fe)
field with continuous normal traction
Definition: definitions.h:179
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
RefElement_MESHSET(const boost::shared_ptr< RefEntity > &ref_ents_ptr)
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
RefElement_EDGE(const boost::shared_ptr< RefEntity > &ref_ents_ptr)
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
Definition: Exceptions.hpp:85
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
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:67
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
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
RefElement_VERTEX(const boost::shared_ptr< RefEntity > &ref_ents_ptr)
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
RefElement_PRISM(const boost::shared_ptr< RefEntity > &ref_ents_ptr)
boost::shared_ptr< RefElement > & getRefElement() const
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
RefElement_TET(const boost::shared_ptr< RefEntity > &ref_ents_ptr)
DeprecatedCoreInterface Interface
Definition: Interface.hpp:1879
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.
boost::string_ref getNameRef() const
Get finite element name.
RefElementFace(const boost::shared_ptr< RefEntity > &ref_ents_ptr)
#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