xref: /petsc/src/dm/interface/dmget.c (revision 26fbe8dc1a3c99fb8dddfa572c8c6b3b4ce3ca53)
1 #include <petsc-private/dmimpl.h> /*I "petscdm.h" I*/
2 
3 #undef __FUNCT__
4 #define __FUNCT__ "DMGetLocalVector"
5 /*@
6    DMGetLocalVector - Gets a Seq PETSc vector that
7    may be used with the DMXXX routines. This vector has spaces for the ghost values.
8 
9    Not Collective
10 
11    Input Parameter:
12 .  dm - the distributed array
13 
14    Output Parameter:
15 .  g - the local vector
16 
17    Level: beginner
18 
19    Note:
20    The vector values are NOT initialized and may have garbage in them, so you may need
21    to zero them.
22 
23    The output parameter, g, is a regular PETSc vector that should be returned with
24    DMRestoreLocalVector() DO NOT call VecDestroy() on it.
25 
26    VecStride*() operations can be useful when using DM with dof > 1
27 
28 .keywords: distributed array, create, local, vector
29 
30 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
31           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
32           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector(),
33           VecStrideMax(), VecStrideMin(), VecStrideNorm()
34 @*/
35 PetscErrorCode  DMGetLocalVector(DM dm,Vec *g)
36 {
37   PetscErrorCode ierr,i;
38 
39   PetscFunctionBegin;
40   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
41   PetscValidPointer(g,2);
42   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
43     if (dm->localin[i]) {
44       *g             = dm->localin[i];
45       dm->localin[i] = PETSC_NULL;
46       goto alldone;
47     }
48   }
49   ierr = DMCreateLocalVector(dm,g);CHKERRQ(ierr);
50 
51 alldone:
52   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
53     if (!dm->localout[i]) {
54       dm->localout[i] = *g;
55       break;
56     }
57   }
58   PetscFunctionReturn(0);
59 }
60 
61 #undef __FUNCT__
62 #define __FUNCT__ "DMRestoreLocalVector"
63 /*@
64    DMRestoreLocalVector - Returns a Seq PETSc vector that
65      obtained from DMGetLocalVector(). Do not use with vector obtained via
66      DMCreateLocalVector().
67 
68    Not Collective
69 
70    Input Parameter:
71 +  dm - the distributed array
72 -  g - the local vector
73 
74    Level: beginner
75 
76 .keywords: distributed array, create, local, vector
77 
78 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
79           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
80           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMGetLocalVector()
81 @*/
82 PetscErrorCode  DMRestoreLocalVector(DM dm,Vec *g)
83 {
84   PetscErrorCode ierr;
85   PetscInt       i,j;
86 
87   PetscFunctionBegin;
88   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
89   PetscValidPointer(g,2);
90   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
91     if (*g == dm->localout[j]) {
92       dm->localout[j] = PETSC_NULL;
93       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
94         if (!dm->localin[i]) {
95           dm->localin[i] = *g;
96           goto alldone;
97         }
98       }
99     }
100   }
101   ierr = VecDestroy(g);CHKERRQ(ierr);
102 alldone:
103   PetscFunctionReturn(0);
104 }
105 
106 #undef __FUNCT__
107 #define __FUNCT__ "DMGetGlobalVector"
108 /*@
109    DMGetGlobalVector - Gets a MPI PETSc vector that
110    may be used with the DMXXX routines.
111 
112    Collective on DM
113 
114    Input Parameter:
115 .  dm - the distributed array
116 
117    Output Parameter:
118 .  g - the global vector
119 
120    Level: beginner
121 
122    Note:
123    The vector values are NOT initialized and may have garbage in them, so you may need
124    to zero them.
125 
126    The output parameter, g, is a regular PETSc vector that should be returned with
127    DMRestoreGlobalVector() DO NOT call VecDestroy() on it.
128 
129    VecStride*() operations can be useful when using DM with dof > 1
130 
131 .keywords: distributed array, create, Global, vector
132 
133 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
134           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
135           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
136           VecStrideMax(), VecStrideMin(), VecStrideNorm()
137 
138 @*/
139 PetscErrorCode  DMGetGlobalVector(DM dm,Vec *g)
140 {
141   PetscErrorCode ierr;
142   PetscInt       i;
143 
144   PetscFunctionBegin;
145   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
146   PetscValidPointer(g,2);
147   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
148     if (dm->globalin[i]) {
149       *g              = dm->globalin[i];
150       dm->globalin[i] = PETSC_NULL;
151       goto alldone;
152     }
153   }
154   ierr = DMCreateGlobalVector(dm,g);CHKERRQ(ierr);
155 
156 alldone:
157   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
158     if (!dm->globalout[i]) {
159       dm->globalout[i] = *g;
160       break;
161     }
162   }
163   PetscFunctionReturn(0);
164 }
165 
166 #undef __FUNCT__
167 #define __FUNCT__ "DMClearGlobalVectors"
168 /*@
169    DMClearGlobalVectors - Destroys all the global vectors that have been stashed in this DM
170 
171    Collective on DM
172 
173    Input Parameter:
174 .  dm - the distributed array
175 
176    Level: developer
177 
178 .keywords: distributed array, create, Global, vector
179 
180 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
181           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
182           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
183           VecStrideMax(), VecStrideMin(), VecStrideNorm()
184 
185 @*/
186 PetscErrorCode  DMClearGlobalVectors(DM dm)
187 {
188   PetscErrorCode ierr;
189   PetscInt       i;
190 
191   PetscFunctionBegin;
192   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
193   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
194     if (dm->globalout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Clearing DM of global vectors that has a global vector obtained with DMGetGlobalVector()");
195     ierr = VecDestroy(&dm->globalin[i]);CHKERRQ(ierr);
196   }
197   PetscFunctionReturn(0);
198 }
199 
200 #undef __FUNCT__
201 #define __FUNCT__ "DMRestoreGlobalVector"
202 /*@
203    DMRestoreGlobalVector - Returns a Seq PETSc vector that
204      obtained from DMGetGlobalVector(). Do not use with vector obtained via
205      DMCreateGlobalVector().
206 
207    Not Collective
208 
209    Input Parameter:
210 +  dm - the distributed array
211 -  g - the global vector
212 
213    Level: beginner
214 
215 .keywords: distributed array, create, global, vector
216 
217 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
218           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(),
219           DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
220 @*/
221 PetscErrorCode  DMRestoreGlobalVector(DM dm,Vec *g)
222 {
223   PetscErrorCode ierr;
224   PetscInt       i,j;
225 
226   PetscFunctionBegin;
227   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
228   PetscValidPointer(g,2);
229   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
230     if (*g == dm->globalout[j]) {
231       dm->globalout[j] = PETSC_NULL;
232       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
233         if (!dm->globalin[i]) {
234           dm->globalin[i] = *g;
235           goto alldone;
236         }
237       }
238     }
239   }
240   ierr = VecDestroy(g);CHKERRQ(ierr);
241 alldone:
242   PetscFunctionReturn(0);
243 }
244 
245 #undef __FUNCT__
246 #define __FUNCT__ "DMGetNamedGlobalVector"
247 /*@C
248    DMGetNamedGlobalVector - get access to a named, persistent global vector
249 
250    Collective on DM
251 
252    Input Arguments:
253 +  dm - DM to hold named vectors
254 -  name - unique name for Vec
255 
256    Output Arguments:
257 .  X - named Vec
258 
259    Level: developer
260 
261    Note: If a Vec with the given name does not exist, it is created.
262 
263 .seealso: DMRestoreNamedGlobalVector()
264 @*/
265 PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
266 {
267   PetscErrorCode ierr;
268   DMNamedVecLink link;
269 
270   PetscFunctionBegin;
271   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
272   PetscValidCharPointer(name,2);
273   PetscValidPointer(X,3);
274   for (link=dm->namedglobal; link; link=link->next) {
275     PetscBool match;
276     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
277     if (match) {
278       if (link->status != DMVEC_STATUS_IN) SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
279       goto found;
280     }
281   }
282 
283   /* Create the Vec */
284   ierr            = PetscMalloc(sizeof(*link),&link);CHKERRQ(ierr);
285   ierr            = PetscStrallocpy(name,&link->name);CHKERRQ(ierr);
286   ierr            = DMCreateGlobalVector(dm,&link->X);CHKERRQ(ierr);
287   link->next      = dm->namedglobal;
288   dm->namedglobal = link;
289 
290 found:
291   *X           = link->X;
292   link->status = DMVEC_STATUS_OUT;
293   PetscFunctionReturn(0);
294 }
295 
296 #undef __FUNCT__
297 #define __FUNCT__ "DMRestoreNamedGlobalVector"
298 /*@C
299    DMRestoreNamedGlobalVector - restore access to a named, persistent global vector
300 
301    Collective on DM
302 
303    Input Arguments:
304 +  dm - DM on which the vector was gotten
305 .  name - name under which the vector was gotten
306 -  X - Vec to restore
307 
308    Output Arguments:
309 
310    Level: developer
311 
312 .seealso: DMGetNamedGlobalVector()
313 @*/
314 PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
315 {
316   PetscErrorCode ierr;
317   DMNamedVecLink link;
318 
319   PetscFunctionBegin;
320   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
321   PetscValidCharPointer(name,2);
322   PetscValidPointer(X,3);
323   PetscValidHeaderSpecific(*X,VEC_CLASSID,3);
324   for (link=dm->namedglobal; link; link=link->next) {
325     PetscBool match;
326     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
327     if (match) {
328       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
329       if (link->X != *X) SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_INCOMP,"Attempt to restore Vec name '%s', but Vec does not match the cache",name);
330       link->status = DMVEC_STATUS_IN;
331       *X           = PETSC_NULL;
332       PetscFunctionReturn(0);
333     }
334   }
335   SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
336   PetscFunctionReturn(0);
337 }
338 
339 #undef __FUNCT__
340 #define __FUNCT__ "DMGetNamedLocalVector"
341 /*@C
342    DMGetNamedLocalVector - get access to a named, persistent local vector
343 
344    Not Collective
345 
346    Input Arguments:
347 +  dm - DM to hold named vectors
348 -  name - unique name for Vec
349 
350    Output Arguments:
351 .  X - named Vec
352 
353    Level: developer
354 
355    Note: If a Vec with the given name does not exist, it is created.
356 
357 .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
358 @*/
359 PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
360 {
361   PetscErrorCode ierr;
362   DMNamedVecLink link;
363 
364   PetscFunctionBegin;
365   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
366   PetscValidCharPointer(name,2);
367   PetscValidPointer(X,3);
368   for (link=dm->namedlocal; link; link=link->next) {
369     PetscBool match;
370     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
371     if (match) {
372       if (link->status != DMVEC_STATUS_IN) SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
373       goto found;
374     }
375   }
376 
377   /* Create the Vec */
378   ierr           = PetscMalloc(sizeof(*link),&link);CHKERRQ(ierr);
379   ierr           = PetscStrallocpy(name,&link->name);CHKERRQ(ierr);
380   ierr           = DMCreateLocalVector(dm,&link->X);CHKERRQ(ierr);
381   link->next     = dm->namedlocal;
382   dm->namedlocal = link;
383 
384 found:
385   *X           = link->X;
386   link->status = DMVEC_STATUS_OUT;
387   PetscFunctionReturn(0);
388 }
389 
390 #undef __FUNCT__
391 #define __FUNCT__ "DMRestoreNamedLocalVector"
392 /*@C
393    DMRestoreNamedLocalVector - restore access to a named, persistent local vector
394 
395    Not Collective
396 
397    Input Arguments:
398 +  dm - DM on which the vector was gotten
399 .  name - name under which the vector was gotten
400 -  X - Vec to restore
401 
402    Output Arguments:
403 
404    Level: developer
405 
406 .seealso: DMRestoreNamedGlobalVector(),DMGetNamedLocalVector()
407 @*/
408 PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
409 {
410   PetscErrorCode ierr;
411   DMNamedVecLink link;
412 
413   PetscFunctionBegin;
414   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
415   PetscValidCharPointer(name,2);
416   PetscValidPointer(X,3);
417   PetscValidHeaderSpecific(*X,VEC_CLASSID,3);
418   for (link=dm->namedlocal; link; link=link->next) {
419     PetscBool match;
420     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
421     if (match) {
422       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
423       if (link->X != *X) SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_INCOMP,"Attempt to restore Vec name '%s', but Vec does not match the cache",name);
424       link->status = DMVEC_STATUS_IN;
425       *X           = PETSC_NULL;
426       PetscFunctionReturn(0);
427     }
428   }
429   SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
430   PetscFunctionReturn(0);
431 }
432