v0.14.0
Files | Functions
ProblemsManager

Adding and managing problems. More...

Collaboration diagram for ProblemsManager:

Files

file  ProblemsManager.cpp
 Managing complexities for problem.
 
file  ProblemsManager.hpp
 Interface managing problems.
 

Functions

DEPRECATED MoFEMErrorCode MoFEM::ProblemsManager::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. More...
 
MoFEMErrorCode MoFEM::ProblemsManager::buildProblem (const std::string name, const bool square_matrix, int verb=VERBOSE)
 build problem data structures More...
 
MoFEMErrorCode MoFEM::ProblemsManager::buildProblem (Problem *problem_ptr, const bool square_matrix, int verb=VERBOSE)
 build problem data structures More...
 
MoFEMErrorCode MoFEM::ProblemsManager::buildProblemOnDistributedMesh (const std::string name, const bool square_matrix, int verb=VERBOSE)
 build problem data structures, assuming that mesh is distributed (collective) More...
 
MoFEMErrorCode MoFEM::ProblemsManager::buildProblemOnDistributedMesh (Problem *problem_ptr, const bool square_matrix=true, int verb=VERBOSE)
 build problem data structures, assuming that mesh is distributed (collective) More...
 
MoFEMErrorCode MoFEM::ProblemsManager::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 More...
 
MoFEMErrorCode MoFEM::ProblemsManager::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 More...
 
MoFEMErrorCode MoFEM::ProblemsManager::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 More...
 
MoFEMErrorCode MoFEM::ProblemsManager::partitionSimpleProblem (const std::string name, int verb=VERBOSE)
 partition problem dofs More...
 
MoFEMErrorCode MoFEM::ProblemsManager::partitionProblem (const std::string name, int verb=VERBOSE)
 partition problem dofs (collective) More...
 
MoFEMErrorCode MoFEM::ProblemsManager::partitionFiniteElements (const std::string name, bool part_from_moab=false, int low_proc=-1, int hi_proc=-1, int verb=VERBOSE)
 partition finite elements More...
 
MoFEMErrorCode MoFEM::ProblemsManager::partitionGhostDofs (const std::string name, int verb=VERBOSE)
 determine ghost nodes More...
 
MoFEMErrorCode MoFEM::ProblemsManager::partitionGhostDofsOnDistributedMesh (const std::string name, int verb=VERBOSE)
 determine ghost nodes on distributed meshes More...
 
MoFEMErrorCode MoFEM::ProblemsManager::getFEMeshset (const std::string prb_name, const std::string &fe_name, EntityHandle *meshset) const
 create add entities of finite element in the problem More...
 
MoFEMErrorCode MoFEM::ProblemsManager::getProblemElementsLayout (const std::string name, const std::string &fe_name, PetscLayout *layout) const
 Get layout of elements in the problem. More...
 
MoFEMErrorCode MoFEM::ProblemsManager::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. More...
 
MoFEMErrorCode MoFEM::ProblemsManager::removeDofsOnEntities (const std::string problem_name, const std::string field_name, const BitRefLevel bit_ref_level, const BitRefLevel bit_ref_mask, Range *ents_ptr=nullptr, 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 by bit ref level. More...
 

Read load and boradcoast

@

MoFEMErrorCode MoFEM::CommInterface::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. More...
 

Detailed Description

Adding and managing problems.

Function Documentation

◆ buildComposedProblem()

MoFEMErrorCode MoFEM::ProblemsManager::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

Parameters
out_namename of build problem
add_row_problemsvector of add row problems
add_col_problemsvector of add col problems
square_matrixtrue if structurally squared matrix
verbverbosity level
Returns
error code

Definition at line 1255 of file ProblemsManager.cpp.

1258  {
1260  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "fields not build");
1261  if (!(cOre.getBuildMoFEM() & Core::BUILD_FE))
1262  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "FEs not build");
1263  if (!(cOre.getBuildMoFEM() & Core::BUILD_ADJ))
1264  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "adjacencies not build");
1265  MoFEM::Interface &m_field = cOre;
1266  auto problems_ptr = m_field.get_problems();
1268 
1269  CHKERR m_field.clear_problem(out_name);
1270  // get reference to all problems
1272  ProblemByName &problems_by_name =
1273  const_cast<ProblemByName &>(problems_ptr->get<Problem_mi_tag>());
1274 
1275  // Get iterators to out problem, i.e. build problem
1276  ProblemByName::iterator out_problem_it = problems_by_name.find(out_name);
1277  if (out_problem_it == problems_by_name.end()) {
1278  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1279  "problem with name < %s > not defined (top tip check spelling)",
1280  out_name.c_str());
1281  }
1282  // Make data structure for composed-problem data
1283  out_problem_it->composedProblemsData =
1284  boost::make_shared<ComposedProblemsData>();
1285  boost::shared_ptr<ComposedProblemsData> cmp_prb_data =
1286  out_problem_it->getComposedProblemsData();
1287 
1288  const std::vector<std::string> *add_prb[] = {&add_row_problems,
1289  &add_col_problems};
1290  std::vector<const Problem *> *add_prb_ptr[] = {&cmp_prb_data->rowProblemsAdd,
1291  &cmp_prb_data->colProblemsAdd};
1292  std::vector<SmartPetscObj<IS>> *add_prb_is[] = {&cmp_prb_data->rowIs,
1293  &cmp_prb_data->colIs};
1294 
1295  // Get local indices counter
1296  int *nb_local_dofs[] = {&out_problem_it->nbLocDofsRow,
1297  &out_problem_it->nbLocDofsCol};
1298  // Get global indices counter
1299  int *nb_dofs[] = {&out_problem_it->nbDofsRow, &out_problem_it->nbDofsCol};
1300 
1301  // Set number of ghost nodes to zero
1302  {
1303  out_problem_it->nbDofsRow = 0;
1304  out_problem_it->nbDofsCol = 0;
1305  out_problem_it->nbLocDofsRow = 0;
1306  out_problem_it->nbLocDofsCol = 0;
1307  out_problem_it->nbGhostDofsRow = 0;
1308  out_problem_it->nbGhostDofsCol = 0;
1309  }
1310  int nb_dofs_reserve[] = {0, 0};
1311 
1312  // Loop over rows and columns in the main problem and sub-problems
1313  for (int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1314  add_prb_ptr[ss]->reserve(add_prb[ss]->size());
1315  add_prb_is[ss]->reserve(add_prb[ss]->size());
1316  for (std::vector<std::string>::const_iterator vit = add_prb[ss]->begin();
1317  vit != add_prb[ss]->end(); vit++) {
1318  ProblemByName::iterator prb_it = problems_by_name.find(*vit);
1319  if (prb_it == problems_by_name.end()) {
1320  SETERRQ1(
1321  PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1322  "problem with name < %s > not defined (top tip check spelling)",
1323  vit->c_str());
1324  }
1325  add_prb_ptr[ss]->push_back(&*prb_it);
1326  // set number of dofs on rows and columns
1327  if (ss == 0) {
1328  // row
1329  *nb_dofs[ss] += add_prb_ptr[ss]->back()->getNbDofsRow();
1330  *nb_local_dofs[ss] += add_prb_ptr[ss]->back()->getNbLocalDofsRow();
1331  nb_dofs_reserve[ss] +=
1332  add_prb_ptr[ss]->back()->numeredRowDofsPtr->size();
1333  } else {
1334  // column
1335  *nb_dofs[ss] += add_prb_ptr[ss]->back()->getNbDofsCol();
1336  *nb_local_dofs[ss] += add_prb_ptr[ss]->back()->getNbLocalDofsCol();
1337  nb_dofs_reserve[ss] +=
1338  add_prb_ptr[ss]->back()->numeredColDofsPtr->size();
1339  }
1340  }
1341  }
1342  // if squre problem, rows and columns are the same
1343  if (square_matrix) {
1344  add_prb_ptr[1]->reserve(add_prb_ptr[0]->size());
1345  add_prb_is[1]->reserve(add_prb_ptr[0]->size());
1346  out_problem_it->numeredColDofsPtr = out_problem_it->numeredRowDofsPtr;
1347  *nb_dofs[1] = *nb_dofs[0];
1348  *nb_local_dofs[1] = *nb_local_dofs[0];
1349  }
1350 
1351  // reserve memory for dofs
1352  boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array[2];
1353  // Reserve memory
1354  for (int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1355  dofs_array[ss] = boost::make_shared<std::vector<NumeredDofEntity>>();
1356  dofs_array[ss]->reserve(nb_dofs_reserve[ss]);
1357  if (!ss)
1358  out_problem_it->getRowDofsSequence()->emplace_back(dofs_array[ss]);
1359  else
1360  out_problem_it->getColDofsSequence()->emplace_back(dofs_array[ss]);
1361  }
1362 
1363  // Push back DOFs
1364  for (int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1365  NumeredDofEntity_multiIndex::index<PetscGlobalIdx_mi_tag>::type::iterator
1366  dit,
1367  hi_dit;
1368  int shift_glob = 0;
1369  int shift_loc = 0;
1370  for (unsigned int pp = 0; pp != add_prb_ptr[ss]->size(); pp++) {
1371  PetscInt *dofs_out_idx_ptr;
1372  int nb_local_dofs = (*add_prb_ptr[ss])[pp]->getNbLocalDofsRow();
1373  CHKERR PetscMalloc(nb_local_dofs * sizeof(int), &dofs_out_idx_ptr);
1374  if (ss == 0) {
1375  dit = (*add_prb_ptr[ss])[pp]
1376  ->numeredRowDofsPtr->get<PetscGlobalIdx_mi_tag>()
1377  .begin();
1378  hi_dit = (*add_prb_ptr[ss])[pp]
1379  ->numeredRowDofsPtr->get<PetscGlobalIdx_mi_tag>()
1380  .end();
1381  } else {
1382  dit = (*add_prb_ptr[ss])[pp]
1383  ->numeredColDofsPtr->get<PetscGlobalIdx_mi_tag>()
1384  .begin();
1385  hi_dit = (*add_prb_ptr[ss])[pp]
1386  ->numeredColDofsPtr->get<PetscGlobalIdx_mi_tag>()
1387  .end();
1388  }
1389  int is_nb = 0;
1390  for (; dit != hi_dit; dit++) {
1391  const BitRefLevel &prb_bit = out_problem_it->getBitRefLevel();
1392  const BitRefLevel &prb_mask = out_problem_it->getBitRefLevelMask();
1393  const BitRefLevel &dof_bit = dit->get()->getBitRefLevel();
1394  if ((dof_bit & prb_bit).none() || ((dof_bit & prb_mask) != dof_bit))
1395  continue;
1396  const int rank = m_field.get_comm_rank();
1397  const int part = dit->get()->getPart();
1398  const int glob_idx = shift_glob + dit->get()->getPetscGlobalDofIdx();
1399  const int loc_idx =
1400  (part == rank) ? (shift_loc + dit->get()->getPetscLocalDofIdx())
1401  : -1;
1402  dofs_array[ss]->emplace_back(dit->get()->getDofEntityPtr(), glob_idx,
1403  glob_idx, loc_idx, part);
1404  if (part == rank) {
1405  dofs_out_idx_ptr[is_nb++] = glob_idx;
1406  }
1407  }
1408  if (is_nb > nb_local_dofs) {
1409  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
1410  "Data inconsistency");
1411  }
1412  IS is;
1413  CHKERR ISCreateGeneral(m_field.get_comm(), is_nb, dofs_out_idx_ptr,
1414  PETSC_OWN_POINTER, &is);
1415  auto smart_is = SmartPetscObj<IS>(is);
1416  (*add_prb_is[ss]).push_back(smart_is);
1417  if (ss == 0) {
1418  shift_glob += (*add_prb_ptr[ss])[pp]->getNbDofsRow();
1419  shift_loc += (*add_prb_ptr[ss])[pp]->getNbLocalDofsRow();
1420  } else {
1421  shift_glob += (*add_prb_ptr[ss])[pp]->getNbDofsCol();
1422  shift_loc += (*add_prb_ptr[ss])[pp]->getNbLocalDofsCol();
1423  }
1424  if (square_matrix) {
1425  (*add_prb_ptr[1]).push_back((*add_prb_ptr[0])[pp]);
1426  (*add_prb_is[1]).push_back(smart_is);
1427  }
1428  }
1429  }
1430 
1431  if ((*add_prb_is[1]).size() != (*add_prb_is[0]).size()) {
1432  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY, "Data inconsistency");
1433  }
1434 
1435  // Insert DOFs to problem multi-index
1436  for (int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1437  auto hint = (ss == 0) ? out_problem_it->numeredRowDofsPtr->end()
1438  : out_problem_it->numeredColDofsPtr->end();
1439  for (auto &v : *dofs_array[ss])
1440  hint = (ss == 0) ? out_problem_it->numeredRowDofsPtr->emplace_hint(
1441  hint, dofs_array[ss], &v)
1442  : out_problem_it->numeredColDofsPtr->emplace_hint(
1443  hint, dofs_array[ss], &v);
1444  }
1445 
1446  // Compress DOFs
1447  *nb_dofs[0] = 0;
1448  *nb_dofs[1] = 0;
1449  *nb_local_dofs[0] = 0;
1450  *nb_local_dofs[1] = 0;
1451  for (int ss = 0; ss != ((square_matrix) ? 1 : 2); ss++) {
1452 
1453  boost::shared_ptr<NumeredDofEntity_multiIndex> dofs_ptr;
1454  if (ss == 0) {
1455  dofs_ptr = out_problem_it->numeredRowDofsPtr;
1456  } else {
1457  dofs_ptr = out_problem_it->numeredColDofsPtr;
1458  }
1459  NumeredDofEntityByUId::iterator dit, hi_dit;
1460  dit = dofs_ptr->get<Unique_mi_tag>().begin();
1461  hi_dit = dofs_ptr->get<Unique_mi_tag>().end();
1462  std::vector<int> idx;
1463  idx.reserve(std::distance(dit, hi_dit));
1464  // set dofs in order entity and dof number on entity
1465  for (; dit != hi_dit; dit++) {
1466  if (dit->get()->getPart() == (unsigned int)m_field.get_comm_rank()) {
1467  bool success = dofs_ptr->get<Unique_mi_tag>().modify(
1468  dit, NumeredDofEntity_local_idx_change((*nb_local_dofs[ss])++));
1469  if (!success) {
1470  SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
1471  "modification unsuccessful");
1472  }
1473  idx.push_back(dit->get()->getPetscGlobalDofIdx());
1474  } else {
1475  if (dit->get()->getPetscLocalDofIdx() != -1) {
1476  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
1477  "local index should be negative");
1478  }
1479  }
1480  }
1481  if (square_matrix) {
1482  *nb_local_dofs[1] = *nb_local_dofs[0];
1483  }
1484 
1485  // set new dofs mapping
1486  IS is;
1487  CHKERR ISCreateGeneral(m_field.get_comm(), idx.size(), &*idx.begin(),
1488  PETSC_USE_POINTER, &is);
1489  CHKERR ISGetSize(is, nb_dofs[ss]);
1490  if (square_matrix) {
1491  *nb_dofs[1] = *nb_dofs[0];
1492  }
1493 
1494  AO ao;
1495  CHKERR AOCreateMappingIS(is, PETSC_NULL, &ao);
1496  for (unsigned int pp = 0; pp != (*add_prb_is[ss]).size(); pp++)
1497  CHKERR AOApplicationToPetscIS(ao, (*add_prb_is[ss])[pp]);
1498 
1499  // Set DOFs numeration
1500  {
1501  std::vector<int> idx_new;
1502  idx_new.reserve(dofs_ptr->size());
1503  for (NumeredDofEntityByUId::iterator dit =
1504  dofs_ptr->get<Unique_mi_tag>().begin();
1505  dit != dofs_ptr->get<Unique_mi_tag>().end(); dit++) {
1506  idx_new.push_back(dit->get()->getPetscGlobalDofIdx());
1507  }
1508  // set new global dofs numeration
1509  IS is_new;
1510  CHKERR ISCreateGeneral(m_field.get_comm(), idx_new.size(),
1511  &*idx_new.begin(), PETSC_USE_POINTER, &is_new);
1512  CHKERR AOApplicationToPetscIS(ao, is_new);
1513  // set global indices to multi-index
1514  std::vector<int>::iterator vit = idx_new.begin();
1515  for (NumeredDofEntityByUId::iterator dit =
1516  dofs_ptr->get<Unique_mi_tag>().begin();
1517  dit != dofs_ptr->get<Unique_mi_tag>().end(); dit++) {
1518  bool success =
1519  dofs_ptr->modify(dit, NumeredDofEntity_part_and_glob_idx_change(
1520  dit->get()->getPart(), *(vit++)));
1521  if (!success) {
1522  SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
1523  "modification unsuccessful");
1524  }
1525  }
1526  CHKERR ISDestroy(&is_new);
1527  }
1528  CHKERR ISDestroy(&is);
1529  CHKERR AODestroy(&ao);
1530  }
1531 
1532  CHKERR printPartitionedProblem(&*out_problem_it, verb);
1533  CHKERR debugPartitionedProblem(&*out_problem_it, verb);
1534 
1535  // Inidcate that porble has been build
1538 
1540 }

◆ buildProblem() [1/2]

MoFEMErrorCode MoFEM::ProblemsManager::buildProblem ( const std::string  name,
const bool  square_matrix,
int  verb = VERBOSE 
)

build problem data structures

Note
If square_matrix is set to true, that indicate that problem is structurally symmetric, i.e. rows and columns have the same dofs and are indexed in the same way.
Parameters
nameproblem name
square_matrixstructurally symmetric problem
verbverbosity level
Returns
error code
Examples
build_problems.cpp, continuity_check_on_contact_prism_side_ele.cpp, continuity_check_on_skeleton_3d.cpp, forces_and_sources_testing_edge_element.cpp, forces_and_sources_testing_flat_prism_element.cpp, hcurl_divergence_operator_2d.cpp, mesh_insert_interface_atom.cpp, nonlinear_dynamics.cpp, nonlinear_elastic.cpp, prism_elements_from_surface.cpp, prism_polynomial_approximation.cpp, quad_polynomial_approximation.cpp, and remove_entities_from_problem_not_partitioned.cpp.

Definition at line 87 of file ProblemsManager.cpp.

89  {
90 
91  MoFEM::Interface &m_field = cOre;
93  if (!(cOre.getBuildMoFEM() & (1 << 0)))
94  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "fields not build");
95  if (!(cOre.getBuildMoFEM() & (1 << 1)))
96  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "FEs not build");
97  if (!(cOre.getBuildMoFEM() & (1 << 2)))
98  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "adjacencies not build");
99  const Problem *problem_ptr;
100  CHKERR m_field.get_problem(name, &problem_ptr);
101  CHKERR buildProblem(const_cast<Problem *>(problem_ptr), square_matrix, verb);
102  cOre.getBuildMoFEM() |= 1 << 3; // It is assumed that user who uses this
103  // function knows what he is doing
105 }

◆ buildProblem() [2/2]

MoFEMErrorCode MoFEM::ProblemsManager::buildProblem ( Problem problem_ptr,
const bool  square_matrix,
int  verb = VERBOSE 
)

build problem data structures

Note
If square_matrix is set to true, that indicate that problem is structurally symmetric, i.e. rows and columns have the same dofs and are indexed in the same way.
Parameters
problempointer
square_matrixstructurally symmetric problem
verbverbosity level
Returns
error code

Definition at line 107 of file ProblemsManager.cpp.

