1 2 #include <petsc-private/tsimpl.h> /*I "petscts.h" I*/ 3 #include <petscdmshell.h> 4 5 /* Logging support */ 6 PetscClassId TS_CLASSID; 7 PetscLogEvent TS_Step, TS_PseudoComputeTimeStep, TS_FunctionEval, TS_JacobianEval; 8 9 #undef __FUNCT__ 10 #define __FUNCT__ "TSSetTypeFromOptions" 11 /* 12 TSSetTypeFromOptions - Sets the type of ts from user options. 13 14 Collective on TS 15 16 Input Parameter: 17 . ts - The ts 18 19 Level: intermediate 20 21 .keywords: TS, set, options, database, type 22 .seealso: TSSetFromOptions(), TSSetType() 23 */ 24 static PetscErrorCode TSSetTypeFromOptions(TS ts) 25 { 26 PetscBool opt; 27 const char *defaultType; 28 char typeName[256]; 29 PetscErrorCode ierr; 30 31 PetscFunctionBegin; 32 if (((PetscObject)ts)->type_name) { 33 defaultType = ((PetscObject)ts)->type_name; 34 } else { 35 defaultType = TSEULER; 36 } 37 38 if (!TSRegisterAllCalled) {ierr = TSRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 39 ierr = PetscOptionsList("-ts_type", "TS method"," TSSetType", TSList, defaultType, typeName, 256, &opt);CHKERRQ(ierr); 40 if (opt) { 41 ierr = TSSetType(ts, typeName);CHKERRQ(ierr); 42 } else { 43 ierr = TSSetType(ts, defaultType);CHKERRQ(ierr); 44 } 45 PetscFunctionReturn(0); 46 } 47 48 #undef __FUNCT__ 49 #define __FUNCT__ "TSSetFromOptions" 50 /*@ 51 TSSetFromOptions - Sets various TS parameters from user options. 52 53 Collective on TS 54 55 Input Parameter: 56 . ts - the TS context obtained from TSCreate() 57 58 Options Database Keys: 59 + -ts_type <type> - TSEULER, TSBEULER, TSSUNDIALS, TSPSEUDO, TSCN, TSRK, TSTHETA, TSGL, TSSSP 60 . -ts_max_steps maxsteps - maximum number of time-steps to take 61 . -ts_final_time time - maximum time to compute to 62 . -ts_dt dt - initial time step 63 . -ts_monitor - print information at each timestep 64 - -ts_monitor_draw - plot information at each timestep 65 66 Level: beginner 67 68 .keywords: TS, timestep, set, options, database 69 70 .seealso: TSGetType() 71 @*/ 72 PetscErrorCode TSSetFromOptions(TS ts) 73 { 74 PetscBool opt,flg; 75 PetscErrorCode ierr; 76 PetscViewer monviewer; 77 char monfilename[PETSC_MAX_PATH_LEN]; 78 SNES snes; 79 TSAdapt adapt; 80 PetscReal time_step; 81 82 PetscFunctionBegin; 83 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 84 ierr = PetscObjectOptionsBegin((PetscObject)ts);CHKERRQ(ierr); 85 /* Handle TS type options */ 86 ierr = TSSetTypeFromOptions(ts);CHKERRQ(ierr); 87 88 /* Handle generic TS options */ 89 ierr = PetscOptionsInt("-ts_max_steps","Maximum number of time steps","TSSetDuration",ts->max_steps,&ts->max_steps,PETSC_NULL);CHKERRQ(ierr); 90 ierr = PetscOptionsReal("-ts_final_time","Time to run to","TSSetDuration",ts->max_time,&ts->max_time,PETSC_NULL);CHKERRQ(ierr); 91 ierr = PetscOptionsReal("-ts_init_time","Initial time","TSSetTime",ts->ptime,&ts->ptime,PETSC_NULL);CHKERRQ(ierr); 92 ierr = PetscOptionsReal("-ts_dt","Initial time step","TSSetTimeStep",ts->time_step,&time_step,&flg);CHKERRQ(ierr); 93 if (flg) { 94 ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr); 95 } 96 opt = ts->exact_final_time == PETSC_DECIDE ? PETSC_FALSE : (PetscBool)ts->exact_final_time; 97 ierr = PetscOptionsBool("-ts_exact_final_time","Interpolate output to stop exactly at the final time","TSSetExactFinalTime",opt,&opt,&flg);CHKERRQ(ierr); 98 if (flg) {ierr = TSSetExactFinalTime(ts,opt);CHKERRQ(ierr);} 99 ierr = PetscOptionsInt("-ts_max_snes_failures","Maximum number of nonlinear solve failures","TSSetMaxSNESFailures",ts->max_snes_failures,&ts->max_snes_failures,PETSC_NULL);CHKERRQ(ierr); 100 ierr = PetscOptionsInt("-ts_max_reject","Maximum number of step rejections before step fails","TSSetMaxStepRejections",ts->max_reject,&ts->max_reject,PETSC_NULL);CHKERRQ(ierr); 101 ierr = PetscOptionsBool("-ts_error_if_step_fails","Error if no step succeeds","TSSetErrorIfStepFails",ts->errorifstepfailed,&ts->errorifstepfailed,PETSC_NULL);CHKERRQ(ierr); 102 ierr = PetscOptionsReal("-ts_rtol","Relative tolerance for local truncation error","TSSetTolerances",ts->rtol,&ts->rtol,PETSC_NULL);CHKERRQ(ierr); 103 ierr = PetscOptionsReal("-ts_atol","Absolute tolerance for local truncation error","TSSetTolerances",ts->atol,&ts->atol,PETSC_NULL);CHKERRQ(ierr); 104 105 /* Monitor options */ 106 ierr = PetscOptionsString("-ts_monitor","Monitor timestep size","TSMonitorDefault","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 107 if (flg) { 108 ierr = PetscViewerASCIIOpen(((PetscObject)ts)->comm,monfilename,&monviewer);CHKERRQ(ierr); 109 ierr = TSMonitorSet(ts,TSMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 110 } 111 ierr = PetscOptionsString("-ts_monitor_python","Use Python function","TSMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 112 if (flg) {ierr = PetscPythonMonitorSet((PetscObject)ts,monfilename);CHKERRQ(ierr);} 113 114 opt = PETSC_FALSE; 115 ierr = PetscOptionsBool("-ts_monitor_draw","Monitor timestep size graphically","TSMonitorLG",opt,&opt,PETSC_NULL);CHKERRQ(ierr); 116 if (opt) { 117 PetscDrawLG lg; 118 119 ierr = TSMonitorLGCreate(((PetscObject)ts)->comm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&lg); 120 ierr = TSMonitorSet(ts,TSMonitorLG,lg,(PetscErrorCode (*)(void**))TSMonitorLGDestroy);CHKERRQ(ierr); 121 } 122 opt = PETSC_FALSE; 123 ierr = PetscOptionsBool("-ts_monitor_solutionode","Monitor solution graphically","TSMonitorSolutionODE",opt,&opt,PETSC_NULL);CHKERRQ(ierr); 124 if (opt) { 125 PetscDrawLG lg; 126 127 ierr = TSMonitorSolutionODECreate(((PetscObject)ts)->comm,3,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,&lg); 128 ierr = TSMonitorSet(ts,TSMonitorSolutionODE,lg,(PetscErrorCode (*)(void**))TSMonitorSolutionODEDestroy);CHKERRQ(ierr); 129 } 130 opt = PETSC_FALSE; 131 ierr = PetscOptionsBool("-ts_monitor_errorode","Monitor error graphically","TSMonitorErrorODE",opt,&opt,PETSC_NULL);CHKERRQ(ierr); 132 if (opt) { 133 PetscDrawLG lg; 134 135 ierr = TSMonitorErrorODECreate(((PetscObject)ts)->comm,3,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,&lg); 136 ierr = TSMonitorSet(ts,TSMonitorErrorODE,lg,(PetscErrorCode (*)(void**))TSMonitorErrorODEDestroy);CHKERRQ(ierr); 137 } 138 opt = PETSC_FALSE; 139 ierr = PetscOptionsBool("-ts_monitor_solution","Monitor solution graphically","TSMonitorSolution",opt,&opt,PETSC_NULL);CHKERRQ(ierr); 140 if (opt) { 141 void *ctx; 142 PetscViewer viewer; 143 144 ierr = PetscViewerDrawOpen(((PetscObject)ts)->comm,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,&viewer); 145 ierr = TSMonitorSolutionCreate(ts,viewer,&ctx);CHKERRQ(ierr); 146 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 147 ierr = TSMonitorSet(ts,TSMonitorSolution,ctx,TSMonitorSolutionDestroy);CHKERRQ(ierr); 148 } 149 opt = PETSC_FALSE; 150 ierr = PetscOptionsString("-ts_monitor_solution_binary","Save each solution to a binary file","TSMonitorSolutionBinary",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 151 if (flg) { 152 PetscViewer ctx; 153 if (monfilename[0]) { 154 ierr = PetscViewerBinaryOpen(((PetscObject)ts)->comm,monfilename,FILE_MODE_WRITE,&ctx);CHKERRQ(ierr); 155 } else { 156 ctx = PETSC_VIEWER_BINARY_(((PetscObject)ts)->comm); 157 } 158 ierr = TSMonitorSet(ts,TSMonitorSolutionBinary,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 159 } 160 opt = PETSC_FALSE; 161 ierr = PetscOptionsString("-ts_monitor_solution_vtk","Save each time step to a binary file, use filename-%%03D.vts","TSMonitorSolutionVTK",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 162 if (flg) { 163 const char *ptr,*ptr2; 164 char *filetemplate; 165 if (!monfilename[0]) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts"); 166 /* Do some cursory validation of the input. */ 167 ierr = PetscStrstr(monfilename,"%",(char**)&ptr);CHKERRQ(ierr); 168 if (!ptr) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts"); 169 for (ptr++ ; ptr && *ptr; ptr++) { 170 ierr = PetscStrchr("DdiouxX",*ptr,(char**)&ptr2);CHKERRQ(ierr); 171 if (!ptr2 && (*ptr < '0' || '9' < *ptr)) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Invalid file template argument to -ts_monitor_solution_vtk, should look like filename-%%03D.vts"); 172 if (ptr2) break; 173 } 174 ierr = PetscStrallocpy(monfilename,&filetemplate);CHKERRQ(ierr); 175 ierr = TSMonitorSet(ts,TSMonitorSolutionVTK,filetemplate,(PetscErrorCode (*)(void**))TSMonitorSolutionVTKDestroy);CHKERRQ(ierr); 176 } 177 178 ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr); 179 ierr = TSAdaptSetFromOptions(adapt);CHKERRQ(ierr); 180 181 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 182 if (ts->problem_type == TS_LINEAR) {ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);} 183 184 /* Handle specific TS options */ 185 if (ts->ops->setfromoptions) { 186 ierr = (*ts->ops->setfromoptions)(ts);CHKERRQ(ierr); 187 } 188 189 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 190 ierr = PetscObjectProcessOptionsHandlers((PetscObject)ts);CHKERRQ(ierr); 191 ierr = PetscOptionsEnd();CHKERRQ(ierr); 192 PetscFunctionReturn(0); 193 } 194 195 #undef __FUNCT__ 196 #undef __FUNCT__ 197 #define __FUNCT__ "TSComputeRHSJacobian" 198 /*@ 199 TSComputeRHSJacobian - Computes the Jacobian matrix that has been 200 set with TSSetRHSJacobian(). 201 202 Collective on TS and Vec 203 204 Input Parameters: 205 + ts - the TS context 206 . t - current timestep 207 - x - input vector 208 209 Output Parameters: 210 + A - Jacobian matrix 211 . B - optional preconditioning matrix 212 - flag - flag indicating matrix structure 213 214 Notes: 215 Most users should not need to explicitly call this routine, as it 216 is used internally within the nonlinear solvers. 217 218 See KSPSetOperators() for important information about setting the 219 flag parameter. 220 221 Level: developer 222 223 .keywords: SNES, compute, Jacobian, matrix 224 225 .seealso: TSSetRHSJacobian(), KSPSetOperators() 226 @*/ 227 PetscErrorCode TSComputeRHSJacobian(TS ts,PetscReal t,Vec X,Mat *A,Mat *B,MatStructure *flg) 228 { 229 PetscErrorCode ierr; 230 PetscInt Xstate; 231 DM dm; 232 TSDM tsdm; 233 TSRHSJacobian rhsjacobianfunc; 234 void *ctx; 235 TSIJacobian ijacobianfunc; 236 237 PetscFunctionBegin; 238 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 239 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 240 PetscCheckSameComm(ts,1,X,3); 241 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 242 ierr = DMTSGetContext(dm,&tsdm);CHKERRQ(ierr); 243 ierr = DMTSGetRHSJacobian(dm,&rhsjacobianfunc,&ctx);CHKERRQ(ierr); 244 ierr = DMTSGetIJacobian(dm,&ijacobianfunc,PETSC_NULL);CHKERRQ(ierr); 245 ierr = PetscObjectStateQuery((PetscObject)X,&Xstate);CHKERRQ(ierr); 246 if (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.X == X && ts->rhsjacobian.Xstate == Xstate))) { 247 *flg = ts->rhsjacobian.mstructure; 248 PetscFunctionReturn(0); 249 } 250 251 if (!rhsjacobianfunc && !ijacobianfunc) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()"); 252 253 if (rhsjacobianfunc) { 254 ierr = PetscLogEventBegin(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr); 255 *flg = DIFFERENT_NONZERO_PATTERN; 256 PetscStackPush("TS user Jacobian function"); 257 ierr = (*rhsjacobianfunc)(ts,t,X,A,B,flg,ctx);CHKERRQ(ierr); 258 PetscStackPop; 259 ierr = PetscLogEventEnd(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr); 260 /* make sure user returned a correct Jacobian and preconditioner */ 261 PetscValidHeaderSpecific(*A,MAT_CLASSID,4); 262 PetscValidHeaderSpecific(*B,MAT_CLASSID,5); 263 } else { 264 ierr = MatZeroEntries(*A);CHKERRQ(ierr); 265 if (*A != *B) {ierr = MatZeroEntries(*B);CHKERRQ(ierr);} 266 *flg = SAME_NONZERO_PATTERN; 267 } 268 ts->rhsjacobian.time = t; 269 ts->rhsjacobian.X = X; 270 ierr = PetscObjectStateQuery((PetscObject)X,&ts->rhsjacobian.Xstate);CHKERRQ(ierr); 271 ts->rhsjacobian.mstructure = *flg; 272 PetscFunctionReturn(0); 273 } 274 275 #undef __FUNCT__ 276 #define __FUNCT__ "TSComputeRHSFunction" 277 /*@ 278 TSComputeRHSFunction - Evaluates the right-hand-side function. 279 280 Collective on TS and Vec 281 282 Input Parameters: 283 + ts - the TS context 284 . t - current time 285 - x - state vector 286 287 Output Parameter: 288 . y - right hand side 289 290 Note: 291 Most users should not need to explicitly call this routine, as it 292 is used internally within the nonlinear solvers. 293 294 Level: developer 295 296 .keywords: TS, compute 297 298 .seealso: TSSetRHSFunction(), TSComputeIFunction() 299 @*/ 300 PetscErrorCode TSComputeRHSFunction(TS ts,PetscReal t,Vec x,Vec y) 301 { 302 PetscErrorCode ierr; 303 304 TSRHSFunction rhsfunction; 305 TSIFunction ifunction; 306 void *ctx; 307 DM dm; 308 309 PetscFunctionBegin; 310 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 311 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 312 PetscValidHeaderSpecific(y,VEC_CLASSID,4); 313 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 314 ierr = DMTSGetRHSFunction(dm,&rhsfunction,&ctx);CHKERRQ(ierr); 315 ierr = DMTSGetIFunction(dm,&ifunction,PETSC_NULL);CHKERRQ(ierr); 316 317 if (!rhsfunction && !ifunction) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 318 319 ierr = PetscLogEventBegin(TS_FunctionEval,ts,x,y,0);CHKERRQ(ierr); 320 if (rhsfunction) { 321 PetscStackPush("TS user right-hand-side function"); 322 ierr = (*rhsfunction)(ts,t,x,y,ctx);CHKERRQ(ierr); 323 PetscStackPop; 324 } else { 325 ierr = VecZeroEntries(y);CHKERRQ(ierr); 326 } 327 328 ierr = PetscLogEventEnd(TS_FunctionEval,ts,x,y,0);CHKERRQ(ierr); 329 PetscFunctionReturn(0); 330 } 331 332 #undef __FUNCT__ 333 #define __FUNCT__ "TSComputeSolutionFunction" 334 /*@ 335 TSComputeSolutionFunction - Evaluates the solution function. 336 337 Collective on TS and Vec 338 339 Input Parameters: 340 + ts - the TS context 341 - t - current time 342 343 Output Parameter: 344 . y - right hand side 345 346 Note: 347 Most users should not need to explicitly call this routine, as it 348 is used internally within the nonlinear solvers. 349 350 Level: developer 351 352 .keywords: TS, compute 353 354 .seealso: TSSetRHSFunction(), TSComputeIFunction() 355 @*/ 356 PetscErrorCode TSComputeSolutionFunction(TS ts,PetscReal t,Vec x) 357 { 358 PetscErrorCode ierr; 359 TSSolutionFunction solutionfunction; 360 void *ctx; 361 DM dm; 362 363 PetscFunctionBegin; 364 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 365 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 366 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 367 ierr = DMTSGetSolutionFunction(dm,&solutionfunction,&ctx);CHKERRQ(ierr); 368 369 if (solutionfunction) { 370 PetscStackPush("TS user right-hand-side function"); 371 ierr = (*solutionfunction)(ts,t,x,ctx);CHKERRQ(ierr); 372 PetscStackPop; 373 } 374 PetscFunctionReturn(0); 375 } 376 377 #undef __FUNCT__ 378 #define __FUNCT__ "TSGetRHSVec_Private" 379 static PetscErrorCode TSGetRHSVec_Private(TS ts,Vec *Frhs) 380 { 381 Vec F; 382 PetscErrorCode ierr; 383 384 PetscFunctionBegin; 385 *Frhs = PETSC_NULL; 386 ierr = TSGetIFunction(ts,&F,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 387 if (!ts->Frhs) { 388 ierr = VecDuplicate(F,&ts->Frhs);CHKERRQ(ierr); 389 } 390 *Frhs = ts->Frhs; 391 PetscFunctionReturn(0); 392 } 393 394 #undef __FUNCT__ 395 #define __FUNCT__ "TSGetRHSMats_Private" 396 static PetscErrorCode TSGetRHSMats_Private(TS ts,Mat *Arhs,Mat *Brhs) 397 { 398 Mat A,B; 399 PetscErrorCode ierr; 400 401 PetscFunctionBegin; 402 ierr = TSGetIJacobian(ts,&A,&B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 403 if (Arhs) { 404 if (!ts->Arhs) { 405 ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&ts->Arhs);CHKERRQ(ierr); 406 } 407 *Arhs = ts->Arhs; 408 } 409 if (Brhs) { 410 if (!ts->Brhs) { 411 ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&ts->Brhs);CHKERRQ(ierr); 412 } 413 *Brhs = ts->Brhs; 414 } 415 PetscFunctionReturn(0); 416 } 417 418 #undef __FUNCT__ 419 #define __FUNCT__ "TSComputeIFunction" 420 /*@ 421 TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,X,Xdot)=0 422 423 Collective on TS and Vec 424 425 Input Parameters: 426 + ts - the TS context 427 . t - current time 428 . X - state vector 429 . Xdot - time derivative of state vector 430 - imex - flag indicates if the method is IMEX so that the RHSFunction should be kept separate 431 432 Output Parameter: 433 . Y - right hand side 434 435 Note: 436 Most users should not need to explicitly call this routine, as it 437 is used internally within the nonlinear solvers. 438 439 If the user did did not write their equations in implicit form, this 440 function recasts them in implicit form. 441 442 Level: developer 443 444 .keywords: TS, compute 445 446 .seealso: TSSetIFunction(), TSComputeRHSFunction() 447 @*/ 448 PetscErrorCode TSComputeIFunction(TS ts,PetscReal t,Vec X,Vec Xdot,Vec Y,PetscBool imex) 449 { 450 PetscErrorCode ierr; 451 TSIFunction ifunction; 452 TSRHSFunction rhsfunction; 453 void *ctx; 454 DM dm; 455 456 PetscFunctionBegin; 457 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 458 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 459 PetscValidHeaderSpecific(Xdot,VEC_CLASSID,4); 460 PetscValidHeaderSpecific(Y,VEC_CLASSID,5); 461 462 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 463 ierr = DMTSGetIFunction(dm,&ifunction,&ctx);CHKERRQ(ierr); 464 ierr = DMTSGetRHSFunction(dm,&rhsfunction,PETSC_NULL);CHKERRQ(ierr); 465 466 if (!rhsfunction && !ifunction) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 467 468 ierr = PetscLogEventBegin(TS_FunctionEval,ts,X,Xdot,Y);CHKERRQ(ierr); 469 if (ifunction) { 470 PetscStackPush("TS user implicit function"); 471 ierr = (*ifunction)(ts,t,X,Xdot,Y,ctx);CHKERRQ(ierr); 472 PetscStackPop; 473 } 474 if (imex) { 475 if (!ifunction) { 476 ierr = VecCopy(Xdot,Y);CHKERRQ(ierr); 477 } 478 } else if (rhsfunction) { 479 if (ifunction) { 480 Vec Frhs; 481 ierr = TSGetRHSVec_Private(ts,&Frhs);CHKERRQ(ierr); 482 ierr = TSComputeRHSFunction(ts,t,X,Frhs);CHKERRQ(ierr); 483 ierr = VecAXPY(Y,-1,Frhs);CHKERRQ(ierr); 484 } else { 485 ierr = TSComputeRHSFunction(ts,t,X,Y);CHKERRQ(ierr); 486 ierr = VecAYPX(Y,-1,Xdot);CHKERRQ(ierr); 487 } 488 } 489 ierr = PetscLogEventEnd(TS_FunctionEval,ts,X,Xdot,Y);CHKERRQ(ierr); 490 PetscFunctionReturn(0); 491 } 492 493 #undef __FUNCT__ 494 #define __FUNCT__ "TSComputeIJacobian" 495 /*@ 496 TSComputeIJacobian - Evaluates the Jacobian of the DAE 497 498 Collective on TS and Vec 499 500 Input 501 Input Parameters: 502 + ts - the TS context 503 . t - current timestep 504 . X - state vector 505 . Xdot - time derivative of state vector 506 . shift - shift to apply, see note below 507 - imex - flag indicates if the method is IMEX so that the RHSJacobian should be kept separate 508 509 Output Parameters: 510 + A - Jacobian matrix 511 . B - optional preconditioning matrix 512 - flag - flag indicating matrix structure 513 514 Notes: 515 If F(t,X,Xdot)=0 is the DAE, the required Jacobian is 516 517 dF/dX + shift*dF/dXdot 518 519 Most users should not need to explicitly call this routine, as it 520 is used internally within the nonlinear solvers. 521 522 Level: developer 523 524 .keywords: TS, compute, Jacobian, matrix 525 526 .seealso: TSSetIJacobian() 527 @*/ 528 PetscErrorCode TSComputeIJacobian(TS ts,PetscReal t,Vec X,Vec Xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,PetscBool imex) 529 { 530 PetscInt Xstate, Xdotstate; 531 PetscErrorCode ierr; 532 TSIJacobian ijacobian; 533 TSRHSJacobian rhsjacobian; 534 DM dm; 535 void *ctx; 536 537 PetscFunctionBegin; 538 539 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 540 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 541 PetscValidHeaderSpecific(Xdot,VEC_CLASSID,4); 542 PetscValidPointer(A,6); 543 PetscValidHeaderSpecific(*A,MAT_CLASSID,6); 544 PetscValidPointer(B,7); 545 PetscValidHeaderSpecific(*B,MAT_CLASSID,7); 546 PetscValidPointer(flg,8); 547 548 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 549 ierr = DMTSGetIJacobian(dm,&ijacobian,&ctx);CHKERRQ(ierr); 550 ierr = DMTSGetRHSJacobian(dm,&rhsjacobian,PETSC_NULL);CHKERRQ(ierr); 551 552 ierr = PetscObjectStateQuery((PetscObject)X,&Xstate);CHKERRQ(ierr); 553 ierr = PetscObjectStateQuery((PetscObject)Xdot,&Xdotstate);CHKERRQ(ierr); 554 if (ts->ijacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->ijacobian.X == X && ts->ijacobian.Xstate == Xstate && ts->ijacobian.Xdot == Xdot && ts->ijacobian.Xdotstate == Xdotstate && ts->ijacobian.imex == imex))) { 555 *flg = ts->ijacobian.mstructure; 556 ierr = MatScale(*A, shift / ts->ijacobian.shift);CHKERRQ(ierr); 557 PetscFunctionReturn(0); 558 } 559 560 if (!rhsjacobian && !ijacobian) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()"); 561 562 *flg = SAME_NONZERO_PATTERN; /* In case we're solving a linear problem in which case it wouldn't get initialized below. */ 563 ierr = PetscLogEventBegin(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr); 564 if (ijacobian) { 565 *flg = DIFFERENT_NONZERO_PATTERN; 566 PetscStackPush("TS user implicit Jacobian"); 567 ierr = (*ijacobian)(ts,t,X,Xdot,shift,A,B,flg,ctx);CHKERRQ(ierr); 568 PetscStackPop; 569 /* make sure user returned a correct Jacobian and preconditioner */ 570 PetscValidHeaderSpecific(*A,MAT_CLASSID,4); 571 PetscValidHeaderSpecific(*B,MAT_CLASSID,5); 572 } 573 if (imex) { 574 if (!ijacobian) { /* system was written as Xdot = F(t,X) */ 575 ierr = MatZeroEntries(*A);CHKERRQ(ierr); 576 ierr = MatShift(*A,shift);CHKERRQ(ierr); 577 if (*A != *B) { 578 ierr = MatZeroEntries(*B);CHKERRQ(ierr); 579 ierr = MatShift(*B,shift);CHKERRQ(ierr); 580 } 581 *flg = SAME_PRECONDITIONER; 582 } 583 } else { 584 if (!ijacobian) { 585 ierr = TSComputeRHSJacobian(ts,t,X,A,B,flg);CHKERRQ(ierr); 586 ierr = MatScale(*A,-1);CHKERRQ(ierr); 587 ierr = MatShift(*A,shift);CHKERRQ(ierr); 588 if (*A != *B) { 589 ierr = MatScale(*B,-1);CHKERRQ(ierr); 590 ierr = MatShift(*B,shift);CHKERRQ(ierr); 591 } 592 } else if (rhsjacobian) { 593 Mat Arhs,Brhs; 594 MatStructure axpy,flg2 = DIFFERENT_NONZERO_PATTERN; 595 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 596 ierr = TSComputeRHSJacobian(ts,t,X,&Arhs,&Brhs,&flg2);CHKERRQ(ierr); 597 axpy = (*flg == flg2) ? SAME_NONZERO_PATTERN : DIFFERENT_NONZERO_PATTERN; 598 ierr = MatAXPY(*A,-1,Arhs,axpy);CHKERRQ(ierr); 599 if (*A != *B) { 600 ierr = MatAXPY(*B,-1,Brhs,axpy);CHKERRQ(ierr); 601 } 602 *flg = PetscMin(*flg,flg2); 603 } 604 } 605 606 ts->ijacobian.time = t; 607 ts->ijacobian.X = X; 608 ts->ijacobian.Xdot = Xdot; 609 ierr = PetscObjectStateQuery((PetscObject)X,&ts->ijacobian.Xstate);CHKERRQ(ierr); 610 ierr = PetscObjectStateQuery((PetscObject)Xdot,&ts->ijacobian.Xdotstate);CHKERRQ(ierr); 611 ts->ijacobian.shift = shift; 612 ts->ijacobian.imex = imex; 613 ts->ijacobian.mstructure = *flg; 614 ierr = PetscLogEventEnd(TS_JacobianEval,ts,X,*A,*B);CHKERRQ(ierr); 615 PetscFunctionReturn(0); 616 } 617 618 #undef __FUNCT__ 619 #define __FUNCT__ "TSSetRHSFunction" 620 /*@C 621 TSSetRHSFunction - Sets the routine for evaluating the function, 622 F(t,u), where U_t = F(t,u). 623 624 Logically Collective on TS 625 626 Input Parameters: 627 + ts - the TS context obtained from TSCreate() 628 . r - vector to put the computed right hand side (or PETSC_NULL to have it created) 629 . f - routine for evaluating the right-hand-side function 630 - ctx - [optional] user-defined context for private data for the 631 function evaluation routine (may be PETSC_NULL) 632 633 Calling sequence of func: 634 $ func (TS ts,PetscReal t,Vec u,Vec F,void *ctx); 635 636 + t - current timestep 637 . u - input vector 638 . F - function vector 639 - ctx - [optional] user-defined function context 640 641 Level: beginner 642 643 .keywords: TS, timestep, set, right-hand-side, function 644 645 .seealso: TSSetRHSJacobian(), TSSetIJacobian() 646 @*/ 647 PetscErrorCode TSSetRHSFunction(TS ts,Vec r,PetscErrorCode (*f)(TS,PetscReal,Vec,Vec,void*),void *ctx) 648 { 649 PetscErrorCode ierr; 650 SNES snes; 651 Vec ralloc = PETSC_NULL; 652 DM dm; 653 654 PetscFunctionBegin; 655 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 656 if (r) PetscValidHeaderSpecific(r,VEC_CLASSID,2); 657 658 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 659 ierr = DMTSSetRHSFunction(dm,f,ctx);CHKERRQ(ierr); 660 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 661 if (!r && !ts->dm && ts->vec_sol) { 662 ierr = VecDuplicate(ts->vec_sol,&ralloc);CHKERRQ(ierr); 663 r = ralloc; 664 } 665 ierr = SNESSetFunction(snes,r,SNESTSFormFunction,ts);CHKERRQ(ierr); 666 ierr = VecDestroy(&ralloc);CHKERRQ(ierr); 667 PetscFunctionReturn(0); 668 } 669 670 #undef __FUNCT__ 671 #define __FUNCT__ "TSSetSolutionFunction" 672 /*@C 673 TSSetSolutionFunction - Provide a function that computes the solution of the ODE 674 675 Logically Collective on TS 676 677 Input Parameters: 678 + ts - the TS context obtained from TSCreate() 679 . f - routine for evaluating the solution 680 - ctx - [optional] user-defined context for private data for the 681 function evaluation routine (may be PETSC_NULL) 682 683 Calling sequence of func: 684 $ func (TS ts,PetscReal t,Vec u,void *ctx); 685 686 + t - current timestep 687 . u - output vector 688 - ctx - [optional] user-defined function context 689 690 Level: beginner 691 692 .keywords: TS, timestep, set, right-hand-side, function 693 694 .seealso: TSSetRHSJacobian(), TSSetIJacobian() 695 @*/ 696 PetscErrorCode TSSetSolutionFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,void*),void *ctx) 697 { 698 PetscErrorCode ierr; 699 DM dm; 700 701 PetscFunctionBegin; 702 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 703 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 704 ierr = DMTSSetSolutionFunction(dm,f,ctx);CHKERRQ(ierr); 705 PetscFunctionReturn(0); 706 } 707 708 #undef __FUNCT__ 709 #define __FUNCT__ "TSSetRHSJacobian" 710 /*@C 711 TSSetRHSJacobian - Sets the function to compute the Jacobian of F, 712 where U_t = F(U,t), as well as the location to store the matrix. 713 714 Logically Collective on TS 715 716 Input Parameters: 717 + ts - the TS context obtained from TSCreate() 718 . A - Jacobian matrix 719 . B - preconditioner matrix (usually same as A) 720 . f - the Jacobian evaluation routine 721 - ctx - [optional] user-defined context for private data for the 722 Jacobian evaluation routine (may be PETSC_NULL) 723 724 Calling sequence of func: 725 $ func (TS ts,PetscReal t,Vec u,Mat *A,Mat *B,MatStructure *flag,void *ctx); 726 727 + t - current timestep 728 . u - input vector 729 . A - matrix A, where U_t = A(t)u 730 . B - preconditioner matrix, usually the same as A 731 . flag - flag indicating information about the preconditioner matrix 732 structure (same as flag in KSPSetOperators()) 733 - ctx - [optional] user-defined context for matrix evaluation routine 734 735 Notes: 736 See KSPSetOperators() for important information about setting the flag 737 output parameter in the routine func(). Be sure to read this information! 738 739 The routine func() takes Mat * as the matrix arguments rather than Mat. 740 This allows the matrix evaluation routine to replace A and/or B with a 741 completely new matrix structure (not just different matrix elements) 742 when appropriate, for instance, if the nonzero structure is changing 743 throughout the global iterations. 744 745 Level: beginner 746 747 .keywords: TS, timestep, set, right-hand-side, Jacobian 748 749 .seealso: SNESDefaultComputeJacobianColor(), TSSetRHSFunction() 750 751 @*/ 752 PetscErrorCode TSSetRHSJacobian(TS ts,Mat A,Mat B,TSRHSJacobian f,void *ctx) 753 { 754 PetscErrorCode ierr; 755 SNES snes; 756 DM dm; 757 TSIJacobian ijacobian; 758 759 PetscFunctionBegin; 760 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 761 if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 762 if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 763 if (A) PetscCheckSameComm(ts,1,A,2); 764 if (B) PetscCheckSameComm(ts,1,B,3); 765 766 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 767 ierr = DMTSSetRHSJacobian(dm,f,ctx);CHKERRQ(ierr); 768 ierr = DMTSGetIJacobian(dm,&ijacobian,PETSC_NULL);CHKERRQ(ierr); 769 770 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 771 if (!ijacobian) { 772 ierr = SNESSetJacobian(snes,A,B,SNESTSFormJacobian,ts);CHKERRQ(ierr); 773 } 774 if (A) { 775 ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 776 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 777 ts->Arhs = A; 778 } 779 if (B) { 780 ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 781 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 782 ts->Brhs = B; 783 } 784 PetscFunctionReturn(0); 785 } 786 787 788 #undef __FUNCT__ 789 #define __FUNCT__ "TSSetIFunction" 790 /*@C 791 TSSetIFunction - Set the function to compute F(t,U,U_t) where F = 0 is the DAE to be solved. 792 793 Logically Collective on TS 794 795 Input Parameters: 796 + ts - the TS context obtained from TSCreate() 797 . r - vector to hold the residual (or PETSC_NULL to have it created internally) 798 . f - the function evaluation routine 799 - ctx - user-defined context for private data for the function evaluation routine (may be PETSC_NULL) 800 801 Calling sequence of f: 802 $ f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx); 803 804 + t - time at step/stage being solved 805 . u - state vector 806 . u_t - time derivative of state vector 807 . F - function vector 808 - ctx - [optional] user-defined context for matrix evaluation routine 809 810 Important: 811 The user MUST call either this routine, TSSetRHSFunction(). This routine must be used when not solving an ODE, for example a DAE. 812 813 Level: beginner 814 815 .keywords: TS, timestep, set, DAE, Jacobian 816 817 .seealso: TSSetRHSJacobian(), TSSetRHSFunction(), TSSetIJacobian() 818 @*/ 819 PetscErrorCode TSSetIFunction(TS ts,Vec res,TSIFunction f,void *ctx) 820 { 821 PetscErrorCode ierr; 822 SNES snes; 823 Vec resalloc = PETSC_NULL; 824 DM dm; 825 826 PetscFunctionBegin; 827 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 828 if (res) PetscValidHeaderSpecific(res,VEC_CLASSID,2); 829 830 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 831 ierr = DMTSSetIFunction(dm,f,ctx);CHKERRQ(ierr); 832 833 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 834 if (!res && !ts->dm && ts->vec_sol) { 835 ierr = VecDuplicate(ts->vec_sol,&resalloc);CHKERRQ(ierr); 836 res = resalloc; 837 } 838 ierr = SNESSetFunction(snes,res,SNESTSFormFunction,ts);CHKERRQ(ierr); 839 ierr = VecDestroy(&resalloc);CHKERRQ(ierr); 840 841 PetscFunctionReturn(0); 842 } 843 844 #undef __FUNCT__ 845 #define __FUNCT__ "TSGetIFunction" 846 /*@C 847 TSGetIFunction - Returns the vector where the implicit residual is stored and the function/contex to compute it. 848 849 Not Collective 850 851 Input Parameter: 852 . ts - the TS context 853 854 Output Parameter: 855 + r - vector to hold residual (or PETSC_NULL) 856 . func - the function to compute residual (or PETSC_NULL) 857 - ctx - the function context (or PETSC_NULL) 858 859 Level: advanced 860 861 .keywords: TS, nonlinear, get, function 862 863 .seealso: TSSetIFunction(), SNESGetFunction() 864 @*/ 865 PetscErrorCode TSGetIFunction(TS ts,Vec *r,TSIFunction *func,void **ctx) 866 { 867 PetscErrorCode ierr; 868 SNES snes; 869 DM dm; 870 871 PetscFunctionBegin; 872 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 873 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 874 ierr = SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 875 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 876 ierr = DMTSGetIFunction(dm,func,ctx);CHKERRQ(ierr); 877 PetscFunctionReturn(0); 878 } 879 880 #undef __FUNCT__ 881 #define __FUNCT__ "TSGetRHSFunction" 882 /*@C 883 TSGetRHSFunction - Returns the vector where the right hand side is stored and the function/context to compute it. 884 885 Not Collective 886 887 Input Parameter: 888 . ts - the TS context 889 890 Output Parameter: 891 + r - vector to hold computed right hand side (or PETSC_NULL) 892 . func - the function to compute right hand side (or PETSC_NULL) 893 - ctx - the function context (or PETSC_NULL) 894 895 Level: advanced 896 897 .keywords: TS, nonlinear, get, function 898 899 .seealso: TSSetRhsfunction(), SNESGetFunction() 900 @*/ 901 PetscErrorCode TSGetRHSFunction(TS ts,Vec *r,TSRHSFunction *func,void **ctx) 902 { 903 PetscErrorCode ierr; 904 SNES snes; 905 DM dm; 906 907 PetscFunctionBegin; 908 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 909 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 910 ierr = SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 911 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 912 ierr = DMTSGetRHSFunction(dm,func,ctx);CHKERRQ(ierr); 913 PetscFunctionReturn(0); 914 } 915 916 #undef __FUNCT__ 917 #define __FUNCT__ "TSSetIJacobian" 918 /*@C 919 TSSetIJacobian - Set the function to compute the matrix dF/dU + a*dF/dU_t where F(t,U,U_t) is the function 920 you provided with TSSetIFunction(). 921 922 Logically Collective on TS 923 924 Input Parameters: 925 + ts - the TS context obtained from TSCreate() 926 . A - Jacobian matrix 927 . B - preconditioning matrix for A (may be same as A) 928 . f - the Jacobian evaluation routine 929 - ctx - user-defined context for private data for the Jacobian evaluation routine (may be PETSC_NULL) 930 931 Calling sequence of f: 932 $ f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat *A,Mat *B,MatStructure *flag,void *ctx); 933 934 + t - time at step/stage being solved 935 . U - state vector 936 . U_t - time derivative of state vector 937 . a - shift 938 . A - Jacobian of G(U) = F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t 939 . B - preconditioning matrix for A, may be same as A 940 . flag - flag indicating information about the preconditioner matrix 941 structure (same as flag in KSPSetOperators()) 942 - ctx - [optional] user-defined context for matrix evaluation routine 943 944 Notes: 945 The matrices A and B are exactly the matrices that are used by SNES for the nonlinear solve. 946 947 The matrix dF/dU + a*dF/dU_t you provide turns out to be 948 the Jacobian of G(U) = F(t,U,W+a*U) where F(t,U,U_t) = 0 is the DAE to be solved. 949 The time integrator internally approximates U_t by W+a*U where the positive "shift" 950 a and vector W depend on the integration method, step size, and past states. For example with 951 the backward Euler method a = 1/dt and W = -a*U(previous timestep) so 952 W + a*U = a*(U - U(previous timestep)) = (U - U(previous timestep))/dt 953 954 Level: beginner 955 956 .keywords: TS, timestep, DAE, Jacobian 957 958 .seealso: TSSetIFunction(), TSSetRHSJacobian(), SNESDefaultComputeJacobianColor(), SNESDefaultComputeJacobian() 959 960 @*/ 961 PetscErrorCode TSSetIJacobian(TS ts,Mat A,Mat B,TSIJacobian f,void *ctx) 962 { 963 PetscErrorCode ierr; 964 SNES snes; 965 DM dm; 966 967 PetscFunctionBegin; 968 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 969 if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 970 if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 971 if (A) PetscCheckSameComm(ts,1,A,2); 972 if (B) PetscCheckSameComm(ts,1,B,3); 973 974 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 975 ierr = DMTSSetIJacobian(dm,f,ctx);CHKERRQ(ierr); 976 977 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 978 ierr = SNESSetJacobian(snes,A,B,SNESTSFormJacobian,ts);CHKERRQ(ierr); 979 PetscFunctionReturn(0); 980 } 981 982 #undef __FUNCT__ 983 #define __FUNCT__ "TSView" 984 /*@C 985 TSView - Prints the TS data structure. 986 987 Collective on TS 988 989 Input Parameters: 990 + ts - the TS context obtained from TSCreate() 991 - viewer - visualization context 992 993 Options Database Key: 994 . -ts_view - calls TSView() at end of TSStep() 995 996 Notes: 997 The available visualization contexts include 998 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 999 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 1000 output where only the first processor opens 1001 the file. All other processors send their 1002 data to the first processor to print. 1003 1004 The user can open an alternative visualization context with 1005 PetscViewerASCIIOpen() - output to a specified file. 1006 1007 Level: beginner 1008 1009 .keywords: TS, timestep, view 1010 1011 .seealso: PetscViewerASCIIOpen() 1012 @*/ 1013 PetscErrorCode TSView(TS ts,PetscViewer viewer) 1014 { 1015 PetscErrorCode ierr; 1016 TSType type; 1017 PetscBool iascii,isstring,isundials; 1018 1019 PetscFunctionBegin; 1020 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1021 if (!viewer) { 1022 ierr = PetscViewerASCIIGetStdout(((PetscObject)ts)->comm,&viewer);CHKERRQ(ierr); 1023 } 1024 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1025 PetscCheckSameComm(ts,1,viewer,2); 1026 1027 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1028 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 1029 if (iascii) { 1030 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ts,viewer,"TS Object");CHKERRQ(ierr); 1031 ierr = PetscViewerASCIIPrintf(viewer," maximum steps=%D\n",ts->max_steps);CHKERRQ(ierr); 1032 ierr = PetscViewerASCIIPrintf(viewer," maximum time=%G\n",ts->max_time);CHKERRQ(ierr); 1033 if (ts->problem_type == TS_NONLINEAR) { 1034 ierr = PetscViewerASCIIPrintf(viewer," total number of nonlinear solver iterations=%D\n",ts->snes_its);CHKERRQ(ierr); 1035 ierr = PetscViewerASCIIPrintf(viewer," total number of nonlinear solve failures=%D\n",ts->num_snes_failures);CHKERRQ(ierr); 1036 } 1037 ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",ts->ksp_its);CHKERRQ(ierr); 1038 ierr = PetscViewerASCIIPrintf(viewer," total number of rejected steps=%D\n",ts->reject);CHKERRQ(ierr); 1039 if (ts->ops->view) { 1040 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1041 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 1042 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1043 } 1044 } else if (isstring) { 1045 ierr = TSGetType(ts,&type);CHKERRQ(ierr); 1046 ierr = PetscViewerStringSPrintf(viewer," %-7.7s",type);CHKERRQ(ierr); 1047 } 1048 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1049 ierr = PetscObjectTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials);CHKERRQ(ierr); 1050 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1051 PetscFunctionReturn(0); 1052 } 1053 1054 1055 #undef __FUNCT__ 1056 #define __FUNCT__ "TSSetApplicationContext" 1057 /*@ 1058 TSSetApplicationContext - Sets an optional user-defined context for 1059 the timesteppers. 1060 1061 Logically Collective on TS 1062 1063 Input Parameters: 1064 + ts - the TS context obtained from TSCreate() 1065 - usrP - optional user context 1066 1067 Level: intermediate 1068 1069 .keywords: TS, timestep, set, application, context 1070 1071 .seealso: TSGetApplicationContext() 1072 @*/ 1073 PetscErrorCode TSSetApplicationContext(TS ts,void *usrP) 1074 { 1075 PetscFunctionBegin; 1076 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1077 ts->user = usrP; 1078 PetscFunctionReturn(0); 1079 } 1080 1081 #undef __FUNCT__ 1082 #define __FUNCT__ "TSGetApplicationContext" 1083 /*@ 1084 TSGetApplicationContext - Gets the user-defined context for the 1085 timestepper. 1086 1087 Not Collective 1088 1089 Input Parameter: 1090 . ts - the TS context obtained from TSCreate() 1091 1092 Output Parameter: 1093 . usrP - user context 1094 1095 Level: intermediate 1096 1097 .keywords: TS, timestep, get, application, context 1098 1099 .seealso: TSSetApplicationContext() 1100 @*/ 1101 PetscErrorCode TSGetApplicationContext(TS ts,void *usrP) 1102 { 1103 PetscFunctionBegin; 1104 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1105 *(void**)usrP = ts->user; 1106 PetscFunctionReturn(0); 1107 } 1108 1109 #undef __FUNCT__ 1110 #define __FUNCT__ "TSGetTimeStepNumber" 1111 /*@ 1112 TSGetTimeStepNumber - Gets the number of time steps completed. 1113 1114 Not Collective 1115 1116 Input Parameter: 1117 . ts - the TS context obtained from TSCreate() 1118 1119 Output Parameter: 1120 . iter - number of steps completed so far 1121 1122 Level: intermediate 1123 1124 .keywords: TS, timestep, get, iteration, number 1125 .seealso: TSGetTime(), TSGetTimeStep(), TSSetPreStep(), TSSetPreStage(), TSSetPostStep() 1126 @*/ 1127 PetscErrorCode TSGetTimeStepNumber(TS ts,PetscInt* iter) 1128 { 1129 PetscFunctionBegin; 1130 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1131 PetscValidIntPointer(iter,2); 1132 *iter = ts->steps; 1133 PetscFunctionReturn(0); 1134 } 1135 1136 #undef __FUNCT__ 1137 #define __FUNCT__ "TSSetInitialTimeStep" 1138 /*@ 1139 TSSetInitialTimeStep - Sets the initial timestep to be used, 1140 as well as the initial time. 1141 1142 Logically Collective on TS 1143 1144 Input Parameters: 1145 + ts - the TS context obtained from TSCreate() 1146 . initial_time - the initial time 1147 - time_step - the size of the timestep 1148 1149 Level: intermediate 1150 1151 .seealso: TSSetTimeStep(), TSGetTimeStep() 1152 1153 .keywords: TS, set, initial, timestep 1154 @*/ 1155 PetscErrorCode TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step) 1156 { 1157 PetscErrorCode ierr; 1158 1159 PetscFunctionBegin; 1160 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1161 ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr); 1162 ierr = TSSetTime(ts,initial_time);CHKERRQ(ierr); 1163 PetscFunctionReturn(0); 1164 } 1165 1166 #undef __FUNCT__ 1167 #define __FUNCT__ "TSSetTimeStep" 1168 /*@ 1169 TSSetTimeStep - Allows one to reset the timestep at any time, 1170 useful for simple pseudo-timestepping codes. 1171 1172 Logically Collective on TS 1173 1174 Input Parameters: 1175 + ts - the TS context obtained from TSCreate() 1176 - time_step - the size of the timestep 1177 1178 Level: intermediate 1179 1180 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 1181 1182 .keywords: TS, set, timestep 1183 @*/ 1184 PetscErrorCode TSSetTimeStep(TS ts,PetscReal time_step) 1185 { 1186 PetscFunctionBegin; 1187 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1188 PetscValidLogicalCollectiveReal(ts,time_step,2); 1189 ts->time_step = time_step; 1190 ts->time_step_orig = time_step; 1191 PetscFunctionReturn(0); 1192 } 1193 1194 #undef __FUNCT__ 1195 #define __FUNCT__ "TSSetExactFinalTime" 1196 /*@ 1197 TSSetExactFinalTime - Determines whether to interpolate solution to the 1198 exact final time requested by the user or just returns it at the final time 1199 it computed. 1200 1201 Logically Collective on TS 1202 1203 Input Parameter: 1204 + ts - the time-step context 1205 - ft - PETSC_TRUE if interpolates, else PETSC_FALSE 1206 1207 Level: beginner 1208 1209 .seealso: TSSetDuration() 1210 @*/ 1211 PetscErrorCode TSSetExactFinalTime(TS ts,PetscBool flg) 1212 { 1213 1214 PetscFunctionBegin; 1215 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1216 PetscValidLogicalCollectiveBool(ts,flg,2); 1217 ts->exact_final_time = flg; 1218 PetscFunctionReturn(0); 1219 } 1220 1221 #undef __FUNCT__ 1222 #define __FUNCT__ "TSGetTimeStep" 1223 /*@ 1224 TSGetTimeStep - Gets the current timestep size. 1225 1226 Not Collective 1227 1228 Input Parameter: 1229 . ts - the TS context obtained from TSCreate() 1230 1231 Output Parameter: 1232 . dt - the current timestep size 1233 1234 Level: intermediate 1235 1236 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 1237 1238 .keywords: TS, get, timestep 1239 @*/ 1240 PetscErrorCode TSGetTimeStep(TS ts,PetscReal* dt) 1241 { 1242 PetscFunctionBegin; 1243 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1244 PetscValidRealPointer(dt,2); 1245 *dt = ts->time_step; 1246 PetscFunctionReturn(0); 1247 } 1248 1249 #undef __FUNCT__ 1250 #define __FUNCT__ "TSGetSolution" 1251 /*@ 1252 TSGetSolution - Returns the solution at the present timestep. It 1253 is valid to call this routine inside the function that you are evaluating 1254 in order to move to the new timestep. This vector not changed until 1255 the solution at the next timestep has been calculated. 1256 1257 Not Collective, but Vec returned is parallel if TS is parallel 1258 1259 Input Parameter: 1260 . ts - the TS context obtained from TSCreate() 1261 1262 Output Parameter: 1263 . v - the vector containing the solution 1264 1265 Level: intermediate 1266 1267 .seealso: TSGetTimeStep() 1268 1269 .keywords: TS, timestep, get, solution 1270 @*/ 1271 PetscErrorCode TSGetSolution(TS ts,Vec *v) 1272 { 1273 PetscFunctionBegin; 1274 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1275 PetscValidPointer(v,2); 1276 *v = ts->vec_sol; 1277 PetscFunctionReturn(0); 1278 } 1279 1280 /* ----- Routines to initialize and destroy a timestepper ---- */ 1281 #undef __FUNCT__ 1282 #define __FUNCT__ "TSSetProblemType" 1283 /*@ 1284 TSSetProblemType - Sets the type of problem to be solved. 1285 1286 Not collective 1287 1288 Input Parameters: 1289 + ts - The TS 1290 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 1291 .vb 1292 U_t = A U 1293 U_t = A(t) U 1294 U_t = F(t,U) 1295 .ve 1296 1297 Level: beginner 1298 1299 .keywords: TS, problem type 1300 .seealso: TSSetUp(), TSProblemType, TS 1301 @*/ 1302 PetscErrorCode TSSetProblemType(TS ts, TSProblemType type) 1303 { 1304 PetscErrorCode ierr; 1305 1306 PetscFunctionBegin; 1307 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1308 ts->problem_type = type; 1309 if (type == TS_LINEAR) { 1310 SNES snes; 1311 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1312 ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr); 1313 } 1314 PetscFunctionReturn(0); 1315 } 1316 1317 #undef __FUNCT__ 1318 #define __FUNCT__ "TSGetProblemType" 1319 /*@C 1320 TSGetProblemType - Gets the type of problem to be solved. 1321 1322 Not collective 1323 1324 Input Parameter: 1325 . ts - The TS 1326 1327 Output Parameter: 1328 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 1329 .vb 1330 M U_t = A U 1331 M(t) U_t = A(t) U 1332 U_t = F(t,U) 1333 .ve 1334 1335 Level: beginner 1336 1337 .keywords: TS, problem type 1338 .seealso: TSSetUp(), TSProblemType, TS 1339 @*/ 1340 PetscErrorCode TSGetProblemType(TS ts, TSProblemType *type) 1341 { 1342 PetscFunctionBegin; 1343 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1344 PetscValidIntPointer(type,2); 1345 *type = ts->problem_type; 1346 PetscFunctionReturn(0); 1347 } 1348 1349 #undef __FUNCT__ 1350 #define __FUNCT__ "TSSetUp" 1351 /*@ 1352 TSSetUp - Sets up the internal data structures for the later use 1353 of a timestepper. 1354 1355 Collective on TS 1356 1357 Input Parameter: 1358 . ts - the TS context obtained from TSCreate() 1359 1360 Notes: 1361 For basic use of the TS solvers the user need not explicitly call 1362 TSSetUp(), since these actions will automatically occur during 1363 the call to TSStep(). However, if one wishes to control this 1364 phase separately, TSSetUp() should be called after TSCreate() 1365 and optional routines of the form TSSetXXX(), but before TSStep(). 1366 1367 Level: advanced 1368 1369 .keywords: TS, timestep, setup 1370 1371 .seealso: TSCreate(), TSStep(), TSDestroy() 1372 @*/ 1373 PetscErrorCode TSSetUp(TS ts) 1374 { 1375 PetscErrorCode ierr; 1376 DM dm; 1377 PetscErrorCode (*func)(SNES,Vec,Vec,void*); 1378 PetscErrorCode (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 1379 TSIJacobian ijac; 1380 TSRHSJacobian rhsjac; 1381 1382 PetscFunctionBegin; 1383 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1384 if (ts->setupcalled) PetscFunctionReturn(0); 1385 1386 if (!((PetscObject)ts)->type_name) { 1387 ierr = TSSetType(ts,TSEULER);CHKERRQ(ierr); 1388 } 1389 if (ts->exact_final_time == PETSC_DECIDE) ts->exact_final_time = PETSC_FALSE; 1390 1391 if (!ts->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first"); 1392 1393 ierr = TSGetAdapt(ts,&ts->adapt);CHKERRQ(ierr); 1394 1395 if (ts->ops->setup) { 1396 ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr); 1397 } 1398 1399 /* in the case where we've set a DMTSFunction or what have you, we need the default SNESFunction 1400 to be set right but can't do it elsewhere due to the overreliance on ctx=ts. 1401 */ 1402 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1403 ierr = DMSNESGetFunction(dm,&func,PETSC_NULL);CHKERRQ(ierr); 1404 if (!func) { 1405 ierr =DMSNESSetFunction(dm,SNESTSFormFunction,ts);CHKERRQ(ierr); 1406 } 1407 /* if the SNES doesn't have a jacobian set and the TS has an ijacobian or rhsjacobian set, set the SNES to use it. 1408 Otherwise, the SNES will use coloring internally to form the Jacobian. 1409 */ 1410 ierr = DMSNESGetJacobian(dm,&jac,PETSC_NULL);CHKERRQ(ierr); 1411 ierr = DMTSGetIJacobian(dm,&ijac,PETSC_NULL);CHKERRQ(ierr); 1412 ierr = DMTSGetRHSJacobian(dm,&rhsjac,PETSC_NULL);CHKERRQ(ierr); 1413 if (!jac && (ijac || rhsjac)) { 1414 ierr = DMSNESSetJacobian(dm,SNESTSFormJacobian,ts);CHKERRQ(ierr); 1415 } 1416 ts->setupcalled = PETSC_TRUE; 1417 PetscFunctionReturn(0); 1418 } 1419 1420 #undef __FUNCT__ 1421 #define __FUNCT__ "TSReset" 1422 /*@ 1423 TSReset - Resets a TS context and removes any allocated Vecs and Mats. 1424 1425 Collective on TS 1426 1427 Input Parameter: 1428 . ts - the TS context obtained from TSCreate() 1429 1430 Level: beginner 1431 1432 .keywords: TS, timestep, reset 1433 1434 .seealso: TSCreate(), TSSetup(), TSDestroy() 1435 @*/ 1436 PetscErrorCode TSReset(TS ts) 1437 { 1438 PetscErrorCode ierr; 1439 1440 PetscFunctionBegin; 1441 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1442 if (ts->ops->reset) { 1443 ierr = (*ts->ops->reset)(ts);CHKERRQ(ierr); 1444 } 1445 if (ts->snes) {ierr = SNESReset(ts->snes);CHKERRQ(ierr);} 1446 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 1447 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 1448 ierr = VecDestroy(&ts->Frhs);CHKERRQ(ierr); 1449 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 1450 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 1451 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 1452 ierr = VecDestroyVecs(ts->nwork,&ts->work);CHKERRQ(ierr); 1453 ts->setupcalled = PETSC_FALSE; 1454 PetscFunctionReturn(0); 1455 } 1456 1457 #undef __FUNCT__ 1458 #define __FUNCT__ "TSDestroy" 1459 /*@ 1460 TSDestroy - Destroys the timestepper context that was created 1461 with TSCreate(). 1462 1463 Collective on TS 1464 1465 Input Parameter: 1466 . ts - the TS context obtained from TSCreate() 1467 1468 Level: beginner 1469 1470 .keywords: TS, timestepper, destroy 1471 1472 .seealso: TSCreate(), TSSetUp(), TSSolve() 1473 @*/ 1474 PetscErrorCode TSDestroy(TS *ts) 1475 { 1476 PetscErrorCode ierr; 1477 1478 PetscFunctionBegin; 1479 if (!*ts) PetscFunctionReturn(0); 1480 PetscValidHeaderSpecific((*ts),TS_CLASSID,1); 1481 if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; PetscFunctionReturn(0);} 1482 1483 ierr = TSReset((*ts));CHKERRQ(ierr); 1484 1485 /* if memory was published with AMS then destroy it */ 1486 ierr = PetscObjectDepublish((*ts));CHKERRQ(ierr); 1487 if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);} 1488 1489 ierr = TSAdaptDestroy(&(*ts)->adapt);CHKERRQ(ierr); 1490 ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr); 1491 ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr); 1492 ierr = TSMonitorCancel((*ts));CHKERRQ(ierr); 1493 1494 ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr); 1495 PetscFunctionReturn(0); 1496 } 1497 1498 #undef __FUNCT__ 1499 #define __FUNCT__ "TSGetSNES" 1500 /*@ 1501 TSGetSNES - Returns the SNES (nonlinear solver) associated with 1502 a TS (timestepper) context. Valid only for nonlinear problems. 1503 1504 Not Collective, but SNES is parallel if TS is parallel 1505 1506 Input Parameter: 1507 . ts - the TS context obtained from TSCreate() 1508 1509 Output Parameter: 1510 . snes - the nonlinear solver context 1511 1512 Notes: 1513 The user can then directly manipulate the SNES context to set various 1514 options, etc. Likewise, the user can then extract and manipulate the 1515 KSP, KSP, and PC contexts as well. 1516 1517 TSGetSNES() does not work for integrators that do not use SNES; in 1518 this case TSGetSNES() returns PETSC_NULL in snes. 1519 1520 Level: beginner 1521 1522 .keywords: timestep, get, SNES 1523 @*/ 1524 PetscErrorCode TSGetSNES(TS ts,SNES *snes) 1525 { 1526 PetscErrorCode ierr; 1527 1528 PetscFunctionBegin; 1529 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1530 PetscValidPointer(snes,2); 1531 if (!ts->snes) { 1532 ierr = SNESCreate(((PetscObject)ts)->comm,&ts->snes);CHKERRQ(ierr); 1533 ierr = SNESSetFunction(ts->snes,PETSC_NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 1534 ierr = PetscLogObjectParent(ts,ts->snes);CHKERRQ(ierr); 1535 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr); 1536 if (ts->dm) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 1537 if (ts->problem_type == TS_LINEAR) { 1538 ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr); 1539 } 1540 } 1541 *snes = ts->snes; 1542 PetscFunctionReturn(0); 1543 } 1544 1545 #undef __FUNCT__ 1546 #define __FUNCT__ "TSGetKSP" 1547 /*@ 1548 TSGetKSP - Returns the KSP (linear solver) associated with 1549 a TS (timestepper) context. 1550 1551 Not Collective, but KSP is parallel if TS is parallel 1552 1553 Input Parameter: 1554 . ts - the TS context obtained from TSCreate() 1555 1556 Output Parameter: 1557 . ksp - the nonlinear solver context 1558 1559 Notes: 1560 The user can then directly manipulate the KSP context to set various 1561 options, etc. Likewise, the user can then extract and manipulate the 1562 KSP and PC contexts as well. 1563 1564 TSGetKSP() does not work for integrators that do not use KSP; 1565 in this case TSGetKSP() returns PETSC_NULL in ksp. 1566 1567 Level: beginner 1568 1569 .keywords: timestep, get, KSP 1570 @*/ 1571 PetscErrorCode TSGetKSP(TS ts,KSP *ksp) 1572 { 1573 PetscErrorCode ierr; 1574 SNES snes; 1575 1576 PetscFunctionBegin; 1577 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1578 PetscValidPointer(ksp,2); 1579 if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first"); 1580 if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()"); 1581 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1582 ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr); 1583 PetscFunctionReturn(0); 1584 } 1585 1586 /* ----------- Routines to set solver parameters ---------- */ 1587 1588 #undef __FUNCT__ 1589 #define __FUNCT__ "TSGetDuration" 1590 /*@ 1591 TSGetDuration - Gets the maximum number of timesteps to use and 1592 maximum time for iteration. 1593 1594 Not Collective 1595 1596 Input Parameters: 1597 + ts - the TS context obtained from TSCreate() 1598 . maxsteps - maximum number of iterations to use, or PETSC_NULL 1599 - maxtime - final time to iterate to, or PETSC_NULL 1600 1601 Level: intermediate 1602 1603 .keywords: TS, timestep, get, maximum, iterations, time 1604 @*/ 1605 PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime) 1606 { 1607 PetscFunctionBegin; 1608 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1609 if (maxsteps) { 1610 PetscValidIntPointer(maxsteps,2); 1611 *maxsteps = ts->max_steps; 1612 } 1613 if (maxtime) { 1614 PetscValidScalarPointer(maxtime,3); 1615 *maxtime = ts->max_time; 1616 } 1617 PetscFunctionReturn(0); 1618 } 1619 1620 #undef __FUNCT__ 1621 #define __FUNCT__ "TSSetDuration" 1622 /*@ 1623 TSSetDuration - Sets the maximum number of timesteps to use and 1624 maximum time for iteration. 1625 1626 Logically Collective on TS 1627 1628 Input Parameters: 1629 + ts - the TS context obtained from TSCreate() 1630 . maxsteps - maximum number of iterations to use 1631 - maxtime - final time to iterate to 1632 1633 Options Database Keys: 1634 . -ts_max_steps <maxsteps> - Sets maxsteps 1635 . -ts_final_time <maxtime> - Sets maxtime 1636 1637 Notes: 1638 The default maximum number of iterations is 5000. Default time is 5.0 1639 1640 Level: intermediate 1641 1642 .keywords: TS, timestep, set, maximum, iterations 1643 1644 .seealso: TSSetExactFinalTime() 1645 @*/ 1646 PetscErrorCode TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime) 1647 { 1648 PetscFunctionBegin; 1649 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1650 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 1651 PetscValidLogicalCollectiveReal(ts,maxtime,2); 1652 if (maxsteps >= 0) ts->max_steps = maxsteps; 1653 if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime; 1654 PetscFunctionReturn(0); 1655 } 1656 1657 #undef __FUNCT__ 1658 #define __FUNCT__ "TSSetSolution" 1659 /*@ 1660 TSSetSolution - Sets the initial solution vector 1661 for use by the TS routines. 1662 1663 Logically Collective on TS and Vec 1664 1665 Input Parameters: 1666 + ts - the TS context obtained from TSCreate() 1667 - x - the solution vector 1668 1669 Level: beginner 1670 1671 .keywords: TS, timestep, set, solution, initial conditions 1672 @*/ 1673 PetscErrorCode TSSetSolution(TS ts,Vec x) 1674 { 1675 PetscErrorCode ierr; 1676 DM dm; 1677 1678 PetscFunctionBegin; 1679 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1680 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1681 ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 1682 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 1683 ts->vec_sol = x; 1684 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1685 ierr = DMShellSetGlobalVector(dm,x);CHKERRQ(ierr); 1686 PetscFunctionReturn(0); 1687 } 1688 1689 #undef __FUNCT__ 1690 #define __FUNCT__ "TSSetPreStep" 1691 /*@C 1692 TSSetPreStep - Sets the general-purpose function 1693 called once at the beginning of each time step. 1694 1695 Logically Collective on TS 1696 1697 Input Parameters: 1698 + ts - The TS context obtained from TSCreate() 1699 - func - The function 1700 1701 Calling sequence of func: 1702 . func (TS ts); 1703 1704 Level: intermediate 1705 1706 Note: 1707 If a step is rejected, TSStep() will call this routine again before each attempt. 1708 The last completed time step number can be queried using TSGetTimeStepNumber(), the 1709 size of the step being attempted can be obtained using TSGetTimeStep(). 1710 1711 .keywords: TS, timestep 1712 .seealso: TSSetPreStage(), TSSetPostStep(), TSStep() 1713 @*/ 1714 PetscErrorCode TSSetPreStep(TS ts, PetscErrorCode (*func)(TS)) 1715 { 1716 PetscFunctionBegin; 1717 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1718 ts->ops->prestep = func; 1719 PetscFunctionReturn(0); 1720 } 1721 1722 #undef __FUNCT__ 1723 #define __FUNCT__ "TSPreStep" 1724 /*@ 1725 TSPreStep - Runs the user-defined pre-step function. 1726 1727 Collective on TS 1728 1729 Input Parameters: 1730 . ts - The TS context obtained from TSCreate() 1731 1732 Notes: 1733 TSPreStep() is typically used within time stepping implementations, 1734 so most users would not generally call this routine themselves. 1735 1736 Level: developer 1737 1738 .keywords: TS, timestep 1739 .seealso: TSSetPreStep(), TSPreStage(), TSPostStep() 1740 @*/ 1741 PetscErrorCode TSPreStep(TS ts) 1742 { 1743 PetscErrorCode ierr; 1744 1745 PetscFunctionBegin; 1746 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1747 if (ts->ops->prestep) { 1748 PetscStackPush("TS PreStep function"); 1749 ierr = (*ts->ops->prestep)(ts);CHKERRQ(ierr); 1750 PetscStackPop; 1751 } 1752 PetscFunctionReturn(0); 1753 } 1754 1755 #undef __FUNCT__ 1756 #define __FUNCT__ "TSSetPreStage" 1757 /*@C 1758 TSSetPreStage - Sets the general-purpose function 1759 called once at the beginning of each stage. 1760 1761 Logically Collective on TS 1762 1763 Input Parameters: 1764 + ts - The TS context obtained from TSCreate() 1765 - func - The function 1766 1767 Calling sequence of func: 1768 . PetscErrorCode func(TS ts, PetscReal stagetime); 1769 1770 Level: intermediate 1771 1772 Note: 1773 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 1774 The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being 1775 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 1776 1777 .keywords: TS, timestep 1778 .seealso: TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 1779 @*/ 1780 PetscErrorCode TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal)) 1781 { 1782 PetscFunctionBegin; 1783 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1784 ts->ops->prestage = func; 1785 PetscFunctionReturn(0); 1786 } 1787 1788 #undef __FUNCT__ 1789 #define __FUNCT__ "TSPreStage" 1790 /*@ 1791 TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage() 1792 1793 Collective on TS 1794 1795 Input Parameters: 1796 . ts - The TS context obtained from TSCreate() 1797 1798 Notes: 1799 TSPreStage() is typically used within time stepping implementations, 1800 most users would not generally call this routine themselves. 1801 1802 Level: developer 1803 1804 .keywords: TS, timestep 1805 .seealso: TSSetPreStep(), TSPreStep(), TSPostStep() 1806 @*/ 1807 PetscErrorCode TSPreStage(TS ts, PetscReal stagetime) 1808 { 1809 PetscErrorCode ierr; 1810 1811 PetscFunctionBegin; 1812 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1813 if (ts->ops->prestage) { 1814 PetscStackPush("TS PreStage function"); 1815 ierr = (*ts->ops->prestage)(ts,stagetime);CHKERRQ(ierr); 1816 PetscStackPop; 1817 } 1818 PetscFunctionReturn(0); 1819 } 1820 1821 #undef __FUNCT__ 1822 #define __FUNCT__ "TSSetPostStep" 1823 /*@C 1824 TSSetPostStep - Sets the general-purpose function 1825 called once at the end of each time step. 1826 1827 Logically Collective on TS 1828 1829 Input Parameters: 1830 + ts - The TS context obtained from TSCreate() 1831 - func - The function 1832 1833 Calling sequence of func: 1834 $ func (TS ts); 1835 1836 Level: intermediate 1837 1838 .keywords: TS, timestep 1839 .seealso: TSSetPreStep(), TSSetPreStage(), TSGetTimeStep(), TSGetTimeStepNumber(), TSGetTime() 1840 @*/ 1841 PetscErrorCode TSSetPostStep(TS ts, PetscErrorCode (*func)(TS)) 1842 { 1843 PetscFunctionBegin; 1844 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1845 ts->ops->poststep = func; 1846 PetscFunctionReturn(0); 1847 } 1848 1849 #undef __FUNCT__ 1850 #define __FUNCT__ "TSPostStep" 1851 /*@ 1852 TSPostStep - Runs the user-defined post-step function. 1853 1854 Collective on TS 1855 1856 Input Parameters: 1857 . ts - The TS context obtained from TSCreate() 1858 1859 Notes: 1860 TSPostStep() is typically used within time stepping implementations, 1861 so most users would not generally call this routine themselves. 1862 1863 Level: developer 1864 1865 .keywords: TS, timestep 1866 @*/ 1867 PetscErrorCode TSPostStep(TS ts) 1868 { 1869 PetscErrorCode ierr; 1870 1871 PetscFunctionBegin; 1872 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1873 if (ts->ops->poststep) { 1874 PetscStackPush("TS PostStep function"); 1875 ierr = (*ts->ops->poststep)(ts);CHKERRQ(ierr); 1876 PetscStackPop; 1877 } 1878 PetscFunctionReturn(0); 1879 } 1880 1881 /* ------------ Routines to set performance monitoring options ----------- */ 1882 1883 #undef __FUNCT__ 1884 #define __FUNCT__ "TSMonitorSet" 1885 /*@C 1886 TSMonitorSet - Sets an ADDITIONAL function that is to be used at every 1887 timestep to display the iteration's progress. 1888 1889 Logically Collective on TS 1890 1891 Input Parameters: 1892 + ts - the TS context obtained from TSCreate() 1893 . monitor - monitoring routine 1894 . mctx - [optional] user-defined context for private data for the 1895 monitor routine (use PETSC_NULL if no context is desired) 1896 - monitordestroy - [optional] routine that frees monitor context 1897 (may be PETSC_NULL) 1898 1899 Calling sequence of monitor: 1900 $ int monitor(TS ts,PetscInt steps,PetscReal time,Vec x,void *mctx) 1901 1902 + ts - the TS context 1903 . steps - iteration number 1904 . time - current time 1905 . x - current iterate 1906 - mctx - [optional] monitoring context 1907 1908 Notes: 1909 This routine adds an additional monitor to the list of monitors that 1910 already has been loaded. 1911 1912 Fortran notes: Only a single monitor function can be set for each TS object 1913 1914 Level: intermediate 1915 1916 .keywords: TS, timestep, set, monitor 1917 1918 .seealso: TSMonitorDefault(), TSMonitorCancel() 1919 @*/ 1920 PetscErrorCode TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**)) 1921 { 1922 PetscFunctionBegin; 1923 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1924 if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 1925 ts->monitor[ts->numbermonitors] = monitor; 1926 ts->mdestroy[ts->numbermonitors] = mdestroy; 1927 ts->monitorcontext[ts->numbermonitors++] = (void*)mctx; 1928 PetscFunctionReturn(0); 1929 } 1930 1931 #undef __FUNCT__ 1932 #define __FUNCT__ "TSMonitorCancel" 1933 /*@C 1934 TSMonitorCancel - Clears all the monitors that have been set on a time-step object. 1935 1936 Logically Collective on TS 1937 1938 Input Parameters: 1939 . ts - the TS context obtained from TSCreate() 1940 1941 Notes: 1942 There is no way to remove a single, specific monitor. 1943 1944 Level: intermediate 1945 1946 .keywords: TS, timestep, set, monitor 1947 1948 .seealso: TSMonitorDefault(), TSMonitorSet() 1949 @*/ 1950 PetscErrorCode TSMonitorCancel(TS ts) 1951 { 1952 PetscErrorCode ierr; 1953 PetscInt i; 1954 1955 PetscFunctionBegin; 1956 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1957 for (i=0; i<ts->numbermonitors; i++) { 1958 if (ts->mdestroy[i]) { 1959 ierr = (*ts->mdestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr); 1960 } 1961 } 1962 ts->numbermonitors = 0; 1963 PetscFunctionReturn(0); 1964 } 1965 1966 #undef __FUNCT__ 1967 #define __FUNCT__ "TSMonitorDefault" 1968 /*@ 1969 TSMonitorDefault - Sets the Default monitor 1970 1971 Level: intermediate 1972 1973 .keywords: TS, set, monitor 1974 1975 .seealso: TSMonitorDefault(), TSMonitorSet() 1976 @*/ 1977 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,void *dummy) 1978 { 1979 PetscErrorCode ierr; 1980 PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(((PetscObject)ts)->comm); 1981 1982 PetscFunctionBegin; 1983 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 1984 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g\n",step,(double)ts->time_step,(double)ptime);CHKERRQ(ierr); 1985 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 1986 PetscFunctionReturn(0); 1987 } 1988 1989 #undef __FUNCT__ 1990 #define __FUNCT__ "TSSetRetainStages" 1991 /*@ 1992 TSSetRetainStages - Request that all stages in the upcoming step be stored so that interpolation will be available. 1993 1994 Logically Collective on TS 1995 1996 Input Argument: 1997 . ts - time stepping context 1998 1999 Output Argument: 2000 . flg - PETSC_TRUE or PETSC_FALSE 2001 2002 Level: intermediate 2003 2004 .keywords: TS, set 2005 2006 .seealso: TSInterpolate(), TSSetPostStep() 2007 @*/ 2008 PetscErrorCode TSSetRetainStages(TS ts,PetscBool flg) 2009 { 2010 2011 PetscFunctionBegin; 2012 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2013 ts->retain_stages = flg; 2014 PetscFunctionReturn(0); 2015 } 2016 2017 #undef __FUNCT__ 2018 #define __FUNCT__ "TSInterpolate" 2019 /*@ 2020 TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval 2021 2022 Collective on TS 2023 2024 Input Argument: 2025 + ts - time stepping context 2026 - t - time to interpolate to 2027 2028 Output Argument: 2029 . X - state at given time 2030 2031 Notes: 2032 The user should call TSSetRetainStages() before taking a step in which interpolation will be requested. 2033 2034 Level: intermediate 2035 2036 Developer Notes: 2037 TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints. 2038 2039 .keywords: TS, set 2040 2041 .seealso: TSSetRetainStages(), TSSetPostStep() 2042 @*/ 2043 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec X) 2044 { 2045 PetscErrorCode ierr; 2046 2047 PetscFunctionBegin; 2048 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2049 if (t < ts->ptime - ts->time_step_prev || t > ts->ptime) SETERRQ3(((PetscObject)ts)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Requested time %G not in last time steps [%G,%G]",t,ts->ptime-ts->time_step_prev,ts->ptime); 2050 if (!ts->ops->interpolate) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name); 2051 ierr = (*ts->ops->interpolate)(ts,t,X);CHKERRQ(ierr); 2052 PetscFunctionReturn(0); 2053 } 2054 2055 #undef __FUNCT__ 2056 #define __FUNCT__ "TSStep" 2057 /*@ 2058 TSStep - Steps one time step 2059 2060 Collective on TS 2061 2062 Input Parameter: 2063 . ts - the TS context obtained from TSCreate() 2064 2065 Level: intermediate 2066 2067 Notes: 2068 The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may 2069 be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages. 2070 2071 .keywords: TS, timestep, solve 2072 2073 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage() 2074 @*/ 2075 PetscErrorCode TSStep(TS ts) 2076 { 2077 PetscReal ptime_prev; 2078 PetscErrorCode ierr; 2079 2080 PetscFunctionBegin; 2081 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2082 ierr = TSSetUp(ts);CHKERRQ(ierr); 2083 2084 ts->reason = TS_CONVERGED_ITERATING; 2085 2086 ptime_prev = ts->ptime; 2087 ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr); 2088 ierr = (*ts->ops->step)(ts);CHKERRQ(ierr); 2089 ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr); 2090 ts->time_step_prev = ts->ptime - ptime_prev; 2091 2092 if (ts->reason < 0) { 2093 if (ts->errorifstepfailed) { 2094 if (ts->reason == TS_DIVERGED_NONLINEAR_SOLVE) { 2095 SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s, increase -ts_max_snes_failures or make negative to attempt recovery",TSConvergedReasons[ts->reason]); 2096 } else SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]); 2097 } 2098 } else if (!ts->reason) { 2099 if (ts->steps >= ts->max_steps) 2100 ts->reason = TS_CONVERGED_ITS; 2101 else if (ts->ptime >= ts->max_time) 2102 ts->reason = TS_CONVERGED_TIME; 2103 } 2104 2105 PetscFunctionReturn(0); 2106 } 2107 2108 #undef __FUNCT__ 2109 #define __FUNCT__ "TSEvaluateStep" 2110 /*@ 2111 TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy. 2112 2113 Collective on TS 2114 2115 Input Arguments: 2116 + ts - time stepping context 2117 . order - desired order of accuracy 2118 - done - whether the step was evaluated at this order (pass PETSC_NULL to generate an error if not available) 2119 2120 Output Arguments: 2121 . X - state at the end of the current step 2122 2123 Level: advanced 2124 2125 Notes: 2126 This function cannot be called until all stages have been evaluated. 2127 It is normally called by adaptive controllers before a step has been accepted and may also be called by the user after TSStep() has returned. 2128 2129 .seealso: TSStep(), TSAdapt 2130 @*/ 2131 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec X,PetscBool *done) 2132 { 2133 PetscErrorCode ierr; 2134 2135 PetscFunctionBegin; 2136 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2137 PetscValidType(ts,1); 2138 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 2139 if (!ts->ops->evaluatestep) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name); 2140 ierr = (*ts->ops->evaluatestep)(ts,order,X,done);CHKERRQ(ierr); 2141 PetscFunctionReturn(0); 2142 } 2143 2144 #undef __FUNCT__ 2145 #define __FUNCT__ "TSSolve" 2146 /*@ 2147 TSSolve - Steps the requested number of timesteps. 2148 2149 Collective on TS 2150 2151 Input Parameter: 2152 + ts - the TS context obtained from TSCreate() 2153 - x - the solution vector 2154 2155 Output Parameter: 2156 . ftime - time of the state vector x upon completion 2157 2158 Level: beginner 2159 2160 Notes: 2161 The final time returned by this function may be different from the time of the internally 2162 held state accessible by TSGetSolution() and TSGetTime() because the method may have 2163 stepped over the final time. 2164 2165 .keywords: TS, timestep, solve 2166 2167 .seealso: TSCreate(), TSSetSolution(), TSStep() 2168 @*/ 2169 PetscErrorCode TSSolve(TS ts,Vec x,PetscReal *ftime) 2170 { 2171 PetscBool flg; 2172 char filename[PETSC_MAX_PATH_LEN]; 2173 PetscViewer viewer; 2174 PetscErrorCode ierr; 2175 2176 PetscFunctionBegin; 2177 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2178 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2179 if (ts->exact_final_time) { /* Need ts->vec_sol to be distinct so it is not overwritten when we interpolate at the end */ 2180 if (!ts->vec_sol || x == ts->vec_sol) { 2181 Vec y; 2182 ierr = VecDuplicate(x,&y);CHKERRQ(ierr); 2183 ierr = TSSetSolution(ts,y);CHKERRQ(ierr); 2184 ierr = VecDestroy(&y);CHKERRQ(ierr); /* grant ownership */ 2185 } 2186 ierr = VecCopy(x,ts->vec_sol);CHKERRQ(ierr); 2187 } else { 2188 ierr = TSSetSolution(ts,x);CHKERRQ(ierr); 2189 } 2190 ierr = TSSetUp(ts);CHKERRQ(ierr); 2191 /* reset time step and iteration counters */ 2192 ts->steps = 0; 2193 ts->ksp_its = 0; 2194 ts->snes_its = 0; 2195 ts->num_snes_failures = 0; 2196 ts->reject = 0; 2197 ts->reason = TS_CONVERGED_ITERATING; 2198 2199 if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */ 2200 ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr); 2201 ierr = VecCopy(ts->vec_sol,x);CHKERRQ(ierr); 2202 if (ftime) *ftime = ts->ptime; 2203 } else { 2204 /* steps the requested number of timesteps. */ 2205 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 2206 if (ts->steps >= ts->max_steps) 2207 ts->reason = TS_CONVERGED_ITS; 2208 else if (ts->ptime >= ts->max_time) 2209 ts->reason = TS_CONVERGED_TIME; 2210 while (!ts->reason) { 2211 ierr = TSStep(ts);CHKERRQ(ierr); 2212 ierr = TSPostStep(ts);CHKERRQ(ierr); 2213 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 2214 } 2215 if (ts->exact_final_time && ts->ptime > ts->max_time) { 2216 ierr = TSInterpolate(ts,ts->max_time,x);CHKERRQ(ierr); 2217 if (ftime) *ftime = ts->max_time; 2218 } else { 2219 ierr = VecCopy(ts->vec_sol,x);CHKERRQ(ierr); 2220 if (ftime) *ftime = ts->ptime; 2221 } 2222 } 2223 ierr = PetscOptionsGetString(((PetscObject)ts)->prefix,"-ts_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 2224 if (flg && !PetscPreLoadingOn) { 2225 ierr = PetscViewerASCIIOpen(((PetscObject)ts)->comm,filename,&viewer);CHKERRQ(ierr); 2226 ierr = TSView(ts,viewer);CHKERRQ(ierr); 2227 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 2228 } 2229 PetscFunctionReturn(0); 2230 } 2231 2232 #undef __FUNCT__ 2233 #define __FUNCT__ "TSMonitor" 2234 /*@ 2235 TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet() 2236 2237 Collective on TS 2238 2239 Input Parameters: 2240 + ts - time stepping context obtained from TSCreate() 2241 . step - step number that has just completed 2242 . ptime - model time of the state 2243 - x - state at the current model time 2244 2245 Notes: 2246 TSMonitor() is typically used within the time stepping implementations. 2247 Users might call this function when using the TSStep() interface instead of TSSolve(). 2248 2249 Level: advanced 2250 2251 .keywords: TS, timestep 2252 @*/ 2253 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec x) 2254 { 2255 PetscErrorCode ierr; 2256 PetscInt i,n = ts->numbermonitors; 2257 2258 PetscFunctionBegin; 2259 for (i=0; i<n; i++) { 2260 ierr = (*ts->monitor[i])(ts,step,ptime,x,ts->monitorcontext[i]);CHKERRQ(ierr); 2261 } 2262 PetscFunctionReturn(0); 2263 } 2264 2265 /* ------------------------------------------------------------------------*/ 2266 2267 #undef __FUNCT__ 2268 #define __FUNCT__ "TSMonitorLGCreate" 2269 /*@C 2270 TSMonitorLGCreate - Creates a line graph context for use with 2271 TS to monitor convergence of preconditioned residual norms. 2272 2273 Collective on TS 2274 2275 Input Parameters: 2276 + host - the X display to open, or null for the local machine 2277 . label - the title to put in the title bar 2278 . x, y - the screen coordinates of the upper left coordinate of the window 2279 - m, n - the screen width and height in pixels 2280 2281 Output Parameter: 2282 . draw - the drawing context 2283 2284 Options Database Key: 2285 . -ts_monitor_draw - automatically sets line graph monitor 2286 2287 Notes: 2288 Use TSMonitorLGDestroy() to destroy this line graph, not PetscDrawLGDestroy(). 2289 2290 Level: intermediate 2291 2292 .keywords: TS, monitor, line graph, residual, seealso 2293 2294 .seealso: TSMonitorLGDestroy(), TSMonitorSet() 2295 2296 @*/ 2297 PetscErrorCode TSMonitorLGCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2298 { 2299 PetscDraw win; 2300 PetscErrorCode ierr; 2301 PetscDrawAxis axis; 2302 2303 PetscFunctionBegin; 2304 ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&win);CHKERRQ(ierr); 2305 ierr = PetscDrawSetType(win,PETSC_DRAW_X);CHKERRQ(ierr); 2306 ierr = PetscDrawLGCreate(win,1,draw);CHKERRQ(ierr); 2307 ierr = PetscDrawLGIndicateDataPoints(*draw);CHKERRQ(ierr); 2308 ierr = PetscDrawLGGetAxis(*draw,&axis);CHKERRQ(ierr); 2309 ierr = PetscDrawAxisSetLabels(axis,"Integration Time","Iteration","Time");CHKERRQ(ierr); 2310 ierr = PetscLogObjectParent(*draw,win);CHKERRQ(ierr); 2311 PetscFunctionReturn(0); 2312 } 2313 2314 #undef __FUNCT__ 2315 #define __FUNCT__ "TSMonitorLG" 2316 PetscErrorCode TSMonitorLG(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 2317 { 2318 PetscDrawLG lg = (PetscDrawLG) monctx; 2319 PetscReal x,y = ptime; 2320 PetscErrorCode ierr; 2321 2322 PetscFunctionBegin; 2323 if (!monctx) { 2324 MPI_Comm comm; 2325 PetscViewer viewer; 2326 PetscDrawAxis axis; 2327 2328 ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr); 2329 viewer = PETSC_VIEWER_DRAW_(comm); 2330 ierr = PetscViewerDrawGetDrawLG(viewer,0,&lg);CHKERRQ(ierr); 2331 ierr = PetscDrawLGGetAxis(lg,&axis);CHKERRQ(ierr); 2332 ierr = PetscDrawAxisSetLabels(axis,"Integration Time","Iteration","Time");CHKERRQ(ierr); 2333 } 2334 2335 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2336 x = (PetscReal)n; 2337 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2338 if (n < 20 || (n % 5)) { 2339 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2340 } 2341 PetscFunctionReturn(0); 2342 } 2343 2344 #undef __FUNCT__ 2345 #define __FUNCT__ "TSMonitorLGDestroy" 2346 /*@C 2347 TSMonitorLGDestroy - Destroys a line graph context that was created 2348 with TSMonitorLGCreate(). 2349 2350 Collective on PetscDrawLG 2351 2352 Input Parameter: 2353 . draw - the drawing context 2354 2355 Level: intermediate 2356 2357 .keywords: TS, monitor, line graph, destroy 2358 2359 .seealso: TSMonitorLGCreate(), TSMonitorSet(), TSMonitorLG(); 2360 @*/ 2361 PetscErrorCode TSMonitorLGDestroy(PetscDrawLG *drawlg) 2362 { 2363 PetscDraw draw; 2364 PetscErrorCode ierr; 2365 2366 PetscFunctionBegin; 2367 ierr = PetscDrawLGGetDraw(*drawlg,&draw);CHKERRQ(ierr); 2368 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 2369 ierr = PetscDrawLGDestroy(drawlg);CHKERRQ(ierr); 2370 PetscFunctionReturn(0); 2371 } 2372 2373 #undef __FUNCT__ 2374 #define __FUNCT__ "TSGetTime" 2375 /*@ 2376 TSGetTime - Gets the time of the most recently completed step. 2377 2378 Not Collective 2379 2380 Input Parameter: 2381 . ts - the TS context obtained from TSCreate() 2382 2383 Output Parameter: 2384 . t - the current time 2385 2386 Level: beginner 2387 2388 Note: 2389 When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(), 2390 TSSetPreStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated. 2391 2392 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 2393 2394 .keywords: TS, get, time 2395 @*/ 2396 PetscErrorCode TSGetTime(TS ts,PetscReal* t) 2397 { 2398 PetscFunctionBegin; 2399 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2400 PetscValidRealPointer(t,2); 2401 *t = ts->ptime; 2402 PetscFunctionReturn(0); 2403 } 2404 2405 #undef __FUNCT__ 2406 #define __FUNCT__ "TSSetTime" 2407 /*@ 2408 TSSetTime - Allows one to reset the time. 2409 2410 Logically Collective on TS 2411 2412 Input Parameters: 2413 + ts - the TS context obtained from TSCreate() 2414 - time - the time 2415 2416 Level: intermediate 2417 2418 .seealso: TSGetTime(), TSSetDuration() 2419 2420 .keywords: TS, set, time 2421 @*/ 2422 PetscErrorCode TSSetTime(TS ts, PetscReal t) 2423 { 2424 PetscFunctionBegin; 2425 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2426 PetscValidLogicalCollectiveReal(ts,t,2); 2427 ts->ptime = t; 2428 PetscFunctionReturn(0); 2429 } 2430 2431 #undef __FUNCT__ 2432 #define __FUNCT__ "TSSetOptionsPrefix" 2433 /*@C 2434 TSSetOptionsPrefix - Sets the prefix used for searching for all 2435 TS options in the database. 2436 2437 Logically Collective on TS 2438 2439 Input Parameter: 2440 + ts - The TS context 2441 - prefix - The prefix to prepend to all option names 2442 2443 Notes: 2444 A hyphen (-) must NOT be given at the beginning of the prefix name. 2445 The first character of all runtime options is AUTOMATICALLY the 2446 hyphen. 2447 2448 Level: advanced 2449 2450 .keywords: TS, set, options, prefix, database 2451 2452 .seealso: TSSetFromOptions() 2453 2454 @*/ 2455 PetscErrorCode TSSetOptionsPrefix(TS ts,const char prefix[]) 2456 { 2457 PetscErrorCode ierr; 2458 SNES snes; 2459 2460 PetscFunctionBegin; 2461 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2462 ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 2463 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2464 ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr); 2465 PetscFunctionReturn(0); 2466 } 2467 2468 2469 #undef __FUNCT__ 2470 #define __FUNCT__ "TSAppendOptionsPrefix" 2471 /*@C 2472 TSAppendOptionsPrefix - Appends to the prefix used for searching for all 2473 TS options in the database. 2474 2475 Logically Collective on TS 2476 2477 Input Parameter: 2478 + ts - The TS context 2479 - prefix - The prefix to prepend to all option names 2480 2481 Notes: 2482 A hyphen (-) must NOT be given at the beginning of the prefix name. 2483 The first character of all runtime options is AUTOMATICALLY the 2484 hyphen. 2485 2486 Level: advanced 2487 2488 .keywords: TS, append, options, prefix, database 2489 2490 .seealso: TSGetOptionsPrefix() 2491 2492 @*/ 2493 PetscErrorCode TSAppendOptionsPrefix(TS ts,const char prefix[]) 2494 { 2495 PetscErrorCode ierr; 2496 SNES snes; 2497 2498 PetscFunctionBegin; 2499 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2500 ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 2501 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2502 ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr); 2503 PetscFunctionReturn(0); 2504 } 2505 2506 #undef __FUNCT__ 2507 #define __FUNCT__ "TSGetOptionsPrefix" 2508 /*@C 2509 TSGetOptionsPrefix - Sets the prefix used for searching for all 2510 TS options in the database. 2511 2512 Not Collective 2513 2514 Input Parameter: 2515 . ts - The TS context 2516 2517 Output Parameter: 2518 . prefix - A pointer to the prefix string used 2519 2520 Notes: On the fortran side, the user should pass in a string 'prifix' of 2521 sufficient length to hold the prefix. 2522 2523 Level: intermediate 2524 2525 .keywords: TS, get, options, prefix, database 2526 2527 .seealso: TSAppendOptionsPrefix() 2528 @*/ 2529 PetscErrorCode TSGetOptionsPrefix(TS ts,const char *prefix[]) 2530 { 2531 PetscErrorCode ierr; 2532 2533 PetscFunctionBegin; 2534 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2535 PetscValidPointer(prefix,2); 2536 ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 2537 PetscFunctionReturn(0); 2538 } 2539 2540 #undef __FUNCT__ 2541 #define __FUNCT__ "TSGetRHSJacobian" 2542 /*@C 2543 TSGetRHSJacobian - Returns the Jacobian J at the present timestep. 2544 2545 Not Collective, but parallel objects are returned if TS is parallel 2546 2547 Input Parameter: 2548 . ts - The TS context obtained from TSCreate() 2549 2550 Output Parameters: 2551 + J - The Jacobian J of F, where U_t = F(U,t) 2552 . M - The preconditioner matrix, usually the same as J 2553 . func - Function to compute the Jacobian of the RHS 2554 - ctx - User-defined context for Jacobian evaluation routine 2555 2556 Notes: You can pass in PETSC_NULL for any return argument you do not need. 2557 2558 Level: intermediate 2559 2560 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 2561 2562 .keywords: TS, timestep, get, matrix, Jacobian 2563 @*/ 2564 PetscErrorCode TSGetRHSJacobian(TS ts,Mat *J,Mat *M,TSRHSJacobian *func,void **ctx) 2565 { 2566 PetscErrorCode ierr; 2567 SNES snes; 2568 DM dm; 2569 2570 PetscFunctionBegin; 2571 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2572 ierr = SNESGetJacobian(snes,J,M,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 2573 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 2574 ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr); 2575 PetscFunctionReturn(0); 2576 } 2577 2578 #undef __FUNCT__ 2579 #define __FUNCT__ "TSGetIJacobian" 2580 /*@C 2581 TSGetIJacobian - Returns the implicit Jacobian at the present timestep. 2582 2583 Not Collective, but parallel objects are returned if TS is parallel 2584 2585 Input Parameter: 2586 . ts - The TS context obtained from TSCreate() 2587 2588 Output Parameters: 2589 + A - The Jacobian of F(t,U,U_t) 2590 . B - The preconditioner matrix, often the same as A 2591 . f - The function to compute the matrices 2592 - ctx - User-defined context for Jacobian evaluation routine 2593 2594 Notes: You can pass in PETSC_NULL for any return argument you do not need. 2595 2596 Level: advanced 2597 2598 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 2599 2600 .keywords: TS, timestep, get, matrix, Jacobian 2601 @*/ 2602 PetscErrorCode TSGetIJacobian(TS ts,Mat *A,Mat *B,TSIJacobian *f,void **ctx) 2603 { 2604 PetscErrorCode ierr; 2605 SNES snes; 2606 DM dm; 2607 PetscFunctionBegin; 2608 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2609 ierr = SNESGetJacobian(snes,A,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 2610 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 2611 ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr); 2612 PetscFunctionReturn(0); 2613 } 2614 2615 typedef struct { 2616 PetscViewer viewer; 2617 Vec initialsolution; 2618 PetscBool showinitial; 2619 } TSMonitorSolutionCtx; 2620 2621 #undef __FUNCT__ 2622 #define __FUNCT__ "TSMonitorSolution" 2623 /*@C 2624 TSMonitorSolution - Monitors progress of the TS solvers by calling 2625 VecView() for the solution at each timestep 2626 2627 Collective on TS 2628 2629 Input Parameters: 2630 + ts - the TS context 2631 . step - current time-step 2632 . ptime - current time 2633 - dummy - either a viewer or PETSC_NULL 2634 2635 Level: intermediate 2636 2637 .keywords: TS, vector, monitor, view 2638 2639 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 2640 @*/ 2641 PetscErrorCode TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec x,void *dummy) 2642 { 2643 PetscErrorCode ierr; 2644 TSMonitorSolutionCtx *ictx = (TSMonitorSolutionCtx*)dummy; 2645 2646 PetscFunctionBegin; 2647 if (!step && ictx->showinitial) { 2648 if (!ictx->initialsolution) { 2649 ierr = VecDuplicate(x,&ictx->initialsolution);CHKERRQ(ierr); 2650 } 2651 ierr = VecCopy(x,ictx->initialsolution);CHKERRQ(ierr); 2652 } 2653 if (ictx->showinitial) { 2654 PetscReal pause; 2655 ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr); 2656 ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr); 2657 ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr); 2658 ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr); 2659 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr); 2660 } 2661 ierr = VecView(x,ictx->viewer);CHKERRQ(ierr); 2662 if (ictx->showinitial) { 2663 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr); 2664 } 2665 PetscFunctionReturn(0); 2666 } 2667 2668 2669 #undef __FUNCT__ 2670 #define __FUNCT__ "TSMonitorSolutionDestroy" 2671 /*@C 2672 TSMonitorSolutionDestroy - Destroys the monitor context for TSMonitorSolution 2673 2674 Collective on TS 2675 2676 Input Parameters: 2677 . ctx - the monitor context 2678 2679 Level: intermediate 2680 2681 .keywords: TS, vector, monitor, view 2682 2683 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorSolution() 2684 @*/ 2685 PetscErrorCode TSMonitorSolutionDestroy(void **ctx) 2686 { 2687 PetscErrorCode ierr; 2688 TSMonitorSolutionCtx *ictx = *(TSMonitorSolutionCtx**)ctx; 2689 2690 PetscFunctionBegin; 2691 ierr = PetscViewerDestroy(&ictx->viewer);CHKERRQ(ierr); 2692 ierr = VecDestroy(&ictx->initialsolution);CHKERRQ(ierr); 2693 ierr = PetscFree(ictx);CHKERRQ(ierr); 2694 PetscFunctionReturn(0); 2695 } 2696 2697 #undef __FUNCT__ 2698 #define __FUNCT__ "TSMonitorSolutionCreate" 2699 /*@C 2700 TSMonitorSolutionCreate - Creates the monitor context for TSMonitorSolution 2701 2702 Collective on TS 2703 2704 Input Parameter: 2705 . ts - time-step context 2706 2707 Output Patameter: 2708 . ctx - the monitor context 2709 2710 Level: intermediate 2711 2712 .keywords: TS, vector, monitor, view 2713 2714 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorSolution() 2715 @*/ 2716 PetscErrorCode TSMonitorSolutionCreate(TS ts,PetscViewer viewer,void **ctx) 2717 { 2718 PetscErrorCode ierr; 2719 TSMonitorSolutionCtx *ictx; 2720 2721 PetscFunctionBegin; 2722 ierr = PetscNew(TSMonitorSolutionCtx,&ictx);CHKERRQ(ierr); 2723 *ctx = (void*)ictx; 2724 if (!viewer) { 2725 viewer = PETSC_VIEWER_DRAW_(((PetscObject)ts)->comm); 2726 } 2727 ierr = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr); 2728 ictx->viewer = viewer; 2729 ictx->showinitial = PETSC_FALSE; 2730 ierr = PetscOptionsGetBool(((PetscObject)ts)->prefix,"-ts_monitor_solution_initial",&ictx->showinitial,PETSC_NULL);CHKERRQ(ierr); 2731 PetscFunctionReturn(0); 2732 } 2733 2734 #undef __FUNCT__ 2735 #define __FUNCT__ "TSSetDM" 2736 /*@ 2737 TSSetDM - Sets the DM that may be used by some preconditioners 2738 2739 Logically Collective on TS and DM 2740 2741 Input Parameters: 2742 + ts - the preconditioner context 2743 - dm - the dm 2744 2745 Level: intermediate 2746 2747 2748 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM() 2749 @*/ 2750 PetscErrorCode TSSetDM(TS ts,DM dm) 2751 { 2752 PetscErrorCode ierr; 2753 SNES snes; 2754 TSDM tsdm; 2755 2756 PetscFunctionBegin; 2757 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2758 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 2759 if (ts->dm) { /* Move the TSDM context over to the new DM unless the new DM already has one */ 2760 PetscContainer oldcontainer,container; 2761 ierr = PetscObjectQuery((PetscObject)ts->dm,"TSDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 2762 ierr = PetscObjectQuery((PetscObject)dm,"TSDM",(PetscObject*)&container);CHKERRQ(ierr); 2763 if (oldcontainer && !container) { 2764 ierr = DMTSCopyContext(ts->dm,dm);CHKERRQ(ierr); 2765 ierr = DMTSGetContext(ts->dm,&tsdm);CHKERRQ(ierr); 2766 if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */ 2767 tsdm->originaldm = dm; 2768 } 2769 } 2770 ierr = DMDestroy(&ts->dm);CHKERRQ(ierr); 2771 } 2772 ts->dm = dm; 2773 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2774 ierr = SNESSetDM(snes,dm);CHKERRQ(ierr); 2775 PetscFunctionReturn(0); 2776 } 2777 2778 #undef __FUNCT__ 2779 #define __FUNCT__ "TSGetDM" 2780 /*@ 2781 TSGetDM - Gets the DM that may be used by some preconditioners 2782 2783 Not Collective 2784 2785 Input Parameter: 2786 . ts - the preconditioner context 2787 2788 Output Parameter: 2789 . dm - the dm 2790 2791 Level: intermediate 2792 2793 2794 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM() 2795 @*/ 2796 PetscErrorCode TSGetDM(TS ts,DM *dm) 2797 { 2798 PetscErrorCode ierr; 2799 2800 PetscFunctionBegin; 2801 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2802 if (!ts->dm) { 2803 ierr = DMShellCreate(((PetscObject)ts)->comm,&ts->dm);CHKERRQ(ierr); 2804 if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 2805 } 2806 *dm = ts->dm; 2807 PetscFunctionReturn(0); 2808 } 2809 2810 #undef __FUNCT__ 2811 #define __FUNCT__ "SNESTSFormFunction" 2812 /*@ 2813 SNESTSFormFunction - Function to evaluate nonlinear residual 2814 2815 Logically Collective on SNES 2816 2817 Input Parameter: 2818 + snes - nonlinear solver 2819 . X - the current state at which to evaluate the residual 2820 - ctx - user context, must be a TS 2821 2822 Output Parameter: 2823 . F - the nonlinear residual 2824 2825 Notes: 2826 This function is not normally called by users and is automatically registered with the SNES used by TS. 2827 It is most frequently passed to MatFDColoringSetFunction(). 2828 2829 Level: advanced 2830 2831 .seealso: SNESSetFunction(), MatFDColoringSetFunction() 2832 @*/ 2833 PetscErrorCode SNESTSFormFunction(SNES snes,Vec X,Vec F,void *ctx) 2834 { 2835 TS ts = (TS)ctx; 2836 PetscErrorCode ierr; 2837 2838 PetscFunctionBegin; 2839 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2840 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2841 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 2842 PetscValidHeaderSpecific(ts,TS_CLASSID,4); 2843 ierr = (ts->ops->snesfunction)(snes,X,F,ts);CHKERRQ(ierr); 2844 PetscFunctionReturn(0); 2845 } 2846 2847 #undef __FUNCT__ 2848 #define __FUNCT__ "SNESTSFormJacobian" 2849 /*@ 2850 SNESTSFormJacobian - Function to evaluate the Jacobian 2851 2852 Collective on SNES 2853 2854 Input Parameter: 2855 + snes - nonlinear solver 2856 . X - the current state at which to evaluate the residual 2857 - ctx - user context, must be a TS 2858 2859 Output Parameter: 2860 + A - the Jacobian 2861 . B - the preconditioning matrix (may be the same as A) 2862 - flag - indicates any structure change in the matrix 2863 2864 Notes: 2865 This function is not normally called by users and is automatically registered with the SNES used by TS. 2866 2867 Level: developer 2868 2869 .seealso: SNESSetJacobian() 2870 @*/ 2871 PetscErrorCode SNESTSFormJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flag,void *ctx) 2872 { 2873 TS ts = (TS)ctx; 2874 PetscErrorCode ierr; 2875 2876 PetscFunctionBegin; 2877 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2878 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2879 PetscValidPointer(A,3); 2880 PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 2881 PetscValidPointer(B,4); 2882 PetscValidHeaderSpecific(*B,MAT_CLASSID,4); 2883 PetscValidPointer(flag,5); 2884 PetscValidHeaderSpecific(ts,TS_CLASSID,6); 2885 ierr = (ts->ops->snesjacobian)(snes,X,A,B,flag,ts);CHKERRQ(ierr); 2886 PetscFunctionReturn(0); 2887 } 2888 2889 #undef __FUNCT__ 2890 #define __FUNCT__ "TSComputeRHSFunctionLinear" 2891 /*@C 2892 TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems only 2893 2894 Collective on TS 2895 2896 Input Arguments: 2897 + ts - time stepping context 2898 . t - time at which to evaluate 2899 . X - state at which to evaluate 2900 - ctx - context 2901 2902 Output Arguments: 2903 . F - right hand side 2904 2905 Level: intermediate 2906 2907 Notes: 2908 This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems. 2909 The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian(). 2910 2911 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 2912 @*/ 2913 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec X,Vec F,void *ctx) 2914 { 2915 PetscErrorCode ierr; 2916 Mat Arhs,Brhs; 2917 MatStructure flg2; 2918 2919 PetscFunctionBegin; 2920 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 2921 ierr = TSComputeRHSJacobian(ts,t,X,&Arhs,&Brhs,&flg2);CHKERRQ(ierr); 2922 ierr = MatMult(Arhs,X,F);CHKERRQ(ierr); 2923 PetscFunctionReturn(0); 2924 } 2925 2926 #undef __FUNCT__ 2927 #define __FUNCT__ "TSComputeRHSJacobianConstant" 2928 /*@C 2929 TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent. 2930 2931 Collective on TS 2932 2933 Input Arguments: 2934 + ts - time stepping context 2935 . t - time at which to evaluate 2936 . X - state at which to evaluate 2937 - ctx - context 2938 2939 Output Arguments: 2940 + A - pointer to operator 2941 . B - pointer to preconditioning matrix 2942 - flg - matrix structure flag 2943 2944 Level: intermediate 2945 2946 Notes: 2947 This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems. 2948 2949 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear() 2950 @*/ 2951 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec X,Mat *A,Mat *B,MatStructure *flg,void *ctx) 2952 { 2953 2954 PetscFunctionBegin; 2955 *flg = SAME_PRECONDITIONER; 2956 PetscFunctionReturn(0); 2957 } 2958 2959 #undef __FUNCT__ 2960 #define __FUNCT__ "TSComputeIFunctionLinear" 2961 /*@C 2962 TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only 2963 2964 Collective on TS 2965 2966 Input Arguments: 2967 + ts - time stepping context 2968 . t - time at which to evaluate 2969 . X - state at which to evaluate 2970 . Xdot - time derivative of state vector 2971 - ctx - context 2972 2973 Output Arguments: 2974 . F - left hand side 2975 2976 Level: intermediate 2977 2978 Notes: 2979 The assumption here is that the left hand side is of the form A*Xdot (and not A*Xdot + B*X). For other cases, the 2980 user is required to write their own TSComputeIFunction. 2981 This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems. 2982 The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian(). 2983 2984 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant() 2985 @*/ 2986 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec X,Vec Xdot,Vec F,void *ctx) 2987 { 2988 PetscErrorCode ierr; 2989 Mat A,B; 2990 MatStructure flg2; 2991 2992 PetscFunctionBegin; 2993 ierr = TSGetIJacobian(ts,&A,&B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 2994 ierr = TSComputeIJacobian(ts,t,X,Xdot,1.0,&A,&B,&flg2,PETSC_TRUE);CHKERRQ(ierr); 2995 ierr = MatMult(A,Xdot,F);CHKERRQ(ierr); 2996 PetscFunctionReturn(0); 2997 } 2998 2999 #undef __FUNCT__ 3000 #define __FUNCT__ "TSComputeIJacobianConstant" 3001 /*@C 3002 TSComputeIJacobianConstant - Reuses a Jacobian that is time-independent. 3003 3004 Collective on TS 3005 3006 Input Arguments: 3007 + ts - time stepping context 3008 . t - time at which to evaluate 3009 . X - state at which to evaluate 3010 . Xdot - time derivative of state vector 3011 . shift - shift to apply 3012 - ctx - context 3013 3014 Output Arguments: 3015 + A - pointer to operator 3016 . B - pointer to preconditioning matrix 3017 - flg - matrix structure flag 3018 3019 Level: intermediate 3020 3021 Notes: 3022 This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems. 3023 3024 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear() 3025 @*/ 3026 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec X,Vec Xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,void *ctx) 3027 { 3028 3029 PetscFunctionBegin; 3030 *flg = SAME_PRECONDITIONER; 3031 PetscFunctionReturn(0); 3032 } 3033 3034 3035 #undef __FUNCT__ 3036 #define __FUNCT__ "TSGetConvergedReason" 3037 /*@ 3038 TSGetConvergedReason - Gets the reason the TS iteration was stopped. 3039 3040 Not Collective 3041 3042 Input Parameter: 3043 . ts - the TS context 3044 3045 Output Parameter: 3046 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 3047 manual pages for the individual convergence tests for complete lists 3048 3049 Level: intermediate 3050 3051 Notes: 3052 Can only be called after the call to TSSolve() is complete. 3053 3054 .keywords: TS, nonlinear, set, convergence, test 3055 3056 .seealso: TSSetConvergenceTest(), TSConvergedReason 3057 @*/ 3058 PetscErrorCode TSGetConvergedReason(TS ts,TSConvergedReason *reason) 3059 { 3060 PetscFunctionBegin; 3061 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3062 PetscValidPointer(reason,2); 3063 *reason = ts->reason; 3064 PetscFunctionReturn(0); 3065 } 3066 3067 #undef __FUNCT__ 3068 #define __FUNCT__ "TSGetSNESIterations" 3069 /*@ 3070 TSGetSNESIterations - Gets the total number of nonlinear iterations 3071 used by the time integrator. 3072 3073 Not Collective 3074 3075 Input Parameter: 3076 . ts - TS context 3077 3078 Output Parameter: 3079 . nits - number of nonlinear iterations 3080 3081 Notes: 3082 This counter is reset to zero for each successive call to TSSolve(). 3083 3084 Level: intermediate 3085 3086 .keywords: TS, get, number, nonlinear, iterations 3087 3088 .seealso: TSGetKSPIterations() 3089 @*/ 3090 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits) 3091 { 3092 PetscFunctionBegin; 3093 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3094 PetscValidIntPointer(nits,2); 3095 *nits = ts->snes_its; 3096 PetscFunctionReturn(0); 3097 } 3098 3099 #undef __FUNCT__ 3100 #define __FUNCT__ "TSGetKSPIterations" 3101 /*@ 3102 TSGetKSPIterations - Gets the total number of linear iterations 3103 used by the time integrator. 3104 3105 Not Collective 3106 3107 Input Parameter: 3108 . ts - TS context 3109 3110 Output Parameter: 3111 . lits - number of linear iterations 3112 3113 Notes: 3114 This counter is reset to zero for each successive call to TSSolve(). 3115 3116 Level: intermediate 3117 3118 .keywords: TS, get, number, linear, iterations 3119 3120 .seealso: TSGetSNESIterations(), SNESGetKSPIterations() 3121 @*/ 3122 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits) 3123 { 3124 PetscFunctionBegin; 3125 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3126 PetscValidIntPointer(lits,2); 3127 *lits = ts->ksp_its; 3128 PetscFunctionReturn(0); 3129 } 3130 3131 #undef __FUNCT__ 3132 #define __FUNCT__ "TSGetStepRejections" 3133 /*@ 3134 TSGetStepRejections - Gets the total number of rejected steps. 3135 3136 Not Collective 3137 3138 Input Parameter: 3139 . ts - TS context 3140 3141 Output Parameter: 3142 . rejects - number of steps rejected 3143 3144 Notes: 3145 This counter is reset to zero for each successive call to TSSolve(). 3146 3147 Level: intermediate 3148 3149 .keywords: TS, get, number 3150 3151 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails() 3152 @*/ 3153 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects) 3154 { 3155 PetscFunctionBegin; 3156 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3157 PetscValidIntPointer(rejects,2); 3158 *rejects = ts->reject; 3159 PetscFunctionReturn(0); 3160 } 3161 3162 #undef __FUNCT__ 3163 #define __FUNCT__ "TSGetSNESFailures" 3164 /*@ 3165 TSGetSNESFailures - Gets the total number of failed SNES solves 3166 3167 Not Collective 3168 3169 Input Parameter: 3170 . ts - TS context 3171 3172 Output Parameter: 3173 . fails - number of failed nonlinear solves 3174 3175 Notes: 3176 This counter is reset to zero for each successive call to TSSolve(). 3177 3178 Level: intermediate 3179 3180 .keywords: TS, get, number 3181 3182 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures() 3183 @*/ 3184 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails) 3185 { 3186 PetscFunctionBegin; 3187 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3188 PetscValidIntPointer(fails,2); 3189 *fails = ts->num_snes_failures; 3190 PetscFunctionReturn(0); 3191 } 3192 3193 #undef __FUNCT__ 3194 #define __FUNCT__ "TSSetMaxStepRejections" 3195 /*@ 3196 TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails 3197 3198 Not Collective 3199 3200 Input Parameter: 3201 + ts - TS context 3202 - rejects - maximum number of rejected steps, pass -1 for unlimited 3203 3204 Notes: 3205 The counter is reset to zero for each step 3206 3207 Options Database Key: 3208 . -ts_max_reject - Maximum number of step rejections before a step fails 3209 3210 Level: intermediate 3211 3212 .keywords: TS, set, maximum, number 3213 3214 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 3215 @*/ 3216 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects) 3217 { 3218 PetscFunctionBegin; 3219 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3220 ts->max_reject = rejects; 3221 PetscFunctionReturn(0); 3222 } 3223 3224 #undef __FUNCT__ 3225 #define __FUNCT__ "TSSetMaxSNESFailures" 3226 /*@ 3227 TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves 3228 3229 Not Collective 3230 3231 Input Parameter: 3232 + ts - TS context 3233 - fails - maximum number of failed nonlinear solves, pass -1 for unlimited 3234 3235 Notes: 3236 The counter is reset to zero for each successive call to TSSolve(). 3237 3238 Options Database Key: 3239 . -ts_max_snes_failures - Maximum number of nonlinear solve failures 3240 3241 Level: intermediate 3242 3243 .keywords: TS, set, maximum, number 3244 3245 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason() 3246 @*/ 3247 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails) 3248 { 3249 PetscFunctionBegin; 3250 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3251 ts->max_snes_failures = fails; 3252 PetscFunctionReturn(0); 3253 } 3254 3255 #undef __FUNCT__ 3256 #define __FUNCT__ "TSSetErrorIfStepFails()" 3257 /*@ 3258 TSSetErrorIfStepFails - Error if no step succeeds 3259 3260 Not Collective 3261 3262 Input Parameter: 3263 + ts - TS context 3264 - err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure 3265 3266 Options Database Key: 3267 . -ts_error_if_step_fails - Error if no step succeeds 3268 3269 Level: intermediate 3270 3271 .keywords: TS, set, error 3272 3273 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 3274 @*/ 3275 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err) 3276 { 3277 PetscFunctionBegin; 3278 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3279 ts->errorifstepfailed = err; 3280 PetscFunctionReturn(0); 3281 } 3282 3283 #undef __FUNCT__ 3284 #define __FUNCT__ "TSMonitorSolutionBinary" 3285 /*@C 3286 TSMonitorSolutionBinary - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file 3287 3288 Collective on TS 3289 3290 Input Parameters: 3291 + ts - the TS context 3292 . step - current time-step 3293 . ptime - current time 3294 . x - current state 3295 - viewer - binary viewer 3296 3297 Level: intermediate 3298 3299 .keywords: TS, vector, monitor, view 3300 3301 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 3302 @*/ 3303 PetscErrorCode TSMonitorSolutionBinary(TS ts,PetscInt step,PetscReal ptime,Vec x,void *viewer) 3304 { 3305 PetscErrorCode ierr; 3306 PetscViewer v = (PetscViewer)viewer; 3307 3308 PetscFunctionBegin; 3309 ierr = VecView(x,v);CHKERRQ(ierr); 3310 PetscFunctionReturn(0); 3311 } 3312 3313 #undef __FUNCT__ 3314 #define __FUNCT__ "TSMonitorSolutionVTK" 3315 /*@C 3316 TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep. 3317 3318 Collective on TS 3319 3320 Input Parameters: 3321 + ts - the TS context 3322 . step - current time-step 3323 . ptime - current time 3324 . x - current state 3325 - filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 3326 3327 Level: intermediate 3328 3329 Notes: 3330 The VTK format does not allow writing multiple time steps in the same file, therefore a different file will be written for each time step. 3331 These are named according to the file name template. 3332 3333 This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy(). 3334 3335 .keywords: TS, vector, monitor, view 3336 3337 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 3338 @*/ 3339 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec x,void *filenametemplate) 3340 { 3341 PetscErrorCode ierr; 3342 char filename[PETSC_MAX_PATH_LEN]; 3343 PetscViewer viewer; 3344 3345 PetscFunctionBegin; 3346 ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr); 3347 ierr = PetscViewerVTKOpen(((PetscObject)ts)->comm,filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); 3348 ierr = VecView(x,viewer);CHKERRQ(ierr); 3349 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3350 PetscFunctionReturn(0); 3351 } 3352 3353 #undef __FUNCT__ 3354 #define __FUNCT__ "TSMonitorSolutionVTKDestroy" 3355 /*@C 3356 TSMonitorSolutionVTKDestroy - Destroy context for monitoring 3357 3358 Collective on TS 3359 3360 Input Parameters: 3361 . filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 3362 3363 Level: intermediate 3364 3365 Note: 3366 This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK(). 3367 3368 .keywords: TS, vector, monitor, view 3369 3370 .seealso: TSMonitorSet(), TSMonitorSolutionVTK() 3371 @*/ 3372 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate) 3373 { 3374 PetscErrorCode ierr; 3375 3376 PetscFunctionBegin; 3377 ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr); 3378 PetscFunctionReturn(0); 3379 } 3380 3381 #undef __FUNCT__ 3382 #define __FUNCT__ "TSGetAdapt" 3383 /*@ 3384 TSGetAdapt - Get the adaptive controller context for the current method 3385 3386 Collective on TS if controller has not been created yet 3387 3388 Input Arguments: 3389 . ts - time stepping context 3390 3391 Output Arguments: 3392 . adapt - adaptive controller 3393 3394 Level: intermediate 3395 3396 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose() 3397 @*/ 3398 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt) 3399 { 3400 PetscErrorCode ierr; 3401 3402 PetscFunctionBegin; 3403 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3404 PetscValidPointer(adapt,2); 3405 if (!ts->adapt) { 3406 ierr = TSAdaptCreate(((PetscObject)ts)->comm,&ts->adapt);CHKERRQ(ierr); 3407 ierr = PetscLogObjectParent(ts,ts->adapt);CHKERRQ(ierr); 3408 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr); 3409 } 3410 *adapt = ts->adapt; 3411 PetscFunctionReturn(0); 3412 } 3413 3414 #undef __FUNCT__ 3415 #define __FUNCT__ "TSSetTolerances" 3416 /*@ 3417 TSSetTolerances - Set tolerances for local truncation error when using adaptive controller 3418 3419 Logically Collective 3420 3421 Input Arguments: 3422 + ts - time integration context 3423 . atol - scalar absolute tolerances, PETSC_DECIDE to leave current value 3424 . vatol - vector of absolute tolerances or PETSC_NULL, used in preference to atol if present 3425 . rtol - scalar relative tolerances, PETSC_DECIDE to leave current value 3426 - vrtol - vector of relative tolerances or PETSC_NULL, used in preference to atol if present 3427 3428 Level: beginner 3429 3430 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances() 3431 @*/ 3432 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol) 3433 { 3434 PetscErrorCode ierr; 3435 3436 PetscFunctionBegin; 3437 if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol; 3438 if (vatol) { 3439 ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr); 3440 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 3441 ts->vatol = vatol; 3442 } 3443 if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol; 3444 if (vrtol) { 3445 ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr); 3446 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 3447 ts->vrtol = vrtol; 3448 } 3449 PetscFunctionReturn(0); 3450 } 3451 3452 #undef __FUNCT__ 3453 #define __FUNCT__ "TSGetTolerances" 3454 /*@ 3455 TSGetTolerances - Get tolerances for local truncation error when using adaptive controller 3456 3457 Logically Collective 3458 3459 Input Arguments: 3460 . ts - time integration context 3461 3462 Output Arguments: 3463 + atol - scalar absolute tolerances, PETSC_NULL to ignore 3464 . vatol - vector of absolute tolerances, PETSC_NULL to ignore 3465 . rtol - scalar relative tolerances, PETSC_NULL to ignore 3466 - vrtol - vector of relative tolerances, PETSC_NULL to ignore 3467 3468 Level: beginner 3469 3470 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances() 3471 @*/ 3472 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol) 3473 { 3474 3475 PetscFunctionBegin; 3476 if (atol) *atol = ts->atol; 3477 if (vatol) *vatol = ts->vatol; 3478 if (rtol) *rtol = ts->rtol; 3479 if (vrtol) *vrtol = ts->vrtol; 3480 PetscFunctionReturn(0); 3481 } 3482 3483 #undef __FUNCT__ 3484 #define __FUNCT__ "TSErrorNormWRMS" 3485 /*@ 3486 TSErrorNormWRMS - compute a weighted norm of the difference between a vector and the current state 3487 3488 Collective on TS 3489 3490 Input Arguments: 3491 + ts - time stepping context 3492 - Y - state vector to be compared to ts->vec_sol 3493 3494 Output Arguments: 3495 . norm - weighted norm, a value of 1.0 is considered small 3496 3497 Level: developer 3498 3499 .seealso: TSSetTolerances() 3500 @*/ 3501 PetscErrorCode TSErrorNormWRMS(TS ts,Vec Y,PetscReal *norm) 3502 { 3503 PetscErrorCode ierr; 3504 PetscInt i,n,N; 3505 const PetscScalar *x,*y; 3506 Vec X; 3507 PetscReal sum,gsum; 3508 3509 PetscFunctionBegin; 3510 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3511 PetscValidHeaderSpecific(Y,VEC_CLASSID,2); 3512 PetscValidPointer(norm,3); 3513 X = ts->vec_sol; 3514 PetscCheckSameTypeAndComm(X,1,Y,2); 3515 if (X == Y) SETERRQ(((PetscObject)X)->comm,PETSC_ERR_ARG_IDN,"Y cannot be the TS solution vector"); 3516 3517 ierr = VecGetSize(X,&N);CHKERRQ(ierr); 3518 ierr = VecGetLocalSize(X,&n);CHKERRQ(ierr); 3519 ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr); 3520 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 3521 sum = 0.; 3522 if (ts->vatol && ts->vrtol) { 3523 const PetscScalar *atol,*rtol; 3524 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 3525 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 3526 for (i=0; i<n; i++) { 3527 PetscReal tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(x[i]),PetscAbsScalar(y[i])); 3528 sum += PetscSqr(PetscAbsScalar(y[i] - x[i]) / tol); 3529 } 3530 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 3531 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 3532 } else if (ts->vatol) { /* vector atol, scalar rtol */ 3533 const PetscScalar *atol; 3534 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 3535 for (i=0; i<n; i++) { 3536 PetscReal tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(x[i]),PetscAbsScalar(y[i])); 3537 sum += PetscSqr(PetscAbsScalar(y[i] - x[i]) / tol); 3538 } 3539 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 3540 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 3541 const PetscScalar *rtol; 3542 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 3543 for (i=0; i<n; i++) { 3544 PetscReal tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(x[i]),PetscAbsScalar(y[i])); 3545 sum += PetscSqr(PetscAbsScalar(y[i] - x[i]) / tol); 3546 } 3547 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 3548 } else { /* scalar atol, scalar rtol */ 3549 for (i=0; i<n; i++) { 3550 PetscReal tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(x[i]),PetscAbsScalar(y[i])); 3551 sum += PetscSqr(PetscAbsScalar(y[i] - x[i]) / tol); 3552 } 3553 } 3554 ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr); 3555 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 3556 3557 ierr = MPI_Allreduce(&sum,&gsum,1,MPIU_REAL,MPIU_SUM,((PetscObject)ts)->comm);CHKERRQ(ierr); 3558 *norm = PetscSqrtReal(gsum / N); 3559 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 3560 PetscFunctionReturn(0); 3561 } 3562 3563 #undef __FUNCT__ 3564 #define __FUNCT__ "TSSetCFLTimeLocal" 3565 /*@ 3566 TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler 3567 3568 Logically Collective on TS 3569 3570 Input Arguments: 3571 + ts - time stepping context 3572 - cfltime - maximum stable time step if using forward Euler (value can be different on each process) 3573 3574 Note: 3575 After calling this function, the global CFL time can be obtained by calling TSGetCFLTime() 3576 3577 Level: intermediate 3578 3579 .seealso: TSGetCFLTime(), TSADAPTCFL 3580 @*/ 3581 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime) 3582 { 3583 3584 PetscFunctionBegin; 3585 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3586 ts->cfltime_local = cfltime; 3587 ts->cfltime = -1.; 3588 PetscFunctionReturn(0); 3589 } 3590 3591 #undef __FUNCT__ 3592 #define __FUNCT__ "TSGetCFLTime" 3593 /*@ 3594 TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler 3595 3596 Collective on TS 3597 3598 Input Arguments: 3599 . ts - time stepping context 3600 3601 Output Arguments: 3602 . cfltime - maximum stable time step for forward Euler 3603 3604 Level: advanced 3605 3606 .seealso: TSSetCFLTimeLocal() 3607 @*/ 3608 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime) 3609 { 3610 PetscErrorCode ierr; 3611 3612 PetscFunctionBegin; 3613 if (ts->cfltime < 0) { 3614 ierr = MPI_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,((PetscObject)ts)->comm);CHKERRQ(ierr); 3615 } 3616 *cfltime = ts->cfltime; 3617 PetscFunctionReturn(0); 3618 } 3619 3620 #undef __FUNCT__ 3621 #define __FUNCT__ "TSVISetVariableBounds" 3622 /*@ 3623 TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu 3624 3625 Input Parameters: 3626 . ts - the TS context. 3627 . xl - lower bound. 3628 . xu - upper bound. 3629 3630 Notes: 3631 If this routine is not called then the lower and upper bounds are set to 3632 SNES_VI_NINF and SNES_VI_INF respectively during SNESSetUp(). 3633 3634 Level: advanced 3635 3636 @*/ 3637 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu) 3638 { 3639 PetscErrorCode ierr; 3640 SNES snes; 3641 3642 PetscFunctionBegin; 3643 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 3644 ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr); 3645 PetscFunctionReturn(0); 3646 } 3647 3648 #if defined(PETSC_HAVE_MATLAB_ENGINE) 3649 #include <mex.h> 3650 3651 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext; 3652 3653 #undef __FUNCT__ 3654 #define __FUNCT__ "TSComputeFunction_Matlab" 3655 /* 3656 TSComputeFunction_Matlab - Calls the function that has been set with 3657 TSSetFunctionMatlab(). 3658 3659 Collective on TS 3660 3661 Input Parameters: 3662 + snes - the TS context 3663 - x - input vector 3664 3665 Output Parameter: 3666 . y - function vector, as set by TSSetFunction() 3667 3668 Notes: 3669 TSComputeFunction() is typically used within nonlinear solvers 3670 implementations, so most users would not generally call this routine 3671 themselves. 3672 3673 Level: developer 3674 3675 .keywords: TS, nonlinear, compute, function 3676 3677 .seealso: TSSetFunction(), TSGetFunction() 3678 */ 3679 PetscErrorCode TSComputeFunction_Matlab(TS snes,PetscReal time,Vec x,Vec xdot,Vec y, void *ctx) 3680 { 3681 PetscErrorCode ierr; 3682 TSMatlabContext *sctx = (TSMatlabContext *)ctx; 3683 int nlhs = 1,nrhs = 7; 3684 mxArray *plhs[1],*prhs[7]; 3685 long long int lx = 0,lxdot = 0,ly = 0,ls = 0; 3686 3687 PetscFunctionBegin; 3688 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 3689 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3690 PetscValidHeaderSpecific(xdot,VEC_CLASSID,4); 3691 PetscValidHeaderSpecific(y,VEC_CLASSID,5); 3692 PetscCheckSameComm(snes,1,x,3); 3693 PetscCheckSameComm(snes,1,y,5); 3694 3695 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3696 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3697 ierr = PetscMemcpy(&lxdot,&xdot,sizeof(xdot));CHKERRQ(ierr); 3698 ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 3699 prhs[0] = mxCreateDoubleScalar((double)ls); 3700 prhs[1] = mxCreateDoubleScalar(time); 3701 prhs[2] = mxCreateDoubleScalar((double)lx); 3702 prhs[3] = mxCreateDoubleScalar((double)lxdot); 3703 prhs[4] = mxCreateDoubleScalar((double)ly); 3704 prhs[5] = mxCreateString(sctx->funcname); 3705 prhs[6] = sctx->ctx; 3706 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr); 3707 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3708 mxDestroyArray(prhs[0]); 3709 mxDestroyArray(prhs[1]); 3710 mxDestroyArray(prhs[2]); 3711 mxDestroyArray(prhs[3]); 3712 mxDestroyArray(prhs[4]); 3713 mxDestroyArray(prhs[5]); 3714 mxDestroyArray(plhs[0]); 3715 PetscFunctionReturn(0); 3716 } 3717 3718 3719 #undef __FUNCT__ 3720 #define __FUNCT__ "TSSetFunctionMatlab" 3721 /* 3722 TSSetFunctionMatlab - Sets the function evaluation routine and function 3723 vector for use by the TS routines in solving ODEs 3724 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 3725 3726 Logically Collective on TS 3727 3728 Input Parameters: 3729 + ts - the TS context 3730 - func - function evaluation routine 3731 3732 Calling sequence of func: 3733 $ func (TS ts,PetscReal time,Vec x,Vec xdot,Vec f,void *ctx); 3734 3735 Level: beginner 3736 3737 .keywords: TS, nonlinear, set, function 3738 3739 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 3740 */ 3741 PetscErrorCode TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx) 3742 { 3743 PetscErrorCode ierr; 3744 TSMatlabContext *sctx; 3745 3746 PetscFunctionBegin; 3747 /* currently sctx is memory bleed */ 3748 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 3749 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3750 /* 3751 This should work, but it doesn't 3752 sctx->ctx = ctx; 3753 mexMakeArrayPersistent(sctx->ctx); 3754 */ 3755 sctx->ctx = mxDuplicateArray(ctx); 3756 ierr = TSSetIFunction(ts,PETSC_NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr); 3757 PetscFunctionReturn(0); 3758 } 3759 3760 #undef __FUNCT__ 3761 #define __FUNCT__ "TSComputeJacobian_Matlab" 3762 /* 3763 TSComputeJacobian_Matlab - Calls the function that has been set with 3764 TSSetJacobianMatlab(). 3765 3766 Collective on TS 3767 3768 Input Parameters: 3769 + ts - the TS context 3770 . x - input vector 3771 . A, B - the matrices 3772 - ctx - user context 3773 3774 Output Parameter: 3775 . flag - structure of the matrix 3776 3777 Level: developer 3778 3779 .keywords: TS, nonlinear, compute, function 3780 3781 .seealso: TSSetFunction(), TSGetFunction() 3782 @*/ 3783 PetscErrorCode TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec x,Vec xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flag, void *ctx) 3784 { 3785 PetscErrorCode ierr; 3786 TSMatlabContext *sctx = (TSMatlabContext *)ctx; 3787 int nlhs = 2,nrhs = 9; 3788 mxArray *plhs[2],*prhs[9]; 3789 long long int lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0; 3790 3791 PetscFunctionBegin; 3792 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3793 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3794 3795 /* call Matlab function in ctx with arguments x and y */ 3796 3797 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 3798 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3799 ierr = PetscMemcpy(&lxdot,&xdot,sizeof(x));CHKERRQ(ierr); 3800 ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 3801 ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 3802 prhs[0] = mxCreateDoubleScalar((double)ls); 3803 prhs[1] = mxCreateDoubleScalar((double)time); 3804 prhs[2] = mxCreateDoubleScalar((double)lx); 3805 prhs[3] = mxCreateDoubleScalar((double)lxdot); 3806 prhs[4] = mxCreateDoubleScalar((double)shift); 3807 prhs[5] = mxCreateDoubleScalar((double)lA); 3808 prhs[6] = mxCreateDoubleScalar((double)lB); 3809 prhs[7] = mxCreateString(sctx->funcname); 3810 prhs[8] = sctx->ctx; 3811 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr); 3812 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3813 *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 3814 mxDestroyArray(prhs[0]); 3815 mxDestroyArray(prhs[1]); 3816 mxDestroyArray(prhs[2]); 3817 mxDestroyArray(prhs[3]); 3818 mxDestroyArray(prhs[4]); 3819 mxDestroyArray(prhs[5]); 3820 mxDestroyArray(prhs[6]); 3821 mxDestroyArray(prhs[7]); 3822 mxDestroyArray(plhs[0]); 3823 mxDestroyArray(plhs[1]); 3824 PetscFunctionReturn(0); 3825 } 3826 3827 3828 #undef __FUNCT__ 3829 #define __FUNCT__ "TSSetJacobianMatlab" 3830 /* 3831 TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 3832 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 3833 3834 Logically Collective on TS 3835 3836 Input Parameters: 3837 + ts - the TS context 3838 . A,B - Jacobian matrices 3839 . func - function evaluation routine 3840 - ctx - user context 3841 3842 Calling sequence of func: 3843 $ flag = func (TS ts,PetscReal time,Vec x,Vec xdot,Mat A,Mat B,void *ctx); 3844 3845 3846 Level: developer 3847 3848 .keywords: TS, nonlinear, set, function 3849 3850 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 3851 */ 3852 PetscErrorCode TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx) 3853 { 3854 PetscErrorCode ierr; 3855 TSMatlabContext *sctx; 3856 3857 PetscFunctionBegin; 3858 /* currently sctx is memory bleed */ 3859 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 3860 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3861 /* 3862 This should work, but it doesn't 3863 sctx->ctx = ctx; 3864 mexMakeArrayPersistent(sctx->ctx); 3865 */ 3866 sctx->ctx = mxDuplicateArray(ctx); 3867 ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 3868 PetscFunctionReturn(0); 3869 } 3870 3871 #undef __FUNCT__ 3872 #define __FUNCT__ "TSMonitor_Matlab" 3873 /* 3874 TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab(). 3875 3876 Collective on TS 3877 3878 .seealso: TSSetFunction(), TSGetFunction() 3879 @*/ 3880 PetscErrorCode TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec x, void *ctx) 3881 { 3882 PetscErrorCode ierr; 3883 TSMatlabContext *sctx = (TSMatlabContext *)ctx; 3884 int nlhs = 1,nrhs = 6; 3885 mxArray *plhs[1],*prhs[6]; 3886 long long int lx = 0,ls = 0; 3887 3888 PetscFunctionBegin; 3889 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3890 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3891 3892 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 3893 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3894 prhs[0] = mxCreateDoubleScalar((double)ls); 3895 prhs[1] = mxCreateDoubleScalar((double)it); 3896 prhs[2] = mxCreateDoubleScalar((double)time); 3897 prhs[3] = mxCreateDoubleScalar((double)lx); 3898 prhs[4] = mxCreateString(sctx->funcname); 3899 prhs[5] = sctx->ctx; 3900 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr); 3901 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3902 mxDestroyArray(prhs[0]); 3903 mxDestroyArray(prhs[1]); 3904 mxDestroyArray(prhs[2]); 3905 mxDestroyArray(prhs[3]); 3906 mxDestroyArray(prhs[4]); 3907 mxDestroyArray(plhs[0]); 3908 PetscFunctionReturn(0); 3909 } 3910 3911 3912 #undef __FUNCT__ 3913 #define __FUNCT__ "TSMonitorSetMatlab" 3914 /* 3915 TSMonitorSetMatlab - Sets the monitor function from Matlab 3916 3917 Level: developer 3918 3919 .keywords: TS, nonlinear, set, function 3920 3921 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 3922 */ 3923 PetscErrorCode TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx) 3924 { 3925 PetscErrorCode ierr; 3926 TSMatlabContext *sctx; 3927 3928 PetscFunctionBegin; 3929 /* currently sctx is memory bleed */ 3930 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 3931 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3932 /* 3933 This should work, but it doesn't 3934 sctx->ctx = ctx; 3935 mexMakeArrayPersistent(sctx->ctx); 3936 */ 3937 sctx->ctx = mxDuplicateArray(ctx); 3938 ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 3939 PetscFunctionReturn(0); 3940 } 3941 #endif 3942 3943 #undef __FUNCT__ 3944 #define __FUNCT__ "TSMonitorSolutionODE" 3945 /*@C 3946 TSMonitorSolutionODE - Monitors progress of the TS solvers by plotting each component of the solution vector 3947 in a time based line graph 3948 3949 Collective on TS 3950 3951 Input Parameters: 3952 + ts - the TS context 3953 . step - current time-step 3954 . ptime - current time 3955 - lg - a line graph object 3956 3957 Level: intermediate 3958 3959 Notes: only for sequential solves 3960 3961 .keywords: TS, vector, monitor, view 3962 3963 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 3964 @*/ 3965 PetscErrorCode TSMonitorSolutionODE(TS ts,PetscInt step,PetscReal ptime,Vec x,void *dummy) 3966 { 3967 PetscErrorCode ierr; 3968 PetscDrawLG lg = (PetscDrawLG)dummy; 3969 const PetscScalar *yy; 3970 3971 PetscFunctionBegin; 3972 if (!step) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3973 ierr = VecGetArrayRead(x,&yy);CHKERRQ(ierr); 3974 ierr = PetscDrawLGAddCommonPoint(lg,ptime,yy);CHKERRQ(ierr); 3975 ierr = VecRestoreArrayRead(x,&yy);CHKERRQ(ierr); 3976 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3977 PetscFunctionReturn(0); 3978 } 3979 3980 #undef __FUNCT__ 3981 #define __FUNCT__ "TSMonitorSolutionODEDestroy" 3982 /*@C 3983 TSMonitorSolutionODEDestroy - Destroys the monitor context for TSMonitorSolutionODE() 3984 3985 Collective on TS 3986 3987 Input Parameters: 3988 . ctx - the monitor context 3989 3990 Level: intermediate 3991 3992 .keywords: TS, vector, monitor, view 3993 3994 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorSolutionODE() 3995 @*/ 3996 PetscErrorCode TSMonitorSolutionODEDestroy(PetscDrawLG *lg) 3997 { 3998 PetscDraw draw; 3999 PetscErrorCode ierr; 4000 4001 PetscFunctionBegin; 4002 ierr = PetscDrawLGGetDraw(*lg,&draw);CHKERRQ(ierr); 4003 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 4004 ierr = PetscDrawLGDestroy(lg);CHKERRQ(ierr); 4005 PetscFunctionReturn(0); 4006 } 4007 4008 #undef __FUNCT__ 4009 #define __FUNCT__ "TSMonitorSolutionODECreate" 4010 /*@C 4011 TSMonitorSolutionODECreate - Creates the monitor context for TSMonitorSolutionODE() 4012 4013 Collective on TS 4014 4015 Input Parameter: 4016 + comm - MPI communicator 4017 . N - number of components in the solution vector 4018 - 4019 4020 Output Patameter: 4021 . ctx - the monitor context 4022 4023 Level: intermediate 4024 4025 .keywords: TS, vector, monitor, view 4026 4027 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorSolution() 4028 @*/ 4029 PetscErrorCode TSMonitorSolutionODECreate(MPI_Comm comm,PetscInt N,const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 4030 { 4031 PetscDraw win; 4032 PetscErrorCode ierr; 4033 PetscDrawAxis axis; 4034 4035 PetscFunctionBegin; 4036 ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&win);CHKERRQ(ierr); 4037 ierr = PetscDrawSetType(win,PETSC_DRAW_X);CHKERRQ(ierr); 4038 ierr = PetscDrawLGCreate(win,N,draw);CHKERRQ(ierr); 4039 ierr = PetscDrawLGIndicateDataPoints(*draw);CHKERRQ(ierr); 4040 ierr = PetscDrawLGGetAxis(*draw,&axis);CHKERRQ(ierr); 4041 ierr = PetscDrawAxisSetLabels(axis,"Solution","Time","Solution");CHKERRQ(ierr); 4042 ierr = PetscLogObjectParent(*draw,win);CHKERRQ(ierr); 4043 PetscFunctionReturn(0); 4044 } 4045 4046 #undef __FUNCT__ 4047 #define __FUNCT__ "TSMonitorErrorODE" 4048 /*@C 4049 TSMonitorErrorODE - Monitors progress of the TS solvers by plotting each component of the solution vector 4050 in a time based line graph 4051 4052 Collective on TS 4053 4054 Input Parameters: 4055 + ts - the TS context 4056 . step - current time-step 4057 . ptime - current time 4058 - lg - a line graph object 4059 4060 Level: intermediate 4061 4062 Notes: only for sequential solves 4063 4064 .keywords: TS, vector, monitor, view 4065 4066 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4067 @*/ 4068 PetscErrorCode TSMonitorErrorODE(TS ts,PetscInt step,PetscReal ptime,Vec x,void *dummy) 4069 { 4070 PetscErrorCode ierr; 4071 PetscDrawLG lg = (PetscDrawLG)dummy; 4072 const PetscScalar *yy; 4073 Vec y; 4074 4075 PetscFunctionBegin; 4076 if (!step) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 4077 ierr = VecDuplicate(x,&y);CHKERRQ(ierr); 4078 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 4079 ierr = VecAXPY(y,-1.0,x);CHKERRQ(ierr); 4080 ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr); 4081 ierr = PetscDrawLGAddCommonPoint(lg,ptime,yy);CHKERRQ(ierr); 4082 ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr); 4083 ierr = VecDestroy(&y);CHKERRQ(ierr); 4084 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 4085 PetscFunctionReturn(0); 4086 } 4087 4088 #undef __FUNCT__ 4089 #define __FUNCT__ "TSMonitorErrorODEDestroy" 4090 /*@C 4091 TSMonitorErrorODEDestroy - Destroys the monitor context for TSMonitorErrorODE() 4092 4093 Collective on TS 4094 4095 Input Parameters: 4096 . ctx - the monitor context 4097 4098 Level: intermediate 4099 4100 .keywords: TS, vector, monitor, view 4101 4102 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorErrorODE() 4103 @*/ 4104 PetscErrorCode TSMonitorErrorODEDestroy(PetscDrawLG *lg) 4105 { 4106 PetscDraw draw; 4107 PetscErrorCode ierr; 4108 4109 PetscFunctionBegin; 4110 ierr = PetscDrawLGGetDraw(*lg,&draw);CHKERRQ(ierr); 4111 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 4112 ierr = PetscDrawLGDestroy(lg);CHKERRQ(ierr); 4113 PetscFunctionReturn(0); 4114 } 4115 4116 #undef __FUNCT__ 4117 #define __FUNCT__ "TSMonitorErrorODECreate" 4118 /*@C 4119 TSMonitorErrorODECreate - Creates the monitor context for TSMonitorErrorODE() 4120 4121 Collective on TS 4122 4123 Input Parameter: 4124 + comm - MPI communicator 4125 . N - number of components in the solution vector 4126 - 4127 4128 Output Patameter: 4129 . ctx - the monitor context 4130 4131 Level: intermediate 4132 4133 .keywords: TS, vector, monitor, view 4134 4135 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorError() 4136 @*/ 4137 PetscErrorCode TSMonitorErrorODECreate(MPI_Comm comm,PetscInt N,const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 4138 { 4139 PetscDraw win; 4140 PetscErrorCode ierr; 4141 PetscDrawAxis axis; 4142 4143 PetscFunctionBegin; 4144 ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&win);CHKERRQ(ierr); 4145 ierr = PetscDrawSetType(win,PETSC_DRAW_X);CHKERRQ(ierr); 4146 ierr = PetscDrawLGCreate(win,N,draw);CHKERRQ(ierr); 4147 ierr = PetscDrawLGIndicateDataPoints(*draw);CHKERRQ(ierr); 4148 ierr = PetscDrawLGGetAxis(*draw,&axis);CHKERRQ(ierr); 4149 ierr = PetscDrawAxisSetLabels(axis,"Error","Time","Error");CHKERRQ(ierr); 4150 ierr = PetscLogObjectParent(*draw,win);CHKERRQ(ierr); 4151 PetscFunctionReturn(0); 4152 } 4153