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: }