Actual source code: dmget.c
petsc-3.12.5 2020-03-29
1: #include <petsc/private/dmimpl.h>
3: /*@
4: DMGetLocalVector - Gets a Seq PETSc vector that
5: may be used with the DMXXX routines. This vector has spaces for the ghost values.
7: Not Collective
9: Input Parameter:
10: . dm - the distributed array
12: Output Parameter:
13: . g - the local vector
15: Level: beginner
17: Note:
18: The vector values are NOT initialized and may have garbage in them, so you may need
19: to zero them.
21: The output parameter, g, is a regular PETSc vector that should be returned with
22: DMRestoreLocalVector() DO NOT call VecDestroy() on it.
24: This is intended to be used for vectors you need for a short time, like within a single function call.
25: For vectors that you intend to keep around (for example in a C struct) or pass around large parts of your
26: code you should use DMCreateLocalVector().
28: VecStride*() operations can be useful when using DM with dof > 1
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: }
61: /*@
62: DMRestoreLocalVector - Returns a Seq PETSc vector that
63: obtained from DMGetLocalVector(). Do not use with vector obtained via
64: DMCreateLocalVector().
66: Not Collective
68: Input Parameter:
69: + dm - the distributed array
70: - g - the local vector
72: Level: beginner
74: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
75: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
76: DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMGetLocalVector()
77: @*/
78: PetscErrorCode DMRestoreLocalVector(DM dm,Vec *g)
79: {
81: PetscInt i,j;
86: for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
87: if (*g == dm->localout[j]) {
88: dm->localout[j] = NULL;
89: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
90: if (!dm->localin[i]) {
91: dm->localin[i] = *g;
92: goto alldone;
93: }
94: }
95: }
96: }
97: VecDestroy(g);
98: alldone:
99: *g = NULL;
100: return(0);
101: }
103: /*@
104: DMGetGlobalVector - Gets a MPI PETSc vector that
105: may be used with the DMXXX routines.
107: Collective on dm
109: Input Parameter:
110: . dm - the distributed array
112: Output Parameter:
113: . g - the global vector
115: Level: beginner
117: Note:
118: The vector values are NOT initialized and may have garbage in them, so you may need
119: to zero them.
121: The output parameter, g, is a regular PETSc vector that should be returned with
122: DMRestoreGlobalVector() DO NOT call VecDestroy() on it.
124: This is intended to be used for vectors you need for a short time, like within a single function call.
125: For vectors that you intend to keep around (for example in a C struct) or pass around large parts of your
126: code you should use DMCreateGlobalVector().
128: VecStride*() operations can be useful when using DM with dof > 1
130: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
131: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
132: DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
133: VecStrideMax(), VecStrideMin(), VecStrideNorm()
135: @*/
136: PetscErrorCode DMGetGlobalVector(DM dm,Vec *g)
137: {
139: PetscInt i;
144: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
145: if (dm->globalin[i]) {
146: *g = dm->globalin[i];
147: dm->globalin[i] = NULL;
148: goto alldone;
149: }
150: }
151: DMCreateGlobalVector(dm,g);
153: alldone:
154: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
155: if (!dm->globalout[i]) {
156: dm->globalout[i] = *g;
157: break;
158: }
159: }
160: return(0);
161: }
163: /*@
164: DMClearGlobalVectors - Destroys all the global vectors that have been stashed in this DM
166: Collective on dm
168: Input Parameter:
169: . dm - the distributed array
171: Level: developer
173: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
174: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
175: DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
176: VecStrideMax(), VecStrideMin(), VecStrideNorm()
178: @*/
179: PetscErrorCode DMClearGlobalVectors(DM dm)
180: {
182: PetscInt i;
186: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
187: Vec g;
188: 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()");
189: g = dm->globalin[i];
190: dm->globalin[i] = NULL;
191: VecDestroy(&g);
192: }
193: return(0);
194: }
196: /*@
197: DMClearLocalVectors - Destroys all the local vectors that have been stashed in this DM
199: Collective on dm
201: Input Parameter:
202: . dm - the distributed array
204: Level: developer
206: .seealso: DMCreateLocalVector(), VecDuplicate(), VecDuplicateVecs(),
207: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMLocalToLocalBegin(),
208: DMLocalToLocalEnd(), DMLocalToLocalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
209: VecStrideMax(), VecStrideMin(), VecStrideNorm()
211: @*/
212: PetscErrorCode DMClearLocalVectors(DM dm)
213: {
215: PetscInt i;
219: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
220: Vec g;
221: if (dm->localout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Clearing DM of local vectors that has a local vector obtained with DMGetLocalVector()");
222: g = dm->localin[i];
223: dm->localin[i] = NULL;
224: VecDestroy(&g);
225: }
226: return(0);
227: }
229: /*@
230: DMRestoreGlobalVector - Returns a Seq PETSc vector that
231: obtained from DMGetGlobalVector(). Do not use with vector obtained via
232: DMCreateGlobalVector().
234: Not Collective
236: Input Parameter:
237: + dm - the distributed array
238: - g - the global vector
240: Level: beginner
242: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
243: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(),
244: DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
245: @*/
246: PetscErrorCode DMRestoreGlobalVector(DM dm,Vec *g)
247: {
249: PetscInt i,j;
254: VecSetErrorIfLocked(*g, 2);
255: for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
256: if (*g == dm->globalout[j]) {
257: dm->globalout[j] = NULL;
258: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
259: if (!dm->globalin[i]) {
260: dm->globalin[i] = *g;
261: goto alldone;
262: }
263: }
264: }
265: }
266: VecDestroy(g);
267: alldone:
268: *g = NULL;
269: return(0);
270: }
272: /*@C
273: DMHasNamedGlobalVector - check for a named, persistent global vector
275: Not Collective
277: Input Arguments:
278: + dm - DM to hold named vectors
279: - name - unique name for Vec
281: Output Arguments:
282: . exists - true if the vector was previously created
284: Level: developer
286: Note: If a Vec with the given name does not exist, it is created.
288: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
289: @*/
290: PetscErrorCode DMHasNamedGlobalVector(DM dm,const char *name,PetscBool *exists)
291: {
293: DMNamedVecLink link;
299: *exists = PETSC_FALSE;
300: for (link=dm->namedglobal; link; link=link->next) {
301: PetscBool match;
302: PetscStrcmp(name,link->name,&match);
303: if (match) {
304: *exists = PETSC_TRUE;
305: break;
306: }
307: }
308: return(0);
309: }
311: /*@C
312: DMGetNamedGlobalVector - get access to a named, persistent global vector
314: Collective on dm
316: Input Arguments:
317: + dm - DM to hold named vectors
318: - name - unique name for Vec
320: Output Arguments:
321: . X - named Vec
323: Level: developer
325: Note: If a Vec with the given name does not exist, it is created.
327: .seealso: DMRestoreNamedGlobalVector()
328: @*/
329: PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
330: {
332: DMNamedVecLink link;
338: for (link=dm->namedglobal; link; link=link->next) {
339: PetscBool match;
340: PetscStrcmp(name,link->name,&match);
341: if (match) {
342: if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
343: goto found;
344: }
345: }
347: /* Create the Vec */
348: PetscNew(&link);
349: PetscStrallocpy(name,&link->name);
350: DMCreateGlobalVector(dm,&link->X);
351: link->next = dm->namedglobal;
352: dm->namedglobal = link;
354: found:
355: *X = link->X;
356: link->status = DMVEC_STATUS_OUT;
357: return(0);
358: }
360: /*@C
361: DMRestoreNamedGlobalVector - restore access to a named, persistent global vector
363: Collective on dm
365: Input Arguments:
366: + dm - DM on which the vector was gotten
367: . name - name under which the vector was gotten
368: - X - Vec to restore
370: Output Arguments:
372: Level: developer
374: .seealso: DMGetNamedGlobalVector()
375: @*/
376: PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
377: {
379: DMNamedVecLink link;
386: for (link=dm->namedglobal; link; link=link->next) {
387: PetscBool match;
388: PetscStrcmp(name,link->name,&match);
389: if (match) {
390: if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
391: 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);
392: link->status = DMVEC_STATUS_IN;
393: *X = NULL;
394: return(0);
395: }
396: }
397: SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
398: return(0);
399: }
401: /*@C
402: DMHasNamedLocalVector - check for a named, persistent local vector
404: Not Collective
406: Input Arguments:
407: + dm - DM to hold named vectors
408: - name - unique name for Vec
410: Output Arguments:
411: . exists - true if the vector was previously created
413: Level: developer
415: Note: If a Vec with the given name does not exist, it is created.
417: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
418: @*/
419: PetscErrorCode DMHasNamedLocalVector(DM dm,const char *name,PetscBool *exists)
420: {
422: DMNamedVecLink link;
428: *exists = PETSC_FALSE;
429: for (link=dm->namedlocal; link; link=link->next) {
430: PetscBool match;
431: PetscStrcmp(name,link->name,&match);
432: if (match) {
433: *exists = PETSC_TRUE;
434: break;
435: }
436: }
437: return(0);
438: }
440: /*@C
441: DMGetNamedLocalVector - get access to a named, persistent local vector
443: Not Collective
445: Input Arguments:
446: + dm - DM to hold named vectors
447: - name - unique name for Vec
449: Output Arguments:
450: . X - named Vec
452: Level: developer
454: Note: If a Vec with the given name does not exist, it is created.
456: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
457: @*/
458: PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
459: {
461: DMNamedVecLink link;
467: for (link=dm->namedlocal; link; link=link->next) {
468: PetscBool match;
469: PetscStrcmp(name,link->name,&match);
470: if (match) {
471: if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
472: goto found;
473: }
474: }
476: /* Create the Vec */
477: PetscNew(&link);
478: PetscStrallocpy(name,&link->name);
479: DMCreateLocalVector(dm,&link->X);
480: link->next = dm->namedlocal;
481: dm->namedlocal = link;
483: found:
484: *X = link->X;
485: link->status = DMVEC_STATUS_OUT;
486: return(0);
487: }
489: /*@C
490: DMRestoreNamedLocalVector - restore access to a named, persistent local vector
492: Not Collective
494: Input Arguments:
495: + dm - DM on which the vector was gotten
496: . name - name under which the vector was gotten
497: - X - Vec to restore
499: Output Arguments:
501: Level: developer
503: .seealso: DMRestoreNamedGlobalVector(),DMGetNamedLocalVector()
504: @*/
505: PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
506: {
508: DMNamedVecLink link;
515: for (link=dm->namedlocal; link; link=link->next) {
516: PetscBool match;
517: PetscStrcmp(name,link->name,&match);
518: if (match) {
519: if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
520: 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);
521: link->status = DMVEC_STATUS_IN;
522: *X = NULL;
523: return(0);
524: }
525: }
526: SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
527: return(0);
528: }