Actual source code: dmget.c
petsc-3.9.4 2018-09-11
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: for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
267: if (*g == dm->globalout[j]) {
268: dm->globalout[j] = NULL;
269: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
270: if (!dm->globalin[i]) {
271: dm->globalin[i] = *g;
272: goto alldone;
273: }
274: }
275: }
276: }
277: VecDestroy(g);
278: alldone:
279: *g = NULL;
280: return(0);
281: }
283: /*@C
284: DMHasNamedGlobalVector - check for a named, persistent global vector
286: Not Collective
288: Input Arguments:
289: + dm - DM to hold named vectors
290: - name - unique name for Vec
292: Output Arguments:
293: . exists - true if the vector was previously created
295: Level: developer
297: Note: If a Vec with the given name does not exist, it is created.
299: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
300: @*/
301: PetscErrorCode DMHasNamedGlobalVector(DM dm,const char *name,PetscBool *exists)
302: {
304: DMNamedVecLink link;
310: *exists = PETSC_FALSE;
311: for (link=dm->namedglobal; link; link=link->next) {
312: PetscBool match;
313: PetscStrcmp(name,link->name,&match);
314: if (match) {
315: *exists = PETSC_TRUE;
316: break;
317: }
318: }
319: return(0);
320: }
322: /*@C
323: DMGetNamedGlobalVector - get access to a named, persistent global vector
325: Collective on DM
327: Input Arguments:
328: + dm - DM to hold named vectors
329: - name - unique name for Vec
331: Output Arguments:
332: . X - named Vec
334: Level: developer
336: Note: If a Vec with the given name does not exist, it is created.
338: .seealso: DMRestoreNamedGlobalVector()
339: @*/
340: PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
341: {
343: DMNamedVecLink link;
349: for (link=dm->namedglobal; link; link=link->next) {
350: PetscBool match;
351: PetscStrcmp(name,link->name,&match);
352: if (match) {
353: if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
354: goto found;
355: }
356: }
358: /* Create the Vec */
359: PetscNew(&link);
360: PetscStrallocpy(name,&link->name);
361: DMCreateGlobalVector(dm,&link->X);
362: link->next = dm->namedglobal;
363: dm->namedglobal = link;
365: found:
366: *X = link->X;
367: link->status = DMVEC_STATUS_OUT;
368: return(0);
369: }
371: /*@C
372: DMRestoreNamedGlobalVector - restore access to a named, persistent global vector
374: Collective on DM
376: Input Arguments:
377: + dm - DM on which the vector was gotten
378: . name - name under which the vector was gotten
379: - X - Vec to restore
381: Output Arguments:
383: Level: developer
385: .seealso: DMGetNamedGlobalVector()
386: @*/
387: PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
388: {
390: DMNamedVecLink link;
397: for (link=dm->namedglobal; link; link=link->next) {
398: PetscBool match;
399: PetscStrcmp(name,link->name,&match);
400: if (match) {
401: if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
402: 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);
403: link->status = DMVEC_STATUS_IN;
404: *X = NULL;
405: return(0);
406: }
407: }
408: SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
409: return(0);
410: }
412: /*@C
413: DMHasNamedLocalVector - check for a named, persistent local vector
415: Not Collective
417: Input Arguments:
418: + dm - DM to hold named vectors
419: - name - unique name for Vec
421: Output Arguments:
422: . exists - true if the vector was previously created
424: Level: developer
426: Note: If a Vec with the given name does not exist, it is created.
428: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
429: @*/
430: PetscErrorCode DMHasNamedLocalVector(DM dm,const char *name,PetscBool *exists)
431: {
433: DMNamedVecLink link;
439: *exists = PETSC_FALSE;
440: for (link=dm->namedlocal; link; link=link->next) {
441: PetscBool match;
442: PetscStrcmp(name,link->name,&match);
443: if (match) {
444: *exists = PETSC_TRUE;
445: break;
446: }
447: }
448: return(0);
449: }
451: /*@C
452: DMGetNamedLocalVector - get access to a named, persistent local vector
454: Not Collective
456: Input Arguments:
457: + dm - DM to hold named vectors
458: - name - unique name for Vec
460: Output Arguments:
461: . X - named Vec
463: Level: developer
465: Note: If a Vec with the given name does not exist, it is created.
467: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
468: @*/
469: PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
470: {
472: DMNamedVecLink link;
478: for (link=dm->namedlocal; link; link=link->next) {
479: PetscBool match;
480: PetscStrcmp(name,link->name,&match);
481: if (match) {
482: if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
483: goto found;
484: }
485: }
487: /* Create the Vec */
488: PetscNew(&link);
489: PetscStrallocpy(name,&link->name);
490: DMCreateLocalVector(dm,&link->X);
491: link->next = dm->namedlocal;
492: dm->namedlocal = link;
494: found:
495: *X = link->X;
496: link->status = DMVEC_STATUS_OUT;
497: return(0);
498: }
500: /*@C
501: DMRestoreNamedLocalVector - restore access to a named, persistent local vector
503: Not Collective
505: Input Arguments:
506: + dm - DM on which the vector was gotten
507: . name - name under which the vector was gotten
508: - X - Vec to restore
510: Output Arguments:
512: Level: developer
514: .seealso: DMRestoreNamedGlobalVector(),DMGetNamedLocalVector()
515: @*/
516: PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
517: {
519: DMNamedVecLink link;
526: for (link=dm->namedlocal; link; link=link->next) {
527: PetscBool match;
528: PetscStrcmp(name,link->name,&match);
529: if (match) {
530: if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
531: 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);
532: link->status = DMVEC_STATUS_IN;
533: *X = NULL;
534: return(0);
535: }
536: }
537: SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
538: return(0);
539: }