7 #define FECoreFunctionBegin \
9 MOFEM_LOG_CHANNEL("WORLD"); \
10 MOFEM_LOG_CHANNEL("SYNC"); \
11 MOFEM_LOG_FUNCTION(); \
12 MOFEM_LOG_TAG("WORLD", "FECore"); \
13 MOFEM_LOG_TAG("SYNC", "FECore");
25 std::string(
"finite element < " + name +
26 " > not in database (top tip: check spelling)")
46 *buildMoFEM &= 1 << 0;
54 auto add_meshset_to_partition = [&](
auto meshset) {
56 const void *tag_vals[] = {&rAnk};
57 ParallelComm *pcomm = ParallelComm::get_pcomm(
58 &get_moab(), get_basic_entity_data_ptr()->pcommID);
59 Tag part_tag = pcomm->part_tag();
61 CHKERR get_moab().get_entities_by_type_and_tag(0, MBENTITYSET, &part_tag,
62 tag_vals, 1, tagged_sets,
63 moab::Interface::UNION);
64 for (
auto s : tagged_sets)
65 CHKERR get_moab().add_entities(s, &meshset, 1);
69 auto &finite_element_name_set =
71 auto it_fe = finite_element_name_set.find(fe_name);
74 if (it_fe != finite_element_name_set.end()) {
80 if (it_fe != finite_element_name_set.end())
84 CHKERR get_moab().create_meshset(MESHSET_SET, meshset);
85 CHKERR add_meshset_to_partition(meshset);
94 auto id =
BitFEId().set(fe_shift);
95 CHKERR get_moab().tag_set_data(th_FEId, &meshset, 1, &
id);
98 void const *tag_data[] = {fe_name.c_str()};
100 tag_sizes[0] = fe_name.size();
101 CHKERR get_moab().tag_set_by_ptr(th_FEName, &meshset, 1, tag_data, tag_sizes);
104 auto p = finiteElements.insert(
105 boost::shared_ptr<FiniteElement>(
new FiniteElement(moab, meshset)));
108 "FiniteElement not inserted");
111 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Add finite element " << fe_name;
118 const EntityType
type,
121 *buildMoFEM &= 1 << 0;
123 FiniteElements_by_name;
124 FiniteElements_by_name &finite_element_name_set =
126 FiniteElements_by_name::iterator it_fe =
127 finite_element_name_set.find(fe_name);
128 if (it_fe == finite_element_name_set.end())
130 "This finite element is not defined (advise: check spelling)");
131 boost::shared_ptr<FiniteElement> fe;
133 fe->elementAdjacencyTable[
type] =
function;
139 const std::string name_data) {
141 *buildMoFEM &= 1 << 0;
143 FiniteElements_by_name;
144 FiniteElements_by_name &finite_element_name_set =
146 FiniteElements_by_name::iterator it_fe =
147 finite_element_name_set.find(fe_name);
148 if (it_fe == finite_element_name_set.end())
150 "This finite element is not defined (advise: check spelling)");
151 bool success = finite_element_name_set.modify(
155 "modification unsuccessful");
161 const std::string name_row) {
163 *buildMoFEM &= 1 << 0;
165 FiniteElements_by_name;
166 FiniteElements_by_name &finite_element_name_set =
168 FiniteElements_by_name::iterator it_fe =
169 finite_element_name_set.find(fe_name);
170 if (it_fe == finite_element_name_set.end())
173 bool success = finite_element_name_set.modify(
177 "modification unsuccessful");
183 const std::string name_col) {
185 *buildMoFEM &= 1 << 0;
186 auto &finite_element_name_set =
188 auto it_fe = finite_element_name_set.find(fe_name);
189 if (it_fe == finite_element_name_set.end())
191 "this FiniteElement is there");
192 bool success = finite_element_name_set.modify(
196 "modification unsuccessful");
202 const std::string name_data) {
204 *buildMoFEM &= 1 << 0;
205 auto &finite_element_name_set =
207 auto it_fe = finite_element_name_set.find(fe_name);
208 if (it_fe == finite_element_name_set.end())
210 bool success = finite_element_name_set.modify(
214 "modification unsuccessful");
220 const std::string name_row) {
222 *buildMoFEM &= 1 << 0;
223 auto &finite_element_name_set =
225 auto it_fe = finite_element_name_set.find(fe_name);
226 if (it_fe == finite_element_name_set.end())
229 bool success = finite_element_name_set.modify(
233 "modification unsuccessful");
239 const std::string name_col) {
241 *buildMoFEM &= 1 << 0;
242 auto &finite_element_name_set =
244 auto it_fe = finite_element_name_set.find(fe_name);
245 if (it_fe == finite_element_name_set.end())
247 bool success = finite_element_name_set.modify(
251 "modification unsuccessful");
257 auto miit = fe_by_id.find(fe_name);
258 if (miit == fe_by_id.end())
260 (
"finite element < " + fe_name +
" > not found (top tip: check spelling)")
262 return (*miit)->getId();
267 auto miit = fe_by_id.find(
id);
268 if (miit == fe_by_id.end())
270 return (*miit)->getName();
275 auto miit = fe_by_id.find(
id);
276 if (miit == fe_by_id.end())
278 return (*miit)->meshset;
282 return get_finite_element_meshset(getBitFEId(name));
291 EntityHandle meshset = get_finite_element_meshset(name);
292 CHKERR get_moab().get_entities_by_dimension(meshset, dim, ents,
true);
302 EntityHandle meshset = get_finite_element_meshset(name);
303 CHKERR get_moab().get_entities_by_type(meshset,
type, ents,
true);
314 EntityHandle meshset = get_finite_element_meshset(name);
315 CHKERR get_moab().get_entities_by_handle(meshset, ents,
true);
331 const bool recursive) {
332 *buildMoFEM &= 1 << 0;
336 idm = get_finite_element_meshset(getBitFEId(name));
338 CHKERR get_moab().get_entities_by_type(meshset,
type, ents, recursive);
339 CHKERR getInterface<BitRefManager>()->setElementsBitRefLevel(ents);
340 CHKERR get_moab().add_entities(idm, ents);
347 const int dim,
const std::string &name,
348 const bool recursive) {
350 *buildMoFEM &= 1 << 0;
352 idm = get_finite_element_meshset(getBitFEId(name));
354 CHKERR get_moab().get_entities_by_dimension(meshset, dim, ents, recursive);
355 CHKERR getInterface<BitRefManager>()->setElementsBitRefLevel(ents);
356 CHKERR get_moab().add_entities(idm, ents);
361 const Range &ents,
const EntityType
type,
const std::string &name) {
363 *buildMoFEM &= 1 << 0;
365 idm = get_finite_element_meshset(getBitFEId(name));
366 CHKERR getInterface<BitRefManager>()->setElementsBitRefLevel(
367 ents.subset_by_type(
type));
368 CHKERR get_moab().add_entities(idm, ents.subset_by_type(
type));
374 const std::string &name) {
376 *buildMoFEM &= 1 << 0;
378 idm = get_finite_element_meshset(getBitFEId(name));
379 CHKERR getInterface<BitRefManager>()->setElementsBitRefLevel(
380 ents.subset_by_dimension(dim));
381 CHKERR get_moab().add_entities(idm, ents.subset_by_dimension(dim));
387 const std::string &name,
388 EntityType
type,
int verb) {
398 EntityType
type,
int verb) {
400 CHKERR add_ents_to_finite_element_by_bit_ref(
bit, mask, name,
type, verb);
407 EntityType
type,
int verb) {
412 *buildMoFEM &= 1 << 0;
413 const BitFEId id = getBitFEId(name);
414 const EntityHandle idm = get_finite_element_meshset(
id);
416 auto &ref_MoFEMFiniteElement = refinedFiniteElements.get<
Ent_mi_tag>();
421 for (; miit != hi_miit; miit++) {
422 const auto &bit2 = miit->get()->getBitRefLevel();
423 if ((bit2 & mask) != bit2)
425 if ((bit2 &
bit).any()) {
427 CHKERR get_moab().add_entities(idm, &ent, 1);
433 <<
"Finite element " << name <<
" added. Nb. of elements added "
434 << nb_add_fes <<
" out of " << std::distance(miit, hi_miit);
442 const EntityHandle meshset,
const std::string &name,
const bool recursive) {
444 *buildMoFEM &= 1 << 0;
445 const BitFEId id = getBitFEId(name);
446 const EntityHandle idm = get_finite_element_meshset(
id);
447 if (recursive ==
false) {
448 CHKERR get_moab().add_entities(idm, &meshset, 1);
451 CHKERR get_moab().get_entities_by_type(meshset, MBENTITYSET, meshsets,
453 CHKERR get_moab().add_entities(idm, meshsets);
460 const Range *ents_ptr,
int verb) {
467 <<
"Build Finite Elements " << fe->getName();
473 std::array<BitFieldId, LAST> fe_fields = {fe.get()->getBitFieldIdRow(),
474 fe.get()->getBitFieldIdCol(),
475 fe.get()->getBitFieldIdData()};
478 EntityHandle meshset = get_finite_element_meshset(fe.get()->getId());
482 CHKERR get_moab().get_entities_by_handle(meshset, fe_ents,
false);
485 fe_ents = intersect(fe_ents, *ents_ptr);
488 typedef std::vector<boost::weak_ptr<EntFiniteElement>> VecOfWeakFEPtrs;
489 VecOfWeakFEPtrs processed_fes;
490 processed_fes.reserve(fe_ents.size());
492 int last_data_field_ents_view_size = 0;
493 int last_row_field_ents_view_size = 0;
494 int last_col_field_ents_view_size = 0;
497 std::vector<EntityHandle> adj_ents;
500 for (Range::const_pair_iterator peit = fe_ents.const_pair_begin();
501 peit != fe_ents.const_pair_end(); peit++) {
503 const auto first = peit->first;
504 const auto second = peit->second;
510 refinedFiniteElements.get<
Ent_mi_tag>().lower_bound(first);
511 if (ref_fe_miit == refinedFiniteElements.get<
Ent_mi_tag>().end()) {
512 std::ostringstream ss;
513 ss <<
"refinedFiniteElements not in database ent = " << first <<
" type "
517 auto hi_ref_fe_miit =
518 refinedFiniteElements.get<
Ent_mi_tag>().upper_bound(second);
520 EntFiniteElement_multiIndex::iterator hint_p = entsFiniteElements.end();
521 for (; ref_fe_miit != hi_ref_fe_miit; ref_fe_miit++) {
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();
530 bool row_as_data =
false, col_as_row =
false;
531 if (fe_fields[
DATA] == fe_fields[
ROW])
533 if (fe_fields[
ROW] == fe_fields[
COL])
536 fe_raw_ptr->getDataFieldEntsPtr()->reserve(
537 last_data_field_ents_view_size);
540 fe_raw_ptr->getRowFieldEntsPtr() = fe_raw_ptr->getDataFieldEntsPtr();
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);
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();
558 fe_raw_ptr->getColFieldEntsPtr() ==
559 fe_raw_ptr->getRowFieldEntsPtr() ||
560 fe_raw_ptr->getColFieldEntsPtr() ==
561 fe_raw_ptr->getDataFieldEntsPtr()
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);
571 for (
unsigned int ii = 0; ii !=
BitFieldId().size(); ++ii) {
576 for (
int ss = 0; ss <
LAST; ss++) {
577 id_common |= fe_fields[ss] &
BitFieldId().set(ii);
579 if (id_common.none())
584 auto miit = fields_by_id.find(field_id);
585 if (miit == fields_by_id.end())
587 auto field_bit_number = (*miit)->getBitNumber();
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();
599 CHKERR fe_raw_ptr->getElementAdjacency(*miit, adj_ents);
601 for (
auto ent : adj_ents) {
608 fe_raw_ptr->getDataFieldEntsPtr()->emplace_back(*dof_it);
610 if (add_to_row && !row_as_data) {
611 fe_raw_ptr->getRowFieldEntsPtr()->emplace_back(*dof_it);
613 if (add_to_col && !col_as_row) {
614 fe_raw_ptr->getColFieldEntsPtr()->emplace_back(*dof_it);
622 auto uid_comp = [](
const auto &
a,
const auto &b) {
623 return a.lock()->getLocalUniqueId() < b.lock()->getLocalUniqueId();
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();
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();
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();
662 for (
auto &fe : finiteElements)
663 CHKERR buildFiniteElements(fe, NULL, verb);
668 for (
auto &fe : finiteElements) {
669 auto miit = fe_ents.lower_bound(
673 get_id_for_max_type<MBENTITYSET>(), fe->getFEUId()));
674 const auto count = std::distance(miit, hi_miit);
676 <<
"Finite element " << fe->getName()
677 <<
" added. Nb. of elements added " << count;
681 for (
auto &field : fIelds) {
682 auto rec = slg.open_record(keywords::severity = Sev::verbose);
684 logging::record_ostream strm(rec);
685 strm <<
"Field " << field->getName() <<
" on finite element: ";
686 if ((field->getId() & fe->getBitFieldIdRow()).any())
688 if ((field->getId() & fe->getBitFieldIdCol()).any())
690 if ((field->getId() & fe->getBitFieldIdData()).any())
693 slg.push_record(boost::move(rec));
701 *buildMoFEM |= 1 << 1;
712 const Range *
const ents_ptr,
723 CHKERR buildFiniteElements(*fe_miit, ents_ptr, verb);
727 auto miit = fe_ents.lower_bound(
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;
738 *buildMoFEM |= 1 << 1;
747 if (!((*buildMoFEM) & BUILD_FIELD))
749 if (!((*buildMoFEM) & BUILD_FE))
751 for (
auto peit = ents.pair_begin(); peit != ents.pair_end(); ++peit) {
752 auto fit = entsFiniteElements.get<
Ent_mi_tag>().lower_bound(peit->first);
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())
761 if ((*fit)->getBitFieldIdRow() != (*fit)->getBitFieldIdCol())
763 if ((*fit)->getBitFieldIdRow() != (*fit)->getBitFieldIdData())
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);
772 "modification unsuccessful");
774 if ((*fit)->getBitFieldIdRow() != (*fit)->getBitFieldIdCol()) {
776 if ((*fit)->getBitFieldIdCol() != (*fit)->getBitFieldIdData())
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);
785 "modification unsuccessful");
788 if ((*fit)->getBitFieldIdRow() != (*fit)->getBitFieldIdData() ||
789 (*fit)->getBitFieldIdCol() != (*fit)->getBitFieldIdData()) {
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);
798 "modification unsuccessful");
806 <<
"Number of adjacencies " << entFEAdjacencies.size();
810 *buildMoFEM |= 1 << 2;
822 CHKERR build_adjacencies(ents, verb);
835 EntFiniteElement_multiIndex::index<Unique_mi_tag>::type::iterator
846 EntFiniteElement_multiIndex::index<Unique_mi_tag>::type::iterator
852 get_id_for_max_type<MBENTITYSET>(), (*miit)->getFEUId()));
859 const std::string &name)
const {
861 FiniteElement_multiIndex::index<FiniteElement_name_mi_tag>::type::iterator it;
864 SETERRQ1(mofemComm, 1,
"finite element not found < %s >", name.c_str());
869 CHKERR get_moab().get_number_entities_by_handle(meshset, num_entities);
871 auto counts_fes = [&]() {
872 return std::distance(get_fe_by_name_begin((*it)->getName()),
873 get_fe_by_name_end((*it)->getName()));
876 if (counts_fes() !=
static_cast<size_t>(num_entities)) {
878 "not equal number of entities in meshset and finite elements "
880 (*it)->getName().c_str());
887 FiniteElement_multiIndex::index<FiniteElement_name_mi_tag>::type::iterator it;
893 CHKERR get_moab().get_number_entities_by_handle(meshset, num_entities);
895 auto counts_fes = [&]() {
896 return std::distance(get_fe_by_name_begin((*it)->getName()),
897 get_fe_by_name_end((*it)->getName()));
900 if (counts_fes() !=
static_cast<size_t>(num_entities)) {
902 "not equal number of entities in meshset and finite elements "
904 (*it)->getName().c_str());
912 const std::string &fe_name,
916 auto p_miit = prb.find(problem_name);
917 if (p_miit == prb.end())
919 "No such problem like < %s >", problem_name.c_str());
924 p_miit->numeredFiniteElementsPtr->get<
Unique_mi_tag>().lower_bound(
926 0, (*fe_miit)->getFEUId()));
928 p_miit->numeredFiniteElementsPtr->get<
Unique_mi_tag>().upper_bound(
930 get_id_for_max_type<MBENTITYSET>(), (*fe_miit)->getFEUId()));
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(),
940 CHKERR get_moab().add_entities(meshset, &*ents.begin(), ents.size());