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 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",
77 const Range &ents,
const int dim,
const int adj_dim,
const int n_parts,
78 Tag *th_vertex_weights, Tag *th_edge_weights, Tag *th_part_weights,
79 int verb,
const bool debug) {
81 .getInterface<CommInterface>()
82 ->partitionMesh(ents, dim, adj_dim, n_parts, th_vertex_weights,
83 th_edge_weights, th_part_weights, verb,
debug);
87 const bool square_matrix,
107 const bool square_matrix,
110 auto dofs_field_ptr = m_field.
get_dofs();
120 SETERRQ(PETSC_COMM_SELF, 1,
"problem <%s> refinement level not set",
121 problem_ptr->
getName().c_str());
129 auto make_rows_and_cols_view = [&](
auto &dofs_rows,
auto &dofs_cols) {
131 for (
auto it = ents_field_ptr->begin(); it != ents_field_ptr->end(); ++it) {
133 const auto uid = (*it)->getLocalUniqueId();
135 auto r = adjacencies_ptr->get<
Unique_mi_tag>().equal_range(uid);
136 for (
auto lo = r.first; lo != r.second; ++lo) {
138 if ((lo->getBitFEId() & problem_ptr->
getBitFEId()).any()) {
139 std::array<bool, 2> row_col = {
false,
false};
143 const BitRefLevel &fe_bit = lo->entFePtr->getBitRefLevel();
146 if ((fe_bit & prb_mask) != fe_bit)
148 if ((fe_bit & prb_bit).none())
151 auto add_to_view = [&](
auto &nb_dofs,
auto &view,
auto rc) {
152 auto dit = nb_dofs->lower_bound(uid);
153 decltype(dit) hi_dit;
154 if (dit != nb_dofs->end()) {
155 hi_dit = nb_dofs->upper_bound(
157 view.insert(dit, hi_dit);
162 if ((lo->entFePtr->getBitFieldIdRow() & (*it)->getId()).any())
163 add_to_view(dofs_field_ptr, dofs_rows,
ROW);
166 if ((lo->entFePtr->getBitFieldIdCol() & (*it)->getId()).any())
167 add_to_view(dofs_field_ptr, dofs_cols,
COL);
169 if (square_matrix && row_col[
ROW])
171 else if (row_col[
ROW] && row_col[
COL])
179 CHKERR make_rows_and_cols_view(dofs_rows, dofs_cols);
189 DofEntity_multiIndex_active_view::nth_index<0>::type::iterator miit,
191 hi_miit = dofs_rows.get<0>().end();
193 int count_dofs = dofs_rows.get<1>().count(
true);
194 boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array =
195 boost::shared_ptr<std::vector<NumeredDofEntity>>(
196 new std::vector<NumeredDofEntity>());
198 dofs_array->reserve(count_dofs);
199 miit = dofs_rows.get<0>().begin();
200 for (; miit != hi_miit; miit++) {
201 if ((*miit)->getActive()) {
202 dofs_array->emplace_back(*miit);
203 dofs_array->back().dofIdx = (problem_ptr->
nbDofsRow)++;
207 for (
auto &
v : *dofs_array) {
213 if (!square_matrix) {
220 DofEntity_multiIndex_active_view::nth_index<0>::type::iterator miit,
222 hi_miit = dofs_cols.get<0>().end();
225 miit = dofs_cols.get<0>().begin();
226 for (; miit != hi_miit; miit++) {
227 if (!(*miit)->getActive()) {
233 boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array =
234 boost::shared_ptr<std::vector<NumeredDofEntity>>(
235 new std::vector<NumeredDofEntity>());
237 dofs_array->reserve(count_dofs);
238 miit = dofs_cols.get<0>().begin();
239 for (; miit != hi_miit; miit++) {
240 if (!(*miit)->getActive()) {
243 dofs_array->emplace_back(*miit);
244 dofs_array->back().dofIdx = problem_ptr->
nbDofsCol++;
247 for (
auto &
v : *dofs_array) {
259 << problem_ptr->
getName() <<
" Nb. local dofs "
267 <<
"FEs row dofs " << *problem_ptr <<
" Nb. row dof "
273 <<
"FEs col dofs " << *problem_ptr <<
" Nb. col dof "
290 const std::string name,
const bool square_matrix,
int verb) {
304 square_matrix, verb);
313 Problem *problem_ptr,
const bool square_matrix,
int verb) {
317 auto dofs_field_ptr = m_field.
get_dofs();
328 "problem <%s> refinement level not set",
329 problem_ptr->
getName().c_str());
337 boost::shared_ptr<NumeredDofEntity_multiIndex>(
351 auto make_rows_and_cols_view = [&](
auto &dofs_rows,
auto &dofs_cols) {
355 for (
auto it = ents_field_ptr->begin(); it != ents_field_ptr->end();
358 const auto uid = (*it)->getLocalUniqueId();
360 auto r = adjacencies_ptr->get<
Unique_mi_tag>().equal_range(uid);
361 for (
auto lo = r.first; lo != r.second; ++lo) {
363 if ((lo->getBitFEId() & problem_ptr->
getBitFEId()).any()) {
364 std::array<bool, 2> row_col = {
false,
false};
366 const BitRefLevel &fe_bit = lo->entFePtr->getBitRefLevel();
369 if ((fe_bit & prb_bit).any() && (fe_bit & prb_mask) == fe_bit) {
371 auto add_to_view = [&](
auto dofs,
auto &view,
auto rc) {
372 auto dit = dofs->lower_bound(uid);
373 decltype(dit) hi_dit;
374 if (dit != dofs->end()) {
375 hi_dit = dofs->upper_bound(
377 view.insert(dit, hi_dit);
382 if ((lo->entFePtr->getBitFieldIdRow() & (*it)->getId()).any())
383 add_to_view(dofs_field_ptr, dofs_rows,
ROW);
386 if ((lo->entFePtr->getBitFieldIdCol() & (*it)->getId()).any())
387 add_to_view(dofs_field_ptr, dofs_cols,
COL);
389 if (square_matrix && row_col[
ROW])
391 else if (row_col[
ROW] && row_col[
COL])
400 CHKERR make_rows_and_cols_view(dofs_rows, dofs_cols);
408 for (
auto fit = fe_ptr->begin(); fit != fe_ptr->end(); fit++) {
409 if ((fit->get()->getId() & problem_ptr->
getBitFEId()).any()) {
410 fields_ids_row |= fit->get()->getBitFieldIdRow();
411 fields_ids_col |= fit->get()->getBitFieldIdCol();
415 for (
auto fit = fields_ptr->begin(); fit != fields_ptr->end(); fit++) {
416 if ((fit->get()->getId() & (fields_ids_row | fields_ids_col)).any()) {
420 auto hi_dit = dofs_field_ptr->get<
Unique_mi_tag>().upper_bound(
423 for (; dit != hi_dit; dit++) {
425 const int owner_proc = dit->get()->getOwnerProc();
427 const unsigned char pstatus = dit->get()->getPStatus();
433 const auto &dof_bit = (*dit)->getBitRefLevel();
435 if ((dof_bit & prb_bit).any() && (dof_bit & prb_mask) == dof_bit) {
437 if ((fit->get()->getId() & fields_ids_row).any()) {
438 dofs_rows.insert(*dit);
440 if (!square_matrix) {
441 if ((fit->get()->getId() & fields_ids_col).any()) {
442 dofs_cols.insert(*dit);
454 BitFieldId *fields_ids[2] = {&fields_ids_row, &fields_ids_col};
455 for (FiniteElement_multiIndex::iterator fit = fe_ptr->begin();
456 fit != fe_ptr->end(); fit++) {
457 if ((fit->get()->getId() & problem_ptr->
getBitFEId()).any()) {
458 fields_ids_row |= fit->get()->getBitFieldIdRow();
459 fields_ids_col |= fit->get()->getBitFieldIdCol();
464 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ++ss) {
465 DofEntity_multiIndex_active_view::nth_index<1>::type::iterator miit,
467 miit = dofs_ptr[ss]->get<1>().lower_bound(1);
468 hi_miit = dofs_ptr[ss]->get<1>().upper_bound(1);
469 Range ents_to_synchronise;
470 for (; miit != hi_miit; ++miit) {
471 if (miit->get()->getEntDofIdx() != 0)
473 ents_to_synchronise.insert(miit->get()->getEnt());
475 Range tmp_ents = ents_to_synchronise;
477 ents_to_synchronise,
nullptr, verb);
478 ents_to_synchronise = subtract(ents_to_synchronise, tmp_ents);
479 for (
auto fit = fields_ptr->begin(); fit != fields_ptr->end(); fit++) {
480 if ((fit->get()->getId() & *fields_ids[ss]).any()) {
481 const auto bit_number = (*fit)->getBitNumber();
482 for (Range::pair_iterator pit = ents_to_synchronise.pair_begin();
483 pit != ents_to_synchronise.pair_end(); ++pit) {
484 const auto f = pit->first;
485 const auto s = pit->second;
491 auto dit = dofs_field_ptr->get<
Unique_mi_tag>().lower_bound(lo_uid);
495 dofs_ptr[ss]->insert(dit, hi_dit);
504 boost::shared_ptr<NumeredDofEntity_multiIndex> numered_dofs_ptr[] = {
511 for (
int ss = 0; ss < 2; ss++) {
512 *(nbdof_ptr[ss]) = 0;
513 *(local_nbdof_ptr[ss]) = 0;
514 *(ghost_nbdof_ptr[ss]) = 0;
519 int nb_local_dofs[] = {0, 0};
520 for (
int ss = 0; ss < loop_size; ss++) {
521 DofEntity_multiIndex_active_view::nth_index<1>::type::iterator miit,
523 miit = dofs_ptr[ss]->get<1>().lower_bound(1);
524 hi_miit = dofs_ptr[ss]->get<1>().upper_bound(1);
525 for (; miit != hi_miit; miit++) {
526 int owner_proc = (*miit)->getOwnerProc();
534 int start_ranges[2], end_ranges[2];
535 for (
int ss = 0; ss != loop_size; ss++) {
538 CHKERR PetscLayoutSetBlockSize(layout, 1);
539 CHKERR PetscLayoutSetLocalSize(layout, nb_local_dofs[ss]);
540 CHKERR PetscLayoutSetUp(layout);
541 CHKERR PetscLayoutGetSize(layout, &*nbdof_ptr[ss]);
542 CHKERR PetscLayoutGetRange(layout, &start_ranges[ss], &end_ranges[ss]);
543 CHKERR PetscLayoutDestroy(&layout);
546 nbdof_ptr[1] = nbdof_ptr[0];
547 nb_local_dofs[1] = nb_local_dofs[0];
548 start_ranges[1] = start_ranges[0];
549 end_ranges[1] = end_ranges[0];
553 const size_t idx_data_type_size =
sizeof(
IdxDataType);
554 const size_t data_block_size = idx_data_type_size /
sizeof(int);
559 std::vector<std::vector<IdxDataType>> ids_data_packed_rows(
565 for (
int ss = 0; ss != loop_size; ++ss) {
567 DofEntity_multiIndex_active_view::nth_index<0>::type::iterator miit,
569 hi_miit = dofs_ptr[ss]->get<0>().end();
571 boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array =
572 boost::shared_ptr<std::vector<NumeredDofEntity>>(
573 new std::vector<NumeredDofEntity>());
574 int nb_dofs_to_add = 0;
575 miit = dofs_ptr[ss]->get<0>().begin();
576 for (; miit != hi_miit; ++miit) {
578 if (!(miit->get()->getActive()))
582 dofs_array->reserve(nb_dofs_to_add);
589 int &local_idx = *local_nbdof_ptr[ss];
590 miit = dofs_ptr[ss]->get<0>().begin();
591 for (; miit != hi_miit; ++miit) {
594 if (!(miit->get()->getActive()))
597 dofs_array->emplace_back(*miit);
599 int owner_proc = dofs_array->back().getOwnerProc();
600 if (owner_proc < 0) {
602 "data inconsistency");
606 dofs_array->back().pArt = owner_proc;
607 dofs_array->back().dofIdx = -1;
608 dofs_array->back().petscGloablDofIdx = -1;
609 dofs_array->back().petscLocalDofIdx = -1;
613 int glob_idx = start_ranges[ss] + local_idx;
614 dofs_array->back().pArt = owner_proc;
615 dofs_array->back().dofIdx = glob_idx;
616 dofs_array->back().petscGloablDofIdx = glob_idx;
617 dofs_array->back().petscLocalDofIdx = local_idx;
620 unsigned char pstatus = dofs_array->back().getPStatus();
626 proc < MAX_SHARING_PROCS &&
627 -1 != dofs_array->back().getSharingProcsPtr()[proc];
631 ids_data_packed_rows[dofs_array->back()
632 .getSharingProcsPtr()[proc]]
633 .emplace_back(dofs_array->back().getGlobalUniqueId(),
636 ids_data_packed_cols[dofs_array->back()
637 .getSharingProcsPtr()[proc]]
638 .emplace_back(dofs_array->back().getGlobalUniqueId(),
641 if (!(pstatus & PSTATUS_MULTISHARED)) {
649 auto hint = numered_dofs_ptr[ss]->end();
650 for (
auto &
v : *dofs_array)
651 hint = numered_dofs_ptr[ss]->emplace_hint(hint, dofs_array, &
v);
654 local_nbdof_ptr[1] = local_nbdof_ptr[0];
657 int nsends_rows = 0, nsends_cols = 0;
661 lengths_rows.clear();
662 lengths_cols.clear();
664 lengths_rows[proc] = ids_data_packed_rows[proc].size() * data_block_size;
665 lengths_cols[proc] = ids_data_packed_cols[proc].size() * data_block_size;
666 if (!ids_data_packed_rows[proc].empty())
668 if (!ids_data_packed_cols[proc].empty())
690 CHKERR PetscGatherNumberOfMessages(comm, NULL, &lengths_rows[0],
696 CHKERR PetscGatherMessageLengths(comm, nsends_rows, nrecvs_rows,
697 &lengths_rows[0], &onodes_rows,
705 CHKERR PetscCommGetNewTag(comm, &tag_row);
709 MPI_Request *r_waits_row;
714 CHKERR PetscPostIrecvInt(comm, tag_row, nrecvs_rows, onodes_rows,
715 olengths_rows, &rbuf_row, &r_waits_row);
716 CHKERR PetscFree(onodes_rows);
718 MPI_Request *s_waits_row;
719 CHKERR PetscMalloc1(nsends_rows, &s_waits_row);
722 for (
int proc = 0, kk = 0; proc < m_field.
get_comm_size(); proc++) {
723 if (!lengths_rows[proc])
725 CHKERR MPI_Isend(&(ids_data_packed_rows[proc])[0],
728 tag_row, comm, s_waits_row + kk);
733 CHKERR MPI_Waitall(nrecvs_rows, r_waits_row, status);
736 CHKERR MPI_Waitall(nsends_rows, s_waits_row, status);
739 CHKERR PetscFree(r_waits_row);
740 CHKERR PetscFree(s_waits_row);
744 int nrecvs_cols = nrecvs_rows;
745 int *olengths_cols = olengths_rows;
746 PetscInt **rbuf_col = rbuf_row;
747 if (!square_matrix) {
750 CHKERR PetscGatherNumberOfMessages(comm, NULL, &lengths_cols[0],
756 CHKERR PetscGatherMessageLengths(comm, nsends_cols, nrecvs_cols,
757 &lengths_cols[0], &onodes_cols,
762 CHKERR PetscCommGetNewTag(comm, &tag_col);
766 MPI_Request *r_waits_col;
767 CHKERR PetscPostIrecvInt(comm, tag_col, nrecvs_cols, onodes_cols,
768 olengths_cols, &rbuf_col, &r_waits_col);
769 CHKERR PetscFree(onodes_cols);
771 MPI_Request *s_waits_col;
772 CHKERR PetscMalloc1(nsends_cols, &s_waits_col);
775 for (
int proc = 0, kk = 0; proc < m_field.
get_comm_size(); proc++) {
776 if (!lengths_cols[proc])
778 CHKERR MPI_Isend(&(ids_data_packed_cols[proc])[0],
781 tag_col, comm, s_waits_col + kk);
786 CHKERR MPI_Waitall(nrecvs_cols, r_waits_col, status);
789 CHKERR MPI_Waitall(nsends_cols, s_waits_col, status);
792 CHKERR PetscFree(r_waits_col);
793 CHKERR PetscFree(s_waits_col);
796 CHKERR PetscCommDestroy(&comm);
800 auto hint = dofs_glob_uid_view.begin();
801 for (
auto dof : *m_field.
get_dofs())
802 dofs_glob_uid_view.emplace_hint(hint, dof);
805 for (
int ss = 0; ss != loop_size; ++ss) {
811 nrecvs = nrecvs_rows;
812 olengths = olengths_rows;
813 data_procs = rbuf_row;
815 nrecvs = nrecvs_cols;
816 olengths = olengths_cols;
817 data_procs = rbuf_col;
821 for (
int kk = 0; kk != nrecvs; ++kk) {
822 int len = olengths[kk];
823 int *data_from_proc = data_procs[kk];
824 for (
int dd = 0; dd < len; dd += data_block_size) {
826 auto ddit = dofs_glob_uid_view.find(uid);
830 PetscUnlikely(ddit == dofs_glob_uid_view.end())) {
835 <<
"DOF is shared or multishared between processors. For example "
836 "if order of field on given entity is set in inconsistently, "
837 "has different value on two processor, error such as this is "
840 MOFEM_LOG(
"SELF", Sev::error) <<
"UId " << uid <<
" is not found";
842 <<
"Problematic UId owner proc is " << owner_proc;
845 <<
"Problematic UId entity owning processor handle is "
846 << uid_handle <<
" entity type "
848 const auto uid_bit_number =
851 <<
"Problematic UId field is "
856 field_view.insert(ents_field_ptr->begin(), ents_field_ptr->end());
858 owner_proc, uid_bit_number, uid_handle));
859 if (fe_it == field_view.end()) {
861 <<
"Also, no field entity in database for given global UId";
863 MOFEM_LOG(
"SELF", Sev::error) <<
"Field entity in databse exist "
864 "(but have no DOF wih give UId";
865 MOFEM_LOG(
"SELF", Sev::error) << **fe_it;
868 auto error_file_name =
869 "error_with_missing_entity_" +
873 <<
"Look to file < " << error_file_name
874 <<
" > it contains entity with missing DOF.";
877 const auto local_fe_ent = (*fe_it)->getEnt();
878 CHKERR m_field.
get_moab().add_entities(*tmp_msh, &local_fe_ent, 1);
879 CHKERR m_field.
get_moab().write_file(error_file_name.c_str(),
"VTK",
880 "", tmp_msh->get_ptr(), 1);
885 "DOF with global UId not found (Compile code in Debug to "
886 "learn more about problem");
889 if (PetscUnlikely(ddit == dofs_glob_uid_view.end())) {
893 auto dit = numered_dofs_ptr[ss]->find((*ddit)->getLocalUniqueId());
895 if (dit != numered_dofs_ptr[ss]->end()) {
899 if (PetscUnlikely(global_idx < 0))
901 "received negative dof");
904 success = numered_dofs_ptr[ss]->modify(
908 if (PetscUnlikely(!success))
910 "modification unsuccessful");
912 success = numered_dofs_ptr[ss]->modify(
916 if (PetscUnlikely(!success))
918 "modification unsuccessful");
923 if (PetscUnlikely(ddit->get()->getPStatus() == 0)) {
930 std::ostringstream zz;
931 zz << **ddit << std::endl;
933 "data inconsistency, dofs is not shared, but received "
948 CHKERR PetscFree(olengths_rows);
949 CHKERR PetscFree(rbuf_row[0]);
950 CHKERR PetscFree(rbuf_row);
951 if (!square_matrix) {
952 CHKERR PetscFree(olengths_cols);
953 CHKERR PetscFree(rbuf_col[0]);
954 CHKERR PetscFree(rbuf_col);
958 if (numered_dofs_ptr[0]->size() != numered_dofs_ptr[1]->size()) {
960 "data inconsistency for square_matrix %ld!=%ld",
961 numered_dofs_ptr[0]->size(), numered_dofs_ptr[1]->size());
965 "data inconsistency for square_matrix");
978 const std::string out_name,
980 const std::vector<std::string> &fields_row,
981 const std::vector<std::string> &fields_col,
983 const std::string main_problem,
const bool square_matrix,
985 const map<std::string, boost::shared_ptr<Range>> *entityMapRow,
986 const map<std::string, boost::shared_ptr<Range>> *entityMapCol,
996 using ProblemByName =
decltype(problems_ptr->get<
Problem_mi_tag>());
997 auto &problems_by_name =
1001 auto out_problem_it = problems_by_name.find(out_name);
1002 if (out_problem_it == problems_by_name.end()) {
1004 "subproblem with name < %s > not defined (top tip check spelling)",
1009 auto main_problem_it = problems_by_name.find(main_problem);
1010 if (main_problem_it == problems_by_name.end()) {
1012 "problem of subproblem with name < %s > not defined (top tip "
1014 main_problem.c_str());
1018 boost::shared_ptr<NumeredDofEntity_multiIndex> out_problem_dofs[] = {
1019 out_problem_it->numeredRowDofsPtr, out_problem_it->numeredColDofsPtr};
1021 boost::shared_ptr<NumeredDofEntity_multiIndex> main_problem_dofs[] = {
1022 main_problem_it->numeredRowDofsPtr, main_problem_it->numeredColDofsPtr};
1024 int *nb_local_dofs[] = {&out_problem_it->nbLocDofsRow,
1025 &out_problem_it->nbLocDofsCol};
1027 int *nb_dofs[] = {&out_problem_it->nbDofsRow, &out_problem_it->nbDofsCol};
1031 out_problem_it->nbGhostDofsRow = 0;
1032 out_problem_it->nbGhostDofsCol = 0;
1036 std::vector<std::string> fields[] = {fields_row, fields_col};
1037 const map<std::string, boost::shared_ptr<Range>> *entityMap[] = {
1038 entityMapRow, entityMapCol};
1041 out_problem_it->subProblemData =
1042 boost::make_shared<Problem::SubProblemData>();
1045 for (
int ss = 0; ss != (square_matrix ? 1 : 2); ++ss) {
1048 (*nb_local_dofs[ss]) = 0;
1051 out_problem_dofs[ss]->clear();
1054 out_problem_it->numeredFiniteElementsPtr->clear();
1057 for (
auto field : fields[ss]) {
1063 boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array =
1064 boost::make_shared<std::vector<NumeredDofEntity>>();
1067 out_problem_it->getRowDofsSequence()->emplace_back(dofs_array);
1069 out_problem_it->getColDofsSequence()->emplace_back(dofs_array);
1074 auto add_dit_to_dofs_array = [&](
auto &dit) {
1075 if (dit->get()->getPetscGlobalDofIdx() >= 0)
1076 dofs_array->emplace_back(
1077 dit->get()->getDofEntityPtr(), dit->get()->getPetscGlobalDofIdx(),
1078 dit->get()->getPetscGlobalDofIdx(),
1079 dit->get()->getPetscLocalDofIdx(), dit->get()->getPart());
1082 auto get_dafult_dof_range = [&]() {
1083 auto dit = main_problem_dofs[ss]->get<
Unique_mi_tag>().lower_bound(
1085 auto hi_dit = main_problem_dofs[ss]->get<
Unique_mi_tag>().upper_bound(
1087 return std::make_pair(dit, hi_dit);
1090 auto check = [&](
auto &field) -> boost::shared_ptr<Range> {
1091 if (entityMap[ss]) {
1092 auto mit = entityMap[ss]->find(field);
1093 if (mit != entityMap[ss]->end()) {
1103 if (
auto r_ptr = check(field)) {
1104 for (
auto p = r_ptr->pair_begin(); p != r_ptr->pair_end(); ++p) {
1105 const auto lo_ent = p->first;
1106 const auto hi_ent = p->second;
1107 auto dit = main_problem_dofs[ss]->get<
Unique_mi_tag>().lower_bound(
1109 auto hi_dit = main_problem_dofs[ss]->get<
Unique_mi_tag>().upper_bound(
1111 dofs_array->reserve(std::distance(dit, hi_dit));
1112 for (; dit != hi_dit; dit++) {
1113 add_dit_to_dofs_array(dit);
1117 auto [dit, hi_dit] = get_dafult_dof_range();
1118 dofs_array->reserve(std::distance(dit, hi_dit));
1119 for (; dit != hi_dit; dit++)
1120 add_dit_to_dofs_array(dit);
1124 auto hint = out_problem_dofs[ss]->end();
1125 for (
auto &
v : *dofs_array)
1126 hint = out_problem_dofs[ss]->emplace_hint(hint, dofs_array, &
v);
1130 auto dit = out_problem_dofs[ss]->get<
Idx_mi_tag>().begin();
1131 auto hi_dit = out_problem_dofs[ss]->get<
Idx_mi_tag>().end();
1132 for (; dit != hi_dit; dit++) {
1134 if (dit->get()->getPart() == (
unsigned int)m_field.
get_comm_rank()) {
1135 idx = (*nb_local_dofs[ss])++;
1137 bool success = out_problem_dofs[ss]->modify(
1138 out_problem_dofs[ss]->project<0>(dit),
1142 "operation unsuccessful");
1152 out_problem_dofs[ss]->size());
1153 const int nb = std::distance(dit, hi_dit);
1155 std::vector<int> main_indices(nb);
1156 for (
auto it = main_indices.begin(); dit != hi_dit; dit++, it++) {
1157 *it = dit->get()->getPetscGlobalDofIdx();
1161 CHKERR ISCreateGeneral(m_field.
get_comm(), nb, &*main_indices.begin(),
1162 PETSC_USE_POINTER, &is);
1166 CHKERR AOCreateMappingIS(is, PETSC_NULLPTR, &ao);
1169 CHKERR ISDuplicate(is, &is_dup);
1174 CHKERR ISDuplicate(is, &is_dup);
1178 CHKERR AOApplicationToPetscIS(ao, is);
1180 CHKERR ISGetSize(is, nb_dofs[ss]);
1184 for (std::vector<int>::iterator it = main_indices.begin(); dit != hi_dit;
1186 bool success = out_problem_dofs[ss]->modify(
1187 out_problem_dofs[ss]->project<0>(dit),
1189 dit->get()->getPart(), *it, *it,
1190 dit->get()->getPetscLocalDofIdx()));
1193 "operation unsuccessful");
1198 NumeredDofEntityByLocalIdx::iterator dit =
1200 NumeredDofEntityByLocalIdx::iterator hi_dit =
1202 const int nb = std::distance(dit, hi_dit);
1203 std::vector<int> main_indices_non_local(nb);
1204 for (
auto it = main_indices_non_local.begin(); dit != hi_dit;
1206 *it = dit->get()->getPetscGlobalDofIdx();
1210 &*main_indices_non_local.begin(),
1211 PETSC_USE_POINTER, &is);
1212 CHKERR AOApplicationToPetscIS(ao, is);
1215 for (
auto it = main_indices_non_local.begin(); dit != hi_dit;
1217 bool success = out_problem_dofs[ss]->modify(
1218 out_problem_dofs[ss]->project<0>(dit),
1220 dit->get()->getPart(), dit->get()->getDofIdx(), *it,
1221 dit->get()->getPetscLocalDofIdx()));
1224 "operation unsuccessful");
1232 if (square_matrix) {
1233 out_problem_it->numeredColDofsPtr = out_problem_it->numeredRowDofsPtr;
1234 out_problem_it->nbLocDofsCol = out_problem_it->nbLocDofsRow;
1235 out_problem_it->nbDofsCol = out_problem_it->nbDofsRow;
1236 out_problem_it->getSubData()->colIs = out_problem_it->getSubData()->rowIs;
1237 out_problem_it->getSubData()->colMap = out_problem_it->getSubData()->rowMap;
1247 const std::string out_name,
const std::vector<std::string> add_row_problems,
1248 const std::vector<std::string> add_col_problems,
const bool square_matrix,
1262 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemByName;
1263 ProblemByName &problems_by_name =
1264 const_cast<ProblemByName &
>(problems_ptr->get<
Problem_mi_tag>());
1267 ProblemByName::iterator out_problem_it = problems_by_name.find(out_name);
1268 if (out_problem_it == problems_by_name.end()) {
1270 "problem with name < %s > not defined (top tip check spelling)",
1274 out_problem_it->composedProblemsData =
1275 boost::make_shared<ComposedProblemsData>();
1276 boost::shared_ptr<ComposedProblemsData> cmp_prb_data =
1277 out_problem_it->getComposedProblemsData();
1279 const std::vector<std::string> *add_prb[] = {&add_row_problems,
1281 std::vector<const Problem *> *add_prb_ptr[] = {&cmp_prb_data->rowProblemsAdd,
1282 &cmp_prb_data->colProblemsAdd};
1283 std::vector<SmartPetscObj<IS>> *add_prb_is[] = {&cmp_prb_data->rowIs,
1284 &cmp_prb_data->colIs};
1287 int *nb_local_dofs[] = {&out_problem_it->nbLocDofsRow,
1288 &out_problem_it->nbLocDofsCol};
1290 int *nb_dofs[] = {&out_problem_it->nbDofsRow, &out_problem_it->nbDofsCol};
1294 out_problem_it->nbDofsRow = 0;
1295 out_problem_it->nbDofsCol = 0;
1296 out_problem_it->nbLocDofsRow = 0;
1297 out_problem_it->nbLocDofsCol = 0;
1298 out_problem_it->nbGhostDofsRow = 0;
1299 out_problem_it->nbGhostDofsCol = 0;
1301 int nb_dofs_reserve[] = {0, 0};
1304 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1305 add_prb_ptr[ss]->reserve(add_prb[ss]->size());
1306 add_prb_is[ss]->reserve(add_prb[ss]->size());
1307 for (std::vector<std::string>::const_iterator vit = add_prb[ss]->begin();
1308 vit != add_prb[ss]->end(); vit++) {
1309 ProblemByName::iterator prb_it = problems_by_name.find(*vit);
1310 if (prb_it == problems_by_name.end()) {
1313 "problem with name < %s > not defined (top tip check spelling)",
1316 add_prb_ptr[ss]->push_back(&*prb_it);
1320 *nb_dofs[ss] += add_prb_ptr[ss]->back()->getNbDofsRow();
1321 *nb_local_dofs[ss] += add_prb_ptr[ss]->back()->getNbLocalDofsRow();
1322 nb_dofs_reserve[ss] +=
1323 add_prb_ptr[ss]->back()->numeredRowDofsPtr->size();
1326 *nb_dofs[ss] += add_prb_ptr[ss]->back()->getNbDofsCol();
1327 *nb_local_dofs[ss] += add_prb_ptr[ss]->back()->getNbLocalDofsCol();
1328 nb_dofs_reserve[ss] +=
1329 add_prb_ptr[ss]->back()->numeredColDofsPtr->size();
1334 if (square_matrix) {
1335 add_prb_ptr[1]->reserve(add_prb_ptr[0]->size());
1336 add_prb_is[1]->reserve(add_prb_ptr[0]->size());
1337 out_problem_it->numeredColDofsPtr = out_problem_it->numeredRowDofsPtr;
1338 *nb_dofs[1] = *nb_dofs[0];
1339 *nb_local_dofs[1] = *nb_local_dofs[0];
1343 boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array[2];
1345 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1346 dofs_array[ss] = boost::make_shared<std::vector<NumeredDofEntity>>();
1347 dofs_array[ss]->reserve(nb_dofs_reserve[ss]);
1349 out_problem_it->getRowDofsSequence()->emplace_back(dofs_array[ss]);
1351 out_problem_it->getColDofsSequence()->emplace_back(dofs_array[ss]);
1355 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1356 NumeredDofEntity_multiIndex::index<PetscGlobalIdx_mi_tag>::type::iterator
1361 for (
unsigned int pp = 0; pp != add_prb_ptr[ss]->size(); pp++) {
1362 PetscInt *dofs_out_idx_ptr;
1363 int nb_local_dofs = (*add_prb_ptr[ss])[pp]->getNbLocalDofsRow();
1364 CHKERR PetscMalloc(nb_local_dofs *
sizeof(
int), &dofs_out_idx_ptr);
1366 dit = (*add_prb_ptr[ss])[pp]
1369 hi_dit = (*add_prb_ptr[ss])[pp]
1373 dit = (*add_prb_ptr[ss])[pp]
1376 hi_dit = (*add_prb_ptr[ss])[pp]
1381 for (; dit != hi_dit; dit++) {
1382 const BitRefLevel &prb_bit = out_problem_it->getBitRefLevel();
1383 const BitRefLevel &prb_mask = out_problem_it->getBitRefLevelMask();
1384 const BitRefLevel &dof_bit = dit->get()->getBitRefLevel();
1385 if ((dof_bit & prb_bit).none() || ((dof_bit & prb_mask) != dof_bit))
1388 const int part = dit->get()->getPart();
1389 const int glob_idx = shift_glob + dit->get()->getPetscGlobalDofIdx();
1391 (part == rank) ? (shift_loc + dit->get()->getPetscLocalDofIdx())
1393 dofs_array[ss]->emplace_back(dit->get()->getDofEntityPtr(), glob_idx,
1394 glob_idx, loc_idx, part);
1396 dofs_out_idx_ptr[is_nb++] = glob_idx;
1399 if (is_nb > nb_local_dofs) {
1401 "Data inconsistency");
1404 CHKERR ISCreateGeneral(m_field.
get_comm(), is_nb, dofs_out_idx_ptr,
1405 PETSC_OWN_POINTER, &is);
1407 (*add_prb_is[ss]).push_back(smart_is);
1409 shift_glob += (*add_prb_ptr[ss])[pp]->getNbDofsRow();
1410 shift_loc += (*add_prb_ptr[ss])[pp]->getNbLocalDofsRow();
1412 shift_glob += (*add_prb_ptr[ss])[pp]->getNbDofsCol();
1413 shift_loc += (*add_prb_ptr[ss])[pp]->getNbLocalDofsCol();
1415 if (square_matrix) {
1416 (*add_prb_ptr[1]).push_back((*add_prb_ptr[0])[pp]);
1417 (*add_prb_is[1]).push_back(smart_is);
1422 if ((*add_prb_is[1]).size() != (*add_prb_is[0]).size()) {
1427 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1428 auto hint = (ss == 0) ? out_problem_it->numeredRowDofsPtr->end()
1429 : out_problem_it->numeredColDofsPtr->end();
1430 for (
auto &
v : *dofs_array[ss])
1431 hint = (ss == 0) ? out_problem_it->numeredRowDofsPtr->emplace_hint(
1432 hint, dofs_array[ss], &
v)
1433 : out_problem_it->numeredColDofsPtr->emplace_hint(
1434 hint, dofs_array[ss], &
v);
1440 *nb_local_dofs[0] = 0;
1441 *nb_local_dofs[1] = 0;
1442 for (
int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1444 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs_ptr;
1446 dofs_ptr = out_problem_it->numeredRowDofsPtr;
1448 dofs_ptr = out_problem_it->numeredColDofsPtr;
1450 NumeredDofEntityByUId::iterator dit, hi_dit;
1453 std::vector<int> idx;
1454 idx.reserve(std::distance(dit, hi_dit));
1456 for (; dit != hi_dit; dit++) {
1457 if (dit->get()->getPart() == (
unsigned int)m_field.
get_comm_rank()) {
1462 "modification unsuccessful");
1464 idx.push_back(dit->get()->getPetscGlobalDofIdx());
1466 if (dit->get()->getPetscLocalDofIdx() != -1) {
1468 "local index should be negative");
1472 if (square_matrix) {
1473 *nb_local_dofs[1] = *nb_local_dofs[0];
1478 CHKERR ISCreateGeneral(m_field.
get_comm(), idx.size(), &*idx.begin(),
1479 PETSC_USE_POINTER, &is);
1480 CHKERR ISGetSize(is, nb_dofs[ss]);
1481 if (square_matrix) {
1482 *nb_dofs[1] = *nb_dofs[0];
1486 CHKERR AOCreateMappingIS(is, PETSC_NULLPTR, &ao);
1487 for (
unsigned int pp = 0; pp != (*add_prb_is[ss]).size(); pp++)
1488 CHKERR AOApplicationToPetscIS(ao, (*add_prb_is[ss])[pp]);
1492 std::vector<int> idx_new;
1493 idx_new.reserve(dofs_ptr->size());
1494 for (NumeredDofEntityByUId::iterator dit =
1497 idx_new.push_back(dit->get()->getPetscGlobalDofIdx());
1502 &*idx_new.begin(), PETSC_USE_POINTER, &is_new);
1503 CHKERR AOApplicationToPetscIS(ao, is_new);
1505 std::vector<int>::iterator vit = idx_new.begin();
1506 for (NumeredDofEntityByUId::iterator dit =
1511 dit->get()->getPart(), *(vit++)));
1514 "modification unsuccessful");
1517 CHKERR ISDestroy(&is_new);
1548 MOFEM_LOG(
"WORLD", Sev::verbose) <<
"Simple partition problem " << name;
1551 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemByName;
1552 ProblemByName &problems_set =
1553 const_cast<ProblemByName &
>(problems_ptr->get<
Problem_mi_tag>());
1554 ProblemByName::iterator p_miit = problems_set.find(name);
1555 if (p_miit == problems_set.end()) {
1556 SETERRQ(PETSC_COMM_SELF, 1,
1557 "problem < %s > is not found (top tip: check spelling)",
1562 NumeredDofEntitysByIdx &dofs_row_by_idx =
1563 p_miit->numeredRowDofsPtr->get<
Idx_mi_tag>();
1564 NumeredDofEntitysByIdx &dofs_col_by_idx =
1565 p_miit->numeredColDofsPtr->get<
Idx_mi_tag>();
1572 DofIdx &nb_row_local_dofs = p_miit->nbLocDofsRow;
1573 DofIdx &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
1574 nb_row_local_dofs = 0;
1575 nb_row_ghost_dofs = 0;
1576 DofIdx &nb_col_local_dofs = p_miit->nbLocDofsCol;
1577 DofIdx &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
1578 nb_col_local_dofs = 0;
1579 nb_col_ghost_dofs = 0;
1581 bool square_matrix =
false;
1582 if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr) {
1583 square_matrix =
true;
1587 PetscLayout layout_row;
1588 const int *ranges_row;
1590 DofIdx nb_dofs_row = dofs_row_by_idx.size();
1592 CHKERR PetscLayoutSetBlockSize(layout_row, 1);
1593 CHKERR PetscLayoutSetSize(layout_row, nb_dofs_row);
1594 CHKERR PetscLayoutSetUp(layout_row);
1595 CHKERR PetscLayoutGetRanges(layout_row, &ranges_row);
1597 PetscLayout layout_col;
1598 const int *ranges_col;
1599 if (!square_matrix) {
1600 DofIdx nb_dofs_col = dofs_col_by_idx.size();
1602 CHKERR PetscLayoutSetBlockSize(layout_col, 1);
1603 CHKERR PetscLayoutSetSize(layout_col, nb_dofs_col);
1604 CHKERR PetscLayoutSetUp(layout_col);
1605 CHKERR PetscLayoutGetRanges(layout_col, &ranges_col);
1607 for (
unsigned int part = 0; part < (
unsigned int)m_field.
get_comm_size();
1609 miit_row = dofs_row_by_idx.lower_bound(ranges_row[part]);
1610 hi_miit_row = dofs_row_by_idx.lower_bound(ranges_row[part + 1]);
1611 if (std::distance(miit_row, hi_miit_row) !=
1612 ranges_row[part + 1] - ranges_row[part]) {
1614 PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1615 "data inconsistency, std::distance(miit_row,hi_miit_row) != rend - "
1616 "rstart (%ld != %d - %d = %d) ",
1617 std::distance(miit_row, hi_miit_row), ranges_row[part + 1],
1618 ranges_row[part], ranges_row[part + 1] - ranges_row[part]);
1621 for (; miit_row != hi_miit_row; miit_row++) {
1622 bool success = dofs_row_by_idx.modify(
1627 "modification unsuccessful");
1629 success = dofs_row_by_idx.modify(
1633 "modification unsuccessful");
1636 if (!square_matrix) {
1637 miit_col = dofs_col_by_idx.lower_bound(ranges_col[part]);
1638 hi_miit_col = dofs_col_by_idx.lower_bound(ranges_col[part + 1]);
1639 if (std::distance(miit_col, hi_miit_col) !=
1640 ranges_col[part + 1] - ranges_col[part]) {
1641 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1642 "data inconsistency, std::distance(miit_col,hi_miit_col) != "
1644 "rstart (%ld != %d - %d = %d) ",
1645 std::distance(miit_col, hi_miit_col), ranges_col[part + 1],
1646 ranges_col[part], ranges_col[part + 1] - ranges_col[part]);
1649 for (; miit_col != hi_miit_col; miit_col++) {
1650 bool success = dofs_col_by_idx.modify(
1652 part, (*miit_col)->dofIdx));
1655 "modification unsuccessful");
1657 success = dofs_col_by_idx.modify(
1661 "modification unsuccessful");
1666 CHKERR PetscLayoutDestroy(&layout_row);
1667 if (!square_matrix) {
1668 CHKERR PetscLayoutDestroy(&layout_col);
1670 if (square_matrix) {
1671 nb_col_local_dofs = nb_row_local_dofs;
1672 nb_col_ghost_dofs = nb_row_ghost_dofs;
1685 MOFEM_LOG(
"WORLD", Sev::noisy) <<
"Partition problem " << name;
1687 using NumeredDofEntitysByIdx =
1688 NumeredDofEntity_multiIndex::index<Idx_mi_tag>::type;
1689 using ProblemsByName = Problem_multiIndex::index<Problem_mi_tag>::type;
1692 auto &problems_set =
1693 const_cast<ProblemsByName &
>(problems_ptr->get<
Problem_mi_tag>());
1694 auto p_miit = problems_set.find(name);
1695 if (p_miit == problems_set.end()) {
1697 "problem with name %s not defined (top tip check spelling)",
1700 int nb_dofs_row = p_miit->getNbDofsRow();
1710 "entFEAdjacencies not build");
1716 ->createMPIAdjWithArrays<Idx_mi_tag>(name, &Adj, verb);
1721 MatView(Adj, PETSC_VIEWER_STDOUT_WORLD);
1724 MatPartitioning part;
1727 CHKERR MatPartitioningSetAdjacency(part, Adj);
1728 CHKERR MatPartitioningSetFromOptions(part);
1730 CHKERR MatPartitioningApply(part, &is);
1732 ISView(is, PETSC_VIEWER_STDOUT_WORLD);
1735 IS is_gather, is_num, is_gather_num;
1736 CHKERR ISAllGather(is, &is_gather);
1737 CHKERR ISPartitioningToNumbering(is, &is_num);
1738 CHKERR ISAllGather(is_num, &is_gather_num);
1739 const int *part_number, *petsc_idx;
1740 CHKERR ISGetIndices(is_gather, &part_number);
1741 CHKERR ISGetIndices(is_gather_num, &petsc_idx);
1742 int size_is_num, size_is_gather;
1743 CHKERR ISGetSize(is_gather, &size_is_gather);
1744 if (size_is_gather != (
int)nb_dofs_row)
1745 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1746 "data inconsistency %d != %d", size_is_gather, nb_dofs_row);
1748 CHKERR ISGetSize(is_num, &size_is_num);
1749 if (size_is_num != (
int)nb_dofs_row)
1750 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1751 "data inconsistency %d != %d", size_is_num, nb_dofs_row);
1753 bool square_matrix =
false;
1754 if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr)
1755 square_matrix =
true;
1782 auto number_dofs = [&](
auto &dofs_idx,
auto &counter) {
1784 for (
auto miit_dofs_row = dofs_idx.begin();
1785 miit_dofs_row != dofs_idx.end(); miit_dofs_row++) {
1786 const int part = part_number[(*miit_dofs_row)->dofIdx];
1788 const bool success = dofs_idx.modify(
1791 part, petsc_idx[(*miit_dofs_row)->dofIdx], counter++));
1794 "modification unsuccessful");
1797 const bool success = dofs_idx.modify(
1799 part, petsc_idx[(*miit_dofs_row)->dofIdx]));
1802 "modification unsuccessful");
1810 auto &dofs_row_by_idx_no_const =
const_cast<NumeredDofEntitysByIdx &
>(
1811 p_miit->numeredRowDofsPtr->get<
Idx_mi_tag>());
1812 int &nb_row_local_dofs = p_miit->nbLocDofsRow;
1813 int &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
1814 nb_row_local_dofs = 0;
1815 nb_row_ghost_dofs = 0;
1817 CHKERR number_dofs(dofs_row_by_idx_no_const, nb_row_local_dofs);
1819 int &nb_col_local_dofs = p_miit->nbLocDofsCol;
1820 int &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
1821 if (square_matrix) {
1822 nb_col_local_dofs = nb_row_local_dofs;
1823 nb_col_ghost_dofs = nb_row_ghost_dofs;
1825 NumeredDofEntitysByIdx &dofs_col_by_idx_no_const =
1826 const_cast<NumeredDofEntitysByIdx &
>(
1827 p_miit->numeredColDofsPtr->get<
Idx_mi_tag>());
1828 nb_col_local_dofs = 0;
1829 nb_col_ghost_dofs = 0;
1830 CHKERR number_dofs(dofs_col_by_idx_no_const, nb_col_local_dofs);
1833 CHKERR ISRestoreIndices(is_gather, &part_number);
1834 CHKERR ISRestoreIndices(is_gather_num, &petsc_idx);
1835 CHKERR ISDestroy(&is_num);
1836 CHKERR ISDestroy(&is_gather_num);
1837 CHKERR ISDestroy(&is_gather);
1839 CHKERR MatPartitioningDestroy(&part);
1844 auto number_dofs = [&](
auto &dof_idx,
auto &counter) {
1846 for (
auto miit_dofs_row = dof_idx.begin(); miit_dofs_row != dof_idx.end();
1848 const bool success = dof_idx.modify(
1854 "modification unsuccessful");
1860 auto &dofs_row_by_idx_no_const =
const_cast<NumeredDofEntitysByIdx &
>(
1861 p_miit->numeredRowDofsPtr->get<
Idx_mi_tag>());
1862 int &nb_row_local_dofs = p_miit->nbLocDofsRow;
1863 int &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
1864 nb_row_local_dofs = 0;
1865 nb_row_ghost_dofs = 0;
1867 CHKERR number_dofs(dofs_row_by_idx_no_const, nb_row_local_dofs);
1869 bool square_matrix =
false;
1870 if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr)
1871 square_matrix =
true;
1873 int &nb_col_local_dofs = p_miit->nbLocDofsCol;
1874 int &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
1875 if (square_matrix) {
1876 nb_col_local_dofs = nb_row_local_dofs;
1877 nb_col_ghost_dofs = nb_row_ghost_dofs;
1879 NumeredDofEntitysByIdx &dofs_col_by_idx_no_const =
1880 const_cast<NumeredDofEntitysByIdx &
>(
1881 p_miit->numeredColDofsPtr->get<
Idx_mi_tag>());
1882 nb_col_local_dofs = 0;
1883 nb_col_ghost_dofs = 0;
1884 CHKERR number_dofs(dofs_col_by_idx_no_const, nb_col_local_dofs);
1893 const std::string name,
const std::string problem_for_rows,
bool copy_rows,
1894 const std::string problem_for_cols,
bool copy_cols,
int verb) {
1902 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemByName;
1905 ProblemByName &problems_by_name =
1906 const_cast<ProblemByName &
>(problems_ptr->get<
Problem_mi_tag>());
1907 ProblemByName::iterator p_miit = problems_by_name.find(name);
1908 if (p_miit == problems_by_name.end()) {
1910 "problem with name < %s > not defined (top tip check spelling)",
1915 << p_miit->getName() <<
" from rows of " << problem_for_rows
1916 <<
" and columns of " << problem_for_cols;
1919 ProblemByName::iterator p_miit_row = problems_by_name.find(problem_for_rows);
1920 if (p_miit_row == problems_by_name.end()) {
1922 "problem with name < %s > not defined (top tip check spelling)",
1923 problem_for_rows.c_str());
1925 const boost::shared_ptr<NumeredDofEntity_multiIndex> dofs_row =
1926 p_miit_row->numeredRowDofsPtr;
1929 ProblemByName::iterator p_miit_col = problems_by_name.find(problem_for_cols);
1930 if (p_miit_col == problems_by_name.end()) {
1932 "problem with name < %s > not defined (top tip check spelling)",
1933 problem_for_cols.c_str());
1935 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs_col =
1936 p_miit_col->numeredColDofsPtr;
1938 bool copy[] = {copy_rows, copy_cols};
1939 boost::shared_ptr<NumeredDofEntity_multiIndex> composed_dofs[] = {
1940 p_miit->numeredRowDofsPtr, p_miit->numeredColDofsPtr};
1942 int *nb_local_dofs[] = {&p_miit->nbLocDofsRow, &p_miit->nbLocDofsCol};
1943 int *nb_dofs[] = {&p_miit->nbDofsRow, &p_miit->nbDofsCol};
1944 boost::shared_ptr<NumeredDofEntity_multiIndex> copied_dofs[] = {dofs_row,
1947 for (
int ss = 0; ss < 2; ss++) {
1950 *nb_local_dofs[ss] = 0;
1954 std::vector<int> is_local, is_new;
1958 for (NumeredDofEntity_multiIndex::iterator dit =
1959 composed_dofs[ss]->begin();
1960 dit != composed_dofs[ss]->end(); dit++) {
1961 NumeredDofEntityByUId::iterator diit =
1962 dofs_by_uid.find((*dit)->getLocalUniqueId());
1963 if (diit == dofs_by_uid.end()) {
1966 "data inconsistency, could not find dof in composite problem");
1968 int part_number = (*diit)->getPart();
1969 int petsc_global_dof = (*diit)->getPetscGlobalDofIdx();
1971 success = composed_dofs[ss]->modify(
1976 "modification unsuccessful");
1978 if ((*dit)->getPart() == (
unsigned int)m_field.
get_comm_rank()) {
1979 success = composed_dofs[ss]->modify(
1983 "modification unsuccessful");
1985 is_local.push_back(petsc_global_dof);
1990 CHKERR AOCreateMapping(m_field.
get_comm(), is_local.size(), &is_local[0],
1995 for (NumeredDofEntity_multiIndex::iterator dit =
1996 composed_dofs[ss]->begin();
1997 dit != composed_dofs[ss]->end(); dit++) {
1998 is_local.push_back((*dit)->getPetscGlobalDofIdx());
2000 CHKERR AOPetscToApplication(ao, is_local.size(), &is_local[0]);
2002 for (NumeredDofEntity_multiIndex::iterator dit =
2003 composed_dofs[ss]->begin();
2004 dit != composed_dofs[ss]->end(); dit++) {
2005 int part_number = (*dit)->getPart();
2006 int petsc_global_dof = is_local[idx2++];
2008 success = composed_dofs[ss]->modify(
2013 "modification unsuccessful");
2021 for (NumeredDofEntity_multiIndex::iterator dit = copied_dofs[ss]->begin();
2022 dit != copied_dofs[ss]->end(); dit++) {
2023 std::pair<NumeredDofEntity_multiIndex::iterator, bool> p;
2024 p = composed_dofs[ss]->insert(boost::shared_ptr<NumeredDofEntity>(
2029 int dof_idx = (*dit)->getDofIdx();
2030 int part_number = (*dit)->getPart();
2031 int petsc_global_dof = (*dit)->getPetscGlobalDofIdx();
2033 const bool success = composed_dofs[ss]->modify(
2035 part_number, dof_idx, petsc_global_dof,
2036 (*nb_local_dofs[ss])++));
2039 "modification unsuccessful");
2042 const bool success = composed_dofs[ss]->modify(
2044 part_number, dof_idx, petsc_global_dof));
2047 "modification unsuccessful");
2068 << problem_ptr->
getName() <<
" Nb. local dof "
2084 auto save_ent = [](moab::Interface &moab,
const std::string name,
2088 CHKERR moab.create_meshset(MESHSET_SET, out_meshset);
2089 CHKERR moab.add_entities(out_meshset, &ent, 1);
2090 CHKERR moab.write_file(name.c_str(),
"VTK",
"", &out_meshset, 1);
2091 CHKERR moab.delete_entities(&out_meshset, 1);
2097 typedef NumeredDofEntity_multiIndex::index<Idx_mi_tag>::type
2098 NumeredDofEntitysByIdx;
2099 NumeredDofEntitysByIdx::iterator dit, hi_dit;
2100 const NumeredDofEntitysByIdx *numered_dofs_ptr[] = {
2108 for (
int ss = 0; ss < 2; ss++) {
2110 dit = numered_dofs_ptr[ss]->begin();
2111 hi_dit = numered_dofs_ptr[ss]->end();
2112 for (; dit != hi_dit; dit++) {
2113 if ((*dit)->getPart() == (
unsigned int)m_field.
get_comm_rank()) {
2114 if ((*dit)->getPetscLocalDofIdx() < 0) {
2115 std::ostringstream zz;
2118 "local dof index for %d (0-row, 1-col) not set, i.e. has "
2119 "negative value\n %s",
2120 ss, zz.str().c_str());
2122 if ((*dit)->getPetscLocalDofIdx() >= *local_nbdof_ptr[ss]) {
2123 std::ostringstream zz;
2126 "local dofs for %d (0-row, 1-col) out of range\n %s", ss,
2130 if ((*dit)->getPetscGlobalDofIdx() < 0) {
2137 "_negative_global_index.vtk",
2140 std::ostringstream zz;
2142 << dit->get()->getBitRefLevel() <<
" " << **dit;
2144 "global dof index for %d (0-row, 1-col) row not set, i.e. "
2145 "has negative value\n %s",
2146 ss, zz.str().c_str());
2148 if ((*dit)->getPetscGlobalDofIdx() >= *nbdof_ptr[ss]) {
2149 std::ostringstream zz;
2151 << *nbdof_ptr[ss] <<
" " << **dit;
2153 "global dofs for %d (0-row, 1-col) out of range\n %s", ss,
2164 bool part_from_moab,
2166 int hi_proc,
int verb) {
2180 "adjacencies not build");
2187 "problem not partitioned");
2195 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemByName;
2197 const_cast<ProblemByName &
>(problems_ptr->get<
Problem_mi_tag>());
2198 ProblemByName::iterator p_miit = problems.find(name);
2199 if (p_miit == problems.end()) {
2201 "problem < %s > not found (top tip: check spelling)",
2207 *p_miit->numeredFiniteElementsPtr;
2210 problem_finite_elements.clear();
2214 bool do_cols_prob =
true;
2215 if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr) {
2216 do_cols_prob =
false;
2219 auto get_good_elems = [&]() {
2220 auto good_elems = std::vector<
decltype(fe_ent_ptr->begin())>();
2221 good_elems.reserve(fe_ent_ptr->size());
2223 const auto prb_bit = p_miit->getBitRefLevel();
2224 const auto prb_mask = p_miit->getBitRefLevelMask();
2228 for (
auto efit = fe_ent_ptr->begin(); efit != fe_ent_ptr->end(); ++efit) {
2231 if (((*efit)->getId() & p_miit->getBitFEId()).any()) {
2233 const auto &fe_bit = (*efit)->getBitRefLevel();
2236 if ((fe_bit & prb_mask) == fe_bit && (fe_bit & prb_bit).any())
2237 good_elems.emplace_back(efit);
2244 auto good_elems = get_good_elems();
2246 auto numbered_good_elems_ptr =
2247 boost::make_shared<std::vector<NumeredEntFiniteElement>>();
2248 numbered_good_elems_ptr->reserve(good_elems.size());
2249 for (
auto &efit : good_elems)
2252 if (!do_cols_prob) {
2253 for (
auto &fe : *numbered_good_elems_ptr) {
2254 if (fe.sPtr->getRowFieldEntsPtr() == fe.sPtr->getColFieldEntsPtr()) {
2255 fe.getColFieldEntsPtr() = fe.getRowFieldEntsPtr();
2260 if (part_from_moab) {
2261 for (
auto &fe : *numbered_good_elems_ptr) {
2262 if (fe.getEntType() == MBENTITYSET) {
2266 int proc = fe.getPartProc();
2267 if (proc == -1 && fe.getEntType() == MBVERTEX)
2268 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) {
2280 if (fe.getEntType() == MBENTITYSET) {
2284 for (
auto &dof_ptr : rows_view)
2285 parts[dof_ptr->pArt]++;
2286 std::vector<int>::iterator pos =
2287 max_element(parts.begin(), parts.end());
2288 const auto max_part = std::distance(parts.begin(), pos);
2294 for (
auto &fe : *numbered_good_elems_ptr) {
2296 auto check_fields_and_dofs = [&]() {
2297 if (!part_from_moab) {
2298 if (fe.getBitFieldIdRow().none() && m_field.
get_comm_size() == 0) {
2300 <<
"At least one field has to be added to element row to "
2301 "determine partition of finite element. Check element " +
2302 boost::lexical_cast<std::string>(fe.getName());
2309 if (check_fields_and_dofs()) {
2311 auto p = problem_finite_elements.insert(
2312 boost::shared_ptr<NumeredEntFiniteElement>(numbered_good_elems_ptr,
2320 auto elements_on_rank =
2321 problem_finite_elements.get<
Part_mi_tag>().equal_range(
2324 << p_miit->getName() <<
" nb. elems "
2325 << std::distance(elements_on_rank.first, elements_on_rank.second);
2327 for (
auto &fe : *fe_ptr) {
2333 <<
"Element " << fe->getName() <<
" nb. elems "
2334 << std::distance(e_range.first, e_range.second);
2352 "partition of problem not build");
2355 "partitions finite elements not build");
2364 int &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
2365 int &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
2366 nb_row_ghost_dofs = 0;
2367 nb_col_ghost_dofs = 0;
2377 p_miit->numeredFiniteElementsPtr->get<
Part_mi_tag>().equal_range(
2383 using Vec = std::vector<boost::shared_ptr<NumeredDofEntity>>;
2384 using It = Vec::iterator;
2385 It operator()(Vec &dofs_view, It &hint,
2386 boost::shared_ptr<NumeredDofEntity> &&dof) {
2387 dofs_view.emplace_back(dof);
2388 return dofs_view.end();
2393 std::vector<boost::shared_ptr<NumeredDofEntity>> fe_vec_view;
2394 auto hint_r = ghost_idx_row_view.begin();
2395 for (
auto fe_ptr = fe_range.first; fe_ptr != fe_range.second; ++fe_ptr) {
2397 fe_vec_view.clear();
2399 *(p_miit->getNumeredRowDofsPtr()),
2400 fe_vec_view, Inserter());
2402 for (
auto &dof_ptr : fe_vec_view) {
2403 if (dof_ptr->getPart() != (
unsigned int)m_field.
get_comm_rank()) {
2404 hint_r = ghost_idx_row_view.emplace_hint(hint_r, dof_ptr);
2410 if (p_miit->numeredColDofsPtr == p_miit->numeredRowDofsPtr) {
2412 auto hint_c = ghost_idx_col_view.begin();
2413 for (
auto fe_ptr = fe_range.first; fe_ptr != fe_range.second; ++fe_ptr) {
2415 fe_vec_view.clear();
2417 *(p_miit->getNumeredColDofsPtr()),
2418 fe_vec_view, Inserter());
2420 for (
auto &dof_ptr : fe_vec_view) {
2421 if (dof_ptr->getPart() != (
unsigned int)m_field.
get_comm_rank()) {
2422 hint_c = ghost_idx_col_view.emplace_hint(hint_c, dof_ptr);
2428 int *nb_ghost_dofs[2] = {&nb_row_ghost_dofs, &nb_col_ghost_dofs};
2429 int nb_local_dofs[2] = {p_miit->nbLocDofsRow, p_miit->nbLocDofsCol};
2432 &ghost_idx_row_view, &ghost_idx_col_view};
2438 if (p_miit->numeredColDofsPtr == p_miit->numeredRowDofsPtr) {
2443 for (
int ss = 0; ss != loop_size; ++ss) {
2444 for (
auto &gid : *ghost_idx_view[ss]) {
2445 NumeredDofEntityByUId::iterator dof =
2446 dof_by_uid_no_const[ss]->find(gid->getLocalUniqueId());
2447 if (PetscUnlikely((*dof)->petscLocalDofIdx != (
DofIdx)-1))
2449 "inconsistent data, ghost dof already set");
2450 bool success = dof_by_uid_no_const[ss]->modify(
2452 if (PetscUnlikely(!success))
2454 "modification unsuccessful");
2455 (*nb_ghost_dofs[ss])++;
2458 if (loop_size == 1) {
2459 (*nb_ghost_dofs[1]) = (*nb_ghost_dofs[0]);
2465 <<
" FEs ghost dofs on problem " << p_miit->getName()
2466 <<
" Nb. ghost dof " << p_miit->getNbGhostDofsRow() <<
" by "
2467 << p_miit->getNbGhostDofsCol() <<
" Nb. local dof "
2468 << p_miit->getNbLocalDofsCol() <<
" by " << p_miit->getNbLocalDofsCol();
2486 "partition of problem not build");
2489 "partitions finite elements not build");
2492 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
2494 ProblemsByName &problems_set =
2495 const_cast<ProblemsByName &
>(problems_ptr->get<
Problem_mi_tag>());
2496 ProblemsByName::iterator p_miit = problems_set.find(name);
2500 DofIdx *nb_ghost_dofs[2] = {&(p_miit->nbGhostDofsRow),
2501 &(p_miit->nbGhostDofsCol)};
2502 DofIdx nb_local_dofs[2] = {p_miit->nbLocDofsRow, p_miit->nbLocDofsCol};
2503 for (
int ss = 0; ss != 2; ++ss) {
2504 (*nb_ghost_dofs[ss]) = 0;
2511 if (p_miit->numeredColDofsPtr == p_miit->numeredRowDofsPtr) {
2515 typedef decltype(p_miit->numeredRowDofsPtr) NumbDofTypeSharedPtr;
2516 NumbDofTypeSharedPtr numered_dofs[] = {p_miit->numeredRowDofsPtr,
2517 p_miit->numeredColDofsPtr};
2520 for (
int ss = 0; ss != loop_size; ++ss) {
2525 std::vector<NumeredDofEntity_multiIndex::iterator> ghost_idx_view;
2526 ghost_idx_view.reserve(std::distance(r.first, r.second));
2527 for (; r.first != r.second; ++r.first)
2528 ghost_idx_view.emplace_back(numered_dofs[ss]->project<0>(r.first));
2530 auto cmp = [](
auto a,
auto b) {
2531 return (*a)->getLocalUniqueId() < (*b)->getLocalUniqueId();
2533 sort(ghost_idx_view.begin(), ghost_idx_view.end(), cmp);
2536 for (
auto gid_it : ghost_idx_view) {
2537 bool success = numered_dofs[ss]->modify(
2541 "modification unsuccessful");
2542 ++(*nb_ghost_dofs[ss]);
2545 if (loop_size == 1) {
2546 (*nb_ghost_dofs[1]) = (*nb_ghost_dofs[0]);
2552 <<
" FEs ghost dofs on problem " << p_miit->getName()
2553 <<
" Nb. ghost dof " << p_miit->getNbGhostDofsRow() <<
" by "
2554 << p_miit->getNbGhostDofsCol() <<
" Nb. local dof "
2555 << p_miit->getNbLocalDofsCol() <<
" by " << p_miit->getNbLocalDofsCol();
2565 const std::string &fe_name,
2581 0, (*fe_miit)->getFEUId()));
2585 get_id_for_max_type<MBENTITYSET>(), (*fe_miit)->getFEUId()));
2586 std::vector<EntityHandle> fe_vec;
2587 fe_vec.reserve(std::distance(fit, hi_fe_it));
2588 for (; fit != hi_fe_it; fit++)
2589 fe_vec.push_back(fit->get()->getEnt());
2590 CHKERR m_field.
get_moab().add_entities(*meshset, &*fe_vec.begin(),
2599 const std::string &fe_name,
2600 PetscLayout *layout)
const {
2612 std::vector<boost::weak_ptr<NumeredDofEntity>> &vec_dof_view,
2615 const Range ents,
int bridge_dim,
const int lo_coeff,
const int hi_coeff,
2616 const int lo_order,
const int hi_order,
int verb,
const bool debug
2641 ents, bridge_dim,
false, bridge_ents, moab::Interface::UNION);
2645 const auto nb_coeffs =
2650 using NumeredDofEntity_it_view_multiIndex = multi_index_container<
2652 NumeredDofEntity_multiIndex::iterator, indexed_by<sequenced<>>
2655 NumeredDofEntity_it_view_multiIndex dofs_it_view;
2657 for (
auto pit = bridge_ents.const_pair_begin();
2658 pit != bridge_ents.const_pair_end(); ++pit) {
2659 auto lo = numered_dofs[rc]->get<
Unique_mi_tag>().lower_bound(
2661 auto hi = numered_dofs[rc]->get<
Unique_mi_tag>().upper_bound(
2664 auto bride_type = moab.type_from_handle(pit->first);
2666 for (; lo != hi; ++lo) {
2667 if ((*lo)->getDofCoeffIdx() >= lo_coeff &&
2668 (*lo)->getDofCoeffIdx() <= hi_coeff &&
2669 (*lo)->getDofOrder() >= lo_order &&
2670 (*lo)->getDofOrder() <= hi_order) {
2671 auto ent_dof_index = (*lo)->getEntDofIdx();
2672 auto side_it = side_dof_map.at(bride_type)
2674 .find(std::floor(
static_cast<double>(ent_dof_index) /
2678 auto bridge_ent = (*lo)->getEnt();
2679 auto type = side_it->type;
2680 auto side = side_it->side;
2681 auto dim = CN::Dimension(type);
2683 CHKERR moab.side_element(bridge_ent, dim, side, side_ent);
2684 if (ents.find(side_ent) != ents.end()) {
2685 dofs_it_view.emplace_back(numered_dofs[rc]->project<0>(lo));
2692 <<
"side not found for entity " << CN::EntityTypeName(bride_type);
2694 <<
"ent_dof_index / nb_coeffs "
2695 << std::floor(
static_cast<double>(ent_dof_index) / nb_coeffs);
2697 <<
"side_dof_map.size() " << side_dof_map.size();
2700 "side not found - you will get more information in debug");
2707 for (
auto &dof : dofs_it_view)
2712 vec_dof_view.reserve(vec_dof_view.size() + dofs_it_view.size());
2713 for (
auto dit : dofs_it_view)
2714 vec_dof_view.push_back(*dit);
2720 const std::string problem_name,
RowColData rc,
2721 std::vector<boost::weak_ptr<NumeredDofEntity>> &vec_dof_view,
int verb,
2753 if (numered_dofs[rc]) {
2757 "Number of DOFs in multi-index %d and to delete %d\n",
2758 numered_dofs[rc]->size(), vec_dof_view.size());
2761 for (
auto weak_dit : vec_dof_view)
2762 if (
auto dit = weak_dit.lock()) {
2763 numered_dofs[rc]->erase(dit->getLocalUniqueId());
2768 "Number of DOFs in multi-index after delete %d\n",
2769 numered_dofs[rc]->size());
2772 int nb_local_dofs = 0;
2773 int nb_ghost_dofs = 0;
2774 for (
auto dit = numered_dofs[rc]->get<PetscLocalIdx_mi_tag>().begin();
2776 if ((*dit)->getPetscLocalDofIdx() >= 0 &&
2777 (*dit)->getPetscLocalDofIdx() < *(local_nbdof_ptr[rc]))
2779 else if ((*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[rc]))
2783 "Impossible case. You could run problem on no distributed "
2784 "mesh. That is not implemented. Dof local index is %d",
2785 (*dit)->getPetscLocalDofIdx());
2789 auto get_indices_by_tag = [&](
auto tag,
auto &indices,
bool only_local) {
2790 const int nb_dofs = numered_dofs[rc]->size();
2792 indices.reserve(nb_dofs);
2793 for (
auto dit = numered_dofs[rc]->get<
decltype(tag)>().begin();
2794 dit != numered_dofs[rc]->get<
decltype(tag)>().end(); ++dit) {
2797 if ((*dit)->getPetscLocalDofIdx() < 0 ||
2798 (*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[rc])) {
2803 indices.push_back(
decltype(tag)::get_index(dit));
2807 auto get_indices_by_uid = [&](
auto tag,
auto &indices) {
2808 const int nb_dofs = numered_dofs[rc]->size();
2810 indices.reserve(nb_dofs);
2811 for (
auto dit = numered_dofs[rc]->begin(); dit != numered_dofs[rc]->end();
2813 indices.push_back(
decltype(tag)::get_index(dit));
2816 auto get_sub_ao = [&](
auto sub_data) {
2818 return sub_data->getSmartRowMap();
2820 return sub_data->getSmartColMap();
2824 auto set_sub_is_and_ao = [&rc, &prb_ptr](
auto sub_data,
auto is,
auto ao) {
2826 sub_data->rowIs = is;
2827 sub_data->rowMap = ao;
2828 sub_data->colIs = is;
2829 sub_data->colMap = ao;
2831 sub_data->colIs = is;
2832 sub_data->colMap = ao;
2836 auto apply_symmetry = [&rc, &prb_ptr](
auto sub_data) {
2839 sub_data->colIs = sub_data->getSmartRowIs();
2840 sub_data->colMap = sub_data->getSmartRowMap();
2845 auto concatenate_dofs = [&](
auto tag,
auto &indices,
2846 const auto local_only) {
2848 get_indices_by_tag(tag, indices, local_only);
2855 &*indices.begin(), PETSC_NULLPTR);
2857 ao =
createAOMapping(PETSC_COMM_SELF, indices.size(), &*indices.begin(),
2865 &*indices.begin(), PETSC_COPY_VALUES);
2868 auto sub_ao = get_sub_ao(sub_data);
2869 CHKERR AOPetscToApplicationIS(sub_ao, sub_is);
2872 set_sub_is_and_ao(sub_data, sub_is, sub_ao);
2873 apply_symmetry(sub_data);
2876 prb_ptr->
getSubData() = boost::make_shared<Problem::SubProblemData>();
2878 &*indices.begin(), PETSC_COPY_VALUES);
2880 set_sub_is_and_ao(prb_ptr->
getSubData(), sub_is, ao);
2885 get_indices_by_uid(tag, indices);
2886 CHKERR AOApplicationToPetsc(ao, indices.size(), &*indices.begin());
2892 auto set_concatenated_indices = [&]() {
2893 std::vector<int> global_indices;
2894 std::vector<int> local_indices;
2898 auto gi = global_indices.begin();
2899 auto li = local_indices.begin();
2900 for (
auto dit = numered_dofs[rc]->begin(); dit != numered_dofs[rc]->end();
2903 (*dit)->getPart(), (*dit)->getDofIdx(), *gi, *li);
2904 bool success = numered_dofs[rc]->modify(dit, mod);
2907 "can not set negative indices");
2913 CHKERR set_concatenated_indices();
2915 MPI_Allreduce(&nb_local_dofs, nbdof_ptr[rc], 1, MPI_INT, MPI_SUM,
2917 *(local_nbdof_ptr[rc]) = nb_local_dofs;
2918 *(ghost_nbdof_ptr[rc]) = nb_ghost_dofs;
2921 for (
auto dof : (*numered_dofs[rc])) {
2922 if (dof->getPetscGlobalDofIdx() < 0) {
2924 "Negative global idx");
2926 if (dof->getPetscLocalDofIdx() < 0) {
2928 "Negative local idx");
2934 *(nbdof_ptr[1]) = *(nbdof_ptr[0]);
2935 *(local_nbdof_ptr[1]) = *(local_nbdof_ptr[0]);
2936 *(ghost_nbdof_ptr[1]) = *(ghost_nbdof_ptr[0]);
2941 "WORLD", Sev::inform,
2942 "Removed DOFs from problem %s dofs [%d / %d (before %d / %d) global]",
2944 prb_ptr->
getNbDofsCol(), nb_init_row_dofs, nb_init_col_dofs);
2946 "Removed DOFs from problem %s dofs [ %d / %d "
2947 "(before %d / %d) local, %d / %d (before %d / %d)]",
2952 nb_init_ghost_col_dofs);
2960 const std::string problem_name,
const std::string
field_name,
2961 const Range ents,
const int lo_coeff,
const int hi_coeff,
2962 const int lo_order,
const int hi_order,
int verb,
const bool debug) {
2986 for (
int s = 0; s != 2; ++s)
2987 if (numered_dofs[s]) {
2989 using NumeredDofEntity_it_view_multiIndex = multi_index_container<
2991 NumeredDofEntity_multiIndex::iterator, indexed_by<sequenced<>>
2996 NumeredDofEntity_it_view_multiIndex dofs_it_view;
2999 for (
auto pit = ents.const_pair_begin(); pit != ents.const_pair_end();
3001 auto lo = numered_dofs[s]->get<
Unique_mi_tag>().lower_bound(
3003 auto hi = numered_dofs[s]->get<
Unique_mi_tag>().upper_bound(
3006 for (; lo != hi; ++lo)
3007 if ((*lo)->getDofCoeffIdx() >= lo_coeff &&
3008 (*lo)->getDofCoeffIdx() <= hi_coeff &&
3009 (*lo)->getDofOrder() >= lo_order &&
3010 (*lo)->getDofOrder() <= hi_order)
3011 dofs_it_view.emplace_back(numered_dofs[s]->project<0>(lo));
3015 for (
auto &dof : dofs_it_view)
3021 std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_weak_view;
3022 dofs_weak_view.reserve(dofs_it_view.size());
3023 for (
auto dit : dofs_it_view)
3024 dofs_weak_view.push_back(*dit);
3028 "Number of DOFs in multi-index %d and to delete %d\n",
3029 numered_dofs[s]->size(), dofs_it_view.size());
3032 for (
auto weak_dit : dofs_weak_view)
3033 if (
auto dit = weak_dit.lock()) {
3034 numered_dofs[s]->erase(dit->getLocalUniqueId());
3039 "Number of DOFs in multi-index after delete %d\n",
3040 numered_dofs[s]->size());
3043 int nb_local_dofs = 0;
3044 int nb_ghost_dofs = 0;
3045 for (
auto dit = numered_dofs[s]->get<PetscLocalIdx_mi_tag>().begin();
3047 if ((*dit)->getPetscLocalDofIdx() >= 0 &&
3048 (*dit)->getPetscLocalDofIdx() < *(local_nbdof_ptr[s]))
3050 else if ((*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[s]))
3054 "Impossible case. You could run problem on no distributed "
3055 "mesh. That is not implemented. Dof local index is %d",
3056 (*dit)->getPetscLocalDofIdx());
3060 auto get_indices_by_tag = [&](
auto tag,
auto &indices,
bool only_local) {
3061 const int nb_dofs = numered_dofs[s]->size();
3063 indices.reserve(nb_dofs);
3064 for (
auto dit = numered_dofs[s]->get<
decltype(tag)>().begin();
3065 dit != numered_dofs[s]->get<
decltype(tag)>().end(); ++dit) {
3068 if ((*dit)->getPetscLocalDofIdx() < 0 ||
3069 (*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[s])) {
3074 indices.push_back(
decltype(tag)::get_index(dit));
3078 auto get_indices_by_uid = [&](
auto tag,
auto &indices) {
3079 const int nb_dofs = numered_dofs[s]->size();
3081 indices.reserve(nb_dofs);
3082 for (
auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3084 indices.push_back(
decltype(tag)::get_index(dit));
3087 auto get_sub_ao = [&](
auto sub_data) {
3089 return sub_data->getSmartRowMap();
3091 return sub_data->getSmartColMap();
3095 auto set_sub_is_and_ao = [&s, &prb_ptr](
auto sub_data,
auto is,
auto ao) {
3097 sub_data->rowIs = is;
3098 sub_data->rowMap = ao;
3099 sub_data->colIs = is;
3100 sub_data->colMap = ao;
3102 sub_data->colIs = is;
3103 sub_data->colMap = ao;
3107 auto apply_symmetry = [&s, &prb_ptr](
auto sub_data) {
3110 sub_data->colIs = sub_data->getSmartRowIs();
3111 sub_data->colMap = sub_data->getSmartRowMap();
3116 auto concatenate_dofs = [&](
auto tag,
auto &indices,
3117 const auto local_only) {
3119 get_indices_by_tag(tag, indices, local_only);
3126 &*indices.begin(), PETSC_NULLPTR);
3129 &*indices.begin(), PETSC_NULLPTR);
3136 &*indices.begin(), PETSC_COPY_VALUES);
3139 auto sub_ao = get_sub_ao(sub_data);
3140 CHKERR AOPetscToApplicationIS(sub_ao, sub_is);
3143 set_sub_is_and_ao(sub_data, sub_is, sub_ao);
3144 apply_symmetry(sub_data);
3148 boost::make_shared<Problem::SubProblemData>();
3150 &*indices.begin(), PETSC_COPY_VALUES);
3152 set_sub_is_and_ao(prb_ptr->
getSubData(), sub_is, ao);
3157 get_indices_by_uid(tag, indices);
3158 CHKERR AOApplicationToPetsc(ao, indices.size(), &*indices.begin());
3164 auto set_concatenated_indices = [&]() {
3165 std::vector<int> global_indices;
3166 std::vector<int> local_indices;
3170 auto gi = global_indices.begin();
3171 auto li = local_indices.begin();
3172 for (
auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3175 (*dit)->getPart(), (*dit)->getDofIdx(), *gi, *li);
3176 bool success = numered_dofs[s]->modify(dit, mod);
3179 "can not set negative indices");
3185 CHKERR set_concatenated_indices();
3187 MPI_Allreduce(&nb_local_dofs, nbdof_ptr[s], 1, MPI_INT, MPI_SUM,
3189 *(local_nbdof_ptr[s]) = nb_local_dofs;
3190 *(ghost_nbdof_ptr[s]) = nb_ghost_dofs;
3193 for (
auto dof : (*numered_dofs[s])) {
3194 if (dof->getPetscGlobalDofIdx() < 0) {
3196 "Negative global idx");
3198 if (dof->getPetscLocalDofIdx() < 0) {
3200 "Negative local idx");
3206 *(nbdof_ptr[1]) = *(nbdof_ptr[0]);
3207 *(local_nbdof_ptr[1]) = *(local_nbdof_ptr[0]);
3208 *(ghost_nbdof_ptr[1]) = *(ghost_nbdof_ptr[0]);
3213 "WORLD", Sev::inform,
3214 "Removed DOFs from problem %s dofs [%d / %d (before %d / %d) global]",
3216 prb_ptr->
getNbDofsCol(), nb_init_row_dofs, nb_init_col_dofs);
3218 "Removed DOFs from problem %s dofs [ %d / %d "
3219 "(before %d / %d) local, %d / %d (before %d / %d)]",
3224 nb_init_ghost_col_dofs);
3232 const std::string problem_name,
const std::string
field_name,
3233 const Range ents,
const int lo_coeff,
const int hi_coeff,
3234 const int lo_order,
const int hi_order,
int verb,
const bool debug) {
3258 const std::array<int, 2> nb_init_dofs = {nb_init_row_dofs, nb_init_col_dofs};
3260 for (
int s = 0; s != 2; ++s)
3261 if (numered_dofs[s]) {
3263 typedef multi_index_container<
3265 NumeredDofEntity_multiIndex::iterator, indexed_by<sequenced<>>
3268 NumeredDofEntity_it_view_multiIndex;
3271 NumeredDofEntity_it_view_multiIndex dofs_it_view;
3274 for (
auto pit = ents.const_pair_begin(); pit != ents.const_pair_end();
3276 auto lo = numered_dofs[s]->get<
Unique_mi_tag>().lower_bound(
3278 auto hi = numered_dofs[s]->get<
Unique_mi_tag>().upper_bound(
3281 for (; lo != hi; ++lo)
3282 if ((*lo)->getDofCoeffIdx() >= lo_coeff &&
3283 (*lo)->getDofCoeffIdx() <= hi_coeff &&
3284 (*lo)->getDofOrder() >= lo_order &&
3285 (*lo)->getDofOrder() <= hi_order)
3286 dofs_it_view.emplace_back(numered_dofs[s]->project<0>(lo));
3290 for (
auto &dof : dofs_it_view)
3296 for (
auto dit : dofs_it_view) {
3297 bool success = numered_dofs[s]->modify(dit, mod);
3300 "can not set negative indices");
3304 std::vector<boost::weak_ptr<NumeredDofEntity>> dosf_weak_view;
3305 dosf_weak_view.reserve(dofs_it_view.size());
3306 for (
auto dit : dofs_it_view)
3307 dosf_weak_view.push_back(*dit);
3311 "Number of DOFs in multi-index %d and to delete %d\n",
3312 numered_dofs[s]->size(), dofs_it_view.size());
3315 for (
auto weak_dit : dosf_weak_view)
3316 if (
auto dit = weak_dit.lock()) {
3317 numered_dofs[s]->erase(dit->getLocalUniqueId());
3322 "Number of DOFs in multi-index after delete %d\n",
3323 numered_dofs[s]->size());
3326 int nb_global_dof = 0;
3327 int nb_local_dofs = 0;
3328 int nb_ghost_dofs = 0;
3330 for (
auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3333 if ((*dit)->getDofIdx() >= 0) {
3335 if ((*dit)->getPetscLocalDofIdx() >= 0 &&
3336 (*dit)->getPetscLocalDofIdx() < *(local_nbdof_ptr[s]))
3338 else if ((*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[s]))
3346 MPI_Allreduce(&nb_local_dofs, nbdof_ptr[s], 1, MPI_INT, MPI_SUM,
3348 if (*(nbdof_ptr[s]) != nb_global_dof)
3350 "Number of local DOFs do not add up %d != %d",
3351 *(nbdof_ptr[s]), nb_global_dof);
3354 *(nbdof_ptr[s]) = nb_global_dof;
3355 *(local_nbdof_ptr[s]) = nb_local_dofs;
3356 *(ghost_nbdof_ptr[s]) = nb_ghost_dofs;
3359 auto get_indices_by_tag = [&](
auto tag) {
3360 std::vector<int> indices;
3361 indices.resize(nb_init_dofs[s], -1);
3362 for (
auto dit = numered_dofs[s]->get<Idx_mi_tag>().lower_bound(0);
3363 dit != numered_dofs[s]->get<
Idx_mi_tag>().end(); ++dit) {
3364 indices[(*dit)->getDofIdx()] =
decltype(tag)::get_index(dit);
3369 auto renumber = [&](
auto tag,
auto &indices) {
3372 for (
auto dit = numered_dofs[s]->get<
decltype(tag)>().lower_bound(0);
3373 dit != numered_dofs[s]->get<
decltype(tag)>().end(); ++dit) {
3374 indices[(*dit)->getDofIdx()] = idx++;
3379 auto get_sub_ao = [&](
auto sub_data) {
3381 return sub_data->getSmartRowMap();
3383 return sub_data->getSmartColMap();
3387 auto set_sub_is_and_ao = [&s, &prb_ptr](
auto sub_data,
auto is,
auto ao) {
3389 sub_data->rowIs = is;
3390 sub_data->rowMap = ao;
3391 sub_data->colIs = is;
3392 sub_data->colMap = ao;
3394 sub_data->colIs = is;
3395 sub_data->colMap = ao;
3399 auto apply_symmetry = [&s, &prb_ptr](
auto sub_data) {
3402 sub_data->colIs = sub_data->getSmartRowIs();
3403 sub_data->colMap = sub_data->getSmartRowMap();
3408 auto set_sub_data = [&](
auto &indices) {
3413 &*indices.begin(), PETSC_COPY_VALUES);
3416 auto sub_ao = get_sub_ao(sub_data);
3417 CHKERR AOPetscToApplicationIS(sub_ao, sub_is);
3420 set_sub_is_and_ao(sub_data, sub_is, sub_ao);
3421 apply_symmetry(sub_data);
3423 prb_ptr->
getSubData() = boost::make_shared<Problem::SubProblemData>();
3425 &*indices.begin(), PETSC_COPY_VALUES);
3428 set_sub_is_and_ao(prb_ptr->
getSubData(), sub_is, sub_ao);
3436 CHKERR set_sub_data(global_indices);
3441 for (
auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3443 auto idx = (*dit)->getDofIdx();
3446 (*dit)->getPart(),
i++, global_indices[idx], local_indices[idx]);
3447 bool success = numered_dofs[s]->modify(dit, mod);
3450 "can not set negative indices");
3453 (*dit)->getPart(), -1, -1, -1);
3454 bool success = numered_dofs[s]->modify(dit, mod);
3457 "can not set negative indices");
3462 for (
auto dof : (*numered_dofs[s])) {
3463 if (dof->getDofIdx() >= 0 && dof->getPetscGlobalDofIdx() < 0) {
3465 "Negative global idx");
3472 *(nbdof_ptr[1]) = *(nbdof_ptr[0]);
3473 *(local_nbdof_ptr[1]) = *(local_nbdof_ptr[0]);
3474 *(ghost_nbdof_ptr[1]) = *(ghost_nbdof_ptr[0]);
3482 "WORLD", Sev::inform,
3483 "Removed DOFs from problem %s dofs [%d / %d (before %d / %d) global]",
3485 prb_ptr->
getNbDofsCol(), nb_init_row_dofs, nb_init_col_dofs);
3487 "Removed DOFs from problem %s dofs [ %d / %d "
3488 "(before %d / %d) local, %d / %d (before %d / %d)]",
3493 nb_init_ghost_col_dofs);
3500 const std::string problem_name,
const std::string
field_name,
3502 Range *ents_ptr,
const int lo_coeff,
const int hi_coeff,
const int lo_order,
3503 const int hi_order,
int verb,
const bool debug) {
3512 CHKERR bit_manager->filterEntitiesByRefLevel(bit_ref_level, bit_ref_mask,
3515 CHKERR bit_manager->getEntitiesByRefLevel(bit_ref_level, bit_ref_mask, ents,
3520 hi_coeff, lo_order, hi_order, verb,
debug);
3526 const std::string problem_name,
const std::string
field_name,
3528 Range *ents_ptr,
const int lo_coeff,
const int hi_coeff,
const int lo_order,
3529 const int hi_order,
int verb,
const bool debug) {
3538 CHKERR bit_manager->filterEntitiesByRefLevel(bit_ref_level, bit_ref_mask,
3541 CHKERR bit_manager->getEntitiesByRefLevel(bit_ref_level, bit_ref_mask, ents,
3546 lo_coeff, hi_coeff, lo_order,
3547 hi_order, verb,
debug);
3555 std::vector<unsigned char> &
marker)
const {
3561 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs;
3571 marker.resize(dofs->size(), 0);
3572 std::vector<unsigned char> marker_tmp;
3576 for (
auto p = ents.pair_begin(); p != ents.pair_end(); ++p) {
3577 auto lo = dofs->get<
Ent_mi_tag>().lower_bound(p->first);
3578 auto hi = dofs->get<
Ent_mi_tag>().upper_bound(p->second);
3579 for (; lo != hi; ++lo)
3580 marker[(*lo)->getPetscLocalDofIdx()] |= 1;
3584 marker_tmp.resize(dofs->size(), 0);
3585 for (
auto p = ents.pair_begin(); p != ents.pair_end(); ++p) {
3586 auto lo = dofs->get<
Ent_mi_tag>().lower_bound(p->first);
3587 auto hi = dofs->get<
Ent_mi_tag>().upper_bound(p->second);
3588 for (; lo != hi; ++lo)
3589 marker_tmp[(*lo)->getPetscLocalDofIdx()] = 1;
3591 for (
int i = 0;
i !=
marker.size(); ++
i) {
3603 const unsigned char c, std::vector<unsigned char> &
marker)
const {
3609 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs;
3619 marker.resize(dofs->size(), 0);
3626 auto marker_ref = [
marker](
auto &it) ->
unsigned int & {
3627 return marker[(*it)->getPetscLocalDofIdx()];
3632 for (; dof_lo != dof_hi; ++dof_lo)
3633 if ((*dof_lo)->getDofCoeffIdx() >= lo &&
3634 (*dof_lo)->getDofCoeffIdx() <= hi)
3635 marker[(*dof_lo)->getPetscLocalDofIdx()] |=
c;
3638 for (; dof_lo != dof_hi; ++dof_lo)
3639 if ((*dof_lo)->getDofCoeffIdx() >= lo &&
3640 (*dof_lo)->getDofCoeffIdx() <= hi)
3641 marker[(*dof_lo)->getPetscLocalDofIdx()] &=
c;
3650 const std::string problem_name,
RowColData rc,
3651 std::vector<boost::weak_ptr<NumeredDofEntity>> &vec_dof_view,
3652 const enum MarkOP op, std::vector<unsigned char> &
marker
3660 boost::shared_ptr<NumeredDofEntity_multiIndex> dofs;
3671 marker.resize(dofs->size(), 0);
3673 for (
auto &dof : vec_dof_view) {
3674 if (
auto dof_ptr = dof.lock()) {
3676 marker[dof_ptr->getPetscLocalDofIdx()] |= 1;
3678 marker[dof_ptr->getPetscLocalDofIdx()] &= 1;
3687 const std::string row_field,
3688 const std::string col_field)
const {
3693 const auto problem_ptr = m_field.
get_problem(problem_name);
3694 auto get_field_id = [&](
const std::string
field_name) {
3697 const auto row_id = get_field_id(row_field);
3698 const auto col_id = get_field_id(col_field);
3700 problem_ptr->addFieldToEmptyFieldBlocks(
BlockFieldPair(row_id, col_id));
#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 ...
@ 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 ...
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)
const double n
refractive index of diffusive medium
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
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
Problem::BlockFieldPair BlockFieldPair
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
FTensor::Index< 'm', 3 > m
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.
FieldCoefficientsNumber getNbOfCoeffs() const
Get number of field coefficients.
std::map< int, BaseFunction::DofsSideMap > & getDofSideMap() const
Get the dofs side map.
const BitFieldId & getId() const
Get unique field id.
IdxDataTypePtr(const int *ptr)
IdxDataType(const UId uid, const int dof)
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
Get the BitFEIDs in problem
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
MoFEMErrorCode getSideDofsOnBrokenSpaceEntities(std::vector< boost::weak_ptr< NumeredDofEntity > > &vec_dof_view, const std::string problem_name, RowColData rc, const std::string field_name, const Range ents, int bridge_dim, 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) const
Get DOFs on side entities for broke space.
PetscBool buildProblemFromFields
MoFEMErrorCode removeDofs(const std::string problem_name, RowColData rc, std::vector< boost::weak_ptr< NumeredDofEntity > > &vec_dof_view, int verb=VERBOSE, const bool debug=false)
Remove DOFs from problem on broken space.
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 reference to pointer of interface.