xref: /petsc/src/dm/interface/dmget.c (revision 2348bcf450f00165f06595d70d3a653940f84aed)
168260fa0SJed Brown #include <petsc-private/dmimpl.h> /*I "petscdm.h" I*/
268260fa0SJed Brown 
368260fa0SJed Brown #undef __FUNCT__
468260fa0SJed Brown #define __FUNCT__ "DMGetLocalVector"
568260fa0SJed Brown /*@
668260fa0SJed Brown    DMGetLocalVector - Gets a Seq PETSc vector that
768260fa0SJed Brown    may be used with the DMXXX routines. This vector has spaces for the ghost values.
868260fa0SJed Brown 
968260fa0SJed Brown    Not Collective
1068260fa0SJed Brown 
1168260fa0SJed Brown    Input Parameter:
1268260fa0SJed Brown .  dm - the distributed array
1368260fa0SJed Brown 
1468260fa0SJed Brown    Output Parameter:
1568260fa0SJed Brown .  g - the local vector
1668260fa0SJed Brown 
1768260fa0SJed Brown    Level: beginner
1868260fa0SJed Brown 
1968260fa0SJed Brown    Note:
2068260fa0SJed Brown    The vector values are NOT initialized and may have garbage in them, so you may need
2168260fa0SJed Brown    to zero them.
2268260fa0SJed Brown 
2368260fa0SJed Brown    The output parameter, g, is a regular PETSc vector that should be returned with
2468260fa0SJed Brown    DMRestoreLocalVector() DO NOT call VecDestroy() on it.
2568260fa0SJed Brown 
2668260fa0SJed Brown    VecStride*() operations can be useful when using DM with dof > 1
2768260fa0SJed Brown 
2868260fa0SJed Brown .keywords: distributed array, create, local, vector
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];
4568260fa0SJed Brown       dm->localin[i] = PETSC_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 #undef __FUNCT__
6268260fa0SJed Brown #define __FUNCT__ "DMRestoreLocalVector"
6368260fa0SJed Brown /*@
6468260fa0SJed Brown    DMRestoreLocalVector - Returns a Seq PETSc vector that
6568260fa0SJed Brown      obtained from DMGetLocalVector(). Do not use with vector obtained via
6668260fa0SJed Brown      DMCreateLocalVector().
6768260fa0SJed Brown 
6868260fa0SJed Brown    Not Collective
6968260fa0SJed Brown 
7068260fa0SJed Brown    Input Parameter:
7168260fa0SJed Brown +  dm - the distributed array
7268260fa0SJed Brown -  g - the local vector
7368260fa0SJed Brown 
7468260fa0SJed Brown    Level: beginner
7568260fa0SJed Brown 
7668260fa0SJed Brown .keywords: distributed array, create, local, vector
7768260fa0SJed Brown 
7868260fa0SJed Brown .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
7968260fa0SJed Brown           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
8068260fa0SJed Brown           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMGetLocalVector()
8168260fa0SJed Brown @*/
8268260fa0SJed Brown PetscErrorCode  DMRestoreLocalVector(DM dm,Vec* g)
8368260fa0SJed Brown {
8468260fa0SJed Brown   PetscErrorCode ierr;
8568260fa0SJed Brown   PetscInt       i,j;
8668260fa0SJed Brown 
8768260fa0SJed Brown   PetscFunctionBegin;
8868260fa0SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8968260fa0SJed Brown   PetscValidPointer(g,2);
9068260fa0SJed Brown   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
9168260fa0SJed Brown     if (*g == dm->localout[j]) {
9268260fa0SJed Brown       dm->localout[j] = PETSC_NULL;
9368260fa0SJed Brown       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
9468260fa0SJed Brown         if (!dm->localin[i]) {
9568260fa0SJed Brown           dm->localin[i] = *g;
9668260fa0SJed Brown           goto alldone;
9768260fa0SJed Brown         }
9868260fa0SJed Brown       }
9968260fa0SJed Brown     }
10068260fa0SJed Brown   }
10168260fa0SJed Brown   ierr = VecDestroy(g);CHKERRQ(ierr);
10268260fa0SJed Brown   alldone:
10368260fa0SJed Brown   PetscFunctionReturn(0);
10468260fa0SJed Brown }
10568260fa0SJed Brown 
10668260fa0SJed Brown #undef __FUNCT__
10768260fa0SJed Brown #define __FUNCT__ "DMGetGlobalVector"
10868260fa0SJed Brown /*@
10968260fa0SJed Brown    DMGetGlobalVector - Gets a MPI PETSc vector that
11068260fa0SJed Brown    may be used with the DMXXX routines.
11168260fa0SJed Brown 
11268260fa0SJed Brown    Collective on DM
11368260fa0SJed Brown 
11468260fa0SJed Brown    Input Parameter:
11568260fa0SJed Brown .  dm - the distributed array
11668260fa0SJed Brown 
11768260fa0SJed Brown    Output Parameter:
11868260fa0SJed Brown .  g - the global vector
11968260fa0SJed Brown 
12068260fa0SJed Brown    Level: beginner
12168260fa0SJed Brown 
12268260fa0SJed Brown    Note:
12368260fa0SJed Brown    The vector values are NOT initialized and may have garbage in them, so you may need
12468260fa0SJed Brown    to zero them.
12568260fa0SJed Brown 
12668260fa0SJed Brown    The output parameter, g, is a regular PETSc vector that should be returned with
12768260fa0SJed Brown    DMRestoreGlobalVector() DO NOT call VecDestroy() on it.
12868260fa0SJed Brown 
12968260fa0SJed Brown    VecStride*() operations can be useful when using DM with dof > 1
13068260fa0SJed Brown 
13168260fa0SJed Brown .keywords: distributed array, create, Global, vector
13268260fa0SJed Brown 
13368260fa0SJed Brown .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
13468260fa0SJed Brown           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
13568260fa0SJed Brown           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
13668260fa0SJed Brown           VecStrideMax(), VecStrideMin(), VecStrideNorm()
13768260fa0SJed Brown 
13868260fa0SJed Brown @*/
13968260fa0SJed Brown PetscErrorCode  DMGetGlobalVector(DM dm,Vec* g)
14068260fa0SJed Brown {
14168260fa0SJed Brown   PetscErrorCode ierr;
14268260fa0SJed Brown   PetscInt       i;
14368260fa0SJed Brown 
14468260fa0SJed Brown   PetscFunctionBegin;
14568260fa0SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
14668260fa0SJed Brown   PetscValidPointer(g,2);
14768260fa0SJed Brown   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
14868260fa0SJed Brown     if (dm->globalin[i]) {
14968260fa0SJed Brown       *g             = dm->globalin[i];
15068260fa0SJed Brown       dm->globalin[i] = PETSC_NULL;
15168260fa0SJed Brown       goto alldone;
15268260fa0SJed Brown     }
15368260fa0SJed Brown   }
15468260fa0SJed Brown   ierr = DMCreateGlobalVector(dm,g);CHKERRQ(ierr);
15568260fa0SJed Brown 
15668260fa0SJed Brown   alldone:
15768260fa0SJed Brown   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
15868260fa0SJed Brown     if (!dm->globalout[i]) {
15968260fa0SJed Brown       dm->globalout[i] = *g;
16068260fa0SJed Brown       break;
16168260fa0SJed Brown     }
16268260fa0SJed Brown   }
16368260fa0SJed Brown   PetscFunctionReturn(0);
16468260fa0SJed Brown }
16568260fa0SJed Brown 
16668260fa0SJed Brown #undef __FUNCT__
16768260fa0SJed Brown #define __FUNCT__ "DMClearGlobalVectors"
16868260fa0SJed Brown /*@
16968260fa0SJed Brown    DMClearGlobalVectors - Destroys all the global vectors that have been stashed in this DM
17068260fa0SJed Brown 
17168260fa0SJed Brown    Collective on DM
17268260fa0SJed Brown 
17368260fa0SJed Brown    Input Parameter:
17468260fa0SJed Brown .  dm - the distributed array
17568260fa0SJed Brown 
17668260fa0SJed Brown    Level: developer
17768260fa0SJed Brown 
17868260fa0SJed Brown .keywords: distributed array, create, Global, vector
17968260fa0SJed Brown 
18068260fa0SJed Brown .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
18168260fa0SJed Brown           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
18268260fa0SJed Brown           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
18368260fa0SJed Brown           VecStrideMax(), VecStrideMin(), VecStrideNorm()
18468260fa0SJed Brown 
18568260fa0SJed Brown @*/
18668260fa0SJed Brown PetscErrorCode  DMClearGlobalVectors(DM dm)
18768260fa0SJed Brown {
18868260fa0SJed Brown   PetscErrorCode ierr;
18968260fa0SJed Brown   PetscInt       i;
19068260fa0SJed Brown 
19168260fa0SJed Brown   PetscFunctionBegin;
19268260fa0SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
19368260fa0SJed Brown   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
19468260fa0SJed 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()");
19568260fa0SJed Brown     ierr = VecDestroy(&dm->globalin[i]);CHKERRQ(ierr);
19668260fa0SJed Brown   }
19768260fa0SJed Brown   PetscFunctionReturn(0);
19868260fa0SJed Brown }
19968260fa0SJed Brown 
20068260fa0SJed Brown #undef __FUNCT__
20168260fa0SJed Brown #define __FUNCT__ "DMRestoreGlobalVector"
20268260fa0SJed Brown /*@
20368260fa0SJed Brown    DMRestoreGlobalVector - Returns a Seq PETSc vector that
20468260fa0SJed Brown      obtained from DMGetGlobalVector(). Do not use with vector obtained via
20568260fa0SJed Brown      DMCreateGlobalVector().
20668260fa0SJed Brown 
20768260fa0SJed Brown    Not Collective
20868260fa0SJed Brown 
20968260fa0SJed Brown    Input Parameter:
21068260fa0SJed Brown +  dm - the distributed array
21168260fa0SJed Brown -  g - the global vector
21268260fa0SJed Brown 
21368260fa0SJed Brown    Level: beginner
21468260fa0SJed Brown 
21568260fa0SJed Brown .keywords: distributed array, create, global, vector
21668260fa0SJed Brown 
21768260fa0SJed Brown .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
21868260fa0SJed Brown           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(),
21968260fa0SJed Brown           DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
22068260fa0SJed Brown @*/
22168260fa0SJed Brown PetscErrorCode  DMRestoreGlobalVector(DM dm,Vec* g)
22268260fa0SJed Brown {
22368260fa0SJed Brown   PetscErrorCode ierr;
22468260fa0SJed Brown   PetscInt       i,j;
22568260fa0SJed Brown 
22668260fa0SJed Brown   PetscFunctionBegin;
22768260fa0SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
22868260fa0SJed Brown   PetscValidPointer(g,2);
22968260fa0SJed Brown   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
23068260fa0SJed Brown     if (*g == dm->globalout[j]) {
23168260fa0SJed Brown       dm->globalout[j] = PETSC_NULL;
23268260fa0SJed Brown       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
23368260fa0SJed Brown         if (!dm->globalin[i]) {
23468260fa0SJed Brown           dm->globalin[i] = *g;
23568260fa0SJed Brown           goto alldone;
23668260fa0SJed Brown         }
23768260fa0SJed Brown       }
23868260fa0SJed Brown     }
23968260fa0SJed Brown   }
24068260fa0SJed Brown   ierr = VecDestroy(g);CHKERRQ(ierr);
24168260fa0SJed Brown   alldone:
24268260fa0SJed Brown   PetscFunctionReturn(0);
24368260fa0SJed Brown }
24468260fa0SJed Brown 
24568260fa0SJed Brown #undef __FUNCT__
24668260fa0SJed Brown #define __FUNCT__ "DMGetNamedGlobalVector"
24768260fa0SJed Brown /*@C
24868260fa0SJed Brown    DMGetNamedGlobalVector - get access to a named, persistent global vector
24968260fa0SJed Brown 
25068260fa0SJed Brown    Collective on DM
25168260fa0SJed Brown 
25268260fa0SJed Brown    Input Arguments:
25368260fa0SJed Brown +  dm - DM to hold named vectors
25468260fa0SJed Brown -  name - unique name for Vec
25568260fa0SJed Brown 
25668260fa0SJed Brown    Output Arguments:
25768260fa0SJed Brown .  X - named Vec
25868260fa0SJed Brown 
25968260fa0SJed Brown    Level: developer
26068260fa0SJed Brown 
26168260fa0SJed Brown    Note: If a Vec with the given name does not exist, it is created.
26268260fa0SJed Brown 
26368260fa0SJed Brown .seealso: DMRestoreNamedGlobalVector()
26468260fa0SJed Brown @*/
26568260fa0SJed Brown PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
26668260fa0SJed Brown {
26768260fa0SJed Brown   PetscErrorCode ierr;
26868260fa0SJed Brown   DMNamedVecLink link;
26968260fa0SJed Brown 
27068260fa0SJed Brown   PetscFunctionBegin;
27168260fa0SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
27268260fa0SJed Brown   PetscValidCharPointer(name,2);
27368260fa0SJed Brown   PetscValidPointer(X,3);
27468260fa0SJed Brown   for (link=dm->namedglobal; link; link=link->next) {
27568260fa0SJed Brown     PetscBool match;
27668260fa0SJed Brown     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
27768260fa0SJed Brown     if (match) {
27868260fa0SJed Brown       if (link->status != DMVEC_STATUS_IN) SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
27968260fa0SJed Brown       goto found;
28068260fa0SJed Brown     }
28168260fa0SJed Brown   }
28268260fa0SJed Brown 
28368260fa0SJed Brown   /* Create the Vec */
2848caf3d72SBarry Smith   ierr = PetscMalloc(sizeof(*link),&link);CHKERRQ(ierr);
28568260fa0SJed Brown   ierr = PetscStrallocpy(name,&link->name);CHKERRQ(ierr);
28668260fa0SJed Brown   ierr = DMCreateGlobalVector(dm,&link->X);CHKERRQ(ierr);
28768260fa0SJed Brown   link->next = dm->namedglobal;
28868260fa0SJed Brown   dm->namedglobal = link;
28968260fa0SJed Brown 
29068260fa0SJed Brown   found:
29168260fa0SJed Brown   *X = link->X;
29268260fa0SJed Brown   link->status = DMVEC_STATUS_OUT;
29368260fa0SJed Brown   PetscFunctionReturn(0);
29468260fa0SJed Brown }
29568260fa0SJed Brown 
29668260fa0SJed Brown #undef __FUNCT__
29768260fa0SJed Brown #define __FUNCT__ "DMRestoreNamedGlobalVector"
29868260fa0SJed Brown /*@C
29968260fa0SJed Brown    DMRestoreNamedGlobalVector - restore access to a named, persistent global vector
30068260fa0SJed Brown 
30168260fa0SJed Brown    Collective on DM
30268260fa0SJed Brown 
30368260fa0SJed Brown    Input Arguments:
30468260fa0SJed Brown +  dm - DM on which the vector was gotten
30568260fa0SJed Brown .  name - name under which the vector was gotten
30668260fa0SJed Brown -  X - Vec to restore
30768260fa0SJed Brown 
30868260fa0SJed Brown    Output Arguments:
30968260fa0SJed Brown 
31068260fa0SJed Brown    Level: developer
31168260fa0SJed Brown 
31268260fa0SJed Brown .seealso: DMGetNamedGlobalVector()
31368260fa0SJed Brown @*/
31468260fa0SJed Brown PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
31568260fa0SJed Brown {
31668260fa0SJed Brown   PetscErrorCode ierr;
31768260fa0SJed Brown   DMNamedVecLink link;
31868260fa0SJed Brown 
31968260fa0SJed Brown   PetscFunctionBegin;
32068260fa0SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
32168260fa0SJed Brown   PetscValidCharPointer(name,2);
32268260fa0SJed Brown   PetscValidPointer(X,3);
32368260fa0SJed Brown   PetscValidHeaderSpecific(*X,VEC_CLASSID,3);
32468260fa0SJed Brown   for (link=dm->namedglobal; link; link=link->next) {
32568260fa0SJed Brown     PetscBool match;
32668260fa0SJed Brown     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
32768260fa0SJed Brown     if (match) {
32868260fa0SJed Brown       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
32968260fa0SJed Brown       if (link->X != *X) SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_INCOMP,"Attempt to restore Vec name '%s', but Vec does not match the cache",name);
33068260fa0SJed Brown       link->status = DMVEC_STATUS_IN;
33168260fa0SJed Brown       *X = PETSC_NULL;
33268260fa0SJed Brown       PetscFunctionReturn(0);
33368260fa0SJed Brown     }
33468260fa0SJed Brown   }
33568260fa0SJed Brown   SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
33668260fa0SJed Brown   PetscFunctionReturn(0);
33768260fa0SJed Brown }
338*2348bcf4SPeter Brune 
339*2348bcf4SPeter Brune #undef __FUNCT__
340*2348bcf4SPeter Brune #define __FUNCT__ "DMGetNamedLocalVector"
341*2348bcf4SPeter Brune /*@C
342*2348bcf4SPeter Brune    DMGetNamedLocalVector - get access to a named, persistent local vector
343*2348bcf4SPeter Brune 
344*2348bcf4SPeter Brune    Not Collective
345*2348bcf4SPeter Brune 
346*2348bcf4SPeter Brune    Input Arguments:
347*2348bcf4SPeter Brune +  dm - DM to hold named vectors
348*2348bcf4SPeter Brune -  name - unique name for Vec
349*2348bcf4SPeter Brune 
350*2348bcf4SPeter Brune    Output Arguments:
351*2348bcf4SPeter Brune .  X - named Vec
352*2348bcf4SPeter Brune 
353*2348bcf4SPeter Brune    Level: developer
354*2348bcf4SPeter Brune 
355*2348bcf4SPeter Brune    Note: If a Vec with the given name does not exist, it is created.
356*2348bcf4SPeter Brune 
357*2348bcf4SPeter Brune .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
358*2348bcf4SPeter Brune @*/
359*2348bcf4SPeter Brune PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
360*2348bcf4SPeter Brune {
361*2348bcf4SPeter Brune   PetscErrorCode ierr;
362*2348bcf4SPeter Brune   DMNamedVecLink link;
363*2348bcf4SPeter Brune 
364*2348bcf4SPeter Brune   PetscFunctionBegin;
365*2348bcf4SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
366*2348bcf4SPeter Brune   PetscValidCharPointer(name,2);
367*2348bcf4SPeter Brune   PetscValidPointer(X,3);
368*2348bcf4SPeter Brune   for (link=dm->namedlocal; link; link=link->next) {
369*2348bcf4SPeter Brune     PetscBool match;
370*2348bcf4SPeter Brune     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
371*2348bcf4SPeter Brune     if (match) {
372*2348bcf4SPeter Brune       if (link->status != DMVEC_STATUS_IN) SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
373*2348bcf4SPeter Brune       goto found;
374*2348bcf4SPeter Brune     }
375*2348bcf4SPeter Brune   }
376*2348bcf4SPeter Brune 
377*2348bcf4SPeter Brune   /* Create the Vec */
378*2348bcf4SPeter Brune   ierr = PetscMalloc(sizeof(*link),&link);CHKERRQ(ierr);
379*2348bcf4SPeter Brune   ierr = PetscStrallocpy(name,&link->name);CHKERRQ(ierr);
380*2348bcf4SPeter Brune   ierr = DMCreateLocalVector(dm,&link->X);CHKERRQ(ierr);
381*2348bcf4SPeter Brune   link->next = dm->namedlocal;
382*2348bcf4SPeter Brune   dm->namedlocal = link;
383*2348bcf4SPeter Brune 
384*2348bcf4SPeter Brune   found:
385*2348bcf4SPeter Brune   *X = link->X;
386*2348bcf4SPeter Brune   link->status = DMVEC_STATUS_OUT;
387*2348bcf4SPeter Brune   PetscFunctionReturn(0);
388*2348bcf4SPeter Brune }
389*2348bcf4SPeter Brune 
390*2348bcf4SPeter Brune #undef __FUNCT__
391*2348bcf4SPeter Brune #define __FUNCT__ "DMRestoreNamedLocalVector"
392*2348bcf4SPeter Brune /*@C
393*2348bcf4SPeter Brune    DMRestoreNamedLocalVector - restore access to a named, persistent local vector
394*2348bcf4SPeter Brune 
395*2348bcf4SPeter Brune    Not Collective
396*2348bcf4SPeter Brune 
397*2348bcf4SPeter Brune    Input Arguments:
398*2348bcf4SPeter Brune +  dm - DM on which the vector was gotten
399*2348bcf4SPeter Brune .  name - name under which the vector was gotten
400*2348bcf4SPeter Brune -  X - Vec to restore
401*2348bcf4SPeter Brune 
402*2348bcf4SPeter Brune    Output Arguments:
403*2348bcf4SPeter Brune 
404*2348bcf4SPeter Brune    Level: developer
405*2348bcf4SPeter Brune 
406*2348bcf4SPeter Brune .seealso: DMRestoreNamedGlobalVector(),DMGetNamedLocalVector()
407*2348bcf4SPeter Brune @*/
408*2348bcf4SPeter Brune PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
409*2348bcf4SPeter Brune {
410*2348bcf4SPeter Brune   PetscErrorCode ierr;
411*2348bcf4SPeter Brune   DMNamedVecLink link;
412*2348bcf4SPeter Brune 
413*2348bcf4SPeter Brune   PetscFunctionBegin;
414*2348bcf4SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
415*2348bcf4SPeter Brune   PetscValidCharPointer(name,2);
416*2348bcf4SPeter Brune   PetscValidPointer(X,3);
417*2348bcf4SPeter Brune   PetscValidHeaderSpecific(*X,VEC_CLASSID,3);
418*2348bcf4SPeter Brune   for (link=dm->namedlocal; link; link=link->next) {
419*2348bcf4SPeter Brune     PetscBool match;
420*2348bcf4SPeter Brune     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
421*2348bcf4SPeter Brune     if (match) {
422*2348bcf4SPeter Brune       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
423*2348bcf4SPeter Brune       if (link->X != *X) SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_INCOMP,"Attempt to restore Vec name '%s', but Vec does not match the cache",name);
424*2348bcf4SPeter Brune       link->status = DMVEC_STATUS_IN;
425*2348bcf4SPeter Brune       *X = PETSC_NULL;
426*2348bcf4SPeter Brune       PetscFunctionReturn(0);
427*2348bcf4SPeter Brune     }
428*2348bcf4SPeter Brune   }
429*2348bcf4SPeter Brune   SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
430*2348bcf4SPeter Brune   PetscFunctionReturn(0);
431*2348bcf4SPeter Brune }
432