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 for (j=0; j<DM_MAX_WORK_VECTORS; j++) { 267 if (*g == dm->globalout[j]) { 268 dm->globalout[j] = NULL; 269 for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 270 if (!dm->globalin[i]) { 271 dm->globalin[i] = *g; 272 goto alldone; 273 } 274 } 275 } 276 } 277 ierr = VecDestroy(g);CHKERRQ(ierr); 278 alldone: 279 *g = NULL; 280 PetscFunctionReturn(0); 281 } 282 283 /*@C 284 DMHasNamedGlobalVector - check for a named, persistent global vector 285 286 Not Collective 287 288 Input Arguments: 289 + dm - DM to hold named vectors 290 - name - unique name for Vec 291 292 Output Arguments: 293 . exists - true if the vector was previously created 294 295 Level: developer 296 297 Note: If a Vec with the given name does not exist, it is created. 298 299 .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector() 300 @*/ 301 PetscErrorCode DMHasNamedGlobalVector(DM dm,const char *name,PetscBool *exists) 302 { 303 PetscErrorCode ierr; 304 DMNamedVecLink link; 305 306 PetscFunctionBegin; 307 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 308 PetscValidCharPointer(name,2); 309 PetscValidPointer(exists,3); 310 *exists = PETSC_FALSE; 311 for (link=dm->namedglobal; link; link=link->next) { 312 PetscBool match; 313 ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr); 314 if (match) { 315 *exists = PETSC_TRUE; 316 break; 317 } 318 } 319 PetscFunctionReturn(0); 320 } 321 322 /*@C 323 DMGetNamedGlobalVector - get access to a named, persistent global vector 324 325 Collective on DM 326 327 Input Arguments: 328 + dm - DM to hold named vectors 329 - name - unique name for Vec 330 331 Output Arguments: 332 . X - named Vec 333 334 Level: developer 335 336 Note: If a Vec with the given name does not exist, it is created. 337 338 .seealso: DMRestoreNamedGlobalVector() 339 @*/ 340 PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X) 341 { 342 PetscErrorCode ierr; 343 DMNamedVecLink link; 344 345 PetscFunctionBegin; 346 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 347 PetscValidCharPointer(name,2); 348 PetscValidPointer(X,3); 349 for (link=dm->namedglobal; link; link=link->next) { 350 PetscBool match; 351 ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr); 352 if (match) { 353 if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name); 354 goto found; 355 } 356 } 357 358 /* Create the Vec */ 359 ierr = PetscNew(&link);CHKERRQ(ierr); 360 ierr = PetscStrallocpy(name,&link->name);CHKERRQ(ierr); 361 ierr = DMCreateGlobalVector(dm,&link->X);CHKERRQ(ierr); 362 link->next = dm->namedglobal; 363 dm->namedglobal = link; 364 365 found: 366 *X = link->X; 367 link->status = DMVEC_STATUS_OUT; 368 PetscFunctionReturn(0); 369 } 370 371 /*@C 372 DMRestoreNamedGlobalVector - restore access to a named, persistent global vector 373 374 Collective on DM 375 376 Input Arguments: 377 + dm - DM on which the vector was gotten 378 . name - name under which the vector was gotten 379 - X - Vec to restore 380 381 Output Arguments: 382 383 Level: developer 384 385 .seealso: DMGetNamedGlobalVector() 386 @*/ 387 PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X) 388 { 389 PetscErrorCode ierr; 390 DMNamedVecLink link; 391 392 PetscFunctionBegin; 393 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 394 PetscValidCharPointer(name,2); 395 PetscValidPointer(X,3); 396 PetscValidHeaderSpecific(*X,VEC_CLASSID,3); 397 for (link=dm->namedglobal; link; link=link->next) { 398 PetscBool match; 399 ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr); 400 if (match) { 401 if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name); 402 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); 403 link->status = DMVEC_STATUS_IN; 404 *X = NULL; 405 PetscFunctionReturn(0); 406 } 407 } 408 SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name); 409 PetscFunctionReturn(0); 410 } 411 412 /*@C 413 DMHasNamedLocalVector - check for a named, persistent local vector 414 415 Not Collective 416 417 Input Arguments: 418 + dm - DM to hold named vectors 419 - name - unique name for Vec 420 421 Output Arguments: 422 . exists - true if the vector was previously created 423 424 Level: developer 425 426 Note: If a Vec with the given name does not exist, it is created. 427 428 .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector() 429 @*/ 430 PetscErrorCode DMHasNamedLocalVector(DM dm,const char *name,PetscBool *exists) 431 { 432 PetscErrorCode ierr; 433 DMNamedVecLink link; 434 435 PetscFunctionBegin; 436 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 437 PetscValidCharPointer(name,2); 438 PetscValidPointer(exists,3); 439 *exists = PETSC_FALSE; 440 for (link=dm->namedlocal; link; link=link->next) { 441 PetscBool match; 442 ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr); 443 if (match) { 444 *exists = PETSC_TRUE; 445 break; 446 } 447 } 448 PetscFunctionReturn(0); 449 } 450 451 /*@C 452 DMGetNamedLocalVector - get access to a named, persistent local vector 453 454 Not Collective 455 456 Input Arguments: 457 + dm - DM to hold named vectors 458 - name - unique name for Vec 459 460 Output Arguments: 461 . X - named Vec 462 463 Level: developer 464 465 Note: If a Vec with the given name does not exist, it is created. 466 467 .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector() 468 @*/ 469 PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X) 470 { 471 PetscErrorCode ierr; 472 DMNamedVecLink link; 473 474 PetscFunctionBegin; 475 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 476 PetscValidCharPointer(name,2); 477 PetscValidPointer(X,3); 478 for (link=dm->namedlocal; link; link=link->next) { 479 PetscBool match; 480 ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr); 481 if (match) { 482 if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name); 483 goto found; 484 } 485 } 486 487 /* Create the Vec */ 488 ierr = PetscNew(&link);CHKERRQ(ierr); 489 ierr = PetscStrallocpy(name,&link->name);CHKERRQ(ierr); 490 ierr = DMCreateLocalVector(dm,&link->X);CHKERRQ(ierr); 491 link->next = dm->namedlocal; 492 dm->namedlocal = link; 493 494 found: 495 *X = link->X; 496 link->status = DMVEC_STATUS_OUT; 497 PetscFunctionReturn(0); 498 } 499 500 /*@C 501 DMRestoreNamedLocalVector - restore access to a named, persistent local vector 502 503 Not Collective 504 505 Input Arguments: 506 + dm - DM on which the vector was gotten 507 . name - name under which the vector was gotten 508 - X - Vec to restore 509 510 Output Arguments: 511 512 Level: developer 513 514 .seealso: DMRestoreNamedGlobalVector(),DMGetNamedLocalVector() 515 @*/ 516 PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X) 517 { 518 PetscErrorCode ierr; 519 DMNamedVecLink link; 520 521 PetscFunctionBegin; 522 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 523 PetscValidCharPointer(name,2); 524 PetscValidPointer(X,3); 525 PetscValidHeaderSpecific(*X,VEC_CLASSID,3); 526 for (link=dm->namedlocal; link; link=link->next) { 527 PetscBool match; 528 ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr); 529 if (match) { 530 if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name); 531 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); 532 link->status = DMVEC_STATUS_IN; 533 *X = NULL; 534 PetscFunctionReturn(0); 535 } 536 } 537 SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name); 538 PetscFunctionReturn(0); 539 } 540