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