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