Actual source code: dmget.c

petsc-3.4.4 2014-03-13
  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:    VecStride*() operations can be useful when using DM with dof > 1

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

 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: }

 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:   return(0);
104: }

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

112:    Collective on DM

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

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

120:    Level: beginner

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

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

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

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

133: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
134:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
135:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
136:           VecStrideMax(), VecStrideMin(), VecStrideNorm()

138: @*/
139: PetscErrorCode  DMGetGlobalVector(DM dm,Vec *g)
140: {
142:   PetscInt       i;

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

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

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

171:    Collective on DM

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

176:    Level: developer

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

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

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

193:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
194:     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()");
195:     VecDestroy(&dm->globalin[i]);
196:   }
197:   return(0);
198: }

202: /*@
203:    DMRestoreGlobalVector - Returns a Seq PETSc vector that
204:      obtained from DMGetGlobalVector(). Do not use with vector obtained via
205:      DMCreateGlobalVector().

207:    Not Collective

209:    Input Parameter:
210: +  dm - the distributed array
211: -  g - the global vector

213:    Level: beginner

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

217: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
218:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(),
219:           DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
220: @*/
221: PetscErrorCode  DMRestoreGlobalVector(DM dm,Vec *g)
222: {
224:   PetscInt       i,j;

229:   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
230:     if (*g == dm->globalout[j]) {
231:       dm->globalout[j] = NULL;
232:       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
233:         if (!dm->globalin[i]) {
234:           dm->globalin[i] = *g;
235:           goto alldone;
236:         }
237:       }
238:     }
239:   }
240:   VecDestroy(g);
241: alldone:
242:   return(0);
243: }

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

250:    Collective on DM

252:    Input Arguments:
253: +  dm - DM to hold named vectors
254: -  name - unique name for Vec

256:    Output Arguments:
257: .  X - named Vec

259:    Level: developer

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

263: .seealso: DMRestoreNamedGlobalVector()
264: @*/
265: PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
266: {
268:   DMNamedVecLink link;

274:   for (link=dm->namedglobal; link; link=link->next) {
275:     PetscBool match;
276:     PetscStrcmp(name,link->name,&match);
277:     if (match) {
278:       if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
279:       goto found;
280:     }
281:   }

283:   /* Create the Vec */
284:   PetscMalloc(sizeof(*link),&link);
285:   PetscStrallocpy(name,&link->name);
286:   DMCreateGlobalVector(dm,&link->X);
287:   link->next      = dm->namedglobal;
288:   dm->namedglobal = link;

290: found:
291:   *X           = link->X;
292:   link->status = DMVEC_STATUS_OUT;
293:   return(0);
294: }

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

301:    Collective on DM

303:    Input Arguments:
304: +  dm - DM on which the vector was gotten
305: .  name - name under which the vector was gotten
306: -  X - Vec to restore

308:    Output Arguments:

310:    Level: developer

312: .seealso: DMGetNamedGlobalVector()
313: @*/
314: PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
315: {
317:   DMNamedVecLink link;

324:   for (link=dm->namedglobal; link; link=link->next) {
325:     PetscBool match;
326:     PetscStrcmp(name,link->name,&match);
327:     if (match) {
328:       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
329:       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);
330:       link->status = DMVEC_STATUS_IN;
331:       *X           = NULL;
332:       return(0);
333:     }
334:   }
335:   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
336:   return(0);
337: }

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

344:    Not Collective

346:    Input Arguments:
347: +  dm - DM to hold named vectors
348: -  name - unique name for Vec

350:    Output Arguments:
351: .  X - named Vec

353:    Level: developer

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

357: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
358: @*/
359: PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
360: {
362:   DMNamedVecLink link;

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

377:   /* Create the Vec */
378:   PetscMalloc(sizeof(*link),&link);
379:   PetscStrallocpy(name,&link->name);
380:   DMCreateLocalVector(dm,&link->X);
381:   link->next     = dm->namedlocal;
382:   dm->namedlocal = link;

384: found:
385:   *X           = link->X;
386:   link->status = DMVEC_STATUS_OUT;
387:   return(0);
388: }

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

395:    Not Collective

397:    Input Arguments:
398: +  dm - DM on which the vector was gotten
399: .  name - name under which the vector was gotten
400: -  X - Vec to restore

402:    Output Arguments:

404:    Level: developer

406: .seealso: DMRestoreNamedGlobalVector(),DMGetNamedLocalVector()
407: @*/
408: PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
409: {
411:   DMNamedVecLink link;

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