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