Actual source code: dmget.c

petsc-3.11.4 2019-09-28
Report Typos and Errors
  1:  #include <petsc/private/dmimpl.h>

  3: /*@
  4:    DMGetLocalVector - Gets a Seq PETSc vector that
  5:    may be used with the DMXXX routines. This vector has spaces for the ghost values.

  7:    Not Collective

  9:    Input Parameter:
 10: .  dm - the distributed array

 12:    Output Parameter:
 13: .  g - the local vector

 15:    Level: beginner

 17:    Note:
 18:    The vector values are NOT initialized and may have garbage in them, so you may need
 19:    to zero them.

 21:    The output parameter, g, is a regular PETSc vector that should be returned with
 22:    DMRestoreLocalVector() DO NOT call VecDestroy() on it.

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

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

 30: .keywords: distributed array, create, local, vector

 32: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
 33:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
 34:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector(),
 35:           VecStrideMax(), VecStrideMin(), VecStrideNorm()
 36: @*/
 37: PetscErrorCode  DMGetLocalVector(DM dm,Vec *g)
 38: {
 39:   PetscErrorCode ierr,i;

 44:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
 45:     if (dm->localin[i]) {
 46:       *g             = dm->localin[i];
 47:       dm->localin[i] = NULL;
 48:       goto alldone;
 49:     }
 50:   }
 51:   DMCreateLocalVector(dm,g);

 53: alldone:
 54:   for (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 Seq PETSc vector that
 65:      obtained from DMGetLocalVector(). Do not use with vector obtained via
 66:      DMCreateLocalVector().

 68:    Not Collective

 70:    Input Parameter:
 71: +  dm - the distributed array
 72: -  g - the local vector

 74:    Level: beginner

 76: .keywords: distributed array, create, local, vector

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

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

107: /*@
108:    DMGetGlobalVector - Gets a MPI PETSc vector that
109:    may be used with the DMXXX routines.

111:    Collective on DM

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

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: .keywords: distributed array, create, Global, vector

136: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
137:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
138:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
139:           VecStrideMax(), VecStrideMin(), VecStrideNorm()

141: @*/
142: PetscErrorCode  DMGetGlobalVector(DM dm,Vec *g)
143: {
145:   PetscInt       i;

150:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
151:     if (dm->globalin[i]) {
152:       *g              = dm->globalin[i];
153:       dm->globalin[i] = NULL;
154:       goto alldone;
155:     }
156:   }
157:   DMCreateGlobalVector(dm,g);

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

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

172:    Collective on DM

174:    Input Parameter:
175: .  dm - the distributed array

177:    Level: developer

179: .keywords: distributed array, create, Global, vector

181: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
182:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
183:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
184:           VecStrideMax(), VecStrideMin(), VecStrideNorm()

186: @*/
187: PetscErrorCode  DMClearGlobalVectors(DM dm)
188: {
190:   PetscInt       i;

194:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
195:     Vec g;
196:     if (dm->globalout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Clearing DM of global vectors that has a global vector obtained with DMGetGlobalVector()");
197:     g = dm->globalin[i];
198:     dm->globalin[i] = NULL;
199:     VecDestroy(&g);
200:   }
201:   return(0);
202: }

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

207:    Collective on DM

209:    Input Parameter:
210: .  dm - the distributed array

212:    Level: developer

214: .keywords: distributed array, create, Local, vector

216: .seealso: DMCreateLocalVector(), VecDuplicate(), VecDuplicateVecs(),
217:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMLocalToLocalBegin(),
218:           DMLocalToLocalEnd(), DMLocalToLocalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
219:           VecStrideMax(), VecStrideMin(), VecStrideNorm()

221: @*/
222: PetscErrorCode  DMClearLocalVectors(DM dm)
223: {
225:   PetscInt       i;

229:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
230:     Vec g;
231:     if (dm->localout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Clearing DM of local vectors that has a local vector obtained with DMGetLocalVector()");
232:     g = dm->localin[i];
233:     dm->localin[i] = NULL;
234:     VecDestroy(&g);
235:   }
236:   return(0);
237: }

239: /*@
240:    DMRestoreGlobalVector - Returns a Seq PETSc vector that
241:      obtained from DMGetGlobalVector(). Do not use with vector obtained via
242:      DMCreateGlobalVector().

244:    Not Collective

246:    Input Parameter:
247: +  dm - the distributed array
248: -  g - the global vector

250:    Level: beginner

252: .keywords: distributed array, create, global, vector

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

266:   VecSetErrorIfLocked(*g, 2);
267:   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
268:     if (*g == dm->globalout[j]) {
269:       dm->globalout[j] = NULL;
270:       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
271:         if (!dm->globalin[i]) {
272:           dm->globalin[i] = *g;
273:           goto alldone;
274:         }
275:       }
276:     }
277:   }
278:   VecDestroy(g);
279: alldone:
280:   *g = NULL;
281:   return(0);
282: }

284: /*@C
285:    DMHasNamedGlobalVector - check for a named, persistent global vector

287:    Not Collective

289:    Input Arguments:
290: +  dm - DM to hold named vectors
291: -  name - unique name for Vec

293:    Output Arguments:
294: .  exists - true if the vector was previously created

296:    Level: developer

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

300: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
301: @*/
302: PetscErrorCode DMHasNamedGlobalVector(DM dm,const char *name,PetscBool *exists)
303: {
305:   DMNamedVecLink link;

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

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

326:    Collective on DM

328:    Input Arguments:
329: +  dm - DM to hold named vectors
330: -  name - unique name for Vec

332:    Output Arguments:
333: .  X - named Vec

335:    Level: developer

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

339: .seealso: DMRestoreNamedGlobalVector()
340: @*/
341: PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
342: {
344:   DMNamedVecLink link;

350:   for (link=dm->namedglobal; link; link=link->next) {
351:     PetscBool match;
352:     PetscStrcmp(name,link->name,&match);
353:     if (match) {
354:       if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
355:       goto found;
356:     }
357:   }

359:   /* Create the Vec */
360:   PetscNew(&link);
361:   PetscStrallocpy(name,&link->name);
362:   DMCreateGlobalVector(dm,&link->X);
363:   link->next      = dm->namedglobal;
364:   dm->namedglobal = link;

366: found:
367:   *X           = link->X;
368:   link->status = DMVEC_STATUS_OUT;
369:   return(0);
370: }

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

375:    Collective on DM

377:    Input Arguments:
378: +  dm - DM on which the vector was gotten
379: .  name - name under which the vector was gotten
380: -  X - Vec to restore

382:    Output Arguments:

384:    Level: developer

386: .seealso: DMGetNamedGlobalVector()
387: @*/
388: PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
389: {
391:   DMNamedVecLink link;

398:   for (link=dm->namedglobal; link; link=link->next) {
399:     PetscBool match;
400:     PetscStrcmp(name,link->name,&match);
401:     if (match) {
402:       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
403:       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);
404:       link->status = DMVEC_STATUS_IN;
405:       *X           = NULL;
406:       return(0);
407:     }
408:   }
409:   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
410:   return(0);
411: }

413: /*@C
414:    DMHasNamedLocalVector - check for a named, persistent local vector

416:    Not Collective

418:    Input Arguments:
419: +  dm - DM to hold named vectors
420: -  name - unique name for Vec

422:    Output Arguments:
423: .  exists - true if the vector was previously created

425:    Level: developer

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

429: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
430: @*/
431: PetscErrorCode DMHasNamedLocalVector(DM dm,const char *name,PetscBool *exists)
432: {
434:   DMNamedVecLink link;

440:   *exists = PETSC_FALSE;
441:   for (link=dm->namedlocal; link; link=link->next) {
442:     PetscBool match;
443:     PetscStrcmp(name,link->name,&match);
444:     if (match) {
445:       *exists = PETSC_TRUE;
446:       break;
447:     }
448:   }
449:   return(0);
450: }

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

455:    Not Collective

457:    Input Arguments:
458: +  dm - DM to hold named vectors
459: -  name - unique name for Vec

461:    Output Arguments:
462: .  X - named Vec

464:    Level: developer

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

468: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
469: @*/
470: PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
471: {
473:   DMNamedVecLink link;

479:   for (link=dm->namedlocal; link; link=link->next) {
480:     PetscBool match;
481:     PetscStrcmp(name,link->name,&match);
482:     if (match) {
483:       if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
484:       goto found;
485:     }
486:   }

488:   /* Create the Vec */
489:   PetscNew(&link);
490:   PetscStrallocpy(name,&link->name);
491:   DMCreateLocalVector(dm,&link->X);
492:   link->next     = dm->namedlocal;
493:   dm->namedlocal = link;

495: found:
496:   *X           = link->X;
497:   link->status = DMVEC_STATUS_OUT;
498:   return(0);
499: }

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

504:    Not Collective

506:    Input Arguments:
507: +  dm - DM on which the vector was gotten
508: .  name - name under which the vector was gotten
509: -  X - Vec to restore

511:    Output Arguments:

513:    Level: developer

515: .seealso: DMRestoreNamedGlobalVector(),DMGetNamedLocalVector()
516: @*/
517: PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
518: {
520:   DMNamedVecLink link;

527:   for (link=dm->namedlocal; link; link=link->next) {
528:     PetscBool match;
529:     PetscStrcmp(name,link->name,&match);
530:     if (match) {
531:       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
532:       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);
533:       link->status = DMVEC_STATUS_IN;
534:       *X           = NULL;
535:       return(0);
536:     }
537:   }
538:   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
539:   return(0);
540: }