109  {
110  MoFEM::Interface &m_field = cOre;
111  auto dofs_field_ptr = m_field.get_dofs();
112  auto ents_field_ptr = m_field.get_field_ents();
113  auto adjacencies_ptr = m_field.get_ents_elements_adjacency();
115  PetscLogEventBegin(MOFEM_EVENT_ProblemsManager, 0, 0, 0, 0);
116 
117  // Note: Only allowed changes on problem_ptr structure which not influence
118  // multi-index.
119 
120  if (problem_ptr->getBitRefLevel().none()) {
121  SETERRQ1(PETSC_COMM_SELF, 1, "problem <%s> refinement level not set",
122  problem_ptr->getName().c_str());
123  }
124  CHKERR m_field.clear_problem(problem_ptr->getName());
125 
126  // zero finite elements
127  problem_ptr->numeredFiniteElementsPtr->clear();
128 
129  DofEntity_multiIndex_active_view dofs_rows, dofs_cols;
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) {
133 
134  const auto uid = (*it)->getLocalUniqueId();
135 
136  auto r = adjacencies_ptr->get<Unique_mi_tag>().equal_range(uid);
137  for (auto lo = r.first; lo != r.second; ++lo) {
138 
139  if ((lo->getBitFEId() & problem_ptr->getBitFEId()).any()) {
140  std::array<bool, 2> row_col = {false, false};
141 
142  const BitRefLevel &prb_bit = problem_ptr->getBitRefLevel();
143  const BitRefLevel &prb_mask = problem_ptr->getBitRefLevelMask();
144  const BitRefLevel &fe_bit = lo->entFePtr->getBitRefLevel();
145 
146  // if entity is not problem refinement level
147  if ((fe_bit & prb_mask) != fe_bit)
148  continue;
149  if ((fe_bit & prb_bit).none())
150  continue;
151 
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(
157  uid | static_cast<UId>(MAX_DOFS_ON_ENTITY - 1));
158  view.insert(dit, hi_dit);
159  row_col[rc] = true;
160  }
161  };
162 
163  if ((lo->entFePtr->getBitFieldIdRow() & (*it)->getId()).any())
164  add_to_view(dofs_field_ptr, dofs_rows, ROW);
165 
166  if (!square_matrix)
167  if ((lo->entFePtr->getBitFieldIdCol() & (*it)->getId()).any())
168  add_to_view(dofs_field_ptr, dofs_cols, COL);
169 
170  if (square_matrix && row_col[ROW])
171  break;
172  else if (row_col[ROW] && row_col[COL])
173  break;
174  }
175  }
176  }
178  };
179 
180  CHKERR make_rows_and_cols_view(dofs_rows, dofs_cols);
181 
182  // Add row dofs to problem
183  {
184  // zero rows
185  problem_ptr->nbDofsRow = 0;
186  problem_ptr->nbLocDofsRow = 0;
187  problem_ptr->nbGhostDofsRow = 0;
188 
189  // add dofs for rows
190  DofEntity_multiIndex_active_view::nth_index<0>::type::iterator miit,
191  hi_miit;
192  hi_miit = dofs_rows.get<0>().end();
193 
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>());
198  problem_ptr->getRowDofsSequence()->push_back(dofs_array);
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)++;
205  }
206  }
207  auto hint = problem_ptr->numeredRowDofsPtr->end();
208  for (auto &v : *dofs_array) {
209  hint = problem_ptr->numeredRowDofsPtr->emplace_hint(hint, dofs_array, &v);
210  }
211  }
212 
213  // Add col dofs to problem
214  if (!square_matrix) {
215  // zero cols
216  problem_ptr->nbDofsCol = 0;
217  problem_ptr->nbLocDofsCol = 0;
218  problem_ptr->nbGhostDofsCol = 0;
219 
220  // add dofs for cols
221  DofEntity_multiIndex_active_view::nth_index<0>::type::iterator miit,
222  hi_miit;
223  hi_miit = dofs_cols.get<0>().end();
224 
225  int count_dofs = 0;
226  miit = dofs_cols.get<0>().begin();
227  for (; miit != hi_miit; miit++) {
228  if (!(*miit)->getActive()) {
229  continue;
230  }
231  count_dofs++;
232  }
233 
234  boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array =
235  boost::shared_ptr<std::vector<NumeredDofEntity>>(
236  new std::vector<NumeredDofEntity>());
237  problem_ptr->getColDofsSequence()->push_back(dofs_array);
238  dofs_array->reserve(count_dofs);
239  miit = dofs_cols.get<0>().begin();
240  for (; miit != hi_miit; miit++) {
241  if (!(*miit)->getActive()) {
242  continue;
243  }
244  dofs_array->emplace_back(*miit);
245  dofs_array->back().dofIdx = problem_ptr->nbDofsCol++;
246  }
247  auto hint = problem_ptr->numeredColDofsPtr->end();
248  for (auto &v : *dofs_array) {
249  hint = problem_ptr->numeredColDofsPtr->emplace_hint(hint, dofs_array, &v);
250  }
251  } else {
252  problem_ptr->numeredColDofsPtr = problem_ptr->numeredRowDofsPtr;
253  problem_ptr->nbLocDofsCol = problem_ptr->nbLocDofsRow;
254  problem_ptr->nbDofsCol = problem_ptr->nbDofsRow;
255  }
256 
257  // job done, some debugging and postprocessing
258  if (verb >= VERBOSE) {
259  MOFEM_LOG("SYNC", Sev::verbose)
260  << problem_ptr->getName() << " Nb. local dofs "
261  << problem_ptr->numeredRowDofsPtr->size() << " by "
262  << problem_ptr->numeredColDofsPtr->size();
263  MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::verbose);
264  }
265 
266  if (verb >= NOISY) {
267  MOFEM_LOG("SYNC", Sev::noisy)
268  << "FEs row dofs " << *problem_ptr << " Nb. row dof "
269  << problem_ptr->getNbDofsRow();
270  for (auto &miit : *problem_ptr->numeredRowDofsPtr)
271  MOFEM_LOG("SYNC", Sev::noisy) << *miit;
272 
273  MOFEM_LOG("SYNC", Sev::noisy)
274  << "FEs col dofs " << *problem_ptr << " Nb. col dof "
275  << problem_ptr->getNbDofsCol();
276  for (auto &miit : *problem_ptr->numeredColDofsPtr)
277  MOFEM_LOG("SYNC", Sev::noisy) << *miit;
278  MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
279  }
280 
281  cOre.getBuildMoFEM() |= Core::BUILD_PROBLEM; // It is assumed that user who
282  // uses this function knows
283  // what he is doing
284 
285  PetscLogEventEnd(MOFEM_EVENT_ProblemsManager, 0, 0, 0, 0);
286 
288 }

◆ buildProblemOnDistributedMesh() [1/2]

MoFEMErrorCode MoFEM::ProblemsManager::buildProblemOnDistributedMesh ( const std::string  name,
const bool  square_matrix,
int  verb = VERBOSE 
)

build problem data structures, assuming that mesh is distributed (collective)

Mesh is distributed, that means that each processor keeps only own part of the mesh and shared entities.

Collective - need to be run on all processors in communicator, i.e. each function has to call this function.

Examples
nonlinear_dynamics.cpp, and remove_entities_from_problem.cpp.

Definition at line 290 of file ProblemsManager.cpp.

291  {
292  MoFEM::Interface &m_field = cOre;
294 
295  if (!((cOre.getBuildMoFEM()) & Core::BUILD_FIELD))
296  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "fields not build");
297  if (!((cOre.getBuildMoFEM()) & Core::BUILD_FE))
298  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "FEs not build");
299  if (!((cOre.getBuildMoFEM()) & Core::BUILD_ADJ))
300  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "adjacencies not build");
301 
302  const Problem *problem_ptr;
303  CHKERR m_field.get_problem(name, &problem_ptr);
304  CHKERR buildProblemOnDistributedMesh(const_cast<Problem *>(problem_ptr),
305  square_matrix, verb);
306 
309 
311 }

◆ buildProblemOnDistributedMesh() [2/2]

MoFEMErrorCode MoFEM::ProblemsManager::buildProblemOnDistributedMesh ( Problem problem_ptr,
const bool  square_matrix = true,
int  verb = VERBOSE 
)

build problem data structures, assuming that mesh is distributed (collective)

Mesh is distributed, that means that each processor keeps only own part of the mesh and shared entities.

Collective - need to be run on all processors in communicator, i.e. each function has to call this function.

Definition at line 313 of file ProblemsManager.cpp.

