1 #include <petscdmshell.h> /*I "petscdmshell.h" I*/ 2 #include <petscmat.h> 3 #include <petsc-private/dmimpl.h> 4 5 typedef struct { 6 Vec Xglobal; 7 Vec Xlocal; 8 Mat A; 9 VecScatter gtol; 10 VecScatter ltog; 11 VecScatter ltol; 12 } DM_Shell; 13 14 #undef __FUNCT__ 15 #define __FUNCT__ "DMGlobalToLocalBeginDefaultShell" 16 /*@ 17 DMGlobalToLocalBeginDefaultShell - Uses the GlobalToLocal VecScatter context set by the user to begin a global to local scatter 18 Collective 19 20 Input Arguments: 21 + dm - shell DM 22 . g - global vector 23 . mode - InsertMode 24 - l - local vector 25 26 Level: advanced 27 28 Note: This is not normally called directly by user code, generally user code calls DMGlobalToLocalBegin() and DMGlobalToLocalEnd(). If the user provides their own custom routines to DMShellSetLocalToGlobal() then those routines might have reason to call this function. 29 30 .seealso: DMGlobalToLocalEndDefaultShell() 31 @*/ 32 PetscErrorCode DMGlobalToLocalBeginDefaultShell(DM dm,Vec g,InsertMode mode,Vec l) 33 { 34 PetscErrorCode ierr; 35 DM_Shell *shell = (DM_Shell*)dm->data; 36 37 PetscFunctionBegin; 38 if (!shell->gtol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()"); 39 ierr = VecScatterBegin(shell->gtol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr); 40 PetscFunctionReturn(0); 41 } 42 43 #undef __FUNCT__ 44 #define __FUNCT__ "DMGlobalToLocalEndDefaultShell" 45 /*@ 46 DMGlobalToLocalEndDefaultShell - Uses the GlobalToLocal VecScatter context set by the user to end a global to local scatter 47 Collective 48 49 Input Arguments: 50 + dm - shell DM 51 . g - global vector 52 . mode - InsertMode 53 - l - local vector 54 55 Level: advanced 56 57 .seealso: DMGlobalToLocalBeginDefaultShell() 58 @*/ 59 PetscErrorCode DMGlobalToLocalEndDefaultShell(DM dm,Vec g,InsertMode mode,Vec l) 60 { 61 PetscErrorCode ierr; 62 DM_Shell *shell = (DM_Shell*)dm->data; 63 64 PetscFunctionBegin; 65 if (!shell->gtol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()"); 66 ierr = VecScatterEnd(shell->gtol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr); 67 PetscFunctionReturn(0); 68 } 69 70 #undef __FUNCT__ 71 #define __FUNCT__ "DMLocalToGlobalBeginDefaultShell" 72 /*@ 73 DMLocalToGlobalBeginDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to begin a local to global scatter 74 Collective 75 76 Input Arguments: 77 + dm - shell DM 78 . l - local vector 79 . mode - InsertMode 80 - g - global vector 81 82 Level: advanced 83 84 Note: This is not normally called directly by user code, generally user code calls DMLocalToGlobalBegin() and DMLocalToGlobalEnd(). If the user provides their own custom routines to DMShellSetLocalToGlobal() then those routines might have reason to call this function. 85 86 .seealso: DMLocalToGlobalEndDefaultShell() 87 @*/ 88 PetscErrorCode DMLocalToGlobalBeginDefaultShell(DM dm,Vec l,InsertMode mode,Vec g) 89 { 90 PetscErrorCode ierr; 91 DM_Shell *shell = (DM_Shell*)dm->data; 92 93 PetscFunctionBegin; 94 if (!shell->ltog) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()"); 95 ierr = VecScatterBegin(shell->ltog,l,g,mode,SCATTER_FORWARD);CHKERRQ(ierr); 96 PetscFunctionReturn(0); 97 } 98 99 #undef __FUNCT__ 100 #define __FUNCT__ "DMLocalToGlobalEndDefaultShell" 101 /*@ 102 DMLocalToGlobalEndDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to end a local to global scatter 103 Collective 104 105 Input Arguments: 106 + dm - shell DM 107 . l - local vector 108 . mode - InsertMode 109 - g - global vector 110 111 Level: advanced 112 113 .seealso: DMLocalToGlobalBeginDefaultShell() 114 @*/ 115 PetscErrorCode DMLocalToGlobalEndDefaultShell(DM dm,Vec l,InsertMode mode,Vec g) 116 { 117 PetscErrorCode ierr; 118 DM_Shell *shell = (DM_Shell*)dm->data; 119 120 PetscFunctionBegin; 121 if (!shell->ltog) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()"); 122 ierr = VecScatterEnd(shell->ltog,l,g,mode,SCATTER_FORWARD);CHKERRQ(ierr); 123 PetscFunctionReturn(0); 124 } 125 126 #undef __FUNCT__ 127 #define __FUNCT__ "DMLocalToLocalBeginDefaultShell" 128 /*@ 129 DMLocalToLocalBeginDefaultShell - Uses the LocalToLocal VecScatter context set by the user to begin a local to local scatter 130 Collective 131 132 Input Arguments: 133 + dm - shell DM 134 . g - the original local vector 135 - mode - InsertMode 136 137 Output Parameter: 138 . l - the local vector with correct ghost values 139 140 Level: advanced 141 142 Note: This is not normally called directly by user code, generally user code calls DMLocalToLocalBegin() and DMLocalToLocalEnd(). If the user provides their own custom routines to DMShellSetLocalToLocal() then those routines might have reason to call this function. 143 144 .seealso: DMLocalToLocalEndDefaultShell() 145 @*/ 146 PetscErrorCode DMLocalToLocalBeginDefaultShell(DM dm,Vec g,InsertMode mode,Vec l) 147 { 148 PetscErrorCode ierr; 149 DM_Shell *shell = (DM_Shell*)dm->data; 150 151 PetscFunctionBegin; 152 if (!shell->ltol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToLocalVecScatter()"); 153 ierr = VecScatterBegin(shell->ltol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr); 154 PetscFunctionReturn(0); 155 } 156 157 #undef __FUNCT__ 158 #define __FUNCT__ "DMLocalToLocalEndDefaultShell" 159 /*@ 160 DMLocalToLocalEndDefaultShell - Uses the LocalToLocal VecScatter context set by the user to end a local to local scatter 161 Collective 162 163 Input Arguments: 164 + dm - shell DM 165 . g - the original local vector 166 - mode - InsertMode 167 168 Output Parameter: 169 . l - the local vector with correct ghost values 170 171 Level: advanced 172 173 .seealso: DMLocalToLocalBeginDefaultShell() 174 @*/ 175 PetscErrorCode DMLocalToLocalEndDefaultShell(DM dm,Vec g,InsertMode mode,Vec l) 176 { 177 PetscErrorCode ierr; 178 DM_Shell *shell = (DM_Shell*)dm->data; 179 180 PetscFunctionBegin; 181 if (!shell->ltol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()"); 182 ierr = VecScatterEnd(shell->ltol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr); 183 PetscFunctionReturn(0); 184 } 185 186 #undef __FUNCT__ 187 #define __FUNCT__ "DMCreateMatrix_Shell" 188 static PetscErrorCode DMCreateMatrix_Shell(DM dm,Mat *J) 189 { 190 PetscErrorCode ierr; 191 DM_Shell *shell = (DM_Shell*)dm->data; 192 Mat A; 193 194 PetscFunctionBegin; 195 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 196 PetscValidPointer(J,3); 197 if (!shell->A) { 198 if (shell->Xglobal) { 199 PetscInt m,M; 200 ierr = PetscInfo(dm,"Naively creating matrix using global vector distribution without preallocation");CHKERRQ(ierr); 201 ierr = VecGetSize(shell->Xglobal,&M);CHKERRQ(ierr); 202 ierr = VecGetLocalSize(shell->Xglobal,&m);CHKERRQ(ierr); 203 ierr = MatCreate(PetscObjectComm((PetscObject)dm),&shell->A);CHKERRQ(ierr); 204 ierr = MatSetSizes(shell->A,m,m,M,M);CHKERRQ(ierr); 205 ierr = MatSetType(shell->A,dm->mattype);CHKERRQ(ierr); 206 ierr = MatSetUp(shell->A);CHKERRQ(ierr); 207 } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetMatrix(), DMShellSetCreateMatrix(), or provide a vector"); 208 } 209 A = shell->A; 210 /* the check below is tacky and incomplete */ 211 if (dm->mattype) { 212 PetscBool flg,aij,seqaij,mpiaij; 213 ierr = PetscObjectTypeCompare((PetscObject)A,dm->mattype,&flg);CHKERRQ(ierr); 214 ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&seqaij);CHKERRQ(ierr); 215 ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&mpiaij);CHKERRQ(ierr); 216 ierr = PetscStrcmp(dm->mattype,MATAIJ,&aij);CHKERRQ(ierr); 217 if (!flg) { 218 if (!(aij && (seqaij || mpiaij))) SETERRQ2(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_NOTSAMETYPE,"Requested matrix of type %s, but only %s available",dm->mattype,((PetscObject)A)->type_name); 219 } 220 } 221 if (((PetscObject)A)->refct < 2) { /* We have an exclusive reference so we can give it out */ 222 ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 223 ierr = MatZeroEntries(A);CHKERRQ(ierr); 224 *J = A; 225 } else { /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */ 226 ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,J);CHKERRQ(ierr); 227 ierr = MatZeroEntries(*J);CHKERRQ(ierr); 228 } 229 PetscFunctionReturn(0); 230 } 231 232 #undef __FUNCT__ 233 #define __FUNCT__ "DMCreateGlobalVector_Shell" 234 PetscErrorCode DMCreateGlobalVector_Shell(DM dm,Vec *gvec) 235 { 236 PetscErrorCode ierr; 237 DM_Shell *shell = (DM_Shell*)dm->data; 238 Vec X; 239 240 PetscFunctionBegin; 241 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 242 PetscValidPointer(gvec,2); 243 *gvec = 0; 244 X = shell->Xglobal; 245 if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetGlobalVector() or DMShellSetCreateGlobalVector()"); 246 if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */ 247 ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 248 ierr = VecZeroEntries(X);CHKERRQ(ierr); 249 *gvec = X; 250 } else { /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */ 251 ierr = VecDuplicate(X,gvec);CHKERRQ(ierr); 252 ierr = VecZeroEntries(*gvec);CHKERRQ(ierr); 253 } 254 ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr); 255 PetscFunctionReturn(0); 256 } 257 258 #undef __FUNCT__ 259 #define __FUNCT__ "DMCreateLocalVector_Shell" 260 PetscErrorCode DMCreateLocalVector_Shell(DM dm,Vec *gvec) 261 { 262 PetscErrorCode ierr; 263 DM_Shell *shell = (DM_Shell*)dm->data; 264 Vec X; 265 266 PetscFunctionBegin; 267 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 268 PetscValidPointer(gvec,2); 269 *gvec = 0; 270 X = shell->Xlocal; 271 if (!X) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetLocalVector() or DMShellSetCreateLocalVector()"); 272 if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */ 273 ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 274 ierr = VecZeroEntries(X);CHKERRQ(ierr); 275 *gvec = X; 276 } else { /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */ 277 ierr = VecDuplicate(X,gvec);CHKERRQ(ierr); 278 ierr = VecZeroEntries(*gvec);CHKERRQ(ierr); 279 } 280 ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr); 281 PetscFunctionReturn(0); 282 } 283 284 #undef __FUNCT__ 285 #define __FUNCT__ "DMShellSetMatrix" 286 /*@ 287 DMShellSetMatrix - sets a template matrix associated with the DMShell 288 289 Collective 290 291 Input Arguments: 292 + dm - shell DM 293 - J - template matrix 294 295 Level: advanced 296 297 .seealso: DMCreateMatrix(), DMShellSetCreateMatrix() 298 @*/ 299 PetscErrorCode DMShellSetMatrix(DM dm,Mat J) 300 { 301 DM_Shell *shell = (DM_Shell*)dm->data; 302 PetscErrorCode ierr; 303 PetscBool isshell; 304 305 PetscFunctionBegin; 306 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 307 PetscValidHeaderSpecific(J,MAT_CLASSID,2); 308 ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr); 309 if (!isshell) PetscFunctionReturn(0); 310 ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr); 311 ierr = MatDestroy(&shell->A);CHKERRQ(ierr); 312 shell->A = J; 313 PetscFunctionReturn(0); 314 } 315 316 #undef __FUNCT__ 317 #define __FUNCT__ "DMShellSetCreateMatrix" 318 /*@C 319 DMShellSetCreateMatrix - sets the routine to create a matrix associated with the shell DM 320 321 Logically Collective on DM 322 323 Input Arguments: 324 + dm - the shell DM 325 - func - the function to create a matrix 326 327 Level: advanced 328 329 .seealso: DMCreateMatrix(), DMShellSetMatrix() 330 @*/ 331 PetscErrorCode DMShellSetCreateMatrix(DM dm,PetscErrorCode (*func)(DM,Mat*)) 332 { 333 334 PetscFunctionBegin; 335 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 336 dm->ops->creatematrix = func; 337 PetscFunctionReturn(0); 338 } 339 340 #undef __FUNCT__ 341 #define __FUNCT__ "DMShellSetGlobalVector" 342 /*@ 343 DMShellSetGlobalVector - sets a template global vector associated with the DMShell 344 345 Logically Collective on DM 346 347 Input Arguments: 348 + dm - shell DM 349 - X - template vector 350 351 Level: advanced 352 353 .seealso: DMCreateGlobalVector(), DMShellSetMatrix(), DMShellSetCreateGlobalVector() 354 @*/ 355 PetscErrorCode DMShellSetGlobalVector(DM dm,Vec X) 356 { 357 DM_Shell *shell = (DM_Shell*)dm->data; 358 PetscErrorCode ierr; 359 PetscBool isshell; 360 361 PetscFunctionBegin; 362 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 363 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 364 ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr); 365 if (!isshell) PetscFunctionReturn(0); 366 ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 367 ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr); 368 shell->Xglobal = X; 369 PetscFunctionReturn(0); 370 } 371 372 #undef __FUNCT__ 373 #define __FUNCT__ "DMShellSetCreateGlobalVector" 374 /*@C 375 DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM 376 377 Logically Collective 378 379 Input Arguments: 380 + dm - the shell DM 381 - func - the creation routine 382 383 Level: advanced 384 385 .seealso: DMShellSetGlobalVector(), DMShellSetCreateMatrix() 386 @*/ 387 PetscErrorCode DMShellSetCreateGlobalVector(DM dm,PetscErrorCode (*func)(DM,Vec*)) 388 { 389 390 PetscFunctionBegin; 391 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 392 dm->ops->createglobalvector = func; 393 PetscFunctionReturn(0); 394 } 395 396 #undef __FUNCT__ 397 #define __FUNCT__ "DMShellSetLocalVector" 398 /*@ 399 DMShellSetLocalVector - sets a template local vector associated with the DMShell 400 401 Logically Collective on DM 402 403 Input Arguments: 404 + dm - shell DM 405 - X - template vector 406 407 Level: advanced 408 409 .seealso: DMCreateLocalVector(), DMShellSetMatrix(), DMShellSetCreateLocalVector() 410 @*/ 411 PetscErrorCode DMShellSetLocalVector(DM dm,Vec X) 412 { 413 DM_Shell *shell = (DM_Shell*)dm->data; 414 PetscErrorCode ierr; 415 PetscBool isshell; 416 417 PetscFunctionBegin; 418 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 419 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 420 ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr); 421 if (!isshell) PetscFunctionReturn(0); 422 ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 423 ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr); 424 shell->Xlocal = X; 425 PetscFunctionReturn(0); 426 } 427 428 #undef __FUNCT__ 429 #define __FUNCT__ "DMShellSetCreateLocalVector" 430 /*@C 431 DMShellSetCreateLocalVector - sets the routine to create a local vector associated with the shell DM 432 433 Logically Collective 434 435 Input Arguments: 436 + dm - the shell DM 437 - func - the creation routine 438 439 Level: advanced 440 441 .seealso: DMShellSetLocalVector(), DMShellSetCreateMatrix() 442 @*/ 443 PetscErrorCode DMShellSetCreateLocalVector(DM dm,PetscErrorCode (*func)(DM,Vec*)) 444 { 445 446 PetscFunctionBegin; 447 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 448 dm->ops->createlocalvector = func; 449 PetscFunctionReturn(0); 450 } 451 452 #undef __FUNCT__ 453 #define __FUNCT__ "DMShellSetGlobalToLocal" 454 /*@C 455 DMShellSetGlobalToLocal - Sets the routines used to perform a global to local scatter 456 457 Logically Collective on DM 458 459 Input Arguments 460 + dm - the shell DM 461 . begin - the routine that begins the global to local scatter 462 - end - the routine that ends the global to local scatter 463 464 Notes: If these functions are not provided but DMShellSetGlobalToLocalVecScatter() is called then 465 DMGlobalToLocalBeginDefaultShell()/DMGlobalToLocalEndDefaultShell() are used to to perform the transfers 466 467 Level: advanced 468 469 .seealso: DMShellSetLocalToGlobal(), DMGlobalToLocalBeginDefaultShell(), DMGlobalToLocalEndDefaultShell() 470 @*/ 471 PetscErrorCode DMShellSetGlobalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) { 472 PetscFunctionBegin; 473 dm->ops->globaltolocalbegin = begin; 474 dm->ops->globaltolocalend = end; 475 PetscFunctionReturn(0); 476 } 477 478 #undef __FUNCT__ 479 #define __FUNCT__ "DMShellSetLocalToGlobal" 480 /*@C 481 DMShellSetLocalToGlobal - Sets the routines used to perform a local to global scatter 482 483 Logically Collective on DM 484 485 Input Arguments 486 + dm - the shell DM 487 . begin - the routine that begins the local to global scatter 488 - end - the routine that ends the local to global scatter 489 490 Notes: If these functions are not provided but DMShellSetLocalToGlobalVecScatter() is called then 491 DMLocalToGlobalBeginDefaultShell()/DMLocalToGlobalEndDefaultShell() are used to to perform the transfers 492 493 Level: advanced 494 495 .seealso: DMShellSetGlobalToLocal() 496 @*/ 497 PetscErrorCode DMShellSetLocalToGlobal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) { 498 PetscFunctionBegin; 499 dm->ops->localtoglobalbegin = begin; 500 dm->ops->localtoglobalend = end; 501 PetscFunctionReturn(0); 502 } 503 504 #undef __FUNCT__ 505 #define __FUNCT__ "DMShellSetLocalToLocal" 506 /*@C 507 DMShellSetLocalToLocal - Sets the routines used to perform a local to local scatter 508 509 Logically Collective on DM 510 511 Input Arguments 512 + dm - the shell DM 513 . begin - the routine that begins the local to local scatter 514 - end - the routine that ends the local to local scatter 515 516 Notes: If these functions are not provided but DMShellSetLocalToLocalVecScatter() is called then 517 DMLocalToLocalBeginDefaultShell()/DMLocalToLocalEndDefaultShell() are used to to perform the transfers 518 519 Level: advanced 520 521 .seealso: DMShellSetGlobalToLocal(), DMLocalToLocalBeginDefaultShell(), DMLocalToLocalEndDefaultShell() 522 @*/ 523 PetscErrorCode DMShellSetLocalToLocal(DM dm,PetscErrorCode (*begin)(DM,Vec,InsertMode,Vec),PetscErrorCode (*end)(DM,Vec,InsertMode,Vec)) { 524 PetscFunctionBegin; 525 dm->ops->localtolocalbegin = begin; 526 dm->ops->localtolocalend = end; 527 PetscFunctionReturn(0); 528 } 529 530 #undef __FUNCT__ 531 #define __FUNCT__ "DMShellSetGlobalToLocalVecScatter" 532 /*@ 533 DMShellSetGlobalToLocalVecScatter - Sets a VecScatter context for global to local communication 534 535 Logically Collective on DM 536 537 Input Arguments 538 + dm - the shell DM 539 - gtol - the global to local VecScatter context 540 541 Level: advanced 542 543 .seealso: DMShellSetGlobalToLocal(), DMGlobalToLocalBeginDefaultShell(), DMGlobalToLocalEndDefaultShell() 544 @*/ 545 PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM dm, VecScatter gtol) 546 { 547 DM_Shell *shell = (DM_Shell*)dm->data; 548 PetscErrorCode ierr; 549 550 PetscFunctionBegin; 551 ierr = PetscObjectReference((PetscObject)gtol);CHKERRQ(ierr); 552 /* Call VecScatterDestroy() to avoid a memory leak in case of re-setting. */ 553 ierr = VecScatterDestroy(&shell->gtol);CHKERRQ(ierr); 554 shell->gtol = gtol; 555 PetscFunctionReturn(0); 556 } 557 558 #undef __FUNCT__ 559 #define __FUNCT__ "DMShellSetLocalToGlobalVecScatter" 560 /*@ 561 DMShellSetLocalToGlobalVecScatter - Sets a VecScatter context for local to global communication 562 563 Logically Collective on DM 564 565 Input Arguments 566 + dm - the shell DM 567 - ltog - the local to global VecScatter context 568 569 Level: advanced 570 571 .seealso: DMShellSetLocalToGlobal(), DMLocalToGlobalBeginDefaultShell(), DMLocalToGlobalEndDefaultShell() 572 @*/ 573 PetscErrorCode DMShellSetLocalToGlobalVecScatter(DM dm, VecScatter ltog) 574 { 575 DM_Shell *shell = (DM_Shell*)dm->data; 576 PetscErrorCode ierr; 577 578 PetscFunctionBegin; 579 ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr); 580 /* Call VecScatterDestroy() to avoid a memory leak in case of re-setting. */ 581 ierr = VecScatterDestroy(&shell->ltog);CHKERRQ(ierr); 582 shell->ltog = ltog; 583 PetscFunctionReturn(0); 584 } 585 586 #undef __FUNCT__ 587 #define __FUNCT__ "DMShellSetLocalToLocalVecScatter" 588 /*@ 589 DMShellSetLocalToLocalVecScatter - Sets a VecScatter context for local to local communication 590 591 Logically Collective on DM 592 593 Input Arguments 594 + dm - the shell DM 595 - ltol - the local to local VecScatter context 596 597 Level: advanced 598 599 .seealso: DMShellSetLocalToLocal(), DMLocalToLocalBeginDefaultShell(), DMLocalToLocalEndDefaultShell() 600 @*/ 601 PetscErrorCode DMShellSetLocalToLocalVecScatter(DM dm, VecScatter ltol) 602 { 603 DM_Shell *shell = (DM_Shell*)dm->data; 604 PetscErrorCode ierr; 605 606 PetscFunctionBegin; 607 ierr = PetscObjectReference((PetscObject)ltol);CHKERRQ(ierr); 608 /* Call VecScatterDestroy() to avoid a memory leak in case of re-setting. */ 609 ierr = VecScatterDestroy(&shell->ltol);CHKERRQ(ierr); 610 shell->ltol = ltol; 611 PetscFunctionReturn(0); 612 } 613 614 #undef __FUNCT__ 615 #define __FUNCT__ "DMDestroy_Shell" 616 static PetscErrorCode DMDestroy_Shell(DM dm) 617 { 618 PetscErrorCode ierr; 619 DM_Shell *shell = (DM_Shell*)dm->data; 620 621 PetscFunctionBegin; 622 ierr = MatDestroy(&shell->A);CHKERRQ(ierr); 623 ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr); 624 ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr); 625 ierr = VecScatterDestroy(&shell->gtol);CHKERRQ(ierr); 626 ierr = VecScatterDestroy(&shell->ltog);CHKERRQ(ierr); 627 /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */ 628 ierr = PetscFree(shell);CHKERRQ(ierr); 629 PetscFunctionReturn(0); 630 } 631 632 #undef __FUNCT__ 633 #define __FUNCT__ "DMView_Shell" 634 static PetscErrorCode DMView_Shell(DM dm,PetscViewer v) 635 { 636 PetscErrorCode ierr; 637 DM_Shell *shell = (DM_Shell*)dm->data; 638 639 PetscFunctionBegin; 640 ierr = VecView(shell->Xglobal,v);CHKERRQ(ierr); 641 PetscFunctionReturn(0); 642 } 643 644 #undef __FUNCT__ 645 #define __FUNCT__ "DMLoad_Shell" 646 static PetscErrorCode DMLoad_Shell(DM dm,PetscViewer v) 647 { 648 PetscErrorCode ierr; 649 DM_Shell *shell = (DM_Shell*)dm->data; 650 651 PetscFunctionBegin; 652 ierr = VecCreate(PetscObjectComm((PetscObject)dm),&shell->Xglobal);CHKERRQ(ierr); 653 ierr = VecLoad(shell->Xglobal,v);CHKERRQ(ierr); 654 PetscFunctionReturn(0); 655 } 656 657 #undef __FUNCT__ 658 #define __FUNCT__ "DMCreateSubDM_Shell" 659 PetscErrorCode DMCreateSubDM_Shell(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm) 660 { 661 PetscErrorCode ierr; 662 663 PetscFunctionBegin; 664 if (subdm) {ierr = DMShellCreate(PetscObjectComm((PetscObject) dm), subdm);CHKERRQ(ierr);} 665 ierr = DMCreateSubDM_Section_Private(dm, numFields, fields, is, subdm);CHKERRQ(ierr); 666 PetscFunctionReturn(0); 667 } 668 669 #undef __FUNCT__ 670 #define __FUNCT__ "DMCreate_Shell" 671 PETSC_EXTERN PetscErrorCode DMCreate_Shell(DM dm) 672 { 673 PetscErrorCode ierr; 674 DM_Shell *shell; 675 676 PetscFunctionBegin; 677 ierr = PetscNewLog(dm,&shell);CHKERRQ(ierr); 678 dm->data = shell; 679 680 ierr = PetscObjectChangeTypeName((PetscObject)dm,DMSHELL);CHKERRQ(ierr); 681 682 dm->ops->destroy = DMDestroy_Shell; 683 dm->ops->createglobalvector = DMCreateGlobalVector_Shell; 684 dm->ops->createlocalvector = DMCreateLocalVector_Shell; 685 dm->ops->creatematrix = DMCreateMatrix_Shell; 686 dm->ops->view = DMView_Shell; 687 dm->ops->load = DMLoad_Shell; 688 dm->ops->globaltolocalbegin = DMGlobalToLocalBeginDefaultShell; 689 dm->ops->globaltolocalend = DMGlobalToLocalEndDefaultShell; 690 dm->ops->localtoglobalbegin = DMLocalToGlobalBeginDefaultShell; 691 dm->ops->localtoglobalend = DMLocalToGlobalEndDefaultShell; 692 dm->ops->localtolocalbegin = DMLocalToLocalBeginDefaultShell; 693 dm->ops->localtolocalend = DMLocalToLocalEndDefaultShell; 694 dm->ops->createsubdm = DMCreateSubDM_Shell; 695 PetscFunctionReturn(0); 696 } 697 698 #undef __FUNCT__ 699 #define __FUNCT__ "DMShellCreate" 700 /*@ 701 DMShellCreate - Creates a shell DM object, used to manage user-defined problem data 702 703 Collective on MPI_Comm 704 705 Input Parameter: 706 . comm - the processors that will share the global vector 707 708 Output Parameters: 709 . shell - the shell DM 710 711 Level: advanced 712 713 .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateLocalVector() 714 @*/ 715 PetscErrorCode DMShellCreate(MPI_Comm comm,DM *dm) 716 { 717 PetscErrorCode ierr; 718 719 PetscFunctionBegin; 720 PetscValidPointer(dm,2); 721 ierr = DMCreate(comm,dm);CHKERRQ(ierr); 722 ierr = DMSetType(*dm,DMSHELL);CHKERRQ(ierr); 723 ierr = DMSetUp(*dm);CHKERRQ(ierr); 724 PetscFunctionReturn(0); 725 } 726 727