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 if (ref_fe_miit == refinedFiniteElements.get<Ent_mi_tag>().end()) {
511 std::ostringstream ss;
512 ss << "refinedFiniteElements not in database ent = " << first << " type "
513 << type_from_handle(first) << " " << *fe;
514 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, ss.str().c_str());
515 }
516 auto hi_ref_fe_miit =
517 refinedFiniteElements.get<Ent_mi_tag>().upper_bound(second);
518
519 EntFiniteElement_multiIndex::iterator hint_p = entsFiniteElements.end();
520 for (; ref_fe_miit != hi_ref_fe_miit; ref_fe_miit++) {
521
522 // Add finite element to database
523 hint_p = entsFiniteElements.emplace_hint(
524 hint_p, boost::make_shared<EntFiniteElement>(*ref_fe_miit, fe));
525 processed_fes.emplace_back(*hint_p);
526 auto fe_raw_ptr = hint_p->get();
527
528 // Allocate space for entities view
529 bool row_as_data = false, col_as_row = false;
530 if (fe_fields[DATA] == fe_fields[ROW])
531 row_as_data = true;
532 if (fe_fields[ROW] == fe_fields[COL])
533 col_as_row = true;
534
535 fe_raw_ptr->getDataFieldEntsPtr()->reserve(
536 last_data_field_ents_view_size);
537
538 if (row_as_data) {
539 fe_raw_ptr->getRowFieldEntsPtr() = fe_raw_ptr->getDataFieldEntsPtr();
540 } else {
541 // row and col are different
542 if (fe_raw_ptr->getRowFieldEntsPtr() ==
543 fe_raw_ptr->getDataFieldEntsPtr())
544 fe_raw_ptr->getRowFieldEntsPtr() =
545 boost::make_shared<FieldEntity_vector_view>();
546 fe_raw_ptr->getRowFieldEntsPtr()->reserve(
547 last_row_field_ents_view_size);
548 }
549
550 if (row_as_data && col_as_row) {
551 fe_raw_ptr->getColFieldEntsPtr() = fe_raw_ptr->getDataFieldEntsPtr();
552 } else if (col_as_row) {
553 fe_raw_ptr->getColFieldEntsPtr() = fe_raw_ptr->getRowFieldEntsPtr();
554 } else {
555 if (
556
557 fe_raw_ptr->getColFieldEntsPtr() ==
558 fe_raw_ptr->getRowFieldEntsPtr() ||
559 fe_raw_ptr->getColFieldEntsPtr() ==
560 fe_raw_ptr->getDataFieldEntsPtr()
561
562 )
563 fe_raw_ptr->getColFieldEntsPtr() =
564 boost::make_shared<FieldEntity_vector_view>();
565 fe_raw_ptr->getColFieldEntsPtr()->reserve(
566 last_col_field_ents_view_size);
567 }
568
569 // Iterate over all field and check which one is on the element
570 for (unsigned int ii = 0; ii != BitFieldId().size(); ++ii) {
571
572 // Common field id for ROW, COL and DATA
573 BitFieldId id_common = 0;
574 // Check if the field (ii) is added to finite element
575 for (int ss = 0; ss < LAST; ss++) {
576 id_common |= fe_fields[ss] & BitFieldId().set(ii);
577 }
578 if (id_common.none())
579 continue;
580
581 // Find in database data associated with the field (ii)
582 const BitFieldId field_id = BitFieldId().set(ii);
583 auto miit = fields_by_id.find(field_id);
584 if (miit == fields_by_id.end())
585 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "Field not found");
586 auto field_bit_number = (*miit)->getBitNumber();
587
588 // Loop over adjacencies of element and find field entities on those
589 // adjacencies, that create hash map map_uid_fe which is used later
590 const std::string field_name = miit->get()->getName();
591 const bool add_to_data = (field_id & fe_fields[DATA]).any();
592 const bool add_to_row = (field_id & fe_fields[ROW]).any();
593 const bool add_to_col = (field_id & fe_fields[COL]).any();
594
595 // Resolve entities on element, those entities are used to build tag
596 // with dof uids on finite element tag
597 adj_ents.clear();
598 CHKERR fe_raw_ptr->getElementAdjacency(*miit, adj_ents);
599
600 for (auto ent : adj_ents) {
601
602 auto dof_it = entsFields.get<Unique_mi_tag>().find(
603 FieldEntity::getLocalUniqueIdCalculate(field_bit_number, ent));
604 if (dof_it != entsFields.get<Unique_mi_tag>().end()) {
605
606 if (add_to_data) {
607 fe_raw_ptr->getDataFieldEntsPtr()->emplace_back(*dof_it);
608 }
609 if (add_to_row && !row_as_data) {
610 fe_raw_ptr->getRowFieldEntsPtr()->emplace_back(*dof_it);
611 }
612 if (add_to_col && !col_as_row) {
613 fe_raw_ptr->getColFieldEntsPtr()->emplace_back(*dof_it);
614 }
615
616 }
617 }
618 }
619
620 // Sort field ents by uid
621 auto uid_comp = [](const auto &a, const auto &b) {
622 return a.lock()->getLocalUniqueId() < b.lock()->getLocalUniqueId();
623 };
624
625 // Sort all views
626
627 // Data
628 sort(fe_raw_ptr->getDataFieldEntsPtr()->begin(),
629 fe_raw_ptr->getDataFieldEntsPtr()->end(), uid_comp);
630 last_data_field_ents_view_size =
631 fe_raw_ptr->getDataFieldEntsPtr()->size();
632
633 // Row
634 if (!row_as_data) {
635 sort(fe_raw_ptr->getRowFieldEntsPtr()->begin(),
636 fe_raw_ptr->getRowFieldEntsPtr()->end(), uid_comp);
637 last_row_field_ents_view_size =
638 fe_raw_ptr->getRowFieldEntsPtr()->size();
639 }
640
641 // Column
642 if (!col_as_row) {
643 sort(fe_raw_ptr->getColFieldEntsPtr()->begin(),
644 fe_raw_ptr->getColFieldEntsPtr()->end(), uid_comp);
645 last_col_field_ents_view_size =
646 fe_raw_ptr->getColFieldEntsPtr()->size();
647 }
648 }
649 }
650
652}
653
654MoFEMErrorCode Core::build_finite_elements(int verb) {
656
657 if (verb == DEFAULT_VERBOSITY)
658 verb = verbose;
659
660 // loop Finite Elements
661 for (auto &fe : finiteElements)
662 CHKERR buildFiniteElements(fe, NULL, verb);
663
664 if (verb > QUIET) {
665
666 auto &fe_ents = entsFiniteElements.get<Unique_mi_tag>();
667 for (auto &fe : finiteElements) {
668 auto miit = fe_ents.lower_bound(
669 EntFiniteElement::getLocalUniqueIdCalculate(0, fe->getFEUId()));
670 auto hi_miit =
671 fe_ents.upper_bound(EntFiniteElement::getLocalUniqueIdCalculate(
672 get_id_for_max_type<MBENTITYSET>(), fe->getFEUId()));
673 const auto count = std::distance(miit, hi_miit);
674 MOFEM_LOG("SYNC", Sev::inform)
675 << "Finite element " << fe->getName()
676 << " added. Nb. of elements added " << count;
677 MOFEM_LOG("SYNC", Sev::noisy) << *fe;
678
679 auto slg = MoFEM::LogManager::getLog("SYNC");
680 for (auto &field : fIelds) {
681 auto rec = slg.open_record(keywords::severity = Sev::verbose);
682 if (rec) {
683 logging::record_ostream strm(rec);
684 strm << "Field " << field->getName() << " on finite element: ";
685 if ((field->getId() & fe->getBitFieldIdRow()).any())
686 strm << "row ";
687 if ((field->getId() & fe->getBitFieldIdCol()).any())
688 strm << "columns ";
689 if ((field->getId() & fe->getBitFieldIdData()).any())
690 strm << "data";
691 strm.flush();
692 slg.push_record(boost::move(rec));
693 }
694 }
695 }
696
697 MOFEM_LOG_SYNCHRONISE(mofemComm);
698 }
699
700 *buildMoFEM |= 1 << 1;
702}
703
704MoFEMErrorCode Core::build_finite_elements(const BitRefLevel &bit, int verb) {
706 SETERRQ(mofemComm, MOFEM_NOT_IMPLEMENTED, "Not yet implemented");
708}
709
710MoFEMErrorCode Core::build_finite_elements(const string fe_name,
711 const Range *const ents_ptr,
712 int verb) {
714 if (verb == -1)
715 verb = verbose;
716
717 auto fe_miit = finiteElements.get<FiniteElement_name_mi_tag>().find(fe_name);
718 if (fe_miit == finiteElements.get<FiniteElement_name_mi_tag>().end())
719 SETERRQ(mofemComm, MOFEM_NOT_FOUND, "Finite element <%s> not found",
720 fe_name.c_str());
721
722 CHKERR buildFiniteElements(*fe_miit, ents_ptr, verb);
723
724 if (verb >= VERBOSE) {
725 auto &fe_ents = entsFiniteElements.get<Unique_mi_tag>();
726 auto miit = fe_ents.lower_bound(
727 EntFiniteElement::getLocalUniqueIdCalculate(0, (*fe_miit)->getFEUId()));
728 auto hi_miit =
729 fe_ents.upper_bound(EntFiniteElement::getLocalUniqueIdCalculate(
730 get_id_for_max_type<MBENTITYSET>(), (*fe_miit)->getFEUId()));
731 const auto count = std::distance(miit, hi_miit);
732 MOFEM_LOG("SYNC", Sev::inform) << "Finite element " << fe_name
733 << " added. Nb. of elements added " << count;
734 MOFEM_LOG_SYNCHRONISE(mofemComm);
735 }
736
737 *buildMoFEM |= 1 << 1;
739}
740
741MoFEMErrorCode Core::build_adjacencies(const Range &ents, int verb) {
743 if (verb == DEFAULT_VERBOSITY)
744 verb = verbose;
745
746 if (!((*buildMoFEM) & BUILD_FIELD))
747 SETERRQ(mofemComm, MOFEM_NOT_FOUND, "field not build");
748 if (!((*buildMoFEM) & BUILD_FE))
749 SETERRQ(mofemComm, MOFEM_NOT_FOUND, "fe not build");
750 for (auto peit = ents.pair_begin(); peit != ents.pair_end(); ++peit) {
751 auto fit = entsFiniteElements.get<Ent_mi_tag>().lower_bound(peit->first);
752 auto hi_fit =
753 entsFiniteElements.get<Ent_mi_tag>().upper_bound(peit->second);
754 for (; fit != hi_fit; ++fit) {
755 if ((*fit)->getBitFieldIdRow().none() &&
756 (*fit)->getBitFieldIdCol().none() &&
757 (*fit)->getBitFieldIdData().none())
758 continue;
759 int by = BYROW;
760 if ((*fit)->getBitFieldIdRow() != (*fit)->getBitFieldIdCol())
761 by |= BYCOL;
762 if ((*fit)->getBitFieldIdRow() != (*fit)->getBitFieldIdData())
763 by |= BYDATA;
764 FieldEntityEntFiniteElementAdjacencyMap_change_ByWhat modify_row(by);
765 auto hint = entFEAdjacencies.end();
766 for (auto e : *(*fit)->getRowFieldEntsPtr()) {
767 hint = entFEAdjacencies.emplace_hint(hint, e.lock(), *fit);
768 bool success = entFEAdjacencies.modify(hint, modify_row);
769 if (!success)
770 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
771 "modification unsuccessful");
772 }
773 if ((*fit)->getBitFieldIdRow() != (*fit)->getBitFieldIdCol()) {
774 int by = BYCOL;
775 if ((*fit)->getBitFieldIdCol() != (*fit)->getBitFieldIdData())
776 by |= BYDATA;
777 FieldEntityEntFiniteElementAdjacencyMap_change_ByWhat modify_col(by);
778 auto hint = entFEAdjacencies.end();
779 for (auto e : *(*fit)->getColFieldEntsPtr()) {
780 hint = entFEAdjacencies.emplace_hint(hint, e.lock(), *fit);
781 bool success = entFEAdjacencies.modify(hint, modify_col);
782 if (!success)
783 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
784 "modification unsuccessful");
785 }
786 }
787 if ((*fit)->getBitFieldIdRow() != (*fit)->getBitFieldIdData() ||
788 (*fit)->getBitFieldIdCol() != (*fit)->getBitFieldIdData()) {
789 FieldEntityEntFiniteElementAdjacencyMap_change_ByWhat modify_data(
790 BYDATA);
791 auto hint = entFEAdjacencies.end();
792 for (auto &e : (*fit)->getDataFieldEnts()) {
793 hint = entFEAdjacencies.emplace_hint(hint, e.lock(), *fit);
794 bool success = entFEAdjacencies.modify(hint, modify_data);
795 if (!success)
796 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
797 "modification unsuccessful");
798 }
799 }
800 }
801 }
802
803 if (verb >= VERBOSE) {
804 MOFEM_LOG("WORLD", Sev::inform)
805 << "Number of adjacencies " << entFEAdjacencies.size();
806 MOFEM_LOG_SYNCHRONISE(mofemComm)
807 }
808
809 *buildMoFEM |= 1 << 2;
811}
812
813MoFEMErrorCode Core::build_adjacencies(const BitRefLevel &bit,
814 const BitRefLevel &mask, int verb) {
816 if (verb == -1)
817 verb = verbose;
818 Range ents;
819 CHKERR BitRefManager(*this).getEntitiesByRefLevel(bit, mask, ents);
820
821 CHKERR build_adjacencies(ents, verb);
822
824}
825MoFEMErrorCode Core::build_adjacencies(const BitRefLevel &bit, int verb) {
827 if (verb == -1)
828 verb = verbose;
829 CHKERR build_adjacencies(bit, BitRefLevel().set(), verb);
830
832}
833
834EntFiniteElement_multiIndex::index<Unique_mi_tag>::type::iterator
835Core::get_fe_by_name_begin(const std::string &fe_name) const {
836 auto miit = finiteElements.get<FiniteElement_name_mi_tag>().find(fe_name);
837 if (miit != finiteElements.get<FiniteElement_name_mi_tag>().end()) {
838 return entsFiniteElements.get<Unique_mi_tag>().lower_bound(
839 EntFiniteElement::getLocalUniqueIdCalculate(0, (*miit)->getFEUId()));
840 } else {
841 return entsFiniteElements.get<Unique_mi_tag>().end();
842 }
843}
844
845EntFiniteElement_multiIndex::index<Unique_mi_tag>::type::iterator
846Core::get_fe_by_name_end(const std::string &fe_name) const {
847 auto miit = finiteElements.get<FiniteElement_name_mi_tag>().find(fe_name);
848 if (miit != finiteElements.get<FiniteElement_name_mi_tag>().end()) {
849 return entsFiniteElements.get<Unique_mi_tag>().upper_bound(
850 EntFiniteElement::getLocalUniqueIdCalculate(
851 get_id_for_max_type<MBENTITYSET>(), (*miit)->getFEUId()));
852 } else {
853 return entsFiniteElements.get<Unique_mi_tag>().end();
854 }
855}
856
857MoFEMErrorCode Core::check_number_of_ents_in_ents_finite_element(
858 const std::string &name) const {
860 FiniteElement_multiIndex::index<FiniteElement_name_mi_tag>::type::iterator it;
861 it = finiteElements.get<FiniteElement_name_mi_tag>().find(name);
862 if (it == finiteElements.get<FiniteElement_name_mi_tag>().end()) {
863 SETERRQ(mofemComm, 1, "finite element not found < %s >", name.c_str());
864 }
865 EntityHandle meshset = (*it)->getMeshset();
866
867 int num_entities;
868 CHKERR get_moab().get_number_entities_by_handle(meshset, num_entities);
869
870 auto counts_fes = [&]() {
871 return std::distance(get_fe_by_name_begin((*it)->getName()),
872 get_fe_by_name_end((*it)->getName()));
873 };
874
875 if (counts_fes() != static_cast<size_t>(num_entities)) {
876 SETERRQ(mofemComm, MOFEM_DATA_INCONSISTENCY,
877 "not equal number of entities in meshset and finite elements "
878 "multiindex < %s >",
879 (*it)->getName().c_str());
880 }
882}
883
884MoFEMErrorCode Core::check_number_of_ents_in_ents_finite_element() const {
886 FiniteElement_multiIndex::index<FiniteElement_name_mi_tag>::type::iterator it;
887 it = finiteElements.get<FiniteElement_name_mi_tag>().begin();
888 for (; it != finiteElements.get<FiniteElement_name_mi_tag>().end(); it++) {
889 EntityHandle meshset = (*it)->getMeshset();
890
891 int num_entities;
892 CHKERR get_moab().get_number_entities_by_handle(meshset, num_entities);
893
894 auto counts_fes = [&]() {
895 return std::distance(get_fe_by_name_begin((*it)->getName()),
896 get_fe_by_name_end((*it)->getName()));
897 };
898
899 if (counts_fes() != static_cast<size_t>(num_entities)) {
900 SETERRQ(mofemComm, MOFEM_DATA_INCONSISTENCY,
901 "not equal number of entities in meshset and finite elements "
902 "multiindex < %s >",
903 (*it)->getName().c_str());
904 }
905 }
907}
908
910Core::get_problem_finite_elements_entities(const std::string problem_name,
911 const std::string &fe_name,
912 const EntityHandle meshset) {
914 auto &prb = pRoblems.get<Problem_mi_tag>();
915 auto p_miit = prb.find(problem_name);
916 if (p_miit == prb.end())
917 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
918 "No such problem like < %s >", problem_name.c_str());
919
920 auto fe_miit = finiteElements.get<FiniteElement_name_mi_tag>().find(fe_name);
921 if (fe_miit != finiteElements.get<FiniteElement_name_mi_tag>().end()) {
922 auto miit =
923 p_miit->numeredFiniteElementsPtr->get<Unique_mi_tag>().lower_bound(
924 EntFiniteElement::getLocalUniqueIdCalculate(
925 0, (*fe_miit)->getFEUId()));
926 auto hi_miit =
927 p_miit->numeredFiniteElementsPtr->get<Unique_mi_tag>().upper_bound(
928 EntFiniteElement::getLocalUniqueIdCalculate(
929 get_id_for_max_type<MBENTITYSET>(), (*fe_miit)->getFEUId()));
930
931 if (miit != hi_miit) {
932 std::vector<EntityHandle> ents;
933 ents.reserve(std::distance(miit, hi_miit));
934 for (; miit != hi_miit; ++miit)
935 ents.push_back((*miit)->getEnt());
936 int part = (*miit)->getPart();
937 CHKERR get_moab().tag_clear_data(th_Part, &*ents.begin(), ents.size(),
938 &part);
939 CHKERR get_moab().add_entities(meshset, &*ents.begin(), ents.size());
940 }
941 }
942
944}
945
946} // 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
auto type_from_handle(const EntityHandle h)
get type from entity handle
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