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