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) {
320 auto dofs_field_ptr = m_field.
get_dofs();
331 "problem <%s> refinement level not set",
332 problem_ptr->
getName().c_str());
340 boost::shared_ptr<NumeredDofEntity_multiIndex>(
354 auto make_rows_and_cols_view = [&](
auto &dofs_rows,
auto &dofs_cols) {
358 for (
auto it = ents_field_ptr->begin(); it != ents_field_ptr->end();
361 const auto uid = (*it)->getLocalUniqueId();
363 auto r = adjacencies_ptr->get<
Unique_mi_tag>().equal_range(uid);
364 for (
auto lo = r.first; lo != r.second; ++lo) {
366 if ((lo->getBitFEId() & problem_ptr->
getBitFEId()).any()) {
367 std::array<bool, 2> row_col = {
false,
false};
369 const BitRefLevel &fe_bit = lo->entFePtr->getBitRefLevel();
372 if ((fe_bit & prb_bit).any() && (fe_bit & prb_mask) == fe_bit) {
374 auto add_to_view = [&](
auto dofs,
auto &view,
auto rc) {
375 auto dit = dofs->lower_bound(uid);
376 decltype(dit) hi_dit;
377 if (dit != dofs->end()) {
378 hi_dit = dofs->upper_bound(
380 view.insert(dit, hi_dit);
385 if ((lo->entFePtr->getBitFieldIdRow() & (*it)->getId()).any())
386 add_to_view(dofs_field_ptr, dofs_rows,
ROW);
389 if ((lo->entFePtr->getBitFieldIdCol() & (*it)->getId()).any())
390 add_to_view(dofs_field_ptr, dofs_cols,
COL);
392 if (square_matrix && row_col[
ROW])
394 else if (row_col[
ROW] && row_col[
COL])
403 CHKERR make_rows_and_cols_view(dofs_rows, dofs_cols);
411 for (
auto fit = fe_ptr->begin(); fit != fe_ptr->end(); fit++) {
412 if ((fit->get()->getId() & problem_ptr->
getBitFEId()).any()) {
413 fields_ids_row |= fit->get()->getBitFieldIdRow();
414 fields_ids_col |= fit->get()->getBitFieldIdCol();
418 for (
auto fit = fields_ptr->begin(); fit != fields_ptr->end(); fit++) {
419 if ((fit->get()->getId() & (fields_ids_row | fields_ids_col)).any()) {
423 auto hi_dit = dofs_field_ptr->get<
Unique_mi_tag>().upper_bound(
426 for (; dit != hi_dit; dit++) {
428 const int owner_proc = dit->get()->getOwnerProc();
430 const unsigned char pstatus = dit->get()->getPStatus();
436 const auto &dof_bit = (*dit)->getBitRefLevel();
438 if ((dof_bit & prb_bit).any() && (dof_bit & prb_mask) == dof_bit) {
440 if ((fit->get()->getId() & fields_ids_row).any()) {
441 dofs_rows.insert(*dit);
443 if (!square_matrix) {
444 if ((fit->get()->getId() & fields_ids_col).any()) {
445 dofs_cols.insert(*dit);
458 BitFieldId *fields_ids[2] = {&fields_ids_row, &fields_ids_col};
459 for (FiniteElement_multiIndex::iterator fit = fe_ptr->begin();
460 fit != fe_ptr->end(); fit++) {
461 if ((fit->get()->getId() & problem_ptr->
getBitFEId()).any()) {
462 fields_ids_row |= fit->get()->getBitFieldIdRow();
463 fields_ids_col |= fit->get()->getBitFieldIdCol();
468 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ++ss) {
469 DofEntity_multiIndex_active_view::nth_index<1>::type::iterator miit,
471 miit = dofs_ptr[ss]->get<1>().lower_bound(1);
472 hi_miit = dofs_ptr[ss]->get<1>().upper_bound(1);
473 Range ents_to_synchronise;
474 for (; miit != hi_miit; ++miit) {
475 if (miit->get()->getEntDofIdx() != 0)
477 ents_to_synchronise.insert(miit->get()->getEnt());
479 Range tmp_ents = ents_to_synchronise;
481 ents_to_synchronise, verb);
482 ents_to_synchronise = subtract(ents_to_synchronise, tmp_ents);
483 for (
auto fit = fields_ptr->begin(); fit != fields_ptr->end(); fit++) {
484 if ((fit->get()->getId() & *fields_ids[ss]).any()) {
485 const auto bit_number = (*fit)->getBitNumber();
486 for (Range::pair_iterator pit = ents_to_synchronise.pair_begin();
487 pit != ents_to_synchronise.pair_end(); ++pit) {
488 const auto f = pit->first;
489 const auto s = pit->second;
495 auto dit = dofs_field_ptr->get<
Unique_mi_tag>().lower_bound(lo_uid);
499 dofs_ptr[ss]->insert(dit, hi_dit);
508 boost::shared_ptr<NumeredDofEntity_multiIndex> numered_dofs_ptr[] = {
515 for (
int ss = 0; ss < 2; ss++) {
516 *(nbdof_ptr[ss]) = 0;
517 *(local_nbdof_ptr[ss]) = 0;
518 *(ghost_nbdof_ptr[ss]) = 0;
523 int nb_local_dofs[] = {0, 0};
524 for (
int ss = 0; ss < loop_size; ss++) {
525 DofEntity_multiIndex_active_view::nth_index<1>::type::iterator miit,
527 miit = dofs_ptr[ss]->get<1>().lower_bound(1);
528 hi_miit = dofs_ptr[ss]->get<1>().upper_bound(1);
529 for (; miit != hi_miit; miit++) {
530 int owner_proc = (*miit)->getOwnerProc();
538 int start_ranges[2], end_ranges[2];
539 for (
int ss = 0; ss != loop_size; ss++) {
542 CHKERR PetscLayoutSetBlockSize(layout, 1);
543 CHKERR PetscLayoutSetLocalSize(layout, nb_local_dofs[ss]);
544 CHKERR PetscLayoutSetUp(layout);
545 CHKERR PetscLayoutGetSize(layout, &*nbdof_ptr[ss]);
546 CHKERR PetscLayoutGetRange(layout, &start_ranges[ss], &end_ranges[ss]);
547 CHKERR PetscLayoutDestroy(&layout);
550 nbdof_ptr[1] = nbdof_ptr[0];
551 nb_local_dofs[1] = nb_local_dofs[0];
552 start_ranges[1] = start_ranges[0];
553 end_ranges[1] = end_ranges[0];
565 const size_t idx_data_type_size =
sizeof(
IdxDataType);
566 const size_t data_block_size = idx_data_type_size /
sizeof(int);
571 std::vector<std::vector<IdxDataType>> ids_data_packed_rows(
577 for (
int ss = 0; ss != loop_size; ++ss) {
579 DofEntity_multiIndex_active_view::nth_index<0>::type::iterator miit,
581 hi_miit = dofs_ptr[ss]->get<0>().end();
583 boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array =
584 boost::shared_ptr<std::vector<NumeredDofEntity>>(
585 new std::vector<NumeredDofEntity>());
586 int nb_dofs_to_add = 0;
587 miit = dofs_ptr[ss]->get<0>().begin();
588 for (; miit != hi_miit; ++miit) {
590 if (!(miit->get()->getActive()))
594 dofs_array->reserve(nb_dofs_to_add);
601 int &local_idx = *local_nbdof_ptr[ss];
602 miit = dofs_ptr[ss]->get<0>().begin();
603 for (; miit != hi_miit; ++miit) {
606 if (!(miit->get()->getActive()))
609 dofs_array->emplace_back(*miit);
611 int owner_proc = dofs_array->back().getOwnerProc();
612 if (owner_proc < 0) {
614 "data inconsistency");
618 dofs_array->back().pArt = owner_proc;
619 dofs_array->back().dofIdx = -1;
620 dofs_array->back().petscGloablDofIdx = -1;
621 dofs_array->back().petscLocalDofIdx = -1;
625 int glob_idx = start_ranges[ss] + local_idx;
626 dofs_array->back().pArt = owner_proc;
627 dofs_array->back().dofIdx = glob_idx;
628 dofs_array->back().petscGloablDofIdx = glob_idx;
629 dofs_array->back().petscLocalDofIdx = local_idx;
632 unsigned char pstatus = dofs_array->back().getPStatus();
638 proc < MAX_SHARING_PROCS &&
639 -1 != dofs_array->back().getSharingProcsPtr()[proc];
643 ids_data_packed_rows[dofs_array->back()
644 .getSharingProcsPtr()[proc]]
645 .emplace_back(dofs_array->back().getGlobalUniqueId(),
648 ids_data_packed_cols[dofs_array->back()
649 .getSharingProcsPtr()[proc]]
650 .emplace_back(dofs_array->back().getGlobalUniqueId(),
653 if (!(pstatus & PSTATUS_MULTISHARED)) {
661 auto hint = numered_dofs_ptr[ss]->end();
662 for (
auto &
v : *dofs_array)
663 hint = numered_dofs_ptr[ss]->emplace_hint(hint, dofs_array, &
v);
666 local_nbdof_ptr[1] = local_nbdof_ptr[0];
669 int nsends_rows = 0, nsends_cols = 0;
673 lengths_rows.clear();
674 lengths_cols.clear();
676 lengths_rows[proc] = ids_data_packed_rows[proc].size() * data_block_size;
677 lengths_cols[proc] = ids_data_packed_cols[proc].size() * data_block_size;
678 if (!ids_data_packed_rows[proc].empty())
680 if (!ids_data_packed_cols[proc].empty())
702 CHKERR PetscGatherNumberOfMessages(comm, NULL, &lengths_rows[0],
708 CHKERR PetscGatherMessageLengths(comm, nsends_rows, nrecvs_rows,
709 &lengths_rows[0], &onodes_rows,
717 CHKERR PetscCommGetNewTag(comm, &tag_row);
721 MPI_Request *r_waits_row;
726 CHKERR PetscPostIrecvInt(comm, tag_row, nrecvs_rows, onodes_rows,
727 olengths_rows, &rbuf_row, &r_waits_row);
728 CHKERR PetscFree(onodes_rows);
730 MPI_Request *s_waits_row;
731 CHKERR PetscMalloc1(nsends_rows, &s_waits_row);
734 for (
int proc = 0, kk = 0; proc < m_field.
get_comm_size(); proc++) {
735 if (!lengths_rows[proc])
737 CHKERR MPI_Isend(&(ids_data_packed_rows[proc])[0],
740 tag_row, comm, s_waits_row + kk);
745 CHKERR MPI_Waitall(nrecvs_rows, r_waits_row, status);
748 CHKERR MPI_Waitall(nsends_rows, s_waits_row, status);
751 CHKERR PetscFree(r_waits_row);
752 CHKERR PetscFree(s_waits_row);
756 int nrecvs_cols = nrecvs_rows;
757 int *olengths_cols = olengths_rows;
758 PetscInt **rbuf_col = rbuf_row;
759 if (!square_matrix) {
762 CHKERR PetscGatherNumberOfMessages(comm, NULL, &lengths_cols[0],
768 CHKERR PetscGatherMessageLengths(comm, nsends_cols, nrecvs_cols,
769 &lengths_cols[0], &onodes_cols,
774 CHKERR PetscCommGetNewTag(comm, &tag_col);
778 MPI_Request *r_waits_col;
779 CHKERR PetscPostIrecvInt(comm, tag_col, nrecvs_cols, onodes_cols,
780 olengths_cols, &rbuf_col, &r_waits_col);
781 CHKERR PetscFree(onodes_cols);
783 MPI_Request *s_waits_col;
784 CHKERR PetscMalloc1(nsends_cols, &s_waits_col);
787 for (
int proc = 0, kk = 0; proc < m_field.
get_comm_size(); proc++) {
788 if (!lengths_cols[proc])
790 CHKERR MPI_Isend(&(ids_data_packed_cols[proc])[0],
793 tag_col, comm, s_waits_col + kk);
798 CHKERR MPI_Waitall(nrecvs_cols, r_waits_col, status);
801 CHKERR MPI_Waitall(nsends_cols, s_waits_col, status);
804 CHKERR PetscFree(r_waits_col);
805 CHKERR PetscFree(s_waits_col);
808 CHKERR PetscCommDestroy(&comm);
812 auto hint = dofs_glob_uid_view.begin();
813 for (
auto dof : *m_field.
get_dofs())
814 dofs_glob_uid_view.emplace_hint(hint, dof);
817 for (
int ss = 0; ss != loop_size; ++ss) {
823 nrecvs = nrecvs_rows;
824 olengths = olengths_rows;
825 data_procs = rbuf_row;
827 nrecvs = nrecvs_cols;
828 olengths = olengths_cols;
829 data_procs = rbuf_col;
833 for (
int kk = 0; kk != nrecvs; ++kk) {
834 int len = olengths[kk];
835 int *data_from_proc = data_procs[kk];
836 for (
int dd = 0; dd < len; dd += data_block_size) {
838 auto ddit = dofs_glob_uid_view.find(uid);
840 if (PetscUnlikely(ddit == dofs_glob_uid_view.end())) {
844 <<
"DOF is shared or multishared between processors. For example "
845 "if order of field on given entity is set in inconsistently, "
846 "has different value on two processor, error such as this is "
849 MOFEM_LOG(
"SELF", Sev::error) <<
"UId " << uid <<
" is not found";
852 <<
"Problematic UId owner proc is " << owner_proc;
855 <<
"Problematic UId entity owning processor handle is "
856 << uid_handle <<
" entity type "
858 const auto uid_bit_number =
861 <<
"Problematic UId field is "
866 field_view.insert(ents_field_ptr->begin(), ents_field_ptr->end());
868 owner_proc, uid_bit_number, uid_handle));
869 if (fe_it == field_view.end()) {
871 <<
"Also, no field entity in database for given global UId";
873 MOFEM_LOG(
"SELF", Sev::error) <<
"Field entity in databse exist "
874 "(but have no DOF wih give UId";
875 MOFEM_LOG(
"SELF", Sev::error) << **fe_it;
878 auto error_file_name =
879 "error_with_missing_entity_" +
883 <<
"Look to file < " << error_file_name
884 <<
" > it contains entity with missing DOF.";
887 const auto local_fe_ent = (*fe_it)->getEnt();
888 CHKERR m_field.
get_moab().add_entities(*tmp_msh, &local_fe_ent, 1);
889 CHKERR m_field.
get_moab().write_file(error_file_name.c_str(),
"VTK",
890 "", tmp_msh->get_ptr(), 1);
895 "DOF with global UId not found (Compile code in Debug to "
896 "learn more about problem");
899 auto dit = numered_dofs_ptr[ss]->find((*ddit)->getLocalUniqueId());
901 if (dit != numered_dofs_ptr[ss]->end()) {
905 if (PetscUnlikely(global_idx < 0))
907 "received negative dof");
910 success = numered_dofs_ptr[ss]->modify(
914 if (PetscUnlikely(!success))
916 "modification unsuccessful");
918 success = numered_dofs_ptr[ss]->modify(
922 if (PetscUnlikely(!success))
924 "modification unsuccessful");
929 if (PetscUnlikely(ddit->get()->getPStatus() == 0)) {
936 std::ostringstream zz;
937 zz << **ddit << std::endl;
939 "data inconsistency, dofs is not shared, but received "
954 CHKERR PetscFree(olengths_rows);
955 CHKERR PetscFree(rbuf_row[0]);
956 CHKERR PetscFree(rbuf_row);
957 if (!square_matrix) {
958 CHKERR PetscFree(olengths_cols);
959 CHKERR PetscFree(rbuf_col[0]);
960 CHKERR PetscFree(rbuf_col);
964 if (numered_dofs_ptr[0]->size() != numered_dofs_ptr[1]->size()) {
966 "data inconsistency for square_matrix %d!=%d",
967 numered_dofs_ptr[0]->size(), numered_dofs_ptr[1]->size());
971 "data inconsistency for square_matrix");
984 const std::string out_name,
986 const std::vector<std::string> &fields_row,
987 const std::vector<std::string> &fields_col,
989 const std::string main_problem,
const bool square_matrix,
991 const map<std::string, boost::shared_ptr<Range>> *entityMapRow,
992 const map<std::string, boost::shared_ptr<Range>> *entityMapCol,
1002 using ProblemByName =
decltype(problems_ptr->get<
Problem_mi_tag>());
1003 auto &problems_by_name =
1004 const_cast<ProblemByName &
>(problems_ptr->get<
Problem_mi_tag>());
1007 auto out_problem_it = problems_by_name.find(out_name);
1008 if (out_problem_it == problems_by_name.end()) {
1010 "subproblem with name < %s > not defined (top tip check spelling)",
1015 auto main_problem_it = problems_by_name.find(main_problem);
1016 if (main_problem_it == problems_by_name.end()) {
1018 "problem of subproblem with name < %s > not defined (top tip "
1020 main_problem.c_str());
1024 boost::shared_ptr<NumeredDofEntity_multiIndex> out_problem_dofs[] = {
1025 out_problem_it->numeredRowDofsPtr, out_problem_it->numeredColDofsPtr};
1027 boost::shared_ptr<NumeredDofEntity_multiIndex> main_problem_dofs[] = {
1028 main_problem_it->numeredRowDofsPtr, main_problem_it->numeredColDofsPtr};
1030 int *nb_local_dofs[] = {&out_problem_it->nbLocDofsRow,
1031 &out_problem_it->nbLocDofsCol};
1033 int *nb_dofs[] = {&out_problem_it->nbDofsRow, &out_problem_it->nbDofsCol};
1037 out_problem_it->nbGhostDofsRow = 0;
1038 out_problem_it->nbGhostDofsCol = 0;
1042 std::vector<std::string> fields[] = {fields_row, fields_col};
1043 const map<std::string, boost::shared_ptr<Range>> *entityMap[] = {
1044 entityMapRow, entityMapCol};
1047 out_problem_it->subProblemData =
1048 boost::make_shared<Problem::SubProblemData>();
1051 for (
int ss = 0; ss != (square_matrix ? 1 : 2); ++ss) {
1054 (*nb_local_dofs[ss]) = 0;
1057 out_problem_dofs[ss]->clear();
1060 out_problem_it->numeredFiniteElementsPtr->clear();
1063 for (
auto field : fields[ss]) {
1069 boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array =
1070 boost::make_shared<std::vector<NumeredDofEntity>>();
1073 out_problem_it->getRowDofsSequence()->emplace_back(dofs_array);
1075 out_problem_it->getColDofsSequence()->emplace_back(dofs_array);
1080 auto add_dit_to_dofs_array = [&](
auto &dit) {
1081 if (dit->get()->getPetscGlobalDofIdx() >= 0)
1082 dofs_array->emplace_back(
1083 dit->get()->getDofEntityPtr(), dit->get()->getPetscGlobalDofIdx(),
1084 dit->get()->getPetscGlobalDofIdx(),
1085 dit->get()->getPetscLocalDofIdx(), dit->get()->getPart());
1088 auto get_dafult_dof_range = [&]() {
1089 auto dit = main_problem_dofs[ss]->get<
Unique_mi_tag>().lower_bound(
1091 auto hi_dit = main_problem_dofs[ss]->get<
Unique_mi_tag>().upper_bound(
1093 return std::make_pair(dit, hi_dit);
1096 if (entityMap[ss]) {
1097 auto mit = entityMap[ss]->find(field);
1099 if (mit != entityMap[ss]->end()) {
1100 for (
auto p = mit->second->pair_begin();
p != mit->second->pair_end();
1102 const auto lo_ent =
p->first;
1103 const auto hi_ent =
p->second;
1104 auto dit = main_problem_dofs[ss]->get<
Unique_mi_tag>().lower_bound(
1109 dofs_array->reserve(std::distance(dit, hi_dit));
1110 for (; dit != hi_dit; dit++) {
1111 add_dit_to_dofs_array(dit);
1115 auto [dit, hi_dit] = get_dafult_dof_range();
1116 dofs_array->reserve(std::distance(dit, hi_dit));
1117 for (; dit != hi_dit; dit++)
1118 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<IS> *add_prb_is[] = {&cmp_prb_data->rowIs, &cmp_prb_data->colIs};
1290 int *nb_local_dofs[] = {&out_problem_it->nbLocDofsRow,
1291 &out_problem_it->nbLocDofsCol};
1293 int *nb_dofs[] = {&out_problem_it->nbDofsRow, &out_problem_it->nbDofsCol};
1297 out_problem_it->nbDofsRow = 0;
1298 out_problem_it->nbDofsCol = 0;
1299 out_problem_it->nbLocDofsRow = 0;
1300 out_problem_it->nbLocDofsCol = 0;
1301 out_problem_it->nbGhostDofsRow = 0;
1302 out_problem_it->nbGhostDofsCol = 0;
1304 int nb_dofs_reserve[] = {0, 0};
1307 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1311 add_prb_ptr[ss]->reserve(add_prb[ss]->size());
1312 add_prb_is[ss]->reserve(add_prb[ss]->size());
1313 for (std::vector<std::string>::const_iterator vit = add_prb[ss]->begin();
1314 vit != add_prb[ss]->end(); vit++) {
1315 ProblemByName::iterator prb_it = problems_by_name.find(*vit);
1316 if (prb_it == problems_by_name.end()) {
1319 "problem with name < %s > not defined (top tip check spelling)",
1322 add_prb_ptr[ss]->push_back(&*prb_it);
1326 *nb_dofs[ss] += add_prb_ptr[ss]->back()->getNbDofsRow();
1327 *nb_local_dofs[ss] += add_prb_ptr[ss]->back()->getNbLocalDofsRow();
1328 nb_dofs_reserve[ss] +=
1329 add_prb_ptr[ss]->back()->numeredRowDofsPtr->size();
1332 *nb_dofs[ss] += add_prb_ptr[ss]->back()->getNbDofsCol();
1333 *nb_local_dofs[ss] += add_prb_ptr[ss]->back()->getNbLocalDofsCol();
1334 nb_dofs_reserve[ss] +=
1335 add_prb_ptr[ss]->back()->numeredColDofsPtr->size();
1340 if (square_matrix) {
1341 add_prb_ptr[1]->reserve(add_prb_ptr[0]->size());
1342 add_prb_is[1]->reserve(add_prb_ptr[0]->size());
1343 out_problem_it->numeredColDofsPtr = out_problem_it->numeredRowDofsPtr;
1344 *nb_dofs[1] = *nb_dofs[0];
1345 *nb_local_dofs[1] = *nb_local_dofs[0];
1349 boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array[2];
1351 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1352 dofs_array[ss] = boost::make_shared<std::vector<NumeredDofEntity>>();
1353 dofs_array[ss]->reserve(nb_dofs_reserve[ss]);
1355 out_problem_it->getRowDofsSequence()->emplace_back(dofs_array[ss]);
1357 out_problem_it->getColDofsSequence()->emplace_back(dofs_array[ss]);
1361 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1362 NumeredDofEntity_multiIndex::index<PetscGlobalIdx_mi_tag>::type::iterator
1367 for (
unsigned int pp = 0; pp != add_prb_ptr[ss]->size(); pp++) {
1368 PetscInt *dofs_out_idx_ptr;
1369 int nb_local_dofs = (*add_prb_ptr[ss])[pp]->getNbLocalDofsRow();
1370 CHKERR PetscMalloc(nb_local_dofs *
sizeof(
int), &dofs_out_idx_ptr);
1372 dit = (*add_prb_ptr[ss])[pp]
1375 hi_dit = (*add_prb_ptr[ss])[pp]
1379 dit = (*add_prb_ptr[ss])[pp]
1382 hi_dit = (*add_prb_ptr[ss])[pp]
1387 for (; dit != hi_dit; dit++) {
1388 const BitRefLevel &prb_bit = out_problem_it->getBitRefLevel();
1389 const BitRefLevel &prb_mask = out_problem_it->getBitRefLevelMask();
1390 const BitRefLevel &dof_bit = dit->get()->getBitRefLevel();
1391 if ((dof_bit & prb_bit).none() || ((dof_bit & prb_mask) != dof_bit))
1394 const int part = dit->get()->getPart();
1395 const int glob_idx = shift_glob + dit->get()->getPetscGlobalDofIdx();
1397 (part == rank) ? (shift_loc + dit->get()->getPetscLocalDofIdx())
1399 dofs_array[ss]->emplace_back(dit->get()->getDofEntityPtr(), glob_idx,
1400 glob_idx, loc_idx, part);
1402 dofs_out_idx_ptr[is_nb++] = glob_idx;
1405 if (is_nb > nb_local_dofs) {
1407 "Data inconsistency");
1410 CHKERR ISCreateGeneral(m_field.
get_comm(), is_nb, dofs_out_idx_ptr,
1411 PETSC_OWN_POINTER, &is);
1412 (*add_prb_is[ss]).push_back(is);
1414 shift_glob += (*add_prb_ptr[ss])[pp]->getNbDofsRow();
1415 shift_loc += (*add_prb_ptr[ss])[pp]->getNbLocalDofsRow();
1417 shift_glob += (*add_prb_ptr[ss])[pp]->getNbDofsCol();
1418 shift_loc += (*add_prb_ptr[ss])[pp]->getNbLocalDofsCol();
1420 if (square_matrix) {
1421 (*add_prb_ptr[1]).push_back((*add_prb_ptr[0])[pp]);
1422 (*add_prb_is[1]).push_back(is);
1423 CHKERR PetscObjectReference((PetscObject)is);
1428 if ((*add_prb_is[1]).size() != (*add_prb_is[0]).size()) {
1433 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1434 auto hint = (ss == 0) ? out_problem_it->numeredRowDofsPtr->end()
1435 : out_problem_it->numeredColDofsPtr->end();
1436 for (
auto &
v : *dofs_array[ss])
1437 hint = (ss == 0) ? out_problem_it->numeredRowDofsPtr->emplace_hint(
1438 hint, dofs_array[ss], &
v)
1439 : out_problem_it->numeredColDofsPtr->emplace_hint(
1440 hint, dofs_array[ss], &
v);
1446 *nb_local_dofs[0] = 0;
1447 *nb_local_dofs[1] = 0;
1448 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1450 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs_ptr;
1452 dofs_ptr = out_problem_it->numeredRowDofsPtr;
1454 dofs_ptr = out_problem_it->numeredColDofsPtr;
1456 NumeredDofEntityByUId::iterator dit, hi_dit;
1459 std::vector<int> idx;
1460 idx.reserve(std::distance(dit, hi_dit));
1462 for (; dit != hi_dit; dit++) {
1463 if (dit->get()->getPart() == (
unsigned int)m_field.
get_comm_rank()) {
1468 "modification unsuccessful");
1470 idx.push_back(dit->get()->getPetscGlobalDofIdx());
1472 if (dit->get()->getPetscLocalDofIdx() != -1) {
1474 "local index should be negative");
1478 if (square_matrix) {
1479 *nb_local_dofs[1] = *nb_local_dofs[0];
1484 CHKERR ISCreateGeneral(m_field.
get_comm(), idx.size(), &*idx.begin(),
1485 PETSC_USE_POINTER, &is);
1486 CHKERR ISGetSize(is, nb_dofs[ss]);
1487 if (square_matrix) {
1488 *nb_dofs[1] = *nb_dofs[0];
1492 CHKERR AOCreateMappingIS(is, PETSC_NULL, &ao);
1493 for (
unsigned int pp = 0; pp != (*add_prb_is[ss]).size(); pp++)
1494 CHKERR AOApplicationToPetscIS(ao, (*add_prb_is[ss])[pp]);
1498 std::vector<int> idx_new;
1499 idx_new.reserve(dofs_ptr->size());
1500 for (NumeredDofEntityByUId::iterator dit =
1503 idx_new.push_back(dit->get()->getPetscGlobalDofIdx());
1508 &*idx_new.begin(), PETSC_USE_POINTER, &is_new);
1509 CHKERR AOApplicationToPetscIS(ao, is_new);
1511 std::vector<int>::iterator vit = idx_new.begin();
1512 for (NumeredDofEntityByUId::iterator dit =
1517 dit->get()->getPart(), *(vit++)));
1520 "modification unsuccessful");
1523 CHKERR ISDestroy(&is_new);
1554 MOFEM_LOG(
"WORLD", Sev::verbose) <<
"Simple partition problem " << name;
1557 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemByName;
1558 ProblemByName &problems_set =
1559 const_cast<ProblemByName &
>(problems_ptr->get<
Problem_mi_tag>());
1560 ProblemByName::iterator p_miit = problems_set.find(name);
1561 if (p_miit == problems_set.end()) {
1562 SETERRQ1(PETSC_COMM_SELF, 1,
1563 "problem < %s > is not found (top tip: check spelling)",
1568 NumeredDofEntitysByIdx &dofs_row_by_idx =
1569 p_miit->numeredRowDofsPtr->get<
Idx_mi_tag>();
1570 NumeredDofEntitysByIdx &dofs_col_by_idx =
1571 p_miit->numeredColDofsPtr->get<
Idx_mi_tag>();
1578 DofIdx &nb_row_local_dofs = p_miit->nbLocDofsRow;
1579 DofIdx &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
1580 nb_row_local_dofs = 0;
1581 nb_row_ghost_dofs = 0;
1582 DofIdx &nb_col_local_dofs = p_miit->nbLocDofsCol;
1583 DofIdx &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
1584 nb_col_local_dofs = 0;
1585 nb_col_ghost_dofs = 0;
1587 bool square_matrix =
false;
1588 if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr) {
1589 square_matrix =
true;
1593 PetscLayout layout_row;
1594 const int *ranges_row;
1596 DofIdx nb_dofs_row = dofs_row_by_idx.size();
1598 CHKERR PetscLayoutSetBlockSize(layout_row, 1);
1599 CHKERR PetscLayoutSetSize(layout_row, nb_dofs_row);
1600 CHKERR PetscLayoutSetUp(layout_row);
1601 CHKERR PetscLayoutGetRanges(layout_row, &ranges_row);
1603 PetscLayout layout_col;
1604 const int *ranges_col;
1605 if (!square_matrix) {
1606 DofIdx nb_dofs_col = dofs_col_by_idx.size();
1608 CHKERR PetscLayoutSetBlockSize(layout_col, 1);
1609 CHKERR PetscLayoutSetSize(layout_col, nb_dofs_col);
1610 CHKERR PetscLayoutSetUp(layout_col);
1611 CHKERR PetscLayoutGetRanges(layout_col, &ranges_col);
1613 for (
unsigned int part = 0; part < (
unsigned int)m_field.
get_comm_size();
1615 miit_row = dofs_row_by_idx.lower_bound(ranges_row[part]);
1616 hi_miit_row = dofs_row_by_idx.lower_bound(ranges_row[part + 1]);
1617 if (std::distance(miit_row, hi_miit_row) !=
1618 ranges_row[part + 1] - ranges_row[part]) {
1620 PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1621 "data inconsistency, std::distance(miit_row,hi_miit_row) != rend - "
1622 "rstart (%d != %d - %d = %d) ",
1623 std::distance(miit_row, hi_miit_row), ranges_row[part + 1],
1624 ranges_row[part], ranges_row[part + 1] - ranges_row[part]);
1627 for (; miit_row != hi_miit_row; miit_row++) {
1628 bool success = dofs_row_by_idx.modify(
1633 "modification unsuccessful");
1635 success = dofs_row_by_idx.modify(
1639 "modification unsuccessful");
1642 if (!square_matrix) {
1643 miit_col = dofs_col_by_idx.lower_bound(ranges_col[part]);
1644 hi_miit_col = dofs_col_by_idx.lower_bound(ranges_col[part + 1]);
1645 if (std::distance(miit_col, hi_miit_col) !=
1646 ranges_col[part + 1] - ranges_col[part]) {
1647 SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1648 "data inconsistency, std::distance(miit_col,hi_miit_col) != "
1650 "rstart (%d != %d - %d = %d) ",
1651 std::distance(miit_col, hi_miit_col), ranges_col[part + 1],
1652 ranges_col[part], ranges_col[part + 1] - ranges_col[part]);
1655 for (; miit_col != hi_miit_col; miit_col++) {
1656 bool success = dofs_col_by_idx.modify(
1658 part, (*miit_col)->dofIdx));
1661 "modification unsuccessful");
1663 success = dofs_col_by_idx.modify(
1667 "modification unsuccessful");
1672 CHKERR PetscLayoutDestroy(&layout_row);
1673 if (!square_matrix) {
1674 CHKERR PetscLayoutDestroy(&layout_col);
1676 if (square_matrix) {
1677 nb_col_local_dofs = nb_row_local_dofs;
1678 nb_col_ghost_dofs = nb_row_ghost_dofs;
1691 MOFEM_LOG(
"WORLD", Sev::noisy) <<
"Partition problem " << name;
1693 using NumeredDofEntitysByIdx =
1694 NumeredDofEntity_multiIndex::index<Idx_mi_tag>::type;
1695 using ProblemsByName = Problem_multiIndex::index<Problem_mi_tag>::type;
1698 auto &problems_set =
1699 const_cast<ProblemsByName &
>(problems_ptr->get<
Problem_mi_tag>());
1700 auto p_miit = problems_set.find(name);
1701 if (p_miit == problems_set.end()) {
1703 "problem with name %s not defined (top tip check spelling)",
1706 int nb_dofs_row = p_miit->getNbDofsRow();
1716 "entFEAdjacencies not build");
1722 ->createMPIAdjWithArrays<Idx_mi_tag>(name, &Adj, verb);
1727 MatView(Adj, PETSC_VIEWER_STDOUT_WORLD);
1730 MatPartitioning part;
1733 CHKERR MatPartitioningSetAdjacency(part, Adj);
1734 CHKERR MatPartitioningSetFromOptions(part);
1736 CHKERR MatPartitioningApply(part, &is);
1738 ISView(is, PETSC_VIEWER_STDOUT_WORLD);
1741 IS is_gather, is_num, is_gather_num;
1742 CHKERR ISAllGather(is, &is_gather);
1743 CHKERR ISPartitioningToNumbering(is, &is_num);
1744 CHKERR ISAllGather(is_num, &is_gather_num);
1745 const int *part_number, *petsc_idx;
1746 CHKERR ISGetIndices(is_gather, &part_number);
1747 CHKERR ISGetIndices(is_gather_num, &petsc_idx);
1748 int size_is_num, size_is_gather;
1749 CHKERR ISGetSize(is_gather, &size_is_gather);
1750 if (size_is_gather != (
int)nb_dofs_row)
1751 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1752 "data inconsistency %d != %d", size_is_gather, nb_dofs_row);
1754 CHKERR ISGetSize(is_num, &size_is_num);
1755 if (size_is_num != (
int)nb_dofs_row)
1756 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1757 "data inconsistency %d != %d", size_is_num, nb_dofs_row);
1759 bool square_matrix =
false;
1760 if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr)
1761 square_matrix =
true;
1788 auto number_dofs = [&](
auto &dofs_idx,
auto &counter) {
1790 for (
auto miit_dofs_row = dofs_idx.begin();
1791 miit_dofs_row != dofs_idx.end(); miit_dofs_row++) {
1792 const int part = part_number[(*miit_dofs_row)->dofIdx];
1794 const bool success = dofs_idx.modify(
1797 part, petsc_idx[(*miit_dofs_row)->dofIdx], counter++));
1800 "modification unsuccessful");
1803 const bool success = dofs_idx.modify(
1805 part, petsc_idx[(*miit_dofs_row)->dofIdx]));
1808 "modification unsuccessful");
1816 auto &dofs_row_by_idx_no_const =
const_cast<NumeredDofEntitysByIdx &
>(
1817 p_miit->numeredRowDofsPtr->get<
Idx_mi_tag>());
1818 int &nb_row_local_dofs = p_miit->nbLocDofsRow;
1819 int &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
1820 nb_row_local_dofs = 0;
1821 nb_row_ghost_dofs = 0;
1823 CHKERR number_dofs(dofs_row_by_idx_no_const, nb_row_local_dofs);
1825 int &nb_col_local_dofs = p_miit->nbLocDofsCol;
1826 int &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
1827 if (square_matrix) {
1828 nb_col_local_dofs = nb_row_local_dofs;
1829 nb_col_ghost_dofs = nb_row_ghost_dofs;
1831 NumeredDofEntitysByIdx &dofs_col_by_idx_no_const =
1832 const_cast<NumeredDofEntitysByIdx &
>(
1833 p_miit->numeredColDofsPtr->get<
Idx_mi_tag>());
1834 nb_col_local_dofs = 0;
1835 nb_col_ghost_dofs = 0;
1836 CHKERR number_dofs(dofs_col_by_idx_no_const, nb_col_local_dofs);
1839 CHKERR ISRestoreIndices(is_gather, &part_number);
1840 CHKERR ISRestoreIndices(is_gather_num, &petsc_idx);
1841 CHKERR ISDestroy(&is_num);
1842 CHKERR ISDestroy(&is_gather_num);
1843 CHKERR ISDestroy(&is_gather);
1845 CHKERR MatPartitioningDestroy(&part);
1850 auto number_dofs = [&](
auto &dof_idx,
auto &counter) {
1852 for (
auto miit_dofs_row = dof_idx.begin(); miit_dofs_row != dof_idx.end();
1854 const bool success = dof_idx.modify(
1860 "modification unsuccessful");
1866 auto &dofs_row_by_idx_no_const =
const_cast<NumeredDofEntitysByIdx &
>(
1867 p_miit->numeredRowDofsPtr->get<
Idx_mi_tag>());
1868 int &nb_row_local_dofs = p_miit->nbLocDofsRow;
1869 int &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
1870 nb_row_local_dofs = 0;
1871 nb_row_ghost_dofs = 0;
1873 CHKERR number_dofs(dofs_row_by_idx_no_const, nb_row_local_dofs);
1875 bool square_matrix =
false;
1876 if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr)
1877 square_matrix =
true;
1879 int &nb_col_local_dofs = p_miit->nbLocDofsCol;
1880 int &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
1881 if (square_matrix) {
1882 nb_col_local_dofs = nb_row_local_dofs;
1883 nb_col_ghost_dofs = nb_row_ghost_dofs;
1885 NumeredDofEntitysByIdx &dofs_col_by_idx_no_const =
1886 const_cast<NumeredDofEntitysByIdx &
>(
1887 p_miit->numeredColDofsPtr->get<
Idx_mi_tag>());
1888 nb_col_local_dofs = 0;
1889 nb_col_ghost_dofs = 0;
1890 CHKERR number_dofs(dofs_col_by_idx_no_const, nb_col_local_dofs);
1899 const std::string name,
const std::string problem_for_rows,
bool copy_rows,
1900 const std::string problem_for_cols,
bool copy_cols,
int verb) {
1908 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemByName;
1911 ProblemByName &problems_by_name =
1912 const_cast<ProblemByName &
>(problems_ptr->get<
Problem_mi_tag>());
1913 ProblemByName::iterator p_miit = problems_by_name.find(name);
1914 if (p_miit == problems_by_name.end()) {
1916 "problem with name < %s > not defined (top tip check spelling)",
1921 << p_miit->getName() <<
" from rows of " << problem_for_rows
1922 <<
" and columns of " << problem_for_cols;
1925 ProblemByName::iterator p_miit_row = problems_by_name.find(problem_for_rows);
1926 if (p_miit_row == problems_by_name.end()) {
1928 "problem with name < %s > not defined (top tip check spelling)",
1929 problem_for_rows.c_str());
1931 const boost::shared_ptr<NumeredDofEntity_multiIndex> dofs_row =
1932 p_miit_row->numeredRowDofsPtr;
1935 ProblemByName::iterator p_miit_col = problems_by_name.find(problem_for_cols);
1936 if (p_miit_col == problems_by_name.end()) {
1938 "problem with name < %s > not defined (top tip check spelling)",
1939 problem_for_cols.c_str());
1941 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs_col =
1942 p_miit_col->numeredColDofsPtr;
1944 bool copy[] = {copy_rows, copy_cols};
1945 boost::shared_ptr<NumeredDofEntity_multiIndex> composed_dofs[] = {
1946 p_miit->numeredRowDofsPtr, p_miit->numeredColDofsPtr};
1948 int *nb_local_dofs[] = {&p_miit->nbLocDofsRow, &p_miit->nbLocDofsCol};
1949 int *nb_dofs[] = {&p_miit->nbDofsRow, &p_miit->nbDofsCol};
1950 boost::shared_ptr<NumeredDofEntity_multiIndex> copied_dofs[] = {dofs_row,
1953 for (
int ss = 0; ss < 2; ss++) {
1956 *nb_local_dofs[ss] = 0;
1960 std::vector<int> is_local, is_new;
1964 for (NumeredDofEntity_multiIndex::iterator dit =
1965 composed_dofs[ss]->begin();
1966 dit != composed_dofs[ss]->end(); dit++) {
1967 NumeredDofEntityByUId::iterator diit =
1968 dofs_by_uid.find((*dit)->getLocalUniqueId());
1969 if (diit == dofs_by_uid.end()) {
1972 "data inconsistency, could not find dof in composite problem");
1974 int part_number = (*diit)->getPart();
1975 int petsc_global_dof = (*diit)->getPetscGlobalDofIdx();
1977 success = composed_dofs[ss]->modify(
1982 "modification unsuccessful");
1984 if ((*dit)->getPart() == (
unsigned int)m_field.
get_comm_rank()) {
1985 success = composed_dofs[ss]->modify(
1989 "modification unsuccessful");
1991 is_local.push_back(petsc_global_dof);
1996 CHKERR AOCreateMapping(m_field.
get_comm(), is_local.size(), &is_local[0],
2001 for (NumeredDofEntity_multiIndex::iterator dit =
2002 composed_dofs[ss]->begin();
2003 dit != composed_dofs[ss]->end(); dit++) {
2004 is_local.push_back((*dit)->getPetscGlobalDofIdx());
2006 CHKERR AOPetscToApplication(ao, is_local.size(), &is_local[0]);
2008 for (NumeredDofEntity_multiIndex::iterator dit =
2009 composed_dofs[ss]->begin();
2010 dit != composed_dofs[ss]->end(); dit++) {
2011 int part_number = (*dit)->getPart();
2012 int petsc_global_dof = is_local[idx2++];
2014 success = composed_dofs[ss]->modify(
2019 "modification unsuccessful");
2027 for (NumeredDofEntity_multiIndex::iterator dit = copied_dofs[ss]->begin();
2028 dit != copied_dofs[ss]->end(); dit++) {
2029 std::pair<NumeredDofEntity_multiIndex::iterator, bool>
p;
2030 p = composed_dofs[ss]->insert(boost::shared_ptr<NumeredDofEntity>(
2035 int dof_idx = (*dit)->getDofIdx();
2036 int part_number = (*dit)->getPart();
2037 int petsc_global_dof = (*dit)->getPetscGlobalDofIdx();
2039 const bool success = composed_dofs[ss]->modify(
2041 part_number, dof_idx, petsc_global_dof,
2042 (*nb_local_dofs[ss])++));
2045 "modification unsuccessful");
2048 const bool success = composed_dofs[ss]->modify(
2050 part_number, dof_idx, petsc_global_dof));
2053 "modification unsuccessful");
2074 << problem_ptr->
getName() <<
" Nb. local dof "
2090 auto save_ent = [](moab::Interface &moab,
const std::string name,
2094 CHKERR moab.create_meshset(MESHSET_SET, out_meshset);
2095 CHKERR moab.add_entities(out_meshset, &ent, 1);
2096 CHKERR moab.write_file(name.c_str(),
"VTK",
"", &out_meshset, 1);
2097 CHKERR moab.delete_entities(&out_meshset, 1);
2103 typedef NumeredDofEntity_multiIndex::index<Idx_mi_tag>::type
2104 NumeredDofEntitysByIdx;
2105 NumeredDofEntitysByIdx::iterator dit, hi_dit;
2106 const NumeredDofEntitysByIdx *numered_dofs_ptr[] = {
2114 for (
int ss = 0; ss < 2; ss++) {
2116 dit = numered_dofs_ptr[ss]->begin();
2117 hi_dit = numered_dofs_ptr[ss]->end();
2118 for (; dit != hi_dit; dit++) {
2119 if ((*dit)->getPart() == (
unsigned int)m_field.
get_comm_rank()) {
2120 if ((*dit)->getPetscLocalDofIdx() < 0) {
2121 std::ostringstream zz;
2124 "local dof index for %d (0-row, 1-col) not set, i.e. has "
2125 "negative value\n %s",
2126 ss, zz.str().c_str());
2128 if ((*dit)->getPetscLocalDofIdx() >= *local_nbdof_ptr[ss]) {
2129 std::ostringstream zz;
2132 "local dofs for %d (0-row, 1-col) out of range\n %s", ss,
2136 if ((*dit)->getPetscGlobalDofIdx() < 0) {
2143 "_negative_global_index.vtk",
2146 std::ostringstream zz;
2148 << dit->get()->getBitRefLevel() <<
" " << **dit;
2150 "global dof index for %d (0-row, 1-col) row not set, i.e. "
2151 "has negative value\n %s",
2152 ss, zz.str().c_str());
2154 if ((*dit)->getPetscGlobalDofIdx() >= *nbdof_ptr[ss]) {
2155 std::ostringstream zz;
2157 << *nbdof_ptr[ss] <<
" " << **dit;
2159 "global dofs for %d (0-row, 1-col) out of range\n %s", ss,
2170 bool part_from_moab,
2172 int hi_proc,
int verb) {
2186 "adjacencies not build");
2193 "problem not partitioned");
2201 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemByName;
2203 const_cast<ProblemByName &
>(problems_ptr->get<
Problem_mi_tag>());
2204 ProblemByName::iterator p_miit = problems.find(name);
2205 if (p_miit == problems.end()) {
2207 "problem < %s > not found (top tip: check spelling)",
2213 *p_miit->numeredFiniteElementsPtr;
2216 problem_finite_elements.clear();
2220 bool do_cols_prob =
true;
2221 if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr) {
2222 do_cols_prob =
false;
2225 auto get_good_elems = [&]() {
2226 auto good_elems = std::vector<
decltype(fe_ent_ptr->begin())>();
2227 good_elems.reserve(fe_ent_ptr->size());
2229 const auto prb_bit = p_miit->getBitRefLevel();
2230 const auto prb_mask = p_miit->getBitRefLevelMask();
2234 for (
auto efit = fe_ent_ptr->begin(); efit != fe_ent_ptr->end(); ++efit) {
2237 if (((*efit)->getId() & p_miit->getBitFEId()).any()) {
2239 const auto &fe_bit = (*efit)->getBitRefLevel();
2242 if ((fe_bit & prb_mask) == fe_bit && (fe_bit & prb_bit).any())
2243 good_elems.emplace_back(efit);
2250 auto good_elems = get_good_elems();
2252 auto numbered_good_elems_ptr =
2253 boost::make_shared<std::vector<NumeredEntFiniteElement>>();
2254 numbered_good_elems_ptr->reserve(good_elems.size());
2255 for (
auto &efit : good_elems)
2258 if (!do_cols_prob) {
2259 for (
auto &fe : *numbered_good_elems_ptr) {
2260 if (fe.sPtr->getRowFieldEntsPtr() == fe.sPtr->getColFieldEntsPtr()) {
2261 fe.getColFieldEntsPtr() = fe.getRowFieldEntsPtr();
2266 if (part_from_moab) {
2267 for (
auto &fe : *numbered_good_elems_ptr) {
2269 int proc = fe.getPartProc();
2270 if (proc == -1 && fe.getEntType() == MBVERTEX)
2271 proc = fe.getOwnerProc();
2276 for (
auto &fe : *numbered_good_elems_ptr) {
2279 CHKERR fe.sPtr->getRowDofView(*(p_miit->numeredRowDofsPtr), rows_view);
2281 if (!part_from_moab) {
2283 for (
auto &dof_ptr : rows_view)
2284 parts[dof_ptr->pArt]++;
2285 std::vector<int>::iterator pos = max_element(parts.begin(), parts.end());
2286 const auto max_part = std::distance(parts.begin(), pos);
2291 for (
auto &fe : *numbered_good_elems_ptr) {
2293 auto check_fields_and_dofs = [&]() {
2294 if (!part_from_moab) {
2295 if (fe.getBitFieldIdRow().none() && m_field.
get_comm_size() == 0) {
2297 <<
"At least one field has to be added to element row to "
2298 "determine partition of finite element. Check element " +
2299 boost::lexical_cast<std::string>(fe.getName());
2306 if (check_fields_and_dofs()) {
2308 auto p = problem_finite_elements.insert(
2309 boost::shared_ptr<NumeredEntFiniteElement>(numbered_good_elems_ptr,
2317 auto elements_on_rank =
2318 problem_finite_elements.get<
Part_mi_tag>().equal_range(
2321 << p_miit->getName() <<
" nb. elems "
2322 << std::distance(elements_on_rank.first, elements_on_rank.second);
2324 for (
auto &fe : *fe_ptr) {
2330 <<
"Element " << fe->getName() <<
" nb. elems "
2331 << std::distance(e_range.first, e_range.second);
2349 "partition of problem not build");
2352 "partitions finite elements not build");
2361 int &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
2362 int &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
2363 nb_row_ghost_dofs = 0;
2364 nb_col_ghost_dofs = 0;
2374 p_miit->numeredFiniteElementsPtr->get<
Part_mi_tag>().equal_range(
2380 using Vec = std::vector<boost::shared_ptr<NumeredDofEntity>>;
2381 using It = Vec::iterator;
2382 It operator()(Vec &dofs_view, It &hint,
2383 boost::shared_ptr<NumeredDofEntity> &&dof) {
2384 dofs_view.emplace_back(dof);
2385 return dofs_view.end();
2390 std::vector<boost::shared_ptr<NumeredDofEntity>> fe_vec_view;
2391 auto hint_r = ghost_idx_row_view.begin();
2392 for (
auto fe_ptr = fe_range.first; fe_ptr != fe_range.second; ++fe_ptr) {
2394 fe_vec_view.clear();
2396 *(p_miit->getNumeredRowDofsPtr()),
2397 fe_vec_view, Inserter());
2399 for (
auto &dof_ptr : fe_vec_view) {
2400 if (dof_ptr->getPart() != (
unsigned int)m_field.
get_comm_rank()) {
2401 hint_r = ghost_idx_row_view.emplace_hint(hint_r, dof_ptr);
2407 if (p_miit->numeredColDofsPtr == p_miit->numeredRowDofsPtr) {
2409 auto hint_c = ghost_idx_col_view.begin();
2410 for (
auto fe_ptr = fe_range.first; fe_ptr != fe_range.second; ++fe_ptr) {
2412 fe_vec_view.clear();
2414 *(p_miit->getNumeredColDofsPtr()),
2415 fe_vec_view, Inserter());
2417 for (
auto &dof_ptr : fe_vec_view) {
2418 if (dof_ptr->getPart() != (
unsigned int)m_field.
get_comm_rank()) {
2419 hint_c = ghost_idx_col_view.emplace_hint(hint_c, dof_ptr);
2425 int *nb_ghost_dofs[2] = {&nb_row_ghost_dofs, &nb_col_ghost_dofs};
2426 int nb_local_dofs[2] = {p_miit->nbLocDofsRow, p_miit->nbLocDofsCol};
2429 &ghost_idx_row_view, &ghost_idx_col_view};
2435 if (p_miit->numeredColDofsPtr == p_miit->numeredRowDofsPtr) {
2440 for (
int ss = 0; ss != loop_size; ++ss) {
2441 for (
auto &gid : *ghost_idx_view[ss]) {
2442 NumeredDofEntityByUId::iterator dof =
2443 dof_by_uid_no_const[ss]->find(gid->getLocalUniqueId());
2444 if (PetscUnlikely((*dof)->petscLocalDofIdx != (
DofIdx)-1))
2446 "inconsistent data, ghost dof already set");
2447 bool success = dof_by_uid_no_const[ss]->modify(
2449 if (PetscUnlikely(!success))
2451 "modification unsuccessful");
2452 (*nb_ghost_dofs[ss])++;
2455 if (loop_size == 1) {
2456 (*nb_ghost_dofs[1]) = (*nb_ghost_dofs[0]);
2462 <<
" FEs ghost dofs on problem " << p_miit->getName()
2463 <<
" Nb. ghost dof " << p_miit->getNbGhostDofsRow() <<
" by "
2464 << p_miit->getNbGhostDofsCol() <<
" Nb. local dof "
2465 << p_miit->getNbLocalDofsCol() <<
" by " << p_miit->getNbLocalDofsCol();
2483 "partition of problem not build");
2486 "partitions finite elements not build");
2489 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
2491 ProblemsByName &problems_set =
2492 const_cast<ProblemsByName &
>(problems_ptr->get<
Problem_mi_tag>());
2493 ProblemsByName::iterator p_miit = problems_set.find(name);
2497 DofIdx *nb_ghost_dofs[2] = {&(p_miit->nbGhostDofsRow),
2498 &(p_miit->nbGhostDofsCol)};
2499 DofIdx nb_local_dofs[2] = {p_miit->nbLocDofsRow, p_miit->nbLocDofsCol};
2500 for (
int ss = 0; ss != 2; ++ss) {
2501 (*nb_ghost_dofs[ss]) = 0;
2508 if (p_miit->numeredColDofsPtr == p_miit->numeredRowDofsPtr) {
2512 typedef decltype(p_miit->numeredRowDofsPtr) NumbDofTypeSharedPtr;
2513 NumbDofTypeSharedPtr numered_dofs[] = {p_miit->numeredRowDofsPtr,
2514 p_miit->numeredColDofsPtr};
2517 for (
int ss = 0; ss != loop_size; ++ss) {
2522 std::vector<NumeredDofEntity_multiIndex::iterator> ghost_idx_view;
2523 ghost_idx_view.reserve(std::distance(r.first, r.second));
2524 for (; r.first != r.second; ++r.first)
2525 ghost_idx_view.emplace_back(numered_dofs[ss]->project<0>(r.first));
2527 auto cmp = [](
auto a,
auto b) {
2528 return (*a)->getLocalUniqueId() < (*b)->getLocalUniqueId();
2530 sort(ghost_idx_view.begin(), ghost_idx_view.end(), cmp);
2533 for (
auto gid_it : ghost_idx_view) {
2534 bool success = numered_dofs[ss]->modify(
2538 "modification unsuccessful");
2539 ++(*nb_ghost_dofs[ss]);
2542 if (loop_size == 1) {
2543 (*nb_ghost_dofs[1]) = (*nb_ghost_dofs[0]);
2549 <<
" FEs ghost dofs on problem " << p_miit->getName()
2550 <<
" Nb. ghost dof " << p_miit->getNbGhostDofsRow() <<
" by "
2551 << p_miit->getNbGhostDofsCol() <<
" Nb. local dof "
2552 << p_miit->getNbLocalDofsCol() <<
" by " << p_miit->getNbLocalDofsCol();
2562 const std::string &fe_name,
2578 0, (*fe_miit)->getFEUId()));
2582 get_id_for_max_type<MBENTITYSET>(), (*fe_miit)->getFEUId()));
2583 std::vector<EntityHandle> fe_vec;
2584 fe_vec.reserve(std::distance(fit, hi_fe_it));
2585 for (; fit != hi_fe_it; fit++)
2586 fe_vec.push_back(fit->get()->getEnt());
2587 CHKERR m_field.
get_moab().add_entities(*meshset, &*fe_vec.begin(),
2596 const std::string &fe_name,
2597 PetscLayout *layout)
const {
2608 const std::string problem_name,
const std::string
field_name,
2609 const Range ents,
const int lo_coeff,
const int hi_coeff,
2610 const int lo_order,
const int hi_order,
int verb,
const bool debug) {
2634 for (
int s = 0; s != 2; ++s)
2635 if (numered_dofs[s]) {
2637 typedef multi_index_container<
2639 NumeredDofEntity_multiIndex::iterator, indexed_by<sequenced<>>
2642 NumeredDofEntity_it_view_multiIndex;
2645 NumeredDofEntity_it_view_multiIndex dofs_it_view;
2648 for (
auto pit = ents.const_pair_begin(); pit != ents.const_pair_end();
2650 auto lo = numered_dofs[s]->get<
Unique_mi_tag>().lower_bound(
2652 auto hi = numered_dofs[s]->get<
Unique_mi_tag>().upper_bound(
2655 for (; lo != hi; ++lo)
2656 if ((*lo)->getDofCoeffIdx() >= lo_coeff &&
2657 (*lo)->getDofCoeffIdx() <= hi_coeff &&
2658 (*lo)->getDofOrder() >= lo_order &&
2659 (*lo)->getDofOrder() <= hi_order)
2660 dofs_it_view.emplace_back(numered_dofs[s]->project<0>(lo));
2664 for (
auto &dof : dofs_it_view)
2670 std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_weak_view;
2671 dofs_weak_view.reserve(dofs_it_view.size());
2672 for (
auto dit : dofs_it_view)
2673 dofs_weak_view.push_back(*dit);
2677 "Number of DOFs in multi-index %d and to delete %d\n",
2678 numered_dofs[s]->size(), dofs_it_view.size());
2681 for (
auto weak_dit : dofs_weak_view)
2682 if (
auto dit = weak_dit.lock()) {
2683 numered_dofs[s]->erase(dit->getLocalUniqueId());
2688 "Number of DOFs in multi-index after delete %d\n",
2689 numered_dofs[s]->size());
2692 int nb_local_dofs = 0;
2693 int nb_ghost_dofs = 0;
2694 for (
auto dit = numered_dofs[s]->get<PetscLocalIdx_mi_tag>().begin();
2696 if ((*dit)->getPetscLocalDofIdx() >= 0 &&
2697 (*dit)->getPetscLocalDofIdx() < *(local_nbdof_ptr[s]))
2699 else if ((*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[s]))
2703 "Impossible case. You could run problem on no distributed "
2704 "mesh. That is not implemented. Dof local index is %d",
2705 (*dit)->getPetscLocalDofIdx());
2709 auto get_indices_by_tag = [&](
auto tag,
auto &indices,
bool only_local) {
2710 const int nb_dofs = numered_dofs[s]->size();
2712 indices.reserve(nb_dofs);
2713 for (
auto dit = numered_dofs[s]->get<
decltype(tag)>().begin();
2714 dit != numered_dofs[s]->get<
decltype(tag)>().end(); ++dit) {
2717 if ((*dit)->getPetscLocalDofIdx() < 0 ||
2718 (*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[s])) {
2723 indices.push_back(
decltype(tag)::get_index(dit));
2727 auto get_indices_by_uid = [&](
auto tag,
auto &indices) {
2728 const int nb_dofs = numered_dofs[s]->size();
2730 indices.reserve(nb_dofs);
2731 for (
auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
2733 indices.push_back(
decltype(tag)::get_index(dit));
2736 auto get_sub_ao = [&](
auto sub_data) {
2738 return sub_data->getSmartRowMap();
2740 return sub_data->getSmartColMap();
2744 auto set_sub_is_and_ao = [&s, &prb_ptr](
auto sub_data,
auto is,
auto ao) {
2746 sub_data->rowIs = is;
2747 sub_data->rowMap = ao;
2749 sub_data->colIs = is;
2750 sub_data->colMap = ao;
2754 auto apply_symmetry = [&s, &prb_ptr](
auto sub_data) {
2757 sub_data->colIs = sub_data->getSmartRowIs();
2758 sub_data->colMap = sub_data->getSmartRowMap();
2763 auto concatenate_dofs = [&](
auto tag,
auto &indices,
2764 const auto local_only) {
2766 get_indices_by_tag(tag, indices, local_only);
2773 &*indices.begin(), PETSC_NULL);
2776 &*indices.begin(), PETSC_NULL);
2783 &*indices.begin(), PETSC_COPY_VALUES);
2786 auto sub_ao = get_sub_ao(sub_data);
2787 CHKERR AOPetscToApplicationIS(sub_ao, sub_is);
2790 set_sub_is_and_ao(sub_data, sub_is, sub_ao);
2791 apply_symmetry(sub_data);
2795 boost::make_shared<Problem::SubProblemData>();
2797 &*indices.begin(), PETSC_COPY_VALUES);
2799 set_sub_is_and_ao(prb_ptr->
getSubData(), sub_is, ao);
2804 get_indices_by_uid(tag, indices);
2805 CHKERR AOApplicationToPetsc(ao, indices.size(), &*indices.begin());
2811 auto set_concatenated_indices = [&]() {
2812 std::vector<int> global_indices;
2813 std::vector<int> local_indices;
2817 auto gi = global_indices.begin();
2818 auto li = local_indices.begin();
2819 for (
auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
2822 (*dit)->getPart(), (*dit)->getDofIdx(), *gi, *li);
2823 bool success = numered_dofs[s]->modify(dit, mod);
2826 "can not set negative indices");
2832 CHKERR set_concatenated_indices();
2834 MPI_Allreduce(&nb_local_dofs, nbdof_ptr[s], 1, MPI_INT, MPI_SUM,
2836 *(local_nbdof_ptr[s]) = nb_local_dofs;
2837 *(ghost_nbdof_ptr[s]) = nb_ghost_dofs;
2840 for (
auto dof : (*numered_dofs[s])) {
2841 if (dof->getPetscGlobalDofIdx() < 0) {
2843 "Negative global idx");
2845 if (dof->getPetscLocalDofIdx() < 0) {
2847 "Negative local idx");
2853 *(nbdof_ptr[1]) = *(nbdof_ptr[0]);
2854 *(local_nbdof_ptr[1]) = *(local_nbdof_ptr[0]);
2855 *(ghost_nbdof_ptr[1]) = *(ghost_nbdof_ptr[0]);
2860 "WORLD", Sev::inform,
2861 "Removed DOFs from problem %s dofs [%d / %d (before %d / %d) global]",
2863 prb_ptr->
getNbDofsCol(), nb_init_row_dofs, nb_init_col_dofs);
2865 "Removed DOFs from problem %s dofs [ %d / %d "
2866 "(before %d / %d) local, %d / %d (before %d / %d)]",
2871 nb_init_ghost_col_dofs);
2879 const std::string problem_name,
const std::string
field_name,
2880 const Range ents,
const int lo_coeff,
const int hi_coeff,
2881 const int lo_order,
const int hi_order,
int verb,
const bool debug) {
2905 const std::array<int, 2> nb_init_dofs = {nb_init_row_dofs, nb_init_col_dofs};
2907 for (
int s = 0; s != 2; ++s)
2908 if (numered_dofs[s]) {
2910 typedef multi_index_container<
2912 NumeredDofEntity_multiIndex::iterator, indexed_by<sequenced<>>
2915 NumeredDofEntity_it_view_multiIndex;
2918 NumeredDofEntity_it_view_multiIndex dofs_it_view;
2921 for (
auto pit = ents.const_pair_begin(); pit != ents.const_pair_end();
2923 auto lo = numered_dofs[s]->get<
Unique_mi_tag>().lower_bound(
2925 auto hi = numered_dofs[s]->get<
Unique_mi_tag>().upper_bound(
2928 for (; lo != hi; ++lo)
2929 if ((*lo)->getDofCoeffIdx() >= lo_coeff &&
2930 (*lo)->getDofCoeffIdx() <= hi_coeff &&
2931 (*lo)->getDofOrder() >= lo_order &&
2932 (*lo)->getDofOrder() <= hi_order)
2933 dofs_it_view.emplace_back(numered_dofs[s]->project<0>(lo));
2937 for (
auto &dof : dofs_it_view)
2943 for (
auto dit : dofs_it_view) {
2944 bool success = numered_dofs[s]->modify(dit, mod);
2947 "can not set negative indices");
2951 std::vector<boost::weak_ptr<NumeredDofEntity>> dosf_weak_view;
2952 dosf_weak_view.reserve(dofs_it_view.size());
2953 for (
auto dit : dofs_it_view)
2954 dosf_weak_view.push_back(*dit);
2958 "Number of DOFs in multi-index %d and to delete %d\n",
2959 numered_dofs[s]->size(), dofs_it_view.size());
2962 for (
auto weak_dit : dosf_weak_view)
2963 if (
auto dit = weak_dit.lock()) {
2964 numered_dofs[s]->erase(dit->getLocalUniqueId());
2969 "Number of DOFs in multi-index after delete %d\n",
2970 numered_dofs[s]->size());
2973 int nb_global_dof = 0;
2974 int nb_local_dofs = 0;
2975 int nb_ghost_dofs = 0;
2977 for (
auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
2980 if ((*dit)->getDofIdx() >= 0) {
2982 if ((*dit)->getPetscLocalDofIdx() >= 0 &&
2983 (*dit)->getPetscLocalDofIdx() < *(local_nbdof_ptr[s]))
2985 else if ((*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[s]))
2993 MPI_Allreduce(&nb_local_dofs, nbdof_ptr[s], 1, MPI_INT, MPI_SUM,
2995 if (*(nbdof_ptr[s]) != nb_global_dof)
2997 "Number of local DOFs do not add up %d != %d",
2998 *(nbdof_ptr[s]), nb_global_dof);
3001 *(nbdof_ptr[s]) = nb_global_dof;
3002 *(local_nbdof_ptr[s]) = nb_local_dofs;
3003 *(ghost_nbdof_ptr[s]) = nb_ghost_dofs;
3006 auto get_indices_by_tag = [&](
auto tag) {
3007 std::vector<int> indices;
3008 indices.resize(nb_init_dofs[s], -1);
3009 for (
auto dit = numered_dofs[s]->get<Idx_mi_tag>().lower_bound(0);
3010 dit != numered_dofs[s]->get<
Idx_mi_tag>().end(); ++dit) {
3011 indices[(*dit)->getDofIdx()] =
decltype(tag)::get_index(dit);
3016 auto renumber = [&](
auto tag,
auto &indices) {
3019 for (
auto dit = numered_dofs[s]->get<
decltype(tag)>().lower_bound(0);
3020 dit != numered_dofs[s]->get<
decltype(tag)>().end(); ++dit) {
3021 indices[(*dit)->getDofIdx()] = idx++;
3026 auto get_sub_ao = [&](
auto sub_data) {
3028 return sub_data->getSmartRowMap();
3030 return sub_data->getSmartColMap();
3034 auto set_sub_is_and_ao = [&s, &prb_ptr](
auto sub_data,
auto is,
auto ao) {
3036 sub_data->rowIs = is;
3037 sub_data->rowMap = ao;
3039 sub_data->colIs = is;
3040 sub_data->colMap = ao;
3044 auto apply_symmetry = [&s, &prb_ptr](
auto sub_data) {
3047 sub_data->colIs = sub_data->getSmartRowIs();
3048 sub_data->colMap = sub_data->getSmartRowMap();
3053 auto set_sub_data = [&](
auto &indices) {
3058 &*indices.begin(), PETSC_COPY_VALUES);
3061 auto sub_ao = get_sub_ao(sub_data);
3062 CHKERR AOPetscToApplicationIS(sub_ao, sub_is);
3065 set_sub_is_and_ao(sub_data, sub_is, sub_ao);
3066 apply_symmetry(sub_data);
3068 prb_ptr->
getSubData() = boost::make_shared<Problem::SubProblemData>();
3070 &*indices.begin(), PETSC_COPY_VALUES);
3073 set_sub_is_and_ao(prb_ptr->
getSubData(), sub_is, sub_ao);
3081 CHKERR set_sub_data(global_indices);
3086 for (
auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3088 auto idx = (*dit)->getDofIdx();
3091 (*dit)->getPart(),
i++, global_indices[idx], local_indices[idx]);
3092 bool success = numered_dofs[s]->modify(dit, mod);
3095 "can not set negative indices");
3098 (*dit)->getPart(), -1, -1, -1);
3099 bool success = numered_dofs[s]->modify(dit, mod);
3102 "can not set negative indices");
3108 for (
auto dof : (*numered_dofs[s])) {
3109 if (dof->getDofIdx() >= 0 && dof->getPetscGlobalDofIdx() < 0) {
3111 "Negative global idx");
3119 *(nbdof_ptr[1]) = *(nbdof_ptr[0]);
3120 *(local_nbdof_ptr[1]) = *(local_nbdof_ptr[0]);
3121 *(ghost_nbdof_ptr[1]) = *(ghost_nbdof_ptr[0]);
3129 "WORLD", Sev::inform,
3130 "Removed DOFs from problem %s dofs [%d / %d (before %d / %d) global]",
3132 prb_ptr->
getNbDofsCol(), nb_init_row_dofs, nb_init_col_dofs);
3134 "Removed DOFs from problem %s dofs [ %d / %d "
3135 "(before %d / %d) local, %d / %d (before %d / %d)]",
3140 nb_init_ghost_col_dofs);
3147 const std::string problem_name,
const std::string
field_name,
3149 Range *ents_ptr,
const int lo_coeff,
const int hi_coeff,
const int lo_order,
3150 const int hi_order,
int verb,
const bool debug) {
3159 CHKERR bit_manager->filterEntitiesByRefLevel(bit_ref_level, bit_ref_mask,
3162 CHKERR bit_manager->getEntitiesByRefLevel(bit_ref_level, bit_ref_mask, ents,
3167 hi_coeff, lo_order, hi_order, verb,
debug);
3173 const std::string problem_name,
const std::string
field_name,
3175 Range *ents_ptr,
const int lo_coeff,
const int hi_coeff,
const int lo_order,
3176 const int hi_order,
int verb,
const bool debug) {
3185 CHKERR bit_manager->filterEntitiesByRefLevel(bit_ref_level, bit_ref_mask,
3188 CHKERR bit_manager->getEntitiesByRefLevel(bit_ref_level, bit_ref_mask, ents,
3193 lo_coeff, hi_coeff, lo_order,
3194 hi_order, verb,
debug);
3202 std::vector<unsigned char> &
marker)
const {
3208 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs;
3218 marker.resize(dofs->size(), 0);
3219 std::vector<unsigned char> marker_tmp;
3223 for (
auto p = ents.pair_begin();
p != ents.pair_end(); ++
p) {
3224 auto lo = dofs->get<
Ent_mi_tag>().lower_bound(
p->first);
3225 auto hi = dofs->get<
Ent_mi_tag>().upper_bound(
p->second);
3226 for (; lo != hi; ++lo)
3227 marker[(*lo)->getPetscLocalDofIdx()] |= 1;
3231 marker_tmp.resize(dofs->size(), 0);
3232 for (
auto p = ents.pair_begin();
p != ents.pair_end(); ++
p) {
3233 auto lo = dofs->get<
Ent_mi_tag>().lower_bound(
p->first);
3234 auto hi = dofs->get<
Ent_mi_tag>().upper_bound(
p->second);
3235 for (; lo != hi; ++lo)
3236 marker_tmp[(*lo)->getPetscLocalDofIdx()] = 1;
3238 for (
int i = 0;
i !=
marker.size(); ++
i) {
3250 const unsigned char c, std::vector<unsigned char> &
marker)
const {
3256 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs;
3266 marker.resize(dofs->size(), 0);
3273 auto marker_ref = [
marker](
auto &it) ->
unsigned int & {
3274 return marker[(*it)->getPetscLocalDofIdx()];
3279 for (; dof_lo != dof_hi; ++dof_lo)
3280 if ((*dof_lo)->getDofCoeffIdx() >= lo &&
3281 (*dof_lo)->getDofCoeffIdx() <= hi)
3282 marker[(*dof_lo)->getPetscLocalDofIdx()] |=
c;
3285 for (; dof_lo != dof_hi; ++dof_lo)
3286 if ((*dof_lo)->getDofCoeffIdx() >= lo &&
3287 (*dof_lo)->getDofCoeffIdx() <= hi)
3288 marker[(*dof_lo)->getPetscLocalDofIdx()] &=
c;
3297 const std::string row_field,
3298 const std::string col_field)
const {
3303 const auto problem_ptr = m_field.
get_problem(problem_name);
3304 auto get_field_id = [&](
const std::string
field_name) {
3307 const auto row_id = get_field_id(row_field);
3308 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)
static auto getFieldBitNumberFromUniqueId(const UId uid)
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.