1 #include <petsc/private/dmimpl.h> /*I "petscdm.h" I*/
2
3 /*@
4 DMGetLocalVector - Gets a PETSc vector that may be used with the DM local routines. This vector has spaces for the ghost values.
5
6 Not Collective
7
8 Input Parameter:
9 . dm - the dm
10
11 Output Parameter:
12 . g - the local vector
13
14 Level: beginner
15
16 Note:
17 The vector values are NOT initialized and may have garbage in them, so you may need
18 to zero them.
19
20 The output parameter, g, is a regular PETSc vector that should be returned with
21 DMRestoreLocalVector() DO NOT call VecDestroy() on it.
22
23 This is intended to be used for vectors you need for a short time, like within a single function call.
24 For vectors that you intend to keep around (for example in a C struct) or pass around large parts of your
25 code you should use DMCreateLocalVector().
26
27 VecStride*() operations can be useful when using DM with dof > 1
28
29 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
30 DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
31 DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector(),
32 VecStrideMax(), VecStrideMin(), VecStrideNorm()
33 @*/
DMGetLocalVector(DM dm,Vec * g)34 PetscErrorCode DMGetLocalVector(DM dm,Vec *g)
35 {
36 PetscErrorCode ierr,i;
37
38 PetscFunctionBegin;
39 PetscValidHeaderSpecific(dm,DM_CLASSID,1);
40 PetscValidPointer(g,2);
41 for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
42 if (dm->localin[i]) {
43 DM vdm;
44
45 *g = dm->localin[i];
46 dm->localin[i] = NULL;
47
48 ierr = VecGetDM(*g,&vdm);CHKERRQ(ierr);
49 if (vdm) SETERRQ(PetscObjectComm((PetscObject)vdm),PETSC_ERR_LIB,"Invalid vector");
50 ierr = VecSetDM(*g,dm);CHKERRQ(ierr);
51 goto alldone;
52 }
53 }
54 ierr = DMCreateLocalVector(dm,g);CHKERRQ(ierr);
55
56 alldone:
57 for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
58 if (!dm->localout[i]) {
59 dm->localout[i] = *g;
60 break;
61 }
62 }
63 PetscFunctionReturn(0);
64 }
65
66 /*@
67 DMRestoreLocalVector - Returns a PETSc vector that was
68 obtained from DMGetLocalVector(). Do not use with vector obtained via
69 DMCreateLocalVector().
70
71 Not Collective
72
73 Input Parameter:
74 + dm - the dm
75 - g - the local vector
76
77 Level: beginner
78
79 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
80 DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
81 DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMGetLocalVector()
82 @*/
DMRestoreLocalVector(DM dm,Vec * g)83 PetscErrorCode DMRestoreLocalVector(DM dm,Vec *g)
84 {
85 PetscErrorCode ierr;
86 PetscInt i,j;
87
88 PetscFunctionBegin;
89 PetscValidHeaderSpecific(dm,DM_CLASSID,1);
90 PetscValidPointer(g,2);
91 for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
92 if (*g == dm->localout[j]) {
93 DM vdm;
94
95 ierr = VecGetDM(*g,&vdm);CHKERRQ(ierr);
96 if (vdm != dm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Invalid vector");
97 ierr = VecSetDM(*g,NULL);CHKERRQ(ierr);
98 dm->localout[j] = NULL;
99 for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
100 if (!dm->localin[i]) {
101 dm->localin[i] = *g;
102 goto alldone;
103 }
104 }
105 }
106 }
107 ierr = VecDestroy(g);CHKERRQ(ierr);
108 alldone:
109 *g = NULL;
110 PetscFunctionReturn(0);
111 }
112
113 /*@
114 DMGetGlobalVector - Gets a PETSc vector that may be used with the DM global routines.
115
116 Collective on dm
117
118 Input Parameter:
119 . dm - the dm
120
121 Output Parameter:
122 . g - the global vector
123
124 Level: beginner
125
126 Note:
127 The vector values are NOT initialized and may have garbage in them, so you may need
128 to zero them.
129
130 The output parameter, g, is a regular PETSc vector that should be returned with
131 DMRestoreGlobalVector() DO NOT call VecDestroy() on it.
132
133 This is intended to be used for vectors you need for a short time, like within a single function call.
134 For vectors that you intend to keep around (for example in a C struct) or pass around large parts of your
135 code you should use DMCreateGlobalVector().
136
137 VecStride*() operations can be useful when using DM with dof > 1
138
139 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
140 DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
141 DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
142 VecStrideMax(), VecStrideMin(), VecStrideNorm()
143 @*/
DMGetGlobalVector(DM dm,Vec * g)144 PetscErrorCode DMGetGlobalVector(DM dm,Vec *g)
145 {
146 PetscErrorCode ierr;
147 PetscInt i;
148
149 PetscFunctionBegin;
150 PetscValidHeaderSpecific(dm,DM_CLASSID,1);
151 PetscValidPointer(g,2);
152 for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
153 if (dm->globalin[i]) {
154 DM vdm;
155
156 *g = dm->globalin[i];
157 dm->globalin[i] = NULL;
158
159 ierr = VecGetDM(*g,&vdm);CHKERRQ(ierr);
160 if (vdm) SETERRQ(PetscObjectComm((PetscObject)vdm),PETSC_ERR_LIB,"Invalid vector");
161 ierr = VecSetDM(*g,dm);CHKERRQ(ierr);
162 goto alldone;
163 }
164 }
165 ierr = DMCreateGlobalVector(dm,g);CHKERRQ(ierr);
166
167 alldone:
168 for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
169 if (!dm->globalout[i]) {
170 dm->globalout[i] = *g;
171 break;
172 }
173 }
174 PetscFunctionReturn(0);
175 }
176
177 /*@
178 DMClearGlobalVectors - Destroys all the global vectors that have been stashed in this DM
179
180 Collective on dm
181
182 Input Parameter:
183 . dm - the dm
184
185 Level: developer
186
187 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
188 DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
189 DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
190 VecStrideMax(), VecStrideMin(), VecStrideNorm()
191 @*/
DMClearGlobalVectors(DM dm)192 PetscErrorCode DMClearGlobalVectors(DM dm)
193 {
194 PetscErrorCode ierr;
195 PetscInt i;
196
197 PetscFunctionBegin;
198 PetscValidHeaderSpecific(dm,DM_CLASSID,1);
199 for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
200 Vec g;
201
202 if (dm->globalout[i]) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Clearing DM of global vectors that has a global vector obtained with DMGetGlobalVector()");
203 g = dm->globalin[i];
204 dm->globalin[i] = NULL;
205 if (g) {
206 DM vdm;
207
208 ierr = VecGetDM(g,&vdm);CHKERRQ(ierr);
209 if (vdm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Clearing global vector that has a DM attached");
210 }
211 ierr = VecDestroy(&g);CHKERRQ(ierr);
212 }
213 PetscFunctionReturn(0);
214 }
215
216 /*@
217 DMClearLocalVectors - Destroys all the local vectors that have been stashed in this DM
218
219 Collective on dm
220
221 Input Parameter:
222 . dm - the dm
223
224 Level: developer
225
226 .seealso: DMCreateLocalVector(), VecDuplicate(), VecDuplicateVecs(),
227 DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMLocalToLocalBegin(),
228 DMLocalToLocalEnd(), DMLocalToLocalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
229 VecStrideMax(), VecStrideMin(), VecStrideNorm()
230 @*/
DMClearLocalVectors(DM dm)231 PetscErrorCode DMClearLocalVectors(DM dm)
232 {
233 PetscErrorCode ierr;
234 PetscInt i;
235
236 PetscFunctionBegin;
237 PetscValidHeaderSpecific(dm,DM_CLASSID,1);
238 for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
239 Vec g;
240
241 if (dm->localout[i]) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Clearing DM of local vectors that has a local vector obtained with DMGetLocalVector()");
242 g = dm->localin[i];
243 dm->localin[i] = NULL;
244 if (g) {
245 DM vdm;
246
247 ierr = VecGetDM(g,&vdm);CHKERRQ(ierr);
248 if (vdm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Clearing local vector that has a DM attached");
249 }
250 ierr = VecDestroy(&g);CHKERRQ(ierr);
251 }
252 PetscFunctionReturn(0);
253 }
254
255 /*@
256 DMRestoreGlobalVector - Returns a PETSc vector that
257 obtained from DMGetGlobalVector(). Do not use with vector obtained via
258 DMCreateGlobalVector().
259
260 Not Collective
261
262 Input Parameter:
263 + dm - the dm
264 - g - the global vector
265
266 Level: beginner
267
268 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
269 DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(),
270 DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
271 @*/
DMRestoreGlobalVector(DM dm,Vec * g)272 PetscErrorCode DMRestoreGlobalVector(DM dm,Vec *g)
273 {
274 PetscErrorCode ierr;
275 PetscInt i,j;
276
277 PetscFunctionBegin;
278 PetscValidHeaderSpecific(dm,DM_CLASSID,1);
279 PetscValidPointer(g,2);
280 ierr = VecSetErrorIfLocked(*g, 2);CHKERRQ(ierr);
281 for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
282 if (*g == dm->globalout[j]) {
283 DM vdm;
284
285 ierr = VecGetDM(*g,&vdm);CHKERRQ(ierr);
286 if (vdm != dm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Invalid vector");
287 ierr = VecSetDM(*g,NULL);CHKERRQ(ierr);
288 dm->globalout[j] = NULL;
289 for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
290 if (!dm->globalin[i]) {
291 dm->globalin[i] = *g;
292 goto alldone;
293 }
294 }
295 }
296 }
297 ierr = VecDestroy(g);CHKERRQ(ierr);
298 alldone:
299 *g = NULL;
300 PetscFunctionReturn(0);
301 }
302
303 /*@C
304 DMHasNamedGlobalVector - check for a named, persistent global vector
305
306 Not Collective
307
308 Input Arguments:
309 + dm - DM to hold named vectors
310 - name - unique name for Vec
311
312 Output Arguments:
313 . exists - true if the vector was previously created
314
315 Level: developer
316
317 Note: If a Vec with the given name does not exist, it is created.
318
319 .seealso: DMGetNamedGlobalVector(), DMRestoreNamedLocalVector()
320 @*/
DMHasNamedGlobalVector(DM dm,const char * name,PetscBool * exists)321 PetscErrorCode DMHasNamedGlobalVector(DM dm,const char *name,PetscBool *exists)
322 {
323 PetscErrorCode ierr;
324 DMNamedVecLink link;
325
326 PetscFunctionBegin;
327 PetscValidHeaderSpecific(dm,DM_CLASSID,1);
328 PetscValidCharPointer(name,2);
329 PetscValidBoolPointer(exists,3);
330 *exists = PETSC_FALSE;
331 for (link=dm->namedglobal; link; link=link->next) {
332 PetscBool match;
333 ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
334 if (match) {
335 *exists = PETSC_TRUE;
336 break;
337 }
338 }
339 PetscFunctionReturn(0);
340 }
341
342 /*@C
343 DMGetNamedGlobalVector - get access to a named, persistent global vector
344
345 Collective on dm
346
347 Input Arguments:
348 + dm - DM to hold named vectors
349 - name - unique name for Vec
350
351 Output Arguments:
352 . X - named Vec
353
354 Level: developer
355
356 Note: If a Vec with the given name does not exist, it is created.
357
358 .seealso: DMRestoreNamedGlobalVector()
359 @*/
DMGetNamedGlobalVector(DM dm,const char * name,Vec * X)360 PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
361 {
362 PetscErrorCode ierr;
363 DMNamedVecLink link;
364
365 PetscFunctionBegin;
366 PetscValidHeaderSpecific(dm,DM_CLASSID,1);
367 PetscValidCharPointer(name,2);
368 PetscValidPointer(X,3);
369 for (link=dm->namedglobal; link; link=link->next) {
370 PetscBool match;
371
372 ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
373 if (match) {
374 DM vdm;
375
376 if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
377 ierr = VecGetDM(link->X,&vdm);CHKERRQ(ierr);
378 if (vdm) SETERRQ(PetscObjectComm((PetscObject)vdm),PETSC_ERR_LIB,"Invalid vector");
379 ierr = VecSetDM(link->X,dm);CHKERRQ(ierr);
380 goto found;
381 }
382 }
383
384 /* Create the Vec */
385 ierr = PetscNew(&link);CHKERRQ(ierr);
386 ierr = PetscStrallocpy(name,&link->name);CHKERRQ(ierr);
387 ierr = DMCreateGlobalVector(dm,&link->X);CHKERRQ(ierr);
388 link->next = dm->namedglobal;
389 dm->namedglobal = link;
390
391 found:
392 *X = link->X;
393 link->status = DMVEC_STATUS_OUT;
394 PetscFunctionReturn(0);
395 }
396
397 /*@C
398 DMRestoreNamedGlobalVector - restore access to a named, persistent global vector
399
400 Collective on dm
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: DMGetNamedGlobalVector()
412 @*/
DMRestoreNamedGlobalVector(DM dm,const char * name,Vec * X)413 PetscErrorCode DMRestoreNamedGlobalVector(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->namedglobal; link; link=link->next) {
424 PetscBool match;
425
426 ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
427 if (match) {
428 DM vdm;
429
430 ierr = VecGetDM(*X,&vdm);CHKERRQ(ierr);
431 if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
432 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);
433 if (vdm != dm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Invalid vector");
434
435 link->status = DMVEC_STATUS_IN;
436 ierr = VecSetDM(link->X,NULL);CHKERRQ(ierr);
437 *X = NULL;
438 PetscFunctionReturn(0);
439 }
440 }
441 SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
442 PetscFunctionReturn(0);
443 }
444
445 /*@C
446 DMHasNamedLocalVector - check for a named, persistent local vector
447
448 Not Collective
449
450 Input Arguments:
451 + dm - DM to hold named vectors
452 - name - unique name for Vec
453
454 Output Arguments:
455 . exists - true if the vector was previously created
456
457 Level: developer
458
459 Note: If a Vec with the given name does not exist, it is created.
460
461 .seealso: DMGetNamedGlobalVector(), DMRestoreNamedLocalVector()
462 @*/
DMHasNamedLocalVector(DM dm,const char * name,PetscBool * exists)463 PetscErrorCode DMHasNamedLocalVector(DM dm,const char *name,PetscBool *exists)
464 {
465 PetscErrorCode ierr;
466 DMNamedVecLink link;
467
468 PetscFunctionBegin;
469 PetscValidHeaderSpecific(dm,DM_CLASSID,1);
470 PetscValidCharPointer(name,2);
471 PetscValidPointer(exists,3);
472 *exists = PETSC_FALSE;
473 for (link=dm->namedlocal; link; link=link->next) {
474 PetscBool match;
475 ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
476 if (match) {
477 *exists = PETSC_TRUE;
478 break;
479 }
480 }
481 PetscFunctionReturn(0);
482 }
483
484 /*@C
485 DMGetNamedLocalVector - get access to a named, persistent local vector
486
487 Not Collective
488
489 Input Arguments:
490 + dm - DM to hold named vectors
491 - name - unique name for Vec
492
493 Output Arguments:
494 . X - named Vec
495
496 Level: developer
497
498 Note: If a Vec with the given name does not exist, it is created.
499
500 .seealso: DMGetNamedGlobalVector(), DMRestoreNamedLocalVector()
501 @*/
DMGetNamedLocalVector(DM dm,const char * name,Vec * X)502 PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
503 {
504 PetscErrorCode ierr;
505 DMNamedVecLink link;
506
507 PetscFunctionBegin;
508 PetscValidHeaderSpecific(dm,DM_CLASSID,1);
509 PetscValidCharPointer(name,2);
510 PetscValidPointer(X,3);
511 for (link=dm->namedlocal; link; link=link->next) {
512 PetscBool match;
513
514 ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
515 if (match) {
516 DM vdm;
517
518 if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
519 ierr = VecGetDM(link->X,&vdm);CHKERRQ(ierr);
520 if (vdm) SETERRQ(PetscObjectComm((PetscObject)vdm),PETSC_ERR_LIB,"Invalid vector");
521 ierr = VecSetDM(link->X,dm);CHKERRQ(ierr);
522 goto found;
523 }
524 }
525
526 /* Create the Vec */
527 ierr = PetscNew(&link);CHKERRQ(ierr);
528 ierr = PetscStrallocpy(name,&link->name);CHKERRQ(ierr);
529 ierr = DMCreateLocalVector(dm,&link->X);CHKERRQ(ierr);
530 link->next = dm->namedlocal;
531 dm->namedlocal = link;
532
533 found:
534 *X = link->X;
535 link->status = DMVEC_STATUS_OUT;
536 PetscFunctionReturn(0);
537 }
538
539 /*@C
540 DMRestoreNamedLocalVector - restore access to a named, persistent local vector
541
542 Not Collective
543
544 Input Arguments:
545 + dm - DM on which the vector was gotten
546 . name - name under which the vector was gotten
547 - X - Vec to restore
548
549 Output Arguments:
550
551 Level: developer
552
553 .seealso: DMRestoreNamedGlobalVector(), DMGetNamedLocalVector()
554 @*/
DMRestoreNamedLocalVector(DM dm,const char * name,Vec * X)555 PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
556 {
557 PetscErrorCode ierr;
558 DMNamedVecLink link;
559
560 PetscFunctionBegin;
561 PetscValidHeaderSpecific(dm,DM_CLASSID,1);
562 PetscValidCharPointer(name,2);
563 PetscValidPointer(X,3);
564 PetscValidHeaderSpecific(*X,VEC_CLASSID,3);
565 for (link=dm->namedlocal; link; link=link->next) {
566 PetscBool match;
567
568 ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr);
569 if (match) {
570 DM vdm;
571
572 ierr = VecGetDM(*X,&vdm);CHKERRQ(ierr);
573 if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
574 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);
575 if (vdm != dm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Invalid vector");
576
577 link->status = DMVEC_STATUS_IN;
578 ierr = VecSetDM(link->X,NULL);CHKERRQ(ierr);
579 *X = NULL;
580 PetscFunctionReturn(0);
581 }
582 }
583 SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
584 PetscFunctionReturn(0);
585 }
586