Actual source code: dmget.c
  1: #include <petsc/private/dmimpl.h>
  3: /*@
  4:    DMGetLocalVector - Gets a PETSc vector that may be used with the DM local routines. This vector has spaces for the ghost values.
  6:    Not Collective
  8:    Input Parameter:
  9: .  dm - the dm
 11:    Output Parameter:
 12: .  g - the local vector
 14:    Level: beginner
 16:    Note:
 17:    The vector values are NOT initialized and may have garbage in them, so you may need
 18:    to zero them.
 20:    The output parameter, g, is a regular PETSc vector that should be returned with
 21:    DMRestoreLocalVector() DO NOT call VecDestroy() on it.
 23:    This is intended to be used for vectors you need for a short time, like within a single function call.
 24:    For vectors that you intend to keep around (for example in a C struct) or pass around large parts of your
 25:    code you should use DMCreateLocalVector().
 27:    VecStride*() operations can be useful when using DM with dof > 1
 29: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
 30:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
 31:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector(),
 32:           VecStrideMax(), VecStrideMin(), VecStrideNorm()
 33: @*/
 34: PetscErrorCode  DMGetLocalVector(DM dm,Vec *g)
 35: {
 36:   PetscErrorCode ierr,i;
 41:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
 42:     if (dm->localin[i]) {
 43:       DM vdm;
 45:       *g             = dm->localin[i];
 46:       dm->localin[i] = NULL;
 48:       VecGetDM(*g,&vdm);
 49:       if (vdm) SETERRQ(PetscObjectComm((PetscObject)vdm),PETSC_ERR_LIB,"Invalid vector");
 50:       VecSetDM(*g,dm);
 51:       goto alldone;
 52:     }
 53:   }
 54:   DMCreateLocalVector(dm,g);
 56: alldone:
 57:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
 58:     if (!dm->localout[i]) {
 59:       dm->localout[i] = *g;
 60:       break;
 61:     }
 62:   }
 63:   return(0);
 64: }
 66: /*@
 67:    DMRestoreLocalVector - Returns a PETSc vector that was
 68:      obtained from DMGetLocalVector(). Do not use with vector obtained via
 69:      DMCreateLocalVector().
 71:    Not Collective
 73:    Input Parameter:
 74: +  dm - the dm
 75: -  g - the local vector
 77:    Level: beginner
 79: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
 80:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
 81:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMGetLocalVector()
 82: @*/
 83: PetscErrorCode  DMRestoreLocalVector(DM dm,Vec *g)
 84: {
 86:   PetscInt       i,j;
 91:   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
 92:     if (*g == dm->localout[j]) {
 93:       DM vdm;
 95:       VecGetDM(*g,&vdm);
 96:       if (vdm != dm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Invalid vector");
 97:       VecSetDM(*g,NULL);
 98:       dm->localout[j] = NULL;
 99:       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
100:         if (!dm->localin[i]) {
101:           dm->localin[i] = *g;
102:           goto alldone;
103:         }
104:       }
105:     }
106:   }
107:   VecDestroy(g);
108: alldone:
109:   *g = NULL;
110:   return(0);
111: }
113: /*@
114:    DMGetGlobalVector - Gets a PETSc vector that may be used with the DM global routines.
116:    Collective on dm
118:    Input Parameter:
119: .  dm - the dm
121:    Output Parameter:
122: .  g - the global vector
124:    Level: beginner
126:    Note:
127:    The vector values are NOT initialized and may have garbage in them, so you may need
128:    to zero them.
130:    The output parameter, g, is a regular PETSc vector that should be returned with
131:    DMRestoreGlobalVector() DO NOT call VecDestroy() on it.
133:    This is intended to be used for vectors you need for a short time, like within a single function call.
134:    For vectors that you intend to keep around (for example in a C struct) or pass around large parts of your
135:    code you should use DMCreateGlobalVector().
137:    VecStride*() operations can be useful when using DM with dof > 1
139: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
140:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
141:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
142:           VecStrideMax(), VecStrideMin(), VecStrideNorm()
143: @*/
144: PetscErrorCode  DMGetGlobalVector(DM dm,Vec *g)
145: {
147:   PetscInt       i;
152:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
153:     if (dm->globalin[i]) {
154:       DM vdm;
156:       *g              = dm->globalin[i];
157:       dm->globalin[i] = NULL;
159:       VecGetDM(*g,&vdm);
160:       if (vdm) SETERRQ(PetscObjectComm((PetscObject)vdm),PETSC_ERR_LIB,"Invalid vector");
161:       VecSetDM(*g,dm);
162:       goto alldone;
163:     }
164:   }
165:   DMCreateGlobalVector(dm,g);
167: alldone:
168:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
169:     if (!dm->globalout[i]) {
170:       dm->globalout[i] = *g;
171:       break;
172:     }
173:   }
174:   return(0);
175: }
177: /*@
178:    DMClearGlobalVectors - Destroys all the global vectors that have been stashed in this DM
180:    Collective on dm
182:    Input Parameter:
183: .  dm - the dm
185:    Level: developer
187: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
188:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
189:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
190:           VecStrideMax(), VecStrideMin(), VecStrideNorm()
191: @*/
192: PetscErrorCode  DMClearGlobalVectors(DM dm)
193: {
195:   PetscInt       i;
199:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
200:     Vec g;
202:     if (dm->globalout[i]) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Clearing DM of global vectors that has a global vector obtained with DMGetGlobalVector()");
203:     g = dm->globalin[i];
204:     dm->globalin[i] = NULL;
205:     if (g) {
206:       DM vdm;
208:       VecGetDM(g,&vdm);
209:       if (vdm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Clearing global vector that has a DM attached");
210:     }
211:     VecDestroy(&g);
212:   }
213:   return(0);
214: }
216: /*@
217:    DMClearLocalVectors - Destroys all the local vectors that have been stashed in this DM
219:    Collective on dm
221:    Input Parameter:
222: .  dm - the dm
224:    Level: developer
226: .seealso: DMCreateLocalVector(), VecDuplicate(), VecDuplicateVecs(),
227:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMLocalToLocalBegin(),
228:           DMLocalToLocalEnd(), DMLocalToLocalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
229:           VecStrideMax(), VecStrideMin(), VecStrideNorm()
230: @*/
231: PetscErrorCode  DMClearLocalVectors(DM dm)
232: {
234:   PetscInt       i;
238:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
239:     Vec g;
241:     if (dm->localout[i]) SETERRQ(PetscObjectComm((PetscObject)dm),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:     if (g) {
245:       DM vdm;
247:       VecGetDM(g,&vdm);
248:       if (vdm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Clearing local vector that has a DM attached");
249:     }
250:     VecDestroy(&g);
251:   }
252:   return(0);
253: }
255: /*@
256:    DMRestoreGlobalVector - Returns a PETSc vector that
257:      obtained from DMGetGlobalVector(). Do not use with vector obtained via
258:      DMCreateGlobalVector().
260:    Not Collective
262:    Input Parameter:
263: +  dm - the dm
264: -  g - the global vector
266:    Level: beginner
268: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
269:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(),
270:           DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
271: @*/
272: PetscErrorCode  DMRestoreGlobalVector(DM dm,Vec *g)
273: {
275:   PetscInt       i,j;
280:   VecSetErrorIfLocked(*g, 2);
281:   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
282:     if (*g == dm->globalout[j]) {
283:       DM vdm;
285:       VecGetDM(*g,&vdm);
286:       if (vdm != dm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Invalid vector");
287:       VecSetDM(*g,NULL);
288:       dm->globalout[j] = NULL;
289:       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
290:         if (!dm->globalin[i]) {
291:           dm->globalin[i] = *g;
292:           goto alldone;
293:         }
294:       }
295:     }
296:   }
297:   VecDestroy(g);
298: alldone:
299:   *g = NULL;
300:   return(0);
301: }
303: /*@C
304:    DMHasNamedGlobalVector - check for a named, persistent global vector
306:    Not Collective
308:    Input Arguments:
309: +  dm - DM to hold named vectors
310: -  name - unique name for Vec
312:    Output Arguments:
313: .  exists - true if the vector was previously created
315:    Level: developer
317:    Note: If a Vec with the given name does not exist, it is created.
319: .seealso: DMGetNamedGlobalVector(), DMRestoreNamedLocalVector()
320: @*/
321: PetscErrorCode DMHasNamedGlobalVector(DM dm,const char *name,PetscBool *exists)
322: {
324:   DMNamedVecLink link;
330:   *exists = PETSC_FALSE;
331:   for (link=dm->namedglobal; link; link=link->next) {
332:     PetscBool match;
333:     PetscStrcmp(name,link->name,&match);
334:     if (match) {
335:       *exists = PETSC_TRUE;
336:       break;
337:     }
338:   }
339:   return(0);
340: }
342: /*@C
343:    DMGetNamedGlobalVector - get access to a named, persistent global vector
345:    Collective on dm
347:    Input Arguments:
348: +  dm - DM to hold named vectors
349: -  name - unique name for Vec
351:    Output Arguments:
352: .  X - named Vec
354:    Level: developer
356:    Note: If a Vec with the given name does not exist, it is created.
358: .seealso: DMRestoreNamedGlobalVector()
359: @*/
360: PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
361: {
363:   DMNamedVecLink link;
369:   for (link=dm->namedglobal; link; link=link->next) {
370:     PetscBool match;
372:     PetscStrcmp(name,link->name,&match);
373:     if (match) {
374:       DM vdm;
376:       if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
377:       VecGetDM(link->X,&vdm);
378:       if (vdm) SETERRQ(PetscObjectComm((PetscObject)vdm),PETSC_ERR_LIB,"Invalid vector");
379:       VecSetDM(link->X,dm);
380:       goto found;
381:     }
382:   }
384:   /* Create the Vec */
385:   PetscNew(&link);
386:   PetscStrallocpy(name,&link->name);
387:   DMCreateGlobalVector(dm,&link->X);
388:   link->next      = dm->namedglobal;
389:   dm->namedglobal = link;
391: found:
392:   *X           = link->X;
393:   link->status = DMVEC_STATUS_OUT;
394:   return(0);
395: }
397: /*@C
398:    DMRestoreNamedGlobalVector - restore access to a named, persistent global vector
400:    Collective on dm
402:    Input Arguments:
403: +  dm - DM on which the vector was gotten
404: .  name - name under which the vector was gotten
405: -  X - Vec to restore
407:    Output Arguments:
409:    Level: developer
411: .seealso: DMGetNamedGlobalVector()
412: @*/
413: PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
414: {
416:   DMNamedVecLink link;
423:   for (link=dm->namedglobal; link; link=link->next) {
424:     PetscBool match;
426:     PetscStrcmp(name,link->name,&match);
427:     if (match) {
428:       DM vdm;
430:       VecGetDM(*X,&vdm);
431:       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
432:       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);
433:       if (vdm != dm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Invalid vector");
435:       link->status = DMVEC_STATUS_IN;
436:       VecSetDM(link->X,NULL);
437:       *X           = NULL;
438:       return(0);
439:     }
440:   }
441:   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
442: }
444: /*@C
445:    DMHasNamedLocalVector - check for a named, persistent local vector
447:    Not Collective
449:    Input Arguments:
450: +  dm - DM to hold named vectors
451: -  name - unique name for Vec
453:    Output Arguments:
454: .  exists - true if the vector was previously created
456:    Level: developer
458:    Note: If a Vec with the given name does not exist, it is created.
460: .seealso: DMGetNamedGlobalVector(), DMRestoreNamedLocalVector()
461: @*/
462: PetscErrorCode DMHasNamedLocalVector(DM dm,const char *name,PetscBool *exists)
463: {
465:   DMNamedVecLink link;
471:   *exists = PETSC_FALSE;
472:   for (link=dm->namedlocal; link; link=link->next) {
473:     PetscBool match;
474:     PetscStrcmp(name,link->name,&match);
475:     if (match) {
476:       *exists = PETSC_TRUE;
477:       break;
478:     }
479:   }
480:   return(0);
481: }
483: /*@C
484:    DMGetNamedLocalVector - get access to a named, persistent local vector
486:    Not Collective
488:    Input Arguments:
489: +  dm - DM to hold named vectors
490: -  name - unique name for Vec
492:    Output Arguments:
493: .  X - named Vec
495:    Level: developer
497:    Note: If a Vec with the given name does not exist, it is created.
499: .seealso: DMGetNamedGlobalVector(), DMRestoreNamedLocalVector()
500: @*/
501: PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
502: {
504:   DMNamedVecLink link;
510:   for (link=dm->namedlocal; link; link=link->next) {
511:     PetscBool match;
513:     PetscStrcmp(name,link->name,&match);
514:     if (match) {
515:       DM vdm;
517:       if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
518:       VecGetDM(link->X,&vdm);
519:       if (vdm) SETERRQ(PetscObjectComm((PetscObject)vdm),PETSC_ERR_LIB,"Invalid vector");
520:       VecSetDM(link->X,dm);
521:       goto found;
522:     }
523:   }
525:   /* Create the Vec */
526:   PetscNew(&link);
527:   PetscStrallocpy(name,&link->name);
528:   DMCreateLocalVector(dm,&link->X);
529:   link->next     = dm->namedlocal;
530:   dm->namedlocal = link;
532: found:
533:   *X           = link->X;
534:   link->status = DMVEC_STATUS_OUT;
535:   return(0);
536: }
538: /*@C
539:    DMRestoreNamedLocalVector - restore access to a named, persistent local vector
541:    Not Collective
543:    Input Arguments:
544: +  dm - DM on which the vector was gotten
545: .  name - name under which the vector was gotten
546: -  X - Vec to restore
548:    Output Arguments:
550:    Level: developer
552: .seealso: DMRestoreNamedGlobalVector(), DMGetNamedLocalVector()
553: @*/
554: PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
555: {
557:   DMNamedVecLink link;
564:   for (link=dm->namedlocal; link; link=link->next) {
565:     PetscBool match;
567:     PetscStrcmp(name,link->name,&match);
568:     if (match) {
569:       DM vdm;
571:       VecGetDM(*X,&vdm);
572:       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
573:       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);
574:       if (vdm != dm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Invalid vector");
576:       link->status = DMVEC_STATUS_IN;
577:       VecSetDM(link->X,NULL);
578:       *X           = NULL;
579:       return(0);
580:     }
581:   }
582:   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
583: }