Actual source code: dmget.c
petsc-3.11.4 2019-09-28
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: .keywords: distributed array, create, local, vector
32: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
33: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
34: DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector(),
35: VecStrideMax(), VecStrideMin(), VecStrideNorm()
36: @*/
37: PetscErrorCode DMGetLocalVector(DM dm,Vec *g)
38: {
39: PetscErrorCode ierr,i;
44: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
45: if (dm->localin[i]) {
46: *g = dm->localin[i];
47: dm->localin[i] = NULL;
48: goto alldone;
49: }
50: }
51: DMCreateLocalVector(dm,g);
53: alldone:
54: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
55: if (!dm->localout[i]) {
56: dm->localout[i] = *g;
57: break;
58: }
59: }
60: return(0);
61: }
63: /*@
64: DMRestoreLocalVector - Returns a Seq PETSc vector that
65: obtained from DMGetLocalVector(). Do not use with vector obtained via
66: DMCreateLocalVector().
68: Not Collective
70: Input Parameter:
71: + dm - the distributed array
72: - g - the local vector
74: Level: beginner
76: .keywords: distributed array, create, local, vector
78: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
79: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
80: DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMGetLocalVector()
81: @*/
82: PetscErrorCode DMRestoreLocalVector(DM dm,Vec *g)
83: {
85: PetscInt i,j;
90: for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
91: if (*g == dm->localout[j]) {
92: dm->localout[j] = NULL;
93: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
94: if (!dm->localin[i]) {
95: dm->localin[i] = *g;
96: goto alldone;
97: }
98: }
99: }
100: }
101: VecDestroy(g);
102: alldone:
103: *g = NULL;
104: return(0);
105: }
107: /*@
108: DMGetGlobalVector - Gets a MPI PETSc vector that
109: may be used with the DMXXX routines.
111: Collective on DM
113: Input Parameter:
114: . dm - the distributed array
116: Output Parameter:
117: . g - the global vector
119: Level: beginner
121: Note:
122: The vector values are NOT initialized and may have garbage in them, so you may need
123: to zero them.
125: The output parameter, g, is a regular PETSc vector that should be returned with
126: DMRestoreGlobalVector() DO NOT call VecDestroy() on it.
128: This is intended to be used for vectors you need for a short time, like within a single function call.
129: For vectors that you intend to keep around (for example in a C struct) or pass around large parts of your
130: code you should use DMCreateGlobalVector().
132: VecStride*() operations can be useful when using DM with dof > 1
134: .keywords: distributed array, create, Global, vector
136: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
137: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
138: DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
139: VecStrideMax(), VecStrideMin(), VecStrideNorm()
141: @*/
142: PetscErrorCode DMGetGlobalVector(DM dm,Vec *g)
143: {
145: PetscInt i;
150: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
151: if (dm->globalin[i]) {
152: *g = dm->globalin[i];
153: dm->globalin[i] = NULL;
154: goto alldone;
155: }
156: }
157: DMCreateGlobalVector(dm,g);
159: alldone:
160: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
161: if (!dm->globalout[i]) {
162: dm->globalout[i] = *g;
163: break;
164: }
165: }
166: return(0);
167: }
169: /*@
170: DMClearGlobalVectors - Destroys all the global vectors that have been stashed in this DM
172: Collective on DM
174: Input Parameter:
175: . dm - the distributed array
177: Level: developer
179: .keywords: distributed array, create, Global, vector
181: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
182: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
183: DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
184: VecStrideMax(), VecStrideMin(), VecStrideNorm()
186: @*/
187: PetscErrorCode DMClearGlobalVectors(DM dm)
188: {
190: PetscInt i;
194: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
195: Vec g;
196: 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()");
197: g = dm->globalin[i];
198: dm->globalin[i] = NULL;
199: VecDestroy(&g);
200: }
201: return(0);
202: }
204: /*@
205: DMClearLocalVectors - Destroys all the local vectors that have been stashed in this DM
207: Collective on DM
209: Input Parameter:
210: . dm - the distributed array
212: Level: developer
214: .keywords: distributed array, create, Local, vector
216: .seealso: DMCreateLocalVector(), VecDuplicate(), VecDuplicateVecs(),
217: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMLocalToLocalBegin(),
218: DMLocalToLocalEnd(), DMLocalToLocalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
219: VecStrideMax(), VecStrideMin(), VecStrideNorm()
221: @*/
222: PetscErrorCode DMClearLocalVectors(DM dm)
223: {
225: PetscInt i;
229: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
230: Vec g;
231: 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()");
232: g = dm->localin[i];
233: dm->localin[i] = NULL;
234: VecDestroy(&g);
235: }
236: return(0);
237: }
239: /*@
240: DMRestoreGlobalVector - Returns a Seq PETSc vector that
241: obtained from DMGetGlobalVector(). Do not use with vector obtained via
242: DMCreateGlobalVector().
244: Not Collective
246: Input Parameter:
247: + dm - the distributed array
248: - g - the global vector
250: Level: beginner
252: .keywords: distributed array, create, global, vector
254: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
255: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(),
256: DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
257: @*/
258: PetscErrorCode DMRestoreGlobalVector(DM dm,Vec *g)
259: {
261: PetscInt i,j;
266: VecSetErrorIfLocked(*g, 2);
267: for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
268: if (*g == dm->globalout[j]) {
269: dm->globalout[j] = NULL;
270: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
271: if (!dm->globalin[i]) {
272: dm->globalin[i] = *g;
273: goto alldone;
274: }
275: }
276: }
277: }
278: VecDestroy(g);
279: alldone:
280: *g = NULL;
281: return(0);
282: }
284: /*@C
285: DMHasNamedGlobalVector - check for a named, persistent global vector
287: Not Collective
289: Input Arguments:
290: + dm - DM to hold named vectors
291: - name - unique name for Vec
293: Output Arguments:
294: . exists - true if the vector was previously created
296: Level: developer
298: Note: If a Vec with the given name does not exist, it is created.
300: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
301: @*/
302: PetscErrorCode DMHasNamedGlobalVector(DM dm,const char *name,PetscBool *exists)
303: {
305: DMNamedVecLink link;
311: *exists = PETSC_FALSE;
312: for (link=dm->namedglobal; link; link=link->next) {
313: PetscBool match;
314: PetscStrcmp(name,link->name,&match);
315: if (match) {
316: *exists = PETSC_TRUE;
317: break;
318: }
319: }
320: return(0);
321: }
323: /*@C
324: DMGetNamedGlobalVector - get access to a named, persistent global vector
326: Collective on DM
328: Input Arguments:
329: + dm - DM to hold named vectors
330: - name - unique name for Vec
332: Output Arguments:
333: . X - named Vec
335: Level: developer
337: Note: If a Vec with the given name does not exist, it is created.
339: .seealso: DMRestoreNamedGlobalVector()
340: @*/
341: PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
342: {
344: DMNamedVecLink link;
350: for (link=dm->namedglobal; link; link=link->next) {
351: PetscBool match;
352: PetscStrcmp(name,link->name,&match);
353: if (match) {
354: if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
355: goto found;
356: }
357: }
359: /* Create the Vec */
360: PetscNew(&link);
361: PetscStrallocpy(name,&link->name);
362: DMCreateGlobalVector(dm,&link->X);
363: link->next = dm->namedglobal;
364: dm->namedglobal = link;
366: found:
367: *X = link->X;
368: link->status = DMVEC_STATUS_OUT;
369: return(0);
370: }
372: /*@C
373: DMRestoreNamedGlobalVector - restore access to a named, persistent global vector
375: Collective on DM
377: Input Arguments:
378: + dm - DM on which the vector was gotten
379: . name - name under which the vector was gotten
380: - X - Vec to restore
382: Output Arguments:
384: Level: developer
386: .seealso: DMGetNamedGlobalVector()
387: @*/
388: PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
389: {
391: DMNamedVecLink link;
398: for (link=dm->namedglobal; link; link=link->next) {
399: PetscBool match;
400: PetscStrcmp(name,link->name,&match);
401: if (match) {
402: if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
403: 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);
404: link->status = DMVEC_STATUS_IN;
405: *X = NULL;
406: return(0);
407: }
408: }
409: SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
410: return(0);
411: }
413: /*@C
414: DMHasNamedLocalVector - check for a named, persistent local vector
416: Not Collective
418: Input Arguments:
419: + dm - DM to hold named vectors
420: - name - unique name for Vec
422: Output Arguments:
423: . exists - true if the vector was previously created
425: Level: developer
427: Note: If a Vec with the given name does not exist, it is created.
429: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
430: @*/
431: PetscErrorCode DMHasNamedLocalVector(DM dm,const char *name,PetscBool *exists)
432: {
434: DMNamedVecLink link;
440: *exists = PETSC_FALSE;
441: for (link=dm->namedlocal; link; link=link->next) {
442: PetscBool match;
443: PetscStrcmp(name,link->name,&match);
444: if (match) {
445: *exists = PETSC_TRUE;
446: break;
447: }
448: }
449: return(0);
450: }
452: /*@C
453: DMGetNamedLocalVector - get access to a named, persistent local vector
455: Not Collective
457: Input Arguments:
458: + dm - DM to hold named vectors
459: - name - unique name for Vec
461: Output Arguments:
462: . X - named Vec
464: Level: developer
466: Note: If a Vec with the given name does not exist, it is created.
468: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
469: @*/
470: PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
471: {
473: DMNamedVecLink link;
479: for (link=dm->namedlocal; link; link=link->next) {
480: PetscBool match;
481: PetscStrcmp(name,link->name,&match);
482: if (match) {
483: if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
484: goto found;
485: }
486: }
488: /* Create the Vec */
489: PetscNew(&link);
490: PetscStrallocpy(name,&link->name);
491: DMCreateLocalVector(dm,&link->X);
492: link->next = dm->namedlocal;
493: dm->namedlocal = link;
495: found:
496: *X = link->X;
497: link->status = DMVEC_STATUS_OUT;
498: return(0);
499: }
501: /*@C
502: DMRestoreNamedLocalVector - restore access to a named, persistent local vector
504: Not Collective
506: Input Arguments:
507: + dm - DM on which the vector was gotten
508: . name - name under which the vector was gotten
509: - X - Vec to restore
511: Output Arguments:
513: Level: developer
515: .seealso: DMRestoreNamedGlobalVector(),DMGetNamedLocalVector()
516: @*/
517: PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
518: {
520: DMNamedVecLink link;
527: for (link=dm->namedlocal; link; link=link->next) {
528: PetscBool match;
529: PetscStrcmp(name,link->name,&match);
530: if (match) {
531: if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
532: 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);
533: link->status = DMVEC_STATUS_IN;
534: *X = NULL;
535: return(0);
536: }
537: }
538: SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
539: return(0);
540: }