xref: /petsc/src/dm/impls/da/dadist.c (revision 21e3ffae2f3b73c0bd738cf6d0a809700fc04bb0)
1 
2 /*
3   Code for manipulating distributed regular arrays in parallel.
4 */
5 
6 #include <petsc/private/dmdaimpl.h> /*I   "petscdmda.h"   I*/
7 
8 PetscErrorCode VecDuplicate_MPI_DA(Vec g, Vec *gg)
9 {
10   DM          da;
11   PetscLayout map;
12 
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 }
20 
21 PetscErrorCode DMCreateGlobalVector_DA(DM da, Vec *g)
22 {
23   DM_DA *dd = (DM_DA *)da->data;
24 
25   PetscFunctionBegin;
26   PetscValidHeaderSpecific(da, DM_CLASSID, 1);
27   PetscValidPointer(g, 2);
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 }
43 
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`.
48 
49    Collective
50 
51    Input Parameter:
52 .  da - the distributed array
53 
54    Output Parameter:
55 .  g - the distributed global vector
56 
57    Level: developer
58 
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.
62 
63    The number of local entries in the vector on each process is the same
64    as in a vector created with `DMCreateGlobalVector()`.
65 
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;
74 
75   PetscFunctionBegin;
76   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
77   PetscValidPointer(g, 2);
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));
90 
91     dd->natural = *g;
92   }
93   PetscFunctionReturn(PETSC_SUCCESS);
94 }
95