Actual source code: dmget.c
petsc-3.14.6 2021-03-30
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: }
444: /*@C
445: DMHasNamedLocalVector - check for a named, persistent local vector
447: Not Collective
449: Input Arguments:
450: + dm - DM to hold named vectors
451: - name - unique name for Vec
453: Output Arguments:
454: . exists - true if the vector was previously created
456: Level: developer
458: Note: If a Vec with the given name does not exist, it is created.
460: .seealso: DMGetNamedGlobalVector(), DMRestoreNamedLocalVector()
461: @*/
462: PetscErrorCode DMHasNamedLocalVector(DM dm,const char *name,PetscBool *exists)
463: {
465: DMNamedVecLink link;
471: *exists = PETSC_FALSE;
472: for (link=dm->namedlocal; link; link=link->next) {
473: PetscBool match;
474: PetscStrcmp(name,link->name,&match);
475: if (match) {
476: *exists = PETSC_TRUE;
477: break;
478: }
479: }
480: return(0);
481: }
483: /*@C
484: DMGetNamedLocalVector - get access to a named, persistent local vector
486: Not Collective
488: Input Arguments:
489: + dm - DM to hold named vectors
490: - name - unique name for Vec
492: Output Arguments:
493: . X - named Vec
495: Level: developer
497: Note: If a Vec with the given name does not exist, it is created.
499: .seealso: DMGetNamedGlobalVector(), DMRestoreNamedLocalVector()
500: @*/
501: PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
502: {
504: DMNamedVecLink link;
510: for (link=dm->namedlocal; link; link=link->next) {
511: PetscBool match;
513: PetscStrcmp(name,link->name,&match);
514: if (match) {
515: DM vdm;
517: if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
518: VecGetDM(link->X,&vdm);
519: if (vdm) SETERRQ(PetscObjectComm((PetscObject)vdm),PETSC_ERR_LIB,"Invalid vector");
520: VecSetDM(link->X,dm);
521: goto found;
522: }
523: }
525: /* Create the Vec */
526: PetscNew(&link);
527: PetscStrallocpy(name,&link->name);
528: DMCreateLocalVector(dm,&link->X);
529: link->next = dm->namedlocal;
530: dm->namedlocal = link;
532: found:
533: *X = link->X;
534: link->status = DMVEC_STATUS_OUT;
535: return(0);
536: }
538: /*@C
539: DMRestoreNamedLocalVector - restore access to a named, persistent local vector
541: Not Collective
543: Input Arguments:
544: + dm - DM on which the vector was gotten
545: . name - name under which the vector was gotten
546: - X - Vec to restore
548: Output Arguments:
550: Level: developer
552: .seealso: DMRestoreNamedGlobalVector(), DMGetNamedLocalVector()
553: @*/
554: PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
555: {
557: DMNamedVecLink link;
564: for (link=dm->namedlocal; link; link=link->next) {
565: PetscBool match;
567: PetscStrcmp(name,link->name,&match);
568: if (match) {
569: DM vdm;
571: VecGetDM(*X,&vdm);
572: if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
573: 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);
574: if (vdm != dm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Invalid vector");
576: link->status = DMVEC_STATUS_IN;
577: VecSetDM(link->X,NULL);
578: *X = NULL;
579: return(0);
580: }
581: }
582: SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
583: }