17 : cOre(const_cast<
MoFEM::
Core &>(core)), dEbug(false) {
20 auto core_log = logging::core::get();
36 MOFEM_LOG(
"BitRefWorld", Sev::noisy) <<
"BitRefManager interface created";
60 Range &seed_ents_range)
const {
63 seed_ents_range.insert(
f, s);
77 for (; rit != hi_rit; ++rit)
80 Range::iterator lo, hi = seed_ents_range.begin();
81 for (
auto pt = to_erase.pair_begin(); pt != to_erase.pair_end(); ++pt) {
82 lo = seed_ents_range.lower_bound(hi, seed_ents_range.end(), pt->first);
83 if (lo != seed_ents_range.end()) {
84 hi = seed_ents_range.upper_bound(lo, seed_ents_range.end(),
86 seed_ents_range.erase(lo, hi);
99 std::vector<boost::shared_ptr<RefEntity>> shared_ref_ents_vec;
100 shared_ref_ents_vec.reserve(seed_ents_range.size());
101 std::vector<const void *> tag_by_ptr;
102 for (Range::const_pair_iterator pit = seed_ents_range.pair_begin();
103 pit != seed_ents_range.pair_end(); pit++) {
108 boost::shared_ptr<std::vector<RefEntityTmp<N>>> ref_ents_vec(
110 ref_ents_vec->reserve(s -
f + 1);
112 tag_by_ptr.resize(s -
f + 1);
115 auto tag_parent_it = tag_by_ptr.begin();
117 ref_ents_vec->emplace_back(
126 tag_by_ptr.resize(s -
f + 1);
129 for (
auto &v_bit_ptr : tag_by_ptr)
134 for (
auto &re : *ref_ents_vec)
135 shared_ref_ents_vec.emplace_back(ref_ents_vec,
138 if (!shared_ref_ents_vec.empty()) {
141 ->insert(shared_ref_ents_vec.begin(), shared_ref_ents_vec.end());
142 if ((
refEntsPtr->size() - s0) != shared_ref_ents_vec.size()) {
144 "Data inconsistency %d != %d",
refEntsPtr->size() - s0,
145 shared_ref_ents_vec.size());
158 return addEntsToDatabaseImpl<0>(seed_ents_range);
160 return addEntsToDatabaseImpl<1>(seed_ents_range);
170 Range &seed_fe_range)
const {
172 seed_fe_range.insert(
f, s);
173 RefElement_multiIndex::iterator rit, hi_rit;
182 for (; rit != hi_rit; ++rit) {
183 seed_fe_range.erase(rit->get()->getEnt());
191 std::vector<boost::shared_ptr<RefElement>> shared_ref_fe_vec;
192 shared_ref_fe_vec.reserve(seed_fe_range.size());
194 for (Range::const_pair_iterator pit = seed_fe_range.const_pair_begin();
195 pit != seed_fe_range.const_pair_end(); ++pit) {
196 RefEntity_multiIndex::iterator rit, hi_rit;
198 hi_rit =
refEntsPtr->upper_bound(pit->second);
199 if (
static_cast<int>(std::distance(rit, hi_rit)) !=
200 static_cast<int>(pit->second - pit->first + 1)) {
202 "data inconsistency %d != %d", std::distance(rit, hi_rit),
203 pit->second - pit->first + 1);
205 switch ((*rit)->getEntType()) {
207 boost::shared_ptr<std::vector<RefElement_VERTEX>> ref_fe_vec =
208 boost::make_shared<std::vector<RefElement_VERTEX>>();
209 ref_fe_vec->reserve(pit->second - pit->first + 1);
210 for (; rit != hi_rit; ++rit) {
212 shared_ref_fe_vec.push_back(
213 boost::shared_ptr<RefElement>(ref_fe_vec, &ref_fe_vec->back()));
217 boost::shared_ptr<std::vector<RefElement_EDGE>> ref_fe_vec =
218 boost::make_shared<std::vector<RefElement_EDGE>>();
219 ref_fe_vec->reserve(pit->second - pit->first + 1);
220 for (; rit != hi_rit; ++rit) {
222 shared_ref_fe_vec.push_back(
223 boost::shared_ptr<RefElement>(ref_fe_vec, &ref_fe_vec->back()));
228 boost::shared_ptr<std::vector<RefElementFace>> ref_fe_vec =
229 boost::make_shared<std::vector<RefElementFace>>();
230 ref_fe_vec->reserve(pit->second - pit->first + 1);
231 for (; rit != hi_rit; ++rit) {
233 shared_ref_fe_vec.push_back(
234 boost::shared_ptr<RefElement>(ref_fe_vec, &ref_fe_vec->back()));
239 boost::shared_ptr<std::vector<RefElementVolume>> ref_fe_vec =
240 boost::make_shared<std::vector<RefElementVolume>>();
241 ref_fe_vec->reserve(pit->second - pit->first + 1);
242 for (; rit != hi_rit; ++rit) {
244 shared_ref_fe_vec.push_back(
245 boost::shared_ptr<RefElement>(ref_fe_vec, &ref_fe_vec->back()));
249 boost::shared_ptr<std::vector<RefElement_PRISM>> ref_fe_vec =
250 boost::make_shared<std::vector<RefElement_PRISM>>();
251 ref_fe_vec->reserve(pit->second - pit->first + 1);
252 for (; rit != hi_rit; ++rit) {
254 shared_ref_fe_vec.push_back(
255 boost::shared_ptr<RefElement>(ref_fe_vec, &ref_fe_vec->back()));
259 boost::shared_ptr<std::vector<RefElement_MESHSET>> ref_fe_vec =
260 boost::make_shared<std::vector<RefElement_MESHSET>>();
261 ref_fe_vec->reserve(pit->second - pit->first + 1);
262 for (; rit != hi_rit; ++rit) {
264 shared_ref_fe_vec.push_back(
265 boost::shared_ptr<RefElement>(ref_fe_vec, &ref_fe_vec->back()));
274 ->insert(shared_ref_fe_vec.begin(), shared_ref_fe_vec.end());
281 const bool only_tets,
int verb,
282 Range *adj_ents_ptr)
const {
289 MOFEM_LOG_C(
"BitRefSelf", Sev::noisy,
"Number of entities to add %d",
295 for (
int d = 3;
d >= 1; --
d) {
297 if (only_tets &&
d == 3) {
298 dim_ents = ents.subset_by_type(MBTET);
300 dim_ents = ents.subset_by_dimension(
d);
305 " Number of dim %d entities to add %d",
d, dim_ents.size());
307 if (!dim_ents.empty()) {
308 for (
int dd = 0;
dd <
d; ++
dd) {
312 rval = m_field.
get_moab().get_connectivity(ents, adj_ents,
true);
319 adj_ents = adj_ents_ptr->subset_by_dimension(MBEDGE);
320 }
else if (
dd == 2) {
321 adj_ents = adj_ents_ptr->subset_by_dimension(MBTRI);
325 dim_ents,
dd,
true, adj_ents, moab::Interface::UNION);
334 " Number of dim %d adj entities for dim %d to add %d",
d,
335 dd, adj_ents.size());
337 if (
rval == MB_MULTIPLE_ENTITIES_FOUND) {
338 auto log_message = [&](
const auto sev) {
342 <<
"When get adjacencies moab return MB_MULTIPLE_ENTITIES_ "
344 <<
dd <<
" and dim of entities " <<
d;
349 log_message(Sev::noisy);
351 log_message(Sev::warning);
356 for (Range::pair_iterator pit = adj_ents.pair_begin();
357 pit != adj_ents.pair_end(); ++pit) {
358 Range seed_ents_range;
364 if (!seed_ents_range.empty())
384 for (Range::const_pair_iterator pit = ents.pair_begin();
385 pit != ents.pair_end(); pit++) {
389 Range seed_ents_range;
394 if (!seed_ents_range.empty())
401 if (!seed_fe_range.empty()) {
409 <<
"Number of entities in databse " << ref_ents_ptr->size();
411 <<
"Number of finite element entities in databse " << ref_fe_ptr->size();
424 for (Range::const_pair_iterator pit = ents.pair_begin();
425 pit != ents.pair_end(); pit++) {
429 Range seed_ents_range;
434 if (!seed_ents_range.empty())
447 CHKERR m_field.
get_moab().get_entities_by_handle(field_meshset, field_ents,
481 std::pair<RefEntity_multiIndex::iterator, bool> p_ent =
483 ->insert(boost::shared_ptr<RefEntity>(
485 *(
const_cast<RefEntity *
>(p_ent.first->get())->getBitRefLevelPtr()) |=
bit;
487 boost::shared_ptr<RefElement> fe_ptr =
489 std::pair<RefElement_multiIndex::iterator, bool> p_fe =
494 <<
"Add meshset as ref_ent " << **p_fe.first;
506 CHKERR m_field.
get_moab().get_entities_by_dimension(meshset, dim, ents,
513 const EntityType
type,
528 auto get_ents = [&]() {
531 m_field.
get_moab().get_root_set(), ents,
true);
532 ents = subtract(ents, ents.subset_by_type(MBENTITYSET));
544 std::vector<const BitRefLevel *> ents_bits_vec;
546 auto eit = ents.begin();
547 for (
auto &it : ents_bits_vec) {
569 CHKERR moab.get_entities_by_dimension(meshset, dim, ents,
true);
570 for (
int dd = dim - 1;
dd >= 0;
dd--)
571 CHKERR moab.get_adjacencies(ents,
dd,
false, adj, moab::Interface::UNION);
574 MOFEM_LOG(
"BitRefSelf", Sev::noisy) <<
"Add add bit ref level by dim";
580 const bool b,
int verb)
const {
582 MOFEM_LOG(
"BitRefSelf", Sev::noisy) <<
"Set bit to " << ents;
590 MOFEM_LOG(
"BitRefSelf", Sev::noisy) <<
"Set bit to all entities";
610 for (
int ii = 0; ii < shift; ii++) {
613 if (delete_bits.any()) {
617 for (RefEntity_multiIndex::iterator ent_it = ref_ents_ptr->begin();
618 ent_it != ref_ents_ptr->end(); ent_it++) {
622 << (*ent_it)->getBitRefLevel() <<
" : ";
624 right_shift(
const_cast<boost::shared_ptr<RefEntity> &
>(*ent_it));
627 MOFEM_LOG(
"BitRefSelf", Sev::noisy) << (*ent_it)->getBitRefLevel();
636 const char *file_name,
637 const char *file_type,
639 const bool check_for_empty)
const {
644 CHKERR moab.create_meshset(MESHSET_SET, meshset);
647 CHKERR moab.get_number_entities_by_handle(meshset, nb_ents,
true);
648 if (check_for_empty && !nb_ents) {
650 <<
"No entities to save < " << file_name <<
" > in writeBitLevel";
654 CHKERR moab.write_file(file_name, file_type, options, &meshset, 1);
655 CHKERR moab.delete_entities(&meshset, 1);
661 const int dim,
const char *file_name,
662 const char *file_type,
const char *options,
663 const bool check_for_empty)
const {
669 if (check_for_empty && ents.empty()) {
671 <<
"No entities to save < " << file_name <<
" > in writeBitLevelByDim";
675 CHKERR moab.create_meshset(MESHSET_SET, meshset);
676 CHKERR moab.add_entities(meshset, ents);
677 CHKERR moab.write_file(file_name, file_type, options, &meshset, 1);
678 CHKERR moab.delete_entities(&meshset, 1);
684 const char *file_name,
const char *file_type,
const char *options,
685 const bool check_for_empty)
const {
691 if (check_for_empty && ents.empty()) {
693 <<
"No entities to save < " << file_name <<
" > in writeBitLevelByType";
697 CHKERR moab.create_meshset(MESHSET_SET, meshset);
698 CHKERR moab.add_entities(meshset, ents);
699 CHKERR moab.write_file(file_name, file_type, options, &meshset, 1);
700 CHKERR moab.delete_entities(&meshset, 1);
705 const char *file_name,
const char *file_type,
const char *options,
706 const bool check_for_empty)
const {
713 if (check_for_empty && ents.empty())
715 CHKERR moab.create_meshset(MESHSET_SET, meshset);
716 CHKERR moab.add_entities(meshset, ents);
717 CHKERR moab.write_file(file_name, file_type, options, &meshset, 1);
718 CHKERR moab.delete_entities(&meshset, 1);
724 const char *file_type,
const char *options) {
727 std::string name = boost::lexical_cast<std::string>(ll) +
"_" + file_name;
729 file_type, options,
true);
742 CHKERR moab.add_entities(meshset, ents);
754 std::vector<EntityHandle> ents_vec;
755 ents_vec.reserve(ents.size());
757 std::vector<BitRefLevel *> tags_bits_ptr_vec(ents.size());
760 auto hint = swap_ents.begin();
762 for (Range::pair_iterator p_eit = ents.pair_begin(); p_eit != ents.pair_end();
770 (
const void **)(&*tags_bits_ptr_vec.begin()));
772 if (
rval == MB_SUCCESS) {
774 auto bit_it = tags_bits_ptr_vec.begin();
776 auto check = [&
bit, &mask](
const auto &entity_bit) ->
bool {
779 (entity_bit &
bit).any() &&
781 ((entity_bit & mask) == entity_bit);
786 while (
f != s + 1 && !check(**bit_it)) {
795 while (
f != (s + 1) && check(**bit_it)) {
800 hint = swap_ents.insert(hint, start,
f - 1);
806 ents.swap(swap_ents);
813 Range &ents,
int verb)
const {
817 CHKERR moab.get_entities_by_type(0,
type, ents,
false);
830 CHKERR moab.add_entities(meshset, ents);
840 CHKERR moab.get_entities_by_dimension(0, dim, ents,
false);
848 const int verb)
const {
854 CHKERR moab.add_entities(meshset, ents);
861 const int verb)
const {
866 CHKERR moab.get_entities_by_type(0, MBENTITYSET, meshset_ents,
false);
867 CHKERR moab.get_entities_by_handle(0, ents,
false);
868 ents.merge(meshset_ents);
875 const EntityType
type,
877 const int verb)
const {
884 std::vector<EntityHandle> ents_vec;
885 ents_vec.reserve(std::distance(it, hi_it));
886 for (; it != hi_it; it++) {
887 const BitRefLevel &ent_bit = it->get()->getBitRefLevel();
888 if ((ent_bit & mask) == ent_bit && (ent_bit &
bit).any())
889 ents_vec.emplace_back(it->get()->getEnt());
891 ents.insert_list(ents_vec.begin(), ents_vec.end());
894 <<
"getEntitiesByParentType: " << ents << endl;
902 CHKERR moab.get_entities_by_handle(0, ents,
false);
903 ents = subtract(ents, ents.subset_by_type(MBENTITYSET));
912 auto eit = ents.begin();
913 for (; eit != ents.end();) {
914 auto rit = ref_ents_ptr->get<
Ent_mi_tag>().find(*eit);
915 if (rit != ref_ents_ptr->get<
Ent_mi_tag>().end()) {
916 eit = ents.erase(eit);
926 const int to_dimension,
927 Range &adj_entities)
const {
934 CHKERR moab.get_adjacencies(&from_entity, 1, to_dimension,
false,
936 std::vector<BitRefLevel> bit_levels(adj_entities.size());
938 &*bit_levels.begin());
939 auto b_it = bit_levels.begin();
940 auto eit = adj_entities.begin();
941 for (; eit != adj_entities.end(); b_it++) {
942 if (bit_from_entity != *b_it) {
943 eit = adj_entities.erase(eit);
952 const int to_dimension,
953 Range &adj_entities)
const {
960 CHKERR moab.get_adjacencies(&from_entity, 1, to_dimension,
false,
962 std::vector<BitRefLevel> bit_levels(adj_entities.size());
964 &*bit_levels.begin());
965 std::vector<BitRefLevel>::iterator b_it = bit_levels.begin();
966 Range::iterator eit = adj_entities.begin();
967 for (; eit != adj_entities.end(); b_it++) {
968 if (!(bit_from_entity & (*b_it)).any()) {
969 eit = adj_entities.erase(eit);
979 const int num_entities,
const int to_dimension,
Range &adj_entities,
980 const int operation_type,
const int verb)
const {
984 adj_entities, operation_type);
990 const int num_entities,
const int to_dimension,
Range &adj_entities,
991 const int operation_type,
const int verb)
const {
1001 CHKERR moab.get_adjacencies(from_entities, num_entities, to_dimension,
false,
1002 adj_entities, operation_type);
1003 std::vector<BitRefLevel> bit_levels(adj_entities.size());
1005 &*bit_levels.begin());
1006 std::vector<BitRefLevel>::iterator b_it = bit_levels.begin();
1007 for (Range::iterator eit = adj_entities.begin(); eit != adj_entities.end();
1017 if (!((*b_it) &
bit).any()) {
1018 eit = adj_entities.erase(eit);
1023 if (b_it != bit_levels.end()) {
1033 EntityType child_type,
const bool recursive,
int verb) {
1038 CHKERR moab.get_entities_by_handle(parent, parent_ents, recursive);
1042 MOFEM_LOG(
"BitRefSelf", Sev::noisy) <<
"Parents: " << parent;
1044 Range children_ents;
1046 if (child_type < MBMAXTYPE)
1047 children_ents = children_ents.subset_by_type(child_type);
1050 CHKERR moab.add_entities(child, children_ents);
1056 const EntityHandle child, EntityType child_type,
const bool recursive,
1061 child, child_type, recursive, verb);
1072 for (
auto &fit : (*fields_ptr)) {
1076 CHKERR moab.get_entities_by_handle(meshset, parent_ents,
true);
1080 MOFEM_LOG(
"BitRefSelf", Sev::noisy) <<
"Parnets:" << std::endl
1081 << parent_ents << std::endl;
1084 Range children_ents;
1087 children_ents, verb);
1089 CHKERR moab.add_entities(meshset, children_ents);
1093 MOFEM_LOG(
"BitRefSelf", Sev::noisy) <<
"Children: " << std::endl
1094 << children_ents << std::endl;
1101 const std::string name,
const BitRefLevel &child_bit,
int verb) {
1109 CHKERR moab.get_entities_by_handle(field_meshset, parent_ents,
true);
1113 MOFEM_LOG(
"BitRefSelf", Sev::noisy) <<
"Parnets:" << endl
1114 << parent_ents << std::endl;
1117 Range children_ents;
1122 CHKERR moab.add_entities(field_meshset, children_ents);
1126 MOFEM_LOG(
"BitRefSelf", Sev::noisy) <<
"Children: " << endl
1127 << children_ents << std::endl;
1134 const std::string name,
const BitRefLevel &child_bit,
1135 const EntityType fe_ent_type,
int verb) {
1140 fe_ent_type,
false, verb);
1152 std::vector<EntityHandle> child_ents_vec;
1153 child_ents_vec.reserve(ref_ents.size());
1154 for (Range::const_pair_iterator pit = parent_ents.const_pair_begin();
1155 pit != parent_ents.const_pair_end(); pit++) {
1156 const auto f = pit->first;
1157 auto it = ref_ents.lower_bound(
f);
1158 if (it != ref_ents.end()) {
1159 const auto s = pit->second;
1160 auto hi_it = ref_ents.upper_bound(s);
1162 if (std::distance(it, hi_it) != (s -
f) + 1) {
1165 "Number of entities and entities parents is different %d != %d ",
1166 std::distance(it, hi_it), (s -
f) + 1);
1169 for (; it != hi_it; it++) {
1171 if (it->get()->getEntType() == MBENTITYSET) {
1173 "This should not happen; Entity should not have part of the "
1174 "meshset. It has no children.");
1177 child_ents_vec.emplace_back((*it)->getEnt());
1183 child_ents.insert_list(child_ents_vec.begin(), child_ents_vec.end());
1195 std::vector<EntityHandle> parent_ents_vec;
1196 parent_ents_vec.reserve(ref_ents.size());
1197 for (Range::const_pair_iterator pit = child_ents.const_pair_begin();
1198 pit != child_ents.const_pair_end(); pit++) {
1199 const auto f = pit->first;
1200 auto it = ref_ents.lower_bound(
f);
1201 if (it != ref_ents.end()) {
1202 const auto s = pit->second;
1203 auto hi_it = ref_ents.upper_bound(s);
1205 if (std::distance(it, hi_it) != (s -
f) + 1) {
1208 "Number of entities and entities parents is different %d != %d ",
1209 std::distance(it, hi_it), (s -
f) + 1);
1212 for (; it != hi_it; it++) {
1214 if (it->get()->getEntType() == MBENTITYSET) {
1216 "This should not happen; Entity should not have part of the "
1217 "meshset. It has no children.");
1220 auto parent = (*it)->getParentEnt();
1222 parent_ents_vec.emplace_back(parent);
1228 parent_ents.insert_list(parent_ents_vec.begin(), parent_ents_vec.end());
1239 if (Tag
th = 0; moab.tag_get_handle(
"_RefBitLevel",
th) == MB_SUCCESS) {
1243 auto get_old_tag = [&](
auto &&name) {
1246 "bit ref level handle does not exist");
1250 auto get_new_tag = [&](
auto &&name,
auto &&def_val) {
1254 MB_TAG_CREAT | MB_TAG_BYTES | MB_TAG_SPARSE, &def_val),
1255 "can not create tag");
1260 CHKERR moab.tag_get_length(get_old_tag(
"_RefBitLevel"), length);
1268 <<
"Fixing tag length";
1271 CHKERR moab.get_entities_by_type(0, MBENTITYSET, all_ents,
true);
1272 CHKERR moab.get_entities_by_handle(0, all_ents,
true);
1274 auto process_tag = [&](
auto &&name,
auto &&def_val) {
1276 auto tag_old = get_old_tag(name);
1277 auto get_bits = [&]() {
1278 std::vector<BitRefLevel> bits;
1279 bits.reserve(all_ents.size());
1280 auto it_bit = bits.begin();
1281 for (
auto e : all_ents) {
1284 CHKERR moab.tag_get_by_ptr(tag_old, &e, 1, (
const void **)&data,
1288 std::min(
sizeof(
BitRefLevel),
static_cast<size_t>(data_size)));
1293 auto bits = get_bits();
1294 CHKERR moab.tag_delete(tag_old);
1295 auto tag_new = get_new_tag(name, def_val);
1296 auto it_bit = bits.begin();
1297 for (
auto e : all_ents) {
1298 if (it_bit->any()) {
1299 CHKERR moab.tag_set_data(tag_new, &e, 1, &*it_bit);