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);
837 if (PetscUnlikely(ddit == dofs_glob_uid_view.end())) {
842 <<
"DOF is shared or multishared between processors. For example "
843 "if order of field on given entity is set in inconsistently, "
844 "has different value on two processor, error such as this is "
847 MOFEM_LOG(
"SELF", Sev::error) <<
"UId " << uid <<
" is not found";
850 <<
"Problematic UId owner proc is " << owner_proc;
853 <<
"Problematic UId entity owning processor handle is "
854 << uid_handle <<
" entity type "
856 const auto uid_bit_number =
859 <<
"Problematic UId field is "
864 field_view.insert(ents_field_ptr->begin(), ents_field_ptr->end());
866 owner_proc, uid_bit_number, uid_handle));
867 if (fe_it == field_view.end()) {
869 <<
"Also, no field entity in database for given global UId";
871 MOFEM_LOG(
"SELF", Sev::error) <<
"Field entity in databse exist "
872 "(but have no DOF wih give UId";
873 MOFEM_LOG(
"SELF", Sev::error) << **fe_it;
876 auto error_file_name =
877 "error_with_missing_entity_" +
881 <<
"Look to file < " << error_file_name
882 <<
" > it contains entity with missing DOF.";
885 const auto local_fe_ent = (*fe_it)->getEnt();
886 CHKERR m_field.
get_moab().add_entities(*tmp_msh, &local_fe_ent, 1);
887 CHKERR m_field.
get_moab().write_file(error_file_name.c_str(),
"VTK",
888 "", tmp_msh->get_ptr(), 1);
893 "DOF with global UId not found (Compile code in Debug to "
894 "learn more about problem");
897 auto dit = numered_dofs_ptr[ss]->find((*ddit)->getLocalUniqueId());
899 if (dit != numered_dofs_ptr[ss]->end()) {
903 if (PetscUnlikely(global_idx < 0))
905 "received negative dof");
908 success = numered_dofs_ptr[ss]->modify(
912 if (PetscUnlikely(!success))
914 "modification unsuccessful");
916 success = numered_dofs_ptr[ss]->modify(
920 if (PetscUnlikely(!success))
922 "modification unsuccessful");
927 if (PetscUnlikely(ddit->get()->getPStatus() == 0)) {
934 std::ostringstream zz;
935 zz << **ddit << std::endl;
937 "data inconsistency, dofs is not shared, but received "
952 CHKERR PetscFree(olengths_rows);
953 CHKERR PetscFree(rbuf_row[0]);
954 CHKERR PetscFree(rbuf_row);
955 if (!square_matrix) {
956 CHKERR PetscFree(olengths_cols);
957 CHKERR PetscFree(rbuf_col[0]);
958 CHKERR PetscFree(rbuf_col);
962 if (numered_dofs_ptr[0]->size() != numered_dofs_ptr[1]->size()) {
964 "data inconsistency for square_matrix %d!=%d",
965 numered_dofs_ptr[0]->size(), numered_dofs_ptr[1]->size());
969 "data inconsistency for square_matrix");
982 const std::string out_name,
984 const std::vector<std::string> &fields_row,
985 const std::vector<std::string> &fields_col,
987 const std::string main_problem,
const bool square_matrix,
989 const map<std::string, boost::shared_ptr<Range>> *entityMapRow,
990 const map<std::string, boost::shared_ptr<Range>> *entityMapCol,
1000 using ProblemByName = decltype(problems_ptr->get<
Problem_mi_tag>());
1001 auto &problems_by_name =
1002 const_cast<ProblemByName &
>(problems_ptr->get<
Problem_mi_tag>());
1005 auto out_problem_it = problems_by_name.find(out_name);
1006 if (out_problem_it == problems_by_name.end()) {
1008 "subproblem with name < %s > not defined (top tip check spelling)",
1013 auto main_problem_it = problems_by_name.find(main_problem);
1014 if (main_problem_it == problems_by_name.end()) {
1016 "problem of subproblem with name < %s > not defined (top tip "
1018 main_problem.c_str());
1022 boost::shared_ptr<NumeredDofEntity_multiIndex> out_problem_dofs[] = {
1023 out_problem_it->numeredRowDofsPtr, out_problem_it->numeredColDofsPtr};
1025 boost::shared_ptr<NumeredDofEntity_multiIndex> main_problem_dofs[] = {
1026 main_problem_it->numeredRowDofsPtr, main_problem_it->numeredColDofsPtr};
1028 int *nb_local_dofs[] = {&out_problem_it->nbLocDofsRow,
1029 &out_problem_it->nbLocDofsCol};
1031 int *nb_dofs[] = {&out_problem_it->nbDofsRow, &out_problem_it->nbDofsCol};
1035 out_problem_it->nbGhostDofsRow = 0;
1036 out_problem_it->nbGhostDofsCol = 0;
1040 std::vector<std::string> fields[] = {fields_row, fields_col};
1041 const map<std::string, boost::shared_ptr<Range>> *entityMap[] = {
1042 entityMapRow, entityMapCol};
1045 out_problem_it->subProblemData =
1046 boost::make_shared<Problem::SubProblemData>();
1049 for (
int ss = 0; ss != (square_matrix ? 1 : 2); ++ss) {
1052 (*nb_local_dofs[ss]) = 0;
1055 out_problem_dofs[ss]->clear();
1058 out_problem_it->numeredFiniteElementsPtr->clear();
1061 for (
auto field : fields[ss]) {
1067 boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array =
1068 boost::make_shared<std::vector<NumeredDofEntity>>();
1071 out_problem_it->getRowDofsSequence()->emplace_back(dofs_array);
1073 out_problem_it->getColDofsSequence()->emplace_back(dofs_array);
1078 auto add_dit_to_dofs_array = [&](
auto &dit) {
1079 if (dit->get()->getPetscGlobalDofIdx() >= 0)
1080 dofs_array->emplace_back(
1081 dit->get()->getDofEntityPtr(), dit->get()->getPetscGlobalDofIdx(),
1082 dit->get()->getPetscGlobalDofIdx(),
1083 dit->get()->getPetscLocalDofIdx(), dit->get()->getPart());
1086 auto get_dafult_dof_range = [&]() {
1087 auto dit = main_problem_dofs[ss]->get<
Unique_mi_tag>().lower_bound(
1089 auto hi_dit = main_problem_dofs[ss]->get<
Unique_mi_tag>().upper_bound(
1091 return std::make_pair(dit, hi_dit);
1094 auto check = [&](
auto &field) -> boost::shared_ptr<Range> {
1095 if (entityMap[ss]) {
1096 auto mit = entityMap[ss]->find(field);
1097 if (mit != entityMap[ss]->end()) {
1107 if (
auto r_ptr = check(field)) {
1108 for (
auto p = r_ptr->pair_begin(); p != r_ptr->pair_end(); ++p) {
1109 const auto lo_ent = p->first;
1110 const auto hi_ent = p->second;
1111 auto dit = main_problem_dofs[ss]->get<
Unique_mi_tag>().lower_bound(
1113 auto hi_dit = main_problem_dofs[ss]->get<
Unique_mi_tag>().upper_bound(
1115 dofs_array->reserve(std::distance(dit, hi_dit));
1116 for (; dit != hi_dit; dit++) {
1117 add_dit_to_dofs_array(dit);
1121 auto [dit, hi_dit] = get_dafult_dof_range();
1122 dofs_array->reserve(std::distance(dit, hi_dit));
1123 for (; dit != hi_dit; dit++)
1124 add_dit_to_dofs_array(dit);
1128 auto hint = out_problem_dofs[ss]->end();
1129 for (
auto &
v : *dofs_array)
1130 hint = out_problem_dofs[ss]->emplace_hint(hint, dofs_array, &
v);
1134 auto dit = out_problem_dofs[ss]->get<
Idx_mi_tag>().begin();
1135 auto hi_dit = out_problem_dofs[ss]->get<
Idx_mi_tag>().end();
1136 for (; dit != hi_dit; dit++) {
1138 if (dit->get()->getPart() == (
unsigned int)m_field.
get_comm_rank()) {
1139 idx = (*nb_local_dofs[ss])++;
1141 bool success = out_problem_dofs[ss]->modify(
1142 out_problem_dofs[ss]->project<0>(dit),
1146 "operation unsuccessful");
1156 out_problem_dofs[ss]->size());
1157 const int nb = std::distance(dit, hi_dit);
1159 std::vector<int> main_indices(nb);
1160 for (
auto it = main_indices.begin(); dit != hi_dit; dit++, it++) {
1161 *it = dit->get()->getPetscGlobalDofIdx();
1165 CHKERR ISCreateGeneral(m_field.
get_comm(), nb, &*main_indices.begin(),
1166 PETSC_USE_POINTER, &is);
1170 CHKERR AOCreateMappingIS(is, PETSC_NULL, &ao);
1173 CHKERR ISDuplicate(is, &is_dup);
1178 CHKERR ISDuplicate(is, &is_dup);
1182 CHKERR AOApplicationToPetscIS(ao, is);
1184 CHKERR ISGetSize(is, nb_dofs[ss]);
1188 for (std::vector<int>::iterator it = main_indices.begin(); dit != hi_dit;
1190 bool success = out_problem_dofs[ss]->modify(
1191 out_problem_dofs[ss]->project<0>(dit),
1193 dit->get()->getPart(), *it, *it,
1194 dit->get()->getPetscLocalDofIdx()));
1197 "operation unsuccessful");
1202 NumeredDofEntityByLocalIdx::iterator dit =
1204 NumeredDofEntityByLocalIdx::iterator hi_dit =
1206 const int nb = std::distance(dit, hi_dit);
1207 std::vector<int> main_indices_non_local(nb);
1208 for (
auto it = main_indices_non_local.begin(); dit != hi_dit;
1210 *it = dit->get()->getPetscGlobalDofIdx();
1214 &*main_indices_non_local.begin(),
1215 PETSC_USE_POINTER, &is);
1216 CHKERR AOApplicationToPetscIS(ao, is);
1219 for (
auto it = main_indices_non_local.begin(); dit != hi_dit;
1221 bool success = out_problem_dofs[ss]->modify(
1222 out_problem_dofs[ss]->project<0>(dit),
1224 dit->get()->getPart(), dit->get()->getDofIdx(), *it,
1225 dit->get()->getPetscLocalDofIdx()));
1228 "operation unsuccessful");
1236 if (square_matrix) {
1237 out_problem_it->numeredColDofsPtr = out_problem_it->numeredRowDofsPtr;
1238 out_problem_it->nbLocDofsCol = out_problem_it->nbLocDofsRow;
1239 out_problem_it->nbDofsCol = out_problem_it->nbDofsRow;
1240 out_problem_it->getSubData()->colIs = out_problem_it->getSubData()->rowIs;
1241 out_problem_it->getSubData()->colMap = out_problem_it->getSubData()->rowMap;
1251 const std::string out_name,
const std::vector<std::string> add_row_problems,
1252 const std::vector<std::string> add_col_problems,
const bool square_matrix,
1267 ProblemByName &problems_by_name =
1268 const_cast<ProblemByName &
>(problems_ptr->get<
Problem_mi_tag>());
1271 ProblemByName::iterator out_problem_it = problems_by_name.find(out_name);
1272 if (out_problem_it == problems_by_name.end()) {
1274 "problem with name < %s > not defined (top tip check spelling)",
1278 out_problem_it->composedProblemsData =
1279 boost::make_shared<ComposedProblemsData>();
1280 boost::shared_ptr<ComposedProblemsData> cmp_prb_data =
1281 out_problem_it->getComposedProblemsData();
1283 const std::vector<std::string> *add_prb[] = {&add_row_problems,
1285 std::vector<const Problem *> *add_prb_ptr[] = {&cmp_prb_data->rowProblemsAdd,
1286 &cmp_prb_data->colProblemsAdd};
1287 std::vector<SmartPetscObj<IS>> *add_prb_is[] = {&cmp_prb_data->rowIs,
1288 &cmp_prb_data->colIs};
1291 int *nb_local_dofs[] = {&out_problem_it->nbLocDofsRow,
1292 &out_problem_it->nbLocDofsCol};
1294 int *nb_dofs[] = {&out_problem_it->nbDofsRow, &out_problem_it->nbDofsCol};
1298 out_problem_it->nbDofsRow = 0;
1299 out_problem_it->nbDofsCol = 0;
1300 out_problem_it->nbLocDofsRow = 0;
1301 out_problem_it->nbLocDofsCol = 0;
1302 out_problem_it->nbGhostDofsRow = 0;
1303 out_problem_it->nbGhostDofsCol = 0;
1305 int nb_dofs_reserve[] = {0, 0};
1308 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1309 add_prb_ptr[ss]->reserve(add_prb[ss]->size());
1310 add_prb_is[ss]->reserve(add_prb[ss]->size());
1311 for (std::vector<std::string>::const_iterator vit = add_prb[ss]->begin();
1312 vit != add_prb[ss]->end(); vit++) {
1313 ProblemByName::iterator prb_it = problems_by_name.find(*vit);
1314 if (prb_it == problems_by_name.end()) {
1317 "problem with name < %s > not defined (top tip check spelling)",
1320 add_prb_ptr[ss]->push_back(&*prb_it);
1324 *nb_dofs[ss] += add_prb_ptr[ss]->back()->getNbDofsRow();
1325 *nb_local_dofs[ss] += add_prb_ptr[ss]->back()->getNbLocalDofsRow();
1326 nb_dofs_reserve[ss] +=
1327 add_prb_ptr[ss]->back()->numeredRowDofsPtr->size();
1330 *nb_dofs[ss] += add_prb_ptr[ss]->back()->getNbDofsCol();
1331 *nb_local_dofs[ss] += add_prb_ptr[ss]->back()->getNbLocalDofsCol();
1332 nb_dofs_reserve[ss] +=
1333 add_prb_ptr[ss]->back()->numeredColDofsPtr->size();
1338 if (square_matrix) {
1339 add_prb_ptr[1]->reserve(add_prb_ptr[0]->size());
1340 add_prb_is[1]->reserve(add_prb_ptr[0]->size());
1341 out_problem_it->numeredColDofsPtr = out_problem_it->numeredRowDofsPtr;
1342 *nb_dofs[1] = *nb_dofs[0];
1343 *nb_local_dofs[1] = *nb_local_dofs[0];
1347 boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array[2];
1349 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1350 dofs_array[ss] = boost::make_shared<std::vector<NumeredDofEntity>>();
1351 dofs_array[ss]->reserve(nb_dofs_reserve[ss]);
1353 out_problem_it->getRowDofsSequence()->emplace_back(dofs_array[ss]);
1355 out_problem_it->getColDofsSequence()->emplace_back(dofs_array[ss]);
1359 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1360 NumeredDofEntity_multiIndex::index<PetscGlobalIdx_mi_tag>::type::iterator
1365 for (
unsigned int pp = 0; pp != add_prb_ptr[ss]->size(); pp++) {
1366 PetscInt *dofs_out_idx_ptr;
1367 int nb_local_dofs = (*add_prb_ptr[ss])[pp]->getNbLocalDofsRow();
1368 CHKERR PetscMalloc(nb_local_dofs *
sizeof(
int), &dofs_out_idx_ptr);
1370 dit = (*add_prb_ptr[ss])[pp]
1373 hi_dit = (*add_prb_ptr[ss])[pp]
1377 dit = (*add_prb_ptr[ss])[pp]
1380 hi_dit = (*add_prb_ptr[ss])[pp]
1385 for (; dit != hi_dit; dit++) {
1386 const BitRefLevel &prb_bit = out_problem_it->getBitRefLevel();
1387 const BitRefLevel &prb_mask = out_problem_it->getBitRefLevelMask();
1388 const BitRefLevel &dof_bit = dit->get()->getBitRefLevel();
1389 if ((dof_bit & prb_bit).none() || ((dof_bit & prb_mask) != dof_bit))
1392 const int part = dit->get()->getPart();
1393 const int glob_idx = shift_glob + dit->get()->getPetscGlobalDofIdx();
1395 (part == rank) ? (shift_loc + dit->get()->getPetscLocalDofIdx())
1397 dofs_array[ss]->emplace_back(dit->get()->getDofEntityPtr(), glob_idx,
1398 glob_idx, loc_idx, part);
1400 dofs_out_idx_ptr[is_nb++] = glob_idx;
1403 if (is_nb > nb_local_dofs) {
1405 "Data inconsistency");
1408 CHKERR ISCreateGeneral(m_field.
get_comm(), is_nb, dofs_out_idx_ptr,
1409 PETSC_OWN_POINTER, &is);
1411 (*add_prb_is[ss]).push_back(smart_is);
1413 shift_glob += (*add_prb_ptr[ss])[pp]->getNbDofsRow();
1414 shift_loc += (*add_prb_ptr[ss])[pp]->getNbLocalDofsRow();
1416 shift_glob += (*add_prb_ptr[ss])[pp]->getNbDofsCol();
1417 shift_loc += (*add_prb_ptr[ss])[pp]->getNbLocalDofsCol();
1419 if (square_matrix) {
1420 (*add_prb_ptr[1]).push_back((*add_prb_ptr[0])[pp]);
1421 (*add_prb_is[1]).push_back(smart_is);
1426 if ((*add_prb_is[1]).size() != (*add_prb_is[0]).size()) {
1431 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1432 auto hint = (ss == 0) ? out_problem_it->numeredRowDofsPtr->end()
1433 : out_problem_it->numeredColDofsPtr->end();
1434 for (
auto &
v : *dofs_array[ss])
1435 hint = (ss == 0) ? out_problem_it->numeredRowDofsPtr->emplace_hint(
1436 hint, dofs_array[ss], &
v)
1437 : out_problem_it->numeredColDofsPtr->emplace_hint(
1438 hint, dofs_array[ss], &
v);
1444 *nb_local_dofs[0] = 0;
1445 *nb_local_dofs[1] = 0;
1446 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1448 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs_ptr;
1450 dofs_ptr = out_problem_it->numeredRowDofsPtr;
1452 dofs_ptr = out_problem_it->numeredColDofsPtr;
1454 NumeredDofEntityByUId::iterator dit, hi_dit;
1457 std::vector<int> idx;
1458 idx.reserve(std::distance(dit, hi_dit));
1460 for (; dit != hi_dit; dit++) {
1461 if (dit->get()->getPart() == (
unsigned int)m_field.
get_comm_rank()) {
1466 "modification unsuccessful");
1468 idx.push_back(dit->get()->getPetscGlobalDofIdx());
1470 if (dit->get()->getPetscLocalDofIdx() != -1) {
1472 "local index should be negative");
1476 if (square_matrix) {
1477 *nb_local_dofs[1] = *nb_local_dofs[0];
1482 CHKERR ISCreateGeneral(m_field.
get_comm(), idx.size(), &*idx.begin(),
1483 PETSC_USE_POINTER, &is);
1484 CHKERR ISGetSize(is, nb_dofs[ss]);
1485 if (square_matrix) {
1486 *nb_dofs[1] = *nb_dofs[0];
1490 CHKERR AOCreateMappingIS(is, PETSC_NULL, &ao);
1491 for (
unsigned int pp = 0; pp != (*add_prb_is[ss]).size(); pp++)
1492 CHKERR AOApplicationToPetscIS(ao, (*add_prb_is[ss])[pp]);
1496 std::vector<int> idx_new;
1497 idx_new.reserve(dofs_ptr->size());
1498 for (NumeredDofEntityByUId::iterator dit =
1501 idx_new.push_back(dit->get()->getPetscGlobalDofIdx());
1506 &*idx_new.begin(), PETSC_USE_POINTER, &is_new);
1507 CHKERR AOApplicationToPetscIS(ao, is_new);
1509 std::vector<int>::iterator vit = idx_new.begin();
1510 for (NumeredDofEntityByUId::iterator dit =
1515 dit->get()->getPart(), *(vit++)));
1518 "modification unsuccessful");
1521 CHKERR ISDestroy(&is_new);
1552 MOFEM_LOG(
"WORLD", Sev::verbose) <<
"Simple partition problem " << name;
1556 ProblemByName &problems_set =
1557 const_cast<ProblemByName &
>(problems_ptr->get<
Problem_mi_tag>());
1558 ProblemByName::iterator p_miit = problems_set.find(name);
1559 if (p_miit == problems_set.end()) {
1560 SETERRQ1(PETSC_COMM_SELF, 1,
1561 "problem < %s > is not found (top tip: check spelling)",
1566 NumeredDofEntitysByIdx &dofs_row_by_idx =
1567 p_miit->numeredRowDofsPtr->get<
Idx_mi_tag>();
1568 NumeredDofEntitysByIdx &dofs_col_by_idx =
1569 p_miit->numeredColDofsPtr->get<
Idx_mi_tag>();
1576 DofIdx &nb_row_local_dofs = p_miit->nbLocDofsRow;
1577 DofIdx &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
1578 nb_row_local_dofs = 0;
1579 nb_row_ghost_dofs = 0;
1580 DofIdx &nb_col_local_dofs = p_miit->nbLocDofsCol;
1581 DofIdx &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
1582 nb_col_local_dofs = 0;
1583 nb_col_ghost_dofs = 0;
1585 bool square_matrix =
false;
1586 if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr) {
1587 square_matrix =
true;
1591 PetscLayout layout_row;
1592 const int *ranges_row;
1594 DofIdx nb_dofs_row = dofs_row_by_idx.size();
1596 CHKERR PetscLayoutSetBlockSize(layout_row, 1);
1597 CHKERR PetscLayoutSetSize(layout_row, nb_dofs_row);
1598 CHKERR PetscLayoutSetUp(layout_row);
1599 CHKERR PetscLayoutGetRanges(layout_row, &ranges_row);
1601 PetscLayout layout_col;
1602 const int *ranges_col;
1603 if (!square_matrix) {
1604 DofIdx nb_dofs_col = dofs_col_by_idx.size();
1606 CHKERR PetscLayoutSetBlockSize(layout_col, 1);
1607 CHKERR PetscLayoutSetSize(layout_col, nb_dofs_col);
1608 CHKERR PetscLayoutSetUp(layout_col);
1609 CHKERR PetscLayoutGetRanges(layout_col, &ranges_col);
1613 miit_row = dofs_row_by_idx.lower_bound(ranges_row[part]);
1614 hi_miit_row = dofs_row_by_idx.lower_bound(ranges_row[part + 1]);
1615 if (std::distance(miit_row, hi_miit_row) !=
1616 ranges_row[part + 1] - ranges_row[part]) {
1618 PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1619 "data inconsistency, std::distance(miit_row,hi_miit_row) != rend - "
1620 "rstart (%d != %d - %d = %d) ",
1621 std::distance(miit_row, hi_miit_row), ranges_row[part + 1],
1622 ranges_row[part], ranges_row[part + 1] - ranges_row[part]);
1625 for (; miit_row != hi_miit_row; miit_row++) {
1626 bool success = dofs_row_by_idx.modify(
1631 "modification unsuccessful");
1633 success = dofs_row_by_idx.modify(
1637 "modification unsuccessful");
1640 if (!square_matrix) {
1641 miit_col = dofs_col_by_idx.lower_bound(ranges_col[part]);
1642 hi_miit_col = dofs_col_by_idx.lower_bound(ranges_col[part + 1]);
1643 if (std::distance(miit_col, hi_miit_col) !=
1644 ranges_col[part + 1] - ranges_col[part]) {
1645 SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1646 "data inconsistency, std::distance(miit_col,hi_miit_col) != "
1648 "rstart (%d != %d - %d = %d) ",
1649 std::distance(miit_col, hi_miit_col), ranges_col[part + 1],
1650 ranges_col[part], ranges_col[part + 1] - ranges_col[part]);
1653 for (; miit_col != hi_miit_col; miit_col++) {
1654 bool success = dofs_col_by_idx.modify(
1656 part, (*miit_col)->dofIdx));
1659 "modification unsuccessful");
1661 success = dofs_col_by_idx.modify(
1665 "modification unsuccessful");
1670 CHKERR PetscLayoutDestroy(&layout_row);
1671 if (!square_matrix) {
1672 CHKERR PetscLayoutDestroy(&layout_col);
1674 if (square_matrix) {
1675 nb_col_local_dofs = nb_row_local_dofs;
1676 nb_col_ghost_dofs = nb_row_ghost_dofs;
1689 MOFEM_LOG(
"WORLD", Sev::noisy) <<
"Partition problem " << name;
1691 using NumeredDofEntitysByIdx =
1696 auto &problems_set =
1697 const_cast<ProblemsByName &
>(problems_ptr->get<
Problem_mi_tag>());
1698 auto p_miit = problems_set.find(name);
1699 if (p_miit == problems_set.end()) {
1701 "problem with name %s not defined (top tip check spelling)",
1704 int nb_dofs_row = p_miit->getNbDofsRow();
1714 "entFEAdjacencies not build");
1720 ->createMPIAdjWithArrays<Idx_mi_tag>(name, &Adj, verb);
1725 MatView(Adj, PETSC_VIEWER_STDOUT_WORLD);
1728 MatPartitioning part;
1731 CHKERR MatPartitioningSetAdjacency(part, Adj);
1732 CHKERR MatPartitioningSetFromOptions(part);
1734 CHKERR MatPartitioningApply(part, &is);
1736 ISView(is, PETSC_VIEWER_STDOUT_WORLD);
1739 IS is_gather, is_num, is_gather_num;
1740 CHKERR ISAllGather(is, &is_gather);
1741 CHKERR ISPartitioningToNumbering(is, &is_num);
1742 CHKERR ISAllGather(is_num, &is_gather_num);
1743 const int *part_number, *petsc_idx;
1744 CHKERR ISGetIndices(is_gather, &part_number);
1745 CHKERR ISGetIndices(is_gather_num, &petsc_idx);
1746 int size_is_num, size_is_gather;
1747 CHKERR ISGetSize(is_gather, &size_is_gather);
1748 if (size_is_gather != (
int)nb_dofs_row)
1749 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1750 "data inconsistency %d != %d", size_is_gather, nb_dofs_row);
1752 CHKERR ISGetSize(is_num, &size_is_num);
1753 if (size_is_num != (
int)nb_dofs_row)
1754 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1755 "data inconsistency %d != %d", size_is_num, nb_dofs_row);
1757 bool square_matrix =
false;
1758 if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr)
1759 square_matrix =
true;
1786 auto number_dofs = [&](
auto &dofs_idx,
auto &counter) {
1788 for (
auto miit_dofs_row = dofs_idx.begin();
1789 miit_dofs_row != dofs_idx.end(); miit_dofs_row++) {
1790 const int part = part_number[(*miit_dofs_row)->dofIdx];
1792 const bool success = dofs_idx.modify(
1795 part, petsc_idx[(*miit_dofs_row)->dofIdx], counter++));
1798 "modification unsuccessful");
1801 const bool success = dofs_idx.modify(
1803 part, petsc_idx[(*miit_dofs_row)->dofIdx]));
1806 "modification unsuccessful");
1814 auto &dofs_row_by_idx_no_const =
const_cast<NumeredDofEntitysByIdx &
>(
1815 p_miit->numeredRowDofsPtr->get<
Idx_mi_tag>());
1816 int &nb_row_local_dofs = p_miit->nbLocDofsRow;
1817 int &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
1818 nb_row_local_dofs = 0;
1819 nb_row_ghost_dofs = 0;
1821 CHKERR number_dofs(dofs_row_by_idx_no_const, nb_row_local_dofs);
1823 int &nb_col_local_dofs = p_miit->nbLocDofsCol;
1824 int &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
1825 if (square_matrix) {
1826 nb_col_local_dofs = nb_row_local_dofs;
1827 nb_col_ghost_dofs = nb_row_ghost_dofs;
1829 NumeredDofEntitysByIdx &dofs_col_by_idx_no_const =
1830 const_cast<NumeredDofEntitysByIdx &
>(
1831 p_miit->numeredColDofsPtr->get<
Idx_mi_tag>());
1832 nb_col_local_dofs = 0;
1833 nb_col_ghost_dofs = 0;
1834 CHKERR number_dofs(dofs_col_by_idx_no_const, nb_col_local_dofs);
1837 CHKERR ISRestoreIndices(is_gather, &part_number);
1838 CHKERR ISRestoreIndices(is_gather_num, &petsc_idx);
1839 CHKERR ISDestroy(&is_num);
1840 CHKERR ISDestroy(&is_gather_num);
1841 CHKERR ISDestroy(&is_gather);
1843 CHKERR MatPartitioningDestroy(&part);
1848 auto number_dofs = [&](
auto &dof_idx,
auto &counter) {
1850 for (
auto miit_dofs_row = dof_idx.begin(); miit_dofs_row != dof_idx.end();
1852 const bool success = dof_idx.modify(
1858 "modification unsuccessful");
1864 auto &dofs_row_by_idx_no_const =
const_cast<NumeredDofEntitysByIdx &
>(
1865 p_miit->numeredRowDofsPtr->get<
Idx_mi_tag>());
1866 int &nb_row_local_dofs = p_miit->nbLocDofsRow;
1867 int &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
1868 nb_row_local_dofs = 0;
1869 nb_row_ghost_dofs = 0;
1871 CHKERR number_dofs(dofs_row_by_idx_no_const, nb_row_local_dofs);
1873 bool square_matrix =
false;
1874 if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr)
1875 square_matrix =
true;
1877 int &nb_col_local_dofs = p_miit->nbLocDofsCol;
1878 int &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
1879 if (square_matrix) {
1880 nb_col_local_dofs = nb_row_local_dofs;
1881 nb_col_ghost_dofs = nb_row_ghost_dofs;
1883 NumeredDofEntitysByIdx &dofs_col_by_idx_no_const =
1884 const_cast<NumeredDofEntitysByIdx &
>(
1885 p_miit->numeredColDofsPtr->get<
Idx_mi_tag>());
1886 nb_col_local_dofs = 0;
1887 nb_col_ghost_dofs = 0;
1888 CHKERR number_dofs(dofs_col_by_idx_no_const, nb_col_local_dofs);
1897 const std::string name,
const std::string problem_for_rows,
bool copy_rows,
1898 const std::string problem_for_cols,
bool copy_cols,
int verb) {
1909 ProblemByName &problems_by_name =
1910 const_cast<ProblemByName &
>(problems_ptr->get<
Problem_mi_tag>());
1911 ProblemByName::iterator p_miit = problems_by_name.find(name);
1912 if (p_miit == problems_by_name.end()) {
1914 "problem with name < %s > not defined (top tip check spelling)",
1919 << p_miit->getName() <<
" from rows of " << problem_for_rows
1920 <<
" and columns of " << problem_for_cols;
1923 ProblemByName::iterator p_miit_row = problems_by_name.find(problem_for_rows);
1924 if (p_miit_row == problems_by_name.end()) {
1926 "problem with name < %s > not defined (top tip check spelling)",
1927 problem_for_rows.c_str());
1929 const boost::shared_ptr<NumeredDofEntity_multiIndex> dofs_row =
1930 p_miit_row->numeredRowDofsPtr;
1933 ProblemByName::iterator p_miit_col = problems_by_name.find(problem_for_cols);
1934 if (p_miit_col == problems_by_name.end()) {
1936 "problem with name < %s > not defined (top tip check spelling)",
1937 problem_for_cols.c_str());
1939 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs_col =
1940 p_miit_col->numeredColDofsPtr;
1942 bool copy[] = {copy_rows, copy_cols};
1943 boost::shared_ptr<NumeredDofEntity_multiIndex> composed_dofs[] = {
1944 p_miit->numeredRowDofsPtr, p_miit->numeredColDofsPtr};
1946 int *nb_local_dofs[] = {&p_miit->nbLocDofsRow, &p_miit->nbLocDofsCol};
1947 int *nb_dofs[] = {&p_miit->nbDofsRow, &p_miit->nbDofsCol};
1948 boost::shared_ptr<NumeredDofEntity_multiIndex> copied_dofs[] = {dofs_row,
1951 for (
int ss = 0; ss < 2; ss++) {
1954 *nb_local_dofs[ss] = 0;
1958 std::vector<int> is_local, is_new;
1962 for (NumeredDofEntity_multiIndex::iterator dit =
1963 composed_dofs[ss]->begin();
1964 dit != composed_dofs[ss]->end(); dit++) {
1965 NumeredDofEntityByUId::iterator diit =
1966 dofs_by_uid.find((*dit)->getLocalUniqueId());
1967 if (diit == dofs_by_uid.end()) {
1970 "data inconsistency, could not find dof in composite problem");
1972 int part_number = (*diit)->getPart();
1973 int petsc_global_dof = (*diit)->getPetscGlobalDofIdx();
1975 success = composed_dofs[ss]->modify(
1980 "modification unsuccessful");
1982 if ((*dit)->getPart() == (
unsigned int)m_field.
get_comm_rank()) {
1983 success = composed_dofs[ss]->modify(
1987 "modification unsuccessful");
1989 is_local.push_back(petsc_global_dof);
1994 CHKERR AOCreateMapping(m_field.
get_comm(), is_local.size(), &is_local[0],
1999 for (NumeredDofEntity_multiIndex::iterator dit =
2000 composed_dofs[ss]->begin();
2001 dit != composed_dofs[ss]->end(); dit++) {
2002 is_local.push_back((*dit)->getPetscGlobalDofIdx());
2004 CHKERR AOPetscToApplication(ao, is_local.size(), &is_local[0]);
2006 for (NumeredDofEntity_multiIndex::iterator dit =
2007 composed_dofs[ss]->begin();
2008 dit != composed_dofs[ss]->end(); dit++) {
2009 int part_number = (*dit)->getPart();
2010 int petsc_global_dof = is_local[idx2++];
2012 success = composed_dofs[ss]->modify(
2017 "modification unsuccessful");
2025 for (NumeredDofEntity_multiIndex::iterator dit = copied_dofs[ss]->begin();
2026 dit != copied_dofs[ss]->end(); dit++) {
2027 std::pair<NumeredDofEntity_multiIndex::iterator, bool> p;
2028 p = composed_dofs[ss]->insert(boost::shared_ptr<NumeredDofEntity>(
2033 int dof_idx = (*dit)->getDofIdx();
2034 int part_number = (*dit)->getPart();
2035 int petsc_global_dof = (*dit)->getPetscGlobalDofIdx();
2037 const bool success = composed_dofs[ss]->modify(
2039 part_number, dof_idx, petsc_global_dof,
2040 (*nb_local_dofs[ss])++));
2043 "modification unsuccessful");
2046 const bool success = composed_dofs[ss]->modify(
2048 part_number, dof_idx, petsc_global_dof));
2051 "modification unsuccessful");
2072 << problem_ptr->
getName() <<
" Nb. local dof "
2092 CHKERR moab.create_meshset(MESHSET_SET, out_meshset);
2093 CHKERR moab.add_entities(out_meshset, &ent, 1);
2094 CHKERR moab.write_file(name.c_str(),
"VTK",
"", &out_meshset, 1);
2095 CHKERR moab.delete_entities(&out_meshset, 1);
2102 NumeredDofEntitysByIdx;
2103 NumeredDofEntitysByIdx::iterator dit, hi_dit;
2104 const NumeredDofEntitysByIdx *numered_dofs_ptr[] = {
2112 for (
int ss = 0; ss < 2; ss++) {
2114 dit = numered_dofs_ptr[ss]->begin();
2115 hi_dit = numered_dofs_ptr[ss]->end();
2116 for (; dit != hi_dit; dit++) {
2118 if ((*dit)->getPetscLocalDofIdx() < 0) {
2119 std::ostringstream zz;
2122 "local dof index for %d (0-row, 1-col) not set, i.e. has "
2123 "negative value\n %s",
2124 ss, zz.str().c_str());
2126 if ((*dit)->getPetscLocalDofIdx() >= *local_nbdof_ptr[ss]) {
2127 std::ostringstream zz;
2130 "local dofs for %d (0-row, 1-col) out of range\n %s", ss,
2134 if ((*dit)->getPetscGlobalDofIdx() < 0) {
2141 "_negative_global_index.vtk",
2144 std::ostringstream zz;
2146 << dit->get()->getBitRefLevel() <<
" " << **dit;
2148 "global dof index for %d (0-row, 1-col) row not set, i.e. "
2149 "has negative value\n %s",
2150 ss, zz.str().c_str());
2152 if ((*dit)->getPetscGlobalDofIdx() >= *nbdof_ptr[ss]) {
2153 std::ostringstream zz;
2155 << *nbdof_ptr[ss] <<
" " << **dit;
2157 "global dofs for %d (0-row, 1-col) out of range\n %s", ss,
2168 bool part_from_moab,
2170 int hi_proc,
int verb) {
2184 "adjacencies not build");
2191 "problem not partitioned");
2201 const_cast<ProblemByName &
>(problems_ptr->get<
Problem_mi_tag>());
2202 ProblemByName::iterator p_miit = problems.find(name);
2203 if (p_miit == problems.end()) {
2205 "problem < %s > not found (top tip: check spelling)",
2211 *p_miit->numeredFiniteElementsPtr;
2214 problem_finite_elements.clear();
2218 bool do_cols_prob =
true;
2219 if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr) {
2220 do_cols_prob =
false;
2223 auto get_good_elems = [&]() {
2224 auto good_elems = std::vector<decltype(fe_ent_ptr->begin())>();
2225 good_elems.reserve(fe_ent_ptr->size());
2227 const auto prb_bit = p_miit->getBitRefLevel();
2228 const auto prb_mask = p_miit->getBitRefLevelMask();
2232 for (
auto efit = fe_ent_ptr->begin(); efit != fe_ent_ptr->end(); ++efit) {
2235 if (((*efit)->getId() & p_miit->getBitFEId()).any()) {
2237 const auto &fe_bit = (*efit)->getBitRefLevel();
2240 if ((fe_bit & prb_mask) == fe_bit && (fe_bit & prb_bit).any())
2241 good_elems.emplace_back(efit);
2248 auto good_elems = get_good_elems();
2250 auto numbered_good_elems_ptr =
2251 boost::make_shared<std::vector<NumeredEntFiniteElement>>();
2252 numbered_good_elems_ptr->reserve(good_elems.size());
2253 for (
auto &efit : good_elems)
2256 if (!do_cols_prob) {
2257 for (
auto &fe : *numbered_good_elems_ptr) {
2258 if (fe.sPtr->getRowFieldEntsPtr() == fe.sPtr->getColFieldEntsPtr()) {
2259 fe.getColFieldEntsPtr() = fe.getRowFieldEntsPtr();
2264 if (part_from_moab) {
2265 for (
auto &fe : *numbered_good_elems_ptr) {
2267 int proc = fe.getPartProc();
2268 if (proc == -1 && fe.getEntType() == MBVERTEX)
2269 proc = fe.getOwnerProc();
2274 for (
auto &fe : *numbered_good_elems_ptr) {
2277 CHKERR fe.sPtr->getRowDofView(*(p_miit->numeredRowDofsPtr), rows_view);
2279 if (!part_from_moab) {
2281 for (
auto &dof_ptr : rows_view)
2282 parts[dof_ptr->pArt]++;
2283 std::vector<int>::iterator pos = max_element(parts.begin(), parts.end());
2284 const auto max_part = std::distance(parts.begin(), pos);
2289 for (
auto &fe : *numbered_good_elems_ptr) {
2291 auto check_fields_and_dofs = [&]() {
2292 if (!part_from_moab) {
2293 if (fe.getBitFieldIdRow().none() && m_field.
get_comm_size() == 0) {
2295 <<
"At least one field has to be added to element row to "
2296 "determine partition of finite element. Check element " +
2297 boost::lexical_cast<std::string>(fe.getName());
2304 if (check_fields_and_dofs()) {
2306 auto p = problem_finite_elements.insert(
2307 boost::shared_ptr<NumeredEntFiniteElement>(numbered_good_elems_ptr,
2315 auto elements_on_rank =
2316 problem_finite_elements.get<
Part_mi_tag>().equal_range(
2319 << p_miit->getName() <<
" nb. elems "
2320 << std::distance(elements_on_rank.first, elements_on_rank.second);
2322 for (
auto &fe : *fe_ptr) {
2328 <<
"Element " << fe->getName() <<
" nb. elems "
2329 << std::distance(e_range.first, e_range.second);
2347 "partition of problem not build");
2350 "partitions finite elements not build");
2359 int &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
2360 int &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
2361 nb_row_ghost_dofs = 0;
2362 nb_col_ghost_dofs = 0;
2372 p_miit->numeredFiniteElementsPtr->get<
Part_mi_tag>().equal_range(
2378 using Vec = std::vector<boost::shared_ptr<NumeredDofEntity>>;
2379 using It = Vec::iterator;
2380 It operator()(
Vec &dofs_view, It &hint,
2381 boost::shared_ptr<NumeredDofEntity> &&dof) {
2382 dofs_view.emplace_back(dof);
2383 return dofs_view.end();
2388 std::vector<boost::shared_ptr<NumeredDofEntity>> fe_vec_view;
2389 auto hint_r = ghost_idx_row_view.begin();
2390 for (
auto fe_ptr = fe_range.first; fe_ptr != fe_range.second; ++fe_ptr) {
2392 fe_vec_view.clear();
2394 *(p_miit->getNumeredRowDofsPtr()),
2395 fe_vec_view, Inserter());
2397 for (
auto &dof_ptr : fe_vec_view) {
2398 if (dof_ptr->getPart() != (
unsigned int)m_field.
get_comm_rank()) {
2399 hint_r = ghost_idx_row_view.emplace_hint(hint_r, dof_ptr);
2405 if (p_miit->numeredColDofsPtr == p_miit->numeredRowDofsPtr) {
2407 auto hint_c = ghost_idx_col_view.begin();
2408 for (
auto fe_ptr = fe_range.first; fe_ptr != fe_range.second; ++fe_ptr) {
2410 fe_vec_view.clear();
2412 *(p_miit->getNumeredColDofsPtr()),
2413 fe_vec_view, Inserter());
2415 for (
auto &dof_ptr : fe_vec_view) {
2416 if (dof_ptr->getPart() != (
unsigned int)m_field.
get_comm_rank()) {
2417 hint_c = ghost_idx_col_view.emplace_hint(hint_c, dof_ptr);
2423 int *nb_ghost_dofs[2] = {&nb_row_ghost_dofs, &nb_col_ghost_dofs};
2424 int nb_local_dofs[2] = {p_miit->nbLocDofsRow, p_miit->nbLocDofsCol};
2427 &ghost_idx_row_view, &ghost_idx_col_view};
2433 if (p_miit->numeredColDofsPtr == p_miit->numeredRowDofsPtr) {
2438 for (
int ss = 0; ss != loop_size; ++ss) {
2439 for (
auto &gid : *ghost_idx_view[ss]) {
2440 NumeredDofEntityByUId::iterator dof =
2441 dof_by_uid_no_const[ss]->find(gid->getLocalUniqueId());
2442 if (PetscUnlikely((*dof)->petscLocalDofIdx != (
DofIdx)-1))
2444 "inconsistent data, ghost dof already set");
2445 bool success = dof_by_uid_no_const[ss]->modify(
2447 if (PetscUnlikely(!success))
2449 "modification unsuccessful");
2450 (*nb_ghost_dofs[ss])++;
2453 if (loop_size == 1) {
2454 (*nb_ghost_dofs[1]) = (*nb_ghost_dofs[0]);
2460 <<
" FEs ghost dofs on problem " << p_miit->getName()
2461 <<
" Nb. ghost dof " << p_miit->getNbGhostDofsRow() <<
" by "
2462 << p_miit->getNbGhostDofsCol() <<
" Nb. local dof "
2463 << p_miit->getNbLocalDofsCol() <<
" by " << p_miit->getNbLocalDofsCol();
2481 "partition of problem not build");
2484 "partitions finite elements not build");
2489 ProblemsByName &problems_set =
2490 const_cast<ProblemsByName &
>(problems_ptr->get<
Problem_mi_tag>());
2491 ProblemsByName::iterator p_miit = problems_set.find(name);
2495 DofIdx *nb_ghost_dofs[2] = {&(p_miit->nbGhostDofsRow),
2496 &(p_miit->nbGhostDofsCol)};
2497 DofIdx nb_local_dofs[2] = {p_miit->nbLocDofsRow, p_miit->nbLocDofsCol};
2498 for (
int ss = 0; ss != 2; ++ss) {
2499 (*nb_ghost_dofs[ss]) = 0;
2506 if (p_miit->numeredColDofsPtr == p_miit->numeredRowDofsPtr) {
2510 typedef decltype(p_miit->numeredRowDofsPtr) NumbDofTypeSharedPtr;
2511 NumbDofTypeSharedPtr numered_dofs[] = {p_miit->numeredRowDofsPtr,
2512 p_miit->numeredColDofsPtr};
2515 for (
int ss = 0; ss != loop_size; ++ss) {
2520 std::vector<NumeredDofEntity_multiIndex::iterator> ghost_idx_view;
2521 ghost_idx_view.reserve(std::distance(
r.first,
r.second));
2522 for (;
r.first !=
r.second; ++
r.first)
2523 ghost_idx_view.emplace_back(numered_dofs[ss]->project<0>(
r.first));
2525 auto cmp = [](
auto a,
auto b) {
2526 return (*a)->getLocalUniqueId() < (*b)->getLocalUniqueId();
2528 sort(ghost_idx_view.begin(), ghost_idx_view.end(), cmp);
2531 for (
auto gid_it : ghost_idx_view) {
2532 bool success = numered_dofs[ss]->modify(
2536 "modification unsuccessful");
2537 ++(*nb_ghost_dofs[ss]);
2540 if (loop_size == 1) {
2541 (*nb_ghost_dofs[1]) = (*nb_ghost_dofs[0]);
2547 <<
" FEs ghost dofs on problem " << p_miit->getName()
2548 <<
" Nb. ghost dof " << p_miit->getNbGhostDofsRow() <<
" by "
2549 << p_miit->getNbGhostDofsCol() <<
" Nb. local dof "
2550 << p_miit->getNbLocalDofsCol() <<
" by " << p_miit->getNbLocalDofsCol();
2560 const std::string &fe_name,
2576 0, (*fe_miit)->getFEUId()));
2580 get_id_for_max_type<MBENTITYSET>(), (*fe_miit)->getFEUId()));
2581 std::vector<EntityHandle> fe_vec;
2582 fe_vec.reserve(std::distance(fit, hi_fe_it));
2583 for (; fit != hi_fe_it; fit++)
2584 fe_vec.push_back(fit->get()->getEnt());
2585 CHKERR m_field.
get_moab().add_entities(*meshset, &*fe_vec.begin(),
2594 const std::string &fe_name,
2595 PetscLayout *layout)
const {
2607 std::vector<boost::weak_ptr<NumeredDofEntity>> &vec_dof_view,
2610 const Range ents,
int bridge_dim,
const int lo_coeff,
const int hi_coeff,
2611 const int lo_order,
const int hi_order,
int verb,
const bool debug
2636 ents, bridge_dim,
false, bridge_ents, moab::Interface::UNION);
2640 const auto nb_coeffs =
2645 using NumeredDofEntity_it_view_multiIndex = multi_index_container<
2647 NumeredDofEntity_multiIndex::iterator, indexed_by<sequenced<>>
2650 NumeredDofEntity_it_view_multiIndex dofs_it_view;
2652 for (
auto pit = bridge_ents.const_pair_begin();
2653 pit != bridge_ents.const_pair_end(); ++pit) {
2654 auto lo = numered_dofs[rc]->get<
Unique_mi_tag>().lower_bound(
2656 auto hi = numered_dofs[rc]->get<
Unique_mi_tag>().upper_bound(
2659 auto bride_type = moab.type_from_handle(pit->first);
2661 for (; lo != hi; ++lo) {
2662 if ((*lo)->getDofCoeffIdx() >= lo_coeff &&
2663 (*lo)->getDofCoeffIdx() <= hi_coeff &&
2664 (*lo)->getDofOrder() >= lo_order &&
2665 (*lo)->getDofOrder() <= hi_order) {
2666 auto ent_dof_index = (*lo)->getEntDofIdx();
2667 auto side_it = side_dof_map.at(bride_type)
2669 .find(std::floor(
static_cast<double>(ent_dof_index) /
2673 auto bridge_ent = (*lo)->getEnt();
2674 auto type = side_it->type;
2675 auto side = side_it->side;
2676 auto dim = CN::Dimension(
type);
2678 CHKERR moab.side_element(bridge_ent, dim, side, side_ent);
2679 if (ents.find(side_ent) != ents.end()) {
2680 dofs_it_view.emplace_back(numered_dofs[rc]->project<0>(lo));
2687 <<
"side not found for entity " << CN::EntityTypeName(bride_type);
2689 <<
"ent_dof_index / nb_coeffs "
2690 << std::floor(
static_cast<double>(ent_dof_index) / nb_coeffs);
2692 <<
"side_dof_map.size() " << side_dof_map.size();
2695 "side not found - you will get more information in debug");
2702 for (
auto &dof : dofs_it_view)
2707 vec_dof_view.reserve(vec_dof_view.size() + dofs_it_view.size());
2708 for (
auto dit : dofs_it_view)
2709 vec_dof_view.push_back(*dit);
2715 const std::string problem_name,
RowColData rc,
2716 std::vector<boost::weak_ptr<NumeredDofEntity>> &vec_dof_view,
int verb,
2748 if (numered_dofs[rc]) {
2752 "Number of DOFs in multi-index %d and to delete %d\n",
2753 numered_dofs[rc]->size(), vec_dof_view.size());
2756 for (
auto weak_dit : vec_dof_view)
2757 if (
auto dit = weak_dit.lock()) {
2758 numered_dofs[rc]->erase(dit->getLocalUniqueId());
2763 "Number of DOFs in multi-index after delete %d\n",
2764 numered_dofs[rc]->size());
2767 int nb_local_dofs = 0;
2768 int nb_ghost_dofs = 0;
2769 for (
auto dit = numered_dofs[rc]->get<PetscLocalIdx_mi_tag>().begin();
2771 if ((*dit)->getPetscLocalDofIdx() >= 0 &&
2772 (*dit)->getPetscLocalDofIdx() < *(local_nbdof_ptr[rc]))
2774 else if ((*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[rc]))
2778 "Impossible case. You could run problem on no distributed "
2779 "mesh. That is not implemented. Dof local index is %d",
2780 (*dit)->getPetscLocalDofIdx());
2784 auto get_indices_by_tag = [&](
auto tag,
auto &indices,
bool only_local) {
2785 const int nb_dofs = numered_dofs[rc]->size();
2787 indices.reserve(nb_dofs);
2788 for (
auto dit = numered_dofs[rc]->get<decltype(tag)>().begin();
2789 dit != numered_dofs[rc]->get<decltype(tag)>().end(); ++dit) {
2792 if ((*dit)->getPetscLocalDofIdx() < 0 ||
2793 (*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[rc])) {
2798 indices.push_back(decltype(tag)::get_index(dit));
2802 auto get_indices_by_uid = [&](
auto tag,
auto &indices) {
2803 const int nb_dofs = numered_dofs[rc]->size();
2805 indices.reserve(nb_dofs);
2806 for (
auto dit = numered_dofs[rc]->begin(); dit != numered_dofs[rc]->end();
2808 indices.push_back(decltype(tag)::get_index(dit));
2811 auto get_sub_ao = [&](
auto sub_data) {
2813 return sub_data->getSmartRowMap();
2815 return sub_data->getSmartColMap();
2819 auto set_sub_is_and_ao = [&rc, &prb_ptr](
auto sub_data,
auto is,
auto ao) {
2821 sub_data->rowIs = is;
2822 sub_data->rowMap = ao;
2823 sub_data->colIs = is;
2824 sub_data->colMap = ao;
2826 sub_data->colIs = is;
2827 sub_data->colMap = ao;
2831 auto apply_symmetry = [&rc, &prb_ptr](
auto sub_data) {
2834 sub_data->colIs = sub_data->getSmartRowIs();
2835 sub_data->colMap = sub_data->getSmartRowMap();
2840 auto concatenate_dofs = [&](
auto tag,
auto &indices,
2841 const auto local_only) {
2843 get_indices_by_tag(tag, indices, local_only);
2850 &*indices.begin(), PETSC_NULL);
2852 ao =
createAOMapping(PETSC_COMM_SELF, indices.size(), &*indices.begin(),
2860 &*indices.begin(), PETSC_COPY_VALUES);
2863 auto sub_ao = get_sub_ao(sub_data);
2864 CHKERR AOPetscToApplicationIS(sub_ao, sub_is);
2867 set_sub_is_and_ao(sub_data, sub_is, sub_ao);
2868 apply_symmetry(sub_data);
2871 prb_ptr->
getSubData() = boost::make_shared<Problem::SubProblemData>();
2873 &*indices.begin(), PETSC_COPY_VALUES);
2875 set_sub_is_and_ao(prb_ptr->
getSubData(), sub_is, ao);
2880 get_indices_by_uid(tag, indices);
2881 CHKERR AOApplicationToPetsc(ao, indices.size(), &*indices.begin());
2887 auto set_concatenated_indices = [&]() {
2888 std::vector<int> global_indices;
2889 std::vector<int> local_indices;
2893 auto gi = global_indices.begin();
2894 auto li = local_indices.begin();
2895 for (
auto dit = numered_dofs[rc]->begin(); dit != numered_dofs[rc]->end();
2898 (*dit)->getPart(), (*dit)->getDofIdx(), *gi, *li);
2899 bool success = numered_dofs[rc]->modify(dit, mod);
2902 "can not set negative indices");
2908 CHKERR set_concatenated_indices();
2910 MPI_Allreduce(&nb_local_dofs, nbdof_ptr[rc], 1, MPI_INT, MPI_SUM,
2912 *(local_nbdof_ptr[rc]) = nb_local_dofs;
2913 *(ghost_nbdof_ptr[rc]) = nb_ghost_dofs;
2916 for (
auto dof : (*numered_dofs[rc])) {
2917 if (dof->getPetscGlobalDofIdx() < 0) {
2919 "Negative global idx");
2921 if (dof->getPetscLocalDofIdx() < 0) {
2923 "Negative local idx");
2929 *(nbdof_ptr[1]) = *(nbdof_ptr[0]);
2930 *(local_nbdof_ptr[1]) = *(local_nbdof_ptr[0]);
2931 *(ghost_nbdof_ptr[1]) = *(ghost_nbdof_ptr[0]);
2936 "WORLD", Sev::inform,
2937 "Removed DOFs from problem %s dofs [%d / %d (before %d / %d) global]",
2939 prb_ptr->
getNbDofsCol(), nb_init_row_dofs, nb_init_col_dofs);
2941 "Removed DOFs from problem %s dofs [ %d / %d "
2942 "(before %d / %d) local, %d / %d (before %d / %d)]",
2947 nb_init_ghost_col_dofs);
2955 const std::string problem_name,
const std::string
field_name,
2956 const Range ents,
const int lo_coeff,
const int hi_coeff,
2957 const int lo_order,
const int hi_order,
int verb,
const bool debug) {
2981 for (
int s = 0; s != 2; ++s)
2982 if (numered_dofs[s]) {
2984 using NumeredDofEntity_it_view_multiIndex = multi_index_container<
2986 NumeredDofEntity_multiIndex::iterator, indexed_by<sequenced<>>
2991 NumeredDofEntity_it_view_multiIndex dofs_it_view;
2994 for (
auto pit = ents.const_pair_begin(); pit != ents.const_pair_end();
2996 auto lo = numered_dofs[s]->get<
Unique_mi_tag>().lower_bound(
2998 auto hi = numered_dofs[s]->get<
Unique_mi_tag>().upper_bound(
3001 for (; lo != hi; ++lo)
3002 if ((*lo)->getDofCoeffIdx() >= lo_coeff &&
3003 (*lo)->getDofCoeffIdx() <= hi_coeff &&
3004 (*lo)->getDofOrder() >= lo_order &&
3005 (*lo)->getDofOrder() <= hi_order)
3006 dofs_it_view.emplace_back(numered_dofs[s]->project<0>(lo));
3010 for (
auto &dof : dofs_it_view)
3016 std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_weak_view;
3017 dofs_weak_view.reserve(dofs_it_view.size());
3018 for (
auto dit : dofs_it_view)
3019 dofs_weak_view.push_back(*dit);
3023 "Number of DOFs in multi-index %d and to delete %d\n",
3024 numered_dofs[s]->size(), dofs_it_view.size());
3027 for (
auto weak_dit : dofs_weak_view)
3028 if (
auto dit = weak_dit.lock()) {
3029 numered_dofs[s]->erase(dit->getLocalUniqueId());
3034 "Number of DOFs in multi-index after delete %d\n",
3035 numered_dofs[s]->size());
3038 int nb_local_dofs = 0;
3039 int nb_ghost_dofs = 0;
3040 for (
auto dit = numered_dofs[s]->get<PetscLocalIdx_mi_tag>().begin();
3042 if ((*dit)->getPetscLocalDofIdx() >= 0 &&
3043 (*dit)->getPetscLocalDofIdx() < *(local_nbdof_ptr[s]))
3045 else if ((*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[s]))
3049 "Impossible case. You could run problem on no distributed "
3050 "mesh. That is not implemented. Dof local index is %d",
3051 (*dit)->getPetscLocalDofIdx());
3055 auto get_indices_by_tag = [&](
auto tag,
auto &indices,
bool only_local) {
3056 const int nb_dofs = numered_dofs[s]->size();
3058 indices.reserve(nb_dofs);
3059 for (
auto dit = numered_dofs[s]->get<decltype(tag)>().begin();
3060 dit != numered_dofs[s]->get<decltype(tag)>().end(); ++dit) {
3063 if ((*dit)->getPetscLocalDofIdx() < 0 ||
3064 (*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[s])) {
3069 indices.push_back(decltype(tag)::get_index(dit));
3073 auto get_indices_by_uid = [&](
auto tag,
auto &indices) {
3074 const int nb_dofs = numered_dofs[s]->size();
3076 indices.reserve(nb_dofs);
3077 for (
auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3079 indices.push_back(decltype(tag)::get_index(dit));
3082 auto get_sub_ao = [&](
auto sub_data) {
3084 return sub_data->getSmartRowMap();
3086 return sub_data->getSmartColMap();
3090 auto set_sub_is_and_ao = [&s, &prb_ptr](
auto sub_data,
auto is,
auto ao) {
3092 sub_data->rowIs = is;
3093 sub_data->rowMap = ao;
3094 sub_data->colIs = is;
3095 sub_data->colMap = ao;
3097 sub_data->colIs = is;
3098 sub_data->colMap = ao;
3102 auto apply_symmetry = [&s, &prb_ptr](
auto sub_data) {
3105 sub_data->colIs = sub_data->getSmartRowIs();
3106 sub_data->colMap = sub_data->getSmartRowMap();
3111 auto concatenate_dofs = [&](
auto tag,
auto &indices,
3112 const auto local_only) {
3114 get_indices_by_tag(tag, indices, local_only);
3121 &*indices.begin(), PETSC_NULL);
3124 &*indices.begin(), PETSC_NULL);
3131 &*indices.begin(), PETSC_COPY_VALUES);
3134 auto sub_ao = get_sub_ao(sub_data);
3135 CHKERR AOPetscToApplicationIS(sub_ao, sub_is);
3138 set_sub_is_and_ao(sub_data, sub_is, sub_ao);
3139 apply_symmetry(sub_data);
3143 boost::make_shared<Problem::SubProblemData>();
3145 &*indices.begin(), PETSC_COPY_VALUES);
3147 set_sub_is_and_ao(prb_ptr->
getSubData(), sub_is, ao);
3152 get_indices_by_uid(tag, indices);
3153 CHKERR AOApplicationToPetsc(ao, indices.size(), &*indices.begin());
3159 auto set_concatenated_indices = [&]() {
3160 std::vector<int> global_indices;
3161 std::vector<int> local_indices;
3165 auto gi = global_indices.begin();
3166 auto li = local_indices.begin();
3167 for (
auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3170 (*dit)->getPart(), (*dit)->getDofIdx(), *gi, *li);
3171 bool success = numered_dofs[s]->modify(dit, mod);
3174 "can not set negative indices");
3180 CHKERR set_concatenated_indices();
3182 MPI_Allreduce(&nb_local_dofs, nbdof_ptr[s], 1, MPI_INT, MPI_SUM,
3184 *(local_nbdof_ptr[s]) = nb_local_dofs;
3185 *(ghost_nbdof_ptr[s]) = nb_ghost_dofs;
3188 for (
auto dof : (*numered_dofs[s])) {
3189 if (dof->getPetscGlobalDofIdx() < 0) {
3191 "Negative global idx");
3193 if (dof->getPetscLocalDofIdx() < 0) {
3195 "Negative local idx");
3201 *(nbdof_ptr[1]) = *(nbdof_ptr[0]);
3202 *(local_nbdof_ptr[1]) = *(local_nbdof_ptr[0]);
3203 *(ghost_nbdof_ptr[1]) = *(ghost_nbdof_ptr[0]);
3208 "WORLD", Sev::inform,
3209 "Removed DOFs from problem %s dofs [%d / %d (before %d / %d) global]",
3211 prb_ptr->
getNbDofsCol(), nb_init_row_dofs, nb_init_col_dofs);
3213 "Removed DOFs from problem %s dofs [ %d / %d "
3214 "(before %d / %d) local, %d / %d (before %d / %d)]",
3219 nb_init_ghost_col_dofs);
3227 const std::string problem_name,
const std::string
field_name,
3228 const Range ents,
const int lo_coeff,
const int hi_coeff,
3229 const int lo_order,
const int hi_order,
int verb,
const bool debug) {
3253 const std::array<int, 2> nb_init_dofs = {nb_init_row_dofs, nb_init_col_dofs};
3255 for (
int s = 0; s != 2; ++s)
3256 if (numered_dofs[s]) {
3258 typedef multi_index_container<
3260 NumeredDofEntity_multiIndex::iterator, indexed_by<sequenced<>>
3263 NumeredDofEntity_it_view_multiIndex;
3266 NumeredDofEntity_it_view_multiIndex dofs_it_view;
3269 for (
auto pit = ents.const_pair_begin(); pit != ents.const_pair_end();
3271 auto lo = numered_dofs[s]->get<
Unique_mi_tag>().lower_bound(
3273 auto hi = numered_dofs[s]->get<
Unique_mi_tag>().upper_bound(
3276 for (; lo != hi; ++lo)
3277 if ((*lo)->getDofCoeffIdx() >= lo_coeff &&
3278 (*lo)->getDofCoeffIdx() <= hi_coeff &&
3279 (*lo)->getDofOrder() >= lo_order &&
3280 (*lo)->getDofOrder() <= hi_order)
3281 dofs_it_view.emplace_back(numered_dofs[s]->project<0>(lo));
3285 for (
auto &dof : dofs_it_view)
3291 for (
auto dit : dofs_it_view) {
3292 bool success = numered_dofs[s]->modify(dit, mod);
3295 "can not set negative indices");
3299 std::vector<boost::weak_ptr<NumeredDofEntity>> dosf_weak_view;
3300 dosf_weak_view.reserve(dofs_it_view.size());
3301 for (
auto dit : dofs_it_view)
3302 dosf_weak_view.push_back(*dit);
3306 "Number of DOFs in multi-index %d and to delete %d\n",
3307 numered_dofs[s]->size(), dofs_it_view.size());
3310 for (
auto weak_dit : dosf_weak_view)
3311 if (
auto dit = weak_dit.lock()) {
3312 numered_dofs[s]->erase(dit->getLocalUniqueId());
3317 "Number of DOFs in multi-index after delete %d\n",
3318 numered_dofs[s]->size());
3321 int nb_global_dof = 0;
3322 int nb_local_dofs = 0;
3323 int nb_ghost_dofs = 0;
3325 for (
auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3328 if ((*dit)->getDofIdx() >= 0) {
3330 if ((*dit)->getPetscLocalDofIdx() >= 0 &&
3331 (*dit)->getPetscLocalDofIdx() < *(local_nbdof_ptr[s]))
3333 else if ((*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[s]))
3341 MPI_Allreduce(&nb_local_dofs, nbdof_ptr[s], 1, MPI_INT, MPI_SUM,
3343 if (*(nbdof_ptr[s]) != nb_global_dof)
3345 "Number of local DOFs do not add up %d != %d",
3346 *(nbdof_ptr[s]), nb_global_dof);
3349 *(nbdof_ptr[s]) = nb_global_dof;
3350 *(local_nbdof_ptr[s]) = nb_local_dofs;
3351 *(ghost_nbdof_ptr[s]) = nb_ghost_dofs;
3354 auto get_indices_by_tag = [&](
auto tag) {
3355 std::vector<int> indices;
3356 indices.resize(nb_init_dofs[s], -1);
3357 for (
auto dit = numered_dofs[s]->get<Idx_mi_tag>().lower_bound(0);
3358 dit != numered_dofs[s]->get<
Idx_mi_tag>().end(); ++dit) {
3359 indices[(*dit)->getDofIdx()] = decltype(tag)::get_index(dit);
3364 auto renumber = [&](
auto tag,
auto &indices) {
3367 for (
auto dit = numered_dofs[s]->get<decltype(tag)>().lower_bound(0);
3368 dit != numered_dofs[s]->get<decltype(tag)>().end(); ++dit) {
3369 indices[(*dit)->getDofIdx()] = idx++;
3374 auto get_sub_ao = [&](
auto sub_data) {
3376 return sub_data->getSmartRowMap();
3378 return sub_data->getSmartColMap();
3382 auto set_sub_is_and_ao = [&s, &prb_ptr](
auto sub_data,
auto is,
auto ao) {
3384 sub_data->rowIs = is;
3385 sub_data->rowMap = ao;
3386 sub_data->colIs = is;
3387 sub_data->colMap = ao;
3389 sub_data->colIs = is;
3390 sub_data->colMap = ao;
3394 auto apply_symmetry = [&s, &prb_ptr](
auto sub_data) {
3397 sub_data->colIs = sub_data->getSmartRowIs();
3398 sub_data->colMap = sub_data->getSmartRowMap();
3403 auto set_sub_data = [&](
auto &indices) {
3408 &*indices.begin(), PETSC_COPY_VALUES);
3411 auto sub_ao = get_sub_ao(sub_data);
3412 CHKERR AOPetscToApplicationIS(sub_ao, sub_is);
3415 set_sub_is_and_ao(sub_data, sub_is, sub_ao);
3416 apply_symmetry(sub_data);
3418 prb_ptr->
getSubData() = boost::make_shared<Problem::SubProblemData>();
3420 &*indices.begin(), PETSC_COPY_VALUES);
3423 set_sub_is_and_ao(prb_ptr->
getSubData(), sub_is, sub_ao);
3431 CHKERR set_sub_data(global_indices);
3436 for (
auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3438 auto idx = (*dit)->getDofIdx();
3441 (*dit)->getPart(),
i++, global_indices[idx], local_indices[idx]);
3442 bool success = numered_dofs[s]->modify(dit, mod);
3445 "can not set negative indices");
3448 (*dit)->getPart(), -1, -1, -1);
3449 bool success = numered_dofs[s]->modify(dit, mod);
3452 "can not set negative indices");
3457 for (
auto dof : (*numered_dofs[s])) {
3458 if (dof->getDofIdx() >= 0 && dof->getPetscGlobalDofIdx() < 0) {
3460 "Negative global idx");
3467 *(nbdof_ptr[1]) = *(nbdof_ptr[0]);
3468 *(local_nbdof_ptr[1]) = *(local_nbdof_ptr[0]);
3469 *(ghost_nbdof_ptr[1]) = *(ghost_nbdof_ptr[0]);
3477 "WORLD", Sev::inform,
3478 "Removed DOFs from problem %s dofs [%d / %d (before %d / %d) global]",
3480 prb_ptr->
getNbDofsCol(), nb_init_row_dofs, nb_init_col_dofs);
3482 "Removed DOFs from problem %s dofs [ %d / %d "
3483 "(before %d / %d) local, %d / %d (before %d / %d)]",
3488 nb_init_ghost_col_dofs);
3495 const std::string problem_name,
const std::string
field_name,
3497 Range *ents_ptr,
const int lo_coeff,
const int hi_coeff,
const int lo_order,
3498 const int hi_order,
int verb,
const bool debug) {
3507 CHKERR bit_manager->filterEntitiesByRefLevel(bit_ref_level, bit_ref_mask,
3510 CHKERR bit_manager->getEntitiesByRefLevel(bit_ref_level, bit_ref_mask, ents,
3515 hi_coeff, lo_order, hi_order, verb,
debug);
3521 const std::string problem_name,
const std::string
field_name,
3523 Range *ents_ptr,
const int lo_coeff,
const int hi_coeff,
const int lo_order,
3524 const int hi_order,
int verb,
const bool debug) {
3533 CHKERR bit_manager->filterEntitiesByRefLevel(bit_ref_level, bit_ref_mask,
3536 CHKERR bit_manager->getEntitiesByRefLevel(bit_ref_level, bit_ref_mask, ents,
3541 lo_coeff, hi_coeff, lo_order,
3542 hi_order, verb,
debug);
3550 std::vector<unsigned char> &
marker)
const {
3556 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs;
3566 marker.resize(dofs->size(), 0);
3567 std::vector<unsigned char> marker_tmp;
3571 for (
auto p = ents.pair_begin(); p != ents.pair_end(); ++p) {
3572 auto lo = dofs->get<
Ent_mi_tag>().lower_bound(p->first);
3573 auto hi = dofs->get<
Ent_mi_tag>().upper_bound(p->second);
3574 for (; lo != hi; ++lo)
3575 marker[(*lo)->getPetscLocalDofIdx()] |= 1;
3579 marker_tmp.resize(dofs->size(), 0);
3580 for (
auto p = ents.pair_begin(); p != ents.pair_end(); ++p) {
3581 auto lo = dofs->get<
Ent_mi_tag>().lower_bound(p->first);
3582 auto hi = dofs->get<
Ent_mi_tag>().upper_bound(p->second);
3583 for (; lo != hi; ++lo)
3584 marker_tmp[(*lo)->getPetscLocalDofIdx()] = 1;
3586 for (
int i = 0;
i !=
marker.size(); ++
i) {
3598 const unsigned char c, std::vector<unsigned char> &
marker)
const {
3604 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs;
3614 marker.resize(dofs->size(), 0);
3621 auto marker_ref = [
marker](
auto &it) ->
unsigned int & {
3622 return marker[(*it)->getPetscLocalDofIdx()];
3627 for (; dof_lo != dof_hi; ++dof_lo)
3628 if ((*dof_lo)->getDofCoeffIdx() >= lo &&
3629 (*dof_lo)->getDofCoeffIdx() <= hi)
3630 marker[(*dof_lo)->getPetscLocalDofIdx()] |=
c;
3633 for (; dof_lo != dof_hi; ++dof_lo)
3634 if ((*dof_lo)->getDofCoeffIdx() >= lo &&
3635 (*dof_lo)->getDofCoeffIdx() <= hi)
3636 marker[(*dof_lo)->getPetscLocalDofIdx()] &=
c;
3645 const std::string problem_name,
RowColData rc,
3646 std::vector<boost::weak_ptr<NumeredDofEntity>> &vec_dof_view,
3647 const enum MarkOP op, std::vector<unsigned char> &
marker
3655 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs;
3666 marker.resize(dofs->size(), 0);
3668 for (
auto &dof : vec_dof_view) {
3669 if (
auto dof_ptr = dof.lock()) {
3670 if (op == MarkOP::OR)
3671 marker[dof_ptr->getPetscLocalDofIdx()] |= 1;
3673 marker[dof_ptr->getPetscLocalDofIdx()] &= 1;
3682 const std::string row_field,
3683 const std::string col_field)
const {
3688 const auto problem_ptr = m_field.
get_problem(problem_name);
3689 auto get_field_id = [&](
const std::string
field_name) {
3692 const auto row_id = get_field_id(row_field);
3693 const auto col_id = get_field_id(col_field);
3695 problem_ptr->addFieldToEmptyFieldBlocks(
BlockFieldPair(row_id, col_id));