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