v0.14.0
EssentialMPCsData.cpp
Go to the documentation of this file.
1 /**
2  * @file EssentialMPCsData.cpp
3  * @brief MPC boundary conditions
4  * @version 13.1
5  * @date 2022-09-03
6  *
7  * @copyright Copyright (c) 2022
8  *
9  */
10 
11 #include <MoFEM.hpp>
12 
13 namespace MoFEM {
14 
17 
19 }
20 
21 
23  boost::shared_ptr<FEMethod> fe_ptr,
24  bool is_spatial_positions)
25  : mField(m_field), fePtr(fe_ptr), isSpatialPositions(is_spatial_positions) {
26 }
27 
29  Interface &m_field, const char *file_name, const char *options) {
31 
32  auto simple = m_field.getInterface<Simple>();
33  auto &moab = m_field.get_moab();
34 
35  // CHKERR moab.load_file(file_name, 0, options);
36  CHKERR simple->loadFile("", file_name);
37 
38  constexpr bool is_debug = false;
39 
40  Range all_ents;
41  CHKERR moab.get_entities_by_handle(0, all_ents, false);
42 
43  if (m_field.get_comm_size() == 1)
45 
46  auto print_range_on_procs = [&](const Range &range, std::string name) {
47  if(!is_debug) return;
48  MOFEM_LOG("SYNC", Sev::inform)
49  << name << " on proc [" << m_field.get_comm_rank() << "] : \n"
50  << range;
52  };
53 
54  auto save_range_to_file = [&](const Range range, std::string name = "part") {
55  if(!is_debug) return;
56  int rr = m_field.get_comm_rank();
57  ostringstream ss;
58  ss << "out_" << name << "_" << rr << ".vtk";
59  MOFEM_LOG("SELF", Sev::inform) << "Save debug part mesh " << ss.str();
60  EntityHandle meshset;
61  CHKERR moab.create_meshset(MESHSET_SET, meshset);
62  CHKERR moab.add_entities(meshset, range);
63  if (!range.empty())
64  CHKERR moab.write_file(ss.str().c_str(), "VTK", "", &meshset, 1);
65  CHKERR moab.delete_entities(&meshset, 1);
66  };
67 
68  auto master_meshset_ptr =
69  m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
70  std::regex((boost::format("%s(.*)") % "MPC_(.*)_LINKS").str()));
71  Range mpc_ents, links_ents;
72  for (auto m : master_meshset_ptr) {
73 
74  Range ents;
75  CHKERR moab.get_entities_by_handle(m->getMeshset(), ents, true);
76 
77  links_ents.merge(ents);
78  for (auto &link : links_ents) {
79  Range verts;
80  CHKERR moab.get_connectivity(&link, 1, verts, true);
81  mpc_ents.merge(verts);
82  }
83  }
84 
85  if(mpc_ents.empty()) {
87  }
88 
89  save_range_to_file(all_ents, "all_ents");
90  print_range_on_procs(mpc_ents, "mpc_ents");
91  print_range_on_procs(links_ents, "links_ents");
92 
93  const int dim = simple->getDim();
94 
95  ParallelComm *pcomm =
96  ParallelComm::get_pcomm(&moab, MYPCOMM_INDEX);
97  if (pcomm == NULL)
98  pcomm = new ParallelComm(&moab, PETSC_COMM_WORLD);
99 
100  Tag part_tag = pcomm->part_tag();
101  Range tagged_sets, proc_ents, off_proc_ents, all_proc_ents;
102 
103  CHKERR moab.get_entities_by_type_and_tag(0, MBENTITYSET, &part_tag, NULL, 1,
104  tagged_sets, moab::Interface::UNION);
105  print_range_on_procs(tagged_sets, "tagged_sets");
106  for (auto &mit : tagged_sets) {
107  int part;
108  CHKERR moab.tag_get_data(part_tag, &mit, 1, &part);
109 
110  if (part == m_field.get_comm_rank()) {
111  CHKERR moab.get_entities_by_dimension(mit, dim, proc_ents, true);
112  CHKERR moab.get_entities_by_handle(mit, all_proc_ents, true);
113  } else {
114  CHKERR moab.get_entities_by_handle(mit, off_proc_ents, true);
115  }
116  }
117 
118  print_range_on_procs(proc_ents, "proc_ents");
119 
120  save_range_to_file(proc_ents);
121  save_range_to_file(off_proc_ents, "all_proc_ents");
122  all_proc_ents = subtract(all_proc_ents, links_ents);
123 
124  Range all_tets;
125  CHKERR moab.get_entities_by_handle(0, all_tets, true);
126 
127  Range tets_skin;
128  Skinner skin(&moab);
129  CHKERR skin.find_skin(0, all_tets.subset_by_dimension(dim), false, tets_skin);
130 
131 
132  // Find the skin of entities on this processor
133  Range proc_ents_skin[4]; // stores only entities shared with other processors
134  CHKERR skin.find_skin(0, proc_ents, false, proc_ents_skin[dim - 1]);
135 
136 
137  Range skin_verts, verts_to_add, edges_to_add;
138  CHKERR moab.get_connectivity(proc_ents_skin[dim - 1],
139  skin_verts); // FIXME: check for 3D
140  for (auto &link : links_ents) {
141  Range verts;
142  CHKERR moab.get_connectivity(&link, 1, verts);
143  for (auto &vert : verts)
144  if (skin_verts.find(vert) != skin_verts.end()) {
145  edges_to_add.insert(link);
146  verts_to_add.merge(verts);
147  }
148  }
149 
150  // Remove shared entities from the skin
151  proc_ents_skin[dim - 1] = subtract(proc_ents_skin[dim - 1], tets_skin);
152 
153  // Get adjacent entities and their connectivity
154 
155  // FIXME: these are NOT (!) only shared entities (includes outside)
156  if (dim > 2) {
157  CHKERR moab.get_adjacencies(proc_ents_skin[2], 1, false, proc_ents_skin[1],
158  moab::Interface::UNION);
159  }
160  Range adj_ents;
161  CHKERR moab.get_connectivity(proc_ents_skin[1], adj_ents, true);
162  proc_ents_skin[0].merge(adj_ents);
163 
164  proc_ents_skin[1].merge(edges_to_add);
165  proc_ents_skin[0].merge(verts_to_add);
166 
167  print_range_on_procs(edges_to_add, "edges_to_add");
168  print_range_on_procs(verts_to_add, "verts_to_add");
169 
170  // do it as early as possible
171  // it slows down all get_connectivity and get_adjacencies
172 
173  // Remove entities not part of this processor
174  save_range_to_file(proc_ents, "proc_ents");
175  save_range_to_file(off_proc_ents, "off_proc_ents");
176 
177  all_tets = off_proc_ents;
178 
179  if (edges_to_add.empty())
180  all_tets.merge(links_ents);
181 
182  save_range_to_file(proc_ents_skin[0], "proc_ents_skin0");
183  save_range_to_file(proc_ents_skin[1], "proc_ents_skin1");
184 
185  for (int dd = dim; dd >= 0; --dd) {
186  all_tets = subtract(all_tets, proc_ents_skin[dd]);
187  }
188  print_range_on_procs(proc_ents, "proc_ents");
189 
190  Range meshsets;
191  CHKERR moab.get_entities_by_type(0, MBENTITYSET, meshsets, true);
192  for (auto m : meshsets) {
193  CHKERR moab.remove_entities(m, all_tets);
194  }
195 
196  print_range_on_procs(all_tets.subset_by_dimension(2), "all_tets to delete");
197  save_range_to_file(all_tets.subset_by_dimension(2), "part_delete");
198 
199  // vertices do not need to be deleted
200  for (int dd = dim; dd > 0; --dd) {
201  CHKERR moab.delete_entities(all_tets.subset_by_dimension(dd));
202  }
203 
204  // Update parallel status tag
205  {
206  Range all_ents;
207  CHKERR moab.get_entities_by_handle(0, all_ents);
208  std::vector<unsigned char> pstat_tag(all_ents.size(), 0);
209  save_range_to_file(all_ents, "all_ents_part");
210  CHKERR moab.tag_set_data(pcomm->pstatus_tag(), all_ents,
211  &*pstat_tag.begin());
212  }
213 
214  Range all_ents_before;
215  CHKERR moab.get_entities_by_handle(0, all_ents_before);
216  save_range_to_file(all_ents_before, "all_ents_part_before");
217 
218  CHKERR pcomm->resolve_shared_ents(0, proc_ents, dim, -1, proc_ents_skin);
219 
220  Range all_ents_after;
221  CHKERR moab.get_entities_by_handle(0, all_ents_after);
222  save_range_to_file(all_ents_after, "all_ents_part_after");
223 
225 }
226 
228  Interface &m_field, moab::Interface &post_proc_mesh_interface,
229  vector<std::string> field_names) {
231 
232  // for each link vertex find entity in mfield database
233  // and add it to post_proc_mesh_interface
234  // for each field give in field_names save data on appropriate tag
235 
236  std::array<double, 9> def;
237  std::fill(def.begin(), def.end(), 0);
238 
239  auto get_tag = [&](const std::string name, size_t size) {
240  Tag th;
241  size = size <= 1 ? 1 : (size <= 3 ? 3 : 9);
242  CHKERR post_proc_mesh_interface.tag_get_handle(
243  name.c_str(), size, MB_TYPE_DOUBLE, th, MB_TAG_CREAT | MB_TAG_SPARSE,
244  def.data());
245  return th;
246  };
247 
248  // get links from meshsets
249  auto master_meshset_ptr =
250  m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
251  std::regex((boost::format("%s(.*)") % "MPC_(.*)_LINKS").str()));
252  Range links_ents;
253  for (auto m : master_meshset_ptr) {
254  Range ents;
255  CHKERR m_field.get_moab().get_entities_by_type(m->getMeshset(), MBEDGE,
256  ents, true);
257  links_ents.merge(ents);
258  }
259 
260  if(links_ents.empty()) {
262  }
263 
264  // create edges in post_proc_mesh_interface
265  std::vector<EntityHandle> p_links_edges(links_ents.size()); // post_proc edges
266  std::vector<EntityHandle> o_nodes(links_ents.size() * 2); // original mesh nodes
267  std::vector<EntityHandle> p_nodes(links_ents.size() * 2); // post_proc nodes
268 
269  int dd = 0;
270  for (auto &link : links_ents) {
271  Range verts;
272  CHKERR m_field.get_moab().get_connectivity(&link, 1, verts, true);
273  ublas::vector<EntityHandle> edge_conn(2);
274  int gg = 0;
275  for (auto &vert : verts) {
276  VectorDouble coords(3);
277  // fill o_nodes with vertices
278  CHKERR m_field.get_moab().get_coords(&vert, 1, &coords[0]);
279  CHKERR post_proc_mesh_interface.create_vertex(&coords[0], edge_conn[gg]);
280  o_nodes[dd * 2 + gg] = vert;
281  p_nodes[dd * 2 + gg] = edge_conn[gg];
282  gg++;
283  }
284 
285  CHKERR post_proc_mesh_interface.create_element(MBEDGE, &edge_conn[0], 2,
286  p_links_edges[dd++]);
287  }
288 
289  const FieldEntity_multiIndex *field_ents;
290  CHKERR m_field.get_field_ents(&field_ents);
291  auto &field_ents_by_uid = field_ents->get<Unique_mi_tag>();
292 
293  for (auto field : field_names) {
294  auto field_ptr = m_field.get_field_structure(field);
295  const int nb_coefficients = field_ptr->getNbOfCoeffs();
296  Tag tag = get_tag(field, nb_coefficients);
297 
298  int gg = 0;
299  for (auto &node : o_nodes) {
300  VectorDouble data(nb_coefficients);
301  auto eit = field_ents_by_uid.find(FieldEntity::getLocalUniqueIdCalculate(
302  m_field.get_field_bit_number(field), node));
303  if (eit != field_ents_by_uid.end()) {
304  noalias(data) = (*eit)->getEntFieldData();
305  }
306  auto ent = p_nodes[gg++];
307  post_proc_mesh_interface.tag_set_data(tag, &ent, 1, &*data.begin());
308  }
309  }
310 
312 }
313 
315  MOFEM_LOG_CHANNEL("WORLD");
317 
318  if (isSpatialPositions) {
319  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
320  }
321 
322  MOFEM_LOG("BcMngWorld", Sev::warning)
323  << "EssentialPreProc<MPCsType> has no effect here. ";
324 
326 }
327 
329  MoFEM::Interface &m_field, boost::shared_ptr<FEMethod> fe_ptr, double diag,
331  : mField(m_field), fePtr(fe_ptr), vDiag(diag), vLhs(lhs), vAO(ao) {}
332 
334  MOFEM_LOG_CHANNEL("WORLD");
336 
337  if (auto fe_ptr = fePtr.lock()) {
338 
339  auto bc_mng = mField.getInterface<BcManager>();
340  auto is_mng = mField.getInterface<ISManager>();
341  const auto problem_name = fe_ptr->problemPtr->getName();
342  bool do_assembly = false;
343  for (auto bc : bc_mng->getBcMapByBlockName()) {
344  if (auto mpc_bc = bc.second->mpcPtr) {
345 
346  auto &bc_id = bc.first;
347 
348  auto regex_str = (boost::format("%s_(.*)") % problem_name).str();
349  if (std::regex_match(bc_id, std::regex(regex_str))) {
350 
351  auto [field_name, block_name] =
352  BcManager::extractStringFromBlockId(bc_id, problem_name);
353 
354  auto get_field_coeffs = [&](auto field_name) {
355  auto field_ptr = mField.get_field_structure(field_name);
356  return field_ptr->getNbOfCoeffs();
357  };
358 
359  const auto nb_field_coeffs = get_field_coeffs(field_name);
360  constexpr auto max_nb_dofs_per_node = 6;
361 
362  if (nb_field_coeffs > max_nb_dofs_per_node)
363  MOFEM_LOG("WORLD", Sev::error)
364  << "MultiPointConstraints PreProcLhs<MPCsType>: support only "
365  "up to 6 dofs per node.";
366  MOFEM_LOG("WORLD", Sev::noisy)
367  << "Apply MultiPointConstraints PreProc<MPCsType>: "
368  << problem_name << "_" << field_name << "_" << block_name;
369 
370  auto mpc_type = mpc_bc->mpcType;
371  switch (mpc_type) {
372  case MPC::COUPLING:
373  case MPC::TIE:
374  case MPC::RIGID_BODY:
375  break;
376  default:
377  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
378  "MPC type not implemented");
379  }
380 
381  // FIXME: there handle the vertices differently (block level)
382  auto master_verts = mpc_bc->mpcMasterEnts.subset_by_type(MBVERTEX);
383  auto slave_verts = mpc_bc->mpcSlaveEnts.subset_by_type(MBVERTEX);
384 
385  auto prb_name = fe_ptr->problemPtr->getName();
386  auto get_flag = [&](int idx) { return (&mpc_bc->data.flag1)[idx]; };
387  MOFEM_LOG("WORLD", Sev::verbose)
388  << "Size of master nodes: " << mpc_bc->mpcMasterEnts.size()
389  << " Size of slave nodes : " << mpc_bc->mpcSlaveEnts.size();
390 
391  if (mpc_bc->mpcMasterEnts.size() > mpc_bc->mpcSlaveEnts.size()) {
392  MOFEM_LOG("WORLD", Sev::error)
393  << "Size of master nodes < Size of slave nodes : "
394  << mpc_bc->mpcMasterEnts.size() << " > " << mpc_bc->mpcSlaveEnts.size();
395  // SETERRQ(PETSC_COMM_WORLD, MOFEM_OPERATION_UNSUCCESSFUL,
396  // "data inconsistency");
397  }
398 
399  auto add_is = [](auto is1, auto is2) {
400  IS is;
401  CHK_THROW_MESSAGE(ISExpand(is1, is2, &is), "is sum");
402  return SmartPetscObj<IS>(is);
403  };
404 
405  SmartPetscObj<IS> is_xyz_row_sum;
406  SmartPetscObj<IS> is_m_row[max_nb_dofs_per_node];
407  SmartPetscObj<IS> is_m_col[max_nb_dofs_per_node];
408  SmartPetscObj<IS> is_s_row[max_nb_dofs_per_node];
409  SmartPetscObj<IS> is_s_col[max_nb_dofs_per_node];
410 
411  for (int dd = 0; dd != nb_field_coeffs; dd++) {
412  if (get_flag(dd)) {
413  // SmartPetscObj<IS> is_xyz_m;
414  CHKERR is_mng->isCreateProblemFieldAndRank(
415  prb_name, ROW, field_name, dd, dd, is_m_row[dd],
416  &master_verts);
417  CHKERR is_mng->isCreateProblemFieldAndRank(
418  prb_name, COL, field_name, dd, dd, is_m_col[dd],
419  &master_verts);
420  CHKERR is_mng->isCreateProblemFieldAndRank(
421  prb_name, COL, field_name, dd, dd, is_s_col[dd],
422  &slave_verts);
423  CHKERR is_mng->isCreateProblemFieldAndRank(
424  prb_name, ROW, field_name, dd, dd, is_s_row[dd],
425  &slave_verts);
426  // ISView(is_s_row[dd], PETSC_VIEWER_STDOUT_WORLD);
427  // ISView(is_s_col[dd], PETSC_VIEWER_STDOUT_WORLD);
428 
429  if (!mpc_bc->isReprocitical) {
430  if (!is_xyz_row_sum) {
431  is_xyz_row_sum = is_s_row[dd];
432  } else {
433  is_xyz_row_sum = add_is(is_xyz_row_sum, is_s_row[dd]);
434  }
435  }
436  }
437  }
438 
439  // if (is_xyz_row_sum) {
441  vLhs ? vLhs : SmartPetscObj<Mat>(fe_ptr->B, true);
442  // The user is responsible for assembly if vLhs is provided
443  MatType typem;
444  CHKERR MatGetType(B, &typem);
445  CHKERR MatSetOption(B, MAT_NEW_NONZERO_LOCATIONS, PETSC_TRUE);
446  if (typem == MATMPIBAIJ)
447  CHKERR MatSetOption(B, MAT_USE_HASH_TABLE, PETSC_TRUE);
448 
449  if ((*fe_ptr->matAssembleSwitch) && !vLhs) {
450  if (*fe_ptr->matAssembleSwitch) {
451  CHKERR MatAssemblyBegin(B, MAT_FLUSH_ASSEMBLY);
452  CHKERR MatAssemblyEnd(B, MAT_FLUSH_ASSEMBLY);
453  *fe_ptr->matAssembleSwitch = false;
454  }
455  }
456 
457  if (vAO) {
458  MOFEM_LOG("WORLD", Sev::error) << "No support for AO yet";
459  }
460 
461  CHKERR MatZeroRowsIS(B, is_xyz_row_sum, 0, PETSC_NULL,
462  PETSC_NULL);
463  // }
464  auto set_mat_values = [&](auto row_is, auto col_is, double val, double perturb = 0) {
466  const int *row_index_ptr;
467  CHKERR ISGetIndices(row_is, &row_index_ptr);
468  const int *col_index_ptr;
469  CHKERR ISGetIndices(col_is, &col_index_ptr);
470  int row_size, col_size;
471  CHKERR ISGetLocalSize(row_is, &row_size);
472  CHKERR ISGetLocalSize(col_is, &col_size);
473 
474  MatrixDouble locMat(row_size, col_size);
475  fill(locMat.data().begin(), locMat.data().end(), 0.0);
476  for (int i = 0; i != row_size; i++)
477  for (int j = 0; j != col_size; j++)
478  if (i == j || col_size == 1)
479  locMat(i, j) = val;
480 
481  if (mpc_bc->isReprocitical) {
482  locMat *= perturb;
483  CHKERR ::MatSetValues(B, row_size, row_index_ptr, col_size,
484  col_index_ptr, &*locMat.data().begin(),
485  ADD_VALUES);
486  } else {
487  CHKERR ::MatSetValues(B, row_size, row_index_ptr, col_size,
488  col_index_ptr, &*locMat.data().begin(),
489  INSERT_VALUES);
490  }
491 
492  CHKERR ISRestoreIndices(row_is, &row_index_ptr);
493  CHKERR ISRestoreIndices(col_is, &col_index_ptr);
494 
496  };
497 
498  for (int dd = 0; dd != nb_field_coeffs; dd++) {
499  if (get_flag(dd)) {
500  do_assembly = true;
501  if (!mpc_bc->isReprocitical) {
502  CHKERR set_mat_values(is_s_row[dd], is_s_col[dd], vDiag);
503  CHKERR set_mat_values(is_s_row[dd], is_m_col[dd], -vDiag);
504  }
505  else
506  {
507  auto &pn = mpc_bc->mPenalty;
508  CHKERR set_mat_values(is_s_row[dd], is_s_col[dd], vDiag, pn);
509  CHKERR set_mat_values(is_s_row[dd], is_m_col[dd], -vDiag, pn);
510  CHKERR set_mat_values(is_m_row[dd], is_m_col[dd], vDiag, pn);
511  CHKERR set_mat_values(is_m_row[dd], is_s_col[dd], -vDiag, pn);
512  }
513  }
514  }
515  } // if regex
516  } // mpc loop
517  } // bc loop
518  if (do_assembly) {
519  SmartPetscObj<Mat> B = vLhs ? vLhs : SmartPetscObj<Mat>(fe_ptr->B, true);
520  CHKERR MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY);
521  CHKERR MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY);
522  }
523 
524  } else {
525  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
526  "Can not lock shared pointer");
527  } // if fe_ptr
529 }
530 
532  MoFEM::Interface &m_field, boost::shared_ptr<FEMethod> fe_ptr, double diag,
533  SmartPetscObj<Vec> rhs)
534  : mField(m_field), fePtr(fe_ptr), vDiag(diag), vRhs(rhs) {}
535 
537  MOFEM_LOG_CHANNEL("WORLD");
539 
540  if (auto fe_method_ptr = fePtr.lock()) {
541 
542  auto bc_mng = mField.getInterface<BcManager>();
543  auto is_mng = mField.getInterface<ISManager>();
544  auto vec_mng = mField.getInterface<VecManager>();
545  const auto problem_name = fe_method_ptr->problemPtr->getName();
546  // get connectivity from edge and assign master, slave ents
547  for (auto bc : bc_mng->getBcMapByBlockName()) {
548  if (auto mpc_bc = bc.second->mpcPtr) {
549 
550  auto &bc_id = bc.first;
551 
552  auto regex_str = (boost::format("%s_(.*)") % problem_name).str();
553  if (std::regex_match(bc_id, std::regex(regex_str))) {
554 
555  auto [field_name, block_name] =
556  BcManager::extractStringFromBlockId(bc_id, problem_name);
557 
558  auto get_field_coeffs = [&](auto field_name) {
559  auto field_ptr = mField.get_field_structure(field_name);
560  return field_ptr->getNbOfCoeffs();
561  };
562 
563  const auto nb_field_coeffs = get_field_coeffs(field_name);
564  constexpr auto max_nb_dofs_per_node = 6;
565 
566  if (nb_field_coeffs > max_nb_dofs_per_node)
567  MOFEM_LOG("WORLD", Sev::error)
568  << "MultiPointConstraints PreProcLhs<MPCsType>: support only "
569  "up to 6 dofs per node for now.";
570 
571  MOFEM_LOG("WORLD", Sev::noisy)
572  << "Apply MultiPointConstraints PreProc<MPCsType>: "
573  << problem_name << "_" << field_name << "_" << block_name;
574 
575  auto mpc_type = mpc_bc->mpcType;
576  switch (mpc_type) {
577  case MPC::COUPLING:
578  case MPC::TIE:
579  case MPC::RIGID_BODY:
580  break;
581  default:
582  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
583  "MPC type not implemented");
584  }
585 
586  auto master_verts = mpc_bc->mpcMasterEnts.subset_by_type(MBVERTEX);
587  auto slave_verts = mpc_bc->mpcSlaveEnts.subset_by_type(MBVERTEX);
588 
589  auto prb_name = fe_method_ptr->problemPtr->getName();
590 
591  auto get_flag = [&](int idx) { return (&mpc_bc->data.flag1)[idx]; };
592 
593  auto add_is = [](auto is1, auto is2) {
594  IS is;
595  CHK_THROW_MESSAGE(ISExpand(is1, is2, &is), "is sum");
596  return SmartPetscObj<IS>(is);
597  };
598 
599  SmartPetscObj<IS> is_m[max_nb_dofs_per_node];
600  SmartPetscObj<IS> is_s[max_nb_dofs_per_node];
601 
602  for (int dd = 0; dd != nb_field_coeffs; dd++) {
603  if (get_flag(dd)) {
604 
605  CHKERR is_mng->isCreateProblemFieldAndRankLocal(
606  prb_name, ROW, field_name, dd, dd, is_m[dd], &master_verts);
607  CHKERR is_mng->isCreateProblemFieldAndRankLocal(
608  prb_name, ROW, field_name, dd, dd, is_s[dd], &slave_verts);
609 
610  }
611  }
612 
613  {
614 
615  if (auto fe_ptr = fePtr.lock()) {
616  auto snes_ctx = fe_ptr->snes_ctx;
617  auto ts_ctx = fe_ptr->ts_ctx;
618  const bool is_nonlinear = snes_ctx != FEMethod::CTX_SNESNONE ||
620  // is_nonlinear = is_nonlinear || mpc_bc->isReprocitical;
621  const int contrb = mpc_bc->isReprocitical ? 1 : 0;
623  vRhs ? vRhs : SmartPetscObj<Vec>(fe_ptr->f, true);
624 
625  if (fe_ptr->vecAssembleSwitch) {
626  if ((*fe_ptr->vecAssembleSwitch) && !vRhs) {
627  CHKERR VecGhostUpdateBegin(F, ADD_VALUES, SCATTER_REVERSE);
628  CHKERR VecGhostUpdateEnd(F, ADD_VALUES, SCATTER_REVERSE);
629  CHKERR VecAssemblyBegin(F);
630  CHKERR VecAssemblyEnd(F);
631  *fe_ptr->vecAssembleSwitch = false;
632  }
633  }
634 
635  auto vec_set_values = [&](auto is_xyz_m, auto is_xyz_s, double val) {
637  const int *m_index_ptr;
638  CHKERR ISGetIndices(is_xyz_m, &m_index_ptr);
639  const int *s_index_ptr;
640  CHKERR ISGetIndices(is_xyz_s, &s_index_ptr);
641  int size_m;
642  CHKERR ISGetLocalSize(is_xyz_m, &size_m);
643  int size_s;
644  CHKERR ISGetLocalSize(is_xyz_s, &size_s);
645 
646  double *f;
647  CHKERR VecGetArray(F, &f);
648  // if (size_m > size_s)
649  // MOFEM_LOG("WORLD", Sev::error)
650  // << "Size of master IS > Size of slave IS : " << size_m
651  // << " > " << size_s;
652  // if (size_m == 0)
653  // MOFEM_LOG("WORLD", Sev::error)
654  // << "Size of master IS is " << size_m;
655 
656  if (is_nonlinear) {
657  auto x = fe_ptr->x;
658  auto tmp_x = vectorDuplicate(F);
659 
660  CHKERR vec_mng->setLocalGhostVector(problem_name, ROW,
661  tmp_x, INSERT_VALUES,
662  SCATTER_FORWARD);
663  const double *v;
664  const double *u;
665 
666  CHKERR VecGetArrayRead(tmp_x, &u);
667  CHKERR VecGetArrayRead(x, &v);
668  if (size_m && size_s) {
669  for (auto i = 0; i != size_s; ++i) {
670  auto m_idx = size_m == 1 ? 0 : i;
671  f[s_index_ptr[i]] = val * (v[s_index_ptr[i]] - v[m_index_ptr[m_idx]]) + f[s_index_ptr[i]] * contrb ;
672  }
673  }
674  CHKERR VecRestoreArrayRead(x, &v);
675  CHKERR VecRestoreArrayRead(tmp_x, &u);
676  } else {
677  if (size_m && size_s)
678  for (auto i = 0; i != size_s; ++i) {
679  f[s_index_ptr[i]] = 0;
680  }
681  }
682 
683  CHKERR VecRestoreArray(F, &f);
684  CHKERR ISRestoreIndices(is_xyz_m, &m_index_ptr);
685  CHKERR ISRestoreIndices(is_xyz_s, &s_index_ptr);
686 
688  };
689 
690  for (int dd = 0; dd != nb_field_coeffs; dd++)
691  if (get_flag(dd)) {
692 
693  if (!mpc_bc->isReprocitical) {
694  CHKERR vec_set_values(is_m[dd], is_s[dd], vDiag);
695  } else {
696  auto &pn = mpc_bc->mPenalty;
697  CHKERR vec_set_values(is_m[dd], is_s[dd], pn);
698  CHKERR vec_set_values(is_s[dd], is_m[dd], pn);
699  }
700  }
701  };
702 
703  // User is responsible for assembly if vLhs is provided
704 
705  // ISView(is_xyz_m, PETSC_VIEWER_STDOUT_WORLD);
706  // CHKERR MatZeroRowsColumnsIS(B, is_xyz_m, vDiag, PETSC_NULL,
707  // PETSC_NULL);
708  }
709  }
710  }
711  }
712  } else {
713  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
714  "Can not lock shared pointer");
715  }
716 
718 }
719 
720 } // namespace MoFEM
MoFEMFunctionReturnHot
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:447
MoFEM::UnknownInterface::getInterface
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface refernce to pointer of interface.
Definition: UnknownInterface.hpp:93
MoFEM::BcManager::extractStringFromBlockId
static std::pair< std::string, std::string > extractStringFromBlockId(const std::string block_id, const std::string prb_name)
Extract block name and block name form block id.
Definition: BcManager.cpp:1389
MoFEM::Field::getNbOfCoeffs
FieldCoefficientsNumber getNbOfCoeffs() const
Get number of field coefficients.
Definition: FieldMultiIndices.hpp:188
MYPCOMM_INDEX
#define MYPCOMM_INDEX
default communicator number PCOMM
Definition: definitions.h:215
MoFEM::MatSetValues
MoFEMErrorCode MatSetValues(Mat M, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, const double *ptr, InsertMode iora)
Assemble PETSc matrix.
Definition: EntitiesFieldData.hpp:1631
MOFEM_LOG_CHANNEL
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
Definition: LogManager.hpp:284
EntityHandle
MoFEM::CoreInterface::get_comm
virtual MPI_Comm & get_comm() const =0
CHK_THROW_MESSAGE
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
Definition: definitions.h:596
MoFEM::CoreInterface::get_field_structure
virtual const Field * get_field_structure(const std::string &name, enum MoFEMTypes bh=MF_EXIST) const =0
get field structure
MoFEM::Exceptions::MoFEMErrorCode
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
MoFEM::Types::MatrixDouble
UBlasMatrix< double > MatrixDouble
Definition: Types.hpp:77
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::th
Tag th
Definition: Projection10NodeCoordsOnField.cpp:122
MoFEM.hpp
ts_ctx
MoFEM::TsCtx * ts_ctx
Definition: level_set.cpp:1932
MoFEM::Simple
Simple interface for fast problem set-up.
Definition: Simple.hpp:27
MoFEM::DeprecatedCoreInterface
Deprecated interface functions.
Definition: DeprecatedCoreInterface.hpp:16
ROW
@ ROW
Definition: definitions.h:123
MoFEM::Interface
DeprecatedCoreInterface Interface
Definition: Interface.hpp:1975
CHKERR
#define CHKERR
Inline error check.
Definition: definitions.h:535
MoFEM::CoreInterface::get_moab
virtual moab::Interface & get_moab()=0
MoFEM
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:10
MoFEM::ISManager
Section manager is used to create indexes and sections.
Definition: ISManager.hpp:23
MoFEM::BcManager
Simple interface for fast problem set-up.
Definition: BcManager.hpp:25
MoFEM::SnesMethod::CTX_SNESNONE
@ CTX_SNESNONE
Definition: LoopMethods.hpp:107
simple
void simple(double P1[], double P2[], double P3[], double c[], const int N)
Definition: acoustic.cpp:69
MoFEM::FieldEntity::getLocalUniqueIdCalculate
UId getLocalUniqueIdCalculate()
Get the Local Unique Id Calculate object.
Definition: FieldEntsMultiIndices.hpp:136
MoFEM::EssentialPostProcLhs
Class (Function) to enforce essential constrains on the left hand side diagonal.
Definition: Essential.hpp:33
MOFEM_LOG_SYNCHRONISE
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
Definition: LogManager.hpp:345
MoFEM::MPC::RIGID_BODY
@ RIGID_BODY
COL
@ COL
Definition: definitions.h:123
MoFEM::TSMethod::CTX_TSNONE
@ CTX_TSNONE
Definition: LoopMethods.hpp:145
MoFEM::CoreInterface::get_comm_size
virtual int get_comm_size() const =0
MoFEM::CoreInterface::get_field_ents
virtual const FieldEntity_multiIndex * get_field_ents() const =0
Get the field ents object.
MoFEM::MPC::TIE
@ TIE
MoFEM::FieldEntity_multiIndex
multi_index_container< boost::shared_ptr< FieldEntity >, indexed_by< ordered_unique< tag< Unique_mi_tag >, member< FieldEntity, UId, &FieldEntity::localUId > >, ordered_non_unique< tag< Ent_mi_tag >, const_mem_fun< FieldEntity::interface_type_RefEntity, EntityHandle, &FieldEntity::getEnt > > > > FieldEntity_multiIndex
Definition: FieldEntsMultiIndices.hpp:489
MoFEM::setMPCParentAdjacency
MoFEMErrorCode setMPCParentAdjacency()
Definition: EssentialMPCsData.cpp:15
i
FTensor::Index< 'i', SPACE_DIM > i
Definition: hcurl_divergence_operator_2d.cpp:27
MoFEM::EssentialPostProcRhs
Class (Function) to enforce essential constrains on the right hand side diagonal.
Definition: Essential.hpp:41
MoFEM::VecManager
Vector manager is used to create vectors \mofem_vectors.
Definition: VecManager.hpp:23
field_name
constexpr auto field_name
Definition: poisson_2d_homogeneous.cpp:13
v
const double v
phase velocity of light in medium (cm/ns)
Definition: initial_diffusion.cpp:40
Range
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::vectorDuplicate
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
Definition: PetscSmartObj.hpp:217
HenckyOps::f
auto f
Definition: HenckyOps.hpp:15
j
FTensor::Index< 'j', 3 > j
Definition: matrix_function.cpp:19
UBlasVector< double >
MOFEM_DATA_INCONSISTENCY
@ MOFEM_DATA_INCONSISTENCY
Definition: definitions.h:31
MoFEM::MeshsetsManager
Interface for managing meshsets containing materials and boundary conditions.
Definition: MeshsetsManager.hpp:104
m
FTensor::Index< 'm', 3 > m
Definition: shallow_wave.cpp:80
MoFEMFunctionBeginHot
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:440
MoFEM::Unique_mi_tag
Definition: TagMultiIndices.hpp:18
MoFEM::EssentialPreProc
Class (Function) to enforce essential constrains.
Definition: Essential.hpp:25
MoFEM::SmartPetscObj< Mat >
MoFEMFunctionReturn
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:416
MOFEM_NOT_IMPLEMENTED
@ MOFEM_NOT_IMPLEMENTED
Definition: definitions.h:32
MoFEMFunctionBegin
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:346
MoFEM::MPC::COUPLING
@ COUPLING
F
@ F
Definition: free_surface.cpp:394