1 #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/ 2 #include <petsc/private/dmimpl.h> 3 4 static PetscErrorCode DMTSDestroy(DMTS *kdm) 5 { 6 PetscErrorCode ierr; 7 8 PetscFunctionBegin; 9 if (!*kdm) PetscFunctionReturn(0); 10 PetscValidHeaderSpecific((*kdm),DMTS_CLASSID,1); 11 if (--((PetscObject)(*kdm))->refct > 0) {*kdm = 0; PetscFunctionReturn(0);} 12 if ((*kdm)->ops->destroy) {ierr = ((*kdm)->ops->destroy)(*kdm);CHKERRQ(ierr);} 13 ierr = PetscHeaderDestroy(kdm);CHKERRQ(ierr); 14 PetscFunctionReturn(0); 15 } 16 17 PetscErrorCode DMTSLoad(DMTS kdm,PetscViewer viewer) 18 { 19 PetscErrorCode ierr; 20 21 PetscFunctionBegin; 22 ierr = PetscViewerBinaryRead(viewer,&kdm->ops->ifunction,1,NULL,PETSC_FUNCTION);CHKERRQ(ierr); 23 ierr = PetscViewerBinaryRead(viewer,&kdm->ops->ifunctionview,1,NULL,PETSC_FUNCTION);CHKERRQ(ierr); 24 ierr = PetscViewerBinaryRead(viewer,&kdm->ops->ifunctionload,1,NULL,PETSC_FUNCTION);CHKERRQ(ierr); 25 if (kdm->ops->ifunctionload) { 26 ierr = (*kdm->ops->ifunctionload)(&kdm->ifunctionctx,viewer);CHKERRQ(ierr); 27 } 28 ierr = PetscViewerBinaryRead(viewer,&kdm->ops->ijacobian,1,NULL,PETSC_FUNCTION);CHKERRQ(ierr); 29 ierr = PetscViewerBinaryRead(viewer,&kdm->ops->ijacobianview,1,NULL,PETSC_FUNCTION);CHKERRQ(ierr); 30 ierr = PetscViewerBinaryRead(viewer,&kdm->ops->ijacobianload,1,NULL,PETSC_FUNCTION);CHKERRQ(ierr); 31 if (kdm->ops->ijacobianload) { 32 ierr = (*kdm->ops->ijacobianload)(&kdm->ijacobianctx,viewer);CHKERRQ(ierr); 33 } 34 PetscFunctionReturn(0); 35 } 36 37 PetscErrorCode DMTSView(DMTS kdm,PetscViewer viewer) 38 { 39 PetscErrorCode ierr; 40 PetscBool isascii,isbinary; 41 42 PetscFunctionBegin; 43 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 44 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 45 if (isascii) { 46 #if defined(PETSC_SERIALIZE_FUNCTIONS) 47 const char *fname; 48 49 ierr = PetscFPTFind(kdm->ops->ifunction,&fname);CHKERRQ(ierr); 50 if (fname) { 51 ierr = PetscViewerASCIIPrintf(viewer," IFunction used by TS: %s\n",fname);CHKERRQ(ierr); 52 } 53 ierr = PetscFPTFind(kdm->ops->ijacobian,&fname);CHKERRQ(ierr); 54 if (fname) { 55 ierr = PetscViewerASCIIPrintf(viewer," IJacobian function used by TS: %s\n",fname);CHKERRQ(ierr); 56 } 57 #endif 58 } else if (isbinary) { 59 struct { 60 TSIFunction ifunction; 61 } funcstruct; 62 struct { 63 PetscErrorCode (*ifunctionview)(void*,PetscViewer); 64 } funcviewstruct; 65 struct { 66 PetscErrorCode (*ifunctionload)(void**,PetscViewer); 67 } funcloadstruct; 68 struct { 69 TSIJacobian ijacobian; 70 } jacstruct; 71 struct { 72 PetscErrorCode (*ijacobianview)(void*,PetscViewer); 73 } jacviewstruct; 74 struct { 75 PetscErrorCode (*ijacobianload)(void**,PetscViewer); 76 } jacloadstruct; 77 78 funcstruct.ifunction = kdm->ops->ifunction; 79 funcviewstruct.ifunctionview = kdm->ops->ifunctionview; 80 funcloadstruct.ifunctionload = kdm->ops->ifunctionload; 81 ierr = PetscViewerBinaryWrite(viewer,&funcstruct,1,PETSC_FUNCTION,PETSC_FALSE);CHKERRQ(ierr); 82 ierr = PetscViewerBinaryWrite(viewer,&funcviewstruct,1,PETSC_FUNCTION,PETSC_FALSE);CHKERRQ(ierr); 83 ierr = PetscViewerBinaryWrite(viewer,&funcloadstruct,1,PETSC_FUNCTION,PETSC_FALSE);CHKERRQ(ierr); 84 if (kdm->ops->ifunctionview) { 85 ierr = (*kdm->ops->ifunctionview)(kdm->ifunctionctx,viewer);CHKERRQ(ierr); 86 } 87 jacstruct.ijacobian = kdm->ops->ijacobian; 88 jacviewstruct.ijacobianview = kdm->ops->ijacobianview; 89 jacloadstruct.ijacobianload = kdm->ops->ijacobianload; 90 ierr = PetscViewerBinaryWrite(viewer,&jacstruct,1,PETSC_FUNCTION,PETSC_FALSE);CHKERRQ(ierr); 91 ierr = PetscViewerBinaryWrite(viewer,&jacviewstruct,1,PETSC_FUNCTION,PETSC_FALSE);CHKERRQ(ierr); 92 ierr = PetscViewerBinaryWrite(viewer,&jacloadstruct,1,PETSC_FUNCTION,PETSC_FALSE);CHKERRQ(ierr); 93 if (kdm->ops->ijacobianview) { 94 ierr = (*kdm->ops->ijacobianview)(kdm->ijacobianctx,viewer);CHKERRQ(ierr); 95 } 96 } 97 PetscFunctionReturn(0); 98 } 99 100 static PetscErrorCode DMTSCreate(MPI_Comm comm,DMTS *kdm) 101 { 102 PetscErrorCode ierr; 103 104 PetscFunctionBegin; 105 ierr = TSInitializePackage();CHKERRQ(ierr); 106 ierr = PetscHeaderCreate(*kdm, DMTS_CLASSID, "DMTS", "DMTS", "DMTS", comm, DMTSDestroy, DMTSView);CHKERRQ(ierr); 107 PetscFunctionReturn(0); 108 } 109 110 /* Attaches the DMTS to the coarse level. 111 * Under what conditions should we copy versus duplicate? 112 */ 113 static PetscErrorCode DMCoarsenHook_DMTS(DM dm,DM dmc,void *ctx) 114 { 115 PetscErrorCode ierr; 116 117 PetscFunctionBegin; 118 ierr = DMCopyDMTS(dm,dmc);CHKERRQ(ierr); 119 PetscFunctionReturn(0); 120 } 121 122 /* This could restrict auxiliary information to the coarse level. 123 */ 124 static PetscErrorCode DMRestrictHook_DMTS(DM dm,Mat Restrict,Vec rscale,Mat Inject,DM dmc,void *ctx) 125 { 126 127 PetscFunctionBegin; 128 PetscFunctionReturn(0); 129 } 130 131 static PetscErrorCode DMSubDomainHook_DMTS(DM dm,DM subdm,void *ctx) 132 { 133 PetscErrorCode ierr; 134 135 PetscFunctionBegin; 136 ierr = DMCopyDMTS(dm,subdm);CHKERRQ(ierr); 137 PetscFunctionReturn(0); 138 } 139 140 /* This could restrict auxiliary information to the coarse level. 141 */ 142 static PetscErrorCode DMSubDomainRestrictHook_DMTS(DM dm,VecScatter gscat,VecScatter lscat,DM subdm,void *ctx) 143 { 144 PetscFunctionBegin; 145 PetscFunctionReturn(0); 146 } 147 148 /*@C 149 DMTSCopy - copies the information in a DMTS to another DMTS 150 151 Not Collective 152 153 Input Argument: 154 + kdm - Original DMTS 155 - nkdm - DMTS to receive the data, should have been created with DMTSCreate() 156 157 Level: developer 158 159 .seealso: DMTSCreate(), DMTSDestroy() 160 @*/ 161 PetscErrorCode DMTSCopy(DMTS kdm,DMTS nkdm) 162 { 163 PetscErrorCode ierr; 164 165 PetscFunctionBegin; 166 PetscValidHeaderSpecific(kdm,DMTS_CLASSID,1); 167 PetscValidHeaderSpecific(nkdm,DMTS_CLASSID,2); 168 nkdm->ops->rhsfunction = kdm->ops->rhsfunction; 169 nkdm->ops->rhsjacobian = kdm->ops->rhsjacobian; 170 nkdm->ops->ifunction = kdm->ops->ifunction; 171 nkdm->ops->ijacobian = kdm->ops->ijacobian; 172 nkdm->ops->i2function = kdm->ops->i2function; 173 nkdm->ops->i2jacobian = kdm->ops->i2jacobian; 174 nkdm->ops->solution = kdm->ops->solution; 175 nkdm->ops->destroy = kdm->ops->destroy; 176 nkdm->ops->duplicate = kdm->ops->duplicate; 177 178 nkdm->rhsfunctionctx = kdm->rhsfunctionctx; 179 nkdm->rhsjacobianctx = kdm->rhsjacobianctx; 180 nkdm->ifunctionctx = kdm->ifunctionctx; 181 nkdm->ijacobianctx = kdm->ijacobianctx; 182 nkdm->i2functionctx = kdm->i2functionctx; 183 nkdm->i2jacobianctx = kdm->i2jacobianctx; 184 nkdm->solutionctx = kdm->solutionctx; 185 186 nkdm->data = kdm->data; 187 188 /* 189 nkdm->fortran_func_pointers[0] = kdm->fortran_func_pointers[0]; 190 nkdm->fortran_func_pointers[1] = kdm->fortran_func_pointers[1]; 191 nkdm->fortran_func_pointers[2] = kdm->fortran_func_pointers[2]; 192 */ 193 194 /* implementation specific copy hooks */ 195 if (kdm->ops->duplicate) {ierr = (*kdm->ops->duplicate)(kdm,nkdm);CHKERRQ(ierr);} 196 PetscFunctionReturn(0); 197 } 198 199 /*@C 200 DMGetDMTS - get read-only private DMTS context from a DM 201 202 Not Collective 203 204 Input Argument: 205 . dm - DM to be used with TS 206 207 Output Argument: 208 . tsdm - private DMTS context 209 210 Level: developer 211 212 Notes: 213 Use DMGetDMTSWrite() if write access is needed. The DMTSSetXXX API should be used wherever possible. 214 215 .seealso: DMGetDMTSWrite() 216 @*/ 217 PetscErrorCode DMGetDMTS(DM dm,DMTS *tsdm) 218 { 219 PetscErrorCode ierr; 220 221 PetscFunctionBegin; 222 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 223 *tsdm = (DMTS) dm->dmts; 224 if (!*tsdm) { 225 ierr = PetscInfo(dm,"Creating new DMTS\n");CHKERRQ(ierr); 226 ierr = DMTSCreate(PetscObjectComm((PetscObject)dm),tsdm);CHKERRQ(ierr); 227 dm->dmts = (PetscObject) *tsdm; 228 ierr = DMCoarsenHookAdd(dm,DMCoarsenHook_DMTS,DMRestrictHook_DMTS,NULL);CHKERRQ(ierr); 229 ierr = DMSubDomainHookAdd(dm,DMSubDomainHook_DMTS,DMSubDomainRestrictHook_DMTS,NULL);CHKERRQ(ierr); 230 } 231 PetscFunctionReturn(0); 232 } 233 234 /*@C 235 DMGetDMTSWrite - get write access to private DMTS context from a DM 236 237 Not Collective 238 239 Input Argument: 240 . dm - DM to be used with TS 241 242 Output Argument: 243 . tsdm - private DMTS context 244 245 Level: developer 246 247 .seealso: DMGetDMTS() 248 @*/ 249 PetscErrorCode DMGetDMTSWrite(DM dm,DMTS *tsdm) 250 { 251 PetscErrorCode ierr; 252 DMTS sdm; 253 254 PetscFunctionBegin; 255 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 256 ierr = DMGetDMTS(dm,&sdm);CHKERRQ(ierr); 257 if (!sdm->originaldm) sdm->originaldm = dm; 258 if (sdm->originaldm != dm) { /* Copy on write */ 259 DMTS oldsdm = sdm; 260 ierr = PetscInfo(dm,"Copying DMTS due to write\n");CHKERRQ(ierr); 261 ierr = DMTSCreate(PetscObjectComm((PetscObject)dm),&sdm);CHKERRQ(ierr); 262 ierr = DMTSCopy(oldsdm,sdm);CHKERRQ(ierr); 263 ierr = DMTSDestroy((DMTS*)&dm->dmts);CHKERRQ(ierr); 264 dm->dmts = (PetscObject) sdm; 265 } 266 *tsdm = sdm; 267 PetscFunctionReturn(0); 268 } 269 270 /*@C 271 DMCopyDMTS - copies a DM context to a new DM 272 273 Logically Collective 274 275 Input Arguments: 276 + dmsrc - DM to obtain context from 277 - dmdest - DM to add context to 278 279 Level: developer 280 281 Note: 282 The context is copied by reference. This function does not ensure that a context exists. 283 284 .seealso: DMGetDMTS(), TSSetDM() 285 @*/ 286 PetscErrorCode DMCopyDMTS(DM dmsrc,DM dmdest) 287 { 288 PetscErrorCode ierr; 289 290 PetscFunctionBegin; 291 PetscValidHeaderSpecific(dmsrc,DM_CLASSID,1); 292 PetscValidHeaderSpecific(dmdest,DM_CLASSID,2); 293 ierr = DMTSDestroy((DMTS*)&dmdest->dmts);CHKERRQ(ierr); 294 dmdest->dmts = dmsrc->dmts; 295 ierr = PetscObjectReference(dmdest->dmts);CHKERRQ(ierr); 296 ierr = DMCoarsenHookAdd(dmdest,DMCoarsenHook_DMTS,DMRestrictHook_DMTS,NULL);CHKERRQ(ierr); 297 ierr = DMSubDomainHookAdd(dmdest,DMSubDomainHook_DMTS,DMSubDomainRestrictHook_DMTS,NULL);CHKERRQ(ierr); 298 PetscFunctionReturn(0); 299 } 300 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 /*@C 334 DMTSGetIFunction - get TS implicit residual evaluation function 335 336 Not Collective 337 338 Input Argument: 339 . dm - DM to be used with TS 340 341 Output Arguments: 342 + func - function evaluation function, see TSSetIFunction() for calling sequence 343 - ctx - context for residual evaluation 344 345 Level: advanced 346 347 Note: 348 TSGetFunction() is normally used, but it calls this function internally because the user context is actually 349 associated with the DM. 350 351 .seealso: DMTSSetContext(), DMTSSetFunction(), TSSetFunction() 352 @*/ 353 PetscErrorCode DMTSGetIFunction(DM dm,TSIFunction *func,void **ctx) 354 { 355 PetscErrorCode ierr; 356 DMTS tsdm; 357 358 PetscFunctionBegin; 359 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 360 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 361 if (func) *func = tsdm->ops->ifunction; 362 if (ctx) *ctx = tsdm->ifunctionctx; 363 PetscFunctionReturn(0); 364 } 365 366 /*@C 367 DMTSSetI2Function - set TS implicit function evaluation function for 2nd order systems 368 369 Not Collective 370 371 Input Arguments: 372 + dm - DM to be used with TS 373 . fun - function evaluation function, see TSSetI2Function() for calling sequence 374 - ctx - context for residual evaluation 375 376 Level: advanced 377 378 Note: 379 TSSetI2Function() is normally used, but it calls this function internally because the user context is actually 380 associated with the DM. 381 382 .seealso: TSSetI2Function() 383 @*/ 384 PetscErrorCode DMTSSetI2Function(DM dm,TSI2Function fun,void *ctx) 385 { 386 DMTS tsdm; 387 PetscErrorCode ierr; 388 389 PetscFunctionBegin; 390 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 391 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 392 if (fun) tsdm->ops->i2function = fun; 393 if (ctx) tsdm->i2functionctx = ctx; 394 PetscFunctionReturn(0); 395 } 396 397 /*@C 398 DMTSGetI2Function - get TS implicit residual evaluation function for 2nd order systems 399 400 Not Collective 401 402 Input Argument: 403 . dm - DM to be used with TS 404 405 Output Arguments: 406 + fun - function evaluation function, see TSSetI2Function() for calling sequence 407 - ctx - context for residual evaluation 408 409 Level: advanced 410 411 Note: 412 TSGetI2Function() is normally used, but it calls this function internally because the user context is actually 413 associated with the DM. 414 415 .seealso: DMTSSetI2Function(),TSGetI2Function() 416 @*/ 417 PetscErrorCode DMTSGetI2Function(DM dm,TSI2Function *fun,void **ctx) 418 { 419 DMTS tsdm; 420 PetscErrorCode ierr; 421 422 PetscFunctionBegin; 423 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 424 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 425 if (fun) *fun = tsdm->ops->i2function; 426 if (ctx) *ctx = tsdm->i2functionctx; 427 PetscFunctionReturn(0); 428 } 429 430 /*@C 431 DMTSSetI2Jacobian - set TS implicit Jacobian evaluation function for 2nd order systems 432 433 Not Collective 434 435 Input Arguments: 436 + dm - DM to be used with TS 437 . fun - Jacobian evaluation function, see TSSetI2Jacobian() for calling sequence 438 - ctx - context for Jacobian evaluation 439 440 Level: advanced 441 442 Note: 443 TSSetI2Jacobian() is normally used, but it calls this function internally because the user context is actually 444 associated with the DM. 445 446 .seealso: TSSetI2Jacobian() 447 @*/ 448 PetscErrorCode DMTSSetI2Jacobian(DM dm,TSI2Jacobian jac,void *ctx) 449 { 450 DMTS tsdm; 451 PetscErrorCode ierr; 452 453 PetscFunctionBegin; 454 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 455 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 456 if (jac) tsdm->ops->i2jacobian = jac; 457 if (ctx) tsdm->i2jacobianctx = ctx; 458 PetscFunctionReturn(0); 459 } 460 461 /*@C 462 DMTSGetI2Jacobian - get TS implicit Jacobian evaluation function for 2nd order systems 463 464 Not Collective 465 466 Input Argument: 467 . dm - DM to be used with TS 468 469 Output Arguments: 470 + jac - Jacobian evaluation function, see TSSetI2Jacobian() for calling sequence 471 - ctx - context for Jacobian evaluation 472 473 Level: advanced 474 475 Note: 476 TSGetI2Jacobian() is normally used, but it calls this function internally because the user context is actually 477 associated with the DM. 478 479 .seealso: DMTSSetI2Jacobian(),TSGetI2Jacobian() 480 @*/ 481 PetscErrorCode DMTSGetI2Jacobian(DM dm,TSI2Jacobian *jac,void **ctx) 482 { 483 DMTS tsdm; 484 PetscErrorCode ierr; 485 486 PetscFunctionBegin; 487 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 488 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 489 if (jac) *jac = tsdm->ops->i2jacobian; 490 if (ctx) *ctx = tsdm->i2jacobianctx; 491 PetscFunctionReturn(0); 492 } 493 494 /*@C 495 DMTSSetRHSFunction - set TS explicit residual evaluation function 496 497 Not Collective 498 499 Input Arguments: 500 + dm - DM to be used with TS 501 . func - RHS function evaluation function, see TSSetRHSFunction() for calling sequence 502 - ctx - context for residual evaluation 503 504 Level: advanced 505 506 Note: 507 TSSetRSHFunction() is normally used, but it calls this function internally because the user context is actually 508 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 509 not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 510 511 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 512 @*/ 513 PetscErrorCode DMTSSetRHSFunction(DM dm,TSRHSFunction func,void *ctx) 514 { 515 PetscErrorCode ierr; 516 DMTS tsdm; 517 518 PetscFunctionBegin; 519 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 520 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 521 if (func) tsdm->ops->rhsfunction = func; 522 if (ctx) tsdm->rhsfunctionctx = ctx; 523 PetscFunctionReturn(0); 524 } 525 526 /*@C 527 DMTSGetSolutionFunction - gets the TS solution evaluation function 528 529 Not Collective 530 531 Input Arguments: 532 . dm - DM to be used with TS 533 534 Output Parameters: 535 + func - solution function evaluation function, see TSSetSolution() for calling sequence 536 - ctx - context for solution evaluation 537 538 Level: advanced 539 540 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian(), DMTSSetSolutionFunction() 541 @*/ 542 PetscErrorCode DMTSGetSolutionFunction(DM dm,TSSolutionFunction *func,void **ctx) 543 { 544 PetscErrorCode ierr; 545 DMTS tsdm; 546 547 PetscFunctionBegin; 548 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 549 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 550 if (func) *func = tsdm->ops->solution; 551 if (ctx) *ctx = tsdm->solutionctx; 552 PetscFunctionReturn(0); 553 } 554 555 /*@C 556 DMTSSetSolutionFunction - set TS solution evaluation function 557 558 Not Collective 559 560 Input Arguments: 561 + dm - DM to be used with TS 562 . func - solution function evaluation function, see TSSetSolution() for calling sequence 563 - ctx - context for solution evaluation 564 565 Level: advanced 566 567 Note: 568 TSSetSolutionFunction() is normally used, but it calls this function internally because the user context is actually 569 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 570 not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 571 572 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian(), DMTSGetSolutionFunction() 573 @*/ 574 PetscErrorCode DMTSSetSolutionFunction(DM dm,TSSolutionFunction func,void *ctx) 575 { 576 PetscErrorCode ierr; 577 DMTS tsdm; 578 579 PetscFunctionBegin; 580 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 581 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 582 if (func) tsdm->ops->solution = func; 583 if (ctx) tsdm->solutionctx = ctx; 584 PetscFunctionReturn(0); 585 } 586 587 /*@C 588 DMTSSetForcingFunction - set TS forcing function evaluation function 589 590 Not Collective 591 592 Input Arguments: 593 + dm - DM to be used with TS 594 . f - forcing function evaluation function; see TSForcingFunction 595 - ctx - context for solution evaluation 596 597 Level: advanced 598 599 Note: 600 TSSetForcingFunction() is normally used, but it calls this function internally because the user context is actually 601 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 602 not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 603 604 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian(), TSSetForcingFunction(), DMTSGetForcingFunction() 605 @*/ 606 PetscErrorCode DMTSSetForcingFunction(DM dm,TSForcingFunction f,void *ctx) 607 { 608 PetscErrorCode ierr; 609 DMTS tsdm; 610 611 PetscFunctionBegin; 612 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 613 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 614 if (f) tsdm->ops->forcing = f; 615 if (ctx) tsdm->forcingctx = ctx; 616 PetscFunctionReturn(0); 617 } 618 619 620 /*@C 621 DMTSGetForcingFunction - get TS forcing function evaluation function 622 623 Not Collective 624 625 Input Argument: 626 . dm - DM to be used with TS 627 628 Output Arguments: 629 + f - forcing function evaluation function; see TSForcingFunction for details 630 - ctx - context for solution evaluation 631 632 Level: advanced 633 634 Note: 635 TSSetForcingFunction() is normally used, but it calls this function internally because the user context is actually 636 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 637 not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 638 639 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian(), TSSetForcingFunction(), DMTSGetForcingFunction() 640 @*/ 641 PetscErrorCode DMTSGetForcingFunction(DM dm,TSForcingFunction *f,void **ctx) 642 { 643 PetscErrorCode ierr; 644 DMTS tsdm; 645 646 PetscFunctionBegin; 647 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 648 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 649 if (f) *f = tsdm->ops->forcing; 650 if (ctx) *ctx = tsdm->forcingctx; 651 PetscFunctionReturn(0); 652 } 653 654 /*@C 655 DMTSGetRHSFunction - get TS explicit residual evaluation function 656 657 Not Collective 658 659 Input Argument: 660 . dm - DM to be used with TS 661 662 Output Arguments: 663 + func - residual evaluation function, see TSSetRHSFunction() for calling sequence 664 - ctx - context for residual evaluation 665 666 Level: advanced 667 668 Note: 669 TSGetFunction() is normally used, but it calls this function internally because the user context is actually 670 associated with the DM. 671 672 .seealso: DMTSSetContext(), DMTSSetFunction(), TSSetFunction() 673 @*/ 674 PetscErrorCode DMTSGetRHSFunction(DM dm,TSRHSFunction *func,void **ctx) 675 { 676 PetscErrorCode ierr; 677 DMTS tsdm; 678 679 PetscFunctionBegin; 680 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 681 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 682 if (func) *func = tsdm->ops->rhsfunction; 683 if (ctx) *ctx = tsdm->rhsfunctionctx; 684 PetscFunctionReturn(0); 685 } 686 687 /*@C 688 DMTSSetIJacobian - set TS Jacobian evaluation function 689 690 Not Collective 691 692 Input Argument: 693 + dm - DM to be used with TS 694 . func - Jacobian evaluation function, see TSSetIJacobian() for calling sequence 695 - ctx - context for residual evaluation 696 697 Level: advanced 698 699 Note: 700 TSSetJacobian() is normally used, but it calls this function internally because the user context is actually 701 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 702 not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian. 703 704 .seealso: DMTSSetContext(), TSSetFunction(), DMTSGetJacobian(), TSSetJacobian() 705 @*/ 706 PetscErrorCode DMTSSetIJacobian(DM dm,TSIJacobian func,void *ctx) 707 { 708 PetscErrorCode ierr; 709 DMTS sdm; 710 711 PetscFunctionBegin; 712 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 713 ierr = DMGetDMTSWrite(dm,&sdm);CHKERRQ(ierr); 714 if (func) sdm->ops->ijacobian = func; 715 if (ctx) sdm->ijacobianctx = ctx; 716 PetscFunctionReturn(0); 717 } 718 719 /*@C 720 DMTSGetIJacobian - get TS Jacobian evaluation function 721 722 Not Collective 723 724 Input Argument: 725 . dm - DM to be used with TS 726 727 Output Arguments: 728 + func - Jacobian evaluation function, see TSSetIJacobian() for calling sequence 729 - ctx - context for residual evaluation 730 731 Level: advanced 732 733 Note: 734 TSGetJacobian() is normally used, but it calls this function internally because the user context is actually 735 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 736 not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian. 737 738 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 739 @*/ 740 PetscErrorCode DMTSGetIJacobian(DM dm,TSIJacobian *func,void **ctx) 741 { 742 PetscErrorCode ierr; 743 DMTS tsdm; 744 745 PetscFunctionBegin; 746 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 747 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 748 if (func) *func = tsdm->ops->ijacobian; 749 if (ctx) *ctx = tsdm->ijacobianctx; 750 PetscFunctionReturn(0); 751 } 752 753 754 /*@C 755 DMTSSetRHSJacobian - set TS Jacobian evaluation function 756 757 Not Collective 758 759 Input Argument: 760 + dm - DM to be used with TS 761 . func - Jacobian evaluation function, see TSSetRHSJacobian() for calling sequence 762 - ctx - context for residual evaluation 763 764 Level: advanced 765 766 Note: 767 TSSetJacobian() is normally used, but it calls this function internally because the user context is actually 768 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 769 not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian. 770 771 .seealso: DMTSSetContext(), TSSetFunction(), DMTSGetJacobian(), TSSetJacobian() 772 @*/ 773 PetscErrorCode DMTSSetRHSJacobian(DM dm,TSRHSJacobian func,void *ctx) 774 { 775 PetscErrorCode ierr; 776 DMTS tsdm; 777 778 PetscFunctionBegin; 779 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 780 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 781 if (func) tsdm->ops->rhsjacobian = func; 782 if (ctx) tsdm->rhsjacobianctx = ctx; 783 PetscFunctionReturn(0); 784 } 785 786 /*@C 787 DMTSGetRHSJacobian - get TS Jacobian evaluation function 788 789 Not Collective 790 791 Input Argument: 792 . dm - DM to be used with TS 793 794 Output Arguments: 795 + func - Jacobian evaluation function, see TSSetRHSJacobian() for calling sequence 796 - ctx - context for residual evaluation 797 798 Level: advanced 799 800 Note: 801 TSGetJacobian() is normally used, but it calls this function internally because the user context is actually 802 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 803 not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian. 804 805 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 806 @*/ 807 PetscErrorCode DMTSGetRHSJacobian(DM dm,TSRHSJacobian *func,void **ctx) 808 { 809 PetscErrorCode ierr; 810 DMTS tsdm; 811 812 PetscFunctionBegin; 813 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 814 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 815 if (func) *func = tsdm->ops->rhsjacobian; 816 if (ctx) *ctx = tsdm->rhsjacobianctx; 817 PetscFunctionReturn(0); 818 } 819 820 /*@C 821 DMTSSetIFunctionSerialize - sets functions used to view and load a IFunction context 822 823 Not Collective 824 825 Input Arguments: 826 + dm - DM to be used with TS 827 . view - viewer function 828 - load - loading function 829 830 Level: advanced 831 832 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 833 @*/ 834 PetscErrorCode DMTSSetIFunctionSerialize(DM dm,PetscErrorCode (*view)(void*,PetscViewer),PetscErrorCode (*load)(void**,PetscViewer)) 835 { 836 PetscErrorCode ierr; 837 DMTS tsdm; 838 839 PetscFunctionBegin; 840 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 841 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 842 tsdm->ops->ifunctionview = view; 843 tsdm->ops->ifunctionload = load; 844 PetscFunctionReturn(0); 845 } 846 847 /*@C 848 DMTSSetIJacobianSerialize - sets functions used to view and load a IJacobian context 849 850 Not Collective 851 852 Input Arguments: 853 + dm - DM to be used with TS 854 . view - viewer function 855 - load - loading function 856 857 Level: advanced 858 859 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 860 @*/ 861 PetscErrorCode DMTSSetIJacobianSerialize(DM dm,PetscErrorCode (*view)(void*,PetscViewer),PetscErrorCode (*load)(void**,PetscViewer)) 862 { 863 PetscErrorCode ierr; 864 DMTS tsdm; 865 866 PetscFunctionBegin; 867 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 868 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 869 tsdm->ops->ijacobianview = view; 870 tsdm->ops->ijacobianload = load; 871 PetscFunctionReturn(0); 872 } 873