314  {
315  MoFEM::Interface &m_field = cOre;
316  auto fields_ptr = m_field.get_fields();
317  auto fe_ptr = m_field.get_finite_elements();
318  auto dofs_field_ptr = m_field.get_dofs();
320  PetscLogEventBegin(MOFEM_EVENT_ProblemsManager, 0, 0, 0, 0);
321 
322  // clear data structures
323  CHKERR m_field.clear_problem(problem_ptr->getName());
324 
325  CHKERR getOptions();
326 
327  if (problem_ptr->getBitRefLevel().none())
328  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND,
329  "problem <%s> refinement level not set",
330  problem_ptr->getName().c_str());
331 
332  int loop_size = 2;
333  if (square_matrix) {
334  loop_size = 1;
335  problem_ptr->numeredColDofsPtr = problem_ptr->numeredRowDofsPtr;
336  } else if (problem_ptr->numeredColDofsPtr == problem_ptr->numeredRowDofsPtr) {
337  problem_ptr->numeredColDofsPtr =
338  boost::shared_ptr<NumeredDofEntity_multiIndex>(
340  }
341 
342  const BitRefLevel &prb_bit = problem_ptr->getBitRefLevel();
343  const BitRefLevel &prb_mask = problem_ptr->getBitRefLevelMask();
344 
345  // // get rows and cols dofs view based on data on elements
346  DofEntity_multiIndex_active_view dofs_rows, dofs_cols;
347 
348  // Add DOFs to problem by visiting all elements and adding DOFs from
349  // elements to the problem
350  if (buildProblemFromFields == PETSC_FALSE) {
351 
352  auto make_rows_and_cols_view = [&](auto &dofs_rows, auto &dofs_cols) {
353  auto ents_field_ptr = m_field.get_field_ents();
354  auto adjacencies_ptr = m_field.get_ents_elements_adjacency();
356  for (auto it = ents_field_ptr->begin(); it != ents_field_ptr->end();
357  ++it) {
358 
359  const auto uid = (*it)->getLocalUniqueId();
360 
361  auto r = adjacencies_ptr->get<Unique_mi_tag>().equal_range(uid);
362  for (auto lo = r.first; lo != r.second; ++lo) {
363 
364  if ((lo->getBitFEId() & problem_ptr->getBitFEId()).any()) {
365  std::array<bool, 2> row_col = {false, false};
366 
367  const BitRefLevel &fe_bit = lo->entFePtr->getBitRefLevel();
368 
369  // if entity is not problem refinement level
370  if ((fe_bit & prb_bit).any() && (fe_bit & prb_mask) == fe_bit) {
371 
372  auto add_to_view = [&](auto dofs, auto &view, auto rc) {
373  auto dit = dofs->lower_bound(uid);
374  decltype(dit) hi_dit;
375  if (dit != dofs->end()) {
376  hi_dit = dofs->upper_bound(
377  uid | static_cast<UId>(MAX_DOFS_ON_ENTITY - 1));
378  view.insert(dit, hi_dit);
379  row_col[rc] = true;
380  }
381  };
382 
383  if ((lo->entFePtr->getBitFieldIdRow() & (*it)->getId()).any())
384  add_to_view(dofs_field_ptr, dofs_rows, ROW);
385 
386  if (!square_matrix)
387  if ((lo->entFePtr->getBitFieldIdCol() & (*it)->getId()).any())
388  add_to_view(dofs_field_ptr, dofs_cols, COL);
389 
390  if (square_matrix && row_col[ROW])
391  break;
392  else if (row_col[ROW] && row_col[COL])
393  break;
394  }
395  }
396  }
397  }
399  };
400 
401  CHKERR make_rows_and_cols_view(dofs_rows, dofs_cols);
402  }
403 
404  // Add DOFS to the problem by searching all the filedes, and adding to
405  // problem owned or shared DOFs
406  if (buildProblemFromFields == PETSC_TRUE) {
407  // Get fields IDs on elements
408  BitFieldId fields_ids_row, fields_ids_col;
409  for (auto fit = fe_ptr->begin(); fit != fe_ptr->end(); fit++) {
410  if ((fit->get()->getId() & problem_ptr->getBitFEId()).any()) {
411  fields_ids_row |= fit->get()->getBitFieldIdRow();
412  fields_ids_col |= fit->get()->getBitFieldIdCol();
413  }
414  }
415  // Get fields DOFs
416  for (auto fit = fields_ptr->begin(); fit != fields_ptr->end(); fit++) {
417  if ((fit->get()->getId() & (fields_ids_row | fields_ids_col)).any()) {
418 
419  auto dit = dofs_field_ptr->get<Unique_mi_tag>().lower_bound(
420  FieldEntity::getLoBitNumberUId((*fit)->getBitNumber()));
421  auto hi_dit = dofs_field_ptr->get<Unique_mi_tag>().upper_bound(
422  FieldEntity::getHiBitNumberUId((*fit)->getBitNumber()));
423 
424  for (; dit != hi_dit; dit++) {
425 
426  const int owner_proc = dit->get()->getOwnerProc();
427  if (owner_proc != m_field.get_comm_rank()) {
428  const unsigned char pstatus = dit->get()->getPStatus();
429  if (pstatus == 0) {
430  continue;
431  }
432  }
433 
434  const auto &dof_bit = (*dit)->getBitRefLevel();
435  // if entity is not problem refinement level
436  if ((dof_bit & prb_bit).any() && (dof_bit & prb_mask) == dof_bit) {
437 
438  if ((fit->get()->getId() & fields_ids_row).any()) {
439  dofs_rows.insert(*dit);
440  }
441  if (!square_matrix) {
442  if ((fit->get()->getId() & fields_ids_col).any()) {
443  dofs_cols.insert(*dit);
444  }
445  }
446  }
447  }
448  }
449  }
450  }
451 
453  // Get fields IDs on elements
454  BitFieldId fields_ids_row, fields_ids_col;
455  BitFieldId *fields_ids[2] = {&fields_ids_row, &fields_ids_col};
456  for (FiniteElement_multiIndex::iterator fit = fe_ptr->begin();
457  fit != fe_ptr->end(); fit++) {
458  if ((fit->get()->getId() & problem_ptr->getBitFEId()).any()) {
459  fields_ids_row |= fit->get()->getBitFieldIdRow();
460  fields_ids_col |= fit->get()->getBitFieldIdCol();
461  }
462  }
463 
464  DofEntity_multiIndex_active_view *dofs_ptr[] = {&dofs_rows, &dofs_cols};
465  for (int ss = 0; ss != ((square_matrix) ? 1 : 2); ++ss) {
466  DofEntity_multiIndex_active_view::nth_index<1>::type::iterator miit,
467  hi_miit;
468  miit = dofs_ptr[ss]->get<1>().lower_bound(1);
469  hi_miit = dofs_ptr[ss]->get<1>().upper_bound(1);
470  Range ents_to_synchronise;
471  for (; miit != hi_miit; ++miit) {
472  if (miit->get()->getEntDofIdx() != 0)
473  continue;
474  ents_to_synchronise.insert(miit->get()->getEnt());
475  }
476  Range tmp_ents = ents_to_synchronise;
477  CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
478  ents_to_synchronise, nullptr, verb);
479  ents_to_synchronise = subtract(ents_to_synchronise, tmp_ents);
480  for (auto fit = fields_ptr->begin(); fit != fields_ptr->end(); fit++) {
481  if ((fit->get()->getId() & *fields_ids[ss]).any()) {
482  const auto bit_number = (*fit)->getBitNumber();
483  for (Range::pair_iterator pit = ents_to_synchronise.pair_begin();
484  pit != ents_to_synchronise.pair_end(); ++pit) {
485  const auto f = pit->first;
486  const auto s = pit->second;
487  const auto lo_uid =
489  const auto hi_uid =
491 
492  auto dit = dofs_field_ptr->get<Unique_mi_tag>().lower_bound(lo_uid);
493  auto hi_dit =
494  dofs_field_ptr->get<Unique_mi_tag>().upper_bound(hi_uid);
495 
496  dofs_ptr[ss]->insert(dit, hi_dit);
497  }
498  }
499  }
500  }
501  }
502 
503  // add dofs for rows and cols and set ownership
504  DofEntity_multiIndex_active_view *dofs_ptr[] = {&dofs_rows, &dofs_cols};
505  boost::shared_ptr<NumeredDofEntity_multiIndex> numered_dofs_ptr[] = {
506  problem_ptr->numeredRowDofsPtr, problem_ptr->numeredColDofsPtr};
507  int *nbdof_ptr[] = {&problem_ptr->nbDofsRow, &problem_ptr->nbDofsCol};
508  int *local_nbdof_ptr[] = {&problem_ptr->nbLocDofsRow,
509  &problem_ptr->nbLocDofsCol};
510  int *ghost_nbdof_ptr[] = {&problem_ptr->nbGhostDofsRow,
511  &problem_ptr->nbGhostDofsCol};
512  for (int ss = 0; ss < 2; ss++) {
513  *(nbdof_ptr[ss]) = 0;
514  *(local_nbdof_ptr[ss]) = 0;
515  *(ghost_nbdof_ptr[ss]) = 0;
516  }
517 
518  // Loop over dofs on rows and columns and add to multi-indices in dofs
519  // problem structure, set partition for each dof
520  int nb_local_dofs[] = {0, 0};
521  for (int ss = 0; ss < loop_size; ss++) {
522  DofEntity_multiIndex_active_view::nth_index<1>::type::iterator miit,
523  hi_miit;
524  miit = dofs_ptr[ss]->get<1>().lower_bound(1);
525  hi_miit = dofs_ptr[ss]->get<1>().upper_bound(1);
526  for (; miit != hi_miit; miit++) {
527  int owner_proc = (*miit)->getOwnerProc();
528  if (owner_proc == m_field.get_comm_rank()) {
529  nb_local_dofs[ss]++;
530  }
531  }
532  }
533 
534  // get layout
535  int start_ranges[2], end_ranges[2];
536  for (int ss = 0; ss != loop_size; ss++) {
537  PetscLayout layout;
538  CHKERR PetscLayoutCreate(m_field.get_comm(), &layout);
539  CHKERR PetscLayoutSetBlockSize(layout, 1);
540  CHKERR PetscLayoutSetLocalSize(layout, nb_local_dofs[ss]);
541  CHKERR PetscLayoutSetUp(layout);
542  CHKERR PetscLayoutGetSize(layout, &*nbdof_ptr[ss]);
543  CHKERR PetscLayoutGetRange(layout, &start_ranges[ss], &end_ranges[ss]);
544  CHKERR PetscLayoutDestroy(&layout);
545  }
546  if (square_matrix) {
547  nbdof_ptr[1] = nbdof_ptr[0];
548  nb_local_dofs[1] = nb_local_dofs[0];
549  start_ranges[1] = start_ranges[0];
550  end_ranges[1] = end_ranges[0];
551  }
552 
553  // if(sizeof(UId) != SIZEOFUID) {
554  // SETERRQ2(
555  // PETSC_COMM_SELF,MOFEM_DATA_INCONSISTENCY,
556  // "check size of UId, size of UId is %u != %u",
557  // sizeof(UId),SIZEOFUID
558  // );
559  // }
560 
561  // set local and global indices on own dofs
562  const size_t idx_data_type_size = sizeof(IdxDataType);
563  const size_t data_block_size = idx_data_type_size / sizeof(int);
564 
565  if (sizeof(IdxDataType) % sizeof(int)) {
566  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
567  }
568  std::vector<std::vector<IdxDataType>> ids_data_packed_rows(
569  m_field.get_comm_size()),
570  ids_data_packed_cols(m_field.get_comm_size());
571 
572  // Loop over dofs on this processor and prepare those dofs to send on
573  // another proc
574  for (int ss = 0; ss != loop_size; ++ss) {
575 
576  DofEntity_multiIndex_active_view::nth_index<0>::type::iterator miit,
577  hi_miit;
578  hi_miit = dofs_ptr[ss]->get<0>().end();
579 
580  boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array =
581  boost::shared_ptr<std::vector<NumeredDofEntity>>(
582  new std::vector<NumeredDofEntity>());
583  int nb_dofs_to_add = 0;
584  miit = dofs_ptr[ss]->get<0>().begin();
585  for (; miit != hi_miit; ++miit) {
586  // Only set global idx for dofs on this processor part
587  if (!(miit->get()->getActive()))
588  continue;
589  ++nb_dofs_to_add;
590  }
591  dofs_array->reserve(nb_dofs_to_add);
592  if (ss == 0) {
593  problem_ptr->getRowDofsSequence()->push_back(dofs_array);
594  } else {
595  problem_ptr->getColDofsSequence()->push_back(dofs_array);
596  }
597 
598  int &local_idx = *local_nbdof_ptr[ss];
599  miit = dofs_ptr[ss]->get<0>().begin();
600  for (; miit != hi_miit; ++miit) {
601 
602  // Only set global idx for dofs on this processor part
603  if (!(miit->get()->getActive()))
604  continue;
605 
606  dofs_array->emplace_back(*miit);
607 
608  int owner_proc = dofs_array->back().getOwnerProc();
609  if (owner_proc < 0) {
610  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
611  "data inconsistency");
612  }
613 
614  if (owner_proc != m_field.get_comm_rank()) {
615  dofs_array->back().pArt = owner_proc;
616  dofs_array->back().dofIdx = -1;
617  dofs_array->back().petscGloablDofIdx = -1;
618  dofs_array->back().petscLocalDofIdx = -1;
619  } else {
620 
621  // Set part and indexes
622  int glob_idx = start_ranges[ss] + local_idx;
623  dofs_array->back().pArt = owner_proc;
624  dofs_array->back().dofIdx = glob_idx;
625  dofs_array->back().petscGloablDofIdx = glob_idx;
626  dofs_array->back().petscLocalDofIdx = local_idx;
627  local_idx++;
628 
629  unsigned char pstatus = dofs_array->back().getPStatus();
630  // check id dof is shared, if that is a case global idx added to data
631  // structure and is sended to other processors
632  if (pstatus > 0) {
633 
634  for (int proc = 0;
635  proc < MAX_SHARING_PROCS &&
636  -1 != dofs_array->back().getSharingProcsPtr()[proc];
637  proc++) {
638  // make it different for rows and columns when needed
639  if (ss == 0) {
640  ids_data_packed_rows[dofs_array->back()
641  .getSharingProcsPtr()[proc]]
642  .emplace_back(dofs_array->back().getGlobalUniqueId(),
643  glob_idx);
644  } else {
645  ids_data_packed_cols[dofs_array->back()
646  .getSharingProcsPtr()[proc]]
647  .emplace_back(dofs_array->back().getGlobalUniqueId(),
648  glob_idx);
649  }
650  if (!(pstatus & PSTATUS_MULTISHARED)) {
651  break;
652  }
653  }
654  }
655  }
656  }
657 
658  auto hint = numered_dofs_ptr[ss]->end();
659  for (auto &v : *dofs_array)
660  hint = numered_dofs_ptr[ss]->emplace_hint(hint, dofs_array, &v);
661  }
662  if (square_matrix) {
663  local_nbdof_ptr[1] = local_nbdof_ptr[0];
664  }
665 
666  int nsends_rows = 0, nsends_cols = 0;
667  // Non zero lengths[i] represent a message to i of length lengths[i].
668  std::vector<int> lengths_rows(m_field.get_comm_size()),
669  lengths_cols(m_field.get_comm_size());
670  lengths_rows.clear();
671  lengths_cols.clear();
672  for (int proc = 0; proc < m_field.get_comm_size(); proc++) {
673  lengths_rows[proc] = ids_data_packed_rows[proc].size() * data_block_size;
674  lengths_cols[proc] = ids_data_packed_cols[proc].size() * data_block_size;
675  if (!ids_data_packed_rows[proc].empty())
676  nsends_rows++;
677  if (!ids_data_packed_cols[proc].empty())
678  nsends_cols++;
679  }
680 
681  MPI_Status *status;
682  CHKERR PetscMalloc1(m_field.get_comm_size(), &status);
683 
684  // Do rows
685  int nrecvs_rows; // number of messages received
686  int *onodes_rows; // list of node-ids from which messages are expected
687  int *olengths_rows; // corresponding message lengths
688  int **rbuf_row; // must bee freed by user
689 
690  // make sure it is a PETSc comm
691  MPI_Comm comm;
692  CHKERR PetscCommDuplicate(m_field.get_comm(), &comm, NULL);
693 
694  {
695 
696  // rows
697 
698  // Computes the number of messages a node expects to receive
699  CHKERR PetscGatherNumberOfMessages(comm, NULL, &lengths_rows[0],
700  &nrecvs_rows);
701  // std::cerr << nrecvs_rows << std::endl;
702 
703  // Computes info about messages that a MPI-node will receive, including
704  // (from-id,length) pairs for each message.
705  CHKERR PetscGatherMessageLengths(comm, nsends_rows, nrecvs_rows,
706  &lengths_rows[0], &onodes_rows,
707  &olengths_rows);
708 
709  // Gets a unique new tag from a PETSc communicator. All processors that
710  // share the communicator MUST call this routine EXACTLY the same number
711  // of times. This tag should only be used with the current objects
712  // communicator; do NOT use it with any other MPI communicator.
713  int tag_row;
714  CHKERR PetscCommGetNewTag(comm, &tag_row);
715 
716  // Allocate a buffer sufficient to hold messages of size specified in
717  // olengths. And post Irecvs on these buffers using node info from onodes
718  MPI_Request *r_waits_row; // must bee freed by user
719  // rbuf has a pointers to messeges. It has size of of nrecvs (number of
720  // messages) +1. In the first index a block is allocated,
721  // such that rbuf[i] = rbuf[i-1]+olengths[i-1].
722 
723  CHKERR PetscPostIrecvInt(comm, tag_row, nrecvs_rows, onodes_rows,
724  olengths_rows, &rbuf_row, &r_waits_row);
725  CHKERR PetscFree(onodes_rows);
726 
727  MPI_Request *s_waits_row; // status of sens messages
728  CHKERR PetscMalloc1(nsends_rows, &s_waits_row);
729 
730  // Send messeges
731  for (int proc = 0, kk = 0; proc < m_field.get_comm_size(); proc++) {
732  if (!lengths_rows[proc])
733  continue; // no message to send to this proc
734  CHKERR MPI_Isend(&(ids_data_packed_rows[proc])[0], // buffer to send
735  lengths_rows[proc], // message length
736  MPIU_INT, proc, // to proc
737  tag_row, comm, s_waits_row + kk);
738  kk++;
739  }
740 
741  if (nrecvs_rows) {
742  CHKERR MPI_Waitall(nrecvs_rows, r_waits_row, status);
743  }
744  if (nsends_rows) {
745  CHKERR MPI_Waitall(nsends_rows, s_waits_row, status);
746  }
747 
748  CHKERR PetscFree(r_waits_row);
749  CHKERR PetscFree(s_waits_row);
750  }
751 
752  // cols
753  int nrecvs_cols = nrecvs_rows;
754  int *olengths_cols = olengths_rows;
755  PetscInt **rbuf_col = rbuf_row;
756  if (!square_matrix) {
757 
758  // Computes the number of messages a node expects to receive
759  CHKERR PetscGatherNumberOfMessages(comm, NULL, &lengths_cols[0],
760  &nrecvs_cols);
761 
762  // Computes info about messages that a MPI-node will receive, including
763  // (from-id,length) pairs for each message.
764  int *onodes_cols;
765  CHKERR PetscGatherMessageLengths(comm, nsends_cols, nrecvs_cols,
766  &lengths_cols[0], &onodes_cols,
767  &olengths_cols);
768 
769  // Gets a unique new tag from a PETSc communicator.
770  int tag_col;
771  CHKERR PetscCommGetNewTag(comm, &tag_col);
772 
773  // Allocate a buffer sufficient to hold messages of size specified in
774  // olengths. And post Irecvs on these buffers using node info from onodes
775  MPI_Request *r_waits_col; // must bee freed by user
776  CHKERR PetscPostIrecvInt(comm, tag_col, nrecvs_cols, onodes_cols,
777  olengths_cols, &rbuf_col, &r_waits_col);
778  CHKERR PetscFree(onodes_cols);
779 
780  MPI_Request *s_waits_col; // status of sens messages
781  CHKERR PetscMalloc1(nsends_cols, &s_waits_col);
782 
783  // Send messages
784  for (int proc = 0, kk = 0; proc < m_field.get_comm_size(); proc++) {
785  if (!lengths_cols[proc])
786  continue; // no message to send to this proc
787  CHKERR MPI_Isend(&(ids_data_packed_cols[proc])[0], // buffer to send
788  lengths_cols[proc], // message length
789  MPIU_INT, proc, // to proc
790  tag_col, comm, s_waits_col + kk);
791  kk++;
792  }
793 
794  if (nrecvs_cols) {
795  CHKERR MPI_Waitall(nrecvs_cols, r_waits_col, status);
796  }
797  if (nsends_cols) {
798  CHKERR MPI_Waitall(nsends_cols, s_waits_col, status);
799  }
800 
801  CHKERR PetscFree(r_waits_col);
802  CHKERR PetscFree(s_waits_col);
803  }
804 
805  CHKERR PetscCommDestroy(&comm);
806  CHKERR PetscFree(status);
807 
808  DofEntity_multiIndex_global_uid_view dofs_glob_uid_view;
809  auto hint = dofs_glob_uid_view.begin();
810  for (auto dof : *m_field.get_dofs())
811  dofs_glob_uid_view.emplace_hint(hint, dof);
812 
813  // set values received from other processors
814  for (int ss = 0; ss != loop_size; ++ss) {
815 
816  int nrecvs;
817  int *olengths;
818  int **data_procs;
819  if (ss == 0) {
820  nrecvs = nrecvs_rows;
821  olengths = olengths_rows;
822  data_procs = rbuf_row;
823  } else {
824  nrecvs = nrecvs_cols;
825  olengths = olengths_cols;
826  data_procs = rbuf_col;
827  }
828 
829  UId uid;
830  for (int kk = 0; kk != nrecvs; ++kk) {
831  int len = olengths[kk];
832  int *data_from_proc = data_procs[kk];
833  for (int dd = 0; dd < len; dd += data_block_size) {
834  uid = IdxDataTypePtr(&data_from_proc[dd]).getUId();
835  auto ddit = dofs_glob_uid_view.find(uid);
836  const auto owner_proc = FieldEntity::getOwnerFromUniqueId(uid);
837 
838  if (owner_proc == m_field.get_comm_rank() &&
839  PetscUnlikely(ddit == dofs_glob_uid_view.end())) {
840 
841 #ifndef NDEBUG
842  auto ents_field_ptr = m_field.get_field_ents();
843  MOFEM_LOG("SELF", Sev::error)
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 "
847  "triggered";
848 
849  MOFEM_LOG("SELF", Sev::error) << "UId " << uid << " is not found";
850  MOFEM_LOG("SELF", Sev::error)
851  << "Problematic UId owner proc is " << owner_proc;
852  const auto uid_handle = FieldEntity::getHandleFromUniqueId(uid);
853  MOFEM_LOG("SELF", Sev::error)
854  << "Problematic UId entity owning processor handle is "
855  << uid_handle << " entity type "
856  << moab::CN::EntityTypeName(type_from_handle(uid_handle));
857  const auto uid_bit_number =
859  MOFEM_LOG("SELF", Sev::error)
860  << "Problematic UId field is "
861  << m_field.get_field_name(
862  field_bit_from_bit_number(uid_bit_number));
863 
865  field_view.insert(ents_field_ptr->begin(), ents_field_ptr->end());
866  auto fe_it = field_view.find(FieldEntity::getGlobalUniqueIdCalculate(
867  owner_proc, uid_bit_number, uid_handle));
868  if (fe_it == field_view.end()) {
869  MOFEM_LOG("SELF", Sev::error)
870  << "Also, no field entity in database for given global UId";
871  } else {
872  MOFEM_LOG("SELF", Sev::error) << "Field entity in databse exist "
873  "(but have no DOF wih give UId";
874  MOFEM_LOG("SELF", Sev::error) << **fe_it;
875 
876  // Save file with missing entity
877  auto error_file_name =
878  "error_with_missing_entity_" +
879  boost::lexical_cast<std::string>(m_field.get_comm_rank()) +
880  ".vtk";
881  MOFEM_LOG("SELF", Sev::error)
882  << "Look to file < " << error_file_name
883  << " > it contains entity with missing DOF.";
884 
885  auto tmp_msh = get_temp_meshset_ptr(m_field.get_moab());
886  const auto local_fe_ent = (*fe_it)->getEnt();
887  CHKERR m_field.get_moab().add_entities(*tmp_msh, &local_fe_ent, 1);
888  CHKERR m_field.get_moab().write_file(error_file_name.c_str(), "VTK",
889  "", tmp_msh->get_ptr(), 1);
890  }
891 #endif
892 
893  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
894  "DOF with global UId not found (Compile code in Debug to "
895  "learn more about problem");
896  }
897 
898  if (PetscUnlikely(ddit == dofs_glob_uid_view.end())) {
899  continue;
900  }
901 
902  auto dit = numered_dofs_ptr[ss]->find((*ddit)->getLocalUniqueId());
903 
904  if (dit != numered_dofs_ptr[ss]->end()) {
905 
906  int global_idx = IdxDataTypePtr(&data_from_proc[dd]).getDofIdx();
907 #ifndef NDEBUG
908  if (PetscUnlikely(global_idx < 0))
909  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
910  "received negative dof");
911 #endif
912  bool success;
913  success = numered_dofs_ptr[ss]->modify(
914  dit, NumeredDofEntity_mofem_index_change(global_idx));
915 
916 #ifndef NDEBUG
917  if (PetscUnlikely(!success))
918  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
919  "modification unsuccessful");
920 #endif
921  success = numered_dofs_ptr[ss]->modify(
922  dit, NumeredDofEntity_part_and_glob_idx_change((*dit)->getPart(),
923  global_idx));
924 #ifndef NDEBUG
925  if (PetscUnlikely(!success))
926  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
927  "modification unsuccessful");
928 #endif
929  };
930 
931 #ifndef NDEBUG
932  if (PetscUnlikely(ddit->get()->getPStatus() == 0)) {
933 
934  // Dof is shared on this processor, however there is no element
935  // which have this dof. If DOF is not shared and received from other
936  // processor, but not marked as a shared on other that means that is
937  // data inconstancy and error should be thrown.
938 
939  std::ostringstream zz;
940  zz << **ddit << std::endl;
941  SETERRQ1(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
942  "data inconsistency, dofs is not shared, but received "
943  "from other proc\n"
944  "%s",
945  zz.str().c_str());
946  }
947 #endif
948  }
949  }
950  }
951 
952  if (square_matrix) {
953  (problem_ptr->nbDofsCol) = (problem_ptr->nbDofsRow);
954  (problem_ptr->nbLocDofsCol) = (problem_ptr->nbLocDofsRow);
955  }
956 
957  CHKERR PetscFree(olengths_rows);
958  CHKERR PetscFree(rbuf_row[0]);
959  CHKERR PetscFree(rbuf_row);
960  if (!square_matrix) {
961  CHKERR PetscFree(olengths_cols);
962  CHKERR PetscFree(rbuf_col[0]);
963  CHKERR PetscFree(rbuf_col);
964  }
965 
966  if (square_matrix) {
967  if (numered_dofs_ptr[0]->size() != numered_dofs_ptr[1]->size()) {
968  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
969  "data inconsistency for square_matrix %d!=%d",
970  numered_dofs_ptr[0]->size(), numered_dofs_ptr[1]->size());
971  }
972  if (problem_ptr->numeredRowDofsPtr != problem_ptr->numeredColDofsPtr) {
973  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
974  "data inconsistency for square_matrix");
975  }
976  }
977 
978  CHKERR printPartitionedProblem(problem_ptr, verb);
979  CHKERR debugPartitionedProblem(problem_ptr, verb);
980 
981  PetscLogEventEnd(MOFEM_EVENT_ProblemsManager, 0, 0, 0, 0);
982 
984 }

◆ buildSubProblem()

MoFEMErrorCode MoFEM::ProblemsManager::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

Parameters
out_nameproblem
fields_rowvector of fields composing problem
fields_colvector of fields composing problem
main_problemmain problem
Returns
error code
Examples
remove_entities_from_problem.cpp.

Definition at line 986 of file ProblemsManager.cpp.

