Actual source code: dadist.c

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

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

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

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

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

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

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

 48:   Collective

 50:   Input Parameter:
 51: . da - the `DMDA`

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

 56:   Level: advanced

 58:   Notes:
 59:   The natural numbering is a number of grid nodes that starts with, in three dimensions, with (0,0,0), (1,0,0), (2,0,0), ..., (m-1,0,0) followed by
 60:   (0,1,0), (1,1,0), (2,1,0), ..., (m,1,0) etc up to (0,n-1,p-1), (1,n-1,p-1), (2,n-1,p-1), ..., (m-1,n-1,p-1).

 62:   The output parameter, `g`, is a regular `Vec` that should be destroyed
 63:   with a call to `VecDestroy()` when usage is finished.

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

 68: .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAGlobalToNaturalBegin()`, `DMDAGlobalToNaturalEnd()`, `DMDANaturalToGlobalBegin()`, `DMDANaturalToGlobalEnd()`,
 69:           `DMCreateLocalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToLocalBegin()`,
 70:           `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`
 71: @*/
 72: PetscErrorCode DMDACreateNaturalVector(DM da, Vec *g)
 73: {
 74:   PetscInt cnt;
 75:   DM_DA   *dd = (DM_DA *)da->data;

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