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