xref: /petsc/src/dm/impls/da/dadist.c (revision 2286efddd54511ab18e8e2adb1e023c4bf8f0b92)
1 /*
2   Code for manipulating distributed regular arrays in parallel.
3 */
4 
5 #include <petsc/private/dmdaimpl.h> /*I   "petscdmda.h"   I*/
6 
DMCreateGlobalVector_DA(DM da,Vec * g)7 PetscErrorCode DMCreateGlobalVector_DA(DM da, Vec *g)
8 {
9   DM_DA *dd = (DM_DA *)da->data;
10 
11   PetscFunctionBegin;
12   PetscValidHeaderSpecific(da, DM_CLASSID, 1);
13   PetscAssertPointer(g, 2);
14   PetscCall(VecCreate(PetscObjectComm((PetscObject)da), g));
15   PetscCall(VecSetSizes(*g, dd->Nlocal, PETSC_DETERMINE));
16   PetscCall(VecSetBlockSize(*g, dd->w));
17   PetscCall(VecSetType(*g, da->vectype));
18   if (dd->Nlocal < da->bind_below) {
19     PetscCall(VecSetBindingPropagates(*g, PETSC_TRUE));
20     PetscCall(VecBindToCPU(*g, PETSC_TRUE));
21   }
22   PetscCall(VecSetDM(*g, da));
23   PetscCall(VecSetLocalToGlobalMapping(*g, da->ltogmap));
24   PetscCall(VecSetOperation(*g, VECOP_VIEW, (PetscErrorCodeFn *)VecView_MPI_DA));
25   PetscCall(VecSetOperation(*g, VECOP_LOAD, (PetscErrorCodeFn *)VecLoad_Default_DA));
26   PetscFunctionReturn(PETSC_SUCCESS);
27 }
28 
29 /*@
30   DMDACreateNaturalVector - Creates a parallel PETSc vector that
31   will hold vector values in the natural numbering, rather than in
32   the PETSc parallel numbering associated with the `DMDA`.
33 
34   Collective
35 
36   Input Parameter:
37 . da - the `DMDA`
38 
39   Output Parameter:
40 . g - the distributed global vector
41 
42   Level: advanced
43 
44   Notes:
45   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
46   (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).
47 
48   The output parameter, `g`, is a regular `Vec` that should be destroyed
49   with a call to `VecDestroy()` when usage is finished.
50 
51   The number of local entries in the vector on each process is the same
52   as in a vector created with `DMCreateGlobalVector()`.
53 
54 .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAGlobalToNaturalBegin()`, `DMDAGlobalToNaturalEnd()`, `DMDANaturalToGlobalBegin()`, `DMDANaturalToGlobalEnd()`,
55           `DMCreateLocalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToLocalBegin()`,
56           `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`
57 @*/
DMDACreateNaturalVector(DM da,Vec * g)58 PetscErrorCode DMDACreateNaturalVector(DM da, Vec *g)
59 {
60   PetscInt cnt;
61   DM_DA   *dd = (DM_DA *)da->data;
62 
63   PetscFunctionBegin;
64   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
65   PetscAssertPointer(g, 2);
66   if (dd->natural) {
67     PetscCall(PetscObjectGetReference((PetscObject)dd->natural, &cnt));
68     if (cnt == 1) { /* object is not currently used by anyone */
69       PetscCall(PetscObjectReference((PetscObject)dd->natural));
70       *g = dd->natural;
71     } else PetscCall(VecDuplicate(dd->natural, g));
72   } else { /* create the first version of this guy */
73     PetscCall(VecCreate(PetscObjectComm((PetscObject)da), g));
74     PetscCall(VecSetSizes(*g, dd->Nlocal, PETSC_DETERMINE));
75     PetscCall(VecSetBlockSize(*g, dd->w));
76     PetscCall(VecSetType(*g, da->vectype));
77     PetscCall(PetscObjectReference((PetscObject)*g));
78     dd->natural = *g;
79   }
80   PetscFunctionReturn(PETSC_SUCCESS);
81 }
82