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: {
 38:   for (PetscInt i = 0; i < DM_MAX_WORK_VECTORS; i++) {
 39:     if (dm->localin[i]) {
 40:       DM vdm;

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

 45:       VecGetDM(*g, &vdm);
 47:       VecSetDM(*g, dm);
 48:       goto alldone;
 49:     }
 50:   }
 51:   DMCreateLocalVector(dm, g);

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

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

 68:    Not Collective

 70:    Input Parameters:
 71: +  dm - the dm
 72: -  g - the local vector

 74:    Level: beginner

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

 86:   for (j = 0; j < DM_MAX_WORK_VECTORS; j++) {
 87:     if (*g == dm->localout[j]) {
 88:       DM vdm;

 90:       VecGetDM(*g, &vdm);
 92:       VecSetDM(*g, NULL);
 93:       dm->localout[j] = NULL;
 94:       for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
 95:         if (!dm->localin[i]) {
 96:           dm->localin[i] = *g;
 97:           goto alldone;
 98:         }
 99:       }
100:     }
101:   }
102:   VecDestroy(g);
103: alldone:
104:   *g = NULL;
105:   return 0;
106: }

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

111:    Collective on dm

113:    Input Parameter:
114: .  dm - the dm

116:    Output Parameter:
117: .  g - the global vector

119:    Level: beginner

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

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

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

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

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

145:   for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
146:     if (dm->globalin[i]) {
147:       DM vdm;

149:       *g              = dm->globalin[i];
150:       dm->globalin[i] = NULL;

152:       VecGetDM(*g, &vdm);
154:       VecSetDM(*g, dm);
155:       goto alldone;
156:     }
157:   }
158:   DMCreateGlobalVector(dm, g);

160: alldone:
161:   for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
162:     if (!dm->globalout[i]) {
163:       dm->globalout[i] = *g;
164:       break;
165:     }
166:   }
167:   return 0;
168: }

170: /*@
171:    DMClearGlobalVectors - Destroys all the global vectors that have been stashed in this DM

173:    Collective on dm

175:    Input Parameter:
176: .  dm - the dm

178:    Level: developer

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

190:   for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
191:     Vec g;

194:     g               = dm->globalin[i];
195:     dm->globalin[i] = NULL;
196:     if (g) {
197:       DM vdm;

199:       VecGetDM(g, &vdm);
201:     }
202:     VecDestroy(&g);
203:   }
204:   return 0;
205: }

207: /*@
208:    DMClearLocalVectors - Destroys all the local vectors that have been stashed in this DM

210:    Collective on dm

212:    Input Parameter:
213: .  dm - the dm

215:    Level: developer

217: .seealso: `DMCreateLocalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
218:           `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMLocalToLocalBegin()`,
219:           `DMLocalToLocalEnd()`, `DMLocalToLocalBegin()`, `DMCreateLocalVector()`, `DMRestoreLocalVector()`
220:           `VecStrideMax()`, `VecStrideMin()`, `VecStrideNorm()`
221: @*/
222: PetscErrorCode DMClearLocalVectors(DM dm)
223: {
224:   PetscInt i;

227:   for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
228:     Vec g;

231:     g              = dm->localin[i];
232:     dm->localin[i] = NULL;
233:     if (g) {
234:       DM vdm;

236:       VecGetDM(g, &vdm);
238:     }
239:     VecDestroy(&g);
240:   }
241:   return 0;
242: }

244: /*@
245:    DMRestoreGlobalVector - Returns a PETSc vector that
246:      obtained from DMGetGlobalVector(). Do not use with vector obtained via
247:      DMCreateGlobalVector().

249:    Not Collective

251:    Input Parameters:
252: +  dm - the dm
253: -  g - the global vector

255:    Level: beginner

257: .seealso: `DMCreateGlobalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
258:           `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToGlobalBegin()`,
259:           `DMGlobalToGlobalEnd()`, `DMGlobalToGlobal()`, `DMCreateLocalVector()`, `DMGetGlobalVector()`
260: @*/
261: PetscErrorCode DMRestoreGlobalVector(DM dm, Vec *g)
262: {
263:   PetscInt i, j;

267:   VecSetErrorIfLocked(*g, 2);
268:   for (j = 0; j < DM_MAX_WORK_VECTORS; j++) {
269:     if (*g == dm->globalout[j]) {
270:       DM vdm;

272:       VecGetDM(*g, &vdm);
274:       VecSetDM(*g, NULL);
275:       dm->globalout[j] = NULL;
276:       for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
277:         if (!dm->globalin[i]) {
278:           dm->globalin[i] = *g;
279:           goto alldone;
280:         }
281:       }
282:     }
283:   }
284:   VecDestroy(g);
285: alldone:
286:   *g = NULL;
287:   return 0;
288: }

290: /*@C
291:    DMHasNamedGlobalVector - check for a named, persistent global vector

293:    Not Collective

295:    Input Parameters:
296: +  dm - DM to hold named vectors
297: -  name - unique name for Vec

299:    Output Parameter:
300: .  exists - true if the vector was previously created

302:    Level: developer

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

306: .seealso: `DMGetNamedGlobalVector()`, `DMRestoreNamedLocalVector()`
307: @*/
308: PetscErrorCode DMHasNamedGlobalVector(DM dm, const char *name, PetscBool *exists)
309: {
310:   DMNamedVecLink link;

315:   *exists = PETSC_FALSE;
316:   for (link = dm->namedglobal; link; link = link->next) {
317:     PetscBool match;
318:     PetscStrcmp(name, link->name, &match);
319:     if (match) {
320:       *exists = PETSC_TRUE;
321:       break;
322:     }
323:   }
324:   return 0;
325: }

