20 Range &ents, std::map<int, Range> *received_ents,
int verb) {
22 ParallelComm *pcomm = ParallelComm::get_pcomm(
26 auto get_pstatus = [&](
const auto ent) {
27 unsigned char pstatus;
30 "can not get pstatus");
34 auto get_sharing_procs = [&](
const auto ent,
const auto pstatus) {
35 std::vector<int> sharing_procs(MAX_SHARING_PROCS, -1);
36 if (pstatus & PSTATUS_MULTISHARED) {
39 pcomm->sharedps_tag(), &ent, 1, &sharing_procs[0]),
40 "can not ger sharing_procs_ptr");
41 }
else if (pstatus & PSTATUS_SHARED) {
44 1, &sharing_procs[0]),
45 "can not get sharing proc");
50 auto get_sharing_handles = [&](
const auto ent,
const auto pstatus) {
51 std::vector<EntityHandle> sharing_handles(MAX_SHARING_PROCS, 0);
52 if (pstatus & PSTATUS_MULTISHARED) {
55 pcomm->sharedhs_tag(), &ent, 1, &sharing_handles[0]),
56 "get shared handles");
57 }
else if (pstatus & PSTATUS_SHARED) {
60 1, &sharing_handles[0]),
61 "get sharing handle");
63 return sharing_handles;
67 std::vector<std::vector<EntityHandle>> sbuffer(m_field.
get_comm_size());
69 for (
auto ent : ents) {
71 auto pstatus = get_pstatus(ent);
73 auto sharing_procs = get_sharing_procs(ent, pstatus);
74 auto sharing_handles = get_sharing_handles(ent, pstatus);
77 MOFEM_LOG(
"SYNC", Sev::noisy) <<
"pstatus " << std::bitset<8>(pstatus);
80 for (
int proc = 0; proc < MAX_SHARING_PROCS && -1 != sharing_procs[proc];
82 if (sharing_procs[proc] == -1)
84 "sharing processor not set");
89 const auto handle_on_sharing_proc = sharing_handles[proc];
91 sbuffer[sharing_procs[proc]].push_back(handle_on_sharing_proc);
93 MOFEM_LOG_C(
"SYNC", Sev::noisy,
"send %lu (%lu) to %d at %d\n", ent,
94 handle_on_sharing_proc, sharing_procs[proc],
98 if (!(pstatus & PSTATUS_MULTISHARED))
108 std::vector<int> sbuffer_lengths(
110 const size_t block_size =
115 if (!sbuffer[proc].empty()) {
117 sbuffer_lengths[proc] = sbuffer[proc].size() * block_size;
122 sbuffer_lengths[proc] = 0;
134 CHKERR PetscGatherNumberOfMessages(comm, NULL, &sbuffer_lengths[0], &nrecvs);
140 CHKERR PetscGatherMessageLengths(comm, nsends, nrecvs, &sbuffer_lengths[0],
148 CHKERR PetscCommGetNewTag(comm, &tag);
153 MPI_Request *r_waits;
157 CHKERR PetscPostIrecvInt(comm, tag, nrecvs, onodes, olengths, &rbuf,
160 MPI_Request *s_waits;
161 CHKERR PetscMalloc1(nsends, &s_waits);
164 for (
int proc = 0, kk = 0; proc < m_field.
get_comm_size(); proc++) {
165 if (!sbuffer_lengths[proc])
167 CHKERR MPI_Isend(&(sbuffer[proc])[0],
168 sbuffer_lengths[proc],
170 tag, comm, s_waits + kk);
176 CHKERR MPI_Waitall(nrecvs, r_waits, &status[0]);
180 CHKERR MPI_Waitall(nsends, s_waits, &status[0]);
183 MOFEM_LOG_C(
"SYNC", Sev::verbose,
"Rank %d nb. before ents %zu\n",
189 for (
int kk = 0; kk < nrecvs; kk++) {
191 int len = olengths[kk];
192 int *data_from_proc = rbuf[kk];
194 for (
int ee = 0; ee < len;) {
200 (*received_ents)[onodes[kk]].insert(ent);
206 MOFEM_LOG_C(
"SYNC", Sev::noisy,
"received %lu from %d at %d\n", ent,
216 MOFEM_LOG_C(
"SYNC", Sev::verbose,
"Rank %d nb. after ents %zu",
222 CHKERR PetscFree(s_waits);
223 CHKERR PetscFree(rbuf[0]);
225 CHKERR PetscFree(r_waits);
227 CHKERR PetscFree(olengths);
228 CHKERR PetscCommDestroy(&comm);
252 ParallelComm *pcomm = ParallelComm::get_pcomm(
258 CHKERR pcomm->filter_pstatus(shared, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1,
260 CHKERR pcomm->filter_pstatus(shared, PSTATUS_SHARED | PSTATUS_MULTISHARED,
261 PSTATUS_OR, -1,
nullptr);
266 auto get_pstatus = [&](
const auto ent) {
267 unsigned char pstatus;
270 "can not get pstatus");
274 auto get_sharing_procs = [&](
const auto ent,
const auto pstatus) {
275 std::vector<int> sharing_procs(MAX_SHARING_PROCS, -1);
276 if (pstatus & PSTATUS_MULTISHARED) {
279 pcomm->sharedps_tag(), &ent, 1, &sharing_procs[0]),
280 "can not ger sharing_procs_ptr");
281 }
else if (pstatus & PSTATUS_SHARED) {
284 1, &sharing_procs[0]),
285 "can not get sharing proc");
287 return sharing_procs;
290 auto get_sharing_handles = [&](
const auto ent,
const auto pstatus) {
291 std::vector<EntityHandle> sharing_handles(MAX_SHARING_PROCS, 0);
292 if (pstatus & PSTATUS_MULTISHARED) {
295 pcomm->sharedhs_tag(), &ent, 1, &sharing_handles[0]),
296 "get shared handles");
297 }
else if (pstatus & PSTATUS_SHARED) {
300 1, &sharing_handles[0]),
301 "get sharing handle");
303 return sharing_handles;
306 auto get_parent_and_bit = [&](
const auto ent) {
309 m_field.
get_moab().tag_get_data(th_RefParentHandle, &ent, 1, &parent),
313 m_field.
get_moab().tag_get_data(th_RefBitLevel, &ent, 1, &
bit),
315 return std::make_pair(parent,
bit);
318 auto set_parent = [&](
const auto ent,
const auto parent) {
319 return m_field.
get_moab().tag_set_data(th_RefParentHandle, &ent, 1,
323 auto set_bit = [&](
const auto ent,
const auto bit) {
324 return m_field.
get_moab().tag_set_data(th_RefBitLevel, &ent, 1, &
bit);
328 std::vector<std::vector<unsigned long long>> sbuffer(m_field.
get_comm_size());
330 for (
auto ent : shared) {
332 auto pstatus = get_pstatus(ent);
333 auto sharing_procs = get_sharing_procs(ent, pstatus);
334 auto sharing_handles = get_sharing_handles(ent, pstatus);
335 auto [parent,
bit] = get_parent_and_bit(ent);
338 MOFEM_LOG(
"SYNC", Sev::noisy) <<
"pstatus " << std::bitset<8>(pstatus);
341 auto pstatus_parent = get_pstatus(parent);
342 auto sharing_procs_parent = get_sharing_procs(parent, pstatus_parent);
343 auto sharing_handles_parent = get_sharing_handles(parent, pstatus_parent);
345 for (
int proc = 0; proc < MAX_SHARING_PROCS && -1 != sharing_procs[proc];
347 if (sharing_procs[proc] == -1)
349 "sharing processor not set");
353 auto it = std::find(sharing_procs_parent.begin(),
354 sharing_procs_parent.end(), sharing_procs[proc]);
355 if (it == sharing_procs_parent.end()) {
357 "Sharing proc for parent entity can not be found proc = %u",
358 sharing_procs[proc]);
361 auto handle_on_sharing_proc = sharing_handles[proc];
362 auto parent_handle_on_sharing_proc =
363 sharing_handles_parent[std::distance(sharing_procs_parent.begin(),
365 sbuffer[sharing_procs[proc]].push_back(handle_on_sharing_proc);
366 sbuffer[sharing_procs[proc]].push_back(parent_handle_on_sharing_proc);
368 sbuffer[sharing_procs[proc]].push_back(
bit.to_ullong());
369 }
catch (std::exception &ex) {
370 MOFEM_LOG(
"SELF", Sev::warning) << ex.what();
372 <<
"On " << ent <<
" "
374 MOFEM_LOG(
"SELF", Sev::warning) <<
"For bit ref " <<
bit;
377 MOFEM_LOG_C(
"SYNC", Sev::noisy,
"send %lu (%lu) to %d at %d\n", ent,
378 handle_on_sharing_proc, sharing_procs[proc],
381 if (!(pstatus & PSTATUS_MULTISHARED))
386 for (
int proc = 0; proc < MAX_SHARING_PROCS && -1 != sharing_procs[proc];
388 if (sharing_procs[proc] == -1)
390 "sharing processor not set");
393 auto handle_on_sharing_proc = sharing_handles[proc];
394 sbuffer[sharing_procs[proc]].push_back(handle_on_sharing_proc);
395 sbuffer[sharing_procs[proc]].push_back(parent);
398 sbuffer[sharing_procs[proc]].push_back(
bit.to_ullong());
399 }
catch (std::exception &ex) {
400 MOFEM_LOG(
"SELF", Sev::warning) << ex.what();
402 <<
"On " << ent <<
" "
404 MOFEM_LOG(
"SELF", Sev::warning) <<
"For bit ref " <<
bit;
408 MOFEM_LOG_C(
"SYNC", Sev::noisy,
"send %lu (%lu) to %d at %d\n", ent,
409 handle_on_sharing_proc, sharing_procs[proc],
412 if (!(pstatus & PSTATUS_MULTISHARED))
420 std::vector<int> sbuffer_lengths(
423 const size_t block_size =
sizeof(
unsigned long long) /
sizeof(
int);
426 if (!sbuffer[proc].empty()) {
428 sbuffer_lengths[proc] = sbuffer[proc].size() * block_size;
433 sbuffer_lengths[proc] = 0;
445 CHKERR PetscGatherNumberOfMessages(comm, NULL, &sbuffer_lengths[0], &nrecvs);
451 CHKERR PetscGatherMessageLengths(comm, nsends, nrecvs, &sbuffer_lengths[0],
459 CHKERR PetscCommGetNewTag(comm, &tag);
464 MPI_Request *r_waits;
468 CHKERR PetscPostIrecvInt(comm, tag, nrecvs, onodes, olengths, &rbuf,
471 MPI_Request *s_waits;
472 CHKERR PetscMalloc1(nsends, &s_waits);
475 for (
int proc = 0, kk = 0; proc < m_field.
get_comm_size(); proc++) {
476 if (!sbuffer_lengths[proc])
478 CHKERR MPI_Isend(&(sbuffer[proc])[0],
479 sbuffer_lengths[proc],
481 tag, comm, s_waits + kk);
487 CHKERR MPI_Waitall(nrecvs, r_waits, &status[0]);
491 CHKERR MPI_Waitall(nsends, s_waits, &status[0]);
495 "Rank %d nb. shared to synchronise parents ents %zu\n",
500 for (
int kk = 0; kk < nrecvs; kk++) {
502 int len = olengths[kk];
503 int *data_from_proc = rbuf[kk];
505 for (
int ee = 0; ee < len;) {
508 unsigned long long uulong_bit;
511 bcopy(&data_from_proc[ee], &parent,
sizeof(
EntityHandle));
513 bcopy(&data_from_proc[ee], &uulong_bit,
sizeof(
unsigned long long));
516 CHKERR set_parent(ent, parent);
520 MOFEM_LOG_C(
"SYNC", Sev::noisy,
"received %lu (%lu) from %d at %d\n",
528 CHKERR PetscFree(s_waits);
529 CHKERR PetscFree(rbuf[0]);
531 CHKERR PetscFree(r_waits);
533 CHKERR PetscFree(olengths);
534 CHKERR PetscCommDestroy(&comm);
543 const Problem *problem_ptr,
const std::string &fe_name,
int verb) {
546 ParallelComm *pcomm = ParallelComm::get_pcomm(
548 std::vector<int> shprocs(MAX_SHARING_PROCS, 0);
549 std::vector<EntityHandle> shhandles(MAX_SHARING_PROCS, 0);
556 CHKERR PetscLayoutGetRange(layout, &gid, &last_gid);
557 CHKERR PetscLayoutDestroy(&layout);
567 0, (*fe_miit)->getFEUId()));
571 get_id_for_max_type<MBENTITYSET>(), (*fe_miit)->getFEUId()));
572 for (; fit != hi_fe_it; ++fit) {
574 auto ent = (*fit)->getEnt();
575 auto part = (*fit)->getPart();
578 CHKERR m_field.
get_moab().tag_set_data(pcomm->part_tag(), &ent, 1, &part);
579 if (part == pcomm->rank()) {
586 if (pcomm->size() > 1) {
588 unsigned char pstatus = 0;
589 if (pcomm->rank() != part) {
590 pstatus = PSTATUS_NOT_OWNED;
591 pstatus |= PSTATUS_GHOST;
594 if (pcomm->size() > 2) {
595 pstatus |= PSTATUS_SHARED;
596 pstatus |= PSTATUS_MULTISHARED;
598 pstatus |= PSTATUS_SHARED;
602 for (
size_t rr = 0; rr < pcomm->size(); ++rr) {
603 if (rr != pcomm->rank()) {
604 shhandles[rrr] = ent;
609 for (; rrr != pcomm->size(); ++rrr)
612 if (pstatus & PSTATUS_SHARED) {
613 CHKERR m_field.
get_moab().tag_set_data(pcomm->sharedp_tag(), &ent, 1,
615 CHKERR m_field.
get_moab().tag_set_data(pcomm->sharedh_tag(), &ent, 1,
619 if (pstatus & PSTATUS_MULTISHARED) {
620 CHKERR m_field.
get_moab().tag_set_data(pcomm->sharedps_tag(), &ent, 1,
622 CHKERR m_field.
get_moab().tag_set_data(pcomm->sharedhs_tag(), &ent, 1,
625 CHKERR m_field.
get_moab().tag_set_data(pcomm->pstatus_tag(), &ent, 1,
631 CHKERR pcomm->exchange_tags(th_gid, ents);
647 const int num_entities,
648 const int owner_proc,
int verb) {
654 ParallelComm *pcomm = ParallelComm::get_pcomm(
657 Range all_ents_range;
658 all_ents_range.insert_list(entities, entities + num_entities);
660 auto get_tag = [&]() {
661 const int negone = -1;
663 m_field.
get_moab().tag_get_handle(
"TMP_GLOBAL_ID_TAG_NAME", 1,
665 MB_TAG_CREAT | MB_TAG_SPARSE, &negone);
669 auto delete_tag = [&](
auto &&th_gid) {
675 auto resolve_shared_ents = [&](
auto &&th_gid,
auto &all_ents_range) {
676 auto set_gid = [&](
auto &th_gid) {
677 std::vector<int> gids(num_entities);
678 for (
size_t g = 0;
g != all_ents_range.size(); ++
g)
686 auto get_skin_ents = [&](
auto &all_ents_range) {
687 std::array<Range, 4> proc_ents_skin;
688 proc_ents_skin[3] = all_ents_range.subset_by_dimension(3);
689 proc_ents_skin[2] = all_ents_range.subset_by_dimension(2);
690 proc_ents_skin[1] = all_ents_range.subset_by_dimension(1);
691 proc_ents_skin[0] = all_ents_range.subset_by_dimension(0);
692 return proc_ents_skin;
695 auto resolve_dim = [&](
auto &all_ents_range) {
696 for (
int resolve_dim = 3; resolve_dim >= 0; --resolve_dim) {
697 if (all_ents_range.num_of_dimension(resolve_dim))
703 auto get_proc_ent = [&](
auto &all_ents_range) {
706 proc_ent = all_ents_range;
710 auto resolve_shared_ents = [&](
auto &&proc_ents,
auto &&skin_ents) {
711 return pcomm->resolve_shared_ents(
712 0, proc_ents, resolve_dim(all_ents_range),
713 resolve_dim(all_ents_range), skin_ents.data(), set_gid(th_gid));
716 CHKERR resolve_shared_ents(get_proc_ent(all_ents_range),
717 get_skin_ents(all_ents_range));
722 CHKERR delete_tag(resolve_shared_ents(get_tag(), all_ents_range));
730 CHKERR pcomm->get_owner_handle(e, moab_owner_proc, moab_owner_handle);
732 unsigned char pstatus = 0;
734 CHKERR m_field.
get_moab().tag_get_data(pcomm->pstatus_tag(), &e, 1,
737 std::vector<int> shprocs(MAX_SHARING_PROCS, 0);
738 std::vector<EntityHandle> shhandles(MAX_SHARING_PROCS, 0);
740 CHKERR m_field.
get_moab().tag_get_data(pcomm->sharedp_tag(), &e, 1,
742 CHKERR m_field.
get_moab().tag_get_data(pcomm->sharedh_tag(), &e, 1,
744 if (pstatus & PSTATUS_MULTISHARED) {
745 CHKERR m_field.
get_moab().tag_get_data(pcomm->sharedps_tag(), &e, 1,
747 CHKERR m_field.
get_moab().tag_get_data(pcomm->sharedhs_tag(), &e, 1,
751 std::ostringstream ss;
754 if (!(pstatus & PSTATUS_NOT_OWNED))
756 if (pstatus & PSTATUS_SHARED)
757 ss <<
"PSTATUS_SHARED ";
758 if (pstatus & PSTATUS_MULTISHARED)
759 ss <<
"PSTATUS_MULTISHARED ";
761 ss <<
"owner " << moab_owner_proc <<
" (" << owner_proc <<
") ";
765 ss << shprocs[r] <<
" ";
769 ss << shhandles[r] <<
" ";
772 MOFEM_LOG(
"SYNC", Sev::noisy) << ss.str();
778 for (
auto e : all_ents_range)
868 const int adj_dim,
const int n_parts,
869 Tag *th_vertex_weights,
Tag *th_edge_weights,
870 Tag *th_part_weights,
int verb,
const bool debug) {
875 int rstart, rend, nb_elems;
879 CHKERR PetscLayoutSetBlockSize(layout, 1);
880 CHKERR PetscLayoutSetSize(layout, ents.size());
881 CHKERR PetscLayoutSetUp(layout);
882 CHKERR PetscLayoutGetSize(layout, &nb_elems);
883 CHKERR PetscLayoutGetRange(layout, &rstart, &rend);
884 CHKERR PetscLayoutDestroy(&layout);
887 <<
"Finite elements in problem: row lower " << rstart <<
" row upper "
888 << rend <<
" nb. elems " << nb_elems <<
" ( " << ents.size() <<
" )";
893 std::vector<EntityHandle> weight_ents;
894 weight_ents.reserve(rend - rstart + 1);
898 std::vector<int> adj;
899 AdjBridge(
const EntityHandle ent, std::vector<int> &adj)
900 : ent(ent), adj(adj) {}
903 typedef multi_index_container<
907 hashed_unique<member<AdjBridge, EntityHandle, &AdjBridge::ent>>
912 auto get_it = [&](
auto i) {
913 auto it = ents.begin();
915 if (it == ents.end())
923 proc_ents.insert(get_it(rstart), get_it(rend));
924 if (proc_ents.size() != rend - rstart)
926 "Wrong number of elements in range %zu != %zu", proc_ents.size(),
927 static_cast<size_t>(rend - rstart));
931 proc_ents, adj_dim,
true, all_dim_ents, moab::Interface::UNION);
933 AdjBridgeMap adj_bridge_map;
934 auto hint = adj_bridge_map.begin();
935 std::vector<int> adj;
936 for (
auto ent : all_dim_ents) {
938 CHKERR m_field.
get_moab().get_adjacencies(&ent, 1, dim,
false, adj_ents);
939 adj_ents = intersect(adj_ents, ents);
941 adj.reserve(adj_ents.size());
942 for (
auto a : adj_ents)
943 adj.emplace_back(ents.index(
a));
944 hint = adj_bridge_map.emplace_hint(hint, ent, adj);
950 const int nb_loc_elements = rend - rstart;
951 std::vector<int>
i(nb_loc_elements + 1, 0),
j;
953 std::vector<int> row_adj;
954 Range::iterator fe_it;
957 for (fe_it = proc_ents.begin(), ii = rstart, jj = 0, max_row_size = 0;
958 fe_it != proc_ents.end(); ++fe_it, ++ii) {
962 "not yet implemented, don't know what to do for meshset "
967 CHKERR m_field.
get_moab().get_adjacencies(&*fe_it, 1, adj_dim,
false,
969 dim_ents = intersect(dim_ents, all_dim_ents);
972 for (
auto e : dim_ents) {
973 auto adj_it = adj_bridge_map.find(e);
974 if (adj_it != adj_bridge_map.end()) {
976 for (
const auto idx : adj_it->adj)
977 row_adj.push_back(idx);
984 std::sort(row_adj.begin(), row_adj.end());
985 auto end = std::unique(row_adj.begin(), row_adj.end());
987 size_t row_size = std::distance(row_adj.begin(), end);
988 max_row_size = std::max(max_row_size, row_size);
989 if (
j.capacity() < (nb_loc_elements - jj) * max_row_size)
990 j.reserve(nb_loc_elements * max_row_size);
993 auto diag = ents.index(*fe_it);
994 for (
auto it = row_adj.begin(); it != end; ++it)
1001 if (th_vertex_weights != NULL)
1002 weight_ents.push_back(*fe_it);
1008 CHKERR PetscMalloc(
i.size() *
sizeof(
int), &_i);
1009 CHKERR PetscMalloc(
j.size() *
sizeof(
int), &_j);
1010 copy(
i.begin(),
i.end(), _i);
1011 copy(
j.begin(),
j.end(), _j);
1015 int *vertex_weights = NULL;
1016 if (th_vertex_weights != NULL) {
1017 CHKERR PetscMalloc(weight_ents.size() *
sizeof(
int), &vertex_weights);
1019 &*weight_ents.begin(),
1020 weight_ents.size(), vertex_weights);
1026 CHKERR MatCreateMPIAdj(m_field.
get_comm(), rend - rstart, nb_elems, _i, _j,
1027 PETSC_NULLPTR, &Adj);
1028 CHKERR MatSetOption(Adj, MAT_STRUCTURALLY_SYMMETRIC, PETSC_TRUE);
1032 CHKERR MatConvert(Adj, MATMPIAIJ, MAT_INITIAL_MATRIX, &
A);
1033 CHKERR MatView(
A, PETSC_VIEWER_DRAW_WORLD);
1040 MOFEM_LOG(
"WORLD", Sev::verbose) <<
"Start";
1042 MatPartitioning part;
1046 CHKERR MatPartitioningSetAdjacency(part, Adj);
1047 CHKERR MatPartitioningSetFromOptions(part);
1048 CHKERR MatPartitioningSetNParts(part, n_parts);
1049 if (th_vertex_weights != NULL) {
1050 CHKERR MatPartitioningSetVertexWeights(part, vertex_weights);
1052 CHKERR MatPartitioningApply(part, &is);
1054 MOFEM_LOG(
"WORLD", Sev::verbose) <<
"End";
1057 IS is_gather, is_num, is_gather_num;
1058 CHKERR ISAllGather(is, &is_gather);
1059 CHKERR ISPartitioningToNumbering(is, &is_num);
1060 CHKERR ISAllGather(is_num, &is_gather_num);
1062 const int *part_number, *gids;
1063 CHKERR ISGetIndices(is_gather, &part_number);
1064 CHKERR ISGetIndices(is_gather_num, &gids);
1067 ParallelComm *pcomm = ParallelComm::get_pcomm(
1069 Tag part_tag = pcomm->part_tag();
1070 CHKERR m_field.
get_moab().tag_set_data(part_tag, ents, part_number);
1073 std::map<int, Range> parts_ents;
1076 Range::iterator eit = ents.begin();
1077 for (
int ii = 0; eit != ents.end(); eit++, ii++) {
1078 parts_ents[part_number[ii]].insert(*eit);
1082 0, MBENTITYSET, &part_tag, NULL, 1, tagged_sets,
1083 moab::Interface::UNION);
1084 if (!tagged_sets.empty())
1085 CHKERR m_field.
get_moab().tag_delete_data(part_tag, tagged_sets);
1087 if (n_parts > (
int)tagged_sets.size()) {
1089 int num_new = n_parts - tagged_sets.size();
1090 for (
int i = 0;
i < num_new;
i++) {
1093 tagged_sets.insert(new_set);
1095 }
else if (n_parts < (
int)tagged_sets.size()) {
1097 int num_del = tagged_sets.size() - n_parts;
1098 for (
int i = 0;
i < num_del;
i++) {
1105 std::vector<int> dum_ids(n_parts);
1106 for (
int i = 0;
i < n_parts;
i++)
1113 for (
int pp = 0; pp != n_parts; pp++) {
1114 Range dim_ents = parts_ents[pp].subset_by_dimension(dim);
1115 for (
int dd = dim - 1; dd >= 0; dd--) {
1118 dim_ents, dd,
false, adj_ents, moab::Interface::UNION);
1119 parts_ents[pp].merge(adj_ents);
1122 for (
int pp = 1; pp != n_parts; pp++) {
1123 for (
int ppp = 0; ppp != pp; ppp++) {
1124 parts_ents[pp] = subtract(parts_ents[pp], parts_ents[ppp]);
1128 for (
int pp = 0; pp != n_parts; pp++) {
1129 CHKERR m_field.
get_moab().add_entities(tagged_sets[pp], parts_ents[pp]);
1132 auto set_part = [&]() {
1134 for (EntityType
t = MBEDGE;
t != MBENTITYSET; ++
t) {
1135 for (
int pp = 0; pp != n_parts; pp++) {
1136 Range type_ents = parts_ents[pp].subset_by_type(
t);
1137 CHKERR m_field.
get_moab().tag_clear_data(part_tag, type_ents, &pp);
1143 auto set_gid = [&]() {
1145 for (
int d = 0; d != 4; ++d) {
1151 for (
int pp = 0; pp != n_parts; pp++) {
1152 Range type_ents = parts_ents[pp].subset_by_dimension(d);
1154 auto eit = type_ents.begin();
1155 for (; eit != type_ents.end();) {
1157 gid_tag, eit, type_ents.end(), count, ptr);
1158 auto gid_tag_ptr =
static_cast<int *
>(ptr);
1159 for (; count > 0; --count) {
1178 for (
int rr = 0; rr != n_parts; rr++) {
1180 ss <<
"out_part_" << rr <<
".vtk";
1181 MOFEM_LOG(
"SELF", Sev::inform) <<
"Save debug part mesh " << ss.str();
1185 CHKERR m_field.
get_moab().write_file(ss.str().c_str(),
"VTK",
"",
1192 CHKERR ISRestoreIndices(is_gather, &part_number);
1193 CHKERR ISRestoreIndices(is_gather_num, &gids);
1194 CHKERR ISDestroy(&is_num);
1195 CHKERR ISDestroy(&is_gather_num);
1196 CHKERR ISDestroy(&is_gather);
1198 CHKERR MatPartitioningDestroy(&part);
1206 moab::Interface &moab,
const char *file_name,
int dim,
1214 CHKERR moab.load_file(file_name, 0, options);
1219 ParallelComm *pcomm = ParallelComm::get_pcomm(&moab,
MYPCOMM_INDEX);
1221 pcomm =
new ParallelComm(&moab, PETSC_COMM_WORLD);
1222 if (pcomm->size() == 1)
1225 Skinner skin(&moab);
1227 auto print_range_on_procs = [&](
const Range &range, std::string name) {
1228 MOFEM_LOG(
"SYNC",
sev) << name <<
" on proc [" << pcomm->rank()
1229 <<
"] : " << range.size();
1233 auto save_range_to_file = [&](
const Range range, std::string name =
"part") {
1236 int rr = pcomm->rank();
1238 ss <<
"out_" << name <<
"_" << rr <<
".vtk";
1239 MOFEM_LOG(
"SYNC",
sev) <<
"Save debug part mesh " << ss.str();
1241 CHKERR moab.create_meshset(MESHSET_SET, meshset);
1242 CHKERR moab.add_entities(meshset, range);
1244 CHKERR moab.write_file(ss.str().c_str(),
"VTK",
"", &meshset, 1);
1246 CHKERR moab.delete_entities(&meshset, 1);
1250 auto get_skin = [&](
auto e) {
1252 CHKERR skin.find_skin(0, e.subset_by_dimension(dim),
false, s);
1256 auto get_adj = [&](
auto ents,
auto dim) {
1258 CHKERR moab.get_adjacencies(ents, dim,
false, adj, moab::Interface::UNION);
1263 CHKERR moab.get_entities_by_handle(0, all_ents,
false);
1264 save_range_to_file(all_ents,
"all_ents");
1266 Tag part_tag = pcomm->part_tag();
1267 Range tagged_sets, proc_ents, off_proc_ents;
1269 CHKERR moab.get_entities_by_type_and_tag(0, MBENTITYSET, &part_tag, NULL, 1,
1270 tagged_sets, moab::Interface::UNION);
1271 print_range_on_procs(tagged_sets,
"tagged_sets");
1272 for (
auto &mit : tagged_sets) {
1274 CHKERR moab.tag_get_data(part_tag, &mit, 1, &part);
1275 if (part == pcomm->rank()) {
1276 CHKERR moab.get_entities_by_handle(mit, proc_ents,
true);
1278 CHKERR moab.get_entities_by_handle(mit, off_proc_ents,
true);
1283 for (
auto &mit : tagged_sets) {
1285 CHKERR moab.tag_get_data(part_tag, &mit, 1, &part);
1287 CHKERR moab.get_entities_by_handle(mit, ents,
true);
1288 CHKERR moab.tag_clear_data(part_tag, ents, &part);
1291 print_range_on_procs(proc_ents,
"proc_ents");
1292 save_range_to_file(proc_ents,
"proc_ents");
1294 auto get_proc_ents_skin = [&]() {
1295 std::array<Range, 4>
1297 auto all_skin = get_skin(all_ents.subset_by_dimension(dim));
1298 auto proc_skin = get_skin(proc_ents.subset_by_dimension(dim));
1300 proc_ents_skin[2] = subtract(proc_skin, all_skin);
1301 proc_ents_skin[1] = get_adj(proc_ents_skin[dim - 1], 1);
1304 proc_ents_skin[1] = subtract(proc_skin, all_skin);
1306 CHKERR moab.get_connectivity(proc_ents_skin[dim - 1], proc_ents_skin[0],
1308 return proc_ents_skin;
1311 auto add_post_proc_skin = [&](
auto &&proc_ents_skin) {
1314 Tag nsTag, ssTag, nsTag_data, ssTag_data, bhTag, bhTag_header;
1316 bhTag, bhTag_header,
QUIET);
1319 CHKERR moab.get_entities_by_type(0, MBENTITYSET, meshsets,
false);
1320 for (
auto m : meshsets) {
1325 auto p = cubit_meshsets_index.insert(block);
1330 CHKERR moab.get_entities_by_handle(
m, ents,
true);
1331 CHKERR moab.add_entities(p.first->getMeshset(), ents);
1332 CHKERR moab.delete_entities(&
m, 1);
1337 for (
auto &
m : cubit_meshsets_index) {
1342 std::vector<const CubitMeshSets *> vec_ptr;
1343 for (
auto &
m : cubit_meshsets_index) {
1344 vec_ptr.push_back(&
m);
1348 return proc_skin_fun(std::move(proc_ents_skin), std::move(vec_ptr));
1351 auto remove_off_proc_ents = [&](
auto &all_ents,
auto &off_proc_ents,
1352 auto &proc_ents_skin) {
1353 auto to_remove = off_proc_ents;
1354 for (
auto d = dim - 1; d >= 0; --d) {
1355 to_remove = subtract(to_remove, proc_ents_skin[d]);
1359 CHKERR moab.get_entities_by_type(0, MBENTITYSET, meshsets,
true);
1360 for (
auto m : meshsets) {
1361 CHKERR moab.remove_entities(
m, to_remove);
1363 for (
int dd = dim; dd > 0; --dd) {
1364 CHKERR moab.delete_entities(to_remove.subset_by_dimension(dd));
1368 auto proc_ents_skin = add_post_proc_skin(get_proc_ents_skin());
1369 for (
auto d = dim - 1; d >= 0; --d) {
1370 save_range_to_file(proc_ents_skin[d],
"proc_ents_skin" + std::to_string(d));
1373 if (pcomm->rank()) {
1374 remove_off_proc_ents(all_ents, off_proc_ents, proc_ents_skin);
1377 for (
auto d = dim - 1; d >= 0; --d) {
1378 print_range_on_procs(proc_ents_skin[d],
1379 "proc_ents_skin by dim" + std::to_string(d));
1382 CHKERR pcomm->resolve_shared_ents(0, proc_ents, dim, -1,
1383 proc_ents_skin.data());
1388 auto gid_tag = moab.globalId_tag();
1392 CHKERR moab.tag_get_handle(
"TestGather", 1, MB_TYPE_INTEGER, tag_handle,
1393 MB_TAG_DENSE | MB_TAG_CREAT, &def_val);
1395 if (pcomm->rank() > 0) {
1396 gather_ents = proc_ents.subset_by_dimension(3);
1397 std::vector<int> vals(gather_ents.size());
1398 std::for_each(vals.begin(), vals.end(), [](
auto &
v) { v = std::rand(); });
1399 CHKERR moab.tag_set_data(tag_handle, gather_ents, vals.data());
1400 CHKERR pcomm->gather_data(gather_ents, tag_handle, gid_tag, 0, 0);
1402 gather_ents = proc_ents.subset_by_dimension(3);
1403 CHKERR pcomm->gather_data(gather_ents, tag_handle, gid_tag, 0, 0);
1407 Range all_ents_after;
1408 CHKERR moab.get_entities_by_handle(0, all_ents_after);
1409 save_range_to_file(all_ents_after.subset_by_dimension(3),
1410 "all_ents_part_after");
1490 MPI_Comm comm, moab::Interface &moab,
1491 std::function<
Range(
Range)> get_entities_fun,
const int nb_coeffs,
Sev sev,
1492 int root_rank,
bool get_vertices) {
1495 Range r, ghost_ents;
1497 auto get_gids = [&](
Range &ents) {
1498 std::vector<int> ids(ents.size());
1499 auto gid_tag = moab.globalId_tag();
1500 CHKERR moab.tag_get_data(gid_tag, ents, ids.data());
1504 auto create_ao = [&](
auto &&ids) {
1507 AOCreateMapping(comm, ids.size(), ids.data(), PETSC_NULLPTR, &ao_raw),
1508 "create ao failed");
1512 auto apply_ao = [&](
auto ao, std::vector<int> &&ids) {
1514 "AOApplicationToPetsc failed");
1518 auto get_tag_ids = [&](
auto ao,
Range &ents) {
1519 return apply_ao(ao, get_gids(ents));
1525 Tag part_tag = pcomm->part_tag();
1527 CHKERR moab.get_entities_by_type_and_tag(0, MBENTITYSET, &part_tag, NULL, 1,
1529 moab::Interface::UNION);
1530 auto get_proc_and_off_proc_ents = [&]() {
1531 Range proc_ents, off_proc_ents;
1532 if (tagged_sets.empty() && pcomm->size() == 1) {
1534 "get_entities_by_handle failed");
1535 proc_ents = subtract(proc_ents, proc_ents.subset_by_type(MBENTITYSET));
1536 proc_ents = subtract(proc_ents, proc_ents.subset_by_type(MBVERTEX));
1537 return std::make_pair(proc_ents,
Range());
1539 for (
auto &mit : tagged_sets) {
1542 "tag_get_data failed");
1543 if (part == pcomm->rank()) {
1544 CHK_MOAB_THROW(moab.get_entities_by_handle(mit, proc_ents,
false),
1545 "get_entities_by_handle failed");
1547 CHK_MOAB_THROW(moab.get_entities_by_handle(mit, off_proc_ents,
false),
1548 "get_entities_by_handle failed");
1550 proc_ents = subtract(proc_ents, off_proc_ents);
1552 return std::make_pair(proc_ents, off_proc_ents);
1555 auto get_proc_and_off_proc_verts = [&]() {
1556 Range proc_ents, off_proc_ents;
1557 if (tagged_sets.empty()) {
1558 CHK_MOAB_THROW(moab.get_entities_by_type(0, MBVERTEX, proc_ents),
1559 "get_entities_by_type failed");
1560 return std::make_pair(proc_ents,
Range());
1562 std::map<int, Range> parts_ents;
1563 for (
auto &mit : tagged_sets) {
1566 "tag_get_data failed");
1568 moab.get_entities_by_handle(mit, parts_ents[part],
false),
1569 "get_entities_by_handle failed");
1570 parts_ents[part] = subtract(
1571 parts_ents[part], parts_ents[part].subset_by_type(MBENTITYSET));
1575 "get_connectivity failed");
1577 for (; p != pcomm->rank(); ++p) {
1580 "get_connectivity failed");
1581 v = subtract(
v, vv);
1582 off_proc_ents.merge(vv);
1584 for (; p != pcomm->size(); ++p) {
1587 "get_connectivity failed");
1588 vv = subtract(vv,
v);
1589 off_proc_ents.merge(vv);
1592 return std::make_pair(proc_ents, off_proc_ents);
1595 auto [proc_ents, off_proc_ents] = get_proc_and_off_proc_ents();
1598 auto [proc_verts, off_proc_verts] = get_proc_and_off_proc_verts();
1599 proc_ents.merge(proc_verts);
1600 off_proc_ents.merge(off_proc_verts);
1602 r = get_entities_fun(proc_ents);
1603 auto o = get_entities_fun(off_proc_ents);
1604 auto ao = create_ao(get_gids(r));
1606 auto set_ghosts = [&](
auto &&ghosts_gids) {
1607 std::vector<int> ghosts_dofs(nb_coeffs * ghosts_gids.size());
1608 for (
int i = 0;
i < ghosts_gids.size(); ++
i)
1609 for (
int j = 0;
j < nb_coeffs; ++
j)
1610 ghosts_dofs[
i * nb_coeffs +
j] = nb_coeffs * ghosts_gids[
i] +
j;
1614 std::vector<int> ghosts;
1615 if (pcomm->rank() == root_rank) {
1616 ghosts = set_ghosts(get_tag_ids(ao, o));
1620 CHKERR moab.get_entities_by_handle(0, ents,
true);
1621 ents = get_entities_fun(ents);
1622 ents = subtract(ents, r);
1623 ghosts = set_ghosts(get_tag_ids(ao, ents));
1627 auto create_vec = [&]() {
1630 ghosts.size(), ghosts.data());
1640 auto out = std::make_pair(std::make_pair(r, ghost_ents), vec);
1645 auto check = [&](
auto &ents,
auto &id,
auto &idx) {
1648 for (
int i = 0;
i < ents.size(); ++
i) {
1649 for (
int j = 0;
j < nb_coeffs; ++
j) {
1650 if (idx[
i * nb_coeffs +
j] != nb_coeffs *
id[
i] +
j) {
1653 <<
"indexes not equal: " << idx[
i * nb_coeffs +
j]
1654 <<
" != " << nb_coeffs * idx[
i] +
j;
1664 std::vector<double> def_val(nb_coeffs, 0.0);
1666 CHKERR moab.tag_get_handle(
"TestGather", nb_coeffs, MB_TYPE_DOUBLE, tag,
1667 MB_TAG_SPARSE | MB_TAG_CREAT, def_val.data());
1668 auto ao = create_ao(get_gids(r));
1669 auto id = get_tag_ids(ao, r);
1670 std::vector<double> idx(nb_coeffs * r.size());
1671 for (
int i = 0;
i < r.size(); ++
i) {
1672 for (
int j = 0;
j < nb_coeffs; ++
j) {
1673 idx[
i * nb_coeffs +
j] = nb_coeffs *
id[
i] +
j;
1676 CHKERR moab.tag_set_data(tag, r, idx.data());
1678 idx.resize(nb_coeffs * r.size());
1679 CHKERR moab.tag_get_data(tag, r, idx.data());
1681 auto ghost_id = get_tag_ids(ao, ghost_ents);
1682 idx.resize(nb_coeffs * ghost_ents.size());
1683 CHKERR moab.tag_get_data(tag, ghost_ents, idx.data());
1685 "ghost indexes do not match")
1686 CHKERR moab.tag_delete(tag);
multi_index_container< CubitMeshSets, indexed_by< hashed_unique< tag< Meshset_mi_tag >, member< CubitMeshSets, EntityHandle, &CubitMeshSets::meshset > >, ordered_non_unique< tag< CubitMeshsetType_mi_tag >, const_mem_fun< CubitMeshSets, unsigned long int, &CubitMeshSets::getBcTypeULong > >, ordered_non_unique< tag< CubitMeshsetMaskedType_mi_tag >, const_mem_fun< CubitMeshSets, unsigned long int, &CubitMeshSets::getMaskedBcTypeULong > >, ordered_non_unique< tag< CubitMeshsets_name >, const_mem_fun< CubitMeshSets, std::string, &CubitMeshSets::getName > >, hashed_unique< tag< Composite_Cubit_msId_And_MeshsetType_mi_tag >, composite_key< CubitMeshSets, const_mem_fun< CubitMeshSets, int, &CubitMeshSets::getMeshsetId >, const_mem_fun< CubitMeshSets, unsigned long int, &CubitMeshSets::getMaskedBcTypeULong > > > > > CubitMeshSet_multiIndex
Stores data about meshsets (see CubitMeshSets) storing data about boundary conditions,...