Actual source code: dadist.c


  2: /*
  3:   Code for manipulating distributed regular arrays in parallel.
  4: */

  6: #include <petsc/private/dmdaimpl.h>

  8: PetscErrorCode VecDuplicate_MPI_DA(Vec g, Vec *gg)
  9: {
 10:   DM          da;
 11:   PetscLayout map;

 13:   PetscFunctionBegin;
 14:   PetscCall(VecGetDM(g, &da));
 15:   PetscCall(DMCreateGlobalVector(da, gg));
 16:   PetscCall(VecGetLayout(g, &map));
 17:   PetscCall(VecSetLayout(*gg, map));
 18:   PetscFunctionReturn(PETSC_SUCCESS);
 19: }

 21: PetscErrorCode DMCreateGlobalVector_DA(DM da, Vec *g)
 22: {
 23:   DM_DA *dd = (DM_DA *)da->data;

 25:   PetscFunctionBegin;
 28:   PetscCall(VecCreate(PetscObjectComm((PetscObject)da), g));
 29:   PetscCall(VecSetSizes(*g, dd->Nlocal, PETSC_DETERMINE));
 30:   PetscCall(VecSetBlockSize(*g, dd->w));
 31:   PetscCall(VecSetType(*g, da->vectype));
 32:   if (dd->Nlocal < da->bind_below) {
 33:     PetscCall(VecSetBindingPropagates(*g, PETSC_TRUE));
 34:     PetscCall(VecBindToCPU(*g, PETSC_TRUE));
 35:   }
 36:   PetscCall(VecSetDM(*g, da));
 37:   PetscCall(VecSetLocalToGlobalMapping(*g, da->ltogmap));
 38:   PetscCall(VecSetOperation(*g, VECOP_VIEW, (void (*)(void))VecView_MPI_DA));
 39:   PetscCall(VecSetOperation(*g, VECOP_LOAD, (void (*)(void))VecLoad_Default_DA));
 40:   PetscCall(VecSetOperation(*g, VECOP_DUPLICATE, (void (*)(void))VecDuplicate_MPI_DA));
 41:   PetscFunctionReturn(PETSC_SUCCESS);
 42: }

 44: /*@
 45:    DMDACreateNaturalVector - Creates a parallel PETSc vector that
 46:    will hold vector values in the natural numbering, rather than in
 47:    the PETSc parallel numbering associated with the `DMDA`.

 49:    Collective

 51:    Input Parameter:
 52: .  da - the distributed array

 54:    Output Parameter:
 55: .  g - the distributed global vector

 57:    Level: developer

 59:    Notes:
 60:    The output parameter, g, is a regular PETSc vector that should be destroyed
 61:    with a call to `VecDestroy()` when usage is finished.

 63:    The number of local entries in the vector on each process is the same
 64:    as in a vector created with `DMCreateGlobalVector()`.

 66: .seealso: `DM`, `DMDA`, `DMCreateLocalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
 67:           `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToLocalBegin()`,
 68:           `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`
 69: @*/
 70: PetscErrorCode DMDACreateNaturalVector(DM da, Vec *g)
 71: {
 72:   PetscInt cnt;
 73:   DM_DA   *dd = (DM_DA *)da->data;

 75:   PetscFunctionBegin;
 78:   if (dd->natural) {
 79:     PetscCall(PetscObjectGetReference((PetscObject)dd->natural, &cnt));
 80:     if (cnt == 1) { /* object is not currently used by anyone */
 81:       PetscCall(PetscObjectReference((PetscObject)dd->natural));
 82:       *g = dd->natural;
 83:     } else PetscCall(VecDuplicate(dd->natural, g));
 84:   } else { /* create the first version of this guy */
 85:     PetscCall(VecCreate(PetscObjectComm((PetscObject)da), g));
 86:     PetscCall(VecSetSizes(*g, dd->Nlocal, PETSC_DETERMINE));
 87:     PetscCall(VecSetBlockSize(*g, dd->w));
 88:     PetscCall(VecSetType(*g, da->vectype));
 89:     PetscCall(PetscObjectReference((PetscObject)*g));

 91:     dd->natural = *g;
 92:   }
 93:   PetscFunctionReturn(PETSC_SUCCESS);
 94: }