xref: /petsc/src/dm/impls/da/dadist.c (revision 1d27aa22b2f6148b2c4e3f06a75e0638d6493e09)
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: developer
57 
58   Notes:
59   The output parameter, g, is a regular PETSc vector that should be destroyed
60   with a call to `VecDestroy()` when usage is finished.
61 
62   The number of local entries in the vector on each process is the same
63   as in a vector created with `DMCreateGlobalVector()`.
64 
65 .seealso: `DM`, `DMDA`, `DMCreateLocalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
66           `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToLocalBegin()`,
67           `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`
68 @*/
69 PetscErrorCode DMDACreateNaturalVector(DM da, Vec *g)
70 {
71   PetscInt cnt;
72   DM_DA   *dd = (DM_DA *)da->data;
73 
74   PetscFunctionBegin;
75   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
76   PetscAssertPointer(g, 2);
77   if (dd->natural) {
78     PetscCall(PetscObjectGetReference((PetscObject)dd->natural, &cnt));
79     if (cnt == 1) { /* object is not currently used by anyone */
80       PetscCall(PetscObjectReference((PetscObject)dd->natural));
81       *g = dd->natural;
82     } else PetscCall(VecDuplicate(dd->natural, g));
83   } else { /* create the first version of this guy */
84     PetscCall(VecCreate(PetscObjectComm((PetscObject)da), g));
85     PetscCall(VecSetSizes(*g, dd->Nlocal, PETSC_DETERMINE));
86     PetscCall(VecSetBlockSize(*g, dd->w));
87     PetscCall(VecSetType(*g, da->vectype));
88     PetscCall(PetscObjectReference((PetscObject)*g));
89 
90     dd->natural = *g;
91   }
92   PetscFunctionReturn(PETSC_SUCCESS);
93 }
94