Actual source code: dmget.c
petsc-3.6.1 2015-08-06
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: DMRestoreGlobalVector - Returns a Seq PETSc vector that
216: obtained from DMGetGlobalVector(). Do not use with vector obtained via
217: DMCreateGlobalVector().
219: Not Collective
221: Input Parameter:
222: + dm - the distributed array
223: - g - the global vector
225: Level: beginner
227: .keywords: distributed array, create, global, vector
229: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
230: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(),
231: DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
232: @*/
233: PetscErrorCode DMRestoreGlobalVector(DM dm,Vec *g)
234: {
236: PetscInt i,j;
241: for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
242: if (*g == dm->globalout[j]) {
243: dm->globalout[j] = NULL;
244: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
245: if (!dm->globalin[i]) {
246: dm->globalin[i] = *g;
247: goto alldone;
248: }
249: }
250: }
251: }
252: VecDestroy(g);
253: alldone:
254: *g = NULL;
255: return(0);
256: }
260: /*@C
261: DMGetNamedGlobalVector - get access to a named, persistent global vector
263: Collective on DM
265: Input Arguments:
266: + dm - DM to hold named vectors
267: - name - unique name for Vec
269: Output Arguments:
270: . X - named Vec
272: Level: developer
274: Note: If a Vec with the given name does not exist, it is created.
276: .seealso: DMRestoreNamedGlobalVector()
277: @*/
278: PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
279: {
281: DMNamedVecLink link;
287: for (link=dm->namedglobal; link; link=link->next) {
288: PetscBool match;
289: PetscStrcmp(name,link->name,&match);
290: if (match) {
291: if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
292: goto found;
293: }
294: }
296: /* Create the Vec */
297: PetscNew(&link);
298: PetscStrallocpy(name,&link->name);
299: DMCreateGlobalVector(dm,&link->X);
300: link->next = dm->namedglobal;
301: dm->namedglobal = link;
303: found:
304: *X = link->X;
305: link->status = DMVEC_STATUS_OUT;
306: return(0);
307: }
311: /*@C
312: DMRestoreNamedGlobalVector - restore access to a named, persistent global vector
314: Collective on DM
316: Input Arguments:
317: + dm - DM on which the vector was gotten
318: . name - name under which the vector was gotten
319: - X - Vec to restore
321: Output Arguments:
323: Level: developer
325: .seealso: DMGetNamedGlobalVector()
326: @*/
327: PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
328: {
330: DMNamedVecLink link;
337: for (link=dm->namedglobal; link; link=link->next) {
338: PetscBool match;
339: PetscStrcmp(name,link->name,&match);
340: if (match) {
341: if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
342: 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);
343: link->status = DMVEC_STATUS_IN;
344: *X = NULL;
345: return(0);
346: }
347: }
348: SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
349: return(0);
350: }
354: /*@C
355: DMGetNamedLocalVector - get access to a named, persistent local vector
357: Not Collective
359: Input Arguments:
360: + dm - DM to hold named vectors
361: - name - unique name for Vec
363: Output Arguments:
364: . X - named Vec
366: Level: developer
368: Note: If a Vec with the given name does not exist, it is created.
370: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
371: @*/
372: PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
373: {
375: DMNamedVecLink link;
381: for (link=dm->namedlocal; link; link=link->next) {
382: PetscBool match;
383: PetscStrcmp(name,link->name,&match);
384: if (match) {
385: if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
386: goto found;
387: }
388: }
390: /* Create the Vec */
391: PetscNew(&link);
392: PetscStrallocpy(name,&link->name);
393: DMCreateLocalVector(dm,&link->X);
394: link->next = dm->namedlocal;
395: dm->namedlocal = link;
397: found:
398: *X = link->X;
399: link->status = DMVEC_STATUS_OUT;
400: return(0);
401: }
405: /*@C
406: DMRestoreNamedLocalVector - restore access to a named, persistent local vector
408: Not Collective
410: Input Arguments:
411: + dm - DM on which the vector was gotten
412: . name - name under which the vector was gotten
413: - X - Vec to restore
415: Output Arguments:
417: Level: developer
419: .seealso: DMRestoreNamedGlobalVector(),DMGetNamedLocalVector()
420: @*/
421: PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
422: {
424: DMNamedVecLink link;
431: for (link=dm->namedlocal; link; link=link->next) {
432: PetscBool match;
433: PetscStrcmp(name,link->name,&match);
434: if (match) {
435: if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
436: 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);
437: link->status = DMVEC_STATUS_IN;
438: *X = NULL;
439: return(0);
440: }
441: }
442: SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
443: return(0);
444: }