997  {
998  MoFEM::Interface &m_field = cOre;
999  auto problems_ptr = m_field.get_problems();
1001 
1002  CHKERR m_field.clear_problem(out_name);
1003 
1004  // get reference to all problems
1005  using ProblemByName = decltype(problems_ptr->get<Problem_mi_tag>());
1006  auto &problems_by_name =
1007  const_cast<ProblemByName &>(problems_ptr->get<Problem_mi_tag>());
1008 
1009  // get iterators to out problem, i.e. build problem
1010  auto out_problem_it = problems_by_name.find(out_name);
1011  if (out_problem_it == problems_by_name.end()) {
1012  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1013  "subproblem with name < %s > not defined (top tip check spelling)",
1014  out_name.c_str());
1015  }
1016  // get iterator to main problem, i.e. out problem is subproblem of main
1017  // problem
1018  auto main_problem_it = problems_by_name.find(main_problem);
1019  if (main_problem_it == problems_by_name.end()) {
1020  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1021  "problem of subproblem with name < %s > not defined (top tip "
1022  "check spelling)",
1023  main_problem.c_str());
1024  }
1025 
1026  // get dofs for row & columns for out problem,
1027  boost::shared_ptr<NumeredDofEntity_multiIndex> out_problem_dofs[] = {
1028  out_problem_it->numeredRowDofsPtr, out_problem_it->numeredColDofsPtr};
1029  // get dofs for row & columns for main problem
1030  boost::shared_ptr<NumeredDofEntity_multiIndex> main_problem_dofs[] = {
1031  main_problem_it->numeredRowDofsPtr, main_problem_it->numeredColDofsPtr};
1032  // get local indices counter
1033  int *nb_local_dofs[] = {&out_problem_it->nbLocDofsRow,
1034  &out_problem_it->nbLocDofsCol};
1035  // get global indices counter
1036  int *nb_dofs[] = {&out_problem_it->nbDofsRow, &out_problem_it->nbDofsCol};
1037 
1038  // set number of ghost nodes to zero
1039  {
1040  out_problem_it->nbGhostDofsRow = 0;
1041  out_problem_it->nbGhostDofsCol = 0;
1042  }
1043 
1044  // put rows & columns field names in array
1045  std::vector<std::string> fields[] = {fields_row, fields_col};
1046  const map<std::string, boost::shared_ptr<Range>> *entityMap[] = {
1047  entityMapRow, entityMapCol};
1048 
1049  // make data structure fos sub-problem data
1050  out_problem_it->subProblemData =
1051  boost::make_shared<Problem::SubProblemData>();
1052 
1053  // Loop over rows and columns
1054  for (int ss = 0; ss != (square_matrix ? 1 : 2); ++ss) {
1055 
1056  // reset dofs and columns counters
1057  (*nb_local_dofs[ss]) = 0;
1058  (*nb_dofs[ss]) = 0;
1059  // clear arrays
1060  out_problem_dofs[ss]->clear();
1061 
1062  // If DOFs are cleared clear finite elements too.
1063  out_problem_it->numeredFiniteElementsPtr->clear();
1064 
1065  // get dofs by field name and insert them in out problem multi-indices
1066  for (auto field : fields[ss]) {
1067 
1068  // Following reserve memory in sequences, only two allocations are here,
1069  // once for array of objects, next for array of shared pointers
1070 
1071  // aliased sequence of pointer is killed with element
1072  boost::shared_ptr<std::vector<NumeredDofEntity>> dofs_array =
1073  boost::make_shared<std::vector<NumeredDofEntity>>();
1074  // reserve memory for field dofs
1075  if (!ss)
1076  out_problem_it->getRowDofsSequence()->emplace_back(dofs_array);
1077  else
1078  out_problem_it->getColDofsSequence()->emplace_back(dofs_array);
1079 
1080  // create elements objects
1081  auto bit_number = m_field.get_field_bit_number(field);
1082 
1083  auto add_dit_to_dofs_array = [&](auto &dit) {
1084  if (dit->get()->getPetscGlobalDofIdx() >= 0)
1085  dofs_array->emplace_back(
1086  dit->get()->getDofEntityPtr(), dit->get()->getPetscGlobalDofIdx(),
1087  dit->get()->getPetscGlobalDofIdx(),
1088  dit->get()->getPetscLocalDofIdx(), dit->get()->getPart());
1089  };
1090 
1091  auto get_dafult_dof_range = [&]() {
1092  auto dit = main_problem_dofs[ss]->get<Unique_mi_tag>().lower_bound(
1093  FieldEntity::getLoBitNumberUId(bit_number));
1094  auto hi_dit = main_problem_dofs[ss]->get<Unique_mi_tag>().upper_bound(
1095  FieldEntity::getHiBitNumberUId(bit_number));
1096  return std::make_pair(dit, hi_dit);
1097  };
1098 
1099  auto check = [&](auto &field) -> boost::shared_ptr<Range> {
1100  if (entityMap[ss]) {
1101  auto mit = entityMap[ss]->find(field);
1102  if (mit != entityMap[ss]->end()) {
1103  return mit->second;
1104  } else {
1105  return nullptr;
1106  }
1107  } else {
1108  return nullptr;
1109  }
1110  };
1111 
1112  if (auto r_ptr = check(field)) {
1113  for (auto p = r_ptr->pair_begin(); p != r_ptr->pair_end(); ++p) {
1114  const auto lo_ent = p->first;
1115  const auto hi_ent = p->second;
1116  auto dit = main_problem_dofs[ss]->get<Unique_mi_tag>().lower_bound(
1117  DofEntity::getLoFieldEntityUId(bit_number, lo_ent));
1118  auto hi_dit = main_problem_dofs[ss]->get<Unique_mi_tag>().upper_bound(
1119  DofEntity::getHiFieldEntityUId(bit_number, hi_ent));
1120  dofs_array->reserve(std::distance(dit, hi_dit));
1121  for (; dit != hi_dit; dit++) {
1122  add_dit_to_dofs_array(dit);
1123  }
1124  }
1125  } else {
1126  auto [dit, hi_dit] = get_dafult_dof_range();
1127  dofs_array->reserve(std::distance(dit, hi_dit));
1128  for (; dit != hi_dit; dit++)
1129  add_dit_to_dofs_array(dit);
1130  }
1131 
1132  // fill multi-index
1133  auto hint = out_problem_dofs[ss]->end();
1134  for (auto &v : *dofs_array)
1135  hint = out_problem_dofs[ss]->emplace_hint(hint, dofs_array, &v);
1136  }
1137  // Set local indexes
1138  {
1139  auto dit = out_problem_dofs[ss]->get<Idx_mi_tag>().begin();
1140  auto hi_dit = out_problem_dofs[ss]->get<Idx_mi_tag>().end();
1141  for (; dit != hi_dit; dit++) {
1142  int idx = -1; // if dof is not part of partition, set local index to -1
1143  if (dit->get()->getPart() == (unsigned int)m_field.get_comm_rank()) {
1144  idx = (*nb_local_dofs[ss])++;
1145  }
1146  bool success = out_problem_dofs[ss]->modify(
1147  out_problem_dofs[ss]->project<0>(dit),
1148  NumeredDofEntity_local_idx_change(idx));
1149  if (!success) {
1150  SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1151  "operation unsuccessful");
1152  }
1153  };
1154  }
1155  // Set global indexes, compress global indices
1156  {
1157  auto dit =
1158  out_problem_dofs[ss]->get<PetscLocalIdx_mi_tag>().lower_bound(0);
1159  auto hi_dit =
1160  out_problem_dofs[ss]->get<PetscLocalIdx_mi_tag>().upper_bound(
1161  out_problem_dofs[ss]->size());
1162  const int nb = std::distance(dit, hi_dit);
1163  // get main problem global indices
1164  std::vector<int> main_indices(nb);
1165  for (auto it = main_indices.begin(); dit != hi_dit; dit++, it++) {
1166  *it = dit->get()->getPetscGlobalDofIdx();
1167  }
1168  // create is with global dofs
1169  IS is;
1170  CHKERR ISCreateGeneral(m_field.get_comm(), nb, &*main_indices.begin(),
1171  PETSC_USE_POINTER, &is);
1172  // create map form main problem global indices to out problem global
1173  // indices
1174  AO ao;
1175  CHKERR AOCreateMappingIS(is, PETSC_NULL, &ao);
1176  if (ss == 0) {
1177  IS is_dup;
1178  CHKERR ISDuplicate(is, &is_dup);
1179  out_problem_it->getSubData()->rowIs = SmartPetscObj<IS>(is_dup, false);
1180  out_problem_it->getSubData()->rowMap = SmartPetscObj<AO>(ao, true);
1181  } else {
1182  IS is_dup;
1183  CHKERR ISDuplicate(is, &is_dup);
1184  out_problem_it->getSubData()->colIs = SmartPetscObj<IS>(is_dup, false);
1185  out_problem_it->getSubData()->colMap = SmartPetscObj<AO>(ao, true);
1186  }
1187  CHKERR AOApplicationToPetscIS(ao, is);
1188  // set global number of DOFs
1189  CHKERR ISGetSize(is, nb_dofs[ss]);
1190  CHKERR ISDestroy(&is);
1191  // set out problem global indices after applying map
1192  dit = out_problem_dofs[ss]->get<PetscLocalIdx_mi_tag>().lower_bound(0);
1193  for (std::vector<int>::iterator it = main_indices.begin(); dit != hi_dit;
1194  dit++, it++) {
1195  bool success = out_problem_dofs[ss]->modify(
1196  out_problem_dofs[ss]->project<0>(dit),
1197  NumeredDofEntity_part_and_all_indices_change(
1198  dit->get()->getPart(), *it, *it,
1199  dit->get()->getPetscLocalDofIdx()));
1200  if (!success) {
1201  SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1202  "operation unsuccessful");
1203  }
1204  }
1205  // set global indices to nodes not on this part
1206  {
1207  NumeredDofEntityByLocalIdx::iterator dit =
1208  out_problem_dofs[ss]->get<PetscLocalIdx_mi_tag>().lower_bound(-1);
1209  NumeredDofEntityByLocalIdx::iterator hi_dit =
1210  out_problem_dofs[ss]->get<PetscLocalIdx_mi_tag>().upper_bound(-1);
1211  const int nb = std::distance(dit, hi_dit);
1212  std::vector<int> main_indices_non_local(nb);
1213  for (auto it = main_indices_non_local.begin(); dit != hi_dit;
1214  dit++, it++) {
1215  *it = dit->get()->getPetscGlobalDofIdx();
1216  }
1217  IS is;
1218  CHKERR ISCreateGeneral(m_field.get_comm(), nb,
1219  &*main_indices_non_local.begin(),
1220  PETSC_USE_POINTER, &is);
1221  CHKERR AOApplicationToPetscIS(ao, is);
1222  CHKERR ISDestroy(&is);
1223  dit = out_problem_dofs[ss]->get<PetscLocalIdx_mi_tag>().lower_bound(-1);
1224  for (auto it = main_indices_non_local.begin(); dit != hi_dit;
1225  dit++, it++) {
1226  bool success = out_problem_dofs[ss]->modify(
1227  out_problem_dofs[ss]->project<0>(dit),
1228  NumeredDofEntity_part_and_all_indices_change(
1229  dit->get()->getPart(), dit->get()->getDofIdx(), *it,
1230  dit->get()->getPetscLocalDofIdx()));
1231  if (!success) {
1232  SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
1233  "operation unsuccessful");
1234  }
1235  }
1236  }
1237  CHKERR AODestroy(&ao);
1238  }
1239  }
1240 
1241  if (square_matrix) {
1242  out_problem_it->numeredColDofsPtr = out_problem_it->numeredRowDofsPtr;
1243  out_problem_it->nbLocDofsCol = out_problem_it->nbLocDofsRow;
1244  out_problem_it->nbDofsCol = out_problem_it->nbDofsRow;
1245  out_problem_it->getSubData()->colIs = out_problem_it->getSubData()->rowIs;
1246  out_problem_it->getSubData()->colMap = out_problem_it->getSubData()->rowMap;
1247  }
1248 
1249  CHKERR printPartitionedProblem(&*out_problem_it, verb);
1250  CHKERR debugPartitionedProblem(&*out_problem_it, verb);
1251 
1253 }

◆ getFEMeshset()

MoFEMErrorCode MoFEM::ProblemsManager::getFEMeshset ( const std::string  prb_name,
const std::string &  fe_name,
EntityHandle meshset 
) const

create add entities of finite element in the problem

\create add entities of finite element in the problem

Note
Meshset entity has to be crated
Meshset entity has to be crated
Parameters
prb_namename of the problem
fe_namename of the entity
meshsetpointer meshset handle
Returns
MoFEMErrorCode

Definition at line 2573 of file ProblemsManager.cpp.

2575  {
2576  MoFEM::Interface &m_field = cOre;
2577  const Problem *problem_ptr;
2578  const FiniteElement_multiIndex *fes_ptr;
2580 
2581  CHKERR m_field.get_moab().create_meshset(MESHSET_SET, *meshset);
2582  CHKERR m_field.get_problem(prb_name, &problem_ptr);
2583  CHKERR m_field.get_finite_elements(&fes_ptr);
2584 
2585  auto fe_miit = fes_ptr->get<FiniteElement_name_mi_tag>().find(fe_name);
2586  if (fe_miit != fes_ptr->get<FiniteElement_name_mi_tag>().end()) {
2587  auto fit =
2588  problem_ptr->numeredFiniteElementsPtr->get<Unique_mi_tag>().lower_bound(
2590  0, (*fe_miit)->getFEUId()));
2591  auto hi_fe_it =
2592  problem_ptr->numeredFiniteElementsPtr->get<Unique_mi_tag>().upper_bound(
2594  get_id_for_max_type<MBENTITYSET>(), (*fe_miit)->getFEUId()));
2595  std::vector<EntityHandle> fe_vec;
2596  fe_vec.reserve(std::distance(fit, hi_fe_it));
2597  for (; fit != hi_fe_it; fit++)
2598  fe_vec.push_back(fit->get()->getEnt());
2599  CHKERR m_field.get_moab().add_entities(*meshset, &*fe_vec.begin(),
2600  fe_vec.size());
2601  }
2602 
2604 }

◆ getProblemElementsLayout()

MoFEMErrorCode MoFEM::ProblemsManager::getProblemElementsLayout ( const std::string  name,
const std::string &  fe_name,
PetscLayout *  layout 
) const

Get layout of elements in the problem.

In layout is stored information how many elements is on each processor, for more information look int petsc documentation http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/IS/PetscLayoutCreate.html#PetscLayoutCreate

Parameters
nameproblem name
fe_namefinite elements
layoutlayout
verbverbosity level
Returns
error code

Definition at line 2607 of file ProblemsManager.cpp.

2609  {
2610  MoFEM::Interface &m_field = cOre;
2611  const Problem *problem_ptr;
2613  CHKERR m_field.get_problem(name, &problem_ptr);
2614  CHKERR problem_ptr->getNumberOfElementsByNameAndPart(PETSC_COMM_WORLD,
2615  fe_name, layout);
2617 }

◆ inheritPartition()

MoFEMErrorCode MoFEM::ProblemsManager::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

Parameters
nameproblem name
problem_for_rowsproblem used to index rows
copy_rowsjust copy rows dofs
problem_for_colsproblem used to index cols
copy_colsjust copy cols dofs

If copy_rows/copy_cols is set to false only partition is copied between problems.

Examples
build_problems.cpp.

Definition at line 1901 of file ProblemsManager.cpp.

1903  {
1904  MoFEM::Interface &m_field = cOre;
1905  auto problems_ptr = m_field.get_problems();
1907 
1909  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY, "pRoblems not build");
1910 
1912 
1913  // find p_miit
1914  ProblemByName &problems_by_name =
1915  const_cast<ProblemByName &>(problems_ptr->get<Problem_mi_tag>());
1916  ProblemByName::iterator p_miit = problems_by_name.find(name);
1917  if (p_miit == problems_by_name.end()) {
1918  SETERRQ1(m_field.get_comm(), MOFEM_NOT_FOUND,
1919  "problem with name < %s > not defined (top tip check spelling)",
1920  name.c_str());
1921  }
1922  if (verb > QUIET)
1923  MOFEM_LOG("WORLD", Sev::inform)
1924  << p_miit->getName() << " from rows of " << problem_for_rows
1925  << " and columns of " << problem_for_cols;
1926 
1927  // find p_miit_row
1928  ProblemByName::iterator p_miit_row = problems_by_name.find(problem_for_rows);
1929  if (p_miit_row == problems_by_name.end()) {
1930  SETERRQ1(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
1931  "problem with name < %s > not defined (top tip check spelling)",
1932  problem_for_rows.c_str());
1933  }
1934  const boost::shared_ptr<NumeredDofEntity_multiIndex> dofs_row =
1935  p_miit_row->numeredRowDofsPtr;
1936 
1937  // find p_mit_col
1938  ProblemByName::iterator p_miit_col = problems_by_name.find(problem_for_cols);
1939  if (p_miit_col == problems_by_name.end()) {
1940  SETERRQ1(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
1941  "problem with name < %s > not defined (top tip check spelling)",
1942  problem_for_cols.c_str());
1943  }
1944  boost::shared_ptr<NumeredDofEntity_multiIndex> dofs_col =
1945  p_miit_col->numeredColDofsPtr;
1946 
1947  bool copy[] = {copy_rows, copy_cols};
1948  boost::shared_ptr<NumeredDofEntity_multiIndex> composed_dofs[] = {
1949  p_miit->numeredRowDofsPtr, p_miit->numeredColDofsPtr};
1950 
1951  int *nb_local_dofs[] = {&p_miit->nbLocDofsRow, &p_miit->nbLocDofsCol};
1952  int *nb_dofs[] = {&p_miit->nbDofsRow, &p_miit->nbDofsCol};
1953  boost::shared_ptr<NumeredDofEntity_multiIndex> copied_dofs[] = {dofs_row,
1954  dofs_col};
1955 
1956  for (int ss = 0; ss < 2; ss++) {
1957 
1958  // build indices
1959  *nb_local_dofs[ss] = 0;
1960  if (!copy[ss]) {
1961 
1962  // only copy indices which are belong to some elements if this problem
1963  std::vector<int> is_local, is_new;
1964 
1965  NumeredDofEntityByUId &dofs_by_uid =
1966  copied_dofs[ss]->get<Unique_mi_tag>();
1967  for (NumeredDofEntity_multiIndex::iterator dit =
1968  composed_dofs[ss]->begin();
1969  dit != composed_dofs[ss]->end(); dit++) {
1970  NumeredDofEntityByUId::iterator diit =
1971  dofs_by_uid.find((*dit)->getLocalUniqueId());
1972  if (diit == dofs_by_uid.end()) {
1973  SETERRQ(
1975  "data inconsistency, could not find dof in composite problem");
1976  }
1977  int part_number = (*diit)->getPart(); // get part number
1978  int petsc_global_dof = (*diit)->getPetscGlobalDofIdx();
1979  bool success;
1980  success = composed_dofs[ss]->modify(
1981  dit, NumeredDofEntity_part_and_glob_idx_change(part_number,
1982  petsc_global_dof));
1983  if (!success) {
1984  SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
1985  "modification unsuccessful");
1986  }
1987  if ((*dit)->getPart() == (unsigned int)m_field.get_comm_rank()) {
1988  success = composed_dofs[ss]->modify(
1989  dit, NumeredDofEntity_local_idx_change((*nb_local_dofs[ss])++));
1990  if (!success) {
1991  SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
1992  "modification unsuccessful");
1993  }
1994  is_local.push_back(petsc_global_dof);
1995  }
1996  }
1997 
1998  AO ao;
1999  CHKERR AOCreateMapping(m_field.get_comm(), is_local.size(), &is_local[0],
2000  NULL, &ao);
2001 
2002  // apply local to global mapping
2003  is_local.resize(0);
2004  for (NumeredDofEntity_multiIndex::iterator dit =
2005  composed_dofs[ss]->begin();
2006  dit != composed_dofs[ss]->end(); dit++) {
2007  is_local.push_back((*dit)->getPetscGlobalDofIdx());
2008  }
2009  CHKERR AOPetscToApplication(ao, is_local.size(), &is_local[0]);
2010  int idx2 = 0;
2011  for (NumeredDofEntity_multiIndex::iterator dit =
2012  composed_dofs[ss]->begin();
2013  dit != composed_dofs[ss]->end(); dit++) {
2014  int part_number = (*dit)->getPart(); // get part number
2015  int petsc_global_dof = is_local[idx2++];
2016  bool success;
2017  success = composed_dofs[ss]->modify(
2018  dit, NumeredDofEntity_part_and_glob_idx_change(part_number,
2019  petsc_global_dof));
2020  if (!success) {
2021  SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
2022  "modification unsuccessful");
2023  }
2024  }
2025 
2026  CHKERR AODestroy(&ao);
2027 
2028  } else {
2029 
2030  for (NumeredDofEntity_multiIndex::iterator dit = copied_dofs[ss]->begin();
2031  dit != copied_dofs[ss]->end(); dit++) {
2032  std::pair<NumeredDofEntity_multiIndex::iterator, bool> p;
2033  p = composed_dofs[ss]->insert(boost::shared_ptr<NumeredDofEntity>(
2034  new NumeredDofEntity((*dit)->getDofEntityPtr())));
2035  if (p.second) {
2036  (*nb_dofs[ss])++;
2037  }
2038  int dof_idx = (*dit)->getDofIdx();
2039  int part_number = (*dit)->getPart(); // get part number
2040  int petsc_global_dof = (*dit)->getPetscGlobalDofIdx();
2041  if (part_number == (unsigned int)m_field.get_comm_rank()) {
2042  const bool success = composed_dofs[ss]->modify(
2043  p.first, NumeredDofEntity_part_and_all_indices_change(
2044  part_number, dof_idx, petsc_global_dof,
2045  (*nb_local_dofs[ss])++));
2046  if (!success) {
2047  SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
2048  "modification unsuccessful");
2049  }
2050  } else {
2051  const bool success = composed_dofs[ss]->modify(
2052  p.first, NumeredDofEntity_part_and_mofem_glob_idx_change(
2053  part_number, dof_idx, petsc_global_dof));
2054  if (!success) {
2055  SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
2056  "modification unsuccessful");
2057  }
2058  }
2059  }
2060  }
2061  }
2062 
2063  CHKERR printPartitionedProblem(&*p_miit, verb);
2064  CHKERR debugPartitionedProblem(&*p_miit, verb);
2065 
2067 }

◆ partitionFiniteElements()

MoFEMErrorCode MoFEM::ProblemsManager::partitionFiniteElements ( const std::string  name,
bool  part_from_moab = false,
int  low_proc = -1,
int  hi_proc = -1,
int  verb = VERBOSE 
)

partition finite elements

Function which partition finite elements based on dofs partitioning.
In addition it sets information about local row and cols dofs at given element on partition.

Parameters
name
part_from_moab
low_proc
hi_proc
verb
Returns
MoFEMErrorCode
Parameters
nameproblem name
Examples
build_problems.cpp, continuity_check_on_skeleton_3d.cpp, forces_and_sources_testing_edge_element.cpp, forces_and_sources_testing_flat_prism_element.cpp, hcurl_divergence_operator_2d.cpp, mesh_insert_interface_atom.cpp, nonlinear_dynamics.cpp, nonlinear_elastic.cpp, prism_elements_from_surface.cpp, prism_polynomial_approximation.cpp, quad_polynomial_approximation.cpp, and remove_entities_from_problem.cpp.

