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 = NULL; 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);CHKERRQ(ierr); 82 ierr = PetscViewerBinaryWrite(viewer,&funcviewstruct,1,PETSC_FUNCTION);CHKERRQ(ierr); 83 ierr = PetscViewerBinaryWrite(viewer,&funcloadstruct,1,PETSC_FUNCTION);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);CHKERRQ(ierr); 91 ierr = PetscViewerBinaryWrite(viewer,&jacviewstruct,1,PETSC_FUNCTION);CHKERRQ(ierr); 92 ierr = PetscViewerBinaryWrite(viewer,&jacloadstruct,1,PETSC_FUNCTION);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 evaluating f(t,u,u_t) 311 - ctx - context for residual evaluation 312 313 Calling sequence of func: 314 $ PetscErrorCode func(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx); 315 316 + t - time at step/stage being solved 317 . u - state vector 318 . u_t - time derivative of state vector 319 . F - function vector 320 - ctx - [optional] user-defined context for matrix evaluation routine 321 322 Level: advanced 323 324 Note: 325 TSSetFunction() is normally used, but it calls this function internally because the user context is actually 326 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 327 not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 328 329 .seealso: DMTSSetContext(), TSSetIFunction(), DMTSSetJacobian() 330 @*/ 331 PetscErrorCode DMTSSetIFunction(DM dm,TSIFunction func,void *ctx) 332 { 333 PetscErrorCode ierr; 334 DMTS tsdm; 335 336 PetscFunctionBegin; 337 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 338 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 339 if (func) tsdm->ops->ifunction = func; 340 if (ctx) tsdm->ifunctionctx = ctx; 341 PetscFunctionReturn(0); 342 } 343 344 /*@C 345 DMTSGetIFunction - get TS implicit residual evaluation function 346 347 Not Collective 348 349 Input Argument: 350 . dm - DM to be used with TS 351 352 Output Arguments: 353 + func - function evaluation function, see TSSetIFunction() for calling sequence 354 - ctx - context for residual evaluation 355 356 Level: advanced 357 358 Note: 359 TSGetFunction() is normally used, but it calls this function internally because the user context is actually 360 associated with the DM. 361 362 .seealso: DMTSSetContext(), DMTSSetFunction(), TSSetFunction() 363 @*/ 364 PetscErrorCode DMTSGetIFunction(DM dm,TSIFunction *func,void **ctx) 365 { 366 PetscErrorCode ierr; 367 DMTS tsdm; 368 369 PetscFunctionBegin; 370 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 371 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 372 if (func) *func = tsdm->ops->ifunction; 373 if (ctx) *ctx = tsdm->ifunctionctx; 374 PetscFunctionReturn(0); 375 } 376 377 /*@C 378 DMTSSetI2Function - set TS implicit function evaluation function for 2nd order systems 379 380 Not Collective 381 382 Input Arguments: 383 + dm - DM to be used with TS 384 . fun - function evaluation routine 385 - ctx - context for residual evaluation 386 387 Calling sequence of fun: 388 $ PetscErrorCode fun(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,Vec F,ctx); 389 390 + t - time at step/stage being solved 391 . U - state vector 392 . U_t - time derivative of state vector 393 . U_tt - second time derivative of state vector 394 . F - function vector 395 - ctx - [optional] user-defined context for matrix evaluation routine (may be NULL) 396 397 Level: advanced 398 399 Note: 400 TSSetI2Function() is normally used, but it calls this function internally because the user context is actually 401 associated with the DM. 402 403 .seealso: TSSetI2Function() 404 @*/ 405 PetscErrorCode DMTSSetI2Function(DM dm,TSI2Function fun,void *ctx) 406 { 407 DMTS tsdm; 408 PetscErrorCode ierr; 409 410 PetscFunctionBegin; 411 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 412 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 413 if (fun) tsdm->ops->i2function = fun; 414 if (ctx) tsdm->i2functionctx = ctx; 415 PetscFunctionReturn(0); 416 } 417 418 /*@C 419 DMTSGetI2Function - get TS implicit residual evaluation function for 2nd order systems 420 421 Not Collective 422 423 Input Argument: 424 . dm - DM to be used with TS 425 426 Output Arguments: 427 + fun - function evaluation function, see TSSetI2Function() for calling sequence 428 - ctx - context for residual evaluation 429 430 Level: advanced 431 432 Note: 433 TSGetI2Function() is normally used, but it calls this function internally because the user context is actually 434 associated with the DM. 435 436 .seealso: DMTSSetI2Function(),TSGetI2Function() 437 @*/ 438 PetscErrorCode DMTSGetI2Function(DM dm,TSI2Function *fun,void **ctx) 439 { 440 DMTS tsdm; 441 PetscErrorCode ierr; 442 443 PetscFunctionBegin; 444 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 445 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 446 if (fun) *fun = tsdm->ops->i2function; 447 if (ctx) *ctx = tsdm->i2functionctx; 448 PetscFunctionReturn(0); 449 } 450 451 /*@C 452 DMTSSetI2Jacobian - set TS implicit Jacobian evaluation function for 2nd order systems 453 454 Not Collective 455 456 Input Arguments: 457 + dm - DM to be used with TS 458 . fun - Jacobian evaluation routine 459 - ctx - context for Jacobian evaluation 460 461 Calling sequence of jac: 462 $ PetscErrorCode jac(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,PetscReal v,PetscReal a,Mat J,Mat P,void *ctx); 463 464 + t - time at step/stage being solved 465 . U - state vector 466 . U_t - time derivative of state vector 467 . U_tt - second time derivative of state vector 468 . v - shift for U_t 469 . a - shift for U_tt 470 . J - Jacobian of G(U) = F(t,U,W+v*U,W'+a*U), equivalent to dF/dU + v*dF/dU_t + a*dF/dU_tt 471 . P - preconditioning matrix for J, may be same as J 472 - ctx - [optional] user-defined context for matrix evaluation routine 473 474 Level: advanced 475 476 Note: 477 TSSetI2Jacobian() is normally used, but it calls this function internally because the user context is actually 478 associated with the DM. 479 480 .seealso: TSSetI2Jacobian() 481 @*/ 482 PetscErrorCode DMTSSetI2Jacobian(DM dm,TSI2Jacobian jac,void *ctx) 483 { 484 DMTS tsdm; 485 PetscErrorCode ierr; 486 487 PetscFunctionBegin; 488 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 489 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 490 if (jac) tsdm->ops->i2jacobian = jac; 491 if (ctx) tsdm->i2jacobianctx = ctx; 492 PetscFunctionReturn(0); 493 } 494 495 /*@C 496 DMTSGetI2Jacobian - get TS implicit Jacobian evaluation function for 2nd order systems 497 498 Not Collective 499 500 Input Argument: 501 . dm - DM to be used with TS 502 503 Output Arguments: 504 + jac - Jacobian evaluation function, see TSSetI2Jacobian() for calling sequence 505 - ctx - context for Jacobian evaluation 506 507 Level: advanced 508 509 Note: 510 TSGetI2Jacobian() is normally used, but it calls this function internally because the user context is actually 511 associated with the DM. 512 513 .seealso: DMTSSetI2Jacobian(),TSGetI2Jacobian() 514 @*/ 515 PetscErrorCode DMTSGetI2Jacobian(DM dm,TSI2Jacobian *jac,void **ctx) 516 { 517 DMTS tsdm; 518 PetscErrorCode ierr; 519 520 PetscFunctionBegin; 521 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 522 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 523 if (jac) *jac = tsdm->ops->i2jacobian; 524 if (ctx) *ctx = tsdm->i2jacobianctx; 525 PetscFunctionReturn(0); 526 } 527 528 /*@C 529 DMTSSetRHSFunction - set TS explicit residual evaluation function 530 531 Not Collective 532 533 Input Arguments: 534 + dm - DM to be used with TS 535 . func - RHS function evaluation routine 536 - ctx - context for residual evaluation 537 538 Calling sequence of func: 539 $ PetscErrorCode func(TS ts,PetscReal t,Vec u,Vec F,void *ctx); 540 541 + ts - timestep context 542 . t - current timestep 543 . u - input vector 544 . F - function vector 545 - ctx - [optional] user-defined function context 546 547 Level: advanced 548 549 Note: 550 TSSetRSHFunction() is normally used, but it calls this function internally because the user context is actually 551 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 552 not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 553 554 .seealso: DMTSSetContext(), TSSetRHSFunction(), DMTSSetJacobian() 555 @*/ 556 PetscErrorCode DMTSSetRHSFunction(DM dm,TSRHSFunction func,void *ctx) 557 { 558 PetscErrorCode ierr; 559 DMTS tsdm; 560 561 PetscFunctionBegin; 562 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 563 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 564 if (func) tsdm->ops->rhsfunction = func; 565 if (ctx) tsdm->rhsfunctionctx = ctx; 566 PetscFunctionReturn(0); 567 } 568 569 /*@C 570 DMTSSetTransientVariable - sets function to transform from state to transient variables 571 572 Logically Collective 573 574 Input Arguments: 575 + dm - DM to be used with TS 576 . tvar - a function that transforms to transient variables 577 - ctx - a context for tvar 578 579 Calling sequence of tvar: 580 $ PetscErrorCode tvar(TS ts,Vec p,Vec c,void *ctx); 581 582 + ts - timestep context 583 . p - input vector (primative form) 584 . c - output vector, transient variables (conservative form) 585 - ctx - [optional] user-defined function context 586 587 Level: advanced 588 589 Notes: 590 This is typically used to transform from primitive to conservative variables so that a time integrator (e.g., TSBDF) 591 can be conservative. In this context, primitive variables P are used to model the state (e.g., because they lead to 592 well-conditioned formulations even in limiting cases such as low-Mach or zero porosity). The transient variable is 593 C(P), specified by calling this function. An IFunction thus receives arguments (P, Cdot) and the IJacobian must be 594 evaluated via the chain rule, as in 595 596 dF/dP + shift * dF/dCdot dC/dP. 597 598 .seealso: TSSetTransientVariable(), DMTSGetTransientVariable(), DMTSSetIFunction(), DMTSSetIJacobian() 599 @*/ 600 PetscErrorCode DMTSSetTransientVariable(DM dm,TSTransientVariable tvar,void *ctx) 601 { 602 PetscErrorCode ierr; 603 DMTS dmts; 604 605 PetscFunctionBegin; 606 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 607 ierr = DMGetDMTSWrite(dm,&dmts);CHKERRQ(ierr); 608 dmts->ops->transientvar = tvar; 609 dmts->transientvarctx = ctx; 610 PetscFunctionReturn(0); 611 } 612 613 /*@C 614 DMTSGetTransientVariable - gets function to transform from state to transient variables 615 616 Logically Collective 617 618 Input Arguments: 619 . dm - DM to be used with TS 620 621 Output Arguments: 622 + tvar - a function that transforms to transient variables 623 - ctx - a context for tvar 624 625 Level: advanced 626 627 .seealso: DMTSSetTransientVariable(), DMTSGetIFunction(), DMTSGetIJacobian() 628 @*/ 629 PetscErrorCode DMTSGetTransientVariable(DM dm,TSTransientVariable *tvar,void *ctx) 630 { 631 PetscErrorCode ierr; 632 DMTS dmts; 633 634 PetscFunctionBegin; 635 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 636 ierr = DMGetDMTS(dm,&dmts);CHKERRQ(ierr); 637 if (tvar) *tvar = dmts->ops->transientvar; 638 if (ctx) *(void**)ctx = dmts->transientvarctx; 639 PetscFunctionReturn(0); 640 } 641 642 /*@C 643 DMTSGetSolutionFunction - gets the TS solution evaluation function 644 645 Not Collective 646 647 Input Arguments: 648 . dm - DM to be used with TS 649 650 Output Parameters: 651 + func - solution function evaluation function, see TSSetSolution() for calling sequence 652 - ctx - context for solution evaluation 653 654 Level: advanced 655 656 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian(), DMTSSetSolutionFunction() 657 @*/ 658 PetscErrorCode DMTSGetSolutionFunction(DM dm,TSSolutionFunction *func,void **ctx) 659 { 660 PetscErrorCode ierr; 661 DMTS tsdm; 662 663 PetscFunctionBegin; 664 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 665 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 666 if (func) *func = tsdm->ops->solution; 667 if (ctx) *ctx = tsdm->solutionctx; 668 PetscFunctionReturn(0); 669 } 670 671 /*@C 672 DMTSSetSolutionFunction - set TS solution evaluation function 673 674 Not Collective 675 676 Input Arguments: 677 + dm - DM to be used with TS 678 . func - solution function evaluation routine 679 - ctx - context for solution evaluation 680 681 Calling sequence of f: 682 $ PetscErrorCode f(TS ts,PetscReal t,Vec u,void *ctx); 683 684 + ts - timestep context 685 . t - current timestep 686 . u - output vector 687 - ctx - [optional] user-defined function context 688 689 Level: advanced 690 691 Note: 692 TSSetSolutionFunction() is normally used, but it calls this function internally because the user context is actually 693 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 694 not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 695 696 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian(), DMTSGetSolutionFunction() 697 @*/ 698 PetscErrorCode DMTSSetSolutionFunction(DM dm,TSSolutionFunction func,void *ctx) 699 { 700 PetscErrorCode ierr; 701 DMTS tsdm; 702 703 PetscFunctionBegin; 704 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 705 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 706 if (func) tsdm->ops->solution = func; 707 if (ctx) tsdm->solutionctx = ctx; 708 PetscFunctionReturn(0); 709 } 710 711 /*@C 712 DMTSSetForcingFunction - set TS forcing function evaluation function 713 714 Not Collective 715 716 Input Arguments: 717 + dm - DM to be used with TS 718 . f - forcing function evaluation routine 719 - ctx - context for solution evaluation 720 721 Calling sequence of func: 722 $ PetscErrorCode func (TS ts,PetscReal t,Vec f,void *ctx); 723 724 + ts - timestep context 725 . t - current timestep 726 . f - output vector 727 - ctx - [optional] user-defined function context 728 729 Level: advanced 730 731 Note: 732 TSSetForcingFunction() is normally used, but it calls this function internally because the user context is actually 733 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 734 not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 735 736 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian(), TSSetForcingFunction(), DMTSGetForcingFunction() 737 @*/ 738 PetscErrorCode DMTSSetForcingFunction(DM dm,TSForcingFunction f,void *ctx) 739 { 740 PetscErrorCode ierr; 741 DMTS tsdm; 742 743 PetscFunctionBegin; 744 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 745 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 746 if (f) tsdm->ops->forcing = f; 747 if (ctx) tsdm->forcingctx = ctx; 748 PetscFunctionReturn(0); 749 } 750 751 /*@C 752 DMTSGetForcingFunction - get TS forcing function evaluation function 753 754 Not Collective 755 756 Input Argument: 757 . dm - DM to be used with TS 758 759 Output Arguments: 760 + f - forcing function evaluation function; see TSForcingFunction for details 761 - ctx - context for solution evaluation 762 763 Level: advanced 764 765 Note: 766 TSSetForcingFunction() is normally used, but it calls this function internally because the user context is actually 767 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 768 not. If DM took a more central role at some later date, this could become the primary method of setting the residual. 769 770 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian(), TSSetForcingFunction(), DMTSGetForcingFunction() 771 @*/ 772 PetscErrorCode DMTSGetForcingFunction(DM dm,TSForcingFunction *f,void **ctx) 773 { 774 PetscErrorCode ierr; 775 DMTS tsdm; 776 777 PetscFunctionBegin; 778 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 779 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 780 if (f) *f = tsdm->ops->forcing; 781 if (ctx) *ctx = tsdm->forcingctx; 782 PetscFunctionReturn(0); 783 } 784 785 /*@C 786 DMTSGetRHSFunction - get TS explicit residual evaluation function 787 788 Not Collective 789 790 Input Argument: 791 . dm - DM to be used with TS 792 793 Output Arguments: 794 + func - residual evaluation function, see TSSetRHSFunction() for calling sequence 795 - ctx - context for residual evaluation 796 797 Level: advanced 798 799 Note: 800 TSGetFunction() is normally used, but it calls this function internally because the user context is actually 801 associated with the DM. 802 803 .seealso: DMTSSetContext(), DMTSSetRHSFunction(), TSSetRHSFunction() 804 @*/ 805 PetscErrorCode DMTSGetRHSFunction(DM dm,TSRHSFunction *func,void **ctx) 806 { 807 PetscErrorCode ierr; 808 DMTS tsdm; 809 810 PetscFunctionBegin; 811 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 812 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 813 if (func) *func = tsdm->ops->rhsfunction; 814 if (ctx) *ctx = tsdm->rhsfunctionctx; 815 PetscFunctionReturn(0); 816 } 817 818 /*@C 819 DMTSSetIJacobian - set TS Jacobian evaluation function 820 821 Not Collective 822 823 Input Argument: 824 + dm - DM to be used with TS 825 . func - Jacobian evaluation routine 826 - ctx - context for residual evaluation 827 828 Calling sequence of f: 829 $ PetscErrorCode f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat Amat,Mat Pmat,void *ctx); 830 831 + t - time at step/stage being solved 832 . U - state vector 833 . U_t - time derivative of state vector 834 . a - shift 835 . Amat - (approximate) Jacobian of F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t 836 . Pmat - matrix used for constructing preconditioner, usually the same as Amat 837 - ctx - [optional] user-defined context for matrix evaluation routine 838 839 Level: advanced 840 841 Note: 842 TSSetJacobian() is normally used, but it calls this function internally because the user context is actually 843 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 844 not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian. 845 846 .seealso: DMTSSetContext(), TSSetRHSFunction(), DMTSGetJacobian(), TSSetIJacobian(), TSSetIFunction() 847 @*/ 848 PetscErrorCode DMTSSetIJacobian(DM dm,TSIJacobian func,void *ctx) 849 { 850 PetscErrorCode ierr; 851 DMTS sdm; 852 853 PetscFunctionBegin; 854 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 855 ierr = DMGetDMTSWrite(dm,&sdm);CHKERRQ(ierr); 856 if (func) sdm->ops->ijacobian = func; 857 if (ctx) sdm->ijacobianctx = ctx; 858 PetscFunctionReturn(0); 859 } 860 861 /*@C 862 DMTSGetIJacobian - get TS Jacobian evaluation function 863 864 Not Collective 865 866 Input Argument: 867 . dm - DM to be used with TS 868 869 Output Arguments: 870 + func - Jacobian evaluation function, see TSSetIJacobian() for calling sequence 871 - ctx - context for residual evaluation 872 873 Level: advanced 874 875 Note: 876 TSGetJacobian() is normally used, but it calls this function internally because the user context is actually 877 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 878 not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian. 879 880 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 881 @*/ 882 PetscErrorCode DMTSGetIJacobian(DM dm,TSIJacobian *func,void **ctx) 883 { 884 PetscErrorCode ierr; 885 DMTS tsdm; 886 887 PetscFunctionBegin; 888 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 889 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 890 if (func) *func = tsdm->ops->ijacobian; 891 if (ctx) *ctx = tsdm->ijacobianctx; 892 PetscFunctionReturn(0); 893 } 894 895 /*@C 896 DMTSSetRHSJacobian - set TS Jacobian evaluation function 897 898 Not Collective 899 900 Input Argument: 901 + dm - DM to be used with TS 902 . func - Jacobian evaluation routine 903 - ctx - context for residual evaluation 904 905 Calling sequence of func: 906 $ PetscErrorCode func(TS ts,PetscReal t,Vec u,Mat A,Mat B,void *ctx); 907 908 + t - current timestep 909 . u - input vector 910 . Amat - (approximate) Jacobian matrix 911 . Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat) 912 - ctx - [optional] user-defined context for matrix evaluation routine 913 914 Level: advanced 915 916 Note: 917 TSSetJacobian() is normally used, but it calls this function internally because the user context is actually 918 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 919 not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian. 920 921 .seealso: DMTSSetContext(), TSSetFunction(), DMTSGetJacobian(), TSSetRHSJacobian() 922 @*/ 923 PetscErrorCode DMTSSetRHSJacobian(DM dm,TSRHSJacobian func,void *ctx) 924 { 925 PetscErrorCode ierr; 926 DMTS tsdm; 927 928 PetscFunctionBegin; 929 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 930 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 931 if (func) tsdm->ops->rhsjacobian = func; 932 if (ctx) tsdm->rhsjacobianctx = ctx; 933 PetscFunctionReturn(0); 934 } 935 936 /*@C 937 DMTSGetRHSJacobian - get TS Jacobian evaluation function 938 939 Not Collective 940 941 Input Argument: 942 . dm - DM to be used with TS 943 944 Output Arguments: 945 + func - Jacobian evaluation function, see TSSetRHSJacobian() for calling sequence 946 - ctx - context for residual evaluation 947 948 Level: advanced 949 950 Note: 951 TSGetJacobian() is normally used, but it calls this function internally because the user context is actually 952 associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or 953 not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian. 954 955 .seealso: DMTSSetContext(), TSSetRHSFunction(), DMTSSetRHSJacobian(), TSSetRHSJacobian() 956 @*/ 957 PetscErrorCode DMTSGetRHSJacobian(DM dm,TSRHSJacobian *func,void **ctx) 958 { 959 PetscErrorCode ierr; 960 DMTS tsdm; 961 962 PetscFunctionBegin; 963 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 964 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 965 if (func) *func = tsdm->ops->rhsjacobian; 966 if (ctx) *ctx = tsdm->rhsjacobianctx; 967 PetscFunctionReturn(0); 968 } 969 970 /*@C 971 DMTSSetIFunctionSerialize - sets functions used to view and load a IFunction context 972 973 Not Collective 974 975 Input Arguments: 976 + dm - DM to be used with TS 977 . view - viewer function 978 - load - loading function 979 980 Level: advanced 981 982 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 983 @*/ 984 PetscErrorCode DMTSSetIFunctionSerialize(DM dm,PetscErrorCode (*view)(void*,PetscViewer),PetscErrorCode (*load)(void**,PetscViewer)) 985 { 986 PetscErrorCode ierr; 987 DMTS tsdm; 988 989 PetscFunctionBegin; 990 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 991 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 992 tsdm->ops->ifunctionview = view; 993 tsdm->ops->ifunctionload = load; 994 PetscFunctionReturn(0); 995 } 996 997 /*@C 998 DMTSSetIJacobianSerialize - sets functions used to view and load a IJacobian context 999 1000 Not Collective 1001 1002 Input Arguments: 1003 + dm - DM to be used with TS 1004 . view - viewer function 1005 - load - loading function 1006 1007 Level: advanced 1008 1009 .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian() 1010 @*/ 1011 PetscErrorCode DMTSSetIJacobianSerialize(DM dm,PetscErrorCode (*view)(void*,PetscViewer),PetscErrorCode (*load)(void**,PetscViewer)) 1012 { 1013 PetscErrorCode ierr; 1014 DMTS tsdm; 1015 1016 PetscFunctionBegin; 1017 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1018 ierr = DMGetDMTSWrite(dm,&tsdm);CHKERRQ(ierr); 1019 tsdm->ops->ijacobianview = view; 1020 tsdm->ops->ijacobianload = load; 1021 PetscFunctionReturn(0); 1022 } 1023