xref: /petsc/src/dm/interface/dmget.c (revision 534a8f05a7a8aff70dd8cfd53d9cd834400a8dbf)
1af0996ceSBarry Smith #include <petsc/private/dmimpl.h> /*I "petscdm.h" I*/
268260fa0SJed Brown 
368260fa0SJed Brown /*@
468260fa0SJed Brown    DMGetLocalVector - Gets a Seq PETSc vector that
568260fa0SJed Brown    may be used with the DMXXX routines. This vector has spaces for the ghost values.
668260fa0SJed Brown 
768260fa0SJed Brown    Not Collective
868260fa0SJed Brown 
968260fa0SJed Brown    Input Parameter:
1068260fa0SJed Brown .  dm - the distributed array
1168260fa0SJed Brown 
1268260fa0SJed Brown    Output Parameter:
1368260fa0SJed Brown .  g - the local vector
1468260fa0SJed Brown 
1568260fa0SJed Brown    Level: beginner
1668260fa0SJed Brown 
1768260fa0SJed Brown    Note:
1868260fa0SJed Brown    The vector values are NOT initialized and may have garbage in them, so you may need
1968260fa0SJed Brown    to zero them.
2068260fa0SJed Brown 
2168260fa0SJed Brown    The output parameter, g, is a regular PETSc vector that should be returned with
2268260fa0SJed Brown    DMRestoreLocalVector() DO NOT call VecDestroy() on it.
2368260fa0SJed Brown 
24f1978aafSBarry Smith    This is intended to be used for vectors you need for a short time, like within a single function call.
25f1978aafSBarry Smith    For vectors that you intend to keep around (for example in a C struct) or pass around large parts of your
26f1978aafSBarry Smith    code you should use DMCreateLocalVector().
27f1978aafSBarry Smith 
2868260fa0SJed Brown    VecStride*() operations can be useful when using DM with dof > 1
2968260fa0SJed Brown 
3068260fa0SJed Brown .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
3168260fa0SJed Brown           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
3268260fa0SJed Brown           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector(),
3368260fa0SJed Brown           VecStrideMax(), VecStrideMin(), VecStrideNorm()
3468260fa0SJed Brown @*/
3568260fa0SJed Brown PetscErrorCode  DMGetLocalVector(DM dm,Vec *g)
3668260fa0SJed Brown {
3768260fa0SJed Brown   PetscErrorCode ierr,i;
3868260fa0SJed Brown 
3968260fa0SJed Brown   PetscFunctionBegin;
4068260fa0SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4168260fa0SJed Brown   PetscValidPointer(g,2);
4268260fa0SJed Brown   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
4368260fa0SJed Brown     if (dm->localin[i]) {
4468260fa0SJed Brown       *g             = dm->localin[i];
450298fd71SBarry Smith       dm->localin[i] = NULL;
4668260fa0SJed Brown       goto alldone;
4768260fa0SJed Brown     }
4868260fa0SJed Brown   }
4968260fa0SJed Brown   ierr = DMCreateLocalVector(dm,g);CHKERRQ(ierr);
5068260fa0SJed Brown 
5168260fa0SJed Brown alldone:
5268260fa0SJed Brown   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
5368260fa0SJed Brown     if (!dm->localout[i]) {
5468260fa0SJed Brown       dm->localout[i] = *g;
5568260fa0SJed Brown       break;
5668260fa0SJed Brown     }
5768260fa0SJed Brown   }
5868260fa0SJed Brown   PetscFunctionReturn(0);
5968260fa0SJed Brown }
6068260fa0SJed Brown 
6168260fa0SJed Brown /*@
6268260fa0SJed Brown    DMRestoreLocalVector - Returns a Seq PETSc vector that
6368260fa0SJed Brown      obtained from DMGetLocalVector(). Do not use with vector obtained via
6468260fa0SJed Brown      DMCreateLocalVector().
6568260fa0SJed Brown 
6668260fa0SJed Brown    Not Collective
6768260fa0SJed Brown 
6868260fa0SJed Brown    Input Parameter:
6968260fa0SJed Brown +  dm - the distributed array
7068260fa0SJed Brown -  g - the local vector
7168260fa0SJed Brown 
7268260fa0SJed Brown    Level: beginner
7368260fa0SJed Brown 
7468260fa0SJed Brown .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
7568260fa0SJed Brown           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
7668260fa0SJed Brown           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMGetLocalVector()
7768260fa0SJed Brown @*/
7868260fa0SJed Brown PetscErrorCode  DMRestoreLocalVector(DM dm,Vec *g)
7968260fa0SJed Brown {
8068260fa0SJed Brown   PetscErrorCode ierr;
8168260fa0SJed Brown   PetscInt       i,j;
8268260fa0SJed Brown 
8368260fa0SJed Brown   PetscFunctionBegin;
8468260fa0SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8568260fa0SJed Brown   PetscValidPointer(g,2);
8668260fa0SJed Brown   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
8768260fa0SJed Brown     if (*g == dm->localout[j]) {
880298fd71SBarry Smith       dm->localout[j] = NULL;
8968260fa0SJed Brown       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
9068260fa0SJed Brown         if (!dm->localin[i]) {
9168260fa0SJed Brown           dm->localin[i] = *g;
9268260fa0SJed Brown           goto alldone;
9368260fa0SJed Brown         }
9468260fa0SJed Brown       }
9568260fa0SJed Brown     }
9668260fa0SJed Brown   }
9768260fa0SJed Brown   ierr = VecDestroy(g);CHKERRQ(ierr);
9868260fa0SJed Brown alldone:
99dd6887adSBarry Smith   *g = NULL;
10068260fa0SJed Brown   PetscFunctionReturn(0);
10168260fa0SJed Brown }
10268260fa0SJed Brown 
10368260fa0SJed Brown /*@
10468260fa0SJed Brown    DMGetGlobalVector - Gets a MPI PETSc vector that
10568260fa0SJed Brown    may be used with the DMXXX routines.
10668260fa0SJed Brown 
107d083f849SBarry Smith    Collective on dm
10868260fa0SJed Brown 
10968260fa0SJed Brown    Input Parameter:
11068260fa0SJed Brown .  dm - the distributed array
11168260fa0SJed Brown 
11268260fa0SJed Brown    Output Parameter:
11368260fa0SJed Brown .  g - the global vector
11468260fa0SJed Brown 
11568260fa0SJed Brown    Level: beginner
11668260fa0SJed Brown 
11768260fa0SJed Brown    Note:
11868260fa0SJed Brown    The vector values are NOT initialized and may have garbage in them, so you may need
11968260fa0SJed Brown    to zero them.
12068260fa0SJed Brown 
12168260fa0SJed Brown    The output parameter, g, is a regular PETSc vector that should be returned with
12268260fa0SJed Brown    DMRestoreGlobalVector() DO NOT call VecDestroy() on it.
12368260fa0SJed Brown 
124f1978aafSBarry Smith    This is intended to be used for vectors you need for a short time, like within a single function call.
125f1978aafSBarry Smith    For vectors that you intend to keep around (for example in a C struct) or pass around large parts of your
126f1978aafSBarry Smith    code you should use DMCreateGlobalVector().
127f1978aafSBarry Smith 
12868260fa0SJed Brown    VecStride*() operations can be useful when using DM with dof > 1
12968260fa0SJed Brown 
13068260fa0SJed Brown .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
13168260fa0SJed Brown           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
13268260fa0SJed Brown           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
13368260fa0SJed Brown           VecStrideMax(), VecStrideMin(), VecStrideNorm()
13468260fa0SJed Brown 
13568260fa0SJed Brown @*/
13668260fa0SJed Brown PetscErrorCode  DMGetGlobalVector(DM dm,Vec *g)
13768260fa0SJed Brown {
13868260fa0SJed Brown   PetscErrorCode ierr;
13968260fa0SJed Brown   PetscInt       i;
14068260fa0SJed Brown 
14168260fa0SJed Brown   PetscFunctionBegin;
14268260fa0SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
14368260fa0SJed Brown   PetscValidPointer(g,2);
14468260fa0SJed Brown   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
14568260fa0SJed Brown     if (dm->globalin[i]) {
14668260fa0SJed Brown       *g              = dm->globalin[i];
1470298fd71SBarry Smith       dm->globalin[i] = NULL;
14868260fa0SJed Brown       goto alldone;
14968260fa0SJed Brown     }
15068260fa0SJed Brown   }
15168260fa0SJed Brown   ierr = DMCreateGlobalVector(dm,g);CHKERRQ(ierr);
15268260fa0SJed Brown 
15368260fa0SJed Brown alldone:
15468260fa0SJed Brown   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
15568260fa0SJed Brown     if (!dm->globalout[i]) {
15668260fa0SJed Brown       dm->globalout[i] = *g;
15768260fa0SJed Brown       break;
15868260fa0SJed Brown     }
15968260fa0SJed Brown   }
16068260fa0SJed Brown   PetscFunctionReturn(0);
16168260fa0SJed Brown }
16268260fa0SJed Brown 
16368260fa0SJed Brown /*@
16468260fa0SJed Brown    DMClearGlobalVectors - Destroys all the global vectors that have been stashed in this DM
16568260fa0SJed Brown 
166d083f849SBarry Smith    Collective on dm
16768260fa0SJed Brown 
16868260fa0SJed Brown    Input Parameter:
16968260fa0SJed Brown .  dm - the distributed array
17068260fa0SJed Brown 
17168260fa0SJed Brown    Level: developer
17268260fa0SJed Brown 
17368260fa0SJed Brown .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
17468260fa0SJed Brown           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
17568260fa0SJed Brown           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
17668260fa0SJed Brown           VecStrideMax(), VecStrideMin(), VecStrideNorm()
17768260fa0SJed Brown 
17868260fa0SJed Brown @*/
17968260fa0SJed Brown PetscErrorCode  DMClearGlobalVectors(DM dm)
18068260fa0SJed Brown {
18168260fa0SJed Brown   PetscErrorCode ierr;
18268260fa0SJed Brown   PetscInt       i;
18368260fa0SJed Brown 
18468260fa0SJed Brown   PetscFunctionBegin;
18568260fa0SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
18668260fa0SJed Brown   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
18762d839e9SJed Brown     Vec g;
18868260fa0SJed Brown     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()");
18962d839e9SJed Brown     g = dm->globalin[i];
19062d839e9SJed Brown     dm->globalin[i] = NULL;
19162d839e9SJed Brown     ierr = VecDestroy(&g);CHKERRQ(ierr);
19268260fa0SJed Brown   }
19368260fa0SJed Brown   PetscFunctionReturn(0);
19468260fa0SJed Brown }
19568260fa0SJed Brown 
19650eeb1caSToby Isaac /*@
19750eeb1caSToby Isaac    DMClearLocalVectors - Destroys all the local vectors that have been stashed in this DM
19850eeb1caSToby Isaac 
199d083f849SBarry Smith    Collective on dm
20050eeb1caSToby Isaac 
20150eeb1caSToby Isaac    Input Parameter:
20250eeb1caSToby Isaac .  dm - the distributed array
20350eeb1caSToby Isaac 
20450eeb1caSToby Isaac    Level: developer
20550eeb1caSToby Isaac 
20650eeb1caSToby Isaac .seealso: DMCreateLocalVector(), VecDuplicate(), VecDuplicateVecs(),
20750eeb1caSToby Isaac           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMLocalToLocalBegin(),
20850eeb1caSToby Isaac           DMLocalToLocalEnd(), DMLocalToLocalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
20950eeb1caSToby Isaac           VecStrideMax(), VecStrideMin(), VecStrideNorm()
21050eeb1caSToby Isaac 
21150eeb1caSToby Isaac @*/
21250eeb1caSToby Isaac PetscErrorCode  DMClearLocalVectors(DM dm)
21350eeb1caSToby Isaac {
21450eeb1caSToby Isaac   PetscErrorCode ierr;
21550eeb1caSToby Isaac   PetscInt       i;
21650eeb1caSToby Isaac 
21750eeb1caSToby Isaac   PetscFunctionBegin;
21850eeb1caSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
21950eeb1caSToby Isaac   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
22050eeb1caSToby Isaac     Vec g;
22150eeb1caSToby Isaac     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()");
22250eeb1caSToby Isaac     g = dm->localin[i];
22350eeb1caSToby Isaac     dm->localin[i] = NULL;
22450eeb1caSToby Isaac     ierr = VecDestroy(&g);CHKERRQ(ierr);
22550eeb1caSToby Isaac   }
22650eeb1caSToby Isaac   PetscFunctionReturn(0);
22750eeb1caSToby Isaac }
22850eeb1caSToby Isaac 
22968260fa0SJed Brown /*@
23068260fa0SJed Brown    DMRestoreGlobalVector - Returns a Seq PETSc vector that
23168260fa0SJed Brown      obtained from DMGetGlobalVector(). Do not use with vector obtained via
23268260fa0SJed Brown      DMCreateGlobalVector().
23368260fa0SJed Brown 
23468260fa0SJed Brown    Not Collective
23568260fa0SJed Brown 
23668260fa0SJed Brown    Input Parameter:
23768260fa0SJed Brown +  dm - the distributed array
23868260fa0SJed Brown -  g - the global vector
23968260fa0SJed Brown 
24068260fa0SJed Brown    Level: beginner
24168260fa0SJed Brown 
24268260fa0SJed Brown .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
24368260fa0SJed Brown           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(),
24468260fa0SJed Brown           DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
24568260fa0SJed Brown @*/
24668260fa0SJed Brown PetscErrorCode  DMRestoreGlobalVector(DM dm,Vec *g)
24768260fa0SJed Brown {
24868260fa0SJed Brown   PetscErrorCode ierr;
24968260fa0SJed Brown   PetscInt       i,j;
25068260fa0SJed Brown 
25168260fa0SJed Brown   PetscFunctionBegin;
25268260fa0SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
25368260fa0SJed Brown   PetscValidPointer(g,2);
25485ea3df1SSatish Balay   ierr = VecSetErrorIfLocked(*g, 2);CHKERRQ(ierr);
25568260fa0SJed Brown   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
25668260fa0SJed Brown     if (*g == dm->globalout[j]) {
2570298fd71SBarry Smith       dm->globalout[j] = NULL;
25868260fa0SJed Brown       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
25968260fa0SJed Brown         if (!dm->globalin[i]) {
26068260fa0SJed Brown           dm->globalin[i] = *g;
26168260fa0SJed Brown           goto alldone;
26268260fa0SJed Brown         }
26368260fa0SJed Brown       }
26468260fa0SJed Brown     }
26568260fa0SJed Brown   }
26668260fa0SJed Brown   ierr = VecDestroy(g);CHKERRQ(ierr);
26768260fa0SJed Brown alldone:
268dd6887adSBarry Smith   *g = NULL;
26968260fa0SJed Brown   PetscFunctionReturn(0);
27068260fa0SJed Brown }
27168260fa0SJed Brown 
272e77ac854SMatthew G. Knepley /*@C
273e77ac854SMatthew G. Knepley    DMHasNamedGlobalVector - check for a named, persistent global vector
274e77ac854SMatthew G. Knepley 
275e77ac854SMatthew G. Knepley    Not Collective
276e77ac854SMatthew G. Knepley 
277e77ac854SMatthew G. Knepley    Input Arguments:
278e77ac854SMatthew G. Knepley +  dm - DM to hold named vectors
279e77ac854SMatthew G. Knepley -  name - unique name for Vec
280e77ac854SMatthew G. Knepley 
281e77ac854SMatthew G. Knepley    Output Arguments:
282e77ac854SMatthew G. Knepley .  exists - true if the vector was previously created
283e77ac854SMatthew G. Knepley 
284e77ac854SMatthew G. Knepley    Level: developer
285e77ac854SMatthew G. Knepley 
286e77ac854SMatthew G. Knepley    Note: If a Vec with the given name does not exist, it is created.
287e77ac854SMatthew G. Knepley 
288e77ac854SMatthew G. Knepley .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
289e77ac854SMatthew G. Knepley @*/
290e77ac854SMatthew G. Knepley PetscErrorCode DMHasNamedGlobalVector(DM dm,const char *name,PetscBool *exists)
291e77ac854SMatthew G. Knepley {
292e77ac854SMatthew G. Knepley   PetscErrorCode ierr;
293e77ac854SMatthew G. Knepley   DMNamedVecLink link;
294e77ac854SMatthew G. Knepley 
295e77ac854SMatthew G. Knepley   PetscFunctionBegin;
296e77ac854SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
297e77ac854SMatthew G. Knepley   PetscValidCharPointer(name,2);
298*534a8f05SLisandro Dalcin   PetscValidBoolPointer(exists,3);
299e77ac854SMatthew G. Knepley   *exists = PETSC_FALSE;
300e77ac854SMatthew G. Knepley   for (link=dm->namedglobal; link; link=link->next) {
301e77ac854SMatthew G. Knepley     PetscBool match;
302e77ac854SMatthew G. Knepley     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
303e77ac854SMatthew G. Knepley     if (match) {
304e77ac854SMatthew G. Knepley       *exists = PETSC_TRUE;
305e77ac854SMatthew G. Knepley       break;
306e77ac854SMatthew G. Knepley     }
307e77ac854SMatthew G. Knepley   }
308e77ac854SMatthew G. Knepley   PetscFunctionReturn(0);
309e77ac854SMatthew G. Knepley }
310e77ac854SMatthew G. Knepley 
31168260fa0SJed Brown /*@C
31268260fa0SJed Brown    DMGetNamedGlobalVector - get access to a named, persistent global vector
31368260fa0SJed Brown 
314d083f849SBarry Smith    Collective on dm
31568260fa0SJed Brown 
31668260fa0SJed Brown    Input Arguments:
31768260fa0SJed Brown +  dm - DM to hold named vectors
31868260fa0SJed Brown -  name - unique name for Vec
31968260fa0SJed Brown 
32068260fa0SJed Brown    Output Arguments:
32168260fa0SJed Brown .  X - named Vec
32268260fa0SJed Brown 
32368260fa0SJed Brown    Level: developer
32468260fa0SJed Brown 
32568260fa0SJed Brown    Note: If a Vec with the given name does not exist, it is created.
32668260fa0SJed Brown 
32768260fa0SJed Brown .seealso: DMRestoreNamedGlobalVector()
32868260fa0SJed Brown @*/
32968260fa0SJed Brown PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
33068260fa0SJed Brown {
33168260fa0SJed Brown   PetscErrorCode ierr;
33268260fa0SJed Brown   DMNamedVecLink link;
33368260fa0SJed Brown 
33468260fa0SJed Brown   PetscFunctionBegin;
33568260fa0SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
33668260fa0SJed Brown   PetscValidCharPointer(name,2);
33768260fa0SJed Brown   PetscValidPointer(X,3);
33868260fa0SJed Brown   for (link=dm->namedglobal; link; link=link->next) {
33968260fa0SJed Brown     PetscBool match;
34068260fa0SJed Brown     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
34168260fa0SJed Brown     if (match) {
342ce94432eSBarry Smith       if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
34368260fa0SJed Brown       goto found;
34468260fa0SJed Brown     }
34568260fa0SJed Brown   }
34668260fa0SJed Brown 
34768260fa0SJed Brown   /* Create the Vec */
348854ce69bSBarry Smith   ierr            = PetscNew(&link);CHKERRQ(ierr);
34968260fa0SJed Brown   ierr            = PetscStrallocpy(name,&link->name);CHKERRQ(ierr);
35068260fa0SJed Brown   ierr            = DMCreateGlobalVector(dm,&link->X);CHKERRQ(ierr);
35168260fa0SJed Brown   link->next      = dm->namedglobal;
35268260fa0SJed Brown   dm->namedglobal = link;
35368260fa0SJed Brown 
35468260fa0SJed Brown found:
35568260fa0SJed Brown   *X           = link->X;
35668260fa0SJed Brown   link->status = DMVEC_STATUS_OUT;
35768260fa0SJed Brown   PetscFunctionReturn(0);
35868260fa0SJed Brown }
35968260fa0SJed Brown 
36068260fa0SJed Brown /*@C
36168260fa0SJed Brown    DMRestoreNamedGlobalVector - restore access to a named, persistent global vector
36268260fa0SJed Brown 
363d083f849SBarry Smith    Collective on dm
36468260fa0SJed Brown 
36568260fa0SJed Brown    Input Arguments:
36668260fa0SJed Brown +  dm - DM on which the vector was gotten
36768260fa0SJed Brown .  name - name under which the vector was gotten
36868260fa0SJed Brown -  X - Vec to restore
36968260fa0SJed Brown 
37068260fa0SJed Brown    Output Arguments:
37168260fa0SJed Brown 
37268260fa0SJed Brown    Level: developer
37368260fa0SJed Brown 
37468260fa0SJed Brown .seealso: DMGetNamedGlobalVector()
37568260fa0SJed Brown @*/
37668260fa0SJed Brown PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
37768260fa0SJed Brown {
37868260fa0SJed Brown   PetscErrorCode ierr;
37968260fa0SJed Brown   DMNamedVecLink link;
38068260fa0SJed Brown 
38168260fa0SJed Brown   PetscFunctionBegin;
38268260fa0SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
38368260fa0SJed Brown   PetscValidCharPointer(name,2);
38468260fa0SJed Brown   PetscValidPointer(X,3);
38568260fa0SJed Brown   PetscValidHeaderSpecific(*X,VEC_CLASSID,3);
38668260fa0SJed Brown   for (link=dm->namedglobal; link; link=link->next) {
38768260fa0SJed Brown     PetscBool match;
38868260fa0SJed Brown     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
38968260fa0SJed Brown     if (match) {
390ce94432eSBarry Smith       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
391ce94432eSBarry Smith       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);
39268260fa0SJed Brown       link->status = DMVEC_STATUS_IN;
3930298fd71SBarry Smith       *X           = NULL;
39468260fa0SJed Brown       PetscFunctionReturn(0);
39568260fa0SJed Brown     }
39668260fa0SJed Brown   }
397ce94432eSBarry Smith   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
39868260fa0SJed Brown   PetscFunctionReturn(0);
39968260fa0SJed Brown }
4002348bcf4SPeter Brune 
401e77ac854SMatthew G. Knepley /*@C
402e77ac854SMatthew G. Knepley    DMHasNamedLocalVector - check for a named, persistent local vector
403e77ac854SMatthew G. Knepley 
404e77ac854SMatthew G. Knepley    Not Collective
405e77ac854SMatthew G. Knepley 
406e77ac854SMatthew G. Knepley    Input Arguments:
407e77ac854SMatthew G. Knepley +  dm - DM to hold named vectors
408e77ac854SMatthew G. Knepley -  name - unique name for Vec
409e77ac854SMatthew G. Knepley 
410e77ac854SMatthew G. Knepley    Output Arguments:
411e77ac854SMatthew G. Knepley .  exists - true if the vector was previously created
412e77ac854SMatthew G. Knepley 
413e77ac854SMatthew G. Knepley    Level: developer
414e77ac854SMatthew G. Knepley 
415e77ac854SMatthew G. Knepley    Note: If a Vec with the given name does not exist, it is created.
416e77ac854SMatthew G. Knepley 
417e77ac854SMatthew G. Knepley .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
418e77ac854SMatthew G. Knepley @*/
419e77ac854SMatthew G. Knepley PetscErrorCode DMHasNamedLocalVector(DM dm,const char *name,PetscBool *exists)
420e77ac854SMatthew G. Knepley {
421e77ac854SMatthew G. Knepley   PetscErrorCode ierr;
422e77ac854SMatthew G. Knepley   DMNamedVecLink link;
423e77ac854SMatthew G. Knepley 
424e77ac854SMatthew G. Knepley   PetscFunctionBegin;
425e77ac854SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
426e77ac854SMatthew G. Knepley   PetscValidCharPointer(name,2);
427e77ac854SMatthew G. Knepley   PetscValidPointer(exists,3);
428e77ac854SMatthew G. Knepley   *exists = PETSC_FALSE;
429e77ac854SMatthew G. Knepley   for (link=dm->namedlocal; link; link=link->next) {
430e77ac854SMatthew G. Knepley     PetscBool match;
431e77ac854SMatthew G. Knepley     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
432e77ac854SMatthew G. Knepley     if (match) {
433e77ac854SMatthew G. Knepley       *exists = PETSC_TRUE;
434e77ac854SMatthew G. Knepley       break;
435e77ac854SMatthew G. Knepley     }
436e77ac854SMatthew G. Knepley   }
437e77ac854SMatthew G. Knepley   PetscFunctionReturn(0);
438e77ac854SMatthew G. Knepley }
439e77ac854SMatthew G. Knepley 
4402348bcf4SPeter Brune /*@C
4412348bcf4SPeter Brune    DMGetNamedLocalVector - get access to a named, persistent local vector
4422348bcf4SPeter Brune 
4432348bcf4SPeter Brune    Not Collective
4442348bcf4SPeter Brune 
4452348bcf4SPeter Brune    Input Arguments:
4462348bcf4SPeter Brune +  dm - DM to hold named vectors
4472348bcf4SPeter Brune -  name - unique name for Vec
4482348bcf4SPeter Brune 
4492348bcf4SPeter Brune    Output Arguments:
4502348bcf4SPeter Brune .  X - named Vec
4512348bcf4SPeter Brune 
4522348bcf4SPeter Brune    Level: developer
4532348bcf4SPeter Brune 
4542348bcf4SPeter Brune    Note: If a Vec with the given name does not exist, it is created.
4552348bcf4SPeter Brune 
4562348bcf4SPeter Brune .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
4572348bcf4SPeter Brune @*/
4582348bcf4SPeter Brune PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
4592348bcf4SPeter Brune {
4602348bcf4SPeter Brune   PetscErrorCode ierr;
4612348bcf4SPeter Brune   DMNamedVecLink link;
4622348bcf4SPeter Brune 
4632348bcf4SPeter Brune   PetscFunctionBegin;
4642348bcf4SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4652348bcf4SPeter Brune   PetscValidCharPointer(name,2);
4662348bcf4SPeter Brune   PetscValidPointer(X,3);
4672348bcf4SPeter Brune   for (link=dm->namedlocal; link; link=link->next) {
4682348bcf4SPeter Brune     PetscBool match;
4692348bcf4SPeter Brune     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
4702348bcf4SPeter Brune     if (match) {
471ce94432eSBarry Smith       if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
4722348bcf4SPeter Brune       goto found;
4732348bcf4SPeter Brune     }
4742348bcf4SPeter Brune   }
4752348bcf4SPeter Brune 
4762348bcf4SPeter Brune   /* Create the Vec */
477854ce69bSBarry Smith   ierr           = PetscNew(&link);CHKERRQ(ierr);
4782348bcf4SPeter Brune   ierr           = PetscStrallocpy(name,&link->name);CHKERRQ(ierr);
4792348bcf4SPeter Brune   ierr           = DMCreateLocalVector(dm,&link->X);CHKERRQ(ierr);
4802348bcf4SPeter Brune   link->next     = dm->namedlocal;
4812348bcf4SPeter Brune   dm->namedlocal = link;
4822348bcf4SPeter Brune 
4832348bcf4SPeter Brune found:
4842348bcf4SPeter Brune   *X           = link->X;
4852348bcf4SPeter Brune   link->status = DMVEC_STATUS_OUT;
4862348bcf4SPeter Brune   PetscFunctionReturn(0);
4872348bcf4SPeter Brune }
4882348bcf4SPeter Brune 
4892348bcf4SPeter Brune /*@C
4902348bcf4SPeter Brune    DMRestoreNamedLocalVector - restore access to a named, persistent local vector
4912348bcf4SPeter Brune 
4922348bcf4SPeter Brune    Not Collective
4932348bcf4SPeter Brune 
4942348bcf4SPeter Brune    Input Arguments:
4952348bcf4SPeter Brune +  dm - DM on which the vector was gotten
4962348bcf4SPeter Brune .  name - name under which the vector was gotten
4972348bcf4SPeter Brune -  X - Vec to restore
4982348bcf4SPeter Brune 
4992348bcf4SPeter Brune    Output Arguments:
5002348bcf4SPeter Brune 
5012348bcf4SPeter Brune    Level: developer
5022348bcf4SPeter Brune 
5032348bcf4SPeter Brune .seealso: DMRestoreNamedGlobalVector(),DMGetNamedLocalVector()
5042348bcf4SPeter Brune @*/
5052348bcf4SPeter Brune PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
5062348bcf4SPeter Brune {
5072348bcf4SPeter Brune   PetscErrorCode ierr;
5082348bcf4SPeter Brune   DMNamedVecLink link;
5092348bcf4SPeter Brune 
5102348bcf4SPeter Brune   PetscFunctionBegin;
5112348bcf4SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5122348bcf4SPeter Brune   PetscValidCharPointer(name,2);
5132348bcf4SPeter Brune   PetscValidPointer(X,3);
5142348bcf4SPeter Brune   PetscValidHeaderSpecific(*X,VEC_CLASSID,3);
5152348bcf4SPeter Brune   for (link=dm->namedlocal; link; link=link->next) {
5162348bcf4SPeter Brune     PetscBool match;
5172348bcf4SPeter Brune     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
5182348bcf4SPeter Brune     if (match) {
519ce94432eSBarry Smith       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
520ce94432eSBarry Smith       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);
5212348bcf4SPeter Brune       link->status = DMVEC_STATUS_IN;
5220298fd71SBarry Smith       *X           = NULL;
5232348bcf4SPeter Brune       PetscFunctionReturn(0);
5242348bcf4SPeter Brune     }
5252348bcf4SPeter Brune   }
526ce94432eSBarry Smith   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
5272348bcf4SPeter Brune   PetscFunctionReturn(0);
5282348bcf4SPeter Brune }
529