v0.9.0
VecManager.cpp
Go to the documentation of this file.
1 /** \file VecManager.cpp
2  * \brief Implementation of VecManager
3  *
4  * MoFEM is free software: you can redistribute it and/or modify it under
5  * the terms of the GNU Lesser General Public License as published by the
6  * Free Software Foundation, either version 3 of the License, or (at your
7  * option) any later version.
8  *
9  * MoFEM is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
12  * License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with MoFEM. If not, see <http://www.gnu.org/licenses/>
16  */
17 
18 namespace MoFEM {
19 
21  UnknownInterface **iface) const {
23  *iface = NULL;
24  if (uuid == IDD_MOFEMVEC) {
25  *iface = const_cast<VecManager *>(this);
27  }
28  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "unknown interface");
30 }
31 
33  : cOre(const_cast<MoFEM::Core &>(core)), dEbug(false) {}
35 
37  Vec *V) const {
38  const MoFEM::Interface &m_field = cOre;
39  const Problem *problem_ptr;
41  CHKERR m_field.get_problem(name, &problem_ptr);
42  DofIdx nb_local_dofs, nb_ghost_dofs;
43  switch (rc) {
44  case ROW:
45  nb_local_dofs = problem_ptr->getNbLocalDofsRow();
46  nb_ghost_dofs = problem_ptr->getNbGhostDofsRow();
47  break;
48  case COL:
49  nb_local_dofs = problem_ptr->getNbLocalDofsCol();
50  nb_ghost_dofs = problem_ptr->getNbGhostDofsCol();
51  break;
52  default:
53  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not implemented");
54  }
55  CHKERR ::VecCreateSeq(PETSC_COMM_SELF, nb_local_dofs + nb_ghost_dofs, V);
57 }
58 
60  RowColData rc, Vec *V) const {
61  const MoFEM::Interface &m_field = cOre;
62  const Problem *problem_ptr;
64  CHKERR m_field.get_problem(name, &problem_ptr);
65  DofIdx nb_dofs, nb_local_dofs, nb_ghost_dofs;
67  switch (rc) {
68  case ROW:
69  nb_dofs = problem_ptr->getNbDofsRow();
70  nb_local_dofs = problem_ptr->getNbLocalDofsRow();
71  nb_ghost_dofs = problem_ptr->getNbGhostDofsRow();
72  dofs = const_cast<NumeredDofEntityByLocalIdx *>(
73  &problem_ptr->numeredDofsRows->get<PetscLocalIdx_mi_tag>());
74  break;
75  case COL:
76  nb_dofs = problem_ptr->getNbDofsCol();
77  nb_local_dofs = problem_ptr->getNbLocalDofsCol();
78  nb_ghost_dofs = problem_ptr->getNbGhostDofsCol();
79  dofs = const_cast<NumeredDofEntityByLocalIdx *>(
80  &problem_ptr->numeredDofsCols->get<PetscLocalIdx_mi_tag>());
81  break;
82  default:
83  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
84  }
85  // get ghost dofs
86  auto miit = dofs->lower_bound(nb_local_dofs);
87  auto hi_miit = dofs->upper_bound(nb_local_dofs + nb_ghost_dofs);
88  int count = std::distance(miit, hi_miit);
89  if (count != nb_ghost_dofs) {
90  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
91  }
92  std::vector<DofIdx> ghost_idx(count);
93  for (auto vit = ghost_idx.begin(); miit != hi_miit; ++miit, ++vit) {
94  *vit = (*miit)->petscGloablDofIdx;
95  }
96  CHKERR ::VecCreateGhost(PETSC_COMM_WORLD, nb_local_dofs, nb_dofs,
97  nb_ghost_dofs, &ghost_idx[0], V);
99 }
100 
102  RowColData rc,
103  SmartPetscObj<Vec> &v_ptr) const {
105  Vec vec;
106  CHKERR vecCreateGhost(name, rc, &vec);
107  v_ptr.reset(vec, false);
109 }
110 
112 VecManager::vecScatterCreate(Vec xin, const std::string &x_problem,
113  const std::string &x_field_name, RowColData x_rc,
114  Vec yin, const std::string &y_problem,
115  const std::string &y_field_name, RowColData y_rc,
116  VecScatter *newctx) const {
117  const MoFEM::Interface &m_field = cOre;
119  std::vector<int> idx(0), idy(0);
120  CHKERR m_field.getInterface<ISManager>()
121  ->isCreateFromProblemFieldToOtherProblemField(
122  x_problem, x_field_name, x_rc, y_problem, y_field_name, y_rc, idx,
123  idy);
124  IS ix, iy;
125  CHKERR ISCreateGeneral(PETSC_COMM_WORLD, idx.size(), &idx[0],
126  PETSC_USE_POINTER, &ix);
127  CHKERR ISCreateGeneral(PETSC_COMM_WORLD, idy.size(), &idy[0],
128  PETSC_USE_POINTER, &iy);
129  CHKERR ::VecScatterCreate(xin, ix, yin, iy, newctx);
130  CHKERR ISDestroy(&ix);
131  CHKERR ISDestroy(&iy);
133 }
134 
136  Vec xin, const std::string &x_problem, RowColData x_rc, Vec yin,
137  const std::string &y_problem, RowColData y_rc, VecScatter *newctx) const {
138  const MoFEM::Interface &m_field = cOre;
140  std::vector<int> idx(0), idy(0);
141  CHKERR m_field.getInterface<ISManager>()->isCreateFromProblemToOtherProblem(
142  x_problem, x_rc, y_problem, y_rc, idx, idy);
143  IS ix, iy;
144  CHKERR ISCreateGeneral(PETSC_COMM_WORLD, idx.size(), &idx[0],
145  PETSC_USE_POINTER, &ix);
146  CHKERR ISCreateGeneral(PETSC_COMM_WORLD, idy.size(), &idy[0],
147  PETSC_USE_POINTER, &iy);
148  if (dEbug) {
149  ISView(ix, PETSC_VIEWER_STDOUT_WORLD);
150  ISView(iy, PETSC_VIEWER_STDOUT_WORLD);
151  }
152  CHKERR ::VecScatterCreate(xin, ix, yin, iy, newctx);
153  CHKERR ISDestroy(&ix);
154  CHKERR ISDestroy(&iy);
156 }
157 
159 VecManager::vecScatterCreate(Vec xin, const std::string &x_problem,
160  const std::string &x_field_name, RowColData x_rc,
161  Vec yin, const std::string &y_problem,
162  const std::string &y_field_name, RowColData y_rc,
163  SmartPetscObj<VecScatter> &smart_newctx) const {
165  VecScatter newctx;
166  CHKERR vecScatterCreate(xin, x_problem, x_field_name, x_rc, yin, y_problem,
167  y_field_name, y_rc, &newctx);
168  smart_newctx = newctx;
170 }
171 
173 VecManager::vecScatterCreate(Vec xin, const std::string &x_problem,
174  RowColData x_rc, Vec yin,
175  const std::string &y_problem, RowColData y_rc,
176  SmartPetscObj<VecScatter> &smart_newctx) const {
178  VecScatter newctx;
179  CHKERR vecScatterCreate(xin, x_problem, x_rc, yin, y_problem, y_rc, &newctx);
180  smart_newctx = newctx;
182 }
183 
185  RowColData rc, Vec V,
186  InsertMode mode,
187  ScatterMode scatter_mode) const {
190  DofIdx nb_local_dofs, nb_ghost_dofs;
191  switch (rc) {
192  case ROW:
193  nb_local_dofs = problem_ptr->getNbLocalDofsRow();
194  nb_ghost_dofs = problem_ptr->getNbGhostDofsRow();
195  dofs = const_cast<NumeredDofEntityByLocalIdx *>(
196  &problem_ptr->numeredDofsRows->get<PetscLocalIdx_mi_tag>());
197  break;
198  case COL:
199  nb_local_dofs = problem_ptr->getNbLocalDofsCol();
200  nb_ghost_dofs = problem_ptr->getNbGhostDofsCol();
201  dofs = const_cast<NumeredDofEntityByLocalIdx *>(
202  &problem_ptr->numeredDofsCols->get<PetscLocalIdx_mi_tag>());
203  break;
204  default:
205  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
206  }
207  Vec Vlocal;
208  CHKERR VecGhostGetLocalForm(V, &Vlocal);
209  int size;
210  CHKERR VecGetLocalSize(V, &size);
211  if (size != nb_local_dofs) {
212  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
213  "data inconsistency: check ghost vector, problem with nb. of "
214  "local nodes %d != %d",
215  size, nb_local_dofs);
216  }
217  CHKERR VecGetLocalSize(Vlocal, &size);
218  if (size != nb_local_dofs + nb_ghost_dofs) {
219  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
220  "data inconsistency: check ghost vector, problem with nb. of "
221  "ghost nodes %d != ",
222  size, nb_local_dofs + nb_ghost_dofs);
223  }
224  NumeredDofEntityByLocalIdx::iterator miit = dofs->lower_bound(0);
225  NumeredDofEntityByLocalIdx::iterator hi_miit =
226  dofs->upper_bound(nb_local_dofs + nb_ghost_dofs);
227  DofIdx ii = 0;
228  switch (scatter_mode) {
229  case SCATTER_FORWARD: {
230  PetscScalar *array;
231  CHKERR VecGetArray(Vlocal, &array);
232  switch (mode) {
233  case INSERT_VALUES:
234  for (; miit != hi_miit; ++miit, ++ii)
235  array[ii] = (*miit)->getFieldData();
236  break;
237  case ADD_VALUES:
238  for (; miit != hi_miit; ++miit, ++ii)
239  array[ii] += (*miit)->getFieldData();
240  break;
241  default:
242  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
243  }
244  CHKERR VecRestoreArray(Vlocal, &array);
245  }; break;
246  case SCATTER_REVERSE: {
247  const PetscScalar *array;
248  CHKERR VecGetArrayRead(Vlocal, &array);
249  switch (mode) {
250  case INSERT_VALUES:
251  for (; miit != hi_miit; ++miit, ++ii) {
252  // std::cerr << *miit << std::endl;
253  // std::cerr << array[ii] << std::endl;
254  (*miit)->getFieldData() = array[ii];
255  }
256  break;
257  case ADD_VALUES:
258  for (; miit != hi_miit; ++miit, ++ii)
259  (*miit)->getFieldData() += array[ii];
260  break;
261  default:
262  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
263  }
264  CHKERR VecRestoreArrayRead(Vlocal, &array);
265  }; break;
266  default:
267  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
268  }
269  CHKERR VecGhostRestoreLocalForm(V, &Vlocal);
271 }
272 
274  RowColData rc, Vec V,
275  InsertMode mode,
276  ScatterMode scatter_mode) const {
277  const MoFEM::Interface &m_field = cOre;
278  const Problem *problem_ptr;
280  CHKERR m_field.get_problem(name, &problem_ptr);
281  CHKERR setLocalGhostVector(problem_ptr, rc, V, mode, scatter_mode);
283 }
284 
287  Vec V, InsertMode mode,
288  ScatterMode scatter_mode) const {
291  DofsByGlobalIdx;
292  DofsByGlobalIdx *dofs;
293  DofIdx nb_dofs;
294  switch (rc) {
295  case ROW:
296  nb_dofs = problem_ptr->getNbDofsRow();
297  dofs = const_cast<DofsByGlobalIdx *>(
298  &problem_ptr->numeredDofsRows->get<PetscGlobalIdx_mi_tag>());
299  break;
300  case COL:
301  nb_dofs = problem_ptr->getNbDofsCol();
302  dofs = const_cast<DofsByGlobalIdx *>(
303  &problem_ptr->numeredDofsCols->get<PetscGlobalIdx_mi_tag>());
304  break;
305  default:
306  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
307  }
308  DofsByGlobalIdx::iterator miit = dofs->lower_bound(0);
309  DofsByGlobalIdx::iterator hi_miit = dofs->upper_bound(nb_dofs);
310  switch (scatter_mode) {
311  case SCATTER_REVERSE: {
312  VecScatter ctx;
313  Vec V_glob;
314  CHKERR VecScatterCreateToAll(V, &ctx, &V_glob);
315  CHKERR VecScatterBegin(ctx, V, V_glob, INSERT_VALUES, SCATTER_FORWARD);
316  CHKERR VecScatterEnd(ctx, V, V_glob, INSERT_VALUES, SCATTER_FORWARD);
317  int size;
318  CHKERR VecGetSize(V_glob, &size);
319  if (size != nb_dofs) {
320  SETERRQ(
321  PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
322  "data inconsistency: nb. of dofs and declared nb. dofs in database");
323  }
324  PetscScalar *array;
325  CHKERR VecGetArray(V_glob, &array);
326  switch (mode) {
327  case INSERT_VALUES:
328  for (; miit != hi_miit; miit++)
329  (*miit)->getFieldData() = array[(*miit)->getPetscGlobalDofIdx()];
330  break;
331  case ADD_VALUES:
332  for (; miit != hi_miit; miit++)
333  (*miit)->getFieldData() += array[(*miit)->getPetscGlobalDofIdx()];
334  break;
335  default:
336  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
337  }
338  CHKERR VecRestoreArray(V_glob, &array);
339  CHKERR VecScatterDestroy(&ctx);
340  CHKERR VecDestroy(&V_glob);
341  break;
342  }
343  default:
344  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
345  }
347 }
348 
350 VecManager::setGlobalGhostVector(const std::string &name, RowColData rc, Vec V,
351  InsertMode mode,
352  ScatterMode scatter_mode) const {
353  const MoFEM::Interface &m_field = cOre;
354  const Problem *problem_ptr;
356  CHKERR m_field.get_problem(name, &problem_ptr);
357  CHKERR setGlobalGhostVector(problem_ptr, rc, V, mode, scatter_mode);
359 }
360 
361 template <int MODE> struct SetOtherLocalGhostVector {
362  template <typename A0, typename A1, typename A2, typename A3, typename A4>
363  inline MoFEMErrorCode operator()(A0 dofs_ptr, A1 array, A2 miit, A3 hi_miit,
364  A4 &cpy_field_name) {
366  for (; miit != hi_miit; miit++) {
367  if (miit->get()->getHasLocalIndex()) {
368  auto diiiit =
369  dofs_ptr
370  ->template get<Composite_Name_And_Ent_And_EntDofIdx_mi_tag>()
371  .find(boost::make_tuple(cpy_field_name, (*miit)->getEnt(),
372  (*miit)->getEntDofIdx()));
373  if (diiiit ==
374  dofs_ptr
375  ->template get<Composite_Name_And_Ent_And_EntDofIdx_mi_tag>()
376  .end()) {
377  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
378  "Automatic creation of entity and dof not implemented");
379  }
380  if (MODE == INSERT_VALUES)
381  (*diiiit)->getFieldData() = array[(*miit)->getPetscLocalDofIdx()];
382  else if (MODE == ADD_VALUES)
383  (*diiiit)->getFieldData() += array[(*miit)->getPetscLocalDofIdx()];
384  }
385  }
387  }
388 };
389 
391  const Problem *problem_ptr, const std::string &field_name,
392  const std::string &cpy_field_name, RowColData rc, Vec V, InsertMode mode,
393  ScatterMode scatter_mode) const {
394  const MoFEM::Interface &m_field = cOre;
395  const Field_multiIndex *fields_ptr;
396  const DofEntity_multiIndex *dofs_ptr;
398  CHKERR m_field.get_fields(&fields_ptr);
399  CHKERR m_field.get_dofs(&dofs_ptr);
401  DofsByName *dofs;
402  switch (rc) {
403  case ROW:
404  dofs = const_cast<DofsByName *>(
405  &problem_ptr->numeredDofsRows->get<FieldName_mi_tag>());
406  break;
407  case COL:
408  dofs = const_cast<DofsByName *>(
409  &problem_ptr->numeredDofsCols->get<FieldName_mi_tag>());
410  break;
411  default:
412  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
413  }
414  Field_multiIndex::index<FieldName_mi_tag>::type::iterator cpy_fit =
415  fields_ptr->get<FieldName_mi_tag>().find(cpy_field_name);
416  if (cpy_fit == fields_ptr->get<FieldName_mi_tag>().end()) {
417  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND,
418  "cpy field < %s > not found, (top tip: check spelling)",
419  cpy_field_name.c_str());
420  }
421  DofsByName::iterator miit = dofs->lower_bound(field_name);
422  if (miit == dofs->end()) {
423  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND,
424  "cpy field < %s > not found, (top tip: check spelling)",
425  field_name.c_str());
426  }
427  DofsByName::iterator hi_miit = dofs->upper_bound(field_name);
428  if ((*miit)->getSpace() != (*cpy_fit)->getSpace()) {
429  SETERRQ4(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
430  "fields have to have same space (%s) %s != (%s) %s",
431  (*miit)->getName().c_str(), FieldSpaceNames[(*miit)->getSpace()],
432  cpy_field_name.c_str(), FieldSpaceNames[(*cpy_fit)->getSpace()]);
433  }
434  if ((*miit)->getNbOfCoeffs() != (*cpy_fit)->getNbOfCoeffs()) {
435  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
436  "fields have to have same rank");
437  }
438 
439  switch (scatter_mode) {
440  case SCATTER_REVERSE: {
441 
442  PetscScalar *array;
443  CHKERR VecGetArray(V, &array);
444  if (mode == INSERT_VALUES)
445  CHKERR SetOtherLocalGhostVector<INSERT_VALUES>()(dofs_ptr, array, miit,
446  hi_miit, cpy_field_name);
447  else if (mode == ADD_VALUES)
448  CHKERR SetOtherLocalGhostVector<ADD_VALUES>()(dofs_ptr, array, miit,
449  hi_miit, cpy_field_name);
450  else
451  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
452  "Operation mode not implemented");
453  CHKERR VecRestoreArray(V, &array);
454  } break;
455  case SCATTER_FORWARD: {
456  for (; miit != hi_miit; miit++) {
457  if (!miit->get()->getHasLocalIndex())
458  continue;
459  DofEntity_multiIndex::index<
460  Composite_Name_And_Ent_And_EntDofIdx_mi_tag>::type::iterator diiiit;
461  diiiit =
462  dofs_ptr->get<Composite_Name_And_Ent_And_EntDofIdx_mi_tag>().find(
463  boost::make_tuple(cpy_field_name, (*miit)->getEnt(),
464  (*miit)->getEntDofIdx()));
465  if (diiiit ==
466  dofs_ptr->get<Composite_Name_And_Ent_And_EntDofIdx_mi_tag>().end()) {
467  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
468  "no data to fill the vector (top tip: you want scatter forward "
469  "or scatter reverse?)");
470  }
471  CHKERR VecSetValue(V, (*miit)->getPetscGlobalDofIdx(),
472  (*diiiit)->getFieldData(), mode);
473  }
474  CHKERR VecAssemblyBegin(V);
475  CHKERR VecAssemblyEnd(V);
476  } break;
477  default:
478  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "not implemented");
479  }
481 }
482 
484  const std::string &name, const std::string &field_name,
485  const std::string &cpy_field_name, RowColData rc, Vec V, InsertMode mode,
486  ScatterMode scatter_mode) const {
487  const MoFEM::Interface &m_field = cOre;
488  const Problem *problem_ptr;
490  CHKERR m_field.get_problem(name, &problem_ptr);
491  CHKERR setOtherLocalGhostVector(problem_ptr, field_name, cpy_field_name, rc,
492  V, mode, scatter_mode);
494 }
495 
496 template <int MODE> struct SetOtherGlobalGhostVector {
497  template <typename A0, typename A1, typename A2, typename A3, typename A4>
498  inline MoFEMErrorCode operator()(A0 dofs_ptr, A1 array, A2 miit, A3 hi_miit,
499  A4 &cpy_field_name) {
501  for (; miit != hi_miit; miit++) {
502  auto diiiit =
503  dofs_ptr->template get<Composite_Name_And_Ent_And_EntDofIdx_mi_tag>()
504  .find(boost::make_tuple(cpy_field_name, (*miit)->getEnt(),
505  (*miit)->getEntDofIdx()));
506  if (diiiit ==
507  dofs_ptr->template get<Composite_Name_And_Ent_And_EntDofIdx_mi_tag>()
508  .end()) {
509  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
510  "Automatic creation of entity and dof not implemented");
511  }
512  if (MODE == INSERT_VALUES)
513  (*diiiit)->getFieldData() = array[(*miit)->getPetscGlobalDofIdx()];
514  else if (MODE == ADD_VALUES)
515  (*diiiit)->getFieldData() += array[(*miit)->getPetscGlobalDofIdx()];
516  }
518  }
519 };
520 
522  const Problem *problem_ptr, const std::string &field_name,
523  const std::string &cpy_field_name, RowColData rc, Vec V, InsertMode mode,
524  ScatterMode scatter_mode) const {
525  const MoFEM::Interface &m_field = cOre;
526  const Field_multiIndex *fields_ptr;
527  const DofEntity_multiIndex *dofs_ptr;
528  const FieldEntity_multiIndex *field_ents;
530  CHKERR m_field.get_fields(&fields_ptr);
531  CHKERR m_field.get_dofs(&dofs_ptr);
532  CHKERR m_field.get_field_ents(&field_ents);
533  typedef NumeredDofEntityByFieldName DofsByName;
534  DofsByName *dofs;
535  DofIdx nb_dofs;
536  switch (rc) {
537  case ROW:
538  nb_dofs = problem_ptr->getNbDofsRow();
539  dofs = const_cast<DofsByName *>(
540  &problem_ptr->numeredDofsRows->get<FieldName_mi_tag>());
541  break;
542  case COL:
543  nb_dofs = problem_ptr->getNbDofsCol();
544  dofs = const_cast<DofsByName *>(
545  &problem_ptr->numeredDofsCols->get<FieldName_mi_tag>());
546  break;
547  default:
548  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "not implemented");
549  }
550  auto cpy_fit = fields_ptr->get<FieldName_mi_tag>().find(cpy_field_name);
551  if (cpy_fit == fields_ptr->get<FieldName_mi_tag>().end()) {
552  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND,
553  "cpy field < %s > not found, (top tip: check spelling)",
554  cpy_field_name.c_str());
555  }
556  auto miit = dofs->lower_bound(field_name);
557  if (miit == dofs->end()) {
558  SETERRQ1(PETSC_COMM_SELF, MOFEM_NOT_FOUND,
559  "problem field < %s > not found, (top tip: check spelling)",
560  field_name.c_str());
561  }
562  auto hi_miit = dofs->upper_bound(field_name);
563  if ((*miit)->getSpace() != (*cpy_fit)->getSpace()) {
564  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
565  "fields have to have same space");
566  }
567  if ((*miit)->getNbOfCoeffs() != (*cpy_fit)->getNbOfCoeffs()) {
568  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
569  "fields have to have same rank");
570  }
571  switch (scatter_mode) {
572  case SCATTER_REVERSE: {
573  Vec V_glob;
574  VecScatter ctx;
575  CHKERR VecScatterCreateToAll(V, &ctx, &V_glob);
576  CHKERR VecScatterBegin(ctx, V, V_glob, INSERT_VALUES, SCATTER_FORWARD);
577  CHKERR VecScatterEnd(ctx, V, V_glob, INSERT_VALUES, SCATTER_FORWARD);
578  int size;
579  CHKERR VecGetSize(V_glob, &size);
580  if (size != nb_dofs)
581  SETERRQ(
582  PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
583  "data inconsistency: nb. of dofs and declared nb. dofs in database");
584  PetscScalar *array;
585  CHKERR VecGetArray(V_glob, &array);
586 
587  if (mode == INSERT_VALUES)
589  dofs_ptr, array, miit, hi_miit, cpy_field_name);
590  else if (mode == ADD_VALUES)
591  CHKERR SetOtherGlobalGhostVector<ADD_VALUES>()(dofs_ptr, array, miit,
592  hi_miit, cpy_field_name);
593  else
594  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
595  "Operation mode not implemented");
596 
597  CHKERR VecRestoreArray(V_glob, &array);
598  CHKERR VecDestroy(&V_glob);
599  CHKERR VecScatterDestroy(&ctx);
600  } break;
601  case SCATTER_FORWARD: {
602  for (; miit != hi_miit; miit++) {
603  auto diiiit =
604  dofs_ptr->get<Composite_Name_And_Ent_And_EntDofIdx_mi_tag>().find(
605  boost::make_tuple(cpy_field_name, (*miit)->getEnt(),
606  (*miit)->getEntDofIdx()));
607  if (diiiit ==
608  dofs_ptr->get<Composite_Name_And_Ent_And_EntDofIdx_mi_tag>().end()) {
609  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
610  "No data to fill the vector (top tip: you want scatter forward "
611  "or scatter reverse?)");
612  }
613  CHKERR VecSetValue(V, (*miit)->getPetscGlobalDofIdx(),
614  (*diiiit)->getFieldData(), mode);
615  }
616  CHKERR VecAssemblyBegin(V);
617  CHKERR VecAssemblyEnd(V);
618  } break;
619  default:
620  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "not implemented");
621  }
623 }
624 
626  const std::string &name, const std::string &field_name,
627  const std::string &cpy_field_name, RowColData rc, Vec V, InsertMode mode,
628  ScatterMode scatter_mode) const {
629  const MoFEM::Interface &m_field = cOre;
630  const Problem *problem_ptr;
632  CHKERR m_field.get_problem(name, &problem_ptr);
633  CHKERR setOtherGlobalGhostVector(problem_ptr, field_name, cpy_field_name, rc,
634  V, mode, scatter_mode);
636 }
637 
638 } // namespace MoFEM
MoFEMErrorCode setOtherLocalGhostVector(const Problem *problem_ptr, const std::string &field_name, const std::string &cpy_field_name, RowColData rc, Vec V, InsertMode mode, ScatterMode scatter_mode) const
Copy vector to field which is not part of the problem.
Definition: VecManager.cpp:390
NumeredDofEntity_multiIndex::index< FieldName_mi_tag >::type NumeredDofEntityByFieldName
Numbered DoF multi-index by field name.
DofIdx getNbDofsRow() const
MoFEM interface unique ID.
DofIdx getNbGhostDofsCol() const
Section manager is used to create indexes and sectionsFIXME: ISManager is not properly testsed by ato...
Definition: ISManager.hpp:36
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:505
base class for all interface classes
multi_index_container< boost::shared_ptr< FieldEntity >, indexed_by< ordered_unique< tag< Unique_mi_tag >, member< FieldEntity, UId, &FieldEntity::globalUId > >, ordered_non_unique< tag< FieldName_mi_tag >, const_mem_fun< FieldEntity::interface_type_Field, boost::string_ref, &FieldEntity::getNameRef > >, ordered_non_unique< tag< Ent_mi_tag >, const_mem_fun< FieldEntity, EntityHandle, &FieldEntity::getEnt > >, ordered_non_unique< tag< Composite_Name_And_Ent_mi_tag >, composite_key< FieldEntity, const_mem_fun< FieldEntity::interface_type_Field, boost::string_ref, &FieldEntity::getNameRef >, const_mem_fun< FieldEntity, EntityHandle, &FieldEntity::getEnt > > > > > FieldEntity_multiIndex
MultiIndex container keeps FieldEntity.
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:481
multi_index_container< boost::shared_ptr< Field >, indexed_by< hashed_unique< tag< BitFieldId_mi_tag >, const_mem_fun< Field, const BitFieldId &, &Field::getId >, HashBit< BitFieldId >, EqBit< BitFieldId > >, ordered_unique< tag< Meshset_mi_tag >, member< Field, EntityHandle, &Field::meshSet > >, ordered_unique< tag< FieldName_mi_tag >, const_mem_fun< Field, boost::string_ref, &Field::getNameRef > >, ordered_non_unique< tag< BitFieldId_space_mi_tag >, const_mem_fun< Field, FieldSpace, &Field::getSpace > > > > Field_multiIndex
Field_multiIndex for Field.
DofIdx getNbLocalDofsRow() const
static const MOFEMuuid IDD_MOFEMVEC
Definition: VecManager.hpp:26
Core (interface) class.
Definition: Core.hpp:50
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:512
NumeredDofEntity_multiIndex::index< PetscLocalIdx_mi_tag >::type NumeredDofEntityByLocalIdx
Numbered DoF multi-index by local index.
keeps basic data about problemThis is low level structure with information about problem,...
DofIdx getNbGhostDofsRow() const
RowColData
RowColData.
Definition: definitions.h:190
MoFEMErrorCode query_interface(const MOFEMuuid &uuid, UnknownInterface **iface) const
Definition: VecManager.cpp:20
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:21
const MoFEM::Interface & cOre
Definition: VecManager.hpp:41
virtual MoFEMErrorCode get_dofs(const DofEntity_multiIndex **dofs_ptr) const =0
Get dofs multi index.
MoFEMErrorCode setLocalGhostVector(const Problem *problem_ptr, RowColData rc, Vec V, InsertMode mode, ScatterMode scatter_mode) const
set values of vector from/to meshdatabase
Definition: VecManager.cpp:184
MoFEMErrorCode setGlobalGhostVector(const Problem *problem_ptr, RowColData rc, Vec V, InsertMode mode, ScatterMode scatter_mode) const
set values of vector from/to mesh database (collective)collective - need tu be run on all processors ...
Definition: VecManager.cpp:286
MoFEMErrorCode vecCreateGhost(const std::string &name, RowColData rc, Vec *V) const
create ghost vector for problem (collective)collective - need to be run on all processors in communic...
Definition: VecManager.cpp:59
MoFEMErrorCode vecScatterCreate(Vec xin, const std::string &x_problem, const std::string &x_field_name, RowColData x_rc, Vec yin, const std::string &y_problem, const std::string &y_field_name, RowColData y_rc, VecScatter *newctx) const
create scatter for vectors form one to another problem (collective)User specify what name of field on...
Definition: VecManager.cpp:112
MoFEMErrorCode getInterface(const MOFEMuuid &uuid, IFACE *&iface) const
Get interface by uuid and return reference to pointer of interface.
virtual MoFEMErrorCode get_problem(const std::string &problem_name, const Problem **problem_ptr) const =0
Get problem database (data structure)
multi_index_container< boost::shared_ptr< DofEntity >, indexed_by< ordered_unique< tag< Unique_mi_tag >, member< DofEntity, UId, &DofEntity::globalUId > >, ordered_non_unique< tag< Composite_Name_And_Ent_And_EntDofIdx_mi_tag >, composite_key< DofEntity, const_mem_fun< DofEntity::interface_type_Field, boost::string_ref, &DofEntity::getNameRef >, const_mem_fun< DofEntity, EntityHandle, &DofEntity::getEnt >, const_mem_fun< DofEntity, DofIdx, &DofEntity::getEntDofIdx > > >, ordered_non_unique< tag< Unique_Ent_mi_tag >, const_mem_fun< DofEntity, const UId &, &DofEntity::getEntGlobalUniqueId > >, ordered_non_unique< tag< FieldName_mi_tag >, const_mem_fun< DofEntity::interface_type_Field, boost::string_ref, &DofEntity::getNameRef > >, ordered_non_unique< tag< Ent_mi_tag >, const_mem_fun< DofEntity, EntityHandle, &DofEntity::getEnt > >, ordered_non_unique< tag< Composite_Name_And_Ent_mi_tag >, composite_key< DofEntity, const_mem_fun< DofEntity::interface_type_Field, boost::string_ref, &DofEntity::getNameRef >, const_mem_fun< DofEntity, EntityHandle, &DofEntity::getEnt > > >, ordered_non_unique< tag< Composite_Name_And_Type_mi_tag >, composite_key< DofEntity, const_mem_fun< DofEntity::interface_type_Field, boost::string_ref, &DofEntity::getNameRef >, const_mem_fun< DofEntity::interface_type_RefEntity, EntityType, &DofEntity::getEntType > > > > > DofEntity_multiIndex
MultiIndex container keeps DofEntity.
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:66
~VecManager()
Destructor.
Definition: VecManager.cpp:34
MoFEMErrorCode operator()(A0 dofs_ptr, A1 array, A2 miit, A3 hi_miit, A4 &cpy_field_name)
Definition: VecManager.cpp:498
boost::shared_ptr< NumeredDofEntity_multiIndex > numeredDofsRows
store DOFs on rows for this problem
static const char *const FieldSpaceNames[]
Definition: definitions.h:182
#define CHKERR
Inline error check.
Definition: definitions.h:600
virtual MoFEMErrorCode get_field_ents(const FieldEntity_multiIndex **field_ents) const =0
Get field multi index.
DofIdx getNbDofsCol() const
MoFEMErrorCode vecCreateSeq(const std::string &name, RowColData rc, Vec *V) const
create local vector for problem
Definition: VecManager.cpp:36
MultiIndex Tag for field name.
VecManager(const MoFEM::Core &core)
Definition: VecManager.cpp:32
int DofIdx
Index of DOF.
Definition: Types.hpp:29
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:411
MoFEMErrorCode setOtherGlobalGhostVector(const Problem *problem_ptr, const std::string &field_name, const std::string &cpy_field_name, RowColData rc, Vec V, InsertMode mode, ScatterMode scatter_mode) const
Copy vector to field which is not part of the problem (collective)collective - need tu be run on all ...
Definition: VecManager.cpp:521
virtual MoFEMErrorCode get_fields(const Field_multiIndex **fields_ptr) const =0
Get fields multi-index from database.
MoFEMErrorCode operator()(A0 dofs_ptr, A1 array, A2 miit, A3 hi_miit, A4 &cpy_field_name)
Definition: VecManager.cpp:363
DofIdx getNbLocalDofsCol() const
boost::shared_ptr< NumeredDofEntity_multiIndex > numeredDofsCols
store DOFs on columns for this problem