v0.8.23
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 RefElement_TRI::RefElement_TRI(const boost::shared_ptr<RefEntity> &ref_ent_ptr)
356  : RefElement(ref_ent_ptr) {
357  switch (ref_ent_ptr->getEntType()) {
358  case MBTRI:
359  break;
360  default:
361  THROW_MESSAGE("this work only for TRIs");
362  }
363  int side_number, sense, offset;
364  EntityHandle tri = getRefEnt();
365  int num_nodes;
366  const EntityHandle *conn;
367  moab::Interface &moab = getRefEntityPtr()->basicDataPtr->moab;
368  rval = moab.get_connectivity(tri, conn, num_nodes, true);
369  MOAB_THROW(rval);
370  for (int nn = 0; nn < 3; nn++) {
371  const_cast<SideNumber_multiIndex &>(side_number_table)
372  .insert(
373  boost::shared_ptr<SideNumber>(new SideNumber(conn[nn], nn, 0, 0)));
374  }
375  for (int ee = 0; ee < 3; ee++) {
376  EntityHandle edge;
377  rval = moab.side_element(tri, 1, ee, edge);
378  MOAB_THROW(rval);
379  rval = moab.side_number(tri, edge, side_number, sense, offset);
380  MOAB_THROW(rval);
381  const_cast<SideNumber_multiIndex &>(side_number_table)
382  .insert(boost::shared_ptr<SideNumber>(
383  new SideNumber(edge, ee, sense, offset)));
384  }
385  const_cast<SideNumber_multiIndex &>(side_number_table)
386  .insert(boost::shared_ptr<SideNumber>(new SideNumber(tri, 0, 0, 0)));
387 }
388 const boost::shared_ptr<SideNumber> &
390  moab::Interface &moab = getRefEntityPtr()->basicDataPtr->moab;
391  SideNumber_multiIndex::iterator miit = side_number_table.find(ent);
392  if (miit != side_number_table.end())
393  return *miit;
394  if (sPtr->ent == ent) {
395  miit =
396  const_cast<SideNumber_multiIndex &>(side_number_table)
397  .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, 0, 0, 0)))
398  .first;
399  return *miit;
400  }
401  if (moab.type_from_handle(ent) == MBENTITYSET) {
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  int side_number, sense, offset;
409  rval = moab.side_number(sPtr->ent, ent, side_number, sense, offset);
410  MOAB_THROW(rval);
411  miit = const_cast<SideNumber_multiIndex &>(side_number_table)
412  .insert(boost::shared_ptr<SideNumber>(
413  new SideNumber(ent, side_number, sense, offset)))
414  .first;
415  // std::cerr << side_number << " " << sense << " " << offset << std::endl;
416  return *miit;
417 }
418 std::ostream &operator<<(std::ostream &os, const RefElement_TRI &e) {
419  os << *e.sPtr;
420  return os;
421 }
423  const boost::shared_ptr<RefEntity> &ref_ent_ptr)
424  : RefElement(ref_ent_ptr) {
425  switch (ref_ent_ptr->getEntType()) {
426  case MBEDGE:
427  break;
428  default:
429  THROW_MESSAGE("this work only for TRIs");
430  }
431 }
432 const boost::shared_ptr<SideNumber> &
434  moab::Interface &moab = getRefEntityPtr()->basicDataPtr->moab;
435  SideNumber_multiIndex::iterator miit = side_number_table.find(ent);
436  if (miit != side_number_table.end())
437  return *miit;
438  if (sPtr->ent == ent) {
439  miit =
440  const_cast<SideNumber_multiIndex &>(side_number_table)
441  .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, 0, 0, 0)))
442  .first;
443  return *miit;
444  }
445  if (moab.type_from_handle(ent) == MBENTITYSET) {
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  int side_number, sense, offset;
453  rval = moab.side_number(sPtr->ent, ent, side_number, sense, offset);
454  MOAB_THROW(rval);
455  miit = const_cast<SideNumber_multiIndex &>(side_number_table)
456  .insert(boost::shared_ptr<SideNumber>(
457  new SideNumber(ent, side_number, sense, offset)))
458  .first;
459  // std::cerr << side_number << " " << sense << " " << offset << std::endl;
460  return *miit;
461 }
462 std::ostream &operator<<(std::ostream &os, const RefElement_EDGE &e) {
463  os << *e.sPtr;
464  return os;
465 }
467  const boost::shared_ptr<RefEntity> &ref_ent_ptr)
468  : RefElement(ref_ent_ptr) {
469  switch (ref_ent_ptr->getEntType()) {
470  case MBVERTEX:
471  break;
472  default:
473  THROW_MESSAGE("this works only for TRIs");
474  }
475 }
476 const boost::shared_ptr<SideNumber> &
478  moab::Interface &moab = getRefEntityPtr()->basicDataPtr->moab;
479  SideNumber_multiIndex::iterator miit = side_number_table.find(ent);
480  if (miit != side_number_table.end())
481  return *miit;
482  if (sPtr->ent == ent) {
483  miit =
484  const_cast<SideNumber_multiIndex &>(side_number_table)
485  .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, 0, 0, 0)))
486  .first;
487  return *miit;
488  }
489  if (moab.type_from_handle(ent) == MBENTITYSET) {
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  THROW_MESSAGE("no side entity for vertex if its is not an vertex itself");
497  return nullSideNumber;
498 }
499 std::ostream &operator<<(std::ostream &os, const RefElement_VERTEX &e) {
500  os << *e.sPtr;
501  return os;
502 }
503 
505  moab::Interface &moab, const Field &field_ptr,
506  const EntFiniteElement &fe_ptr, Range &adjacency) {
508  switch (field_ptr.getSpace()) {
509  case H1:
510  adjacency.insert(fe_ptr.getEnt());
511  break;
512  case NOFIELD: {
513  Range ents;
514  CHKERR moab.get_entities_by_handle(field_ptr.getMeshset(), ents, false);
515  adjacency.merge(ents);
516  for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
517  const_cast<SideNumber_multiIndex &>(fe_ptr.getSideNumberTable())
518  .insert(
519  boost::shared_ptr<SideNumber>(new SideNumber(*eit, -1, 0, 0)));
520  }
521  } break;
522  default:
523  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
524  "this field is not implemented for VERTEX finite element");
525  }
526  // build side table
527  for (Range::iterator eit = adjacency.begin(); eit != adjacency.end(); eit++) {
528  fe_ptr.getSideNumberPtr(*eit);
529  }
531 }
533  moab::Interface &moab, const Field &field_ptr,
534  const EntFiniteElement &fe_ptr, Range &adjacency) {
536  EntityHandle fe_ent = fe_ptr.getEnt();
537  // Range nodes;
538  switch (field_ptr.getSpace()) {
539  case H1:
540  CHKERR moab.get_connectivity(&fe_ent, 1, adjacency, true);
541  case L2:
542  case HCURL:
543  adjacency.insert(fe_ent);
544  break;
545  case NOFIELD: {
546  Range ents;
547  CHKERR moab.get_entities_by_handle(field_ptr.getMeshset(), ents, false);
548  adjacency.merge(ents);
549  for (auto e : ents) {
550  const_cast<SideNumber_multiIndex &>(fe_ptr.getSideNumberTable())
551  .insert(boost::shared_ptr<SideNumber>(new SideNumber(e, -1, 0, 0)));
552  }
553  } break;
554  default:
555  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
556  "this field is not implemented for EDGE finite element");
557  }
558  // build side table
559  for (auto e : adjacency)
560  fe_ptr.getSideNumberPtr(e);
562 }
563 
565  moab::Interface &moab, const Field &field_ptr,
566  const EntFiniteElement &fe_ptr, Range &adjacency) {
568  // Range nodes,edges;
569  const EntityHandle fe_ent = fe_ptr.getEnt();
570  switch (field_ptr.getSpace()) {
571  case H1:
572  CHKERR moab.get_connectivity(&fe_ent, 1, adjacency, true);
573  case HCURL:
574  CHKERR moab.get_adjacencies(&fe_ent, 1, 1, false, adjacency,
575  moab::Interface::UNION);
576  case HDIV:
577  adjacency.insert(fe_ent);
578  break;
579  case NOFIELD: {
580  Range ents;
581  CHKERR moab.get_entities_by_handle(field_ptr.getMeshset(), ents, false);
582  adjacency.merge(ents);
583  for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
584  const_cast<SideNumber_multiIndex &>(fe_ptr.getSideNumberTable())
585  .insert(
586  boost::shared_ptr<SideNumber>(new SideNumber(*eit, -1, 0, 0)));
587  }
588  } break;
589  case L2:
590  adjacency.insert(fe_ent); // add this just in case, if L2 is on skeleton
591  break;
592  default:
593  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
594  "this field is not implemented for TRI finite element");
595  }
596  // build side table
597  for (Range::iterator eit = adjacency.begin(); eit != adjacency.end(); eit++)
598  fe_ptr.getSideNumberPtr(*eit);
600 }
602  moab::Interface &moab, const Field &field_ptr,
603  const EntFiniteElement &fe_ptr, Range &adjacency) {
605  EntityHandle fe_ent = fe_ptr.getEnt();
606  switch (field_ptr.getSpace()) {
607  case H1:
608  CHKERR moab.get_connectivity(&fe_ent, 1, adjacency, true);
609  case HCURL:
610  CHKERR moab.get_adjacencies(&fe_ent, 1, 1, false, adjacency,
611  moab::Interface::UNION);
612  case HDIV:
613  CHKERR moab.get_adjacencies(&fe_ent, 1, 2, false, adjacency,
614  moab::Interface::UNION);
615  case L2:
616  adjacency.insert(fe_ent);
617  break;
618  case NOFIELD: {
619  Range ents;
620  CHKERR moab.get_entities_by_handle(field_ptr.getMeshset(), ents, false);
621  adjacency.merge(ents);
622  for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
623  const_cast<SideNumber_multiIndex &>(fe_ptr.getSideNumberTable())
624  .insert(
625  boost::shared_ptr<SideNumber>(new SideNumber(*eit, -1, 0, 0)));
626  }
627  } break;
628  default:
629  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
630  "this field is not implemented for TRI finite element");
631  }
632  // build side table
633  for (Range::iterator eit = adjacency.begin(); eit != adjacency.end(); eit++)
634  fe_ptr.getSideNumberPtr(*eit);
636 }
637 
639  moab::Interface &moab, const Field &field_ptr,
640  const EntFiniteElement &fe_ptr, Range &adjacency) {
642  const EntityHandle prism = fe_ptr.getEnt();
643  Range nodes;
644  // initialize side sets
645  fe_ptr.getRefElement()->getSideNumberPtr(prism);
646  EntityHandle face_side3, face_side4;
647  CHKERR moab.side_element(prism, 2, 3, face_side3);
648  CHKERR moab.side_element(prism, 2, 4, face_side4);
649  fe_ptr.getRefElement()->getSideNumberPtr(face_side3);
650  fe_ptr.getRefElement()->getSideNumberPtr(face_side4);
651  for (int qq = 0; qq < 3; qq++) {
652  EntityHandle quad = 0;
653  rval = moab.side_element(prism, 2, qq, quad);
654  if (rval != MB_SUCCESS || quad == 0)
655  continue;
656  int side_number, sense, offset;
657  rval = moab.side_number(prism, quad, side_number, sense, offset);
658  if (side_number == -1 || rval != MB_SUCCESS)
659  continue;
660  const_cast<SideNumber_multiIndex &>(fe_ptr.getSideNumberTable())
661  .insert(boost::shared_ptr<SideNumber>(
662  new SideNumber(quad, side_number, sense, offset)));
663  }
664  int ee = 0;
665  for (; ee < 3; ee++) {
666  EntityHandle edge = 0;
667  CHKERR moab.side_element(prism, 1, ee, edge);
668  boost::shared_ptr<SideNumber> side_ptr =
669  fe_ptr.getRefElement()->getSideNumberPtr(edge);
670  if (side_ptr->side_number != ee) {
671  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
672  "data inconsistency for edge %d while in FE datastructure is "
673  "numbered %d.",
674  ee, side_ptr->side_number);
675  }
676  CHKERR moab.side_element(prism, 1, 6 + ee, edge);
677  side_ptr = fe_ptr.getRefElement()->getSideNumberPtr(edge);
678  if (side_ptr->side_number != ee + 6) {
679  if (side_ptr->side_number != ee) {
680  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
681  "data inconsistency for edge %d while in FE datastructure "
682  "is numbered %d.",
683  ee, side_ptr->side_number);
684  } else {
685  side_ptr->brother_side_number = ee + 6;
686  }
687  }
688  }
689  for (; ee < 6; ee++) {
690  EntityHandle edge = 0;
691  rval = moab.side_element(prism, 1, ee, edge);
692  if (rval != MB_SUCCESS || edge == 0)
693  continue;
694  int side_number, sense, offset;
695  rval = moab.side_number(prism, edge, side_number, sense, offset);
696  if (side_number == -1 || rval != MB_SUCCESS)
697  continue;
698  const_cast<SideNumber_multiIndex &>(fe_ptr.getSideNumberTable())
699  .insert(boost::shared_ptr<SideNumber>(
700  new SideNumber(edge, side_number, sense, offset)));
701  }
702  int nn = 0;
703  for (; nn < 3; nn++) {
704  EntityHandle node;
705  CHKERR moab.side_element(prism, 0, nn, node);
706  boost::shared_ptr<SideNumber> side_ptr =
707  fe_ptr.getRefElement()->getSideNumberPtr(node);
708  if (side_ptr->side_number != nn) {
709  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
710  "data inconsistency for node %d while in FE datastructure is "
711  "numbered %d.",
712  nn, side_ptr->side_number);
713  }
714  CHKERR moab.side_element(prism, 0, nn + 3, node);
715  side_ptr = fe_ptr.getRefElement()->getSideNumberPtr(node);
716  if (side_ptr->side_number != nn + 3) {
717  if (side_ptr->side_number != nn) {
718  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
719  "data inconsistency for node %d while in FE datastructure is "
720  "numbered %d.",
721  nn, side_ptr->side_number);
722  } else {
723  side_ptr->brother_side_number = nn + 3;
724  }
725  }
726  }
727 
728  // get adjacencies
729  SideNumber_multiIndex &side_table =
730  fe_ptr.getRefElement()->getSideNumberTable();
731  switch (field_ptr.getSpace()) {
732  case H1:
733  // moab.get_connectivity(&prism,1,nodes,true);
734  // use get adjacencies, this will allow take in account adjacencies set user
735  CHKERR moab.get_adjacencies(&prism, 1, 0, false, nodes,
736  moab::Interface::UNION);
737  {
738  Range topo_nodes;
739  CHKERR moab.get_connectivity(&prism, 1, topo_nodes, true);
740  Range mid_nodes;
741  CHKERR moab.get_connectivity(&prism, 1, mid_nodes, false);
742  mid_nodes = subtract(mid_nodes, topo_nodes);
743  nodes = subtract(nodes, mid_nodes);
744  }
745  adjacency.insert(nodes.begin(), nodes.end());
746  case HCURL: {
747  SideNumber_multiIndex::nth_index<2>::type::iterator siit, hi_siit;
748  siit = side_table.get<2>().lower_bound(MBEDGE);
749  hi_siit = side_table.get<2>().upper_bound(MBEDGE);
750  for (; siit != hi_siit; siit++)
751  adjacency.insert(siit->get()->ent);
752  }
753  case HDIV: {
754  SideNumber_multiIndex::nth_index<2>::type::iterator siit, hi_siit;
755  siit = side_table.get<2>().lower_bound(MBTRI);
756  hi_siit = side_table.get<2>().upper_bound(MBTRI);
757  for (; siit != hi_siit; siit++)
758  adjacency.insert(siit->get()->ent);
759  siit = side_table.get<2>().lower_bound(MBQUAD);
760  hi_siit = side_table.get<2>().upper_bound(MBQUAD);
761  for (; siit != hi_siit; siit++)
762  adjacency.insert(siit->get()->ent);
763  }
764  case L2:
765  adjacency.insert(prism);
766  break;
767  case NOFIELD: {
768  Range ents;
769  CHKERR moab.get_entities_by_handle(field_ptr.getMeshset(), ents, false);
770  adjacency.merge(ents);
771  for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
772  const_cast<SideNumber_multiIndex &>(fe_ptr.getSideNumberTable())
773  .insert(
774  boost::shared_ptr<SideNumber>(new SideNumber(*eit, -1, 0, 0)));
775  }
776  } break;
777  default:
778  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
779  "this field is not implemented for TRI finite element");
780  }
782 }
784  moab::Interface &moab, const Field &field_ptr,
785  const EntFiniteElement &fe_ptr, Range &adjacency) {
787  EntityHandle fe_ent = fe_ptr.getEnt();
788  // get all meshsets in finite element meshset
789  Range ent_ents_meshset;
790  CHKERR moab.get_entities_by_type(fe_ent, MBENTITYSET, ent_ents_meshset,
791  false);
792  // resolve recursively all ents in the meshset
793  Range ent_ents;
794  CHKERR moab.get_entities_by_handle(fe_ent, ent_ents, true);
795  switch (field_ptr.getSpace()) {
796  case H1:
797  adjacency.merge(ent_ents.subset_by_type(MBVERTEX));
798  case HCURL:
799  adjacency.merge(ent_ents.subset_by_type(MBEDGE));
800  case HDIV:
801  adjacency.merge(ent_ents.subset_by_type(MBTRI));
802  case L2:
803  adjacency.merge(ent_ents.subset_by_type(MBTET));
804  break;
805  case NOFIELD: {
806  Range ents;
807  CHKERR moab.get_entities_by_handle(field_ptr.getMeshset(), ents, false);
808  adjacency.merge(ents);
809  for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
810  const_cast<SideNumber_multiIndex &>(fe_ptr.getSideNumberTable())
811  .insert(
812  boost::shared_ptr<SideNumber>(new SideNumber(*eit, -1, 0, 0)));
813  }
814  } break;
815  default:
816  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
817  }
819 }
820 
821 // FiniteElement
822 FiniteElement::FiniteElement(moab::Interface &moab, const EntityHandle _meshset)
823  : meshset(_meshset) {
824  Tag th_FEId;
825  rval = moab.tag_get_handle("_FEId", th_FEId);
826  MOAB_THROW(rval);
827  rval = moab.tag_get_by_ptr(th_FEId, &meshset, 1, (const void **)&tagId);
828  MOAB_THROW(rval);
829  Tag th_FEName;
830  rval = moab.tag_get_handle("_FEName", th_FEName);
831  MOAB_THROW(rval);
832  rval = moab.tag_get_by_ptr(th_FEName, &meshset, 1, (const void **)&tagName,
833  &tagNameSize);
834  MOAB_THROW(rval);
835  Tag th_FEIdCol, th_FEIdRow, th_FEIdData;
836  rval = moab.tag_get_handle("_FEIdCol", th_FEIdCol);
837  MOAB_THROW(rval);
838  rval = moab.tag_get_by_ptr(th_FEIdCol, &meshset, 1,
839  (const void **)&tag_BitFieldId_col_data);
840  MOAB_THROW(rval);
841  rval = moab.tag_get_handle("_FEIdRow", th_FEIdRow);
842  MOAB_THROW(rval);
843  rval = moab.tag_get_by_ptr(th_FEIdRow, &meshset, 1,
844  (const void **)&tag_BitFieldId_row_data);
845  MOAB_THROW(rval);
846  rval = moab.tag_get_handle("_FEIdData", th_FEIdData);
847  MOAB_THROW(rval);
848  rval = moab.tag_get_by_ptr(th_FEIdData, &meshset, 1,
849  (const void **)&tag_BitFieldId_data);
850  MOAB_THROW(rval);
851 
858 }
859 
860 std::ostream &operator<<(std::ostream &os, const FiniteElement &e) {
861  os << "id " << e.getId() << " name " << e.getNameRef() << " f_id_row "
862  << e.getBitFieldIdRow() << " f_id_col " << e.getBitFieldIdCol()
863  << " BitFEId_data " << e.getBitFieldIdData();
864  return os;
865 }
866 
868 operator()(boost::shared_ptr<FiniteElement> &fe) {
869  *((BitFieldId *)(fe->tag_BitFieldId_col_data)) |= fIdCol;
870 }
871 
873 operator()(boost::shared_ptr<FiniteElement> &fe) {
874  *((BitFieldId *)(fe->tag_BitFieldId_row_data)) |= fIdRow;
875 }
876 
878 operator()(boost::shared_ptr<FiniteElement> &fe) {
879  *((BitFieldId *)(fe->tag_BitFieldId_data)) |= fIdData;
880 }
881 
883 operator()(boost::shared_ptr<FiniteElement> &fe) {
884  *((BitFieldId *)(fe->tag_BitFieldId_col_data)) &= fIdCol.flip();
885 }
886 
888 operator()(boost::shared_ptr<FiniteElement> &fe) {
889  *((BitFieldId *)(fe->tag_BitFieldId_row_data)) &= fIdRow.flip();
890 }
891 
893 operator()(boost::shared_ptr<FiniteElement> &fe) {
894  *((BitFieldId *)(fe->tag_BitFieldId_data)) &= fIdData.flip();
895 }
896 
897 // FiniteElement data
899  const boost::shared_ptr<RefElement> &ref_finite_element,
900  const boost::shared_ptr<FiniteElement> &fe_ptr)
902  interface_RefElement<RefElement>(ref_finite_element),
903  data_dofs(new FEDofEntity_multiIndex()),
904  row_field_ents_view(new FieldEntity_vector_view()),
905  col_field_ents_view(new FieldEntity_vector_view()),
906  data_field_ents_view(new FieldEntity_multiIndex_spaceType_view()) {
907  // get finite element entity
909 }
910 
911 std::ostream &operator<<(std::ostream &os, const EntFiniteElement &e) {
912  os << *e.sFePtr << std::endl;
913  os << *e.sPtr << std::endl;
914  os << "data dof_uids ";
915  FEDofEntity_multiIndex::iterator dit;
916  dit = e.data_dofs->begin();
917  for (; dit != e.data_dofs->end(); dit++) {
918  if (!(*dit)) {
919  os << "null ptr";
920  } else {
921  if (!(*dit)->getDofEntityPtr()) {
922  os << "( null ptr to dof ) ";
923  } else {
924  if (!(*dit)->getFieldEntityPtr()) {
925  os << "(( null ptr to field entity )) ";
926  } else {
927  os << (*dit)->getGlobalUniqueId() << " ";
928  }
929  }
930  }
931  }
932  return os;
933 }
934 
936 EntFiniteElement::getElementAdjacency(const boost::shared_ptr<Field> field_ptr,
937  Range &adjacency) {
938  moab::Interface &moab = getRefEntityPtr()->basicDataPtr->moab;
940  const EntFiniteElement *this_fe_ptr = this;
941  if (get_MoFEMFiniteElementPtr()->elementAdjacencyTable[getEntType()] ==
942  NULL) {
943  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
944  }
945  CHKERR get_MoFEMFiniteElementPtr()->elementAdjacencyTable[getEntType()](
946  moab, *field_ptr, *this_fe_ptr, adjacency);
948 }
949 
950 boost::weak_ptr<FENumeredDofEntity>
952  auto comp = [idx](const auto &a) { return a->getPetscGlobalDofIdx() == idx; };
953  auto dit = std::find_if(rows_dofs->begin(), rows_dofs->end(), comp);
954  if (dit != rows_dofs->end())
955  return *dit;
956  else
957  return boost::weak_ptr<FENumeredDofEntity>();
958 }
959 
960 boost::weak_ptr<FENumeredDofEntity>
962  auto comp = [idx](const auto &a) { return a->getPetscGlobalDofIdx() == idx; };
963  auto dit = std::find_if(cols_dofs->begin(), cols_dofs->end(), comp);
964  if (dit != cols_dofs->end())
965  return *dit;
966  else
967  return boost::weak_ptr<FENumeredDofEntity>();
968 }
969 
970 } // 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
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:172
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 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:169
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:476
BitFieldId getBitFieldIdRow() const
Get field ids on rows.
static MoFEMErrorCode defaultTri(Interface &moab, const Field &field_ptr, const EntFiniteElement &fe_ptr, Range &adjacency)
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.
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:619
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:601
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)
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:171
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:595
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:406
void * tagName
ptr to tag storing FE name
continuous field
Definition: definitions.h:170
keeps data about abstract TRI finite element
EntityHandle getMeshset() const
Get field meshset.
const boost::shared_ptr< SideNumber > & getSideNumberPtr(const EntityHandle ent) const
RefElement_TET(const boost::shared_ptr< RefEntity > &ref_ent_ptr)
boost::string_ref getNameRef() const
Get finite element name.
RefElement_TRI(const boost::shared_ptr< RefEntity > &ref_ent_ptr)
const boost::shared_ptr< SideNumber > & getSideNumberPtr(const EntityHandle ent) const
#define NOT_USED(x)
Definition: definitions.h:302
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:173