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