1 2 #include <private/tsimpl.h> /*I "petscts.h" I*/ 3 4 /* Logging support */ 5 PetscClassId TS_CLASSID; 6 PetscLogEvent TS_Step, TS_PseudoComputeTimeStep, TS_FunctionEval, TS_JacobianEval; 7 8 #undef __FUNCT__ 9 #define __FUNCT__ "TSSetTypeFromOptions" 10 /* 11 TSSetTypeFromOptions - Sets the type of ts from user options. 12 13 Collective on TS 14 15 Input Parameter: 16 . ts - The ts 17 18 Level: intermediate 19 20 .keywords: TS, set, options, database, type 21 .seealso: TSSetFromOptions(), TSSetType() 22 */ 23 static PetscErrorCode TSSetTypeFromOptions(TS ts) 24 { 25 PetscBool opt; 26 const char *defaultType; 27 char typeName[256]; 28 PetscErrorCode ierr; 29 30 PetscFunctionBegin; 31 if (((PetscObject)ts)->type_name) { 32 defaultType = ((PetscObject)ts)->type_name; 33 } else { 34 defaultType = TSEULER; 35 } 36 37 if (!TSRegisterAllCalled) {ierr = TSRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 38 ierr = PetscOptionsList("-ts_type", "TS method"," TSSetType", TSList, defaultType, typeName, 256, &opt);CHKERRQ(ierr); 39 if (opt) { 40 ierr = TSSetType(ts, typeName);CHKERRQ(ierr); 41 } else { 42 ierr = TSSetType(ts, defaultType);CHKERRQ(ierr); 43 } 44 PetscFunctionReturn(0); 45 } 46 47 #undef __FUNCT__ 48 #define __FUNCT__ "TSSetFromOptions" 49 /*@ 50 TSSetFromOptions - Sets various TS parameters from user options. 51 52 Collective on TS 53 54 Input Parameter: 55 . ts - the TS context obtained from TSCreate() 56 57 Options Database Keys: 58 + -ts_type <type> - TSEULER, TSBEULER, TSSUNDIALS, TSPSEUDO, TSCN, TSRK, TSTHETA, TSGL, TSSSP 59 . -ts_max_steps maxsteps - maximum number of time-steps to take 60 . -ts_max_time time - maximum time to compute to 61 . -ts_dt dt - initial time step 62 . -ts_monitor - print information at each timestep 63 - -ts_monitor_draw - plot information at each timestep 64 65 Level: beginner 66 67 .keywords: TS, timestep, set, options, database 68 69 .seealso: TSGetType() 70 @*/ 71 PetscErrorCode TSSetFromOptions(TS ts) 72 { 73 PetscReal dt; 74 PetscBool opt,flg; 75 PetscErrorCode ierr; 76 PetscViewer monviewer; 77 char monfilename[PETSC_MAX_PATH_LEN]; 78 SNES snes; 79 80 PetscFunctionBegin; 81 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 82 ierr = PetscOptionsBegin(((PetscObject)ts)->comm, ((PetscObject)ts)->prefix, "Time step options", "TS");CHKERRQ(ierr); 83 84 /* Handle generic TS options */ 85 ierr = PetscOptionsInt("-ts_max_steps","Maximum number of time steps","TSSetDuration",ts->max_steps,&ts->max_steps,PETSC_NULL);CHKERRQ(ierr); 86 ierr = PetscOptionsReal("-ts_max_time","Time to run to","TSSetDuration",ts->max_time,&ts->max_time,PETSC_NULL);CHKERRQ(ierr); 87 ierr = PetscOptionsReal("-ts_init_time","Initial time","TSSetInitialTime", ts->ptime, &ts->ptime, PETSC_NULL);CHKERRQ(ierr); 88 ierr = PetscOptionsReal("-ts_dt","Initial time step","TSSetInitialTimeStep",ts->initial_time_step,&dt,&opt);CHKERRQ(ierr); 89 if (opt) {ierr = TSSetInitialTimeStep(ts,ts->ptime,dt);CHKERRQ(ierr);} 90 ierr = PetscOptionsInt("-ts_max_snes_failures","Maximum number of nonlinear solve failures","",ts->max_snes_failures,&ts->max_snes_failures,PETSC_NULL);CHKERRQ(ierr); 91 ierr = PetscOptionsInt("-ts_max_reject","Maximum number of step rejections","",ts->max_reject,&ts->max_reject,PETSC_NULL);CHKERRQ(ierr); 92 ierr = PetscOptionsBool("-ts_error_if_step_failed","Error if no step succeeds","",ts->errorifstepfailed,&ts->errorifstepfailed,PETSC_NULL);CHKERRQ(ierr); 93 94 /* Monitor options */ 95 ierr = PetscOptionsString("-ts_monitor","Monitor timestep size","TSMonitorDefault","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 96 if (flg) { 97 ierr = PetscViewerASCIIOpen(((PetscObject)ts)->comm,monfilename,&monviewer);CHKERRQ(ierr); 98 ierr = TSMonitorSet(ts,TSMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 99 } 100 opt = PETSC_FALSE; 101 ierr = PetscOptionsBool("-ts_monitor_draw","Monitor timestep size graphically","TSMonitorLG",opt,&opt,PETSC_NULL);CHKERRQ(ierr); 102 if (opt) { 103 ierr = TSMonitorSet(ts,TSMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 104 } 105 opt = PETSC_FALSE; 106 ierr = PetscOptionsBool("-ts_monitor_solution","Monitor solution graphically","TSMonitorSolution",opt,&opt,PETSC_NULL);CHKERRQ(ierr); 107 if (opt) { 108 ierr = TSMonitorSet(ts,TSMonitorSolution,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 109 } 110 111 /* Handle TS type options */ 112 ierr = TSSetTypeFromOptions(ts);CHKERRQ(ierr); 113 114 /* Handle specific TS options */ 115 if (ts->ops->setfromoptions) { 116 ierr = (*ts->ops->setfromoptions)(ts);CHKERRQ(ierr); 117 } 118 119 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 120 ierr = PetscObjectProcessOptionsHandlers((PetscObject)ts);CHKERRQ(ierr); 121 ierr = PetscOptionsEnd();CHKERRQ(ierr); 122 123 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 124 /* Handle subobject options */ 125 if (ts->problem_type == TS_LINEAR) {ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);} 126 ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); 127 PetscFunctionReturn(0); 128 } 129 130 #undef __FUNCT__ 131 #define __FUNCT__ "TSViewFromOptions" 132 /*@ 133 TSViewFromOptions - This function visualizes the ts based upon user options. 134 135 Collective on TS 136 137 Input Parameter: 138 . ts - The ts 139 140 Level: intermediate 141 142 .keywords: TS, view, options, database 143 .seealso: TSSetFromOptions(), TSView() 144 @*/ 145 PetscErrorCode TSViewFromOptions(TS ts,const char title[]) 146 { 147 PetscViewer viewer; 148 PetscDraw draw; 149 PetscBool opt = PETSC_FALSE; 150 char fileName[PETSC_MAX_PATH_LEN]; 151 PetscErrorCode ierr; 152 153 PetscFunctionBegin; 154 ierr = PetscOptionsGetString(((PetscObject)ts)->prefix, "-ts_view", fileName, PETSC_MAX_PATH_LEN, &opt);CHKERRQ(ierr); 155 if (opt && !PetscPreLoadingOn) { 156 ierr = PetscViewerASCIIOpen(((PetscObject)ts)->comm,fileName,&viewer);CHKERRQ(ierr); 157 ierr = TSView(ts, viewer);CHKERRQ(ierr); 158 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 159 } 160 opt = PETSC_FALSE; 161 ierr = PetscOptionsGetBool(((PetscObject)ts)->prefix, "-ts_view_draw", &opt,PETSC_NULL);CHKERRQ(ierr); 162 if (opt) { 163 ierr = PetscViewerDrawOpen(((PetscObject)ts)->comm, 0, 0, 0, 0, 300, 300, &viewer);CHKERRQ(ierr); 164 ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr); 165 if (title) { 166 ierr = PetscDrawSetTitle(draw, (char *)title);CHKERRQ(ierr); 167 } else { 168 ierr = PetscObjectName((PetscObject)ts);CHKERRQ(ierr); 169 ierr = PetscDrawSetTitle(draw, ((PetscObject)ts)->name);CHKERRQ(ierr); 170 } 171 ierr = TSView(ts, viewer);CHKERRQ(ierr); 172 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 173 ierr = PetscDrawPause(draw);CHKERRQ(ierr); 174 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 175 } 176 PetscFunctionReturn(0); 177 } 178 179 #undef __FUNCT__ 180 #define __FUNCT__ "TSComputeRHSJacobian" 181 /*@ 182 TSComputeRHSJacobian - Computes the Jacobian matrix that has been 183 set with TSSetRHSJacobian(). 184 185 Collective on TS and Vec 186 187 Input Parameters: 188 + ts - the TS context 189 . t - current timestep 190 - x - input vector 191 192 Output Parameters: 193 + A - Jacobian matrix 194 . B - optional preconditioning matrix 195 - flag - flag indicating matrix structure 196 197 Notes: 198 Most users should not need to explicitly call this routine, as it 199 is used internally within the nonlinear solvers. 200 201 See KSPSetOperators() for important information about setting the 202 flag parameter. 203 204 Level: developer 205 206 .keywords: SNES, compute, Jacobian, matrix 207 208 .seealso: TSSetRHSJacobian(), KSPSetOperators() 209 @*/ 210 PetscErrorCode TSComputeRHSJacobian(TS ts,PetscReal t,Vec X,Mat *A,Mat *B,MatStructure *flg) 211 { 212 PetscErrorCode ierr; 213 214 PetscFunctionBegin; 215 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 216 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 217 PetscCheckSameComm(ts,1,X,3); 218 if (!ts->userops->rhsjacobian && !ts->userops->ijacobian) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()"); 219 if (ts->userops->rhsjacobian) { 220 ierr = PetscLogEventBegin(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr); 221 *flg = DIFFERENT_NONZERO_PATTERN; 222 PetscStackPush("TS user Jacobian function"); 223 ierr = (*ts->userops->rhsjacobian)(ts,t,X,A,B,flg,ts->jacP);CHKERRQ(ierr); 224 PetscStackPop; 225 ierr = PetscLogEventEnd(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr); 226 /* make sure user returned a correct Jacobian and preconditioner */ 227 PetscValidHeaderSpecific(*A,MAT_CLASSID,4); 228 PetscValidHeaderSpecific(*B,MAT_CLASSID,5); 229 } else { 230 ierr = MatZeroEntries(*A);CHKERRQ(ierr); 231 if (*A != *B) {ierr = MatZeroEntries(*B);CHKERRQ(ierr);} 232 *flg = SAME_NONZERO_PATTERN; 233 } 234 PetscFunctionReturn(0); 235 } 236 237 #undef __FUNCT__ 238 #define __FUNCT__ "TSComputeRHSFunction" 239 /*@ 240 TSComputeRHSFunction - Evaluates the right-hand-side function. 241 242 Collective on TS and Vec 243 244 Input Parameters: 245 + ts - the TS context 246 . t - current time 247 - x - state vector 248 249 Output Parameter: 250 . y - right hand side 251 252 Note: 253 Most users should not need to explicitly call this routine, as it 254 is used internally within the nonlinear solvers. 255 256 Level: developer 257 258 .keywords: TS, compute 259 260 .seealso: TSSetRHSFunction(), TSComputeIFunction() 261 @*/ 262 PetscErrorCode TSComputeRHSFunction(TS ts,PetscReal t,Vec x,Vec y) 263 { 264 PetscErrorCode ierr; 265 266 PetscFunctionBegin; 267 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 268 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 269 PetscValidHeaderSpecific(y,VEC_CLASSID,4); 270 if (!ts->userops->rhsfunction && !ts->userops->ifunction) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 271 272 ierr = PetscLogEventBegin(TS_FunctionEval,ts,x,y,0);CHKERRQ(ierr); 273 if (ts->userops->rhsfunction) { 274 PetscStackPush("TS user right-hand-side function"); 275 ierr = (*ts->userops->rhsfunction)(ts,t,x,y,ts->funP);CHKERRQ(ierr); 276 PetscStackPop; 277 } else { 278 ierr = VecZeroEntries(y);CHKERRQ(ierr); 279 } 280 281 ierr = PetscLogEventEnd(TS_FunctionEval,ts,x,y,0);CHKERRQ(ierr); 282 PetscFunctionReturn(0); 283 } 284 285 #undef __FUNCT__ 286 #define __FUNCT__ "TSGetRHSVec_Private" 287 static PetscErrorCode TSGetRHSVec_Private(TS ts,Vec *Frhs) 288 { 289 PetscErrorCode ierr; 290 291 PetscFunctionBegin; 292 if (!ts->Frhs) { 293 ierr = VecDuplicate(ts->vec_sol,&ts->Frhs);CHKERRQ(ierr); 294 } 295 *Frhs = ts->Frhs; 296 PetscFunctionReturn(0); 297 } 298 299 #undef __FUNCT__ 300 #define __FUNCT__ "TSGetRHSMats_Private" 301 static PetscErrorCode TSGetRHSMats_Private(TS ts,Mat *Arhs,Mat *Brhs) 302 { 303 PetscErrorCode ierr; 304 Mat A,B; 305 306 PetscFunctionBegin; 307 ierr = TSGetIJacobian(ts,&A,&B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 308 if (Arhs) { 309 if (!ts->Arhs) { 310 ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&ts->Arhs);CHKERRQ(ierr); 311 } 312 *Arhs = ts->Arhs; 313 } 314 if (Brhs) { 315 if (!ts->Brhs) { 316 ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&ts->Brhs);CHKERRQ(ierr); 317 } 318 *Brhs = ts->Brhs; 319 } 320 PetscFunctionReturn(0); 321 } 322 323 #undef __FUNCT__ 324 #define __FUNCT__ "TSComputeIFunction" 325 /*@ 326 TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,X,Xdot)=0 327 328 Collective on TS and Vec 329 330 Input Parameters: 331 + ts - the TS context 332 . t - current time 333 . X - state vector 334 . Xdot - time derivative of state vector 335 - imex - flag indicates if the method is IMEX so that the RHSFunction should be kept separate 336 337 Output Parameter: 338 . Y - right hand side 339 340 Note: 341 Most users should not need to explicitly call this routine, as it 342 is used internally within the nonlinear solvers. 343 344 If the user did did not write their equations in implicit form, this 345 function recasts them in implicit form. 346 347 Level: developer 348 349 .keywords: TS, compute 350 351 .seealso: TSSetIFunction(), TSComputeRHSFunction() 352 @*/ 353 PetscErrorCode TSComputeIFunction(TS ts,PetscReal t,Vec X,Vec Xdot,Vec Y,PetscBool imex) 354 { 355 PetscErrorCode ierr; 356 357 PetscFunctionBegin; 358 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 359 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 360 PetscValidHeaderSpecific(Xdot,VEC_CLASSID,4); 361 PetscValidHeaderSpecific(Y,VEC_CLASSID,5); 362 363 ierr = PetscLogEventBegin(TS_FunctionEval,ts,X,Xdot,Y);CHKERRQ(ierr); 364 if (ts->userops->ifunction) { 365 PetscStackPush("TS user implicit function"); 366 ierr = (*ts->userops->ifunction)(ts,t,X,Xdot,Y,ts->funP);CHKERRQ(ierr); 367 PetscStackPop; 368 } 369 if (imex) { 370 if (!ts->userops->ifunction) {ierr = VecCopy(Xdot,Y);CHKERRQ(ierr);} 371 } else { 372 if (!ts->userops->ifunction) { 373 ierr = TSComputeRHSFunction(ts,t,X,Y);CHKERRQ(ierr); 374 ierr = VecAYPX(Y,-1,Xdot);CHKERRQ(ierr); 375 } else { 376 Vec Frhs; 377 ierr = TSGetRHSVec_Private(ts,&Frhs);CHKERRQ(ierr); 378 ierr = TSComputeRHSFunction(ts,t,X,Frhs);CHKERRQ(ierr); 379 ierr = VecAXPY(Y,-1,Frhs);CHKERRQ(ierr); 380 } 381 } 382 ierr = PetscLogEventEnd(TS_FunctionEval,ts,X,Xdot,Y);CHKERRQ(ierr); 383 PetscFunctionReturn(0); 384 } 385 386 #undef __FUNCT__ 387 #define __FUNCT__ "TSComputeIJacobian" 388 /*@ 389 TSComputeIJacobian - Evaluates the Jacobian of the DAE 390 391 Collective on TS and Vec 392 393 Input 394 Input Parameters: 395 + ts - the TS context 396 . t - current timestep 397 . X - state vector 398 . Xdot - time derivative of state vector 399 . shift - shift to apply, see note below 400 - imex - flag indicates if the method is IMEX so that the RHSJacobian should be kept separate 401 402 Output Parameters: 403 + A - Jacobian matrix 404 . B - optional preconditioning matrix 405 - flag - flag indicating matrix structure 406 407 Notes: 408 If F(t,X,Xdot)=0 is the DAE, the required Jacobian is 409 410 dF/dX + shift*dF/dXdot 411 412 Most users should not need to explicitly call this routine, as it 413 is used internally within the nonlinear solvers. 414 415 Level: developer 416 417 .keywords: TS, compute, Jacobian, matrix 418 419 .seealso: TSSetIJacobian() 420 @*/ 421 PetscErrorCode TSComputeIJacobian(TS ts,PetscReal t,Vec X,Vec Xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,PetscBool imex) 422 { 423 PetscErrorCode ierr; 424 425 PetscFunctionBegin; 426 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 427 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 428 PetscValidHeaderSpecific(Xdot,VEC_CLASSID,4); 429 PetscValidPointer(A,6); 430 PetscValidHeaderSpecific(*A,MAT_CLASSID,6); 431 PetscValidPointer(B,7); 432 PetscValidHeaderSpecific(*B,MAT_CLASSID,7); 433 PetscValidPointer(flg,8); 434 if (!ts->userops->rhsjacobian && !ts->userops->ijacobian) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()"); 435 436 *flg = SAME_NONZERO_PATTERN; /* In case we're solving a linear problem in which case it wouldn't get initialized below. */ 437 ierr = PetscLogEventBegin(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr); 438 if (ts->userops->ijacobian) { 439 PetscStackPush("TS user implicit Jacobian"); 440 ierr = (*ts->userops->ijacobian)(ts,t,X,Xdot,shift,A,B,flg,ts->jacP);CHKERRQ(ierr); 441 PetscStackPop; 442 /* make sure user returned a correct Jacobian and preconditioner */ 443 PetscValidHeaderSpecific(*A,MAT_CLASSID,4); 444 PetscValidHeaderSpecific(*B,MAT_CLASSID,5); 445 } 446 if (imex) { 447 if (!ts->userops->ijacobian) { /* system was written as Xdot = F(t,X) */ 448 ierr = MatZeroEntries(*A);CHKERRQ(ierr); 449 ierr = MatShift(*A,1.0);CHKERRQ(ierr); 450 if (*A != *B) { 451 ierr = MatZeroEntries(*B);CHKERRQ(ierr); 452 ierr = MatShift(*B,shift);CHKERRQ(ierr); 453 } 454 *flg = SAME_PRECONDITIONER; 455 } 456 } else { 457 if (!ts->userops->ijacobian) { 458 ierr = TSComputeRHSJacobian(ts,t,X,A,B,flg);CHKERRQ(ierr); 459 ierr = MatScale(*A,-1);CHKERRQ(ierr); 460 ierr = MatShift(*A,shift);CHKERRQ(ierr); 461 if (*A != *B) { 462 ierr = MatScale(*B,-1);CHKERRQ(ierr); 463 ierr = MatShift(*B,shift);CHKERRQ(ierr); 464 } 465 } else if (ts->userops->rhsjacobian) { 466 Mat Arhs,Brhs; 467 MatStructure axpy,flg2 = DIFFERENT_NONZERO_PATTERN; 468 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 469 ierr = TSComputeRHSJacobian(ts,t,X,&Arhs,&Brhs,&flg2);CHKERRQ(ierr); 470 axpy = (*flg == flg2) ? SAME_NONZERO_PATTERN : DIFFERENT_NONZERO_PATTERN; 471 ierr = MatAXPY(*A,-1,Arhs,axpy);CHKERRQ(ierr); 472 if (*A != *B) { 473 ierr = MatAXPY(*B,-1,Brhs,axpy);CHKERRQ(ierr); 474 } 475 *flg = PetscMin(*flg,flg2); 476 } 477 } 478 ierr = PetscLogEventEnd(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr); 479 PetscFunctionReturn(0); 480 } 481 482 #undef __FUNCT__ 483 #define __FUNCT__ "TSSetRHSFunction" 484 /*@C 485 TSSetRHSFunction - Sets the routine for evaluating the function, 486 F(t,u), where U_t = F(t,u). 487 488 Logically Collective on TS 489 490 Input Parameters: 491 + ts - the TS context obtained from TSCreate() 492 . r - vector to put the computed right hand side (or PETSC_NULL to have it created) 493 . f - routine for evaluating the right-hand-side function 494 - ctx - [optional] user-defined context for private data for the 495 function evaluation routine (may be PETSC_NULL) 496 497 Calling sequence of func: 498 $ func (TS ts,PetscReal t,Vec u,Vec F,void *ctx); 499 500 + t - current timestep 501 . u - input vector 502 . F - function vector 503 - ctx - [optional] user-defined function context 504 505 Important: 506 The user MUST call either this routine or TSSetMatrices(). 507 508 Level: beginner 509 510 .keywords: TS, timestep, set, right-hand-side, function 511 512 .seealso: TSSetMatrices() 513 @*/ 514 PetscErrorCode TSSetRHSFunction(TS ts,Vec r,PetscErrorCode (*f)(TS,PetscReal,Vec,Vec,void*),void *ctx) 515 { 516 PetscErrorCode ierr; 517 SNES snes; 518 519 PetscFunctionBegin; 520 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 521 if (r) PetscValidHeaderSpecific(r,VEC_CLASSID,2); 522 if (f) ts->userops->rhsfunction = f; 523 if (ctx) ts->funP = ctx; 524 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 525 ierr = SNESSetFunction(snes,r,SNESTSFormFunction,ts);CHKERRQ(ierr); 526 PetscFunctionReturn(0); 527 } 528 529 #undef __FUNCT__ 530 #define __FUNCT__ "TSSetRHSJacobian" 531 /*@C 532 TSSetRHSJacobian - Sets the function to compute the Jacobian of F, 533 where U_t = F(U,t), as well as the location to store the matrix. 534 Use TSSetMatrices() for linear problems. 535 536 Logically Collective on TS 537 538 Input Parameters: 539 + ts - the TS context obtained from TSCreate() 540 . A - Jacobian matrix 541 . B - preconditioner matrix (usually same as A) 542 . f - the Jacobian evaluation routine 543 - ctx - [optional] user-defined context for private data for the 544 Jacobian evaluation routine (may be PETSC_NULL) 545 546 Calling sequence of func: 547 $ func (TS ts,PetscReal t,Vec u,Mat *A,Mat *B,MatStructure *flag,void *ctx); 548 549 + t - current timestep 550 . u - input vector 551 . A - matrix A, where U_t = A(t)u 552 . B - preconditioner matrix, usually the same as A 553 . flag - flag indicating information about the preconditioner matrix 554 structure (same as flag in KSPSetOperators()) 555 - ctx - [optional] user-defined context for matrix evaluation routine 556 557 Notes: 558 See KSPSetOperators() for important information about setting the flag 559 output parameter in the routine func(). Be sure to read this information! 560 561 The routine func() takes Mat * as the matrix arguments rather than Mat. 562 This allows the matrix evaluation routine to replace A and/or B with a 563 completely new matrix structure (not just different matrix elements) 564 when appropriate, for instance, if the nonzero structure is changing 565 throughout the global iterations. 566 567 Level: beginner 568 569 .keywords: TS, timestep, set, right-hand-side, Jacobian 570 571 .seealso: TSDefaultComputeJacobianColor(), 572 SNESDefaultComputeJacobianColor(), TSSetRHSFunction(), TSSetMatrices() 573 574 @*/ 575 PetscErrorCode TSSetRHSJacobian(TS ts,Mat A,Mat B,TSRHSJacobian f,void *ctx) 576 { 577 PetscErrorCode ierr; 578 SNES snes; 579 580 PetscFunctionBegin; 581 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 582 if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 583 if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 584 if (A) PetscCheckSameComm(ts,1,A,2); 585 if (B) PetscCheckSameComm(ts,1,B,3); 586 587 if (f) ts->userops->rhsjacobian = f; 588 if (ctx) ts->jacP = ctx; 589 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 590 ierr = SNESSetJacobian(snes,A,B,SNESTSFormJacobian,ts);CHKERRQ(ierr); 591 PetscFunctionReturn(0); 592 } 593 594 595 #undef __FUNCT__ 596 #define __FUNCT__ "TSSetIFunction" 597 /*@C 598 TSSetIFunction - Set the function to compute F(t,U,U_t) where F = 0 is the DAE to be solved. 599 600 Logically Collective on TS 601 602 Input Parameters: 603 + ts - the TS context obtained from TSCreate() 604 . r - vector to hold the residual (or PETSC_NULL to have it created internally) 605 . f - the function evaluation routine 606 - ctx - user-defined context for private data for the function evaluation routine (may be PETSC_NULL) 607 608 Calling sequence of f: 609 $ f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx); 610 611 + t - time at step/stage being solved 612 . u - state vector 613 . u_t - time derivative of state vector 614 . F - function vector 615 - ctx - [optional] user-defined context for matrix evaluation routine 616 617 Important: 618 The user MUST call either this routine, TSSetRHSFunction(), or TSSetMatrices(). This routine must be used when not solving an ODE. 619 620 Level: beginner 621 622 .keywords: TS, timestep, set, DAE, Jacobian 623 624 .seealso: TSSetMatrices(), TSSetRHSFunction(), TSSetIJacobian() 625 @*/ 626 PetscErrorCode TSSetIFunction(TS ts,Vec res,TSIFunction f,void *ctx) 627 { 628 PetscErrorCode ierr; 629 SNES snes; 630 631 PetscFunctionBegin; 632 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 633 if (!ts->userops->rhsfunction && !ts->userops->ifunction) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 634 if (res) PetscValidHeaderSpecific(res,VEC_CLASSID,2); 635 if (f) ts->userops->ifunction = f; 636 if (ctx) ts->funP = ctx; 637 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 638 ierr = SNESSetFunction(snes,res,SNESTSFormFunction,ts);CHKERRQ(ierr); 639 PetscFunctionReturn(0); 640 } 641 642 #undef __FUNCT__ 643 #define __FUNCT__ "TSGetIFunction" 644 /*@C 645 TSGetIFunction - Returns the vector where the implicit residual is stored and the function/contex to compute it. 646 647 Not Collective 648 649 Input Parameter: 650 . ts - the TS context 651 652 Output Parameter: 653 + r - vector to hold residual (or PETSC_NULL) 654 . func - the function to compute residual (or PETSC_NULL) 655 - ctx - the function context (or PETSC_NULL) 656 657 Level: advanced 658 659 .keywords: TS, nonlinear, get, function 660 661 .seealso: TSSetIFunction(), SNESGetFunction() 662 @*/ 663 PetscErrorCode TSGetIFunction(TS ts,Vec *r,TSIFunction *func,void **ctx) 664 { 665 PetscErrorCode ierr; 666 SNES snes; 667 668 PetscFunctionBegin; 669 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 670 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 671 ierr = SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 672 if (func) *func = ts->userops->ifunction; 673 if (ctx) *ctx = ts->funP; 674 PetscFunctionReturn(0); 675 } 676 677 #undef __FUNCT__ 678 #define __FUNCT__ "TSGetRHSFunction" 679 /*@C 680 TSGetRHSFunction - Returns the vector where the right hand side is stored and the function/context to compute it. 681 682 Not Collective 683 684 Input Parameter: 685 . ts - the TS context 686 687 Output Parameter: 688 + r - vector to hold computed right hand side (or PETSC_NULL) 689 . func - the function to compute right hand side (or PETSC_NULL) 690 - ctx - the function context (or PETSC_NULL) 691 692 Level: advanced 693 694 .keywords: TS, nonlinear, get, function 695 696 .seealso: TSSetRhsfunction(), SNESGetFunction() 697 @*/ 698 PetscErrorCode TSGetRHSFunction(TS ts,Vec *r,TSRHSFunction *func,void **ctx) 699 { 700 PetscErrorCode ierr; 701 SNES snes; 702 703 PetscFunctionBegin; 704 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 705 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 706 ierr = SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 707 if (func) *func = ts->userops->rhsfunction; 708 if (ctx) *ctx = ts->funP; 709 PetscFunctionReturn(0); 710 } 711 712 #undef __FUNCT__ 713 #define __FUNCT__ "TSSetIJacobian" 714 /*@C 715 TSSetIJacobian - Set the function to compute the matrix dF/dU + a*dF/dU_t where F(t,U,U_t) is the function 716 you provided with TSSetIFunction(). 717 718 Logically Collective on TS 719 720 Input Parameters: 721 + ts - the TS context obtained from TSCreate() 722 . A - Jacobian matrix 723 . B - preconditioning matrix for A (may be same as A) 724 . f - the Jacobian evaluation routine 725 - ctx - user-defined context for private data for the Jacobian evaluation routine (may be PETSC_NULL) 726 727 Calling sequence of f: 728 $ f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat *A,Mat *B,MatStructure *flag,void *ctx); 729 730 + t - time at step/stage being solved 731 . U - state vector 732 . U_t - time derivative of state vector 733 . a - shift 734 . A - Jacobian of G(U) = F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t 735 . B - preconditioning matrix for A, may be same as A 736 . flag - flag indicating information about the preconditioner matrix 737 structure (same as flag in KSPSetOperators()) 738 - ctx - [optional] user-defined context for matrix evaluation routine 739 740 Notes: 741 The matrices A and B are exactly the matrices that are used by SNES for the nonlinear solve. 742 743 The matrix dF/dU + a*dF/dU_t you provide turns out to be 744 the Jacobian of G(U) = F(t,U,W+a*U) where F(t,U,U_t) = 0 is the DAE to be solved. 745 The time integrator internally approximates U_t by W+a*U where the positive "shift" 746 a and vector W depend on the integration method, step size, and past states. For example with 747 the backward Euler method a = 1/dt and W = -a*U(previous timestep) so 748 W + a*U = a*(U - U(previous timestep)) = (U - U(previous timestep))/dt 749 750 Level: beginner 751 752 .keywords: TS, timestep, DAE, Jacobian 753 754 .seealso: TSSetIFunction(), TSSetRHSJacobian() 755 756 @*/ 757 PetscErrorCode TSSetIJacobian(TS ts,Mat A,Mat B,TSIJacobian f,void *ctx) 758 { 759 PetscErrorCode ierr; 760 SNES snes; 761 762 PetscFunctionBegin; 763 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 764 if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 765 if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 766 if (A) PetscCheckSameComm(ts,1,A,2); 767 if (B) PetscCheckSameComm(ts,1,B,3); 768 if (f) ts->userops->ijacobian = f; 769 if (ctx) ts->jacP = ctx; 770 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 771 ierr = SNESSetJacobian(snes,A,B,SNESTSFormJacobian,ts);CHKERRQ(ierr); 772 PetscFunctionReturn(0); 773 } 774 775 #undef __FUNCT__ 776 #define __FUNCT__ "TSView" 777 /*@C 778 TSView - Prints the TS data structure. 779 780 Collective on TS 781 782 Input Parameters: 783 + ts - the TS context obtained from TSCreate() 784 - viewer - visualization context 785 786 Options Database Key: 787 . -ts_view - calls TSView() at end of TSStep() 788 789 Notes: 790 The available visualization contexts include 791 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 792 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 793 output where only the first processor opens 794 the file. All other processors send their 795 data to the first processor to print. 796 797 The user can open an alternative visualization context with 798 PetscViewerASCIIOpen() - output to a specified file. 799 800 Level: beginner 801 802 .keywords: TS, timestep, view 803 804 .seealso: PetscViewerASCIIOpen() 805 @*/ 806 PetscErrorCode TSView(TS ts,PetscViewer viewer) 807 { 808 PetscErrorCode ierr; 809 const TSType type; 810 PetscBool iascii,isstring,isundials; 811 812 PetscFunctionBegin; 813 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 814 if (!viewer) { 815 ierr = PetscViewerASCIIGetStdout(((PetscObject)ts)->comm,&viewer);CHKERRQ(ierr); 816 } 817 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 818 PetscCheckSameComm(ts,1,viewer,2); 819 820 ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 821 ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 822 if (iascii) { 823 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ts,viewer,"TS Object");CHKERRQ(ierr); 824 if (ts->ops->view) { 825 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 826 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 827 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 828 } 829 ierr = PetscViewerASCIIPrintf(viewer," maximum steps=%D\n",ts->max_steps);CHKERRQ(ierr); 830 ierr = PetscViewerASCIIPrintf(viewer," maximum time=%G\n",ts->max_time);CHKERRQ(ierr); 831 if (ts->problem_type == TS_NONLINEAR) { 832 ierr = PetscViewerASCIIPrintf(viewer," total number of nonlinear solver iterations=%D\n",ts->nonlinear_its);CHKERRQ(ierr); 833 ierr = PetscViewerASCIIPrintf(viewer," total number of nonlinear solve failures=%D\n",ts->max_snes_failures);CHKERRQ(ierr); 834 } 835 ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",ts->linear_its);CHKERRQ(ierr); 836 ierr = PetscViewerASCIIPrintf(viewer," total number of rejected steps=%D\n",ts->reject);CHKERRQ(ierr); 837 } else if (isstring) { 838 ierr = TSGetType(ts,&type);CHKERRQ(ierr); 839 ierr = PetscViewerStringSPrintf(viewer," %-7.7s",type);CHKERRQ(ierr); 840 } 841 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 842 ierr = PetscTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials);CHKERRQ(ierr); 843 if (!isundials && ts->snes) {ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr);} 844 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 845 PetscFunctionReturn(0); 846 } 847 848 849 #undef __FUNCT__ 850 #define __FUNCT__ "TSSetApplicationContext" 851 /*@ 852 TSSetApplicationContext - Sets an optional user-defined context for 853 the timesteppers. 854 855 Logically Collective on TS 856 857 Input Parameters: 858 + ts - the TS context obtained from TSCreate() 859 - usrP - optional user context 860 861 Level: intermediate 862 863 .keywords: TS, timestep, set, application, context 864 865 .seealso: TSGetApplicationContext() 866 @*/ 867 PetscErrorCode TSSetApplicationContext(TS ts,void *usrP) 868 { 869 PetscFunctionBegin; 870 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 871 ts->user = usrP; 872 PetscFunctionReturn(0); 873 } 874 875 #undef __FUNCT__ 876 #define __FUNCT__ "TSGetApplicationContext" 877 /*@ 878 TSGetApplicationContext - Gets the user-defined context for the 879 timestepper. 880 881 Not Collective 882 883 Input Parameter: 884 . ts - the TS context obtained from TSCreate() 885 886 Output Parameter: 887 . usrP - user context 888 889 Level: intermediate 890 891 .keywords: TS, timestep, get, application, context 892 893 .seealso: TSSetApplicationContext() 894 @*/ 895 PetscErrorCode TSGetApplicationContext(TS ts,void *usrP) 896 { 897 PetscFunctionBegin; 898 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 899 *(void**)usrP = ts->user; 900 PetscFunctionReturn(0); 901 } 902 903 #undef __FUNCT__ 904 #define __FUNCT__ "TSGetTimeStepNumber" 905 /*@ 906 TSGetTimeStepNumber - Gets the current number of timesteps. 907 908 Not Collective 909 910 Input Parameter: 911 . ts - the TS context obtained from TSCreate() 912 913 Output Parameter: 914 . iter - number steps so far 915 916 Level: intermediate 917 918 .keywords: TS, timestep, get, iteration, number 919 @*/ 920 PetscErrorCode TSGetTimeStepNumber(TS ts,PetscInt* iter) 921 { 922 PetscFunctionBegin; 923 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 924 PetscValidIntPointer(iter,2); 925 *iter = ts->steps; 926 PetscFunctionReturn(0); 927 } 928 929 #undef __FUNCT__ 930 #define __FUNCT__ "TSSetInitialTimeStep" 931 /*@ 932 TSSetInitialTimeStep - Sets the initial timestep to be used, 933 as well as the initial time. 934 935 Logically Collective on TS 936 937 Input Parameters: 938 + ts - the TS context obtained from TSCreate() 939 . initial_time - the initial time 940 - time_step - the size of the timestep 941 942 Level: intermediate 943 944 .seealso: TSSetTimeStep(), TSGetTimeStep() 945 946 .keywords: TS, set, initial, timestep 947 @*/ 948 PetscErrorCode TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step) 949 { 950 PetscErrorCode ierr; 951 952 PetscFunctionBegin; 953 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 954 ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr); 955 ts->initial_time_step = time_step; 956 ts->ptime = initial_time; 957 PetscFunctionReturn(0); 958 } 959 960 #undef __FUNCT__ 961 #define __FUNCT__ "TSSetTimeStep" 962 /*@ 963 TSSetTimeStep - Allows one to reset the timestep at any time, 964 useful for simple pseudo-timestepping codes. 965 966 Logically Collective on TS 967 968 Input Parameters: 969 + ts - the TS context obtained from TSCreate() 970 - time_step - the size of the timestep 971 972 Level: intermediate 973 974 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 975 976 .keywords: TS, set, timestep 977 @*/ 978 PetscErrorCode TSSetTimeStep(TS ts,PetscReal time_step) 979 { 980 PetscFunctionBegin; 981 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 982 PetscValidLogicalCollectiveReal(ts,time_step,2); 983 ts->time_step = time_step; 984 ts->next_time_step = time_step; 985 PetscFunctionReturn(0); 986 } 987 988 #undef __FUNCT__ 989 #define __FUNCT__ "TSGetTimeStep" 990 /*@ 991 TSGetTimeStep - Gets the current timestep size. 992 993 Not Collective 994 995 Input Parameter: 996 . ts - the TS context obtained from TSCreate() 997 998 Output Parameter: 999 . dt - the current timestep size 1000 1001 Level: intermediate 1002 1003 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 1004 1005 .keywords: TS, get, timestep 1006 @*/ 1007 PetscErrorCode TSGetTimeStep(TS ts,PetscReal* dt) 1008 { 1009 PetscFunctionBegin; 1010 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1011 PetscValidDoublePointer(dt,2); 1012 *dt = ts->time_step; 1013 PetscFunctionReturn(0); 1014 } 1015 1016 #undef __FUNCT__ 1017 #define __FUNCT__ "TSGetSolution" 1018 /*@ 1019 TSGetSolution - Returns the solution at the present timestep. It 1020 is valid to call this routine inside the function that you are evaluating 1021 in order to move to the new timestep. This vector not changed until 1022 the solution at the next timestep has been calculated. 1023 1024 Not Collective, but Vec returned is parallel if TS is parallel 1025 1026 Input Parameter: 1027 . ts - the TS context obtained from TSCreate() 1028 1029 Output Parameter: 1030 . v - the vector containing the solution 1031 1032 Level: intermediate 1033 1034 .seealso: TSGetTimeStep() 1035 1036 .keywords: TS, timestep, get, solution 1037 @*/ 1038 PetscErrorCode TSGetSolution(TS ts,Vec *v) 1039 { 1040 PetscFunctionBegin; 1041 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1042 PetscValidPointer(v,2); 1043 *v = ts->vec_sol; 1044 PetscFunctionReturn(0); 1045 } 1046 1047 /* ----- Routines to initialize and destroy a timestepper ---- */ 1048 #undef __FUNCT__ 1049 #define __FUNCT__ "TSSetProblemType" 1050 /*@ 1051 TSSetProblemType - Sets the type of problem to be solved. 1052 1053 Not collective 1054 1055 Input Parameters: 1056 + ts - The TS 1057 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 1058 .vb 1059 U_t = A U 1060 U_t = A(t) U 1061 U_t = F(t,U) 1062 .ve 1063 1064 Level: beginner 1065 1066 .keywords: TS, problem type 1067 .seealso: TSSetUp(), TSProblemType, TS 1068 @*/ 1069 PetscErrorCode TSSetProblemType(TS ts, TSProblemType type) 1070 { 1071 PetscErrorCode ierr; 1072 1073 PetscFunctionBegin; 1074 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1075 ts->problem_type = type; 1076 if (type == TS_LINEAR) { 1077 SNES snes; 1078 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1079 ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr); 1080 } 1081 PetscFunctionReturn(0); 1082 } 1083 1084 #undef __FUNCT__ 1085 #define __FUNCT__ "TSGetProblemType" 1086 /*@C 1087 TSGetProblemType - Gets the type of problem to be solved. 1088 1089 Not collective 1090 1091 Input Parameter: 1092 . ts - The TS 1093 1094 Output Parameter: 1095 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 1096 .vb 1097 M U_t = A U 1098 M(t) U_t = A(t) U 1099 U_t = F(t,U) 1100 .ve 1101 1102 Level: beginner 1103 1104 .keywords: TS, problem type 1105 .seealso: TSSetUp(), TSProblemType, TS 1106 @*/ 1107 PetscErrorCode TSGetProblemType(TS ts, TSProblemType *type) 1108 { 1109 PetscFunctionBegin; 1110 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1111 PetscValidIntPointer(type,2); 1112 *type = ts->problem_type; 1113 PetscFunctionReturn(0); 1114 } 1115 1116 #undef __FUNCT__ 1117 #define __FUNCT__ "TSSetUp" 1118 /*@ 1119 TSSetUp - Sets up the internal data structures for the later use 1120 of a timestepper. 1121 1122 Collective on TS 1123 1124 Input Parameter: 1125 . ts - the TS context obtained from TSCreate() 1126 1127 Notes: 1128 For basic use of the TS solvers the user need not explicitly call 1129 TSSetUp(), since these actions will automatically occur during 1130 the call to TSStep(). However, if one wishes to control this 1131 phase separately, TSSetUp() should be called after TSCreate() 1132 and optional routines of the form TSSetXXX(), but before TSStep(). 1133 1134 Level: advanced 1135 1136 .keywords: TS, timestep, setup 1137 1138 .seealso: TSCreate(), TSStep(), TSDestroy() 1139 @*/ 1140 PetscErrorCode TSSetUp(TS ts) 1141 { 1142 PetscErrorCode ierr; 1143 1144 PetscFunctionBegin; 1145 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1146 if (ts->setupcalled) PetscFunctionReturn(0); 1147 1148 if (!((PetscObject)ts)->type_name) { 1149 ierr = TSSetType(ts,TSEULER);CHKERRQ(ierr); 1150 } 1151 1152 if (!ts->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first"); 1153 1154 if (ts->ops->setup) { 1155 ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr); 1156 } 1157 1158 ts->setupcalled = PETSC_TRUE; 1159 PetscFunctionReturn(0); 1160 } 1161 1162 #undef __FUNCT__ 1163 #define __FUNCT__ "TSReset" 1164 /*@ 1165 TSReset - Resets a TS context and removes any allocated Vecs and Mats. 1166 1167 Collective on TS 1168 1169 Input Parameter: 1170 . ts - the TS context obtained from TSCreate() 1171 1172 Level: beginner 1173 1174 .keywords: TS, timestep, reset 1175 1176 .seealso: TSCreate(), TSSetup(), TSDestroy() 1177 @*/ 1178 PetscErrorCode TSReset(TS ts) 1179 { 1180 PetscErrorCode ierr; 1181 1182 PetscFunctionBegin; 1183 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1184 if (ts->ops->reset) { 1185 ierr = (*ts->ops->reset)(ts);CHKERRQ(ierr); 1186 } 1187 if (ts->snes) {ierr = SNESReset(ts->snes);CHKERRQ(ierr);} 1188 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 1189 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 1190 ierr = VecDestroy(&ts->Frhs);CHKERRQ(ierr); 1191 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 1192 if (ts->work) {ierr = VecDestroyVecs(ts->nwork,&ts->work);CHKERRQ(ierr);} 1193 ts->setupcalled = PETSC_FALSE; 1194 PetscFunctionReturn(0); 1195 } 1196 1197 #undef __FUNCT__ 1198 #define __FUNCT__ "TSDestroy" 1199 /*@ 1200 TSDestroy - Destroys the timestepper context that was created 1201 with TSCreate(). 1202 1203 Collective on TS 1204 1205 Input Parameter: 1206 . ts - the TS context obtained from TSCreate() 1207 1208 Level: beginner 1209 1210 .keywords: TS, timestepper, destroy 1211 1212 .seealso: TSCreate(), TSSetUp(), TSSolve() 1213 @*/ 1214 PetscErrorCode TSDestroy(TS *ts) 1215 { 1216 PetscErrorCode ierr; 1217 1218 PetscFunctionBegin; 1219 if (!*ts) PetscFunctionReturn(0); 1220 PetscValidHeaderSpecific((*ts),TS_CLASSID,1); 1221 if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; PetscFunctionReturn(0);} 1222 1223 ierr = TSReset((*ts));CHKERRQ(ierr); 1224 1225 /* if memory was published with AMS then destroy it */ 1226 ierr = PetscObjectDepublish((*ts));CHKERRQ(ierr); 1227 if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);} 1228 1229 ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr); 1230 ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr); 1231 ierr = TSMonitorCancel((*ts));CHKERRQ(ierr); 1232 1233 ierr = PetscFree((*ts)->userops); 1234 1235 ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr); 1236 PetscFunctionReturn(0); 1237 } 1238 1239 #undef __FUNCT__ 1240 #define __FUNCT__ "TSGetSNES" 1241 /*@ 1242 TSGetSNES - Returns the SNES (nonlinear solver) associated with 1243 a TS (timestepper) context. Valid only for nonlinear problems. 1244 1245 Not Collective, but SNES is parallel if TS is parallel 1246 1247 Input Parameter: 1248 . ts - the TS context obtained from TSCreate() 1249 1250 Output Parameter: 1251 . snes - the nonlinear solver context 1252 1253 Notes: 1254 The user can then directly manipulate the SNES context to set various 1255 options, etc. Likewise, the user can then extract and manipulate the 1256 KSP, KSP, and PC contexts as well. 1257 1258 TSGetSNES() does not work for integrators that do not use SNES; in 1259 this case TSGetSNES() returns PETSC_NULL in snes. 1260 1261 Level: beginner 1262 1263 .keywords: timestep, get, SNES 1264 @*/ 1265 PetscErrorCode TSGetSNES(TS ts,SNES *snes) 1266 { 1267 PetscErrorCode ierr; 1268 1269 PetscFunctionBegin; 1270 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1271 PetscValidPointer(snes,2); 1272 if (!ts->snes) { 1273 ierr = SNESCreate(((PetscObject)ts)->comm,&ts->snes);CHKERRQ(ierr); 1274 ierr = PetscLogObjectParent(ts,ts->snes);CHKERRQ(ierr); 1275 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr); 1276 if (ts->problem_type == TS_LINEAR) { 1277 ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr); 1278 } 1279 } 1280 *snes = ts->snes; 1281 PetscFunctionReturn(0); 1282 } 1283 1284 #undef __FUNCT__ 1285 #define __FUNCT__ "TSGetKSP" 1286 /*@ 1287 TSGetKSP - Returns the KSP (linear solver) associated with 1288 a TS (timestepper) context. 1289 1290 Not Collective, but KSP is parallel if TS is parallel 1291 1292 Input Parameter: 1293 . ts - the TS context obtained from TSCreate() 1294 1295 Output Parameter: 1296 . ksp - the nonlinear solver context 1297 1298 Notes: 1299 The user can then directly manipulate the KSP context to set various 1300 options, etc. Likewise, the user can then extract and manipulate the 1301 KSP and PC contexts as well. 1302 1303 TSGetKSP() does not work for integrators that do not use KSP; 1304 in this case TSGetKSP() returns PETSC_NULL in ksp. 1305 1306 Level: beginner 1307 1308 .keywords: timestep, get, KSP 1309 @*/ 1310 PetscErrorCode TSGetKSP(TS ts,KSP *ksp) 1311 { 1312 PetscErrorCode ierr; 1313 SNES snes; 1314 1315 PetscFunctionBegin; 1316 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1317 PetscValidPointer(ksp,2); 1318 if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first"); 1319 if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()"); 1320 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1321 ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr); 1322 PetscFunctionReturn(0); 1323 } 1324 1325 /* ----------- Routines to set solver parameters ---------- */ 1326 1327 #undef __FUNCT__ 1328 #define __FUNCT__ "TSGetDuration" 1329 /*@ 1330 TSGetDuration - Gets the maximum number of timesteps to use and 1331 maximum time for iteration. 1332 1333 Not Collective 1334 1335 Input Parameters: 1336 + ts - the TS context obtained from TSCreate() 1337 . maxsteps - maximum number of iterations to use, or PETSC_NULL 1338 - maxtime - final time to iterate to, or PETSC_NULL 1339 1340 Level: intermediate 1341 1342 .keywords: TS, timestep, get, maximum, iterations, time 1343 @*/ 1344 PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime) 1345 { 1346 PetscFunctionBegin; 1347 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1348 if (maxsteps) { 1349 PetscValidIntPointer(maxsteps,2); 1350 *maxsteps = ts->max_steps; 1351 } 1352 if (maxtime ) { 1353 PetscValidScalarPointer(maxtime,3); 1354 *maxtime = ts->max_time; 1355 } 1356 PetscFunctionReturn(0); 1357 } 1358 1359 #undef __FUNCT__ 1360 #define __FUNCT__ "TSSetDuration" 1361 /*@ 1362 TSSetDuration - Sets the maximum number of timesteps to use and 1363 maximum time for iteration. 1364 1365 Logically Collective on TS 1366 1367 Input Parameters: 1368 + ts - the TS context obtained from TSCreate() 1369 . maxsteps - maximum number of iterations to use 1370 - maxtime - final time to iterate to 1371 1372 Options Database Keys: 1373 . -ts_max_steps <maxsteps> - Sets maxsteps 1374 . -ts_max_time <maxtime> - Sets maxtime 1375 1376 Notes: 1377 The default maximum number of iterations is 5000. Default time is 5.0 1378 1379 Level: intermediate 1380 1381 .keywords: TS, timestep, set, maximum, iterations 1382 @*/ 1383 PetscErrorCode TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime) 1384 { 1385 PetscFunctionBegin; 1386 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1387 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 1388 PetscValidLogicalCollectiveReal(ts,maxtime,2); 1389 ts->max_steps = maxsteps; 1390 ts->max_time = maxtime; 1391 PetscFunctionReturn(0); 1392 } 1393 1394 #undef __FUNCT__ 1395 #define __FUNCT__ "TSSetSolution" 1396 /*@ 1397 TSSetSolution - Sets the initial solution vector 1398 for use by the TS routines. 1399 1400 Logically Collective on TS and Vec 1401 1402 Input Parameters: 1403 + ts - the TS context obtained from TSCreate() 1404 - x - the solution vector 1405 1406 Level: beginner 1407 1408 .keywords: TS, timestep, set, solution, initial conditions 1409 @*/ 1410 PetscErrorCode TSSetSolution(TS ts,Vec x) 1411 { 1412 PetscErrorCode ierr; 1413 1414 PetscFunctionBegin; 1415 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1416 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1417 ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 1418 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 1419 ts->vec_sol = x; 1420 PetscFunctionReturn(0); 1421 } 1422 1423 #undef __FUNCT__ 1424 #define __FUNCT__ "TSSetPreStep" 1425 /*@C 1426 TSSetPreStep - Sets the general-purpose function 1427 called once at the beginning of each time step. 1428 1429 Logically Collective on TS 1430 1431 Input Parameters: 1432 + ts - The TS context obtained from TSCreate() 1433 - func - The function 1434 1435 Calling sequence of func: 1436 . func (TS ts); 1437 1438 Level: intermediate 1439 1440 .keywords: TS, timestep 1441 @*/ 1442 PetscErrorCode TSSetPreStep(TS ts, PetscErrorCode (*func)(TS)) 1443 { 1444 PetscFunctionBegin; 1445 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1446 ts->ops->prestep = func; 1447 PetscFunctionReturn(0); 1448 } 1449 1450 #undef __FUNCT__ 1451 #define __FUNCT__ "TSPreStep" 1452 /*@C 1453 TSPreStep - Runs the user-defined pre-step function. 1454 1455 Collective on TS 1456 1457 Input Parameters: 1458 . ts - The TS context obtained from TSCreate() 1459 1460 Notes: 1461 TSPreStep() is typically used within time stepping implementations, 1462 so most users would not generally call this routine themselves. 1463 1464 Level: developer 1465 1466 .keywords: TS, timestep 1467 @*/ 1468 PetscErrorCode TSPreStep(TS ts) 1469 { 1470 PetscErrorCode ierr; 1471 1472 PetscFunctionBegin; 1473 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1474 if (ts->ops->prestep) { 1475 PetscStackPush("TS PreStep function"); 1476 ierr = (*ts->ops->prestep)(ts);CHKERRQ(ierr); 1477 PetscStackPop; 1478 } 1479 PetscFunctionReturn(0); 1480 } 1481 1482 #undef __FUNCT__ 1483 #define __FUNCT__ "TSSetPostStep" 1484 /*@C 1485 TSSetPostStep - Sets the general-purpose function 1486 called once at the end of each time step. 1487 1488 Logically Collective on TS 1489 1490 Input Parameters: 1491 + ts - The TS context obtained from TSCreate() 1492 - func - The function 1493 1494 Calling sequence of func: 1495 . func (TS ts); 1496 1497 Level: intermediate 1498 1499 .keywords: TS, timestep 1500 @*/ 1501 PetscErrorCode TSSetPostStep(TS ts, PetscErrorCode (*func)(TS)) 1502 { 1503 PetscFunctionBegin; 1504 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1505 ts->ops->poststep = func; 1506 PetscFunctionReturn(0); 1507 } 1508 1509 #undef __FUNCT__ 1510 #define __FUNCT__ "TSPostStep" 1511 /*@C 1512 TSPostStep - Runs the user-defined post-step function. 1513 1514 Collective on TS 1515 1516 Input Parameters: 1517 . ts - The TS context obtained from TSCreate() 1518 1519 Notes: 1520 TSPostStep() is typically used within time stepping implementations, 1521 so most users would not generally call this routine themselves. 1522 1523 Level: developer 1524 1525 .keywords: TS, timestep 1526 @*/ 1527 PetscErrorCode TSPostStep(TS ts) 1528 { 1529 PetscErrorCode ierr; 1530 1531 PetscFunctionBegin; 1532 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1533 if (ts->ops->poststep) { 1534 PetscStackPush("TS PostStep function"); 1535 ierr = (*ts->ops->poststep)(ts);CHKERRQ(ierr); 1536 PetscStackPop; 1537 } 1538 PetscFunctionReturn(0); 1539 } 1540 1541 /* ------------ Routines to set performance monitoring options ----------- */ 1542 1543 #undef __FUNCT__ 1544 #define __FUNCT__ "TSMonitorSet" 1545 /*@C 1546 TSMonitorSet - Sets an ADDITIONAL function that is to be used at every 1547 timestep to display the iteration's progress. 1548 1549 Logically Collective on TS 1550 1551 Input Parameters: 1552 + ts - the TS context obtained from TSCreate() 1553 . func - monitoring routine 1554 . mctx - [optional] user-defined context for private data for the 1555 monitor routine (use PETSC_NULL if no context is desired) 1556 - monitordestroy - [optional] routine that frees monitor context 1557 (may be PETSC_NULL) 1558 1559 Calling sequence of func: 1560 $ int func(TS ts,PetscInt steps,PetscReal time,Vec x,void *mctx) 1561 1562 + ts - the TS context 1563 . steps - iteration number 1564 . time - current time 1565 . x - current iterate 1566 - mctx - [optional] monitoring context 1567 1568 Notes: 1569 This routine adds an additional monitor to the list of monitors that 1570 already has been loaded. 1571 1572 Fortran notes: Only a single monitor function can be set for each TS object 1573 1574 Level: intermediate 1575 1576 .keywords: TS, timestep, set, monitor 1577 1578 .seealso: TSMonitorDefault(), TSMonitorCancel() 1579 @*/ 1580 PetscErrorCode TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**)) 1581 { 1582 PetscFunctionBegin; 1583 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1584 if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 1585 ts->monitor[ts->numbermonitors] = monitor; 1586 ts->mdestroy[ts->numbermonitors] = mdestroy; 1587 ts->monitorcontext[ts->numbermonitors++] = (void*)mctx; 1588 PetscFunctionReturn(0); 1589 } 1590 1591 #undef __FUNCT__ 1592 #define __FUNCT__ "TSMonitorCancel" 1593 /*@C 1594 TSMonitorCancel - Clears all the monitors that have been set on a time-step object. 1595 1596 Logically Collective on TS 1597 1598 Input Parameters: 1599 . ts - the TS context obtained from TSCreate() 1600 1601 Notes: 1602 There is no way to remove a single, specific monitor. 1603 1604 Level: intermediate 1605 1606 .keywords: TS, timestep, set, monitor 1607 1608 .seealso: TSMonitorDefault(), TSMonitorSet() 1609 @*/ 1610 PetscErrorCode TSMonitorCancel(TS ts) 1611 { 1612 PetscErrorCode ierr; 1613 PetscInt i; 1614 1615 PetscFunctionBegin; 1616 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1617 for (i=0; i<ts->numbermonitors; i++) { 1618 if (ts->mdestroy[i]) { 1619 ierr = (*ts->mdestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr); 1620 } 1621 } 1622 ts->numbermonitors = 0; 1623 PetscFunctionReturn(0); 1624 } 1625 1626 #undef __FUNCT__ 1627 #define __FUNCT__ "TSMonitorDefault" 1628 /*@ 1629 TSMonitorDefault - Sets the Default monitor 1630 1631 Level: intermediate 1632 1633 .keywords: TS, set, monitor 1634 1635 .seealso: TSMonitorDefault(), TSMonitorSet() 1636 @*/ 1637 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,void *dummy) 1638 { 1639 PetscErrorCode ierr; 1640 PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(((PetscObject)ts)->comm); 1641 1642 PetscFunctionBegin; 1643 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 1644 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %G time %G\n",step,ts->time_step,ptime);CHKERRQ(ierr); 1645 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 1646 PetscFunctionReturn(0); 1647 } 1648 1649 #undef __FUNCT__ 1650 #define __FUNCT__ "TSStep" 1651 /*@ 1652 TSStep - Steps the requested number of timesteps. 1653 1654 Collective on TS 1655 1656 Input Parameter: 1657 . ts - the TS context obtained from TSCreate() 1658 1659 Output Parameters: 1660 + steps - number of iterations until termination 1661 - ptime - time until termination 1662 1663 Level: beginner 1664 1665 .keywords: TS, timestep, solve 1666 1667 .seealso: TSCreate(), TSSetUp(), TSDestroy() 1668 @*/ 1669 PetscErrorCode TSStep(TS ts) 1670 { 1671 PetscErrorCode ierr; 1672 1673 PetscFunctionBegin; 1674 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1675 1676 ierr = TSSetUp(ts);CHKERRQ(ierr); 1677 1678 ierr = PetscLogEventBegin(TS_Step, ts, 0, 0, 0);CHKERRQ(ierr); 1679 ierr = (*ts->ops->step)(ts);CHKERRQ(ierr); 1680 ierr = PetscLogEventEnd(TS_Step, ts, 0, 0, 0);CHKERRQ(ierr); 1681 PetscFunctionReturn(0); 1682 } 1683 1684 #undef __FUNCT__ 1685 #define __FUNCT__ "TSSolve" 1686 /*@ 1687 TSSolve - Steps the requested number of timesteps. 1688 1689 Collective on TS 1690 1691 Input Parameter: 1692 + ts - the TS context obtained from TSCreate() 1693 - x - the solution vector, or PETSC_NULL if it was set with TSSetSolution() 1694 1695 Level: beginner 1696 1697 .keywords: TS, timestep, solve 1698 1699 .seealso: TSCreate(), TSSetSolution(), TSStep() 1700 @*/ 1701 PetscErrorCode TSSolve(TS ts, Vec x) 1702 { 1703 PetscInt i; 1704 PetscErrorCode ierr; 1705 1706 PetscFunctionBegin; 1707 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1708 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1709 ierr = TSSetSolution(ts,x); CHKERRQ(ierr); 1710 ierr = TSSetUp(ts); CHKERRQ(ierr); 1711 /* reset time step and iteration counters */ 1712 ts->steps = 0; 1713 ts->linear_its = 0; 1714 ts->nonlinear_its = 0; 1715 ts->reason = TS_CONVERGED_ITERATING; 1716 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 1717 1718 if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */ 1719 ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr); 1720 } else { 1721 /* steps the requested number of timesteps. */ 1722 for (i=0; !ts->reason; ) { 1723 ierr = TSPreStep(ts);CHKERRQ(ierr); 1724 ierr = TSStep(ts);CHKERRQ(ierr); 1725 if (ts->reason < 0) { 1726 if (ts->errorifstepfailed) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_NOT_CONVERGED,"TSStep has failed"); 1727 } else if (++i >= ts->max_steps) { 1728 ts->reason = TS_CONVERGED_ITS; 1729 } else if (ts->ptime >= ts->max_time) { 1730 ts->reason = TS_CONVERGED_TIME; 1731 } 1732 ierr = TSPostStep(ts);CHKERRQ(ierr); 1733 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 1734 } 1735 } 1736 if (!PetscPreLoadingOn) { 1737 ierr = TSViewFromOptions(ts,((PetscObject)ts)->name);CHKERRQ(ierr); 1738 } 1739 PetscFunctionReturn(0); 1740 } 1741 1742 #undef __FUNCT__ 1743 #define __FUNCT__ "TSMonitor" 1744 /* 1745 Runs the user provided monitor routines, if they exists. 1746 */ 1747 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec x) 1748 { 1749 PetscErrorCode ierr; 1750 PetscInt i,n = ts->numbermonitors; 1751 1752 PetscFunctionBegin; 1753 for (i=0; i<n; i++) { 1754 ierr = (*ts->monitor[i])(ts,step,ptime,x,ts->monitorcontext[i]);CHKERRQ(ierr); 1755 } 1756 PetscFunctionReturn(0); 1757 } 1758 1759 /* ------------------------------------------------------------------------*/ 1760 1761 #undef __FUNCT__ 1762 #define __FUNCT__ "TSMonitorLGCreate" 1763 /*@C 1764 TSMonitorLGCreate - Creates a line graph context for use with 1765 TS to monitor convergence of preconditioned residual norms. 1766 1767 Collective on TS 1768 1769 Input Parameters: 1770 + host - the X display to open, or null for the local machine 1771 . label - the title to put in the title bar 1772 . x, y - the screen coordinates of the upper left coordinate of the window 1773 - m, n - the screen width and height in pixels 1774 1775 Output Parameter: 1776 . draw - the drawing context 1777 1778 Options Database Key: 1779 . -ts_monitor_draw - automatically sets line graph monitor 1780 1781 Notes: 1782 Use TSMonitorLGDestroy() to destroy this line graph, not PetscDrawLGDestroy(). 1783 1784 Level: intermediate 1785 1786 .keywords: TS, monitor, line graph, residual, seealso 1787 1788 .seealso: TSMonitorLGDestroy(), TSMonitorSet() 1789 1790 @*/ 1791 PetscErrorCode TSMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 1792 { 1793 PetscDraw win; 1794 PetscErrorCode ierr; 1795 1796 PetscFunctionBegin; 1797 ierr = PetscDrawCreate(PETSC_COMM_SELF,host,label,x,y,m,n,&win);CHKERRQ(ierr); 1798 ierr = PetscDrawSetType(win,PETSC_DRAW_X);CHKERRQ(ierr); 1799 ierr = PetscDrawLGCreate(win,1,draw);CHKERRQ(ierr); 1800 ierr = PetscDrawLGIndicateDataPoints(*draw);CHKERRQ(ierr); 1801 1802 ierr = PetscLogObjectParent(*draw,win);CHKERRQ(ierr); 1803 PetscFunctionReturn(0); 1804 } 1805 1806 #undef __FUNCT__ 1807 #define __FUNCT__ "TSMonitorLG" 1808 PetscErrorCode TSMonitorLG(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 1809 { 1810 PetscDrawLG lg = (PetscDrawLG) monctx; 1811 PetscReal x,y = ptime; 1812 PetscErrorCode ierr; 1813 1814 PetscFunctionBegin; 1815 if (!monctx) { 1816 MPI_Comm comm; 1817 PetscViewer viewer; 1818 1819 ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr); 1820 viewer = PETSC_VIEWER_DRAW_(comm); 1821 ierr = PetscViewerDrawGetDrawLG(viewer,0,&lg);CHKERRQ(ierr); 1822 } 1823 1824 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 1825 x = (PetscReal)n; 1826 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 1827 if (n < 20 || (n % 5)) { 1828 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 1829 } 1830 PetscFunctionReturn(0); 1831 } 1832 1833 #undef __FUNCT__ 1834 #define __FUNCT__ "TSMonitorLGDestroy" 1835 /*@C 1836 TSMonitorLGDestroy - Destroys a line graph context that was created 1837 with TSMonitorLGCreate(). 1838 1839 Collective on PetscDrawLG 1840 1841 Input Parameter: 1842 . draw - the drawing context 1843 1844 Level: intermediate 1845 1846 .keywords: TS, monitor, line graph, destroy 1847 1848 .seealso: TSMonitorLGCreate(), TSMonitorSet(), TSMonitorLG(); 1849 @*/ 1850 PetscErrorCode TSMonitorLGDestroy(PetscDrawLG *drawlg) 1851 { 1852 PetscDraw draw; 1853 PetscErrorCode ierr; 1854 1855 PetscFunctionBegin; 1856 ierr = PetscDrawLGGetDraw(*drawlg,&draw);CHKERRQ(ierr); 1857 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 1858 ierr = PetscDrawLGDestroy(drawlg);CHKERRQ(ierr); 1859 PetscFunctionReturn(0); 1860 } 1861 1862 #undef __FUNCT__ 1863 #define __FUNCT__ "TSGetTime" 1864 /*@ 1865 TSGetTime - Gets the current time. 1866 1867 Not Collective 1868 1869 Input Parameter: 1870 . ts - the TS context obtained from TSCreate() 1871 1872 Output Parameter: 1873 . t - the current time 1874 1875 Level: beginner 1876 1877 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 1878 1879 .keywords: TS, get, time 1880 @*/ 1881 PetscErrorCode TSGetTime(TS ts,PetscReal* t) 1882 { 1883 PetscFunctionBegin; 1884 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1885 PetscValidDoublePointer(t,2); 1886 *t = ts->ptime; 1887 PetscFunctionReturn(0); 1888 } 1889 1890 #undef __FUNCT__ 1891 #define __FUNCT__ "TSSetTime" 1892 /*@ 1893 TSSetTime - Allows one to reset the time. 1894 1895 Logically Collective on TS 1896 1897 Input Parameters: 1898 + ts - the TS context obtained from TSCreate() 1899 - time - the time 1900 1901 Level: intermediate 1902 1903 .seealso: TSGetTime(), TSSetDuration() 1904 1905 .keywords: TS, set, time 1906 @*/ 1907 PetscErrorCode TSSetTime(TS ts, PetscReal t) 1908 { 1909 PetscFunctionBegin; 1910 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1911 PetscValidLogicalCollectiveReal(ts,t,2); 1912 ts->ptime = t; 1913 PetscFunctionReturn(0); 1914 } 1915 1916 #undef __FUNCT__ 1917 #define __FUNCT__ "TSSetOptionsPrefix" 1918 /*@C 1919 TSSetOptionsPrefix - Sets the prefix used for searching for all 1920 TS options in the database. 1921 1922 Logically Collective on TS 1923 1924 Input Parameter: 1925 + ts - The TS context 1926 - prefix - The prefix to prepend to all option names 1927 1928 Notes: 1929 A hyphen (-) must NOT be given at the beginning of the prefix name. 1930 The first character of all runtime options is AUTOMATICALLY the 1931 hyphen. 1932 1933 Level: advanced 1934 1935 .keywords: TS, set, options, prefix, database 1936 1937 .seealso: TSSetFromOptions() 1938 1939 @*/ 1940 PetscErrorCode TSSetOptionsPrefix(TS ts,const char prefix[]) 1941 { 1942 PetscErrorCode ierr; 1943 SNES snes; 1944 1945 PetscFunctionBegin; 1946 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1947 ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 1948 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1949 ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr); 1950 PetscFunctionReturn(0); 1951 } 1952 1953 1954 #undef __FUNCT__ 1955 #define __FUNCT__ "TSAppendOptionsPrefix" 1956 /*@C 1957 TSAppendOptionsPrefix - Appends to the prefix used for searching for all 1958 TS options in the database. 1959 1960 Logically Collective on TS 1961 1962 Input Parameter: 1963 + ts - The TS context 1964 - prefix - The prefix to prepend to all option names 1965 1966 Notes: 1967 A hyphen (-) must NOT be given at the beginning of the prefix name. 1968 The first character of all runtime options is AUTOMATICALLY the 1969 hyphen. 1970 1971 Level: advanced 1972 1973 .keywords: TS, append, options, prefix, database 1974 1975 .seealso: TSGetOptionsPrefix() 1976 1977 @*/ 1978 PetscErrorCode TSAppendOptionsPrefix(TS ts,const char prefix[]) 1979 { 1980 PetscErrorCode ierr; 1981 SNES snes; 1982 1983 PetscFunctionBegin; 1984 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1985 ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 1986 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1987 ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr); 1988 PetscFunctionReturn(0); 1989 } 1990 1991 #undef __FUNCT__ 1992 #define __FUNCT__ "TSGetOptionsPrefix" 1993 /*@C 1994 TSGetOptionsPrefix - Sets the prefix used for searching for all 1995 TS options in the database. 1996 1997 Not Collective 1998 1999 Input Parameter: 2000 . ts - The TS context 2001 2002 Output Parameter: 2003 . prefix - A pointer to the prefix string used 2004 2005 Notes: On the fortran side, the user should pass in a string 'prifix' of 2006 sufficient length to hold the prefix. 2007 2008 Level: intermediate 2009 2010 .keywords: TS, get, options, prefix, database 2011 2012 .seealso: TSAppendOptionsPrefix() 2013 @*/ 2014 PetscErrorCode TSGetOptionsPrefix(TS ts,const char *prefix[]) 2015 { 2016 PetscErrorCode ierr; 2017 2018 PetscFunctionBegin; 2019 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2020 PetscValidPointer(prefix,2); 2021 ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 2022 PetscFunctionReturn(0); 2023 } 2024 2025 #undef __FUNCT__ 2026 #define __FUNCT__ "TSGetRHSJacobian" 2027 /*@C 2028 TSGetRHSJacobian - Returns the Jacobian J at the present timestep. 2029 2030 Not Collective, but parallel objects are returned if TS is parallel 2031 2032 Input Parameter: 2033 . ts - The TS context obtained from TSCreate() 2034 2035 Output Parameters: 2036 + J - The Jacobian J of F, where U_t = F(U,t) 2037 . M - The preconditioner matrix, usually the same as J 2038 . func - Function to compute the Jacobian of the RHS 2039 - ctx - User-defined context for Jacobian evaluation routine 2040 2041 Notes: You can pass in PETSC_NULL for any return argument you do not need. 2042 2043 Level: intermediate 2044 2045 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 2046 2047 .keywords: TS, timestep, get, matrix, Jacobian 2048 @*/ 2049 PetscErrorCode TSGetRHSJacobian(TS ts,Mat *J,Mat *M,TSRHSJacobian *func,void **ctx) 2050 { 2051 PetscErrorCode ierr; 2052 SNES snes; 2053 2054 PetscFunctionBegin; 2055 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2056 ierr = SNESGetJacobian(snes,J,M,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 2057 if (func) *func = ts->userops->rhsjacobian; 2058 if (ctx) *ctx = ts->jacP; 2059 PetscFunctionReturn(0); 2060 } 2061 2062 #undef __FUNCT__ 2063 #define __FUNCT__ "TSGetIJacobian" 2064 /*@C 2065 TSGetIJacobian - Returns the implicit Jacobian at the present timestep. 2066 2067 Not Collective, but parallel objects are returned if TS is parallel 2068 2069 Input Parameter: 2070 . ts - The TS context obtained from TSCreate() 2071 2072 Output Parameters: 2073 + A - The Jacobian of F(t,U,U_t) 2074 . B - The preconditioner matrix, often the same as A 2075 . f - The function to compute the matrices 2076 - ctx - User-defined context for Jacobian evaluation routine 2077 2078 Notes: You can pass in PETSC_NULL for any return argument you do not need. 2079 2080 Level: advanced 2081 2082 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 2083 2084 .keywords: TS, timestep, get, matrix, Jacobian 2085 @*/ 2086 PetscErrorCode TSGetIJacobian(TS ts,Mat *A,Mat *B,TSIJacobian *f,void **ctx) 2087 { 2088 PetscErrorCode ierr; 2089 SNES snes; 2090 2091 PetscFunctionBegin; 2092 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2093 ierr = SNESGetJacobian(snes,A,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 2094 if (f) *f = ts->userops->ijacobian; 2095 if (ctx) *ctx = ts->jacP; 2096 PetscFunctionReturn(0); 2097 } 2098 2099 #undef __FUNCT__ 2100 #define __FUNCT__ "TSMonitorSolution" 2101 /*@C 2102 TSMonitorSolution - Monitors progress of the TS solvers by calling 2103 VecView() for the solution at each timestep 2104 2105 Collective on TS 2106 2107 Input Parameters: 2108 + ts - the TS context 2109 . step - current time-step 2110 . ptime - current time 2111 - dummy - either a viewer or PETSC_NULL 2112 2113 Level: intermediate 2114 2115 .keywords: TS, vector, monitor, view 2116 2117 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 2118 @*/ 2119 PetscErrorCode TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec x,void *dummy) 2120 { 2121 PetscErrorCode ierr; 2122 PetscViewer viewer = (PetscViewer) dummy; 2123 2124 PetscFunctionBegin; 2125 if (!dummy) { 2126 viewer = PETSC_VIEWER_DRAW_(((PetscObject)ts)->comm); 2127 } 2128 ierr = VecView(x,viewer);CHKERRQ(ierr); 2129 PetscFunctionReturn(0); 2130 } 2131 2132 2133 #undef __FUNCT__ 2134 #define __FUNCT__ "TSSetDM" 2135 /*@ 2136 TSSetDM - Sets the DM that may be used by some preconditioners 2137 2138 Logically Collective on TS and DM 2139 2140 Input Parameters: 2141 + ts - the preconditioner context 2142 - dm - the dm 2143 2144 Level: intermediate 2145 2146 2147 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM() 2148 @*/ 2149 PetscErrorCode TSSetDM(TS ts,DM dm) 2150 { 2151 PetscErrorCode ierr; 2152 SNES snes; 2153 2154 PetscFunctionBegin; 2155 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2156 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 2157 ierr = DMDestroy(&ts->dm);CHKERRQ(ierr); 2158 ts->dm = dm; 2159 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2160 ierr = SNESSetDM(snes,dm);CHKERRQ(ierr); 2161 PetscFunctionReturn(0); 2162 } 2163 2164 #undef __FUNCT__ 2165 #define __FUNCT__ "TSGetDM" 2166 /*@ 2167 TSGetDM - Gets the DM that may be used by some preconditioners 2168 2169 Not Collective 2170 2171 Input Parameter: 2172 . ts - the preconditioner context 2173 2174 Output Parameter: 2175 . dm - the dm 2176 2177 Level: intermediate 2178 2179 2180 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM() 2181 @*/ 2182 PetscErrorCode TSGetDM(TS ts,DM *dm) 2183 { 2184 PetscFunctionBegin; 2185 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2186 *dm = ts->dm; 2187 PetscFunctionReturn(0); 2188 } 2189 2190 #undef __FUNCT__ 2191 #define __FUNCT__ "SNESTSFormFunction" 2192 /*@ 2193 SNESTSFormFunction - Function to evaluate nonlinear residual 2194 2195 Logically Collective on SNES 2196 2197 Input Parameter: 2198 + snes - nonlinear solver 2199 . X - the current state at which to evaluate the residual 2200 - ctx - user context, must be a TS 2201 2202 Output Parameter: 2203 . F - the nonlinear residual 2204 2205 Notes: 2206 This function is not normally called by users and is automatically registered with the SNES used by TS. 2207 It is most frequently passed to MatFDColoringSetFunction(). 2208 2209 Level: advanced 2210 2211 .seealso: SNESSetFunction(), MatFDColoringSetFunction() 2212 @*/ 2213 PetscErrorCode SNESTSFormFunction(SNES snes,Vec X,Vec F,void *ctx) 2214 { 2215 TS ts = (TS)ctx; 2216 PetscErrorCode ierr; 2217 2218 PetscFunctionBegin; 2219 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2220 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2221 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 2222 PetscValidHeaderSpecific(ts,TS_CLASSID,4); 2223 ierr = (ts->ops->snesfunction)(snes,X,F,ts);CHKERRQ(ierr); 2224 PetscFunctionReturn(0); 2225 } 2226 2227 #undef __FUNCT__ 2228 #define __FUNCT__ "SNESTSFormJacobian" 2229 /*@ 2230 SNESTSFormJacobian - Function to evaluate the Jacobian 2231 2232 Collective on SNES 2233 2234 Input Parameter: 2235 + snes - nonlinear solver 2236 . X - the current state at which to evaluate the residual 2237 - ctx - user context, must be a TS 2238 2239 Output Parameter: 2240 + A - the Jacobian 2241 . B - the preconditioning matrix (may be the same as A) 2242 - flag - indicates any structure change in the matrix 2243 2244 Notes: 2245 This function is not normally called by users and is automatically registered with the SNES used by TS. 2246 2247 Level: developer 2248 2249 .seealso: SNESSetJacobian() 2250 @*/ 2251 PetscErrorCode SNESTSFormJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flag,void *ctx) 2252 { 2253 TS ts = (TS)ctx; 2254 PetscErrorCode ierr; 2255 2256 PetscFunctionBegin; 2257 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2258 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2259 PetscValidPointer(A,3); 2260 PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 2261 PetscValidPointer(B,4); 2262 PetscValidHeaderSpecific(*B,MAT_CLASSID,4); 2263 PetscValidPointer(flag,5); 2264 PetscValidHeaderSpecific(ts,TS_CLASSID,6); 2265 ierr = (ts->ops->snesjacobian)(snes,X,A,B,flag,ts);CHKERRQ(ierr); 2266 PetscFunctionReturn(0); 2267 } 2268 2269 #if defined(PETSC_HAVE_MATLAB_ENGINE) 2270 #include <mex.h> 2271 2272 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext; 2273 2274 #undef __FUNCT__ 2275 #define __FUNCT__ "TSComputeFunction_Matlab" 2276 /* 2277 TSComputeFunction_Matlab - Calls the function that has been set with 2278 TSSetFunctionMatlab(). 2279 2280 Collective on TS 2281 2282 Input Parameters: 2283 + snes - the TS context 2284 - x - input vector 2285 2286 Output Parameter: 2287 . y - function vector, as set by TSSetFunction() 2288 2289 Notes: 2290 TSComputeFunction() is typically used within nonlinear solvers 2291 implementations, so most users would not generally call this routine 2292 themselves. 2293 2294 Level: developer 2295 2296 .keywords: TS, nonlinear, compute, function 2297 2298 .seealso: TSSetFunction(), TSGetFunction() 2299 */ 2300 PetscErrorCode TSComputeFunction_Matlab(TS snes,PetscReal time,Vec x,Vec xdot,Vec y, void *ctx) 2301 { 2302 PetscErrorCode ierr; 2303 TSMatlabContext *sctx = (TSMatlabContext *)ctx; 2304 int nlhs = 1,nrhs = 7; 2305 mxArray *plhs[1],*prhs[7]; 2306 long long int lx = 0,lxdot = 0,ly = 0,ls = 0; 2307 2308 PetscFunctionBegin; 2309 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 2310 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 2311 PetscValidHeaderSpecific(xdot,VEC_CLASSID,4); 2312 PetscValidHeaderSpecific(y,VEC_CLASSID,5); 2313 PetscCheckSameComm(snes,1,x,3); 2314 PetscCheckSameComm(snes,1,y,5); 2315 2316 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 2317 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 2318 ierr = PetscMemcpy(&lxdot,&xdot,sizeof(xdot));CHKERRQ(ierr); 2319 ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 2320 prhs[0] = mxCreateDoubleScalar((double)ls); 2321 prhs[1] = mxCreateDoubleScalar(time); 2322 prhs[2] = mxCreateDoubleScalar((double)lx); 2323 prhs[3] = mxCreateDoubleScalar((double)lxdot); 2324 prhs[4] = mxCreateDoubleScalar((double)ly); 2325 prhs[5] = mxCreateString(sctx->funcname); 2326 prhs[6] = sctx->ctx; 2327 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr); 2328 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 2329 mxDestroyArray(prhs[0]); 2330 mxDestroyArray(prhs[1]); 2331 mxDestroyArray(prhs[2]); 2332 mxDestroyArray(prhs[3]); 2333 mxDestroyArray(prhs[4]); 2334 mxDestroyArray(prhs[5]); 2335 mxDestroyArray(plhs[0]); 2336 PetscFunctionReturn(0); 2337 } 2338 2339 2340 #undef __FUNCT__ 2341 #define __FUNCT__ "TSSetFunctionMatlab" 2342 /* 2343 TSSetFunctionMatlab - Sets the function evaluation routine and function 2344 vector for use by the TS routines in solving ODEs 2345 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 2346 2347 Logically Collective on TS 2348 2349 Input Parameters: 2350 + ts - the TS context 2351 - func - function evaluation routine 2352 2353 Calling sequence of func: 2354 $ func (TS ts,PetscReal time,Vec x,Vec xdot,Vec f,void *ctx); 2355 2356 Level: beginner 2357 2358 .keywords: TS, nonlinear, set, function 2359 2360 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 2361 */ 2362 PetscErrorCode TSSetFunctionMatlab(TS snes,const char *func,mxArray *ctx) 2363 { 2364 PetscErrorCode ierr; 2365 TSMatlabContext *sctx; 2366 2367 PetscFunctionBegin; 2368 /* currently sctx is memory bleed */ 2369 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 2370 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 2371 /* 2372 This should work, but it doesn't 2373 sctx->ctx = ctx; 2374 mexMakeArrayPersistent(sctx->ctx); 2375 */ 2376 sctx->ctx = mxDuplicateArray(ctx); 2377 ierr = TSSetIFunction(snes,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr); 2378 PetscFunctionReturn(0); 2379 } 2380 2381 #undef __FUNCT__ 2382 #define __FUNCT__ "TSComputeJacobian_Matlab" 2383 /* 2384 TSComputeJacobian_Matlab - Calls the function that has been set with 2385 TSSetJacobianMatlab(). 2386 2387 Collective on TS 2388 2389 Input Parameters: 2390 + snes - the TS context 2391 . x - input vector 2392 . A, B - the matrices 2393 - ctx - user context 2394 2395 Output Parameter: 2396 . flag - structure of the matrix 2397 2398 Level: developer 2399 2400 .keywords: TS, nonlinear, compute, function 2401 2402 .seealso: TSSetFunction(), TSGetFunction() 2403 @*/ 2404 PetscErrorCode TSComputeJacobian_Matlab(TS snes,PetscReal time,Vec x,Vec xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flag, void *ctx) 2405 { 2406 PetscErrorCode ierr; 2407 TSMatlabContext *sctx = (TSMatlabContext *)ctx; 2408 int nlhs = 2,nrhs = 9; 2409 mxArray *plhs[2],*prhs[9]; 2410 long long int lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0; 2411 2412 PetscFunctionBegin; 2413 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 2414 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 2415 2416 /* call Matlab function in ctx with arguments x and y */ 2417 2418 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 2419 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 2420 ierr = PetscMemcpy(&lxdot,&xdot,sizeof(x));CHKERRQ(ierr); 2421 ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 2422 ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 2423 prhs[0] = mxCreateDoubleScalar((double)ls); 2424 prhs[1] = mxCreateDoubleScalar((double)time); 2425 prhs[2] = mxCreateDoubleScalar((double)lx); 2426 prhs[3] = mxCreateDoubleScalar((double)lxdot); 2427 prhs[4] = mxCreateDoubleScalar((double)shift); 2428 prhs[5] = mxCreateDoubleScalar((double)lA); 2429 prhs[6] = mxCreateDoubleScalar((double)lB); 2430 prhs[7] = mxCreateString(sctx->funcname); 2431 prhs[8] = sctx->ctx; 2432 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr); 2433 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 2434 *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 2435 mxDestroyArray(prhs[0]); 2436 mxDestroyArray(prhs[1]); 2437 mxDestroyArray(prhs[2]); 2438 mxDestroyArray(prhs[3]); 2439 mxDestroyArray(prhs[4]); 2440 mxDestroyArray(prhs[5]); 2441 mxDestroyArray(prhs[6]); 2442 mxDestroyArray(prhs[7]); 2443 mxDestroyArray(plhs[0]); 2444 mxDestroyArray(plhs[1]); 2445 PetscFunctionReturn(0); 2446 } 2447 2448 2449 #undef __FUNCT__ 2450 #define __FUNCT__ "TSSetJacobianMatlab" 2451 /* 2452 TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 2453 vector for use by the TS routines in solving ODEs from MATLAB. Here the function is a string containing the name of a MATLAB function 2454 2455 Logically Collective on TS 2456 2457 Input Parameters: 2458 + snes - the TS context 2459 . A,B - Jacobian matrices 2460 . func - function evaluation routine 2461 - ctx - user context 2462 2463 Calling sequence of func: 2464 $ flag = func (TS snes,PetscReal time,Vec x,Vec xdot,Mat A,Mat B,void *ctx); 2465 2466 2467 Level: developer 2468 2469 .keywords: TS, nonlinear, set, function 2470 2471 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 2472 */ 2473 PetscErrorCode TSSetJacobianMatlab(TS snes,Mat A,Mat B,const char *func,mxArray *ctx) 2474 { 2475 PetscErrorCode ierr; 2476 TSMatlabContext *sctx; 2477 2478 PetscFunctionBegin; 2479 /* currently sctx is memory bleed */ 2480 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 2481 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 2482 /* 2483 This should work, but it doesn't 2484 sctx->ctx = ctx; 2485 mexMakeArrayPersistent(sctx->ctx); 2486 */ 2487 sctx->ctx = mxDuplicateArray(ctx); 2488 ierr = TSSetIJacobian(snes,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 2489 PetscFunctionReturn(0); 2490 } 2491 2492 #undef __FUNCT__ 2493 #define __FUNCT__ "TSMonitor_Matlab" 2494 /* 2495 TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab(). 2496 2497 Collective on TS 2498 2499 .seealso: TSSetFunction(), TSGetFunction() 2500 @*/ 2501 PetscErrorCode TSMonitor_Matlab(TS snes,PetscInt it, PetscReal time,Vec x, void *ctx) 2502 { 2503 PetscErrorCode ierr; 2504 TSMatlabContext *sctx = (TSMatlabContext *)ctx; 2505 int nlhs = 1,nrhs = 6; 2506 mxArray *plhs[1],*prhs[6]; 2507 long long int lx = 0,ls = 0; 2508 2509 PetscFunctionBegin; 2510 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 2511 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 2512 2513 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 2514 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 2515 prhs[0] = mxCreateDoubleScalar((double)ls); 2516 prhs[1] = mxCreateDoubleScalar((double)it); 2517 prhs[2] = mxCreateDoubleScalar((double)time); 2518 prhs[3] = mxCreateDoubleScalar((double)lx); 2519 prhs[4] = mxCreateString(sctx->funcname); 2520 prhs[5] = sctx->ctx; 2521 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr); 2522 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 2523 mxDestroyArray(prhs[0]); 2524 mxDestroyArray(prhs[1]); 2525 mxDestroyArray(prhs[2]); 2526 mxDestroyArray(prhs[3]); 2527 mxDestroyArray(prhs[4]); 2528 mxDestroyArray(plhs[0]); 2529 PetscFunctionReturn(0); 2530 } 2531 2532 2533 #undef __FUNCT__ 2534 #define __FUNCT__ "TSMonitorSetMatlab" 2535 /* 2536 TSMonitorSetMatlab - Sets the monitor function from Matlab 2537 2538 Level: developer 2539 2540 .keywords: TS, nonlinear, set, function 2541 2542 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 2543 */ 2544 PetscErrorCode TSMonitorSetMatlab(TS snes,const char *func,mxArray *ctx) 2545 { 2546 PetscErrorCode ierr; 2547 TSMatlabContext *sctx; 2548 2549 PetscFunctionBegin; 2550 /* currently sctx is memory bleed */ 2551 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 2552 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 2553 /* 2554 This should work, but it doesn't 2555 sctx->ctx = ctx; 2556 mexMakeArrayPersistent(sctx->ctx); 2557 */ 2558 sctx->ctx = mxDuplicateArray(ctx); 2559 ierr = TSMonitorSet(snes,TSMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 2560 PetscFunctionReturn(0); 2561 } 2562 2563 #endif 2564