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 (*tsdm)->originaldm = dm; 229 ierr = DMCoarsenHookAdd(dm,DMCoarsenHook_DMTS,DMRestrictHook_DMTS,NULL);CHKERRQ(ierr); 230 ierr = DMSubDomainHookAdd(dm,DMSubDomainHook_DMTS,DMSubDomainRestrictHook_DMTS,NULL);CHKERRQ(ierr); 231 } 232 PetscFunctionReturn(0); 233 } 234 235 /*@C 236 DMGetDMTSWrite - get write access to private DMTS context from a DM 237 238 Not Collective 239 240 Input Argument: 241 . dm - DM to be used with TS 242 243 Output Argument: 244 . tsdm - private DMTS context 245 246 Level: developer 247 248 .seealso: DMGetDMTS() 249 @*/ 250 PetscErrorCode DMGetDMTSWrite(DM dm,DMTS *tsdm) 251 { 252 PetscErrorCode ierr; 253 DMTS sdm; 254 255 PetscFunctionBegin; 256 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 257 ierr = DMGetDMTS(dm,&sdm);CHKERRQ(ierr); 258 if (!sdm->originaldm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"DMTS has a NULL originaldm"); 259 if (sdm->originaldm != dm) { /* Copy on write */ 260 DMTS oldsdm = sdm; 261 ierr = PetscInfo(dm,"Copying DMTS due to write\n");CHKERRQ(ierr); 262 ierr = DMTSCreate(PetscObjectComm((PetscObject)dm),&sdm);CHKERRQ(ierr); 263 ierr = DMTSCopy(oldsdm,sdm);CHKERRQ(ierr); 264 ierr = DMTSDestroy((DMTS*)&dm->dmts);CHKERRQ(ierr); 265 dm->dmts = (PetscObject) sdm; 266 sdm->originaldm = dm; 267 } 268 *tsdm = sdm; 269 PetscFunctionReturn(0); 270 } 271 272 /*@C 273 DMCopyDMTS - copies a DM context to a new DM 274 275 Logically Collective 276 277 Input Arguments: 278 + dmsrc - DM to obtain context from 279 - dmdest - DM to add context to 280 281 Level: developer 282 283 Note: 284 The context is copied by reference. This function does not ensure that a context exists. 285 286 .seealso: DMGetDMTS(), TSSetDM() 287 @*/ 288 PetscErrorCode DMCopyDMTS(DM dmsrc,DM dmdest) 289 { 290 PetscErrorCode ierr; 291 292 PetscFunctionBegin; 293 PetscValidHeaderSpecific(dmsrc,DM_CLASSID,1); 294 PetscValidHeaderSpecific(dmdest,DM_CLASSID,2); 295 ierr = DMTSDestroy((DMTS*)&dmdest->dmts);CHKERRQ(ierr); 296 dmdest->dmts = dmsrc->dmts; 297 ierr = PetscObjectReference(dmdest->dmts);CHKERRQ(ierr); 298 ierr = DMCoarsenHookAdd(dmdest,DMCoarsenHook_DMTS,DMRestrictHook_DMTS,NULL);CHKERRQ(ierr); 299 ierr = DMSubDomainHookAdd(dmdest,DMSubDomainHook_DMTS,DMSubDomainRestrictHook_DMTS,NULL);CHKERRQ(ierr); 300 PetscFunctionReturn(0); 301 } 302 303 /*@C 304 DMTSSetIFunction - set TS implicit function evaluation function 305 306 Not Collective 307 308 Input Arguments: 309 + dm - DM to be used with TS 310 . func - function evaluation function, see TSSetIFunction() for calling sequence 311 - ctx - context for residual evaluation 312 313 Level: advanced 314 315 Note: 316 TSSetFunction() is normally used, but it calls this function internally because the user context is actually 317 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 318 not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 319 320 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 321 @*/ 322 PetscErrorCode DMTSSetIFunction(DM dm,TSIFunction func,void *ctx) 323 { 324 PetscErrorCode ierr; 325 DMTS tsdm; 326 327 PetscFunctionBegin; 328 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 329 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 330 if (func) tsdm->ops->ifunction = func; 331 if (ctx) tsdm->ifunctionctx = ctx; 332 PetscFunctionReturn(0); 333 } 334 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 /*@C 369 DMTSSetI2Function - set TS implicit function evaluation function for 2nd order systems 370 371 Not Collective 372 373 Input Arguments: 374 + dm - DM to be used with TS 375 . fun - function evaluation function, see TSSetI2Function() for calling sequence 376 - ctx - context for residual evaluation 377 378 Level: advanced 379 380 Note: 381 TSSetI2Function() is normally used, but it calls this function internally because the user context is actually 382 associated with the DM. 383 384 .seealso: TSSetI2Function() 385 @*/ 386 PetscErrorCode DMTSSetI2Function(DM dm,TSI2Function fun,void *ctx) 387 { 388 DMTS tsdm; 389 PetscErrorCode ierr; 390 391 PetscFunctionBegin; 392 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 393 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 394 if (fun) tsdm->ops->i2function = fun; 395 if (ctx) tsdm->i2functionctx = ctx; 396 PetscFunctionReturn(0); 397 } 398 399 /*@C 400 DMTSGetI2Function - get TS implicit residual evaluation function for 2nd order systems 401 402 Not Collective 403 404 Input Argument: 405 . dm - DM to be used with TS 406 407 Output Arguments: 408 + fun - function evaluation function, see TSSetI2Function() for calling sequence 409 - ctx - context for residual evaluation 410 411 Level: advanced 412 413 Note: 414 TSGetI2Function() is normally used, but it calls this function internally because the user context is actually 415 associated with the DM. 416 417 .seealso: DMTSSetI2Function(),TSGetI2Function() 418 @*/ 419 PetscErrorCode DMTSGetI2Function(DM dm,TSI2Function *fun,void **ctx) 420 { 421 DMTS tsdm; 422 PetscErrorCode ierr; 423 424 PetscFunctionBegin; 425 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 426 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 427 if (fun) *fun = tsdm->ops->i2function; 428 if (ctx) *ctx = tsdm->i2functionctx; 429 PetscFunctionReturn(0); 430 } 431 432 /*@C 433 DMTSSetI2Jacobian - set TS implicit Jacobian evaluation function for 2nd order systems 434 435 Not Collective 436 437 Input Arguments: 438 + dm - DM to be used with TS 439 . fun - Jacobian evaluation function, see TSSetI2Jacobian() for calling sequence 440 - ctx - context for Jacobian evaluation 441 442 Level: advanced 443 444 Note: 445 TSSetI2Jacobian() is normally used, but it calls this function internally because the user context is actually 446 associated with the DM. 447 448 .seealso: TSSetI2Jacobian() 449 @*/ 450 PetscErrorCode DMTSSetI2Jacobian(DM dm,TSI2Jacobian jac,void *ctx) 451 { 452 DMTS tsdm; 453 PetscErrorCode ierr; 454 455 PetscFunctionBegin; 456 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 457 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 458 if (jac) tsdm->ops->i2jacobian = jac; 459 if (ctx) tsdm->i2jacobianctx = ctx; 460 PetscFunctionReturn(0); 461 } 462 463 /*@C 464 DMTSGetI2Jacobian - get TS implicit Jacobian evaluation function for 2nd order systems 465 466 Not Collective 467 468 Input Argument: 469 . dm - DM to be used with TS 470 471 Output Arguments: 472 + jac - Jacobian evaluation function, see TSSetI2Jacobian() for calling sequence 473 - ctx - context for Jacobian evaluation 474 475 Level: advanced 476 477 Note: 478 TSGetI2Jacobian() is normally used, but it calls this function internally because the user context is actually 479 associated with the DM. 480 481 .seealso: DMTSSetI2Jacobian(),TSGetI2Jacobian() 482 @*/ 483 PetscErrorCode DMTSGetI2Jacobian(DM dm,TSI2Jacobian *jac,void **ctx) 484 { 485 DMTS tsdm; 486 PetscErrorCode ierr; 487 488 PetscFunctionBegin; 489 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 490 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 491 if (jac) *jac = tsdm->ops->i2jacobian; 492 if (ctx) *ctx = tsdm->i2jacobianctx; 493 PetscFunctionReturn(0); 494 } 495 496 /*@C 497 DMTSSetRHSFunction - set TS explicit residual evaluation function 498 499 Not Collective 500 501 Input Arguments: 502 + dm - DM to be used with TS 503 . func - RHS function evaluation function, see TSSetRHSFunction() for calling sequence 504 - ctx - context for residual evaluation 505 506 Level: advanced 507 508 Note: 509 TSSetRSHFunction() is normally used, but it calls this function internally because the user context is actually 510 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 511 not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 512 513 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 514 @*/ 515 PetscErrorCode DMTSSetRHSFunction(DM dm,TSRHSFunction func,void *ctx) 516 { 517 PetscErrorCode ierr; 518 DMTS tsdm; 519 520 PetscFunctionBegin; 521 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 522 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 523 if (func) tsdm->ops->rhsfunction = func; 524 if (ctx) tsdm->rhsfunctionctx = ctx; 525 PetscFunctionReturn(0); 526 } 527 528 /*@C 529 DMTSGetSolutionFunction - gets the TS solution evaluation function 530 531 Not Collective 532 533 Input Arguments: 534 . dm - DM to be used with TS 535 536 Output Parameters: 537 + func - solution function evaluation function, see TSSetSolution() for calling sequence 538 - ctx - context for solution evaluation 539 540 Level: advanced 541 542 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian(), DMTSSetSolutionFunction() 543 @*/ 544 PetscErrorCode DMTSGetSolutionFunction(DM dm,TSSolutionFunction *func,void **ctx) 545 { 546 PetscErrorCode ierr; 547 DMTS tsdm; 548 549 PetscFunctionBegin; 550 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 551 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 552 if (func) *func = tsdm->ops->solution; 553 if (ctx) *ctx = tsdm->solutionctx; 554 PetscFunctionReturn(0); 555 } 556 557 /*@C 558 DMTSSetSolutionFunction - set TS solution evaluation function 559 560 Not Collective 561 562 Input Arguments: 563 + dm - DM to be used with TS 564 . func - solution function evaluation function, see TSSetSolution() for calling sequence 565 - ctx - context for solution evaluation 566 567 Level: advanced 568 569 Note: 570 TSSetSolutionFunction() is normally used, but it calls this function internally because the user context is actually 571 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 572 not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 573 574 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian(), DMTSGetSolutionFunction() 575 @*/ 576 PetscErrorCode DMTSSetSolutionFunction(DM dm,TSSolutionFunction func,void *ctx) 577 { 578 PetscErrorCode ierr; 579 DMTS tsdm; 580 581 PetscFunctionBegin; 582 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 583 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 584 if (func) tsdm->ops->solution = func; 585 if (ctx) tsdm->solutionctx = ctx; 586 PetscFunctionReturn(0); 587 } 588 589 /*@C 590 DMTSSetForcingFunction - set TS forcing function evaluation function 591 592 Not Collective 593 594 Input Arguments: 595 + dm - DM to be used with TS 596 . f - forcing function evaluation function; see TSForcingFunction 597 - ctx - context for solution evaluation 598 599 Level: advanced 600 601 Note: 602 TSSetForcingFunction() is normally used, but it calls this function internally because the user context is actually 603 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 604 not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 605 606 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian(), TSSetForcingFunction(), DMTSGetForcingFunction() 607 @*/ 608 PetscErrorCode DMTSSetForcingFunction(DM dm,TSForcingFunction f,void *ctx) 609 { 610 PetscErrorCode ierr; 611 DMTS tsdm; 612 613 PetscFunctionBegin; 614 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 615 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 616 if (f) tsdm->ops->forcing = f; 617 if (ctx) tsdm->forcingctx = ctx; 618 PetscFunctionReturn(0); 619 } 620 621 622 /*@C 623 DMTSGetForcingFunction - get TS forcing function evaluation function 624 625 Not Collective 626 627 Input Argument: 628 . dm - DM to be used with TS 629 630 Output Arguments: 631 + f - forcing function evaluation function; see TSForcingFunction for details 632 - ctx - context for solution evaluation 633 634 Level: advanced 635 636 Note: 637 TSSetForcingFunction() is normally used, but it calls this function internally because the user context is actually 638 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 639 not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 640 641 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian(), TSSetForcingFunction(), DMTSGetForcingFunction() 642 @*/ 643 PetscErrorCode DMTSGetForcingFunction(DM dm,TSForcingFunction *f,void **ctx) 644 { 645 PetscErrorCode ierr; 646 DMTS tsdm; 647 648 PetscFunctionBegin; 649 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 650 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 651 if (f) *f = tsdm->ops->forcing; 652 if (ctx) *ctx = tsdm->forcingctx; 653 PetscFunctionReturn(0); 654 } 655 656 /*@C 657 DMTSGetRHSFunction - get TS explicit residual evaluation function 658 659 Not Collective 660 661 Input Argument: 662 . dm - DM to be used with TS 663 664 Output Arguments: 665 + func - residual evaluation function, see TSSetRHSFunction() for calling sequence 666 - ctx - context for residual evaluation 667 668 Level: advanced 669 670 Note: 671 TSGetFunction() is normally used, but it calls this function internally because the user context is actually 672 associated with the DM. 673 674 .seealso: DMTSSetContext(), DMTSSetFunction(), TSSetFunction() 675 @*/ 676 PetscErrorCode DMTSGetRHSFunction(DM dm,TSRHSFunction *func,void **ctx) 677 { 678 PetscErrorCode ierr; 679 DMTS tsdm; 680 681 PetscFunctionBegin; 682 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 683 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 684 if (func) *func = tsdm->ops->rhsfunction; 685 if (ctx) *ctx = tsdm->rhsfunctionctx; 686 PetscFunctionReturn(0); 687 } 688 689 /*@C 690 DMTSSetIJacobian - set TS Jacobian evaluation function 691 692 Not Collective 693 694 Input Argument: 695 + dm - DM to be used with TS 696 . func - Jacobian evaluation function, see TSSetIJacobian() for calling sequence 697 - ctx - context for residual evaluation 698 699 Level: advanced 700 701 Note: 702 TSSetJacobian() is normally used, but it calls this function internally because the user context is actually 703 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 704 not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian. 705 706 .seealso: DMTSSetContext(), TSSetFunction(), DMTSGetJacobian(), TSSetJacobian() 707 @*/ 708 PetscErrorCode DMTSSetIJacobian(DM dm,TSIJacobian func,void *ctx) 709 { 710 PetscErrorCode ierr; 711 DMTS sdm; 712 713 PetscFunctionBegin; 714 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 715 ierr = DMGetDMTSWrite(dm,&sdm);CHKERRQ(ierr); 716 if (func) sdm->ops->ijacobian = func; 717 if (ctx) sdm->ijacobianctx = ctx; 718 PetscFunctionReturn(0); 719 } 720 721 /*@C 722 DMTSGetIJacobian - get TS Jacobian evaluation function 723 724 Not Collective 725 726 Input Argument: 727 . dm - DM to be used with TS 728 729 Output Arguments: 730 + func - Jacobian evaluation function, see TSSetIJacobian() for calling sequence 731 - ctx - context for residual evaluation 732 733 Level: advanced 734 735 Note: 736 TSGetJacobian() is normally used, but it calls this function internally because the user context is actually 737 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 738 not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian. 739 740 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 741 @*/ 742 PetscErrorCode DMTSGetIJacobian(DM dm,TSIJacobian *func,void **ctx) 743 { 744 PetscErrorCode ierr; 745 DMTS tsdm; 746 747 PetscFunctionBegin; 748 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 749 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 750 if (func) *func = tsdm->ops->ijacobian; 751 if (ctx) *ctx = tsdm->ijacobianctx; 752 PetscFunctionReturn(0); 753 } 754 755 756 /*@C 757 DMTSSetRHSJacobian - set TS Jacobian evaluation function 758 759 Not Collective 760 761 Input Argument: 762 + dm - DM to be used with TS 763 . func - Jacobian evaluation function, see TSSetRHSJacobian() for calling sequence 764 - ctx - context for residual evaluation 765 766 Level: advanced 767 768 Note: 769 TSSetJacobian() is normally used, but it calls this function internally because the user context is actually 770 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 771 not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian. 772 773 .seealso: DMTSSetContext(), TSSetFunction(), DMTSGetJacobian(), TSSetJacobian() 774 @*/ 775 PetscErrorCode DMTSSetRHSJacobian(DM dm,TSRHSJacobian func,void *ctx) 776 { 777 PetscErrorCode ierr; 778 DMTS tsdm; 779 780 PetscFunctionBegin; 781 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 782 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 783 if (func) tsdm->ops->rhsjacobian = func; 784 if (ctx) tsdm->rhsjacobianctx = ctx; 785 PetscFunctionReturn(0); 786 } 787 788 /*@C 789 DMTSGetRHSJacobian - get TS Jacobian evaluation function 790 791 Not Collective 792 793 Input Argument: 794 . dm - DM to be used with TS 795 796 Output Arguments: 797 + func - Jacobian evaluation function, see TSSetRHSJacobian() for calling sequence 798 - ctx - context for residual evaluation 799 800 Level: advanced 801 802 Note: 803 TSGetJacobian() is normally used, but it calls this function internally because the user context is actually 804 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 805 not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian. 806 807 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 808 @*/ 809 PetscErrorCode DMTSGetRHSJacobian(DM dm,TSRHSJacobian *func,void **ctx) 810 { 811 PetscErrorCode ierr; 812 DMTS tsdm; 813 814 PetscFunctionBegin; 815 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 816 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 817 if (func) *func = tsdm->ops->rhsjacobian; 818 if (ctx) *ctx = tsdm->rhsjacobianctx; 819 PetscFunctionReturn(0); 820 } 821 822 /*@C 823 DMTSSetIFunctionSerialize - sets functions used to view and load a IFunction context 824 825 Not Collective 826 827 Input Arguments: 828 + dm - DM to be used with TS 829 . view - viewer function 830 - load - loading function 831 832 Level: advanced 833 834 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 835 @*/ 836 PetscErrorCode DMTSSetIFunctionSerialize(DM dm,PetscErrorCode (*view)(void*,PetscViewer),PetscErrorCode (*load)(void**,PetscViewer)) 837 { 838 PetscErrorCode ierr; 839 DMTS tsdm; 840 841 PetscFunctionBegin; 842 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 843 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 844 tsdm->ops->ifunctionview = view; 845 tsdm->ops->ifunctionload = load; 846 PetscFunctionReturn(0); 847 } 848 849 /*@C 850 DMTSSetIJacobianSerialize - sets functions used to view and load a IJacobian context 851 852 Not Collective 853 854 Input Arguments: 855 + dm - DM to be used with TS 856 . view - viewer function 857 - load - loading function 858 859 Level: advanced 860 861 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 862 @*/ 863 PetscErrorCode DMTSSetIJacobianSerialize(DM dm,PetscErrorCode (*view)(void*,PetscViewer),PetscErrorCode (*load)(void**,PetscViewer)) 864 { 865 PetscErrorCode ierr; 866 DMTS tsdm; 867 868 PetscFunctionBegin; 869 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 870 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 871 tsdm->ops->ijacobianview = view; 872 tsdm->ops->ijacobianload = load; 873 PetscFunctionReturn(0); 874 } 875