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