xref: /petsc/src/dm/interface/dmget.c (revision 90e2ccaccedfcccf0455169565b32f5d2c95b3c0)
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__ "DMHasNamedGlobalVector"
260 /*@C
261    DMHasNamedGlobalVector - check for a named, persistent global vector
262 
263    Not Collective
264 
265    Input Arguments:
266 +  dm - DM to hold named vectors
267 -  name - unique name for Vec
268 
269    Output Arguments:
270 .  exists - true if the vector was previously created
271 
272    Level: developer
273 
274    Note: If a Vec with the given name does not exist, it is created.
275 
276 .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
277 @*/
278 PetscErrorCode DMHasNamedGlobalVector(DM dm,const char *name,PetscBool *exists)
279 {
280   PetscErrorCode ierr;
281   DMNamedVecLink link;
282 
283   PetscFunctionBegin;
284   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
285   PetscValidCharPointer(name,2);
286   PetscValidPointer(exists,3);
287   *exists = PETSC_FALSE;
288   for (link=dm->namedglobal; link; link=link->next) {
289     PetscBool match;
290     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
291     if (match) {
292       *exists = PETSC_TRUE;
293       break;
294     }
295   }
296   PetscFunctionReturn(0);
297 }
298 
299 #undef __FUNCT__
300 #define __FUNCT__ "DMGetNamedGlobalVector"
301 /*@C
302    DMGetNamedGlobalVector - get access to a named, persistent global vector
303 
304    Collective on DM
305 
306    Input Arguments:
307 +  dm - DM to hold named vectors
308 -  name - unique name for Vec
309 
310    Output Arguments:
311 .  X - named Vec
312 
313    Level: developer
314 
315    Note: If a Vec with the given name does not exist, it is created.
316 
317 .seealso: DMRestoreNamedGlobalVector()
318 @*/
319 PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
320 {
321   PetscErrorCode ierr;
322   DMNamedVecLink link;
323 
324   PetscFunctionBegin;
325   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
326   PetscValidCharPointer(name,2);
327   PetscValidPointer(X,3);
328   for (link=dm->namedglobal; link; link=link->next) {
329     PetscBool match;
330     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
331     if (match) {
332       if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
333       goto found;
334     }
335   }
336 
337   /* Create the Vec */
338   ierr            = PetscNew(&link);CHKERRQ(ierr);
339   ierr            = PetscStrallocpy(name,&link->name);CHKERRQ(ierr);
340   ierr            = DMCreateGlobalVector(dm,&link->X);CHKERRQ(ierr);
341   link->next      = dm->namedglobal;
342   dm->namedglobal = link;
343 
344 found:
345   *X           = link->X;
346   link->status = DMVEC_STATUS_OUT;
347   PetscFunctionReturn(0);
348 }
349 
350 #undef __FUNCT__
351 #define __FUNCT__ "DMRestoreNamedGlobalVector"
352 /*@C
353    DMRestoreNamedGlobalVector - restore access to a named, persistent global vector
354 
355    Collective on DM
356 
357    Input Arguments:
358 +  dm - DM on which the vector was gotten
359 .  name - name under which the vector was gotten
360 -  X - Vec to restore
361 
362    Output Arguments:
363 
364    Level: developer
365 
366 .seealso: DMGetNamedGlobalVector()
367 @*/
368 PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
369 {
370   PetscErrorCode ierr;
371   DMNamedVecLink link;
372 
373   PetscFunctionBegin;
374   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
375   PetscValidCharPointer(name,2);
376   PetscValidPointer(X,3);
377   PetscValidHeaderSpecific(*X,VEC_CLASSID,3);
378   for (link=dm->namedglobal; link; link=link->next) {
379     PetscBool match;
380     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
381     if (match) {
382       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
383       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);
384       link->status = DMVEC_STATUS_IN;
385       *X           = NULL;
386       PetscFunctionReturn(0);
387     }
388   }
389   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
390   PetscFunctionReturn(0);
391 }
392 
393 #undef __FUNCT__
394 #define __FUNCT__ "DMHasNamedLocalVector"
395 /*@C
396    DMHasNamedLocalVector - check for a named, persistent local vector
397 
398    Not Collective
399 
400    Input Arguments:
401 +  dm - DM to hold named vectors
402 -  name - unique name for Vec
403 
404    Output Arguments:
405 .  exists - true if the vector was previously created
406 
407    Level: developer
408 
409    Note: If a Vec with the given name does not exist, it is created.
410 
411 .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
412 @*/
413 PetscErrorCode DMHasNamedLocalVector(DM dm,const char *name,PetscBool *exists)
414 {
415   PetscErrorCode ierr;
416   DMNamedVecLink link;
417 
418   PetscFunctionBegin;
419   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
420   PetscValidCharPointer(name,2);
421   PetscValidPointer(exists,3);
422   *exists = PETSC_FALSE;
423   for (link=dm->namedlocal; link; link=link->next) {
424     PetscBool match;
425     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
426     if (match) {
427       *exists = PETSC_TRUE;
428       break;
429     }
430   }
431   PetscFunctionReturn(0);
432 }
433 
434 #undef __FUNCT__
435 #define __FUNCT__ "DMGetNamedLocalVector"
436 /*@C
437    DMGetNamedLocalVector - get access to a named, persistent local vector
438 
439    Not Collective
440 
441    Input Arguments:
442 +  dm - DM to hold named vectors
443 -  name - unique name for Vec
444 
445    Output Arguments:
446 .  X - named Vec
447 
448    Level: developer
449 
450    Note: If a Vec with the given name does not exist, it is created.
451 
452 .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
453 @*/
454 PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
455 {
456   PetscErrorCode ierr;
457   DMNamedVecLink link;
458 
459   PetscFunctionBegin;
460   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
461   PetscValidCharPointer(name,2);
462   PetscValidPointer(X,3);
463   for (link=dm->namedlocal; link; link=link->next) {
464     PetscBool match;
465     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
466     if (match) {
467       if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
468       goto found;
469     }
470   }
471 
472   /* Create the Vec */
473   ierr           = PetscNew(&link);CHKERRQ(ierr);
474   ierr           = PetscStrallocpy(name,&link->name);CHKERRQ(ierr);
475   ierr           = DMCreateLocalVector(dm,&link->X);CHKERRQ(ierr);
476   link->next     = dm->namedlocal;
477   dm->namedlocal = link;
478 
479 found:
480   *X           = link->X;
481   link->status = DMVEC_STATUS_OUT;
482   PetscFunctionReturn(0);
483 }
484 
485 #undef __FUNCT__
486 #define __FUNCT__ "DMRestoreNamedLocalVector"
487 /*@C
488    DMRestoreNamedLocalVector - restore access to a named, persistent local vector
489 
490    Not Collective
491 
492    Input Arguments:
493 +  dm - DM on which the vector was gotten
494 .  name - name under which the vector was gotten
495 -  X - Vec to restore
496 
497    Output Arguments:
498 
499    Level: developer
500 
501 .seealso: DMRestoreNamedGlobalVector(),DMGetNamedLocalVector()
502 @*/
503 PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
504 {
505   PetscErrorCode ierr;
506   DMNamedVecLink link;
507 
508   PetscFunctionBegin;
509   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
510   PetscValidCharPointer(name,2);
511   PetscValidPointer(X,3);
512   PetscValidHeaderSpecific(*X,VEC_CLASSID,3);
513   for (link=dm->namedlocal; link; link=link->next) {
514     PetscBool match;
515     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
516     if (match) {
517       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
518       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);
519       link->status = DMVEC_STATUS_IN;
520       *X           = NULL;
521       PetscFunctionReturn(0);
522     }
523   }
524   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
525   PetscFunctionReturn(0);
526 }
527