xref: /petsc/src/dm/impls/da/dadist.c (revision a69119a591a03a9d906b29c0a4e9802e4d7c9795) !
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   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(0);
18 }
19 
20 PetscErrorCode DMCreateGlobalVector_DA(DM da, Vec *g) {
21   DM_DA *dd = (DM_DA *)da->data;
22 
23   PetscFunctionBegin;
24   PetscValidHeaderSpecific(da, DM_CLASSID, 1);
25   PetscValidPointer(g, 2);
26   PetscCall(VecCreate(PetscObjectComm((PetscObject)da), g));
27   PetscCall(VecSetSizes(*g, dd->Nlocal, PETSC_DETERMINE));
28   PetscCall(VecSetBlockSize(*g, dd->w));
29   PetscCall(VecSetType(*g, da->vectype));
30   if (dd->Nlocal < da->bind_below) {
31     PetscCall(VecSetBindingPropagates(*g, PETSC_TRUE));
32     PetscCall(VecBindToCPU(*g, PETSC_TRUE));
33   }
34   PetscCall(VecSetDM(*g, da));
35   PetscCall(VecSetLocalToGlobalMapping(*g, da->ltogmap));
36   PetscCall(VecSetOperation(*g, VECOP_VIEW, (void (*)(void))VecView_MPI_DA));
37   PetscCall(VecSetOperation(*g, VECOP_LOAD, (void (*)(void))VecLoad_Default_DA));
38   PetscCall(VecSetOperation(*g, VECOP_DUPLICATE, (void (*)(void))VecDuplicate_MPI_DA));
39   PetscFunctionReturn(0);
40 }
41 
42 /*@
43    DMDACreateNaturalVector - Creates a parallel PETSc vector that
44    will hold vector values in the natural numbering, rather than in
45    the PETSc parallel numbering associated with the DMDA.
46 
47    Collective
48 
49    Input Parameter:
50 .  da - the distributed array
51 
52    Output Parameter:
53 .  g - the distributed global vector
54 
55    Level: developer
56 
57    Note:
58    The output parameter, g, is a regular PETSc vector that should be destroyed
59    with a call to VecDestroy() when usage is finished.
60 
61    The number of local entries in the vector on each process is the same
62    as in a vector created with DMCreateGlobalVector().
63 
64 .seealso: `DMCreateLocalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
65           `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToLocalBegin()`,
66           `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`
67 @*/
68 PetscErrorCode DMDACreateNaturalVector(DM da, Vec *g) {
69   PetscInt cnt;
70   DM_DA   *dd = (DM_DA *)da->data;
71 
72   PetscFunctionBegin;
73   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
74   PetscValidPointer(g, 2);
75   if (dd->natural) {
76     PetscCall(PetscObjectGetReference((PetscObject)dd->natural, &cnt));
77     if (cnt == 1) { /* object is not currently used by anyone */
78       PetscCall(PetscObjectReference((PetscObject)dd->natural));
79       *g = dd->natural;
80     } else PetscCall(VecDuplicate(dd->natural, g));
81   } else { /* create the first version of this guy */
82     PetscCall(VecCreate(PetscObjectComm((PetscObject)da), g));
83     PetscCall(VecSetSizes(*g, dd->Nlocal, PETSC_DETERMINE));
84     PetscCall(VecSetBlockSize(*g, dd->w));
85     PetscCall(VecSetType(*g, da->vectype));
86     PetscCall(PetscObjectReference((PetscObject)*g));
87 
88     dd->natural = *g;
89   }
90   PetscFunctionReturn(0);
91 }
92