Actual source code: dmget.c
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: {
38: for (PetscInt i = 0; i < DM_MAX_WORK_VECTORS; i++) {
39: if (dm->localin[i]) {
40: DM vdm;
42: *g = dm->localin[i];
43: dm->localin[i] = NULL;
45: VecGetDM(*g, &vdm);
47: VecSetDM(*g, dm);
48: goto alldone;
49: }
50: }
51: DMCreateLocalVector(dm, g);
53: alldone:
54: for (PetscInt 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 PETSc vector that was
65: obtained from `DMGetLocalVector()`. Do not use with vector obtained via
66: `DMCreateLocalVector()`.
68: Not Collective
70: Input Parameters:
71: + dm - the dm
72: - g - the local vector
74: Level: beginner
76: .seealso: `DM`, `DMCreateGlobalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
77: `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToLocalBegin()`,
78: `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMCreateLocalVector()`, `DMGetLocalVector()`
79: @*/
80: PetscErrorCode DMRestoreLocalVector(DM dm, Vec *g)
81: {
82: PetscInt i, j;
86: for (j = 0; j < DM_MAX_WORK_VECTORS; j++) {
87: if (*g == dm->localout[j]) {
88: DM vdm;
90: VecGetDM(*g, &vdm);
92: VecSetDM(*g, NULL);
93: dm->localout[j] = NULL;
94: for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
95: if (!dm->localin[i]) {
96: dm->localin[i] = *g;
97: goto alldone;
98: }
99: }
100: }
101: }
102: VecDestroy(g);
103: alldone:
104: *g = NULL;
105: return 0;
106: }
108: /*@
109: DMGetGlobalVector - Gets a PETSc vector that may be used with the `DM` global routines.
111: Collective on dm
113: Input Parameter:
114: . dm - the dm
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: .seealso: `DM`, `DMCreateGlobalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
135: `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToLocalBegin()`,
136: `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMCreateLocalVector()`, `DMRestoreLocalVector()`
137: `VecStrideMax()`, `VecStrideMin()`, `VecStrideNorm()`
138: @*/
139: PetscErrorCode DMGetGlobalVector(DM dm, Vec *g)
140: {
141: PetscInt i;
145: for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
146: if (dm->globalin[i]) {
147: DM vdm;
149: *g = dm->globalin[i];
150: dm->globalin[i] = NULL;
152: VecGetDM(*g, &vdm);
154: VecSetDM(*g, dm);
155: goto alldone;
156: }
157: }
158: DMCreateGlobalVector(dm, g);
160: alldone:
161: for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
162: if (!dm->globalout[i]) {
163: dm->globalout[i] = *g;
164: break;
165: }
166: }
167: return 0;
168: }
170: /*@
171: DMClearGlobalVectors - Destroys all the global vectors that have been stashed in this DM
173: Collective on dm
175: Input Parameter:
176: . dm - the dm
178: Level: developer
180: .seealso: `DMCreateGlobalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
181: `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToLocalBegin()`,
182: `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMCreateLocalVector()`, `DMRestoreLocalVector()`
183: `VecStrideMax()`, `VecStrideMin()`, `VecStrideNorm()`
184: @*/
185: PetscErrorCode DMClearGlobalVectors(DM dm)
186: {
187: PetscInt i;
190: for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
191: Vec g;
194: g = dm->globalin[i];
195: dm->globalin[i] = NULL;
196: if (g) {
197: DM vdm;
199: VecGetDM(g, &vdm);
201: }
202: VecDestroy(&g);
203: }
204: return 0;
205: }
207: /*@
208: DMClearLocalVectors - Destroys all the local vectors that have been stashed in this DM
210: Collective on dm
212: Input Parameter:
213: . dm - the dm
215: Level: developer
217: .seealso: `DMCreateLocalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
218: `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMLocalToLocalBegin()`,
219: `DMLocalToLocalEnd()`, `DMLocalToLocalBegin()`, `DMCreateLocalVector()`, `DMRestoreLocalVector()`
220: `VecStrideMax()`, `VecStrideMin()`, `VecStrideNorm()`
221: @*/
222: PetscErrorCode DMClearLocalVectors(DM dm)
223: {
224: PetscInt i;
227: for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
228: Vec g;
231: g = dm->localin[i];
232: dm->localin[i] = NULL;
233: if (g) {
234: DM vdm;
236: VecGetDM(g, &vdm);
238: }
239: VecDestroy(&g);
240: }
241: return 0;
242: }
244: /*@
245: DMRestoreGlobalVector - Returns a PETSc vector that
246: obtained from DMGetGlobalVector(). Do not use with vector obtained via
247: DMCreateGlobalVector().
249: Not Collective
251: Input Parameters:
252: + dm - the dm
253: - g - the global vector
255: Level: beginner
257: .seealso: `DMCreateGlobalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
258: `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToGlobalBegin()`,
259: `DMGlobalToGlobalEnd()`, `DMGlobalToGlobal()`, `DMCreateLocalVector()`, `DMGetGlobalVector()`
260: @*/
261: PetscErrorCode DMRestoreGlobalVector(DM dm, Vec *g)
262: {
263: PetscInt i, j;
267: VecSetErrorIfLocked(*g, 2);
268: for (j = 0; j < DM_MAX_WORK_VECTORS; j++) {
269: if (*g == dm->globalout[j]) {
270: DM vdm;
272: VecGetDM(*g, &vdm);
274: VecSetDM(*g, NULL);
275: dm->globalout[j] = NULL;
276: for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
277: if (!dm->globalin[i]) {
278: dm->globalin[i] = *g;
279: goto alldone;
280: }
281: }
282: }
283: }
284: VecDestroy(g);
285: alldone:
286: *g = NULL;
287: return 0;
288: }
290: /*@C
291: DMHasNamedGlobalVector - check for a named, persistent global vector
293: Not Collective
295: Input Parameters:
296: + dm - DM to hold named vectors
297: - name - unique name for Vec
299: Output Parameter:
300: . exists - true if the vector was previously created
302: Level: developer
304: Note: If a Vec with the given name does not exist, it is created.
306: .seealso: `DMGetNamedGlobalVector()`, `DMRestoreNamedLocalVector()`
307: @*/
308: PetscErrorCode DMHasNamedGlobalVector(DM dm, const char *name, PetscBool *exists)
309: {
310: DMNamedVecLink link;
315: *exists = PETSC_FALSE;
316: for (link = dm->namedglobal; link; link = link->next) {
317: PetscBool match;
318: PetscStrcmp(name, link->name, &match);
319: if (match) {
320: *exists = PETSC_TRUE;
321: break;
322: }
323: }
324: return 0;
325: }
327: /*@C
328: DMGetNamedGlobalVector - get access to a named, persistent global vector
330: Collective on dm
332: Input Parameters:
333: + dm - DM to hold named vectors
334: - name - unique name for Vec
336: Output Parameter:
337: . X - named Vec
339: Level: developer
341: Note: If a Vec with the given name does not exist, it is created.
343: .seealso: `DMRestoreNamedGlobalVector()`
344: @*/
345: PetscErrorCode DMGetNamedGlobalVector(DM dm, const char *name, Vec *X)
346: {
347: DMNamedVecLink link;
352: for (link = dm->namedglobal; link; link = link->next) {
353: PetscBool match;
355: PetscStrcmp(name, link->name, &match);
356: if (match) {
357: DM vdm;
360: VecGetDM(link->X, &vdm);
362: VecSetDM(link->X, dm);
363: goto found;
364: }
365: }
367: /* Create the Vec */
368: PetscNew(&link);
369: PetscStrallocpy(name, &link->name);
370: DMCreateGlobalVector(dm, &link->X);
371: link->next = dm->namedglobal;
372: dm->namedglobal = link;
374: found:
375: *X = link->X;
376: link->status = DMVEC_STATUS_OUT;
377: return 0;
378: }
380: /*@C
381: DMRestoreNamedGlobalVector - restore access to a named, persistent global vector
383: Collective on dm
385: Input Parameters:
386: + dm - DM on which the vector was gotten
387: . name - name under which the vector was gotten
388: - X - Vec to restore
390: Level: developer
392: .seealso: `DMGetNamedGlobalVector()`
393: @*/
394: PetscErrorCode DMRestoreNamedGlobalVector(DM dm, const char *name, Vec *X)
395: {
396: DMNamedVecLink link;
402: for (link = dm->namedglobal; link; link = link->next) {
403: PetscBool match;
405: PetscStrcmp(name, link->name, &match);
406: if (match) {
407: DM vdm;
409: VecGetDM(*X, &vdm);
414: link->status = DMVEC_STATUS_IN;
415: VecSetDM(link->X, NULL);
416: *X = NULL;
417: return 0;
418: }
419: }
420: SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_INCOMP, "Could not find Vec name '%s' to restore", name);
421: }
423: /*@C
424: DMHasNamedLocalVector - check for a named, persistent local vector
426: Not Collective
428: Input Parameters:
429: + dm - DM to hold named vectors
430: - name - unique name for Vec
432: Output Parameter:
433: . exists - true if the vector was previously created
435: Level: developer
437: Note: If a Vec with the given name does not exist, it is created.
439: .seealso: `DMGetNamedGlobalVector()`, `DMRestoreNamedLocalVector()`
440: @*/
441: PetscErrorCode DMHasNamedLocalVector(DM dm, const char *name, PetscBool *exists)
442: {
443: DMNamedVecLink link;
448: *exists = PETSC_FALSE;
449: for (link = dm->namedlocal; link; link = link->next) {
450: PetscBool match;
451: PetscStrcmp(name, link->name, &match);
452: if (match) {
453: *exists = PETSC_TRUE;
454: break;
455: }
456: }
457: return 0;
458: }
460: /*@C
461: DMGetNamedLocalVector - get access to a named, persistent local vector
463: Not Collective
465: Input Parameters:
466: + dm - DM to hold named vectors
467: - name - unique name for Vec
469: Output Parameter:
470: . X - named Vec
472: Level: developer
474: Note: If a Vec with the given name does not exist, it is created.
476: .seealso: `DMGetNamedGlobalVector()`, `DMRestoreNamedLocalVector()`
477: @*/
478: PetscErrorCode DMGetNamedLocalVector(DM dm, const char *name, Vec *X)
479: {
480: DMNamedVecLink link;
485: for (link = dm->namedlocal; link; link = link->next) {
486: PetscBool match;
488: PetscStrcmp(name, link->name, &match);
489: if (match) {
490: DM vdm;
493: VecGetDM(link->X, &vdm);
495: VecSetDM(link->X, dm);
496: goto found;
497: }
498: }
500: /* Create the Vec */
501: PetscNew(&link);
502: PetscStrallocpy(name, &link->name);
503: DMCreateLocalVector(dm, &link->X);
504: link->next = dm->namedlocal;
505: dm->namedlocal = link;
507: found:
508: *X = link->X;
509: link->status = DMVEC_STATUS_OUT;
510: return 0;
511: }
513: /*@C
514: DMRestoreNamedLocalVector - restore access to a named, persistent local vector
516: Not Collective
518: Input Parameters:
519: + dm - DM on which the vector was gotten
520: . name - name under which the vector was gotten
521: - X - Vec to restore
523: Level: developer
525: .seealso: `DMRestoreNamedGlobalVector()`, `DMGetNamedLocalVector()`
526: @*/
527: PetscErrorCode DMRestoreNamedLocalVector(DM dm, const char *name, Vec *X)
528: {
529: DMNamedVecLink link;
535: for (link = dm->namedlocal; link; link = link->next) {
536: PetscBool match;
538: PetscStrcmp(name, link->name, &match);
539: if (match) {
540: DM vdm;
542: VecGetDM(*X, &vdm);
547: link->status = DMVEC_STATUS_IN;
548: VecSetDM(link->X, NULL);
549: *X = NULL;
550: return 0;
551: }
552: }
553: SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_INCOMP, "Could not find Vec name '%s' to restore", name);
554: }