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