8 #define ProblemManagerFunctionBegin \
10 MOFEM_LOG_CHANNEL("WORLD"); \
11 MOFEM_LOG_CHANNEL("SYNC"); \
12 MOFEM_LOG_FUNCTION(); \
13 MOFEM_LOG_TAG("SYNC", "ProblemsManager"); \
14 MOFEM_LOG_TAG("WORLD", "ProblemsManager")
18 bcopy(&uid,
dAta, 4 *
sizeof(
int));
29 int global_dof =
pTr[4];
33 unsigned int b0, b1, b2, b3;
34 bcopy(&
pTr[0], &b0,
sizeof(
int));
35 bcopy(&
pTr[1], &b1,
sizeof(
int));
36 bcopy(&
pTr[2], &b2,
sizeof(
int));
37 bcopy(&
pTr[3], &b3,
sizeof(
int));
38 UId uid =
static_cast<UId>(b0) |
static_cast<UId>(b1) << 8 *
sizeof(
int) |
39 static_cast<UId>(b2) << 16 *
sizeof(
int) |
40 static_cast<UId>(b3) << 24 *
sizeof(
int);
57 buildProblemFromFields(PETSC_FALSE),
58 synchroniseProblemEntities(PETSC_FALSE) {
65 CHKERR PetscOptionsBegin(m_field.
get_comm(),
"",
"Problem manager",
"none");
68 "-problem_build_from_fields",
69 "Add DOFs to problem directly from fields not through DOFs on elements",
72 ierr = PetscOptionsEnd();
78 const Range &ents,
const int dim,
const int adj_dim,
const int n_parts,
79 Tag *th_vertex_weights, Tag *th_edge_weights, Tag *th_part_weights,
80 int verb,
const bool debug) {
82 .getInterface<CommInterface>()
83 ->partitionMesh(ents, dim, adj_dim, n_parts, th_vertex_weights,
84 th_edge_weights, th_part_weights, verb,
debug);
88 const bool square_matrix,
108 const bool square_matrix,
111 auto dofs_field_ptr = m_field.
get_dofs();
121 SETERRQ1(PETSC_COMM_SELF, 1,
"problem <%s> refinement level not set",
122 problem_ptr->
getName().c_str());
130 auto make_rows_and_cols_view = [&](
auto &dofs_rows,
auto &dofs_cols) {
132 for (
auto it = ents_field_ptr->begin(); it != ents_field_ptr->end(); ++it) {
134 const auto uid = (*it)->getLocalUniqueId();
137 for (
auto lo =
r.first; lo !=
r.second; ++lo) {
139 if ((lo->getBitFEId() & problem_ptr->
getBitFEId()).any()) {
140 std::array<bool, 2> row_col = {
false,
false};
144 const BitRefLevel &fe_bit = lo->entFePtr->getBitRefLevel();
147 if ((fe_bit & prb_mask) != fe_bit)
149 if ((fe_bit & prb_bit).none())
152 auto add_to_view = [&](
auto &nb_dofs,
auto &view,
auto rc) {
153 auto dit = nb_dofs->lower_bound(uid);
154 decltype(dit) hi_dit;
155 if (dit != nb_dofs->end()) {
156 hi_dit = nb_dofs->upper_bound(
158 view.insert(dit, hi_dit);
163 if ((lo->entFePtr->getBitFieldIdRow() & (*it)->getId()).any())
164 add_to_view(dofs_field_ptr, dofs_rows,
ROW);
167 if ((lo->entFePtr->getBitFieldIdCol() & (*it)->getId()).any())
168 add_to_view(dofs_field_ptr, dofs_cols,
COL);
170 if (square_matrix && row_col[
ROW])
172 else if (row_col[
ROW] && row_col[
COL])
180 CHKERR make_rows_and_cols_view(dofs_rows, dofs_cols);
190 DofEntity_multiIndex_active_view::nth_index<0>::type::iterator miit,
192 hi_miit = dofs_rows.get<0>().end();
194 int count_dofs = dofs_rows.get<1>().count(
true);
195 boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array =
196 boost::shared_ptr<std::vector<NumeredDofEntity>>(
197 new std::vector<NumeredDofEntity>());
199 dofs_array->reserve(count_dofs);
200 miit = dofs_rows.get<0>().begin();
201 for (; miit != hi_miit; miit++) {
202 if ((*miit)->getActive()) {
203 dofs_array->emplace_back(*miit);
204 dofs_array->back().dofIdx = (problem_ptr->
nbDofsRow)++;
208 for (
auto &
v : *dofs_array) {
214 if (!square_matrix) {
221 DofEntity_multiIndex_active_view::nth_index<0>::type::iterator miit,
223 hi_miit = dofs_cols.get<0>().end();
226 miit = dofs_cols.get<0>().begin();
227 for (; miit != hi_miit; miit++) {
228 if (!(*miit)->getActive()) {
234 boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array =
235 boost::shared_ptr<std::vector<NumeredDofEntity>>(
236 new std::vector<NumeredDofEntity>());
238 dofs_array->reserve(count_dofs);
239 miit = dofs_cols.get<0>().begin();
240 for (; miit != hi_miit; miit++) {
241 if (!(*miit)->getActive()) {
244 dofs_array->emplace_back(*miit);
245 dofs_array->back().dofIdx = problem_ptr->
nbDofsCol++;
248 for (
auto &
v : *dofs_array) {
260 << problem_ptr->
getName() <<
" Nb. local dofs "
268 <<
"FEs row dofs " << *problem_ptr <<
" Nb. row dof "
274 <<
"FEs col dofs " << *problem_ptr <<
" Nb. col dof "
291 const std::string name,
const bool square_matrix,
int verb) {
305 square_matrix, verb);
314 Problem *problem_ptr,
const bool square_matrix,
int verb) {
318 auto dofs_field_ptr = m_field.
get_dofs();
329 "problem <%s> refinement level not set",
330 problem_ptr->
getName().c_str());
338 boost::shared_ptr<NumeredDofEntity_multiIndex>(
352 auto make_rows_and_cols_view = [&](
auto &dofs_rows,
auto &dofs_cols) {
356 for (
auto it = ents_field_ptr->begin(); it != ents_field_ptr->end();
359 const auto uid = (*it)->getLocalUniqueId();
362 for (
auto lo =
r.first; lo !=
r.second; ++lo) {
364 if ((lo->getBitFEId() & problem_ptr->
getBitFEId()).any()) {
365 std::array<bool, 2> row_col = {
false,
false};
367 const BitRefLevel &fe_bit = lo->entFePtr->getBitRefLevel();
370 if ((fe_bit & prb_bit).any() && (fe_bit & prb_mask) == fe_bit) {
372 auto add_to_view = [&](
auto dofs,
auto &view,
auto rc) {
373 auto dit = dofs->lower_bound(uid);
374 decltype(dit) hi_dit;
375 if (dit != dofs->end()) {
376 hi_dit = dofs->upper_bound(
378 view.insert(dit, hi_dit);
383 if ((lo->entFePtr->getBitFieldIdRow() & (*it)->getId()).any())
384 add_to_view(dofs_field_ptr, dofs_rows,
ROW);
387 if ((lo->entFePtr->getBitFieldIdCol() & (*it)->getId()).any())
388 add_to_view(dofs_field_ptr, dofs_cols,
COL);
390 if (square_matrix && row_col[
ROW])
392 else if (row_col[
ROW] && row_col[
COL])
401 CHKERR make_rows_and_cols_view(dofs_rows, dofs_cols);
409 for (
auto fit = fe_ptr->begin(); fit != fe_ptr->end(); fit++) {
410 if ((fit->get()->getId() & problem_ptr->
getBitFEId()).any()) {
411 fields_ids_row |= fit->get()->getBitFieldIdRow();
412 fields_ids_col |= fit->get()->getBitFieldIdCol();
416 for (
auto fit = fields_ptr->begin(); fit != fields_ptr->end(); fit++) {
417 if ((fit->get()->getId() & (fields_ids_row | fields_ids_col)).any()) {
421 auto hi_dit = dofs_field_ptr->get<
Unique_mi_tag>().upper_bound(
424 for (; dit != hi_dit; dit++) {
426 const int owner_proc = dit->get()->getOwnerProc();
428 const unsigned char pstatus = dit->get()->getPStatus();
434 const auto &dof_bit = (*dit)->getBitRefLevel();
436 if ((dof_bit & prb_bit).any() && (dof_bit & prb_mask) == dof_bit) {
438 if ((fit->get()->getId() & fields_ids_row).any()) {
439 dofs_rows.insert(*dit);
441 if (!square_matrix) {
442 if ((fit->get()->getId() & fields_ids_col).any()) {
443 dofs_cols.insert(*dit);
455 BitFieldId *fields_ids[2] = {&fields_ids_row, &fields_ids_col};
456 for (FiniteElement_multiIndex::iterator fit = fe_ptr->begin();
457 fit != fe_ptr->end(); fit++) {
458 if ((fit->get()->getId() & problem_ptr->
getBitFEId()).any()) {
459 fields_ids_row |= fit->get()->getBitFieldIdRow();
460 fields_ids_col |= fit->get()->getBitFieldIdCol();
465 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ++ss) {
466 DofEntity_multiIndex_active_view::nth_index<1>::type::iterator miit,
468 miit = dofs_ptr[ss]->get<1>().lower_bound(1);
469 hi_miit = dofs_ptr[ss]->get<1>().upper_bound(1);
470 Range ents_to_synchronise;
471 for (; miit != hi_miit; ++miit) {
472 if (miit->get()->getEntDofIdx() != 0)
474 ents_to_synchronise.insert(miit->get()->getEnt());
476 Range tmp_ents = ents_to_synchronise;
478 ents_to_synchronise,
nullptr, verb);
479 ents_to_synchronise = subtract(ents_to_synchronise, tmp_ents);
480 for (
auto fit = fields_ptr->begin(); fit != fields_ptr->end(); fit++) {
481 if ((fit->get()->getId() & *fields_ids[ss]).any()) {
482 const auto bit_number = (*fit)->getBitNumber();
483 for (Range::pair_iterator pit = ents_to_synchronise.pair_begin();
484 pit != ents_to_synchronise.pair_end(); ++pit) {
485 const auto f = pit->first;
486 const auto s = pit->second;
492 auto dit = dofs_field_ptr->get<
Unique_mi_tag>().lower_bound(lo_uid);
496 dofs_ptr[ss]->insert(dit, hi_dit);
505 boost::shared_ptr<NumeredDofEntity_multiIndex> numered_dofs_ptr[] = {
512 for (
int ss = 0; ss < 2; ss++) {
513 *(nbdof_ptr[ss]) = 0;
514 *(local_nbdof_ptr[ss]) = 0;
515 *(ghost_nbdof_ptr[ss]) = 0;
520 int nb_local_dofs[] = {0, 0};
521 for (
int ss = 0; ss < loop_size; ss++) {
522 DofEntity_multiIndex_active_view::nth_index<1>::type::iterator miit,
524 miit = dofs_ptr[ss]->get<1>().lower_bound(1);
525 hi_miit = dofs_ptr[ss]->get<1>().upper_bound(1);
526 for (; miit != hi_miit; miit++) {
527 int owner_proc = (*miit)->getOwnerProc();
535 int start_ranges[2], end_ranges[2];
536 for (
int ss = 0; ss != loop_size; ss++) {
539 CHKERR PetscLayoutSetBlockSize(layout, 1);
540 CHKERR PetscLayoutSetLocalSize(layout, nb_local_dofs[ss]);
541 CHKERR PetscLayoutSetUp(layout);
542 CHKERR PetscLayoutGetSize(layout, &*nbdof_ptr[ss]);
543 CHKERR PetscLayoutGetRange(layout, &start_ranges[ss], &end_ranges[ss]);
544 CHKERR PetscLayoutDestroy(&layout);
547 nbdof_ptr[1] = nbdof_ptr[0];
548 nb_local_dofs[1] = nb_local_dofs[0];
549 start_ranges[1] = start_ranges[0];
550 end_ranges[1] = end_ranges[0];
562 const size_t idx_data_type_size =
sizeof(
IdxDataType);
563 const size_t data_block_size = idx_data_type_size /
sizeof(
int);
568 std::vector<std::vector<IdxDataType>> ids_data_packed_rows(
574 for (
int ss = 0; ss != loop_size; ++ss) {
576 DofEntity_multiIndex_active_view::nth_index<0>::type::iterator miit,
578 hi_miit = dofs_ptr[ss]->get<0>().end();
580 boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array =
581 boost::shared_ptr<std::vector<NumeredDofEntity>>(
582 new std::vector<NumeredDofEntity>());
583 int nb_dofs_to_add = 0;
584 miit = dofs_ptr[ss]->get<0>().begin();
585 for (; miit != hi_miit; ++miit) {
587 if (!(miit->get()->getActive()))
591 dofs_array->reserve(nb_dofs_to_add);
598 int &local_idx = *local_nbdof_ptr[ss];
599 miit = dofs_ptr[ss]->get<0>().begin();
600 for (; miit != hi_miit; ++miit) {
603 if (!(miit->get()->getActive()))
606 dofs_array->emplace_back(*miit);
608 int owner_proc = dofs_array->back().getOwnerProc();
609 if (owner_proc < 0) {
611 "data inconsistency");
615 dofs_array->back().pArt = owner_proc;
616 dofs_array->back().dofIdx = -1;
617 dofs_array->back().petscGloablDofIdx = -1;
618 dofs_array->back().petscLocalDofIdx = -1;
622 int glob_idx = start_ranges[ss] + local_idx;
623 dofs_array->back().pArt = owner_proc;
624 dofs_array->back().dofIdx = glob_idx;
625 dofs_array->back().petscGloablDofIdx = glob_idx;
626 dofs_array->back().petscLocalDofIdx = local_idx;
629 unsigned char pstatus = dofs_array->back().getPStatus();
635 proc < MAX_SHARING_PROCS &&
636 -1 != dofs_array->back().getSharingProcsPtr()[proc];
640 ids_data_packed_rows[dofs_array->back()
641 .getSharingProcsPtr()[proc]]
642 .emplace_back(dofs_array->back().getGlobalUniqueId(),
645 ids_data_packed_cols[dofs_array->back()
646 .getSharingProcsPtr()[proc]]
647 .emplace_back(dofs_array->back().getGlobalUniqueId(),
650 if (!(pstatus & PSTATUS_MULTISHARED)) {
658 auto hint = numered_dofs_ptr[ss]->end();
659 for (
auto &
v : *dofs_array)
660 hint = numered_dofs_ptr[ss]->emplace_hint(hint, dofs_array, &
v);
663 local_nbdof_ptr[1] = local_nbdof_ptr[0];
666 int nsends_rows = 0, nsends_cols = 0;
670 lengths_rows.clear();
671 lengths_cols.clear();
673 lengths_rows[proc] = ids_data_packed_rows[proc].size() * data_block_size;
674 lengths_cols[proc] = ids_data_packed_cols[proc].size() * data_block_size;
675 if (!ids_data_packed_rows[proc].empty())
677 if (!ids_data_packed_cols[proc].empty())
699 CHKERR PetscGatherNumberOfMessages(comm, NULL, &lengths_rows[0],
705 CHKERR PetscGatherMessageLengths(comm, nsends_rows, nrecvs_rows,
706 &lengths_rows[0], &onodes_rows,
714 CHKERR PetscCommGetNewTag(comm, &tag_row);
718 MPI_Request *r_waits_row;
723 CHKERR PetscPostIrecvInt(comm, tag_row, nrecvs_rows, onodes_rows,
724 olengths_rows, &rbuf_row, &r_waits_row);
725 CHKERR PetscFree(onodes_rows);
727 MPI_Request *s_waits_row;
728 CHKERR PetscMalloc1(nsends_rows, &s_waits_row);
731 for (
int proc = 0, kk = 0; proc < m_field.
get_comm_size(); proc++) {
732 if (!lengths_rows[proc])
734 CHKERR MPI_Isend(&(ids_data_packed_rows[proc])[0],
737 tag_row, comm, s_waits_row + kk);
742 CHKERR MPI_Waitall(nrecvs_rows, r_waits_row, status);
745 CHKERR MPI_Waitall(nsends_rows, s_waits_row, status);
748 CHKERR PetscFree(r_waits_row);
749 CHKERR PetscFree(s_waits_row);
753 int nrecvs_cols = nrecvs_rows;
754 int *olengths_cols = olengths_rows;
755 PetscInt **rbuf_col = rbuf_row;
756 if (!square_matrix) {
759 CHKERR PetscGatherNumberOfMessages(comm, NULL, &lengths_cols[0],
765 CHKERR PetscGatherMessageLengths(comm, nsends_cols, nrecvs_cols,
766 &lengths_cols[0], &onodes_cols,
771 CHKERR PetscCommGetNewTag(comm, &tag_col);
775 MPI_Request *r_waits_col;
776 CHKERR PetscPostIrecvInt(comm, tag_col, nrecvs_cols, onodes_cols,
777 olengths_cols, &rbuf_col, &r_waits_col);
778 CHKERR PetscFree(onodes_cols);
780 MPI_Request *s_waits_col;
781 CHKERR PetscMalloc1(nsends_cols, &s_waits_col);
784 for (
int proc = 0, kk = 0; proc < m_field.
get_comm_size(); proc++) {
785 if (!lengths_cols[proc])
787 CHKERR MPI_Isend(&(ids_data_packed_cols[proc])[0],
790 tag_col, comm, s_waits_col + kk);
795 CHKERR MPI_Waitall(nrecvs_cols, r_waits_col, status);
798 CHKERR MPI_Waitall(nsends_cols, s_waits_col, status);
801 CHKERR PetscFree(r_waits_col);
802 CHKERR PetscFree(s_waits_col);
805 CHKERR PetscCommDestroy(&comm);
809 auto hint = dofs_glob_uid_view.begin();
810 for (
auto dof : *m_field.
get_dofs())
811 dofs_glob_uid_view.emplace_hint(hint, dof);
814 for (
int ss = 0; ss != loop_size; ++ss) {
820 nrecvs = nrecvs_rows;
821 olengths = olengths_rows;
822 data_procs = rbuf_row;
824 nrecvs = nrecvs_cols;
825 olengths = olengths_cols;
826 data_procs = rbuf_col;
830 for (
int kk = 0; kk != nrecvs; ++kk) {
831 int len = olengths[kk];
832 int *data_from_proc = data_procs[kk];
833 for (
int dd = 0;
dd < len;
dd += data_block_size) {
835 auto ddit = dofs_glob_uid_view.find(uid);
839 PetscUnlikely(ddit == dofs_glob_uid_view.end())) {
844 <<
"DOF is shared or multishared between processors. For example "
845 "if order of field on given entity is set in inconsistently, "
846 "has different value on two processor, error such as this is "
849 MOFEM_LOG(
"SELF", Sev::error) <<
"UId " << uid <<
" is not found";
851 <<
"Problematic UId owner proc is " << owner_proc;
854 <<
"Problematic UId entity owning processor handle is "
855 << uid_handle <<
" entity type "
857 const auto uid_bit_number =
860 <<
"Problematic UId field is "
865 field_view.insert(ents_field_ptr->begin(), ents_field_ptr->end());
867 owner_proc, uid_bit_number, uid_handle));
868 if (fe_it == field_view.end()) {
870 <<
"Also, no field entity in database for given global UId";
872 MOFEM_LOG(
"SELF", Sev::error) <<
"Field entity in databse exist "
873 "(but have no DOF wih give UId";
874 MOFEM_LOG(
"SELF", Sev::error) << **fe_it;
877 auto error_file_name =
878 "error_with_missing_entity_" +
882 <<
"Look to file < " << error_file_name
883 <<
" > it contains entity with missing DOF.";
886 const auto local_fe_ent = (*fe_it)->getEnt();
887 CHKERR m_field.
get_moab().add_entities(*tmp_msh, &local_fe_ent, 1);
888 CHKERR m_field.
get_moab().write_file(error_file_name.c_str(),
"VTK",
889 "", tmp_msh->get_ptr(), 1);
894 "DOF with global UId not found (Compile code in Debug to "
895 "learn more about problem");
898 if (PetscUnlikely(ddit == dofs_glob_uid_view.end())) {
902 auto dit = numered_dofs_ptr[ss]->find((*ddit)->getLocalUniqueId());
904 if (dit != numered_dofs_ptr[ss]->end()) {
908 if (PetscUnlikely(global_idx < 0))
910 "received negative dof");
913 success = numered_dofs_ptr[ss]->modify(
917 if (PetscUnlikely(!success))
919 "modification unsuccessful");
921 success = numered_dofs_ptr[ss]->modify(
925 if (PetscUnlikely(!success))
927 "modification unsuccessful");
932 if (PetscUnlikely(ddit->get()->getPStatus() == 0)) {
939 std::ostringstream zz;
940 zz << **ddit << std::endl;
942 "data inconsistency, dofs is not shared, but received "
957 CHKERR PetscFree(olengths_rows);
958 CHKERR PetscFree(rbuf_row[0]);
959 CHKERR PetscFree(rbuf_row);
960 if (!square_matrix) {
961 CHKERR PetscFree(olengths_cols);
962 CHKERR PetscFree(rbuf_col[0]);
963 CHKERR PetscFree(rbuf_col);
967 if (numered_dofs_ptr[0]->size() != numered_dofs_ptr[1]->size()) {
969 "data inconsistency for square_matrix %d!=%d",
970 numered_dofs_ptr[0]->size(), numered_dofs_ptr[1]->size());
974 "data inconsistency for square_matrix");
987 const std::string out_name,
989 const std::vector<std::string> &fields_row,
990 const std::vector<std::string> &fields_col,
992 const std::string main_problem,
const bool square_matrix,
994 const map<std::string, boost::shared_ptr<Range>> *entityMapRow,
995 const map<std::string, boost::shared_ptr<Range>> *entityMapCol,
1005 using ProblemByName = decltype(problems_ptr->get<
Problem_mi_tag>());
1006 auto &problems_by_name =
1007 const_cast<ProblemByName &
>(problems_ptr->get<
Problem_mi_tag>());
1010 auto out_problem_it = problems_by_name.find(out_name);
1011 if (out_problem_it == problems_by_name.end()) {
1013 "subproblem with name < %s > not defined (top tip check spelling)",
1018 auto main_problem_it = problems_by_name.find(main_problem);
1019 if (main_problem_it == problems_by_name.end()) {
1021 "problem of subproblem with name < %s > not defined (top tip "
1023 main_problem.c_str());
1027 boost::shared_ptr<NumeredDofEntity_multiIndex> out_problem_dofs[] = {
1028 out_problem_it->numeredRowDofsPtr, out_problem_it->numeredColDofsPtr};
1030 boost::shared_ptr<NumeredDofEntity_multiIndex> main_problem_dofs[] = {
1031 main_problem_it->numeredRowDofsPtr, main_problem_it->numeredColDofsPtr};
1033 int *nb_local_dofs[] = {&out_problem_it->nbLocDofsRow,
1034 &out_problem_it->nbLocDofsCol};
1036 int *nb_dofs[] = {&out_problem_it->nbDofsRow, &out_problem_it->nbDofsCol};
1040 out_problem_it->nbGhostDofsRow = 0;
1041 out_problem_it->nbGhostDofsCol = 0;
1045 std::vector<std::string> fields[] = {fields_row, fields_col};
1046 const map<std::string, boost::shared_ptr<Range>> *entityMap[] = {
1047 entityMapRow, entityMapCol};
1050 out_problem_it->subProblemData =
1051 boost::make_shared<Problem::SubProblemData>();
1054 for (
int ss = 0; ss != (square_matrix ? 1 : 2); ++ss) {
1057 (*nb_local_dofs[ss]) = 0;
1060 out_problem_dofs[ss]->clear();
1063 out_problem_it->numeredFiniteElementsPtr->clear();
1066 for (
auto field : fields[ss]) {
1072 boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array =
1073 boost::make_shared<std::vector<NumeredDofEntity>>();
1076 out_problem_it->getRowDofsSequence()->emplace_back(dofs_array);
1078 out_problem_it->getColDofsSequence()->emplace_back(dofs_array);
1083 auto add_dit_to_dofs_array = [&](
auto &dit) {
1084 if (dit->get()->getPetscGlobalDofIdx() >= 0)
1085 dofs_array->emplace_back(
1086 dit->get()->getDofEntityPtr(), dit->get()->getPetscGlobalDofIdx(),
1087 dit->get()->getPetscGlobalDofIdx(),
1088 dit->get()->getPetscLocalDofIdx(), dit->get()->getPart());
1091 auto get_dafult_dof_range = [&]() {
1092 auto dit = main_problem_dofs[ss]->get<
Unique_mi_tag>().lower_bound(
1094 auto hi_dit = main_problem_dofs[ss]->get<
Unique_mi_tag>().upper_bound(
1096 return std::make_pair(dit, hi_dit);
1099 auto check = [&](
auto &field) -> boost::shared_ptr<Range> {
1100 if (entityMap[ss]) {
1101 auto mit = entityMap[ss]->find(field);
1102 if (mit != entityMap[ss]->end()) {
1112 if (
auto r_ptr = check(field)) {
1113 for (
auto p = r_ptr->pair_begin(); p != r_ptr->pair_end(); ++p) {
1114 const auto lo_ent = p->first;
1115 const auto hi_ent = p->second;
1116 auto dit = main_problem_dofs[ss]->get<
Unique_mi_tag>().lower_bound(
1118 auto hi_dit = main_problem_dofs[ss]->get<
Unique_mi_tag>().upper_bound(
1120 dofs_array->reserve(std::distance(dit, hi_dit));
1121 for (; dit != hi_dit; dit++) {
1122 add_dit_to_dofs_array(dit);
1126 auto [dit, hi_dit] = get_dafult_dof_range();
1127 dofs_array->reserve(std::distance(dit, hi_dit));
1128 for (; dit != hi_dit; dit++)
1129 add_dit_to_dofs_array(dit);
1133 auto hint = out_problem_dofs[ss]->end();
1134 for (
auto &
v : *dofs_array)
1135 hint = out_problem_dofs[ss]->emplace_hint(hint, dofs_array, &
v);
1139 auto dit = out_problem_dofs[ss]->get<
Idx_mi_tag>().begin();
1140 auto hi_dit = out_problem_dofs[ss]->get<
Idx_mi_tag>().end();
1141 for (; dit != hi_dit; dit++) {
1143 if (dit->get()->getPart() == (
unsigned int)m_field.
get_comm_rank()) {
1144 idx = (*nb_local_dofs[ss])++;
1146 bool success = out_problem_dofs[ss]->modify(
1147 out_problem_dofs[ss]->project<0>(dit),
1151 "operation unsuccessful");
1161 out_problem_dofs[ss]->size());
1162 const int nb = std::distance(dit, hi_dit);
1164 std::vector<int> main_indices(nb);
1165 for (
auto it = main_indices.begin(); dit != hi_dit; dit++, it++) {
1166 *it = dit->get()->getPetscGlobalDofIdx();
1170 CHKERR ISCreateGeneral(m_field.
get_comm(), nb, &*main_indices.begin(),
1171 PETSC_USE_POINTER, &is);
1175 CHKERR AOCreateMappingIS(is, PETSC_NULL, &ao);
1178 CHKERR ISDuplicate(is, &is_dup);
1183 CHKERR ISDuplicate(is, &is_dup);
1187 CHKERR AOApplicationToPetscIS(ao, is);
1189 CHKERR ISGetSize(is, nb_dofs[ss]);
1193 for (std::vector<int>::iterator it = main_indices.begin(); dit != hi_dit;
1195 bool success = out_problem_dofs[ss]->modify(
1196 out_problem_dofs[ss]->project<0>(dit),
1198 dit->get()->getPart(), *it, *it,
1199 dit->get()->getPetscLocalDofIdx()));
1202 "operation unsuccessful");
1207 NumeredDofEntityByLocalIdx::iterator dit =
1209 NumeredDofEntityByLocalIdx::iterator hi_dit =
1211 const int nb = std::distance(dit, hi_dit);
1212 std::vector<int> main_indices_non_local(nb);
1213 for (
auto it = main_indices_non_local.begin(); dit != hi_dit;
1215 *it = dit->get()->getPetscGlobalDofIdx();
1219 &*main_indices_non_local.begin(),
1220 PETSC_USE_POINTER, &is);
1221 CHKERR AOApplicationToPetscIS(ao, is);
1224 for (
auto it = main_indices_non_local.begin(); dit != hi_dit;
1226 bool success = out_problem_dofs[ss]->modify(
1227 out_problem_dofs[ss]->project<0>(dit),
1229 dit->get()->getPart(), dit->get()->getDofIdx(), *it,
1230 dit->get()->getPetscLocalDofIdx()));
1233 "operation unsuccessful");
1241 if (square_matrix) {
1242 out_problem_it->numeredColDofsPtr = out_problem_it->numeredRowDofsPtr;
1243 out_problem_it->nbLocDofsCol = out_problem_it->nbLocDofsRow;
1244 out_problem_it->nbDofsCol = out_problem_it->nbDofsRow;
1245 out_problem_it->getSubData()->colIs = out_problem_it->getSubData()->rowIs;
1246 out_problem_it->getSubData()->colMap = out_problem_it->getSubData()->rowMap;
1256 const std::string out_name,
const std::vector<std::string> add_row_problems,
1257 const std::vector<std::string> add_col_problems,
const bool square_matrix,
1272 ProblemByName &problems_by_name =
1273 const_cast<ProblemByName &
>(problems_ptr->get<
Problem_mi_tag>());
1276 ProblemByName::iterator out_problem_it = problems_by_name.find(out_name);
1277 if (out_problem_it == problems_by_name.end()) {
1279 "problem with name < %s > not defined (top tip check spelling)",
1283 out_problem_it->composedProblemsData =
1284 boost::make_shared<ComposedProblemsData>();
1285 boost::shared_ptr<ComposedProblemsData> cmp_prb_data =
1286 out_problem_it->getComposedProblemsData();
1288 const std::vector<std::string> *add_prb[] = {&add_row_problems,
1290 std::vector<const Problem *> *add_prb_ptr[] = {&cmp_prb_data->rowProblemsAdd,
1291 &cmp_prb_data->colProblemsAdd};
1292 std::vector<SmartPetscObj<IS>> *add_prb_is[] = {&cmp_prb_data->rowIs,
1293 &cmp_prb_data->colIs};
1296 int *nb_local_dofs[] = {&out_problem_it->nbLocDofsRow,
1297 &out_problem_it->nbLocDofsCol};
1299 int *nb_dofs[] = {&out_problem_it->nbDofsRow, &out_problem_it->nbDofsCol};
1303 out_problem_it->nbDofsRow = 0;
1304 out_problem_it->nbDofsCol = 0;
1305 out_problem_it->nbLocDofsRow = 0;
1306 out_problem_it->nbLocDofsCol = 0;
1307 out_problem_it->nbGhostDofsRow = 0;
1308 out_problem_it->nbGhostDofsCol = 0;
1310 int nb_dofs_reserve[] = {0, 0};
1313 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1314 add_prb_ptr[ss]->reserve(add_prb[ss]->size());
1315 add_prb_is[ss]->reserve(add_prb[ss]->size());
1316 for (std::vector<std::string>::const_iterator vit = add_prb[ss]->begin();
1317 vit != add_prb[ss]->end(); vit++) {
1318 ProblemByName::iterator prb_it = problems_by_name.find(*vit);
1319 if (prb_it == problems_by_name.end()) {
1322 "problem with name < %s > not defined (top tip check spelling)",
1325 add_prb_ptr[ss]->push_back(&*prb_it);
1329 *nb_dofs[ss] += add_prb_ptr[ss]->back()->getNbDofsRow();
1330 *nb_local_dofs[ss] += add_prb_ptr[ss]->back()->getNbLocalDofsRow();
1331 nb_dofs_reserve[ss] +=
1332 add_prb_ptr[ss]->back()->numeredRowDofsPtr->size();
1335 *nb_dofs[ss] += add_prb_ptr[ss]->back()->getNbDofsCol();
1336 *nb_local_dofs[ss] += add_prb_ptr[ss]->back()->getNbLocalDofsCol();
1337 nb_dofs_reserve[ss] +=
1338 add_prb_ptr[ss]->back()->numeredColDofsPtr->size();
1343 if (square_matrix) {
1344 add_prb_ptr[1]->reserve(add_prb_ptr[0]->size());
1345 add_prb_is[1]->reserve(add_prb_ptr[0]->size());
1346 out_problem_it->numeredColDofsPtr = out_problem_it->numeredRowDofsPtr;
1347 *nb_dofs[1] = *nb_dofs[0];
1348 *nb_local_dofs[1] = *nb_local_dofs[0];
1352 boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array[2];
1354 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1355 dofs_array[ss] = boost::make_shared<std::vector<NumeredDofEntity>>();
1356 dofs_array[ss]->reserve(nb_dofs_reserve[ss]);
1358 out_problem_it->getRowDofsSequence()->emplace_back(dofs_array[ss]);
1360 out_problem_it->getColDofsSequence()->emplace_back(dofs_array[ss]);
1364 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1365 NumeredDofEntity_multiIndex::index<PetscGlobalIdx_mi_tag>::type::iterator
1370 for (
unsigned int pp = 0; pp != add_prb_ptr[ss]->size(); pp++) {
1371 PetscInt *dofs_out_idx_ptr;
1372 int nb_local_dofs = (*add_prb_ptr[ss])[pp]->getNbLocalDofsRow();
1373 CHKERR PetscMalloc(nb_local_dofs *
sizeof(
int), &dofs_out_idx_ptr);
1375 dit = (*add_prb_ptr[ss])[pp]
1378 hi_dit = (*add_prb_ptr[ss])[pp]
1382 dit = (*add_prb_ptr[ss])[pp]
1385 hi_dit = (*add_prb_ptr[ss])[pp]
1390 for (; dit != hi_dit; dit++) {
1391 const BitRefLevel &prb_bit = out_problem_it->getBitRefLevel();
1392 const BitRefLevel &prb_mask = out_problem_it->getBitRefLevelMask();
1393 const BitRefLevel &dof_bit = dit->get()->getBitRefLevel();
1394 if ((dof_bit & prb_bit).none() || ((dof_bit & prb_mask) != dof_bit))
1397 const int part = dit->get()->getPart();
1398 const int glob_idx = shift_glob + dit->get()->getPetscGlobalDofIdx();
1400 (part == rank) ? (shift_loc + dit->get()->getPetscLocalDofIdx())
1402 dofs_array[ss]->emplace_back(dit->get()->getDofEntityPtr(), glob_idx,
1403 glob_idx, loc_idx, part);
1405 dofs_out_idx_ptr[is_nb++] = glob_idx;
1408 if (is_nb > nb_local_dofs) {
1410 "Data inconsistency");
1413 CHKERR ISCreateGeneral(m_field.
get_comm(), is_nb, dofs_out_idx_ptr,
1414 PETSC_OWN_POINTER, &is);
1416 (*add_prb_is[ss]).push_back(smart_is);
1418 shift_glob += (*add_prb_ptr[ss])[pp]->getNbDofsRow();
1419 shift_loc += (*add_prb_ptr[ss])[pp]->getNbLocalDofsRow();
1421 shift_glob += (*add_prb_ptr[ss])[pp]->getNbDofsCol();
1422 shift_loc += (*add_prb_ptr[ss])[pp]->getNbLocalDofsCol();
1424 if (square_matrix) {
1425 (*add_prb_ptr[1]).push_back((*add_prb_ptr[0])[pp]);
1426 (*add_prb_is[1]).push_back(smart_is);
1431 if ((*add_prb_is[1]).size() != (*add_prb_is[0]).size()) {
1436 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1437 auto hint = (ss == 0) ? out_problem_it->numeredRowDofsPtr->end()
1438 : out_problem_it->numeredColDofsPtr->end();
1439 for (
auto &
v : *dofs_array[ss])
1440 hint = (ss == 0) ? out_problem_it->numeredRowDofsPtr->emplace_hint(
1441 hint, dofs_array[ss], &
v)
1442 : out_problem_it->numeredColDofsPtr->emplace_hint(
1443 hint, dofs_array[ss], &
v);
1449 *nb_local_dofs[0] = 0;
1450 *nb_local_dofs[1] = 0;
1451 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1453 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs_ptr;
1455 dofs_ptr = out_problem_it->numeredRowDofsPtr;
1457 dofs_ptr = out_problem_it->numeredColDofsPtr;
1459 NumeredDofEntityByUId::iterator dit, hi_dit;
1462 std::vector<int> idx;
1463 idx.reserve(std::distance(dit, hi_dit));
1465 for (; dit != hi_dit; dit++) {
1466 if (dit->get()->getPart() == (
unsigned int)m_field.
get_comm_rank()) {
1471 "modification unsuccessful");
1473 idx.push_back(dit->get()->getPetscGlobalDofIdx());
1475 if (dit->get()->getPetscLocalDofIdx() != -1) {
1477 "local index should be negative");
1481 if (square_matrix) {
1482 *nb_local_dofs[1] = *nb_local_dofs[0];
1487 CHKERR ISCreateGeneral(m_field.
get_comm(), idx.size(), &*idx.begin(),
1488 PETSC_USE_POINTER, &is);
1489 CHKERR ISGetSize(is, nb_dofs[ss]);
1490 if (square_matrix) {
1491 *nb_dofs[1] = *nb_dofs[0];
1495 CHKERR AOCreateMappingIS(is, PETSC_NULL, &ao);
1496 for (
unsigned int pp = 0; pp != (*add_prb_is[ss]).size(); pp++)
1497 CHKERR AOApplicationToPetscIS(ao, (*add_prb_is[ss])[pp]);
1501 std::vector<int> idx_new;
1502 idx_new.reserve(dofs_ptr->size());
1503 for (NumeredDofEntityByUId::iterator dit =
1506 idx_new.push_back(dit->get()->getPetscGlobalDofIdx());
1511 &*idx_new.begin(), PETSC_USE_POINTER, &is_new);
1512 CHKERR AOApplicationToPetscIS(ao, is_new);
1514 std::vector<int>::iterator vit = idx_new.begin();
1515 for (NumeredDofEntityByUId::iterator dit =
1520 dit->get()->getPart(), *(vit++)));
1523 "modification unsuccessful");
1526 CHKERR ISDestroy(&is_new);
1557 MOFEM_LOG(
"WORLD", Sev::verbose) <<
"Simple partition problem " << name;
1561 ProblemByName &problems_set =
1562 const_cast<ProblemByName &
>(problems_ptr->get<
Problem_mi_tag>());
1563 ProblemByName::iterator p_miit = problems_set.find(name);
1564 if (p_miit == problems_set.end()) {
1565 SETERRQ1(PETSC_COMM_SELF, 1,
1566 "problem < %s > is not found (top tip: check spelling)",
1571 NumeredDofEntitysByIdx &dofs_row_by_idx =
1572 p_miit->numeredRowDofsPtr->get<
Idx_mi_tag>();
1573 NumeredDofEntitysByIdx &dofs_col_by_idx =
1574 p_miit->numeredColDofsPtr->get<
Idx_mi_tag>();
1581 DofIdx &nb_row_local_dofs = p_miit->nbLocDofsRow;
1582 DofIdx &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
1583 nb_row_local_dofs = 0;
1584 nb_row_ghost_dofs = 0;
1585 DofIdx &nb_col_local_dofs = p_miit->nbLocDofsCol;
1586 DofIdx &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
1587 nb_col_local_dofs = 0;
1588 nb_col_ghost_dofs = 0;
1590 bool square_matrix =
false;
1591 if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr) {
1592 square_matrix =
true;
1596 PetscLayout layout_row;
1597 const int *ranges_row;
1599 DofIdx nb_dofs_row = dofs_row_by_idx.size();
1601 CHKERR PetscLayoutSetBlockSize(layout_row, 1);
1602 CHKERR PetscLayoutSetSize(layout_row, nb_dofs_row);
1603 CHKERR PetscLayoutSetUp(layout_row);
1604 CHKERR PetscLayoutGetRanges(layout_row, &ranges_row);
1606 PetscLayout layout_col;
1607 const int *ranges_col;
1608 if (!square_matrix) {
1609 DofIdx nb_dofs_col = dofs_col_by_idx.size();
1611 CHKERR PetscLayoutSetBlockSize(layout_col, 1);
1612 CHKERR PetscLayoutSetSize(layout_col, nb_dofs_col);
1613 CHKERR PetscLayoutSetUp(layout_col);
1614 CHKERR PetscLayoutGetRanges(layout_col, &ranges_col);
1618 miit_row = dofs_row_by_idx.lower_bound(ranges_row[part]);
1619 hi_miit_row = dofs_row_by_idx.lower_bound(ranges_row[part + 1]);
1620 if (std::distance(miit_row, hi_miit_row) !=
1621 ranges_row[part + 1] - ranges_row[part]) {
1623 PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1624 "data inconsistency, std::distance(miit_row,hi_miit_row) != rend - "
1625 "rstart (%d != %d - %d = %d) ",
1626 std::distance(miit_row, hi_miit_row), ranges_row[part + 1],
1627 ranges_row[part], ranges_row[part + 1] - ranges_row[part]);
1630 for (; miit_row != hi_miit_row; miit_row++) {
1631 bool success = dofs_row_by_idx.modify(
1636 "modification unsuccessful");
1638 success = dofs_row_by_idx.modify(
1642 "modification unsuccessful");
1645 if (!square_matrix) {
1646 miit_col = dofs_col_by_idx.lower_bound(ranges_col[part]);
1647 hi_miit_col = dofs_col_by_idx.lower_bound(ranges_col[part + 1]);
1648 if (std::distance(miit_col, hi_miit_col) !=
1649 ranges_col[part + 1] - ranges_col[part]) {
1650 SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1651 "data inconsistency, std::distance(miit_col,hi_miit_col) != "
1653 "rstart (%d != %d - %d = %d) ",
1654 std::distance(miit_col, hi_miit_col), ranges_col[part + 1],
1655 ranges_col[part], ranges_col[part + 1] - ranges_col[part]);
1658 for (; miit_col != hi_miit_col; miit_col++) {
1659 bool success = dofs_col_by_idx.modify(
1661 part, (*miit_col)->dofIdx));
1664 "modification unsuccessful");
1666 success = dofs_col_by_idx.modify(
1670 "modification unsuccessful");
1675 CHKERR PetscLayoutDestroy(&layout_row);
1676 if (!square_matrix) {
1677 CHKERR PetscLayoutDestroy(&layout_col);
1679 if (square_matrix) {
1680 nb_col_local_dofs = nb_row_local_dofs;
1681 nb_col_ghost_dofs = nb_row_ghost_dofs;
1694 MOFEM_LOG(
"WORLD", Sev::noisy) <<
"Partition problem " << name;
1696 using NumeredDofEntitysByIdx =
1701 auto &problems_set =
1702 const_cast<ProblemsByName &
>(problems_ptr->get<
Problem_mi_tag>());
1703 auto p_miit = problems_set.find(name);
1704 if (p_miit == problems_set.end()) {
1706 "problem with name %s not defined (top tip check spelling)",
1709 int nb_dofs_row = p_miit->getNbDofsRow();
1719 "entFEAdjacencies not build");
1725 ->createMPIAdjWithArrays<Idx_mi_tag>(name, &Adj, verb);
1730 MatView(Adj, PETSC_VIEWER_STDOUT_WORLD);
1733 MatPartitioning part;
1736 CHKERR MatPartitioningSetAdjacency(part, Adj);
1737 CHKERR MatPartitioningSetFromOptions(part);
1739 CHKERR MatPartitioningApply(part, &is);
1741 ISView(is, PETSC_VIEWER_STDOUT_WORLD);
1744 IS is_gather, is_num, is_gather_num;
1745 CHKERR ISAllGather(is, &is_gather);
1746 CHKERR ISPartitioningToNumbering(is, &is_num);
1747 CHKERR ISAllGather(is_num, &is_gather_num);
1748 const int *part_number, *petsc_idx;
1749 CHKERR ISGetIndices(is_gather, &part_number);
1750 CHKERR ISGetIndices(is_gather_num, &petsc_idx);
1751 int size_is_num, size_is_gather;
1752 CHKERR ISGetSize(is_gather, &size_is_gather);
1753 if (size_is_gather != (
int)nb_dofs_row)
1754 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1755 "data inconsistency %d != %d", size_is_gather, nb_dofs_row);
1757 CHKERR ISGetSize(is_num, &size_is_num);
1758 if (size_is_num != (
int)nb_dofs_row)
1759 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1760 "data inconsistency %d != %d", size_is_num, nb_dofs_row);
1762 bool square_matrix =
false;
1763 if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr)
1764 square_matrix =
true;
1791 auto number_dofs = [&](
auto &dofs_idx,
auto &counter) {
1793 for (
auto miit_dofs_row = dofs_idx.begin();
1794 miit_dofs_row != dofs_idx.end(); miit_dofs_row++) {
1795 const int part = part_number[(*miit_dofs_row)->dofIdx];
1797 const bool success = dofs_idx.modify(
1800 part, petsc_idx[(*miit_dofs_row)->dofIdx], counter++));
1803 "modification unsuccessful");
1806 const bool success = dofs_idx.modify(
1808 part, petsc_idx[(*miit_dofs_row)->dofIdx]));
1811 "modification unsuccessful");
1819 auto &dofs_row_by_idx_no_const =
const_cast<NumeredDofEntitysByIdx &
>(
1820 p_miit->numeredRowDofsPtr->get<
Idx_mi_tag>());
1821 int &nb_row_local_dofs = p_miit->nbLocDofsRow;
1822 int &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
1823 nb_row_local_dofs = 0;
1824 nb_row_ghost_dofs = 0;
1826 CHKERR number_dofs(dofs_row_by_idx_no_const, nb_row_local_dofs);
1828 int &nb_col_local_dofs = p_miit->nbLocDofsCol;
1829 int &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
1830 if (square_matrix) {
1831 nb_col_local_dofs = nb_row_local_dofs;
1832 nb_col_ghost_dofs = nb_row_ghost_dofs;
1834 NumeredDofEntitysByIdx &dofs_col_by_idx_no_const =
1835 const_cast<NumeredDofEntitysByIdx &
>(
1836 p_miit->numeredColDofsPtr->get<
Idx_mi_tag>());
1837 nb_col_local_dofs = 0;
1838 nb_col_ghost_dofs = 0;
1839 CHKERR number_dofs(dofs_col_by_idx_no_const, nb_col_local_dofs);
1842 CHKERR ISRestoreIndices(is_gather, &part_number);
1843 CHKERR ISRestoreIndices(is_gather_num, &petsc_idx);
1844 CHKERR ISDestroy(&is_num);
1845 CHKERR ISDestroy(&is_gather_num);
1846 CHKERR ISDestroy(&is_gather);
1848 CHKERR MatPartitioningDestroy(&part);
1853 auto number_dofs = [&](
auto &dof_idx,
auto &counter) {
1855 for (
auto miit_dofs_row = dof_idx.begin(); miit_dofs_row != dof_idx.end();
1857 const bool success = dof_idx.modify(
1863 "modification unsuccessful");
1869 auto &dofs_row_by_idx_no_const =
const_cast<NumeredDofEntitysByIdx &
>(
1870 p_miit->numeredRowDofsPtr->get<
Idx_mi_tag>());
1871 int &nb_row_local_dofs = p_miit->nbLocDofsRow;
1872 int &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
1873 nb_row_local_dofs = 0;
1874 nb_row_ghost_dofs = 0;
1876 CHKERR number_dofs(dofs_row_by_idx_no_const, nb_row_local_dofs);
1878 bool square_matrix =
false;
1879 if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr)
1880 square_matrix =
true;
1882 int &nb_col_local_dofs = p_miit->nbLocDofsCol;
1883 int &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
1884 if (square_matrix) {
1885 nb_col_local_dofs = nb_row_local_dofs;
1886 nb_col_ghost_dofs = nb_row_ghost_dofs;
1888 NumeredDofEntitysByIdx &dofs_col_by_idx_no_const =
1889 const_cast<NumeredDofEntitysByIdx &
>(
1890 p_miit->numeredColDofsPtr->get<
Idx_mi_tag>());
1891 nb_col_local_dofs = 0;
1892 nb_col_ghost_dofs = 0;
1893 CHKERR number_dofs(dofs_col_by_idx_no_const, nb_col_local_dofs);
1902 const std::string name,
const std::string problem_for_rows,
bool copy_rows,
1903 const std::string problem_for_cols,
bool copy_cols,
int verb) {
1914 ProblemByName &problems_by_name =
1915 const_cast<ProblemByName &
>(problems_ptr->get<
Problem_mi_tag>());
1916 ProblemByName::iterator p_miit = problems_by_name.find(name);
1917 if (p_miit == problems_by_name.end()) {
1919 "problem with name < %s > not defined (top tip check spelling)",
1924 << p_miit->getName() <<
" from rows of " << problem_for_rows
1925 <<
" and columns of " << problem_for_cols;
1928 ProblemByName::iterator p_miit_row = problems_by_name.find(problem_for_rows);
1929 if (p_miit_row == problems_by_name.end()) {
1931 "problem with name < %s > not defined (top tip check spelling)",
1932 problem_for_rows.c_str());
1934 const boost::shared_ptr<NumeredDofEntity_multiIndex> dofs_row =
1935 p_miit_row->numeredRowDofsPtr;
1938 ProblemByName::iterator p_miit_col = problems_by_name.find(problem_for_cols);
1939 if (p_miit_col == problems_by_name.end()) {
1941 "problem with name < %s > not defined (top tip check spelling)",
1942 problem_for_cols.c_str());
1944 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs_col =
1945 p_miit_col->numeredColDofsPtr;
1947 bool copy[] = {copy_rows, copy_cols};
1948 boost::shared_ptr<NumeredDofEntity_multiIndex> composed_dofs[] = {
1949 p_miit->numeredRowDofsPtr, p_miit->numeredColDofsPtr};
1951 int *nb_local_dofs[] = {&p_miit->nbLocDofsRow, &p_miit->nbLocDofsCol};
1952 int *nb_dofs[] = {&p_miit->nbDofsRow, &p_miit->nbDofsCol};
1953 boost::shared_ptr<NumeredDofEntity_multiIndex> copied_dofs[] = {dofs_row,
1956 for (
int ss = 0; ss < 2; ss++) {
1959 *nb_local_dofs[ss] = 0;
1963 std::vector<int> is_local, is_new;
1967 for (NumeredDofEntity_multiIndex::iterator dit =
1968 composed_dofs[ss]->begin();
1969 dit != composed_dofs[ss]->end(); dit++) {
1970 NumeredDofEntityByUId::iterator diit =
1971 dofs_by_uid.find((*dit)->getLocalUniqueId());
1972 if (diit == dofs_by_uid.end()) {
1975 "data inconsistency, could not find dof in composite problem");
1977 int part_number = (*diit)->getPart();
1978 int petsc_global_dof = (*diit)->getPetscGlobalDofIdx();
1980 success = composed_dofs[ss]->modify(
1985 "modification unsuccessful");
1987 if ((*dit)->getPart() == (
unsigned int)m_field.
get_comm_rank()) {
1988 success = composed_dofs[ss]->modify(
1992 "modification unsuccessful");
1994 is_local.push_back(petsc_global_dof);
1999 CHKERR AOCreateMapping(m_field.
get_comm(), is_local.size(), &is_local[0],
2004 for (NumeredDofEntity_multiIndex::iterator dit =
2005 composed_dofs[ss]->begin();
2006 dit != composed_dofs[ss]->end(); dit++) {
2007 is_local.push_back((*dit)->getPetscGlobalDofIdx());
2009 CHKERR AOPetscToApplication(ao, is_local.size(), &is_local[0]);
2011 for (NumeredDofEntity_multiIndex::iterator dit =
2012 composed_dofs[ss]->begin();
2013 dit != composed_dofs[ss]->end(); dit++) {
2014 int part_number = (*dit)->getPart();
2015 int petsc_global_dof = is_local[idx2++];
2017 success = composed_dofs[ss]->modify(
2022 "modification unsuccessful");
2030 for (NumeredDofEntity_multiIndex::iterator dit = copied_dofs[ss]->begin();
2031 dit != copied_dofs[ss]->end(); dit++) {
2032 std::pair<NumeredDofEntity_multiIndex::iterator, bool> p;
2033 p = composed_dofs[ss]->insert(boost::shared_ptr<NumeredDofEntity>(
2038 int dof_idx = (*dit)->getDofIdx();
2039 int part_number = (*dit)->getPart();
2040 int petsc_global_dof = (*dit)->getPetscGlobalDofIdx();
2042 const bool success = composed_dofs[ss]->modify(
2044 part_number, dof_idx, petsc_global_dof,
2045 (*nb_local_dofs[ss])++));
2048 "modification unsuccessful");
2051 const bool success = composed_dofs[ss]->modify(
2053 part_number, dof_idx, petsc_global_dof));
2056 "modification unsuccessful");
2077 << problem_ptr->
getName() <<
" Nb. local dof "
2097 CHKERR moab.create_meshset(MESHSET_SET, out_meshset);
2098 CHKERR moab.add_entities(out_meshset, &ent, 1);
2099 CHKERR moab.write_file(name.c_str(),
"VTK",
"", &out_meshset, 1);
2100 CHKERR moab.delete_entities(&out_meshset, 1);
2107 NumeredDofEntitysByIdx;
2108 NumeredDofEntitysByIdx::iterator dit, hi_dit;
2109 const NumeredDofEntitysByIdx *numered_dofs_ptr[] = {
2117 for (
int ss = 0; ss < 2; ss++) {
2119 dit = numered_dofs_ptr[ss]->begin();
2120 hi_dit = numered_dofs_ptr[ss]->end();
2121 for (; dit != hi_dit; dit++) {
2123 if ((*dit)->getPetscLocalDofIdx() < 0) {
2124 std::ostringstream zz;
2127 "local dof index for %d (0-row, 1-col) not set, i.e. has "
2128 "negative value\n %s",
2129 ss, zz.str().c_str());
2131 if ((*dit)->getPetscLocalDofIdx() >= *local_nbdof_ptr[ss]) {
2132 std::ostringstream zz;
2135 "local dofs for %d (0-row, 1-col) out of range\n %s", ss,
2139 if ((*dit)->getPetscGlobalDofIdx() < 0) {
2146 "_negative_global_index.vtk",
2149 std::ostringstream zz;
2151 << dit->get()->getBitRefLevel() <<
" " << **dit;
2153 "global dof index for %d (0-row, 1-col) row not set, i.e. "
2154 "has negative value\n %s",
2155 ss, zz.str().c_str());
2157 if ((*dit)->getPetscGlobalDofIdx() >= *nbdof_ptr[ss]) {
2158 std::ostringstream zz;
2160 << *nbdof_ptr[ss] <<
" " << **dit;
2162 "global dofs for %d (0-row, 1-col) out of range\n %s", ss,
2173 bool part_from_moab,
2175 int hi_proc,
int verb) {
2189 "adjacencies not build");
2196 "problem not partitioned");
2206 const_cast<ProblemByName &
>(problems_ptr->get<
Problem_mi_tag>());
2207 ProblemByName::iterator p_miit = problems.find(name);
2208 if (p_miit == problems.end()) {
2210 "problem < %s > not found (top tip: check spelling)",
2216 *p_miit->numeredFiniteElementsPtr;
2219 problem_finite_elements.clear();
2223 bool do_cols_prob =
true;
2224 if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr) {
2225 do_cols_prob =
false;
2228 auto get_good_elems = [&]() {
2229 auto good_elems = std::vector<decltype(fe_ent_ptr->begin())>();
2230 good_elems.reserve(fe_ent_ptr->size());
2232 const auto prb_bit = p_miit->getBitRefLevel();
2233 const auto prb_mask = p_miit->getBitRefLevelMask();
2237 for (
auto efit = fe_ent_ptr->begin(); efit != fe_ent_ptr->end(); ++efit) {
2240 if (((*efit)->getId() & p_miit->getBitFEId()).any()) {
2242 const auto &fe_bit = (*efit)->getBitRefLevel();
2245 if ((fe_bit & prb_mask) == fe_bit && (fe_bit & prb_bit).any())
2246 good_elems.emplace_back(efit);
2253 auto good_elems = get_good_elems();
2255 auto numbered_good_elems_ptr =
2256 boost::make_shared<std::vector<NumeredEntFiniteElement>>();
2257 numbered_good_elems_ptr->reserve(good_elems.size());
2258 for (
auto &efit : good_elems)
2261 if (!do_cols_prob) {
2262 for (
auto &fe : *numbered_good_elems_ptr) {
2263 if (fe.sPtr->getRowFieldEntsPtr() == fe.sPtr->getColFieldEntsPtr()) {
2264 fe.getColFieldEntsPtr() = fe.getRowFieldEntsPtr();
2269 if (part_from_moab) {
2270 for (
auto &fe : *numbered_good_elems_ptr) {
2271 if (fe.getEntType() == MBENTITYSET) {
2275 int proc = fe.getPartProc();
2276 if (proc == -1 && fe.getEntType() == MBVERTEX)
2277 proc = fe.getOwnerProc();
2283 for (
auto &fe : *numbered_good_elems_ptr) {
2286 CHKERR fe.sPtr->getRowDofView(*(p_miit->numeredRowDofsPtr), rows_view);
2288 if (!part_from_moab) {
2289 if (fe.getEntType() == MBENTITYSET) {
2293 for (
auto &dof_ptr : rows_view)
2294 parts[dof_ptr->pArt]++;
2295 std::vector<int>::iterator pos =
2296 max_element(parts.begin(), parts.end());
2297 const auto max_part = std::distance(parts.begin(), pos);
2303 for (
auto &fe : *numbered_good_elems_ptr) {
2305 auto check_fields_and_dofs = [&]() {
2306 if (!part_from_moab) {
2307 if (fe.getBitFieldIdRow().none() && m_field.
get_comm_size() == 0) {
2309 <<
"At least one field has to be added to element row to "
2310 "determine partition of finite element. Check element " +
2311 boost::lexical_cast<std::string>(fe.getName());
2318 if (check_fields_and_dofs()) {
2320 auto p = problem_finite_elements.insert(
2321 boost::shared_ptr<NumeredEntFiniteElement>(numbered_good_elems_ptr,
2329 auto elements_on_rank =
2330 problem_finite_elements.get<
Part_mi_tag>().equal_range(
2333 << p_miit->getName() <<
" nb. elems "
2334 << std::distance(elements_on_rank.first, elements_on_rank.second);
2336 for (
auto &fe : *fe_ptr) {
2342 <<
"Element " << fe->getName() <<
" nb. elems "
2343 << std::distance(e_range.first, e_range.second);
2361 "partition of problem not build");
2364 "partitions finite elements not build");
2373 int &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
2374 int &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
2375 nb_row_ghost_dofs = 0;
2376 nb_col_ghost_dofs = 0;
2386 p_miit->numeredFiniteElementsPtr->get<
Part_mi_tag>().equal_range(
2392 using Vec = std::vector<boost::shared_ptr<NumeredDofEntity>>;
2393 using It = Vec::iterator;
2394 It operator()(
Vec &dofs_view, It &hint,
2395 boost::shared_ptr<NumeredDofEntity> &&dof) {
2396 dofs_view.emplace_back(dof);
2397 return dofs_view.end();
2402 std::vector<boost::shared_ptr<NumeredDofEntity>> fe_vec_view;
2403 auto hint_r = ghost_idx_row_view.begin();
2404 for (
auto fe_ptr = fe_range.first; fe_ptr != fe_range.second; ++fe_ptr) {
2406 fe_vec_view.clear();
2408 *(p_miit->getNumeredRowDofsPtr()),
2409 fe_vec_view, Inserter());
2411 for (
auto &dof_ptr : fe_vec_view) {
2412 if (dof_ptr->getPart() != (
unsigned int)m_field.
get_comm_rank()) {
2413 hint_r = ghost_idx_row_view.emplace_hint(hint_r, dof_ptr);
2419 if (p_miit->numeredColDofsPtr == p_miit->numeredRowDofsPtr) {
2421 auto hint_c = ghost_idx_col_view.begin();
2422 for (
auto fe_ptr = fe_range.first; fe_ptr != fe_range.second; ++fe_ptr) {
2424 fe_vec_view.clear();
2426 *(p_miit->getNumeredColDofsPtr()),
2427 fe_vec_view, Inserter());
2429 for (
auto &dof_ptr : fe_vec_view) {
2430 if (dof_ptr->getPart() != (
unsigned int)m_field.
get_comm_rank()) {
2431 hint_c = ghost_idx_col_view.emplace_hint(hint_c, dof_ptr);
2437 int *nb_ghost_dofs[2] = {&nb_row_ghost_dofs, &nb_col_ghost_dofs};
2438 int nb_local_dofs[2] = {p_miit->nbLocDofsRow, p_miit->nbLocDofsCol};
2441 &ghost_idx_row_view, &ghost_idx_col_view};
2447 if (p_miit->numeredColDofsPtr == p_miit->numeredRowDofsPtr) {
2452 for (
int ss = 0; ss != loop_size; ++ss) {
2453 for (
auto &gid : *ghost_idx_view[ss]) {
2454 NumeredDofEntityByUId::iterator dof =
2455 dof_by_uid_no_const[ss]->find(gid->getLocalUniqueId());
2456 if (PetscUnlikely((*dof)->petscLocalDofIdx != (
DofIdx)-1))
2458 "inconsistent data, ghost dof already set");
2459 bool success = dof_by_uid_no_const[ss]->modify(
2461 if (PetscUnlikely(!success))
2463 "modification unsuccessful");
2464 (*nb_ghost_dofs[ss])++;
2467 if (loop_size == 1) {
2468 (*nb_ghost_dofs[1]) = (*nb_ghost_dofs[0]);
2474 <<
" FEs ghost dofs on problem " << p_miit->getName()
2475 <<
" Nb. ghost dof " << p_miit->getNbGhostDofsRow() <<
" by "
2476 << p_miit->getNbGhostDofsCol() <<
" Nb. local dof "
2477 << p_miit->getNbLocalDofsCol() <<
" by " << p_miit->getNbLocalDofsCol();
2495 "partition of problem not build");
2498 "partitions finite elements not build");
2503 ProblemsByName &problems_set =
2504 const_cast<ProblemsByName &
>(problems_ptr->get<
Problem_mi_tag>());
2505 ProblemsByName::iterator p_miit = problems_set.find(name);
2509 DofIdx *nb_ghost_dofs[2] = {&(p_miit->nbGhostDofsRow),
2510 &(p_miit->nbGhostDofsCol)};
2511 DofIdx nb_local_dofs[2] = {p_miit->nbLocDofsRow, p_miit->nbLocDofsCol};
2512 for (
int ss = 0; ss != 2; ++ss) {
2513 (*nb_ghost_dofs[ss]) = 0;
2520 if (p_miit->numeredColDofsPtr == p_miit->numeredRowDofsPtr) {
2524 typedef decltype(p_miit->numeredRowDofsPtr) NumbDofTypeSharedPtr;
2525 NumbDofTypeSharedPtr numered_dofs[] = {p_miit->numeredRowDofsPtr,
2526 p_miit->numeredColDofsPtr};
2529 for (
int ss = 0; ss != loop_size; ++ss) {
2534 std::vector<NumeredDofEntity_multiIndex::iterator> ghost_idx_view;
2535 ghost_idx_view.reserve(std::distance(
r.first,
r.second));
2536 for (;
r.first !=
r.second; ++
r.first)
2537 ghost_idx_view.emplace_back(numered_dofs[ss]->project<0>(
r.first));
2539 auto cmp = [](
auto a,
auto b) {
2540 return (*a)->getLocalUniqueId() < (*b)->getLocalUniqueId();
2542 sort(ghost_idx_view.begin(), ghost_idx_view.end(), cmp);
2545 for (
auto gid_it : ghost_idx_view) {
2546 bool success = numered_dofs[ss]->modify(
2550 "modification unsuccessful");
2551 ++(*nb_ghost_dofs[ss]);
2554 if (loop_size == 1) {
2555 (*nb_ghost_dofs[1]) = (*nb_ghost_dofs[0]);
2561 <<
" FEs ghost dofs on problem " << p_miit->getName()
2562 <<
" Nb. ghost dof " << p_miit->getNbGhostDofsRow() <<
" by "
2563 << p_miit->getNbGhostDofsCol() <<
" Nb. local dof "
2564 << p_miit->getNbLocalDofsCol() <<
" by " << p_miit->getNbLocalDofsCol();
2574 const std::string &fe_name,
2590 0, (*fe_miit)->getFEUId()));
2594 get_id_for_max_type<MBENTITYSET>(), (*fe_miit)->getFEUId()));
2595 std::vector<EntityHandle> fe_vec;
2596 fe_vec.reserve(std::distance(fit, hi_fe_it));
2597 for (; fit != hi_fe_it; fit++)
2598 fe_vec.push_back(fit->get()->getEnt());
2599 CHKERR m_field.
get_moab().add_entities(*meshset, &*fe_vec.begin(),
2608 const std::string &fe_name,
2609 PetscLayout *layout)
const {
2621 std::vector<boost::weak_ptr<NumeredDofEntity>> &vec_dof_view,
2624 const Range ents,
int bridge_dim,
const int lo_coeff,
const int hi_coeff,
2625 const int lo_order,
const int hi_order,
int verb,
const bool debug
2650 ents, bridge_dim,
false, bridge_ents, moab::Interface::UNION);
2654 const auto nb_coeffs =
2659 using NumeredDofEntity_it_view_multiIndex = multi_index_container<
2661 NumeredDofEntity_multiIndex::iterator, indexed_by<sequenced<>>
2664 NumeredDofEntity_it_view_multiIndex dofs_it_view;
2666 for (
auto pit = bridge_ents.const_pair_begin();
2667 pit != bridge_ents.const_pair_end(); ++pit) {
2668 auto lo = numered_dofs[rc]->get<
Unique_mi_tag>().lower_bound(
2670 auto hi = numered_dofs[rc]->get<
Unique_mi_tag>().upper_bound(
2673 auto bride_type = moab.type_from_handle(pit->first);
2675 for (; lo != hi; ++lo) {
2676 if ((*lo)->getDofCoeffIdx() >= lo_coeff &&
2677 (*lo)->getDofCoeffIdx() <= hi_coeff &&
2678 (*lo)->getDofOrder() >= lo_order &&
2679 (*lo)->getDofOrder() <= hi_order) {
2680 auto ent_dof_index = (*lo)->getEntDofIdx();
2681 auto side_it = side_dof_map.at(bride_type)
2683 .find(std::floor(
static_cast<double>(ent_dof_index) /
2687 auto bridge_ent = (*lo)->getEnt();
2688 auto type = side_it->type;
2689 auto side = side_it->side;
2690 auto dim = CN::Dimension(
type);
2692 CHKERR moab.side_element(bridge_ent, dim, side, side_ent);
2693 if (ents.find(side_ent) != ents.end()) {
2694 dofs_it_view.emplace_back(numered_dofs[rc]->project<0>(lo));
2701 <<
"side not found for entity " << CN::EntityTypeName(bride_type);
2703 <<
"ent_dof_index / nb_coeffs "
2704 << std::floor(
static_cast<double>(ent_dof_index) / nb_coeffs);
2706 <<
"side_dof_map.size() " << side_dof_map.size();
2709 "side not found - you will get more information in debug");
2716 for (
auto &dof : dofs_it_view)
2721 vec_dof_view.reserve(vec_dof_view.size() + dofs_it_view.size());
2722 for (
auto dit : dofs_it_view)
2723 vec_dof_view.push_back(*dit);
2729 const std::string problem_name,
RowColData rc,
2730 std::vector<boost::weak_ptr<NumeredDofEntity>> &vec_dof_view,
int verb,
2762 if (numered_dofs[rc]) {
2766 "Number of DOFs in multi-index %d and to delete %d\n",
2767 numered_dofs[rc]->size(), vec_dof_view.size());
2770 for (
auto weak_dit : vec_dof_view)
2771 if (
auto dit = weak_dit.lock()) {
2772 numered_dofs[rc]->erase(dit->getLocalUniqueId());
2777 "Number of DOFs in multi-index after delete %d\n",
2778 numered_dofs[rc]->size());
2781 int nb_local_dofs = 0;
2782 int nb_ghost_dofs = 0;
2783 for (
auto dit = numered_dofs[rc]->get<PetscLocalIdx_mi_tag>().begin();
2785 if ((*dit)->getPetscLocalDofIdx() >= 0 &&
2786 (*dit)->getPetscLocalDofIdx() < *(local_nbdof_ptr[rc]))
2788 else if ((*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[rc]))
2792 "Impossible case. You could run problem on no distributed "
2793 "mesh. That is not implemented. Dof local index is %d",
2794 (*dit)->getPetscLocalDofIdx());
2798 auto get_indices_by_tag = [&](
auto tag,
auto &indices,
bool only_local) {
2799 const int nb_dofs = numered_dofs[rc]->size();
2801 indices.reserve(nb_dofs);
2802 for (
auto dit = numered_dofs[rc]->get<decltype(tag)>().begin();
2803 dit != numered_dofs[rc]->get<decltype(tag)>().end(); ++dit) {
2806 if ((*dit)->getPetscLocalDofIdx() < 0 ||
2807 (*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[rc])) {
2812 indices.push_back(decltype(tag)::get_index(dit));
2816 auto get_indices_by_uid = [&](
auto tag,
auto &indices) {
2817 const int nb_dofs = numered_dofs[rc]->size();
2819 indices.reserve(nb_dofs);
2820 for (
auto dit = numered_dofs[rc]->begin(); dit != numered_dofs[rc]->end();
2822 indices.push_back(decltype(tag)::get_index(dit));
2825 auto get_sub_ao = [&](
auto sub_data) {
2827 return sub_data->getSmartRowMap();
2829 return sub_data->getSmartColMap();
2833 auto set_sub_is_and_ao = [&rc, &prb_ptr](
auto sub_data,
auto is,
auto ao) {
2835 sub_data->rowIs = is;
2836 sub_data->rowMap = ao;
2837 sub_data->colIs = is;
2838 sub_data->colMap = ao;
2840 sub_data->colIs = is;
2841 sub_data->colMap = ao;
2845 auto apply_symmetry = [&rc, &prb_ptr](
auto sub_data) {
2848 sub_data->colIs = sub_data->getSmartRowIs();
2849 sub_data->colMap = sub_data->getSmartRowMap();
2854 auto concatenate_dofs = [&](
auto tag,
auto &indices,
2855 const auto local_only) {
2857 get_indices_by_tag(tag, indices, local_only);
2864 &*indices.begin(), PETSC_NULL);
2866 ao =
createAOMapping(PETSC_COMM_SELF, indices.size(), &*indices.begin(),
2874 &*indices.begin(), PETSC_COPY_VALUES);
2877 auto sub_ao = get_sub_ao(sub_data);
2878 CHKERR AOPetscToApplicationIS(sub_ao, sub_is);
2881 set_sub_is_and_ao(sub_data, sub_is, sub_ao);
2882 apply_symmetry(sub_data);
2885 prb_ptr->
getSubData() = boost::make_shared<Problem::SubProblemData>();
2887 &*indices.begin(), PETSC_COPY_VALUES);
2889 set_sub_is_and_ao(prb_ptr->
getSubData(), sub_is, ao);
2894 get_indices_by_uid(tag, indices);
2895 CHKERR AOApplicationToPetsc(ao, indices.size(), &*indices.begin());
2901 auto set_concatenated_indices = [&]() {
2902 std::vector<int> global_indices;
2903 std::vector<int> local_indices;
2907 auto gi = global_indices.begin();
2908 auto li = local_indices.begin();
2909 for (
auto dit = numered_dofs[rc]->begin(); dit != numered_dofs[rc]->end();
2912 (*dit)->getPart(), (*dit)->getDofIdx(), *gi, *li);
2913 bool success = numered_dofs[rc]->modify(dit, mod);
2916 "can not set negative indices");
2922 CHKERR set_concatenated_indices();
2924 MPI_Allreduce(&nb_local_dofs, nbdof_ptr[rc], 1, MPI_INT, MPI_SUM,
2926 *(local_nbdof_ptr[rc]) = nb_local_dofs;
2927 *(ghost_nbdof_ptr[rc]) = nb_ghost_dofs;
2930 for (
auto dof : (*numered_dofs[rc])) {
2931 if (dof->getPetscGlobalDofIdx() < 0) {
2933 "Negative global idx");
2935 if (dof->getPetscLocalDofIdx() < 0) {
2937 "Negative local idx");
2943 *(nbdof_ptr[1]) = *(nbdof_ptr[0]);
2944 *(local_nbdof_ptr[1]) = *(local_nbdof_ptr[0]);
2945 *(ghost_nbdof_ptr[1]) = *(ghost_nbdof_ptr[0]);
2950 "WORLD", Sev::inform,
2951 "Removed DOFs from problem %s dofs [%d / %d (before %d / %d) global]",
2953 prb_ptr->
getNbDofsCol(), nb_init_row_dofs, nb_init_col_dofs);
2955 "Removed DOFs from problem %s dofs [ %d / %d "
2956 "(before %d / %d) local, %d / %d (before %d / %d)]",
2961 nb_init_ghost_col_dofs);
2969 const std::string problem_name,
const std::string
field_name,
2970 const Range ents,
const int lo_coeff,
const int hi_coeff,
2971 const int lo_order,
const int hi_order,
int verb,
const bool debug) {
2995 for (
int s = 0; s != 2; ++s)
2996 if (numered_dofs[s]) {
2998 using NumeredDofEntity_it_view_multiIndex = multi_index_container<
3000 NumeredDofEntity_multiIndex::iterator, indexed_by<sequenced<>>
3005 NumeredDofEntity_it_view_multiIndex dofs_it_view;
3008 for (
auto pit = ents.const_pair_begin(); pit != ents.const_pair_end();
3010 auto lo = numered_dofs[s]->get<
Unique_mi_tag>().lower_bound(
3012 auto hi = numered_dofs[s]->get<
Unique_mi_tag>().upper_bound(
3015 for (; lo != hi; ++lo)
3016 if ((*lo)->getDofCoeffIdx() >= lo_coeff &&
3017 (*lo)->getDofCoeffIdx() <= hi_coeff &&
3018 (*lo)->getDofOrder() >= lo_order &&
3019 (*lo)->getDofOrder() <= hi_order)
3020 dofs_it_view.emplace_back(numered_dofs[s]->project<0>(lo));
3024 for (
auto &dof : dofs_it_view)
3030 std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_weak_view;
3031 dofs_weak_view.reserve(dofs_it_view.size());
3032 for (
auto dit : dofs_it_view)
3033 dofs_weak_view.push_back(*dit);
3037 "Number of DOFs in multi-index %d and to delete %d\n",
3038 numered_dofs[s]->size(), dofs_it_view.size());
3041 for (
auto weak_dit : dofs_weak_view)
3042 if (
auto dit = weak_dit.lock()) {
3043 numered_dofs[s]->erase(dit->getLocalUniqueId());
3048 "Number of DOFs in multi-index after delete %d\n",
3049 numered_dofs[s]->size());
3052 int nb_local_dofs = 0;
3053 int nb_ghost_dofs = 0;
3054 for (
auto dit = numered_dofs[s]->get<PetscLocalIdx_mi_tag>().begin();
3056 if ((*dit)->getPetscLocalDofIdx() >= 0 &&
3057 (*dit)->getPetscLocalDofIdx() < *(local_nbdof_ptr[s]))
3059 else if ((*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[s]))
3063 "Impossible case. You could run problem on no distributed "
3064 "mesh. That is not implemented. Dof local index is %d",
3065 (*dit)->getPetscLocalDofIdx());
3069 auto get_indices_by_tag = [&](
auto tag,
auto &indices,
bool only_local) {
3070 const int nb_dofs = numered_dofs[s]->size();
3072 indices.reserve(nb_dofs);
3073 for (
auto dit = numered_dofs[s]->get<decltype(tag)>().begin();
3074 dit != numered_dofs[s]->get<decltype(tag)>().end(); ++dit) {
3077 if ((*dit)->getPetscLocalDofIdx() < 0 ||
3078 (*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[s])) {
3083 indices.push_back(decltype(tag)::get_index(dit));
3087 auto get_indices_by_uid = [&](
auto tag,
auto &indices) {
3088 const int nb_dofs = numered_dofs[s]->size();
3090 indices.reserve(nb_dofs);
3091 for (
auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3093 indices.push_back(decltype(tag)::get_index(dit));
3096 auto get_sub_ao = [&](
auto sub_data) {
3098 return sub_data->getSmartRowMap();
3100 return sub_data->getSmartColMap();
3104 auto set_sub_is_and_ao = [&s, &prb_ptr](
auto sub_data,
auto is,
auto ao) {
3106 sub_data->rowIs = is;
3107 sub_data->rowMap = ao;
3108 sub_data->colIs = is;
3109 sub_data->colMap = ao;
3111 sub_data->colIs = is;
3112 sub_data->colMap = ao;
3116 auto apply_symmetry = [&s, &prb_ptr](
auto sub_data) {
3119 sub_data->colIs = sub_data->getSmartRowIs();
3120 sub_data->colMap = sub_data->getSmartRowMap();
3125 auto concatenate_dofs = [&](
auto tag,
auto &indices,
3126 const auto local_only) {
3128 get_indices_by_tag(tag, indices, local_only);
3135 &*indices.begin(), PETSC_NULL);
3138 &*indices.begin(), PETSC_NULL);
3145 &*indices.begin(), PETSC_COPY_VALUES);
3148 auto sub_ao = get_sub_ao(sub_data);
3149 CHKERR AOPetscToApplicationIS(sub_ao, sub_is);
3152 set_sub_is_and_ao(sub_data, sub_is, sub_ao);
3153 apply_symmetry(sub_data);
3157 boost::make_shared<Problem::SubProblemData>();
3159 &*indices.begin(), PETSC_COPY_VALUES);
3161 set_sub_is_and_ao(prb_ptr->
getSubData(), sub_is, ao);
3166 get_indices_by_uid(tag, indices);
3167 CHKERR AOApplicationToPetsc(ao, indices.size(), &*indices.begin());
3173 auto set_concatenated_indices = [&]() {
3174 std::vector<int> global_indices;
3175 std::vector<int> local_indices;
3179 auto gi = global_indices.begin();
3180 auto li = local_indices.begin();
3181 for (
auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3184 (*dit)->getPart(), (*dit)->getDofIdx(), *gi, *li);
3185 bool success = numered_dofs[s]->modify(dit, mod);
3188 "can not set negative indices");
3194 CHKERR set_concatenated_indices();
3196 MPI_Allreduce(&nb_local_dofs, nbdof_ptr[s], 1, MPI_INT, MPI_SUM,
3198 *(local_nbdof_ptr[s]) = nb_local_dofs;
3199 *(ghost_nbdof_ptr[s]) = nb_ghost_dofs;
3202 for (
auto dof : (*numered_dofs[s])) {
3203 if (dof->getPetscGlobalDofIdx() < 0) {
3205 "Negative global idx");
3207 if (dof->getPetscLocalDofIdx() < 0) {
3209 "Negative local idx");
3215 *(nbdof_ptr[1]) = *(nbdof_ptr[0]);
3216 *(local_nbdof_ptr[1]) = *(local_nbdof_ptr[0]);
3217 *(ghost_nbdof_ptr[1]) = *(ghost_nbdof_ptr[0]);
3222 "WORLD", Sev::inform,
3223 "Removed DOFs from problem %s dofs [%d / %d (before %d / %d) global]",
3225 prb_ptr->
getNbDofsCol(), nb_init_row_dofs, nb_init_col_dofs);
3227 "Removed DOFs from problem %s dofs [ %d / %d "
3228 "(before %d / %d) local, %d / %d (before %d / %d)]",
3233 nb_init_ghost_col_dofs);
3241 const std::string problem_name,
const std::string
field_name,
3242 const Range ents,
const int lo_coeff,
const int hi_coeff,
3243 const int lo_order,
const int hi_order,
int verb,
const bool debug) {
3267 const std::array<int, 2> nb_init_dofs = {nb_init_row_dofs, nb_init_col_dofs};
3269 for (
int s = 0; s != 2; ++s)
3270 if (numered_dofs[s]) {
3272 typedef multi_index_container<
3274 NumeredDofEntity_multiIndex::iterator, indexed_by<sequenced<>>
3277 NumeredDofEntity_it_view_multiIndex;
3280 NumeredDofEntity_it_view_multiIndex dofs_it_view;
3283 for (
auto pit = ents.const_pair_begin(); pit != ents.const_pair_end();
3285 auto lo = numered_dofs[s]->get<
Unique_mi_tag>().lower_bound(
3287 auto hi = numered_dofs[s]->get<
Unique_mi_tag>().upper_bound(
3290 for (; lo != hi; ++lo)
3291 if ((*lo)->getDofCoeffIdx() >= lo_coeff &&
3292 (*lo)->getDofCoeffIdx() <= hi_coeff &&
3293 (*lo)->getDofOrder() >= lo_order &&
3294 (*lo)->getDofOrder() <= hi_order)
3295 dofs_it_view.emplace_back(numered_dofs[s]->project<0>(lo));
3299 for (
auto &dof : dofs_it_view)
3305 for (
auto dit : dofs_it_view) {
3306 bool success = numered_dofs[s]->modify(dit, mod);
3309 "can not set negative indices");
3313 std::vector<boost::weak_ptr<NumeredDofEntity>> dosf_weak_view;
3314 dosf_weak_view.reserve(dofs_it_view.size());
3315 for (
auto dit : dofs_it_view)
3316 dosf_weak_view.push_back(*dit);
3320 "Number of DOFs in multi-index %d and to delete %d\n",
3321 numered_dofs[s]->size(), dofs_it_view.size());
3324 for (
auto weak_dit : dosf_weak_view)
3325 if (
auto dit = weak_dit.lock()) {
3326 numered_dofs[s]->erase(dit->getLocalUniqueId());
3331 "Number of DOFs in multi-index after delete %d\n",
3332 numered_dofs[s]->size());
3335 int nb_global_dof = 0;
3336 int nb_local_dofs = 0;
3337 int nb_ghost_dofs = 0;
3339 for (
auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3342 if ((*dit)->getDofIdx() >= 0) {
3344 if ((*dit)->getPetscLocalDofIdx() >= 0 &&
3345 (*dit)->getPetscLocalDofIdx() < *(local_nbdof_ptr[s]))
3347 else if ((*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[s]))
3355 MPI_Allreduce(&nb_local_dofs, nbdof_ptr[s], 1, MPI_INT, MPI_SUM,
3357 if (*(nbdof_ptr[s]) != nb_global_dof)
3359 "Number of local DOFs do not add up %d != %d",
3360 *(nbdof_ptr[s]), nb_global_dof);
3363 *(nbdof_ptr[s]) = nb_global_dof;
3364 *(local_nbdof_ptr[s]) = nb_local_dofs;
3365 *(ghost_nbdof_ptr[s]) = nb_ghost_dofs;
3368 auto get_indices_by_tag = [&](
auto tag) {
3369 std::vector<int> indices;
3370 indices.resize(nb_init_dofs[s], -1);
3371 for (
auto dit = numered_dofs[s]->get<Idx_mi_tag>().lower_bound(0);
3372 dit != numered_dofs[s]->get<
Idx_mi_tag>().end(); ++dit) {
3373 indices[(*dit)->getDofIdx()] = decltype(tag)::get_index(dit);
3378 auto renumber = [&](
auto tag,
auto &indices) {
3381 for (
auto dit = numered_dofs[s]->get<decltype(tag)>().lower_bound(0);
3382 dit != numered_dofs[s]->get<decltype(tag)>().end(); ++dit) {
3383 indices[(*dit)->getDofIdx()] = idx++;
3388 auto get_sub_ao = [&](
auto sub_data) {
3390 return sub_data->getSmartRowMap();
3392 return sub_data->getSmartColMap();
3396 auto set_sub_is_and_ao = [&s, &prb_ptr](
auto sub_data,
auto is,
auto ao) {
3398 sub_data->rowIs = is;
3399 sub_data->rowMap = ao;
3400 sub_data->colIs = is;
3401 sub_data->colMap = ao;
3403 sub_data->colIs = is;
3404 sub_data->colMap = ao;
3408 auto apply_symmetry = [&s, &prb_ptr](
auto sub_data) {
3411 sub_data->colIs = sub_data->getSmartRowIs();
3412 sub_data->colMap = sub_data->getSmartRowMap();
3417 auto set_sub_data = [&](
auto &indices) {
3422 &*indices.begin(), PETSC_COPY_VALUES);
3425 auto sub_ao = get_sub_ao(sub_data);
3426 CHKERR AOPetscToApplicationIS(sub_ao, sub_is);
3429 set_sub_is_and_ao(sub_data, sub_is, sub_ao);
3430 apply_symmetry(sub_data);
3432 prb_ptr->
getSubData() = boost::make_shared<Problem::SubProblemData>();
3434 &*indices.begin(), PETSC_COPY_VALUES);
3437 set_sub_is_and_ao(prb_ptr->
getSubData(), sub_is, sub_ao);
3445 CHKERR set_sub_data(global_indices);
3450 for (
auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3452 auto idx = (*dit)->getDofIdx();
3455 (*dit)->getPart(),
i++, global_indices[idx], local_indices[idx]);
3456 bool success = numered_dofs[s]->modify(dit, mod);
3459 "can not set negative indices");
3462 (*dit)->getPart(), -1, -1, -1);
3463 bool success = numered_dofs[s]->modify(dit, mod);
3466 "can not set negative indices");
3471 for (
auto dof : (*numered_dofs[s])) {
3472 if (dof->getDofIdx() >= 0 && dof->getPetscGlobalDofIdx() < 0) {
3474 "Negative global idx");
3481 *(nbdof_ptr[1]) = *(nbdof_ptr[0]);
3482 *(local_nbdof_ptr[1]) = *(local_nbdof_ptr[0]);
3483 *(ghost_nbdof_ptr[1]) = *(ghost_nbdof_ptr[0]);
3491 "WORLD", Sev::inform,
3492 "Removed DOFs from problem %s dofs [%d / %d (before %d / %d) global]",
3494 prb_ptr->
getNbDofsCol(), nb_init_row_dofs, nb_init_col_dofs);
3496 "Removed DOFs from problem %s dofs [ %d / %d "
3497 "(before %d / %d) local, %d / %d (before %d / %d)]",
3502 nb_init_ghost_col_dofs);
3509 const std::string problem_name,
const std::string
field_name,
3511 Range *ents_ptr,
const int lo_coeff,
const int hi_coeff,
const int lo_order,
3512 const int hi_order,
int verb,
const bool debug) {
3521 CHKERR bit_manager->filterEntitiesByRefLevel(bit_ref_level, bit_ref_mask,
3524 CHKERR bit_manager->getEntitiesByRefLevel(bit_ref_level, bit_ref_mask, ents,
3529 hi_coeff, lo_order, hi_order, verb,
debug);
3535 const std::string problem_name,
const std::string
field_name,
3537 Range *ents_ptr,
const int lo_coeff,
const int hi_coeff,
const int lo_order,
3538 const int hi_order,
int verb,
const bool debug) {
3547 CHKERR bit_manager->filterEntitiesByRefLevel(bit_ref_level, bit_ref_mask,
3550 CHKERR bit_manager->getEntitiesByRefLevel(bit_ref_level, bit_ref_mask, ents,
3555 lo_coeff, hi_coeff, lo_order,
3556 hi_order, verb,
debug);
3564 std::vector<unsigned char> &
marker)
const {
3570 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs;
3580 marker.resize(dofs->size(), 0);
3581 std::vector<unsigned char> marker_tmp;
3585 for (
auto p = ents.pair_begin(); p != ents.pair_end(); ++p) {
3586 auto lo = dofs->get<
Ent_mi_tag>().lower_bound(p->first);
3587 auto hi = dofs->get<
Ent_mi_tag>().upper_bound(p->second);
3588 for (; lo != hi; ++lo)
3589 marker[(*lo)->getPetscLocalDofIdx()] |= 1;
3593 marker_tmp.resize(dofs->size(), 0);
3594 for (
auto p = ents.pair_begin(); p != ents.pair_end(); ++p) {
3595 auto lo = dofs->get<
Ent_mi_tag>().lower_bound(p->first);
3596 auto hi = dofs->get<
Ent_mi_tag>().upper_bound(p->second);
3597 for (; lo != hi; ++lo)
3598 marker_tmp[(*lo)->getPetscLocalDofIdx()] = 1;
3600 for (
int i = 0;
i !=
marker.size(); ++
i) {
3612 const unsigned char c, std::vector<unsigned char> &
marker)
const {
3618 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs;
3628 marker.resize(dofs->size(), 0);
3635 auto marker_ref = [
marker](
auto &it) ->
unsigned int & {
3636 return marker[(*it)->getPetscLocalDofIdx()];
3641 for (; dof_lo != dof_hi; ++dof_lo)
3642 if ((*dof_lo)->getDofCoeffIdx() >= lo &&
3643 (*dof_lo)->getDofCoeffIdx() <= hi)
3644 marker[(*dof_lo)->getPetscLocalDofIdx()] |=
c;
3647 for (; dof_lo != dof_hi; ++dof_lo)
3648 if ((*dof_lo)->getDofCoeffIdx() >= lo &&
3649 (*dof_lo)->getDofCoeffIdx() <= hi)
3650 marker[(*dof_lo)->getPetscLocalDofIdx()] &=
c;
3659 const std::string problem_name,
RowColData rc,
3660 std::vector<boost::weak_ptr<NumeredDofEntity>> &vec_dof_view,
3661 const enum MarkOP op, std::vector<unsigned char> &
marker
3669 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs;
3680 marker.resize(dofs->size(), 0);
3682 for (
auto &dof : vec_dof_view) {
3683 if (
auto dof_ptr = dof.lock()) {
3684 if (op == MarkOP::OR)
3685 marker[dof_ptr->getPetscLocalDofIdx()] |= 1;
3687 marker[dof_ptr->getPetscLocalDofIdx()] &= 1;
3696 const std::string row_field,
3697 const std::string col_field)
const {
3702 const auto problem_ptr = m_field.
get_problem(problem_name);
3703 auto get_field_id = [&](
const std::string
field_name) {
3706 const auto row_id = get_field_id(row_field);
3707 const auto col_id = get_field_id(col_field);
3709 problem_ptr->addFieldToEmptyFieldBlocks(
BlockFieldPair(row_id, col_id));