Actual source code: dmget.c
petsc-3.7.7 2017-09-25
1: #include <petsc/private/dmimpl.h> /*I "petscdm.h" I*/
5: /*@
6: DMGetLocalVector - Gets a Seq PETSc vector that
7: may be used with the DMXXX routines. This vector has spaces for the ghost values.
9: Not Collective
11: Input Parameter:
12: . dm - the distributed array
14: Output Parameter:
15: . g - the local vector
17: Level: beginner
19: Note:
20: The vector values are NOT initialized and may have garbage in them, so you may need
21: to zero them.
23: The output parameter, g, is a regular PETSc vector that should be returned with
24: DMRestoreLocalVector() DO NOT call VecDestroy() on it.
26: This is intended to be used for vectors you need for a short time, like within a single function call.
27: For vectors that you intend to keep around (for example in a C struct) or pass around large parts of your
28: code you should use DMCreateLocalVector().
30: VecStride*() operations can be useful when using DM with dof > 1
32: .keywords: distributed array, create, local, vector
34: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
35: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
36: DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector(),
37: VecStrideMax(), VecStrideMin(), VecStrideNorm()
38: @*/
39: PetscErrorCode DMGetLocalVector(DM dm,Vec *g)
40: {
41: PetscErrorCode ierr,i;
46: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
47: if (dm->localin[i]) {
48: *g = dm->localin[i];
49: dm->localin[i] = NULL;
50: goto alldone;
51: }
52: }
53: DMCreateLocalVector(dm,g);
55: alldone:
56: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
57: if (!dm->localout[i]) {
58: dm->localout[i] = *g;
59: break;
60: }
61: }
62: return(0);
63: }
67: /*@
68: DMRestoreLocalVector - Returns a Seq PETSc vector that
69: obtained from DMGetLocalVector(). Do not use with vector obtained via
70: DMCreateLocalVector().
72: Not Collective
74: Input Parameter:
75: + dm - the distributed array
76: - g - the local vector
78: Level: beginner
80: .keywords: distributed array, create, local, vector
82: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
83: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
84: DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMGetLocalVector()
85: @*/
86: PetscErrorCode DMRestoreLocalVector(DM dm,Vec *g)
87: {
89: PetscInt i,j;
94: for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
95: if (*g == dm->localout[j]) {
96: dm->localout[j] = NULL;
97: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
98: if (!dm->localin[i]) {
99: dm->localin[i] = *g;
100: goto alldone;
101: }
102: }
103: }
104: }
105: VecDestroy(g);
106: alldone:
107: *g = NULL;
108: return(0);
109: }
113: /*@
114: DMGetGlobalVector - Gets a MPI PETSc vector that
115: may be used with the DMXXX routines.
117: Collective on DM
119: Input Parameter:
120: . dm - the distributed array
122: Output Parameter:
123: . g - the global vector
125: Level: beginner
127: Note:
128: The vector values are NOT initialized and may have garbage in them, so you may need
129: to zero them.
131: The output parameter, g, is a regular PETSc vector that should be returned with
132: DMRestoreGlobalVector() DO NOT call VecDestroy() on it.
134: This is intended to be used for vectors you need for a short time, like within a single function call.
135: For vectors that you intend to keep around (for example in a C struct) or pass around large parts of your
136: code you should use DMCreateGlobalVector().
138: VecStride*() operations can be useful when using DM with dof > 1
140: .keywords: distributed array, create, Global, vector
142: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
143: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
144: DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
145: VecStrideMax(), VecStrideMin(), VecStrideNorm()
147: @*/
148: PetscErrorCode DMGetGlobalVector(DM dm,Vec *g)
149: {
151: PetscInt i;
156: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
157: if (dm->globalin[i]) {
158: *g = dm->globalin[i];
159: dm->globalin[i] = NULL;
160: goto alldone;
161: }
162: }
163: DMCreateGlobalVector(dm,g);
165: alldone:
166: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
167: if (!dm->globalout[i]) {
168: dm->globalout[i] = *g;
169: break;
170: }
171: }
172: return(0);
173: }
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 distributed array
185: Level: developer
187: .keywords: distributed array, create, Global, vector
189: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
190: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
191: DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
192: VecStrideMax(), VecStrideMin(), VecStrideNorm()
194: @*/
195: PetscErrorCode DMClearGlobalVectors(DM dm)
196: {
198: PetscInt i;
202: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
203: Vec g;
204: 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()");
205: g = dm->globalin[i];
206: dm->globalin[i] = NULL;
207: VecDestroy(&g);
208: }
209: return(0);
210: }
214: /*@
215: DMClearLocalVectors - Destroys all the local vectors that have been stashed in this DM
217: Collective on DM
219: Input Parameter:
220: . dm - the distributed array
222: Level: developer
224: .keywords: distributed array, create, Local, vector
226: .seealso: DMCreateLocalVector(), VecDuplicate(), VecDuplicateVecs(),
227: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMLocalToLocalBegin(),
228: DMLocalToLocalEnd(), DMLocalToLocalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
229: VecStrideMax(), VecStrideMin(), VecStrideNorm()
231: @*/
232: PetscErrorCode DMClearLocalVectors(DM dm)
233: {
235: PetscInt i;
239: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
240: Vec g;
241: 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()");
242: g = dm->localin[i];
243: dm->localin[i] = NULL;
244: VecDestroy(&g);
245: }
246: return(0);
247: }
251: /*@
252: DMRestoreGlobalVector - Returns a Seq PETSc vector that
253: obtained from DMGetGlobalVector(). Do not use with vector obtained via
254: DMCreateGlobalVector().
256: Not Collective
258: Input Parameter:
259: + dm - the distributed array
260: - g - the global vector
262: Level: beginner
264: .keywords: distributed array, create, global, vector
266: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
267: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(),
268: DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
269: @*/
270: PetscErrorCode DMRestoreGlobalVector(DM dm,Vec *g)
271: {
273: PetscInt i,j;
278: for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
279: if (*g == dm->globalout[j]) {
280: dm->globalout[j] = NULL;
281: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
282: if (!dm->globalin[i]) {
283: dm->globalin[i] = *g;
284: goto alldone;
285: }
286: }
287: }
288: }
289: VecDestroy(g);
290: alldone:
291: *g = NULL;
292: return(0);
293: }
297: /*@C
298: DMHasNamedGlobalVector - check for a named, persistent global vector
300: Not Collective
302: Input Arguments:
303: + dm - DM to hold named vectors
304: - name - unique name for Vec
306: Output Arguments:
307: . exists - true if the vector was previously created
309: Level: developer
311: Note: If a Vec with the given name does not exist, it is created.
313: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
314: @*/
315: PetscErrorCode DMHasNamedGlobalVector(DM dm,const char *name,PetscBool *exists)
316: {
318: DMNamedVecLink link;
324: *exists = PETSC_FALSE;
325: for (link=dm->namedglobal; link; link=link->next) {
326: PetscBool match;
327: PetscStrcmp(name,link->name,&match);
328: if (match) {
329: *exists = PETSC_TRUE;
330: break;
331: }
332: }
333: return(0);
334: }
338: /*@C
339: DMGetNamedGlobalVector - get access to a named, persistent global vector
341: Collective on DM
343: Input Arguments:
344: + dm - DM to hold named vectors
345: - name - unique name for Vec
347: Output Arguments:
348: . X - named Vec
350: Level: developer
352: Note: If a Vec with the given name does not exist, it is created.
354: .seealso: DMRestoreNamedGlobalVector()
355: @*/
356: PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
357: {
359: DMNamedVecLink link;
365: for (link=dm->namedglobal; link; link=link->next) {
366: PetscBool match;
367: PetscStrcmp(name,link->name,&match);
368: if (match) {
369: if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
370: goto found;
371: }
372: }
374: /* Create the Vec */
375: PetscNew(&link);
376: PetscStrallocpy(name,&link->name);
377: DMCreateGlobalVector(dm,&link->X);
378: link->next = dm->namedglobal;
379: dm->namedglobal = link;
381: found:
382: *X = link->X;
383: link->status = DMVEC_STATUS_OUT;
384: return(0);
385: }
389: /*@C
390: DMRestoreNamedGlobalVector - restore access to a named, persistent global vector
392: Collective on DM
394: Input Arguments:
395: + dm - DM on which the vector was gotten
396: . name - name under which the vector was gotten
397: - X - Vec to restore
399: Output Arguments:
401: Level: developer
403: .seealso: DMGetNamedGlobalVector()
404: @*/
405: PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
406: {
408: DMNamedVecLink link;
415: for (link=dm->namedglobal; link; link=link->next) {
416: PetscBool match;
417: PetscStrcmp(name,link->name,&match);
418: if (match) {
419: if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
420: 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);
421: link->status = DMVEC_STATUS_IN;
422: *X = NULL;
423: return(0);
424: }
425: }
426: SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
427: return(0);
428: }
432: /*@C
433: DMHasNamedLocalVector - check for a named, persistent local vector
435: Not Collective
437: Input Arguments:
438: + dm - DM to hold named vectors
439: - name - unique name for Vec
441: Output Arguments:
442: . exists - true if the vector was previously created
444: Level: developer
446: Note: If a Vec with the given name does not exist, it is created.
448: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
449: @*/
450: PetscErrorCode DMHasNamedLocalVector(DM dm,const char *name,PetscBool *exists)
451: {
453: DMNamedVecLink link;
459: *exists = PETSC_FALSE;
460: for (link=dm->namedlocal; link; link=link->next) {
461: PetscBool match;
462: PetscStrcmp(name,link->name,&match);
463: if (match) {
464: *exists = PETSC_TRUE;
465: break;
466: }
467: }
468: return(0);
469: }
473: /*@C
474: DMGetNamedLocalVector - get access to a named, persistent local vector
476: Not Collective
478: Input Arguments:
479: + dm - DM to hold named vectors
480: - name - unique name for Vec
482: Output Arguments:
483: . X - named Vec
485: Level: developer
487: Note: If a Vec with the given name does not exist, it is created.
489: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
490: @*/
491: PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
492: {
494: DMNamedVecLink link;
500: for (link=dm->namedlocal; link; link=link->next) {
501: PetscBool match;
502: PetscStrcmp(name,link->name,&match);
503: if (match) {
504: if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
505: goto found;
506: }
507: }
509: /* Create the Vec */
510: PetscNew(&link);
511: PetscStrallocpy(name,&link->name);
512: DMCreateLocalVector(dm,&link->X);
513: link->next = dm->namedlocal;
514: dm->namedlocal = link;
516: found:
517: *X = link->X;
518: link->status = DMVEC_STATUS_OUT;
519: return(0);
520: }
524: /*@C
525: DMRestoreNamedLocalVector - restore access to a named, persistent local vector
527: Not Collective
529: Input Arguments:
530: + dm - DM on which the vector was gotten
531: . name - name under which the vector was gotten
532: - X - Vec to restore
534: Output Arguments:
536: Level: developer
538: .seealso: DMRestoreNamedGlobalVector(),DMGetNamedLocalVector()
539: @*/
540: PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
541: {
543: DMNamedVecLink link;
550: for (link=dm->namedlocal; link; link=link->next) {
551: PetscBool match;
552: PetscStrcmp(name,link->name,&match);
553: if (match) {
554: if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
555: 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);
556: link->status = DMVEC_STATUS_IN;
557: *X = NULL;
558: return(0);
559: }
560: }
561: SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
562: return(0);
563: }