Actual source code: dmget.c

petsc-master 2017-11-20
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:   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
267:     if (*g == dm->globalout[j]) {
268:       dm->globalout[j] = NULL;
269:       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
270:         if (!dm->globalin[i]) {
271:           dm->globalin[i] = *g;
272:           goto alldone;
273:         }
274:       }
275:     }
276:   }
277:   VecDestroy(g);
278: alldone:
279:   *g = NULL;
280:   return(0);
281: }

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

286:    Not Collective

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

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

295:    Level: developer

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

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

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

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

325:    Collective on DM

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

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

334:    Level: developer

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

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

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

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

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

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

374:    Collective on DM

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

381:    Output Arguments:

383:    Level: developer

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

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

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

415:    Not Collective

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

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

424:    Level: developer

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

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

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

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

454:    Not Collective

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

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

463:    Level: developer

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

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

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

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

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

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

503:    Not Collective

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

510:    Output Arguments:

512:    Level: developer

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

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