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: `DM`, `DMCreateGlobalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
 30:           `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToLocalBegin()`,
 31:           `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMCreateLocalVector()`, `DMRestoreLocalVector()`,
 32:           `VecStrideMax()`, `VecStrideMin()`, `VecStrideNorm()`, `DMClearLocalVectors()`, `DMGetNamedGlobalVector()`, `DMGetNamedLocalVector()`
 33: @*/
 34: PetscErrorCode DMGetLocalVector(DM dm, Vec *g)
 35: {
 36:   PetscFunctionBegin;
 38:   PetscAssertPointer(g, 2);
 39:   for (PetscInt i = 0; i < DM_MAX_WORK_VECTORS; i++) {
 40:     if (dm->localin[i]) {
 41:       DM vdm;

 43:       *g             = dm->localin[i];
 44:       dm->localin[i] = NULL;

 46:       PetscCall(VecGetDM(*g, &vdm));
 47:       PetscCheck(!vdm, PetscObjectComm((PetscObject)vdm), PETSC_ERR_LIB, "Invalid vector");
 48:       PetscCall(VecSetDM(*g, dm));
 49:       goto alldone;
 50:     }
 51:   }
 52:   PetscCall(DMCreateLocalVector(dm, g));

 54: alldone:
 55:   for (PetscInt i = 0; i < DM_MAX_WORK_VECTORS; i++) {
 56:     if (!dm->localout[i]) {
 57:       dm->localout[i] = *g;
 58:       break;
 59:     }
 60:   }
 61:   PetscFunctionReturn(PETSC_SUCCESS);
 62: }

 64: /*@
 65:   DMRestoreLocalVector - Returns a PETSc vector that was
 66:   obtained from `DMGetLocalVector()`. Do not use with vector obtained via
 67:   `DMCreateLocalVector()`.

 69:   Not Collective

 71:   Input Parameters:
 72: + dm - the `DM`
 73: - g  - the local vector

 75:   Level: beginner

 77: .seealso: `DM`, `DMCreateGlobalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
 78:           `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToLocalBegin()`,
 79:           `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMCreateLocalVector()`, `DMGetLocalVector()`, `DMClearLocalVectors()`
 80: @*/
 81: PetscErrorCode DMRestoreLocalVector(DM dm, Vec *g)
 82: {
 83:   PetscInt i, j;

 85:   PetscFunctionBegin;
 87:   PetscAssertPointer(g, 2);
 88:   for (j = 0; j < DM_MAX_WORK_VECTORS; j++) {
 89:     if (*g == dm->localout[j]) {
 90:       DM vdm;

 92:       PetscCall(VecGetDM(*g, &vdm));
 93:       PetscCheck(vdm == dm, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Invalid vector");
 94:       PetscCall(VecSetDM(*g, NULL));
 95:       dm->localout[j] = NULL;
 96:       for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
 97:         if (!dm->localin[i]) {
 98:           dm->localin[i] = *g;
 99:           goto alldone;
100:         }
101:       }
102:     }
103:   }
104:   PetscCall(VecDestroy(g));
105: alldone:
106:   *g = NULL;
107:   PetscFunctionReturn(PETSC_SUCCESS);
108: }

110: /*@
111:   DMGetGlobalVector - Gets a PETSc vector that may be used with the `DM` global routines.

113:   Collective

115:   Input Parameter:
116: . dm - the `DM`

118:   Output Parameter:
119: . g - the global vector

121:   Level: beginner

123:   Note:
124:   The vector values are NOT initialized and may have garbage in them, so you may need
125:   to zero them.

127:   The output parameter, `g`, is a regular PETSc vector that should be returned with
128:   `DMRestoreGlobalVector()` DO NOT call `VecDestroy()` on it.

130:   This is intended to be used for vectors you need for a short time, like within a single function call.
131:   For vectors that you intend to keep around (for example in a C struct) or pass around large parts of your
132:   code you should use `DMCreateGlobalVector()`.

134:   VecStride*() operations can be useful when using `DM` with dof > 1

136: .seealso: `DM`, `DMCreateGlobalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
137:           `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToLocalBegin()`,
138:           `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMCreateLocalVector()`, `DMRestoreLocalVector()`,
139:           `VecStrideMax()`, `VecStrideMin()`, `VecStrideNorm()`, `DMClearGlobalVectors()`, `DMGetNamedGlobalVector()`, `DMGetNamedLocalVector()`
140: @*/
141: PetscErrorCode DMGetGlobalVector(DM dm, Vec *g)
142: {
143:   PetscInt i;

145:   PetscFunctionBegin;
147:   PetscAssertPointer(g, 2);
148:   for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
149:     if (dm->globalin[i]) {
150:       DM vdm;

152:       *g              = dm->globalin[i];
153:       dm->globalin[i] = NULL;

155:       PetscCall(VecGetDM(*g, &vdm));
156:       PetscCheck(!vdm, PetscObjectComm((PetscObject)vdm), PETSC_ERR_LIB, "Invalid vector");
157:       PetscCall(VecSetDM(*g, dm));
158:       goto alldone;
159:     }
160:   }
161:   PetscCall(DMCreateGlobalVector(dm, g));