Definition at line 2172 of file ProblemsManager.cpp.

2175  {
2176  MoFEM::Interface &m_field = cOre;
2177  auto problems_ptr = m_field.get_problems();
2178  auto fe_ent_ptr = m_field.get_ents_finite_elements();
2180 
2182  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY, "fields not build");
2183 
2184  if (!(cOre.getBuildMoFEM() & Core::BUILD_FE))
2185  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY, "FEs not build");
2186 
2187  if (!(cOre.getBuildMoFEM() & Core::BUILD_ADJ))
2188  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2189  "adjacencies not build");
2190 
2192  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY, "problem not build");
2193 
2195  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2196  "problem not partitioned");
2197 
2198  if (low_proc == -1)
2199  low_proc = m_field.get_comm_rank();
2200  if (hi_proc == -1)
2201  hi_proc = m_field.get_comm_rank();
2202 
2203  // Find pointer to problem of given name
2205  auto &problems =
2206  const_cast<ProblemByName &>(problems_ptr->get<Problem_mi_tag>());
2207  ProblemByName::iterator p_miit = problems.find(name);
2208  if (p_miit == problems.end()) {
2209  SETERRQ1(m_field.get_comm(), MOFEM_NOT_FOUND,
2210  "problem < %s > not found (top tip: check spelling)",
2211  name.c_str());
2212  }
2213 
2214  // Get reference on finite elements multi-index on the problem
2215  NumeredEntFiniteElement_multiIndex &problem_finite_elements =
2216  *p_miit->numeredFiniteElementsPtr;
2217 
2218  // Clear all elements and data, build it again
2219  problem_finite_elements.clear();
2220 
2221  // Check if dofs and columns are the same, i.e. structurally symmetric
2222  // problem
2223  bool do_cols_prob = true;
2224  if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr) {
2225  do_cols_prob = false;
2226  }
2227 
2228  auto get_good_elems = [&]() {
2229  auto good_elems = std::vector<decltype(fe_ent_ptr->begin())>();
2230  good_elems.reserve(fe_ent_ptr->size());
2231 
2232  const auto prb_bit = p_miit->getBitRefLevel();
2233  const auto prb_mask = p_miit->getBitRefLevelMask();
2234 
2235  // Loop over all elements in database and if right element is there add it
2236  // to problem finite element multi-index
2237  for (auto efit = fe_ent_ptr->begin(); efit != fe_ent_ptr->end(); ++efit) {
2238 
2239  // if element is not part of problem
2240  if (((*efit)->getId() & p_miit->getBitFEId()).any()) {
2241 
2242  const auto &fe_bit = (*efit)->getBitRefLevel();
2243 
2244  // if entity is not problem refinement level
2245  if ((fe_bit & prb_mask) == fe_bit && (fe_bit & prb_bit).any())
2246  good_elems.emplace_back(efit);
2247  }
2248  }
2249 
2250  return good_elems;
2251  };
2252 
2253  auto good_elems = get_good_elems();
2254 
2255  auto numbered_good_elems_ptr =
2256  boost::make_shared<std::vector<NumeredEntFiniteElement>>();
2257  numbered_good_elems_ptr->reserve(good_elems.size());
2258  for (auto &efit : good_elems)
2259  numbered_good_elems_ptr->emplace_back(NumeredEntFiniteElement(*efit));
2260 
2261  if (!do_cols_prob) {
2262  for (auto &fe : *numbered_good_elems_ptr) {
2263  if (fe.sPtr->getRowFieldEntsPtr() == fe.sPtr->getColFieldEntsPtr()) {
2264  fe.getColFieldEntsPtr() = fe.getRowFieldEntsPtr();
2265  }
2266  }
2267  }
2268 
2269  if (part_from_moab) {
2270  for (auto &fe : *numbered_good_elems_ptr) {
2271  if (fe.getEntType() == MBENTITYSET) {
2272  fe.part = m_field.get_comm_rank();
2273  } else {
2274  // if partition is taken from moab partition
2275  int proc = fe.getPartProc();
2276  if (proc == -1 && fe.getEntType() == MBVERTEX)
2277  proc = fe.getOwnerProc();
2278  fe.part = proc;
2279  }
2280  }
2281  }
2282 
2283  for (auto &fe : *numbered_good_elems_ptr) {
2284 
2286  CHKERR fe.sPtr->getRowDofView(*(p_miit->numeredRowDofsPtr), rows_view);
2287 
2288  if (!part_from_moab) {
2289  if (fe.getEntType() == MBENTITYSET) {
2290  fe.part = m_field.get_comm_rank();
2291  } else {
2292  std::vector<int> parts(m_field.get_comm_size(), 0);
2293  for (auto &dof_ptr : rows_view)
2294  parts[dof_ptr->pArt]++;
2295  std::vector<int>::iterator pos =
2296  max_element(parts.begin(), parts.end());
2297  const auto max_part = std::distance(parts.begin(), pos);
2298  fe.part = max_part;
2299  }
2300  }
2301  }
2302 
2303  for (auto &fe : *numbered_good_elems_ptr) {
2304 
2305  auto check_fields_and_dofs = [&]() {
2306  if (!part_from_moab) {
2307  if (fe.getBitFieldIdRow().none() && m_field.get_comm_size() == 0) {
2308  MOFEM_LOG("WORLD", Sev::warning)
2309  << "At least one field has to be added to element row to "
2310  "determine partition of finite element. Check element " +
2311  boost::lexical_cast<std::string>(fe.getName());
2312  }
2313  }
2314 
2315  return true;
2316  };
2317 
2318  if (check_fields_and_dofs()) {
2319  // Add element to the problem
2320  auto p = problem_finite_elements.insert(
2321  boost::shared_ptr<NumeredEntFiniteElement>(numbered_good_elems_ptr,
2322  &fe));
2323  if (!p.second)
2324  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_FOUND, "element is there");
2325  }
2326  }
2327 
2328  if (verb >= VERBOSE) {
2329  auto elements_on_rank =
2330  problem_finite_elements.get<Part_mi_tag>().equal_range(
2331  m_field.get_comm_rank());
2332  MOFEM_LOG("SYNC", Sev::verbose)
2333  << p_miit->getName() << " nb. elems "
2334  << std::distance(elements_on_rank.first, elements_on_rank.second);
2335  auto fe_ptr = m_field.get_finite_elements();
2336  for (auto &fe : *fe_ptr) {
2337  auto e_range =
2338  problem_finite_elements.get<Composite_Name_And_Part_mi_tag>()
2339  .equal_range(
2340  boost::make_tuple(fe->getName(), m_field.get_comm_rank()));
2341  MOFEM_LOG("SYNC", Sev::noisy)
2342  << "Element " << fe->getName() << " nb. elems "
2343  << std::distance(e_range.first, e_range.second);
2344  }
2345 
2346  MOFEM_LOG_SYNCHRONISE(m_field.get_comm());
2347  }
2348 
2351 }

◆ partitionGhostDofs()

MoFEMErrorCode MoFEM::ProblemsManager::partitionGhostDofs ( const std::string  name,
int  verb = VERBOSE 
)

determine ghost nodes

Parameters
nameproblem name

DOFs are ghost dofs if are used by elements on given partition, but not owned by that partition.

Examples
build_problems.cpp, continuity_check_on_skeleton_3d.cpp, forces_and_sources_testing_edge_element.cpp, forces_and_sources_testing_flat_prism_element.cpp, hcurl_divergence_operator_2d.cpp, mesh_insert_interface_atom.cpp, nonlinear_dynamics.cpp, nonlinear_elastic.cpp, prism_elements_from_surface.cpp, prism_polynomial_approximation.cpp, quad_polynomial_approximation.cpp, and remove_entities_from_problem.cpp.

Definition at line 2353 of file ProblemsManager.cpp.

2354  {
2355  MoFEM::Interface &m_field = cOre;
2356  auto problems_ptr = m_field.get_problems();
2358 
2360  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2361  "partition of problem not build");
2363  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2364  "partitions finite elements not build");
2365 
2366  // get problem pointer
2367  auto p_miit = problems_ptr->get<Problem_mi_tag>().find(name);
2368  if (p_miit == problems_ptr->get<Problem_mi_tag>().end())
2369  SETERRQ1(PETSC_COMM_SELF, MOFEM_INVALID_DATA, "Problem %s not fond",
2370  name.c_str());
2371 
2372  // get reference to number of ghost dofs
2373  int &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
2374  int &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
2375  nb_row_ghost_dofs = 0;
2376  nb_col_ghost_dofs = 0;
2377 
2378  // do work if more than one processor
2379  if (m_field.get_comm_size() > 1) {
2380 
2382  ghost_idx_col_view;
2383 
2384  // get elements on this partition
2385  auto fe_range =
2386  p_miit->numeredFiniteElementsPtr->get<Part_mi_tag>().equal_range(
2387  m_field.get_comm_rank());
2388 
2389  // get dofs on elements which are not part of this partition
2390 
2391  struct Inserter {
2392  using Vec = std::vector<boost::shared_ptr<NumeredDofEntity>>;
2393  using It = Vec::iterator;
2394  It operator()(Vec &dofs_view, It &hint,
2395  boost::shared_ptr<NumeredDofEntity> &&dof) {
2396  dofs_view.emplace_back(dof);
2397  return dofs_view.end();
2398  }
2399  };
2400 
2401  // rows
2402  std::vector<boost::shared_ptr<NumeredDofEntity>> fe_vec_view;
2403  auto hint_r = ghost_idx_row_view.begin();
2404  for (auto fe_ptr = fe_range.first; fe_ptr != fe_range.second; ++fe_ptr) {
2405 
2406  fe_vec_view.clear();
2407  CHKERR EntFiniteElement::getDofView((*fe_ptr)->getRowFieldEnts(),
2408  *(p_miit->getNumeredRowDofsPtr()),
2409  fe_vec_view, Inserter());
2410 
2411  for (auto &dof_ptr : fe_vec_view) {
2412  if (dof_ptr->getPart() != (unsigned int)m_field.get_comm_rank()) {
2413  hint_r = ghost_idx_row_view.emplace_hint(hint_r, dof_ptr);
2414  }
2415  }
2416  }
2417 
2418  // columns
2419  if (p_miit->numeredColDofsPtr == p_miit->numeredRowDofsPtr) {
2420 
2421  auto hint_c = ghost_idx_col_view.begin();
2422  for (auto fe_ptr = fe_range.first; fe_ptr != fe_range.second; ++fe_ptr) {
2423 
2424  fe_vec_view.clear();
2425  CHKERR EntFiniteElement::getDofView((*fe_ptr)->getColFieldEnts(),
2426  *(p_miit->getNumeredColDofsPtr()),
2427  fe_vec_view, Inserter());
2428 
2429  for (auto &dof_ptr : fe_vec_view) {
2430  if (dof_ptr->getPart() != (unsigned int)m_field.get_comm_rank()) {
2431  hint_c = ghost_idx_col_view.emplace_hint(hint_c, dof_ptr);
2432  }
2433  }
2434  }
2435  }
2436 
2437  int *nb_ghost_dofs[2] = {&nb_row_ghost_dofs, &nb_col_ghost_dofs};
2438  int nb_local_dofs[2] = {p_miit->nbLocDofsRow, p_miit->nbLocDofsCol};
2439 
2440  NumeredDofEntity_multiIndex_uid_view_ordered *ghost_idx_view[2] = {
2441  &ghost_idx_row_view, &ghost_idx_col_view};
2442  NumeredDofEntityByUId *dof_by_uid_no_const[2] = {
2443  &p_miit->numeredRowDofsPtr->get<Unique_mi_tag>(),
2444  &p_miit->numeredColDofsPtr->get<Unique_mi_tag>()};
2445 
2446  int loop_size = 2;
2447  if (p_miit->numeredColDofsPtr == p_miit->numeredRowDofsPtr) {
2448  loop_size = 1;
2449  }
2450 
2451  // set local ghost dofs indices
2452  for (int ss = 0; ss != loop_size; ++ss) {
2453  for (auto &gid : *ghost_idx_view[ss]) {
2454  NumeredDofEntityByUId::iterator dof =
2455  dof_by_uid_no_const[ss]->find(gid->getLocalUniqueId());
2456  if (PetscUnlikely((*dof)->petscLocalDofIdx != (DofIdx)-1))
2457  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2458  "inconsistent data, ghost dof already set");
2459  bool success = dof_by_uid_no_const[ss]->modify(
2460  dof, NumeredDofEntity_local_idx_change(nb_local_dofs[ss]++));
2461  if (PetscUnlikely(!success))
2462  SETERRQ(m_field.get_comm(), MOFEM_OPERATION_UNSUCCESSFUL,
2463  "modification unsuccessful");
2464  (*nb_ghost_dofs[ss])++;
2465  }
2466  }
2467  if (loop_size == 1) {
2468  (*nb_ghost_dofs[1]) = (*nb_ghost_dofs[0]);
2469  }
2470  }
2471 
2472  if (verb > QUIET) {
2473  MOFEM_LOG("SYNC", Sev::inform)
2474  << " FEs ghost dofs on problem " << p_miit->getName()
2475  << " Nb. ghost dof " << p_miit->getNbGhostDofsRow() << " by "
2476  << p_miit->getNbGhostDofsCol() << " Nb. local dof "
2477  << p_miit->getNbLocalDofsCol() << " by " << p_miit->getNbLocalDofsCol();
2478 
2479  MOFEM_LOG_SYNCHRONISE(m_field.get_comm())
2480  }
2481 
2484 }

◆ partitionGhostDofsOnDistributedMesh()

MoFEMErrorCode MoFEM::ProblemsManager::partitionGhostDofsOnDistributedMesh ( const std::string  name,
int  verb = VERBOSE 
)

determine ghost nodes on distributed meshes

Parameters
nameproblem name

It is very similar for partitionGhostDofs, however this explits that mesh is distributed.

DOFs are ghosted if are shered but not owned by partition.

Examples
remove_entities_from_problem.cpp.

Definition at line 2487 of file ProblemsManager.cpp.

2488  {
2489  MoFEM::Interface &m_field = cOre;
2490  auto problems_ptr = m_field.get_problems();
2492 
2494  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2495  "partition of problem not build");
2497  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
2498  "partitions finite elements not build");
2499 
2500  // get problem pointer
2501  typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
2502  // find p_miit
2503  ProblemsByName &problems_set =
2504  const_cast<ProblemsByName &>(problems_ptr->get<Problem_mi_tag>());
2505  ProblemsByName::iterator p_miit = problems_set.find(name);
2506 
2507  // get reference to number of ghost dofs
2508  // get number of local dofs
2509  DofIdx *nb_ghost_dofs[2] = {&(p_miit->nbGhostDofsRow),
2510  &(p_miit->nbGhostDofsCol)};
2511  DofIdx nb_local_dofs[2] = {p_miit->nbLocDofsRow, p_miit->nbLocDofsCol};
2512  for (int ss = 0; ss != 2; ++ss) {
2513  (*nb_ghost_dofs[ss]) = 0;
2514  }
2515 
2516  // do work if more than one processor
2517  if (m_field.get_comm_size() > 1) {
2518  // determine if rows on columns are different from dofs on rows
2519  int loop_size = 2;
2520  if (p_miit->numeredColDofsPtr == p_miit->numeredRowDofsPtr) {
2521  loop_size = 1;
2522  }
2523 
2524  typedef decltype(p_miit->numeredRowDofsPtr) NumbDofTypeSharedPtr;
2525  NumbDofTypeSharedPtr numered_dofs[] = {p_miit->numeredRowDofsPtr,
2526  p_miit->numeredColDofsPtr};
2527 
2528  // iterate over dofs on rows and dofs on columns
2529  for (int ss = 0; ss != loop_size; ++ss) {
2530 
2531  // create dofs view by uid
2532  auto r = numered_dofs[ss]->get<PetscLocalIdx_mi_tag>().equal_range(-1);
2533 
2534  std::vector<NumeredDofEntity_multiIndex::iterator> ghost_idx_view;
2535  ghost_idx_view.reserve(std::distance(r.first, r.second));
2536  for (; r.first != r.second; ++r.first)
2537  ghost_idx_view.emplace_back(numered_dofs[ss]->project<0>(r.first));
2538 
2539  auto cmp = [](auto a, auto b) {
2540  return (*a)->getLocalUniqueId() < (*b)->getLocalUniqueId();
2541  };
2542  sort(ghost_idx_view.begin(), ghost_idx_view.end(), cmp);
2543 
2544  // iterate over dofs which have negative local index
2545  for (auto gid_it : ghost_idx_view) {
2546  bool success = numered_dofs[ss]->modify(
2547  gid_it, NumeredDofEntity_local_idx_change((nb_local_dofs[ss])++));
2548  if (!success)
2549  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
2550  "modification unsuccessful");
2551  ++(*nb_ghost_dofs[ss]);
2552  }
2553  }
2554  if (loop_size == 1) {
2555  (*nb_ghost_dofs[1]) = (*nb_ghost_dofs[0]);
2556  }
2557  }
2558 
2559  if (verb > QUIET) {
2560  MOFEM_LOG("SYNC", Sev::inform)
2561  << " FEs ghost dofs on problem " << p_miit->getName()
2562  << " Nb. ghost dof " << p_miit->getNbGhostDofsRow() << " by "
2563  << p_miit->getNbGhostDofsCol() << " Nb. local dof "
2564  << p_miit->getNbLocalDofsCol() << " by " << p_miit->getNbLocalDofsCol();
2565 
2566  MOFEM_LOG_SYNCHRONISE(m_field.get_comm())
2567  }
2568 
2571 }

◆ partitionMesh() [1/2]

MoFEMErrorCode MoFEM::ProblemsManager::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.

Deprecated:
Use CommInterface

This will use one of the mesh partitioning programs available from PETSc See http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Mat/MatPartitioningType.html

Parameters
entsEntities to partition
dimDimension of entities to partition
adj_dimAdjacency dimension
n_partsNumber of partitions
verbVerbosity level
Returns
Error code

Definition at line 77 of file ProblemsManager.cpp.

80  {
81  return static_cast<MoFEM::Interface &>(cOre)
82  .getInterface<CommInterface>()
83  ->partitionMesh(ents, dim, adj_dim, n_parts, th_vertex_weights,
84  th_edge_weights, th_part_weights, verb, debug);
85 }

◆ partitionMesh() [2/2]

MoFEMErrorCode MoFEM::CommInterface::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.

This will use one of the mesh partitioning programs available from PETSc See http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Mat/MatPartitioningType.html

Parameters
entsEntities to partition
dimDimension of entities to partition
adj_dimAdjacency dimension
n_partsNumber of partitions
verbVerbosity level
Returns
Error code
Examples
partition_mesh.cpp.

Definition at line 875 of file CommInterface.cpp.

