14                {
   15 
   16const FiniteElement *
   17Core::get_finite_element_structure(const std::string &name,
   19  auto miit = finiteElements.get<FiniteElement_name_mi_tag>().find(name);
   20  if (miit == finiteElements.get<FiniteElement_name_mi_tag>().end()) {
   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 
   45  *buildMoFEM &= 1 << 0;
   46  if (verb == -1) {
   47    verb = verbose;
   48  }
   49 
   50  
   51  
   52  
   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();
 
   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 
   73    if (it_fe != finite_element_name_set.end()) {
   75               fe_name.c_str());
   76    }
   77 
   78  } else {
   79    if (it_fe != finite_element_name_set.end())
   81  }
   83  CHKERR get_moab().create_meshset(MESHSET_SET, meshset);
 
   84  CHKERR add_meshset_to_partition(meshset);
 
   85 
   86  
   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  
   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  
  103  auto p = finiteElements.insert(
  104      boost::shared_ptr<FiniteElement>(new FiniteElement(moab, meshset)));
  105  if (!p.second)
  107            "FiniteElement not inserted");
  108 
  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())
  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())
  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)
  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())
  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)
  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())
  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)
  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())
  209  bool success = finite_element_name_set.modify(
  210      it_fe, FiniteElement_change_bit_off(get_field_id(name_data)));
  211  if (!success)
  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())
  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)
  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())
  246  bool success = finite_element_name_set.modify(
  247      it_fe, FiniteElement_col_change_bit_off(get_field_id(name_col)));
  248  if (!success)
  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())
  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())
  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,
  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,
  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,
  310 
  312 
  313  EntityHandle meshset = get_finite_element_meshset(name);
 
  314  CHKERR get_moab().get_entities_by_handle(meshset, ents, 
true);
 
  315 
  317}
  318 
  321  for (auto &fe : finiteElements.get<FiniteElement_name_mi_tag>())
  323 
  326}
  327 
  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));
  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));
  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 
  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} 
  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) {
  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 
  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>();
  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()) {
 
  426      CHKERR get_moab().add_entities(idm, &ent, 1);
 
  427      nb_add_fes++;
  428    }
  429  }
  430 
  432      << "Finite element " << name << " added. Nb. of elements added "
  433      << nb_add_fes << " out of " << std::distance(miit, hi_miit);
  434 
  436 
  438}
  439 
  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 {
  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) {
 
  462    verb = verbose;
  463 
  466        << "Build Finite Elements " << fe->getName();
  467 
  468  auto &fields_by_id = fIelds.get<BitFieldId_mi_tag>();
  469 
  470  
  472  std::array<BitFieldId, LAST> fe_fields = {fe.get()->getBitFieldIdRow(),
  473                                            fe.get()->getBitFieldIdCol(),
  474                                            fe.get()->getBitFieldIdData()};
  475 
  476  
  477  EntityHandle meshset = get_finite_element_meshset(fe.get()->getId());
 
  478 
  479  
  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  
  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  
  496  std::vector<EntityHandle> adj_ents;
  497 
  498  
  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    
  506    
  507    
  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";
  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      
  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      
  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        
  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      
  571      for (
unsigned int ii = 0; ii != 
BitFieldId().size(); ++ii) {
 
  572 
  573        
  575        
  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        
  584        auto miit = fields_by_id.find(field_id);
  585        if (miit == fields_by_id.end())
  587        auto field_bit_number = (*miit)->getBitNumber();
  588 
  589        
  590        
  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        
  597        
  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      
  622      auto uid_comp = [](
const auto &
a, 
const auto &b) {
 
  623        return a.lock()->getLocalUniqueId() < b.lock()->getLocalUniqueId();
 
  624      };
  625 
  626      
  627 
  628      
  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      
  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      
  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 
  657 
  659    verb = verbose;
  660 
  661  
  662  for (auto &fe : finiteElements)
  663    CHKERR buildFiniteElements(fe, NULL, verb);
 
  664 
  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);
  676          << "Finite element " << fe->getName()
  677          << " added. Nb. of elements added " << count;
  679 
  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 
  699  }
  700 
  701  *buildMoFEM |= 1 << 1;
  703}
  704 
  709}
  710 
  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())
  721             fe_name.c_str());
  722 
  723  CHKERR buildFiniteElements(*fe_miit, ents_ptr, verb);
 
  724 
  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;
  736  }
  737 
  738  *buildMoFEM |= 1 << 1;
  740}
  741 
  745    verb = verbose;
  746 
  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);
  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;
  761      if ((*fit)->getBitFieldIdRow() != (*fit)->getBitFieldIdCol())
  763      if ((*fit)->getBitFieldIdRow() != (*fit)->getBitFieldIdData())
  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)
  772                  "modification unsuccessful");
  773      }
  774      if ((*fit)->getBitFieldIdRow() != (*fit)->getBitFieldIdCol()) {
  776        if ((*fit)->getBitFieldIdCol() != (*fit)->getBitFieldIdData())
  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)
  785                    "modification unsuccessful");
  786        }
  787      }
  788      if ((*fit)->getBitFieldIdRow() != (*fit)->getBitFieldIdData() ||
  789          (*fit)->getBitFieldIdCol() != (*fit)->getBitFieldIdData()) {
  790        FieldEntityEntFiniteElementAdjacencyMap_change_ByWhat modify_data(
  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)
  798                    "modification unsuccessful");
  799        }
  800      }
  801    }
  802  }
  803 
  806        << "Number of adjacencies " << entFEAdjacencies.size();
  808  }
  809 
  810  *buildMoFEM |= 1 << 2;
  812}
  813 
  815                                       const BitRefLevel &mask, int verb) {
  817  if (verb == -1)
  818    verb = verbose;
  820  CHKERR BitRefManager(*this).getEntitiesByRefLevel(
bit, mask, ents);
 
  821 
  822  CHKERR build_adjacencies(ents, verb);
 
  823 
  825}
  828  if (verb == -1)
  829    verb = verbose;
  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 
  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  }
  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)) {
  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++) {
  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)) {
  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,
  915  auto &prb = pRoblems.get<Problem_mi_tag>();
  916  auto p_miit = prb.find(problem_name);
  917  if (p_miit == prb.end())
  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} 
#define FECoreFunctionBegin
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
MoFEMTypes
Those types control how functions respond on arguments, f.e. error handling.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ MOFEM_OPERATION_UNSUCCESSFUL
@ MOFEM_DATA_INCONSISTENCY
#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.
#define MOFEM_LOG(channel, severity)
Log.
static LoggerType & getLog(const std::string channel)
Get logger by channel.
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
std::bitset< BITFEID_SIZE > BitFEId
Finite element Id.
std::bitset< BITFIELDID_SIZE > BitFieldId
Field Id.
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
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.
constexpr auto field_name