1 /* $Id: ts.c,v 1.36 2001/03/22 20:32:17 bsmith Exp balay $ */ 2 #include "src/ts/tsimpl.h" /*I "petscts.h" I*/ 3 4 #undef __FUNCT__ 5 #define __FUNCT__ "TSComputeRHSJacobian" 6 /*@ 7 TSComputeRHSJacobian - Computes the Jacobian matrix that has been 8 set with TSSetRHSJacobian(). 9 10 Collective on TS and Vec 11 12 Input Parameters: 13 + ts - the SNES context 14 . t - current timestep 15 - x - input vector 16 17 Output Parameters: 18 + A - Jacobian matrix 19 . B - optional preconditioning matrix 20 - flag - flag indicating matrix structure 21 22 Notes: 23 Most users should not need to explicitly call this routine, as it 24 is used internally within the nonlinear solvers. 25 26 See SLESSetOperators() for important information about setting the 27 flag parameter. 28 29 TSComputeJacobian() is valid only for TS_NONLINEAR 30 31 Level: developer 32 33 .keywords: SNES, compute, Jacobian, matrix 34 35 .seealso: TSSetRHSJacobian(), SLESSetOperators() 36 @*/ 37 int TSComputeRHSJacobian(TS ts,double t,Vec X,Mat *A,Mat *B,MatStructure *flg) 38 { 39 int ierr; 40 41 PetscFunctionBegin; 42 PetscValidHeaderSpecific(ts,TS_COOKIE); 43 PetscValidHeaderSpecific(X,VEC_COOKIE); 44 PetscCheckSameComm(ts,X); 45 if (ts->problem_type != TS_NONLINEAR) { 46 SETERRQ(PETSC_ERR_ARG_WRONG,"For TS_NONLINEAR only"); 47 } 48 if (!ts->rhsjacobian) PetscFunctionReturn(0); 49 ierr = PetscLogEventBegin(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr); 50 *flg = DIFFERENT_NONZERO_PATTERN; 51 PetscStackPush("TS user Jacobian function"); 52 ierr = (*ts->rhsjacobian)(ts,t,X,A,B,flg,ts->jacP);CHKERRQ(ierr); 53 PetscStackPop; 54 ierr = PetscLogEventEnd(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr); 55 /* make sure user returned a correct Jacobian and preconditioner */ 56 PetscValidHeaderSpecific(*A,MAT_COOKIE); 57 PetscValidHeaderSpecific(*B,MAT_COOKIE); 58 PetscFunctionReturn(0); 59 } 60 61 #undef __FUNCT__ 62 #define __FUNCT__ "TSComputeRHSFunction" 63 /* 64 TSComputeRHSFunction - Evaluates the right-hand-side function. 65 66 Note: If the user did not provide a function but merely a matrix, 67 this routine applies the matrix. 68 */ 69 int TSComputeRHSFunction(TS ts,double t,Vec x,Vec y) 70 { 71 int ierr; 72 73 PetscFunctionBegin; 74 PetscValidHeaderSpecific(ts,TS_COOKIE); 75 PetscValidHeader(x); 76 PetscValidHeader(y); 77 78 ierr = PetscLogEventBegin(TS_FunctionEval,ts,x,y,0);CHKERRQ(ierr); 79 if (ts->rhsfunction) { 80 PetscStackPush("TS user right-hand-side function"); 81 ierr = (*ts->rhsfunction)(ts,t,x,y,ts->funP);CHKERRQ(ierr); 82 PetscStackPop; 83 } else { 84 if (ts->rhsmatrix) { /* assemble matrix for this timestep */ 85 MatStructure flg; 86 PetscStackPush("TS user right-hand-side matrix function"); 87 ierr = (*ts->rhsmatrix)(ts,t,&ts->A,&ts->B,&flg,ts->jacP);CHKERRQ(ierr); 88 PetscStackPop; 89 } 90 ierr = MatMult(ts->A,x,y);CHKERRQ(ierr); 91 } 92 93 /* apply user-provided boundary conditions (only needed if these are time dependent) */ 94 ierr = TSComputeRHSBoundaryConditions(ts,t,y);CHKERRQ(ierr); 95 ierr = PetscLogEventEnd(TS_FunctionEval,ts,x,y,0);CHKERRQ(ierr); 96 97 PetscFunctionReturn(0); 98 } 99 100 #undef __FUNCT__ 101 #define __FUNCT__ "TSSetRHSFunction" 102 /*@C 103 TSSetRHSFunction - Sets the routine for evaluating the function, 104 F(t,u), where U_t = F(t,u). 105 106 Collective on TS 107 108 Input Parameters: 109 + ts - the TS context obtained from TSCreate() 110 . f - routine for evaluating the right-hand-side function 111 - ctx - [optional] user-defined context for private data for the 112 function evaluation routine (may be PETSC_NULL) 113 114 Calling sequence of func: 115 $ func (TS ts,double t,Vec u,Vec F,void *ctx); 116 117 + t - current timestep 118 . u - input vector 119 . F - function vector 120 - ctx - [optional] user-defined function context 121 122 Important: 123 The user MUST call either this routine or TSSetRHSMatrix(). 124 125 Level: beginner 126 127 .keywords: TS, timestep, set, right-hand-side, function 128 129 .seealso: TSSetRHSMatrix() 130 @*/ 131 int TSSetRHSFunction(TS ts,int (*f)(TS,double,Vec,Vec,void*),void *ctx) 132 { 133 PetscFunctionBegin; 134 135 PetscValidHeaderSpecific(ts,TS_COOKIE); 136 if (ts->problem_type == TS_LINEAR) { 137 SETERRQ(PETSC_ERR_ARG_WRONG,"Cannot set function for linear problem"); 138 } 139 ts->rhsfunction = f; 140 ts->funP = ctx; 141 PetscFunctionReturn(0); 142 } 143 144 #undef __FUNCT__ 145 #define __FUNCT__ "TSSetRHSMatrix" 146 /*@C 147 TSSetRHSMatrix - Sets the function to compute the matrix A, where U_t = A(t) U. 148 Also sets the location to store A. 149 150 Collective on TS 151 152 Input Parameters: 153 + ts - the TS context obtained from TSCreate() 154 . A - matrix 155 . B - preconditioner matrix (usually same as A) 156 . f - the matrix evaluation routine; use PETSC_NULL (PETSC_NULL_FUNCTION in fortran) 157 if A is not a function of t. 158 - ctx - [optional] user-defined context for private data for the 159 matrix evaluation routine (may be PETSC_NULL) 160 161 Calling sequence of func: 162 $ func (TS ts,double t,Mat *A,Mat *B,int *flag,void *ctx); 163 164 + t - current timestep 165 . A - matrix A, where U_t = A(t) U 166 . B - preconditioner matrix, usually the same as A 167 . flag - flag indicating information about the preconditioner matrix 168 structure (same as flag in SLESSetOperators()) 169 - ctx - [optional] user-defined context for matrix evaluation routine 170 171 Notes: 172 See SLESSetOperators() for important information about setting the flag 173 output parameter in the routine func(). Be sure to read this information! 174 175 The routine func() takes Mat * as the matrix arguments rather than Mat. 176 This allows the matrix evaluation routine to replace A and/or B with a 177 completely new new matrix structure (not just different matrix elements) 178 when appropriate, for instance, if the nonzero structure is changing 179 throughout the global iterations. 180 181 Important: 182 The user MUST call either this routine or TSSetRHSFunction(). 183 184 Level: beginner 185 186 .keywords: TS, timestep, set, right-hand-side, matrix 187 188 .seealso: TSSetRHSFunction() 189 @*/ 190 int TSSetRHSMatrix(TS ts,Mat A,Mat B,int (*f)(TS,double,Mat*,Mat*,MatStructure*,void*),void *ctx) 191 { 192 PetscFunctionBegin; 193 PetscValidHeaderSpecific(ts,TS_COOKIE); 194 PetscValidHeaderSpecific(A,MAT_COOKIE); 195 PetscValidHeaderSpecific(B,MAT_COOKIE); 196 PetscCheckSameComm(ts,A); 197 PetscCheckSameComm(ts,B); 198 if (ts->problem_type == TS_NONLINEAR) { 199 SETERRQ(PETSC_ERR_ARG_WRONG,"Not for nonlinear problems; use TSSetRHSJacobian()"); 200 } 201 202 ts->rhsmatrix = f; 203 ts->jacP = ctx; 204 ts->A = A; 205 ts->B = B; 206 207 PetscFunctionReturn(0); 208 } 209 210 #undef __FUNCT__ 211 #define __FUNCT__ "TSSetRHSJacobian" 212 /*@C 213 TSSetRHSJacobian - Sets the function to compute the Jacobian of F, 214 where U_t = F(U,t), as well as the location to store the matrix. 215 216 Collective on TS 217 218 Input Parameters: 219 + ts - the TS context obtained from TSCreate() 220 . A - Jacobian matrix 221 . B - preconditioner matrix (usually same as A) 222 . f - the Jacobian evaluation routine 223 - ctx - [optional] user-defined context for private data for the 224 Jacobian evaluation routine (may be PETSC_NULL) 225 226 Calling sequence of func: 227 $ func (TS ts,double t,Vec u,Mat *A,Mat *B,MatStructure *flag,void *ctx); 228 229 + t - current timestep 230 . u - input vector 231 . A - matrix A, where U_t = A(t)u 232 . B - preconditioner matrix, usually the same as A 233 . flag - flag indicating information about the preconditioner matrix 234 structure (same as flag in SLESSetOperators()) 235 - ctx - [optional] user-defined context for matrix evaluation routine 236 237 Notes: 238 See SLESSetOperators() for important information about setting the flag 239 output parameter in the routine func(). Be sure to read this information! 240 241 The routine func() takes Mat * as the matrix arguments rather than Mat. 242 This allows the matrix evaluation routine to replace A and/or B with a 243 completely new new matrix structure (not just different matrix elements) 244 when appropriate, for instance, if the nonzero structure is changing 245 throughout the global iterations. 246 247 Level: beginner 248 249 .keywords: TS, timestep, set, right-hand-side, Jacobian 250 251 .seealso: TSDefaultComputeJacobianColor(), 252 SNESDefaultComputeJacobianColor() 253 254 @*/ 255 int TSSetRHSJacobian(TS ts,Mat A,Mat B,int (*f)(TS,double,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 256 { 257 PetscFunctionBegin; 258 PetscValidHeaderSpecific(ts,TS_COOKIE); 259 PetscValidHeaderSpecific(A,MAT_COOKIE); 260 PetscValidHeaderSpecific(B,MAT_COOKIE); 261 PetscCheckSameComm(ts,A); 262 PetscCheckSameComm(ts,B); 263 if (ts->problem_type != TS_NONLINEAR) { 264 SETERRQ(PETSC_ERR_ARG_WRONG,"Not for linear problems; use TSSetRHSMatrix()"); 265 } 266 267 ts->rhsjacobian = f; 268 ts->jacP = ctx; 269 ts->A = A; 270 ts->B = B; 271 PetscFunctionReturn(0); 272 } 273 274 #undef __FUNCT__ 275 #define __FUNCT__ "TSComputeRHSBoundaryConditions" 276 /* 277 TSComputeRHSBoundaryConditions - Evaluates the boundary condition function. 278 279 Note: If the user did not provide a function but merely a matrix, 280 this routine applies the matrix. 281 */ 282 int TSComputeRHSBoundaryConditions(TS ts,double t,Vec x) 283 { 284 int ierr; 285 286 PetscFunctionBegin; 287 PetscValidHeaderSpecific(ts,TS_COOKIE); 288 PetscValidHeader(x); 289 PetscCheckSameComm(ts,x); 290 291 if (ts->rhsbc) { 292 PetscStackPush("TS user boundary condition function"); 293 ierr = (*ts->rhsbc)(ts,t,x,ts->bcP);CHKERRQ(ierr); 294 PetscStackPop; 295 PetscFunctionReturn(0); 296 } 297 298 PetscFunctionReturn(0); 299 } 300 301 #undef __FUNCT__ 302 #define __FUNCT__ "TSSetRHSBoundaryConditions" 303 /*@C 304 TSSetRHSBoundaryConditions - Sets the routine for evaluating the function, 305 boundary conditions for the function F. 306 307 Collective on TS 308 309 Input Parameters: 310 + ts - the TS context obtained from TSCreate() 311 . f - routine for evaluating the boundary condition function 312 - ctx - [optional] user-defined context for private data for the 313 function evaluation routine (may be PETSC_NULL) 314 315 Calling sequence of func: 316 $ func (TS ts,double t,Vec F,void *ctx); 317 318 + t - current timestep 319 . F - function vector 320 - ctx - [optional] user-defined function context 321 322 Level: intermediate 323 324 .keywords: TS, timestep, set, boundary conditions, function 325 @*/ 326 int TSSetRHSBoundaryConditions(TS ts,int (*f)(TS,double,Vec,void*),void *ctx) 327 { 328 PetscFunctionBegin; 329 330 PetscValidHeaderSpecific(ts,TS_COOKIE); 331 if (ts->problem_type != TS_LINEAR) { 332 SETERRQ(PETSC_ERR_ARG_WRONG,"For linear problems only"); 333 } 334 ts->rhsbc = f; 335 ts->bcP = ctx; 336 PetscFunctionReturn(0); 337 } 338 339 #undef __FUNCT__ 340 #define __FUNCT__ "TSView" 341 /*@C 342 TSView - Prints the TS data structure. 343 344 Collective on TS 345 346 Input Parameters: 347 + ts - the TS context obtained from TSCreate() 348 - viewer - visualization context 349 350 Options Database Key: 351 . -ts_view - calls TSView() at end of TSStep() 352 353 Notes: 354 The available visualization contexts include 355 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 356 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 357 output where only the first processor opens 358 the file. All other processors send their 359 data to the first processor to print. 360 361 The user can open an alternative visualization context with 362 PetscViewerASCIIOpen() - output to a specified file. 363 364 Level: beginner 365 366 .keywords: TS, timestep, view 367 368 .seealso: PetscViewerASCIIOpen() 369 @*/ 370 int TSView(TS ts,PetscViewer viewer) 371 { 372 int ierr; 373 char *type; 374 PetscTruth isascii,isstring; 375 376 PetscFunctionBegin; 377 PetscValidHeaderSpecific(ts,TS_COOKIE); 378 if (!viewer) viewer = PETSC_VIEWER_STDOUT_(ts->comm); 379 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE); 380 PetscCheckSameComm(ts,viewer); 381 382 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr); 383 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);CHKERRQ(ierr); 384 if (isascii) { 385 ierr = PetscViewerASCIIPrintf(viewer,"TS Object:\n");CHKERRQ(ierr); 386 ierr = TSGetType(ts,(TSType *)&type);CHKERRQ(ierr); 387 if (type) { 388 ierr = PetscViewerASCIIPrintf(viewer," type: %s\n",type);CHKERRQ(ierr); 389 } else { 390 ierr = PetscViewerASCIIPrintf(viewer," type: not yet set\n");CHKERRQ(ierr); 391 } 392 if (ts->view) { 393 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 394 ierr = (*ts->view)(ts,viewer);CHKERRQ(ierr); 395 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 396 } 397 ierr = PetscViewerASCIIPrintf(viewer," maximum steps=%d\n",ts->max_steps);CHKERRQ(ierr); 398 ierr = PetscViewerASCIIPrintf(viewer," maximum time=%g\n",ts->max_time);CHKERRQ(ierr); 399 if (ts->problem_type == TS_NONLINEAR) { 400 ierr = PetscViewerASCIIPrintf(viewer," total number of nonlinear solver iterations=%d\n",ts->nonlinear_its);CHKERRQ(ierr); 401 } 402 ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%d\n",ts->linear_its);CHKERRQ(ierr); 403 } else if (isstring) { 404 ierr = TSGetType(ts,(TSType *)&type);CHKERRQ(ierr); 405 ierr = PetscViewerStringSPrintf(viewer," %-7.7s",type);CHKERRQ(ierr); 406 } 407 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 408 if (ts->sles) {ierr = SLESView(ts->sles,viewer);CHKERRQ(ierr);} 409 if (ts->snes) {ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr);} 410 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 411 PetscFunctionReturn(0); 412 } 413 414 415 #undef __FUNCT__ 416 #define __FUNCT__ "TSSetApplicationContext" 417 /*@C 418 TSSetApplicationContext - Sets an optional user-defined context for 419 the timesteppers. 420 421 Collective on TS 422 423 Input Parameters: 424 + ts - the TS context obtained from TSCreate() 425 - usrP - optional user context 426 427 Level: intermediate 428 429 .keywords: TS, timestep, set, application, context 430 431 .seealso: TSGetApplicationContext() 432 @*/ 433 int TSSetApplicationContext(TS ts,void *usrP) 434 { 435 PetscFunctionBegin; 436 PetscValidHeaderSpecific(ts,TS_COOKIE); 437 ts->user = usrP; 438 PetscFunctionReturn(0); 439 } 440 441 #undef __FUNCT__ 442 #define __FUNCT__ "TSGetApplicationContext" 443 /*@C 444 TSGetApplicationContext - Gets the user-defined context for the 445 timestepper. 446 447 Not Collective 448 449 Input Parameter: 450 . ts - the TS context obtained from TSCreate() 451 452 Output Parameter: 453 . usrP - user context 454 455 Level: intermediate 456 457 .keywords: TS, timestep, get, application, context 458 459 .seealso: TSSetApplicationContext() 460 @*/ 461 int TSGetApplicationContext(TS ts,void **usrP) 462 { 463 PetscFunctionBegin; 464 PetscValidHeaderSpecific(ts,TS_COOKIE); 465 *usrP = ts->user; 466 PetscFunctionReturn(0); 467 } 468 469 #undef __FUNCT__ 470 #define __FUNCT__ "TSGetTimeStepNumber" 471 /*@ 472 TSGetTimeStepNumber - Gets the current number of timesteps. 473 474 Not Collective 475 476 Input Parameter: 477 . ts - the TS context obtained from TSCreate() 478 479 Output Parameter: 480 . iter - number steps so far 481 482 Level: intermediate 483 484 .keywords: TS, timestep, get, iteration, number 485 @*/ 486 int TSGetTimeStepNumber(TS ts,int* iter) 487 { 488 PetscFunctionBegin; 489 PetscValidHeaderSpecific(ts,TS_COOKIE); 490 *iter = ts->steps; 491 PetscFunctionReturn(0); 492 } 493 494 #undef __FUNCT__ 495 #define __FUNCT__ "TSSetInitialTimeStep" 496 /*@ 497 TSSetInitialTimeStep - Sets the initial timestep to be used, 498 as well as the initial time. 499 500 Collective on TS 501 502 Input Parameters: 503 + ts - the TS context obtained from TSCreate() 504 . initial_time - the initial time 505 - time_step - the size of the timestep 506 507 Level: intermediate 508 509 .seealso: TSSetTimeStep(), TSGetTimeStep() 510 511 .keywords: TS, set, initial, timestep 512 @*/ 513 int TSSetInitialTimeStep(TS ts,double initial_time,double time_step) 514 { 515 PetscFunctionBegin; 516 PetscValidHeaderSpecific(ts,TS_COOKIE); 517 ts->time_step = time_step; 518 ts->initial_time_step = time_step; 519 ts->ptime = initial_time; 520 PetscFunctionReturn(0); 521 } 522 523 #undef __FUNCT__ 524 #define __FUNCT__ "TSSetTimeStep" 525 /*@ 526 TSSetTimeStep - Allows one to reset the timestep at any time, 527 useful for simple pseudo-timestepping codes. 528 529 Collective on TS 530 531 Input Parameters: 532 + ts - the TS context obtained from TSCreate() 533 - time_step - the size of the timestep 534 535 Level: intermediate 536 537 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 538 539 .keywords: TS, set, timestep 540 @*/ 541 int TSSetTimeStep(TS ts,double time_step) 542 { 543 PetscFunctionBegin; 544 PetscValidHeaderSpecific(ts,TS_COOKIE); 545 ts->time_step = time_step; 546 PetscFunctionReturn(0); 547 } 548 549 #undef __FUNCT__ 550 #define __FUNCT__ "TSGetTimeStep" 551 /*@ 552 TSGetTimeStep - Gets the current timestep size. 553 554 Not Collective 555 556 Input Parameter: 557 . ts - the TS context obtained from TSCreate() 558 559 Output Parameter: 560 . dt - the current timestep size 561 562 Level: intermediate 563 564 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 565 566 .keywords: TS, get, timestep 567 @*/ 568 int TSGetTimeStep(TS ts,double* dt) 569 { 570 PetscFunctionBegin; 571 PetscValidHeaderSpecific(ts,TS_COOKIE); 572 *dt = ts->time_step; 573 PetscFunctionReturn(0); 574 } 575 576 #undef __FUNCT__ 577 #define __FUNCT__ "TSGetSolution" 578 /*@C 579 TSGetSolution - Returns the solution at the present timestep. It 580 is valid to call this routine inside the function that you are evaluating 581 in order to move to the new timestep. This vector not changed until 582 the solution at the next timestep has been calculated. 583 584 Not Collective, but Vec returned is parallel if TS is parallel 585 586 Input Parameter: 587 . ts - the TS context obtained from TSCreate() 588 589 Output Parameter: 590 . v - the vector containing the solution 591 592 Level: intermediate 593 594 .seealso: TSGetTimeStep() 595 596 .keywords: TS, timestep, get, solution 597 @*/ 598 int TSGetSolution(TS ts,Vec *v) 599 { 600 PetscFunctionBegin; 601 PetscValidHeaderSpecific(ts,TS_COOKIE); 602 *v = ts->vec_sol_always; 603 PetscFunctionReturn(0); 604 } 605 606 #undef __FUNCT__ 607 #define __FUNCT__ "TSPublish_Petsc" 608 static int TSPublish_Petsc(PetscObject obj) 609 { 610 #if defined(PETSC_HAVE_AMS) 611 TS v = (TS) obj; 612 int ierr; 613 #endif 614 615 PetscFunctionBegin; 616 617 #if defined(PETSC_HAVE_AMS) 618 /* if it is already published then return */ 619 if (v->amem >=0) PetscFunctionReturn(0); 620 621 ierr = PetscObjectPublishBaseBegin(obj);CHKERRQ(ierr); 622 ierr = AMS_Memory_add_field((AMS_Memory)v->amem,"Step",&v->steps,1,AMS_INT,AMS_READ, 623 AMS_COMMON,AMS_REDUCT_UNDEF);CHKERRQ(ierr); 624 ierr = AMS_Memory_add_field((AMS_Memory)v->amem,"Time",&v->ptime,1,AMS_DOUBLE,AMS_READ, 625 AMS_COMMON,AMS_REDUCT_UNDEF);CHKERRQ(ierr); 626 ierr = AMS_Memory_add_field((AMS_Memory)v->amem,"CurrentTimeStep",&v->time_step,1, 627 AMS_DOUBLE,AMS_READ,AMS_COMMON,AMS_REDUCT_UNDEF);CHKERRQ(ierr); 628 ierr = PetscObjectPublishBaseEnd(obj);CHKERRQ(ierr); 629 #endif 630 PetscFunctionReturn(0); 631 } 632 633 /* -----------------------------------------------------------*/ 634 635 #undef __FUNCT__ 636 #define __FUNCT__ "TSCreate" 637 /*@C 638 TSCreate - Creates a timestepper context. 639 640 Collective on MPI_Comm 641 642 Input Parameter: 643 + comm - MPI communicator 644 - type - One of TS_LINEAR,TS_NONLINEAR 645 where these types refer to problems of the forms 646 .vb 647 U_t = A U 648 U_t = A(t) U 649 U_t = F(t,U) 650 .ve 651 652 Output Parameter: 653 . outts - the new TS context 654 655 Level: beginner 656 657 .keywords: TS, timestep, create, context 658 659 .seealso: TSSetUp(), TSStep(), TSDestroy(), TSProblemType, TS 660 @*/ 661 int TSCreate(MPI_Comm comm,TSProblemType problemtype,TS *outts) 662 { 663 TS ts; 664 665 PetscFunctionBegin; 666 *outts = 0; 667 PetscHeaderCreate(ts,_p_TS,int,TS_COOKIE,-1,"TS",comm,TSDestroy,TSView); 668 PetscLogObjectCreate(ts); 669 ts->bops->publish = TSPublish_Petsc; 670 ts->max_steps = 5000; 671 ts->max_time = 5.0; 672 ts->time_step = .1; 673 ts->initial_time_step = ts->time_step; 674 ts->steps = 0; 675 ts->ptime = 0.0; 676 ts->data = 0; 677 ts->view = 0; 678 ts->setupcalled = 0; 679 ts->problem_type = problemtype; 680 ts->numbermonitors = 0; 681 ts->linear_its = 0; 682 ts->nonlinear_its = 0; 683 684 *outts = ts; 685 PetscFunctionReturn(0); 686 } 687 688 /* ----- Routines to initialize and destroy a timestepper ---- */ 689 690 #undef __FUNCT__ 691 #define __FUNCT__ "TSSetUp" 692 /*@ 693 TSSetUp - Sets up the internal data structures for the later use 694 of a timestepper. 695 696 Collective on TS 697 698 Input Parameter: 699 . ts - the TS context obtained from TSCreate() 700 701 Notes: 702 For basic use of the TS solvers the user need not explicitly call 703 TSSetUp(), since these actions will automatically occur during 704 the call to TSStep(). However, if one wishes to control this 705 phase separately, TSSetUp() should be called after TSCreate() 706 and optional routines of the form TSSetXXX(), but before TSStep(). 707 708 Level: advanced 709 710 .keywords: TS, timestep, setup 711 712 .seealso: TSCreate(), TSStep(), TSDestroy() 713 @*/ 714 int TSSetUp(TS ts) 715 { 716 int ierr; 717 718 PetscFunctionBegin; 719 PetscValidHeaderSpecific(ts,TS_COOKIE); 720 if (!ts->vec_sol) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first"); 721 if (!ts->type_name) { 722 ierr = TSSetType(ts,TS_EULER);CHKERRQ(ierr); 723 } 724 ierr = (*ts->setup)(ts);CHKERRQ(ierr); 725 ts->setupcalled = 1; 726 PetscFunctionReturn(0); 727 } 728 729 #undef __FUNCT__ 730 #define __FUNCT__ "TSDestroy" 731 /*@C 732 TSDestroy - Destroys the timestepper context that was created 733 with TSCreate(). 734 735 Collective on TS 736 737 Input Parameter: 738 . ts - the TS context obtained from TSCreate() 739 740 Level: beginner 741 742 .keywords: TS, timestepper, destroy 743 744 .seealso: TSCreate(), TSSetUp(), TSSolve() 745 @*/ 746 int TSDestroy(TS ts) 747 { 748 int ierr,i; 749 750 PetscFunctionBegin; 751 PetscValidHeaderSpecific(ts,TS_COOKIE); 752 if (--ts->refct > 0) PetscFunctionReturn(0); 753 754 /* if memory was published with AMS then destroy it */ 755 ierr = PetscObjectDepublish(ts);CHKERRQ(ierr); 756 757 if (ts->sles) {ierr = SLESDestroy(ts->sles);CHKERRQ(ierr);} 758 if (ts->snes) {ierr = SNESDestroy(ts->snes);CHKERRQ(ierr);} 759 ierr = (*(ts)->destroy)(ts);CHKERRQ(ierr); 760 for (i=0; i<ts->numbermonitors; i++) { 761 if (ts->mdestroy[i]) { 762 ierr = (*ts->mdestroy[i])(ts->monitorcontext[i]);CHKERRQ(ierr); 763 } 764 } 765 PetscLogObjectDestroy((PetscObject)ts); 766 PetscHeaderDestroy((PetscObject)ts); 767 PetscFunctionReturn(0); 768 } 769 770 #undef __FUNCT__ 771 #define __FUNCT__ "TSGetSNES" 772 /*@C 773 TSGetSNES - Returns the SNES (nonlinear solver) associated with 774 a TS (timestepper) context. Valid only for nonlinear problems. 775 776 Not Collective, but SNES is parallel if TS is parallel 777 778 Input Parameter: 779 . ts - the TS context obtained from TSCreate() 780 781 Output Parameter: 782 . snes - the nonlinear solver context 783 784 Notes: 785 The user can then directly manipulate the SNES context to set various 786 options, etc. Likewise, the user can then extract and manipulate the 787 SLES, KSP, and PC contexts as well. 788 789 TSGetSNES() does not work for integrators that do not use SNES; in 790 this case TSGetSNES() returns PETSC_NULL in snes. 791 792 Level: beginner 793 794 .keywords: timestep, get, SNES 795 @*/ 796 int TSGetSNES(TS ts,SNES *snes) 797 { 798 PetscFunctionBegin; 799 PetscValidHeaderSpecific(ts,TS_COOKIE); 800 if (ts->problem_type == TS_LINEAR) SETERRQ(PETSC_ERR_ARG_WRONG,"Nonlinear only; use TSGetSLES()"); 801 *snes = ts->snes; 802 PetscFunctionReturn(0); 803 } 804 805 #undef __FUNCT__ 806 #define __FUNCT__ "TSGetSLES" 807 /*@C 808 TSGetSLES - Returns the SLES (linear solver) associated with 809 a TS (timestepper) context. 810 811 Not Collective, but SLES is parallel if TS is parallel 812 813 Input Parameter: 814 . ts - the TS context obtained from TSCreate() 815 816 Output Parameter: 817 . sles - the nonlinear solver context 818 819 Notes: 820 The user can then directly manipulate the SLES context to set various 821 options, etc. Likewise, the user can then extract and manipulate the 822 KSP and PC contexts as well. 823 824 TSGetSLES() does not work for integrators that do not use SLES; 825 in this case TSGetSLES() returns PETSC_NULL in sles. 826 827 Level: beginner 828 829 .keywords: timestep, get, SLES 830 @*/ 831 int TSGetSLES(TS ts,SLES *sles) 832 { 833 PetscFunctionBegin; 834 PetscValidHeaderSpecific(ts,TS_COOKIE); 835 if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()"); 836 *sles = ts->sles; 837 PetscFunctionReturn(0); 838 } 839 840 /* ----------- Routines to set solver parameters ---------- */ 841 842 #undef __FUNCT__ 843 #define __FUNCT__ "TSSetDuration" 844 /*@ 845 TSSetDuration - Sets the maximum number of timesteps to use and 846 maximum time for iteration. 847 848 Collective on TS 849 850 Input Parameters: 851 + ts - the TS context obtained from TSCreate() 852 . maxsteps - maximum number of iterations to use 853 - maxtime - final time to iterate to 854 855 Options Database Keys: 856 . -ts_max_steps <maxsteps> - Sets maxsteps 857 . -ts_max_time <maxtime> - Sets maxtime 858 859 Notes: 860 The default maximum number of iterations is 5000. Default time is 5.0 861 862 Level: intermediate 863 864 .keywords: TS, timestep, set, maximum, iterations 865 @*/ 866 int TSSetDuration(TS ts,int maxsteps,double maxtime) 867 { 868 PetscFunctionBegin; 869 PetscValidHeaderSpecific(ts,TS_COOKIE); 870 ts->max_steps = maxsteps; 871 ts->max_time = maxtime; 872 PetscFunctionReturn(0); 873 } 874 875 #undef __FUNCT__ 876 #define __FUNCT__ "TSSetSolution" 877 /*@ 878 TSSetSolution - Sets the initial solution vector 879 for use by the TS routines. 880 881 Collective on TS and Vec 882 883 Input Parameters: 884 + ts - the TS context obtained from TSCreate() 885 - x - the solution vector 886 887 Level: beginner 888 889 .keywords: TS, timestep, set, solution, initial conditions 890 @*/ 891 int TSSetSolution(TS ts,Vec x) 892 { 893 PetscFunctionBegin; 894 PetscValidHeaderSpecific(ts,TS_COOKIE); 895 ts->vec_sol = ts->vec_sol_always = x; 896 PetscFunctionReturn(0); 897 } 898 899 /* ------------ Routines to set performance monitoring options ----------- */ 900 901 #undef __FUNCT__ 902 #define __FUNCT__ "TSSetMonitor" 903 /*@C 904 TSSetMonitor - Sets an ADDITIONAL function that is to be used at every 905 timestep to display the iteration's progress. 906 907 Collective on TS 908 909 Input Parameters: 910 + ts - the TS context obtained from TSCreate() 911 . func - monitoring routine 912 . mctx - [optional] user-defined context for private data for the 913 monitor routine (use PETSC_NULL if no context is desired) 914 - monitordestroy - [optional] routine that frees monitor context 915 (may be PETSC_NULL) 916 917 Calling sequence of func: 918 $ int func(TS ts,int steps,double time,Vec x,void *mctx) 919 920 + ts - the TS context 921 . steps - iteration number 922 . time - current time 923 . x - current iterate 924 - mctx - [optional] monitoring context 925 926 Notes: 927 This routine adds an additional monitor to the list of monitors that 928 already has been loaded. 929 930 Level: intermediate 931 932 .keywords: TS, timestep, set, monitor 933 934 .seealso: TSDefaultMonitor(), TSClearMonitor() 935 @*/ 936 int TSSetMonitor(TS ts,int (*monitor)(TS,int,double,Vec,void*),void *mctx,int (*mdestroy)(void*)) 937 { 938 PetscFunctionBegin; 939 PetscValidHeaderSpecific(ts,TS_COOKIE); 940 if (ts->numbermonitors >= MAXTSMONITORS) { 941 SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 942 } 943 ts->monitor[ts->numbermonitors] = monitor; 944 ts->mdestroy[ts->numbermonitors] = mdestroy; 945 ts->monitorcontext[ts->numbermonitors++] = (void*)mctx; 946 PetscFunctionReturn(0); 947 } 948 949 #undef __FUNCT__ 950 #define __FUNCT__ "TSClearMonitor" 951 /*@C 952 TSClearMonitor - Clears all the monitors that have been set on a time-step object. 953 954 Collective on TS 955 956 Input Parameters: 957 . ts - the TS context obtained from TSCreate() 958 959 Notes: 960 There is no way to remove a single, specific monitor. 961 962 Level: intermediate 963 964 .keywords: TS, timestep, set, monitor 965 966 .seealso: TSDefaultMonitor(), TSSetMonitor() 967 @*/ 968 int TSClearMonitor(TS ts) 969 { 970 PetscFunctionBegin; 971 PetscValidHeaderSpecific(ts,TS_COOKIE); 972 ts->numbermonitors = 0; 973 PetscFunctionReturn(0); 974 } 975 976 #undef __FUNCT__ 977 #define __FUNCT__ "TSDefaultMonitor" 978 int TSDefaultMonitor(TS ts,int step,double time,Vec v,void *ctx) 979 { 980 int ierr; 981 982 PetscFunctionBegin; 983 ierr = PetscPrintf(ts->comm,"timestep %d dt %g time %g\n",step,ts->time_step,time);CHKERRQ(ierr); 984 PetscFunctionReturn(0); 985 } 986 987 #undef __FUNCT__ 988 #define __FUNCT__ "TSStep" 989 /*@ 990 TSStep - Steps the requested number of timesteps. 991 992 Collective on TS 993 994 Input Parameter: 995 . ts - the TS context obtained from TSCreate() 996 997 Output Parameters: 998 + steps - number of iterations until termination 999 - time - time until termination 1000 1001 Level: beginner 1002 1003 .keywords: TS, timestep, solve 1004 1005 .seealso: TSCreate(), TSSetUp(), TSDestroy() 1006 @*/ 1007 int TSStep(TS ts,int *steps,double *time) 1008 { 1009 int ierr; 1010 PetscTruth flg; 1011 1012 PetscFunctionBegin; 1013 PetscValidHeaderSpecific(ts,TS_COOKIE); 1014 if (!ts->setupcalled) {ierr = TSSetUp(ts);CHKERRQ(ierr);} 1015 ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr); 1016 ierr = (*ts->step)(ts,steps,time);CHKERRQ(ierr); 1017 ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr); 1018 ierr = PetscOptionsHasName(ts->prefix,"-ts_view",&flg);CHKERRQ(ierr); 1019 if (flg && !PetscPreLoadingOn) {ierr = TSView(ts,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);} 1020 PetscFunctionReturn(0); 1021 } 1022 1023 #undef __FUNCT__ 1024 #define __FUNCT__ "TSMonitor" 1025 /* 1026 Runs the user provided monitor routines, if they exists. 1027 */ 1028 int TSMonitor(TS ts,int step,double time,Vec x) 1029 { 1030 int i,ierr,n = ts->numbermonitors; 1031 1032 PetscFunctionBegin; 1033 for (i=0; i<n; i++) { 1034 ierr = (*ts->monitor[i])(ts,step,time,x,ts->monitorcontext[i]);CHKERRQ(ierr); 1035 } 1036 PetscFunctionReturn(0); 1037 } 1038 1039 /* ------------------------------------------------------------------------*/ 1040 1041 #undef __FUNCT__ 1042 #define __FUNCT__ "TSLGMonitorCreate" 1043 /*@C 1044 TSLGMonitorCreate - Creates a line graph context for use with 1045 TS to monitor convergence of preconditioned residual norms. 1046 1047 Collective on TS 1048 1049 Input Parameters: 1050 + host - the X display to open, or null for the local machine 1051 . label - the title to put in the title bar 1052 . x, y - the screen coordinates of the upper left coordinate of the window 1053 - m, n - the screen width and height in pixels 1054 1055 Output Parameter: 1056 . draw - the drawing context 1057 1058 Options Database Key: 1059 . -ts_xmonitor - automatically sets line graph monitor 1060 1061 Notes: 1062 Use TSLGMonitorDestroy() to destroy this line graph, not PetscDrawLGDestroy(). 1063 1064 Level: intermediate 1065 1066 .keywords: TS, monitor, line graph, residual, seealso 1067 1068 .seealso: TSLGMonitorDestroy(), TSSetMonitor() 1069 1070 @*/ 1071 int TSLGMonitorCreate(char *host,char *label,int x,int y,int m,int n,PetscDrawLG *draw) 1072 { 1073 PetscDraw win; 1074 int ierr; 1075 1076 PetscFunctionBegin; 1077 ierr = PetscDrawCreate(PETSC_COMM_SELF,host,label,x,y,m,n,&win);CHKERRQ(ierr); 1078 ierr = PetscDrawSetType(win,PETSC_DRAW_X);CHKERRQ(ierr); 1079 ierr = PetscDrawLGCreate(win,1,draw);CHKERRQ(ierr); 1080 ierr = PetscDrawLGIndicateDataPoints(*draw);CHKERRQ(ierr); 1081 1082 PetscLogObjectParent(*draw,win); 1083 PetscFunctionReturn(0); 1084 } 1085 1086 #undef __FUNCT__ 1087 #define __FUNCT__ "TSLGMonitor" 1088 int TSLGMonitor(TS ts,int n,double time,Vec v,void *monctx) 1089 { 1090 PetscDrawLG lg = (PetscDrawLG) monctx; 1091 double x,y = time; 1092 int ierr; 1093 1094 PetscFunctionBegin; 1095 if (!monctx) { 1096 MPI_Comm comm; 1097 PetscViewer viewer; 1098 1099 ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr); 1100 viewer = PETSC_VIEWER_DRAW_(comm); 1101 ierr = PetscViewerDrawGetDrawLG(viewer,0,&lg);CHKERRQ(ierr); 1102 } 1103 1104 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 1105 x = (double)n; 1106 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 1107 if (n < 20 || (n % 5)) { 1108 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 1109 } 1110 PetscFunctionReturn(0); 1111 } 1112 1113 #undef __FUNCT__ 1114 #define __FUNCT__ "TSLGMonitorDestroy" 1115 /*@C 1116 TSLGMonitorDestroy - Destroys a line graph context that was created 1117 with TSLGMonitorCreate(). 1118 1119 Collective on PetscDrawLG 1120 1121 Input Parameter: 1122 . draw - the drawing context 1123 1124 Level: intermediate 1125 1126 .keywords: TS, monitor, line graph, destroy 1127 1128 .seealso: TSLGMonitorCreate(), TSSetMonitor(), TSLGMonitor(); 1129 @*/ 1130 int TSLGMonitorDestroy(PetscDrawLG drawlg) 1131 { 1132 PetscDraw draw; 1133 int ierr; 1134 1135 PetscFunctionBegin; 1136 ierr = PetscDrawLGGetDraw(drawlg,&draw);CHKERRQ(ierr); 1137 ierr = PetscDrawDestroy(draw);CHKERRQ(ierr); 1138 ierr = PetscDrawLGDestroy(drawlg);CHKERRQ(ierr); 1139 PetscFunctionReturn(0); 1140 } 1141 1142 #undef __FUNCT__ 1143 #define __FUNCT__ "TSGetTime" 1144 /*@ 1145 TSGetTime - Gets the current time. 1146 1147 Not Collective 1148 1149 Input Parameter: 1150 . ts - the TS context obtained from TSCreate() 1151 1152 Output Parameter: 1153 . t - the current time 1154 1155 Contributed by: Matthew Knepley 1156 1157 Level: beginner 1158 1159 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 1160 1161 .keywords: TS, get, time 1162 @*/ 1163 int TSGetTime(TS ts,double* t) 1164 { 1165 PetscFunctionBegin; 1166 PetscValidHeaderSpecific(ts,TS_COOKIE); 1167 *t = ts->ptime; 1168 PetscFunctionReturn(0); 1169 } 1170 1171 #undef __FUNCT__ 1172 #define __FUNCT__ "TSGetProblemType" 1173 /*@C 1174 TSGetProblemType - Returns the problem type of a TS (timestepper) context. 1175 1176 Not Collective 1177 1178 Input Parameter: 1179 . ts - The TS context obtained from TSCreate() 1180 1181 Output Parameter: 1182 . type - The problem type, TS_LINEAR or TS_NONLINEAR 1183 1184 Level: intermediate 1185 1186 Contributed by: Matthew Knepley 1187 1188 .keywords: ts, get, type 1189 1190 @*/ 1191 int TSGetProblemType(TS ts,TSProblemType *type) 1192 { 1193 PetscFunctionBegin; 1194 PetscValidHeaderSpecific(ts,TS_COOKIE); 1195 *type = ts->problem_type; 1196 PetscFunctionReturn(0); 1197 } 1198 1199 #undef __FUNCT__ 1200 #define __FUNCT__ "TSSetOptionsPrefix" 1201 /*@C 1202 TSSetOptionsPrefix - Sets the prefix used for searching for all 1203 TS options in the database. 1204 1205 Collective on TS 1206 1207 Input Parameter: 1208 + ts - The TS context 1209 - prefix - The prefix to prepend to all option names 1210 1211 Notes: 1212 A hyphen (-) must NOT be given at the beginning of the prefix name. 1213 The first character of all runtime options is AUTOMATICALLY the 1214 hyphen. 1215 1216 Contributed by: Matthew Knepley 1217 1218 Level: advanced 1219 1220 .keywords: TS, set, options, prefix, database 1221 1222 .seealso: TSSetFromOptions() 1223 1224 @*/ 1225 int TSSetOptionsPrefix(TS ts,char *prefix) 1226 { 1227 int ierr; 1228 1229 PetscFunctionBegin; 1230 PetscValidHeaderSpecific(ts,TS_COOKIE); 1231 ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 1232 switch(ts->problem_type) { 1233 case TS_NONLINEAR: 1234 ierr = SNESSetOptionsPrefix(ts->snes,prefix);CHKERRQ(ierr); 1235 break; 1236 case TS_LINEAR: 1237 ierr = SLESSetOptionsPrefix(ts->sles,prefix);CHKERRQ(ierr); 1238 break; 1239 } 1240 PetscFunctionReturn(0); 1241 } 1242 1243 1244 #undef __FUNCT__ 1245 #define __FUNCT__ "TSAppendOptionsPrefix" 1246 /*@C 1247 TSAppendOptionsPrefix - Appends to the prefix used for searching for all 1248 TS options in the database. 1249 1250 Collective on TS 1251 1252 Input Parameter: 1253 + ts - The TS context 1254 - prefix - The prefix to prepend to all option names 1255 1256 Notes: 1257 A hyphen (-) must NOT be given at the beginning of the prefix name. 1258 The first character of all runtime options is AUTOMATICALLY the 1259 hyphen. 1260 1261 Contributed by: Matthew Knepley 1262 1263 Level: advanced 1264 1265 .keywords: TS, append, options, prefix, database 1266 1267 .seealso: TSGetOptionsPrefix() 1268 1269 @*/ 1270 int TSAppendOptionsPrefix(TS ts,char *prefix) 1271 { 1272 int ierr; 1273 1274 PetscFunctionBegin; 1275 PetscValidHeaderSpecific(ts,TS_COOKIE); 1276 ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 1277 switch(ts->problem_type) { 1278 case TS_NONLINEAR: 1279 ierr = SNESAppendOptionsPrefix(ts->snes,prefix);CHKERRQ(ierr); 1280 break; 1281 case TS_LINEAR: 1282 ierr = SLESAppendOptionsPrefix(ts->sles,prefix);CHKERRQ(ierr); 1283 break; 1284 } 1285 PetscFunctionReturn(0); 1286 } 1287 1288 #undef __FUNCT__ 1289 #define __FUNCT__ "TSGetOptionsPrefix" 1290 /*@C 1291 TSGetOptionsPrefix - Sets the prefix used for searching for all 1292 TS options in the database. 1293 1294 Not Collective 1295 1296 Input Parameter: 1297 . ts - The TS context 1298 1299 Output Parameter: 1300 . prefix - A pointer to the prefix string used 1301 1302 Contributed by: Matthew Knepley 1303 1304 Notes: On the fortran side, the user should pass in a string 'prifix' of 1305 sufficient length to hold the prefix. 1306 1307 Level: intermediate 1308 1309 .keywords: TS, get, options, prefix, database 1310 1311 .seealso: TSAppendOptionsPrefix() 1312 @*/ 1313 int TSGetOptionsPrefix(TS ts,char **prefix) 1314 { 1315 int ierr; 1316 1317 PetscFunctionBegin; 1318 PetscValidHeaderSpecific(ts,TS_COOKIE); 1319 ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 1320 PetscFunctionReturn(0); 1321 } 1322 1323 #undef __FUNCT__ 1324 #define __FUNCT__ "TSGetRHSMatrix" 1325 /*@C 1326 TSGetRHSMatrix - Returns the matrix A at the present timestep. 1327 1328 Not Collective, but parallel objects are returned if TS is parallel 1329 1330 Input Parameter: 1331 . ts - The TS context obtained from TSCreate() 1332 1333 Output Parameters: 1334 + A - The matrix A, where U_t = A(t) U 1335 . M - The preconditioner matrix, usually the same as A 1336 - ctx - User-defined context for matrix evaluation routine 1337 1338 Notes: You can pass in PETSC_NULL for any return argument you do not need. 1339 1340 Contributed by: Matthew Knepley 1341 1342 Level: intermediate 1343 1344 .seealso: TSGetTimeStep(), TSGetTime(), TSGetTimeStepNumber(), TSGetRHSJacobian() 1345 1346 .keywords: TS, timestep, get, matrix 1347 1348 @*/ 1349 int TSGetRHSMatrix(TS ts,Mat *A,Mat *M,void **ctx) 1350 { 1351 PetscFunctionBegin; 1352 PetscValidHeaderSpecific(ts,TS_COOKIE); 1353 if (A) *A = ts->A; 1354 if (M) *M = ts->B; 1355 if (ctx) *ctx = ts->jacP; 1356 PetscFunctionReturn(0); 1357 } 1358 1359 #undef __FUNCT__ 1360 #define __FUNCT__ "TSGetRHSJacobian" 1361 /*@C 1362 TSGetRHSJacobian - Returns the Jacobian J at the present timestep. 1363 1364 Not Collective, but parallel objects are returned if TS is parallel 1365 1366 Input Parameter: 1367 . ts - The TS context obtained from TSCreate() 1368 1369 Output Parameters: 1370 + J - The Jacobian J of F, where U_t = F(U,t) 1371 . M - The preconditioner matrix, usually the same as J 1372 - ctx - User-defined context for Jacobian evaluation routine 1373 1374 Notes: You can pass in PETSC_NULL for any return argument you do not need. 1375 1376 Contributed by: Matthew Knepley 1377 1378 Level: intermediate 1379 1380 .seealso: TSGetTimeStep(), TSGetRHSMatrix(), TSGetTime(), TSGetTimeStepNumber() 1381 1382 .keywords: TS, timestep, get, matrix, Jacobian 1383 @*/ 1384 int TSGetRHSJacobian(TS ts,Mat *J,Mat *M,void **ctx) 1385 { 1386 int ierr; 1387 1388 PetscFunctionBegin; 1389 ierr = TSGetRHSMatrix(ts,J,M,ctx);CHKERRQ(ierr); 1390 PetscFunctionReturn(0); 1391 } 1392 1393 /*MC 1394 TSRegisterDynamic - Adds a method to the timestepping solver package. 1395 1396 Synopsis: 1397 1398 TSRegisterDynamic(char *name_solver,char *path,char *name_create,int (*routine_create)(TS)) 1399 1400 Not collective 1401 1402 Input Parameters: 1403 + name_solver - name of a new user-defined solver 1404 . path - path (either absolute or relative) the library containing this solver 1405 . name_create - name of routine to create method context 1406 - routine_create - routine to create method context 1407 1408 Notes: 1409 TSRegisterDynamic() may be called multiple times to add several user-defined solvers. 1410 1411 If dynamic libraries are used, then the fourth input argument (routine_create) 1412 is ignored. 1413 1414 Sample usage: 1415 .vb 1416 TSRegisterDynamic("my_solver",/home/username/my_lib/lib/libO/solaris/mylib.a, 1417 "MySolverCreate",MySolverCreate); 1418 .ve 1419 1420 Then, your solver can be chosen with the procedural interface via 1421 $ TSSetType(ts,"my_solver") 1422 or at runtime via the option 1423 $ -ts_type my_solver 1424 1425 Level: advanced 1426 1427 Environmental variables such as ${PETSC_ARCH}, ${PETSC_DIR}, ${PETSC_LDIR}, ${BOPT}, 1428 and others of the form ${any_environmental_variable} occuring in pathname will be 1429 replaced with appropriate values. 1430 1431 .keywords: TS, register 1432 1433 .seealso: TSRegisterAll(), TSRegisterDestroy() 1434 M*/ 1435 1436 #undef __FUNCT__ 1437 #define __FUNCT__ "TSRegister" 1438 int TSRegister(char *sname,char *path,char *name,int (*function)(TS)) 1439 { 1440 char fullname[256]; 1441 int ierr; 1442 1443 PetscFunctionBegin; 1444 ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 1445 ierr = PetscFListAdd(&TSList,sname,fullname,(int (*)(void*))function);CHKERRQ(ierr); 1446 PetscFunctionReturn(0); 1447 } 1448