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