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