1 2 #include <private/dmimpl.h> /*I "petscdm.h" I*/ 3 4 PetscLogEvent DM_Convert, DM_GlobalToLocal, DM_LocalToGlobal; 5 6 #undef __FUNCT__ 7 #define __FUNCT__ "DMCreate" 8 /*@ 9 DMCreate - Creates an empty vector object. The type can then be set with DMetType(). 10 11 If you never call DMSetType() it will generate an 12 error when you try to use the vector. 13 14 Collective on MPI_Comm 15 16 Input Parameter: 17 . comm - The communicator for the DM object 18 19 Output Parameter: 20 . dm - The DM object 21 22 Level: beginner 23 24 .seealso: DMSetType(), DMDA, DMSLICED, DMCOMPOSITE 25 @*/ 26 PetscErrorCode DMCreate(MPI_Comm comm,DM *dm) 27 { 28 DM v; 29 PetscErrorCode ierr; 30 31 PetscFunctionBegin; 32 PetscValidPointer(dm,2); 33 *dm = PETSC_NULL; 34 #ifndef PETSC_USE_DYNAMIC_LIBRARIES 35 ierr = DMInitializePackage(PETSC_NULL);CHKERRQ(ierr); 36 #endif 37 38 ierr = PetscHeaderCreate(v, _p_DM, struct _DMOps, DM_CLASSID, -1, "DM", comm, DMDestroy, DMView);CHKERRQ(ierr); 39 ierr = PetscMemzero(v->ops, sizeof(struct _DMOps));CHKERRQ(ierr); 40 41 v->ltogmap = PETSC_NULL; 42 v->ltogmapb = PETSC_NULL; 43 v->bs = 1; 44 45 *dm = v; 46 PetscFunctionReturn(0); 47 } 48 49 50 #undef __FUNCT__ 51 #define __FUNCT__ "DMSetVecType" 52 /*@C 53 DMSetVecType - Sets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector() 54 55 Logically Collective on DMDA 56 57 Input Parameter: 58 + da - initial distributed array 59 . ctype - the vector type, currently either VECSTANDARD or VECCUSP 60 61 Options Database: 62 . -da_vec_type ctype 63 64 Level: intermediate 65 66 .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDA, DMDAInterpolationType, VecType 67 @*/ 68 PetscErrorCode DMSetVecType(DM da,const VecType ctype) 69 { 70 PetscErrorCode ierr; 71 72 PetscFunctionBegin; 73 PetscValidHeaderSpecific(da,DM_CLASSID,1); 74 ierr = PetscFree(da->vectype);CHKERRQ(ierr); 75 ierr = PetscStrallocpy(ctype,&da->vectype);CHKERRQ(ierr); 76 PetscFunctionReturn(0); 77 } 78 79 #undef __FUNCT__ 80 #define __FUNCT__ "DMSetOptionsPrefix" 81 /*@C 82 DMSetOptionsPrefix - Sets the prefix used for searching for all 83 DMDA options in the database. 84 85 Logically Collective on DMDA 86 87 Input Parameter: 88 + da - the DMDA context 89 - prefix - the prefix to prepend to all option names 90 91 Notes: 92 A hyphen (-) must NOT be given at the beginning of the prefix name. 93 The first character of all runtime options is AUTOMATICALLY the hyphen. 94 95 Level: advanced 96 97 .keywords: DMDA, set, options, prefix, database 98 99 .seealso: DMSetFromOptions() 100 @*/ 101 PetscErrorCode DMSetOptionsPrefix(DM dm,const char prefix[]) 102 { 103 PetscErrorCode ierr; 104 105 PetscFunctionBegin; 106 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 107 ierr = PetscObjectSetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr); 108 PetscFunctionReturn(0); 109 } 110 111 #undef __FUNCT__ 112 #define __FUNCT__ "DMDestroy" 113 /*@ 114 DMDestroy - Destroys a vector packer or DMDA. 115 116 Collective on DM 117 118 Input Parameter: 119 . dm - the DM object to destroy 120 121 Level: developer 122 123 .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix() 124 125 @*/ 126 PetscErrorCode DMDestroy(DM *dm) 127 { 128 PetscErrorCode ierr; 129 130 PetscFunctionBegin; 131 if (!*dm) PetscFunctionReturn(0); 132 ierr = (*(*dm)->ops->destroy)(dm);CHKERRQ(ierr); 133 PetscFunctionReturn(0); 134 } 135 136 #undef __FUNCT__ 137 #define __FUNCT__ "DMSetUp" 138 /*@ 139 DMSetUp - sets up the data structures inside a DM object 140 141 Collective on DM 142 143 Input Parameter: 144 . dm - the DM object to setup 145 146 Level: developer 147 148 .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix() 149 150 @*/ 151 PetscErrorCode DMSetUp(DM dm) 152 { 153 PetscErrorCode ierr; 154 155 PetscFunctionBegin; 156 if (dm->ops->setup) { 157 ierr = (*dm->ops->setup)(dm);CHKERRQ(ierr); 158 } 159 PetscFunctionReturn(0); 160 } 161 162 #undef __FUNCT__ 163 #define __FUNCT__ "DMSetFromOptions" 164 /*@ 165 DMSetFromOptions - sets parameters in a DM from the options database 166 167 Collective on DM 168 169 Input Parameter: 170 . dm - the DM object to set options for 171 172 Level: developer 173 174 .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix() 175 176 @*/ 177 PetscErrorCode DMSetFromOptions(DM dm) 178 { 179 PetscErrorCode ierr; 180 181 PetscFunctionBegin; 182 if (dm->ops->setfromoptions) { 183 ierr = (*dm->ops->setfromoptions)(dm);CHKERRQ(ierr); 184 } 185 PetscFunctionReturn(0); 186 } 187 188 #undef __FUNCT__ 189 #define __FUNCT__ "DMView" 190 /*@C 191 DMView - Views a vector packer or DMDA. 192 193 Collective on DM 194 195 Input Parameter: 196 + dm - the DM object to view 197 - v - the viewer 198 199 Level: developer 200 201 .seealso DMDestroy(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix() 202 203 @*/ 204 PetscErrorCode DMView(DM dm,PetscViewer v) 205 { 206 PetscErrorCode ierr; 207 208 PetscFunctionBegin; 209 if (!v) { 210 ierr = PetscViewerASCIIGetStdout(((PetscObject)dm)->comm,&v);CHKERRQ(ierr); 211 } 212 if (dm->ops->view) { 213 ierr = (*dm->ops->view)(dm,v);CHKERRQ(ierr); 214 } 215 PetscFunctionReturn(0); 216 } 217 218 #undef __FUNCT__ 219 #define __FUNCT__ "DMCreateGlobalVector" 220 /*@ 221 DMCreateGlobalVector - Creates a global vector from a DMDA or DMComposite object 222 223 Collective on DM 224 225 Input Parameter: 226 . dm - the DM object 227 228 Output Parameter: 229 . vec - the global vector 230 231 Level: developer 232 233 .seealso DMDestroy(), DMView(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix() 234 235 @*/ 236 PetscErrorCode DMCreateGlobalVector(DM dm,Vec *vec) 237 { 238 PetscErrorCode ierr; 239 240 PetscFunctionBegin; 241 ierr = (*dm->ops->createglobalvector)(dm,vec);CHKERRQ(ierr); 242 PetscFunctionReturn(0); 243 } 244 245 #undef __FUNCT__ 246 #define __FUNCT__ "DMCreateLocalVector" 247 /*@ 248 DMCreateLocalVector - Creates a local vector from a DMDA or DMComposite object 249 250 Not Collective 251 252 Input Parameter: 253 . dm - the DM object 254 255 Output Parameter: 256 . vec - the local vector 257 258 Level: developer 259 260 .seealso DMDestroy(), DMView(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix() 261 262 @*/ 263 PetscErrorCode DMCreateLocalVector(DM dm,Vec *vec) 264 { 265 PetscErrorCode ierr; 266 267 PetscFunctionBegin; 268 ierr = (*dm->ops->createlocalvector)(dm,vec);CHKERRQ(ierr); 269 PetscFunctionReturn(0); 270 } 271 272 #undef __FUNCT__ 273 #define __FUNCT__ "DMGetLocalToGlobalMapping" 274 /*@ 275 DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a DM. 276 277 Collective on DM 278 279 Input Parameter: 280 . dm - the DM that provides the mapping 281 282 Output Parameter: 283 . ltog - the mapping 284 285 Level: intermediate 286 287 Notes: 288 This mapping can then be used by VecSetLocalToGlobalMapping() or 289 MatSetLocalToGlobalMapping(). 290 291 .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMappingBlock() 292 @*/ 293 PetscErrorCode DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog) 294 { 295 PetscErrorCode ierr; 296 297 PetscFunctionBegin; 298 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 299 PetscValidPointer(ltog,2); 300 if (!dm->ltogmap) { 301 if (!dm->ops->createlocaltoglobalmapping) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMapping"); 302 ierr = (*dm->ops->createlocaltoglobalmapping)(dm);CHKERRQ(ierr); 303 } 304 *ltog = dm->ltogmap; 305 PetscFunctionReturn(0); 306 } 307 308 #undef __FUNCT__ 309 #define __FUNCT__ "DMGetLocalToGlobalMappingBlock" 310 /*@ 311 DMGetLocalToGlobalMappingBlock - Accesses the blocked local-to-global mapping in a DM. 312 313 Collective on DM 314 315 Input Parameter: 316 . da - the distributed array that provides the mapping 317 318 Output Parameter: 319 . ltog - the block mapping 320 321 Level: intermediate 322 323 Notes: 324 This mapping can then be used by VecSetLocalToGlobalMappingBlock() or 325 MatSetLocalToGlobalMappingBlock(). 326 327 .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMapping(), DMGetBlockSize(), VecSetBlockSize(), MatSetBlockSize() 328 @*/ 329 PetscErrorCode DMGetLocalToGlobalMappingBlock(DM dm,ISLocalToGlobalMapping *ltog) 330 { 331 PetscErrorCode ierr; 332 333 PetscFunctionBegin; 334 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 335 PetscValidPointer(ltog,2); 336 if (!dm->ltogmapb) { 337 PetscInt bs; 338 ierr = DMGetBlockSize(dm,&bs);CHKERRQ(ierr); 339 if (bs > 1) { 340 if (!dm->ops->createlocaltoglobalmappingblock) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMappingBlock"); 341 ierr = (*dm->ops->createlocaltoglobalmappingblock)(dm);CHKERRQ(ierr); 342 } else { 343 ierr = DMGetLocalToGlobalMapping(dm,&dm->ltogmapb);CHKERRQ(ierr); 344 ierr = PetscObjectReference((PetscObject)dm->ltogmapb);CHKERRQ(ierr); 345 } 346 } 347 *ltog = dm->ltogmapb; 348 PetscFunctionReturn(0); 349 } 350 351 #undef __FUNCT__ 352 #define __FUNCT__ "DMGetBlockSize" 353 /*@ 354 DMGetBlockSize - Gets the inherent block size associated with a DM 355 356 Not Collective 357 358 Input Parameter: 359 . dm - the DM with block structure 360 361 Output Parameter: 362 . bs - the block size, 1 implies no exploitable block structure 363 364 Level: intermediate 365 366 .seealso: ISCreateBlock(), VecSetBlockSize(), MatSetBlockSize(), DMGetLocalToGlobalMappingBlock() 367 @*/ 368 PetscErrorCode DMGetBlockSize(DM dm,PetscInt *bs) 369 { 370 PetscFunctionBegin; 371 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 372 PetscValidPointer(bs,2); 373 if (dm->bs < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"DM does not have enough information to provide a block size yet"); 374 *bs = dm->bs; 375 PetscFunctionReturn(0); 376 } 377 378 #undef __FUNCT__ 379 #define __FUNCT__ "DMGetInterpolation" 380 /*@ 381 DMGetInterpolation - Gets interpolation matrix between two DMDA or DMComposite objects 382 383 Collective on DM 384 385 Input Parameter: 386 + dm1 - the DM object 387 - dm2 - the second, finer DM object 388 389 Output Parameter: 390 + mat - the interpolation 391 - vec - the scaling (optional) 392 393 Level: developer 394 395 .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetColoring(), DMGetMatrix() 396 397 @*/ 398 PetscErrorCode DMGetInterpolation(DM dm1,DM dm2,Mat *mat,Vec *vec) 399 { 400 PetscErrorCode ierr; 401 402 PetscFunctionBegin; 403 ierr = (*dm1->ops->getinterpolation)(dm1,dm2,mat,vec);CHKERRQ(ierr); 404 PetscFunctionReturn(0); 405 } 406 407 #undef __FUNCT__ 408 #define __FUNCT__ "DMGetInjection" 409 /*@ 410 DMGetInjection - Gets injection matrix between two DMDA or DMComposite objects 411 412 Collective on DM 413 414 Input Parameter: 415 + dm1 - the DM object 416 - dm2 - the second, finer DM object 417 418 Output Parameter: 419 . ctx - the injection 420 421 Level: developer 422 423 .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetColoring(), DMGetMatrix(), DMGetInterpolation() 424 425 @*/ 426 PetscErrorCode DMGetInjection(DM dm1,DM dm2,VecScatter *ctx) 427 { 428 PetscErrorCode ierr; 429 430 PetscFunctionBegin; 431 ierr = (*dm1->ops->getinjection)(dm1,dm2,ctx);CHKERRQ(ierr); 432 PetscFunctionReturn(0); 433 } 434 435 #undef __FUNCT__ 436 #define __FUNCT__ "DMGetColoring" 437 /*@ 438 DMGetColoring - Gets coloring for a DMDA or DMComposite 439 440 Collective on DM 441 442 Input Parameter: 443 + dm - the DM object 444 . ctype - IS_COLORING_GHOSTED or IS_COLORING_GLOBAL 445 - matype - either MATAIJ or MATBAIJ 446 447 Output Parameter: 448 . coloring - the coloring 449 450 Level: developer 451 452 .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetMatrix() 453 454 @*/ 455 PetscErrorCode DMGetColoring(DM dm,ISColoringType ctype,const MatType mtype,ISColoring *coloring) 456 { 457 PetscErrorCode ierr; 458 459 PetscFunctionBegin; 460 if (!dm->ops->getcoloring) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No coloring for this type of DM yet"); 461 ierr = (*dm->ops->getcoloring)(dm,ctype,mtype,coloring);CHKERRQ(ierr); 462 PetscFunctionReturn(0); 463 } 464 465 #undef __FUNCT__ 466 #define __FUNCT__ "DMGetMatrix" 467 /*@C 468 DMGetMatrix - Gets empty Jacobian for a DMDA or DMComposite 469 470 Collective on DM 471 472 Input Parameter: 473 + dm - the DM object 474 - mtype - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, or 475 any type which inherits from one of these (such as MATAIJ) 476 477 Output Parameter: 478 . mat - the empty Jacobian 479 480 Level: developer 481 482 Notes: This properly preallocates the number of nonzeros in the sparse matrix so you 483 do not need to do it yourself. 484 485 By default it also sets the nonzero structure and puts in the zero entries. To prevent setting 486 the nonzero pattern call DMDASetMatPreallocateOnly() 487 488 For structured grid problems, when you call MatView() on this matrix it is displayed using the global natural ordering, NOT in the ordering used 489 internally by PETSc. 490 491 For structured grid problems, in general it is easiest to use MatSetValuesStencil() or MatSetValuesLocal() to put values into the matrix because MatSetValues() requires 492 the indices for the global numbering for DMDAs which is complicated. 493 494 .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetMatrix() 495 496 @*/ 497 PetscErrorCode DMGetMatrix(DM dm,const MatType mtype,Mat *mat) 498 { 499 PetscErrorCode ierr; 500 char ttype[256]; 501 PetscBool flg; 502 503 PetscFunctionBegin; 504 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 505 PetscValidPointer(mat,3); 506 ierr = PetscStrncpy(ttype,mtype,sizeof ttype);CHKERRQ(ierr); 507 ttype[sizeof ttype-1] = 0; 508 ierr = PetscOptionsBegin(((PetscObject)dm)->comm,((PetscObject)dm)->prefix,"DM options","Mat");CHKERRQ(ierr); 509 ierr = PetscOptionsList("-dm_mat_type","Matrix type","MatSetType",MatList,ttype,ttype,sizeof ttype,&flg);CHKERRQ(ierr); 510 ierr = PetscOptionsEnd(); 511 if (flg || mtype) { 512 ierr = (*dm->ops->getmatrix)(dm,ttype,mat);CHKERRQ(ierr); 513 } else { /* Let the implementation decide */ 514 ierr = (*dm->ops->getmatrix)(dm,PETSC_NULL,mat);CHKERRQ(ierr); 515 } 516 PetscFunctionReturn(0); 517 } 518 519 #undef __FUNCT__ 520 #define __FUNCT__ "DMRefine" 521 /*@ 522 DMRefine - Refines a DM object 523 524 Collective on DM 525 526 Input Parameter: 527 + dm - the DM object 528 - comm - the communicator to contain the new DM object (or PETSC_NULL) 529 530 Output Parameter: 531 . dmf - the refined DM 532 533 Level: developer 534 535 .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetInterpolation() 536 537 @*/ 538 PetscErrorCode DMRefine(DM dm,MPI_Comm comm,DM *dmf) 539 { 540 PetscErrorCode ierr; 541 542 PetscFunctionBegin; 543 ierr = (*dm->ops->refine)(dm,comm,dmf);CHKERRQ(ierr); 544 PetscFunctionReturn(0); 545 } 546 547 #undef __FUNCT__ 548 #define __FUNCT__ "DMGlobalToLocalBegin" 549 /*@ 550 DMGlobalToLocalBegin - Begins updating local vectors from global vector 551 552 Neighbor-wise Collective on DM 553 554 Input Parameters: 555 + dm - the DM object 556 . g - the global vector 557 . mode - INSERT_VALUES or ADD_VALUES 558 - l - the local vector 559 560 561 Level: beginner 562 563 .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin() 564 565 @*/ 566 PetscErrorCode DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l) 567 { 568 PetscErrorCode ierr; 569 570 PetscFunctionBegin; 571 ierr = (*dm->ops->globaltolocalbegin)(dm,g,mode,l);CHKERRQ(ierr); 572 PetscFunctionReturn(0); 573 } 574 575 #undef __FUNCT__ 576 #define __FUNCT__ "DMGlobalToLocalEnd" 577 /*@ 578 DMGlobalToLocalEnd - Ends updating local vectors from global vector 579 580 Neighbor-wise Collective on DM 581 582 Input Parameters: 583 + dm - the DM object 584 . g - the global vector 585 . mode - INSERT_VALUES or ADD_VALUES 586 - l - the local vector 587 588 589 Level: beginner 590 591 .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin() 592 593 @*/ 594 PetscErrorCode DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l) 595 { 596 PetscErrorCode ierr; 597 598 PetscFunctionBegin; 599 ierr = (*dm->ops->globaltolocalend)(dm,g,mode,l);CHKERRQ(ierr); 600 PetscFunctionReturn(0); 601 } 602 603 #undef __FUNCT__ 604 #define __FUNCT__ "DMLocalToGlobalBegin" 605 /*@ 606 DMLocalToGlobalBegin - updates global vectors from local vectors 607 608 Neighbor-wise Collective on DM 609 610 Input Parameters: 611 + dm - the DM object 612 . l - the local vector 613 . mode - if INSERT_VALUES then no parallel communication is used, if ADD_VALUES then all ghost points from the same base point accumulate into that 614 base point. 615 - - the global vector 616 617 Notes: In the ADD_VALUES case you normally would zero the receiving vector before beginning this operation. If you would like to simply add the non-ghosted values in the local 618 array into the global array you need to either (1) zero the ghosted locations and use ADD_VALUES or (2) use INSERT_VALUES into a work global array and then add the work 619 global array to the final global array with VecAXPY(). 620 621 Level: beginner 622 623 .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin() 624 625 @*/ 626 PetscErrorCode DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g) 627 { 628 PetscErrorCode ierr; 629 630 PetscFunctionBegin; 631 ierr = (*dm->ops->localtoglobalbegin)(dm,l,mode,g);CHKERRQ(ierr); 632 PetscFunctionReturn(0); 633 } 634 635 #undef __FUNCT__ 636 #define __FUNCT__ "DMLocalToGlobalEnd" 637 /*@ 638 DMLocalToGlobalEnd - updates global vectors from local vectors 639 640 Neighbor-wise Collective on DM 641 642 Input Parameters: 643 + dm - the DM object 644 . l - the local vector 645 . mode - INSERT_VALUES or ADD_VALUES 646 - g - the global vector 647 648 649 Level: beginner 650 651 .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalEnd() 652 653 @*/ 654 PetscErrorCode DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g) 655 { 656 PetscErrorCode ierr; 657 658 PetscFunctionBegin; 659 ierr = (*dm->ops->localtoglobalend)(dm,l,mode,g);CHKERRQ(ierr); 660 PetscFunctionReturn(0); 661 } 662 663 #undef __FUNCT__ 664 #define __FUNCT__ "DMComputeJacobianDefault" 665 /*@ 666 DMComputeJacobianDefault - computes the Jacobian using the DMComputeFunction() if Jacobian computer is not provided 667 668 Collective on DM 669 670 Input Parameter: 671 + dm - the DM object 672 . x - location to compute Jacobian at; may be ignored for linear problems 673 . A - matrix that defines the operator for the linear solve 674 - B - the matrix used to construct the preconditioner 675 676 Level: developer 677 678 .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetContext(), DMSetInitialGuess(), 679 DMSetFunction() 680 681 @*/ 682 PetscErrorCode DMComputeJacobianDefault(DM dm,Vec x,Mat A,Mat B,MatStructure *stflag) 683 { 684 PetscErrorCode ierr; 685 PetscFunctionBegin; 686 *stflag = SAME_NONZERO_PATTERN; 687 ierr = MatFDColoringApply(B,dm->fd,x,stflag,dm);CHKERRQ(ierr); 688 if (A != B) { 689 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 690 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 691 } 692 PetscFunctionReturn(0); 693 } 694 695 #undef __FUNCT__ 696 #define __FUNCT__ "DMCoarsen" 697 /*@ 698 DMCoarsen - Coarsens a DM object 699 700 Collective on DM 701 702 Input Parameter: 703 + dm - the DM object 704 - comm - the communicator to contain the new DM object (or PETSC_NULL) 705 706 Output Parameter: 707 . dmc - the coarsened DM 708 709 Level: developer 710 711 .seealso DMRefine(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetInterpolation() 712 713 @*/ 714 PetscErrorCode DMCoarsen(DM dm, MPI_Comm comm, DM *dmc) 715 { 716 PetscErrorCode ierr; 717 718 PetscFunctionBegin; 719 ierr = (*dm->ops->coarsen)(dm, comm, dmc);CHKERRQ(ierr); 720 (*dmc)->ops->initialguess = dm->ops->initialguess; 721 (*dmc)->ops->function = dm->ops->function; 722 (*dmc)->ops->functionj = dm->ops->functionj; 723 if (dm->ops->jacobian != DMComputeJacobianDefault) { 724 (*dmc)->ops->jacobian = dm->ops->jacobian; 725 } 726 PetscFunctionReturn(0); 727 } 728 729 #undef __FUNCT__ 730 #define __FUNCT__ "DMRefineHierarchy" 731 /*@C 732 DMRefineHierarchy - Refines a DM object, all levels at once 733 734 Collective on DM 735 736 Input Parameter: 737 + dm - the DM object 738 - nlevels - the number of levels of refinement 739 740 Output Parameter: 741 . dmf - the refined DM hierarchy 742 743 Level: developer 744 745 .seealso DMCoarsenHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetInterpolation() 746 747 @*/ 748 PetscErrorCode DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[]) 749 { 750 PetscErrorCode ierr; 751 752 PetscFunctionBegin; 753 if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 754 if (nlevels == 0) PetscFunctionReturn(0); 755 if (dm->ops->refinehierarchy) { 756 ierr = (*dm->ops->refinehierarchy)(dm,nlevels,dmf);CHKERRQ(ierr); 757 } else if (dm->ops->refine) { 758 PetscInt i; 759 760 ierr = DMRefine(dm,((PetscObject)dm)->comm,&dmf[0]);CHKERRQ(ierr); 761 for (i=1; i<nlevels; i++) { 762 ierr = DMRefine(dmf[i-1],((PetscObject)dm)->comm,&dmf[i]);CHKERRQ(ierr); 763 } 764 } else { 765 SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No RefineHierarchy for this DM yet"); 766 } 767 PetscFunctionReturn(0); 768 } 769 770 #undef __FUNCT__ 771 #define __FUNCT__ "DMCoarsenHierarchy" 772 /*@C 773 DMCoarsenHierarchy - Coarsens a DM object, all levels at once 774 775 Collective on DM 776 777 Input Parameter: 778 + dm - the DM object 779 - nlevels - the number of levels of coarsening 780 781 Output Parameter: 782 . dmc - the coarsened DM hierarchy 783 784 Level: developer 785 786 .seealso DMRefineHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetInterpolation() 787 788 @*/ 789 PetscErrorCode DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[]) 790 { 791 PetscErrorCode ierr; 792 793 PetscFunctionBegin; 794 if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 795 if (nlevels == 0) PetscFunctionReturn(0); 796 PetscValidPointer(dmc,3); 797 if (dm->ops->coarsenhierarchy) { 798 ierr = (*dm->ops->coarsenhierarchy)(dm, nlevels, dmc);CHKERRQ(ierr); 799 } else if (dm->ops->coarsen) { 800 PetscInt i; 801 802 ierr = DMCoarsen(dm,((PetscObject)dm)->comm,&dmc[0]);CHKERRQ(ierr); 803 for (i=1; i<nlevels; i++) { 804 ierr = DMCoarsen(dmc[i-1],((PetscObject)dm)->comm,&dmc[i]);CHKERRQ(ierr); 805 } 806 } else { 807 SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet"); 808 } 809 PetscFunctionReturn(0); 810 } 811 812 #undef __FUNCT__ 813 #define __FUNCT__ "DMGetAggregates" 814 /*@ 815 DMGetAggregates - Gets the aggregates that map between 816 grids associated with two DMs. 817 818 Collective on DM 819 820 Input Parameters: 821 + dmc - the coarse grid DM 822 - dmf - the fine grid DM 823 824 Output Parameters: 825 . rest - the restriction matrix (transpose of the projection matrix) 826 827 Level: intermediate 828 829 .keywords: interpolation, restriction, multigrid 830 831 .seealso: DMRefine(), DMGetInjection(), DMGetInterpolation() 832 @*/ 833 PetscErrorCode DMGetAggregates(DM dmc, DM dmf, Mat *rest) 834 { 835 PetscErrorCode ierr; 836 837 PetscFunctionBegin; 838 ierr = (*dmc->ops->getaggregates)(dmc, dmf, rest);CHKERRQ(ierr); 839 PetscFunctionReturn(0); 840 } 841 842 #undef __FUNCT__ 843 #define __FUNCT__ "DMSetContext" 844 /*@ 845 DMSetContext - Set a user context into a DM object 846 847 Not Collective 848 849 Input Parameters: 850 + dm - the DM object 851 - ctx - the user context 852 853 Level: intermediate 854 855 .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetContext() 856 857 @*/ 858 PetscErrorCode DMSetContext(DM dm,void *ctx) 859 { 860 PetscFunctionBegin; 861 dm->ctx = ctx; 862 PetscFunctionReturn(0); 863 } 864 865 #undef __FUNCT__ 866 #define __FUNCT__ "DMGetContext" 867 /*@ 868 DMGetContext - Gets a user context from a DM object 869 870 Not Collective 871 872 Input Parameter: 873 . dm - the DM object 874 875 Output Parameter: 876 . ctx - the user context 877 878 Level: intermediate 879 880 .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetContext() 881 882 @*/ 883 PetscErrorCode DMGetContext(DM dm,void **ctx) 884 { 885 PetscFunctionBegin; 886 *ctx = dm->ctx; 887 PetscFunctionReturn(0); 888 } 889 890 #undef __FUNCT__ 891 #define __FUNCT__ "DMSetInitialGuess" 892 /*@ 893 DMSetInitialGuess - sets a function to compute an initial guess vector entries for the solvers 894 895 Logically Collective on DM 896 897 Input Parameter: 898 + dm - the DM object to destroy 899 - f - the function to compute the initial guess 900 901 Level: intermediate 902 903 .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetContext(), DMSetFunction(), DMSetJacobian() 904 905 @*/ 906 PetscErrorCode DMSetInitialGuess(DM dm,PetscErrorCode (*f)(DM,Vec)) 907 { 908 PetscFunctionBegin; 909 dm->ops->initialguess = f; 910 PetscFunctionReturn(0); 911 } 912 913 #undef __FUNCT__ 914 #define __FUNCT__ "DMSetFunction" 915 /*@ 916 DMSetFunction - sets a function to compute the right hand side vector entries for the KSP solver or nonlinear function for SNES 917 918 Logically Collective on DM 919 920 Input Parameter: 921 + dm - the DM object 922 - f - the function to compute (use PETSC_NULL to cancel a previous function that was set) 923 924 Level: intermediate 925 926 Notes: This sets both the function for function evaluations and the function used to compute Jacobians via finite differences if no Jacobian 927 computer is provided with DMSetJacobian(). Canceling cancels the function, but not the function used to compute the Jacobian. 928 929 .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetContext(), DMSetInitialGuess(), 930 DMSetJacobian() 931 932 @*/ 933 PetscErrorCode DMSetFunction(DM dm,PetscErrorCode (*f)(DM,Vec,Vec)) 934 { 935 PetscFunctionBegin; 936 dm->ops->function = f; 937 if (f) { 938 dm->ops->functionj = f; 939 } 940 PetscFunctionReturn(0); 941 } 942 943 #undef __FUNCT__ 944 #define __FUNCT__ "DMSetJacobian" 945 /*@ 946 DMSetJacobian - sets a function to compute the matrix entries for the KSP solver or Jacobian for SNES 947 948 Logically Collective on DM 949 950 Input Parameter: 951 + dm - the DM object to destroy 952 - f - the function to compute the matrix entries 953 954 Level: intermediate 955 956 .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetContext(), DMSetInitialGuess(), 957 DMSetFunction() 958 959 @*/ 960 PetscErrorCode DMSetJacobian(DM dm,PetscErrorCode (*f)(DM,Vec,Mat,Mat,MatStructure*)) 961 { 962 PetscFunctionBegin; 963 dm->ops->jacobian = f; 964 PetscFunctionReturn(0); 965 } 966 967 #undef __FUNCT__ 968 #define __FUNCT__ "DMComputeInitialGuess" 969 /*@ 970 DMComputeInitialGuess - computes an initial guess vector entries for the KSP solvers 971 972 Collective on DM 973 974 Input Parameter: 975 + dm - the DM object to destroy 976 - x - the vector to hold the initial guess values 977 978 Level: developer 979 980 .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetContext(), DMSetRhs(), DMSetMat() 981 982 @*/ 983 PetscErrorCode DMComputeInitialGuess(DM dm,Vec x) 984 { 985 PetscErrorCode ierr; 986 PetscFunctionBegin; 987 if (!dm->ops->initialguess) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide function with DMSetInitialGuess()"); 988 ierr = (*dm->ops->initialguess)(dm,x);CHKERRQ(ierr); 989 PetscFunctionReturn(0); 990 } 991 992 #undef __FUNCT__ 993 #define __FUNCT__ "DMHasInitialGuess" 994 /*@ 995 DMHasInitialGuess - does the DM object have an initial guess function 996 997 Not Collective 998 999 Input Parameter: 1000 . dm - the DM object to destroy 1001 1002 Output Parameter: 1003 . flg - PETSC_TRUE if function exists 1004 1005 Level: developer 1006 1007 .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetContext(), DMSetFunction(), DMSetJacobian() 1008 1009 @*/ 1010 PetscErrorCode DMHasInitialGuess(DM dm,PetscBool *flg) 1011 { 1012 PetscFunctionBegin; 1013 *flg = (dm->ops->initialguess) ? PETSC_TRUE : PETSC_FALSE; 1014 PetscFunctionReturn(0); 1015 } 1016 1017 #undef __FUNCT__ 1018 #define __FUNCT__ "DMHasFunction" 1019 /*@ 1020 DMHasFunction - does the DM object have a function 1021 1022 Not Collective 1023 1024 Input Parameter: 1025 . dm - the DM object to destroy 1026 1027 Output Parameter: 1028 . flg - PETSC_TRUE if function exists 1029 1030 Level: developer 1031 1032 .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetContext(), DMSetFunction(), DMSetJacobian() 1033 1034 @*/ 1035 PetscErrorCode DMHasFunction(DM dm,PetscBool *flg) 1036 { 1037 PetscFunctionBegin; 1038 *flg = (dm->ops->function) ? PETSC_TRUE : PETSC_FALSE; 1039 PetscFunctionReturn(0); 1040 } 1041 1042 #undef __FUNCT__ 1043 #define __FUNCT__ "DMHasJacobian" 1044 /*@ 1045 DMHasJacobian - does the DM object have a matrix function 1046 1047 Not Collective 1048 1049 Input Parameter: 1050 . dm - the DM object to destroy 1051 1052 Output Parameter: 1053 . flg - PETSC_TRUE if function exists 1054 1055 Level: developer 1056 1057 .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetContext(), DMSetFunction(), DMSetJacobian() 1058 1059 @*/ 1060 PetscErrorCode DMHasJacobian(DM dm,PetscBool *flg) 1061 { 1062 PetscFunctionBegin; 1063 *flg = (dm->ops->jacobian) ? PETSC_TRUE : PETSC_FALSE; 1064 PetscFunctionReturn(0); 1065 } 1066 1067 #undef __FUNCT__ 1068 #define __FUNCT__ "DMComputeFunction" 1069 /*@ 1070 DMComputeFunction - computes the right hand side vector entries for the KSP solver or nonlinear function for SNES 1071 1072 Collective on DM 1073 1074 Input Parameter: 1075 + dm - the DM object to destroy 1076 . x - the location where the function is evaluationed, may be ignored for linear problems 1077 - b - the vector to hold the right hand side entries 1078 1079 Level: developer 1080 1081 .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetContext(), DMSetInitialGuess(), 1082 DMSetJacobian() 1083 1084 @*/ 1085 PetscErrorCode DMComputeFunction(DM dm,Vec x,Vec b) 1086 { 1087 PetscErrorCode ierr; 1088 PetscFunctionBegin; 1089 if (!dm->ops->function) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide function with DMSetFunction()"); 1090 if (!x) x = dm->x; 1091 ierr = (*dm->ops->function)(dm,x,b);CHKERRQ(ierr); 1092 PetscFunctionReturn(0); 1093 } 1094 1095 1096 #undef __FUNCT__ 1097 #define __FUNCT__ "DMComputeJacobian" 1098 /*@ 1099 DMComputeJacobian - compute the matrix entries for the solver 1100 1101 Collective on DM 1102 1103 Input Parameter: 1104 + dm - the DM object 1105 . x - location to compute Jacobian at; may be ignored for linear problems 1106 . A - matrix that defines the operator for the linear solve 1107 - B - the matrix used to construct the preconditioner 1108 1109 Level: developer 1110 1111 .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetContext(), DMSetInitialGuess(), 1112 DMSetFunction() 1113 1114 @*/ 1115 PetscErrorCode DMComputeJacobian(DM dm,Vec x,Mat A,Mat B,MatStructure *stflag) 1116 { 1117 PetscErrorCode ierr; 1118 1119 PetscFunctionBegin; 1120 if (!dm->ops->jacobian) { 1121 ISColoring coloring; 1122 MatFDColoring fd; 1123 1124 ierr = DMGetColoring(dm,IS_COLORING_GHOSTED,MATAIJ,&coloring);CHKERRQ(ierr); 1125 ierr = MatFDColoringCreate(B,coloring,&fd);CHKERRQ(ierr); 1126 ierr = ISColoringDestroy(&coloring);CHKERRQ(ierr); 1127 ierr = MatFDColoringSetFunction(fd,(PetscErrorCode (*)(void))dm->ops->functionj,dm);CHKERRQ(ierr); 1128 dm->fd = fd; 1129 dm->ops->jacobian = DMComputeJacobianDefault; 1130 1131 if (!dm->x) { 1132 ierr = MatGetVecs(B,&dm->x,PETSC_NULL);CHKERRQ(ierr); 1133 } 1134 } 1135 if (!x) x = dm->x; 1136 ierr = (*dm->ops->jacobian)(dm,x,A,B,stflag);CHKERRQ(ierr); 1137 PetscFunctionReturn(0); 1138 } 1139 1140 PetscFList DMList = PETSC_NULL; 1141 PetscBool DMRegisterAllCalled = PETSC_FALSE; 1142 1143 #undef __FUNCT__ 1144 #define __FUNCT__ "DMSetType" 1145 /*@C 1146 DMSetType - Builds a DM, for a particular DM implementation. 1147 1148 Collective on DM 1149 1150 Input Parameters: 1151 + dm - The DM object 1152 - method - The name of the DM type 1153 1154 Options Database Key: 1155 . -dm_type <type> - Sets the DM type; use -help for a list of available types 1156 1157 Notes: 1158 See "petsc/include/petscdm.h" for available DM types (for instance, DM1D, DM2D, or DM3D). 1159 1160 Level: intermediate 1161 1162 .keywords: DM, set, type 1163 .seealso: DMGetType(), DMCreate() 1164 @*/ 1165 PetscErrorCode DMSetType(DM dm, const DMType method) 1166 { 1167 PetscErrorCode (*r)(DM); 1168 PetscBool match; 1169 PetscErrorCode ierr; 1170 1171 PetscFunctionBegin; 1172 PetscValidHeaderSpecific(dm, DM_CLASSID,1); 1173 ierr = PetscTypeCompare((PetscObject) dm, method, &match);CHKERRQ(ierr); 1174 if (match) PetscFunctionReturn(0); 1175 1176 if (!DMRegisterAllCalled) {ierr = DMRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 1177 ierr = PetscFListFind(DMList, ((PetscObject)dm)->comm, method,(void (**)(void)) &r);CHKERRQ(ierr); 1178 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method); 1179 1180 if (dm->ops->destroy) { 1181 ierr = (*dm->ops->destroy)(dm);CHKERRQ(ierr); 1182 } 1183 ierr = (*r)(dm);CHKERRQ(ierr); 1184 ierr = PetscObjectChangeTypeName((PetscObject)dm,method);CHKERRQ(ierr); 1185 PetscFunctionReturn(0); 1186 } 1187 1188 #undef __FUNCT__ 1189 #define __FUNCT__ "DMGetType" 1190 /*@C 1191 DMGetType - Gets the DM type name (as a string) from the DM. 1192 1193 Not Collective 1194 1195 Input Parameter: 1196 . dm - The DM 1197 1198 Output Parameter: 1199 . type - The DM type name 1200 1201 Level: intermediate 1202 1203 .keywords: DM, get, type, name 1204 .seealso: DMSetType(), DMCreate() 1205 @*/ 1206 PetscErrorCode DMGetType(DM dm, const DMType *type) 1207 { 1208 PetscErrorCode ierr; 1209 1210 PetscFunctionBegin; 1211 PetscValidHeaderSpecific(dm, DM_CLASSID,1); 1212 PetscValidCharPointer(type,2); 1213 if (!DMRegisterAllCalled) { 1214 ierr = DMRegisterAll(PETSC_NULL);CHKERRQ(ierr); 1215 } 1216 *type = ((PetscObject)dm)->type_name; 1217 PetscFunctionReturn(0); 1218 } 1219 1220 #undef __FUNCT__ 1221 #define __FUNCT__ "DMConvert" 1222 /*@C 1223 DMConvert - Converts a DM to another DM, either of the same or different type. 1224 1225 Collective on DM 1226 1227 Input Parameters: 1228 + dm - the DM 1229 - newtype - new DM type (use "same" for the same type) 1230 1231 Output Parameter: 1232 . M - pointer to new DM 1233 1234 Notes: 1235 Cannot be used to convert a sequential DM to parallel or parallel to sequential, 1236 the MPI communicator of the generated DM is always the same as the communicator 1237 of the input DM. 1238 1239 Level: intermediate 1240 1241 .seealso: DMCreate() 1242 @*/ 1243 PetscErrorCode DMConvert(DM dm, const DMType newtype, DM *M) 1244 { 1245 DM B; 1246 char convname[256]; 1247 PetscBool sametype, issame; 1248 PetscErrorCode ierr; 1249 1250 PetscFunctionBegin; 1251 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1252 PetscValidType(dm,1); 1253 PetscValidPointer(M,3); 1254 ierr = PetscTypeCompare((PetscObject) dm, newtype, &sametype);CHKERRQ(ierr); 1255 ierr = PetscStrcmp(newtype, "same", &issame);CHKERRQ(ierr); 1256 { 1257 PetscErrorCode (*conv)(DM, const DMType, DM *) = PETSC_NULL; 1258 1259 /* 1260 Order of precedence: 1261 1) See if a specialized converter is known to the current DM. 1262 2) See if a specialized converter is known to the desired DM class. 1263 3) See if a good general converter is registered for the desired class 1264 4) See if a good general converter is known for the current matrix. 1265 5) Use a really basic converter. 1266 */ 1267 1268 /* 1) See if a specialized converter is known to the current DM and the desired class */ 1269 ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr); 1270 ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr); 1271 ierr = PetscStrcat(convname,"_");CHKERRQ(ierr); 1272 ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr); 1273 ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr); 1274 ierr = PetscObjectQueryFunction((PetscObject)dm,convname,(void (**)(void))&conv);CHKERRQ(ierr); 1275 if (conv) goto foundconv; 1276 1277 /* 2) See if a specialized converter is known to the desired DM class. */ 1278 ierr = DMCreate(((PetscObject) dm)->comm, &B);CHKERRQ(ierr); 1279 ierr = DMSetType(B, newtype);CHKERRQ(ierr); 1280 ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr); 1281 ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr); 1282 ierr = PetscStrcat(convname,"_");CHKERRQ(ierr); 1283 ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr); 1284 ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr); 1285 ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr); 1286 if (conv) { 1287 ierr = DMDestroy(&B);CHKERRQ(ierr); 1288 goto foundconv; 1289 } 1290 1291 #if 0 1292 /* 3) See if a good general converter is registered for the desired class */ 1293 conv = B->ops->convertfrom; 1294 ierr = DMDestroy(&B);CHKERRQ(ierr); 1295 if (conv) goto foundconv; 1296 1297 /* 4) See if a good general converter is known for the current matrix */ 1298 if (dm->ops->convert) { 1299 conv = dm->ops->convert; 1300 } 1301 if (conv) goto foundconv; 1302 #endif 1303 1304 /* 5) Use a really basic converter. */ 1305 SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype); 1306 1307 foundconv: 1308 ierr = PetscLogEventBegin(DM_Convert,dm,0,0,0);CHKERRQ(ierr); 1309 ierr = (*conv)(dm,newtype,M);CHKERRQ(ierr); 1310 ierr = PetscLogEventEnd(DM_Convert,dm,0,0,0);CHKERRQ(ierr); 1311 } 1312 ierr = PetscObjectStateIncrease((PetscObject) *M);CHKERRQ(ierr); 1313 PetscFunctionReturn(0); 1314 } 1315 1316 /*--------------------------------------------------------------------------------------------------------------------*/ 1317 1318 #undef __FUNCT__ 1319 #define __FUNCT__ "DMRegister" 1320 /*@C 1321 DMRegister - See DMRegisterDynamic() 1322 1323 Level: advanced 1324 @*/ 1325 PetscErrorCode DMRegister(const char sname[], const char path[], const char name[], PetscErrorCode (*function)(DM)) 1326 { 1327 char fullname[PETSC_MAX_PATH_LEN]; 1328 PetscErrorCode ierr; 1329 1330 PetscFunctionBegin; 1331 ierr = PetscStrcpy(fullname, path);CHKERRQ(ierr); 1332 ierr = PetscStrcat(fullname, ":");CHKERRQ(ierr); 1333 ierr = PetscStrcat(fullname, name);CHKERRQ(ierr); 1334 ierr = PetscFListAdd(&DMList, sname, fullname, (void (*)(void)) function);CHKERRQ(ierr); 1335 PetscFunctionReturn(0); 1336 } 1337 1338 1339 /*--------------------------------------------------------------------------------------------------------------------*/ 1340 #undef __FUNCT__ 1341 #define __FUNCT__ "DMRegisterDestroy" 1342 /*@C 1343 DMRegisterDestroy - Frees the list of DM methods that were registered by DMRegister()/DMRegisterDynamic(). 1344 1345 Not Collective 1346 1347 Level: advanced 1348 1349 .keywords: DM, register, destroy 1350 .seealso: DMRegister(), DMRegisterAll(), DMRegisterDynamic() 1351 @*/ 1352 PetscErrorCode DMRegisterDestroy(void) 1353 { 1354 PetscErrorCode ierr; 1355 1356 PetscFunctionBegin; 1357 ierr = PetscFListDestroy(&DMList);CHKERRQ(ierr); 1358 DMRegisterAllCalled = PETSC_FALSE; 1359 PetscFunctionReturn(0); 1360 } 1361 1362 #if defined(PETSC_HAVE_MATLAB_ENGINE) 1363 #include <mex.h> 1364 1365 typedef struct {char *funcname; char *jacname; mxArray *ctx;} DMMatlabContext; 1366 1367 #undef __FUNCT__ 1368 #define __FUNCT__ "DMComputeFunction_Matlab" 1369 /* 1370 DMComputeFunction_Matlab - Calls the function that has been set with 1371 DMSetFunctionMatlab(). 1372 1373 For linear problems x is null 1374 1375 .seealso: DMSetFunction(), DMGetFunction() 1376 */ 1377 PetscErrorCode DMComputeFunction_Matlab(DM dm,Vec x,Vec y) 1378 { 1379 PetscErrorCode ierr; 1380 DMMatlabContext *sctx; 1381 int nlhs = 1,nrhs = 4; 1382 mxArray *plhs[1],*prhs[4]; 1383 long long int lx = 0,ly = 0,ls = 0; 1384 1385 PetscFunctionBegin; 1386 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1387 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1388 PetscCheckSameComm(dm,1,y,3); 1389 1390 /* call Matlab function in ctx with arguments x and y */ 1391 ierr = DMGetContext(dm,(void**)&sctx);CHKERRQ(ierr); 1392 ierr = PetscMemcpy(&ls,&dm,sizeof(dm));CHKERRQ(ierr); 1393 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 1394 ierr = PetscMemcpy(&ly,&y,sizeof(y));CHKERRQ(ierr); 1395 prhs[0] = mxCreateDoubleScalar((double)ls); 1396 prhs[1] = mxCreateDoubleScalar((double)lx); 1397 prhs[2] = mxCreateDoubleScalar((double)ly); 1398 prhs[3] = mxCreateString(sctx->funcname); 1399 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscDMComputeFunctionInternal");CHKERRQ(ierr); 1400 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 1401 mxDestroyArray(prhs[0]); 1402 mxDestroyArray(prhs[1]); 1403 mxDestroyArray(prhs[2]); 1404 mxDestroyArray(prhs[3]); 1405 mxDestroyArray(plhs[0]); 1406 PetscFunctionReturn(0); 1407 } 1408 1409 1410 #undef __FUNCT__ 1411 #define __FUNCT__ "DMSetFunctionMatlab" 1412 /* 1413 DMSetFunctionMatlab - Sets the function evaluation routine 1414 1415 */ 1416 PetscErrorCode DMSetFunctionMatlab(DM dm,const char *func) 1417 { 1418 PetscErrorCode ierr; 1419 DMMatlabContext *sctx; 1420 1421 PetscFunctionBegin; 1422 /* currently sctx is memory bleed */ 1423 ierr = DMGetContext(dm,(void**)&sctx);CHKERRQ(ierr); 1424 if (!sctx) { 1425 ierr = PetscMalloc(sizeof(DMMatlabContext),&sctx);CHKERRQ(ierr); 1426 } 1427 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 1428 ierr = DMSetContext(dm,sctx);CHKERRQ(ierr); 1429 ierr = DMSetFunction(dm,DMComputeFunction_Matlab);CHKERRQ(ierr); 1430 PetscFunctionReturn(0); 1431 } 1432 1433 #undef __FUNCT__ 1434 #define __FUNCT__ "DMComputeJacobian_Matlab" 1435 /* 1436 DMComputeJacobian_Matlab - Calls the function that has been set with 1437 DMSetJacobianMatlab(). 1438 1439 For linear problems x is null 1440 1441 .seealso: DMSetFunction(), DMGetFunction() 1442 */ 1443 PetscErrorCode DMComputeJacobian_Matlab(DM dm,Vec x,Mat A,Mat B,MatStructure *str) 1444 { 1445 PetscErrorCode ierr; 1446 DMMatlabContext *sctx; 1447 int nlhs = 2,nrhs = 5; 1448 mxArray *plhs[2],*prhs[5]; 1449 long long int lx = 0,lA = 0,lB = 0,ls = 0; 1450 1451 PetscFunctionBegin; 1452 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1453 PetscValidHeaderSpecific(A,MAT_CLASSID,3); 1454 1455 /* call MATLAB function in ctx with arguments x, A, and B */ 1456 ierr = DMGetContext(dm,(void**)&sctx);CHKERRQ(ierr); 1457 ierr = PetscMemcpy(&ls,&dm,sizeof(dm));CHKERRQ(ierr); 1458 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 1459 ierr = PetscMemcpy(&lA,&A,sizeof(A));CHKERRQ(ierr); 1460 ierr = PetscMemcpy(&lB,&B,sizeof(B));CHKERRQ(ierr); 1461 prhs[0] = mxCreateDoubleScalar((double)ls); 1462 prhs[1] = mxCreateDoubleScalar((double)lx); 1463 prhs[2] = mxCreateDoubleScalar((double)lA); 1464 prhs[3] = mxCreateDoubleScalar((double)lB); 1465 prhs[4] = mxCreateString(sctx->jacname); 1466 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscDMComputeJacobianInternal");CHKERRQ(ierr); 1467 *str = (MatStructure) mxGetScalar(plhs[0]); 1468 ierr = (PetscInt) mxGetScalar(plhs[1]);CHKERRQ(ierr); 1469 mxDestroyArray(prhs[0]); 1470 mxDestroyArray(prhs[1]); 1471 mxDestroyArray(prhs[2]); 1472 mxDestroyArray(prhs[3]); 1473 mxDestroyArray(prhs[4]); 1474 mxDestroyArray(plhs[0]); 1475 mxDestroyArray(plhs[1]); 1476 PetscFunctionReturn(0); 1477 } 1478 1479 1480 #undef __FUNCT__ 1481 #define __FUNCT__ "DMSetJacobianMatlab" 1482 /* 1483 DMSetJacobianMatlab - Sets the Jacobian function evaluation routine 1484 1485 */ 1486 PetscErrorCode DMSetJacobianMatlab(DM dm,const char *func) 1487 { 1488 PetscErrorCode ierr; 1489 DMMatlabContext *sctx; 1490 1491 PetscFunctionBegin; 1492 /* currently sctx is memory bleed */ 1493 ierr = DMGetContext(dm,(void**)&sctx);CHKERRQ(ierr); 1494 if (!sctx) { 1495 ierr = PetscMalloc(sizeof(DMMatlabContext),&sctx);CHKERRQ(ierr); 1496 } 1497 ierr = PetscStrallocpy(func,&sctx->jacname);CHKERRQ(ierr); 1498 ierr = DMSetContext(dm,sctx);CHKERRQ(ierr); 1499 ierr = DMSetJacobian(dm,DMComputeJacobian_Matlab);CHKERRQ(ierr); 1500 PetscFunctionReturn(0); 1501 } 1502 #endif 1503