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();
136 auto r = adjacencies_ptr->get<
Unique_mi_tag>().equal_range(uid);
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();
361 auto r = adjacencies_ptr->get<
Unique_mi_tag>().equal_range(uid);
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,
1266 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemByName;
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;
1555 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemByName;
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);
1611 for (
unsigned int part = 0; part < (
unsigned int)m_field.
get_comm_size();
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 =
1692 NumeredDofEntity_multiIndex::index<Idx_mi_tag>::type;
1693 using ProblemsByName = Problem_multiIndex::index<Problem_mi_tag>::type;
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) {
1906 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemByName;
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 "
2088 auto save_ent = [](moab::Interface &moab,
const std::string name,
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);
2101 typedef NumeredDofEntity_multiIndex::index<Idx_mi_tag>::type
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++) {
2117 if ((*dit)->getPart() == (
unsigned int)m_field.
get_comm_rank()) {
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");
2199 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemByName;
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");
2487 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
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 {
2606 const std::string problem_name,
const std::string
field_name,
2607 const Range ents,
const int lo_coeff,
const int hi_coeff,
2608 const int lo_order,
const int hi_order,
int verb,
const bool debug) {
2632 for (
int s = 0; s != 2; ++s)
2633 if (numered_dofs[s]) {
2635 typedef multi_index_container<
2637 NumeredDofEntity_multiIndex::iterator, indexed_by<sequenced<>>
2640 NumeredDofEntity_it_view_multiIndex;
2643 NumeredDofEntity_it_view_multiIndex dofs_it_view;
2646 for (
auto pit = ents.const_pair_begin(); pit != ents.const_pair_end();
2648 auto lo = numered_dofs[s]->get<
Unique_mi_tag>().lower_bound(
2650 auto hi = numered_dofs[s]->get<
Unique_mi_tag>().upper_bound(
2653 for (; lo != hi; ++lo)
2654 if ((*lo)->getDofCoeffIdx() >= lo_coeff &&
2655 (*lo)->getDofCoeffIdx() <= hi_coeff &&
2656 (*lo)->getDofOrder() >= lo_order &&
2657 (*lo)->getDofOrder() <= hi_order)
2658 dofs_it_view.emplace_back(numered_dofs[s]->project<0>(lo));
2662 for (
auto &dof : dofs_it_view)
2668 std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_weak_view;
2669 dofs_weak_view.reserve(dofs_it_view.size());
2670 for (
auto dit : dofs_it_view)
2671 dofs_weak_view.push_back(*dit);
2675 "Number of DOFs in multi-index %d and to delete %d\n",
2676 numered_dofs[s]->size(), dofs_it_view.size());
2679 for (
auto weak_dit : dofs_weak_view)
2680 if (
auto dit = weak_dit.lock()) {
2681 numered_dofs[s]->erase(dit->getLocalUniqueId());
2686 "Number of DOFs in multi-index after delete %d\n",
2687 numered_dofs[s]->size());
2690 int nb_local_dofs = 0;
2691 int nb_ghost_dofs = 0;
2692 for (
auto dit = numered_dofs[s]->get<PetscLocalIdx_mi_tag>().begin();
2694 if ((*dit)->getPetscLocalDofIdx() >= 0 &&
2695 (*dit)->getPetscLocalDofIdx() < *(local_nbdof_ptr[s]))
2697 else if ((*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[s]))
2701 "Impossible case. You could run problem on no distributed "
2702 "mesh. That is not implemented. Dof local index is %d",
2703 (*dit)->getPetscLocalDofIdx());
2707 auto get_indices_by_tag = [&](
auto tag,
auto &indices,
bool only_local) {
2708 const int nb_dofs = numered_dofs[s]->size();
2710 indices.reserve(nb_dofs);
2711 for (
auto dit = numered_dofs[s]->get<
decltype(tag)>().begin();
2712 dit != numered_dofs[s]->get<
decltype(tag)>().end(); ++dit) {
2715 if ((*dit)->getPetscLocalDofIdx() < 0 ||
2716 (*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[s])) {
2721 indices.push_back(
decltype(tag)::get_index(dit));
2725 auto get_indices_by_uid = [&](
auto tag,
auto &indices) {
2726 const int nb_dofs = numered_dofs[s]->size();
2728 indices.reserve(nb_dofs);
2729 for (
auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
2731 indices.push_back(
decltype(tag)::get_index(dit));
2734 auto get_sub_ao = [&](
auto sub_data) {
2736 return sub_data->getSmartRowMap();
2738 return sub_data->getSmartColMap();
2742 auto set_sub_is_and_ao = [&s, &prb_ptr](
auto sub_data,
auto is,
auto ao) {
2744 sub_data->rowIs = is;
2745 sub_data->rowMap = ao;
2747 sub_data->colIs = is;
2748 sub_data->colMap = ao;
2752 auto apply_symmetry = [&s, &prb_ptr](
auto sub_data) {
2755 sub_data->colIs = sub_data->getSmartRowIs();
2756 sub_data->colMap = sub_data->getSmartRowMap();
2761 auto concatenate_dofs = [&](
auto tag,
auto &indices,
2762 const auto local_only) {
2764 get_indices_by_tag(tag, indices, local_only);
2771 &*indices.begin(), PETSC_NULL);
2774 &*indices.begin(), PETSC_NULL);
2781 &*indices.begin(), PETSC_COPY_VALUES);
2784 auto sub_ao = get_sub_ao(sub_data);
2785 CHKERR AOPetscToApplicationIS(sub_ao, sub_is);
2788 set_sub_is_and_ao(sub_data, sub_is, sub_ao);
2789 apply_symmetry(sub_data);
2793 boost::make_shared<Problem::SubProblemData>();
2795 &*indices.begin(), PETSC_COPY_VALUES);
2797 set_sub_is_and_ao(prb_ptr->
getSubData(), sub_is, ao);
2802 get_indices_by_uid(tag, indices);
2803 CHKERR AOApplicationToPetsc(ao, indices.size(), &*indices.begin());
2809 auto set_concatenated_indices = [&]() {
2810 std::vector<int> global_indices;
2811 std::vector<int> local_indices;
2815 auto gi = global_indices.begin();
2816 auto li = local_indices.begin();
2817 for (
auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
2820 (*dit)->getPart(), (*dit)->getDofIdx(), *gi, *li);
2821 bool success = numered_dofs[s]->modify(dit, mod);
2824 "can not set negative indices");
2830 CHKERR set_concatenated_indices();
2832 MPI_Allreduce(&nb_local_dofs, nbdof_ptr[s], 1, MPI_INT, MPI_SUM,
2834 *(local_nbdof_ptr[s]) = nb_local_dofs;
2835 *(ghost_nbdof_ptr[s]) = nb_ghost_dofs;
2838 for (
auto dof : (*numered_dofs[s])) {
2839 if (dof->getPetscGlobalDofIdx() < 0) {
2841 "Negative global idx");
2843 if (dof->getPetscLocalDofIdx() < 0) {
2845 "Negative local idx");
2851 *(nbdof_ptr[1]) = *(nbdof_ptr[0]);
2852 *(local_nbdof_ptr[1]) = *(local_nbdof_ptr[0]);
2853 *(ghost_nbdof_ptr[1]) = *(ghost_nbdof_ptr[0]);
2858 "WORLD", Sev::inform,
2859 "Removed DOFs from problem %s dofs [%d / %d (before %d / %d) global]",
2861 prb_ptr->
getNbDofsCol(), nb_init_row_dofs, nb_init_col_dofs);
2863 "Removed DOFs from problem %s dofs [ %d / %d "
2864 "(before %d / %d) local, %d / %d (before %d / %d)]",
2869 nb_init_ghost_col_dofs);
2877 const std::string problem_name,
const std::string
field_name,
2878 const Range ents,
const int lo_coeff,
const int hi_coeff,
2879 const int lo_order,
const int hi_order,
int verb,
const bool debug) {
2903 const std::array<int, 2> nb_init_dofs = {nb_init_row_dofs, nb_init_col_dofs};
2905 for (
int s = 0; s != 2; ++s)
2906 if (numered_dofs[s]) {
2908 typedef multi_index_container<
2910 NumeredDofEntity_multiIndex::iterator, indexed_by<sequenced<>>
2913 NumeredDofEntity_it_view_multiIndex;
2916 NumeredDofEntity_it_view_multiIndex dofs_it_view;
2919 for (
auto pit = ents.const_pair_begin(); pit != ents.const_pair_end();
2921 auto lo = numered_dofs[s]->get<
Unique_mi_tag>().lower_bound(
2923 auto hi = numered_dofs[s]->get<
Unique_mi_tag>().upper_bound(
2926 for (; lo != hi; ++lo)
2927 if ((*lo)->getDofCoeffIdx() >= lo_coeff &&
2928 (*lo)->getDofCoeffIdx() <= hi_coeff &&
2929 (*lo)->getDofOrder() >= lo_order &&
2930 (*lo)->getDofOrder() <= hi_order)
2931 dofs_it_view.emplace_back(numered_dofs[s]->project<0>(lo));
2935 for (
auto &dof : dofs_it_view)
2941 for (
auto dit : dofs_it_view) {
2942 bool success = numered_dofs[s]->modify(dit, mod);
2945 "can not set negative indices");
2949 std::vector<boost::weak_ptr<NumeredDofEntity>> dosf_weak_view;
2950 dosf_weak_view.reserve(dofs_it_view.size());
2951 for (
auto dit : dofs_it_view)
2952 dosf_weak_view.push_back(*dit);
2956 "Number of DOFs in multi-index %d and to delete %d\n",
2957 numered_dofs[s]->size(), dofs_it_view.size());
2960 for (
auto weak_dit : dosf_weak_view)
2961 if (
auto dit = weak_dit.lock()) {
2962 numered_dofs[s]->erase(dit->getLocalUniqueId());
2967 "Number of DOFs in multi-index after delete %d\n",
2968 numered_dofs[s]->size());
2971 int nb_global_dof = 0;
2972 int nb_local_dofs = 0;
2973 int nb_ghost_dofs = 0;
2975 for (
auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
2978 if ((*dit)->getDofIdx() >= 0) {
2980 if ((*dit)->getPetscLocalDofIdx() >= 0 &&
2981 (*dit)->getPetscLocalDofIdx() < *(local_nbdof_ptr[s]))
2983 else if ((*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[s]))
2991 MPI_Allreduce(&nb_local_dofs, nbdof_ptr[s], 1, MPI_INT, MPI_SUM,
2993 if (*(nbdof_ptr[s]) != nb_global_dof)
2995 "Number of local DOFs do not add up %d != %d",
2996 *(nbdof_ptr[s]), nb_global_dof);
2999 *(nbdof_ptr[s]) = nb_global_dof;
3000 *(local_nbdof_ptr[s]) = nb_local_dofs;
3001 *(ghost_nbdof_ptr[s]) = nb_ghost_dofs;
3004 auto get_indices_by_tag = [&](
auto tag) {
3005 std::vector<int> indices;
3006 indices.resize(nb_init_dofs[s], -1);
3007 for (
auto dit = numered_dofs[s]->get<Idx_mi_tag>().lower_bound(0);
3008 dit != numered_dofs[s]->get<
Idx_mi_tag>().end(); ++dit) {
3009 indices[(*dit)->getDofIdx()] =
decltype(tag)::get_index(dit);
3014 auto renumber = [&](
auto tag,
auto &indices) {
3017 for (
auto dit = numered_dofs[s]->get<
decltype(tag)>().lower_bound(0);
3018 dit != numered_dofs[s]->get<
decltype(tag)>().end(); ++dit) {
3019 indices[(*dit)->getDofIdx()] = idx++;
3024 auto get_sub_ao = [&](
auto sub_data) {
3026 return sub_data->getSmartRowMap();
3028 return sub_data->getSmartColMap();
3032 auto set_sub_is_and_ao = [&s, &prb_ptr](
auto sub_data,
auto is,
auto ao) {
3034 sub_data->rowIs = is;
3035 sub_data->rowMap = ao;
3037 sub_data->colIs = is;
3038 sub_data->colMap = ao;
3042 auto apply_symmetry = [&s, &prb_ptr](
auto sub_data) {
3045 sub_data->colIs = sub_data->getSmartRowIs();
3046 sub_data->colMap = sub_data->getSmartRowMap();
3051 auto set_sub_data = [&](
auto &indices) {
3056 &*indices.begin(), PETSC_COPY_VALUES);
3059 auto sub_ao = get_sub_ao(sub_data);
3060 CHKERR AOPetscToApplicationIS(sub_ao, sub_is);
3063 set_sub_is_and_ao(sub_data, sub_is, sub_ao);
3064 apply_symmetry(sub_data);
3066 prb_ptr->
getSubData() = boost::make_shared<Problem::SubProblemData>();
3068 &*indices.begin(), PETSC_COPY_VALUES);
3071 set_sub_is_and_ao(prb_ptr->
getSubData(), sub_is, sub_ao);
3079 CHKERR set_sub_data(global_indices);
3084 for (
auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3086 auto idx = (*dit)->getDofIdx();
3089 (*dit)->getPart(),
i++, global_indices[idx], local_indices[idx]);
3090 bool success = numered_dofs[s]->modify(dit, mod);
3093 "can not set negative indices");
3096 (*dit)->getPart(), -1, -1, -1);
3097 bool success = numered_dofs[s]->modify(dit, mod);
3100 "can not set negative indices");
3105 for (
auto dof : (*numered_dofs[s])) {
3106 if (dof->getDofIdx() >= 0 && dof->getPetscGlobalDofIdx() < 0) {
3108 "Negative global idx");
3115 *(nbdof_ptr[1]) = *(nbdof_ptr[0]);
3116 *(local_nbdof_ptr[1]) = *(local_nbdof_ptr[0]);
3117 *(ghost_nbdof_ptr[1]) = *(ghost_nbdof_ptr[0]);
3125 "WORLD", Sev::inform,
3126 "Removed DOFs from problem %s dofs [%d / %d (before %d / %d) global]",
3128 prb_ptr->
getNbDofsCol(), nb_init_row_dofs, nb_init_col_dofs);
3130 "Removed DOFs from problem %s dofs [ %d / %d "
3131 "(before %d / %d) local, %d / %d (before %d / %d)]",
3136 nb_init_ghost_col_dofs);
3143 const std::string problem_name,
const std::string
field_name,
3145 Range *ents_ptr,
const int lo_coeff,
const int hi_coeff,
const int lo_order,
3146 const int hi_order,
int verb,
const bool debug) {
3155 CHKERR bit_manager->filterEntitiesByRefLevel(bit_ref_level, bit_ref_mask,
3158 CHKERR bit_manager->getEntitiesByRefLevel(bit_ref_level, bit_ref_mask, ents,
3163 hi_coeff, lo_order, hi_order, verb,
debug);
3169 const std::string problem_name,
const std::string
field_name,
3171 Range *ents_ptr,
const int lo_coeff,
const int hi_coeff,
const int lo_order,
3172 const int hi_order,
int verb,
const bool debug) {
3181 CHKERR bit_manager->filterEntitiesByRefLevel(bit_ref_level, bit_ref_mask,
3184 CHKERR bit_manager->getEntitiesByRefLevel(bit_ref_level, bit_ref_mask, ents,
3189 lo_coeff, hi_coeff, lo_order,
3190 hi_order, verb,
debug);
3198 std::vector<unsigned char> &
marker)
const {
3204 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs;
3214 marker.resize(dofs->size(), 0);
3215 std::vector<unsigned char> marker_tmp;
3219 for (
auto p = ents.pair_begin();
p != ents.pair_end(); ++
p) {
3220 auto lo = dofs->get<
Ent_mi_tag>().lower_bound(
p->first);
3221 auto hi = dofs->get<
Ent_mi_tag>().upper_bound(
p->second);
3222 for (; lo != hi; ++lo)
3223 marker[(*lo)->getPetscLocalDofIdx()] |= 1;
3227 marker_tmp.resize(dofs->size(), 0);
3228 for (
auto p = ents.pair_begin();
p != ents.pair_end(); ++
p) {
3229 auto lo = dofs->get<
Ent_mi_tag>().lower_bound(
p->first);
3230 auto hi = dofs->get<
Ent_mi_tag>().upper_bound(
p->second);
3231 for (; lo != hi; ++lo)
3232 marker_tmp[(*lo)->getPetscLocalDofIdx()] = 1;
3234 for (
int i = 0;
i !=
marker.size(); ++
i) {
3246 const unsigned char c, std::vector<unsigned char> &
marker)
const {
3252 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs;
3262 marker.resize(dofs->size(), 0);
3269 auto marker_ref = [
marker](
auto &it) ->
unsigned int & {
3270 return marker[(*it)->getPetscLocalDofIdx()];
3275 for (; dof_lo != dof_hi; ++dof_lo)
3276 if ((*dof_lo)->getDofCoeffIdx() >= lo &&
3277 (*dof_lo)->getDofCoeffIdx() <= hi)
3278 marker[(*dof_lo)->getPetscLocalDofIdx()] |=
c;
3281 for (; dof_lo != dof_hi; ++dof_lo)
3282 if ((*dof_lo)->getDofCoeffIdx() >= lo &&
3283 (*dof_lo)->getDofCoeffIdx() <= hi)
3284 marker[(*dof_lo)->getPetscLocalDofIdx()] &=
c;
3293 const std::string row_field,
3294 const std::string col_field)
const {
3299 const auto problem_ptr = m_field.
get_problem(problem_name);
3300 auto get_field_id = [&](
const std::string
field_name) {
3303 const auto row_id = get_field_id(row_field);
3304 const auto col_id = get_field_id(col_field);
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
#define MOFEM_LOG_C(channel, severity, format,...)
#define ProblemManagerFunctionBegin
#define MAX_DOFS_ON_ENTITY
Maximal number of DOFs on entity.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define CHKERRG(n)
Check error code of MoFEM/MOAB/PETSc function.
@ MOFEM_OPERATION_UNSUCCESSFUL
@ MOFEM_ATOM_TEST_INVALID
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
FTensor::Index< 'n', SPACE_DIM > n
FTensor::Index< 'm', SPACE_DIM > m
multi_index_container< boost::shared_ptr< FieldEntity >, indexed_by< ordered_unique< tag< Unique_mi_tag >, const_mem_fun< FieldEntity, UId, &FieldEntity::getGlobalUniqueId > > > > FieldEntity_multiIndex_global_uid_view
multi-index view on DofEntity by uid
multi_index_container< boost::shared_ptr< DofEntity >, indexed_by< ordered_unique< const_mem_fun< DofEntity, UId, &DofEntity::getLocalUniqueId > >, ordered_non_unique< const_mem_fun< DofEntity, char, &DofEntity::getActive > > > > DofEntity_multiIndex_active_view
multi-index view on DofEntity activity
NumeredDofEntity_multiIndex::index< Unique_mi_tag >::type NumeredDofEntityByUId
Numbered DoF multi-index by UId.
multi_index_container< boost::shared_ptr< NumeredDofEntity >, indexed_by< ordered_unique< tag< Unique_mi_tag >, const_mem_fun< NumeredDofEntity::interface_type_DofEntity, UId, &NumeredDofEntity::getLocalUniqueId > >, ordered_non_unique< tag< Part_mi_tag >, member< NumeredDofEntity, unsigned int, &NumeredDofEntity::pArt > >, ordered_non_unique< tag< Idx_mi_tag >, member< NumeredDofEntity, DofIdx, &NumeredDofEntity::dofIdx > >, ordered_non_unique< tag< PetscGlobalIdx_mi_tag >, member< NumeredDofEntity, DofIdx, &NumeredDofEntity::petscGloablDofIdx > >, ordered_non_unique< tag< PetscLocalIdx_mi_tag >, member< NumeredDofEntity, DofIdx, &NumeredDofEntity::petscLocalDofIdx > >, ordered_non_unique< tag< Ent_mi_tag >, const_mem_fun< NumeredDofEntity::interface_type_DofEntity, EntityHandle, &NumeredDofEntity::getEnt > > > > NumeredDofEntity_multiIndex
MultiIndex container keeps NumeredDofEntity.
multi_index_container< boost::shared_ptr< DofEntity >, indexed_by< ordered_unique< const_mem_fun< DofEntity, UId, &DofEntity::getGlobalUniqueId > > > > DofEntity_multiIndex_global_uid_view
multi-index view on DofEntity by uid
multi_index_container< boost::shared_ptr< NumeredEntFiniteElement >, indexed_by< ordered_unique< tag< Unique_mi_tag >, const_mem_fun< NumeredEntFiniteElement::interface_type_EntFiniteElement, UId, &NumeredEntFiniteElement::getLocalUniqueId > >, ordered_non_unique< tag< Part_mi_tag >, member< NumeredEntFiniteElement, unsigned int, &NumeredEntFiniteElement::part > >, ordered_non_unique< tag< Ent_mi_tag >, const_mem_fun< NumeredEntFiniteElement::interface_type_RefEntity, EntityHandle, &NumeredEntFiniteElement::getEnt > >, ordered_non_unique< tag< Composite_Name_And_Part_mi_tag >, composite_key< NumeredEntFiniteElement, const_mem_fun< NumeredEntFiniteElement::interface_type_FiniteElement, boost::string_ref, &NumeredEntFiniteElement::getNameRef >, member< NumeredEntFiniteElement, unsigned int, &NumeredEntFiniteElement::part > > > > > NumeredEntFiniteElement_multiIndex
MultiIndex for entities for NumeredEntFiniteElement.
multi_index_container< boost::shared_ptr< FiniteElement >, indexed_by< hashed_unique< tag< FiniteElement_Meshset_mi_tag >, member< FiniteElement, EntityHandle, &FiniteElement::meshset > >, hashed_unique< tag< BitFEId_mi_tag >, const_mem_fun< FiniteElement, BitFEId, &FiniteElement::getId >, HashBit< BitFEId >, EqBit< BitFEId > >, ordered_unique< tag< FiniteElement_name_mi_tag >, const_mem_fun< FiniteElement, boost::string_ref, &FiniteElement::getNameRef > > > > FiniteElement_multiIndex
MultiIndex for entities for FiniteElement.
virtual const Problem * get_problem(const std::string problem_name) const =0
Get the problem object.
virtual const FieldEntity_multiIndex * get_field_ents() const =0
Get the field ents object.
virtual MoFEMErrorCode get_ents_elements_adjacency(const FieldEntityEntFiniteElementAdjacencyMap_multiIndex **dofs_elements_adjacency) const =0
Get the dofs elements adjacency object.
virtual const FiniteElement_multiIndex * get_finite_elements() const =0
Get the finite elements object.
virtual const DofEntity_multiIndex * get_dofs() const =0
Get the dofs object.
virtual const Problem_multiIndex * get_problems() const =0
Get the problems object.
virtual const EntFiniteElement_multiIndex * get_ents_finite_elements() const =0
Get the ents finite elements object.
virtual const Field_multiIndex * get_fields() const =0
Get the fields object.
virtual const Field * get_field_structure(const std::string &name, enum MoFEMTypes bh=MF_EXIST) const =0
get field structure
#define MOFEM_LOG(channel, severity)
Log.
MoFEMErrorCode buildProblemOnDistributedMesh(const std::string name, const bool square_matrix, int verb=VERBOSE)
build problem data structures, assuming that mesh is distributed (collective)
MoFEMErrorCode partitionGhostDofs(const std::string name, int verb=VERBOSE)
determine ghost nodes
MoFEMErrorCode partitionSimpleProblem(const std::string name, int verb=VERBOSE)
partition problem dofs
MoFEMErrorCode buildComposedProblem(const std::string out_name, const std::vector< std::string > add_row_problems, const std::vector< std::string > add_col_problems, const bool square_matrix=true, int verb=1)
build composite problem
MoFEMErrorCode buildProblem(const std::string name, const bool square_matrix, int verb=VERBOSE)
build problem data structures
DEPRECATED MoFEMErrorCode partitionMesh(const Range &ents, const int dim, const int adj_dim, const int n_parts, Tag *th_vertex_weights=nullptr, Tag *th_edge_weights=nullptr, Tag *th_part_weights=nullptr, int verb=VERBOSE, const bool debug=false)
Set partition tag to each finite element in the problem.
MoFEMErrorCode buildSubProblem(const std::string out_name, const std::vector< std::string > &fields_row, const std::vector< std::string > &fields_col, const std::string main_problem, const bool square_matrix=true, const map< std::string, boost::shared_ptr< Range > > *entityMapRow=nullptr, const map< std::string, boost::shared_ptr< Range > > *entityMapCol=nullptr, int verb=VERBOSE)
build sub problem
MoFEMErrorCode partitionProblem(const std::string name, int verb=VERBOSE)
partition problem dofs (collective)
MoFEMErrorCode partitionGhostDofsOnDistributedMesh(const std::string name, int verb=VERBOSE)
determine ghost nodes on distributed meshes
MoFEMErrorCode getProblemElementsLayout(const std::string name, const std::string &fe_name, PetscLayout *layout) const
Get layout of elements in the problem.
MoFEMErrorCode getFEMeshset(const std::string prb_name, const std::string &fe_name, EntityHandle *meshset) const
create add entities of finite element in the problem
MoFEMErrorCode inheritPartition(const std::string name, const std::string problem_for_rows, bool copy_rows, const std::string problem_for_cols, bool copy_cols, int verb=VERBOSE)
build indexing and partition problem inheriting indexing and partitioning from two other problems
MoFEMErrorCode partitionFiniteElements(const std::string name, bool part_from_moab=false, int low_proc=-1, int hi_proc=-1, int verb=VERBOSE)
partition finite elements
MoFEMErrorCode removeDofsOnEntities(const std::string problem_name, const std::string field_name, const Range ents, const int lo_coeff=0, const int hi_coeff=MAX_DOFS_ON_ENTITY, const int lo_order=0, const int hi_order=100, int verb=VERBOSE, const bool debug=false)
Remove DOFs from problem.
virtual MoFEMErrorCode clear_problem(const std::string name, int verb=DEFAULT_VERBOSITY)=0
clear problem
auto marker
set bit to marker
FTensor::Index< 'i', SPACE_DIM > i
const double c
speed of light (cm/ns)
const double v
phase velocity of light in medium (cm/ns)
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
std::bitset< BITFIELDID_SIZE > BitFieldId
Field Id.
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
implementation of Data Operators for Forces and Sources
auto type_from_handle(const EntityHandle h)
get type from entity handle
Problem::EmptyFieldBlocks EmptyFieldBlocks
auto createISGeneral(MPI_Comm comm, PetscInt n, const PetscInt idx[], PetscCopyMode mode)
Creates a data structure for an index set containing a list of integers.
auto createAOMapping(MPI_Comm comm, PetscInt napp, const PetscInt myapp[], const PetscInt mypetsc[])
Creates an application mapping using two integer arrays.
auto createAOMappingIS(IS isapp, IS ispetsc)
Creates an application mapping using two index sets.
auto field_bit_from_bit_number(const int bit_number)
get field bit id from bit number
auto get_temp_meshset_ptr(moab::Interface &moab)
Create smart pointer to temporary meshset.
multi_index_container< boost::shared_ptr< NumeredDofEntity >, indexed_by< ordered_unique< const_mem_fun< NumeredDofEntity::interface_type_DofEntity, UId, &NumeredDofEntity::getLocalUniqueId > > > > NumeredDofEntity_multiIndex_uid_view_ordered
constexpr auto field_name
virtual int get_comm_size() const =0
virtual FieldBitNumber get_field_bit_number(const std::string name) const =0
get field bit number
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =0
virtual std::string get_field_name(const BitFieldId id) const =0
get field name from id
virtual int get_comm_rank() const =0
int & getBuildMoFEM() const
Get flags/semaphores for different stages.
Deprecated interface functions.
static UId getLoFieldEntityUId(const FieldBitNumber bit, const EntityHandle ent)
static UId getHiFieldEntityUId(const FieldBitNumber bit, const EntityHandle ent)
UId getLocalUniqueIdCalculate() const
Generate UId for finite element entity.
static MoFEMErrorCode getDofView(const FE_ENTS &fe_ents_view, const MOFEM_DOFS &mofem_dofs, MOFEM_DOFS_VIEW &dofs_view, INSERTER &&inserter)
static UId getHiBitNumberUId(const FieldBitNumber bit_number)
static auto getHandleFromUniqueId(const UId uid)
Get the Handle From Unique Id.
static auto getFieldBitNumberFromUniqueId(const UId uid)
Get the Field Bit Number From Unique Id.
UId getLocalUniqueIdCalculate()
Get the Local Unique Id Calculate object.
static UId getLoBitNumberUId(const FieldBitNumber bit_number)
static auto getOwnerFromUniqueId(const UId uid)
UId getGlobalUniqueIdCalculate() const
Calculate global UId.
const BitFieldId & getId() const
Get unique field id.
IdxDataType(const UId uid, const int dof)
IdxDataTypePtr(const int *ptr)
Matrix manager is used to build and partition problems.
keeps information about indexed dofs for the problem
Partitioned (Indexed) Finite Element in Problem.
keeps basic data about problem
DofIdx getNbLocalDofsRow() const
MoFEMErrorCode getNumberOfElementsByNameAndPart(MPI_Comm comm, const std::string name, PetscLayout *layout) const
Get number of finite elements by name on processors.
DofIdx getNbDofsRow() const
BitRefLevel getBitRefLevel() const
auto & getColDofsSequence() const
Get reference to sequence data numbered dof container.
BitRefLevel getBitRefLevelMask() const
boost::shared_ptr< SubProblemData > & getSubData() const
Get main problem of sub-problem is.
DofIdx nbGhostDofsCol
Number of ghost DOFs in col.
boost::shared_ptr< NumeredDofEntity_multiIndex > numeredRowDofsPtr
store DOFs on rows for this problem
boost::shared_ptr< NumeredEntFiniteElement_multiIndex > numeredFiniteElementsPtr
store finite elements
DofIdx getNbGhostDofsCol() const
DofIdx nbLocDofsRow
Local number of DOFs in row.
BitFEId getBitFEId() const
DofIdx nbDofsCol
Global number of DOFs in col.
DofIdx getNbDofsCol() const
DofIdx getNbLocalDofsCol() const
DofIdx nbGhostDofsRow
Number of ghost DOFs in row.
auto & getNumeredColDofsPtr() const
get access to numeredColDofsPtr storing DOFs on cols
DofIdx nbLocDofsCol
Local number of DOFs in colIs.
DofIdx nbDofsRow
Global number of DOFs in row.
DofIdx getNbGhostDofsRow() const
boost::shared_ptr< NumeredDofEntity_multiIndex > numeredColDofsPtr
store DOFs on columns for this problem
auto & getNumeredRowDofsPtr() const
get access to numeredRowDofsPtr storing DOFs on rows
auto & getRowDofsSequence() const
Get reference to sequence data numbered dof container.
Problem manager is used to build and partition problems.
MoFEMErrorCode markDofs(const std::string problem_name, RowColData rc, const enum MarkOP op, const Range ents, std::vector< unsigned char > &marker) const
Create vector with marked indices.
ProblemsManager(const MoFEM::Core &core)
MoFEMErrorCode printPartitionedProblem(const Problem *problem_ptr, int verb=VERBOSE)
MoFEMErrorCode addFieldToEmptyFieldBlocks(const std::string problem_name, const std::string row_field, const std::string col_field) const
add empty block to problem
MoFEMErrorCode modifyMarkDofs(const std::string problem_name, RowColData rc, const std::string field_name, const int lo, const int hi, const enum MarkOP op, const unsigned char c, std::vector< unsigned char > &marker) const
Mark DOFs.
PetscLogEvent MOFEM_EVENT_ProblemsManager
PetscBool buildProblemFromFields
PetscBool synchroniseProblemEntities
DOFs in fields, not from DOFs on elements.
MoFEMErrorCode debugPartitionedProblem(const Problem *problem_ptr, int verb=VERBOSE)
MoFEMErrorCode query_interface(boost::typeindex::type_index type_index, UnknownInterface **iface) const
MoFEMErrorCode removeDofsOnEntitiesNotDistributed(const std::string problem_name, const std::string field_name, const Range ents, const int lo_coeff=0, const int hi_coeff=MAX_DOFS_ON_ENTITY, const int lo_order=0, const int hi_order=100, int verb=VERBOSE, const bool debug=false)
Remove DOFs from problem.
MoFEMErrorCode getOptions()
intrusive_ptr for managing petsc objects
base class for all interface classes
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface refernce to pointer of interface.