xref: /petsc/src/dm/interface/dmget.c (revision 4fc747eaadbeca11629f314a99edccbc2ed7b3d3)
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__ "DMClearLocalVectors"
214 /*@
215    DMClearLocalVectors - Destroys all the local vectors that have been stashed in this DM
216 
217    Collective on DM
218 
219    Input Parameter:
220 .  dm - the distributed array
221 
222    Level: developer
223 
224 .keywords: distributed array, create, Local, vector
225 
226 .seealso: DMCreateLocalVector(), VecDuplicate(), VecDuplicateVecs(),
227           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMLocalToLocalBegin(),
228           DMLocalToLocalEnd(), DMLocalToLocalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
229           VecStrideMax(), VecStrideMin(), VecStrideNorm()
230 
231 @*/
232 PetscErrorCode  DMClearLocalVectors(DM dm)
233 {
234   PetscErrorCode ierr;
235   PetscInt       i;
236 
237   PetscFunctionBegin;
238   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
239   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
240     Vec g;
241     if (dm->localout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Clearing DM of local vectors that has a local vector obtained with DMGetLocalVector()");
242     g = dm->localin[i];
243     dm->localin[i] = NULL;
244     ierr = VecDestroy(&g);CHKERRQ(ierr);
245   }
246   PetscFunctionReturn(0);
247 }
248 
249 #undef __FUNCT__
250 #define __FUNCT__ "DMRestoreGlobalVector"
251 /*@
252    DMRestoreGlobalVector - Returns a Seq PETSc vector that
253      obtained from DMGetGlobalVector(). Do not use with vector obtained via
254      DMCreateGlobalVector().
255 
256    Not Collective
257 
258    Input Parameter:
259 +  dm - the distributed array
260 -  g - the global vector
261 
262    Level: beginner
263 
264 .keywords: distributed array, create, global, vector
265 
266 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
267           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(),
268           DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
269 @*/
270 PetscErrorCode  DMRestoreGlobalVector(DM dm,Vec *g)
271 {
272   PetscErrorCode ierr;
273   PetscInt       i,j;
274 
275   PetscFunctionBegin;
276   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
277   PetscValidPointer(g,2);
278   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
279     if (*g == dm->globalout[j]) {
280       dm->globalout[j] = NULL;
281       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
282         if (!dm->globalin[i]) {
283           dm->globalin[i] = *g;
284           goto alldone;
285         }
286       }
287     }
288   }
289   ierr = VecDestroy(g);CHKERRQ(ierr);
290 alldone:
291   *g = NULL;
292   PetscFunctionReturn(0);
293 }
294 
295 #undef __FUNCT__
296 #define __FUNCT__ "DMHasNamedGlobalVector"
297 /*@C
298    DMHasNamedGlobalVector - check for a named, persistent global vector
299 
300    Not Collective
301 
302    Input Arguments:
303 +  dm - DM to hold named vectors
304 -  name - unique name for Vec
305 
306    Output Arguments:
307 .  exists - true if the vector was previously created
308 
309    Level: developer
310 
311    Note: If a Vec with the given name does not exist, it is created.
312 
313 .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
314 @*/
315 PetscErrorCode DMHasNamedGlobalVector(DM dm,const char *name,PetscBool *exists)
316 {
317   PetscErrorCode ierr;
318   DMNamedVecLink link;
319 
320   PetscFunctionBegin;
321   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
322   PetscValidCharPointer(name,2);
323   PetscValidPointer(exists,3);
324   *exists = PETSC_FALSE;
325   for (link=dm->namedglobal; link; link=link->next) {
326     PetscBool match;
327     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
328     if (match) {
329       *exists = PETSC_TRUE;
330       break;
331     }
332   }
333   PetscFunctionReturn(0);
334 }
335 
336 #undef __FUNCT__
337 #define __FUNCT__ "DMGetNamedGlobalVector"
338 /*@C
339    DMGetNamedGlobalVector - get access to a named, persistent global vector
340 
341    Collective on DM
342 
343    Input Arguments:
344 +  dm - DM to hold named vectors
345 -  name - unique name for Vec
346 
347    Output Arguments:
348 .  X - named Vec
349 
350    Level: developer
351 
352    Note: If a Vec with the given name does not exist, it is created.
353 
354 .seealso: DMRestoreNamedGlobalVector()
355 @*/
356 PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
357 {
358   PetscErrorCode ierr;
359   DMNamedVecLink link;
360 
361   PetscFunctionBegin;
362   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
363   PetscValidCharPointer(name,2);
364   PetscValidPointer(X,3);
365   for (link=dm->namedglobal; link; link=link->next) {
366     PetscBool match;
367     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
368     if (match) {
369       if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
370       goto found;
371     }
372   }
373 
374   /* Create the Vec */
375   ierr            = PetscNew(&link);CHKERRQ(ierr);
376   ierr            = PetscStrallocpy(name,&link->name);CHKERRQ(ierr);
377   ierr            = DMCreateGlobalVector(dm,&link->X);CHKERRQ(ierr);
378   link->next      = dm->namedglobal;
379   dm->namedglobal = link;
380 
381 found:
382   *X           = link->X;
383   link->status = DMVEC_STATUS_OUT;
384   PetscFunctionReturn(0);
385 }
386 
387 #undef __FUNCT__
388 #define __FUNCT__ "DMRestoreNamedGlobalVector"
389 /*@C
390    DMRestoreNamedGlobalVector - restore access to a named, persistent global vector
391 
392    Collective on DM
393 
394    Input Arguments:
395 +  dm - DM on which the vector was gotten
396 .  name - name under which the vector was gotten
397 -  X - Vec to restore
398 
399    Output Arguments:
400 
401    Level: developer
402 
403 .seealso: DMGetNamedGlobalVector()
404 @*/
405 PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
406 {
407   PetscErrorCode ierr;
408   DMNamedVecLink link;
409 
410   PetscFunctionBegin;
411   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
412   PetscValidCharPointer(name,2);
413   PetscValidPointer(X,3);
414   PetscValidHeaderSpecific(*X,VEC_CLASSID,3);
415   for (link=dm->namedglobal; link; link=link->next) {
416     PetscBool match;
417     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
418     if (match) {
419       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
420       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);
421       link->status = DMVEC_STATUS_IN;
422       *X           = NULL;
423       PetscFunctionReturn(0);
424     }
425   }
426   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
427   PetscFunctionReturn(0);
428 }
429 
430 #undef __FUNCT__
431 #define __FUNCT__ "DMHasNamedLocalVector"
432 /*@C
433    DMHasNamedLocalVector - check for a named, persistent local vector
434 
435    Not Collective
436 
437    Input Arguments:
438 +  dm - DM to hold named vectors
439 -  name - unique name for Vec
440 
441    Output Arguments:
442 .  exists - true if the vector was previously created
443 
444    Level: developer
445 
446    Note: If a Vec with the given name does not exist, it is created.
447 
448 .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
449 @*/
450 PetscErrorCode DMHasNamedLocalVector(DM dm,const char *name,PetscBool *exists)
451 {
452   PetscErrorCode ierr;
453   DMNamedVecLink link;
454 
455   PetscFunctionBegin;
456   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
457   PetscValidCharPointer(name,2);
458   PetscValidPointer(exists,3);
459   *exists = PETSC_FALSE;
460   for (link=dm->namedlocal; link; link=link->next) {
461     PetscBool match;
462     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
463     if (match) {
464       *exists = PETSC_TRUE;
465       break;
466     }
467   }
468   PetscFunctionReturn(0);
469 }
470 
471 #undef __FUNCT__
472 #define __FUNCT__ "DMGetNamedLocalVector"
473 /*@C
474    DMGetNamedLocalVector - get access to a named, persistent local vector
475 
476    Not Collective
477 
478    Input Arguments:
479 +  dm - DM to hold named vectors
480 -  name - unique name for Vec
481 
482    Output Arguments:
483 .  X - named Vec
484 
485    Level: developer
486 
487    Note: If a Vec with the given name does not exist, it is created.
488 
489 .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
490 @*/
491 PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
492 {
493   PetscErrorCode ierr;
494   DMNamedVecLink link;
495 
496   PetscFunctionBegin;
497   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
498   PetscValidCharPointer(name,2);
499   PetscValidPointer(X,3);
500   for (link=dm->namedlocal; link; link=link->next) {
501     PetscBool match;
502     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
503     if (match) {
504       if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
505       goto found;
506     }
507   }
508 
509   /* Create the Vec */
510   ierr           = PetscNew(&link);CHKERRQ(ierr);
511   ierr           = PetscStrallocpy(name,&link->name);CHKERRQ(ierr);
512   ierr           = DMCreateLocalVector(dm,&link->X);CHKERRQ(ierr);
513   link->next     = dm->namedlocal;
514   dm->namedlocal = link;
515 
516 found:
517   *X           = link->X;
518   link->status = DMVEC_STATUS_OUT;
519   PetscFunctionReturn(0);
520 }
521 
522 #undef __FUNCT__
523 #define __FUNCT__ "DMRestoreNamedLocalVector"
524 /*@C
525    DMRestoreNamedLocalVector - restore access to a named, persistent local vector
526 
527    Not Collective
528 
529    Input Arguments:
530 +  dm - DM on which the vector was gotten
531 .  name - name under which the vector was gotten
532 -  X - Vec to restore
533 
534    Output Arguments:
535 
536    Level: developer
537 
538 .seealso: DMRestoreNamedGlobalVector(),DMGetNamedLocalVector()
539 @*/
540 PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
541 {
542   PetscErrorCode ierr;
543   DMNamedVecLink link;
544 
545   PetscFunctionBegin;
546   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
547   PetscValidCharPointer(name,2);
548   PetscValidPointer(X,3);
549   PetscValidHeaderSpecific(*X,VEC_CLASSID,3);
550   for (link=dm->namedlocal; link; link=link->next) {
551     PetscBool match;
552     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
553     if (match) {
554       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
555       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);
556       link->status = DMVEC_STATUS_IN;
557       *X           = NULL;
558       PetscFunctionReturn(0);
559     }
560   }
561   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
562   PetscFunctionReturn(0);
563 }
564