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