327: /*@C
328:    DMGetNamedGlobalVector - get access to a named, persistent global vector

330:    Collective on dm

332:    Input Parameters:
333: +  dm - DM to hold named vectors
334: -  name - unique name for Vec

336:    Output Parameter:
337: .  X - named Vec

339:    Level: developer

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

343: .seealso: `DMRestoreNamedGlobalVector()`
344: @*/
345: PetscErrorCode DMGetNamedGlobalVector(DM dm, const char *name, Vec *X)
346: {
347:   DMNamedVecLink link;

352:   for (link = dm->namedglobal; link; link = link->next) {
353:     PetscBool match;

355:     PetscStrcmp(name, link->name, &match);
356:     if (match) {
357:       DM vdm;

360:       VecGetDM(link->X, &vdm);
362:       VecSetDM(link->X, dm);
363:       goto found;
364:     }
365:   }

367:   /* Create the Vec */
368:   PetscNew(&link);
369:   PetscStrallocpy(name, &link->name);
370:   DMCreateGlobalVector(dm, &link->X);
371:   link->next      = dm->namedglobal;
372:   dm->namedglobal = link;

374: found:
375:   *X           = link->X;
376:   link->status = DMVEC_STATUS_OUT;
377:   return 0;
378: }

380: /*@C
381:    DMRestoreNamedGlobalVector - restore access to a named, persistent global vector

383:    Collective on dm

385:    Input Parameters:
386: +  dm - DM on which the vector was gotten
387: .  name - name under which the vector was gotten
388: -  X - Vec to restore

390:    Level: developer

392: .seealso: `DMGetNamedGlobalVector()`
393: @*/
394: PetscErrorCode DMRestoreNamedGlobalVector(DM dm, const char *name, Vec *X)
395: {
396:   DMNamedVecLink link;

402:   for (link = dm->namedglobal; link; link = link->next) {
403:     PetscBool match;

405:     PetscStrcmp(name, link->name, &match);
406:     if (match) {
407:       DM vdm;

409:       VecGetDM(*X, &vdm);

414:       link->status = DMVEC_STATUS_IN;
415:       VecSetDM(link->X, NULL);
416:       *X = NULL;
417:       return 0;
418:     }
419:   }
420:   SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_INCOMP, "Could not find Vec name '%s' to restore", name);
421: }

423: /*@C
424:    DMHasNamedLocalVector - check for a named, persistent local vector

426:    Not Collective

428:    Input Parameters:
429: +  dm - DM to hold named vectors
430: -  name - unique name for Vec

432:    Output Parameter:
433: .  exists - true if the vector was previously created

435:    Level: developer

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

439: .seealso: `DMGetNamedGlobalVector()`, `DMRestoreNamedLocalVector()`
440: @*/
441: PetscErrorCode DMHasNamedLocalVector(DM dm, const char *name, PetscBool *exists)
442: {
443:   DMNamedVecLink link;

448:   *exists = PETSC_FALSE;
449:   for (link = dm->namedlocal; link; link = link->next) {
450:     PetscBool match;
451:     PetscStrcmp(name, link->name, &match);
452:     if (match) {
453:       *exists = PETSC_TRUE;
454:       break;
455:     }
456:   }
457:   return 0;
458: }

460: /*@C
461:    DMGetNamedLocalVector - get access to a named, persistent local vector

463:    Not Collective

465:    Input Parameters:
466: +  dm - DM to hold named vectors
467: -  name - unique name for Vec

469:    Output Parameter:
470: .  X - named Vec

472:    Level: developer

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

476: .seealso: `DMGetNamedGlobalVector()`, `DMRestoreNamedLocalVector()`
477: @*/
478: PetscErrorCode DMGetNamedLocalVector(DM dm, const char *name, Vec *X)
479: {
480:   DMNamedVecLink link;

485:   for (link = dm->namedlocal; link; link = link->next) {
486:     PetscBool match;

488:     PetscStrcmp(name, link->name, &match);
489:     if (match) {
490:       DM vdm;

493:       VecGetDM(link->X, &vdm);
495:       VecSetDM(link->X, dm);
496:       goto found;
497:     }
498:   }

500:   /* Create the Vec */
501:   PetscNew(&link);
502:   PetscStrallocpy(name, &link->name);
503:   DMCreateLocalVector(dm, &link->X);
504:   link->next     = dm->namedlocal;
505:   dm->namedlocal = link;

507: found:
508:   *X           = link->X;
509:   link->status = DMVEC_STATUS_OUT;
510:   return 0;
511: }

513: /*@C
514:    DMRestoreNamedLocalVector - restore access to a named, persistent local vector

516:    Not Collective

518:    Input Parameters:
519: +  dm - DM on which the vector was gotten
520: .  name - name under which the vector was gotten
521: -  X - Vec to restore

523:    Level: developer

525: .seealso: `DMRestoreNamedGlobalVector()`, `DMGetNamedLocalVector()`
526: @*/
527: PetscErrorCode DMRestoreNamedLocalVector(DM dm, const char *name, Vec *X)
528: {
529:   DMNamedVecLink link;

535:   for (link = dm->namedlocal; link; link = link->next) {
536:     PetscBool match;

538:     PetscStrcmp(name, link->name, &match);
539:     if (match) {
540:       DM vdm;

542:       VecGetDM(*X, &vdm);

547:       link->status = DMVEC_STATUS_IN;
548:       VecSetDM(link->X, NULL);
549:       *X = NULL;
550:       return 0;
551:     }
552:   }
553:   SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_INCOMP, "Could not find Vec name '%s' to restore", name);
554: }