878  {
879  MoFEM::Interface &m_field = cOre;
881 
882  // get layout
883  int rstart, rend, nb_elems;
884  {
885  PetscLayout layout;
886  CHKERR PetscLayoutCreate(m_field.get_comm(), &layout);
887  CHKERR PetscLayoutSetBlockSize(layout, 1);
888  CHKERR PetscLayoutSetSize(layout, ents.size());
889  CHKERR PetscLayoutSetUp(layout);
890  CHKERR PetscLayoutGetSize(layout, &nb_elems);
891  CHKERR PetscLayoutGetRange(layout, &rstart, &rend);
892  CHKERR PetscLayoutDestroy(&layout);
893  if (verb >= VERBOSE) {
894  MOFEM_LOG("SYNC", Sev::inform)
895  << "Finite elements in problem: row lower " << rstart << " row upper "
896  << rend << " nb. elems " << nb_elems << " ( " << ents.size() << " )";
898  }
899  }
900 
901  std::vector<EntityHandle> weight_ents;
902  weight_ents.reserve(rend - rstart + 1);
903 
904  struct AdjBridge {
905  EntityHandle ent;
906  std::vector<int> adj;
907  AdjBridge(const EntityHandle ent, std::vector<int> &adj)
908  : ent(ent), adj(adj) {}
909  };
910 
911  typedef multi_index_container<
912  AdjBridge,
913  indexed_by<
914 
915  hashed_unique<member<AdjBridge, EntityHandle, &AdjBridge::ent>>
916 
917  >>
918  AdjBridgeMap;
919 
920  auto get_it = [&](auto i) {
921  auto it = ents.begin();
922  for (; i > 0; --i) {
923  if (it == ents.end())
924  break;
925  ++it;
926  }
927  return it;
928  };
929 
930  Range proc_ents;
931  proc_ents.insert(get_it(rstart), get_it(rend));
932  if (proc_ents.size() != rend - rstart)
933  SETERRQ2(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
934  "Wrong number of elements in range %d != %d", proc_ents.size(),
935  rend - rstart);
936 
937  Range all_dim_ents;
938  CHKERR m_field.get_moab().get_adjacencies(
939  proc_ents, adj_dim, true, all_dim_ents, moab::Interface::UNION);
940 
941  AdjBridgeMap adj_bridge_map;
942  auto hint = adj_bridge_map.begin();
943  std::vector<int> adj;
944  for (auto ent : all_dim_ents) {
945  Range adj_ents;
946  CHKERR m_field.get_moab().get_adjacencies(&ent, 1, dim, false, adj_ents);
947  adj_ents = intersect(adj_ents, ents);
948  adj.clear();
949  adj.reserve(adj_ents.size());
950  for (auto a : adj_ents)
951  adj.emplace_back(ents.index(a));
952  hint = adj_bridge_map.emplace_hint(hint, ent, adj);
953  }
954 
955  int *_i;
956  int *_j;
957  {
958  const int nb_loc_elements = rend - rstart;
959  std::vector<int> i(nb_loc_elements + 1, 0), j;
960  {
961  std::vector<int> row_adj;
962  Range::iterator fe_it;
963  int ii, jj;
964  size_t max_row_size;
965  for (fe_it = proc_ents.begin(), ii = rstart, jj = 0, max_row_size = 0;
966  fe_it != proc_ents.end(); ++fe_it, ++ii) {
967 
968  if (type_from_handle(*fe_it) == MBENTITYSET) {
969  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
970  "not yet implemented, don't know what to do for meshset "
971  "element");
972  } else {
973 
974  Range dim_ents;
975  CHKERR m_field.get_moab().get_adjacencies(&*fe_it, 1, adj_dim, false,
976  dim_ents);
977  dim_ents = intersect(dim_ents, all_dim_ents);
978 
979  row_adj.clear();
980  for (auto e : dim_ents) {
981  auto adj_it = adj_bridge_map.find(e);
982  if (adj_it != adj_bridge_map.end()) {
983 
984  for (const auto idx : adj_it->adj)
985  row_adj.push_back(idx);
986 
987  } else
988  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
989  "Entity not found");
990  }
991 
992  std::sort(row_adj.begin(), row_adj.end());
993  auto end = std::unique(row_adj.begin(), row_adj.end());
994 
995  size_t row_size = std::distance(row_adj.begin(), end);
996  max_row_size = std::max(max_row_size, row_size);
997  if (j.capacity() < (nb_loc_elements - jj) * max_row_size)
998  j.reserve(nb_loc_elements * max_row_size);
999 
1000  i[jj] = j.size();
1001  auto diag = ents.index(*fe_it);
1002  for (auto it = row_adj.begin(); it != end; ++it)
1003  if (*it != diag)
1004  j.push_back(*it);
1005  }
1006 
1007  ++jj;
1008 
1009  if (th_vertex_weights != NULL)
1010  weight_ents.push_back(*fe_it);
1011  }
1012 
1013  i[jj] = j.size();
1014  }
1015 
1016  CHKERR PetscMalloc(i.size() * sizeof(int), &_i);
1017  CHKERR PetscMalloc(j.size() * sizeof(int), &_j);
1018  copy(i.begin(), i.end(), _i);
1019  copy(j.begin(), j.end(), _j);
1020  }
1021 
1022  // get weights
1023  int *vertex_weights = NULL;
1024  if (th_vertex_weights != NULL) {
1025  CHKERR PetscMalloc(weight_ents.size() * sizeof(int), &vertex_weights);
1026  CHKERR m_field.get_moab().tag_get_data(*th_vertex_weights,
1027  &*weight_ents.begin(),
1028  weight_ents.size(), vertex_weights);
1029  }
1030 
1031  {
1032  Mat Adj;
1033  // Adjacency matrix used to partition problems, f.e. METIS
1034  CHKERR MatCreateMPIAdj(m_field.get_comm(), rend - rstart, nb_elems, _i, _j,
1035  PETSC_NULL, &Adj);
1036  CHKERR MatSetOption(Adj, MAT_STRUCTURALLY_SYMMETRIC, PETSC_TRUE);
1037 
1038  if (debug) {
1039  Mat A;
1040  CHKERR MatConvert(Adj, MATMPIAIJ, MAT_INITIAL_MATRIX, &A);
1041  CHKERR MatView(A, PETSC_VIEWER_DRAW_WORLD);
1042  std::string wait;
1043  std::cin >> wait;
1044  CHKERR MatDestroy(&A);
1045  }
1046 
1047  // run pets to do partitioning
1048  MOFEM_LOG("WORLD", Sev::verbose) << "Start";
1049 
1050  MatPartitioning part;
1051  IS is;
1052  CHKERR MatPartitioningCreate(m_field.get_comm(), &part);
1053 
1054  CHKERR MatPartitioningSetAdjacency(part, Adj);
1055  CHKERR MatPartitioningSetFromOptions(part);
1056  CHKERR MatPartitioningSetNParts(part, n_parts);
1057  if (th_vertex_weights != NULL) {
1058  CHKERR MatPartitioningSetVertexWeights(part, vertex_weights);
1059  }
1060  PetscBool same;
1061  PetscObjectTypeCompare((PetscObject)part, MATPARTITIONINGPARMETIS, &same);
1062  if (same) {
1063 #ifdef PARMETIS
1064  CHKERR MatPartitioningApply_Parmetis_MoFEM(part, &is);
1065 #endif
1066  } else {
1067  CHKERR MatPartitioningApply(part, &is);
1068  }
1069 
1070  MOFEM_LOG("WORLD", Sev::verbose) << "End";
1071 
1072  // gather
1073  IS is_gather, is_num, is_gather_num;
1074  CHKERR ISAllGather(is, &is_gather);
1075  CHKERR ISPartitioningToNumbering(is, &is_num);
1076  CHKERR ISAllGather(is_num, &is_gather_num);
1077 
1078  const int *part_number, *gids;
1079  CHKERR ISGetIndices(is_gather, &part_number);
1080  CHKERR ISGetIndices(is_gather_num, &gids);
1081 
1082  // set partition tag and gid tag to entities
1083  ParallelComm *pcomm = ParallelComm::get_pcomm(
1084  &m_field.get_moab(), m_field.get_basic_entity_data_ptr()->pcommID);
1085  Tag part_tag = pcomm->part_tag();
1086  CHKERR m_field.get_moab().tag_set_data(part_tag, ents, part_number);
1087  Tag gid_tag = m_field.get_moab().globalId_tag();
1088 
1089  std::map<int, Range> parts_ents;
1090  {
1091  // get entities on each part
1092  Range::iterator eit = ents.begin();
1093  for (int ii = 0; eit != ents.end(); eit++, ii++) {
1094  parts_ents[part_number[ii]].insert(*eit);
1095  }
1096  Range tagged_sets;
1097  CHKERR m_field.get_moab().get_entities_by_type_and_tag(
1098  0, MBENTITYSET, &part_tag, NULL, 1, tagged_sets,
1099  moab::Interface::UNION);
1100  if (!tagged_sets.empty())
1101  CHKERR m_field.get_moab().tag_delete_data(part_tag, tagged_sets);
1102 
1103  if (n_parts > (int)tagged_sets.size()) {
1104  // too few partition sets - create missing ones
1105  int num_new = n_parts - tagged_sets.size();
1106  for (int i = 0; i < num_new; i++) {
1107  EntityHandle new_set;
1108  CHKERR m_field.get_moab().create_meshset(MESHSET_SET, new_set);
1109  tagged_sets.insert(new_set);
1110  }
1111  } else if (n_parts < (int)tagged_sets.size()) {
1112  // too many partition sets - delete extras
1113  int num_del = tagged_sets.size() - n_parts;
1114  for (int i = 0; i < num_del; i++) {
1115  EntityHandle old_set = tagged_sets.pop_back();
1116  CHKERR m_field.get_moab().delete_entities(&old_set, 1);
1117  }
1118  }
1119  // write a tag to those sets denoting they're partition sets, with a
1120  // value of the proc number
1121  std::vector<int> dum_ids(n_parts);
1122  for (int i = 0; i < n_parts; i++)
1123  dum_ids[i] = i;
1124  CHKERR m_field.get_moab().tag_set_data(part_tag, tagged_sets,
1125  &*dum_ids.begin());
1126  CHKERR m_field.get_moab().clear_meshset(tagged_sets);
1127 
1128  // get lower dimension entities on each part
1129  for (int pp = 0; pp != n_parts; pp++) {
1130  Range dim_ents = parts_ents[pp].subset_by_dimension(dim);
1131  for (int dd = dim - 1; dd >= 0; dd--) {
1132  Range adj_ents;
1133  CHKERR m_field.get_moab().get_adjacencies(
1134  dim_ents, dd, false, adj_ents, moab::Interface::UNION);
1135  parts_ents[pp].merge(adj_ents);
1136  }
1137  }
1138  for (int pp = 1; pp != n_parts; pp++) {
1139  for (int ppp = 0; ppp != pp; ppp++) {
1140  parts_ents[pp] = subtract(parts_ents[pp], parts_ents[ppp]);
1141  }
1142  }
1143 
1144  for (int pp = 0; pp != n_parts; pp++) {
1145  CHKERR m_field.get_moab().add_entities(tagged_sets[pp], parts_ents[pp]);
1146  }
1147 
1148  auto set_part = [&]() {
1150  for (EntityType t = MBEDGE; t != MBENTITYSET; ++t) {
1151  for (int pp = 0; pp != n_parts; pp++) {
1152  Range type_ents = parts_ents[pp].subset_by_type(t);
1153  CHKERR m_field.get_moab().tag_clear_data(part_tag, type_ents, &pp);
1154  }
1155  }
1157  };
1158 
1159  auto set_gid = [&]() {
1161  for (int d = 0; d != 4; ++d) {
1162 
1163  void *ptr;
1164  int count;
1165 
1166  int gid = 1; // moab indexing from 1
1167  for (int pp = 0; pp != n_parts; pp++) {
1168  Range type_ents = parts_ents[pp].subset_by_dimension(d);
1169 
1170  auto eit = type_ents.begin();
1171  for (; eit != type_ents.end();) {
1172  CHKERR m_field.get_moab().tag_iterate(
1173  gid_tag, eit, type_ents.end(), count, ptr);
1174  auto gid_tag_ptr = static_cast<int *>(ptr);
1175  for (; count > 0; --count) {
1176  *gid_tag_ptr = gid;
1177  ++eit;
1178  ++gid;
1179  ++gid_tag_ptr;
1180  }
1181  }
1182  }
1183  }
1184 
1186  };
1187 
1188  CHKERR set_part();
1189  CHKERR set_gid();
1190  }
1191 
1192  if (debug) {
1193  if (m_field.get_comm_rank() == 0) {
1194  for (int rr = 0; rr != n_parts; rr++) {
1195  ostringstream ss;
1196  ss << "out_part_" << rr << ".vtk";
1197  MOFEM_LOG("SELF", Sev::inform) << "Save debug part mesh " << ss.str();
1198  EntityHandle meshset;
1199  CHKERR m_field.get_moab().create_meshset(MESHSET_SET, meshset);
1200  CHKERR m_field.get_moab().add_entities(meshset, parts_ents[rr]);
1201  CHKERR m_field.get_moab().write_file(ss.str().c_str(), "VTK", "",
1202  &meshset, 1);
1203  CHKERR m_field.get_moab().delete_entities(&meshset, 1);
1204  }
1205  }
1206  }
1207 
1208  CHKERR ISRestoreIndices(is_gather, &part_number);
1209  CHKERR ISRestoreIndices(is_gather_num, &gids);
1210  CHKERR ISDestroy(&is_num);
1211  CHKERR ISDestroy(&is_gather_num);
1212  CHKERR ISDestroy(&is_gather);
1213  CHKERR ISDestroy(&is);
1214  CHKERR MatPartitioningDestroy(&part);
1215  CHKERR MatDestroy(&Adj);
1216  }
1217 
1219 }

◆ partitionProblem()

MoFEMErrorCode MoFEM::ProblemsManager::partitionProblem ( const std::string  name,
int  verb = VERBOSE 
)

partition problem dofs (collective)

Parameters
nameproblem name
Examples
build_problems.cpp, continuity_check_on_skeleton_3d.cpp, mesh_insert_interface_atom.cpp, nonlinear_dynamics.cpp, nonlinear_elastic.cpp, and remove_entities_from_problem_not_partitioned.cpp.

Definition at line 1688 of file ProblemsManager.cpp.

1689  {
1690  MoFEM::Interface &m_field = cOre;
1691  auto problems_ptr = m_field.get_problems();
1693 
1694  MOFEM_LOG("WORLD", Sev::noisy) << "Partition problem " << name;
1695 
1696  using NumeredDofEntitysByIdx =
1698  using ProblemsByName = Problem_multiIndex::index<Problem_mi_tag>::type;
1699 
1700  // Find problem pointer by name
1701  auto &problems_set =
1702  const_cast<ProblemsByName &>(problems_ptr->get<Problem_mi_tag>());
1703  auto p_miit = problems_set.find(name);
1704  if (p_miit == problems_set.end()) {
1705  SETERRQ1(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
1706  "problem with name %s not defined (top tip check spelling)",
1707  name.c_str());
1708  }
1709  int nb_dofs_row = p_miit->getNbDofsRow();
1710 
1711  if (m_field.get_comm_size() != 1) {
1712 
1713  if (!(cOre.getBuildMoFEM() & (1 << 0)))
1714  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "fields not build");
1715  if (!(cOre.getBuildMoFEM() & (1 << 1)))
1716  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "FEs not build");
1717  if (!(cOre.getBuildMoFEM() & (1 << 2)))
1718  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1719  "entFEAdjacencies not build");
1720  if (!(cOre.getBuildMoFEM() & (1 << 3)))
1721  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "Problems not build");
1722 
1723  Mat Adj;
1724  CHKERR m_field.getInterface<MatrixManager>()
1725  ->createMPIAdjWithArrays<Idx_mi_tag>(name, &Adj, verb);
1726 
1727  int m, n;
1728  CHKERR MatGetSize(Adj, &m, &n);
1729  if (verb > VERY_VERBOSE)
1730  MatView(Adj, PETSC_VIEWER_STDOUT_WORLD);
1731 
1732  // partitioning
1733  MatPartitioning part;
1734  IS is;
1735  CHKERR MatPartitioningCreate(m_field.get_comm(), &part);
1736  CHKERR MatPartitioningSetAdjacency(part, Adj);
1737  CHKERR MatPartitioningSetFromOptions(part);
1738  CHKERR MatPartitioningSetNParts(part, m_field.get_comm_size());
1739  CHKERR MatPartitioningApply(part, &is);
1740  if (verb > VERY_VERBOSE)
1741  ISView(is, PETSC_VIEWER_STDOUT_WORLD);
1742 
1743  // gather
1744  IS is_gather, is_num, is_gather_num;
1745  CHKERR ISAllGather(is, &is_gather);
1746  CHKERR ISPartitioningToNumbering(is, &is_num);
1747  CHKERR ISAllGather(is_num, &is_gather_num);
1748  const int *part_number, *petsc_idx;
1749  CHKERR ISGetIndices(is_gather, &part_number);
1750  CHKERR ISGetIndices(is_gather_num, &petsc_idx);
1751  int size_is_num, size_is_gather;
1752  CHKERR ISGetSize(is_gather, &size_is_gather);
1753  if (size_is_gather != (int)nb_dofs_row)
1754  SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1755  "data inconsistency %d != %d", size_is_gather, nb_dofs_row);
1756 
1757  CHKERR ISGetSize(is_num, &size_is_num);
1758  if (size_is_num != (int)nb_dofs_row)
1759  SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1760  "data inconsistency %d != %d", size_is_num, nb_dofs_row);
1761 
1762  bool square_matrix = false;
1763  if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr)
1764  square_matrix = true;
1765 
1766  // if (!square_matrix) {
1767  // // FIXME: This is for back compatibility, if deprecate interface
1768  // function
1769  // // build interfaces is removed, this part of the code will be obsolete
1770  // auto mit_row = p_miit->numeredRowDofsPtr->get<Idx_mi_tag>().begin();
1771  // auto hi_mit_row = p_miit->numeredRowDofsPtr->get<Idx_mi_tag>().end();
1772  // auto mit_col = p_miit->numeredColDofsPtr->get<Idx_mi_tag>().begin();
1773  // auto hi_mit_col = p_miit->numeredColDofsPtr->get<Idx_mi_tag>().end();
1774  // for (; mit_row != hi_mit_row; mit_row++, mit_col++) {
1775  // if (mit_col == hi_mit_col) {
1776  // SETERRQ(
1777  // PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1778  // "check finite element definition, nb. of rows is not equal to "
1779  // "number for columns");
1780  // }
1781  // if (mit_row->get()->getLocalUniqueId() !=
1782  // mit_col->get()->getLocalUniqueId()) {
1783  // SETERRQ(
1784  // PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1785  // "check finite element definition, nb. of rows is not equal to "
1786  // "number for columns");
1787  // }
1788  // }
1789  // }
1790 
1791  auto number_dofs = [&](auto &dofs_idx, auto &counter) {
1793  for (auto miit_dofs_row = dofs_idx.begin();
1794  miit_dofs_row != dofs_idx.end(); miit_dofs_row++) {
1795  const int part = part_number[(*miit_dofs_row)->dofIdx];
1796  if (part == (unsigned int)m_field.get_comm_rank()) {
1797  const bool success = dofs_idx.modify(
1798  miit_dofs_row,
1799  NumeredDofEntity_part_and_indices_change(
1800  part, petsc_idx[(*miit_dofs_row)->dofIdx], counter++));
1801  if (!success) {
1802  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
1803  "modification unsuccessful");
1804  }
1805  } else {
1806  const bool success = dofs_idx.modify(
1807  miit_dofs_row, NumeredDofEntity_part_and_glob_idx_change(
1808  part, petsc_idx[(*miit_dofs_row)->dofIdx]));
1809  if (!success) {
1810  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
1811  "modification unsuccessful");
1812  }
1813  }
1814  }
1816  };
1817 
1818  // Set petsc global indices
1819  auto &dofs_row_by_idx_no_const = const_cast<NumeredDofEntitysByIdx &>(
1820  p_miit->numeredRowDofsPtr->get<Idx_mi_tag>());
1821  int &nb_row_local_dofs = p_miit->nbLocDofsRow;
1822  int &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
1823  nb_row_local_dofs = 0;
1824  nb_row_ghost_dofs = 0;
1825 
1826  CHKERR number_dofs(dofs_row_by_idx_no_const, nb_row_local_dofs);
1827 
1828  int &nb_col_local_dofs = p_miit->nbLocDofsCol;
1829  int &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
1830  if (square_matrix) {
1831  nb_col_local_dofs = nb_row_local_dofs;
1832  nb_col_ghost_dofs = nb_row_ghost_dofs;
1833  } else {
1834  NumeredDofEntitysByIdx &dofs_col_by_idx_no_const =
1835  const_cast<NumeredDofEntitysByIdx &>(
1836  p_miit->numeredColDofsPtr->get<Idx_mi_tag>());
1837  nb_col_local_dofs = 0;
1838  nb_col_ghost_dofs = 0;
1839  CHKERR number_dofs(dofs_col_by_idx_no_const, nb_col_local_dofs);
1840  }
1841 
1842  CHKERR ISRestoreIndices(is_gather, &part_number);
1843  CHKERR ISRestoreIndices(is_gather_num, &petsc_idx);
1844  CHKERR ISDestroy(&is_num);
1845  CHKERR ISDestroy(&is_gather_num);
1846  CHKERR ISDestroy(&is_gather);
1847  CHKERR ISDestroy(&is);
1848  CHKERR MatPartitioningDestroy(&part);
1849  CHKERR MatDestroy(&Adj);
1850  CHKERR printPartitionedProblem(&*p_miit, verb);
1851  } else {
1852 
1853  auto number_dofs = [&](auto &dof_idx, auto &counter) {
1855  for (auto miit_dofs_row = dof_idx.begin(); miit_dofs_row != dof_idx.end();
1856  miit_dofs_row++) {
1857  const bool success = dof_idx.modify(
1858  miit_dofs_row,
1859  NumeredDofEntity_part_and_indices_change(0, counter, counter));
1860  ++counter;
1861  if (!success) {
1862  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
1863  "modification unsuccessful");
1864  }
1865  }
1867  };
1868 
1869  auto &dofs_row_by_idx_no_const = const_cast<NumeredDofEntitysByIdx &>(
1870  p_miit->numeredRowDofsPtr->get<Idx_mi_tag>());
1871  int &nb_row_local_dofs = p_miit->nbLocDofsRow;
1872  int &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
1873  nb_row_local_dofs = 0;
1874  nb_row_ghost_dofs = 0;
1875 
1876  CHKERR number_dofs(dofs_row_by_idx_no_const, nb_row_local_dofs);
1877 
1878  bool square_matrix = false;
1879  if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr)
1880  square_matrix = true;
1881 
1882  int &nb_col_local_dofs = p_miit->nbLocDofsCol;
1883  int &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
1884  if (square_matrix) {
1885  nb_col_local_dofs = nb_row_local_dofs;
1886  nb_col_ghost_dofs = nb_row_ghost_dofs;
1887  } else {
1888  NumeredDofEntitysByIdx &dofs_col_by_idx_no_const =
1889  const_cast<NumeredDofEntitysByIdx &>(
1890  p_miit->numeredColDofsPtr->get<Idx_mi_tag>());
1891  nb_col_local_dofs = 0;
1892  nb_col_ghost_dofs = 0;
1893  CHKERR number_dofs(dofs_col_by_idx_no_const, nb_col_local_dofs);
1894  }
1895  }
1896 
1897  cOre.getBuildMoFEM() |= 1 << 4;
1899 }

