Actual source code: dmget.c

petsc-master 2016-08-22
Report Typos and Errors
  1: #include <petsc/private/dmimpl.h> /*I "petscdm.h" I*/

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

  9:    Not Collective

 11:    Input Parameter:
 12: .  dm - the distributed array

 14:    Output Parameter:
 15: .  g - the local vector

 17:    Level: beginner

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

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

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

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

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

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

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

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

 67: /*@
 68:    DMRestoreLocalVector - Returns a Seq PETSc vector that
 69:      obtained from DMGetLocalVector(). Do not use with vector obtained via
 70:      DMCreateLocalVector().

 72:    Not Collective

 74:    Input Parameter:
 75: +  dm - the distributed array
 76: -  g - the local vector

 78:    Level: beginner

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

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

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

113: /*@
114:    DMGetGlobalVector - Gets a MPI PETSc vector that
115:    may be used with the DMXXX routines.

117:    Collective on DM

119:    Input Parameter:
120: .  dm - the distributed array

122:    Output Parameter:
123: .  g - the global vector

125:    Level: beginner

127:    Note:
128:    The vector values are NOT initialized and may have garbage in them, so you may need
129:    to zero them.

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

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

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

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

142: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
143:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
144:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
145:           VecStrideMax(), VecStrideMin(), VecStrideNorm()

147: @*/
148: PetscErrorCode  DMGetGlobalVector(DM dm,Vec *g)
149: {
151:   PetscInt       i;

156:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
157:     if (dm->globalin[i]) {
158:       *g              = dm->globalin[i];
159:       dm->globalin[i] = NULL;
160:       goto alldone;
161:     }
162:   }
163:   DMCreateGlobalVector(dm,g);

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

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 distributed array

185:    Level: developer

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

189: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
190:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
191:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
192:           VecStrideMax(), VecStrideMin(), VecStrideNorm()

194: @*/
195: PetscErrorCode  DMClearGlobalVectors(DM dm)
196: {
198:   PetscInt       i;

202:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
203:     Vec g;
204:     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()");
205:     g = dm->globalin[i];
206:     dm->globalin[i] = NULL;
207:     VecDestroy(&g);
208:   }
209:   return(0);
210: }

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

217:    Collective on DM

219:    Input Parameter:
220: .  dm - the distributed array

222:    Level: developer

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

226: .seealso: DMCreateLocalVector(), VecDuplicate(), VecDuplicateVecs(),
227:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMLocalToLocalBegin(),
228:           DMLocalToLocalEnd(), DMLocalToLocalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
229:           VecStrideMax(), VecStrideMin(), VecStrideNorm()

231: @*/
232: PetscErrorCode  DMClearLocalVectors(DM dm)
233: {
235:   PetscInt       i;

239:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
240:     Vec g;
241:     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()");
242:     g = dm->localin[i];
243:     dm->localin[i] = NULL;
244:     VecDestroy(&g);
245:   }
246:   return(0);
247: }

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

256:    Not Collective

258:    Input Parameter:
259: +  dm - the distributed array
260: -  g - the global vector

262:    Level: beginner

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

266: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
267:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(),
268:           DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
269: @*/
270: PetscErrorCode  DMRestoreGlobalVector(DM dm,Vec *g)
271: {
273:   PetscInt       i,j;

278:   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
279:     if (*g == dm->globalout[j]) {
280:       dm->globalout[j] = NULL;
281:       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
282:         if (!dm->globalin[i]) {
283:           dm->globalin[i] = *g;
284:           goto alldone;
285:         }
286:       }
287:     }
288:   }
289:   VecDestroy(g);
290: alldone:
291:   *g = NULL;
292:   return(0);
293: }

297: /*@C
298:    DMHasNamedGlobalVector - check for a named, persistent global vector

300:    Not Collective

302:    Input Arguments:
303: +  dm - DM to hold named vectors
304: -  name - unique name for Vec

306:    Output Arguments:
307: .  exists - true if the vector was previously created

309:    Level: developer

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

313: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
314: @*/
315: PetscErrorCode DMHasNamedGlobalVector(DM dm,const char *name,PetscBool *exists)
316: {
318:   DMNamedVecLink link;

324:   *exists = PETSC_FALSE;
325:   for (link=dm->namedglobal; link; link=link->next) {
326:     PetscBool match;
327:     PetscStrcmp(name,link->name,&match);
328:     if (match) {
329:       *exists = PETSC_TRUE;
330:       break;
331:     }
332:   }
333:   return(0);
334: }

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

