1 #include <petsc-private/tsimpl.h> /*I "petscts.h" I*/ 2 #include <petsc-private/dmimpl.h> 3 4 #undef __FUNCT__ 5 #define __FUNCT__ "DMTSDestroy" 6 static PetscErrorCode DMTSDestroy(DMTS *kdm) 7 { 8 PetscErrorCode ierr; 9 10 PetscFunctionBegin; 11 if (!*kdm) PetscFunctionReturn(0); 12 PetscValidHeaderSpecific((*kdm),DMTS_CLASSID,1); 13 if (--((PetscObject)(*kdm))->refct > 0) {*kdm = 0; PetscFunctionReturn(0);} 14 if ((*kdm)->ops->destroy) {ierr = ((*kdm)->ops->destroy)(*kdm);CHKERRQ(ierr);} 15 ierr = PetscHeaderDestroy(kdm);CHKERRQ(ierr); 16 PetscFunctionReturn(0); 17 } 18 19 #undef __FUNCT__ 20 #define __FUNCT__ "DMTSLoad" 21 PetscErrorCode DMTSLoad(DMTS kdm,PetscViewer viewer) 22 { 23 PetscErrorCode ierr; 24 25 PetscFunctionBegin; 26 ierr = PetscViewerBinaryRead(viewer,&kdm->ops->ifunction,1,PETSC_FUNCTION);CHKERRQ(ierr); 27 ierr = PetscViewerBinaryRead(viewer,&kdm->ops->ifunctionview,1,PETSC_FUNCTION);CHKERRQ(ierr); 28 ierr = PetscViewerBinaryRead(viewer,&kdm->ops->ifunctionload,1,PETSC_FUNCTION);CHKERRQ(ierr); 29 if (kdm->ops->ifunctionload) { 30 ierr = (*kdm->ops->ifunctionload)(&kdm->ifunctionctx,viewer);CHKERRQ(ierr); 31 } 32 ierr = PetscViewerBinaryRead(viewer,&kdm->ops->ijacobian,1,PETSC_FUNCTION);CHKERRQ(ierr); 33 ierr = PetscViewerBinaryRead(viewer,&kdm->ops->ijacobianview,1,PETSC_FUNCTION);CHKERRQ(ierr); 34 ierr = PetscViewerBinaryRead(viewer,&kdm->ops->ijacobianload,1,PETSC_FUNCTION);CHKERRQ(ierr); 35 if (kdm->ops->ijacobianload) { 36 ierr = (*kdm->ops->ijacobianload)(&kdm->ijacobianctx,viewer);CHKERRQ(ierr); 37 } 38 PetscFunctionReturn(0); 39 } 40 41 #undef __FUNCT__ 42 #define __FUNCT__ "DMTSView" 43 PetscErrorCode DMTSView(DMTS kdm,PetscViewer viewer) 44 { 45 PetscErrorCode ierr; 46 PetscBool isascii,isbinary; 47 48 PetscFunctionBegin; 49 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 50 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 51 if (isascii) { 52 #if defined(PETSC_SERIALIZE_FUNCTIONS) 53 const char *fname; 54 55 ierr = PetscFPTFind(kdm->ops->ifunction,&fname);CHKERRQ(ierr); 56 if (fname) { 57 ierr = PetscViewerASCIIPrintf(viewer," IFunction used by TS: %s\n",fname);CHKERRQ(ierr); 58 } 59 ierr = PetscFPTFind(kdm->ops->ijacobian,&fname);CHKERRQ(ierr); 60 if (fname) { 61 ierr = PetscViewerASCIIPrintf(viewer," IJacobian function used by TS: %s\n",fname);CHKERRQ(ierr); 62 } 63 #endif 64 } else if (isbinary) { 65 ierr = PetscViewerBinaryWrite(viewer,(void*)kdm->ops->ifunction,1,PETSC_FUNCTION,PETSC_FALSE);CHKERRQ(ierr); 66 ierr = PetscViewerBinaryWrite(viewer,(void*)kdm->ops->ifunctionview,1,PETSC_FUNCTION,PETSC_FALSE);CHKERRQ(ierr); 67 ierr = PetscViewerBinaryWrite(viewer,(void*)kdm->ops->ifunctionload,1,PETSC_FUNCTION,PETSC_FALSE);CHKERRQ(ierr); 68 if (kdm->ops->ifunctionview) { 69 ierr = (*kdm->ops->ifunctionview)(kdm->ifunctionctx,viewer);CHKERRQ(ierr); 70 } 71 ierr = PetscViewerBinaryWrite(viewer,(void*)kdm->ops->ijacobian,1,PETSC_FUNCTION,PETSC_FALSE);CHKERRQ(ierr); 72 ierr = PetscViewerBinaryWrite(viewer,(void*)kdm->ops->ijacobianview,1,PETSC_FUNCTION,PETSC_FALSE);CHKERRQ(ierr); 73 ierr = PetscViewerBinaryWrite(viewer,(void*)kdm->ops->ijacobianload,1,PETSC_FUNCTION,PETSC_FALSE);CHKERRQ(ierr); 74 if (kdm->ops->ijacobianview) { 75 ierr = (*kdm->ops->ijacobianview)(kdm->ijacobianctx,viewer);CHKERRQ(ierr); 76 } 77 } 78 PetscFunctionReturn(0); 79 } 80 81 #undef __FUNCT__ 82 #define __FUNCT__ "DMTSCreate" 83 static PetscErrorCode DMTSCreate(MPI_Comm comm,DMTS *kdm) 84 { 85 PetscErrorCode ierr; 86 87 PetscFunctionBegin; 88 #if !defined(PETSC_USE_DYNAMIC_LIBRARIES) 89 ierr = TSInitializePackage(PETSC_NULL);CHKERRQ(ierr); 90 #endif 91 ierr = PetscHeaderCreate(*kdm, _p_DMTS, struct _DMTSOps, DMTS_CLASSID, -1, "DMTS", "DMTS", "DMTS", comm, DMTSDestroy, DMTSView);CHKERRQ(ierr); 92 ierr = PetscMemzero((*kdm)->ops, sizeof(struct _DMTSOps));CHKERRQ(ierr); 93 PetscFunctionReturn(0); 94 } 95 96 #undef __FUNCT__ 97 #define __FUNCT__ "DMCoarsenHook_DMTS" 98 /* Attaches the DMTS to the coarse level. 99 * Under what conditions should we copy versus duplicate? 100 */ 101 static PetscErrorCode DMCoarsenHook_DMTS(DM dm,DM dmc,void *ctx) 102 { 103 PetscErrorCode ierr; 104 105 PetscFunctionBegin; 106 ierr = DMCopyDMTS(dm,dmc);CHKERRQ(ierr); 107 PetscFunctionReturn(0); 108 } 109 110 #undef __FUNCT__ 111 #define __FUNCT__ "DMRestrictHook_DMTS" 112 /* This could restrict auxiliary information to the coarse level. 113 */ 114 static PetscErrorCode DMRestrictHook_DMTS(DM dm,Mat Restrict,Vec rscale,Mat Inject,DM dmc,void *ctx) 115 { 116 117 PetscFunctionBegin; 118 PetscFunctionReturn(0); 119 } 120 121 #undef __FUNCT__ 122 #define __FUNCT__ "DMSubDomainHook_DMTS" 123 static PetscErrorCode DMSubDomainHook_DMTS(DM dm,DM subdm,void *ctx) 124 { 125 PetscErrorCode ierr; 126 127 PetscFunctionBegin; 128 ierr = DMCopyDMTS(dm,subdm);CHKERRQ(ierr); 129 PetscFunctionReturn(0); 130 } 131 132 #undef __FUNCT__ 133 #define __FUNCT__ "DMSubDomainRestrictHook_DMTS" 134 /* This could restrict auxiliary information to the coarse level. 135 */ 136 static PetscErrorCode DMSubDomainRestrictHook_DMTS(DM dm,VecScatter gscat,VecScatter lscat,DM subdm,void *ctx) 137 { 138 PetscFunctionBegin; 139 PetscFunctionReturn(0); 140 } 141 142 #undef __FUNCT__ 143 #define __FUNCT__ "DMTSCopy" 144 /*@C 145 DMTSCopy - copies the information in a DMTS to another DMTS 146 147 Not Collective 148 149 Input Argument: 150 + kdm - Original DMTS 151 - nkdm - DMTS to receive the data, should have been created with DMTSCreate() 152 153 Level: developer 154 155 .seealso: DMTSCreate(), DMTSDestroy() 156 @*/ 157 PetscErrorCode DMTSCopy(DMTS kdm,DMTS nkdm) 158 { 159 PetscErrorCode ierr; 160 161 PetscFunctionBegin; 162 PetscValidHeaderSpecific(kdm,DMTS_CLASSID,1); 163 PetscValidHeaderSpecific(nkdm,DMTS_CLASSID,2); 164 nkdm->ops->rhsfunction = kdm->ops->rhsfunction; 165 nkdm->ops->rhsjacobian = kdm->ops->rhsjacobian; 166 nkdm->ops->ifunction = kdm->ops->ifunction; 167 nkdm->ops->ijacobian = kdm->ops->ijacobian; 168 nkdm->ops->solution = kdm->ops->solution; 169 nkdm->ops->destroy = kdm->ops->destroy; 170 nkdm->ops->duplicate = kdm->ops->duplicate; 171 172 nkdm->rhsfunctionctx = kdm->rhsfunctionctx; 173 nkdm->rhsjacobianctx = kdm->rhsjacobianctx; 174 nkdm->ifunctionctx = kdm->ifunctionctx; 175 nkdm->ijacobianctx = kdm->ijacobianctx; 176 nkdm->solutionctx = kdm->solutionctx; 177 178 nkdm->data = kdm->data; 179 180 /* 181 nkdm->fortran_func_pointers[0] = kdm->fortran_func_pointers[0]; 182 nkdm->fortran_func_pointers[1] = kdm->fortran_func_pointers[1]; 183 nkdm->fortran_func_pointers[2] = kdm->fortran_func_pointers[2]; 184 */ 185 186 /* implementation specific copy hooks */ 187 if (kdm->ops->duplicate) {ierr = (*kdm->ops->duplicate)(kdm,nkdm);CHKERRQ(ierr);} 188 PetscFunctionReturn(0); 189 } 190 191 #undef __FUNCT__ 192 #define __FUNCT__ "DMGetDMTS" 193 /*@C 194 DMGetDMTS - get read-only private DMTS context from a DM 195 196 Not Collective 197 198 Input Argument: 199 . dm - DM to be used with TS 200 201 Output Argument: 202 . tsdm - private DMTS context 203 204 Level: developer 205 206 Notes: 207 Use DMGetDMTSWrite() if write access is needed. The DMTSSetXXX API should be used wherever possible. 208 209 .seealso: DMGetDMTSWrite() 210 @*/ 211 PetscErrorCode DMGetDMTS(DM dm,DMTS *tsdm) 212 { 213 PetscErrorCode ierr; 214 215 PetscFunctionBegin; 216 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 217 *tsdm = (DMTS) dm->dmts; 218 if (!*tsdm) { 219 ierr = PetscInfo(dm,"Creating new DMTS\n");CHKERRQ(ierr); 220 ierr = DMTSCreate(((PetscObject)dm)->comm,tsdm);CHKERRQ(ierr); 221 dm->dmts = (PetscObject) *tsdm; 222 ierr = DMCoarsenHookAdd(dm,DMCoarsenHook_DMTS,DMRestrictHook_DMTS,PETSC_NULL);CHKERRQ(ierr); 223 ierr = DMSubDomainHookAdd(dm,DMSubDomainHook_DMTS,DMSubDomainRestrictHook_DMTS,PETSC_NULL);CHKERRQ(ierr); 224 } 225 PetscFunctionReturn(0); 226 } 227 228 #undef __FUNCT__ 229 #define __FUNCT__ "DMGetDMTSWrite" 230 /*@C 231 DMGetDMTSWrite - get write access to private DMTS context from a DM 232 233 Not Collective 234 235 Input Argument: 236 . dm - DM to be used with TS 237 238 Output Argument: 239 . tsdm - private DMTS context 240 241 Level: developer 242 243 .seealso: DMGetDMTS() 244 @*/ 245 PetscErrorCode DMGetDMTSWrite(DM dm,DMTS *tsdm) 246 { 247 PetscErrorCode ierr; 248 DMTS sdm; 249 250 PetscFunctionBegin; 251 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 252 ierr = DMGetDMTS(dm,&sdm);CHKERRQ(ierr); 253 if (!sdm->originaldm) sdm->originaldm = dm; 254 if (sdm->originaldm != dm) { /* Copy on write */ 255 DMTS oldsdm = sdm; 256 ierr = PetscInfo(dm,"Copying DMTS due to write\n");CHKERRQ(ierr); 257 ierr = DMTSCreate(((PetscObject)dm)->comm,&sdm);CHKERRQ(ierr); 258 ierr = DMTSCopy(oldsdm,sdm);CHKERRQ(ierr); 259 ierr = DMTSDestroy((DMTS*)&dm->dmts);CHKERRQ(ierr); 260 dm->dmts = (PetscObject) sdm; 261 } 262 *tsdm = sdm; 263 PetscFunctionReturn(0); 264 } 265 266 #undef __FUNCT__ 267 #define __FUNCT__ "DMCopyDMTS" 268 /*@C 269 DMCopyDMTS - copies a DM context to a new DM 270 271 Logically Collective 272 273 Input Arguments: 274 + dmsrc - DM to obtain context from 275 - dmdest - DM to add context to 276 277 Level: developer 278 279 Note: 280 The context is copied by reference. This function does not ensure that a context exists. 281 282 .seealso: DMGetDMTS(), TSSetDM() 283 @*/ 284 PetscErrorCode DMCopyDMTS(DM dmsrc,DM dmdest) 285 { 286 PetscErrorCode ierr; 287 288 PetscFunctionBegin; 289 PetscValidHeaderSpecific(dmsrc,DM_CLASSID,1); 290 PetscValidHeaderSpecific(dmdest,DM_CLASSID,2); 291 ierr = DMTSDestroy((DMTS*)&dmdest->dmts);CHKERRQ(ierr); 292 dmdest->dmts = dmsrc->dmts; 293 ierr = PetscObjectReference(dmdest->dmts);CHKERRQ(ierr); 294 ierr = DMCoarsenHookAdd(dmdest,DMCoarsenHook_DMTS,DMRestrictHook_DMTS,PETSC_NULL);CHKERRQ(ierr); 295 ierr = DMSubDomainHookAdd(dmdest,DMSubDomainHook_DMTS,DMSubDomainRestrictHook_DMTS,PETSC_NULL);CHKERRQ(ierr); 296 PetscFunctionReturn(0); 297 } 298 299 #undef __FUNCT__ 300 #define __FUNCT__ "DMTSSetIFunction" 301 /*@C 302 DMTSSetIFunction - set TS implicit function evaluation function 303 304 Not Collective 305 306 Input Arguments: 307 + dm - DM to be used with TS 308 . func - function evaluation function, see TSSetIFunction() for calling sequence 309 - ctx - context for residual evaluation 310 311 Level: advanced 312 313 Note: 314 TSSetFunction() is normally used, but it calls this function internally because the user context is actually 315 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 316 not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 317 318 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 319 @*/ 320 PetscErrorCode DMTSSetIFunction(DM dm,TSIFunction func,void *ctx) 321 { 322 PetscErrorCode ierr; 323 DMTS tsdm; 324 325 PetscFunctionBegin; 326 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 327 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 328 if (func) tsdm->ops->ifunction = func; 329 if (ctx) tsdm->ifunctionctx = ctx; 330 PetscFunctionReturn(0); 331 } 332 333 #undef __FUNCT__ 334 #define __FUNCT__ "DMTSGetIFunction" 335 /*@C 336 DMTSGetIFunction - get TS implicit residual evaluation function 337 338 Not Collective 339 340 Input Argument: 341 . dm - DM to be used with TS 342 343 Output Arguments: 344 + func - function evaluation function, see TSSetIFunction() for calling sequence 345 - ctx - context for residual evaluation 346 347 Level: advanced 348 349 Note: 350 TSGetFunction() is normally used, but it calls this function internally because the user context is actually 351 associated with the DM. 352 353 .seealso: DMTSSetContext(), DMTSSetFunction(), TSSetFunction() 354 @*/ 355 PetscErrorCode DMTSGetIFunction(DM dm,TSIFunction *func,void **ctx) 356 { 357 PetscErrorCode ierr; 358 DMTS tsdm; 359 360 PetscFunctionBegin; 361 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 362 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 363 if (func) *func = tsdm->ops->ifunction; 364 if (ctx) *ctx = tsdm->ifunctionctx; 365 PetscFunctionReturn(0); 366 } 367 368 369 #undef __FUNCT__ 370 #define __FUNCT__ "DMTSSetRHSFunction" 371 /*@C 372 DMTSSetRHSFunction - set TS explicit residual evaluation function 373 374 Not Collective 375 376 Input Arguments: 377 + dm - DM to be used with TS 378 . func - RHS function evaluation function, see TSSetRHSFunction() for calling sequence 379 - ctx - context for residual evaluation 380 381 Level: advanced 382 383 Note: 384 TSSetRSHFunction() is normally used, but it calls this function internally because the user context is actually 385 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 386 not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 387 388 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 389 @*/ 390 PetscErrorCode DMTSSetRHSFunction(DM dm,TSRHSFunction func,void *ctx) 391 { 392 PetscErrorCode ierr; 393 DMTS tsdm; 394 395 PetscFunctionBegin; 396 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 397 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 398 if (func) tsdm->ops->rhsfunction = func; 399 if (ctx) tsdm->rhsfunctionctx = ctx; 400 PetscFunctionReturn(0); 401 } 402 403 #undef __FUNCT__ 404 #define __FUNCT__ "DMTSGetSolutionFunction" 405 /*@C 406 DMTSGetSolutionFunction - gets the TS solution evaluation function 407 408 Not Collective 409 410 Input Arguments: 411 . dm - DM to be used with TS 412 413 Output Parameters: 414 + func - solution function evaluation function, see TSSetSolution() for calling sequence 415 - ctx - context for solution evaluation 416 417 Level: advanced 418 419 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 420 @*/ 421 PetscErrorCode DMTSGetSolutionFunction(DM dm,TSSolutionFunction *func,void **ctx) 422 { 423 PetscErrorCode ierr; 424 DMTS tsdm; 425 426 PetscFunctionBegin; 427 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 428 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 429 if (func) *func = tsdm->ops->solution; 430 if (ctx) *ctx = tsdm->solutionctx; 431 PetscFunctionReturn(0); 432 } 433 434 #undef __FUNCT__ 435 #define __FUNCT__ "DMTSSetSolutionFunction" 436 /*@C 437 DMTSSetSolutionFunction - set TS solution evaluation function 438 439 Not Collective 440 441 Input Arguments: 442 + dm - DM to be used with TS 443 . func - solution function evaluation function, see TSSetSolution() for calling sequence 444 - ctx - context for solution evaluation 445 446 Level: advanced 447 448 Note: 449 TSSetSolutionFunction() is normally used, but it calls this function internally because the user context is actually 450 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 451 not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 452 453 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 454 @*/ 455 PetscErrorCode DMTSSetSolutionFunction(DM dm,TSSolutionFunction func,void *ctx) 456 { 457 PetscErrorCode ierr; 458 DMTS tsdm; 459 460 PetscFunctionBegin; 461 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 462 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 463 if (func) tsdm->ops->solution = func; 464 if (ctx) tsdm->solutionctx = ctx; 465 PetscFunctionReturn(0); 466 } 467 468 #undef __FUNCT__ 469 #define __FUNCT__ "DMTSGetRHSFunction" 470 /*@C 471 DMTSGetRHSFunction - get TS explicit residual evaluation function 472 473 Not Collective 474 475 Input Argument: 476 . dm - DM to be used with TS 477 478 Output Arguments: 479 + func - residual evaluation function, see TSSetRHSFunction() for calling sequence 480 - ctx - context for residual evaluation 481 482 Level: advanced 483 484 Note: 485 TSGetFunction() is normally used, but it calls this function internally because the user context is actually 486 associated with the DM. 487 488 .seealso: DMTSSetContext(), DMTSSetFunction(), TSSetFunction() 489 @*/ 490 PetscErrorCode DMTSGetRHSFunction(DM dm,TSRHSFunction *func,void **ctx) 491 { 492 PetscErrorCode ierr; 493 DMTS tsdm; 494 495 PetscFunctionBegin; 496 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 497 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 498 if (func) *func = tsdm->ops->rhsfunction; 499 if (ctx) *ctx = tsdm->rhsfunctionctx; 500 PetscFunctionReturn(0); 501 } 502 503 #undef __FUNCT__ 504 #define __FUNCT__ "DMTSSetIJacobian" 505 /*@C 506 DMTSSetIJacobian - set TS Jacobian evaluation function 507 508 Not Collective 509 510 Input Argument: 511 + dm - DM to be used with TS 512 . func - Jacobian evaluation function, see TSSetIJacobian() for calling sequence 513 - ctx - context for residual evaluation 514 515 Level: advanced 516 517 Note: 518 TSSetJacobian() is normally used, but it calls this function internally because the user context is actually 519 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 520 not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian. 521 522 .seealso: DMTSSetContext(), TSSetFunction(), DMTSGetJacobian(), TSSetJacobian() 523 @*/ 524 PetscErrorCode DMTSSetIJacobian(DM dm,TSIJacobian func,void *ctx) 525 { 526 PetscErrorCode ierr; 527 DMTS sdm; 528 529 PetscFunctionBegin; 530 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 531 ierr = DMGetDMTSWrite(dm,&sdm);CHKERRQ(ierr); 532 if (func) sdm->ops->ijacobian = func; 533 if (ctx) sdm->ijacobianctx = ctx; 534 PetscFunctionReturn(0); 535 } 536 537 #undef __FUNCT__ 538 #define __FUNCT__ "DMTSGetIJacobian" 539 /*@C 540 DMTSGetIJacobian - get TS Jacobian evaluation function 541 542 Not Collective 543 544 Input Argument: 545 . dm - DM to be used with TS 546 547 Output Arguments: 548 + func - Jacobian evaluation function, see TSSetIJacobian() for calling sequence 549 - ctx - context for residual evaluation 550 551 Level: advanced 552 553 Note: 554 TSGetJacobian() is normally used, but it calls this function internally because the user context is actually 555 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 556 not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian. 557 558 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 559 @*/ 560 PetscErrorCode DMTSGetIJacobian(DM dm,TSIJacobian *func,void **ctx) 561 { 562 PetscErrorCode ierr; 563 DMTS tsdm; 564 565 PetscFunctionBegin; 566 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 567 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 568 if (func) *func = tsdm->ops->ijacobian; 569 if (ctx) *ctx = tsdm->ijacobianctx; 570 PetscFunctionReturn(0); 571 } 572 573 574 #undef __FUNCT__ 575 #define __FUNCT__ "DMTSSetRHSJacobian" 576 /*@C 577 DMTSSetRHSJacobian - set TS Jacobian evaluation function 578 579 Not Collective 580 581 Input Argument: 582 + dm - DM to be used with TS 583 . func - Jacobian evaluation function, see TSSetRHSJacobian() for calling sequence 584 - ctx - context for residual evaluation 585 586 Level: advanced 587 588 Note: 589 TSSetJacobian() is normally used, but it calls this function internally because the user context is actually 590 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 591 not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian. 592 593 .seealso: DMTSSetContext(), TSSetFunction(), DMTSGetJacobian(), TSSetJacobian() 594 @*/ 595 PetscErrorCode DMTSSetRHSJacobian(DM dm,TSRHSJacobian func,void *ctx) 596 { 597 PetscErrorCode ierr; 598 DMTS tsdm; 599 600 PetscFunctionBegin; 601 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 602 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 603 if (func) tsdm->ops->rhsjacobian = func; 604 if (ctx) tsdm->rhsjacobianctx = ctx; 605 PetscFunctionReturn(0); 606 } 607 608 #undef __FUNCT__ 609 #define __FUNCT__ "DMTSGetRHSJacobian" 610 /*@C 611 DMTSGetRHSJacobian - get TS Jacobian evaluation function 612 613 Not Collective 614 615 Input Argument: 616 . dm - DM to be used with TS 617 618 Output Arguments: 619 + func - Jacobian evaluation function, see TSSetRHSJacobian() for calling sequence 620 - ctx - context for residual evaluation 621 622 Level: advanced 623 624 Note: 625 TSGetJacobian() is normally used, but it calls this function internally because the user context is actually 626 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 627 not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian. 628 629 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 630 @*/ 631 PetscErrorCode DMTSGetRHSJacobian(DM dm,TSRHSJacobian *func,void **ctx) 632 { 633 PetscErrorCode ierr; 634 DMTS tsdm; 635 636 PetscFunctionBegin; 637 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 638 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 639 if (func) *func = tsdm->ops->rhsjacobian; 640 if (ctx) *ctx = tsdm->rhsjacobianctx; 641 PetscFunctionReturn(0); 642 } 643 644 #undef __FUNCT__ 645 #define __FUNCT__ "DMTSSetIFunctionSerialize" 646 /*@C 647 DMTSSetIFunctionSerialize - sets functions used to view and load a IFunction context 648 649 Not Collective 650 651 Input Arguments: 652 + dm - DM to be used with TS 653 . view - viewer function 654 - load - loading function 655 656 Level: advanced 657 658 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 659 @*/ 660 PetscErrorCode DMTSSetIFunctionSerialize(DM dm,PetscErrorCode (*view)(void*,PetscViewer),PetscErrorCode (*load)(void**,PetscViewer)) 661 { 662 PetscErrorCode ierr; 663 DMTS tsdm; 664 665 PetscFunctionBegin; 666 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 667 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 668 tsdm->ops->ifunctionview = view; 669 tsdm->ops->ifunctionload = load; 670 PetscFunctionReturn(0); 671 } 672 673 #undef __FUNCT__ 674 #define __FUNCT__ "DMTSSetIJacobianSerialize" 675 /*@C 676 DMTSSetIJacobianSerialize - sets functions used to view and load a IJacobian context 677 678 Not Collective 679 680 Input Arguments: 681 + dm - DM to be used with TS 682 . view - viewer function 683 - load - loading function 684 685 Level: advanced 686 687 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 688 @*/ 689 PetscErrorCode DMTSSetIJacobianSerialize(DM dm,PetscErrorCode (*view)(void*,PetscViewer),PetscErrorCode (*load)(void**,PetscViewer)) 690 { 691 PetscErrorCode ierr; 692 DMTS tsdm; 693 694 PetscFunctionBegin; 695 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 696 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 697 tsdm->ops->ijacobianview = view; 698 tsdm->ops->ijacobianload = load; 699 PetscFunctionReturn(0); 700 } 701