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