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