xref: /petsc/src/dm/interface/dmget.c (revision 68260fa0d2ad4abc564627f058e06dc055891020)
1*68260fa0SJed Brown #include <petsc-private/dmimpl.h> /*I "petscdm.h" I*/
2*68260fa0SJed Brown 
3*68260fa0SJed Brown #undef __FUNCT__
4*68260fa0SJed Brown #define __FUNCT__ "DMGetLocalVector"
5*68260fa0SJed Brown /*@
6*68260fa0SJed Brown    DMGetLocalVector - Gets a Seq PETSc vector that
7*68260fa0SJed Brown    may be used with the DMXXX routines. This vector has spaces for the ghost values.
8*68260fa0SJed Brown 
9*68260fa0SJed Brown    Not Collective
10*68260fa0SJed Brown 
11*68260fa0SJed Brown    Input Parameter:
12*68260fa0SJed Brown .  dm - the distributed array
13*68260fa0SJed Brown 
14*68260fa0SJed Brown    Output Parameter:
15*68260fa0SJed Brown .  g - the local vector
16*68260fa0SJed Brown 
17*68260fa0SJed Brown    Level: beginner
18*68260fa0SJed Brown 
19*68260fa0SJed Brown    Note:
20*68260fa0SJed Brown    The vector values are NOT initialized and may have garbage in them, so you may need
21*68260fa0SJed Brown    to zero them.
22*68260fa0SJed Brown 
23*68260fa0SJed Brown    The output parameter, g, is a regular PETSc vector that should be returned with
24*68260fa0SJed Brown    DMRestoreLocalVector() DO NOT call VecDestroy() on it.
25*68260fa0SJed Brown 
26*68260fa0SJed Brown    VecStride*() operations can be useful when using DM with dof > 1
27*68260fa0SJed Brown 
28*68260fa0SJed Brown .keywords: distributed array, create, local, vector
29*68260fa0SJed Brown 
30*68260fa0SJed Brown .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
31*68260fa0SJed Brown           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
32*68260fa0SJed Brown           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector(),
33*68260fa0SJed Brown           VecStrideMax(), VecStrideMin(), VecStrideNorm()
34*68260fa0SJed Brown @*/
35*68260fa0SJed Brown PetscErrorCode  DMGetLocalVector(DM dm,Vec* g)
36*68260fa0SJed Brown {
37*68260fa0SJed Brown   PetscErrorCode ierr,i;
38*68260fa0SJed Brown 
39*68260fa0SJed Brown   PetscFunctionBegin;
40*68260fa0SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
41*68260fa0SJed Brown   PetscValidPointer(g,2);
42*68260fa0SJed Brown   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
43*68260fa0SJed Brown     if (dm->localin[i]) {
44*68260fa0SJed Brown       *g             = dm->localin[i];
45*68260fa0SJed Brown       dm->localin[i] = PETSC_NULL;
46*68260fa0SJed Brown       goto alldone;
47*68260fa0SJed Brown     }
48*68260fa0SJed Brown   }
49*68260fa0SJed Brown   ierr = DMCreateLocalVector(dm,g);CHKERRQ(ierr);
50*68260fa0SJed Brown 
51*68260fa0SJed Brown   alldone:
52*68260fa0SJed Brown   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
53*68260fa0SJed Brown     if (!dm->localout[i]) {
54*68260fa0SJed Brown       dm->localout[i] = *g;
55*68260fa0SJed Brown       break;
56*68260fa0SJed Brown     }
57*68260fa0SJed Brown   }
58*68260fa0SJed Brown   PetscFunctionReturn(0);
59*68260fa0SJed Brown }
60*68260fa0SJed Brown 
61*68260fa0SJed Brown #undef __FUNCT__
62*68260fa0SJed Brown #define __FUNCT__ "DMRestoreLocalVector"
63*68260fa0SJed Brown /*@
64*68260fa0SJed Brown    DMRestoreLocalVector - Returns a Seq PETSc vector that
65*68260fa0SJed Brown      obtained from DMGetLocalVector(). Do not use with vector obtained via
66*68260fa0SJed Brown      DMCreateLocalVector().
67*68260fa0SJed Brown 
68*68260fa0SJed Brown    Not Collective
69*68260fa0SJed Brown 
70*68260fa0SJed Brown    Input Parameter:
71*68260fa0SJed Brown +  dm - the distributed array
72*68260fa0SJed Brown -  g - the local vector
73*68260fa0SJed Brown 
74*68260fa0SJed Brown    Level: beginner
75*68260fa0SJed Brown 
76*68260fa0SJed Brown .keywords: distributed array, create, local, vector
77*68260fa0SJed Brown 
78*68260fa0SJed Brown .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
79*68260fa0SJed Brown           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
80*68260fa0SJed Brown           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMGetLocalVector()
81*68260fa0SJed Brown @*/
82*68260fa0SJed Brown PetscErrorCode  DMRestoreLocalVector(DM dm,Vec* g)
83*68260fa0SJed Brown {
84*68260fa0SJed Brown   PetscErrorCode ierr;
85*68260fa0SJed Brown   PetscInt       i,j;
86*68260fa0SJed Brown 
87*68260fa0SJed Brown   PetscFunctionBegin;
88*68260fa0SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
89*68260fa0SJed Brown   PetscValidPointer(g,2);
90*68260fa0SJed Brown   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
91*68260fa0SJed Brown     if (*g == dm->localout[j]) {
92*68260fa0SJed Brown       dm->localout[j] = PETSC_NULL;
93*68260fa0SJed Brown       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
94*68260fa0SJed Brown         if (!dm->localin[i]) {
95*68260fa0SJed Brown           dm->localin[i] = *g;
96*68260fa0SJed Brown           goto alldone;
97*68260fa0SJed Brown         }
98*68260fa0SJed Brown       }
99*68260fa0SJed Brown     }
100*68260fa0SJed Brown   }
101*68260fa0SJed Brown   ierr = VecDestroy(g);CHKERRQ(ierr);
102*68260fa0SJed Brown   alldone:
103*68260fa0SJed Brown   PetscFunctionReturn(0);
104*68260fa0SJed Brown }
105*68260fa0SJed Brown 
106*68260fa0SJed Brown #undef __FUNCT__
107*68260fa0SJed Brown #define __FUNCT__ "DMGetGlobalVector"
108*68260fa0SJed Brown /*@
109*68260fa0SJed Brown    DMGetGlobalVector - Gets a MPI PETSc vector that
110*68260fa0SJed Brown    may be used with the DMXXX routines.
111*68260fa0SJed Brown 
112*68260fa0SJed Brown    Collective on DM
113*68260fa0SJed Brown 
114*68260fa0SJed Brown    Input Parameter:
115*68260fa0SJed Brown .  dm - the distributed array
116*68260fa0SJed Brown 
117*68260fa0SJed Brown    Output Parameter:
118*68260fa0SJed Brown .  g - the global vector
119*68260fa0SJed Brown 
120*68260fa0SJed Brown    Level: beginner
121*68260fa0SJed Brown 
122*68260fa0SJed Brown    Note:
123*68260fa0SJed Brown    The vector values are NOT initialized and may have garbage in them, so you may need
124*68260fa0SJed Brown    to zero them.
125*68260fa0SJed Brown 
126*68260fa0SJed Brown    The output parameter, g, is a regular PETSc vector that should be returned with
127*68260fa0SJed Brown    DMRestoreGlobalVector() DO NOT call VecDestroy() on it.
128*68260fa0SJed Brown 
129*68260fa0SJed Brown    VecStride*() operations can be useful when using DM with dof > 1
130*68260fa0SJed Brown 
131*68260fa0SJed Brown .keywords: distributed array, create, Global, vector
132*68260fa0SJed Brown 
133*68260fa0SJed Brown .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
134*68260fa0SJed Brown           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
135*68260fa0SJed Brown           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
136*68260fa0SJed Brown           VecStrideMax(), VecStrideMin(), VecStrideNorm()
137*68260fa0SJed Brown 
138*68260fa0SJed Brown @*/
139*68260fa0SJed Brown PetscErrorCode  DMGetGlobalVector(DM dm,Vec* g)
140*68260fa0SJed Brown {
141*68260fa0SJed Brown   PetscErrorCode ierr;
142*68260fa0SJed Brown   PetscInt       i;
143*68260fa0SJed Brown 
144*68260fa0SJed Brown   PetscFunctionBegin;
145*68260fa0SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
146*68260fa0SJed Brown   PetscValidPointer(g,2);
147*68260fa0SJed Brown   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
148*68260fa0SJed Brown     if (dm->globalin[i]) {
149*68260fa0SJed Brown       *g             = dm->globalin[i];
150*68260fa0SJed Brown       dm->globalin[i] = PETSC_NULL;
151*68260fa0SJed Brown       goto alldone;
152*68260fa0SJed Brown     }
153*68260fa0SJed Brown   }
154*68260fa0SJed Brown   ierr = DMCreateGlobalVector(dm,g);CHKERRQ(ierr);
155*68260fa0SJed Brown 
156*68260fa0SJed Brown   alldone:
157*68260fa0SJed Brown   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
158*68260fa0SJed Brown     if (!dm->globalout[i]) {
159*68260fa0SJed Brown       dm->globalout[i] = *g;
160*68260fa0SJed Brown       break;
161*68260fa0SJed Brown     }
162*68260fa0SJed Brown   }
163*68260fa0SJed Brown   PetscFunctionReturn(0);
164*68260fa0SJed Brown }
165*68260fa0SJed Brown 
166*68260fa0SJed Brown #undef __FUNCT__
167*68260fa0SJed Brown #define __FUNCT__ "DMClearGlobalVectors"
168*68260fa0SJed Brown /*@
169*68260fa0SJed Brown    DMClearGlobalVectors - Destroys all the global vectors that have been stashed in this DM
170*68260fa0SJed Brown 
171*68260fa0SJed Brown    Collective on DM
172*68260fa0SJed Brown 
173*68260fa0SJed Brown    Input Parameter:
174*68260fa0SJed Brown .  dm - the distributed array
175*68260fa0SJed Brown 
176*68260fa0SJed Brown    Level: developer
177*68260fa0SJed Brown 
178*68260fa0SJed Brown .keywords: distributed array, create, Global, vector
179*68260fa0SJed Brown 
180*68260fa0SJed Brown .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
181*68260fa0SJed Brown           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
182*68260fa0SJed Brown           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
183*68260fa0SJed Brown           VecStrideMax(), VecStrideMin(), VecStrideNorm()
184*68260fa0SJed Brown 
185*68260fa0SJed Brown @*/
186*68260fa0SJed Brown PetscErrorCode  DMClearGlobalVectors(DM dm)
187*68260fa0SJed Brown {
188*68260fa0SJed Brown   PetscErrorCode ierr;
189*68260fa0SJed Brown   PetscInt       i;
190*68260fa0SJed Brown 
191*68260fa0SJed Brown   PetscFunctionBegin;
192*68260fa0SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
193*68260fa0SJed Brown   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
194*68260fa0SJed 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()");
195*68260fa0SJed Brown     ierr = VecDestroy(&dm->globalin[i]);CHKERRQ(ierr);
196*68260fa0SJed Brown   }
197*68260fa0SJed Brown   PetscFunctionReturn(0);
198*68260fa0SJed Brown }
199*68260fa0SJed Brown 
200*68260fa0SJed Brown #undef __FUNCT__
201*68260fa0SJed Brown #define __FUNCT__ "DMRestoreGlobalVector"
202*68260fa0SJed Brown /*@
203*68260fa0SJed Brown    DMRestoreGlobalVector - Returns a Seq PETSc vector that
204*68260fa0SJed Brown      obtained from DMGetGlobalVector(). Do not use with vector obtained via
205*68260fa0SJed Brown      DMCreateGlobalVector().
206*68260fa0SJed Brown 
207*68260fa0SJed Brown    Not Collective
208*68260fa0SJed Brown 
209*68260fa0SJed Brown    Input Parameter:
210*68260fa0SJed Brown +  dm - the distributed array
211*68260fa0SJed Brown -  g - the global vector
212*68260fa0SJed Brown 
213*68260fa0SJed Brown    Level: beginner
214*68260fa0SJed Brown 
215*68260fa0SJed Brown .keywords: distributed array, create, global, vector
216*68260fa0SJed Brown 
217*68260fa0SJed Brown .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
218*68260fa0SJed Brown           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(),
219*68260fa0SJed Brown           DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
220*68260fa0SJed Brown @*/
221*68260fa0SJed Brown PetscErrorCode  DMRestoreGlobalVector(DM dm,Vec* g)
222*68260fa0SJed Brown {
223*68260fa0SJed Brown   PetscErrorCode ierr;
224*68260fa0SJed Brown   PetscInt       i,j;
225*68260fa0SJed Brown 
226*68260fa0SJed Brown   PetscFunctionBegin;
227*68260fa0SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
228*68260fa0SJed Brown   PetscValidPointer(g,2);
229*68260fa0SJed Brown   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
230*68260fa0SJed Brown     if (*g == dm->globalout[j]) {
231*68260fa0SJed Brown       dm->globalout[j] = PETSC_NULL;
232*68260fa0SJed Brown       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
233*68260fa0SJed Brown         if (!dm->globalin[i]) {
234*68260fa0SJed Brown           dm->globalin[i] = *g;
235*68260fa0SJed Brown           goto alldone;
236*68260fa0SJed Brown         }
237*68260fa0SJed Brown       }
238*68260fa0SJed Brown     }
239*68260fa0SJed Brown   }
240*68260fa0SJed Brown   ierr = VecDestroy(g);CHKERRQ(ierr);
241*68260fa0SJed Brown   alldone:
242*68260fa0SJed Brown   PetscFunctionReturn(0);
243*68260fa0SJed Brown }
244*68260fa0SJed Brown 
245*68260fa0SJed Brown #undef __FUNCT__
246*68260fa0SJed Brown #define __FUNCT__ "DMGetNamedGlobalVector"
247*68260fa0SJed Brown /*@C
248*68260fa0SJed Brown    DMGetNamedGlobalVector - get access to a named, persistent global vector
249*68260fa0SJed Brown 
250*68260fa0SJed Brown    Collective on DM
251*68260fa0SJed Brown 
252*68260fa0SJed Brown    Input Arguments:
253*68260fa0SJed Brown +  dm - DM to hold named vectors
254*68260fa0SJed Brown -  name - unique name for Vec
255*68260fa0SJed Brown 
256*68260fa0SJed Brown    Output Arguments:
257*68260fa0SJed Brown .  X - named Vec
258*68260fa0SJed Brown 
259*68260fa0SJed Brown    Level: developer
260*68260fa0SJed Brown 
261*68260fa0SJed Brown    Note: If a Vec with the given name does not exist, it is created.
262*68260fa0SJed Brown 
263*68260fa0SJed Brown .seealso: DMRestoreNamedGlobalVector()
264*68260fa0SJed Brown @*/
265*68260fa0SJed Brown PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
266*68260fa0SJed Brown {
267*68260fa0SJed Brown   PetscErrorCode ierr;
268*68260fa0SJed Brown   DMNamedVecLink link;
269*68260fa0SJed Brown 
270*68260fa0SJed Brown   PetscFunctionBegin;
271*68260fa0SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
272*68260fa0SJed Brown   PetscValidCharPointer(name,2);
273*68260fa0SJed Brown   PetscValidPointer(X,3);
274*68260fa0SJed Brown   for (link=dm->namedglobal; link; link=link->next) {
275*68260fa0SJed Brown     PetscBool match;
276*68260fa0SJed Brown     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
277*68260fa0SJed Brown     if (match) {
278*68260fa0SJed Brown       if (link->status != DMVEC_STATUS_IN) SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
279*68260fa0SJed Brown       goto found;
280*68260fa0SJed Brown     }
281*68260fa0SJed Brown   }
282*68260fa0SJed Brown 
283*68260fa0SJed Brown   /* Create the Vec */
284*68260fa0SJed Brown   ierr = PetscMalloc(sizeof *link,&link);CHKERRQ(ierr);
285*68260fa0SJed Brown   ierr = PetscStrallocpy(name,&link->name);CHKERRQ(ierr);
286*68260fa0SJed Brown   ierr = DMCreateGlobalVector(dm,&link->X);CHKERRQ(ierr);
287*68260fa0SJed Brown   link->next = dm->namedglobal;
288*68260fa0SJed Brown   dm->namedglobal = link;
289*68260fa0SJed Brown 
290*68260fa0SJed Brown   found:
291*68260fa0SJed Brown   *X = link->X;
292*68260fa0SJed Brown   link->status = DMVEC_STATUS_OUT;
293*68260fa0SJed Brown   PetscFunctionReturn(0);
294*68260fa0SJed Brown }
295*68260fa0SJed Brown 
296*68260fa0SJed Brown #undef __FUNCT__
297*68260fa0SJed Brown #define __FUNCT__ "DMRestoreNamedGlobalVector"
298*68260fa0SJed Brown /*@C
299*68260fa0SJed Brown    DMRestoreNamedGlobalVector - restore access to a named, persistent global vector
300*68260fa0SJed Brown 
301*68260fa0SJed Brown    Collective on DM
302*68260fa0SJed Brown 
303*68260fa0SJed Brown    Input Arguments:
304*68260fa0SJed Brown +  dm - DM on which the vector was gotten
305*68260fa0SJed Brown .  name - name under which the vector was gotten
306*68260fa0SJed Brown -  X - Vec to restore
307*68260fa0SJed Brown 
308*68260fa0SJed Brown    Output Arguments:
309*68260fa0SJed Brown 
310*68260fa0SJed Brown    Level: developer
311*68260fa0SJed Brown 
312*68260fa0SJed Brown .seealso: DMGetNamedGlobalVector()
313*68260fa0SJed Brown @*/
314*68260fa0SJed Brown PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
315*68260fa0SJed Brown {
316*68260fa0SJed Brown   PetscErrorCode ierr;
317*68260fa0SJed Brown   DMNamedVecLink link;
318*68260fa0SJed Brown 
319*68260fa0SJed Brown   PetscFunctionBegin;
320*68260fa0SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
321*68260fa0SJed Brown   PetscValidCharPointer(name,2);
322*68260fa0SJed Brown   PetscValidPointer(X,3);
323*68260fa0SJed Brown   PetscValidHeaderSpecific(*X,VEC_CLASSID,3);
324*68260fa0SJed Brown   for (link=dm->namedglobal; link; link=link->next) {
325*68260fa0SJed Brown     PetscBool match;
326*68260fa0SJed Brown     ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
327*68260fa0SJed Brown     if (match) {
328*68260fa0SJed Brown       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
329*68260fa0SJed 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);
330*68260fa0SJed Brown       link->status = DMVEC_STATUS_IN;
331*68260fa0SJed Brown       *X = PETSC_NULL;
332*68260fa0SJed Brown       PetscFunctionReturn(0);
333*68260fa0SJed Brown     }
334*68260fa0SJed Brown   }
335*68260fa0SJed Brown   SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
336*68260fa0SJed Brown   PetscFunctionReturn(0);
337*68260fa0SJed Brown }
338