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,"Timestep as function of time","Time","Time step");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 = ptime,y; 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,"Timestep as function of time","Time","Time step");CHKERRQ(ierr); 2333 } 2334 2335 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2336 ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr); 2337 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2338 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2339 PetscFunctionReturn(0); 2340 } 2341 2342 #undef __FUNCT__ 2343 #define __FUNCT__ "TSMonitorLGDestroy" 2344 /*@C 2345 TSMonitorLGDestroy - Destroys a line graph context that was created 2346 with TSMonitorLGCreate(). 2347 2348 Collective on PetscDrawLG 2349 2350 Input Parameter: 2351 . draw - the drawing context 2352 2353 Level: intermediate 2354 2355 .keywords: TS, monitor, line graph, destroy 2356 2357 .seealso: TSMonitorLGCreate(), TSMonitorSet(), TSMonitorLG(); 2358 @*/ 2359 PetscErrorCode TSMonitorLGDestroy(PetscDrawLG *drawlg) 2360 { 2361 PetscDraw draw; 2362 PetscErrorCode ierr; 2363 2364 PetscFunctionBegin; 2365 ierr = PetscDrawLGGetDraw(*drawlg,&draw);CHKERRQ(ierr); 2366 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 2367 ierr = PetscDrawLGDestroy(drawlg);CHKERRQ(ierr); 2368 PetscFunctionReturn(0); 2369 } 2370 2371 #undef __FUNCT__ 2372 #define __FUNCT__ "TSGetTime" 2373 /*@ 2374 TSGetTime - Gets the time of the most recently completed step. 2375 2376 Not Collective 2377 2378 Input Parameter: 2379 . ts - the TS context obtained from TSCreate() 2380 2381 Output Parameter: 2382 . t - the current time 2383 2384 Level: beginner 2385 2386 Note: 2387 When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(), 2388 TSSetPreStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated. 2389 2390 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 2391 2392 .keywords: TS, get, time 2393 @*/ 2394 PetscErrorCode TSGetTime(TS ts,PetscReal* t) 2395 { 2396 PetscFunctionBegin; 2397 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2398 PetscValidRealPointer(t,2); 2399 *t = ts->ptime; 2400 PetscFunctionReturn(0); 2401 } 2402 2403 #undef __FUNCT__ 2404 #define __FUNCT__ "TSSetTime" 2405 /*@ 2406 TSSetTime - Allows one to reset the time. 2407 2408 Logically Collective on TS 2409 2410 Input Parameters: 2411 + ts - the TS context obtained from TSCreate() 2412 - time - the time 2413 2414 Level: intermediate 2415 2416 .seealso: TSGetTime(), TSSetDuration() 2417 2418 .keywords: TS, set, time 2419 @*/ 2420 PetscErrorCode TSSetTime(TS ts, PetscReal t) 2421 { 2422 PetscFunctionBegin; 2423 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2424 PetscValidLogicalCollectiveReal(ts,t,2); 2425 ts->ptime = t; 2426 PetscFunctionReturn(0); 2427 } 2428 2429 #undef __FUNCT__ 2430 #define __FUNCT__ "TSSetOptionsPrefix" 2431 /*@C 2432 TSSetOptionsPrefix - Sets the prefix used for searching for all 2433 TS options in the database. 2434 2435 Logically Collective on TS 2436 2437 Input Parameter: 2438 + ts - The TS context 2439 - prefix - The prefix to prepend to all option names 2440 2441 Notes: 2442 A hyphen (-) must NOT be given at the beginning of the prefix name. 2443 The first character of all runtime options is AUTOMATICALLY the 2444 hyphen. 2445 2446 Level: advanced 2447 2448 .keywords: TS, set, options, prefix, database 2449 2450 .seealso: TSSetFromOptions() 2451 2452 @*/ 2453 PetscErrorCode TSSetOptionsPrefix(TS ts,const char prefix[]) 2454 { 2455 PetscErrorCode ierr; 2456 SNES snes; 2457 2458 PetscFunctionBegin; 2459 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2460 ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 2461 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2462 ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr); 2463 PetscFunctionReturn(0); 2464 } 2465 2466 2467 #undef __FUNCT__ 2468 #define __FUNCT__ "TSAppendOptionsPrefix" 2469 /*@C 2470 TSAppendOptionsPrefix - Appends to the prefix used for searching for all 2471 TS options in the database. 2472 2473 Logically Collective on TS 2474 2475 Input Parameter: 2476 + ts - The TS context 2477 - prefix - The prefix to prepend to all option names 2478 2479 Notes: 2480 A hyphen (-) must NOT be given at the beginning of the prefix name. 2481 The first character of all runtime options is AUTOMATICALLY the 2482 hyphen. 2483 2484 Level: advanced 2485 2486 .keywords: TS, append, options, prefix, database 2487 2488 .seealso: TSGetOptionsPrefix() 2489 2490 @*/ 2491 PetscErrorCode TSAppendOptionsPrefix(TS ts,const char prefix[]) 2492 { 2493 PetscErrorCode ierr; 2494 SNES snes; 2495 2496 PetscFunctionBegin; 2497 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2498 ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 2499 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2500 ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr); 2501 PetscFunctionReturn(0); 2502 } 2503 2504 #undef __FUNCT__ 2505 #define __FUNCT__ "TSGetOptionsPrefix" 2506 /*@C 2507 TSGetOptionsPrefix - Sets the prefix used for searching for all 2508 TS options in the database. 2509 2510 Not Collective 2511 2512 Input Parameter: 2513 . ts - The TS context 2514 2515 Output Parameter: 2516 . prefix - A pointer to the prefix string used 2517 2518 Notes: On the fortran side, the user should pass in a string 'prifix' of 2519 sufficient length to hold the prefix. 2520 2521 Level: intermediate 2522 2523 .keywords: TS, get, options, prefix, database 2524 2525 .seealso: TSAppendOptionsPrefix() 2526 @*/ 2527 PetscErrorCode TSGetOptionsPrefix(TS ts,const char *prefix[]) 2528 { 2529 PetscErrorCode ierr; 2530 2531 PetscFunctionBegin; 2532 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2533 PetscValidPointer(prefix,2); 2534 ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 2535 PetscFunctionReturn(0); 2536 } 2537 2538 #undef __FUNCT__ 2539 #define __FUNCT__ "TSGetRHSJacobian" 2540 /*@C 2541 TSGetRHSJacobian - Returns the Jacobian J at the present timestep. 2542 2543 Not Collective, but parallel objects are returned if TS is parallel 2544 2545 Input Parameter: 2546 . ts - The TS context obtained from TSCreate() 2547 2548 Output Parameters: 2549 + J - The Jacobian J of F, where U_t = F(U,t) 2550 . M - The preconditioner matrix, usually the same as J 2551 . func - Function to compute the Jacobian of the RHS 2552 - ctx - User-defined context for Jacobian evaluation routine 2553 2554 Notes: You can pass in PETSC_NULL for any return argument you do not need. 2555 2556 Level: intermediate 2557 2558 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 2559 2560 .keywords: TS, timestep, get, matrix, Jacobian 2561 @*/ 2562 PetscErrorCode TSGetRHSJacobian(TS ts,Mat *J,Mat *M,TSRHSJacobian *func,void **ctx) 2563 { 2564 PetscErrorCode ierr; 2565 SNES snes; 2566 DM dm; 2567 2568 PetscFunctionBegin; 2569 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2570 ierr = SNESGetJacobian(snes,J,M,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 2571 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 2572 ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr); 2573 PetscFunctionReturn(0); 2574 } 2575 2576 #undef __FUNCT__ 2577 #define __FUNCT__ "TSGetIJacobian" 2578 /*@C 2579 TSGetIJacobian - Returns the implicit Jacobian at the present timestep. 2580 2581 Not Collective, but parallel objects are returned if TS is parallel 2582 2583 Input Parameter: 2584 . ts - The TS context obtained from TSCreate() 2585 2586 Output Parameters: 2587 + A - The Jacobian of F(t,U,U_t) 2588 . B - The preconditioner matrix, often the same as A 2589 . f - The function to compute the matrices 2590 - ctx - User-defined context for Jacobian evaluation routine 2591 2592 Notes: You can pass in PETSC_NULL for any return argument you do not need. 2593 2594 Level: advanced 2595 2596 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 2597 2598 .keywords: TS, timestep, get, matrix, Jacobian 2599 @*/ 2600 PetscErrorCode TSGetIJacobian(TS ts,Mat *A,Mat *B,TSIJacobian *f,void **ctx) 2601 { 2602 PetscErrorCode ierr; 2603 SNES snes; 2604 DM dm; 2605 PetscFunctionBegin; 2606 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2607 ierr = SNESGetJacobian(snes,A,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 2608 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 2609 ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr); 2610 PetscFunctionReturn(0); 2611 } 2612 2613 typedef struct { 2614 PetscViewer viewer; 2615 Vec initialsolution; 2616 PetscBool showinitial; 2617 } TSMonitorSolutionCtx; 2618 2619 #undef __FUNCT__ 2620 #define __FUNCT__ "TSMonitorSolution" 2621 /*@C 2622 TSMonitorSolution - Monitors progress of the TS solvers by calling 2623 VecView() for the solution at each timestep 2624 2625 Collective on TS 2626 2627 Input Parameters: 2628 + ts - the TS context 2629 . step - current time-step 2630 . ptime - current time 2631 - dummy - either a viewer or PETSC_NULL 2632 2633 Level: intermediate 2634 2635 .keywords: TS, vector, monitor, view 2636 2637 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 2638 @*/ 2639 PetscErrorCode TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec x,void *dummy) 2640 { 2641 PetscErrorCode ierr; 2642 TSMonitorSolutionCtx *ictx = (TSMonitorSolutionCtx*)dummy; 2643 2644 PetscFunctionBegin; 2645 if (!step && ictx->showinitial) { 2646 if (!ictx->initialsolution) { 2647 ierr = VecDuplicate(x,&ictx->initialsolution);CHKERRQ(ierr); 2648 } 2649 ierr = VecCopy(x,ictx->initialsolution);CHKERRQ(ierr); 2650 } 2651 if (ictx->showinitial) { 2652 PetscReal pause; 2653 ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr); 2654 ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr); 2655 ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr); 2656 ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr); 2657 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr); 2658 } 2659 ierr = VecView(x,ictx->viewer);CHKERRQ(ierr); 2660 if (ictx->showinitial) { 2661 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr); 2662 } 2663 PetscFunctionReturn(0); 2664 } 2665 2666 2667 #undef __FUNCT__ 2668 #define __FUNCT__ "TSMonitorSolutionDestroy" 2669 /*@C 2670 TSMonitorSolutionDestroy - Destroys the monitor context for TSMonitorSolution 2671 2672 Collective on TS 2673 2674 Input Parameters: 2675 . ctx - the monitor context 2676 2677 Level: intermediate 2678 2679 .keywords: TS, vector, monitor, view 2680 2681 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorSolution() 2682 @*/ 2683 PetscErrorCode TSMonitorSolutionDestroy(void **ctx) 2684 { 2685 PetscErrorCode ierr; 2686 TSMonitorSolutionCtx *ictx = *(TSMonitorSolutionCtx**)ctx; 2687 2688 PetscFunctionBegin; 2689 ierr = PetscViewerDestroy(&ictx->viewer);CHKERRQ(ierr); 2690 ierr = VecDestroy(&ictx->initialsolution);CHKERRQ(ierr); 2691 ierr = PetscFree(ictx);CHKERRQ(ierr); 2692 PetscFunctionReturn(0); 2693 } 2694 2695 #undef __FUNCT__ 2696 #define __FUNCT__ "TSMonitorSolutionCreate" 2697 /*@C 2698 TSMonitorSolutionCreate - Creates the monitor context for TSMonitorSolution 2699 2700 Collective on TS 2701 2702 Input Parameter: 2703 . ts - time-step context 2704 2705 Output Patameter: 2706 . ctx - the monitor context 2707 2708 Level: intermediate 2709 2710 .keywords: TS, vector, monitor, view 2711 2712 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorSolution() 2713 @*/ 2714 PetscErrorCode TSMonitorSolutionCreate(TS ts,PetscViewer viewer,void **ctx) 2715 { 2716 PetscErrorCode ierr; 2717 TSMonitorSolutionCtx *ictx; 2718 2719 PetscFunctionBegin; 2720 ierr = PetscNew(TSMonitorSolutionCtx,&ictx);CHKERRQ(ierr); 2721 *ctx = (void*)ictx; 2722 if (!viewer) { 2723 viewer = PETSC_VIEWER_DRAW_(((PetscObject)ts)->comm); 2724 } 2725 ierr = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr); 2726 ictx->viewer = viewer; 2727 ictx->showinitial = PETSC_FALSE; 2728 ierr = PetscOptionsGetBool(((PetscObject)ts)->prefix,"-ts_monitor_solution_initial",&ictx->showinitial,PETSC_NULL);CHKERRQ(ierr); 2729 PetscFunctionReturn(0); 2730 } 2731 2732 #undef __FUNCT__ 2733 #define __FUNCT__ "TSSetDM" 2734 /*@ 2735 TSSetDM - Sets the DM that may be used by some preconditioners 2736 2737 Logically Collective on TS and DM 2738 2739 Input Parameters: 2740 + ts - the preconditioner context 2741 - dm - the dm 2742 2743 Level: intermediate 2744 2745 2746 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM() 2747 @*/ 2748 PetscErrorCode TSSetDM(TS ts,DM dm) 2749 { 2750 PetscErrorCode ierr; 2751 SNES snes; 2752 TSDM tsdm; 2753 2754 PetscFunctionBegin; 2755 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2756 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 2757 if (ts->dm) { /* Move the TSDM context over to the new DM unless the new DM already has one */ 2758 PetscContainer oldcontainer,container; 2759 ierr = PetscObjectQuery((PetscObject)ts->dm,"TSDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 2760 ierr = PetscObjectQuery((PetscObject)dm,"TSDM",(PetscObject*)&container);CHKERRQ(ierr); 2761 if (oldcontainer && !container) { 2762 ierr = DMTSCopyContext(ts->dm,dm);CHKERRQ(ierr); 2763 ierr = DMTSGetContext(ts->dm,&tsdm);CHKERRQ(ierr); 2764 if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */ 2765 tsdm->originaldm = dm; 2766 } 2767 } 2768 ierr = DMDestroy(&ts->dm);CHKERRQ(ierr); 2769 } 2770 ts->dm = dm; 2771 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2772 ierr = SNESSetDM(snes,dm);CHKERRQ(ierr); 2773 PetscFunctionReturn(0); 2774 } 2775 2776 #undef __FUNCT__ 2777 #define __FUNCT__ "TSGetDM" 2778 /*@ 2779 TSGetDM - Gets the DM that may be used by some preconditioners 2780 2781 Not Collective 2782 2783 Input Parameter: 2784 . ts - the preconditioner context 2785 2786 Output Parameter: 2787 . dm - the dm 2788 2789 Level: intermediate 2790 2791 2792 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM() 2793 @*/ 2794 PetscErrorCode TSGetDM(TS ts,DM *dm) 2795 { 2796 PetscErrorCode ierr; 2797 2798 PetscFunctionBegin; 2799 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2800 if (!ts->dm) { 2801 ierr = DMShellCreate(((PetscObject)ts)->comm,&ts->dm);CHKERRQ(ierr); 2802 if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 2803 } 2804 *dm = ts->dm; 2805 PetscFunctionReturn(0); 2806 } 2807 2808 #undef __FUNCT__ 2809 #define __FUNCT__ "SNESTSFormFunction" 2810 /*@ 2811 SNESTSFormFunction - Function to evaluate nonlinear residual 2812 2813 Logically Collective on SNES 2814 2815 Input Parameter: 2816 + snes - nonlinear solver 2817 . X - the current state at which to evaluate the residual 2818 - ctx - user context, must be a TS 2819 2820 Output Parameter: 2821 . F - the nonlinear residual 2822 2823 Notes: 2824 This function is not normally called by users and is automatically registered with the SNES used by TS. 2825 It is most frequently passed to MatFDColoringSetFunction(). 2826 2827 Level: advanced 2828 2829 .seealso: SNESSetFunction(), MatFDColoringSetFunction() 2830 @*/ 2831 PetscErrorCode SNESTSFormFunction(SNES snes,Vec X,Vec F,void *ctx) 2832 { 2833 TS ts = (TS)ctx; 2834 PetscErrorCode ierr; 2835 2836 PetscFunctionBegin; 2837 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2838 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2839 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 2840 PetscValidHeaderSpecific(ts,TS_CLASSID,4); 2841 ierr = (ts->ops->snesfunction)(snes,X,F,ts);CHKERRQ(ierr); 2842 PetscFunctionReturn(0); 2843 } 2844 2845 #undef __FUNCT__ 2846 #define __FUNCT__ "SNESTSFormJacobian" 2847 /*@ 2848 SNESTSFormJacobian - Function to evaluate the Jacobian 2849 2850 Collective on SNES 2851 2852 Input Parameter: 2853 + snes - nonlinear solver 2854 . X - the current state at which to evaluate the residual 2855 - ctx - user context, must be a TS 2856 2857 Output Parameter: 2858 + A - the Jacobian 2859 . B - the preconditioning matrix (may be the same as A) 2860 - flag - indicates any structure change in the matrix 2861 2862 Notes: 2863 This function is not normally called by users and is automatically registered with the SNES used by TS. 2864 2865 Level: developer 2866 2867 .seealso: SNESSetJacobian() 2868 @*/ 2869 PetscErrorCode SNESTSFormJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flag,void *ctx) 2870 { 2871 TS ts = (TS)ctx; 2872 PetscErrorCode ierr; 2873 2874 PetscFunctionBegin; 2875 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2876 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2877 PetscValidPointer(A,3); 2878 PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 2879 PetscValidPointer(B,4); 2880 PetscValidHeaderSpecific(*B,MAT_CLASSID,4); 2881 PetscValidPointer(flag,5); 2882 PetscValidHeaderSpecific(ts,TS_CLASSID,6); 2883 ierr = (ts->ops->snesjacobian)(snes,X,A,B,flag,ts);CHKERRQ(ierr); 2884 PetscFunctionReturn(0); 2885 } 2886 2887 #undef __FUNCT__ 2888 #define __FUNCT__ "TSComputeRHSFunctionLinear" 2889 /*@C 2890 TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems only 2891 2892 Collective on TS 2893 2894 Input Arguments: 2895 + ts - time stepping context 2896 . t - time at which to evaluate 2897 . X - state at which to evaluate 2898 - ctx - context 2899 2900 Output Arguments: 2901 . F - right hand side 2902 2903 Level: intermediate 2904 2905 Notes: 2906 This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems. 2907 The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian(). 2908 2909 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 2910 @*/ 2911 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec X,Vec F,void *ctx) 2912 { 2913 PetscErrorCode ierr; 2914 Mat Arhs,Brhs; 2915 MatStructure flg2; 2916 2917 PetscFunctionBegin; 2918 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 2919 ierr = TSComputeRHSJacobian(ts,t,X,&Arhs,&Brhs,&flg2);CHKERRQ(ierr); 2920 ierr = MatMult(Arhs,X,F);CHKERRQ(ierr); 2921 PetscFunctionReturn(0); 2922 } 2923 2924 #undef __FUNCT__ 2925 #define __FUNCT__ "TSComputeRHSJacobianConstant" 2926 /*@C 2927 TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent. 2928 2929 Collective on TS 2930 2931 Input Arguments: 2932 + ts - time stepping context 2933 . t - time at which to evaluate 2934 . X - state at which to evaluate 2935 - ctx - context 2936 2937 Output Arguments: 2938 + A - pointer to operator 2939 . B - pointer to preconditioning matrix 2940 - flg - matrix structure flag 2941 2942 Level: intermediate 2943 2944 Notes: 2945 This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems. 2946 2947 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear() 2948 @*/ 2949 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec X,Mat *A,Mat *B,MatStructure *flg,void *ctx) 2950 { 2951 2952 PetscFunctionBegin; 2953 *flg = SAME_PRECONDITIONER; 2954 PetscFunctionReturn(0); 2955 } 2956 2957 #undef __FUNCT__ 2958 #define __FUNCT__ "TSComputeIFunctionLinear" 2959 /*@C 2960 TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only 2961 2962 Collective on TS 2963 2964 Input Arguments: 2965 + ts - time stepping context 2966 . t - time at which to evaluate 2967 . X - state at which to evaluate 2968 . Xdot - time derivative of state vector 2969 - ctx - context 2970 2971 Output Arguments: 2972 . F - left hand side 2973 2974 Level: intermediate 2975 2976 Notes: 2977 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 2978 user is required to write their own TSComputeIFunction. 2979 This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems. 2980 The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian(). 2981 2982 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant() 2983 @*/ 2984 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec X,Vec Xdot,Vec F,void *ctx) 2985 { 2986 PetscErrorCode ierr; 2987 Mat A,B; 2988 MatStructure flg2; 2989 2990 PetscFunctionBegin; 2991 ierr = TSGetIJacobian(ts,&A,&B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 2992 ierr = TSComputeIJacobian(ts,t,X,Xdot,1.0,&A,&B,&flg2,PETSC_TRUE);CHKERRQ(ierr); 2993 ierr = MatMult(A,Xdot,F);CHKERRQ(ierr); 2994 PetscFunctionReturn(0); 2995 } 2996 2997 #undef __FUNCT__ 2998 #define __FUNCT__ "TSComputeIJacobianConstant" 2999 /*@C 3000 TSComputeIJacobianConstant - Reuses a Jacobian that is time-independent. 3001 3002 Collective on TS 3003 3004 Input Arguments: 3005 + ts - time stepping context 3006 . t - time at which to evaluate 3007 . X - state at which to evaluate 3008 . Xdot - time derivative of state vector 3009 . shift - shift to apply 3010 - ctx - context 3011 3012 Output Arguments: 3013 + A - pointer to operator 3014 . B - pointer to preconditioning matrix 3015 - flg - matrix structure flag 3016 3017 Level: intermediate 3018 3019 Notes: 3020 This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems. 3021 3022 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear() 3023 @*/ 3024 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec X,Vec Xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,void *ctx) 3025 { 3026 3027 PetscFunctionBegin; 3028 *flg = SAME_PRECONDITIONER; 3029 PetscFunctionReturn(0); 3030 } 3031 3032 3033 #undef __FUNCT__ 3034 #define __FUNCT__ "TSGetConvergedReason" 3035 /*@ 3036 TSGetConvergedReason - Gets the reason the TS iteration was stopped. 3037 3038 Not Collective 3039 3040 Input Parameter: 3041 . ts - the TS context 3042 3043 Output Parameter: 3044 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 3045 manual pages for the individual convergence tests for complete lists 3046 3047 Level: intermediate 3048 3049 Notes: 3050 Can only be called after the call to TSSolve() is complete. 3051 3052 .keywords: TS, nonlinear, set, convergence, test 3053 3054 .seealso: TSSetConvergenceTest(), TSConvergedReason 3055 @*/ 3056 PetscErrorCode TSGetConvergedReason(TS ts,TSConvergedReason *reason) 3057 { 3058 PetscFunctionBegin; 3059 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3060 PetscValidPointer(reason,2); 3061 *reason = ts->reason; 3062 PetscFunctionReturn(0); 3063 } 3064 3065 #undef __FUNCT__ 3066 #define __FUNCT__ "TSGetSNESIterations" 3067 /*@ 3068 TSGetSNESIterations - Gets the total number of nonlinear iterations 3069 used by the time integrator. 3070 3071 Not Collective 3072 3073 Input Parameter: 3074 . ts - TS context 3075 3076 Output Parameter: 3077 . nits - number of nonlinear iterations 3078 3079 Notes: 3080 This counter is reset to zero for each successive call to TSSolve(). 3081 3082 Level: intermediate 3083 3084 .keywords: TS, get, number, nonlinear, iterations 3085 3086 .seealso: TSGetKSPIterations() 3087 @*/ 3088 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits) 3089 { 3090 PetscFunctionBegin; 3091 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3092 PetscValidIntPointer(nits,2); 3093 *nits = ts->snes_its; 3094 PetscFunctionReturn(0); 3095 } 3096 3097 #undef __FUNCT__ 3098 #define __FUNCT__ "TSGetKSPIterations" 3099 /*@ 3100 TSGetKSPIterations - Gets the total number of linear iterations 3101 used by the time integrator. 3102 3103 Not Collective 3104 3105 Input Parameter: 3106 . ts - TS context 3107 3108 Output Parameter: 3109 . lits - number of linear iterations 3110 3111 Notes: 3112 This counter is reset to zero for each successive call to TSSolve(). 3113 3114 Level: intermediate 3115 3116 .keywords: TS, get, number, linear, iterations 3117 3118 .seealso: TSGetSNESIterations(), SNESGetKSPIterations() 3119 @*/ 3120 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits) 3121 { 3122 PetscFunctionBegin; 3123 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3124 PetscValidIntPointer(lits,2); 3125 *lits = ts->ksp_its; 3126 PetscFunctionReturn(0); 3127 } 3128 3129 #undef __FUNCT__ 3130 #define __FUNCT__ "TSGetStepRejections" 3131 /*@ 3132 TSGetStepRejections - Gets the total number of rejected steps. 3133 3134 Not Collective 3135 3136 Input Parameter: 3137 . ts - TS context 3138 3139 Output Parameter: 3140 . rejects - number of steps rejected 3141 3142 Notes: 3143 This counter is reset to zero for each successive call to TSSolve(). 3144 3145 Level: intermediate 3146 3147 .keywords: TS, get, number 3148 3149 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails() 3150 @*/ 3151 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects) 3152 { 3153 PetscFunctionBegin; 3154 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3155 PetscValidIntPointer(rejects,2); 3156 *rejects = ts->reject; 3157 PetscFunctionReturn(0); 3158 } 3159 3160 #undef __FUNCT__ 3161 #define __FUNCT__ "TSGetSNESFailures" 3162 /*@ 3163 TSGetSNESFailures - Gets the total number of failed SNES solves 3164 3165 Not Collective 3166 3167 Input Parameter: 3168 . ts - TS context 3169 3170 Output Parameter: 3171 . fails - number of failed nonlinear solves 3172 3173 Notes: 3174 This counter is reset to zero for each successive call to TSSolve(). 3175 3176 Level: intermediate 3177 3178 .keywords: TS, get, number 3179 3180 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures() 3181 @*/ 3182 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails) 3183 { 3184 PetscFunctionBegin; 3185 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3186 PetscValidIntPointer(fails,2); 3187 *fails = ts->num_snes_failures; 3188 PetscFunctionReturn(0); 3189 } 3190 3191 #undef __FUNCT__ 3192 #define __FUNCT__ "TSSetMaxStepRejections" 3193 /*@ 3194 TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails 3195 3196 Not Collective 3197 3198 Input Parameter: 3199 + ts - TS context 3200 - rejects - maximum number of rejected steps, pass -1 for unlimited 3201 3202 Notes: 3203 The counter is reset to zero for each step 3204 3205 Options Database Key: 3206 . -ts_max_reject - Maximum number of step rejections before a step fails 3207 3208 Level: intermediate 3209 3210 .keywords: TS, set, maximum, number 3211 3212 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 3213 @*/ 3214 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects) 3215 { 3216 PetscFunctionBegin; 3217 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3218 ts->max_reject = rejects; 3219 PetscFunctionReturn(0); 3220 } 3221 3222 #undef __FUNCT__ 3223 #define __FUNCT__ "TSSetMaxSNESFailures" 3224 /*@ 3225 TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves 3226 3227 Not Collective 3228 3229 Input Parameter: 3230 + ts - TS context 3231 - fails - maximum number of failed nonlinear solves, pass -1 for unlimited 3232 3233 Notes: 3234 The counter is reset to zero for each successive call to TSSolve(). 3235 3236 Options Database Key: 3237 . -ts_max_snes_failures - Maximum number of nonlinear solve failures 3238 3239 Level: intermediate 3240 3241 .keywords: TS, set, maximum, number 3242 3243 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason() 3244 @*/ 3245 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails) 3246 { 3247 PetscFunctionBegin; 3248 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3249 ts->max_snes_failures = fails; 3250 PetscFunctionReturn(0); 3251 } 3252 3253 #undef __FUNCT__ 3254 #define __FUNCT__ "TSSetErrorIfStepFails()" 3255 /*@ 3256 TSSetErrorIfStepFails - Error if no step succeeds 3257 3258 Not Collective 3259 3260 Input Parameter: 3261 + ts - TS context 3262 - err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure 3263 3264 Options Database Key: 3265 . -ts_error_if_step_fails - Error if no step succeeds 3266 3267 Level: intermediate 3268 3269 .keywords: TS, set, error 3270 3271 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 3272 @*/ 3273 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err) 3274 { 3275 PetscFunctionBegin; 3276 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3277 ts->errorifstepfailed = err; 3278 PetscFunctionReturn(0); 3279 } 3280 3281 #undef __FUNCT__ 3282 #define __FUNCT__ "TSMonitorSolutionBinary" 3283 /*@C 3284 TSMonitorSolutionBinary - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file 3285 3286 Collective on TS 3287 3288 Input Parameters: 3289 + ts - the TS context 3290 . step - current time-step 3291 . ptime - current time 3292 . x - current state 3293 - viewer - binary viewer 3294 3295 Level: intermediate 3296 3297 .keywords: TS, vector, monitor, view 3298 3299 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 3300 @*/ 3301 PetscErrorCode TSMonitorSolutionBinary(TS ts,PetscInt step,PetscReal ptime,Vec x,void *viewer) 3302 { 3303 PetscErrorCode ierr; 3304 PetscViewer v = (PetscViewer)viewer; 3305 3306 PetscFunctionBegin; 3307 ierr = VecView(x,v);CHKERRQ(ierr); 3308 PetscFunctionReturn(0); 3309 } 3310 3311 #undef __FUNCT__ 3312 #define __FUNCT__ "TSMonitorSolutionVTK" 3313 /*@C 3314 TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep. 3315 3316 Collective on TS 3317 3318 Input Parameters: 3319 + ts - the TS context 3320 . step - current time-step 3321 . ptime - current time 3322 . x - current state 3323 - filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 3324 3325 Level: intermediate 3326 3327 Notes: 3328 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. 3329 These are named according to the file name template. 3330 3331 This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy(). 3332 3333 .keywords: TS, vector, monitor, view 3334 3335 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 3336 @*/ 3337 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec x,void *filenametemplate) 3338 { 3339 PetscErrorCode ierr; 3340 char filename[PETSC_MAX_PATH_LEN]; 3341 PetscViewer viewer; 3342 3343 PetscFunctionBegin; 3344 ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr); 3345 ierr = PetscViewerVTKOpen(((PetscObject)ts)->comm,filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); 3346 ierr = VecView(x,viewer);CHKERRQ(ierr); 3347 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3348 PetscFunctionReturn(0); 3349 } 3350 3351 #undef __FUNCT__ 3352 #define __FUNCT__ "TSMonitorSolutionVTKDestroy" 3353 /*@C 3354 TSMonitorSolutionVTKDestroy - Destroy context for monitoring 3355 3356 Collective on TS 3357 3358 Input Parameters: 3359 . filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 3360 3361 Level: intermediate 3362 3363 Note: 3364 This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK(). 3365 3366 .keywords: TS, vector, monitor, view 3367 3368 .seealso: TSMonitorSet(), TSMonitorSolutionVTK() 3369 @*/ 3370 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate) 3371 { 3372 PetscErrorCode ierr; 3373 3374 PetscFunctionBegin; 3375 ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr); 3376 PetscFunctionReturn(0); 3377 } 3378 3379 #undef __FUNCT__ 3380 #define __FUNCT__ "TSGetAdapt" 3381 /*@ 3382 TSGetAdapt - Get the adaptive controller context for the current method 3383 3384 Collective on TS if controller has not been created yet 3385 3386 Input Arguments: 3387 . ts - time stepping context 3388 3389 Output Arguments: 3390 . adapt - adaptive controller 3391 3392 Level: intermediate 3393 3394 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose() 3395 @*/ 3396 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt) 3397 { 3398 PetscErrorCode ierr; 3399 3400 PetscFunctionBegin; 3401 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3402 PetscValidPointer(adapt,2); 3403 if (!ts->adapt) { 3404 ierr = TSAdaptCreate(((PetscObject)ts)->comm,&ts->adapt);CHKERRQ(ierr); 3405 ierr = PetscLogObjectParent(ts,ts->adapt);CHKERRQ(ierr); 3406 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr); 3407 } 3408 *adapt = ts->adapt; 3409 PetscFunctionReturn(0); 3410 } 3411 3412 #undef __FUNCT__ 3413 #define __FUNCT__ "TSSetTolerances" 3414 /*@ 3415 TSSetTolerances - Set tolerances for local truncation error when using adaptive controller 3416 3417 Logically Collective 3418 3419 Input Arguments: 3420 + ts - time integration context 3421 . atol - scalar absolute tolerances, PETSC_DECIDE to leave current value 3422 . vatol - vector of absolute tolerances or PETSC_NULL, used in preference to atol if present 3423 . rtol - scalar relative tolerances, PETSC_DECIDE to leave current value 3424 - vrtol - vector of relative tolerances or PETSC_NULL, used in preference to atol if present 3425 3426 Level: beginner 3427 3428 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances() 3429 @*/ 3430 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol) 3431 { 3432 PetscErrorCode ierr; 3433 3434 PetscFunctionBegin; 3435 if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol; 3436 if (vatol) { 3437 ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr); 3438 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 3439 ts->vatol = vatol; 3440 } 3441 if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol; 3442 if (vrtol) { 3443 ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr); 3444 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 3445 ts->vrtol = vrtol; 3446 } 3447 PetscFunctionReturn(0); 3448 } 3449 3450 #undef __FUNCT__ 3451 #define __FUNCT__ "TSGetTolerances" 3452 /*@ 3453 TSGetTolerances - Get tolerances for local truncation error when using adaptive controller 3454 3455 Logically Collective 3456 3457 Input Arguments: 3458 . ts - time integration context 3459 3460 Output Arguments: 3461 + atol - scalar absolute tolerances, PETSC_NULL to ignore 3462 . vatol - vector of absolute tolerances, PETSC_NULL to ignore 3463 . rtol - scalar relative tolerances, PETSC_NULL to ignore 3464 - vrtol - vector of relative tolerances, PETSC_NULL to ignore 3465 3466 Level: beginner 3467 3468 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances() 3469 @*/ 3470 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol) 3471 { 3472 3473 PetscFunctionBegin; 3474 if (atol) *atol = ts->atol; 3475 if (vatol) *vatol = ts->vatol; 3476 if (rtol) *rtol = ts->rtol; 3477 if (vrtol) *vrtol = ts->vrtol; 3478 PetscFunctionReturn(0); 3479 } 3480 3481 #undef __FUNCT__ 3482 #define __FUNCT__ "TSErrorNormWRMS" 3483 /*@ 3484 TSErrorNormWRMS - compute a weighted norm of the difference between a vector and the current state 3485 3486 Collective on TS 3487 3488 Input Arguments: 3489 + ts - time stepping context 3490 - Y - state vector to be compared to ts->vec_sol 3491 3492 Output Arguments: 3493 . norm - weighted norm, a value of 1.0 is considered small 3494 3495 Level: developer 3496 3497 .seealso: TSSetTolerances() 3498 @*/ 3499 PetscErrorCode TSErrorNormWRMS(TS ts,Vec Y,PetscReal *norm) 3500 { 3501 PetscErrorCode ierr; 3502 PetscInt i,n,N; 3503 const PetscScalar *x,*y; 3504 Vec X; 3505 PetscReal sum,gsum; 3506 3507 PetscFunctionBegin; 3508 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3509 PetscValidHeaderSpecific(Y,VEC_CLASSID,2); 3510 PetscValidPointer(norm,3); 3511 X = ts->vec_sol; 3512 PetscCheckSameTypeAndComm(X,1,Y,2); 3513 if (X == Y) SETERRQ(((PetscObject)X)->comm,PETSC_ERR_ARG_IDN,"Y cannot be the TS solution vector"); 3514 3515 ierr = VecGetSize(X,&N);CHKERRQ(ierr); 3516 ierr = VecGetLocalSize(X,&n);CHKERRQ(ierr); 3517 ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr); 3518 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 3519 sum = 0.; 3520 if (ts->vatol && ts->vrtol) { 3521 const PetscScalar *atol,*rtol; 3522 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 3523 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 3524 for (i=0; i<n; i++) { 3525 PetscReal tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(x[i]),PetscAbsScalar(y[i])); 3526 sum += PetscSqr(PetscAbsScalar(y[i] - x[i]) / tol); 3527 } 3528 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 3529 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 3530 } else if (ts->vatol) { /* vector atol, scalar rtol */ 3531 const PetscScalar *atol; 3532 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 3533 for (i=0; i<n; i++) { 3534 PetscReal tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(x[i]),PetscAbsScalar(y[i])); 3535 sum += PetscSqr(PetscAbsScalar(y[i] - x[i]) / tol); 3536 } 3537 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 3538 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 3539 const PetscScalar *rtol; 3540 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 3541 for (i=0; i<n; i++) { 3542 PetscReal tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(x[i]),PetscAbsScalar(y[i])); 3543 sum += PetscSqr(PetscAbsScalar(y[i] - x[i]) / tol); 3544 } 3545 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 3546 } else { /* scalar atol, scalar rtol */ 3547 for (i=0; i<n; i++) { 3548 PetscReal tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(x[i]),PetscAbsScalar(y[i])); 3549 sum += PetscSqr(PetscAbsScalar(y[i] - x[i]) / tol); 3550 } 3551 } 3552 ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr); 3553 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 3554 3555 ierr = MPI_Allreduce(&sum,&gsum,1,MPIU_REAL,MPIU_SUM,((PetscObject)ts)->comm);CHKERRQ(ierr); 3556 *norm = PetscSqrtReal(gsum / N); 3557 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 3558 PetscFunctionReturn(0); 3559 } 3560 3561 #undef __FUNCT__ 3562 #define __FUNCT__ "TSSetCFLTimeLocal" 3563 /*@ 3564 TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler 3565 3566 Logically Collective on TS 3567 3568 Input Arguments: 3569 + ts - time stepping context 3570 - cfltime - maximum stable time step if using forward Euler (value can be different on each process) 3571 3572 Note: 3573 After calling this function, the global CFL time can be obtained by calling TSGetCFLTime() 3574 3575 Level: intermediate 3576 3577 .seealso: TSGetCFLTime(), TSADAPTCFL 3578 @*/ 3579 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime) 3580 { 3581 3582 PetscFunctionBegin; 3583 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3584 ts->cfltime_local = cfltime; 3585 ts->cfltime = -1.; 3586 PetscFunctionReturn(0); 3587 } 3588 3589 #undef __FUNCT__ 3590 #define __FUNCT__ "TSGetCFLTime" 3591 /*@ 3592 TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler 3593 3594 Collective on TS 3595 3596 Input Arguments: 3597 . ts - time stepping context 3598 3599 Output Arguments: 3600 . cfltime - maximum stable time step for forward Euler 3601 3602 Level: advanced 3603 3604 .seealso: TSSetCFLTimeLocal() 3605 @*/ 3606 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime) 3607 { 3608 PetscErrorCode ierr; 3609 3610 PetscFunctionBegin; 3611 if (ts->cfltime < 0) { 3612 ierr = MPI_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,((PetscObject)ts)->comm);CHKERRQ(ierr); 3613 } 3614 *cfltime = ts->cfltime; 3615 PetscFunctionReturn(0); 3616 } 3617 3618 #undef __FUNCT__ 3619 #define __FUNCT__ "TSVISetVariableBounds" 3620 /*@ 3621 TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu 3622 3623 Input Parameters: 3624 . ts - the TS context. 3625 . xl - lower bound. 3626 . xu - upper bound. 3627 3628 Notes: 3629 If this routine is not called then the lower and upper bounds are set to 3630 SNES_VI_NINF and SNES_VI_INF respectively during SNESSetUp(). 3631 3632 Level: advanced 3633 3634 @*/ 3635 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu) 3636 { 3637 PetscErrorCode ierr; 3638 SNES snes; 3639 3640 PetscFunctionBegin; 3641 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 3642 ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr); 3643 PetscFunctionReturn(0); 3644 } 3645 3646 #if defined(PETSC_HAVE_MATLAB_ENGINE) 3647 #include <mex.h> 3648 3649 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext; 3650 3651 #undef __FUNCT__ 3652 #define __FUNCT__ "TSComputeFunction_Matlab" 3653 /* 3654 TSComputeFunction_Matlab - Calls the function that has been set with 3655 TSSetFunctionMatlab(). 3656 3657 Collective on TS 3658 3659 Input Parameters: 3660 + snes - the TS context 3661 - x - input vector 3662 3663 Output Parameter: 3664 . y - function vector, as set by TSSetFunction() 3665 3666 Notes: 3667 TSComputeFunction() is typically used within nonlinear solvers 3668 implementations, so most users would not generally call this routine 3669 themselves. 3670 3671 Level: developer 3672 3673 .keywords: TS, nonlinear, compute, function 3674 3675 .seealso: TSSetFunction(), TSGetFunction() 3676 */ 3677 PetscErrorCode TSComputeFunction_Matlab(TS snes,PetscReal time,Vec x,Vec xdot,Vec y, void *ctx) 3678 { 3679 PetscErrorCode ierr; 3680 TSMatlabContext *sctx = (TSMatlabContext *)ctx; 3681 int nlhs = 1,nrhs = 7; 3682 mxArray *plhs[1],*prhs[7]; 3683 long long int lx = 0,lxdot = 0,ly = 0,ls = 0; 3684 3685 PetscFunctionBegin; 3686 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 3687 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3688 PetscValidHeaderSpecific(xdot,VEC_CLASSID,4); 3689 PetscValidHeaderSpecific(y,VEC_CLASSID,5); 3690 PetscCheckSameComm(snes,1,x,3); 3691 PetscCheckSameComm(snes,1,y,5); 3692 3693 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3694 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3695 ierr = PetscMemcpy(&lxdot,&xdot,sizeof(xdot));CHKERRQ(ierr); 3696 ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 3697 prhs[0] = mxCreateDoubleScalar((double)ls); 3698 prhs[1] = mxCreateDoubleScalar(time); 3699 prhs[2] = mxCreateDoubleScalar((double)lx); 3700 prhs[3] = mxCreateDoubleScalar((double)lxdot); 3701 prhs[4] = mxCreateDoubleScalar((double)ly); 3702 prhs[5] = mxCreateString(sctx->funcname); 3703 prhs[6] = sctx->ctx; 3704 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr); 3705 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3706 mxDestroyArray(prhs[0]); 3707 mxDestroyArray(prhs[1]); 3708 mxDestroyArray(prhs[2]); 3709 mxDestroyArray(prhs[3]); 3710 mxDestroyArray(prhs[4]); 3711 mxDestroyArray(prhs[5]); 3712 mxDestroyArray(plhs[0]); 3713 PetscFunctionReturn(0); 3714 } 3715 3716 3717 #undef __FUNCT__ 3718 #define __FUNCT__ "TSSetFunctionMatlab" 3719 /* 3720 TSSetFunctionMatlab - Sets the function evaluation routine and function 3721 vector for use by the TS routines in solving ODEs 3722 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 3723 3724 Logically Collective on TS 3725 3726 Input Parameters: 3727 + ts - the TS context 3728 - func - function evaluation routine 3729 3730 Calling sequence of func: 3731 $ func (TS ts,PetscReal time,Vec x,Vec xdot,Vec f,void *ctx); 3732 3733 Level: beginner 3734 3735 .keywords: TS, nonlinear, set, function 3736 3737 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 3738 */ 3739 PetscErrorCode TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx) 3740 { 3741 PetscErrorCode ierr; 3742 TSMatlabContext *sctx; 3743 3744 PetscFunctionBegin; 3745 /* currently sctx is memory bleed */ 3746 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 3747 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3748 /* 3749 This should work, but it doesn't 3750 sctx->ctx = ctx; 3751 mexMakeArrayPersistent(sctx->ctx); 3752 */ 3753 sctx->ctx = mxDuplicateArray(ctx); 3754 ierr = TSSetIFunction(ts,PETSC_NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr); 3755 PetscFunctionReturn(0); 3756 } 3757 3758 #undef __FUNCT__ 3759 #define __FUNCT__ "TSComputeJacobian_Matlab" 3760 /* 3761 TSComputeJacobian_Matlab - Calls the function that has been set with 3762 TSSetJacobianMatlab(). 3763 3764 Collective on TS 3765 3766 Input Parameters: 3767 + ts - the TS context 3768 . x - input vector 3769 . A, B - the matrices 3770 - ctx - user context 3771 3772 Output Parameter: 3773 . flag - structure of the matrix 3774 3775 Level: developer 3776 3777 .keywords: TS, nonlinear, compute, function 3778 3779 .seealso: TSSetFunction(), TSGetFunction() 3780 @*/ 3781 PetscErrorCode TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec x,Vec xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flag, void *ctx) 3782 { 3783 PetscErrorCode ierr; 3784 TSMatlabContext *sctx = (TSMatlabContext *)ctx; 3785 int nlhs = 2,nrhs = 9; 3786 mxArray *plhs[2],*prhs[9]; 3787 long long int lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0; 3788 3789 PetscFunctionBegin; 3790 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3791 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3792 3793 /* call Matlab function in ctx with arguments x and y */ 3794 3795 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 3796 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3797 ierr = PetscMemcpy(&lxdot,&xdot,sizeof(x));CHKERRQ(ierr); 3798 ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 3799 ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 3800 prhs[0] = mxCreateDoubleScalar((double)ls); 3801 prhs[1] = mxCreateDoubleScalar((double)time); 3802 prhs[2] = mxCreateDoubleScalar((double)lx); 3803 prhs[3] = mxCreateDoubleScalar((double)lxdot); 3804 prhs[4] = mxCreateDoubleScalar((double)shift); 3805 prhs[5] = mxCreateDoubleScalar((double)lA); 3806 prhs[6] = mxCreateDoubleScalar((double)lB); 3807 prhs[7] = mxCreateString(sctx->funcname); 3808 prhs[8] = sctx->ctx; 3809 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr); 3810 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3811 *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 3812 mxDestroyArray(prhs[0]); 3813 mxDestroyArray(prhs[1]); 3814 mxDestroyArray(prhs[2]); 3815 mxDestroyArray(prhs[3]); 3816 mxDestroyArray(prhs[4]); 3817 mxDestroyArray(prhs[5]); 3818 mxDestroyArray(prhs[6]); 3819 mxDestroyArray(prhs[7]); 3820 mxDestroyArray(plhs[0]); 3821 mxDestroyArray(plhs[1]); 3822 PetscFunctionReturn(0); 3823 } 3824 3825 3826 #undef __FUNCT__ 3827 #define __FUNCT__ "TSSetJacobianMatlab" 3828 /* 3829 TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 3830 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 3831 3832 Logically Collective on TS 3833 3834 Input Parameters: 3835 + ts - the TS context 3836 . A,B - Jacobian matrices 3837 . func - function evaluation routine 3838 - ctx - user context 3839 3840 Calling sequence of func: 3841 $ flag = func (TS ts,PetscReal time,Vec x,Vec xdot,Mat A,Mat B,void *ctx); 3842 3843 3844 Level: developer 3845 3846 .keywords: TS, nonlinear, set, function 3847 3848 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 3849 */ 3850 PetscErrorCode TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx) 3851 { 3852 PetscErrorCode ierr; 3853 TSMatlabContext *sctx; 3854 3855 PetscFunctionBegin; 3856 /* currently sctx is memory bleed */ 3857 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 3858 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3859 /* 3860 This should work, but it doesn't 3861 sctx->ctx = ctx; 3862 mexMakeArrayPersistent(sctx->ctx); 3863 */ 3864 sctx->ctx = mxDuplicateArray(ctx); 3865 ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 3866 PetscFunctionReturn(0); 3867 } 3868 3869 #undef __FUNCT__ 3870 #define __FUNCT__ "TSMonitor_Matlab" 3871 /* 3872 TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab(). 3873 3874 Collective on TS 3875 3876 .seealso: TSSetFunction(), TSGetFunction() 3877 @*/ 3878 PetscErrorCode TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec x, void *ctx) 3879 { 3880 PetscErrorCode ierr; 3881 TSMatlabContext *sctx = (TSMatlabContext *)ctx; 3882 int nlhs = 1,nrhs = 6; 3883 mxArray *plhs[1],*prhs[6]; 3884 long long int lx = 0,ls = 0; 3885 3886 PetscFunctionBegin; 3887 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3888 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3889 3890 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 3891 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3892 prhs[0] = mxCreateDoubleScalar((double)ls); 3893 prhs[1] = mxCreateDoubleScalar((double)it); 3894 prhs[2] = mxCreateDoubleScalar((double)time); 3895 prhs[3] = mxCreateDoubleScalar((double)lx); 3896 prhs[4] = mxCreateString(sctx->funcname); 3897 prhs[5] = sctx->ctx; 3898 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr); 3899 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3900 mxDestroyArray(prhs[0]); 3901 mxDestroyArray(prhs[1]); 3902 mxDestroyArray(prhs[2]); 3903 mxDestroyArray(prhs[3]); 3904 mxDestroyArray(prhs[4]); 3905 mxDestroyArray(plhs[0]); 3906 PetscFunctionReturn(0); 3907 } 3908 3909 3910 #undef __FUNCT__ 3911 #define __FUNCT__ "TSMonitorSetMatlab" 3912 /* 3913 TSMonitorSetMatlab - Sets the monitor function from Matlab 3914 3915 Level: developer 3916 3917 .keywords: TS, nonlinear, set, function 3918 3919 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 3920 */ 3921 PetscErrorCode TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx) 3922 { 3923 PetscErrorCode ierr; 3924 TSMatlabContext *sctx; 3925 3926 PetscFunctionBegin; 3927 /* currently sctx is memory bleed */ 3928 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 3929 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3930 /* 3931 This should work, but it doesn't 3932 sctx->ctx = ctx; 3933 mexMakeArrayPersistent(sctx->ctx); 3934 */ 3935 sctx->ctx = mxDuplicateArray(ctx); 3936 ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 3937 PetscFunctionReturn(0); 3938 } 3939 #endif 3940 3941 #undef __FUNCT__ 3942 #define __FUNCT__ "TSMonitorSolutionODE" 3943 /*@C 3944 TSMonitorSolutionODE - Monitors progress of the TS solvers by plotting each component of the solution vector 3945 in a time based line graph 3946 3947 Collective on TS 3948 3949 Input Parameters: 3950 + ts - the TS context 3951 . step - current time-step 3952 . ptime - current time 3953 - lg - a line graph object 3954 3955 Level: intermediate 3956 3957 Notes: only for sequential solves 3958 3959 .keywords: TS, vector, monitor, view 3960 3961 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 3962 @*/ 3963 PetscErrorCode TSMonitorSolutionODE(TS ts,PetscInt step,PetscReal ptime,Vec x,void *dummy) 3964 { 3965 PetscErrorCode ierr; 3966 PetscDrawLG lg = (PetscDrawLG)dummy; 3967 const PetscScalar *yy; 3968 3969 PetscFunctionBegin; 3970 if (!step) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3971 ierr = VecGetArrayRead(x,&yy);CHKERRQ(ierr); 3972 ierr = PetscDrawLGAddCommonPoint(lg,ptime,yy);CHKERRQ(ierr); 3973 ierr = VecRestoreArrayRead(x,&yy);CHKERRQ(ierr); 3974 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3975 PetscFunctionReturn(0); 3976 } 3977 3978 #undef __FUNCT__ 3979 #define __FUNCT__ "TSMonitorSolutionODEDestroy" 3980 /*@C 3981 TSMonitorSolutionODEDestroy - Destroys the monitor context for TSMonitorSolutionODE() 3982 3983 Collective on TS 3984 3985 Input Parameters: 3986 . ctx - the monitor context 3987 3988 Level: intermediate 3989 3990 .keywords: TS, vector, monitor, view 3991 3992 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorSolutionODE() 3993 @*/ 3994 PetscErrorCode TSMonitorSolutionODEDestroy(PetscDrawLG *lg) 3995 { 3996 PetscDraw draw; 3997 PetscErrorCode ierr; 3998 3999 PetscFunctionBegin; 4000 ierr = PetscDrawLGGetDraw(*lg,&draw);CHKERRQ(ierr); 4001 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 4002 ierr = PetscDrawLGDestroy(lg);CHKERRQ(ierr); 4003 PetscFunctionReturn(0); 4004 } 4005 4006 #undef __FUNCT__ 4007 #define __FUNCT__ "TSMonitorSolutionODECreate" 4008 /*@C 4009 TSMonitorSolutionODECreate - Creates the monitor context for TSMonitorSolutionODE() 4010 4011 Collective on TS 4012 4013 Input Parameter: 4014 + comm - MPI communicator 4015 . N - number of components in the solution vector 4016 - 4017 4018 Output Patameter: 4019 . ctx - the monitor context 4020 4021 Level: intermediate 4022 4023 .keywords: TS, vector, monitor, view 4024 4025 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorSolution() 4026 @*/ 4027 PetscErrorCode TSMonitorSolutionODECreate(MPI_Comm comm,PetscInt N,const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 4028 { 4029 PetscDraw win; 4030 PetscErrorCode ierr; 4031 PetscDrawAxis axis; 4032 4033 PetscFunctionBegin; 4034 ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&win);CHKERRQ(ierr); 4035 ierr = PetscDrawSetType(win,PETSC_DRAW_X);CHKERRQ(ierr); 4036 ierr = PetscDrawLGCreate(win,N,draw);CHKERRQ(ierr); 4037 ierr = PetscDrawLGIndicateDataPoints(*draw);CHKERRQ(ierr); 4038 ierr = PetscDrawLGGetAxis(*draw,&axis);CHKERRQ(ierr); 4039 ierr = PetscDrawAxisSetLabels(axis,"Solution","Time","Solution");CHKERRQ(ierr); 4040 ierr = PetscLogObjectParent(*draw,win);CHKERRQ(ierr); 4041 PetscFunctionReturn(0); 4042 } 4043 4044 #undef __FUNCT__ 4045 #define __FUNCT__ "TSMonitorErrorODE" 4046 /*@C 4047 TSMonitorErrorODE - Monitors progress of the TS solvers by plotting each component of the solution vector 4048 in a time based line graph 4049 4050 Collective on TS 4051 4052 Input Parameters: 4053 + ts - the TS context 4054 . step - current time-step 4055 . ptime - current time 4056 - lg - a line graph object 4057 4058 Level: intermediate 4059 4060 Notes: only for sequential solves 4061 4062 .keywords: TS, vector, monitor, view 4063 4064 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4065 @*/ 4066 PetscErrorCode TSMonitorErrorODE(TS ts,PetscInt step,PetscReal ptime,Vec x,void *dummy) 4067 { 4068 PetscErrorCode ierr; 4069 PetscDrawLG lg = (PetscDrawLG)dummy; 4070 const PetscScalar *yy; 4071 Vec y; 4072 4073 PetscFunctionBegin; 4074 if (!step) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 4075 ierr = VecDuplicate(x,&y);CHKERRQ(ierr); 4076 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 4077 ierr = VecAXPY(y,-1.0,x);CHKERRQ(ierr); 4078 ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr); 4079 ierr = PetscDrawLGAddCommonPoint(lg,ptime,yy);CHKERRQ(ierr); 4080 ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr); 4081 ierr = VecDestroy(&y);CHKERRQ(ierr); 4082 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 4083 PetscFunctionReturn(0); 4084 } 4085 4086 #undef __FUNCT__ 4087 #define __FUNCT__ "TSMonitorErrorODEDestroy" 4088 /*@C 4089 TSMonitorErrorODEDestroy - Destroys the monitor context for TSMonitorErrorODE() 4090 4091 Collective on TS 4092 4093 Input Parameters: 4094 . ctx - the monitor context 4095 4096 Level: intermediate 4097 4098 .keywords: TS, vector, monitor, view 4099 4100 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorErrorODE() 4101 @*/ 4102 PetscErrorCode TSMonitorErrorODEDestroy(PetscDrawLG *lg) 4103 { 4104 PetscDraw draw; 4105 PetscErrorCode ierr; 4106 4107 PetscFunctionBegin; 4108 ierr = PetscDrawLGGetDraw(*lg,&draw);CHKERRQ(ierr); 4109 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 4110 ierr = PetscDrawLGDestroy(lg);CHKERRQ(ierr); 4111 PetscFunctionReturn(0); 4112 } 4113 4114 #undef __FUNCT__ 4115 #define __FUNCT__ "TSMonitorErrorODECreate" 4116 /*@C 4117 TSMonitorErrorODECreate - Creates the monitor context for TSMonitorErrorODE() 4118 4119 Collective on TS 4120 4121 Input Parameter: 4122 + comm - MPI communicator 4123 . N - number of components in the solution vector 4124 - 4125 4126 Output Patameter: 4127 . ctx - the monitor context 4128 4129 Level: intermediate 4130 4131 .keywords: TS, vector, monitor, view 4132 4133 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorError() 4134 @*/ 4135 PetscErrorCode TSMonitorErrorODECreate(MPI_Comm comm,PetscInt N,const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 4136 { 4137 PetscDraw win; 4138 PetscErrorCode ierr; 4139 PetscDrawAxis axis; 4140 4141 PetscFunctionBegin; 4142 ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&win);CHKERRQ(ierr); 4143 ierr = PetscDrawSetType(win,PETSC_DRAW_X);CHKERRQ(ierr); 4144 ierr = PetscDrawLGCreate(win,N,draw);CHKERRQ(ierr); 4145 ierr = PetscDrawLGIndicateDataPoints(*draw);CHKERRQ(ierr); 4146 ierr = PetscDrawLGGetAxis(*draw,&axis);CHKERRQ(ierr); 4147 ierr = PetscDrawAxisSetLabels(axis,"Error","Time","Error");CHKERRQ(ierr); 4148 ierr = PetscLogObjectParent(*draw,win);CHKERRQ(ierr); 4149 PetscFunctionReturn(0); 4150 } 4151