xref: /petsc/src/dm/impls/da/dadist.c (revision cac3c07dbc4e95423e22cb699bb64807a71d0bfe)
1 /*
2   Code for manipulating distributed regular arrays in parallel.
3 */
4 
5 #include <petsc/private/dmdaimpl.h> /*I   "petscdmda.h"   I*/
6 
7 static PetscErrorCode VecDuplicate_MPI_DA(Vec g, Vec *gg)
8 {
9   DM          da;
10   PetscLayout map;
11 
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 }
19 
20 PetscErrorCode DMCreateGlobalVector_DA(DM da, Vec *g)
21 {
22   DM_DA *dd = (DM_DA *)da->data;
23 
24   PetscFunctionBegin;
25   PetscValidHeaderSpecific(da, DM_CLASSID, 1);
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 }
42 
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`.
47 
48   Collective
49 
50   Input Parameter:
51 . da - the distributed array
52 
53   Output Parameter:
54 . g - the distributed global vector
55 
56   Level: advanced
57 
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).
61 
62   The output parameter, `g`, is a regular `Vec` that should be destroyed
63   with a call to `VecDestroy()` when usage is finished.
64 
65   The number of local entries in the vector on each process is the same
66   as in a vector created with `DMCreateGlobalVector()`.
67 
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;
76 
77   PetscFunctionBegin;
78   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
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 }
96