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:   PetscInt i;

230:   PetscFunctionBegin;
232:   for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
233:     Vec g;

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

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

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

254:   Not Collective

256:   Input Parameters:
257: + dm - the `DM`
258: - g  - the global vector

260:   Level: beginner

262: .seealso: `DM`, `DMCreateGlobalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
263:           `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToGlobalBegin()`,
264:           `DMGlobalToGlobalEnd()`, `DMGlobalToGlobal()`, `DMCreateLocalVector()`, `DMGetGlobalVector()`, `DMClearGlobalVectors()`
265: @*/
266: PetscErrorCode DMRestoreGlobalVector(DM dm, Vec *g)
267: {
268:   PetscInt i, j;

270:   PetscFunctionBegin;
272:   PetscAssertPointer(g, 2);
273:   PetscCall(VecSetErrorIfLocked(*g, 2));
274:   for (j = 0; j < DM_MAX_WORK_VECTORS; j++) {
275:     if (*g == dm->globalout[j]) {
276:       DM vdm;

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

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

299:   Collective

301:   Input Parameter:
302: . dm - the `DM`

304:   Level: developer

306: .seealso: `DM`, `DMGetNamedGlobalVector()`, `DMGetNamedLocalVector()`, `DMClearNamedLocalVectors()`
307: @*/
308: PetscErrorCode DMClearNamedGlobalVectors(DM dm)
309: {
310:   DMNamedVecLink nnext;

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

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

329:   Collective

331:   Input Parameter:
332: . dm - the `DM`

334:   Level: developer

336: .seealso: `DM`, `DMGetNamedGlobalVector()`, `DMGetNamedLocalVector()`, `DMClearNamedGlobalVectors()`
337: @*/
338: PetscErrorCode DMClearNamedLocalVectors(DM dm)
339: {
340:   DMNamedVecLink nnext;

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

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

359:   Not Collective

361:   Input Parameters:
362: + dm   - `DM` to hold named vectors
363: - name - unique name for `Vec`

365:   Output Parameter:
366: . exists - true if the vector was previously created

368:   Level: developer

370: .seealso: `DM`, `DMGetNamedGlobalVector()`, `DMRestoreNamedLocalVector()`, `DMClearNamedGlobalVectors()`
371: @*/
372: PetscErrorCode DMHasNamedGlobalVector(DM dm, const char *name, PetscBool *exists)
373: {
374:   DMNamedVecLink link;

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

392: /*@
393:   DMGetNamedGlobalVector - get access to a named, persistent global vector

395:   Collective

397:   Input Parameters:
398: + dm   - `DM` to hold named vectors
399: - name - unique name for `X`

401:   Output Parameter:
402: . X - named `Vec`

404:   Level: developer

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

409: .seealso: `DM`, `DMRestoreNamedGlobalVector()`, `DMHasNamedGlobalVector()`, `DMClearNamedGlobalVectors()`, `DMGetGlobalVector()`, `DMGetLocalVector()`
410: @*/
411: PetscErrorCode DMGetNamedGlobalVector(DM dm, const char *name, Vec *X)
412: {
413:   DMNamedVecLink link;

415:   PetscFunctionBegin;
417:   PetscAssertPointer(name, 2);
418:   PetscAssertPointer(X, 3);
419:   for (link = dm->namedglobal; link; link = link->next) {
420:     PetscBool match;

422:     PetscCall(PetscStrcmp(name, link->name, &match));
423:     if (match) {
424:       DM vdm;

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

434:   /* Create the Vec */
435:   PetscCall(PetscNew(&link));
436:   PetscCall(PetscStrallocpy(name, &link->name));
437:   PetscCall(DMCreateGlobalVector(dm, &link->X));
438:   link->next      = dm->namedglobal;
439:   dm->namedglobal = link;

441: found:
442:   *X           = link->X;
443:   link->status = DMVEC_STATUS_OUT;
444:   PetscFunctionReturn(PETSC_SUCCESS);
445: }

447: /*@
448:   DMRestoreNamedGlobalVector - restore access to a named, persistent global vector

450:   Collective

452:   Input Parameters:
453: + dm   - `DM` on which `X` was gotten
454: . name - name under which `X` was gotten
455: - X    - `Vec` to restore

457:   Level: developer

459: .seealso: `DM`, `DMGetNamedGlobalVector()`, `DMClearNamedGlobalVectors()`
460: @*/
461: PetscErrorCode DMRestoreNamedGlobalVector(DM dm, const char *name, Vec *X)
462: {
463:   DMNamedVecLink link;

465:   PetscFunctionBegin;
467:   PetscAssertPointer(name, 2);
468:   PetscAssertPointer(X, 3);
470:   for (link = dm->namedglobal; link; link = link->next) {
471:     PetscBool match;

473:     PetscCall(PetscStrcmp(name, link->name, &match));
474:     if (match) {
475:       DM vdm;

477:       PetscCall(VecGetDM(*X, &vdm));
478:       PetscCheck(link->status == DMVEC_STATUS_OUT, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Vec name '%s' was not checked out", name);
479:       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);
480:       PetscCheck(vdm == dm, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Invalid vector");

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

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

494:   Not Collective

496:   Input Parameters:
497: + dm   - `DM` to hold named vectors
498: - name - unique name for `Vec`

500:   Output Parameter:
501: . exists - true if the vector was previously created

503:   Level: developer

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

508: .seealso: `DM`, `DMGetNamedGlobalVector()`, `DMRestoreNamedLocalVector()`, `DMClearNamedLocalVectors()`
509: @*/
510: PetscErrorCode DMHasNamedLocalVector(DM dm, const char *name, PetscBool *exists)
511: {
512:   DMNamedVecLink link;

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

530: /*@
531:   DMGetNamedLocalVector - get access to a named, persistent local vector

533:   Not Collective

535:   Input Parameters:
536: + dm   - `DM` to hold named vectors
537: - name - unique name for `X`

539:   Output Parameter:
540: . X - named `Vec`

542:   Level: developer

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

547: .seealso: `DM`, `DMGetNamedGlobalVector()`, `DMRestoreNamedLocalVector()`, `DMHasNamedLocalVector()`, `DMClearNamedLocalVectors()`, `DMGetGlobalVector()`, `DMGetLocalVector()`
548: @*/
549: PetscErrorCode DMGetNamedLocalVector(DM dm, const char *name, Vec *X)
550: {
551:   DMNamedVecLink link;

553:   PetscFunctionBegin;
555:   PetscAssertPointer(name, 2);
556:   PetscAssertPointer(X, 3);
557:   for (link = dm->namedlocal; link; link = link->next) {
558:     PetscBool match;

560:     PetscCall(PetscStrcmp(name, link->name, &match));
561:     if (match) {
562:       DM vdm;

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

572:   /* Create the Vec */
573:   PetscCall(PetscNew(&link));
574:   PetscCall(PetscStrallocpy(name, &link->name));
575:   PetscCall(DMCreateLocalVector(dm, &link->X));
576:   link->next     = dm->namedlocal;
577:   dm->namedlocal = link;

579: found:
580:   *X           = link->X;
581:   link->status = DMVEC_STATUS_OUT;
582:   PetscFunctionReturn(PETSC_SUCCESS);
583: }

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

588:   Not Collective

590:   Input Parameters:
591: + dm   - `DM` on which `X` was gotten
592: . name - name under which `X` was gotten
593: - X    - `Vec` to restore

595:   Level: developer

597: .seealso: `DM`, `DMRestoreNamedGlobalVector()`, `DMGetNamedLocalVector()`, `DMClearNamedLocalVectors()`
598: @*/
599: PetscErrorCode DMRestoreNamedLocalVector(DM dm, const char *name, Vec *X)
600: {
601:   DMNamedVecLink link;

603:   PetscFunctionBegin;
605:   PetscAssertPointer(name, 2);
606:   PetscAssertPointer(X, 3);
608:   for (link = dm->namedlocal; link; link = link->next) {
609:     PetscBool match;

611:     PetscCall(PetscStrcmp(name, link->name, &match));
612:     if (match) {
613:       DM vdm;

615:       PetscCall(VecGetDM(*X, &vdm));
616:       PetscCheck(link->status == DMVEC_STATUS_OUT, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Vec name '%s' was not checked out", name);
617:       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);
618:       PetscCheck(vdm == dm, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Invalid vector");

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