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