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