Actual source code: dmget.c

petsc-master 2019-10-17
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: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
 31:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
 32:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector(),
 33:           VecStrideMax(), VecStrideMin(), VecStrideNorm()
 34: @*/
 35: PetscErrorCode  DMGetLocalVector(DM dm,Vec *g)
 36: {
 37:   PetscErrorCode ierr,i;

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

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

 61: /*@
 62:    DMRestoreLocalVector - Returns a Seq PETSc vector that
 63:      obtained from DMGetLocalVector(). Do not use with vector obtained via
 64:      DMCreateLocalVector().

 66:    Not Collective

 68:    Input Parameter:
 69: +  dm - the distributed array
 70: -  g - the local vector

 72:    Level: beginner

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

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

103: /*@
104:    DMGetGlobalVector - Gets a MPI PETSc vector that
105:    may be used with the DMXXX routines.

107:    Collective on dm

109:    Input Parameter:
110: .  dm - the distributed array

112:    Output Parameter:
113: .  g - the global vector

115:    Level: beginner

117:    Note:
118:    The vector values are NOT initialized and may have garbage in them, so you may need
119:    to zero them.

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

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

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

130: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
131:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
132:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
133:           VecStrideMax(), VecStrideMin(), VecStrideNorm()

135: @*/
136: PetscErrorCode  DMGetGlobalVector(DM dm,Vec *g)
137: {
139:   PetscInt       i;

144:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
145:     if (dm->globalin[i]) {
146:       *g              = dm->globalin[i];
147:       dm->globalin[i] = NULL;
148:       goto alldone;
149:     }
150:   }
151:   DMCreateGlobalVector(dm,g);

153: alldone:
154:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
155:     if (!dm->globalout[i]) {
156:       dm->globalout[i] = *g;
157:       break;
158:     }
159:   }
160:   return(0);
161: }

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

166:    Collective on dm

168:    Input Parameter:
169: .  dm - the distributed array

171:    Level: developer

173: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
174:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
175:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
176:           VecStrideMax(), VecStrideMin(), VecStrideNorm()

178: @*/
179: PetscErrorCode  DMClearGlobalVectors(DM dm)
180: {
182:   PetscInt       i;

186:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
187:     Vec g;
188:     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()");
189:     g = dm->globalin[i];
190:     dm->globalin[i] = NULL;
191:     VecDestroy(&g);
192:   }
193:   return(0);
194: }

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

199:    Collective on dm

201:    Input Parameter:
202: .  dm - the distributed array

204:    Level: developer

206: .seealso: DMCreateLocalVector(), VecDuplicate(), VecDuplicateVecs(),
207:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMLocalToLocalBegin(),
208:           DMLocalToLocalEnd(), DMLocalToLocalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
209:           VecStrideMax(), VecStrideMin(), VecStrideNorm()

211: @*/
212: PetscErrorCode  DMClearLocalVectors(DM dm)
213: {
215:   PetscInt       i;

219:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
220:     Vec g;
221:     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()");
222:     g = dm->localin[i];
223:     dm->localin[i] = NULL;
224:     VecDestroy(&g);
225:   }
226:   return(0);
227: }

229: /*@
230:    DMRestoreGlobalVector - Returns a Seq PETSc vector that
231:      obtained from DMGetGlobalVector(). Do not use with vector obtained via
232:      DMCreateGlobalVector().

234:    Not Collective

236:    Input Parameter:
237: +  dm - the distributed array
238: -  g - the global vector

240:    Level: beginner

242: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
243:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(),
244:           DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
245: @*/
246: PetscErrorCode  DMRestoreGlobalVector(DM dm,Vec *g)
247: {
249:   PetscInt       i,j;

254:   VecSetErrorIfLocked(*g, 2);
255:   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
256:     if (*g == dm->globalout[j]) {
257:       dm->globalout[j] = NULL;
258:       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
259:         if (!dm->globalin[i]) {
260:           dm->globalin[i] = *g;
261:           goto alldone;
262:         }
263:       }
264:     }
265:   }
266:   VecDestroy(g);
267: alldone:
268:   *g = NULL;
269:   return(0);
270: }

272: /*@C
273:    DMHasNamedGlobalVector - check for a named, persistent global vector

275:    Not Collective

277:    Input Arguments:
278: +  dm - DM to hold named vectors
279: -  name - unique name for Vec

281:    Output Arguments:
282: .  exists - true if the vector was previously created

284:    Level: developer

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

288: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
289: @*/
290: PetscErrorCode DMHasNamedGlobalVector(DM dm,const char *name,PetscBool *exists)
291: {
293:   DMNamedVecLink link;

299:   *exists = PETSC_FALSE;
300:   for (link=dm->namedglobal; link; link=link->next) {
301:     PetscBool match;
302:     PetscStrcmp(name,link->name,&match);
303:     if (match) {
304:       *exists = PETSC_TRUE;
305:       break;
306:     }
307:   }
308:   return(0);
309: }

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

