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 @*/ 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 @*/ 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 @*/ 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 @*/ 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 @*/ 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 @*/ 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 @*/ 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 @*/ 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 @*/ 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 @*/ 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 @*/ 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 @*/ 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