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