163: alldone:
164:   for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
165:     if (!dm->globalout[i]) {
166:       dm->globalout[i] = *g;
167:       break;
168:     }
169:   }
170:   PetscFunctionReturn(PETSC_SUCCESS);
171: }

173: /*@
174:   DMClearGlobalVectors - Destroys all the global vectors that have been created for `DMGetGlobalVector()` calls in this `DM`

176:   Collective

178:   Input Parameter:
179: . dm - the `DM`

181:   Level: developer

183: .seealso: `DM`, `DMCreateGlobalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
184:           `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToLocalBegin()`,
185:           `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMCreateLocalVector()`, `DMRestoreLocalVector()`,
186:           `VecStrideMax()`, `VecStrideMin()`, `VecStrideNorm()`, `DMClearLocalVectors()`
187: @*/
188: PetscErrorCode DMClearGlobalVectors(DM dm)
189: {
190:   PetscInt i;

192:   PetscFunctionBegin;
194:   for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
195:     Vec g;

197:     PetscCheck(!dm->globalout[i], PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Clearing DM of global vectors that has a global vector obtained with DMGetGlobalVector()");
198:     g               = dm->globalin[i];
199:     dm->globalin[i] = NULL;
200:     if (g) {
201:       DM vdm;

203:       PetscCall(VecGetDM(g, &vdm));
204:       PetscCheck(!vdm, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Clearing global vector that has a DM attached");
205:     }
206:     PetscCall(VecDestroy(&g));
207:   }
208:   PetscFunctionReturn(PETSC_SUCCESS);
209: }

211: /*@
212:   DMClearLocalVectors - Destroys all the local vectors that have been created for `DMGetLocalVector()` calls in this `DM`

214:   Collective

216:   Input Parameter:
217: . dm - the `DM`

219:   Level: developer

221: .seealso: `DM`, `DMCreateLocalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
222:           `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMLocalToLocalBegin()`,
223:           `DMLocalToLocalEnd()`, `DMRestoreLocalVector()`,
224:           `VecStrideMax()`, `VecStrideMin()`, `VecStrideNorm()`, `DMClearGlobalVectors()`
225: @*/
226: PetscErrorCode DMClearLocalVectors(DM dm)
227: {
228:   PetscFunctionBegin;
230:   for (PetscInt i = 0; i < DM_MAX_WORK_VECTORS; i++) {
231:     Vec g;

233:     PetscCheck(!dm->localout[i], PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Clearing DM of local vectors that has a local vector obtained with DMGetLocalVector()");
234:     g              = dm->localin[i];
235:     dm->localin[i] = NULL;
236:     if (g) {
237:       DM vdm;

239:       PetscCall(VecGetDM(g, &vdm));
240:       PetscCheck(!vdm, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Clearing local vector that has a DM attached");
241:     }
242:     PetscCall(VecDestroy(&g));
243:   }
244:   PetscFunctionReturn(PETSC_SUCCESS);
245: }

247: /*@
248:   DMRestoreGlobalVector - Returns a PETSc vector that
249:   obtained from `DMGetGlobalVector()`. Do not use with vector obtained via
250:   `DMCreateGlobalVector()`.

252:   Not Collective

254:   Input Parameters:
255: + dm - the `DM`
256: - g  - the global vector

258:   Level: beginner

260: .seealso: `DM`, `DMCreateGlobalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
261:           `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToGlobalBegin()`,
262:           `DMGlobalToGlobalEnd()`, `DMGlobalToGlobal()`, `DMCreateLocalVector()`, `DMGetGlobalVector()`, `DMClearGlobalVectors()`
263: @*/
264: PetscErrorCode DMRestoreGlobalVector(DM dm, Vec *g)
265: {
266:   PetscFunctionBegin;
268:   PetscAssertPointer(g, 2);
269:   PetscCall(VecSetErrorIfLocked(*g, 2));
270:   for (PetscInt j = 0; j < DM_MAX_WORK_VECTORS; j++) {
271:     if (*g == dm->globalout[j]) {
272:       DM vdm;

274:       PetscCall(VecGetDM(*g, &vdm));
275:       PetscCheck(vdm == dm, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Invalid vector");
276:       PetscCall(VecSetDM(*g, NULL));
277:       dm->globalout[j] = NULL;
278:       for (PetscInt i = 0; i < DM_MAX_WORK_VECTORS; i++) {
279:         if (!dm->globalin[i]) {
280:           dm->globalin[i] = *g;
281:           goto alldone;
282:         }
283:       }
284:     }
285:   }
286:   PetscCall(VecDestroy(g));
287: alldone:
288:   *g = NULL;
289:   PetscFunctionReturn(PETSC_SUCCESS);
290: }

292: /*@
293:   DMClearNamedGlobalVectors - Destroys all the named global vectors that have been created with `DMGetNamedGlobalVector()` in this `DM`

295:   Collective

297:   Input Parameter:
298: . dm - the `DM`

300:   Level: developer

302: .seealso: `DM`, `DMGetNamedGlobalVector()`, `DMGetNamedLocalVector()`, `DMClearNamedLocalVectors()`
303: @*/
304: PetscErrorCode DMClearNamedGlobalVectors(DM dm)
305: {
306:   DMNamedVecLink nnext;

308:   PetscFunctionBegin;
310:   nnext           = dm->namedglobal;
311:   dm->namedglobal = NULL;
312:   for (DMNamedVecLink nlink = nnext; nlink; nlink = nnext) { /* Destroy the named vectors */
313:     nnext = nlink->next;
314:     PetscCheck(nlink->status == DMVEC_STATUS_IN, ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "DM still has global Vec named '%s' checked out", nlink->name);
315:     PetscCall(PetscFree(nlink->name));
316:     PetscCall(VecDestroy(&nlink->X));
317:     PetscCall(PetscFree(nlink));
318:   }
319:   PetscFunctionReturn(PETSC_SUCCESS);
320: }

322: /*@
323:   DMClearNamedLocalVectors - Destroys all the named local vectors that have been created with `DMGetNamedLocalVector()` in this `DM`

325:   Collective

327:   Input Parameter:
328: . dm - the `DM`

330:   Level: developer

332: .seealso: `DM`, `DMGetNamedGlobalVector()`, `DMGetNamedLocalVector()`, `DMClearNamedGlobalVectors()`
333: @*/
334: PetscErrorCode DMClearNamedLocalVectors(DM dm)
335: {
336:   DMNamedVecLink nnext;

338:   PetscFunctionBegin;
340:   nnext          = dm->namedlocal;
341:   dm->namedlocal = NULL;
342:   for (DMNamedVecLink nlink = nnext; nlink; nlink = nnext) { /* Destroy the named vectors */
343:     nnext = nlink->next;
344:     PetscCheck(nlink->status == DMVEC_STATUS_IN, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DM still has local Vec named '%s' checked out", nlink->name);
345:     PetscCall(PetscFree(nlink->name));
346:     PetscCall(VecDestroy(&nlink->X));
347:     PetscCall(PetscFree(nlink));
348:   }
349:   PetscFunctionReturn(PETSC_SUCCESS);
350: }

352: /*@
353:   DMHasNamedGlobalVector - check for a named, persistent global vector created with `DMGetNamedGlobalVector()`

355:   Not Collective

357:   Input Parameters:
358: + dm   - `DM` to hold named vectors
359: - name - unique name for `Vec`

361:   Output Parameter:
362: . exists - true if the vector was previously created

364:   Level: developer

366: .seealso: `DM`, `DMGetNamedGlobalVector()`, `DMRestoreNamedLocalVector()`, `DMClearNamedGlobalVectors()`
367: @*/
368: PetscErrorCode DMHasNamedGlobalVector(DM dm, const char *name, PetscBool *exists)
369: {
370:   DMNamedVecLink link;

372:   PetscFunctionBegin;
374:   PetscAssertPointer(name, 2);
375:   PetscAssertPointer(exists, 3);
376:   *exists = PETSC_FALSE;
377:   for (link = dm->namedglobal; link; link = link->next) {
378:     PetscBool match;
379:     PetscCall(PetscStrcmp(name, link->name, &match));
380:     if (match) {
381:       *exists = PETSC_TRUE;
382:       break;
383:     }
384:   }
385:   PetscFunctionReturn(PETSC_SUCCESS);
386: }

388: /*@
389:   DMGetNamedGlobalVector - get access to a named, persistent global vector

391:   Collective

393:   Input Parameters:
394: + dm   - `DM` to hold named vectors
395: - name - unique name for `X`

397:   Output Parameter:
398: . X - named `Vec`

400:   Level: developer

402:   Note:
403:   If a `Vec` with the given name does not exist, it is created.

405: .seealso: `DM`, `DMRestoreNamedGlobalVector()`, `DMHasNamedGlobalVector()`, `DMClearNamedGlobalVectors()`, `DMGetGlobalVector()`, `DMGetLocalVector()`
406: @*/
407: PetscErrorCode DMGetNamedGlobalVector(DM dm, const char *name, Vec *X)
408: {
409:   DMNamedVecLink link;

411:   PetscFunctionBegin;
413:   PetscAssertPointer(name, 2);
414:   PetscAssertPointer(X, 3);
415:   for (link = dm->namedglobal; link; link = link->next) {
416:     PetscBool match;

418:     PetscCall(PetscStrcmp(name, link->name, &match));
419:     if (match) {
420:       DM vdm;

422:       PetscCheck(link->status == DMVEC_STATUS_IN, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Vec name '%s' already checked out", name);
423:       PetscCall(VecGetDM(link->X, &vdm));
424:       PetscCheck(!vdm, PetscObjectComm((PetscObject)vdm), PETSC_ERR_LIB, "Invalid vector");
425:       PetscCall(VecSetDM(link->X, dm));
426:       goto found;
427:     }
428:   }

430:   /* Create the Vec */
431:   PetscCall(PetscNew(&link));
432:   PetscCall(PetscStrallocpy(name, &link->name));
433:   PetscCall(DMCreateGlobalVector(dm, &link->X));
434:   link->next      = dm->namedglobal;
435:   dm->namedglobal = link;

437: found:
438:   *X           = link->X;
439:   link->status = DMVEC_STATUS_OUT;
440:   PetscFunctionReturn(PETSC_SUCCESS);
441: }

443: /*@
444:   DMRestoreNamedGlobalVector - restore access to a named, persistent global vector

446:   Collective

448:   Input Parameters:
449: + dm   - `DM` on which `X` was gotten
450: . name - name under which `X` was gotten
451: - X    - `Vec` to restore

453:   Level: developer

455: .seealso: `DM`, `DMGetNamedGlobalVector()`, `DMClearNamedGlobalVectors()`
456: @*/
457: PetscErrorCode DMRestoreNamedGlobalVector(DM dm, const char *name, Vec *X)
458: {
459:   DMNamedVecLink link;

461:   PetscFunctionBegin;
463:   PetscAssertPointer(name, 2);
464:   PetscAssertPointer(X, 3);
466:   for (link = dm->namedglobal; link; link = link->next) {
467:     PetscBool match;

469:     PetscCall(PetscStrcmp(name, link->name, &match));
470:     if (match) {
471:       DM vdm;

473:       PetscCall(VecGetDM(*X, &vdm));
474:       PetscCheck(link->status == DMVEC_STATUS_OUT, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Vec name '%s' was not checked out", name);
475:       PetscCheck(link->X == *X, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_INCOMP, "Attempt to restore Vec name '%s', but Vec does not match the cache", name);
476:       PetscCheck(vdm == dm, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Invalid vector");

478:       link->status = DMVEC_STATUS_IN;
479:       PetscCall(VecSetDM(link->X, NULL));
480:       *X = NULL;
481:       PetscFunctionReturn(PETSC_SUCCESS);
482:     }
483:   }
484:   SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_INCOMP, "Could not find Vec name '%s' to restore", name);
485: }

487: /*@
488:   DMHasNamedLocalVector - check for a named, persistent local vector created with `DMGetNamedLocalVector()`

490:   Not Collective

492:   Input Parameters:
493: + dm   - `DM` to hold named vectors
494: - name - unique name for `Vec`

496:   Output Parameter:
497: . exists - true if the vector was previously created

499:   Level: developer

501:   Note:
502:   If a `Vec` with the given name does not exist, it is created.

504: .seealso: `DM`, `DMGetNamedGlobalVector()`, `DMRestoreNamedLocalVector()`, `DMClearNamedLocalVectors()`
505: @*/
506: PetscErrorCode DMHasNamedLocalVector(DM dm, const char *name, PetscBool *exists)
507: {
508:   DMNamedVecLink link;

510:   PetscFunctionBegin;
512:   PetscAssertPointer(name, 2);
513:   PetscAssertPointer(exists, 3);
514:   *exists = PETSC_FALSE;
515:   for (link = dm->namedlocal; link; link = link->next) {
516:     PetscBool match;
517:     PetscCall(PetscStrcmp(name, link->name, &match));
518:     if (match) {
519:       *exists = PETSC_TRUE;
520:       break;
521:     }
522:   }
523:   PetscFunctionReturn(PETSC_SUCCESS);
524: }

526: /*@
527:   DMGetNamedLocalVector - get access to a named, persistent local vector

529:   Not Collective

531:   Input Parameters:
532: + dm   - `DM` to hold named vectors
533: - name - unique name for `X`

535:   Output Parameter:
536: . X - named `Vec`

538:   Level: developer

540:   Note:
541:   If a `Vec` with the given name does not exist, it is created.

543: .seealso: `DM`, `DMGetNamedGlobalVector()`, `DMRestoreNamedLocalVector()`, `DMHasNamedLocalVector()`, `DMClearNamedLocalVectors()`, `DMGetGlobalVector()`, `DMGetLocalVector()`
544: @*/
545: PetscErrorCode DMGetNamedLocalVector(DM dm, const char *name, Vec *X)
546: {
547:   DMNamedVecLink link;

549:   PetscFunctionBegin;
551:   PetscAssertPointer(name, 2);
552:   PetscAssertPointer(X, 3);
553:   for (link = dm->namedlocal; link; link = link->next) {
554:     PetscBool match;

556:     PetscCall(PetscStrcmp(name, link->name, &match));
557:     if (match) {
558:       DM vdm;

560:       PetscCheck(link->status == DMVEC_STATUS_IN, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Vec name '%s' already checked out", name);
561:       PetscCall(VecGetDM(link->X, &vdm));
562:       PetscCheck(!vdm, PetscObjectComm((PetscObject)vdm), PETSC_ERR_LIB, "Invalid vector");
563:       PetscCall(VecSetDM(link->X, dm));
564:       goto found;
565:     }
566:   }

568:   /* Create the Vec */
569:   PetscCall(PetscNew(&link));
570:   PetscCall(PetscStrallocpy(name, &link->name));
571:   PetscCall(DMCreateLocalVector(dm, &link->X));
572:   link->next     = dm->namedlocal;
573:   dm->namedlocal = link;

575: found:
576:   *X           = link->X;
577:   link->status = DMVEC_STATUS_OUT;
578:   PetscFunctionReturn(PETSC_SUCCESS);
579: }

581: /*@
582:   DMRestoreNamedLocalVector - restore access to a named, persistent local vector obtained with `DMGetNamedLocalVector()`

584:   Not Collective

586:   Input Parameters:
587: + dm   - `DM` on which `X` was gotten
588: . name - name under which `X` was gotten
589: - X    - `Vec` to restore

591:   Level: developer

593: .seealso: `DM`, `DMRestoreNamedGlobalVector()`, `DMGetNamedLocalVector()`, `DMClearNamedLocalVectors()`
594: @*/
595: PetscErrorCode DMRestoreNamedLocalVector(DM dm, const char *name, Vec *X)
596: {
597:   DMNamedVecLink link;

599:   PetscFunctionBegin;
601:   PetscAssertPointer(name, 2);
602:   PetscAssertPointer(X, 3);
604:   for (link = dm->namedlocal; link; link = link->next) {
605:     PetscBool match;

607:     PetscCall(PetscStrcmp(name, link->name, &match));
608:     if (match) {
609:       DM vdm;

611:       PetscCall(VecGetDM(*X, &vdm));
612:       PetscCheck(link->status == DMVEC_STATUS_OUT, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Vec name '%s' was not checked out", name);
613:       PetscCheck(link->X == *X, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_INCOMP, "Attempt to restore Vec name '%s', but Vec does not match the cache", name);
614:       PetscCheck(vdm == dm, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Invalid vector");

616:       link->status = DMVEC_STATUS_IN;
617:       PetscCall(VecSetDM(link->X, NULL));
618:       *X = NULL;
619:       PetscFunctionReturn(PETSC_SUCCESS);
620:     }
621:   }
622:   SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_INCOMP, "Could not find Vec name '%s' to restore", name);
623: }