341:    Collective on DM

343:    Input Arguments:
344: +  dm - DM to hold named vectors
345: -  name - unique name for Vec

347:    Output Arguments:
348: .  X - named Vec

350:    Level: developer

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

354: .seealso: DMRestoreNamedGlobalVector()
355: @*/
356: PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
357: {
359:   DMNamedVecLink link;

365:   for (link=dm->namedglobal; link; link=link->next) {
366:     PetscBool match;
367:     PetscStrcmp(name,link->name,&match);
368:     if (match) {
369:       if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
370:       goto found;
371:     }
372:   }

374:   /* Create the Vec */
375:   PetscNew(&link);
376:   PetscStrallocpy(name,&link->name);
377:   DMCreateGlobalVector(dm,&link->X);
378:   link->next      = dm->namedglobal;
379:   dm->namedglobal = link;

381: found:
382:   *X           = link->X;
383:   link->status = DMVEC_STATUS_OUT;
384:   return(0);
385: }

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

392:    Collective on DM

394:    Input Arguments:
395: +  dm - DM on which the vector was gotten
396: .  name - name under which the vector was gotten
397: -  X - Vec to restore

399:    Output Arguments:

401:    Level: developer

403: .seealso: DMGetNamedGlobalVector()
404: @*/
405: PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
406: {
408:   DMNamedVecLink link;

415:   for (link=dm->namedglobal; link; link=link->next) {
416:     PetscBool match;
417:     PetscStrcmp(name,link->name,&match);
418:     if (match) {
419:       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
420:       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);
421:       link->status = DMVEC_STATUS_IN;
422:       *X           = NULL;
423:       return(0);
424:     }
425:   }
426:   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
427:   return(0);
428: }

432: /*@C
433:    DMHasNamedLocalVector - check for a named, persistent local vector

435:    Not Collective

437:    Input Arguments:
438: +  dm - DM to hold named vectors
439: -  name - unique name for Vec

441:    Output Arguments:
442: .  exists - true if the vector was previously created

444:    Level: developer

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

448: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
449: @*/
450: PetscErrorCode DMHasNamedLocalVector(DM dm,const char *name,PetscBool *exists)
451: {
453:   DMNamedVecLink link;

459:   *exists = PETSC_FALSE;
460:   for (link=dm->namedlocal; link; link=link->next) {
461:     PetscBool match;
462:     PetscStrcmp(name,link->name,&match);
463:     if (match) {
464:       *exists = PETSC_TRUE;
465:       break;
466:     }
467:   }
468:   return(0);
469: }

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

476:    Not Collective

478:    Input Arguments:
479: +  dm - DM to hold named vectors
480: -  name - unique name for Vec

482:    Output Arguments:
483: .  X - named Vec

485:    Level: developer

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

489: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
490: @*/
491: PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
492: {
494:   DMNamedVecLink link;

500:   for (link=dm->namedlocal; link; link=link->next) {
501:     PetscBool match;
502:     PetscStrcmp(name,link->name,&match);
503:     if (match) {
504:       if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
505:       goto found;
506:     }
507:   }

509:   /* Create the Vec */
510:   PetscNew(&link);
511:   PetscStrallocpy(name,&link->name);
512:   DMCreateLocalVector(dm,&link->X);
513:   link->next     = dm->namedlocal;
514:   dm->namedlocal = link;

516: found:
517:   *X           = link->X;
518:   link->status = DMVEC_STATUS_OUT;
519:   return(0);
520: }

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

527:    Not Collective

529:    Input Arguments:
530: +  dm - DM on which the vector was gotten
531: .  name - name under which the vector was gotten
532: -  X - Vec to restore

534:    Output Arguments:

536:    Level: developer

538: .seealso: DMRestoreNamedGlobalVector(),DMGetNamedLocalVector()
539: @*/
540: PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
541: {
543:   DMNamedVecLink link;

550:   for (link=dm->namedlocal; link; link=link->next) {
551:     PetscBool match;
552:     PetscStrcmp(name,link->name,&match);
553:     if (match) {
554:       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
555:       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);
556:       link->status = DMVEC_STATUS_IN;
557:       *X           = NULL;
558:       return(0);
559:     }
560:   }
561:   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
562:   return(0);
563: }