xref: /petsc/src/dm/impls/da/dagtol.c (revision 705a7f0eb0ef90644623ad86b4e8bfdbdabd856c)
1 /*
2   Code for manipulating distributed regular arrays in parallel.
3 */
4 
5 #include <petsc/private/dmdaimpl.h> /*I   "petscdmda.h"   I*/
6 
DMGlobalToLocalBegin_DA(DM da,Vec g,InsertMode mode,Vec l)7 PetscErrorCode DMGlobalToLocalBegin_DA(DM da, Vec g, InsertMode mode, Vec l)
8 {
9   DM_DA *dd = (DM_DA *)da->data;
10 
11   PetscFunctionBegin;
12   PetscValidHeaderSpecific(da, DM_CLASSID, 1);
13   PetscValidHeaderSpecific(g, VEC_CLASSID, 2);
14   PetscValidHeaderSpecific(l, VEC_CLASSID, 4);
15   PetscCall(VecScatterBegin(dd->gtol, g, l, mode, SCATTER_FORWARD));
16   PetscFunctionReturn(PETSC_SUCCESS);
17 }
18 
DMGlobalToLocalEnd_DA(DM da,Vec g,InsertMode mode,Vec l)19 PetscErrorCode DMGlobalToLocalEnd_DA(DM da, Vec g, InsertMode mode, Vec l)
20 {
21   DM_DA *dd = (DM_DA *)da->data;
22 
23   PetscFunctionBegin;
24   PetscValidHeaderSpecific(da, DM_CLASSID, 1);
25   PetscValidHeaderSpecific(g, VEC_CLASSID, 2);
26   PetscValidHeaderSpecific(l, VEC_CLASSID, 4);
27   PetscCall(VecScatterEnd(dd->gtol, g, l, mode, SCATTER_FORWARD));
28   PetscFunctionReturn(PETSC_SUCCESS);
29 }
30 
DMLocalToGlobalBegin_DA(DM da,Vec l,InsertMode mode,Vec g)31 PetscErrorCode DMLocalToGlobalBegin_DA(DM da, Vec l, InsertMode mode, Vec g)
32 {
33   DM_DA *dd = (DM_DA *)da->data;
34 
35   PetscFunctionBegin;
36   PetscValidHeaderSpecific(da, DM_CLASSID, 1);
37   PetscValidHeaderSpecific(l, VEC_CLASSID, 2);
38   PetscValidHeaderSpecific(g, VEC_CLASSID, 4);
39   if (mode == ADD_VALUES) {
40     PetscCall(VecScatterBegin(dd->gtol, l, g, ADD_VALUES, SCATTER_REVERSE));
41   } else if (mode == INSERT_VALUES) {
42     PetscCheck(dd->bx == DM_BOUNDARY_GHOSTED || dd->bx == DM_BOUNDARY_NONE || dd->s <= 0 || dd->m != 1, PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Available only for boundary none or with parallelism in x direction");
43     PetscCheck(dd->bx == DM_BOUNDARY_GHOSTED || dd->by == DM_BOUNDARY_NONE || dd->s <= 0 || dd->n != 1, PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Available only for boundary none or with parallelism in y direction");
44     PetscCheck(dd->bx == DM_BOUNDARY_GHOSTED || dd->bz == DM_BOUNDARY_NONE || dd->s <= 0 || dd->p != 1, PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Available only for boundary none or with parallelism in z direction");
45     PetscCall(VecScatterBegin(dd->gtol, l, g, INSERT_VALUES, SCATTER_REVERSE_LOCAL));
46   } else SETERRQ(PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Not yet implemented");
47   PetscFunctionReturn(PETSC_SUCCESS);
48 }
49 
DMLocalToGlobalEnd_DA(DM da,Vec l,InsertMode mode,Vec g)50 PetscErrorCode DMLocalToGlobalEnd_DA(DM da, Vec l, InsertMode mode, Vec g)
51 {
52   DM_DA *dd = (DM_DA *)da->data;
53 
54   PetscFunctionBegin;
55   PetscValidHeaderSpecific(da, DM_CLASSID, 1);
56   PetscValidHeaderSpecific(l, VEC_CLASSID, 2);
57   PetscValidHeaderSpecific(g, VEC_CLASSID, 4);
58   if (mode == ADD_VALUES) {
59     PetscCall(VecScatterEnd(dd->gtol, l, g, ADD_VALUES, SCATTER_REVERSE));
60   } else if (mode == INSERT_VALUES) {
61     PetscCall(VecScatterEnd(dd->gtol, l, g, INSERT_VALUES, SCATTER_REVERSE_LOCAL));
62   } else SETERRQ(PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Not yet implemented");
63   PetscFunctionReturn(PETSC_SUCCESS);
64 }
65 
66 /*
67   DMDAGlobalToNatural_Create - Create the global to natural scatter object
68 
69   Collective
70 
71   Input Parameter:
72 . da - the `DMDA` context
73 
74   Level: developer
75 
76   Note:
77   This is an internal routine called by `DMDAGlobalToNatural()` to
78   create the scatter context.
79 
80 .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAGlobalToNaturalBegin()`, `DMDAGlobalToNaturalEnd()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`,
81           `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()`
82 */
DMDAGlobalToNatural_Create(DM da)83 static PetscErrorCode DMDAGlobalToNatural_Create(DM da)
84 {
85   PetscInt m, start, Nlocal;
86   IS       from, to;
87   Vec      global;
88   DM_DA   *dd = (DM_DA *)da->data;
89 
90   PetscFunctionBegin;
91   PetscValidHeaderSpecific(da, DM_CLASSID, 1);
92   PetscCheck(dd->natural, PetscObjectComm((PetscObject)da), PETSC_ERR_ORDER, "Natural layout vector not yet created; cannot scatter into it");
93 
94   /* create the scatter context */
95   PetscCall(VecGetLocalSize(dd->natural, &m));
96   PetscCall(VecGetOwnershipRange(dd->natural, &start, NULL));
97 
98   PetscCall(DMDAGetNatural_Private(da, &Nlocal, &to));
99   PetscCheck(Nlocal == m, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Internal error: Nlocal %" PetscInt_FMT " local vector size %" PetscInt_FMT, Nlocal, m);
100   PetscCall(ISCreateStride(PetscObjectComm((PetscObject)da), m, start, 1, &from));
101   PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)da), dd->w, dd->Nlocal, PETSC_DETERMINE, NULL, &global));
102   PetscCall(VecScatterCreate(global, from, dd->natural, to, &dd->gton));
103   PetscCall(VecDestroy(&global));
104   PetscCall(ISDestroy(&from));
105   PetscCall(ISDestroy(&to));
106   PetscFunctionReturn(PETSC_SUCCESS);
107 }
108 
109 /*@
110   DMDAGlobalToNaturalBegin - Maps values from the global vector obtained with `DMCreateGlobalVector()` to a global vector
111   in the "natural" grid ordering. Must be followed by
112   `DMDAGlobalToNaturalEnd()` to complete the exchange.
113 
114   Neighbor-wise Collective
115 
116   Input Parameters:
117 + da   - the `DMDA` context
118 . g    - the global vector, see `DMCreateGlobalVector()`
119 - mode - one of `INSERT_VALUES` or `ADD_VALUES`
120 
121   Output Parameter:
122 . n - the natural ordering values, see `DMDACreateNaturalVector()`
123 
124   Level: advanced
125 
126   Notes:
127   The global and natural vectors used here need not be the same as those
128   obtained from `DMCreateGlobalVector()` and `DMDACreateNaturalVector()`, BUT they
129   must have the same parallel data layout; they could, for example, be
130   obtained with `VecDuplicate()` from the `DMDA` originating vectors.
131 
132   You must call `DMDACreateNaturalVector()` before using this routine
133 
134 .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAGlobalToNaturalEnd()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`,
135           `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()`
136 @*/
DMDAGlobalToNaturalBegin(DM da,Vec g,InsertMode mode,Vec n)137 PetscErrorCode DMDAGlobalToNaturalBegin(DM da, Vec g, InsertMode mode, Vec n)
138 {
139   DM_DA *dd = (DM_DA *)da->data;
140 
141   PetscFunctionBegin;
142   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
143   PetscValidHeaderSpecific(g, VEC_CLASSID, 2);
144   PetscValidHeaderSpecific(n, VEC_CLASSID, 4);
145   if (!dd->gton) {
146     /* create the scatter context */
147     PetscCall(DMDAGlobalToNatural_Create(da));
148   }
149   PetscCall(VecScatterBegin(dd->gton, g, n, mode, SCATTER_FORWARD));
150   PetscFunctionReturn(PETSC_SUCCESS);
151 }
152 
153 /*@
154   DMDAGlobalToNaturalEnd - Maps values from the global vector obtained with `DMCreateGlobalVector()` to a global vector
155   in the natural ordering. Must be preceded by `DMDAGlobalToNaturalBegin()`.
156 
157   Neighbor-wise Collective
158 
159   Input Parameters:
160 + da   - the `DMDA` context
161 . g    - the global vector, see `DMCreateGlobalVector()`
162 - mode - one of `INSERT_VALUES` or `ADD_VALUES`
163 
164   Output Parameter:
165 . n - the global values in the natural ordering, see `DMDACreateNaturalVector()`
166 
167   Level: advanced
168 
169   Note:
170   The global and local vectors used here need not be the same as those
171   obtained from `DMCreateGlobalVector()` and `DMDACreateNaturalVector()`, BUT they
172   must have the same parallel data layout; they could, for example, be
173   obtained with VecDuplicate() from the `DMDA` originating vectors.
174 
175 .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAGlobalToNaturalBegin()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`,
176           `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()`
177 @*/
DMDAGlobalToNaturalEnd(DM da,Vec g,InsertMode mode,Vec n)178 PetscErrorCode DMDAGlobalToNaturalEnd(DM da, Vec g, InsertMode mode, Vec n)
179 {
180   DM_DA *dd = (DM_DA *)da->data;
181 
182   PetscFunctionBegin;
183   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
184   PetscValidHeaderSpecific(g, VEC_CLASSID, 2);
185   PetscValidHeaderSpecific(n, VEC_CLASSID, 4);
186   PetscCall(VecScatterEnd(dd->gton, g, n, mode, SCATTER_FORWARD));
187   PetscFunctionReturn(PETSC_SUCCESS);
188 }
189 
190 /*@
191   DMDANaturalToGlobalBegin - Maps values from a global vector in the "natural" ordering
192   to a global vector in the PETSc `DMDA` grid ordering. Must be followed by
193   `DMDANaturalToGlobalEnd()` to complete the exchange.
194 
195   Neighbor-wise Collective
196 
197   Input Parameters:
198 + da   - the `DMDA` context
199 . g    - the global vector in a natural ordering, see `DMDACreateNaturalVector()`
200 - mode - one of `INSERT_VALUES` or `ADD_VALUES`
201 
202   Output Parameter:
203 . n - the values in the `DMDA` ordering
204 
205   Level: advanced
206 
207   Note:
208   The global and natural vectors used here need not be the same as those
209   obtained from `DMCreateGlobalVector()` and `DMDACreateNaturalVector()`, BUT they
210   must have the same parallel data layout; they could, for example, be
211   obtained with `VecDuplicate()` from the `DMDA` originating vectors.
212 
213 .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAGlobalToNaturalEnd()`, `DMDAGlobalToNaturalBegin()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`,
214           `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()`
215 @*/
DMDANaturalToGlobalBegin(DM da,Vec n,InsertMode mode,Vec g)216 PetscErrorCode DMDANaturalToGlobalBegin(DM da, Vec n, InsertMode mode, Vec g)
217 {
218   DM_DA *dd = (DM_DA *)da->data;
219 
220   PetscFunctionBegin;
221   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
222   PetscValidHeaderSpecific(n, VEC_CLASSID, 2);
223   PetscValidHeaderSpecific(g, VEC_CLASSID, 4);
224   if (!dd->gton) {
225     /* create the scatter context */
226     PetscCall(DMDAGlobalToNatural_Create(da));
227   }
228   PetscCall(VecScatterBegin(dd->gton, n, g, mode, SCATTER_REVERSE));
229   PetscFunctionReturn(PETSC_SUCCESS);
230 }
231 
232 /*@
233   DMDANaturalToGlobalEnd - Maps values from the natural ordering global vector
234   to a global vector in the PETSc `DMDA` ordering. Must be preceded by `DMDANaturalToGlobalBegin()`.
235 
236   Neighbor-wise Collective
237 
238   Input Parameters:
239 + da   - the `DMDA` context
240 . g    - the global vector in a natural ordering
241 - mode - one of `INSERT_VALUES` or `ADD_VALUES`
242 
243   Output Parameter:
244 . n - the global values in the PETSc `DMDA` ordering
245 
246   Level: advanced
247 
248   Note:
249   The global and local vectors used here need not be the same as those
250   obtained from `DMCreateGlobalVector()` and `DMDACreateNaturalVector()`, BUT they
251   must have the same parallel data layout; they could, for example, be
252   obtained with `VecDuplicate()` from the `DMDA` originating vectors.
253 
254 .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAGlobalToNaturalBegin()`, `DMDAGlobalToNaturalEnd()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`,
255           `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()`
256 @*/
DMDANaturalToGlobalEnd(DM da,Vec n,InsertMode mode,Vec g)257 PetscErrorCode DMDANaturalToGlobalEnd(DM da, Vec n, InsertMode mode, Vec g)
258 {
259   DM_DA *dd = (DM_DA *)da->data;
260 
261   PetscFunctionBegin;
262   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
263   PetscValidHeaderSpecific(n, VEC_CLASSID, 2);
264   PetscValidHeaderSpecific(g, VEC_CLASSID, 4);
265   PetscCall(VecScatterEnd(dd->gton, n, g, mode, SCATTER_REVERSE));
266   PetscFunctionReturn(PETSC_SUCCESS);
267 }
268