314:    Collective on dm

316:    Input Arguments:
317: +  dm - DM to hold named vectors
318: -  name - unique name for Vec

320:    Output Arguments:
321: .  X - named Vec

323:    Level: developer

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

327: .seealso: DMRestoreNamedGlobalVector()
328: @*/
329: PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
330: {
332:   DMNamedVecLink link;

338:   for (link=dm->namedglobal; link; link=link->next) {
339:     PetscBool match;
340:     PetscStrcmp(name,link->name,&match);
341:     if (match) {
342:       if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
343:       goto found;
344:     }
345:   }

347:   /* Create the Vec */
348:   PetscNew(&link);
349:   PetscStrallocpy(name,&link->name);
350:   DMCreateGlobalVector(dm,&link->X);
351:   link->next      = dm->namedglobal;
352:   dm->namedglobal = link;

354: found:
355:   *X           = link->X;
356:   link->status = DMVEC_STATUS_OUT;
357:   return(0);
358: }

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

363:    Collective on dm

365:    Input Arguments:
366: +  dm - DM on which the vector was gotten
367: .  name - name under which the vector was gotten
368: -  X - Vec to restore

370:    Output Arguments:

372:    Level: developer

374: .seealso: DMGetNamedGlobalVector()
375: @*/
376: PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
377: {
379:   DMNamedVecLink link;

386:   for (link=dm->namedglobal; link; link=link->next) {
387:     PetscBool match;
388:     PetscStrcmp(name,link->name,&match);
389:     if (match) {
390:       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
391:       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);
392:       link->status = DMVEC_STATUS_IN;
393:       *X           = NULL;
394:       return(0);
395:     }
396:   }
397:   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
398:   return(0);
399: }

401: /*@C
402:    DMHasNamedLocalVector - check for a named, persistent local vector

404:    Not Collective

406:    Input Arguments:
407: +  dm - DM to hold named vectors
408: -  name - unique name for Vec

410:    Output Arguments:
411: .  exists - true if the vector was previously created

413:    Level: developer

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

417: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
418: @*/
419: PetscErrorCode DMHasNamedLocalVector(DM dm,const char *name,PetscBool *exists)
420: {
422:   DMNamedVecLink link;

428:   *exists = PETSC_FALSE;
429:   for (link=dm->namedlocal; link; link=link->next) {
430:     PetscBool match;
431:     PetscStrcmp(name,link->name,&match);
432:     if (match) {
433:       *exists = PETSC_TRUE;
434:       break;
435:     }
436:   }
437:   return(0);
438: }

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

443:    Not Collective

445:    Input Arguments:
446: +  dm - DM to hold named vectors
447: -  name - unique name for Vec

449:    Output Arguments:
450: .  X - named Vec

452:    Level: developer

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

456: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
457: @*/
458: PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
459: {
461:   DMNamedVecLink link;

467:   for (link=dm->namedlocal; link; link=link->next) {
468:     PetscBool match;
469:     PetscStrcmp(name,link->name,&match);
470:     if (match) {
471:       if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
472:       goto found;
473:     }
474:   }

476:   /* Create the Vec */
477:   PetscNew(&link);
478:   PetscStrallocpy(name,&link->name);
479:   DMCreateLocalVector(dm,&link->X);
480:   link->next     = dm->namedlocal;
481:   dm->namedlocal = link;

483: found:
484:   *X           = link->X;
485:   link->status = DMVEC_STATUS_OUT;
486:   return(0);
487: }

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

492:    Not Collective

494:    Input Arguments:
495: +  dm - DM on which the vector was gotten
496: .  name - name under which the vector was gotten
497: -  X - Vec to restore

499:    Output Arguments:

501:    Level: developer

503: .seealso: DMRestoreNamedGlobalVector(),DMGetNamedLocalVector()
504: @*/
505: PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
506: {
508:   DMNamedVecLink link;

515:   for (link=dm->namedlocal; link; link=link->next) {
516:     PetscBool match;
517:     PetscStrcmp(name,link->name,&match);
518:     if (match) {
519:       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
520:       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);
521:       link->status = DMVEC_STATUS_IN;
522:       *X           = NULL;
523:       return(0);
524:     }
525:   }
526:   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
527:   return(0);
528: }