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