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 distributed array
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: }