◆ partitionSimpleProblem()

MoFEMErrorCode MoFEM::ProblemsManager::partitionSimpleProblem ( const std::string  name,
int  verb = VERBOSE 
)

partition problem dofs

Parameters
nameproblem name
Examples
forces_and_sources_testing_edge_element.cpp, forces_and_sources_testing_flat_prism_element.cpp, hcurl_divergence_operator_2d.cpp, prism_elements_from_surface.cpp, prism_polynomial_approximation.cpp, and quad_polynomial_approximation.cpp.

Definition at line 1542 of file ProblemsManager.cpp.

1543  {
1544 
1545  MoFEM::Interface &m_field = cOre;
1546  auto problems_ptr = m_field.get_problems();
1548 
1550  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "fields not build");
1551  if (!(cOre.getBuildMoFEM() & Core::BUILD_FE))
1552  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "FEs not build");
1553  if (!(cOre.getBuildMoFEM() & Core::BUILD_ADJ))
1554  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "adjacencies not build");
1556  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "adjacencies not build");
1557  MOFEM_LOG("WORLD", Sev::verbose) << "Simple partition problem " << name;
1558 
1559  // find p_miit
1561  ProblemByName &problems_set =
1562  const_cast<ProblemByName &>(problems_ptr->get<Problem_mi_tag>());
1563  ProblemByName::iterator p_miit = problems_set.find(name);
1564  if (p_miit == problems_set.end()) {
1565  SETERRQ1(PETSC_COMM_SELF, 1,
1566  "problem < %s > is not found (top tip: check spelling)",
1567  name.c_str());
1568  }
1569  typedef boost::multi_index::index<NumeredDofEntity_multiIndex,
1570  Idx_mi_tag>::type NumeredDofEntitysByIdx;
1571  NumeredDofEntitysByIdx &dofs_row_by_idx =
1572  p_miit->numeredRowDofsPtr->get<Idx_mi_tag>();
1573  NumeredDofEntitysByIdx &dofs_col_by_idx =
1574  p_miit->numeredColDofsPtr->get<Idx_mi_tag>();
1575  boost::multi_index::index<NumeredDofEntity_multiIndex,
1576  Idx_mi_tag>::type::iterator miit_row,
1577  hi_miit_row;
1578  boost::multi_index::index<NumeredDofEntity_multiIndex,
1579  Idx_mi_tag>::type::iterator miit_col,
1580  hi_miit_col;
1581  DofIdx &nb_row_local_dofs = p_miit->nbLocDofsRow;
1582  DofIdx &nb_row_ghost_dofs = p_miit->nbGhostDofsRow;
1583  nb_row_local_dofs = 0;
1584  nb_row_ghost_dofs = 0;
1585  DofIdx &nb_col_local_dofs = p_miit->nbLocDofsCol;
1586  DofIdx &nb_col_ghost_dofs = p_miit->nbGhostDofsCol;
1587  nb_col_local_dofs = 0;
1588  nb_col_ghost_dofs = 0;
1589 
1590  bool square_matrix = false;
1591  if (p_miit->numeredRowDofsPtr == p_miit->numeredColDofsPtr) {
1592  square_matrix = true;
1593  }
1594 
1595  // get row range of local indices
1596  PetscLayout layout_row;
1597  const int *ranges_row;
1598 
1599  DofIdx nb_dofs_row = dofs_row_by_idx.size();
1600  CHKERR PetscLayoutCreate(m_field.get_comm(), &layout_row);
1601  CHKERR PetscLayoutSetBlockSize(layout_row, 1);
1602  CHKERR PetscLayoutSetSize(layout_row, nb_dofs_row);
1603  CHKERR PetscLayoutSetUp(layout_row);
1604  CHKERR PetscLayoutGetRanges(layout_row, &ranges_row);
1605  // get col range of local indices
1606  PetscLayout layout_col;
1607  const int *ranges_col;
1608  if (!square_matrix) {
1609  DofIdx nb_dofs_col = dofs_col_by_idx.size();
1610  CHKERR PetscLayoutCreate(m_field.get_comm(), &layout_col);
1611  CHKERR PetscLayoutSetBlockSize(layout_col, 1);
1612  CHKERR PetscLayoutSetSize(layout_col, nb_dofs_col);
1613  CHKERR PetscLayoutSetUp(layout_col);
1614  CHKERR PetscLayoutGetRanges(layout_col, &ranges_col);
1615  }
1616  for (unsigned int part = 0; part < (unsigned int)m_field.get_comm_size();
1617  part++) {
1618  miit_row = dofs_row_by_idx.lower_bound(ranges_row[part]);
1619  hi_miit_row = dofs_row_by_idx.lower_bound(ranges_row[part + 1]);
1620  if (std::distance(miit_row, hi_miit_row) !=
1621  ranges_row[part + 1] - ranges_row[part]) {
1622  SETERRQ4(
1623  PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1624  "data inconsistency, std::distance(miit_row,hi_miit_row) != rend - "
1625  "rstart (%d != %d - %d = %d) ",
1626  std::distance(miit_row, hi_miit_row), ranges_row[part + 1],
1627  ranges_row[part], ranges_row[part + 1] - ranges_row[part]);
1628  }
1629  // loop rows
1630  for (; miit_row != hi_miit_row; miit_row++) {
1631  bool success = dofs_row_by_idx.modify(
1632  miit_row,
1633  NumeredDofEntity_part_and_glob_idx_change(part, (*miit_row)->dofIdx));
1634  if (!success)
1635  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
1636  "modification unsuccessful");
1637  if (part == (unsigned int)m_field.get_comm_rank()) {
1638  success = dofs_row_by_idx.modify(
1639  miit_row, NumeredDofEntity_local_idx_change(nb_row_local_dofs++));
1640  if (!success)
1641  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
1642  "modification unsuccessful");
1643  }
1644  }
1645  if (!square_matrix) {
1646  miit_col = dofs_col_by_idx.lower_bound(ranges_col[part]);
1647  hi_miit_col = dofs_col_by_idx.lower_bound(ranges_col[part + 1]);
1648  if (std::distance(miit_col, hi_miit_col) !=
1649  ranges_col[part + 1] - ranges_col[part]) {
1650  SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
1651  "data inconsistency, std::distance(miit_col,hi_miit_col) != "
1652  "rend - "
1653  "rstart (%d != %d - %d = %d) ",
1654  std::distance(miit_col, hi_miit_col), ranges_col[part + 1],
1655  ranges_col[part], ranges_col[part + 1] - ranges_col[part]);
1656  }
1657  // loop cols
1658  for (; miit_col != hi_miit_col; miit_col++) {
1659  bool success = dofs_col_by_idx.modify(
1660  miit_col, NumeredDofEntity_part_and_glob_idx_change(
1661  part, (*miit_col)->dofIdx));
1662  if (!success)
1663  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
1664  "modification unsuccessful");
1665  if (part == (unsigned int)m_field.get_comm_rank()) {
1666  success = dofs_col_by_idx.modify(
1667  miit_col, NumeredDofEntity_local_idx_change(nb_col_local_dofs++));
1668  if (!success)
1669  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
1670  "modification unsuccessful");
1671  }
1672  }
1673  }
1674  }
1675  CHKERR PetscLayoutDestroy(&layout_row);
1676  if (!square_matrix) {
1677  CHKERR PetscLayoutDestroy(&layout_col);
1678  }
1679  if (square_matrix) {
1680  nb_col_local_dofs = nb_row_local_dofs;
1681  nb_col_ghost_dofs = nb_row_ghost_dofs;
1682  }
1683  CHKERR printPartitionedProblem(&*p_miit, verb);
1686 }

◆ removeDofsOnEntities() [1/2]

