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