v0.15.0
Loading...
Searching...
No Matches
Namespaces | Macros
FECore.cpp File Reference

Core interface methods for managing deletions and insertion dofs. More...

#include <MoFEM.hpp>

Go to the source code of this file.

Namespaces

namespace  MoFEM
 implementation of Data Operators for Forces and Sources
 

Macros

#define FECoreFunctionBegin
 

Detailed Description

Core interface methods for managing deletions and insertion dofs.

Definition in file FECore.cpp.

Macro Definition Documentation

◆ FECoreFunctionBegin

#define FECoreFunctionBegin
Value:
MOFEM_LOG_CHANNEL("WORLD"); \
MOFEM_LOG_CHANNEL("SYNC"); \
MOFEM_LOG_FUNCTION(); \
MOFEM_LOG_TAG("WORLD", "FECore"); \
MOFEM_LOG_TAG("SYNC", "FECore");
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...

Definition at line 7 of file FECore.cpp.

14 {
15
16const FiniteElement *
17Core::get_finite_element_structure(const std::string &name,
18 enum MoFEMTypes bh) const {
19 auto miit = finiteElements.get<FiniteElement_name_mi_tag>().find(name);
20 if (miit == finiteElements.get<FiniteElement_name_mi_tag>().end()) {
21 if (bh == MF_EXIST) {
22 throw MoFEMException(
24 std::string("finite element < " + name +
25 " > not in database (top tip: check spelling)")
26 .c_str());
27 } else {
28 return nullptr;
29 }
30 }
31 return miit->get();
32}
33
34bool Core::check_finite_element(const std::string &name) const {
35 auto miit = finiteElements.get<FiniteElement_name_mi_tag>().find(name);
36 if (miit == finiteElements.get<FiniteElement_name_mi_tag>().end())
37 return false;
38 else
39 return true;
40}
41
42MoFEMErrorCode Core::add_finite_element(const std::string &fe_name,
43 enum MoFEMTypes bh, int verb) {
45 *buildMoFEM &= 1 << 0;
46 if (verb == -1) {
47 verb = verbose;
48 }
49
50 // Add finite element meshset to partition meshset. In case of no elements
51 // on processor part, when mesh file is read, finite element meshset is
52 // prevented from deletion by moab reader.
53 auto add_meshset_to_partition = [&](auto meshset) {
55 const void *tag_vals[] = {&rAnk};
56 ParallelComm *pcomm = ParallelComm::get_pcomm(
57 &get_moab(), get_basic_entity_data_ptr()->pcommID);
58 Tag part_tag = pcomm->part_tag();
59 Range tagged_sets;
60 CHKERR get_moab().get_entities_by_type_and_tag(0, MBENTITYSET, &part_tag,
61 tag_vals, 1, tagged_sets,
62 moab::Interface::UNION);
63 for (auto s : tagged_sets)
64 CHKERR get_moab().add_entities(s, &meshset, 1);
66 };
67
68 auto &finite_element_name_set =
69 finiteElements.get<FiniteElement_name_mi_tag>();
70 auto it_fe = finite_element_name_set.find(fe_name);
71
72 if (bh == MF_EXCL) {
73 if (it_fe != finite_element_name_set.end()) {
74 SETERRQ(mofemComm, MOFEM_NOT_FOUND, "this < %s > is there",
75 fe_name.c_str());
76 }
77
78 } else {
79 if (it_fe != finite_element_name_set.end())
81 }
82 EntityHandle meshset;
83 CHKERR get_moab().create_meshset(MESHSET_SET, meshset);
84 CHKERR add_meshset_to_partition(meshset);
85
86 // id
87 int fe_shift = 0;
88 for (; finiteElements.get<BitFEId_mi_tag>().find(BitFEId().set(fe_shift)) !=
89 finiteElements.get<BitFEId_mi_tag>().end();
90 ++fe_shift) {
91 }
92
93 auto id = BitFEId().set(fe_shift);
94 CHKERR get_moab().tag_set_data(th_FEId, &meshset, 1, &id);
95
96 // id name
97 void const *tag_data[] = {fe_name.c_str()};
98 int tag_sizes[1];
99 tag_sizes[0] = fe_name.size();
100 CHKERR get_moab().tag_set_by_ptr(th_FEName, &meshset, 1, tag_data, tag_sizes);
101
102 // add FiniteElement
103 auto p = finiteElements.insert(
104 boost::shared_ptr<FiniteElement>(new FiniteElement(moab, meshset)));
105 if (!p.second)
106 SETERRQ(mofemComm, MOFEM_OPERATION_UNSUCCESSFUL,
107 "FiniteElement not inserted");
108
109 if (verb > QUIET)
110 MOFEM_LOG("WORLD", Sev::inform) << "Add finite element " << fe_name;
111
113}
114
116Core::modify_finite_element_adjacency_table(const std::string &fe_name,
117 const EntityType type,
118 ElementAdjacencyFunct function) {
120 *buildMoFEM &= 1 << 0;
121 typedef FiniteElement_multiIndex::index<FiniteElement_name_mi_tag>::type
122 FiniteElements_by_name;
123 FiniteElements_by_name &finite_element_name_set =
124 finiteElements.get<FiniteElement_name_mi_tag>();
125 FiniteElements_by_name::iterator it_fe =
126 finite_element_name_set.find(fe_name);
127 if (it_fe == finite_element_name_set.end())
128 SETERRQ(mofemComm, MOFEM_NOT_FOUND,
129 "This finite element is not defined (advise: check spelling)");
130 boost::shared_ptr<FiniteElement> fe;
131 fe = *it_fe;
132 fe->elementAdjacencyTable[type] = function;
134}
135
137Core::modify_finite_element_add_field_data(const std::string &fe_name,
138 const std::string name_data) {
140 *buildMoFEM &= 1 << 0;
141 typedef FiniteElement_multiIndex::index<FiniteElement_name_mi_tag>::type
142 FiniteElements_by_name;
143 FiniteElements_by_name &finite_element_name_set =
144 finiteElements.get<FiniteElement_name_mi_tag>();
145 FiniteElements_by_name::iterator it_fe =
146 finite_element_name_set.find(fe_name);
147 if (it_fe == finite_element_name_set.end())
148 SETERRQ(mofemComm, MOFEM_NOT_FOUND,
149 "This finite element is not defined (advise: check spelling)");
150 bool success = finite_element_name_set.modify(
151 it_fe, FiniteElement_change_bit_add(get_field_id(name_data)));
152 if (!success)
153 SETERRQ(mofemComm, MOFEM_OPERATION_UNSUCCESSFUL,
154 "modification unsuccessful");
156}
157
159Core::modify_finite_element_add_field_row(const std::string &fe_name,
160 const std::string name_row) {
162 *buildMoFEM &= 1 << 0;
163 typedef FiniteElement_multiIndex::index<FiniteElement_name_mi_tag>::type
164 FiniteElements_by_name;
165 FiniteElements_by_name &finite_element_name_set =
166 finiteElements.get<FiniteElement_name_mi_tag>();
167 FiniteElements_by_name::iterator it_fe =
168 finite_element_name_set.find(fe_name);
169 if (it_fe == finite_element_name_set.end())
170 SETERRQ(mofemComm, MOFEM_NOT_FOUND, "this < %s > is not there",
171 fe_name.c_str());
172 bool success = finite_element_name_set.modify(
173 it_fe, FiniteElement_row_change_bit_add(get_field_id(name_row)));
174 if (!success)
175 SETERRQ(mofemComm, MOFEM_OPERATION_UNSUCCESSFUL,
176 "modification unsuccessful");
178}
179
181Core::modify_finite_element_add_field_col(const std::string &fe_name,
182 const std::string name_col) {
184 *buildMoFEM &= 1 << 0;
185 auto &finite_element_name_set =
186 finiteElements.get<FiniteElement_name_mi_tag>();
187 auto it_fe = finite_element_name_set.find(fe_name);
188 if (it_fe == finite_element_name_set.end())
189 SETERRQ(mofemComm, MOFEM_OPERATION_UNSUCCESSFUL,
190 "this FiniteElement is there");
191 bool success = finite_element_name_set.modify(
192 it_fe, FiniteElement_col_change_bit_add(get_field_id(name_col)));
193 if (!success)
194 SETERRQ(mofemComm, MOFEM_OPERATION_UNSUCCESSFUL,
195 "modification unsuccessful");
197}
198
200Core::modify_finite_element_off_field_data(const std::string &fe_name,
201 const std::string name_data) {
203 *buildMoFEM &= 1 << 0;
204 auto &finite_element_name_set =
205 finiteElements.get<FiniteElement_name_mi_tag>();
206 auto it_fe = finite_element_name_set.find(fe_name);
207 if (it_fe == finite_element_name_set.end())
208 SETERRQ(mofemComm, MOFEM_NOT_FOUND, "this FiniteElement is there");
209 bool success = finite_element_name_set.modify(
210 it_fe, FiniteElement_change_bit_off(get_field_id(name_data)));
211 if (!success)
212 SETERRQ(mofemComm, MOFEM_OPERATION_UNSUCCESSFUL,
213 "modification unsuccessful");
215}
216
218Core::modify_finite_element_off_field_row(const std::string &fe_name,
219 const std::string name_row) {
221 *buildMoFEM &= 1 << 0;
222 auto &finite_element_name_set =
223 finiteElements.get<FiniteElement_name_mi_tag>();
224 auto it_fe = finite_element_name_set.find(fe_name);
225 if (it_fe == finite_element_name_set.end())
226 SETERRQ(mofemComm, MOFEM_NOT_FOUND, "this < %s > is not there",
227 fe_name.c_str());
228 bool success = finite_element_name_set.modify(
229 it_fe, FiniteElement_row_change_bit_off(get_field_id(name_row)));
230 if (!success)
231 SETERRQ(mofemComm, MOFEM_OPERATION_UNSUCCESSFUL,
232 "modification unsuccessful");
234}
235
237Core::modify_finite_element_off_field_col(const std::string &fe_name,
238 const std::string name_col) {
240 *buildMoFEM &= 1 << 0;
241 auto &finite_element_name_set =
242 finiteElements.get<FiniteElement_name_mi_tag>();
243 auto it_fe = finite_element_name_set.find(fe_name);
244 if (it_fe == finite_element_name_set.end())
245 SETERRQ(mofemComm, MOFEM_NOT_FOUND, "this FiniteElement is there");
246 bool success = finite_element_name_set.modify(
247 it_fe, FiniteElement_col_change_bit_off(get_field_id(name_col)));
248 if (!success)
249 SETERRQ(mofemComm, MOFEM_OPERATION_UNSUCCESSFUL,
250 "modification unsuccessful");
252}
253
254BitFEId Core::getBitFEId(const std::string &fe_name) const {
255 auto &fe_by_id = finiteElements.get<FiniteElement_name_mi_tag>();
256 auto miit = fe_by_id.find(fe_name);
257 if (miit == fe_by_id.end())
259 ("finite element < " + fe_name + " > not found (top tip: check spelling)")
260 .c_str());
261 return (*miit)->getId();
262}
263
264std::string Core::getBitFEIdName(const BitFEId id) const {
265 auto &fe_by_id = finiteElements.get<BitFEId_mi_tag>();
266 auto miit = fe_by_id.find(id);
267 if (miit == fe_by_id.end())
268 THROW_MESSAGE("finite element not found");
269 return (*miit)->getName();
270}
271
272EntityHandle Core::get_finite_element_meshset(const BitFEId id) const {
273 auto &fe_by_id = finiteElements.get<BitFEId_mi_tag>();
274 auto miit = fe_by_id.find(id);
275 if (miit == fe_by_id.end())
276 THROW_MESSAGE("finite element not found");
277 return (*miit)->meshset;
278}
279
280EntityHandle Core::get_finite_element_meshset(const std::string name) const {
281 return get_finite_element_meshset(getBitFEId(name));
282}
283
285Core::get_finite_element_entities_by_dimension(const std::string name, int dim,
286 Range &ents) const {
287
289
290 EntityHandle meshset = get_finite_element_meshset(name);
291 CHKERR get_moab().get_entities_by_dimension(meshset, dim, ents, true);
293}
294
295MoFEMErrorCode Core::get_finite_element_entities_by_type(const std::string name,
296 EntityType type,
297 Range &ents) const {
298
300
301 EntityHandle meshset = get_finite_element_meshset(name);
302 CHKERR get_moab().get_entities_by_type(meshset, type, ents, true);
303
305}
306
308Core::get_finite_element_entities_by_handle(const std::string name,
309 Range &ents) const {
310
312
313 EntityHandle meshset = get_finite_element_meshset(name);
314 CHKERR get_moab().get_entities_by_handle(meshset, ents, true);
315
317}
318
319MoFEMErrorCode Core::list_finite_elements() const {
321 for (auto &fe : finiteElements.get<FiniteElement_name_mi_tag>())
322 MOFEM_LOG("SYNC", Sev::inform) << fe;
323
324 MOFEM_LOG_SYNCHRONISE(mofemComm);
326}
327
328MoFEMErrorCode Core::add_ents_to_finite_element_by_type(
329 const EntityHandle meshset, const EntityType type, const std::string name,
330 const bool recursive) {
331 *buildMoFEM &= 1 << 0;
334
335 idm = get_finite_element_meshset(getBitFEId(name));
336 Range ents;
337 CHKERR get_moab().get_entities_by_type(meshset, type, ents, recursive);
338 CHKERR getInterface<BitRefManager>()->setElementsBitRefLevel(ents);
339 CHKERR get_moab().add_entities(idm, ents);
340
342}
343
345Core::add_ents_to_finite_element_by_dim(const EntityHandle meshset,
346 const int dim, const std::string name,
347 const bool recursive) {
349 *buildMoFEM &= 1 << 0;
351 idm = get_finite_element_meshset(getBitFEId(name));
352 Range ents;
353 CHKERR get_moab().get_entities_by_dimension(meshset, dim, ents, recursive);
354 CHKERR getInterface<BitRefManager>()->setElementsBitRefLevel(ents);
355 CHKERR get_moab().add_entities(idm, ents);
357}
358
359MoFEMErrorCode Core::add_ents_to_finite_element_by_type(
360 const Range ents, const EntityType type, const std::string name) {
362 *buildMoFEM &= 1 << 0;
364 idm = get_finite_element_meshset(getBitFEId(name));
365 CHKERR getInterface<BitRefManager>()->setElementsBitRefLevel(
366 ents.subset_by_type(type));
367 CHKERR get_moab().add_entities(idm, ents.subset_by_type(type));
369} // namespace MoFEM
370
372Core::add_ents_to_finite_element_by_dim(const Range ents, const int dim,
373 const std::string name) {
375 *buildMoFEM &= 1 << 0;
377 idm = get_finite_element_meshset(getBitFEId(name));
378 CHKERR getInterface<BitRefManager>()->setElementsBitRefLevel(
379 ents.subset_by_dimension(dim));
380 CHKERR get_moab().add_entities(idm, ents.subset_by_dimension(dim));
382}
383
385Core::add_ents_to_finite_element_EntType_by_bit_ref(const BitRefLevel &bit,
386 const std::string &name,
387 EntityType type, int verb) {
389 CHKERR add_ents_to_finite_element_by_bit_ref(bit, BitRefLevel().set(), name,
390 type, verb);
391
393}
394
395MoFEMErrorCode Core::add_ents_to_finite_element_EntType_by_bit_ref(
396 const BitRefLevel &bit, const BitRefLevel &mask, const std::string &name,
397 EntityType type, int verb) {
399 CHKERR add_ents_to_finite_element_by_bit_ref(bit, mask, name, type, verb);
400
402}
403
404MoFEMErrorCode Core::add_ents_to_finite_element_by_bit_ref(
405 const BitRefLevel bit, const BitRefLevel mask, const std::string name,
406 EntityType type, int verb) {
408
409 if (verb == -1)
410 verb = verbose;
411 *buildMoFEM &= 1 << 0;
412 const BitFEId id = getBitFEId(name);
413 const EntityHandle idm = get_finite_element_meshset(id);
414
415 auto &ref_MoFEMFiniteElement = refinedFiniteElements.get<Ent_mi_tag>();
416 auto miit = ref_MoFEMFiniteElement.lower_bound(get_id_for_min_type(type));
417 auto hi_miit = ref_MoFEMFiniteElement.upper_bound(get_id_for_max_type(type));
418
419 int nb_add_fes = 0;
420 for (; miit != hi_miit; miit++) {
421 const auto &bit2 = miit->get()->getBitRefLevel();
422 if ((bit2 & mask) != bit2)
423 continue;
424 if ((bit2 & bit).any()) {
425 EntityHandle ent = miit->get()->getEnt();
426 CHKERR get_moab().add_entities(idm, &ent, 1);
427 nb_add_fes++;
428 }
429 }
430
431 MOFEM_LOG("SYNC", Sev::inform)
432 << "Finite element " << name << " added. Nb. of elements added "
433 << nb_add_fes << " out of " << std::distance(miit, hi_miit);
434
435 MOFEM_LOG_SYNCHRONISE(mofemComm)
436
438}
439
440MoFEMErrorCode Core::add_ents_to_finite_element_by_MESHSET(
441 const EntityHandle meshset, const std::string &name, const bool recursive) {
443 *buildMoFEM &= 1 << 0;
444 const BitFEId id = getBitFEId(name);
445 const EntityHandle idm = get_finite_element_meshset(id);
446 if (recursive == false) {
447 CHKERR get_moab().add_entities(idm, &meshset, 1);
448 } else {
449 Range meshsets;
450 CHKERR get_moab().get_entities_by_type(meshset, MBENTITYSET, meshsets,
451 false);
452 CHKERR get_moab().add_entities(idm, meshsets);
453 }
455}
456
458Core::buildFiniteElements(const boost::shared_ptr<FiniteElement> &fe,
459 const Range *ents_ptr, int verb) {
461 if (verb == DEFAULT_VERBOSITY)
462 verb = verbose;
463
464 if (verb > QUIET)
465 MOFEM_LOG("SYNC", Sev::verbose)
466 << "Build Finite Elements " << fe->getName();
467
468 auto &fields_by_id = fIelds.get<BitFieldId_mi_tag>();
469
470 // Get id of mofem fields for row, col and data
471 enum IntLoop { ROW = 0, COL, DATA, LAST };
472 std::array<BitFieldId, LAST> fe_fields = {fe.get()->getBitFieldIdRow(),
473 fe.get()->getBitFieldIdCol(),
474 fe.get()->getBitFieldIdData()};
475
476 // Get finite element meshset
477 EntityHandle meshset = get_finite_element_meshset(fe.get()->getId());
478
479 // Get entities from finite element meshset // if meshset
480 Range fe_ents;
481 CHKERR get_moab().get_entities_by_handle(meshset, fe_ents, false);
482
483 if (ents_ptr)
484 fe_ents = intersect(fe_ents, *ents_ptr);
485
486 // Map entity uid to pointers
487 typedef std::vector<boost::weak_ptr<EntFiniteElement>> VecOfWeakFEPtrs;
488 VecOfWeakFEPtrs processed_fes;
489 processed_fes.reserve(fe_ents.size());
490
491 int last_data_field_ents_view_size = 0;
492 int last_row_field_ents_view_size = 0;
493 int last_col_field_ents_view_size = 0;
494
495 // Entities adjacent to entities
496 std::vector<EntityHandle> adj_ents;
497
498 // Loop meshset finite element ents and add finite elements
499 for (Range::const_pair_iterator peit = fe_ents.const_pair_begin();
500 peit != fe_ents.const_pair_end(); peit++) {
501
502 const auto first = peit->first;
503 const auto second = peit->second;
504
505 // Find range of ref entities that is sequence
506 // note: iterator is a wrapper
507 // check if is in refinedFiniteElements database
508 auto ref_fe_miit =
509 refinedFiniteElements.get<Ent_mi_tag>().lower_bound(first);
510 auto hi_ref_fe_miit =
511 refinedFiniteElements.get<Ent_mi_tag>().upper_bound(second);
512 if (std::distance(ref_fe_miit, hi_ref_fe_miit) != (second - first + 1)) {
513 MOFEM_LOG("SELF", Sev::noisy) << "Finite element " << fe->getName()
514 << " not defined on all entities in "
515 "the meshset, missing entities";
516 MOFEM_LOG("SELF", Sev::noisy)
517 << "Missing entities: " << first << " - " << second;
518 }
519
520 EntFiniteElement_multiIndex::iterator hint_p = entsFiniteElements.end();
521 for (; ref_fe_miit != hi_ref_fe_miit; ref_fe_miit++) {
522
523 // Add finite element to database
524 hint_p = entsFiniteElements.emplace_hint(
525 hint_p, boost::make_shared<EntFiniteElement>(*ref_fe_miit, fe));
526 processed_fes.emplace_back(*hint_p);
527 auto fe_raw_ptr = hint_p->get();
528
529 // Allocate space for entities view
530 bool row_as_data = false, col_as_row = false;
531 if (fe_fields[DATA] == fe_fields[ROW])
532 row_as_data = true;
533 if (fe_fields[ROW] == fe_fields[COL])
534 col_as_row = true;
535
536 fe_raw_ptr->getDataFieldEntsPtr()->reserve(
537 last_data_field_ents_view_size);
538
539 if (row_as_data) {
540 fe_raw_ptr->getRowFieldEntsPtr() = fe_raw_ptr->getDataFieldEntsPtr();
541 } else {
542 // row and col are different
543 if (fe_raw_ptr->getRowFieldEntsPtr() ==
544 fe_raw_ptr->getDataFieldEntsPtr())
545 fe_raw_ptr->getRowFieldEntsPtr() =
546 boost::make_shared<FieldEntity_vector_view>();
547 fe_raw_ptr->getRowFieldEntsPtr()->reserve(
548 last_row_field_ents_view_size);
549 }
550
551 if (row_as_data && col_as_row) {
552 fe_raw_ptr->getColFieldEntsPtr() = fe_raw_ptr->getDataFieldEntsPtr();
553 } else if (col_as_row) {
554 fe_raw_ptr->getColFieldEntsPtr() = fe_raw_ptr->getRowFieldEntsPtr();
555 } else {
556 if (
557
558 fe_raw_ptr->getColFieldEntsPtr() ==
559 fe_raw_ptr->getRowFieldEntsPtr() ||
560 fe_raw_ptr->getColFieldEntsPtr() ==
561 fe_raw_ptr->getDataFieldEntsPtr()
562
563 )
564 fe_raw_ptr->getColFieldEntsPtr() =
565 boost::make_shared<FieldEntity_vector_view>();
566 fe_raw_ptr->getColFieldEntsPtr()->reserve(
567 last_col_field_ents_view_size);
568 }
569
570 // Iterate over all field and check which one is on the element
571 for (unsigned int ii = 0; ii != BitFieldId().size(); ++ii) {
572
573 // Common field id for ROW, COL and DATA
574 BitFieldId id_common = 0;
575 // Check if the field (ii) is added to finite element
576 for (int ss = 0; ss < LAST; ss++) {
577 id_common |= fe_fields[ss] & BitFieldId().set(ii);
578 }
579 if (id_common.none())
580 continue;
581
582 // Find in database data associated with the field (ii)
583 const BitFieldId field_id = BitFieldId().set(ii);
584 auto miit = fields_by_id.find(field_id);
585 if (miit == fields_by_id.end())
586 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "Field not found");
587 auto field_bit_number = (*miit)->getBitNumber();
588
589 // Loop over adjacencies of element and find field entities on those
590 // adjacencies, that create hash map map_uid_fe which is used later
591 const std::string field_name = miit->get()->getName();
592 const bool add_to_data = (field_id & fe_fields[DATA]).any();
593 const bool add_to_row = (field_id & fe_fields[ROW]).any();
594 const bool add_to_col = (field_id & fe_fields[COL]).any();
595
596 // Resolve entities on element, those entities are used to build tag
597 // with dof uids on finite element tag
598 adj_ents.clear();
599 CHKERR fe_raw_ptr->getElementAdjacency(*miit, adj_ents);
600
601 for (auto ent : adj_ents) {
602
603 auto dof_it = entsFields.get<Unique_mi_tag>().find(
604 FieldEntity::getLocalUniqueIdCalculate(field_bit_number, ent));
605 if (dof_it != entsFields.get<Unique_mi_tag>().end()) {
606
607 if (add_to_data) {
608 fe_raw_ptr->getDataFieldEntsPtr()->emplace_back(*dof_it);
609 }
610 if (add_to_row && !row_as_data) {
611 fe_raw_ptr->getRowFieldEntsPtr()->emplace_back(*dof_it);
612 }
613 if (add_to_col && !col_as_row) {
614 fe_raw_ptr->getColFieldEntsPtr()->emplace_back(*dof_it);
615 }
616
617 }
618 }
619 }
620
621 // Sort field ents by uid
622 auto uid_comp = [](const auto &a, const auto &b) {
623 return a.lock()->getLocalUniqueId() < b.lock()->getLocalUniqueId();
624 };
625
626 // Sort all views
627
628 // Data
629 sort(fe_raw_ptr->getDataFieldEntsPtr()->begin(),
630 fe_raw_ptr->getDataFieldEntsPtr()->end(), uid_comp);
631 last_data_field_ents_view_size =
632 fe_raw_ptr->getDataFieldEntsPtr()->size();
633
634 // Row
635 if (!row_as_data) {
636 sort(fe_raw_ptr->getRowFieldEntsPtr()->begin(),
637 fe_raw_ptr->getRowFieldEntsPtr()->end(), uid_comp);
638 last_row_field_ents_view_size =
639 fe_raw_ptr->getRowFieldEntsPtr()->size();
640 }
641
642 // Column
643 if (!col_as_row) {
644 sort(fe_raw_ptr->getColFieldEntsPtr()->begin(),
645 fe_raw_ptr->getColFieldEntsPtr()->end(), uid_comp);
646 last_col_field_ents_view_size =
647 fe_raw_ptr->getColFieldEntsPtr()->size();
648 }
649 }
650 }
651
653}
654
655MoFEMErrorCode Core::build_finite_elements(int verb) {
657
658 if (verb == DEFAULT_VERBOSITY)
659 verb = verbose;
660
661 // loop Finite Elements
662 for (auto &fe : finiteElements)
663 CHKERR buildFiniteElements(fe, NULL, verb);
664
665 if (verb > QUIET) {
666
667 auto &fe_ents = entsFiniteElements.get<Unique_mi_tag>();
668 for (auto &fe : finiteElements) {
669 auto miit = fe_ents.lower_bound(
670 EntFiniteElement::getLocalUniqueIdCalculate(0, fe->getFEUId()));
671 auto hi_miit =
672 fe_ents.upper_bound(EntFiniteElement::getLocalUniqueIdCalculate(
673 get_id_for_max_type<MBENTITYSET>(), fe->getFEUId()));
674 const auto count = std::distance(miit, hi_miit);
675 MOFEM_LOG("SYNC", Sev::inform)
676 << "Finite element " << fe->getName()
677 << " added. Nb. of elements added " << count;
678 MOFEM_LOG("SYNC", Sev::noisy) << *fe;
679
680 auto slg = MoFEM::LogManager::getLog("SYNC");
681 for (auto &field : fIelds) {
682 auto rec = slg.open_record(keywords::severity = Sev::verbose);
683 if (rec) {
684 logging::record_ostream strm(rec);
685 strm << "Field " << field->getName() << " on finite element: ";
686 if ((field->getId() & fe->getBitFieldIdRow()).any())
687 strm << "row ";
688 if ((field->getId() & fe->getBitFieldIdCol()).any())
689 strm << "columns ";
690 if ((field->getId() & fe->getBitFieldIdData()).any())
691 strm << "data";
692 strm.flush();
693 slg.push_record(boost::move(rec));
694 }
695 }
696 }
697
698 MOFEM_LOG_SYNCHRONISE(mofemComm);
699 }
700
701 *buildMoFEM |= 1 << 1;
703}
704
705MoFEMErrorCode Core::build_finite_elements(const BitRefLevel &bit, int verb) {
707 SETERRQ(mofemComm, MOFEM_NOT_IMPLEMENTED, "Not yet implemented");
709}
710
711MoFEMErrorCode Core::build_finite_elements(const string fe_name,
712 const Range *const ents_ptr,
713 int verb) {
715 if (verb == -1)
716 verb = verbose;
717
718 auto fe_miit = finiteElements.get<FiniteElement_name_mi_tag>().find(fe_name);
719 if (fe_miit == finiteElements.get<FiniteElement_name_mi_tag>().end())
720 SETERRQ(mofemComm, MOFEM_NOT_FOUND, "Finite element <%s> not found",
721 fe_name.c_str());
722
723 CHKERR buildFiniteElements(*fe_miit, ents_ptr, verb);
724
725 if (verb >= VERBOSE) {
726 auto &fe_ents = entsFiniteElements.get<Unique_mi_tag>();
727 auto miit = fe_ents.lower_bound(
728 EntFiniteElement::getLocalUniqueIdCalculate(0, (*fe_miit)->getFEUId()));
729 auto hi_miit =
730 fe_ents.upper_bound(EntFiniteElement::getLocalUniqueIdCalculate(
731 get_id_for_max_type<MBENTITYSET>(), (*fe_miit)->getFEUId()));
732 const auto count = std::distance(miit, hi_miit);
733 MOFEM_LOG("SYNC", Sev::inform) << "Finite element " << fe_name
734 << " added. Nb. of elements added " << count;
735 MOFEM_LOG_SYNCHRONISE(mofemComm);
736 }
737
738 *buildMoFEM |= 1 << 1;
740}
741
742MoFEMErrorCode Core::build_adjacencies(const Range &ents, int verb) {
744 if (verb == DEFAULT_VERBOSITY)
745 verb = verbose;
746
747 if (!((*buildMoFEM) & BUILD_FIELD))
748 SETERRQ(mofemComm, MOFEM_NOT_FOUND, "field not build");
749 if (!((*buildMoFEM) & BUILD_FE))
750 SETERRQ(mofemComm, MOFEM_NOT_FOUND, "fe not build");
751 for (auto peit = ents.pair_begin(); peit != ents.pair_end(); ++peit) {
752 auto fit = entsFiniteElements.get<Ent_mi_tag>().lower_bound(peit->first);
753 auto hi_fit =
754 entsFiniteElements.get<Ent_mi_tag>().upper_bound(peit->second);
755 for (; fit != hi_fit; ++fit) {
756 if ((*fit)->getBitFieldIdRow().none() &&
757 (*fit)->getBitFieldIdCol().none() &&
758 (*fit)->getBitFieldIdData().none())
759 continue;
760 int by = BYROW;
761 if ((*fit)->getBitFieldIdRow() != (*fit)->getBitFieldIdCol())
762 by |= BYCOL;
763 if ((*fit)->getBitFieldIdRow() != (*fit)->getBitFieldIdData())
764 by |= BYDATA;
765 FieldEntityEntFiniteElementAdjacencyMap_change_ByWhat modify_row(by);
766 auto hint = entFEAdjacencies.end();
767 for (auto e : *(*fit)->getRowFieldEntsPtr()) {
768 hint = entFEAdjacencies.emplace_hint(hint, e.lock(), *fit);
769 bool success = entFEAdjacencies.modify(hint, modify_row);
770 if (!success)
771 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
772 "modification unsuccessful");
773 }
774 if ((*fit)->getBitFieldIdRow() != (*fit)->getBitFieldIdCol()) {
775 int by = BYCOL;
776 if ((*fit)->getBitFieldIdCol() != (*fit)->getBitFieldIdData())
777 by |= BYDATA;
778 FieldEntityEntFiniteElementAdjacencyMap_change_ByWhat modify_col(by);
779 auto hint = entFEAdjacencies.end();
780 for (auto e : *(*fit)->getColFieldEntsPtr()) {
781 hint = entFEAdjacencies.emplace_hint(hint, e.lock(), *fit);
782 bool success = entFEAdjacencies.modify(hint, modify_col);
783 if (!success)
784 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
785 "modification unsuccessful");
786 }
787 }
788 if ((*fit)->getBitFieldIdRow() != (*fit)->getBitFieldIdData() ||
789 (*fit)->getBitFieldIdCol() != (*fit)->getBitFieldIdData()) {
790 FieldEntityEntFiniteElementAdjacencyMap_change_ByWhat modify_data(
791 BYDATA);
792 auto hint = entFEAdjacencies.end();
793 for (auto &e : (*fit)->getDataFieldEnts()) {
794 hint = entFEAdjacencies.emplace_hint(hint, e.lock(), *fit);
795 bool success = entFEAdjacencies.modify(hint, modify_data);
796 if (!success)
797 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
798 "modification unsuccessful");
799 }
800 }
801 }
802 }
803
804 if (verb >= VERBOSE) {
805 MOFEM_LOG("WORLD", Sev::inform)
806 << "Number of adjacencies " << entFEAdjacencies.size();
807 MOFEM_LOG_SYNCHRONISE(mofemComm)
808 }
809
810 *buildMoFEM |= 1 << 2;
812}
813
814MoFEMErrorCode Core::build_adjacencies(const BitRefLevel &bit,
815 const BitRefLevel &mask, int verb) {
817 if (verb == -1)
818 verb = verbose;
819 Range ents;
820 CHKERR BitRefManager(*this).getEntitiesByRefLevel(bit, mask, ents);
821
822 CHKERR build_adjacencies(ents, verb);
823
825}
826MoFEMErrorCode Core::build_adjacencies(const BitRefLevel &bit, int verb) {
828 if (verb == -1)
829 verb = verbose;
830 CHKERR build_adjacencies(bit, BitRefLevel().set(), verb);
831
833}
834
835EntFiniteElement_multiIndex::index<Unique_mi_tag>::type::iterator
836Core::get_fe_by_name_begin(const std::string &fe_name) const {
837 auto miit = finiteElements.get<FiniteElement_name_mi_tag>().find(fe_name);
838 if (miit != finiteElements.get<FiniteElement_name_mi_tag>().end()) {
839 return entsFiniteElements.get<Unique_mi_tag>().lower_bound(
840 EntFiniteElement::getLocalUniqueIdCalculate(0, (*miit)->getFEUId()));
841 } else {
842 return entsFiniteElements.get<Unique_mi_tag>().end();
843 }
844}
845
846EntFiniteElement_multiIndex::index<Unique_mi_tag>::type::iterator
847Core::get_fe_by_name_end(const std::string &fe_name) const {
848 auto miit = finiteElements.get<FiniteElement_name_mi_tag>().find(fe_name);
849 if (miit != finiteElements.get<FiniteElement_name_mi_tag>().end()) {
850 return entsFiniteElements.get<Unique_mi_tag>().upper_bound(
851 EntFiniteElement::getLocalUniqueIdCalculate(
852 get_id_for_max_type<MBENTITYSET>(), (*miit)->getFEUId()));
853 } else {
854 return entsFiniteElements.get<Unique_mi_tag>().end();
855 }
856}
857
858MoFEMErrorCode Core::check_number_of_ents_in_ents_finite_element(
859 const std::string &name) const {
861 FiniteElement_multiIndex::index<FiniteElement_name_mi_tag>::type::iterator it;
862 it = finiteElements.get<FiniteElement_name_mi_tag>().find(name);
863 if (it == finiteElements.get<FiniteElement_name_mi_tag>().end()) {
864 SETERRQ(mofemComm, 1, "finite element not found < %s >", name.c_str());
865 }
866 EntityHandle meshset = (*it)->getMeshset();
867
868 int num_entities;
869 CHKERR get_moab().get_number_entities_by_handle(meshset, num_entities);
870
871 auto counts_fes = [&]() {
872 return std::distance(get_fe_by_name_begin((*it)->getName()),
873 get_fe_by_name_end((*it)->getName()));
874 };
875
876 if (counts_fes() != static_cast<size_t>(num_entities)) {
877 SETERRQ(mofemComm, MOFEM_DATA_INCONSISTENCY,
878 "not equal number of entities in meshset and finite elements "
879 "multiindex < %s >",
880 (*it)->getName().c_str());
881 }
883}
884
885MoFEMErrorCode Core::check_number_of_ents_in_ents_finite_element() const {
887 FiniteElement_multiIndex::index<FiniteElement_name_mi_tag>::type::iterator it;
888 it = finiteElements.get<FiniteElement_name_mi_tag>().begin();
889 for (; it != finiteElements.get<FiniteElement_name_mi_tag>().end(); it++) {
890 EntityHandle meshset = (*it)->getMeshset();
891
892 int num_entities;
893 CHKERR get_moab().get_number_entities_by_handle(meshset, num_entities);
894
895 auto counts_fes = [&]() {
896 return std::distance(get_fe_by_name_begin((*it)->getName()),
897 get_fe_by_name_end((*it)->getName()));
898 };
899
900 if (counts_fes() != static_cast<size_t>(num_entities)) {
901 SETERRQ(mofemComm, MOFEM_DATA_INCONSISTENCY,
902 "not equal number of entities in meshset and finite elements "
903 "multiindex < %s >",
904 (*it)->getName().c_str());
905 }
906 }
908}
909
911Core::get_problem_finite_elements_entities(const std::string problem_name,
912 const std::string &fe_name,
913 const EntityHandle meshset) {
915 auto &prb = pRoblems.get<Problem_mi_tag>();
916 auto p_miit = prb.find(problem_name);
917 if (p_miit == prb.end())
918 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
919 "No such problem like < %s >", problem_name.c_str());
920
921 auto fe_miit = finiteElements.get<FiniteElement_name_mi_tag>().find(fe_name);
922 if (fe_miit != finiteElements.get<FiniteElement_name_mi_tag>().end()) {
923 auto miit =
924 p_miit->numeredFiniteElementsPtr->get<Unique_mi_tag>().lower_bound(
925 EntFiniteElement::getLocalUniqueIdCalculate(
926 0, (*fe_miit)->getFEUId()));
927 auto hi_miit =
928 p_miit->numeredFiniteElementsPtr->get<Unique_mi_tag>().upper_bound(
929 EntFiniteElement::getLocalUniqueIdCalculate(
930 get_id_for_max_type<MBENTITYSET>(), (*fe_miit)->getFEUId()));
931
932 if (miit != hi_miit) {
933 std::vector<EntityHandle> ents;
934 ents.reserve(std::distance(miit, hi_miit));
935 for (; miit != hi_miit; ++miit)
936 ents.push_back((*miit)->getEnt());
937 int part = (*miit)->getPart();
938 CHKERR get_moab().tag_clear_data(th_Part, &*ents.begin(), ents.size(),
939 &part);
940 CHKERR get_moab().add_entities(meshset, &*ents.begin(), ents.size());
941 }
942 }
943
945}
946
947} // namespace MoFEM
#define FECoreFunctionBegin
Definition FECore.cpp:7
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
constexpr double a
@ QUIET
@ DEFAULT_VERBOSITY
@ VERBOSE
@ COL
@ DATA
@ ROW
MoFEMTypes
Those types control how functions respond on arguments, f.e. error handling.
@ MF_EXIST
@ MF_EXCL
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ MOFEM_NOT_FOUND
Definition definitions.h:33
@ MOFEM_OPERATION_UNSUCCESSFUL
Definition definitions.h:34
@ 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()
@ BYCOL
@ BYDATA
@ BYROW
#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.
#define MOFEM_LOG(channel, severity)
Log.
static LoggerType & getLog(const std::string channel)
Get logger by channel.
auto bit
set bit
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
std::bitset< BITFEID_SIZE > BitFEId
Finite element Id.
Definition Types.hpp:43
std::bitset< BITFIELDID_SIZE > BitFieldId
Field Id.
Definition Types.hpp:42
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
Definition Types.hpp:40
EntityHandle get_id_for_max_type()
EntityHandle get_id_for_min_type()
MoFEM::LogManager::SeverityLevel Sev
const EntityHandle no_handle
No entity handle is indicated by zero handle, i.e. root meshset.
Definition Common.hpp:12
constexpr auto field_name