MoFEMErrorCode MoFEM::ProblemsManager::removeDofsOnEntities ( const std::string  problem_name,
const std::string  field_name,
const BitRefLevel  bit_ref_level,
const BitRefLevel  bit_ref_mask,
Range ents_ptr = nullptr,
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 by bit ref level.

See for more detail other implementation for removeDofsOnEntities.

Parameters
problem_namename of the problem
field_namename of the field
bit_ref_levelbit ref level on which DOFs are removed
bit_ref_maskbit ref mask on which DOFs are removed
ents_ptrfilter entities with given bit and mask
lo_coefflow dof coefficient (rank)
hi_coeffhigh dof coefficient (rank)
verbverbosity level
debugto debug and seek for inconsistencies set to true
Returns
MoFEMErrorCode

Definition at line 3508 of file ProblemsManager.cpp.

3512  {
3513  MoFEM::Interface &m_field = cOre;
3515 
3516  auto bit_manager = m_field.getInterface<BitRefManager>();
3517 
3518  Range ents;
3519  if (ents_ptr) {
3520  ents = *ents_ptr;
3521  CHKERR bit_manager->filterEntitiesByRefLevel(bit_ref_level, bit_ref_mask,
3522  ents, verb);
3523  } else {
3524  CHKERR bit_manager->getEntitiesByRefLevel(bit_ref_level, bit_ref_mask, ents,
3525  verb);
3526  }
3527 
3528  CHKERR removeDofsOnEntities(problem_name, field_name, ents, lo_coeff,
3529  hi_coeff, lo_order, hi_order, verb, debug);
3530 
3532 }

◆ removeDofsOnEntities() [2/2]

MoFEMErrorCode MoFEM::ProblemsManager::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.

Remove DOFs from problem which are on entities on the given range and given field name. On the finite element level, DOFs can be still accessed however local PETSc indices and global PETSc indices are marked with the index -1.

Note
If the index is marked -1 it is not assembled and dropped by VecSetValues and MatSetValues.
Todo:
Not yet implemented update for AO maps and IS ranges if removed entities in composite problem or sub-problem
Parameters
problem_namename of the problem
field_namename of the field
entsentities on which DOFs are removed
lo_coefflow dof coefficient (rank)
hi_coeffhigh dof coefficient (rank)
verbverbosity level
debugto debug and seek for inconsistencies set to true
Returns
MoFEMErrorCode
Examples
hanging_node_approx.cpp, and remove_entities_from_problem.cpp.

Definition at line 2968 of file ProblemsManager.cpp.

2971  {
2972 
2973  MoFEM::Interface &m_field = cOre;
2975 
2976  const Problem *prb_ptr;
2977  CHKERR m_field.get_problem(problem_name, &prb_ptr);
2978 
2979  decltype(prb_ptr->numeredRowDofsPtr) numered_dofs[2] = {
2980  prb_ptr->numeredRowDofsPtr, nullptr};
2981  if (prb_ptr->numeredRowDofsPtr != prb_ptr->numeredColDofsPtr)
2982  numered_dofs[1] = prb_ptr->numeredColDofsPtr;
2983 
2984  int *nbdof_ptr[] = {&prb_ptr->nbDofsRow, &prb_ptr->nbDofsCol};
2985  int *local_nbdof_ptr[] = {&prb_ptr->nbLocDofsRow, &prb_ptr->nbLocDofsCol};
2986  int *ghost_nbdof_ptr[] = {&prb_ptr->nbGhostDofsRow, &prb_ptr->nbGhostDofsCol};
2987 
2988  const int nb_init_row_dofs = prb_ptr->getNbDofsRow();
2989  const int nb_init_col_dofs = prb_ptr->getNbDofsCol();
2990  const int nb_init_loc_row_dofs = prb_ptr->getNbLocalDofsRow();
2991  // const int nb_init_loc_col_dofs = prb_ptr->getNbLocalDofsCol();
2992  const int nb_init_ghost_row_dofs = prb_ptr->getNbGhostDofsRow();
2993  const int nb_init_ghost_col_dofs = prb_ptr->getNbGhostDofsCol();
2994 
2995  for (int s = 0; s != 2; ++s)
2996  if (numered_dofs[s]) {
2997 
2998  using NumeredDofEntity_it_view_multiIndex = multi_index_container<
2999 
3000  NumeredDofEntity_multiIndex::iterator, indexed_by<sequenced<>>
3001 
3002  >;
3003 
3004  const auto bit_number = m_field.get_field_bit_number(field_name);
3005  NumeredDofEntity_it_view_multiIndex dofs_it_view;
3006 
3007  // Set -1 to global and local dofs indices
3008  for (auto pit = ents.const_pair_begin(); pit != ents.const_pair_end();
3009  ++pit) {
3010  auto lo = numered_dofs[s]->get<Unique_mi_tag>().lower_bound(
3011  DofEntity::getLoFieldEntityUId(bit_number, pit->first));
3012  auto hi = numered_dofs[s]->get<Unique_mi_tag>().upper_bound(
3013  DofEntity::getHiFieldEntityUId(bit_number, pit->second));
3014 
3015  for (; lo != hi; ++lo)
3016  if ((*lo)->getDofCoeffIdx() >= lo_coeff &&
3017  (*lo)->getDofCoeffIdx() <= hi_coeff &&
3018  (*lo)->getDofOrder() >= lo_order &&
3019  (*lo)->getDofOrder() <= hi_order)
3020  dofs_it_view.emplace_back(numered_dofs[s]->project<0>(lo));
3021  }
3022 
3023  if (verb > QUIET) {
3024  for (auto &dof : dofs_it_view)
3025  MOFEM_LOG("SYNC", Sev::noisy) << **dof;
3026  MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
3027  }
3028 
3029  // create weak view
3030  std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_weak_view;
3031  dofs_weak_view.reserve(dofs_it_view.size());
3032  for (auto dit : dofs_it_view)
3033  dofs_weak_view.push_back(*dit);
3034 
3035  if (verb >= NOISY)
3036  MOFEM_LOG_C("SYNC", Sev::noisy,
3037  "Number of DOFs in multi-index %d and to delete %d\n",
3038  numered_dofs[s]->size(), dofs_it_view.size());
3039 
3040  // erase dofs from problem
3041  for (auto weak_dit : dofs_weak_view)
3042  if (auto dit = weak_dit.lock()) {
3043  numered_dofs[s]->erase(dit->getLocalUniqueId());
3044  }
3045 
3046  if (verb >= NOISY)
3047  MOFEM_LOG_C("SYNC", Sev::noisy,
3048  "Number of DOFs in multi-index after delete %d\n",
3049  numered_dofs[s]->size());
3050 
3051  // get current number of ghost dofs
3052  int nb_local_dofs = 0;
3053  int nb_ghost_dofs = 0;
3054  for (auto dit = numered_dofs[s]->get<PetscLocalIdx_mi_tag>().begin();
3055  dit != numered_dofs[s]->get<PetscLocalIdx_mi_tag>().end(); ++dit) {
3056  if ((*dit)->getPetscLocalDofIdx() >= 0 &&
3057  (*dit)->getPetscLocalDofIdx() < *(local_nbdof_ptr[s]))
3058  ++nb_local_dofs;
3059  else if ((*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[s]))
3060  ++nb_ghost_dofs;
3061  else
3062  SETERRQ1(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
3063  "Impossible case. You could run problem on no distributed "
3064  "mesh. That is not implemented. Dof local index is %d",
3065  (*dit)->getPetscLocalDofIdx());
3066  }
3067 
3068  // get indices
3069  auto get_indices_by_tag = [&](auto tag, auto &indices, bool only_local) {
3070  const int nb_dofs = numered_dofs[s]->size();
3071  indices.clear();
3072  indices.reserve(nb_dofs);
3073  for (auto dit = numered_dofs[s]->get<decltype(tag)>().begin();
3074  dit != numered_dofs[s]->get<decltype(tag)>().end(); ++dit) {
3075  bool add = true;
3076  if (only_local) {
3077  if ((*dit)->getPetscLocalDofIdx() < 0 ||
3078  (*dit)->getPetscLocalDofIdx() >= *(local_nbdof_ptr[s])) {
3079  add = false;
3080  }
3081  }
3082  if (add)
3083  indices.push_back(decltype(tag)::get_index(dit));
3084  }
3085  };
3086 
3087  auto get_indices_by_uid = [&](auto tag, auto &indices) {
3088  const int nb_dofs = numered_dofs[s]->size();
3089  indices.clear();
3090  indices.reserve(nb_dofs);
3091  for (auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3092  ++dit)
3093  indices.push_back(decltype(tag)::get_index(dit));
3094  };
3095 
3096  auto get_sub_ao = [&](auto sub_data) {
3097  if (s == 0) {
3098  return sub_data->getSmartRowMap();
3099  } else {
3100  return sub_data->getSmartColMap();
3101  }
3102  };
3103 
3104  auto set_sub_is_and_ao = [&s, &prb_ptr](auto sub_data, auto is, auto ao) {
3105  if (s == 0) {
3106  sub_data->rowIs = is;
3107  sub_data->rowMap = ao;
3108  sub_data->colIs = is; // if square problem col is equal to row
3109  sub_data->colMap = ao;
3110  } else {
3111  sub_data->colIs = is;
3112  sub_data->colMap = ao;
3113  }
3114  };
3115 
3116  auto apply_symmetry = [&s, &prb_ptr](auto sub_data) {
3117  if (s == 0) {
3118  if (prb_ptr->numeredRowDofsPtr == prb_ptr->numeredColDofsPtr) {
3119  sub_data->colIs = sub_data->getSmartRowIs();
3120  sub_data->colMap = sub_data->getSmartRowMap();
3121  }
3122  }
3123  };
3124 
3125  auto concatenate_dofs = [&](auto tag, auto &indices,
3126  const auto local_only) {
3128  get_indices_by_tag(tag, indices, local_only);
3129 
3130  SmartPetscObj<AO> ao;
3131  // Create AO from app indices (i.e. old), to pestc indices (new after
3132  // remove)
3133  if (local_only)
3134  ao = createAOMapping(m_field.get_comm(), indices.size(),
3135  &*indices.begin(), PETSC_NULL);
3136  else
3137  ao = createAOMapping(PETSC_COMM_SELF, indices.size(),
3138  &*indices.begin(), PETSC_NULL);
3139 
3140  // Set mapping to sub dm data
3141  if (local_only) {
3142  if (auto sub_data = prb_ptr->getSubData()) {
3143  // create is and then map it to main problem of sub-problem
3144  auto sub_is = createISGeneral(m_field.get_comm(), indices.size(),
3145  &*indices.begin(), PETSC_COPY_VALUES);
3146  // get old app, i.e. oroginal befor sub indices, and ao, from app,
3147  // to petsc sub indices.
3148  auto sub_ao = get_sub_ao(sub_data);
3149  CHKERR AOPetscToApplicationIS(sub_ao, sub_is);
3150  sub_ao = createAOMappingIS(sub_is, PETSC_NULL);
3151  // set new sub ao
3152  set_sub_is_and_ao(sub_data, sub_is, sub_ao);
3153  apply_symmetry(sub_data);
3154  } else {
3155  // create sub data
3156  prb_ptr->getSubData() =
3157  boost::make_shared<Problem::SubProblemData>();
3158  auto sub_is = createISGeneral(m_field.get_comm(), indices.size(),
3159  &*indices.begin(), PETSC_COPY_VALUES);
3160  // set sub is ao
3161  set_sub_is_and_ao(prb_ptr->getSubData(), sub_is, ao);
3162  apply_symmetry(prb_ptr->getSubData());
3163  }
3164  }
3165 
3166  get_indices_by_uid(tag, indices);
3167  CHKERR AOApplicationToPetsc(ao, indices.size(), &*indices.begin());
3168 
3170  };
3171 
3172  // set indices index
3173  auto set_concatenated_indices = [&]() {
3174  std::vector<int> global_indices;
3175  std::vector<int> local_indices;
3177  CHKERR concatenate_dofs(PetscGlobalIdx_mi_tag(), global_indices, true);
3178  CHKERR concatenate_dofs(PetscLocalIdx_mi_tag(), local_indices, false);
3179  auto gi = global_indices.begin();
3180  auto li = local_indices.begin();
3181  for (auto dit = numered_dofs[s]->begin(); dit != numered_dofs[s]->end();
3182  ++dit) {
3183  auto mod = NumeredDofEntity_part_and_all_indices_change(
3184  (*dit)->getPart(), (*dit)->getDofIdx(), *gi, *li);
3185  bool success = numered_dofs[s]->modify(dit, mod);
3186  if (!success)
3187  SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
3188  "can not set negative indices");
3189  ++gi;
3190  ++li;
3191  }
3193  };
3194  CHKERR set_concatenated_indices();
3195 
3196  MPI_Allreduce(&nb_local_dofs, nbdof_ptr[s], 1, MPI_INT, MPI_SUM,
3197  m_field.get_comm());
3198  *(local_nbdof_ptr[s]) = nb_local_dofs;
3199  *(ghost_nbdof_ptr[s]) = nb_ghost_dofs;
3200 
3201  if (debug)
3202  for (auto dof : (*numered_dofs[s])) {
3203  if (dof->getPetscGlobalDofIdx() < 0) {
3204  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
3205  "Negative global idx");
3206  }
3207  if (dof->getPetscLocalDofIdx() < 0) {
3208  SETERRQ(m_field.get_comm(), MOFEM_DATA_INCONSISTENCY,
3209  "Negative local idx");
3210  }
3211  }
3212 
3213  } else {
3214 
3215  *(nbdof_ptr[1]) = *(nbdof_ptr[0]);
3216  *(local_nbdof_ptr[1]) = *(local_nbdof_ptr[0]);
3217  *(ghost_nbdof_ptr[1]) = *(ghost_nbdof_ptr[0]);
3218  }
3219 
3220  if (verb > QUIET) {
3221  MOFEM_LOG_C(
3222  "WORLD", Sev::inform,
3223  "Removed DOFs from problem %s dofs [%d / %d (before %d / %d) global]",
3224  prb_ptr->getName().c_str(), prb_ptr->getNbDofsRow(),
3225  prb_ptr->getNbDofsCol(), nb_init_row_dofs, nb_init_col_dofs);
3226  MOFEM_LOG_C("SYNC", Sev::verbose,
3227  "Removed DOFs from problem %s dofs [ %d / %d "
3228  "(before %d / %d) local, %d / %d (before %d / %d)]",
3229  prb_ptr->getName().c_str(), prb_ptr->getNbLocalDofsRow(),
3230  prb_ptr->getNbLocalDofsCol(), nb_init_loc_row_dofs,
3231  nb_init_loc_row_dofs, prb_ptr->getNbGhostDofsRow(),
3232  prb_ptr->getNbGhostDofsCol(), nb_init_ghost_row_dofs,
3233  nb_init_ghost_col_dofs);
3234  MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::verbose);
3235  }
3236 
3238 }
MoFEMFunctionReturnHot
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:460
MoFEM::UnknownInterface::getInterface
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Definition: UnknownInterface.hpp:93
MoFEM::createAOMappingIS
auto createAOMappingIS(IS isapp, IS ispetsc)
Creates an application mapping using two index sets.
Definition: PetscSmartObj.hpp:318
MoFEM::ProblemsManager::buildProblemFromFields
PetscBool buildProblemFromFields
Definition: ProblemsManager.hpp:30
MoFEM::CoreInterface::get_field_name
virtual std::string get_field_name(const BitFieldId id) const =0
get field name from id
MoFEM::FieldEntity::getGlobalUniqueIdCalculate
UId getGlobalUniqueIdCalculate() const
Calculate global UId.
Definition: FieldEntsMultiIndices.hpp:216
MoFEM::CoreInterface::get_ents_finite_elements
virtual const EntFiniteElement_multiIndex * get_ents_finite_elements() const =0
Get the ents finite elements object.
MoFEM::debug
const static bool debug
Definition: ConstrainMatrixCtx.cpp:9
MoFEM::ProblemsManager::buildProblem
MoFEMErrorCode buildProblem(const std::string name, const bool square_matrix, int verb=VERBOSE)
build problem data structures
Definition: ProblemsManager.cpp:87
ProblemManagerFunctionBegin
#define ProblemManagerFunctionBegin
Definition: ProblemsManager.cpp:8
MoFEM::field_bit_from_bit_number
auto field_bit_from_bit_number(const int bit_number)
get field bit id from bit number
Definition: Templates.hpp:1930
MOFEM_LOG_SEVERITY_SYNC
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
Definition: LogManager.hpp:352
MoFEM::createISGeneral
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.
Definition: PetscSmartObj.hpp:287
EntityHandle
NOISY
@ NOISY
Definition: definitions.h:224
MoFEM::CoreInterface::get_comm
virtual MPI_Comm & get_comm() const =0
MoFEM::CoreInterface::get_field_bit_number
virtual FieldBitNumber get_field_bit_number(const std::string name) const =0
get field bit number
MoFEM::CoreInterface::get_comm_rank
virtual int get_comm_rank() const =0
MoFEM::Types::BitFieldId
std::bitset< BITFIELDID_SIZE > BitFieldId
Field Id.
Definition: Types.hpp:42
MoFEM::CoreInterface::get_problem
virtual const Problem * get_problem(const std::string problem_name) const =0
Get the problem object.
A
constexpr AssemblyType A
Definition: operators_tests.cpp:30
MoFEM::CoreTmp< 0 >::BUILD_ADJ
@ BUILD_ADJ
Definition: Core.hpp:214
MoFEM::CoreInterface::get_finite_elements
virtual const FiniteElement_multiIndex * get_finite_elements() const =0
Get the finite elements object.
MoFEM::ProblemsManager::printPartitionedProblem
MoFEMErrorCode printPartitionedProblem(const Problem *problem_ptr, int verb=VERBOSE)
Definition: ProblemsManager.cpp:2070
MoFEM::ProblemsManager::debugPartitionedProblem
MoFEMErrorCode debugPartitionedProblem(const Problem *problem_ptr, int verb=VERBOSE)
Definition: ProblemsManager.cpp:2089
MoFEM::DofEntity_multiIndex_active_view
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
Definition: DofsMultiIndices.hpp:370
sdf.r
int r
Definition: sdf.py:8
MoFEM::DeprecatedCoreInterface
Deprecated interface functions.
Definition: DeprecatedCoreInterface.hpp:16
ROW
@ ROW
Definition: definitions.h:136
MoFEM::CoreInterface::get_dofs
virtual const DofEntity_multiIndex * get_dofs() const =0
Get the dofs object.
NumeredDofEntity_multiIndex
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.
Definition: DofsMultiIndices.hpp:469
MoFEM::NumeredDofEntityByUId
NumeredDofEntity_multiIndex::index< Unique_mi_tag >::type NumeredDofEntityByUId
Numbered DoF multi-index by UId.
Definition: DofsMultiIndices.hpp:476
VERBOSE
@ VERBOSE
Definition: definitions.h:222
MoFEM::createAOMapping
auto createAOMapping(MPI_Comm comm, PetscInt napp, const PetscInt myapp[], const PetscInt mypetsc[])
Creates an application mapping using two integer arrays.
Definition: PetscSmartObj.hpp:338
CHKERR
#define CHKERR
Inline error check.
Definition: definitions.h:548
MoFEM::CoreInterface::get_moab
virtual moab::Interface & get_moab()=0
MoFEM::ProblemsManager::cOre
MoFEM::Core & cOre
Definition: ProblemsManager.hpp:26
a
constexpr double a
Definition: approx_sphere.cpp:30
MOFEM_LOG_C
#define MOFEM_LOG_C(channel, severity, format,...)
Definition: LogManager.hpp:311
MoFEM::FieldEntity::getHandleFromUniqueId
static auto getHandleFromUniqueId(const UId uid)
Get the Handle From Unique Id.
Definition: FieldEntsMultiIndices.hpp:192
MoFEM::Types::UId
uint128_t UId
Unique Id.
Definition: Types.hpp:31
MoFEM::get_temp_meshset_ptr
auto get_temp_meshset_ptr(moab::Interface &moab)
Create smart pointer to temporary meshset.
Definition: Templates.hpp:1886
MoFEM::ProblemsManager::removeDofsOnEntities
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.
Definition: ProblemsManager.cpp:2968
convert.type
type
Definition: convert.py:64
MoFEM::FieldEntity::getLocalUniqueIdCalculate
UId getLocalUniqueIdCalculate()
Get the Local Unique Id Calculate object.
Definition: FieldEntsMultiIndices.hpp:136
MoFEM::CoreInterface::get_basic_entity_data_ptr
virtual boost::shared_ptr< BasicEntityData > & get_basic_entity_data_ptr()=0
Get pointer to basic entity data.
MoFEM::EntFiniteElement::getLocalUniqueIdCalculate
UId getLocalUniqueIdCalculate() const
Generate UId for finite element entity.
Definition: FEMultiIndices.hpp:528
MoFEM::CoreTmp< 0 >::BUILD_FIELD
@ BUILD_FIELD
Definition: Core.hpp:212
MOFEM_LOG_SYNCHRONISE
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
Definition: LogManager.hpp:345
MoFEM::FieldEntity::getLoBitNumberUId
static UId getLoBitNumberUId(const FieldBitNumber bit_number)
Definition: FieldEntsMultiIndices.hpp:222
COL
@ COL
Definition: definitions.h:136
MoFEM::NumeredDofEntity_multiIndex_uid_view_ordered
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
Definition: DofsMultiIndices.hpp:503
MoFEM::CoreInterface::get_comm_size
virtual int get_comm_size() const =0
MoFEM::ProblemsManager::getOptions
MoFEMErrorCode getOptions()
Definition: ProblemsManager.cpp:62
MoFEM::CoreInterface::get_field_ents
virtual const FieldEntity_multiIndex * get_field_ents() const =0
Get the field ents object.
MoFEM::CoreTmp< 0 >::BUILD_PROBLEM
@ BUILD_PROBLEM
Definition: Core.hpp:215
MoFEM::CoreTmp< 0 >::PARTITION_PROBLEM
@ PARTITION_PROBLEM
Definition: Core.hpp:216
MOFEM_OPERATION_UNSUCCESSFUL
@ MOFEM_OPERATION_UNSUCCESSFUL
Definition: definitions.h:34
MoFEM::type_from_handle
auto type_from_handle(const EntityHandle h)
get type from entity handle
Definition: Templates.hpp:1898
MoFEM::FieldEntity_multiIndex_global_uid_view
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
Definition: FieldEntsMultiIndices.hpp:444
MoFEM::CoreInterface::get_problems
virtual const Problem_multiIndex * get_problems() const =0
Get the problems object.
t
constexpr double t
plate stiffness
Definition: plate.cpp:58
i
FTensor::Index< 'i', SPACE_DIM > i
Definition: hcurl_divergence_operator_2d.cpp:27
MoFEM::DofEntity_multiIndex_global_uid_view
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
Definition: DofsMultiIndices.hpp:349
MoFEM::DofEntity::getLoFieldEntityUId
static UId getLoFieldEntityUId(const FieldBitNumber bit, const EntityHandle ent)
Definition: DofsMultiIndices.hpp:69
MOFEM_NOT_FOUND
@ MOFEM_NOT_FOUND
Definition: definitions.h:33
NumeredEntFiniteElement_multiIndex
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.
Definition: FEMultiIndices.hpp:830
field_name
constexpr auto field_name
Definition: poisson_2d_homogeneous.cpp:13
convert.n
n
Definition: convert.py:82
MoFEM::CoreInterface::get_fields
virtual const Field_multiIndex * get_fields() const =0
Get the fields object.
MoFEM::Problem::numeredRowDofsPtr
boost::shared_ptr< NumeredDofEntity_multiIndex > numeredRowDofsPtr
store DOFs on rows for this problem
Definition: ProblemsMultiIndices.hpp:73
MAX_DOFS_ON_ENTITY
#define MAX_DOFS_ON_ENTITY
Maximal number of DOFs on entity.
Definition: definitions.h:249
v
const double v
phase velocity of light in medium (cm/ns)
Definition: initial_diffusion.cpp:40
MoFEM::CoreTmp< 0 >::PARTITION_FE
@ PARTITION_FE
Definition: Core.hpp:217
Range
MoFEM::CoreTmp< 0 >::getBuildMoFEM
int & getBuildMoFEM() const
Get flags/semaphores for different stages.
Definition: Core.hpp:225
MoFEM::ProblemsManager::MOFEM_EVENT_ProblemsManager
PetscLogEvent MOFEM_EVENT_ProblemsManager
Definition: ProblemsManager.hpp:495
FTensor::dd
const Tensor2_symmetric_Expr< const ddTensor0< T, Dim, i, j >, typename promote< T, double >::V, Dim, i, j > dd(const Tensor0< T * > &a, const Index< i, Dim > index1, const Index< j, Dim > index2, const Tensor1< int, Dim > &d_ijk, const Tensor1< double, Dim > &d_xyz)
Definition: ddTensor0.hpp:33
MOFEM_LOG
#define MOFEM_LOG(channel, severity)
Log.
Definition: LogManager.hpp:308
MoFEM::CommInterface::debug
static bool debug
Definition: CommInterface.hpp:23
MoFEM::EntFiniteElement::getDofView
static MoFEMErrorCode getDofView(const FE_ENTS &fe_ents_view, const MOFEM_DOFS &mofem_dofs, MOFEM_DOFS_VIEW &dofs_view, INSERTER &&inserter)
Definition: FEMultiIndices.hpp:583
MoFEM::DofEntity::getHiFieldEntityUId
static UId getHiFieldEntityUId(const FieldBitNumber bit, const EntityHandle ent)
Definition: DofsMultiIndices.hpp:75
MoFEM::ProblemsManager::synchroniseProblemEntities
PetscBool synchroniseProblemEntities
DOFs in fields, not from DOFs on elements.
Definition: ProblemsManager.hpp:33
HenckyOps::f
auto f
Definition: HenckyOps.hpp:15
j
FTensor::Index< 'j', 3 > j
Definition: matrix_function.cpp:19
MoFEM::CoreInterface::get_ents_elements_adjacency
virtual MoFEMErrorCode get_ents_elements_adjacency(const FieldEntityEntFiniteElementAdjacencyMap_multiIndex **dofs_elements_adjacency) const =0
Get the dofs elements adjacency object.
EigenMatrix::Vec
const FTensor::Tensor2< T, Dim, Dim > Vec
Definition: MatrixFunction.hpp:64
MOFEM_DATA_INCONSISTENCY
@ MOFEM_DATA_INCONSISTENCY
Definition: definitions.h:31
MoFEM::ProblemsManager::buildProblemOnDistributedMesh
MoFEMErrorCode buildProblemOnDistributedMesh(const std::string name, const bool square_matrix, int verb=VERBOSE)
build problem data structures, assuming that mesh is distributed (collective)
Definition: ProblemsManager.cpp:290
MoFEM::CoreInterface::clear_problem
virtual MoFEMErrorCode clear_problem(const std::string name, int verb=DEFAULT_VERBOSITY)=0
clear problem
sdf_hertz_2d_axisymm_plane.d
float d
Definition: sdf_hertz_2d_axisymm_plane.py:4
MoFEM::FieldEntity::getHiBitNumberUId
static UId getHiBitNumberUId(const FieldBitNumber bit_number)
Definition: FieldEntsMultiIndices.hpp:228
MoFEM::CoreTmp< 0 >::BUILD_FE
@ BUILD_FE
Definition: Core.hpp:213
FiniteElement_multiIndex
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.
Definition: FEMultiIndices.hpp:849
MoFEM::CommInterface::cOre
MoFEM::Core & cOre
Definition: CommInterface.hpp:29
m
FTensor::Index< 'm', 3 > m
Definition: shallow_wave.cpp:80
MoFEM::Types::BitRefLevel
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
Definition: Types.hpp:40
MOFEM_ATOM_TEST_INVALID
@ MOFEM_ATOM_TEST_INVALID
Definition: definitions.h:40
MoFEMFunctionBeginHot
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:453
QUIET
@ QUIET
Definition: definitions.h:221
MoFEM::CoreTmp< 0 >::PARTITION_GHOST_DOFS
@ PARTITION_GHOST_DOFS
Definition: Core.hpp:218
MoFEM::FieldEntity::getFieldBitNumberFromUniqueId
static auto getFieldBitNumberFromUniqueId(const UId uid)
Get the Field Bit Number From Unique Id.
Definition: FieldEntsMultiIndices.hpp:205
convert.int
int
Definition: convert.py:64
MoFEMFunctionReturn
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:429
MOFEM_NOT_IMPLEMENTED
@ MOFEM_NOT_IMPLEMENTED
Definition: definitions.h:32
VERY_VERBOSE
@ VERY_VERBOSE
Definition: definitions.h:223
MoFEMFunctionBegin
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:359
MOFEM_INVALID_DATA
@ MOFEM_INVALID_DATA
Definition: definitions.h:36
MoFEM::Types::DofIdx
int DofIdx
Index of DOF.
Definition: Types.hpp:18
MoFEM::FieldEntity::getOwnerFromUniqueId
static auto getOwnerFromUniqueId(const UId uid)
Definition: FieldEntsMultiIndices.hpp:177