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