Actual source code: dmget.c
1: #include <petsc/private/dmimpl.h>
3: /*@
4: DMGetLocalVector - Gets a PETSc vector that may be used with the DM local routines. This vector has spaces for the ghost values.
6: Not Collective
8: Input Parameter:
9: . dm - the dm
11: Output Parameter:
12: . g - the local vector
14: Level: beginner
16: Note:
17: The vector values are NOT initialized and may have garbage in them, so you may need
18: to zero them.
20: The output parameter, g, is a regular PETSc vector that should be returned with
21: DMRestoreLocalVector() DO NOT call VecDestroy() on it.
23: This is intended to be used for vectors you need for a short time, like within a single function call.
24: For vectors that you intend to keep around (for example in a C struct) or pass around large parts of your
25: code you should use DMCreateLocalVector().
27: VecStride*() operations can be useful when using DM with dof > 1
29: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
30: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
31: DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector(),
32: VecStrideMax(), VecStrideMin(), VecStrideNorm()
33: @*/
34: PetscErrorCode DMGetLocalVector(DM dm,Vec *g)
35: {
36: PetscErrorCode ierr,i;
41: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
42: if (dm->localin[i]) {
43: DM vdm;
45: *g = dm->localin[i];
46: dm->localin[i] = NULL;
48: VecGetDM(*g,&vdm);
49: if (vdm) SETERRQ(PetscObjectComm((PetscObject)vdm),PETSC_ERR_LIB,"Invalid vector");
50: VecSetDM(*g,dm);
51: goto alldone;
52: }
53: }
54: DMCreateLocalVector(dm,g);
56: alldone:
57: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
58: if (!dm->localout[i]) {
59: dm->localout[i] = *g;
60: break;
61: }
62: }
63: return(0);
64: }
66: /*@
67: DMRestoreLocalVector - Returns a PETSc vector that was
68: obtained from DMGetLocalVector(). Do not use with vector obtained via
69: DMCreateLocalVector().
71: Not Collective
73: Input Parameters:
74: + dm - the dm
75: - g - the local vector
77: Level: beginner
79: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
80: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
81: DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMGetLocalVector()
82: @*/
83: PetscErrorCode DMRestoreLocalVector(DM dm,Vec *g)
84: {
86: PetscInt i,j;
91: for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
92: if (*g == dm->localout[j]) {
93: DM vdm;
95: VecGetDM(*g,&vdm);
96: if (vdm != dm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Invalid vector");
97: VecSetDM(*g,NULL);
98: dm->localout[j] = NULL;
99: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
100: if (!dm->localin[i]) {
101: dm->localin[i] = *g;
102: goto alldone;
103: }
104: }
105: }
106: }
107: VecDestroy(g);
108: alldone:
109: *g = NULL;
110: return(0);
111: }
113: /*@
114: DMGetGlobalVector - Gets a PETSc vector that may be used with the DM global routines.
116: Collective on dm
118: Input Parameter:
119: . dm - the dm
121: Output Parameter:
122: . g - the global vector
124: Level: beginner
126: Note:
127: The vector values are NOT initialized and may have garbage in them, so you may need
128: to zero them.
130: The output parameter, g, is a regular PETSc vector that should be returned with
131: DMRestoreGlobalVector() DO NOT call VecDestroy() on it.
133: This is intended to be used for vectors you need for a short time, like within a single function call.
134: For vectors that you intend to keep around (for example in a C struct) or pass around large parts of your
135: code you should use DMCreateGlobalVector().
137: VecStride*() operations can be useful when using DM with dof > 1
139: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
140: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
141: DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
142: VecStrideMax(), VecStrideMin(), VecStrideNorm()
143: @*/
144: PetscErrorCode DMGetGlobalVector(DM dm,Vec *g)
145: {
147: PetscInt i;
152: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
153: if (dm->globalin[i]) {
154: DM vdm;
156: *g = dm->globalin[i];
157: dm->globalin[i] = NULL;
159: VecGetDM(*g,&vdm);
160: if (vdm) SETERRQ(PetscObjectComm((PetscObject)vdm),PETSC_ERR_LIB,"Invalid vector");
161: VecSetDM(*g,dm);
162: goto alldone;
163: }
164: }
165: DMCreateGlobalVector(dm,g);
167: alldone:
168: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
169: if (!dm->globalout[i]) {
170: dm->globalout[i] = *g;
171: break;
172: }
173: }
174: return(0);
175: }
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 dm
185: Level: developer
187: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
188: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
189: DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
190: VecStrideMax(), VecStrideMin(), VecStrideNorm()
191: @*/
192: PetscErrorCode DMClearGlobalVectors(DM dm)
193: {
195: PetscInt i;
199: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
200: Vec g;
202: if (dm->globalout[i]) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Clearing DM of global vectors that has a global vector obtained with DMGetGlobalVector()");
203: g = dm->globalin[i];
204: dm->globalin[i] = NULL;
205: if (g) {
206: DM vdm;
208: VecGetDM(g,&vdm);
209: if (vdm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Clearing global vector that has a DM attached");
210: }
211: VecDestroy(&g);
212: }
213: return(0);
214: }
216: /*@
217: DMClearLocalVectors - Destroys all the local vectors that have been stashed in this DM
219: Collective on dm
221: Input Parameter:
222: . dm - the dm
224: Level: developer
226: .seealso: DMCreateLocalVector(), VecDuplicate(), VecDuplicateVecs(),
227: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMLocalToLocalBegin(),
228: DMLocalToLocalEnd(), DMLocalToLocalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
229: VecStrideMax(), VecStrideMin(), VecStrideNorm()
230: @*/
231: PetscErrorCode DMClearLocalVectors(DM dm)
232: {
234: PetscInt i;
238: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
239: Vec g;
241: if (dm->localout[i]) SETERRQ(PetscObjectComm((PetscObject)dm),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: if (g) {
245: DM vdm;
247: VecGetDM(g,&vdm);
248: if (vdm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Clearing local vector that has a DM attached");
249: }
250: VecDestroy(&g);
251: }
252: return(0);
253: }
255: /*@
256: DMRestoreGlobalVector - Returns a PETSc vector that
257: obtained from DMGetGlobalVector(). Do not use with vector obtained via
258: DMCreateGlobalVector().
260: Not Collective
262: Input Parameters:
263: + dm - the dm
264: - g - the global vector
266: Level: beginner
268: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
269: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(),
270: DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
271: @*/
272: PetscErrorCode DMRestoreGlobalVector(DM dm,Vec *g)
273: {
275: PetscInt i,j;
280: VecSetErrorIfLocked(*g, 2);
281: for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
282: if (*g == dm->globalout[j]) {
283: DM vdm;
285: VecGetDM(*g,&vdm);
286: if (vdm != dm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Invalid vector");
287: VecSetDM(*g,NULL);
288: dm->globalout[j] = NULL;
289: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
290: if (!dm->globalin[i]) {
291: dm->globalin[i] = *g;
292: goto alldone;
293: }
294: }
295: }
296: }
297: VecDestroy(g);
298: alldone:
299: *g = NULL;
300: return(0);
301: }
303: /*@C
304: DMHasNamedGlobalVector - check for a named, persistent global vector
306: Not Collective
308: Input Parameters:
309: + dm - DM to hold named vectors
310: - name - unique name for Vec
312: Output Parameter:
313: . exists - true if the vector was previously created
315: Level: developer
317: Note: If a Vec with the given name does not exist, it is created.
319: .seealso: DMGetNamedGlobalVector(), DMRestoreNamedLocalVector()
320: @*/
321: PetscErrorCode DMHasNamedGlobalVector(DM dm,const char *name,PetscBool *exists)
322: {
324: DMNamedVecLink link;
330: *exists = PETSC_FALSE;
331: for (link=dm->namedglobal; link; link=link->next) {
332: PetscBool match;
333: PetscStrcmp(name,link->name,&match);
334: if (match) {
335: *exists = PETSC_TRUE;
336: break;
337: }
338: }
339: return(0);
340: }
342: /*@C
343: DMGetNamedGlobalVector - get access to a named, persistent global vector
345: Collective on dm
347: Input Parameters:
348: + dm - DM to hold named vectors
349: - name - unique name for Vec
351: Output Parameter:
352: . X - named Vec
354: Level: developer
356: Note: If a Vec with the given name does not exist, it is created.
358: .seealso: DMRestoreNamedGlobalVector()
359: @*/
360: PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
361: {
363: DMNamedVecLink link;
369: for (link=dm->namedglobal; link; link=link->next) {
370: PetscBool match;
372: PetscStrcmp(name,link->name,&match);
373: if (match) {
374: DM vdm;
376: if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
377: VecGetDM(link->X,&vdm);
378: if (vdm) SETERRQ(PetscObjectComm((PetscObject)vdm),PETSC_ERR_LIB,"Invalid vector");
379: VecSetDM(link->X,dm);
380: goto found;
381: }
382: }
384: /* Create the Vec */
385: PetscNew(&link);
386: PetscStrallocpy(name,&link->name);
387: DMCreateGlobalVector(dm,&link->X);
388: link->next = dm->namedglobal;
389: dm->namedglobal = link;
391: found:
392: *X = link->X;
393: link->status = DMVEC_STATUS_OUT;
394: return(0);
395: }
397: /*@C
398: DMRestoreNamedGlobalVector - restore access to a named, persistent global vector
400: Collective on dm
402: Input Parameters:
403: + dm - DM on which the vector was gotten
404: . name - name under which the vector was gotten
405: - X - Vec to restore
407: Level: developer
409: .seealso: DMGetNamedGlobalVector()
410: @*/
411: PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
412: {
414: DMNamedVecLink link;
421: for (link=dm->namedglobal; link; link=link->next) {
422: PetscBool match;
424: PetscStrcmp(name,link->name,&match);
425: if (match) {
426: DM vdm;
428: VecGetDM(*X,&vdm);
429: if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
430: 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);
431: if (vdm != dm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Invalid vector");
433: link->status = DMVEC_STATUS_IN;
434: VecSetDM(link->X,NULL);
435: *X = NULL;
436: return(0);
437: }
438: }
439: SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
440: }
442: /*@C
443: DMHasNamedLocalVector - check for a named, persistent local vector
445: Not Collective
447: Input Parameters:
448: + dm - DM to hold named vectors
449: - name - unique name for Vec
451: Output Parameter:
452: . exists - true if the vector was previously created
454: Level: developer
456: Note: If a Vec with the given name does not exist, it is created.
458: .seealso: DMGetNamedGlobalVector(), DMRestoreNamedLocalVector()
459: @*/
460: PetscErrorCode DMHasNamedLocalVector(DM dm,const char *name,PetscBool *exists)
461: {
463: DMNamedVecLink link;
469: *exists = PETSC_FALSE;
470: for (link=dm->namedlocal; link; link=link->next) {
471: PetscBool match;
472: PetscStrcmp(name,link->name,&match);
473: if (match) {
474: *exists = PETSC_TRUE;
475: break;
476: }
477: }
478: return(0);
479: }
481: /*@C
482: DMGetNamedLocalVector - get access to a named, persistent local vector
484: Not Collective
486: Input Parameters:
487: + dm - DM to hold named vectors
488: - name - unique name for Vec
490: Output Parameter:
491: . X - named Vec
493: Level: developer
495: Note: If a Vec with the given name does not exist, it is created.
497: .seealso: DMGetNamedGlobalVector(), DMRestoreNamedLocalVector()
498: @*/
499: PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
500: {
502: DMNamedVecLink link;
508: for (link=dm->namedlocal; link; link=link->next) {
509: PetscBool match;
511: PetscStrcmp(name,link->name,&match);
512: if (match) {
513: DM vdm;
515: if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
516: VecGetDM(link->X,&vdm);
517: if (vdm) SETERRQ(PetscObjectComm((PetscObject)vdm),PETSC_ERR_LIB,"Invalid vector");
518: VecSetDM(link->X,dm);
519: goto found;
520: }
521: }
523: /* Create the Vec */
524: PetscNew(&link);
525: PetscStrallocpy(name,&link->name);
526: DMCreateLocalVector(dm,&link->X);
527: link->next = dm->namedlocal;
528: dm->namedlocal = link;
530: found:
531: *X = link->X;
532: link->status = DMVEC_STATUS_OUT;
533: return(0);
534: }
536: /*@C
537: DMRestoreNamedLocalVector - restore access to a named, persistent local vector
539: Not Collective
541: Input Parameters:
542: + dm - DM on which the vector was gotten
543: . name - name under which the vector was gotten
544: - X - Vec to restore
546: Level: developer
548: .seealso: DMRestoreNamedGlobalVector(), DMGetNamedLocalVector()
549: @*/
550: PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
551: {
553: DMNamedVecLink link;
560: for (link=dm->namedlocal; link; link=link->next) {
561: PetscBool match;
563: PetscStrcmp(name,link->name,&match);
564: if (match) {
565: DM vdm;
567: VecGetDM(*X,&vdm);
568: if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
569: 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);
570: if (vdm != dm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Invalid vector");
572: link->status = DMVEC_STATUS_IN;
573: VecSetDM(link->X,NULL);
574: *X = NULL;
575: return(0);
576: }
577: }
578: SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
579: }