xref: /petsc/src/dm/interface/dmget.c (revision dce8aeba1c9b69b19f651c53d8a6b674bd7e9cbd)
1af0996ceSBarry Smith #include <petsc/private/dmimpl.h> /*I "petscdm.h" I*/
268260fa0SJed Brown 
368260fa0SJed Brown /*@
46eb26441SStefano Zampini    DMGetLocalVector - Gets a PETSc vector that may be used with the DM local routines. This vector has spaces for the ghost values.
568260fa0SJed Brown 
668260fa0SJed Brown    Not Collective
768260fa0SJed Brown 
868260fa0SJed Brown    Input Parameter:
96eb26441SStefano Zampini .  dm - the dm
1068260fa0SJed Brown 
1168260fa0SJed Brown    Output Parameter:
1268260fa0SJed Brown .  g - the local vector
1368260fa0SJed Brown 
1468260fa0SJed Brown    Level: beginner
1568260fa0SJed Brown 
1668260fa0SJed Brown    Note:
1768260fa0SJed Brown    The vector values are NOT initialized and may have garbage in them, so you may need
1868260fa0SJed Brown    to zero them.
1968260fa0SJed Brown 
2068260fa0SJed Brown    The output parameter, g, is a regular PETSc vector that should be returned with
2168260fa0SJed Brown    DMRestoreLocalVector() DO NOT call VecDestroy() on it.
2268260fa0SJed Brown 
23f1978aafSBarry Smith    This is intended to be used for vectors you need for a short time, like within a single function call.
24f1978aafSBarry Smith    For vectors that you intend to keep around (for example in a C struct) or pass around large parts of your
25f1978aafSBarry Smith    code you should use DMCreateLocalVector().
26f1978aafSBarry Smith 
2768260fa0SJed Brown    VecStride*() operations can be useful when using DM with dof > 1
2868260fa0SJed Brown 
29db781477SPatrick Sanan .seealso: `DMCreateGlobalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
30db781477SPatrick Sanan           `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToLocalBegin()`,
31db781477SPatrick Sanan           `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMCreateLocalVector()`, `DMRestoreLocalVector()`,
32db781477SPatrick Sanan           `VecStrideMax()`, `VecStrideMin()`, `VecStrideNorm()`
3368260fa0SJed Brown @*/
34d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLocalVector(DM dm, Vec *g)
35d71ae5a4SJacob Faibussowitsch {
3668260fa0SJed Brown   PetscFunctionBegin;
3768260fa0SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3868260fa0SJed Brown   PetscValidPointer(g, 2);
395f80ce2aSJacob Faibussowitsch   for (PetscInt i = 0; i < DM_MAX_WORK_VECTORS; i++) {
4068260fa0SJed Brown     if (dm->localin[i]) {
416eb26441SStefano Zampini       DM vdm;
426eb26441SStefano Zampini 
4368260fa0SJed Brown       *g             = dm->localin[i];
440298fd71SBarry Smith       dm->localin[i] = NULL;
456eb26441SStefano Zampini 
469566063dSJacob Faibussowitsch       PetscCall(VecGetDM(*g, &vdm));
4728b400f6SJacob Faibussowitsch       PetscCheck(!vdm, PetscObjectComm((PetscObject)vdm), PETSC_ERR_LIB, "Invalid vector");
489566063dSJacob Faibussowitsch       PetscCall(VecSetDM(*g, dm));
4968260fa0SJed Brown       goto alldone;
5068260fa0SJed Brown     }
5168260fa0SJed Brown   }
529566063dSJacob Faibussowitsch   PetscCall(DMCreateLocalVector(dm, g));
5368260fa0SJed Brown 
5468260fa0SJed Brown alldone:
555f80ce2aSJacob Faibussowitsch   for (PetscInt i = 0; i < DM_MAX_WORK_VECTORS; i++) {
5668260fa0SJed Brown     if (!dm->localout[i]) {
5768260fa0SJed Brown       dm->localout[i] = *g;
5868260fa0SJed Brown       break;
5968260fa0SJed Brown     }
6068260fa0SJed Brown   }
6168260fa0SJed Brown   PetscFunctionReturn(0);
6268260fa0SJed Brown }
6368260fa0SJed Brown 
6468260fa0SJed Brown /*@
656eb26441SStefano Zampini    DMRestoreLocalVector - Returns a PETSc vector that was
66*dce8aebaSBarry Smith      obtained from `DMGetLocalVector()`. Do not use with vector obtained via
67*dce8aebaSBarry Smith      `DMCreateLocalVector()`.
6868260fa0SJed Brown 
6968260fa0SJed Brown    Not Collective
7068260fa0SJed Brown 
71d8d19677SJose E. Roman    Input Parameters:
726eb26441SStefano Zampini +  dm - the dm
7368260fa0SJed Brown -  g - the local vector
7468260fa0SJed Brown 
7568260fa0SJed Brown    Level: beginner
7668260fa0SJed Brown 
77*dce8aebaSBarry Smith .seealso: `DM`, `DMCreateGlobalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
78db781477SPatrick Sanan           `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToLocalBegin()`,
79db781477SPatrick Sanan           `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMCreateLocalVector()`, `DMGetLocalVector()`
8068260fa0SJed Brown @*/
81d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRestoreLocalVector(DM dm, Vec *g)
82d71ae5a4SJacob Faibussowitsch {
8368260fa0SJed Brown   PetscInt i, j;
8468260fa0SJed Brown 
8568260fa0SJed Brown   PetscFunctionBegin;
8668260fa0SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8768260fa0SJed Brown   PetscValidPointer(g, 2);
8868260fa0SJed Brown   for (j = 0; j < DM_MAX_WORK_VECTORS; j++) {
8968260fa0SJed Brown     if (*g == dm->localout[j]) {
906eb26441SStefano Zampini       DM vdm;
916eb26441SStefano Zampini 
929566063dSJacob Faibussowitsch       PetscCall(VecGetDM(*g, &vdm));
9308401ef6SPierre Jolivet       PetscCheck(vdm == dm, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Invalid vector");
949566063dSJacob Faibussowitsch       PetscCall(VecSetDM(*g, NULL));
950298fd71SBarry Smith       dm->localout[j] = NULL;
9668260fa0SJed Brown       for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
9768260fa0SJed Brown         if (!dm->localin[i]) {
9868260fa0SJed Brown           dm->localin[i] = *g;
9968260fa0SJed Brown           goto alldone;
10068260fa0SJed Brown         }
10168260fa0SJed Brown       }
10268260fa0SJed Brown     }
10368260fa0SJed Brown   }
1049566063dSJacob Faibussowitsch   PetscCall(VecDestroy(g));
10568260fa0SJed Brown alldone:
106dd6887adSBarry Smith   *g = NULL;
10768260fa0SJed Brown   PetscFunctionReturn(0);
10868260fa0SJed Brown }
10968260fa0SJed Brown 
11068260fa0SJed Brown /*@
111*dce8aebaSBarry Smith    DMGetGlobalVector - Gets a PETSc vector that may be used with the `DM` global routines.
11268260fa0SJed Brown 
113d083f849SBarry Smith    Collective on dm
11468260fa0SJed Brown 
11568260fa0SJed Brown    Input Parameter:
1166eb26441SStefano Zampini .  dm - the dm
11768260fa0SJed Brown 
11868260fa0SJed Brown    Output Parameter:
11968260fa0SJed Brown .  g - the global vector
12068260fa0SJed Brown 
12168260fa0SJed Brown    Level: beginner
12268260fa0SJed Brown 
12368260fa0SJed Brown    Note:
12468260fa0SJed Brown    The vector values are NOT initialized and may have garbage in them, so you may need
12568260fa0SJed Brown    to zero them.
12668260fa0SJed Brown 
12768260fa0SJed Brown    The output parameter, g, is a regular PETSc vector that should be returned with
128*dce8aebaSBarry Smith    `DMRestoreGlobalVector()` DO NOT call `VecDestroy()` on it.
12968260fa0SJed Brown 
130f1978aafSBarry Smith    This is intended to be used for vectors you need for a short time, like within a single function call.
131f1978aafSBarry Smith    For vectors that you intend to keep around (for example in a C struct) or pass around large parts of your
132*dce8aebaSBarry Smith    code you should use `DMCreateGlobalVector()`.
133f1978aafSBarry Smith 
134*dce8aebaSBarry Smith    VecStride*() operations can be useful when using `DM` with dof > 1
13568260fa0SJed Brown 
136*dce8aebaSBarry Smith .seealso: `DM`, `DMCreateGlobalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
137db781477SPatrick Sanan           `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToLocalBegin()`,
138db781477SPatrick Sanan           `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMCreateLocalVector()`, `DMRestoreLocalVector()`
139db781477SPatrick Sanan           `VecStrideMax()`, `VecStrideMin()`, `VecStrideNorm()`
14068260fa0SJed Brown @*/
141d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetGlobalVector(DM dm, Vec *g)
142d71ae5a4SJacob Faibussowitsch {
14368260fa0SJed Brown   PetscInt i;
14468260fa0SJed Brown 
14568260fa0SJed Brown   PetscFunctionBegin;
14668260fa0SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
14768260fa0SJed Brown   PetscValidPointer(g, 2);
14868260fa0SJed Brown   for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
14968260fa0SJed Brown     if (dm->globalin[i]) {
1506eb26441SStefano Zampini       DM vdm;
1516eb26441SStefano Zampini 
15268260fa0SJed Brown       *g              = dm->globalin[i];
1530298fd71SBarry Smith       dm->globalin[i] = NULL;
1546eb26441SStefano Zampini 
1559566063dSJacob Faibussowitsch       PetscCall(VecGetDM(*g, &vdm));
15628b400f6SJacob Faibussowitsch       PetscCheck(!vdm, PetscObjectComm((PetscObject)vdm), PETSC_ERR_LIB, "Invalid vector");
1579566063dSJacob Faibussowitsch       PetscCall(VecSetDM(*g, dm));
15868260fa0SJed Brown       goto alldone;
15968260fa0SJed Brown     }
16068260fa0SJed Brown   }
1619566063dSJacob Faibussowitsch   PetscCall(DMCreateGlobalVector(dm, g));
16268260fa0SJed Brown 
16368260fa0SJed Brown alldone:
16468260fa0SJed Brown   for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
16568260fa0SJed Brown     if (!dm->globalout[i]) {
16668260fa0SJed Brown       dm->globalout[i] = *g;
16768260fa0SJed Brown       break;
16868260fa0SJed Brown     }
16968260fa0SJed Brown   }
17068260fa0SJed Brown   PetscFunctionReturn(0);
17168260fa0SJed Brown }
17268260fa0SJed Brown 
17368260fa0SJed Brown /*@
17468260fa0SJed Brown    DMClearGlobalVectors - Destroys all the global vectors that have been stashed in this DM
17568260fa0SJed Brown 
176d083f849SBarry Smith    Collective on dm
17768260fa0SJed Brown 
17868260fa0SJed Brown    Input Parameter:
1796eb26441SStefano Zampini .  dm - the dm
18068260fa0SJed Brown 
18168260fa0SJed Brown    Level: developer
18268260fa0SJed Brown 
183db781477SPatrick Sanan .seealso: `DMCreateGlobalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
184db781477SPatrick Sanan           `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToLocalBegin()`,
185db781477SPatrick Sanan           `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMCreateLocalVector()`, `DMRestoreLocalVector()`
186db781477SPatrick Sanan           `VecStrideMax()`, `VecStrideMin()`, `VecStrideNorm()`
18768260fa0SJed Brown @*/
188d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearGlobalVectors(DM dm)
189d71ae5a4SJacob Faibussowitsch {
19068260fa0SJed Brown   PetscInt i;
19168260fa0SJed Brown 
19268260fa0SJed Brown   PetscFunctionBegin;
19368260fa0SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
19468260fa0SJed Brown   for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
19562d839e9SJed Brown     Vec g;
1966eb26441SStefano Zampini 
1971dca8a05SBarry Smith     PetscCheck(!dm->globalout[i], PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Clearing DM of global vectors that has a global vector obtained with DMGetGlobalVector()");
19862d839e9SJed Brown     g               = dm->globalin[i];
19962d839e9SJed Brown     dm->globalin[i] = NULL;
2006eb26441SStefano Zampini     if (g) {
2016eb26441SStefano Zampini       DM vdm;
2026eb26441SStefano Zampini 
2039566063dSJacob Faibussowitsch       PetscCall(VecGetDM(g, &vdm));
20428b400f6SJacob Faibussowitsch       PetscCheck(!vdm, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Clearing global vector that has a DM attached");
2056eb26441SStefano Zampini     }
2069566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&g));
20768260fa0SJed Brown   }
20868260fa0SJed Brown   PetscFunctionReturn(0);
20968260fa0SJed Brown }
21068260fa0SJed Brown 
21150eeb1caSToby Isaac /*@
21250eeb1caSToby Isaac    DMClearLocalVectors - Destroys all the local vectors that have been stashed in this DM
21350eeb1caSToby Isaac 
214d083f849SBarry Smith    Collective on dm
21550eeb1caSToby Isaac 
21650eeb1caSToby Isaac    Input Parameter:
2176eb26441SStefano Zampini .  dm - the dm
21850eeb1caSToby Isaac 
21950eeb1caSToby Isaac    Level: developer
22050eeb1caSToby Isaac 
221db781477SPatrick Sanan .seealso: `DMCreateLocalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
222db781477SPatrick Sanan           `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMLocalToLocalBegin()`,
223db781477SPatrick Sanan           `DMLocalToLocalEnd()`, `DMLocalToLocalBegin()`, `DMCreateLocalVector()`, `DMRestoreLocalVector()`
224db781477SPatrick Sanan           `VecStrideMax()`, `VecStrideMin()`, `VecStrideNorm()`
22550eeb1caSToby Isaac @*/
226d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearLocalVectors(DM dm)
227d71ae5a4SJacob Faibussowitsch {
22850eeb1caSToby Isaac   PetscInt i;
22950eeb1caSToby Isaac 
23050eeb1caSToby Isaac   PetscFunctionBegin;
23150eeb1caSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
23250eeb1caSToby Isaac   for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
23350eeb1caSToby Isaac     Vec g;
2346eb26441SStefano Zampini 
2351dca8a05SBarry Smith     PetscCheck(!dm->localout[i], PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Clearing DM of local vectors that has a local vector obtained with DMGetLocalVector()");
23650eeb1caSToby Isaac     g              = dm->localin[i];
23750eeb1caSToby Isaac     dm->localin[i] = NULL;
2386eb26441SStefano Zampini     if (g) {
2396eb26441SStefano Zampini       DM vdm;
2406eb26441SStefano Zampini 
2419566063dSJacob Faibussowitsch       PetscCall(VecGetDM(g, &vdm));
24228b400f6SJacob Faibussowitsch       PetscCheck(!vdm, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Clearing local vector that has a DM attached");
2436eb26441SStefano Zampini     }
2449566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&g));
24550eeb1caSToby Isaac   }
24650eeb1caSToby Isaac   PetscFunctionReturn(0);
24750eeb1caSToby Isaac }
24850eeb1caSToby Isaac 
24968260fa0SJed Brown /*@
2506eb26441SStefano Zampini    DMRestoreGlobalVector - Returns a PETSc vector that
25168260fa0SJed Brown      obtained from DMGetGlobalVector(). Do not use with vector obtained via
25268260fa0SJed Brown      DMCreateGlobalVector().
25368260fa0SJed Brown 
25468260fa0SJed Brown    Not Collective
25568260fa0SJed Brown 
256d8d19677SJose E. Roman    Input Parameters:
2576eb26441SStefano Zampini +  dm - the dm
25868260fa0SJed Brown -  g - the global vector
25968260fa0SJed Brown 
26068260fa0SJed Brown    Level: beginner
26168260fa0SJed Brown 
262db781477SPatrick Sanan .seealso: `DMCreateGlobalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`,
263db781477SPatrick Sanan           `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToGlobalBegin()`,
264db781477SPatrick Sanan           `DMGlobalToGlobalEnd()`, `DMGlobalToGlobal()`, `DMCreateLocalVector()`, `DMGetGlobalVector()`
26568260fa0SJed Brown @*/
266d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRestoreGlobalVector(DM dm, Vec *g)
267d71ae5a4SJacob Faibussowitsch {
26868260fa0SJed Brown   PetscInt i, j;
26968260fa0SJed Brown 
27068260fa0SJed Brown   PetscFunctionBegin;
27168260fa0SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
27268260fa0SJed Brown   PetscValidPointer(g, 2);
2739566063dSJacob Faibussowitsch   PetscCall(VecSetErrorIfLocked(*g, 2));
27468260fa0SJed Brown   for (j = 0; j < DM_MAX_WORK_VECTORS; j++) {
27568260fa0SJed Brown     if (*g == dm->globalout[j]) {
2766eb26441SStefano Zampini       DM vdm;
2776eb26441SStefano Zampini 
2789566063dSJacob Faibussowitsch       PetscCall(VecGetDM(*g, &vdm));
27908401ef6SPierre Jolivet       PetscCheck(vdm == dm, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Invalid vector");
2809566063dSJacob Faibussowitsch       PetscCall(VecSetDM(*g, NULL));
2810298fd71SBarry Smith       dm->globalout[j] = NULL;
28268260fa0SJed Brown       for (i = 0; i < DM_MAX_WORK_VECTORS; i++) {
28368260fa0SJed Brown         if (!dm->globalin[i]) {
28468260fa0SJed Brown           dm->globalin[i] = *g;
28568260fa0SJed Brown           goto alldone;
28668260fa0SJed Brown         }
28768260fa0SJed Brown       }
28868260fa0SJed Brown     }
28968260fa0SJed Brown   }
2909566063dSJacob Faibussowitsch   PetscCall(VecDestroy(g));
29168260fa0SJed Brown alldone:
292dd6887adSBarry Smith   *g = NULL;
29368260fa0SJed Brown   PetscFunctionReturn(0);
29468260fa0SJed Brown }
29568260fa0SJed Brown 
296e77ac854SMatthew G. Knepley /*@C
297e77ac854SMatthew G. Knepley    DMHasNamedGlobalVector - check for a named, persistent global vector
298e77ac854SMatthew G. Knepley 
299e77ac854SMatthew G. Knepley    Not Collective
300e77ac854SMatthew G. Knepley 
3014165533cSJose E. Roman    Input Parameters:
302e77ac854SMatthew G. Knepley +  dm - DM to hold named vectors
303e77ac854SMatthew G. Knepley -  name - unique name for Vec
304e77ac854SMatthew G. Knepley 
3054165533cSJose E. Roman    Output Parameter:
306e77ac854SMatthew G. Knepley .  exists - true if the vector was previously created
307e77ac854SMatthew G. Knepley 
308e77ac854SMatthew G. Knepley    Level: developer
309e77ac854SMatthew G. Knepley 
310e77ac854SMatthew G. Knepley    Note: If a Vec with the given name does not exist, it is created.
311e77ac854SMatthew G. Knepley 
312db781477SPatrick Sanan .seealso: `DMGetNamedGlobalVector()`, `DMRestoreNamedLocalVector()`
313e77ac854SMatthew G. Knepley @*/
314d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasNamedGlobalVector(DM dm, const char *name, PetscBool *exists)
315d71ae5a4SJacob Faibussowitsch {
316e77ac854SMatthew G. Knepley   DMNamedVecLink link;
317e77ac854SMatthew G. Knepley 
318e77ac854SMatthew G. Knepley   PetscFunctionBegin;
319e77ac854SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
320e77ac854SMatthew G. Knepley   PetscValidCharPointer(name, 2);
321534a8f05SLisandro Dalcin   PetscValidBoolPointer(exists, 3);
322e77ac854SMatthew G. Knepley   *exists = PETSC_FALSE;
323e77ac854SMatthew G. Knepley   for (link = dm->namedglobal; link; link = link->next) {
324e77ac854SMatthew G. Knepley     PetscBool match;
3259566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name, link->name, &match));
326e77ac854SMatthew G. Knepley     if (match) {
327e77ac854SMatthew G. Knepley       *exists = PETSC_TRUE;
328e77ac854SMatthew G. Knepley       break;
329e77ac854SMatthew G. Knepley     }
330e77ac854SMatthew G. Knepley   }
331e77ac854SMatthew G. Knepley   PetscFunctionReturn(0);
332e77ac854SMatthew G. Knepley }
333e77ac854SMatthew G. Knepley 
33468260fa0SJed Brown /*@C
33568260fa0SJed Brown    DMGetNamedGlobalVector - get access to a named, persistent global vector
33668260fa0SJed Brown 
337d083f849SBarry Smith    Collective on dm
33868260fa0SJed Brown 
3394165533cSJose E. Roman    Input Parameters:
34068260fa0SJed Brown +  dm - DM to hold named vectors
34168260fa0SJed Brown -  name - unique name for Vec
34268260fa0SJed Brown 
3434165533cSJose E. Roman    Output Parameter:
34468260fa0SJed Brown .  X - named Vec
34568260fa0SJed Brown 
34668260fa0SJed Brown    Level: developer
34768260fa0SJed Brown 
34868260fa0SJed Brown    Note: If a Vec with the given name does not exist, it is created.
34968260fa0SJed Brown 
350db781477SPatrick Sanan .seealso: `DMRestoreNamedGlobalVector()`
35168260fa0SJed Brown @*/
352d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNamedGlobalVector(DM dm, const char *name, Vec *X)
353d71ae5a4SJacob Faibussowitsch {
35468260fa0SJed Brown   DMNamedVecLink link;
35568260fa0SJed Brown 
35668260fa0SJed Brown   PetscFunctionBegin;
35768260fa0SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
35868260fa0SJed Brown   PetscValidCharPointer(name, 2);
35968260fa0SJed Brown   PetscValidPointer(X, 3);
36068260fa0SJed Brown   for (link = dm->namedglobal; link; link = link->next) {
36168260fa0SJed Brown     PetscBool match;
3626eb26441SStefano Zampini 
3639566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name, link->name, &match));
36468260fa0SJed Brown     if (match) {
3656eb26441SStefano Zampini       DM vdm;
3666eb26441SStefano Zampini 
36708401ef6SPierre Jolivet       PetscCheck(link->status == DMVEC_STATUS_IN, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Vec name '%s' already checked out", name);
3689566063dSJacob Faibussowitsch       PetscCall(VecGetDM(link->X, &vdm));
36928b400f6SJacob Faibussowitsch       PetscCheck(!vdm, PetscObjectComm((PetscObject)vdm), PETSC_ERR_LIB, "Invalid vector");
3709566063dSJacob Faibussowitsch       PetscCall(VecSetDM(link->X, dm));
37168260fa0SJed Brown       goto found;
37268260fa0SJed Brown     }
37368260fa0SJed Brown   }
37468260fa0SJed Brown 
37568260fa0SJed Brown   /* Create the Vec */
3769566063dSJacob Faibussowitsch   PetscCall(PetscNew(&link));
3779566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, &link->name));
3789566063dSJacob Faibussowitsch   PetscCall(DMCreateGlobalVector(dm, &link->X));
37968260fa0SJed Brown   link->next      = dm->namedglobal;
38068260fa0SJed Brown   dm->namedglobal = link;
38168260fa0SJed Brown 
38268260fa0SJed Brown found:
38368260fa0SJed Brown   *X           = link->X;
38468260fa0SJed Brown   link->status = DMVEC_STATUS_OUT;
38568260fa0SJed Brown   PetscFunctionReturn(0);
38668260fa0SJed Brown }
38768260fa0SJed Brown 
38868260fa0SJed Brown /*@C
38968260fa0SJed Brown    DMRestoreNamedGlobalVector - restore access to a named, persistent global vector
39068260fa0SJed Brown 
391d083f849SBarry Smith    Collective on dm
39268260fa0SJed Brown 
3934165533cSJose E. Roman    Input Parameters:
39468260fa0SJed Brown +  dm - DM on which the vector was gotten
39568260fa0SJed Brown .  name - name under which the vector was gotten
39668260fa0SJed Brown -  X - Vec to restore
39768260fa0SJed Brown 
39868260fa0SJed Brown    Level: developer
39968260fa0SJed Brown 
400db781477SPatrick Sanan .seealso: `DMGetNamedGlobalVector()`
40168260fa0SJed Brown @*/
402d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRestoreNamedGlobalVector(DM dm, const char *name, Vec *X)
403d71ae5a4SJacob Faibussowitsch {
40468260fa0SJed Brown   DMNamedVecLink link;
40568260fa0SJed Brown 
40668260fa0SJed Brown   PetscFunctionBegin;
40768260fa0SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
40868260fa0SJed Brown   PetscValidCharPointer(name, 2);
40968260fa0SJed Brown   PetscValidPointer(X, 3);
41068260fa0SJed Brown   PetscValidHeaderSpecific(*X, VEC_CLASSID, 3);
41168260fa0SJed Brown   for (link = dm->namedglobal; link; link = link->next) {
41268260fa0SJed Brown     PetscBool match;
4136eb26441SStefano Zampini 
4149566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name, link->name, &match));
41568260fa0SJed Brown     if (match) {
4166eb26441SStefano Zampini       DM vdm;
4176eb26441SStefano Zampini 
4189566063dSJacob Faibussowitsch       PetscCall(VecGetDM(*X, &vdm));
41908401ef6SPierre Jolivet       PetscCheck(link->status == DMVEC_STATUS_OUT, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Vec name '%s' was not checked out", name);
42008401ef6SPierre Jolivet       PetscCheck(link->X == *X, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_INCOMP, "Attempt to restore Vec name '%s', but Vec does not match the cache", name);
42108401ef6SPierre Jolivet       PetscCheck(vdm == dm, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Invalid vector");
4226eb26441SStefano Zampini 
42368260fa0SJed Brown       link->status = DMVEC_STATUS_IN;
4249566063dSJacob Faibussowitsch       PetscCall(VecSetDM(link->X, NULL));
4250298fd71SBarry Smith       *X = NULL;
42668260fa0SJed Brown       PetscFunctionReturn(0);
42768260fa0SJed Brown     }
42868260fa0SJed Brown   }
42998921bdaSJacob Faibussowitsch   SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_INCOMP, "Could not find Vec name '%s' to restore", name);
43068260fa0SJed Brown }
4312348bcf4SPeter Brune 
432e77ac854SMatthew G. Knepley /*@C
433e77ac854SMatthew G. Knepley    DMHasNamedLocalVector - check for a named, persistent local vector
434e77ac854SMatthew G. Knepley 
435e77ac854SMatthew G. Knepley    Not Collective
436e77ac854SMatthew G. Knepley 
4374165533cSJose E. Roman    Input Parameters:
438e77ac854SMatthew G. Knepley +  dm - DM to hold named vectors
439e77ac854SMatthew G. Knepley -  name - unique name for Vec
440e77ac854SMatthew G. Knepley 
4414165533cSJose E. Roman    Output Parameter:
442e77ac854SMatthew G. Knepley .  exists - true if the vector was previously created
443e77ac854SMatthew G. Knepley 
444e77ac854SMatthew G. Knepley    Level: developer
445e77ac854SMatthew G. Knepley 
446e77ac854SMatthew G. Knepley    Note: If a Vec with the given name does not exist, it is created.
447e77ac854SMatthew G. Knepley 
448db781477SPatrick Sanan .seealso: `DMGetNamedGlobalVector()`, `DMRestoreNamedLocalVector()`
449e77ac854SMatthew G. Knepley @*/
450d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasNamedLocalVector(DM dm, const char *name, PetscBool *exists)
451d71ae5a4SJacob Faibussowitsch {
452e77ac854SMatthew G. Knepley   DMNamedVecLink link;
453e77ac854SMatthew G. Knepley 
454e77ac854SMatthew G. Knepley   PetscFunctionBegin;
455e77ac854SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
456e77ac854SMatthew G. Knepley   PetscValidCharPointer(name, 2);
457dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(exists, 3);
458e77ac854SMatthew G. Knepley   *exists = PETSC_FALSE;
459e77ac854SMatthew G. Knepley   for (link = dm->namedlocal; link; link = link->next) {
460e77ac854SMatthew G. Knepley     PetscBool match;
4619566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name, link->name, &match));
462e77ac854SMatthew G. Knepley     if (match) {
463e77ac854SMatthew G. Knepley       *exists = PETSC_TRUE;
464e77ac854SMatthew G. Knepley       break;
465e77ac854SMatthew G. Knepley     }
466e77ac854SMatthew G. Knepley   }
467e77ac854SMatthew G. Knepley   PetscFunctionReturn(0);
468e77ac854SMatthew G. Knepley }
469e77ac854SMatthew G. Knepley 
4702348bcf4SPeter Brune /*@C
4712348bcf4SPeter Brune    DMGetNamedLocalVector - get access to a named, persistent local vector
4722348bcf4SPeter Brune 
4732348bcf4SPeter Brune    Not Collective
4742348bcf4SPeter Brune 
4754165533cSJose E. Roman    Input Parameters:
4762348bcf4SPeter Brune +  dm - DM to hold named vectors
4772348bcf4SPeter Brune -  name - unique name for Vec
4782348bcf4SPeter Brune 
4794165533cSJose E. Roman    Output Parameter:
4802348bcf4SPeter Brune .  X - named Vec
4812348bcf4SPeter Brune 
4822348bcf4SPeter Brune    Level: developer
4832348bcf4SPeter Brune 
4842348bcf4SPeter Brune    Note: If a Vec with the given name does not exist, it is created.
4852348bcf4SPeter Brune 
486db781477SPatrick Sanan .seealso: `DMGetNamedGlobalVector()`, `DMRestoreNamedLocalVector()`
4872348bcf4SPeter Brune @*/
488d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNamedLocalVector(DM dm, const char *name, Vec *X)
489d71ae5a4SJacob Faibussowitsch {
4902348bcf4SPeter Brune   DMNamedVecLink link;
4912348bcf4SPeter Brune 
4922348bcf4SPeter Brune   PetscFunctionBegin;
4932348bcf4SPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4942348bcf4SPeter Brune   PetscValidCharPointer(name, 2);
4952348bcf4SPeter Brune   PetscValidPointer(X, 3);
4962348bcf4SPeter Brune   for (link = dm->namedlocal; link; link = link->next) {
4972348bcf4SPeter Brune     PetscBool match;
4986eb26441SStefano Zampini 
4999566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name, link->name, &match));
5002348bcf4SPeter Brune     if (match) {
5016eb26441SStefano Zampini       DM vdm;
5026eb26441SStefano Zampini 
50308401ef6SPierre Jolivet       PetscCheck(link->status == DMVEC_STATUS_IN, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Vec name '%s' already checked out", name);
5049566063dSJacob Faibussowitsch       PetscCall(VecGetDM(link->X, &vdm));
50528b400f6SJacob Faibussowitsch       PetscCheck(!vdm, PetscObjectComm((PetscObject)vdm), PETSC_ERR_LIB, "Invalid vector");
5069566063dSJacob Faibussowitsch       PetscCall(VecSetDM(link->X, dm));
5072348bcf4SPeter Brune       goto found;
5082348bcf4SPeter Brune     }
5092348bcf4SPeter Brune   }
5102348bcf4SPeter Brune 
5112348bcf4SPeter Brune   /* Create the Vec */
5129566063dSJacob Faibussowitsch   PetscCall(PetscNew(&link));
5139566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, &link->name));
5149566063dSJacob Faibussowitsch   PetscCall(DMCreateLocalVector(dm, &link->X));
5152348bcf4SPeter Brune   link->next     = dm->namedlocal;
5162348bcf4SPeter Brune   dm->namedlocal = link;
5172348bcf4SPeter Brune 
5182348bcf4SPeter Brune found:
5192348bcf4SPeter Brune   *X           = link->X;
5202348bcf4SPeter Brune   link->status = DMVEC_STATUS_OUT;
5212348bcf4SPeter Brune   PetscFunctionReturn(0);
5222348bcf4SPeter Brune }
5232348bcf4SPeter Brune 
5242348bcf4SPeter Brune /*@C
5252348bcf4SPeter Brune    DMRestoreNamedLocalVector - restore access to a named, persistent local vector
5262348bcf4SPeter Brune 
5272348bcf4SPeter Brune    Not Collective
5282348bcf4SPeter Brune 
5294165533cSJose E. Roman    Input Parameters:
5302348bcf4SPeter Brune +  dm - DM on which the vector was gotten
5312348bcf4SPeter Brune .  name - name under which the vector was gotten
5322348bcf4SPeter Brune -  X - Vec to restore
5332348bcf4SPeter Brune 
5342348bcf4SPeter Brune    Level: developer
5352348bcf4SPeter Brune 
536db781477SPatrick Sanan .seealso: `DMRestoreNamedGlobalVector()`, `DMGetNamedLocalVector()`
5372348bcf4SPeter Brune @*/
538d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRestoreNamedLocalVector(DM dm, const char *name, Vec *X)
539d71ae5a4SJacob Faibussowitsch {
5402348bcf4SPeter Brune   DMNamedVecLink link;
5412348bcf4SPeter Brune 
5422348bcf4SPeter Brune   PetscFunctionBegin;
5432348bcf4SPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5442348bcf4SPeter Brune   PetscValidCharPointer(name, 2);
5452348bcf4SPeter Brune   PetscValidPointer(X, 3);
5462348bcf4SPeter Brune   PetscValidHeaderSpecific(*X, VEC_CLASSID, 3);
5472348bcf4SPeter Brune   for (link = dm->namedlocal; link; link = link->next) {
5482348bcf4SPeter Brune     PetscBool match;
5496eb26441SStefano Zampini 
5509566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name, link->name, &match));
5512348bcf4SPeter Brune     if (match) {
5526eb26441SStefano Zampini       DM vdm;
5536eb26441SStefano Zampini 
5549566063dSJacob Faibussowitsch       PetscCall(VecGetDM(*X, &vdm));
55508401ef6SPierre Jolivet       PetscCheck(link->status == DMVEC_STATUS_OUT, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Vec name '%s' was not checked out", name);
55608401ef6SPierre Jolivet       PetscCheck(link->X == *X, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_INCOMP, "Attempt to restore Vec name '%s', but Vec does not match the cache", name);
55708401ef6SPierre Jolivet       PetscCheck(vdm == dm, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Invalid vector");
5586eb26441SStefano Zampini 
5592348bcf4SPeter Brune       link->status = DMVEC_STATUS_IN;
5609566063dSJacob Faibussowitsch       PetscCall(VecSetDM(link->X, NULL));
5610298fd71SBarry Smith       *X = NULL;
5622348bcf4SPeter Brune       PetscFunctionReturn(0);
5632348bcf4SPeter Brune     }
5642348bcf4SPeter Brune   }
56598921bdaSJacob Faibussowitsch   SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_INCOMP, "Could not find Vec name '%s' to restore", name);
5662348bcf4SPeter Brune }
567