v0.15.0
Loading...
Searching...
No Matches
FEMultiIndices.cpp
Go to the documentation of this file.
1/** \file FEMultiIndices.cpp
2 * \brief Multi-index containers for finite elements
3 */
4
5namespace MoFEM {
6
7constexpr int FiniteElement::ent_shift; // EntityHandle size
8
25constexpr std::array<const DefaultElementAdjacency::DefEntTypeMap *, MBMAXTYPE>
27
28Tag FiniteElement::getNoFieldTag(moab::Interface &moab, const Field &field) {
29 static Tag th_no_field;
30 EntityHandle def_handle = field.getMeshset();
31 CHK_THROW_MESSAGE(moab.tag_get_handle(("_NOFIELD_" + field.getName()).c_str(),
32 1, MB_TYPE_HANDLE, th_no_field,
33 MB_TAG_CREAT | MB_TAG_SPARSE,
34 &def_handle),
35 "Cannot get or create _NOFIELD_ tag");
36 return th_no_field;
37}
38
40 Range &fe_ents,
41 const Field &field,
42 EntityHandle meshset) {
44 Tag th_no_field = getNoFieldTag(moab, field);
45 CHKERR moab.tag_clear_data(th_no_field, fe_ents, &meshset);
47}
48
51 std::vector<EntityHandle> &fe_ents,
52 const Field &field, EntityHandle meshset) {
54 Tag th_no_field = getNoFieldTag(moab, field);
55 CHKERR moab.tag_clear_data(th_no_field, fe_ents.data(), fe_ents.size(),
56 &meshset);
58}
59
61 EntityHandle fe_ent,
62 const Field &field) {
63 Tag th_no_field = getNoFieldTag(moab, field);
64 EntityHandle meshset[] = {0};
65 CHK_THROW_MESSAGE(moab.tag_get_data(th_no_field, &fe_ent, 1, meshset),
66 "Cannot get _NOFIELD_ tag data");
67 return meshset[0];
68}
69
71 moab::Interface &moab, const Field &field, const EntFiniteElement &fe,
72 std::vector<EntityHandle> &adjacency) {
74 switch (field.getSpace()) {
75 case H1:
76 adjacency.push_back(fe.getEnt());
77 // build side table
78 for (auto ent : adjacency)
79 fe.getSideNumberPtr(ent);
80 break;
81 case NOFIELD: {
82 auto adjacency_meshset =
84 CHKERR moab.get_entities_by_handle(adjacency_meshset, adjacency, false);
85 for (auto ent : adjacency) {
87 .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, -1, 0, 0)));
88 }
89 } break;
90 default:
91 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
92 "this field is not implemented for VERTEX finite element");
93 }
94
96}
97
99DefaultElementAdjacency::defaultEdge(moab::Interface &moab, const Field &field,
100 const EntFiniteElement &fe,
101 std::vector<EntityHandle> &adjacency) {
103 EntityHandle fe_ent = fe.getEnt();
104 // Range nodes;
105 switch (field.getSpace()) {
106 case H1:
107 CHKERR moab.get_connectivity(&fe_ent, 1, adjacency, true);
108 case HCURL:
109 case L2:
110 adjacency.push_back(fe_ent);
111 // build side table
112 for (auto e : adjacency)
113 fe.getSideNumberPtr(e);
114 break;
115 case NOFIELD: {
116 auto adjacency_meshset =
118 CHKERR moab.get_entities_by_handle(adjacency_meshset, adjacency, false);
119 for (auto e : adjacency) {
120 const_cast<SideNumber_multiIndex &>(fe.getSideNumberTable())
121 .insert(boost::shared_ptr<SideNumber>(new SideNumber(e, -1, 0, 0)));
122 }
123 } break;
124 default:
125 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
126 "this field is not implemented for EDGE finite element");
127 }
128
130}
131
133DefaultElementAdjacency::defaultFace(moab::Interface &moab, const Field &field,
134 const EntFiniteElement &fe,
135 std::vector<EntityHandle> &adjacency) {
137 // Range nodes,edges;
138 const EntityHandle fe_ent = fe.getEnt();
139 switch (field.getSpace()) {
140 case H1:
141 CHKERR moab.get_connectivity(&fe_ent, 1, adjacency, true);
142 case HCURL:
143 CHKERR moab.get_adjacencies(&fe_ent, 1, 1, false, adjacency,
144 moab::Interface::UNION);
145 case HDIV:
146 case L2:
147 adjacency.push_back(fe_ent);
148 // build side table
149 for (auto ent : adjacency)
150 fe.getSideNumberPtr(ent);
151 break;
152 case NOFIELD: {
153 auto adjacency_meshset =
155 CHKERR moab.get_entities_by_handle(adjacency_meshset, adjacency, false);
156 for (auto ent : adjacency) {
157 const_cast<SideNumber_multiIndex &>(fe.getSideNumberTable())
158 .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, -1, 0, 0)));
159 }
160 } break;
161 default:
162 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
163 "this field is not implemented for TRI finite element");
164 }
165
167}
168
170 moab::Interface &moab, const Field &field, const EntFiniteElement &fe,
171 std::vector<EntityHandle> &adjacency) {
173 EntityHandle fe_ent = fe.getEnt();
174 switch (field.getSpace()) {
175 case H1:
176 CHKERR moab.get_connectivity(&fe_ent, 1, adjacency, true);
177 case HCURL:
178 CHKERR moab.get_adjacencies(&fe_ent, 1, 1, false, adjacency,
179 moab::Interface::UNION);
180 case HDIV:
181 CHKERR moab.get_adjacencies(&fe_ent, 1, 2, false, adjacency,
182 moab::Interface::UNION);
183 case L2:
184 adjacency.push_back(fe_ent);
185 // build side table
186 for (auto ent : adjacency)
187 fe.getSideNumberPtr(ent);
188 break;
189 case NOFIELD: {
190 auto adjacency_meshset =
192 CHKERR moab.get_entities_by_handle(adjacency_meshset, adjacency, false);
193 for (auto ent : adjacency) {
194 const_cast<SideNumber_multiIndex &>(fe.getSideNumberTable())
195 .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, -1, 0, 0)));
196 }
197 } break;
198 default:
199 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
200 "this field is not implemented for TRI finite element");
201 }
202
204}
205
207DefaultElementAdjacency::defaultPrism(moab::Interface &moab, const Field &field,
208 const EntFiniteElement &fe,
209 std::vector<EntityHandle> &adjacency) {
211 const EntityHandle prism = fe.getEnt();
212 Range nodes;
213 // initialize side sets
214 fe.getRefElement()->getSideNumberPtr(prism);
215 EntityHandle face_side3, face_side4;
216 CHKERR moab.side_element(prism, 2, 3, face_side3);
217 CHKERR moab.side_element(prism, 2, 4, face_side4);
218 fe.getRefElement()->getSideNumberPtr(face_side3);
219 fe.getRefElement()->getSideNumberPtr(face_side4);
220 for (int qq = 0; qq < 3; qq++) {
221 EntityHandle quad = 0;
222 rval = moab.side_element(prism, 2, qq, quad);
223 if (rval != MB_SUCCESS || quad == 0)
224 continue;
225 int side_number, sense, offset;
226 rval = moab.side_number(prism, quad, side_number, sense, offset);
227 if (side_number == -1 || rval != MB_SUCCESS)
228 continue;
229 const_cast<SideNumber_multiIndex &>(fe.getSideNumberTable())
230 .insert(boost::shared_ptr<SideNumber>(
231 new SideNumber(quad, side_number, sense, offset)));
232 }
233 int ee = 0;
234 for (; ee < 3; ee++) {
235 EntityHandle edge = 0;
236 CHKERR moab.side_element(prism, 1, ee, edge);
237 boost::shared_ptr<SideNumber> side_ptr =
238 fe.getRefElement()->getSideNumberPtr(edge);
239 if (side_ptr->side_number != ee) {
240 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
241 "data inconsistency for edge %d while in FE data structure is "
242 "numbered %d.",
243 ee, side_ptr->side_number);
244 }
245 CHKERR moab.side_element(prism, 1, 6 + ee, edge);
246 side_ptr = fe.getRefElement()->getSideNumberPtr(edge);
247 if (side_ptr->side_number != ee + 6) {
248 if (side_ptr->side_number != ee) {
249 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
250 "data inconsistency for edge %d while in FE data structure "
251 "is numbered %d.",
252 ee, side_ptr->side_number);
253 } else {
254 side_ptr->brother_side_number = ee + 6;
255 }
256 }
257 }
258 for (; ee < 6; ee++) {
259 EntityHandle edge = 0;
260 rval = moab.side_element(prism, 1, ee, edge);
261 if (rval != MB_SUCCESS || edge == 0)
262 continue;
263 int side_number, sense, offset;
264 rval = moab.side_number(prism, edge, side_number, sense, offset);
265 if (side_number == -1 || rval != MB_SUCCESS)
266 continue;
267 const_cast<SideNumber_multiIndex &>(fe.getSideNumberTable())
268 .insert(boost::shared_ptr<SideNumber>(
269 new SideNumber(edge, side_number, sense, offset)));
270 }
271 int nn = 0;
272 for (; nn < 3; nn++) {
273 EntityHandle node;
274 CHKERR moab.side_element(prism, 0, nn, node);
275 boost::shared_ptr<SideNumber> side_ptr =
276 fe.getRefElement()->getSideNumberPtr(node);
277 if (side_ptr->side_number != nn) {
278 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
279 "data inconsistency for node %d while in FE datastructure is "
280 "numbered %d.",
281 nn, side_ptr->side_number);
282 }
283 CHKERR moab.side_element(prism, 0, nn + 3, node);
284 side_ptr = fe.getRefElement()->getSideNumberPtr(node);
285 if (side_ptr->side_number != nn + 3) {
286 if (side_ptr->side_number != nn) {
287 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
288 "data inconsistency for node %d while in FE datastructure is "
289 "numbered %d.",
290 nn, side_ptr->side_number);
291 } else {
292 side_ptr->brother_side_number = nn + 3;
293 }
294 }
295 }
296
297 // get adjacencies
298 SideNumber_multiIndex &side_table = fe.getRefElement()->getSideNumberTable();
299 switch (field.getSpace()) {
300 case H1:
301 // moab.get_connectivity(&prism,1,nodes,true);
302 // use get adjacencies, this will allow take in account adjacencies set user
303 CHKERR moab.get_adjacencies(&prism, 1, 0, false, nodes,
304 moab::Interface::UNION);
305 {
306 Range topo_nodes;
307 CHKERR moab.get_connectivity(&prism, 1, topo_nodes, true);
308 Range mid_nodes;
309 CHKERR moab.get_connectivity(&prism, 1, mid_nodes, false);
310 mid_nodes = subtract(mid_nodes, topo_nodes);
311 nodes = subtract(nodes, mid_nodes);
312 }
313 adjacency.insert(adjacency.end(), nodes.begin(), nodes.end());
314 case HCURL: {
315 auto siit = side_table.get<0>().lower_bound(get_id_for_min_type<MBEDGE>());
316 auto hi_siit =
317 side_table.get<0>().upper_bound(get_id_for_max_type<MBEDGE>());
318 for (; siit != hi_siit; siit++)
319 adjacency.push_back(siit->get()->ent);
320 }
321 case HDIV: {
322 auto siit = side_table.get<0>().lower_bound(get_id_for_min_type<MBTRI>());
323 auto hi_siit =
324 side_table.get<0>().upper_bound(get_id_for_max_type<MBQUAD>());
325 for (; siit != hi_siit; siit++)
326 adjacency.push_back(siit->get()->ent);
327 }
328 case L2:
329 adjacency.push_back(prism);
330 break;
331 case NOFIELD: {
332 auto adjacency_meshset =
334 CHKERR moab.get_entities_by_handle(adjacency_meshset, adjacency, false);
335 for (auto ent : adjacency) {
336 const_cast<SideNumber_multiIndex &>(fe.getSideNumberTable())
337 .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, -1, 0, 0)));
338 }
339 } break;
340 default:
341 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
342 "this field is not implemented for TRI finite element");
343 }
345}
346
348 moab::Interface &moab, const Field &field, const EntFiniteElement &fe,
349 std::vector<EntityHandle> &adjacency) {
351
352#ifndef NDEBUG
353 if (fe.getEntType() != MBENTITYSET)
354 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
355 "Finite element is not of type MBENTITYSET");
356#endif
357
358 // resolve recursively all ents in the meshset
359 switch (field.getSpace()) {
360 case H1:
361 case HCURL:
362 case HDIV:
363 case L2:
364 // H1, HCURL, HDIV, L2 we not suppose to access those from OP, so that why
365 // sign -1. That is to optimism efficiency
366 CHKERR moab.get_entities_by_handle(fe.getEnt(), adjacency, false);
367 for (auto ent : adjacency) {
368 const_cast<SideNumber_multiIndex &>(fe.getSideNumberTable())
369 .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, -1, 0, 0)));
370 }
371 break;
372 case NOFIELD: {
373 auto adjacency_meshset =
375 CHKERR moab.get_entities_by_handle(adjacency_meshset, adjacency, false);
376 for (auto ent : adjacency) {
377 const_cast<SideNumber_multiIndex &>(fe.getSideNumberTable())
378 .insert(boost::shared_ptr<SideNumber>(new SideNumber(ent, -1, 0, 0)));
379 }
380 } break;
381 default:
382 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
383 }
385}
386
387// FiniteElement
388FiniteElement::FiniteElement(moab::Interface &moab, const EntityHandle _meshset)
389 : meshset(_meshset) {
390 Tag th_FEId;
391 CHK_MOAB_THROW(moab.tag_get_handle("_FEId", th_FEId), "get tag");
393 moab.tag_get_by_ptr(th_FEId, &meshset, 1, (const void **)&tagId),
394 "get tag data");
395 Tag th_FEName;
396 CHK_MOAB_THROW(moab.tag_get_handle("_FEName", th_FEName), "get tag");
397 CHK_MOAB_THROW(moab.tag_get_by_ptr(th_FEName, &meshset, 1,
398 (const void **)&tagName, &tagNameSize),
399 "get tag data");
400 Tag th_FEIdCol, th_FEIdRow, th_FEIdData;
401 CHK_MOAB_THROW(moab.tag_get_handle("_FEIdCol", th_FEIdCol), "get_tag");
402 CHK_MOAB_THROW(moab.tag_get_by_ptr(th_FEIdCol, &meshset, 1,
403 (const void **)&tag_BitFieldId_col_data),
404 "get tag data");
405 CHK_MOAB_THROW(moab.tag_get_handle("_FEIdRow", th_FEIdRow), "get tag");
406 CHK_MOAB_THROW(moab.tag_get_by_ptr(th_FEIdRow, &meshset, 1,
407 (const void **)&tag_BitFieldId_row_data),
408 "get tag data");
409 CHK_MOAB_THROW(moab.tag_get_handle("_FEIdData", th_FEIdData), "get tag");
410 CHK_MOAB_THROW(moab.tag_get_by_ptr(th_FEIdData, &meshset, 1,
411 (const void **)&tag_BitFieldId_data),
412 "get tag data");
413
422
423 feUId = static_cast<UId>(getBitNumber()) << ent_shift;
424}
425
426std::ostream &operator<<(std::ostream &os, const FiniteElement &e) {
427 os << e.getNameRef() << " fe_id " << e.getId().to_ulong() << " f_id_row "
428 << e.getBitFieldIdRow() << " f_id_col " << e.getBitFieldIdCol()
429 << " BitFEId_data " << e.getBitFieldIdData();
430 return os;
431}
432
434 boost::shared_ptr<FiniteElement> &fe) {
435 *static_cast<BitFieldId *>(fe->tag_BitFieldId_col_data) |= fIdCol;
436}
437
439 boost::shared_ptr<FiniteElement> &fe) {
440 *static_cast<BitFieldId *>(fe->tag_BitFieldId_row_data) |= fIdRow;
441}
442
444 boost::shared_ptr<FiniteElement> &fe) {
445 *static_cast<BitFieldId *>(fe->tag_BitFieldId_data) |= fIdData;
446}
447
449 boost::shared_ptr<FiniteElement> &fe) {
450 *static_cast<BitFieldId *>(fe->tag_BitFieldId_col_data) &= fIdCol.flip();
451}
452
454 boost::shared_ptr<FiniteElement> &fe) {
455 *static_cast<BitFieldId *>(fe->tag_BitFieldId_row_data) &= fIdRow.flip();
456}
457
459 boost::shared_ptr<FiniteElement> &fe) {
460 *static_cast<BitFieldId *>(fe->tag_BitFieldId_data) &= fIdData.flip();
461}
462
464 boost::shared_ptr<FiniteElement> &fe) {
465 static_cast<BitFieldId *>(fe->tag_BitFieldId_col_data)->reset();
466}
467
469 boost::shared_ptr<FiniteElement> &fe) {
470 static_cast<BitFieldId *>(fe->tag_BitFieldId_row_data)->reset();
471}
472
474 boost::shared_ptr<FiniteElement> &fe) {
475 static_cast<BitFieldId *>(fe->tag_BitFieldId_data)->reset();
476}
477
478// FiniteElement data
480 const boost::shared_ptr<RefElement> &ref_finite_element,
481 const boost::shared_ptr<FiniteElement> &fe_ptr)
483 ref_finite_element),
484 dataFieldEnts(new FieldEntity_vector_view()),
485 rowFieldEnts(new FieldEntity_vector_view()),
486 colFieldEnts(new FieldEntity_vector_view()) {}
487
488std::ostream &operator<<(std::ostream &os, const EntFiniteElement &e) {
489 os << *e.getFiniteElementPtr() << std::endl;
490 os << *e.sPtr;
491 return os;
492}
493
495EntFiniteElement::getElementAdjacency(const boost::shared_ptr<Field> field_ptr,
496 std::vector<EntityHandle> &adjacency) {
497 moab::Interface &moab = getRefEntityPtr()->getBasicDataPtr()->moab;
499 const EntFiniteElement *this_fe_ptr = this;
500#ifndef NDEBUG
501 if (getFiniteElementPtr()->elementAdjacencyTable[getEntType()] == NULL)
502 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
503#endif
504 CHKERR getFiniteElementPtr() -> elementAdjacencyTable[getEntType()](
505 moab, *field_ptr, *this_fe_ptr, adjacency);
507}
508
509/**
510 * \Construct indexed finite element
511 */
513 const boost::shared_ptr<EntFiniteElement> &sptr)
514 : interface_EntFiniteElement<EntFiniteElement>(sptr), part(-1) {};
515
516boost::weak_ptr<FENumeredDofEntity>
518 auto comp = [idx](const auto &a) { return a->getPetscGlobalDofIdx() == idx; };
519
520 for (auto &it : getRowFieldEnts()) {
521 if (auto e = it.lock()) {
522 if (auto cache = e->entityCacheColDofs.lock()) {
523 auto dit = std::find_if(cache->loHi[0], cache->loHi[1], comp);
524 if (dit != cache->loHi[1])
525 return boost::reinterpret_pointer_cast<FENumeredDofEntity>(*dit);
526 } else
527 THROW_MESSAGE("Cache not set");
528 }
529 }
530
531 return boost::weak_ptr<FENumeredDofEntity>();
532}
533
534boost::weak_ptr<FENumeredDofEntity>
536
537 auto comp = [idx](const auto &a) { return a->getPetscGlobalDofIdx() == idx; };
538
539 for (auto &it : getColFieldEnts()) {
540 if (auto e = it.lock()) {
541 if (auto cache = e->entityCacheColDofs.lock()) {
542 auto dit = std::find_if(cache->loHi[0], cache->loHi[1], comp);
543 if (dit != cache->loHi[1])
544 return boost::reinterpret_pointer_cast<FENumeredDofEntity>(*dit);
545 } else
546 THROW_MESSAGE("Cache not set");
547 }
548 }
549
550 return boost::weak_ptr<FENumeredDofEntity>();
551}
552
553std::ostream &operator<<(std::ostream &os, const NumeredEntFiniteElement &e) {
554 os << "part " << e.part << " " << *(e.getEntFiniteElement());
555 return os;
556}
557
558template <typename ENTSVIEW, typename DOFSVIEW, typename EXTRACTOR,
559 typename INSERTER>
560inline static MoFEMErrorCode
561get_cache_data_dofs_view(ENTSVIEW &ents_view, DOFSVIEW &dofs_view,
562 EXTRACTOR &&extractor, INSERTER &&inserter) {
564
565 auto hint = dofs_view->end();
566 using ValType = typename std::remove_reference<decltype(**hint)>::type;
567
568 for (auto &it : *ents_view) {
569 if (auto e = it.lock()) {
570
571 if (auto cache = extractor(e).lock())
572 for (auto dit = cache->loHi[0]; dit != cache->loHi[1]; ++dit)
573 hint = inserter(dofs_view, hint,
574 boost::reinterpret_pointer_cast<ValType>(*dit));
575 else
576 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "Cache not set");
577 }
578 }
579
581}
582
583boost::shared_ptr<FEDofEntity_multiIndex>
586 struct Extractor {
587 boost::weak_ptr<EntityCacheDofs>
588 operator()(boost::shared_ptr<FieldEntity> &e) {
589 return e->entityCacheDataDofs;
590 }
591 };
592
593 struct Inserter {
594 FEDofEntity_multiIndex::iterator
595 operator()(boost::shared_ptr<FEDofEntity_multiIndex> &dofs_view,
596 FEDofEntity_multiIndex::iterator &hint,
597 boost::shared_ptr<FEDofEntity> &&dof) {
598 return dofs_view->emplace_hint(hint, dof);
599 }
600 };
601
602 auto data_dofs = boost::make_shared<FEDofEntity_multiIndex>();
603 if (get_cache_data_dofs_view(dataFieldEnts, data_dofs, Extractor(),
604 Inserter()))
605 THROW_MESSAGE("data_dofs can not be created");
606 return data_dofs;
607};
608
609boost::shared_ptr<std::vector<boost::shared_ptr<FEDofEntity>>>
612
613 struct Extractor {
614 boost::weak_ptr<EntityCacheDofs>
615 operator()(boost::shared_ptr<FieldEntity> &e) {
616 return e->entityCacheDataDofs;
617 }
618 };
619
620 struct Inserter {
621 using Vec = std::vector<boost::shared_ptr<FEDofEntity>>;
622 using It = Vec::iterator;
623 It operator()(boost::shared_ptr<Vec> &dofs_view, It &hint,
624 boost::shared_ptr<FEDofEntity> &&dof) {
625 dofs_view->emplace_back(dof);
626 return dofs_view->end();
627 }
628 };
629
630 auto data_vector_dofs =
631 boost::make_shared<std::vector<boost::shared_ptr<FEDofEntity>>>();
632 if (get_cache_data_dofs_view(dataFieldEnts, data_vector_dofs, Extractor(),
633 Inserter()))
634 THROW_MESSAGE("dataDofs can not be created");
635
636 return data_vector_dofs;
637};
638
639boost::shared_ptr<FENumeredDofEntity_multiIndex>
642
643 struct Extractor {
644 boost::weak_ptr<EntityCacheNumeredDofs>
645 operator()(boost::shared_ptr<FieldEntity> &e) {
646 return e->entityCacheRowDofs;
647 }
648 };
649
650 struct Inserter {
652 using It = Idx::iterator;
653 It operator()(boost::shared_ptr<Idx> &dofs_view, It &hint,
654 boost::shared_ptr<FENumeredDofEntity> &&dof) {
655 return dofs_view->emplace_hint(hint, dof);
656 }
657 };
658
659 auto row_dofs = boost::make_shared<FENumeredDofEntity_multiIndex>();
660 if (get_cache_data_dofs_view(getRowFieldEntsPtr(), row_dofs, Extractor(),
661 Inserter()))
662 THROW_MESSAGE("row_dofs can not be created");
663
664 return row_dofs;
665}
666
667boost::shared_ptr<FENumeredDofEntity_multiIndex>
670
671 struct Extractor {
672 boost::weak_ptr<EntityCacheNumeredDofs>
673 operator()(boost::shared_ptr<FieldEntity> &e) {
674 return e->entityCacheColDofs;
675 }
676 };
677
678 struct Inserter {
680 using It = Idx::iterator;
681 It operator()(boost::shared_ptr<Idx> &dofs_view, It &hint,
682 boost::shared_ptr<FENumeredDofEntity> &&dof) {
683 return dofs_view->emplace_hint(hint, dof);
684 }
685 };
686
687 auto col_dofs = boost::make_shared<FENumeredDofEntity_multiIndex>();
688 if (get_cache_data_dofs_view(getColFieldEntsPtr(), col_dofs, Extractor(),
689 Inserter()))
690 THROW_MESSAGE("col_dofs can not be created");
691
692 return col_dofs;
693}
694
695} // namespace MoFEM
constexpr double a
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ L2
field with C-1 continuity
Definition definitions.h:88
@ NOFIELD
scalar or vector of scalars describe (no true field)
Definition definitions.h:84
@ H1
continuous field
Definition definitions.h:85
@ HCURL
field with continuous tangents
Definition definitions.h:86
@ HDIV
field with continuous normal traction
Definition definitions.h:87
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define THROW_MESSAGE(msg)
Throw MoFEM exception.
multi_index_container< boost::shared_ptr< FENumeredDofEntity >, indexed_by< ordered_unique< tag< Unique_mi_tag >, const_mem_fun< FENumeredDofEntity::interface_type_DofEntity, UId, &FENumeredDofEntity::getLocalUniqueId > >, ordered_non_unique< tag< Ent_mi_tag >, const_mem_fun< FENumeredDofEntity::interface_type_DofEntity, EntityHandle, &FENumeredDofEntity::getEnt > > > > FENumeredDofEntity_multiIndex
MultiIndex container keeps FENumeredDofEntity.
multi_index_container< boost::shared_ptr< SideNumber >, indexed_by< ordered_unique< member< SideNumber, EntityHandle, &SideNumber::ent > >, ordered_non_unique< composite_key< SideNumber, const_mem_fun< SideNumber, EntityType, &SideNumber::getEntType >, member< SideNumber, signed char, &SideNumber::side_number > > > > > SideNumber_multiIndex
SideNumber_multiIndex for SideNumber.
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
std::bitset< BITFIELDID_SIZE > BitFieldId
Field Id.
Definition Types.hpp:42
uint128_t UId
Unique Id.
Definition Types.hpp:31
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
EntityHandle get_id_for_max_type()
EntityHandle get_id_for_min_type()
std::ostream & operator<<(std::ostream &os, const EntitiesFieldData::EntData &e)
std::vector< boost::weak_ptr< FieldEntity > > FieldEntity_vector_view
static MoFEMErrorCode get_cache_data_dofs_view(ENTSVIEW &ents_view, DOFSVIEW &dofs_view, EXTRACTOR &&extractor, INSERTER &&inserter)
static constexpr DefEntTypeMap defVertexTypeMap
static constexpr DefEntTypeMap defEdgeTypeMap
std::array< bool, MBMAXTYPE > DefEntTypeMap
static constexpr DefEntTypeMap defQuadTypeMap
static constexpr DefEntTypeMap defTriTypeMap
static MoFEMErrorCode defaultMeshset(Interface &moab, const Field &field, const EntFiniteElement &fe, std::vector< EntityHandle > &adjacency)
static MoFEMErrorCode defaultVertex(Interface &moab, const Field &field, const EntFiniteElement &fe, std::vector< EntityHandle > &adjacency)
static MoFEMErrorCode defaultVolume(Interface &moab, const Field &field, const EntFiniteElement &fe, std::vector< EntityHandle > &adjacency)
static constexpr std::array< const DefEntTypeMap *, MBMAXTYPE > defTypeMap
static constexpr DefEntTypeMap defTetTypeMap
static constexpr DefEntTypeMap defHexTypeMap
static constexpr DefEntTypeMap defMeshsetTypeMap
static MoFEMErrorCode defaultEdge(Interface &moab, const Field &field, const EntFiniteElement &fe, std::vector< EntityHandle > &adjacency)
static MoFEMErrorCode defaultPrism(Interface &moab, const Field &field, const EntFiniteElement &fe, std::vector< EntityHandle > &adjacency)
static MoFEMErrorCode defaultFace(Interface &moab, const Field &field, const EntFiniteElement &fe, std::vector< EntityHandle > &adjacency)
static constexpr DefEntTypeMap defPrismTypeMap
Finite element data for entity.
EntFiniteElement(const boost::shared_ptr< RefElement > &ref_finite_element, const boost::shared_ptr< FiniteElement > &fe_ptr)
boost::shared_ptr< std::vector< boost::shared_ptr< FEDofEntity > > > getDataVectorDofsPtr() const
Get data data dos multi-index structure.
boost::shared_ptr< FieldEntity_vector_view > dataFieldEnts
boost::shared_ptr< FEDofEntity_multiIndex > getDataDofsPtr() const
Get the Data Dofs Ptr object.
MoFEMErrorCode getElementAdjacency(const boost::shared_ptr< Field > field_ptr, std::vector< EntityHandle > &adjacency)
Provide data structure for (tensor) field approximation.
std::string getName() const
Get field name.
EntityHandle getMeshset() const
Get field meshset.
FieldSpace getSpace() const
Get field approximation space.
void operator()(boost::shared_ptr< FiniteElement > &fe)
void operator()(boost::shared_ptr< FiniteElement > &fe)
void operator()(boost::shared_ptr< FiniteElement > &fe)
void operator()(boost::shared_ptr< FiniteElement > &fe)
void operator()(boost::shared_ptr< FiniteElement > &fe)
void operator()(boost::shared_ptr< FiniteElement > &fe)
void operator()(boost::shared_ptr< FiniteElement > &fe)
void operator()(boost::shared_ptr< FiniteElement > &fe)
void operator()(boost::shared_ptr< FiniteElement > &fe)
Finite element definition.
BitFieldId * tag_BitFieldId_col_data
tag stores col id_id for fields
void * tagName
ptr to tag storing FE name
unsigned int getBitNumber() const
Get bit identifying this element.
BitFieldId * tag_BitFieldId_data
tag stores data id_id for fields
static MoFEMErrorCode setNoFieldTagField(moab::Interface &moab, Range &fe_ents, const Field &field, EntityHandle meshset)
Set the No Field meshset to finite element entities storing no field adjacencies to it.
static Tag getNoFieldTag(moab::Interface &moab, const Field &field)
Get the tag storing meshset with adjacent entities to finite element.
BitFEId * tagId
ptr to tag storing FE id
BitFieldId getBitFieldIdRow() const
Get field ids on rows.
BitFEId getId() const
Get finite element id.
FiniteElement(Interface &moab, const EntityHandle _meshset)
BitFieldId * tag_BitFieldId_row_data
tag stores row id_id for fields
static EntityHandle getNoFieldAdjacencyMeshset(moab::Interface &moab, EntityHandle fe_ent, const Field &field)
Get the No Field adjacency meshset from finite element entity.
static constexpr int ent_shift
boost::string_ref getNameRef() const
Get finite element name.
BitFieldId getBitFieldIdData() const
Get field ids on data.
BitFieldId getBitFieldIdCol() const
Get field ids on columns.
int tagNameSize
numer of characters in FE name
EntityHandle meshset
meshset stores FE ents
std::array< ElementAdjacencyFunct, MBMAXTYPE > elementAdjacencyTable
Table of functions retrieving adjacencies for finite element User can alter and change default behavi...
Partitioned (Indexed) Finite Element in Problem.
boost::weak_ptr< FENumeredDofEntity > getRowDofsByPetscGlobalDofIdx(const int idx) const
get FE dof by petsc index
boost::weak_ptr< FENumeredDofEntity > getColDofsByPetscGlobalDofIdx(const int idx) const
get FE dof by petsc index
NumeredEntFiniteElement(const boost::shared_ptr< EntFiniteElement > &sptr)
boost::shared_ptr< EntFiniteElement > & getEntFiniteElement() const
boost::shared_ptr< FENumeredDofEntity_multiIndex > getRowDofsPtr() const
get FE dof on row
boost::shared_ptr< FENumeredDofEntity_multiIndex > getColDofsPtr() const
get FE dof on column
unsigned int part
Partition number.
keeps data about abstract refined finite element
keeps information about side number for the finite element
interface to EntFiniteElement
boost::shared_ptr< FieldEntity_vector_view > & getColFieldEntsPtr() const
boost::shared_ptr< FieldEntity_vector_view > & getRowFieldEntsPtr() const
const boost::shared_ptr< RefElement > & getRefElement() const
boost::shared_ptr< FE > & getFiniteElementPtr() const
const boost::shared_ptr< SideNumber > & getSideNumberPtr(const EntityHandle ent) const
boost::shared_ptr< RefEntity > & getRefEntityPtr() const
SideNumber_multiIndex & getSideNumberTable() const
boost::shared_ptr< T > & getRefElement() const