Actual source code: dmget.c
petsc-3.13.6 2020-09-29
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 Parameter:
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 Parameter:
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 Arguments:
309: + dm - DM to hold named vectors
310: - name - unique name for Vec
312: Output Arguments:
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 Arguments:
348: + dm - DM to hold named vectors
349: - name - unique name for Vec
351: Output Arguments:
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 Arguments:
403: + dm - DM on which the vector was gotten
404: . name - name under which the vector was gotten
405: - X - Vec to restore
407: Output Arguments:
409: Level: developer
411: .seealso: DMGetNamedGlobalVector()
412: @*/
413: PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
414: {
416: DMNamedVecLink link;
423: for (link=dm->namedglobal; link; link=link->next) {
424: PetscBool match;
426: PetscStrcmp(name,link->name,&match);
427: if (match) {
428: DM vdm;
430: VecGetDM(*X,&vdm);
431: if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
432: 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);
433: if (vdm != dm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Invalid vector");
435: link->status = DMVEC_STATUS_IN;
436: VecSetDM(link->X,NULL);
437: *X = NULL;
438: return(0);
439: }
440: }
441: SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
442: return(0);
443: }
445: /*@C
446: DMHasNamedLocalVector - check for a named, persistent local vector
448: Not Collective
450: Input Arguments:
451: + dm - DM to hold named vectors
452: - name - unique name for Vec
454: Output Arguments:
455: . exists - true if the vector was previously created
457: Level: developer
459: Note: If a Vec with the given name does not exist, it is created.
461: .seealso: DMGetNamedGlobalVector(), DMRestoreNamedLocalVector()
462: @*/
463: PetscErrorCode DMHasNamedLocalVector(DM dm,const char *name,PetscBool *exists)
464: {
466: DMNamedVecLink link;
472: *exists = PETSC_FALSE;
473: for (link=dm->namedlocal; link; link=link->next) {
474: PetscBool match;
475: PetscStrcmp(name,link->name,&match);
476: if (match) {
477: *exists = PETSC_TRUE;
478: break;
479: }
480: }
481: return(0);
482: }
484: /*@C
485: DMGetNamedLocalVector - get access to a named, persistent local vector
487: Not Collective
489: Input Arguments:
490: + dm - DM to hold named vectors
491: - name - unique name for Vec
493: Output Arguments:
494: . X - named Vec
496: Level: developer
498: Note: If a Vec with the given name does not exist, it is created.
500: .seealso: DMGetNamedGlobalVector(), DMRestoreNamedLocalVector()
501: @*/
502: PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
503: {
505: DMNamedVecLink link;
511: for (link=dm->namedlocal; link; link=link->next) {
512: PetscBool match;
514: PetscStrcmp(name,link->name,&match);
515: if (match) {
516: DM vdm;
518: if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
519: VecGetDM(link->X,&vdm);
520: if (vdm) SETERRQ(PetscObjectComm((PetscObject)vdm),PETSC_ERR_LIB,"Invalid vector");
521: VecSetDM(link->X,dm);
522: goto found;
523: }
524: }
526: /* Create the Vec */
527: PetscNew(&link);
528: PetscStrallocpy(name,&link->name);
529: DMCreateLocalVector(dm,&link->X);
530: link->next = dm->namedlocal;
531: dm->namedlocal = link;
533: found:
534: *X = link->X;
535: link->status = DMVEC_STATUS_OUT;
536: return(0);
537: }
539: /*@C
540: DMRestoreNamedLocalVector - restore access to a named, persistent local vector
542: Not Collective
544: Input Arguments:
545: + dm - DM on which the vector was gotten
546: . name - name under which the vector was gotten
547: - X - Vec to restore
549: Output Arguments:
551: Level: developer
553: .seealso: DMRestoreNamedGlobalVector(), DMGetNamedLocalVector()
554: @*/
555: PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
556: {
558: DMNamedVecLink link;
565: for (link=dm->namedlocal; link; link=link->next) {
566: PetscBool match;
568: PetscStrcmp(name,link->name,&match);
569: if (match) {
570: DM vdm;
572: VecGetDM(*X,&vdm);
573: if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
574: 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);
575: if (vdm != dm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Invalid vector");
577: link->status = DMVEC_STATUS_IN;
578: VecSetDM(link->X,NULL);
579: *X = NULL;
580: return(0);
581: }
582: }
583: SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
584: return(0);
585: }