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