1 #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/ 2 #include <petscdmshell.h> 3 #include <petscdmda.h> 4 #include <petscviewer.h> 5 #include <petscdraw.h> 6 #include <petscconvest.h> 7 8 #define SkipSmallValue(a,b,tol) if (PetscAbsScalar(a)< tol || PetscAbsScalar(b)< tol) continue; 9 10 /* Logging support */ 11 PetscClassId TS_CLASSID, DMTS_CLASSID; 12 PetscLogEvent TS_Step, TS_PseudoComputeTimeStep, TS_FunctionEval, TS_JacobianEval; 13 14 const char *const TSExactFinalTimeOptions[] = {"UNSPECIFIED","STEPOVER","INTERPOLATE","MATCHSTEP","TSExactFinalTimeOption","TS_EXACTFINALTIME_",NULL}; 15 16 17 /*@C 18 TSMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 19 20 Collective on TS 21 22 Input Parameters: 23 + ts - TS object you wish to monitor 24 . name - the monitor type one is seeking 25 . help - message indicating what monitoring is done 26 . manual - manual page for the monitor 27 . monitor - the monitor function 28 - monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the TS or PetscViewer objects 29 30 Level: developer 31 32 .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 33 PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 34 PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 35 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 36 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 37 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 38 PetscOptionsFList(), PetscOptionsEList() 39 @*/ 40 PetscErrorCode TSMonitorSetFromOptions(TS ts,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(TS,PetscViewerAndFormat*)) 41 { 42 PetscErrorCode ierr; 43 PetscViewer viewer; 44 PetscViewerFormat format; 45 PetscBool flg; 46 47 PetscFunctionBegin; 48 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts),((PetscObject) ts)->options,((PetscObject)ts)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr); 49 if (flg) { 50 PetscViewerAndFormat *vf; 51 ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr); 52 ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr); 53 if (monitorsetup) { 54 ierr = (*monitorsetup)(ts,vf);CHKERRQ(ierr); 55 } 56 ierr = TSMonitorSet(ts,(PetscErrorCode (*)(TS,PetscInt,PetscReal,Vec,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr); 57 } 58 PetscFunctionReturn(0); 59 } 60 61 static PetscErrorCode TSAdaptSetDefaultType(TSAdapt adapt,TSAdaptType default_type) 62 { 63 PetscErrorCode ierr; 64 65 PetscFunctionBegin; 66 PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1); 67 PetscValidCharPointer(default_type,2); 68 if (!((PetscObject)adapt)->type_name) { 69 ierr = TSAdaptSetType(adapt,default_type);CHKERRQ(ierr); 70 } 71 PetscFunctionReturn(0); 72 } 73 74 /*@ 75 TSSetFromOptions - Sets various TS parameters from user options. 76 77 Collective on TS 78 79 Input Parameter: 80 . ts - the TS context obtained from TSCreate() 81 82 Options Database Keys: 83 + -ts_type <type> - TSEULER, TSBEULER, TSSUNDIALS, TSPSEUDO, TSCN, TSRK, TSTHETA, TSALPHA, TSGLLE, TSSSP, TSGLEE, TSBSYMP 84 . -ts_save_trajectory - checkpoint the solution at each time-step 85 . -ts_max_time <time> - maximum time to compute to 86 . -ts_max_steps <steps> - maximum number of time-steps to take 87 . -ts_init_time <time> - initial time to start computation 88 . -ts_final_time <time> - final time to compute to (deprecated: use -ts_max_time) 89 . -ts_dt <dt> - initial time step 90 . -ts_exact_final_time <stepover,interpolate,matchstep> - whether to stop at the exact given final time and how to compute the solution at that ti,e 91 . -ts_max_snes_failures <maxfailures> - Maximum number of nonlinear solve failures allowed 92 . -ts_max_reject <maxrejects> - Maximum number of step rejections before step fails 93 . -ts_error_if_step_fails <true,false> - Error if no step succeeds 94 . -ts_rtol <rtol> - relative tolerance for local truncation error 95 . -ts_atol <atol> Absolute tolerance for local truncation error 96 . -ts_rhs_jacobian_test_mult -mat_shell_test_mult_view - test the Jacobian at each iteration against finite difference with RHS function 97 . -ts_rhs_jacobian_test_mult_transpose -mat_shell_test_mult_transpose_view - test the Jacobian at each iteration against finite difference with RHS function 98 . -ts_adjoint_solve <yes,no> After solving the ODE/DAE solve the adjoint problem (requires -ts_save_trajectory) 99 . -ts_fd_color - Use finite differences with coloring to compute IJacobian 100 . -ts_monitor - print information at each timestep 101 . -ts_monitor_lg_solution - Monitor solution graphically 102 . -ts_monitor_lg_error - Monitor error graphically 103 . -ts_monitor_error - Monitors norm of error 104 . -ts_monitor_lg_timestep - Monitor timestep size graphically 105 . -ts_monitor_lg_timestep_log - Monitor log timestep size graphically 106 . -ts_monitor_lg_snes_iterations - Monitor number nonlinear iterations for each timestep graphically 107 . -ts_monitor_lg_ksp_iterations - Monitor number nonlinear iterations for each timestep graphically 108 . -ts_monitor_sp_eig - Monitor eigenvalues of linearized operator graphically 109 . -ts_monitor_draw_solution - Monitor solution graphically 110 . -ts_monitor_draw_solution_phase <xleft,yleft,xright,yright> - Monitor solution graphically with phase diagram, requires problem with exactly 2 degrees of freedom 111 . -ts_monitor_draw_error - Monitor error graphically, requires use to have provided TSSetSolutionFunction() 112 . -ts_monitor_solution [ascii binary draw][:filename][:viewerformat] - monitors the solution at each timestep 113 . -ts_monitor_solution_vtk <filename.vts,filename.vtu> - Save each time step to a binary file, use filename-%%03D.vts (filename-%%03D.vtu) 114 - -ts_monitor_envelope - determine maximum and minimum value of each component of the solution over the solution time 115 116 Notes: 117 See SNESSetFromOptions() and KSPSetFromOptions() for how to control the nonlinear and linear solves used by the time-stepper. 118 119 Certain SNES options get reset for each new nonlinear solver, for example -snes_lag_jacobian <its> and -snes_lag_preconditioner <its>, in order 120 to retain them over the multiple nonlinear solves that TS uses you mush also provide -snes_lag_jacobian_persists true and 121 -snes_lag_preconditioner_persists true 122 123 Developer Note: 124 We should unify all the -ts_monitor options in the way that -xxx_view has been unified 125 126 Level: beginner 127 128 .seealso: TSGetType() 129 @*/ 130 PetscErrorCode TSSetFromOptions(TS ts) 131 { 132 PetscBool opt,flg,tflg; 133 PetscErrorCode ierr; 134 char monfilename[PETSC_MAX_PATH_LEN]; 135 PetscReal time_step; 136 TSExactFinalTimeOption eftopt; 137 char dir[16]; 138 TSIFunction ifun; 139 const char *defaultType; 140 char typeName[256]; 141 142 PetscFunctionBegin; 143 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 144 145 ierr = TSRegisterAll();CHKERRQ(ierr); 146 ierr = TSGetIFunction(ts,NULL,&ifun,NULL);CHKERRQ(ierr); 147 148 ierr = PetscObjectOptionsBegin((PetscObject)ts);CHKERRQ(ierr); 149 if (((PetscObject)ts)->type_name) defaultType = ((PetscObject)ts)->type_name; 150 else defaultType = ifun ? TSBEULER : TSEULER; 151 ierr = PetscOptionsFList("-ts_type","TS method","TSSetType",TSList,defaultType,typeName,256,&opt);CHKERRQ(ierr); 152 if (opt) { 153 ierr = TSSetType(ts,typeName);CHKERRQ(ierr); 154 } else { 155 ierr = TSSetType(ts,defaultType);CHKERRQ(ierr); 156 } 157 158 /* Handle generic TS options */ 159 ierr = PetscOptionsDeprecated("-ts_final_time","-ts_max_time","3.10",NULL);CHKERRQ(ierr); 160 ierr = PetscOptionsReal("-ts_max_time","Maximum time to run to","TSSetMaxTime",ts->max_time,&ts->max_time,NULL);CHKERRQ(ierr); 161 ierr = PetscOptionsInt("-ts_max_steps","Maximum number of time steps","TSSetMaxSteps",ts->max_steps,&ts->max_steps,NULL);CHKERRQ(ierr); 162 ierr = PetscOptionsReal("-ts_init_time","Initial time","TSSetTime",ts->ptime,&ts->ptime,NULL);CHKERRQ(ierr); 163 ierr = PetscOptionsReal("-ts_dt","Initial time step","TSSetTimeStep",ts->time_step,&time_step,&flg);CHKERRQ(ierr); 164 if (flg) {ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr);} 165 ierr = PetscOptionsEnum("-ts_exact_final_time","Option for handling of final time step","TSSetExactFinalTime",TSExactFinalTimeOptions,(PetscEnum)ts->exact_final_time,(PetscEnum*)&eftopt,&flg);CHKERRQ(ierr); 166 if (flg) {ierr = TSSetExactFinalTime(ts,eftopt);CHKERRQ(ierr);} 167 ierr = PetscOptionsInt("-ts_max_snes_failures","Maximum number of nonlinear solve failures","TSSetMaxSNESFailures",ts->max_snes_failures,&ts->max_snes_failures,NULL);CHKERRQ(ierr); 168 ierr = PetscOptionsInt("-ts_max_reject","Maximum number of step rejections before step fails","TSSetMaxStepRejections",ts->max_reject,&ts->max_reject,NULL);CHKERRQ(ierr); 169 ierr = PetscOptionsBool("-ts_error_if_step_fails","Error if no step succeeds","TSSetErrorIfStepFails",ts->errorifstepfailed,&ts->errorifstepfailed,NULL);CHKERRQ(ierr); 170 ierr = PetscOptionsReal("-ts_rtol","Relative tolerance for local truncation error","TSSetTolerances",ts->rtol,&ts->rtol,NULL);CHKERRQ(ierr); 171 ierr = PetscOptionsReal("-ts_atol","Absolute tolerance for local truncation error","TSSetTolerances",ts->atol,&ts->atol,NULL);CHKERRQ(ierr); 172 173 ierr = PetscOptionsBool("-ts_rhs_jacobian_test_mult","Test the RHS Jacobian for consistency with RHS at each solve ","None",ts->testjacobian,&ts->testjacobian,NULL);CHKERRQ(ierr); 174 ierr = PetscOptionsBool("-ts_rhs_jacobian_test_mult_transpose","Test the RHS Jacobian transpose for consistency with RHS at each solve ","None",ts->testjacobiantranspose,&ts->testjacobiantranspose,NULL);CHKERRQ(ierr); 175 ierr = PetscOptionsBool("-ts_use_splitrhsfunction","Use the split RHS function for multirate solvers ","TSSetUseSplitRHSFunction",ts->use_splitrhsfunction,&ts->use_splitrhsfunction,NULL);CHKERRQ(ierr); 176 #if defined(PETSC_HAVE_SAWS) 177 { 178 PetscBool set; 179 flg = PETSC_FALSE; 180 ierr = PetscOptionsBool("-ts_saws_block","Block for SAWs memory snooper at end of TSSolve","PetscObjectSAWsBlock",((PetscObject)ts)->amspublishblock,&flg,&set);CHKERRQ(ierr); 181 if (set) { 182 ierr = PetscObjectSAWsSetBlock((PetscObject)ts,flg);CHKERRQ(ierr); 183 } 184 } 185 #endif 186 187 /* Monitor options */ 188 ierr = TSMonitorSetFromOptions(ts,"-ts_monitor","Monitor time and timestep size","TSMonitorDefault",TSMonitorDefault,NULL);CHKERRQ(ierr); 189 ierr = TSMonitorSetFromOptions(ts,"-ts_monitor_extreme","Monitor extreme values of the solution","TSMonitorExtreme",TSMonitorExtreme,NULL);CHKERRQ(ierr); 190 ierr = TSMonitorSetFromOptions(ts,"-ts_monitor_solution","View the solution at each timestep","TSMonitorSolution",TSMonitorSolution,NULL);CHKERRQ(ierr); 191 192 ierr = PetscOptionsString("-ts_monitor_python","Use Python function","TSMonitorSet",NULL,monfilename,sizeof(monfilename),&flg);CHKERRQ(ierr); 193 if (flg) {ierr = PetscPythonMonitorSet((PetscObject)ts,monfilename);CHKERRQ(ierr);} 194 195 ierr = PetscOptionsName("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",&opt);CHKERRQ(ierr); 196 if (opt) { 197 PetscInt howoften = 1; 198 DM dm; 199 PetscBool net; 200 201 ierr = PetscOptionsInt("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",howoften,&howoften,NULL);CHKERRQ(ierr); 202 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 203 ierr = PetscObjectTypeCompare((PetscObject)dm,DMNETWORK,&net);CHKERRQ(ierr); 204 if (net) { 205 TSMonitorLGCtxNetwork ctx; 206 ierr = TSMonitorLGCtxNetworkCreate(ts,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr); 207 ierr = TSMonitorSet(ts,TSMonitorLGCtxNetworkSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxNetworkDestroy);CHKERRQ(ierr); 208 ierr = PetscOptionsBool("-ts_monitor_lg_solution_semilogy","Plot the solution with a semi-log axis","",ctx->semilogy,&ctx->semilogy,NULL);CHKERRQ(ierr); 209 } else { 210 TSMonitorLGCtx ctx; 211 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);CHKERRQ(ierr); 212 ierr = TSMonitorSet(ts,TSMonitorLGSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 213 } 214 } 215 216 ierr = PetscOptionsName("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",&opt);CHKERRQ(ierr); 217 if (opt) { 218 TSMonitorLGCtx ctx; 219 PetscInt howoften = 1; 220 221 ierr = PetscOptionsInt("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",howoften,&howoften,NULL);CHKERRQ(ierr); 222 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);CHKERRQ(ierr); 223 ierr = TSMonitorSet(ts,TSMonitorLGError,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 224 } 225 ierr = TSMonitorSetFromOptions(ts,"-ts_monitor_error","View the error at each timestep","TSMonitorError",TSMonitorError,NULL);CHKERRQ(ierr); 226 227 ierr = PetscOptionsName("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",&opt);CHKERRQ(ierr); 228 if (opt) { 229 TSMonitorLGCtx ctx; 230 PetscInt howoften = 1; 231 232 ierr = PetscOptionsInt("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",howoften,&howoften,NULL);CHKERRQ(ierr); 233 ierr = TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);CHKERRQ(ierr); 234 ierr = TSMonitorSet(ts,TSMonitorLGTimeStep,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 235 } 236 ierr = PetscOptionsName("-ts_monitor_lg_timestep_log","Monitor log timestep size graphically","TSMonitorLGTimeStep",&opt);CHKERRQ(ierr); 237 if (opt) { 238 TSMonitorLGCtx ctx; 239 PetscInt howoften = 1; 240 241 ierr = PetscOptionsInt("-ts_monitor_lg_timestep_log","Monitor log timestep size graphically","TSMonitorLGTimeStep",howoften,&howoften,NULL);CHKERRQ(ierr); 242 ierr = TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);CHKERRQ(ierr); 243 ierr = TSMonitorSet(ts,TSMonitorLGTimeStep,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 244 ctx->semilogy = PETSC_TRUE; 245 } 246 247 ierr = PetscOptionsName("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",&opt);CHKERRQ(ierr); 248 if (opt) { 249 TSMonitorLGCtx ctx; 250 PetscInt howoften = 1; 251 252 ierr = PetscOptionsInt("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",howoften,&howoften,NULL);CHKERRQ(ierr); 253 ierr = TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);CHKERRQ(ierr); 254 ierr = TSMonitorSet(ts,TSMonitorLGSNESIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 255 } 256 ierr = PetscOptionsName("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",&opt);CHKERRQ(ierr); 257 if (opt) { 258 TSMonitorLGCtx ctx; 259 PetscInt howoften = 1; 260 261 ierr = PetscOptionsInt("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",howoften,&howoften,NULL);CHKERRQ(ierr); 262 ierr = TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx);CHKERRQ(ierr); 263 ierr = TSMonitorSet(ts,TSMonitorLGKSPIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 264 } 265 ierr = PetscOptionsName("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",&opt);CHKERRQ(ierr); 266 if (opt) { 267 TSMonitorSPEigCtx ctx; 268 PetscInt howoften = 1; 269 270 ierr = PetscOptionsInt("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",howoften,&howoften,NULL);CHKERRQ(ierr); 271 ierr = TSMonitorSPEigCtxCreate(PETSC_COMM_SELF,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 272 ierr = TSMonitorSet(ts,TSMonitorSPEig,ctx,(PetscErrorCode (*)(void**))TSMonitorSPEigCtxDestroy);CHKERRQ(ierr); 273 } 274 ierr = PetscOptionsName("-ts_monitor_sp_swarm","Display particle phase from the DMSwarm","TSMonitorSPSwarm",&opt);CHKERRQ(ierr); 275 if (opt) { 276 TSMonitorSPCtx ctx; 277 PetscInt howoften = 1; 278 ierr = PetscOptionsInt("-ts_monitor_sp_swarm","Display particles phase from the DMSwarm","TSMonitorSPSwarm",howoften,&howoften,NULL);CHKERRQ(ierr); 279 ierr = TSMonitorSPCtxCreate(PETSC_COMM_SELF, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, &ctx);CHKERRQ(ierr); 280 ierr = TSMonitorSet(ts, TSMonitorSPSwarmSolution, ctx, (PetscErrorCode (*)(void**))TSMonitorSPCtxDestroy);CHKERRQ(ierr); 281 } 282 opt = PETSC_FALSE; 283 ierr = PetscOptionsName("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",&opt);CHKERRQ(ierr); 284 if (opt) { 285 TSMonitorDrawCtx ctx; 286 PetscInt howoften = 1; 287 288 ierr = PetscOptionsInt("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",howoften,&howoften,NULL);CHKERRQ(ierr); 289 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),NULL,"Computed Solution",PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 290 ierr = TSMonitorSet(ts,TSMonitorDrawSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 291 } 292 opt = PETSC_FALSE; 293 ierr = PetscOptionsName("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",&opt);CHKERRQ(ierr); 294 if (opt) { 295 TSMonitorDrawCtx ctx; 296 PetscReal bounds[4]; 297 PetscInt n = 4; 298 PetscDraw draw; 299 PetscDrawAxis axis; 300 301 ierr = PetscOptionsRealArray("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",bounds,&n,NULL);CHKERRQ(ierr); 302 if (n != 4) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Must provide bounding box of phase field"); 303 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,300,300,1,&ctx);CHKERRQ(ierr); 304 ierr = PetscViewerDrawGetDraw(ctx->viewer,0,&draw);CHKERRQ(ierr); 305 ierr = PetscViewerDrawGetDrawAxis(ctx->viewer,0,&axis);CHKERRQ(ierr); 306 ierr = PetscDrawAxisSetLimits(axis,bounds[0],bounds[2],bounds[1],bounds[3]);CHKERRQ(ierr); 307 ierr = PetscDrawAxisSetLabels(axis,"Phase Diagram","Variable 1","Variable 2");CHKERRQ(ierr); 308 ierr = TSMonitorSet(ts,TSMonitorDrawSolutionPhase,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 309 } 310 opt = PETSC_FALSE; 311 ierr = PetscOptionsName("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",&opt);CHKERRQ(ierr); 312 if (opt) { 313 TSMonitorDrawCtx ctx; 314 PetscInt howoften = 1; 315 316 ierr = PetscOptionsInt("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",howoften,&howoften,NULL);CHKERRQ(ierr); 317 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),NULL,"Error",PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 318 ierr = TSMonitorSet(ts,TSMonitorDrawError,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 319 } 320 opt = PETSC_FALSE; 321 ierr = PetscOptionsName("-ts_monitor_draw_solution_function","Monitor solution provided by TSMonitorSetSolutionFunction() graphically","TSMonitorDrawSolutionFunction",&opt);CHKERRQ(ierr); 322 if (opt) { 323 TSMonitorDrawCtx ctx; 324 PetscInt howoften = 1; 325 326 ierr = PetscOptionsInt("-ts_monitor_draw_solution_function","Monitor solution provided by TSMonitorSetSolutionFunction() graphically","TSMonitorDrawSolutionFunction",howoften,&howoften,NULL);CHKERRQ(ierr); 327 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),NULL,"Solution provided by user function",PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 328 ierr = TSMonitorSet(ts,TSMonitorDrawSolutionFunction,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 329 } 330 331 opt = PETSC_FALSE; 332 ierr = PetscOptionsString("-ts_monitor_solution_vtk","Save each time step to a binary file, use filename-%%03D.vts","TSMonitorSolutionVTK",NULL,monfilename,sizeof(monfilename),&flg);CHKERRQ(ierr); 333 if (flg) { 334 const char *ptr,*ptr2; 335 char *filetemplate; 336 if (!monfilename[0]) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts"); 337 /* Do some cursory validation of the input. */ 338 ierr = PetscStrstr(monfilename,"%",(char**)&ptr);CHKERRQ(ierr); 339 if (!ptr) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts"); 340 for (ptr++; ptr && *ptr; ptr++) { 341 ierr = PetscStrchr("DdiouxX",*ptr,(char**)&ptr2);CHKERRQ(ierr); 342 if (!ptr2 && (*ptr < '0' || '9' < *ptr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Invalid file template argument to -ts_monitor_solution_vtk, should look like filename-%%03D.vts"); 343 if (ptr2) break; 344 } 345 ierr = PetscStrallocpy(monfilename,&filetemplate);CHKERRQ(ierr); 346 ierr = TSMonitorSet(ts,TSMonitorSolutionVTK,filetemplate,(PetscErrorCode (*)(void**))TSMonitorSolutionVTKDestroy);CHKERRQ(ierr); 347 } 348 349 ierr = PetscOptionsString("-ts_monitor_dmda_ray","Display a ray of the solution","None","y=0",dir,sizeof(dir),&flg);CHKERRQ(ierr); 350 if (flg) { 351 TSMonitorDMDARayCtx *rayctx; 352 int ray = 0; 353 DMDirection ddir; 354 DM da; 355 PetscMPIInt rank; 356 357 if (dir[1] != '=') SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir); 358 if (dir[0] == 'x') ddir = DM_X; 359 else if (dir[0] == 'y') ddir = DM_Y; 360 else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir); 361 sscanf(dir+2,"%d",&ray); 362 363 ierr = PetscInfo2(((PetscObject)ts),"Displaying DMDA ray %c = %d\n",dir[0],ray);CHKERRQ(ierr); 364 ierr = PetscNew(&rayctx);CHKERRQ(ierr); 365 ierr = TSGetDM(ts,&da);CHKERRQ(ierr); 366 ierr = DMDAGetRay(da,ddir,ray,&rayctx->ray,&rayctx->scatter);CHKERRQ(ierr); 367 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)ts),&rank);CHKERRQ(ierr); 368 if (!rank) { 369 ierr = PetscViewerDrawOpen(PETSC_COMM_SELF,NULL,NULL,0,0,600,300,&rayctx->viewer);CHKERRQ(ierr); 370 } 371 rayctx->lgctx = NULL; 372 ierr = TSMonitorSet(ts,TSMonitorDMDARay,rayctx,TSMonitorDMDARayDestroy);CHKERRQ(ierr); 373 } 374 ierr = PetscOptionsString("-ts_monitor_lg_dmda_ray","Display a ray of the solution","None","x=0",dir,sizeof(dir),&flg);CHKERRQ(ierr); 375 if (flg) { 376 TSMonitorDMDARayCtx *rayctx; 377 int ray = 0; 378 DMDirection ddir; 379 DM da; 380 PetscInt howoften = 1; 381 382 if (dir[1] != '=') SETERRQ1(PetscObjectComm((PetscObject) ts), PETSC_ERR_ARG_WRONG, "Malformed ray %s", dir); 383 if (dir[0] == 'x') ddir = DM_X; 384 else if (dir[0] == 'y') ddir = DM_Y; 385 else SETERRQ1(PetscObjectComm((PetscObject) ts), PETSC_ERR_ARG_WRONG, "Unknown ray direction %s", dir); 386 sscanf(dir+2, "%d", &ray); 387 388 ierr = PetscInfo2(((PetscObject) ts),"Displaying LG DMDA ray %c = %d\n", dir[0], ray);CHKERRQ(ierr); 389 ierr = PetscNew(&rayctx);CHKERRQ(ierr); 390 ierr = TSGetDM(ts, &da);CHKERRQ(ierr); 391 ierr = DMDAGetRay(da, ddir, ray, &rayctx->ray, &rayctx->scatter);CHKERRQ(ierr); 392 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&rayctx->lgctx);CHKERRQ(ierr); 393 ierr = TSMonitorSet(ts, TSMonitorLGDMDARay, rayctx, TSMonitorDMDARayDestroy);CHKERRQ(ierr); 394 } 395 396 ierr = PetscOptionsName("-ts_monitor_envelope","Monitor maximum and minimum value of each component of the solution","TSMonitorEnvelope",&opt);CHKERRQ(ierr); 397 if (opt) { 398 TSMonitorEnvelopeCtx ctx; 399 400 ierr = TSMonitorEnvelopeCtxCreate(ts,&ctx);CHKERRQ(ierr); 401 ierr = TSMonitorSet(ts,TSMonitorEnvelope,ctx,(PetscErrorCode (*)(void**))TSMonitorEnvelopeCtxDestroy);CHKERRQ(ierr); 402 } 403 404 flg = PETSC_FALSE; 405 ierr = PetscOptionsBool("-ts_fd_color", "Use finite differences with coloring to compute IJacobian", "TSComputeJacobianDefaultColor", flg, &flg, NULL);CHKERRQ(ierr); 406 if (flg) { 407 DM dm; 408 DMTS tdm; 409 410 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 411 ierr = DMGetDMTS(dm, &tdm);CHKERRQ(ierr); 412 tdm->ijacobianctx = NULL; 413 ierr = TSSetIJacobian(ts, NULL, NULL, TSComputeIJacobianDefaultColor, NULL);CHKERRQ(ierr); 414 ierr = PetscInfo(ts, "Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr); 415 } 416 417 /* Handle specific TS options */ 418 if (ts->ops->setfromoptions) { 419 ierr = (*ts->ops->setfromoptions)(PetscOptionsObject,ts);CHKERRQ(ierr); 420 } 421 422 /* Handle TSAdapt options */ 423 ierr = TSGetAdapt(ts,&ts->adapt);CHKERRQ(ierr); 424 ierr = TSAdaptSetDefaultType(ts->adapt,ts->default_adapt_type);CHKERRQ(ierr); 425 ierr = TSAdaptSetFromOptions(PetscOptionsObject,ts->adapt);CHKERRQ(ierr); 426 427 /* TS trajectory must be set after TS, since it may use some TS options above */ 428 tflg = ts->trajectory ? PETSC_TRUE : PETSC_FALSE; 429 ierr = PetscOptionsBool("-ts_save_trajectory","Save the solution at each timestep","TSSetSaveTrajectory",tflg,&tflg,NULL);CHKERRQ(ierr); 430 if (tflg) { 431 ierr = TSSetSaveTrajectory(ts);CHKERRQ(ierr); 432 } 433 434 ierr = TSAdjointSetFromOptions(PetscOptionsObject,ts);CHKERRQ(ierr); 435 436 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 437 ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)ts);CHKERRQ(ierr); 438 ierr = PetscOptionsEnd();CHKERRQ(ierr); 439 440 if (ts->trajectory) { 441 ierr = TSTrajectorySetFromOptions(ts->trajectory,ts);CHKERRQ(ierr); 442 } 443 444 /* why do we have to do this here and not during TSSetUp? */ 445 ierr = TSGetSNES(ts,&ts->snes);CHKERRQ(ierr); 446 if (ts->problem_type == TS_LINEAR) { 447 ierr = PetscObjectTypeCompareAny((PetscObject)ts->snes,&flg,SNESKSPONLY,SNESKSPTRANSPOSEONLY,"");CHKERRQ(ierr); 448 if (!flg) { ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr); } 449 } 450 ierr = SNESSetFromOptions(ts->snes);CHKERRQ(ierr); 451 PetscFunctionReturn(0); 452 } 453 454 /*@ 455 TSGetTrajectory - Gets the trajectory from a TS if it exists 456 457 Collective on TS 458 459 Input Parameters: 460 . ts - the TS context obtained from TSCreate() 461 462 Output Parameters: 463 . tr - the TSTrajectory object, if it exists 464 465 Note: This routine should be called after all TS options have been set 466 467 Level: advanced 468 469 .seealso: TSGetTrajectory(), TSAdjointSolve(), TSTrajectory, TSTrajectoryCreate() 470 471 @*/ 472 PetscErrorCode TSGetTrajectory(TS ts,TSTrajectory *tr) 473 { 474 PetscFunctionBegin; 475 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 476 *tr = ts->trajectory; 477 PetscFunctionReturn(0); 478 } 479 480 /*@ 481 TSSetSaveTrajectory - Causes the TS to save its solutions as it iterates forward in time in a TSTrajectory object 482 483 Collective on TS 484 485 Input Parameters: 486 . ts - the TS context obtained from TSCreate() 487 488 Options Database: 489 + -ts_save_trajectory - saves the trajectory to a file 490 - -ts_trajectory_type type 491 492 Note: This routine should be called after all TS options have been set 493 494 The TSTRAJECTORYVISUALIZATION files can be loaded into Python with $PETSC_DIR/lib/petsc/bin/PetscBinaryIOTrajectory.py and 495 MATLAB with $PETSC_DIR/share/petsc/matlab/PetscReadBinaryTrajectory.m 496 497 Level: intermediate 498 499 .seealso: TSGetTrajectory(), TSAdjointSolve() 500 501 @*/ 502 PetscErrorCode TSSetSaveTrajectory(TS ts) 503 { 504 PetscErrorCode ierr; 505 506 PetscFunctionBegin; 507 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 508 if (!ts->trajectory) { 509 ierr = TSTrajectoryCreate(PetscObjectComm((PetscObject)ts),&ts->trajectory);CHKERRQ(ierr); 510 } 511 PetscFunctionReturn(0); 512 } 513 514 /*@ 515 TSResetTrajectory - Destroys and recreates the internal TSTrajectory object 516 517 Collective on TS 518 519 Input Parameters: 520 . ts - the TS context obtained from TSCreate() 521 522 Level: intermediate 523 524 .seealso: TSGetTrajectory(), TSAdjointSolve() 525 526 @*/ 527 PetscErrorCode TSResetTrajectory(TS ts) 528 { 529 PetscErrorCode ierr; 530 531 PetscFunctionBegin; 532 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 533 if (ts->trajectory) { 534 ierr = TSTrajectoryDestroy(&ts->trajectory);CHKERRQ(ierr); 535 ierr = TSTrajectoryCreate(PetscObjectComm((PetscObject)ts),&ts->trajectory);CHKERRQ(ierr); 536 } 537 PetscFunctionReturn(0); 538 } 539 540 /*@ 541 TSComputeRHSJacobian - Computes the Jacobian matrix that has been 542 set with TSSetRHSJacobian(). 543 544 Collective on TS 545 546 Input Parameters: 547 + ts - the TS context 548 . t - current timestep 549 - U - input vector 550 551 Output Parameters: 552 + A - Jacobian matrix 553 . B - optional preconditioning matrix 554 - flag - flag indicating matrix structure 555 556 Notes: 557 Most users should not need to explicitly call this routine, as it 558 is used internally within the nonlinear solvers. 559 560 See KSPSetOperators() for important information about setting the 561 flag parameter. 562 563 Level: developer 564 565 .seealso: TSSetRHSJacobian(), KSPSetOperators() 566 @*/ 567 PetscErrorCode TSComputeRHSJacobian(TS ts,PetscReal t,Vec U,Mat A,Mat B) 568 { 569 PetscErrorCode ierr; 570 PetscObjectState Ustate; 571 PetscObjectId Uid; 572 DM dm; 573 DMTS tsdm; 574 TSRHSJacobian rhsjacobianfunc; 575 void *ctx; 576 TSRHSFunction rhsfunction; 577 578 PetscFunctionBegin; 579 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 580 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 581 PetscCheckSameComm(ts,1,U,3); 582 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 583 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 584 ierr = DMTSGetRHSFunction(dm,&rhsfunction,NULL);CHKERRQ(ierr); 585 ierr = DMTSGetRHSJacobian(dm,&rhsjacobianfunc,&ctx);CHKERRQ(ierr); 586 ierr = PetscObjectStateGet((PetscObject)U,&Ustate);CHKERRQ(ierr); 587 ierr = PetscObjectGetId((PetscObject)U,&Uid);CHKERRQ(ierr); 588 589 if (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.Xid == Uid && ts->rhsjacobian.Xstate == Ustate)) && (rhsfunction != TSComputeRHSFunctionLinear)) PetscFunctionReturn(0); 590 591 if (ts->rhsjacobian.shift && ts->rhsjacobian.reuse) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Should not call TSComputeRHSJacobian() on a shifted matrix (shift=%lf) when RHSJacobian is reusable.",ts->rhsjacobian.shift); 592 if (rhsjacobianfunc) { 593 ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr); 594 PetscStackPush("TS user Jacobian function"); 595 ierr = (*rhsjacobianfunc)(ts,t,U,A,B,ctx);CHKERRQ(ierr); 596 PetscStackPop; 597 ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr); 598 } else { 599 ierr = MatZeroEntries(A);CHKERRQ(ierr); 600 if (B && A != B) {ierr = MatZeroEntries(B);CHKERRQ(ierr);} 601 } 602 ts->rhsjacobian.time = t; 603 ts->rhsjacobian.shift = 0; 604 ts->rhsjacobian.scale = 1.; 605 ierr = PetscObjectGetId((PetscObject)U,&ts->rhsjacobian.Xid);CHKERRQ(ierr); 606 ierr = PetscObjectStateGet((PetscObject)U,&ts->rhsjacobian.Xstate);CHKERRQ(ierr); 607 PetscFunctionReturn(0); 608 } 609 610 /*@ 611 TSComputeRHSFunction - Evaluates the right-hand-side function. 612 613 Collective on TS 614 615 Input Parameters: 616 + ts - the TS context 617 . t - current time 618 - U - state vector 619 620 Output Parameter: 621 . y - right hand side 622 623 Note: 624 Most users should not need to explicitly call this routine, as it 625 is used internally within the nonlinear solvers. 626 627 Level: developer 628 629 .seealso: TSSetRHSFunction(), TSComputeIFunction() 630 @*/ 631 PetscErrorCode TSComputeRHSFunction(TS ts,PetscReal t,Vec U,Vec y) 632 { 633 PetscErrorCode ierr; 634 TSRHSFunction rhsfunction; 635 TSIFunction ifunction; 636 void *ctx; 637 DM dm; 638 639 PetscFunctionBegin; 640 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 641 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 642 PetscValidHeaderSpecific(y,VEC_CLASSID,4); 643 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 644 ierr = DMTSGetRHSFunction(dm,&rhsfunction,&ctx);CHKERRQ(ierr); 645 ierr = DMTSGetIFunction(dm,&ifunction,NULL);CHKERRQ(ierr); 646 647 if (!rhsfunction && !ifunction) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 648 649 ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr); 650 if (rhsfunction) { 651 ierr = VecLockReadPush(U);CHKERRQ(ierr); 652 PetscStackPush("TS user right-hand-side function"); 653 ierr = (*rhsfunction)(ts,t,U,y,ctx);CHKERRQ(ierr); 654 PetscStackPop; 655 ierr = VecLockReadPop(U);CHKERRQ(ierr); 656 } else { 657 ierr = VecZeroEntries(y);CHKERRQ(ierr); 658 } 659 660 ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr); 661 PetscFunctionReturn(0); 662 } 663 664 /*@ 665 TSComputeSolutionFunction - Evaluates the solution function. 666 667 Collective on TS 668 669 Input Parameters: 670 + ts - the TS context 671 - t - current time 672 673 Output Parameter: 674 . U - the solution 675 676 Note: 677 Most users should not need to explicitly call this routine, as it 678 is used internally within the nonlinear solvers. 679 680 Level: developer 681 682 .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction() 683 @*/ 684 PetscErrorCode TSComputeSolutionFunction(TS ts,PetscReal t,Vec U) 685 { 686 PetscErrorCode ierr; 687 TSSolutionFunction solutionfunction; 688 void *ctx; 689 DM dm; 690 691 PetscFunctionBegin; 692 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 693 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 694 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 695 ierr = DMTSGetSolutionFunction(dm,&solutionfunction,&ctx);CHKERRQ(ierr); 696 697 if (solutionfunction) { 698 PetscStackPush("TS user solution function"); 699 ierr = (*solutionfunction)(ts,t,U,ctx);CHKERRQ(ierr); 700 PetscStackPop; 701 } 702 PetscFunctionReturn(0); 703 } 704 /*@ 705 TSComputeForcingFunction - Evaluates the forcing function. 706 707 Collective on TS 708 709 Input Parameters: 710 + ts - the TS context 711 - t - current time 712 713 Output Parameter: 714 . U - the function value 715 716 Note: 717 Most users should not need to explicitly call this routine, as it 718 is used internally within the nonlinear solvers. 719 720 Level: developer 721 722 .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction() 723 @*/ 724 PetscErrorCode TSComputeForcingFunction(TS ts,PetscReal t,Vec U) 725 { 726 PetscErrorCode ierr, (*forcing)(TS,PetscReal,Vec,void*); 727 void *ctx; 728 DM dm; 729 730 PetscFunctionBegin; 731 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 732 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 733 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 734 ierr = DMTSGetForcingFunction(dm,&forcing,&ctx);CHKERRQ(ierr); 735 736 if (forcing) { 737 PetscStackPush("TS user forcing function"); 738 ierr = (*forcing)(ts,t,U,ctx);CHKERRQ(ierr); 739 PetscStackPop; 740 } 741 PetscFunctionReturn(0); 742 } 743 744 static PetscErrorCode TSGetRHSVec_Private(TS ts,Vec *Frhs) 745 { 746 Vec F; 747 PetscErrorCode ierr; 748 749 PetscFunctionBegin; 750 *Frhs = NULL; 751 ierr = TSGetIFunction(ts,&F,NULL,NULL);CHKERRQ(ierr); 752 if (!ts->Frhs) { 753 ierr = VecDuplicate(F,&ts->Frhs);CHKERRQ(ierr); 754 } 755 *Frhs = ts->Frhs; 756 PetscFunctionReturn(0); 757 } 758 759 PetscErrorCode TSGetRHSMats_Private(TS ts,Mat *Arhs,Mat *Brhs) 760 { 761 Mat A,B; 762 PetscErrorCode ierr; 763 TSIJacobian ijacobian; 764 765 PetscFunctionBegin; 766 if (Arhs) *Arhs = NULL; 767 if (Brhs) *Brhs = NULL; 768 ierr = TSGetIJacobian(ts,&A,&B,&ijacobian,NULL);CHKERRQ(ierr); 769 if (Arhs) { 770 if (!ts->Arhs) { 771 if (ijacobian) { 772 ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&ts->Arhs);CHKERRQ(ierr); 773 } else { 774 ts->Arhs = A; 775 ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 776 } 777 } else { 778 PetscBool flg; 779 ierr = SNESGetUseMatrixFree(ts->snes,NULL,&flg);CHKERRQ(ierr); 780 /* Handle case where user provided only RHSJacobian and used -snes_mf_operator */ 781 if (flg && !ijacobian && ts->Arhs == ts->Brhs){ 782 ierr = PetscObjectDereference((PetscObject)ts->Arhs);CHKERRQ(ierr); 783 ts->Arhs = A; 784 ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 785 } 786 } 787 *Arhs = ts->Arhs; 788 } 789 if (Brhs) { 790 if (!ts->Brhs) { 791 if (A != B) { 792 if (ijacobian) { 793 ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&ts->Brhs);CHKERRQ(ierr); 794 } else { 795 ts->Brhs = B; 796 ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 797 } 798 } else { 799 ierr = PetscObjectReference((PetscObject)ts->Arhs);CHKERRQ(ierr); 800 ts->Brhs = ts->Arhs; 801 } 802 } 803 *Brhs = ts->Brhs; 804 } 805 PetscFunctionReturn(0); 806 } 807 808 /*@ 809 TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,U,Udot)=0 810 811 Collective on TS 812 813 Input Parameters: 814 + ts - the TS context 815 . t - current time 816 . U - state vector 817 . Udot - time derivative of state vector 818 - imex - flag indicates if the method is IMEX so that the RHSFunction should be kept separate 819 820 Output Parameter: 821 . Y - right hand side 822 823 Note: 824 Most users should not need to explicitly call this routine, as it 825 is used internally within the nonlinear solvers. 826 827 If the user did did not write their equations in implicit form, this 828 function recasts them in implicit form. 829 830 Level: developer 831 832 .seealso: TSSetIFunction(), TSComputeRHSFunction() 833 @*/ 834 PetscErrorCode TSComputeIFunction(TS ts,PetscReal t,Vec U,Vec Udot,Vec Y,PetscBool imex) 835 { 836 PetscErrorCode ierr; 837 TSIFunction ifunction; 838 TSRHSFunction rhsfunction; 839 void *ctx; 840 DM dm; 841 842 PetscFunctionBegin; 843 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 844 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 845 PetscValidHeaderSpecific(Udot,VEC_CLASSID,4); 846 PetscValidHeaderSpecific(Y,VEC_CLASSID,5); 847 848 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 849 ierr = DMTSGetIFunction(dm,&ifunction,&ctx);CHKERRQ(ierr); 850 ierr = DMTSGetRHSFunction(dm,&rhsfunction,NULL);CHKERRQ(ierr); 851 852 if (!rhsfunction && !ifunction) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 853 854 ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr); 855 if (ifunction) { 856 PetscStackPush("TS user implicit function"); 857 ierr = (*ifunction)(ts,t,U,Udot,Y,ctx);CHKERRQ(ierr); 858 PetscStackPop; 859 } 860 if (imex) { 861 if (!ifunction) { 862 ierr = VecCopy(Udot,Y);CHKERRQ(ierr); 863 } 864 } else if (rhsfunction) { 865 if (ifunction) { 866 Vec Frhs; 867 ierr = TSGetRHSVec_Private(ts,&Frhs);CHKERRQ(ierr); 868 ierr = TSComputeRHSFunction(ts,t,U,Frhs);CHKERRQ(ierr); 869 ierr = VecAXPY(Y,-1,Frhs);CHKERRQ(ierr); 870 } else { 871 ierr = TSComputeRHSFunction(ts,t,U,Y);CHKERRQ(ierr); 872 ierr = VecAYPX(Y,-1,Udot);CHKERRQ(ierr); 873 } 874 } 875 ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr); 876 PetscFunctionReturn(0); 877 } 878 879 /* 880 TSRecoverRHSJacobian - Recover the Jacobian matrix so that one can call TSComputeRHSJacobian() on it. 881 882 Note: 883 This routine is needed when one switches from TSComputeIJacobian() to TSComputeRHSJacobian() because the Jacobian matrix may be shifted or scaled in TSComputeIJacobian(). 884 885 */ 886 static PetscErrorCode TSRecoverRHSJacobian(TS ts,Mat A,Mat B) 887 { 888 PetscErrorCode ierr; 889 890 PetscFunctionBegin; 891 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 892 if (A != ts->Arhs) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Invalid Amat"); 893 if (B != ts->Brhs) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Invalid Bmat"); 894 895 if (ts->rhsjacobian.shift) { 896 ierr = MatShift(A,-ts->rhsjacobian.shift);CHKERRQ(ierr); 897 } 898 if (ts->rhsjacobian.scale == -1.) { 899 ierr = MatScale(A,-1);CHKERRQ(ierr); 900 } 901 if (B && B == ts->Brhs && A != B) { 902 if (ts->rhsjacobian.shift) { 903 ierr = MatShift(B,-ts->rhsjacobian.shift);CHKERRQ(ierr); 904 } 905 if (ts->rhsjacobian.scale == -1.) { 906 ierr = MatScale(B,-1);CHKERRQ(ierr); 907 } 908 } 909 ts->rhsjacobian.shift = 0; 910 ts->rhsjacobian.scale = 1.; 911 PetscFunctionReturn(0); 912 } 913 914 /*@ 915 TSComputeIJacobian - Evaluates the Jacobian of the DAE 916 917 Collective on TS 918 919 Input 920 Input Parameters: 921 + ts - the TS context 922 . t - current timestep 923 . U - state vector 924 . Udot - time derivative of state vector 925 . shift - shift to apply, see note below 926 - imex - flag indicates if the method is IMEX so that the RHSJacobian should be kept separate 927 928 Output Parameters: 929 + A - Jacobian matrix 930 - B - matrix from which the preconditioner is constructed; often the same as A 931 932 Notes: 933 If F(t,U,Udot)=0 is the DAE, the required Jacobian is 934 935 dF/dU + shift*dF/dUdot 936 937 Most users should not need to explicitly call this routine, as it 938 is used internally within the nonlinear solvers. 939 940 Level: developer 941 942 .seealso: TSSetIJacobian() 943 @*/ 944 PetscErrorCode TSComputeIJacobian(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,PetscBool imex) 945 { 946 PetscErrorCode ierr; 947 TSIJacobian ijacobian; 948 TSRHSJacobian rhsjacobian; 949 DM dm; 950 void *ctx; 951 952 PetscFunctionBegin; 953 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 954 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 955 PetscValidHeaderSpecific(Udot,VEC_CLASSID,4); 956 PetscValidPointer(A,6); 957 PetscValidHeaderSpecific(A,MAT_CLASSID,6); 958 PetscValidPointer(B,7); 959 PetscValidHeaderSpecific(B,MAT_CLASSID,7); 960 961 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 962 ierr = DMTSGetIJacobian(dm,&ijacobian,&ctx);CHKERRQ(ierr); 963 ierr = DMTSGetRHSJacobian(dm,&rhsjacobian,NULL);CHKERRQ(ierr); 964 965 if (!rhsjacobian && !ijacobian) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()"); 966 967 ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr); 968 if (ijacobian) { 969 PetscStackPush("TS user implicit Jacobian"); 970 ierr = (*ijacobian)(ts,t,U,Udot,shift,A,B,ctx);CHKERRQ(ierr); 971 PetscStackPop; 972 } 973 if (imex) { 974 if (!ijacobian) { /* system was written as Udot = G(t,U) */ 975 PetscBool assembled; 976 if (rhsjacobian) { 977 Mat Arhs = NULL; 978 ierr = TSGetRHSMats_Private(ts,&Arhs,NULL);CHKERRQ(ierr); 979 if (A == Arhs) { 980 if (rhsjacobian == TSComputeRHSJacobianConstant) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Unsupported operation! cannot use TSComputeRHSJacobianConstant"); /* there is no way to reconstruct shift*M-J since J cannot be reevaluated */ 981 ts->rhsjacobian.time = PETSC_MIN_REAL; 982 } 983 } 984 ierr = MatZeroEntries(A);CHKERRQ(ierr); 985 ierr = MatAssembled(A,&assembled);CHKERRQ(ierr); 986 if (!assembled) { 987 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 988 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 989 } 990 ierr = MatShift(A,shift);CHKERRQ(ierr); 991 if (A != B) { 992 ierr = MatZeroEntries(B);CHKERRQ(ierr); 993 ierr = MatAssembled(B,&assembled);CHKERRQ(ierr); 994 if (!assembled) { 995 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 996 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 997 } 998 ierr = MatShift(B,shift);CHKERRQ(ierr); 999 } 1000 } 1001 } else { 1002 Mat Arhs = NULL,Brhs = NULL; 1003 if (rhsjacobian) { /* RHSJacobian needs to be converted to part of IJacobian if exists */ 1004 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 1005 } 1006 if (Arhs == A) { /* No IJacobian matrix, so we only have the RHS matrix */ 1007 PetscObjectState Ustate; 1008 PetscObjectId Uid; 1009 TSRHSFunction rhsfunction; 1010 1011 ierr = DMTSGetRHSFunction(dm,&rhsfunction,NULL);CHKERRQ(ierr); 1012 ierr = PetscObjectStateGet((PetscObject)U,&Ustate);CHKERRQ(ierr); 1013 ierr = PetscObjectGetId((PetscObject)U,&Uid);CHKERRQ(ierr); 1014 if ((rhsjacobian == TSComputeRHSJacobianConstant || (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.Xid == Uid && ts->rhsjacobian.Xstate == Ustate)) && rhsfunction != TSComputeRHSFunctionLinear)) && ts->rhsjacobian.scale == -1.) { /* No need to recompute RHSJacobian */ 1015 ierr = MatShift(A,shift-ts->rhsjacobian.shift);CHKERRQ(ierr); /* revert the old shift and add the new shift with a single call to MatShift */ 1016 if (A != B) { 1017 ierr = MatShift(B,shift-ts->rhsjacobian.shift);CHKERRQ(ierr); 1018 } 1019 } else { 1020 PetscBool flg; 1021 1022 if (ts->rhsjacobian.reuse) { /* Undo the damage */ 1023 /* MatScale has a short path for this case. 1024 However, this code path is taken the first time TSComputeRHSJacobian is called 1025 and the matrices have not been assembled yet */ 1026 ierr = TSRecoverRHSJacobian(ts,A,B);CHKERRQ(ierr); 1027 } 1028 ierr = TSComputeRHSJacobian(ts,t,U,A,B);CHKERRQ(ierr); 1029 ierr = SNESGetUseMatrixFree(ts->snes,NULL,&flg);CHKERRQ(ierr); 1030 /* since -snes_mf_operator uses the full SNES function it does not need to be shifted or scaled here */ 1031 if (!flg) { 1032 ierr = MatScale(A,-1);CHKERRQ(ierr); 1033 ierr = MatShift(A,shift);CHKERRQ(ierr); 1034 } 1035 if (A != B) { 1036 ierr = MatScale(B,-1);CHKERRQ(ierr); 1037 ierr = MatShift(B,shift);CHKERRQ(ierr); 1038 } 1039 } 1040 ts->rhsjacobian.scale = -1; 1041 ts->rhsjacobian.shift = shift; 1042 } else if (Arhs) { /* Both IJacobian and RHSJacobian exist or the RHS matrix provided (A) is different from the internal RHS matrix (Arhs) */ 1043 MatStructure axpy = DIFFERENT_NONZERO_PATTERN; 1044 1045 if (!ijacobian) { /* No IJacobian provided, but we have a separate RHS matrix */ 1046 ierr = MatZeroEntries(A);CHKERRQ(ierr); 1047 ierr = MatShift(A,shift);CHKERRQ(ierr); 1048 if (A != B) { 1049 ierr = MatZeroEntries(B);CHKERRQ(ierr); 1050 ierr = MatShift(B,shift);CHKERRQ(ierr); 1051 } 1052 } 1053 ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr); 1054 ierr = MatAXPY(A,-1,Arhs,axpy);CHKERRQ(ierr); 1055 if (A != B) { 1056 ierr = MatAXPY(B,-1,Brhs,axpy);CHKERRQ(ierr); 1057 } 1058 } 1059 } 1060 ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr); 1061 PetscFunctionReturn(0); 1062 } 1063 1064 /*@C 1065 TSSetRHSFunction - Sets the routine for evaluating the function, 1066 where U_t = G(t,u). 1067 1068 Logically Collective on TS 1069 1070 Input Parameters: 1071 + ts - the TS context obtained from TSCreate() 1072 . r - vector to put the computed right hand side (or NULL to have it created) 1073 . f - routine for evaluating the right-hand-side function 1074 - ctx - [optional] user-defined context for private data for the 1075 function evaluation routine (may be NULL) 1076 1077 Calling sequence of f: 1078 $ PetscErrorCode f(TS ts,PetscReal t,Vec u,Vec F,void *ctx); 1079 1080 + ts - timestep context 1081 . t - current timestep 1082 . u - input vector 1083 . F - function vector 1084 - ctx - [optional] user-defined function context 1085 1086 Level: beginner 1087 1088 Notes: 1089 You must call this function or TSSetIFunction() to define your ODE. You cannot use this function when solving a DAE. 1090 1091 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSSetIFunction() 1092 @*/ 1093 PetscErrorCode TSSetRHSFunction(TS ts,Vec r,PetscErrorCode (*f)(TS,PetscReal,Vec,Vec,void*),void *ctx) 1094 { 1095 PetscErrorCode ierr; 1096 SNES snes; 1097 Vec ralloc = NULL; 1098 DM dm; 1099 1100 PetscFunctionBegin; 1101 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1102 if (r) PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1103 1104 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1105 ierr = DMTSSetRHSFunction(dm,f,ctx);CHKERRQ(ierr); 1106 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1107 if (!r && !ts->dm && ts->vec_sol) { 1108 ierr = VecDuplicate(ts->vec_sol,&ralloc);CHKERRQ(ierr); 1109 r = ralloc; 1110 } 1111 ierr = SNESSetFunction(snes,r,SNESTSFormFunction,ts);CHKERRQ(ierr); 1112 ierr = VecDestroy(&ralloc);CHKERRQ(ierr); 1113 PetscFunctionReturn(0); 1114 } 1115 1116 /*@C 1117 TSSetSolutionFunction - Provide a function that computes the solution of the ODE or DAE 1118 1119 Logically Collective on TS 1120 1121 Input Parameters: 1122 + ts - the TS context obtained from TSCreate() 1123 . f - routine for evaluating the solution 1124 - ctx - [optional] user-defined context for private data for the 1125 function evaluation routine (may be NULL) 1126 1127 Calling sequence of f: 1128 $ PetscErrorCode f(TS ts,PetscReal t,Vec u,void *ctx); 1129 1130 + t - current timestep 1131 . u - output vector 1132 - ctx - [optional] user-defined function context 1133 1134 Options Database: 1135 + -ts_monitor_lg_error - create a graphical monitor of error history, requires user to have provided TSSetSolutionFunction() 1136 - -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction() 1137 1138 Notes: 1139 This routine is used for testing accuracy of time integration schemes when you already know the solution. 1140 If analytic solutions are not known for your system, consider using the Method of Manufactured Solutions to 1141 create closed-form solutions with non-physical forcing terms. 1142 1143 For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history. 1144 1145 Level: beginner 1146 1147 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetForcingFunction(), TSSetSolution(), TSGetSolution(), TSMonitorLGError(), TSMonitorDrawError() 1148 @*/ 1149 PetscErrorCode TSSetSolutionFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,void*),void *ctx) 1150 { 1151 PetscErrorCode ierr; 1152 DM dm; 1153 1154 PetscFunctionBegin; 1155 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1156 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1157 ierr = DMTSSetSolutionFunction(dm,f,ctx);CHKERRQ(ierr); 1158 PetscFunctionReturn(0); 1159 } 1160 1161 /*@C 1162 TSSetForcingFunction - Provide a function that computes a forcing term for a ODE or PDE 1163 1164 Logically Collective on TS 1165 1166 Input Parameters: 1167 + ts - the TS context obtained from TSCreate() 1168 . func - routine for evaluating the forcing function 1169 - ctx - [optional] user-defined context for private data for the 1170 function evaluation routine (may be NULL) 1171 1172 Calling sequence of func: 1173 $ PetscErrorCode func (TS ts,PetscReal t,Vec f,void *ctx); 1174 1175 + t - current timestep 1176 . f - output vector 1177 - ctx - [optional] user-defined function context 1178 1179 Notes: 1180 This routine is useful for testing accuracy of time integration schemes when using the Method of Manufactured Solutions to 1181 create closed-form solutions with a non-physical forcing term. It allows you to use the Method of Manufactored Solution without directly editing the 1182 definition of the problem you are solving and hence possibly introducing bugs. 1183 1184 This replaces the ODE F(u,u_t,t) = 0 the TS is solving with F(u,u_t,t) - func(t) = 0 1185 1186 This forcing function does not depend on the solution to the equations, it can only depend on spatial location, time, and possibly parameters, the 1187 parameters can be passed in the ctx variable. 1188 1189 For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history. 1190 1191 Level: beginner 1192 1193 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetSolutionFunction() 1194 @*/ 1195 PetscErrorCode TSSetForcingFunction(TS ts,TSForcingFunction func,void *ctx) 1196 { 1197 PetscErrorCode ierr; 1198 DM dm; 1199 1200 PetscFunctionBegin; 1201 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1202 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1203 ierr = DMTSSetForcingFunction(dm,func,ctx);CHKERRQ(ierr); 1204 PetscFunctionReturn(0); 1205 } 1206 1207 /*@C 1208 TSSetRHSJacobian - Sets the function to compute the Jacobian of G, 1209 where U_t = G(U,t), as well as the location to store the matrix. 1210 1211 Logically Collective on TS 1212 1213 Input Parameters: 1214 + ts - the TS context obtained from TSCreate() 1215 . Amat - (approximate) Jacobian matrix 1216 . Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat) 1217 . f - the Jacobian evaluation routine 1218 - ctx - [optional] user-defined context for private data for the 1219 Jacobian evaluation routine (may be NULL) 1220 1221 Calling sequence of f: 1222 $ PetscErrorCode f(TS ts,PetscReal t,Vec u,Mat A,Mat B,void *ctx); 1223 1224 + t - current timestep 1225 . u - input vector 1226 . Amat - (approximate) Jacobian matrix 1227 . Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat) 1228 - ctx - [optional] user-defined context for matrix evaluation routine 1229 1230 Notes: 1231 You must set all the diagonal entries of the matrices, if they are zero you must still set them with a zero value 1232 1233 The TS solver may modify the nonzero structure and the entries of the matrices Amat and Pmat between the calls to f() 1234 You should not assume the values are the same in the next call to f() as you set them in the previous call. 1235 1236 Level: beginner 1237 1238 .seealso: SNESComputeJacobianDefaultColor(), TSSetRHSFunction(), TSRHSJacobianSetReuse(), TSSetIJacobian() 1239 1240 @*/ 1241 PetscErrorCode TSSetRHSJacobian(TS ts,Mat Amat,Mat Pmat,TSRHSJacobian f,void *ctx) 1242 { 1243 PetscErrorCode ierr; 1244 SNES snes; 1245 DM dm; 1246 TSIJacobian ijacobian; 1247 1248 PetscFunctionBegin; 1249 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1250 if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 1251 if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 1252 if (Amat) PetscCheckSameComm(ts,1,Amat,2); 1253 if (Pmat) PetscCheckSameComm(ts,1,Pmat,3); 1254 1255 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1256 ierr = DMTSSetRHSJacobian(dm,f,ctx);CHKERRQ(ierr); 1257 ierr = DMTSGetIJacobian(dm,&ijacobian,NULL);CHKERRQ(ierr); 1258 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1259 if (!ijacobian) { 1260 ierr = SNESSetJacobian(snes,Amat,Pmat,SNESTSFormJacobian,ts);CHKERRQ(ierr); 1261 } 1262 if (Amat) { 1263 ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 1264 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 1265 ts->Arhs = Amat; 1266 } 1267 if (Pmat) { 1268 ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr); 1269 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 1270 ts->Brhs = Pmat; 1271 } 1272 PetscFunctionReturn(0); 1273 } 1274 1275 /*@C 1276 TSSetIFunction - Set the function to compute F(t,U,U_t) where F() = 0 is the DAE to be solved. 1277 1278 Logically Collective on TS 1279 1280 Input Parameters: 1281 + ts - the TS context obtained from TSCreate() 1282 . r - vector to hold the residual (or NULL to have it created internally) 1283 . f - the function evaluation routine 1284 - ctx - user-defined context for private data for the function evaluation routine (may be NULL) 1285 1286 Calling sequence of f: 1287 $ PetscErrorCode f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx); 1288 1289 + t - time at step/stage being solved 1290 . u - state vector 1291 . u_t - time derivative of state vector 1292 . F - function vector 1293 - ctx - [optional] user-defined context for matrix evaluation routine 1294 1295 Important: 1296 The user MUST call either this routine or TSSetRHSFunction() to define the ODE. When solving DAEs you must use this function. 1297 1298 Level: beginner 1299 1300 .seealso: TSSetRHSJacobian(), TSSetRHSFunction(), TSSetIJacobian() 1301 @*/ 1302 PetscErrorCode TSSetIFunction(TS ts,Vec r,TSIFunction f,void *ctx) 1303 { 1304 PetscErrorCode ierr; 1305 SNES snes; 1306 Vec ralloc = NULL; 1307 DM dm; 1308 1309 PetscFunctionBegin; 1310 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1311 if (r) PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1312 1313 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1314 ierr = DMTSSetIFunction(dm,f,ctx);CHKERRQ(ierr); 1315 1316 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1317 if (!r && !ts->dm && ts->vec_sol) { 1318 ierr = VecDuplicate(ts->vec_sol,&ralloc);CHKERRQ(ierr); 1319 r = ralloc; 1320 } 1321 ierr = SNESSetFunction(snes,r,SNESTSFormFunction,ts);CHKERRQ(ierr); 1322 ierr = VecDestroy(&ralloc);CHKERRQ(ierr); 1323 PetscFunctionReturn(0); 1324 } 1325 1326 /*@C 1327 TSGetIFunction - Returns the vector where the implicit residual is stored and the function/contex to compute it. 1328 1329 Not Collective 1330 1331 Input Parameter: 1332 . ts - the TS context 1333 1334 Output Parameter: 1335 + r - vector to hold residual (or NULL) 1336 . func - the function to compute residual (or NULL) 1337 - ctx - the function context (or NULL) 1338 1339 Level: advanced 1340 1341 .seealso: TSSetIFunction(), SNESGetFunction() 1342 @*/ 1343 PetscErrorCode TSGetIFunction(TS ts,Vec *r,TSIFunction *func,void **ctx) 1344 { 1345 PetscErrorCode ierr; 1346 SNES snes; 1347 DM dm; 1348 1349 PetscFunctionBegin; 1350 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1351 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1352 ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 1353 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1354 ierr = DMTSGetIFunction(dm,func,ctx);CHKERRQ(ierr); 1355 PetscFunctionReturn(0); 1356 } 1357 1358 /*@C 1359 TSGetRHSFunction - Returns the vector where the right hand side is stored and the function/context to compute it. 1360 1361 Not Collective 1362 1363 Input Parameter: 1364 . ts - the TS context 1365 1366 Output Parameter: 1367 + r - vector to hold computed right hand side (or NULL) 1368 . func - the function to compute right hand side (or NULL) 1369 - ctx - the function context (or NULL) 1370 1371 Level: advanced 1372 1373 .seealso: TSSetRHSFunction(), SNESGetFunction() 1374 @*/ 1375 PetscErrorCode TSGetRHSFunction(TS ts,Vec *r,TSRHSFunction *func,void **ctx) 1376 { 1377 PetscErrorCode ierr; 1378 SNES snes; 1379 DM dm; 1380 1381 PetscFunctionBegin; 1382 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1383 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1384 ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 1385 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1386 ierr = DMTSGetRHSFunction(dm,func,ctx);CHKERRQ(ierr); 1387 PetscFunctionReturn(0); 1388 } 1389 1390 /*@C 1391 TSSetIJacobian - Set the function to compute the matrix dF/dU + a*dF/dU_t where F(t,U,U_t) is the function 1392 provided with TSSetIFunction(). 1393 1394 Logically Collective on TS 1395 1396 Input Parameters: 1397 + ts - the TS context obtained from TSCreate() 1398 . Amat - (approximate) Jacobian matrix 1399 . Pmat - matrix used to compute preconditioner (usually the same as Amat) 1400 . f - the Jacobian evaluation routine 1401 - ctx - user-defined context for private data for the Jacobian evaluation routine (may be NULL) 1402 1403 Calling sequence of f: 1404 $ PetscErrorCode f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat Amat,Mat Pmat,void *ctx); 1405 1406 + t - time at step/stage being solved 1407 . U - state vector 1408 . U_t - time derivative of state vector 1409 . a - shift 1410 . Amat - (approximate) Jacobian of F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t 1411 . Pmat - matrix used for constructing preconditioner, usually the same as Amat 1412 - ctx - [optional] user-defined context for matrix evaluation routine 1413 1414 Notes: 1415 The matrices Amat and Pmat are exactly the matrices that are used by SNES for the nonlinear solve. 1416 1417 If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null 1418 space to Amat and the KSP solvers will automatically use that null space as needed during the solution process. 1419 1420 The matrix dF/dU + a*dF/dU_t you provide turns out to be 1421 the Jacobian of F(t,U,W+a*U) where F(t,U,U_t) = 0 is the DAE to be solved. 1422 The time integrator internally approximates U_t by W+a*U where the positive "shift" 1423 a and vector W depend on the integration method, step size, and past states. For example with 1424 the backward Euler method a = 1/dt and W = -a*U(previous timestep) so 1425 W + a*U = a*(U - U(previous timestep)) = (U - U(previous timestep))/dt 1426 1427 You must set all the diagonal entries of the matrices, if they are zero you must still set them with a zero value 1428 1429 The TS solver may modify the nonzero structure and the entries of the matrices Amat and Pmat between the calls to f() 1430 You should not assume the values are the same in the next call to f() as you set them in the previous call. 1431 1432 Level: beginner 1433 1434 .seealso: TSSetIFunction(), TSSetRHSJacobian(), SNESComputeJacobianDefaultColor(), SNESComputeJacobianDefault(), TSSetRHSFunction() 1435 1436 @*/ 1437 PetscErrorCode TSSetIJacobian(TS ts,Mat Amat,Mat Pmat,TSIJacobian f,void *ctx) 1438 { 1439 PetscErrorCode ierr; 1440 SNES snes; 1441 DM dm; 1442 1443 PetscFunctionBegin; 1444 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1445 if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 1446 if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 1447 if (Amat) PetscCheckSameComm(ts,1,Amat,2); 1448 if (Pmat) PetscCheckSameComm(ts,1,Pmat,3); 1449 1450 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1451 ierr = DMTSSetIJacobian(dm,f,ctx);CHKERRQ(ierr); 1452 1453 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1454 ierr = SNESSetJacobian(snes,Amat,Pmat,SNESTSFormJacobian,ts);CHKERRQ(ierr); 1455 PetscFunctionReturn(0); 1456 } 1457 1458 /*@ 1459 TSRHSJacobianSetReuse - restore RHS Jacobian before re-evaluating. Without this flag, TS will change the sign and 1460 shift the RHS Jacobian for a finite-time-step implicit solve, in which case the user function will need to recompute 1461 the entire Jacobian. The reuse flag must be set if the evaluation function will assume that the matrix entries have 1462 not been changed by the TS. 1463 1464 Logically Collective 1465 1466 Input Arguments: 1467 + ts - TS context obtained from TSCreate() 1468 - reuse - PETSC_TRUE if the RHS Jacobian 1469 1470 Level: intermediate 1471 1472 .seealso: TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 1473 @*/ 1474 PetscErrorCode TSRHSJacobianSetReuse(TS ts,PetscBool reuse) 1475 { 1476 PetscFunctionBegin; 1477 ts->rhsjacobian.reuse = reuse; 1478 PetscFunctionReturn(0); 1479 } 1480 1481 /*@C 1482 TSSetI2Function - Set the function to compute F(t,U,U_t,U_tt) where F = 0 is the DAE to be solved. 1483 1484 Logically Collective on TS 1485 1486 Input Parameters: 1487 + ts - the TS context obtained from TSCreate() 1488 . F - vector to hold the residual (or NULL to have it created internally) 1489 . fun - the function evaluation routine 1490 - ctx - user-defined context for private data for the function evaluation routine (may be NULL) 1491 1492 Calling sequence of fun: 1493 $ PetscErrorCode fun(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,Vec F,ctx); 1494 1495 + t - time at step/stage being solved 1496 . U - state vector 1497 . U_t - time derivative of state vector 1498 . U_tt - second time derivative of state vector 1499 . F - function vector 1500 - ctx - [optional] user-defined context for matrix evaluation routine (may be NULL) 1501 1502 Level: beginner 1503 1504 .seealso: TSSetI2Jacobian(), TSSetIFunction(), TSCreate(), TSSetRHSFunction() 1505 @*/ 1506 PetscErrorCode TSSetI2Function(TS ts,Vec F,TSI2Function fun,void *ctx) 1507 { 1508 DM dm; 1509 PetscErrorCode ierr; 1510 1511 PetscFunctionBegin; 1512 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1513 if (F) PetscValidHeaderSpecific(F,VEC_CLASSID,2); 1514 ierr = TSSetIFunction(ts,F,NULL,NULL);CHKERRQ(ierr); 1515 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1516 ierr = DMTSSetI2Function(dm,fun,ctx);CHKERRQ(ierr); 1517 PetscFunctionReturn(0); 1518 } 1519 1520 /*@C 1521 TSGetI2Function - Returns the vector where the implicit residual is stored and the function/contex to compute it. 1522 1523 Not Collective 1524 1525 Input Parameter: 1526 . ts - the TS context 1527 1528 Output Parameter: 1529 + r - vector to hold residual (or NULL) 1530 . fun - the function to compute residual (or NULL) 1531 - ctx - the function context (or NULL) 1532 1533 Level: advanced 1534 1535 .seealso: TSSetIFunction(), SNESGetFunction(), TSCreate() 1536 @*/ 1537 PetscErrorCode TSGetI2Function(TS ts,Vec *r,TSI2Function *fun,void **ctx) 1538 { 1539 PetscErrorCode ierr; 1540 SNES snes; 1541 DM dm; 1542 1543 PetscFunctionBegin; 1544 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1545 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1546 ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 1547 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1548 ierr = DMTSGetI2Function(dm,fun,ctx);CHKERRQ(ierr); 1549 PetscFunctionReturn(0); 1550 } 1551 1552 /*@C 1553 TSSetI2Jacobian - Set the function to compute the matrix dF/dU + v*dF/dU_t + a*dF/dU_tt 1554 where F(t,U,U_t,U_tt) is the function you provided with TSSetI2Function(). 1555 1556 Logically Collective on TS 1557 1558 Input Parameters: 1559 + ts - the TS context obtained from TSCreate() 1560 . J - Jacobian matrix 1561 . P - preconditioning matrix for J (may be same as J) 1562 . jac - the Jacobian evaluation routine 1563 - ctx - user-defined context for private data for the Jacobian evaluation routine (may be NULL) 1564 1565 Calling sequence of jac: 1566 $ PetscErrorCode jac(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,PetscReal v,PetscReal a,Mat J,Mat P,void *ctx); 1567 1568 + t - time at step/stage being solved 1569 . U - state vector 1570 . U_t - time derivative of state vector 1571 . U_tt - second time derivative of state vector 1572 . v - shift for U_t 1573 . a - shift for U_tt 1574 . J - Jacobian of G(U) = F(t,U,W+v*U,W'+a*U), equivalent to dF/dU + v*dF/dU_t + a*dF/dU_tt 1575 . P - preconditioning matrix for J, may be same as J 1576 - ctx - [optional] user-defined context for matrix evaluation routine 1577 1578 Notes: 1579 The matrices J and P are exactly the matrices that are used by SNES for the nonlinear solve. 1580 1581 The matrix dF/dU + v*dF/dU_t + a*dF/dU_tt you provide turns out to be 1582 the Jacobian of G(U) = F(t,U,W+v*U,W'+a*U) where F(t,U,U_t,U_tt) = 0 is the DAE to be solved. 1583 The time integrator internally approximates U_t by W+v*U and U_tt by W'+a*U where the positive "shift" 1584 parameters 'v' and 'a' and vectors W, W' depend on the integration method, step size, and past states. 1585 1586 Level: beginner 1587 1588 .seealso: TSSetI2Function(), TSGetI2Jacobian() 1589 @*/ 1590 PetscErrorCode TSSetI2Jacobian(TS ts,Mat J,Mat P,TSI2Jacobian jac,void *ctx) 1591 { 1592 DM dm; 1593 PetscErrorCode ierr; 1594 1595 PetscFunctionBegin; 1596 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1597 if (J) PetscValidHeaderSpecific(J,MAT_CLASSID,2); 1598 if (P) PetscValidHeaderSpecific(P,MAT_CLASSID,3); 1599 ierr = TSSetIJacobian(ts,J,P,NULL,NULL);CHKERRQ(ierr); 1600 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1601 ierr = DMTSSetI2Jacobian(dm,jac,ctx);CHKERRQ(ierr); 1602 PetscFunctionReturn(0); 1603 } 1604 1605 /*@C 1606 TSGetI2Jacobian - Returns the implicit Jacobian at the present timestep. 1607 1608 Not Collective, but parallel objects are returned if TS is parallel 1609 1610 Input Parameter: 1611 . ts - The TS context obtained from TSCreate() 1612 1613 Output Parameters: 1614 + J - The (approximate) Jacobian of F(t,U,U_t,U_tt) 1615 . P - The matrix from which the preconditioner is constructed, often the same as J 1616 . jac - The function to compute the Jacobian matrices 1617 - ctx - User-defined context for Jacobian evaluation routine 1618 1619 Notes: 1620 You can pass in NULL for any return argument you do not need. 1621 1622 Level: advanced 1623 1624 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetStepNumber(), TSSetI2Jacobian(), TSGetI2Function(), TSCreate() 1625 1626 @*/ 1627 PetscErrorCode TSGetI2Jacobian(TS ts,Mat *J,Mat *P,TSI2Jacobian *jac,void **ctx) 1628 { 1629 PetscErrorCode ierr; 1630 SNES snes; 1631 DM dm; 1632 1633 PetscFunctionBegin; 1634 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1635 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 1636 ierr = SNESGetJacobian(snes,J,P,NULL,NULL);CHKERRQ(ierr); 1637 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1638 ierr = DMTSGetI2Jacobian(dm,jac,ctx);CHKERRQ(ierr); 1639 PetscFunctionReturn(0); 1640 } 1641 1642 /*@ 1643 TSComputeI2Function - Evaluates the DAE residual written in implicit form F(t,U,U_t,U_tt) = 0 1644 1645 Collective on TS 1646 1647 Input Parameters: 1648 + ts - the TS context 1649 . t - current time 1650 . U - state vector 1651 . V - time derivative of state vector (U_t) 1652 - A - second time derivative of state vector (U_tt) 1653 1654 Output Parameter: 1655 . F - the residual vector 1656 1657 Note: 1658 Most users should not need to explicitly call this routine, as it 1659 is used internally within the nonlinear solvers. 1660 1661 Level: developer 1662 1663 .seealso: TSSetI2Function(), TSGetI2Function() 1664 @*/ 1665 PetscErrorCode TSComputeI2Function(TS ts,PetscReal t,Vec U,Vec V,Vec A,Vec F) 1666 { 1667 DM dm; 1668 TSI2Function I2Function; 1669 void *ctx; 1670 TSRHSFunction rhsfunction; 1671 PetscErrorCode ierr; 1672 1673 PetscFunctionBegin; 1674 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1675 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 1676 PetscValidHeaderSpecific(V,VEC_CLASSID,4); 1677 PetscValidHeaderSpecific(A,VEC_CLASSID,5); 1678 PetscValidHeaderSpecific(F,VEC_CLASSID,6); 1679 1680 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1681 ierr = DMTSGetI2Function(dm,&I2Function,&ctx);CHKERRQ(ierr); 1682 ierr = DMTSGetRHSFunction(dm,&rhsfunction,NULL);CHKERRQ(ierr); 1683 1684 if (!I2Function) { 1685 ierr = TSComputeIFunction(ts,t,U,A,F,PETSC_FALSE);CHKERRQ(ierr); 1686 PetscFunctionReturn(0); 1687 } 1688 1689 ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,V,F);CHKERRQ(ierr); 1690 1691 PetscStackPush("TS user implicit function"); 1692 ierr = I2Function(ts,t,U,V,A,F,ctx);CHKERRQ(ierr); 1693 PetscStackPop; 1694 1695 if (rhsfunction) { 1696 Vec Frhs; 1697 ierr = TSGetRHSVec_Private(ts,&Frhs);CHKERRQ(ierr); 1698 ierr = TSComputeRHSFunction(ts,t,U,Frhs);CHKERRQ(ierr); 1699 ierr = VecAXPY(F,-1,Frhs);CHKERRQ(ierr); 1700 } 1701 1702 ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,V,F);CHKERRQ(ierr); 1703 PetscFunctionReturn(0); 1704 } 1705 1706 /*@ 1707 TSComputeI2Jacobian - Evaluates the Jacobian of the DAE 1708 1709 Collective on TS 1710 1711 Input Parameters: 1712 + ts - the TS context 1713 . t - current timestep 1714 . U - state vector 1715 . V - time derivative of state vector 1716 . A - second time derivative of state vector 1717 . shiftV - shift to apply, see note below 1718 - shiftA - shift to apply, see note below 1719 1720 Output Parameters: 1721 + J - Jacobian matrix 1722 - P - optional preconditioning matrix 1723 1724 Notes: 1725 If F(t,U,V,A)=0 is the DAE, the required Jacobian is 1726 1727 dF/dU + shiftV*dF/dV + shiftA*dF/dA 1728 1729 Most users should not need to explicitly call this routine, as it 1730 is used internally within the nonlinear solvers. 1731 1732 Level: developer 1733 1734 .seealso: TSSetI2Jacobian() 1735 @*/ 1736 PetscErrorCode TSComputeI2Jacobian(TS ts,PetscReal t,Vec U,Vec V,Vec A,PetscReal shiftV,PetscReal shiftA,Mat J,Mat P) 1737 { 1738 DM dm; 1739 TSI2Jacobian I2Jacobian; 1740 void *ctx; 1741 TSRHSJacobian rhsjacobian; 1742 PetscErrorCode ierr; 1743 1744 PetscFunctionBegin; 1745 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1746 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 1747 PetscValidHeaderSpecific(V,VEC_CLASSID,4); 1748 PetscValidHeaderSpecific(A,VEC_CLASSID,5); 1749 PetscValidHeaderSpecific(J,MAT_CLASSID,8); 1750 PetscValidHeaderSpecific(P,MAT_CLASSID,9); 1751 1752 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1753 ierr = DMTSGetI2Jacobian(dm,&I2Jacobian,&ctx);CHKERRQ(ierr); 1754 ierr = DMTSGetRHSJacobian(dm,&rhsjacobian,NULL);CHKERRQ(ierr); 1755 1756 if (!I2Jacobian) { 1757 ierr = TSComputeIJacobian(ts,t,U,A,shiftA,J,P,PETSC_FALSE);CHKERRQ(ierr); 1758 PetscFunctionReturn(0); 1759 } 1760 1761 ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,J,P);CHKERRQ(ierr); 1762 1763 PetscStackPush("TS user implicit Jacobian"); 1764 ierr = I2Jacobian(ts,t,U,V,A,shiftV,shiftA,J,P,ctx);CHKERRQ(ierr); 1765 PetscStackPop; 1766 1767 if (rhsjacobian) { 1768 Mat Jrhs,Prhs; MatStructure axpy = DIFFERENT_NONZERO_PATTERN; 1769 ierr = TSGetRHSMats_Private(ts,&Jrhs,&Prhs);CHKERRQ(ierr); 1770 ierr = TSComputeRHSJacobian(ts,t,U,Jrhs,Prhs);CHKERRQ(ierr); 1771 ierr = MatAXPY(J,-1,Jrhs,axpy);CHKERRQ(ierr); 1772 if (P != J) {ierr = MatAXPY(P,-1,Prhs,axpy);CHKERRQ(ierr);} 1773 } 1774 1775 ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,J,P);CHKERRQ(ierr); 1776 PetscFunctionReturn(0); 1777 } 1778 1779 /*@C 1780 TSSetTransientVariable - sets function to transform from state to transient variables 1781 1782 Logically Collective 1783 1784 Input Arguments: 1785 + ts - time stepping context on which to change the transient variable 1786 . tvar - a function that transforms to transient variables 1787 - ctx - a context for tvar 1788 1789 Calling sequence of tvar: 1790 $ PetscErrorCode tvar(TS ts,Vec p,Vec c,void *ctx); 1791 1792 + ts - timestep context 1793 . p - input vector (primative form) 1794 . c - output vector, transient variables (conservative form) 1795 - ctx - [optional] user-defined function context 1796 1797 Level: advanced 1798 1799 Notes: 1800 This is typically used to transform from primitive to conservative variables so that a time integrator (e.g., TSBDF) 1801 can be conservative. In this context, primitive variables P are used to model the state (e.g., because they lead to 1802 well-conditioned formulations even in limiting cases such as low-Mach or zero porosity). The transient variable is 1803 C(P), specified by calling this function. An IFunction thus receives arguments (P, Cdot) and the IJacobian must be 1804 evaluated via the chain rule, as in 1805 1806 dF/dP + shift * dF/dCdot dC/dP. 1807 1808 .seealso: DMTSSetTransientVariable(), DMTSGetTransientVariable(), TSSetIFunction(), TSSetIJacobian() 1809 @*/ 1810 PetscErrorCode TSSetTransientVariable(TS ts,TSTransientVariable tvar,void *ctx) 1811 { 1812 PetscErrorCode ierr; 1813 DM dm; 1814 1815 PetscFunctionBegin; 1816 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1817 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1818 ierr = DMTSSetTransientVariable(dm,tvar,ctx);CHKERRQ(ierr); 1819 PetscFunctionReturn(0); 1820 } 1821 1822 /*@ 1823 TSComputeTransientVariable - transforms state (primitive) variables to transient (conservative) variables 1824 1825 Logically Collective 1826 1827 Input Parameters: 1828 + ts - TS on which to compute 1829 - U - state vector to be transformed to transient variables 1830 1831 Output Parameters: 1832 . C - transient (conservative) variable 1833 1834 Developer Notes: 1835 If DMTSSetTransientVariable() has not been called, then C is not modified in this routine and C=NULL is allowed. 1836 This makes it safe to call without a guard. One can use TSHasTransientVariable() to check if transient variables are 1837 being used. 1838 1839 Level: developer 1840 1841 .seealso: DMTSSetTransientVariable(), TSComputeIFunction(), TSComputeIJacobian() 1842 @*/ 1843 PetscErrorCode TSComputeTransientVariable(TS ts,Vec U,Vec C) 1844 { 1845 PetscErrorCode ierr; 1846 DM dm; 1847 DMTS dmts; 1848 1849 PetscFunctionBegin; 1850 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1851 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 1852 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1853 ierr = DMGetDMTS(dm,&dmts);CHKERRQ(ierr); 1854 if (dmts->ops->transientvar) { 1855 PetscValidHeaderSpecific(C,VEC_CLASSID,3); 1856 ierr = (*dmts->ops->transientvar)(ts,U,C,dmts->transientvarctx);CHKERRQ(ierr); 1857 } 1858 PetscFunctionReturn(0); 1859 } 1860 1861 /*@ 1862 TSHasTransientVariable - determine whether transient variables have been set 1863 1864 Logically Collective 1865 1866 Input Parameters: 1867 . ts - TS on which to compute 1868 1869 Output Parameters: 1870 . has - PETSC_TRUE if transient variables have been set 1871 1872 Level: developer 1873 1874 .seealso: DMTSSetTransientVariable(), TSComputeTransientVariable() 1875 @*/ 1876 PetscErrorCode TSHasTransientVariable(TS ts,PetscBool *has) 1877 { 1878 PetscErrorCode ierr; 1879 DM dm; 1880 DMTS dmts; 1881 1882 PetscFunctionBegin; 1883 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1884 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1885 ierr = DMGetDMTS(dm,&dmts);CHKERRQ(ierr); 1886 *has = dmts->ops->transientvar ? PETSC_TRUE : PETSC_FALSE; 1887 PetscFunctionReturn(0); 1888 } 1889 1890 /*@ 1891 TS2SetSolution - Sets the initial solution and time derivative vectors 1892 for use by the TS routines handling second order equations. 1893 1894 Logically Collective on TS 1895 1896 Input Parameters: 1897 + ts - the TS context obtained from TSCreate() 1898 . u - the solution vector 1899 - v - the time derivative vector 1900 1901 Level: beginner 1902 1903 @*/ 1904 PetscErrorCode TS2SetSolution(TS ts,Vec u,Vec v) 1905 { 1906 PetscErrorCode ierr; 1907 1908 PetscFunctionBegin; 1909 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1910 PetscValidHeaderSpecific(u,VEC_CLASSID,2); 1911 PetscValidHeaderSpecific(v,VEC_CLASSID,3); 1912 ierr = TSSetSolution(ts,u);CHKERRQ(ierr); 1913 ierr = PetscObjectReference((PetscObject)v);CHKERRQ(ierr); 1914 ierr = VecDestroy(&ts->vec_dot);CHKERRQ(ierr); 1915 ts->vec_dot = v; 1916 PetscFunctionReturn(0); 1917 } 1918 1919 /*@ 1920 TS2GetSolution - Returns the solution and time derivative at the present timestep 1921 for second order equations. It is valid to call this routine inside the function 1922 that you are evaluating in order to move to the new timestep. This vector not 1923 changed until the solution at the next timestep has been calculated. 1924 1925 Not Collective, but Vec returned is parallel if TS is parallel 1926 1927 Input Parameter: 1928 . ts - the TS context obtained from TSCreate() 1929 1930 Output Parameter: 1931 + u - the vector containing the solution 1932 - v - the vector containing the time derivative 1933 1934 Level: intermediate 1935 1936 .seealso: TS2SetSolution(), TSGetTimeStep(), TSGetTime() 1937 1938 @*/ 1939 PetscErrorCode TS2GetSolution(TS ts,Vec *u,Vec *v) 1940 { 1941 PetscFunctionBegin; 1942 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1943 if (u) PetscValidPointer(u,2); 1944 if (v) PetscValidPointer(v,3); 1945 if (u) *u = ts->vec_sol; 1946 if (v) *v = ts->vec_dot; 1947 PetscFunctionReturn(0); 1948 } 1949 1950 /*@C 1951 TSLoad - Loads a KSP that has been stored in binary with KSPView(). 1952 1953 Collective on PetscViewer 1954 1955 Input Parameters: 1956 + newdm - the newly loaded TS, this needs to have been created with TSCreate() or 1957 some related function before a call to TSLoad(). 1958 - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() 1959 1960 Level: intermediate 1961 1962 Notes: 1963 The type is determined by the data in the file, any type set into the TS before this call is ignored. 1964 1965 Notes for advanced users: 1966 Most users should not need to know the details of the binary storage 1967 format, since TSLoad() and TSView() completely hide these details. 1968 But for anyone who's interested, the standard binary matrix storage 1969 format is 1970 .vb 1971 has not yet been determined 1972 .ve 1973 1974 .seealso: PetscViewerBinaryOpen(), TSView(), MatLoad(), VecLoad() 1975 @*/ 1976 PetscErrorCode TSLoad(TS ts, PetscViewer viewer) 1977 { 1978 PetscErrorCode ierr; 1979 PetscBool isbinary; 1980 PetscInt classid; 1981 char type[256]; 1982 DMTS sdm; 1983 DM dm; 1984 1985 PetscFunctionBegin; 1986 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1987 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1988 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1989 if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 1990 1991 ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr); 1992 if (classid != TS_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Not TS next in file"); 1993 ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr); 1994 ierr = TSSetType(ts, type);CHKERRQ(ierr); 1995 if (ts->ops->load) { 1996 ierr = (*ts->ops->load)(ts,viewer);CHKERRQ(ierr); 1997 } 1998 ierr = DMCreate(PetscObjectComm((PetscObject)ts),&dm);CHKERRQ(ierr); 1999 ierr = DMLoad(dm,viewer);CHKERRQ(ierr); 2000 ierr = TSSetDM(ts,dm);CHKERRQ(ierr); 2001 ierr = DMCreateGlobalVector(ts->dm,&ts->vec_sol);CHKERRQ(ierr); 2002 ierr = VecLoad(ts->vec_sol,viewer);CHKERRQ(ierr); 2003 ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr); 2004 ierr = DMTSLoad(sdm,viewer);CHKERRQ(ierr); 2005 PetscFunctionReturn(0); 2006 } 2007 2008 #include <petscdraw.h> 2009 #if defined(PETSC_HAVE_SAWS) 2010 #include <petscviewersaws.h> 2011 #endif 2012 2013 /*@C 2014 TSViewFromOptions - View from Options 2015 2016 Collective on TS 2017 2018 Input Parameters: 2019 + A - the application ordering context 2020 . obj - Optional object 2021 - name - command line option 2022 2023 Level: intermediate 2024 .seealso: TS, TSView, PetscObjectViewFromOptions(), TSCreate() 2025 @*/ 2026 PetscErrorCode TSViewFromOptions(TS A,PetscObject obj,const char name[]) 2027 { 2028 PetscErrorCode ierr; 2029 2030 PetscFunctionBegin; 2031 PetscValidHeaderSpecific(A,TS_CLASSID,1); 2032 ierr = PetscObjectViewFromOptions((PetscObject)A,obj,name);CHKERRQ(ierr); 2033 PetscFunctionReturn(0); 2034 } 2035 2036 /*@C 2037 TSView - Prints the TS data structure. 2038 2039 Collective on TS 2040 2041 Input Parameters: 2042 + ts - the TS context obtained from TSCreate() 2043 - viewer - visualization context 2044 2045 Options Database Key: 2046 . -ts_view - calls TSView() at end of TSStep() 2047 2048 Notes: 2049 The available visualization contexts include 2050 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 2051 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 2052 output where only the first processor opens 2053 the file. All other processors send their 2054 data to the first processor to print. 2055 2056 The user can open an alternative visualization context with 2057 PetscViewerASCIIOpen() - output to a specified file. 2058 2059 In the debugger you can do "call TSView(ts,0)" to display the TS solver. (The same holds for any PETSc object viewer). 2060 2061 Level: beginner 2062 2063 .seealso: PetscViewerASCIIOpen() 2064 @*/ 2065 PetscErrorCode TSView(TS ts,PetscViewer viewer) 2066 { 2067 PetscErrorCode ierr; 2068 TSType type; 2069 PetscBool iascii,isstring,isundials,isbinary,isdraw; 2070 DMTS sdm; 2071 #if defined(PETSC_HAVE_SAWS) 2072 PetscBool issaws; 2073 #endif 2074 2075 PetscFunctionBegin; 2076 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2077 if (!viewer) { 2078 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ts),&viewer);CHKERRQ(ierr); 2079 } 2080 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 2081 PetscCheckSameComm(ts,1,viewer,2); 2082 2083 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 2084 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 2085 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 2086 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 2087 #if defined(PETSC_HAVE_SAWS) 2088 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 2089 #endif 2090 if (iascii) { 2091 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ts,viewer);CHKERRQ(ierr); 2092 if (ts->ops->view) { 2093 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2094 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 2095 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2096 } 2097 if (ts->max_steps < PETSC_MAX_INT) { 2098 ierr = PetscViewerASCIIPrintf(viewer," maximum steps=%D\n",ts->max_steps);CHKERRQ(ierr); 2099 } 2100 if (ts->max_time < PETSC_MAX_REAL) { 2101 ierr = PetscViewerASCIIPrintf(viewer," maximum time=%g\n",(double)ts->max_time);CHKERRQ(ierr); 2102 } 2103 if (ts->usessnes) { 2104 PetscBool lin; 2105 if (ts->problem_type == TS_NONLINEAR) { 2106 ierr = PetscViewerASCIIPrintf(viewer," total number of nonlinear solver iterations=%D\n",ts->snes_its);CHKERRQ(ierr); 2107 } 2108 ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",ts->ksp_its);CHKERRQ(ierr); 2109 ierr = PetscObjectTypeCompareAny((PetscObject)ts->snes,&lin,SNESKSPONLY,SNESKSPTRANSPOSEONLY,"");CHKERRQ(ierr); 2110 ierr = PetscViewerASCIIPrintf(viewer," total number of %slinear solve failures=%D\n",lin ? "" : "non",ts->num_snes_failures);CHKERRQ(ierr); 2111 } 2112 ierr = PetscViewerASCIIPrintf(viewer," total number of rejected steps=%D\n",ts->reject);CHKERRQ(ierr); 2113 if (ts->vrtol) { 2114 ierr = PetscViewerASCIIPrintf(viewer," using vector of relative error tolerances, ");CHKERRQ(ierr); 2115 } else { 2116 ierr = PetscViewerASCIIPrintf(viewer," using relative error tolerance of %g, ",(double)ts->rtol);CHKERRQ(ierr); 2117 } 2118 if (ts->vatol) { 2119 ierr = PetscViewerASCIIPrintf(viewer," using vector of absolute error tolerances\n");CHKERRQ(ierr); 2120 } else { 2121 ierr = PetscViewerASCIIPrintf(viewer," using absolute error tolerance of %g\n",(double)ts->atol);CHKERRQ(ierr); 2122 } 2123 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2124 ierr = TSAdaptView(ts->adapt,viewer);CHKERRQ(ierr); 2125 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2126 } else if (isstring) { 2127 ierr = TSGetType(ts,&type);CHKERRQ(ierr); 2128 ierr = PetscViewerStringSPrintf(viewer," TSType: %-7.7s",type);CHKERRQ(ierr); 2129 if (ts->ops->view) {ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);} 2130 } else if (isbinary) { 2131 PetscInt classid = TS_FILE_CLASSID; 2132 MPI_Comm comm; 2133 PetscMPIInt rank; 2134 char type[256]; 2135 2136 ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr); 2137 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 2138 if (!rank) { 2139 ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr); 2140 ierr = PetscStrncpy(type,((PetscObject)ts)->type_name,256);CHKERRQ(ierr); 2141 ierr = PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR);CHKERRQ(ierr); 2142 } 2143 if (ts->ops->view) { 2144 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 2145 } 2146 if (ts->adapt) {ierr = TSAdaptView(ts->adapt,viewer);CHKERRQ(ierr);} 2147 ierr = DMView(ts->dm,viewer);CHKERRQ(ierr); 2148 ierr = VecView(ts->vec_sol,viewer);CHKERRQ(ierr); 2149 ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr); 2150 ierr = DMTSView(sdm,viewer);CHKERRQ(ierr); 2151 } else if (isdraw) { 2152 PetscDraw draw; 2153 char str[36]; 2154 PetscReal x,y,bottom,h; 2155 2156 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 2157 ierr = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr); 2158 ierr = PetscStrcpy(str,"TS: ");CHKERRQ(ierr); 2159 ierr = PetscStrcat(str,((PetscObject)ts)->type_name);CHKERRQ(ierr); 2160 ierr = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLACK,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr); 2161 bottom = y - h; 2162 ierr = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr); 2163 if (ts->ops->view) { 2164 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 2165 } 2166 if (ts->adapt) {ierr = TSAdaptView(ts->adapt,viewer);CHKERRQ(ierr);} 2167 if (ts->snes) {ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr);} 2168 ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr); 2169 #if defined(PETSC_HAVE_SAWS) 2170 } else if (issaws) { 2171 PetscMPIInt rank; 2172 const char *name; 2173 2174 ierr = PetscObjectGetName((PetscObject)ts,&name);CHKERRQ(ierr); 2175 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 2176 if (!((PetscObject)ts)->amsmem && !rank) { 2177 char dir[1024]; 2178 2179 ierr = PetscObjectViewSAWs((PetscObject)ts,viewer);CHKERRQ(ierr); 2180 ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time_step",name);CHKERRQ(ierr); 2181 PetscStackCallSAWs(SAWs_Register,(dir,&ts->steps,1,SAWs_READ,SAWs_INT)); 2182 ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time",name);CHKERRQ(ierr); 2183 PetscStackCallSAWs(SAWs_Register,(dir,&ts->ptime,1,SAWs_READ,SAWs_DOUBLE)); 2184 } 2185 if (ts->ops->view) { 2186 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 2187 } 2188 #endif 2189 } 2190 if (ts->snes && ts->usessnes) { 2191 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2192 ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr); 2193 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2194 } 2195 ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr); 2196 ierr = DMTSView(sdm,viewer);CHKERRQ(ierr); 2197 2198 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2199 ierr = PetscObjectTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials);CHKERRQ(ierr); 2200 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2201 PetscFunctionReturn(0); 2202 } 2203 2204 /*@ 2205 TSSetApplicationContext - Sets an optional user-defined context for 2206 the timesteppers. 2207 2208 Logically Collective on TS 2209 2210 Input Parameters: 2211 + ts - the TS context obtained from TSCreate() 2212 - usrP - optional user context 2213 2214 Fortran Notes: 2215 To use this from Fortran you must write a Fortran interface definition for this 2216 function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 2217 2218 Level: intermediate 2219 2220 .seealso: TSGetApplicationContext() 2221 @*/ 2222 PetscErrorCode TSSetApplicationContext(TS ts,void *usrP) 2223 { 2224 PetscFunctionBegin; 2225 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2226 ts->user = usrP; 2227 PetscFunctionReturn(0); 2228 } 2229 2230 /*@ 2231 TSGetApplicationContext - Gets the user-defined context for the 2232 timestepper. 2233 2234 Not Collective 2235 2236 Input Parameter: 2237 . ts - the TS context obtained from TSCreate() 2238 2239 Output Parameter: 2240 . usrP - user context 2241 2242 Fortran Notes: 2243 To use this from Fortran you must write a Fortran interface definition for this 2244 function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 2245 2246 Level: intermediate 2247 2248 .seealso: TSSetApplicationContext() 2249 @*/ 2250 PetscErrorCode TSGetApplicationContext(TS ts,void *usrP) 2251 { 2252 PetscFunctionBegin; 2253 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2254 *(void**)usrP = ts->user; 2255 PetscFunctionReturn(0); 2256 } 2257 2258 /*@ 2259 TSGetStepNumber - Gets the number of steps completed. 2260 2261 Not Collective 2262 2263 Input Parameter: 2264 . ts - the TS context obtained from TSCreate() 2265 2266 Output Parameter: 2267 . steps - number of steps completed so far 2268 2269 Level: intermediate 2270 2271 .seealso: TSGetTime(), TSGetTimeStep(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSSetPostStep() 2272 @*/ 2273 PetscErrorCode TSGetStepNumber(TS ts,PetscInt *steps) 2274 { 2275 PetscFunctionBegin; 2276 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2277 PetscValidIntPointer(steps,2); 2278 *steps = ts->steps; 2279 PetscFunctionReturn(0); 2280 } 2281 2282 /*@ 2283 TSSetStepNumber - Sets the number of steps completed. 2284 2285 Logically Collective on TS 2286 2287 Input Parameters: 2288 + ts - the TS context 2289 - steps - number of steps completed so far 2290 2291 Notes: 2292 For most uses of the TS solvers the user need not explicitly call 2293 TSSetStepNumber(), as the step counter is appropriately updated in 2294 TSSolve()/TSStep()/TSRollBack(). Power users may call this routine to 2295 reinitialize timestepping by setting the step counter to zero (and time 2296 to the initial time) to solve a similar problem with different initial 2297 conditions or parameters. Other possible use case is to continue 2298 timestepping from a previously interrupted run in such a way that TS 2299 monitors will be called with a initial nonzero step counter. 2300 2301 Level: advanced 2302 2303 .seealso: TSGetStepNumber(), TSSetTime(), TSSetTimeStep(), TSSetSolution() 2304 @*/ 2305 PetscErrorCode TSSetStepNumber(TS ts,PetscInt steps) 2306 { 2307 PetscFunctionBegin; 2308 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2309 PetscValidLogicalCollectiveInt(ts,steps,2); 2310 if (steps < 0) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Step number must be non-negative"); 2311 ts->steps = steps; 2312 PetscFunctionReturn(0); 2313 } 2314 2315 /*@ 2316 TSSetTimeStep - Allows one to reset the timestep at any time, 2317 useful for simple pseudo-timestepping codes. 2318 2319 Logically Collective on TS 2320 2321 Input Parameters: 2322 + ts - the TS context obtained from TSCreate() 2323 - time_step - the size of the timestep 2324 2325 Level: intermediate 2326 2327 .seealso: TSGetTimeStep(), TSSetTime() 2328 2329 @*/ 2330 PetscErrorCode TSSetTimeStep(TS ts,PetscReal time_step) 2331 { 2332 PetscFunctionBegin; 2333 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2334 PetscValidLogicalCollectiveReal(ts,time_step,2); 2335 ts->time_step = time_step; 2336 PetscFunctionReturn(0); 2337 } 2338 2339 /*@ 2340 TSSetExactFinalTime - Determines whether to adapt the final time step to 2341 match the exact final time, interpolate solution to the exact final time, 2342 or just return at the final time TS computed. 2343 2344 Logically Collective on TS 2345 2346 Input Parameter: 2347 + ts - the time-step context 2348 - eftopt - exact final time option 2349 2350 $ TS_EXACTFINALTIME_STEPOVER - Don't do anything if final time is exceeded 2351 $ TS_EXACTFINALTIME_INTERPOLATE - Interpolate back to final time 2352 $ TS_EXACTFINALTIME_MATCHSTEP - Adapt final time step to match the final time 2353 2354 Options Database: 2355 . -ts_exact_final_time <stepover,interpolate,matchstep> - select the final step at runtime 2356 2357 Warning: If you use the option TS_EXACTFINALTIME_STEPOVER the solution may be at a very different time 2358 then the final time you selected. 2359 2360 Level: beginner 2361 2362 .seealso: TSExactFinalTimeOption, TSGetExactFinalTime() 2363 @*/ 2364 PetscErrorCode TSSetExactFinalTime(TS ts,TSExactFinalTimeOption eftopt) 2365 { 2366 PetscFunctionBegin; 2367 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2368 PetscValidLogicalCollectiveEnum(ts,eftopt,2); 2369 ts->exact_final_time = eftopt; 2370 PetscFunctionReturn(0); 2371 } 2372 2373 /*@ 2374 TSGetExactFinalTime - Gets the exact final time option. 2375 2376 Not Collective 2377 2378 Input Parameter: 2379 . ts - the TS context 2380 2381 Output Parameter: 2382 . eftopt - exact final time option 2383 2384 Level: beginner 2385 2386 .seealso: TSExactFinalTimeOption, TSSetExactFinalTime() 2387 @*/ 2388 PetscErrorCode TSGetExactFinalTime(TS ts,TSExactFinalTimeOption *eftopt) 2389 { 2390 PetscFunctionBegin; 2391 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2392 PetscValidPointer(eftopt,2); 2393 *eftopt = ts->exact_final_time; 2394 PetscFunctionReturn(0); 2395 } 2396 2397 /*@ 2398 TSGetTimeStep - Gets the current timestep size. 2399 2400 Not Collective 2401 2402 Input Parameter: 2403 . ts - the TS context obtained from TSCreate() 2404 2405 Output Parameter: 2406 . dt - the current timestep size 2407 2408 Level: intermediate 2409 2410 .seealso: TSSetTimeStep(), TSGetTime() 2411 2412 @*/ 2413 PetscErrorCode TSGetTimeStep(TS ts,PetscReal *dt) 2414 { 2415 PetscFunctionBegin; 2416 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2417 PetscValidRealPointer(dt,2); 2418 *dt = ts->time_step; 2419 PetscFunctionReturn(0); 2420 } 2421 2422 /*@ 2423 TSGetSolution - Returns the solution at the present timestep. It 2424 is valid to call this routine inside the function that you are evaluating 2425 in order to move to the new timestep. This vector not changed until 2426 the solution at the next timestep has been calculated. 2427 2428 Not Collective, but Vec returned is parallel if TS is parallel 2429 2430 Input Parameter: 2431 . ts - the TS context obtained from TSCreate() 2432 2433 Output Parameter: 2434 . v - the vector containing the solution 2435 2436 Note: If you used TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP); this does not return the solution at the requested 2437 final time. It returns the solution at the next timestep. 2438 2439 Level: intermediate 2440 2441 .seealso: TSGetTimeStep(), TSGetTime(), TSGetSolveTime(), TSGetSolutionComponents(), TSSetSolutionFunction() 2442 2443 @*/ 2444 PetscErrorCode TSGetSolution(TS ts,Vec *v) 2445 { 2446 PetscFunctionBegin; 2447 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2448 PetscValidPointer(v,2); 2449 *v = ts->vec_sol; 2450 PetscFunctionReturn(0); 2451 } 2452 2453 /*@ 2454 TSGetSolutionComponents - Returns any solution components at the present 2455 timestep, if available for the time integration method being used. 2456 Solution components are quantities that share the same size and 2457 structure as the solution vector. 2458 2459 Not Collective, but Vec returned is parallel if TS is parallel 2460 2461 Parameters : 2462 + ts - the TS context obtained from TSCreate() (input parameter). 2463 . n - If v is PETSC_NULL, then the number of solution components is 2464 returned through n, else the n-th solution component is 2465 returned in v. 2466 - v - the vector containing the n-th solution component 2467 (may be PETSC_NULL to use this function to find out 2468 the number of solutions components). 2469 2470 Level: advanced 2471 2472 .seealso: TSGetSolution() 2473 2474 @*/ 2475 PetscErrorCode TSGetSolutionComponents(TS ts,PetscInt *n,Vec *v) 2476 { 2477 PetscErrorCode ierr; 2478 2479 PetscFunctionBegin; 2480 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2481 if (!ts->ops->getsolutioncomponents) *n = 0; 2482 else { 2483 ierr = (*ts->ops->getsolutioncomponents)(ts,n,v);CHKERRQ(ierr); 2484 } 2485 PetscFunctionReturn(0); 2486 } 2487 2488 /*@ 2489 TSGetAuxSolution - Returns an auxiliary solution at the present 2490 timestep, if available for the time integration method being used. 2491 2492 Not Collective, but Vec returned is parallel if TS is parallel 2493 2494 Parameters : 2495 + ts - the TS context obtained from TSCreate() (input parameter). 2496 - v - the vector containing the auxiliary solution 2497 2498 Level: intermediate 2499 2500 .seealso: TSGetSolution() 2501 2502 @*/ 2503 PetscErrorCode TSGetAuxSolution(TS ts,Vec *v) 2504 { 2505 PetscErrorCode ierr; 2506 2507 PetscFunctionBegin; 2508 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2509 if (ts->ops->getauxsolution) { 2510 ierr = (*ts->ops->getauxsolution)(ts,v);CHKERRQ(ierr); 2511 } else { 2512 ierr = VecZeroEntries(*v);CHKERRQ(ierr); 2513 } 2514 PetscFunctionReturn(0); 2515 } 2516 2517 /*@ 2518 TSGetTimeError - Returns the estimated error vector, if the chosen 2519 TSType has an error estimation functionality. 2520 2521 Not Collective, but Vec returned is parallel if TS is parallel 2522 2523 Note: MUST call after TSSetUp() 2524 2525 Parameters : 2526 + ts - the TS context obtained from TSCreate() (input parameter). 2527 . n - current estimate (n=0) or previous one (n=-1) 2528 - v - the vector containing the error (same size as the solution). 2529 2530 Level: intermediate 2531 2532 .seealso: TSGetSolution(), TSSetTimeError() 2533 2534 @*/ 2535 PetscErrorCode TSGetTimeError(TS ts,PetscInt n,Vec *v) 2536 { 2537 PetscErrorCode ierr; 2538 2539 PetscFunctionBegin; 2540 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2541 if (ts->ops->gettimeerror) { 2542 ierr = (*ts->ops->gettimeerror)(ts,n,v);CHKERRQ(ierr); 2543 } else { 2544 ierr = VecZeroEntries(*v);CHKERRQ(ierr); 2545 } 2546 PetscFunctionReturn(0); 2547 } 2548 2549 /*@ 2550 TSSetTimeError - Sets the estimated error vector, if the chosen 2551 TSType has an error estimation functionality. This can be used 2552 to restart such a time integrator with a given error vector. 2553 2554 Not Collective, but Vec returned is parallel if TS is parallel 2555 2556 Parameters : 2557 + ts - the TS context obtained from TSCreate() (input parameter). 2558 - v - the vector containing the error (same size as the solution). 2559 2560 Level: intermediate 2561 2562 .seealso: TSSetSolution(), TSGetTimeError) 2563 2564 @*/ 2565 PetscErrorCode TSSetTimeError(TS ts,Vec v) 2566 { 2567 PetscErrorCode ierr; 2568 2569 PetscFunctionBegin; 2570 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2571 if (!ts->setupcalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetUp() first"); 2572 if (ts->ops->settimeerror) { 2573 ierr = (*ts->ops->settimeerror)(ts,v);CHKERRQ(ierr); 2574 } 2575 PetscFunctionReturn(0); 2576 } 2577 2578 /* ----- Routines to initialize and destroy a timestepper ---- */ 2579 /*@ 2580 TSSetProblemType - Sets the type of problem to be solved. 2581 2582 Not collective 2583 2584 Input Parameters: 2585 + ts - The TS 2586 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 2587 .vb 2588 U_t - A U = 0 (linear) 2589 U_t - A(t) U = 0 (linear) 2590 F(t,U,U_t) = 0 (nonlinear) 2591 .ve 2592 2593 Level: beginner 2594 2595 .seealso: TSSetUp(), TSProblemType, TS 2596 @*/ 2597 PetscErrorCode TSSetProblemType(TS ts, TSProblemType type) 2598 { 2599 PetscErrorCode ierr; 2600 2601 PetscFunctionBegin; 2602 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2603 ts->problem_type = type; 2604 if (type == TS_LINEAR) { 2605 SNES snes; 2606 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2607 ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr); 2608 } 2609 PetscFunctionReturn(0); 2610 } 2611 2612 /*@C 2613 TSGetProblemType - Gets the type of problem to be solved. 2614 2615 Not collective 2616 2617 Input Parameter: 2618 . ts - The TS 2619 2620 Output Parameter: 2621 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 2622 .vb 2623 M U_t = A U 2624 M(t) U_t = A(t) U 2625 F(t,U,U_t) 2626 .ve 2627 2628 Level: beginner 2629 2630 .seealso: TSSetUp(), TSProblemType, TS 2631 @*/ 2632 PetscErrorCode TSGetProblemType(TS ts, TSProblemType *type) 2633 { 2634 PetscFunctionBegin; 2635 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2636 PetscValidIntPointer(type,2); 2637 *type = ts->problem_type; 2638 PetscFunctionReturn(0); 2639 } 2640 2641 /* 2642 Attempt to check/preset a default value for the exact final time option. This is needed at the beginning of TSSolve() and in TSSetUp() 2643 */ 2644 static PetscErrorCode TSSetExactFinalTimeDefault(TS ts) 2645 { 2646 PetscErrorCode ierr; 2647 PetscBool isnone; 2648 2649 PetscFunctionBegin; 2650 ierr = TSGetAdapt(ts,&ts->adapt);CHKERRQ(ierr); 2651 ierr = TSAdaptSetDefaultType(ts->adapt,ts->default_adapt_type);CHKERRQ(ierr); 2652 2653 ierr = PetscObjectTypeCompare((PetscObject)ts->adapt,TSADAPTNONE,&isnone);CHKERRQ(ierr); 2654 if (!isnone && ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) { 2655 ts->exact_final_time = TS_EXACTFINALTIME_MATCHSTEP; 2656 } else if (ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) { 2657 ts->exact_final_time = TS_EXACTFINALTIME_INTERPOLATE; 2658 } 2659 PetscFunctionReturn(0); 2660 } 2661 2662 2663 /*@ 2664 TSSetUp - Sets up the internal data structures for the later use of a timestepper. 2665 2666 Collective on TS 2667 2668 Input Parameter: 2669 . ts - the TS context obtained from TSCreate() 2670 2671 Notes: 2672 For basic use of the TS solvers the user need not explicitly call 2673 TSSetUp(), since these actions will automatically occur during 2674 the call to TSStep() or TSSolve(). However, if one wishes to control this 2675 phase separately, TSSetUp() should be called after TSCreate() 2676 and optional routines of the form TSSetXXX(), but before TSStep() and TSSolve(). 2677 2678 Level: advanced 2679 2680 .seealso: TSCreate(), TSStep(), TSDestroy(), TSSolve() 2681 @*/ 2682 PetscErrorCode TSSetUp(TS ts) 2683 { 2684 PetscErrorCode ierr; 2685 DM dm; 2686 PetscErrorCode (*func)(SNES,Vec,Vec,void*); 2687 PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 2688 TSIFunction ifun; 2689 TSIJacobian ijac; 2690 TSI2Jacobian i2jac; 2691 TSRHSJacobian rhsjac; 2692 2693 PetscFunctionBegin; 2694 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2695 if (ts->setupcalled) PetscFunctionReturn(0); 2696 2697 if (!((PetscObject)ts)->type_name) { 2698 ierr = TSGetIFunction(ts,NULL,&ifun,NULL);CHKERRQ(ierr); 2699 ierr = TSSetType(ts,ifun ? TSBEULER : TSEULER);CHKERRQ(ierr); 2700 } 2701 2702 if (!ts->vec_sol) { 2703 if (ts->dm) { 2704 ierr = DMCreateGlobalVector(ts->dm,&ts->vec_sol);CHKERRQ(ierr); 2705 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first"); 2706 } 2707 2708 if (!ts->Jacp && ts->Jacprhs) { /* IJacobianP shares the same matrix with RHSJacobianP if only RHSJacobianP is provided */ 2709 ierr = PetscObjectReference((PetscObject)ts->Jacprhs);CHKERRQ(ierr); 2710 ts->Jacp = ts->Jacprhs; 2711 } 2712 2713 if (ts->quadraturets) { 2714 ierr = TSSetUp(ts->quadraturets);CHKERRQ(ierr); 2715 ierr = VecDestroy(&ts->vec_costintegrand);CHKERRQ(ierr); 2716 ierr = VecDuplicate(ts->quadraturets->vec_sol,&ts->vec_costintegrand);CHKERRQ(ierr); 2717 } 2718 2719 ierr = TSGetRHSJacobian(ts,NULL,NULL,&rhsjac,NULL);CHKERRQ(ierr); 2720 if (rhsjac == TSComputeRHSJacobianConstant) { 2721 Mat Amat,Pmat; 2722 SNES snes; 2723 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2724 ierr = SNESGetJacobian(snes,&Amat,&Pmat,NULL,NULL);CHKERRQ(ierr); 2725 /* Matching matrices implies that an IJacobian is NOT set, because if it had been set, the IJacobian's matrix would 2726 * have displaced the RHS matrix */ 2727 if (Amat && Amat == ts->Arhs) { 2728 /* we need to copy the values of the matrix because for the constant Jacobian case the user will never set the numerical values in this new location */ 2729 ierr = MatDuplicate(ts->Arhs,MAT_COPY_VALUES,&Amat);CHKERRQ(ierr); 2730 ierr = SNESSetJacobian(snes,Amat,NULL,NULL,NULL);CHKERRQ(ierr); 2731 ierr = MatDestroy(&Amat);CHKERRQ(ierr); 2732 } 2733 if (Pmat && Pmat == ts->Brhs) { 2734 ierr = MatDuplicate(ts->Brhs,MAT_COPY_VALUES,&Pmat);CHKERRQ(ierr); 2735 ierr = SNESSetJacobian(snes,NULL,Pmat,NULL,NULL);CHKERRQ(ierr); 2736 ierr = MatDestroy(&Pmat);CHKERRQ(ierr); 2737 } 2738 } 2739 2740 ierr = TSGetAdapt(ts,&ts->adapt);CHKERRQ(ierr); 2741 ierr = TSAdaptSetDefaultType(ts->adapt,ts->default_adapt_type);CHKERRQ(ierr); 2742 2743 if (ts->ops->setup) { 2744 ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr); 2745 } 2746 2747 ierr = TSSetExactFinalTimeDefault(ts);CHKERRQ(ierr); 2748 2749 /* In the case where we've set a DMTSFunction or what have you, we need the default SNESFunction 2750 to be set right but can't do it elsewhere due to the overreliance on ctx=ts. 2751 */ 2752 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 2753 ierr = DMSNESGetFunction(dm,&func,NULL);CHKERRQ(ierr); 2754 if (!func) { 2755 ierr = DMSNESSetFunction(dm,SNESTSFormFunction,ts);CHKERRQ(ierr); 2756 } 2757 /* If the SNES doesn't have a jacobian set and the TS has an ijacobian or rhsjacobian set, set the SNES to use it. 2758 Otherwise, the SNES will use coloring internally to form the Jacobian. 2759 */ 2760 ierr = DMSNESGetJacobian(dm,&jac,NULL);CHKERRQ(ierr); 2761 ierr = DMTSGetIJacobian(dm,&ijac,NULL);CHKERRQ(ierr); 2762 ierr = DMTSGetI2Jacobian(dm,&i2jac,NULL);CHKERRQ(ierr); 2763 ierr = DMTSGetRHSJacobian(dm,&rhsjac,NULL);CHKERRQ(ierr); 2764 if (!jac && (ijac || i2jac || rhsjac)) { 2765 ierr = DMSNESSetJacobian(dm,SNESTSFormJacobian,ts);CHKERRQ(ierr); 2766 } 2767 2768 /* if time integration scheme has a starting method, call it */ 2769 if (ts->ops->startingmethod) { 2770 ierr = (*ts->ops->startingmethod)(ts);CHKERRQ(ierr); 2771 } 2772 2773 ts->setupcalled = PETSC_TRUE; 2774 PetscFunctionReturn(0); 2775 } 2776 2777 /*@ 2778 TSReset - Resets a TS context and removes any allocated Vecs and Mats. 2779 2780 Collective on TS 2781 2782 Input Parameter: 2783 . ts - the TS context obtained from TSCreate() 2784 2785 Level: beginner 2786 2787 .seealso: TSCreate(), TSSetup(), TSDestroy() 2788 @*/ 2789 PetscErrorCode TSReset(TS ts) 2790 { 2791 TS_RHSSplitLink ilink = ts->tsrhssplit,next; 2792 PetscErrorCode ierr; 2793 2794 PetscFunctionBegin; 2795 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2796 2797 if (ts->ops->reset) { 2798 ierr = (*ts->ops->reset)(ts);CHKERRQ(ierr); 2799 } 2800 if (ts->snes) {ierr = SNESReset(ts->snes);CHKERRQ(ierr);} 2801 if (ts->adapt) {ierr = TSAdaptReset(ts->adapt);CHKERRQ(ierr);} 2802 2803 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 2804 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 2805 ierr = VecDestroy(&ts->Frhs);CHKERRQ(ierr); 2806 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 2807 ierr = VecDestroy(&ts->vec_dot);CHKERRQ(ierr); 2808 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 2809 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 2810 ierr = VecDestroyVecs(ts->nwork,&ts->work);CHKERRQ(ierr); 2811 2812 ierr = MatDestroy(&ts->Jacprhs);CHKERRQ(ierr); 2813 ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr); 2814 if (ts->forward_solve) { 2815 ierr = TSForwardReset(ts);CHKERRQ(ierr); 2816 } 2817 if (ts->quadraturets) { 2818 ierr = TSReset(ts->quadraturets);CHKERRQ(ierr); 2819 ierr = VecDestroy(&ts->vec_costintegrand);CHKERRQ(ierr); 2820 } 2821 while (ilink) { 2822 next = ilink->next; 2823 ierr = TSDestroy(&ilink->ts);CHKERRQ(ierr); 2824 ierr = PetscFree(ilink->splitname);CHKERRQ(ierr); 2825 ierr = ISDestroy(&ilink->is);CHKERRQ(ierr); 2826 ierr = PetscFree(ilink);CHKERRQ(ierr); 2827 ilink = next; 2828 } 2829 ts->num_rhs_splits = 0; 2830 ts->setupcalled = PETSC_FALSE; 2831 PetscFunctionReturn(0); 2832 } 2833 2834 /*@ 2835 TSDestroy - Destroys the timestepper context that was created 2836 with TSCreate(). 2837 2838 Collective on TS 2839 2840 Input Parameter: 2841 . ts - the TS context obtained from TSCreate() 2842 2843 Level: beginner 2844 2845 .seealso: TSCreate(), TSSetUp(), TSSolve() 2846 @*/ 2847 PetscErrorCode TSDestroy(TS *ts) 2848 { 2849 PetscErrorCode ierr; 2850 2851 PetscFunctionBegin; 2852 if (!*ts) PetscFunctionReturn(0); 2853 PetscValidHeaderSpecific(*ts,TS_CLASSID,1); 2854 if (--((PetscObject)(*ts))->refct > 0) {*ts = NULL; PetscFunctionReturn(0);} 2855 2856 ierr = TSReset(*ts);CHKERRQ(ierr); 2857 ierr = TSAdjointReset(*ts);CHKERRQ(ierr); 2858 if ((*ts)->forward_solve) { 2859 ierr = TSForwardReset(*ts);CHKERRQ(ierr); 2860 } 2861 /* if memory was published with SAWs then destroy it */ 2862 ierr = PetscObjectSAWsViewOff((PetscObject)*ts);CHKERRQ(ierr); 2863 if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);} 2864 2865 ierr = TSTrajectoryDestroy(&(*ts)->trajectory);CHKERRQ(ierr); 2866 2867 ierr = TSAdaptDestroy(&(*ts)->adapt);CHKERRQ(ierr); 2868 ierr = TSEventDestroy(&(*ts)->event);CHKERRQ(ierr); 2869 2870 ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr); 2871 ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr); 2872 ierr = TSMonitorCancel((*ts));CHKERRQ(ierr); 2873 ierr = TSAdjointMonitorCancel((*ts));CHKERRQ(ierr); 2874 2875 ierr = TSDestroy(&(*ts)->quadraturets);CHKERRQ(ierr); 2876 ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr); 2877 PetscFunctionReturn(0); 2878 } 2879 2880 /*@ 2881 TSGetSNES - Returns the SNES (nonlinear solver) associated with 2882 a TS (timestepper) context. Valid only for nonlinear problems. 2883 2884 Not Collective, but SNES is parallel if TS is parallel 2885 2886 Input Parameter: 2887 . ts - the TS context obtained from TSCreate() 2888 2889 Output Parameter: 2890 . snes - the nonlinear solver context 2891 2892 Notes: 2893 The user can then directly manipulate the SNES context to set various 2894 options, etc. Likewise, the user can then extract and manipulate the 2895 KSP, KSP, and PC contexts as well. 2896 2897 TSGetSNES() does not work for integrators that do not use SNES; in 2898 this case TSGetSNES() returns NULL in snes. 2899 2900 Level: beginner 2901 2902 @*/ 2903 PetscErrorCode TSGetSNES(TS ts,SNES *snes) 2904 { 2905 PetscErrorCode ierr; 2906 2907 PetscFunctionBegin; 2908 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2909 PetscValidPointer(snes,2); 2910 if (!ts->snes) { 2911 ierr = SNESCreate(PetscObjectComm((PetscObject)ts),&ts->snes);CHKERRQ(ierr); 2912 ierr = PetscObjectSetOptions((PetscObject)ts->snes,((PetscObject)ts)->options);CHKERRQ(ierr); 2913 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 2914 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->snes);CHKERRQ(ierr); 2915 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr); 2916 if (ts->dm) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 2917 if (ts->problem_type == TS_LINEAR) { 2918 ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr); 2919 } 2920 } 2921 *snes = ts->snes; 2922 PetscFunctionReturn(0); 2923 } 2924 2925 /*@ 2926 TSSetSNES - Set the SNES (nonlinear solver) to be used by the timestepping context 2927 2928 Collective 2929 2930 Input Parameter: 2931 + ts - the TS context obtained from TSCreate() 2932 - snes - the nonlinear solver context 2933 2934 Notes: 2935 Most users should have the TS created by calling TSGetSNES() 2936 2937 Level: developer 2938 2939 @*/ 2940 PetscErrorCode TSSetSNES(TS ts,SNES snes) 2941 { 2942 PetscErrorCode ierr; 2943 PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*); 2944 2945 PetscFunctionBegin; 2946 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2947 PetscValidHeaderSpecific(snes,SNES_CLASSID,2); 2948 ierr = PetscObjectReference((PetscObject)snes);CHKERRQ(ierr); 2949 ierr = SNESDestroy(&ts->snes);CHKERRQ(ierr); 2950 2951 ts->snes = snes; 2952 2953 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 2954 ierr = SNESGetJacobian(ts->snes,NULL,NULL,&func,NULL);CHKERRQ(ierr); 2955 if (func == SNESTSFormJacobian) { 2956 ierr = SNESSetJacobian(ts->snes,NULL,NULL,SNESTSFormJacobian,ts);CHKERRQ(ierr); 2957 } 2958 PetscFunctionReturn(0); 2959 } 2960 2961 /*@ 2962 TSGetKSP - Returns the KSP (linear solver) associated with 2963 a TS (timestepper) context. 2964 2965 Not Collective, but KSP is parallel if TS is parallel 2966 2967 Input Parameter: 2968 . ts - the TS context obtained from TSCreate() 2969 2970 Output Parameter: 2971 . ksp - the nonlinear solver context 2972 2973 Notes: 2974 The user can then directly manipulate the KSP context to set various 2975 options, etc. Likewise, the user can then extract and manipulate the 2976 KSP and PC contexts as well. 2977 2978 TSGetKSP() does not work for integrators that do not use KSP; 2979 in this case TSGetKSP() returns NULL in ksp. 2980 2981 Level: beginner 2982 2983 @*/ 2984 PetscErrorCode TSGetKSP(TS ts,KSP *ksp) 2985 { 2986 PetscErrorCode ierr; 2987 SNES snes; 2988 2989 PetscFunctionBegin; 2990 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2991 PetscValidPointer(ksp,2); 2992 if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first"); 2993 if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()"); 2994 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2995 ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr); 2996 PetscFunctionReturn(0); 2997 } 2998 2999 /* ----------- Routines to set solver parameters ---------- */ 3000 3001 /*@ 3002 TSSetMaxSteps - Sets the maximum number of steps to use. 3003 3004 Logically Collective on TS 3005 3006 Input Parameters: 3007 + ts - the TS context obtained from TSCreate() 3008 - maxsteps - maximum number of steps to use 3009 3010 Options Database Keys: 3011 . -ts_max_steps <maxsteps> - Sets maxsteps 3012 3013 Notes: 3014 The default maximum number of steps is 5000 3015 3016 Level: intermediate 3017 3018 .seealso: TSGetMaxSteps(), TSSetMaxTime(), TSSetExactFinalTime() 3019 @*/ 3020 PetscErrorCode TSSetMaxSteps(TS ts,PetscInt maxsteps) 3021 { 3022 PetscFunctionBegin; 3023 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3024 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 3025 if (maxsteps < 0) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of steps must be non-negative"); 3026 ts->max_steps = maxsteps; 3027 PetscFunctionReturn(0); 3028 } 3029 3030 /*@ 3031 TSGetMaxSteps - Gets the maximum number of steps to use. 3032 3033 Not Collective 3034 3035 Input Parameters: 3036 . ts - the TS context obtained from TSCreate() 3037 3038 Output Parameter: 3039 . maxsteps - maximum number of steps to use 3040 3041 Level: advanced 3042 3043 .seealso: TSSetMaxSteps(), TSGetMaxTime(), TSSetMaxTime() 3044 @*/ 3045 PetscErrorCode TSGetMaxSteps(TS ts,PetscInt *maxsteps) 3046 { 3047 PetscFunctionBegin; 3048 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3049 PetscValidIntPointer(maxsteps,2); 3050 *maxsteps = ts->max_steps; 3051 PetscFunctionReturn(0); 3052 } 3053 3054 /*@ 3055 TSSetMaxTime - Sets the maximum (or final) time for timestepping. 3056 3057 Logically Collective on TS 3058 3059 Input Parameters: 3060 + ts - the TS context obtained from TSCreate() 3061 - maxtime - final time to step to 3062 3063 Options Database Keys: 3064 . -ts_max_time <maxtime> - Sets maxtime 3065 3066 Notes: 3067 The default maximum time is 5.0 3068 3069 Level: intermediate 3070 3071 .seealso: TSGetMaxTime(), TSSetMaxSteps(), TSSetExactFinalTime() 3072 @*/ 3073 PetscErrorCode TSSetMaxTime(TS ts,PetscReal maxtime) 3074 { 3075 PetscFunctionBegin; 3076 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3077 PetscValidLogicalCollectiveReal(ts,maxtime,2); 3078 ts->max_time = maxtime; 3079 PetscFunctionReturn(0); 3080 } 3081 3082 /*@ 3083 TSGetMaxTime - Gets the maximum (or final) time for timestepping. 3084 3085 Not Collective 3086 3087 Input Parameters: 3088 . ts - the TS context obtained from TSCreate() 3089 3090 Output Parameter: 3091 . maxtime - final time to step to 3092 3093 Level: advanced 3094 3095 .seealso: TSSetMaxTime(), TSGetMaxSteps(), TSSetMaxSteps() 3096 @*/ 3097 PetscErrorCode TSGetMaxTime(TS ts,PetscReal *maxtime) 3098 { 3099 PetscFunctionBegin; 3100 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3101 PetscValidRealPointer(maxtime,2); 3102 *maxtime = ts->max_time; 3103 PetscFunctionReturn(0); 3104 } 3105 3106 /*@ 3107 TSSetInitialTimeStep - Deprecated, use TSSetTime() and TSSetTimeStep(). 3108 3109 Level: deprecated 3110 3111 @*/ 3112 PetscErrorCode TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step) 3113 { 3114 PetscErrorCode ierr; 3115 PetscFunctionBegin; 3116 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3117 ierr = TSSetTime(ts,initial_time);CHKERRQ(ierr); 3118 ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr); 3119 PetscFunctionReturn(0); 3120 } 3121 3122 /*@ 3123 TSGetDuration - Deprecated, use TSGetMaxSteps() and TSGetMaxTime(). 3124 3125 Level: deprecated 3126 3127 @*/ 3128 PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime) 3129 { 3130 PetscFunctionBegin; 3131 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3132 if (maxsteps) { 3133 PetscValidIntPointer(maxsteps,2); 3134 *maxsteps = ts->max_steps; 3135 } 3136 if (maxtime) { 3137 PetscValidScalarPointer(maxtime,3); 3138 *maxtime = ts->max_time; 3139 } 3140 PetscFunctionReturn(0); 3141 } 3142 3143 /*@ 3144 TSSetDuration - Deprecated, use TSSetMaxSteps() and TSSetMaxTime(). 3145 3146 Level: deprecated 3147 3148 @*/ 3149 PetscErrorCode TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime) 3150 { 3151 PetscFunctionBegin; 3152 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3153 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 3154 PetscValidLogicalCollectiveReal(ts,maxtime,2); 3155 if (maxsteps >= 0) ts->max_steps = maxsteps; 3156 if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime; 3157 PetscFunctionReturn(0); 3158 } 3159 3160 /*@ 3161 TSGetTimeStepNumber - Deprecated, use TSGetStepNumber(). 3162 3163 Level: deprecated 3164 3165 @*/ 3166 PetscErrorCode TSGetTimeStepNumber(TS ts,PetscInt *steps) { return TSGetStepNumber(ts,steps); } 3167 3168 /*@ 3169 TSGetTotalSteps - Deprecated, use TSGetStepNumber(). 3170 3171 Level: deprecated 3172 3173 @*/ 3174 PetscErrorCode TSGetTotalSteps(TS ts,PetscInt *steps) { return TSGetStepNumber(ts,steps); } 3175 3176 /*@ 3177 TSSetSolution - Sets the initial solution vector 3178 for use by the TS routines. 3179 3180 Logically Collective on TS 3181 3182 Input Parameters: 3183 + ts - the TS context obtained from TSCreate() 3184 - u - the solution vector 3185 3186 Level: beginner 3187 3188 .seealso: TSSetSolutionFunction(), TSGetSolution(), TSCreate() 3189 @*/ 3190 PetscErrorCode TSSetSolution(TS ts,Vec u) 3191 { 3192 PetscErrorCode ierr; 3193 DM dm; 3194 3195 PetscFunctionBegin; 3196 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3197 PetscValidHeaderSpecific(u,VEC_CLASSID,2); 3198 ierr = PetscObjectReference((PetscObject)u);CHKERRQ(ierr); 3199 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 3200 ts->vec_sol = u; 3201 3202 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 3203 ierr = DMShellSetGlobalVector(dm,u);CHKERRQ(ierr); 3204 PetscFunctionReturn(0); 3205 } 3206 3207 /*@C 3208 TSSetPreStep - Sets the general-purpose function 3209 called once at the beginning of each time step. 3210 3211 Logically Collective on TS 3212 3213 Input Parameters: 3214 + ts - The TS context obtained from TSCreate() 3215 - func - The function 3216 3217 Calling sequence of func: 3218 . PetscErrorCode func (TS ts); 3219 3220 Level: intermediate 3221 3222 .seealso: TSSetPreStage(), TSSetPostStage(), TSSetPostStep(), TSStep(), TSRestartStep() 3223 @*/ 3224 PetscErrorCode TSSetPreStep(TS ts, PetscErrorCode (*func)(TS)) 3225 { 3226 PetscFunctionBegin; 3227 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3228 ts->prestep = func; 3229 PetscFunctionReturn(0); 3230 } 3231 3232 /*@ 3233 TSPreStep - Runs the user-defined pre-step function. 3234 3235 Collective on TS 3236 3237 Input Parameters: 3238 . ts - The TS context obtained from TSCreate() 3239 3240 Notes: 3241 TSPreStep() is typically used within time stepping implementations, 3242 so most users would not generally call this routine themselves. 3243 3244 Level: developer 3245 3246 .seealso: TSSetPreStep(), TSPreStage(), TSPostStage(), TSPostStep() 3247 @*/ 3248 PetscErrorCode TSPreStep(TS ts) 3249 { 3250 PetscErrorCode ierr; 3251 3252 PetscFunctionBegin; 3253 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3254 if (ts->prestep) { 3255 Vec U; 3256 PetscObjectState sprev,spost; 3257 3258 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3259 ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr); 3260 PetscStackCallStandard((*ts->prestep),(ts)); 3261 ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr); 3262 if (sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);} 3263 } 3264 PetscFunctionReturn(0); 3265 } 3266 3267 /*@C 3268 TSSetPreStage - Sets the general-purpose function 3269 called once at the beginning of each stage. 3270 3271 Logically Collective on TS 3272 3273 Input Parameters: 3274 + ts - The TS context obtained from TSCreate() 3275 - func - The function 3276 3277 Calling sequence of func: 3278 . PetscErrorCode func(TS ts, PetscReal stagetime); 3279 3280 Level: intermediate 3281 3282 Note: 3283 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 3284 The time step number being computed can be queried using TSGetStepNumber() and the total size of the step being 3285 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 3286 3287 .seealso: TSSetPostStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3288 @*/ 3289 PetscErrorCode TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal)) 3290 { 3291 PetscFunctionBegin; 3292 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3293 ts->prestage = func; 3294 PetscFunctionReturn(0); 3295 } 3296 3297 /*@C 3298 TSSetPostStage - Sets the general-purpose function 3299 called once at the end of each stage. 3300 3301 Logically Collective on TS 3302 3303 Input Parameters: 3304 + ts - The TS context obtained from TSCreate() 3305 - func - The function 3306 3307 Calling sequence of func: 3308 . PetscErrorCode func(TS ts, PetscReal stagetime, PetscInt stageindex, Vec* Y); 3309 3310 Level: intermediate 3311 3312 Note: 3313 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 3314 The time step number being computed can be queried using TSGetStepNumber() and the total size of the step being 3315 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 3316 3317 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3318 @*/ 3319 PetscErrorCode TSSetPostStage(TS ts, PetscErrorCode (*func)(TS,PetscReal,PetscInt,Vec*)) 3320 { 3321 PetscFunctionBegin; 3322 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3323 ts->poststage = func; 3324 PetscFunctionReturn(0); 3325 } 3326 3327 /*@C 3328 TSSetPostEvaluate - Sets the general-purpose function 3329 called once at the end of each step evaluation. 3330 3331 Logically Collective on TS 3332 3333 Input Parameters: 3334 + ts - The TS context obtained from TSCreate() 3335 - func - The function 3336 3337 Calling sequence of func: 3338 . PetscErrorCode func(TS ts); 3339 3340 Level: intermediate 3341 3342 Note: 3343 Semantically, TSSetPostEvaluate() differs from TSSetPostStep() since the function it sets is called before event-handling 3344 thus guaranteeing the same solution (computed by the time-stepper) will be passed to it. On the other hand, TSPostStep() 3345 may be passed a different solution, possibly changed by the event handler. TSPostEvaluate() is called after the next step 3346 solution is evaluated allowing to modify it, if need be. The solution can be obtained with TSGetSolution(), the time step 3347 with TSGetTimeStep(), and the time at the start of the step is available via TSGetTime() 3348 3349 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3350 @*/ 3351 PetscErrorCode TSSetPostEvaluate(TS ts, PetscErrorCode (*func)(TS)) 3352 { 3353 PetscFunctionBegin; 3354 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3355 ts->postevaluate = func; 3356 PetscFunctionReturn(0); 3357 } 3358 3359 /*@ 3360 TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage() 3361 3362 Collective on TS 3363 3364 Input Parameters: 3365 . ts - The TS context obtained from TSCreate() 3366 stagetime - The absolute time of the current stage 3367 3368 Notes: 3369 TSPreStage() is typically used within time stepping implementations, 3370 most users would not generally call this routine themselves. 3371 3372 Level: developer 3373 3374 .seealso: TSPostStage(), TSSetPreStep(), TSPreStep(), TSPostStep() 3375 @*/ 3376 PetscErrorCode TSPreStage(TS ts, PetscReal stagetime) 3377 { 3378 PetscFunctionBegin; 3379 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3380 if (ts->prestage) { 3381 PetscStackCallStandard((*ts->prestage),(ts,stagetime)); 3382 } 3383 PetscFunctionReturn(0); 3384 } 3385 3386 /*@ 3387 TSPostStage - Runs the user-defined post-stage function set using TSSetPostStage() 3388 3389 Collective on TS 3390 3391 Input Parameters: 3392 . ts - The TS context obtained from TSCreate() 3393 stagetime - The absolute time of the current stage 3394 stageindex - Stage number 3395 Y - Array of vectors (of size = total number 3396 of stages) with the stage solutions 3397 3398 Notes: 3399 TSPostStage() is typically used within time stepping implementations, 3400 most users would not generally call this routine themselves. 3401 3402 Level: developer 3403 3404 .seealso: TSPreStage(), TSSetPreStep(), TSPreStep(), TSPostStep() 3405 @*/ 3406 PetscErrorCode TSPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y) 3407 { 3408 PetscFunctionBegin; 3409 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3410 if (ts->poststage) { 3411 PetscStackCallStandard((*ts->poststage),(ts,stagetime,stageindex,Y)); 3412 } 3413 PetscFunctionReturn(0); 3414 } 3415 3416 /*@ 3417 TSPostEvaluate - Runs the user-defined post-evaluate function set using TSSetPostEvaluate() 3418 3419 Collective on TS 3420 3421 Input Parameters: 3422 . ts - The TS context obtained from TSCreate() 3423 3424 Notes: 3425 TSPostEvaluate() is typically used within time stepping implementations, 3426 most users would not generally call this routine themselves. 3427 3428 Level: developer 3429 3430 .seealso: TSSetPostEvaluate(), TSSetPreStep(), TSPreStep(), TSPostStep() 3431 @*/ 3432 PetscErrorCode TSPostEvaluate(TS ts) 3433 { 3434 PetscErrorCode ierr; 3435 3436 PetscFunctionBegin; 3437 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3438 if (ts->postevaluate) { 3439 Vec U; 3440 PetscObjectState sprev,spost; 3441 3442 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3443 ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr); 3444 PetscStackCallStandard((*ts->postevaluate),(ts)); 3445 ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr); 3446 if (sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);} 3447 } 3448 PetscFunctionReturn(0); 3449 } 3450 3451 /*@C 3452 TSSetPostStep - Sets the general-purpose function 3453 called once at the end of each time step. 3454 3455 Logically Collective on TS 3456 3457 Input Parameters: 3458 + ts - The TS context obtained from TSCreate() 3459 - func - The function 3460 3461 Calling sequence of func: 3462 $ func (TS ts); 3463 3464 Notes: 3465 The function set by TSSetPostStep() is called after each successful step. The solution vector X 3466 obtained by TSGetSolution() may be different than that computed at the step end if the event handler 3467 locates an event and TSPostEvent() modifies it. Use TSSetPostEvaluate() if an unmodified solution is needed instead. 3468 3469 Level: intermediate 3470 3471 .seealso: TSSetPreStep(), TSSetPreStage(), TSSetPostEvaluate(), TSGetTimeStep(), TSGetStepNumber(), TSGetTime(), TSRestartStep() 3472 @*/ 3473 PetscErrorCode TSSetPostStep(TS ts, PetscErrorCode (*func)(TS)) 3474 { 3475 PetscFunctionBegin; 3476 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3477 ts->poststep = func; 3478 PetscFunctionReturn(0); 3479 } 3480 3481 /*@ 3482 TSPostStep - Runs the user-defined post-step function. 3483 3484 Collective on TS 3485 3486 Input Parameters: 3487 . ts - The TS context obtained from TSCreate() 3488 3489 Notes: 3490 TSPostStep() is typically used within time stepping implementations, 3491 so most users would not generally call this routine themselves. 3492 3493 Level: developer 3494 3495 @*/ 3496 PetscErrorCode TSPostStep(TS ts) 3497 { 3498 PetscErrorCode ierr; 3499 3500 PetscFunctionBegin; 3501 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3502 if (ts->poststep) { 3503 Vec U; 3504 PetscObjectState sprev,spost; 3505 3506 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3507 ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr); 3508 PetscStackCallStandard((*ts->poststep),(ts)); 3509 ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr); 3510 if (sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);} 3511 } 3512 PetscFunctionReturn(0); 3513 } 3514 3515 /* ------------ Routines to set performance monitoring options ----------- */ 3516 3517 /*@C 3518 TSMonitorSet - Sets an ADDITIONAL function that is to be used at every 3519 timestep to display the iteration's progress. 3520 3521 Logically Collective on TS 3522 3523 Input Parameters: 3524 + ts - the TS context obtained from TSCreate() 3525 . monitor - monitoring routine 3526 . mctx - [optional] user-defined context for private data for the 3527 monitor routine (use NULL if no context is desired) 3528 - monitordestroy - [optional] routine that frees monitor context 3529 (may be NULL) 3530 3531 Calling sequence of monitor: 3532 $ PetscErrorCode monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx) 3533 3534 + ts - the TS context 3535 . steps - iteration number (after the final time step the monitor routine may be called with a step of -1, this indicates the solution has been interpolated to this time) 3536 . time - current time 3537 . u - current iterate 3538 - mctx - [optional] monitoring context 3539 3540 Notes: 3541 This routine adds an additional monitor to the list of monitors that 3542 already has been loaded. 3543 3544 Fortran Notes: 3545 Only a single monitor function can be set for each TS object 3546 3547 Level: intermediate 3548 3549 .seealso: TSMonitorDefault(), TSMonitorCancel() 3550 @*/ 3551 PetscErrorCode TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**)) 3552 { 3553 PetscErrorCode ierr; 3554 PetscInt i; 3555 PetscBool identical; 3556 3557 PetscFunctionBegin; 3558 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3559 for (i=0; i<ts->numbermonitors;i++) { 3560 ierr = PetscMonitorCompare((PetscErrorCode (*)(void))monitor,mctx,mdestroy,(PetscErrorCode (*)(void))ts->monitor[i],ts->monitorcontext[i],ts->monitordestroy[i],&identical);CHKERRQ(ierr); 3561 if (identical) PetscFunctionReturn(0); 3562 } 3563 if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3564 ts->monitor[ts->numbermonitors] = monitor; 3565 ts->monitordestroy[ts->numbermonitors] = mdestroy; 3566 ts->monitorcontext[ts->numbermonitors++] = (void*)mctx; 3567 PetscFunctionReturn(0); 3568 } 3569 3570 /*@C 3571 TSMonitorCancel - Clears all the monitors that have been set on a time-step object. 3572 3573 Logically Collective on TS 3574 3575 Input Parameters: 3576 . ts - the TS context obtained from TSCreate() 3577 3578 Notes: 3579 There is no way to remove a single, specific monitor. 3580 3581 Level: intermediate 3582 3583 .seealso: TSMonitorDefault(), TSMonitorSet() 3584 @*/ 3585 PetscErrorCode TSMonitorCancel(TS ts) 3586 { 3587 PetscErrorCode ierr; 3588 PetscInt i; 3589 3590 PetscFunctionBegin; 3591 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3592 for (i=0; i<ts->numbermonitors; i++) { 3593 if (ts->monitordestroy[i]) { 3594 ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr); 3595 } 3596 } 3597 ts->numbermonitors = 0; 3598 PetscFunctionReturn(0); 3599 } 3600 3601 /*@C 3602 TSMonitorDefault - The Default monitor, prints the timestep and time for each step 3603 3604 Level: intermediate 3605 3606 .seealso: TSMonitorSet() 3607 @*/ 3608 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf) 3609 { 3610 PetscErrorCode ierr; 3611 PetscViewer viewer = vf->viewer; 3612 PetscBool iascii,ibinary; 3613 3614 PetscFunctionBegin; 3615 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 3616 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 3617 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 3618 ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr); 3619 if (iascii) { 3620 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3621 if (step == -1){ /* this indicates it is an interpolated solution */ 3622 ierr = PetscViewerASCIIPrintf(viewer,"Interpolated solution at time %g between steps %D and %D\n",(double)ptime,ts->steps-1,ts->steps);CHKERRQ(ierr); 3623 } else { 3624 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr); 3625 } 3626 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3627 } else if (ibinary) { 3628 PetscMPIInt rank; 3629 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 3630 if (!rank) { 3631 PetscBool skipHeader; 3632 PetscInt classid = REAL_FILE_CLASSID; 3633 3634 ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr); 3635 if (!skipHeader) { 3636 ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr); 3637 } 3638 ierr = PetscRealView(1,&ptime,viewer);CHKERRQ(ierr); 3639 } else { 3640 ierr = PetscRealView(0,&ptime,viewer);CHKERRQ(ierr); 3641 } 3642 } 3643 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 3644 PetscFunctionReturn(0); 3645 } 3646 3647 /*@C 3648 TSMonitorExtreme - Prints the extreme values of the solution at each timestep 3649 3650 Level: intermediate 3651 3652 .seealso: TSMonitorSet() 3653 @*/ 3654 PetscErrorCode TSMonitorExtreme(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf) 3655 { 3656 PetscErrorCode ierr; 3657 PetscViewer viewer = vf->viewer; 3658 PetscBool iascii; 3659 PetscReal max,min; 3660 3661 3662 PetscFunctionBegin; 3663 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 3664 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 3665 ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr); 3666 if (iascii) { 3667 ierr = VecMax(v,NULL,&max);CHKERRQ(ierr); 3668 ierr = VecMin(v,NULL,&min);CHKERRQ(ierr); 3669 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3670 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s max %g min %g\n",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)" : "",(double)max,(double)min);CHKERRQ(ierr); 3671 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3672 } 3673 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 3674 PetscFunctionReturn(0); 3675 } 3676 3677 /*@ 3678 TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval 3679 3680 Collective on TS 3681 3682 Input Argument: 3683 + ts - time stepping context 3684 - t - time to interpolate to 3685 3686 Output Argument: 3687 . U - state at given time 3688 3689 Level: intermediate 3690 3691 Developer Notes: 3692 TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints. 3693 3694 .seealso: TSSetExactFinalTime(), TSSolve() 3695 @*/ 3696 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U) 3697 { 3698 PetscErrorCode ierr; 3699 3700 PetscFunctionBegin; 3701 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3702 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 3703 if (t < ts->ptime_prev || t > ts->ptime) SETERRQ3(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Requested time %g not in last time steps [%g,%g]",t,(double)ts->ptime_prev,(double)ts->ptime); 3704 if (!ts->ops->interpolate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name); 3705 ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr); 3706 PetscFunctionReturn(0); 3707 } 3708 3709 /*@ 3710 TSStep - Steps one time step 3711 3712 Collective on TS 3713 3714 Input Parameter: 3715 . ts - the TS context obtained from TSCreate() 3716 3717 Level: developer 3718 3719 Notes: 3720 The public interface for the ODE/DAE solvers is TSSolve(), you should almost for sure be using that routine and not this routine. 3721 3722 The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may 3723 be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages. 3724 3725 This may over-step the final time provided in TSSetMaxTime() depending on the time-step used. TSSolve() interpolates to exactly the 3726 time provided in TSSetMaxTime(). One can use TSInterpolate() to determine an interpolated solution within the final timestep. 3727 3728 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSInterpolate() 3729 @*/ 3730 PetscErrorCode TSStep(TS ts) 3731 { 3732 PetscErrorCode ierr; 3733 static PetscBool cite = PETSC_FALSE; 3734 PetscReal ptime; 3735 3736 PetscFunctionBegin; 3737 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3738 ierr = PetscCitationsRegister("@article{tspaper,\n" 3739 " title = {{PETSc/TS}: A Modern Scalable {DAE/ODE} Solver Library},\n" 3740 " author = {Abhyankar, Shrirang and Brown, Jed and Constantinescu, Emil and Ghosh, Debojyoti and Smith, Barry F. and Zhang, Hong},\n" 3741 " journal = {arXiv e-preprints},\n" 3742 " eprint = {1806.01437},\n" 3743 " archivePrefix = {arXiv},\n" 3744 " year = {2018}\n}\n",&cite);CHKERRQ(ierr); 3745 3746 ierr = TSSetUp(ts);CHKERRQ(ierr); 3747 ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr); 3748 3749 if (!ts->ops->step) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSStep not implemented for type '%s'",((PetscObject)ts)->type_name); 3750 if (ts->max_time >= PETSC_MAX_REAL && ts->max_steps == PETSC_MAX_INT) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"You must call TSSetMaxTime() or TSSetMaxSteps(), or use -ts_max_time <time> or -ts_max_steps <steps>"); 3751 if (ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"You must call TSSetExactFinalTime() or use -ts_exact_final_time <stepover,interpolate,matchstep> before calling TSStep()"); 3752 if (ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP && !ts->adapt) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Since TS is not adaptive you cannot use TS_EXACTFINALTIME_MATCHSTEP, suggest TS_EXACTFINALTIME_INTERPOLATE"); 3753 3754 if (!ts->steps) ts->ptime_prev = ts->ptime; 3755 ptime = ts->ptime; ts->ptime_prev_rollback = ts->ptime_prev; 3756 ts->reason = TS_CONVERGED_ITERATING; 3757 3758 ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3759 ierr = (*ts->ops->step)(ts);CHKERRQ(ierr); 3760 ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3761 3762 if (ts->reason >= 0) { 3763 ts->ptime_prev = ptime; 3764 ts->steps++; 3765 ts->steprollback = PETSC_FALSE; 3766 ts->steprestart = PETSC_FALSE; 3767 } 3768 3769 if (!ts->reason) { 3770 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 3771 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 3772 } 3773 3774 if (ts->reason < 0 && ts->errorifstepfailed && ts->reason == TS_DIVERGED_NONLINEAR_SOLVE) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s, increase -ts_max_snes_failures or make negative to attempt recovery",TSConvergedReasons[ts->reason]); 3775 if (ts->reason < 0 && ts->errorifstepfailed) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]); 3776 PetscFunctionReturn(0); 3777 } 3778 3779 /*@ 3780 TSEvaluateWLTE - Evaluate the weighted local truncation error norm 3781 at the end of a time step with a given order of accuracy. 3782 3783 Collective on TS 3784 3785 Input Arguments: 3786 + ts - time stepping context 3787 . wnormtype - norm type, either NORM_2 or NORM_INFINITY 3788 - order - optional, desired order for the error evaluation or PETSC_DECIDE 3789 3790 Output Arguments: 3791 + order - optional, the actual order of the error evaluation 3792 - wlte - the weighted local truncation error norm 3793 3794 Level: advanced 3795 3796 Notes: 3797 If the timestepper cannot evaluate the error in a particular step 3798 (eg. in the first step or restart steps after event handling), 3799 this routine returns wlte=-1.0 . 3800 3801 .seealso: TSStep(), TSAdapt, TSErrorWeightedNorm() 3802 @*/ 3803 PetscErrorCode TSEvaluateWLTE(TS ts,NormType wnormtype,PetscInt *order,PetscReal *wlte) 3804 { 3805 PetscErrorCode ierr; 3806 3807 PetscFunctionBegin; 3808 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3809 PetscValidType(ts,1); 3810 PetscValidLogicalCollectiveEnum(ts,wnormtype,4); 3811 if (order) PetscValidIntPointer(order,3); 3812 if (order) PetscValidLogicalCollectiveInt(ts,*order,3); 3813 PetscValidRealPointer(wlte,4); 3814 if (wnormtype != NORM_2 && wnormtype != NORM_INFINITY) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 3815 if (!ts->ops->evaluatewlte) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateWLTE not implemented for type '%s'",((PetscObject)ts)->type_name); 3816 ierr = (*ts->ops->evaluatewlte)(ts,wnormtype,order,wlte);CHKERRQ(ierr); 3817 PetscFunctionReturn(0); 3818 } 3819 3820 /*@ 3821 TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy. 3822 3823 Collective on TS 3824 3825 Input Arguments: 3826 + ts - time stepping context 3827 . order - desired order of accuracy 3828 - done - whether the step was evaluated at this order (pass NULL to generate an error if not available) 3829 3830 Output Arguments: 3831 . U - state at the end of the current step 3832 3833 Level: advanced 3834 3835 Notes: 3836 This function cannot be called until all stages have been evaluated. 3837 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. 3838 3839 .seealso: TSStep(), TSAdapt 3840 @*/ 3841 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done) 3842 { 3843 PetscErrorCode ierr; 3844 3845 PetscFunctionBegin; 3846 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3847 PetscValidType(ts,1); 3848 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 3849 if (!ts->ops->evaluatestep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name); 3850 ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr); 3851 PetscFunctionReturn(0); 3852 } 3853 3854 /*@C 3855 TSGetComputeInitialCondition - Get the function used to automatically compute an initial condition for the timestepping. 3856 3857 Not collective 3858 3859 Input Argument: 3860 . ts - time stepping context 3861 3862 Output Argument: 3863 . initConditions - The function which computes an initial condition 3864 3865 Level: advanced 3866 3867 Notes: 3868 The calling sequence for the function is 3869 $ initCondition(TS ts, Vec u) 3870 $ ts - The timestepping context 3871 $ u - The input vector in which the initial condition is stored 3872 3873 .seealso: TSSetComputeInitialCondition(), TSComputeInitialCondition() 3874 @*/ 3875 PetscErrorCode TSGetComputeInitialCondition(TS ts, PetscErrorCode (**initCondition)(TS, Vec)) 3876 { 3877 PetscFunctionBegin; 3878 PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 3879 PetscValidPointer(initCondition, 2); 3880 *initCondition = ts->ops->initcondition; 3881 PetscFunctionReturn(0); 3882 } 3883 3884 /*@C 3885 TSSetComputeInitialCondition - Set the function used to automatically compute an initial condition for the timestepping. 3886 3887 Logically collective on ts 3888 3889 Input Arguments: 3890 + ts - time stepping context 3891 - initCondition - The function which computes an initial condition 3892 3893 Level: advanced 3894 3895 Calling sequence for initCondition: 3896 $ PetscErrorCode initCondition(TS ts, Vec u) 3897 3898 + ts - The timestepping context 3899 - u - The input vector in which the initial condition is to be stored 3900 3901 .seealso: TSGetComputeInitialCondition(), TSComputeInitialCondition() 3902 @*/ 3903 PetscErrorCode TSSetComputeInitialCondition(TS ts, PetscErrorCode (*initCondition)(TS, Vec)) 3904 { 3905 PetscFunctionBegin; 3906 PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 3907 PetscValidFunction(initCondition, 2); 3908 ts->ops->initcondition = initCondition; 3909 PetscFunctionReturn(0); 3910 } 3911 3912 /*@ 3913 TSComputeInitialCondition - Compute an initial condition for the timestepping using the function previously set. 3914 3915 Collective on ts 3916 3917 Input Arguments: 3918 + ts - time stepping context 3919 - u - The Vec to store the condition in which will be used in TSSolve() 3920 3921 Level: advanced 3922 3923 .seealso: TSGetComputeInitialCondition(), TSSetComputeInitialCondition(), TSSolve() 3924 @*/ 3925 PetscErrorCode TSComputeInitialCondition(TS ts, Vec u) 3926 { 3927 PetscErrorCode ierr; 3928 3929 PetscFunctionBegin; 3930 PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 3931 PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 3932 if (ts->ops->initcondition) {ierr = (*ts->ops->initcondition)(ts, u);CHKERRQ(ierr);} 3933 PetscFunctionReturn(0); 3934 } 3935 3936 /*@C 3937 TSGetComputeExactError - Get the function used to automatically compute the exact error for the timestepping. 3938 3939 Not collective 3940 3941 Input Argument: 3942 . ts - time stepping context 3943 3944 Output Argument: 3945 . exactError - The function which computes the solution error 3946 3947 Level: advanced 3948 3949 Calling sequence for exactError: 3950 $ PetscErrorCode exactError(TS ts, Vec u) 3951 3952 + ts - The timestepping context 3953 . u - The approximate solution vector 3954 - e - The input vector in which the error is stored 3955 3956 .seealso: TSGetComputeExactError(), TSComputeExactError() 3957 @*/ 3958 PetscErrorCode TSGetComputeExactError(TS ts, PetscErrorCode (**exactError)(TS, Vec, Vec)) 3959 { 3960 PetscFunctionBegin; 3961 PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 3962 PetscValidPointer(exactError, 2); 3963 *exactError = ts->ops->exacterror; 3964 PetscFunctionReturn(0); 3965 } 3966 3967 /*@C 3968 TSSetComputeExactError - Set the function used to automatically compute the exact error for the timestepping. 3969 3970 Logically collective on ts 3971 3972 Input Arguments: 3973 + ts - time stepping context 3974 - exactError - The function which computes the solution error 3975 3976 Level: advanced 3977 3978 Calling sequence for exactError: 3979 $ PetscErrorCode exactError(TS ts, Vec u) 3980 3981 + ts - The timestepping context 3982 . u - The approximate solution vector 3983 - e - The input vector in which the error is stored 3984 3985 .seealso: TSGetComputeExactError(), TSComputeExactError() 3986 @*/ 3987 PetscErrorCode TSSetComputeExactError(TS ts, PetscErrorCode (*exactError)(TS, Vec, Vec)) 3988 { 3989 PetscFunctionBegin; 3990 PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 3991 PetscValidFunction(exactError, 2); 3992 ts->ops->exacterror = exactError; 3993 PetscFunctionReturn(0); 3994 } 3995 3996 /*@ 3997 TSComputeExactError - Compute the solution error for the timestepping using the function previously set. 3998 3999 Collective on ts 4000 4001 Input Arguments: 4002 + ts - time stepping context 4003 . u - The approximate solution 4004 - e - The Vec used to store the error 4005 4006 Level: advanced 4007 4008 .seealso: TSGetComputeInitialCondition(), TSSetComputeInitialCondition(), TSSolve() 4009 @*/ 4010 PetscErrorCode TSComputeExactError(TS ts, Vec u, Vec e) 4011 { 4012 PetscErrorCode ierr; 4013 4014 PetscFunctionBegin; 4015 PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 4016 PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 4017 PetscValidHeaderSpecific(e, VEC_CLASSID, 3); 4018 if (ts->ops->exacterror) {ierr = (*ts->ops->exacterror)(ts, u, e);CHKERRQ(ierr);} 4019 PetscFunctionReturn(0); 4020 } 4021 4022 /*@ 4023 TSSolve - Steps the requested number of timesteps. 4024 4025 Collective on TS 4026 4027 Input Parameter: 4028 + ts - the TS context obtained from TSCreate() 4029 - u - the solution vector (can be null if TSSetSolution() was used and TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP) was not used, 4030 otherwise must contain the initial conditions and will contain the solution at the final requested time 4031 4032 Level: beginner 4033 4034 Notes: 4035 The final time returned by this function may be different from the time of the internally 4036 held state accessible by TSGetSolution() and TSGetTime() because the method may have 4037 stepped over the final time. 4038 4039 .seealso: TSCreate(), TSSetSolution(), TSStep(), TSGetTime(), TSGetSolveTime() 4040 @*/ 4041 PetscErrorCode TSSolve(TS ts,Vec u) 4042 { 4043 Vec solution; 4044 PetscErrorCode ierr; 4045 4046 PetscFunctionBegin; 4047 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4048 if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2); 4049 4050 ierr = TSSetExactFinalTimeDefault(ts);CHKERRQ(ierr); 4051 if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && u) { /* Need ts->vec_sol to be distinct so it is not overwritten when we interpolate at the end */ 4052 if (!ts->vec_sol || u == ts->vec_sol) { 4053 ierr = VecDuplicate(u,&solution);CHKERRQ(ierr); 4054 ierr = TSSetSolution(ts,solution);CHKERRQ(ierr); 4055 ierr = VecDestroy(&solution);CHKERRQ(ierr); /* grant ownership */ 4056 } 4057 ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr); 4058 if (ts->forward_solve) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Sensitivity analysis does not support the mode TS_EXACTFINALTIME_INTERPOLATE"); 4059 } else if (u) { 4060 ierr = TSSetSolution(ts,u);CHKERRQ(ierr); 4061 } 4062 ierr = TSSetUp(ts);CHKERRQ(ierr); 4063 ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr); 4064 4065 if (ts->max_time >= PETSC_MAX_REAL && ts->max_steps == PETSC_MAX_INT) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"You must call TSSetMaxTime() or TSSetMaxSteps(), or use -ts_max_time <time> or -ts_max_steps <steps>"); 4066 if (ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"You must call TSSetExactFinalTime() or use -ts_exact_final_time <stepover,interpolate,matchstep> before calling TSSolve()"); 4067 if (ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP && !ts->adapt) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Since TS is not adaptive you cannot use TS_EXACTFINALTIME_MATCHSTEP, suggest TS_EXACTFINALTIME_INTERPOLATE"); 4068 4069 if (ts->forward_solve) { 4070 ierr = TSForwardSetUp(ts);CHKERRQ(ierr); 4071 } 4072 4073 /* reset number of steps only when the step is not restarted. ARKIMEX 4074 restarts the step after an event. Resetting these counters in such case causes 4075 TSTrajectory to incorrectly save the output files 4076 */ 4077 /* reset time step and iteration counters */ 4078 if (!ts->steps) { 4079 ts->ksp_its = 0; 4080 ts->snes_its = 0; 4081 ts->num_snes_failures = 0; 4082 ts->reject = 0; 4083 ts->steprestart = PETSC_TRUE; 4084 ts->steprollback = PETSC_FALSE; 4085 ts->rhsjacobian.time = PETSC_MIN_REAL; 4086 } 4087 4088 /* make sure initial time step does not overshoot final time */ 4089 if (ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP) { 4090 PetscReal maxdt = ts->max_time-ts->ptime; 4091 PetscReal dt = ts->time_step; 4092 4093 ts->time_step = dt >= maxdt ? maxdt : (PetscIsCloseAtTol(dt,maxdt,10*PETSC_MACHINE_EPSILON,0) ? maxdt : dt); 4094 } 4095 ts->reason = TS_CONVERGED_ITERATING; 4096 4097 { 4098 PetscViewer viewer; 4099 PetscViewerFormat format; 4100 PetscBool flg; 4101 static PetscBool incall = PETSC_FALSE; 4102 4103 if (!incall) { 4104 /* Estimate the convergence rate of the time discretization */ 4105 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) ts),((PetscObject)ts)->options, ((PetscObject) ts)->prefix, "-ts_convergence_estimate", &viewer, &format, &flg);CHKERRQ(ierr); 4106 if (flg) { 4107 PetscConvEst conv; 4108 DM dm; 4109 PetscReal *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */ 4110 PetscInt Nf; 4111 PetscBool checkTemporal = PETSC_TRUE; 4112 4113 incall = PETSC_TRUE; 4114 ierr = PetscOptionsGetBool(((PetscObject)ts)->options, ((PetscObject) ts)->prefix, "-ts_convergence_temporal", &checkTemporal, &flg);CHKERRQ(ierr); 4115 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 4116 ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 4117 ierr = PetscCalloc1(PetscMax(Nf, 1), &alpha);CHKERRQ(ierr); 4118 ierr = PetscConvEstCreate(PetscObjectComm((PetscObject) ts), &conv);CHKERRQ(ierr); 4119 ierr = PetscConvEstUseTS(conv, checkTemporal);CHKERRQ(ierr); 4120 ierr = PetscConvEstSetSolver(conv, (PetscObject) ts);CHKERRQ(ierr); 4121 ierr = PetscConvEstSetFromOptions(conv);CHKERRQ(ierr); 4122 ierr = PetscConvEstSetUp(conv);CHKERRQ(ierr); 4123 ierr = PetscConvEstGetConvRate(conv, alpha);CHKERRQ(ierr); 4124 ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr); 4125 ierr = PetscConvEstRateView(conv, alpha, viewer);CHKERRQ(ierr); 4126 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 4127 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4128 ierr = PetscConvEstDestroy(&conv);CHKERRQ(ierr); 4129 ierr = PetscFree(alpha);CHKERRQ(ierr); 4130 incall = PETSC_FALSE; 4131 } 4132 } 4133 } 4134 4135 ierr = TSViewFromOptions(ts,NULL,"-ts_view_pre");CHKERRQ(ierr); 4136 4137 if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */ 4138 ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr); 4139 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 4140 ts->solvetime = ts->ptime; 4141 solution = ts->vec_sol; 4142 } else { /* Step the requested number of timesteps. */ 4143 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 4144 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 4145 4146 if (!ts->steps) { 4147 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4148 ierr = TSEventInitialize(ts->event,ts,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4149 } 4150 4151 while (!ts->reason) { 4152 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4153 if (!ts->steprollback) { 4154 ierr = TSPreStep(ts);CHKERRQ(ierr); 4155 } 4156 ierr = TSStep(ts);CHKERRQ(ierr); 4157 if (ts->testjacobian) { 4158 ierr = TSRHSJacobianTest(ts,NULL);CHKERRQ(ierr); 4159 } 4160 if (ts->testjacobiantranspose) { 4161 ierr = TSRHSJacobianTestTranspose(ts,NULL);CHKERRQ(ierr); 4162 } 4163 if (ts->quadraturets && ts->costintegralfwd) { /* Must evaluate the cost integral before event is handled. The cost integral value can also be rolled back. */ 4164 if (ts->reason >= 0) ts->steps--; /* Revert the step number changed by TSStep() */ 4165 ierr = TSForwardCostIntegral(ts);CHKERRQ(ierr); 4166 if (ts->reason >= 0) ts->steps++; 4167 } 4168 if (ts->forward_solve) { /* compute forward sensitivities before event handling because postevent() may change RHS and jump conditions may have to be applied */ 4169 if (ts->reason >= 0) ts->steps--; /* Revert the step number changed by TSStep() */ 4170 ierr = TSForwardStep(ts);CHKERRQ(ierr); 4171 if (ts->reason >= 0) ts->steps++; 4172 } 4173 ierr = TSPostEvaluate(ts);CHKERRQ(ierr); 4174 ierr = TSEventHandler(ts);CHKERRQ(ierr); /* The right-hand side may be changed due to event. Be careful with Any computation using the RHS information after this point. */ 4175 if (ts->steprollback) { 4176 ierr = TSPostEvaluate(ts);CHKERRQ(ierr); 4177 } 4178 if (!ts->steprollback) { 4179 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4180 ierr = TSPostStep(ts);CHKERRQ(ierr); 4181 } 4182 } 4183 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4184 4185 if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) { 4186 ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr); 4187 ts->solvetime = ts->max_time; 4188 solution = u; 4189 ierr = TSMonitor(ts,-1,ts->solvetime,solution);CHKERRQ(ierr); 4190 } else { 4191 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 4192 ts->solvetime = ts->ptime; 4193 solution = ts->vec_sol; 4194 } 4195 } 4196 4197 ierr = TSViewFromOptions(ts,NULL,"-ts_view");CHKERRQ(ierr); 4198 ierr = VecViewFromOptions(solution,NULL,"-ts_view_solution");CHKERRQ(ierr); 4199 ierr = PetscObjectSAWsBlock((PetscObject)ts);CHKERRQ(ierr); 4200 if (ts->adjoint_solve) { 4201 ierr = TSAdjointSolve(ts);CHKERRQ(ierr); 4202 } 4203 PetscFunctionReturn(0); 4204 } 4205 4206 /*@C 4207 TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet() 4208 4209 Collective on TS 4210 4211 Input Parameters: 4212 + ts - time stepping context obtained from TSCreate() 4213 . step - step number that has just completed 4214 . ptime - model time of the state 4215 - u - state at the current model time 4216 4217 Notes: 4218 TSMonitor() is typically used automatically within the time stepping implementations. 4219 Users would almost never call this routine directly. 4220 4221 A step of -1 indicates that the monitor is being called on a solution obtained by interpolating from computed solutions 4222 4223 Level: developer 4224 4225 @*/ 4226 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u) 4227 { 4228 DM dm; 4229 PetscInt i,n = ts->numbermonitors; 4230 PetscErrorCode ierr; 4231 4232 PetscFunctionBegin; 4233 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4234 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 4235 4236 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4237 ierr = DMSetOutputSequenceNumber(dm,step,ptime);CHKERRQ(ierr); 4238 4239 ierr = VecLockReadPush(u);CHKERRQ(ierr); 4240 for (i=0; i<n; i++) { 4241 ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr); 4242 } 4243 ierr = VecLockReadPop(u);CHKERRQ(ierr); 4244 PetscFunctionReturn(0); 4245 } 4246 4247 /* ------------------------------------------------------------------------*/ 4248 /*@C 4249 TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with 4250 TS to monitor the solution process graphically in various ways 4251 4252 Collective on TS 4253 4254 Input Parameters: 4255 + host - the X display to open, or null for the local machine 4256 . label - the title to put in the title bar 4257 . x, y - the screen coordinates of the upper left coordinate of the window 4258 . m, n - the screen width and height in pixels 4259 - howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time 4260 4261 Output Parameter: 4262 . ctx - the context 4263 4264 Options Database Key: 4265 + -ts_monitor_lg_timestep - automatically sets line graph monitor 4266 + -ts_monitor_lg_timestep_log - automatically sets line graph monitor 4267 . -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables()) 4268 . -ts_monitor_lg_error - monitor the error 4269 . -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep 4270 . -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep 4271 - -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true 4272 4273 Notes: 4274 Use TSMonitorLGCtxDestroy() to destroy. 4275 4276 One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform() 4277 4278 Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a TS object as the 4279 first argument (if that TS object does not have a TSMonitorLGCtx associated with it the function call is ignored) and the second takes a TSMonitorLGCtx object 4280 as the first argument. 4281 4282 One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames() 4283 4284 Level: intermediate 4285 4286 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError(), TSMonitorDefault(), VecView(), 4287 TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(), 4288 TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(), 4289 TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(), 4290 TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop() 4291 4292 @*/ 4293 PetscErrorCode TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx) 4294 { 4295 PetscDraw draw; 4296 PetscErrorCode ierr; 4297 4298 PetscFunctionBegin; 4299 ierr = PetscNew(ctx);CHKERRQ(ierr); 4300 ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr); 4301 ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr); 4302 ierr = PetscDrawLGCreate(draw,1,&(*ctx)->lg);CHKERRQ(ierr); 4303 ierr = PetscDrawLGSetFromOptions((*ctx)->lg);CHKERRQ(ierr); 4304 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 4305 (*ctx)->howoften = howoften; 4306 PetscFunctionReturn(0); 4307 } 4308 4309 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx) 4310 { 4311 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 4312 PetscReal x = ptime,y; 4313 PetscErrorCode ierr; 4314 4315 PetscFunctionBegin; 4316 if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */ 4317 if (!step) { 4318 PetscDrawAxis axis; 4319 const char *ylabel = ctx->semilogy ? "Log Time Step" : "Time Step"; 4320 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 4321 ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time",ylabel);CHKERRQ(ierr); 4322 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 4323 } 4324 ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr); 4325 if (ctx->semilogy) y = PetscLog10Real(y); 4326 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 4327 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 4328 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 4329 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 4330 } 4331 PetscFunctionReturn(0); 4332 } 4333 4334 /*@C 4335 TSMonitorLGCtxDestroy - Destroys a line graph context that was created 4336 with TSMonitorLGCtxCreate(). 4337 4338 Collective on TSMonitorLGCtx 4339 4340 Input Parameter: 4341 . ctx - the monitor context 4342 4343 Level: intermediate 4344 4345 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep(); 4346 @*/ 4347 PetscErrorCode TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx) 4348 { 4349 PetscErrorCode ierr; 4350 4351 PetscFunctionBegin; 4352 if ((*ctx)->transformdestroy) { 4353 ierr = ((*ctx)->transformdestroy)((*ctx)->transformctx);CHKERRQ(ierr); 4354 } 4355 ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr); 4356 ierr = PetscStrArrayDestroy(&(*ctx)->names);CHKERRQ(ierr); 4357 ierr = PetscStrArrayDestroy(&(*ctx)->displaynames);CHKERRQ(ierr); 4358 ierr = PetscFree((*ctx)->displayvariables);CHKERRQ(ierr); 4359 ierr = PetscFree((*ctx)->displayvalues);CHKERRQ(ierr); 4360 ierr = PetscFree(*ctx);CHKERRQ(ierr); 4361 PetscFunctionReturn(0); 4362 } 4363 4364 /* 4365 4366 Creates a TS Monitor SPCtx for use with DM Swarm particle visualizations 4367 4368 */ 4369 PetscErrorCode TSMonitorSPCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorSPCtx *ctx) 4370 { 4371 PetscDraw draw; 4372 PetscErrorCode ierr; 4373 4374 PetscFunctionBegin; 4375 ierr = PetscNew(ctx);CHKERRQ(ierr); 4376 ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr); 4377 ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr); 4378 ierr = PetscDrawSPCreate(draw,1,&(*ctx)->sp);CHKERRQ(ierr); 4379 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 4380 (*ctx)->howoften = howoften; 4381 PetscFunctionReturn(0); 4382 4383 } 4384 4385 /* 4386 Destroys a TSMonitorSPCtx that was created with TSMonitorSPCtxCreate 4387 */ 4388 PetscErrorCode TSMonitorSPCtxDestroy(TSMonitorSPCtx *ctx) 4389 { 4390 PetscErrorCode ierr; 4391 4392 PetscFunctionBegin; 4393 4394 ierr = PetscDrawSPDestroy(&(*ctx)->sp);CHKERRQ(ierr); 4395 ierr = PetscFree(*ctx);CHKERRQ(ierr); 4396 4397 PetscFunctionReturn(0); 4398 4399 } 4400 4401 /*@ 4402 TSGetTime - Gets the time of the most recently completed step. 4403 4404 Not Collective 4405 4406 Input Parameter: 4407 . ts - the TS context obtained from TSCreate() 4408 4409 Output Parameter: 4410 . t - the current time. This time may not corresponds to the final time set with TSSetMaxTime(), use TSGetSolveTime(). 4411 4412 Level: beginner 4413 4414 Note: 4415 When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(), 4416 TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated. 4417 4418 .seealso: TSGetSolveTime(), TSSetTime(), TSGetTimeStep(), TSGetStepNumber() 4419 4420 @*/ 4421 PetscErrorCode TSGetTime(TS ts,PetscReal *t) 4422 { 4423 PetscFunctionBegin; 4424 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4425 PetscValidRealPointer(t,2); 4426 *t = ts->ptime; 4427 PetscFunctionReturn(0); 4428 } 4429 4430 /*@ 4431 TSGetPrevTime - Gets the starting time of the previously completed step. 4432 4433 Not Collective 4434 4435 Input Parameter: 4436 . ts - the TS context obtained from TSCreate() 4437 4438 Output Parameter: 4439 . t - the previous time 4440 4441 Level: beginner 4442 4443 .seealso: TSGetTime(), TSGetSolveTime(), TSGetTimeStep() 4444 4445 @*/ 4446 PetscErrorCode TSGetPrevTime(TS ts,PetscReal *t) 4447 { 4448 PetscFunctionBegin; 4449 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4450 PetscValidRealPointer(t,2); 4451 *t = ts->ptime_prev; 4452 PetscFunctionReturn(0); 4453 } 4454 4455 /*@ 4456 TSSetTime - Allows one to reset the time. 4457 4458 Logically Collective on TS 4459 4460 Input Parameters: 4461 + ts - the TS context obtained from TSCreate() 4462 - time - the time 4463 4464 Level: intermediate 4465 4466 .seealso: TSGetTime(), TSSetMaxSteps() 4467 4468 @*/ 4469 PetscErrorCode TSSetTime(TS ts, PetscReal t) 4470 { 4471 PetscFunctionBegin; 4472 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4473 PetscValidLogicalCollectiveReal(ts,t,2); 4474 ts->ptime = t; 4475 PetscFunctionReturn(0); 4476 } 4477 4478 /*@C 4479 TSSetOptionsPrefix - Sets the prefix used for searching for all 4480 TS options in the database. 4481 4482 Logically Collective on TS 4483 4484 Input Parameter: 4485 + ts - The TS context 4486 - prefix - The prefix to prepend to all option names 4487 4488 Notes: 4489 A hyphen (-) must NOT be given at the beginning of the prefix name. 4490 The first character of all runtime options is AUTOMATICALLY the 4491 hyphen. 4492 4493 Level: advanced 4494 4495 .seealso: TSSetFromOptions() 4496 4497 @*/ 4498 PetscErrorCode TSSetOptionsPrefix(TS ts,const char prefix[]) 4499 { 4500 PetscErrorCode ierr; 4501 SNES snes; 4502 4503 PetscFunctionBegin; 4504 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4505 ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4506 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4507 ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4508 PetscFunctionReturn(0); 4509 } 4510 4511 /*@C 4512 TSAppendOptionsPrefix - Appends to the prefix used for searching for all 4513 TS options in the database. 4514 4515 Logically Collective on TS 4516 4517 Input Parameter: 4518 + ts - The TS context 4519 - prefix - The prefix to prepend to all option names 4520 4521 Notes: 4522 A hyphen (-) must NOT be given at the beginning of the prefix name. 4523 The first character of all runtime options is AUTOMATICALLY the 4524 hyphen. 4525 4526 Level: advanced 4527 4528 .seealso: TSGetOptionsPrefix() 4529 4530 @*/ 4531 PetscErrorCode TSAppendOptionsPrefix(TS ts,const char prefix[]) 4532 { 4533 PetscErrorCode ierr; 4534 SNES snes; 4535 4536 PetscFunctionBegin; 4537 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4538 ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4539 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4540 ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4541 PetscFunctionReturn(0); 4542 } 4543 4544 /*@C 4545 TSGetOptionsPrefix - Sets the prefix used for searching for all 4546 TS options in the database. 4547 4548 Not Collective 4549 4550 Input Parameter: 4551 . ts - The TS context 4552 4553 Output Parameter: 4554 . prefix - A pointer to the prefix string used 4555 4556 Notes: 4557 On the fortran side, the user should pass in a string 'prifix' of 4558 sufficient length to hold the prefix. 4559 4560 Level: intermediate 4561 4562 .seealso: TSAppendOptionsPrefix() 4563 @*/ 4564 PetscErrorCode TSGetOptionsPrefix(TS ts,const char *prefix[]) 4565 { 4566 PetscErrorCode ierr; 4567 4568 PetscFunctionBegin; 4569 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4570 PetscValidPointer(prefix,2); 4571 ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4572 PetscFunctionReturn(0); 4573 } 4574 4575 /*@C 4576 TSGetRHSJacobian - Returns the Jacobian J at the present timestep. 4577 4578 Not Collective, but parallel objects are returned if TS is parallel 4579 4580 Input Parameter: 4581 . ts - The TS context obtained from TSCreate() 4582 4583 Output Parameters: 4584 + Amat - The (approximate) Jacobian J of G, where U_t = G(U,t) (or NULL) 4585 . Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat (or NULL) 4586 . func - Function to compute the Jacobian of the RHS (or NULL) 4587 - ctx - User-defined context for Jacobian evaluation routine (or NULL) 4588 4589 Notes: 4590 You can pass in NULL for any return argument you do not need. 4591 4592 Level: intermediate 4593 4594 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetStepNumber() 4595 4596 @*/ 4597 PetscErrorCode TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx) 4598 { 4599 PetscErrorCode ierr; 4600 DM dm; 4601 4602 PetscFunctionBegin; 4603 if (Amat || Pmat) { 4604 SNES snes; 4605 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4606 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4607 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4608 } 4609 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4610 ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr); 4611 PetscFunctionReturn(0); 4612 } 4613 4614 /*@C 4615 TSGetIJacobian - Returns the implicit Jacobian at the present timestep. 4616 4617 Not Collective, but parallel objects are returned if TS is parallel 4618 4619 Input Parameter: 4620 . ts - The TS context obtained from TSCreate() 4621 4622 Output Parameters: 4623 + Amat - The (approximate) Jacobian of F(t,U,U_t) 4624 . Pmat - The matrix from which the preconditioner is constructed, often the same as Amat 4625 . f - The function to compute the matrices 4626 - ctx - User-defined context for Jacobian evaluation routine 4627 4628 Notes: 4629 You can pass in NULL for any return argument you do not need. 4630 4631 Level: advanced 4632 4633 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetStepNumber() 4634 4635 @*/ 4636 PetscErrorCode TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx) 4637 { 4638 PetscErrorCode ierr; 4639 DM dm; 4640 4641 PetscFunctionBegin; 4642 if (Amat || Pmat) { 4643 SNES snes; 4644 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4645 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4646 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4647 } 4648 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4649 ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr); 4650 PetscFunctionReturn(0); 4651 } 4652 4653 /*@C 4654 TSMonitorDrawSolution - Monitors progress of the TS solvers by calling 4655 VecView() for the solution at each timestep 4656 4657 Collective on TS 4658 4659 Input Parameters: 4660 + ts - the TS context 4661 . step - current time-step 4662 . ptime - current time 4663 - dummy - either a viewer or NULL 4664 4665 Options Database: 4666 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 4667 4668 Notes: 4669 the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial 4670 will look bad 4671 4672 Level: intermediate 4673 4674 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4675 @*/ 4676 PetscErrorCode TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4677 { 4678 PetscErrorCode ierr; 4679 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 4680 PetscDraw draw; 4681 4682 PetscFunctionBegin; 4683 if (!step && ictx->showinitial) { 4684 if (!ictx->initialsolution) { 4685 ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr); 4686 } 4687 ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr); 4688 } 4689 if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4690 4691 if (ictx->showinitial) { 4692 PetscReal pause; 4693 ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr); 4694 ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr); 4695 ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr); 4696 ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr); 4697 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr); 4698 } 4699 ierr = VecView(u,ictx->viewer);CHKERRQ(ierr); 4700 if (ictx->showtimestepandtime) { 4701 PetscReal xl,yl,xr,yr,h; 4702 char time[32]; 4703 4704 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 4705 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 4706 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 4707 h = yl + .95*(yr - yl); 4708 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 4709 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 4710 } 4711 4712 if (ictx->showinitial) { 4713 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr); 4714 } 4715 PetscFunctionReturn(0); 4716 } 4717 4718 /*@C 4719 TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram 4720 4721 Collective on TS 4722 4723 Input Parameters: 4724 + ts - the TS context 4725 . step - current time-step 4726 . ptime - current time 4727 - dummy - either a viewer or NULL 4728 4729 Level: intermediate 4730 4731 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4732 @*/ 4733 PetscErrorCode TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4734 { 4735 PetscErrorCode ierr; 4736 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 4737 PetscDraw draw; 4738 PetscDrawAxis axis; 4739 PetscInt n; 4740 PetscMPIInt size; 4741 PetscReal U0,U1,xl,yl,xr,yr,h; 4742 char time[32]; 4743 const PetscScalar *U; 4744 4745 PetscFunctionBegin; 4746 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size);CHKERRQ(ierr); 4747 if (size != 1) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs"); 4748 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 4749 if (n != 2) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns"); 4750 4751 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 4752 ierr = PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis);CHKERRQ(ierr); 4753 ierr = PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr); 4754 if (!step) { 4755 ierr = PetscDrawClear(draw);CHKERRQ(ierr); 4756 ierr = PetscDrawAxisDraw(axis);CHKERRQ(ierr); 4757 } 4758 4759 ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr); 4760 U0 = PetscRealPart(U[0]); 4761 U1 = PetscRealPart(U[1]); 4762 ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr); 4763 if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0); 4764 4765 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 4766 ierr = PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK);CHKERRQ(ierr); 4767 if (ictx->showtimestepandtime) { 4768 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 4769 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 4770 h = yl + .95*(yr - yl); 4771 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 4772 } 4773 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 4774 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 4775 ierr = PetscDrawPause(draw);CHKERRQ(ierr); 4776 ierr = PetscDrawSave(draw);CHKERRQ(ierr); 4777 PetscFunctionReturn(0); 4778 } 4779 4780 /*@C 4781 TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution() 4782 4783 Collective on TS 4784 4785 Input Parameters: 4786 . ctx - the monitor context 4787 4788 Level: intermediate 4789 4790 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError() 4791 @*/ 4792 PetscErrorCode TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx) 4793 { 4794 PetscErrorCode ierr; 4795 4796 PetscFunctionBegin; 4797 ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr); 4798 ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr); 4799 ierr = PetscFree(*ictx);CHKERRQ(ierr); 4800 PetscFunctionReturn(0); 4801 } 4802 4803 /*@C 4804 TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx 4805 4806 Collective on TS 4807 4808 Input Parameter: 4809 . ts - time-step context 4810 4811 Output Patameter: 4812 . ctx - the monitor context 4813 4814 Options Database: 4815 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 4816 4817 Level: intermediate 4818 4819 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx() 4820 @*/ 4821 PetscErrorCode TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx) 4822 { 4823 PetscErrorCode ierr; 4824 4825 PetscFunctionBegin; 4826 ierr = PetscNew(ctx);CHKERRQ(ierr); 4827 ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr); 4828 ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr); 4829 4830 (*ctx)->howoften = howoften; 4831 (*ctx)->showinitial = PETSC_FALSE; 4832 ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr); 4833 4834 (*ctx)->showtimestepandtime = PETSC_FALSE; 4835 ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr); 4836 PetscFunctionReturn(0); 4837 } 4838 4839 /*@C 4840 TSMonitorDrawSolutionFunction - Monitors progress of the TS solvers by calling 4841 VecView() for the solution provided by TSSetSolutionFunction() at each timestep 4842 4843 Collective on TS 4844 4845 Input Parameters: 4846 + ts - the TS context 4847 . step - current time-step 4848 . ptime - current time 4849 - dummy - either a viewer or NULL 4850 4851 Options Database: 4852 . -ts_monitor_draw_solution_function - Monitor error graphically, requires user to have provided TSSetSolutionFunction() 4853 4854 Level: intermediate 4855 4856 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 4857 @*/ 4858 PetscErrorCode TSMonitorDrawSolutionFunction(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4859 { 4860 PetscErrorCode ierr; 4861 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 4862 PetscViewer viewer = ctx->viewer; 4863 Vec work; 4864 4865 PetscFunctionBegin; 4866 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4867 ierr = VecDuplicate(u,&work);CHKERRQ(ierr); 4868 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 4869 ierr = VecView(work,viewer);CHKERRQ(ierr); 4870 ierr = VecDestroy(&work);CHKERRQ(ierr); 4871 PetscFunctionReturn(0); 4872 } 4873 4874 /*@C 4875 TSMonitorDrawError - Monitors progress of the TS solvers by calling 4876 VecView() for the error at each timestep 4877 4878 Collective on TS 4879 4880 Input Parameters: 4881 + ts - the TS context 4882 . step - current time-step 4883 . ptime - current time 4884 - dummy - either a viewer or NULL 4885 4886 Options Database: 4887 . -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction() 4888 4889 Level: intermediate 4890 4891 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 4892 @*/ 4893 PetscErrorCode TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4894 { 4895 PetscErrorCode ierr; 4896 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 4897 PetscViewer viewer = ctx->viewer; 4898 Vec work; 4899 4900 PetscFunctionBegin; 4901 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4902 ierr = VecDuplicate(u,&work);CHKERRQ(ierr); 4903 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 4904 ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr); 4905 ierr = VecView(work,viewer);CHKERRQ(ierr); 4906 ierr = VecDestroy(&work);CHKERRQ(ierr); 4907 PetscFunctionReturn(0); 4908 } 4909 4910 #include <petsc/private/dmimpl.h> 4911 /*@ 4912 TSSetDM - Sets the DM that may be used by some nonlinear solvers or preconditioners under the TS 4913 4914 Logically Collective on ts 4915 4916 Input Parameters: 4917 + ts - the ODE integrator object 4918 - dm - the dm, cannot be NULL 4919 4920 Notes: 4921 A DM can only be used for solving one problem at a time because information about the problem is stored on the DM, 4922 even when not using interfaces like DMTSSetIFunction(). Use DMClone() to get a distinct DM when solving 4923 different problems using the same function space. 4924 4925 Level: intermediate 4926 4927 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM() 4928 @*/ 4929 PetscErrorCode TSSetDM(TS ts,DM dm) 4930 { 4931 PetscErrorCode ierr; 4932 SNES snes; 4933 DMTS tsdm; 4934 4935 PetscFunctionBegin; 4936 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4937 PetscValidHeaderSpecific(dm,DM_CLASSID,2); 4938 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 4939 if (ts->dm) { /* Move the DMTS context over to the new DM unless the new DM already has one */ 4940 if (ts->dm->dmts && !dm->dmts) { 4941 ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr); 4942 ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr); 4943 if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */ 4944 tsdm->originaldm = dm; 4945 } 4946 } 4947 ierr = DMDestroy(&ts->dm);CHKERRQ(ierr); 4948 } 4949 ts->dm = dm; 4950 4951 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4952 ierr = SNESSetDM(snes,dm);CHKERRQ(ierr); 4953 PetscFunctionReturn(0); 4954 } 4955 4956 /*@ 4957 TSGetDM - Gets the DM that may be used by some preconditioners 4958 4959 Not Collective 4960 4961 Input Parameter: 4962 . ts - the preconditioner context 4963 4964 Output Parameter: 4965 . dm - the dm 4966 4967 Level: intermediate 4968 4969 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM() 4970 @*/ 4971 PetscErrorCode TSGetDM(TS ts,DM *dm) 4972 { 4973 PetscErrorCode ierr; 4974 4975 PetscFunctionBegin; 4976 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4977 if (!ts->dm) { 4978 ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr); 4979 if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 4980 } 4981 *dm = ts->dm; 4982 PetscFunctionReturn(0); 4983 } 4984 4985 /*@ 4986 SNESTSFormFunction - Function to evaluate nonlinear residual 4987 4988 Logically Collective on SNES 4989 4990 Input Parameter: 4991 + snes - nonlinear solver 4992 . U - the current state at which to evaluate the residual 4993 - ctx - user context, must be a TS 4994 4995 Output Parameter: 4996 . F - the nonlinear residual 4997 4998 Notes: 4999 This function is not normally called by users and is automatically registered with the SNES used by TS. 5000 It is most frequently passed to MatFDColoringSetFunction(). 5001 5002 Level: advanced 5003 5004 .seealso: SNESSetFunction(), MatFDColoringSetFunction() 5005 @*/ 5006 PetscErrorCode SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx) 5007 { 5008 TS ts = (TS)ctx; 5009 PetscErrorCode ierr; 5010 5011 PetscFunctionBegin; 5012 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5013 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5014 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 5015 PetscValidHeaderSpecific(ts,TS_CLASSID,4); 5016 ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr); 5017 PetscFunctionReturn(0); 5018 } 5019 5020 /*@ 5021 SNESTSFormJacobian - Function to evaluate the Jacobian 5022 5023 Collective on SNES 5024 5025 Input Parameter: 5026 + snes - nonlinear solver 5027 . U - the current state at which to evaluate the residual 5028 - ctx - user context, must be a TS 5029 5030 Output Parameter: 5031 + A - the Jacobian 5032 . B - the preconditioning matrix (may be the same as A) 5033 - flag - indicates any structure change in the matrix 5034 5035 Notes: 5036 This function is not normally called by users and is automatically registered with the SNES used by TS. 5037 5038 Level: developer 5039 5040 .seealso: SNESSetJacobian() 5041 @*/ 5042 PetscErrorCode SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx) 5043 { 5044 TS ts = (TS)ctx; 5045 PetscErrorCode ierr; 5046 5047 PetscFunctionBegin; 5048 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5049 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5050 PetscValidPointer(A,3); 5051 PetscValidHeaderSpecific(A,MAT_CLASSID,3); 5052 PetscValidPointer(B,4); 5053 PetscValidHeaderSpecific(B,MAT_CLASSID,4); 5054 PetscValidHeaderSpecific(ts,TS_CLASSID,6); 5055 ierr = (ts->ops->snesjacobian)(snes,U,A,B,ts);CHKERRQ(ierr); 5056 PetscFunctionReturn(0); 5057 } 5058 5059 /*@C 5060 TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems Udot = A U only 5061 5062 Collective on TS 5063 5064 Input Arguments: 5065 + ts - time stepping context 5066 . t - time at which to evaluate 5067 . U - state at which to evaluate 5068 - ctx - context 5069 5070 Output Arguments: 5071 . F - right hand side 5072 5073 Level: intermediate 5074 5075 Notes: 5076 This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems. 5077 The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian(). 5078 5079 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 5080 @*/ 5081 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx) 5082 { 5083 PetscErrorCode ierr; 5084 Mat Arhs,Brhs; 5085 5086 PetscFunctionBegin; 5087 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 5088 /* undo the damage caused by shifting */ 5089 ierr = TSRecoverRHSJacobian(ts,Arhs,Brhs);CHKERRQ(ierr); 5090 ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr); 5091 ierr = MatMult(Arhs,U,F);CHKERRQ(ierr); 5092 PetscFunctionReturn(0); 5093 } 5094 5095 /*@C 5096 TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent. 5097 5098 Collective on TS 5099 5100 Input Arguments: 5101 + ts - time stepping context 5102 . t - time at which to evaluate 5103 . U - state at which to evaluate 5104 - ctx - context 5105 5106 Output Arguments: 5107 + A - pointer to operator 5108 . B - pointer to preconditioning matrix 5109 - flg - matrix structure flag 5110 5111 Level: intermediate 5112 5113 Notes: 5114 This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems. 5115 5116 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear() 5117 @*/ 5118 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx) 5119 { 5120 PetscFunctionBegin; 5121 PetscFunctionReturn(0); 5122 } 5123 5124 /*@C 5125 TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only 5126 5127 Collective on TS 5128 5129 Input Arguments: 5130 + ts - time stepping context 5131 . t - time at which to evaluate 5132 . U - state at which to evaluate 5133 . Udot - time derivative of state vector 5134 - ctx - context 5135 5136 Output Arguments: 5137 . F - left hand side 5138 5139 Level: intermediate 5140 5141 Notes: 5142 The assumption here is that the left hand side is of the form A*Udot (and not A*Udot + B*U). For other cases, the 5143 user is required to write their own TSComputeIFunction. 5144 This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems. 5145 The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian(). 5146 5147 Note that using this function is NOT equivalent to using TSComputeRHSFunctionLinear() since that solves Udot = A U 5148 5149 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant(), TSComputeRHSFunctionLinear() 5150 @*/ 5151 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx) 5152 { 5153 PetscErrorCode ierr; 5154 Mat A,B; 5155 5156 PetscFunctionBegin; 5157 ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr); 5158 ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE);CHKERRQ(ierr); 5159 ierr = MatMult(A,Udot,F);CHKERRQ(ierr); 5160 PetscFunctionReturn(0); 5161 } 5162 5163 /*@C 5164 TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE 5165 5166 Collective on TS 5167 5168 Input Arguments: 5169 + ts - time stepping context 5170 . t - time at which to evaluate 5171 . U - state at which to evaluate 5172 . Udot - time derivative of state vector 5173 . shift - shift to apply 5174 - ctx - context 5175 5176 Output Arguments: 5177 + A - pointer to operator 5178 . B - pointer to preconditioning matrix 5179 - flg - matrix structure flag 5180 5181 Level: advanced 5182 5183 Notes: 5184 This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems. 5185 5186 It is only appropriate for problems of the form 5187 5188 $ M Udot = F(U,t) 5189 5190 where M is constant and F is non-stiff. The user must pass M to TSSetIJacobian(). The current implementation only 5191 works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing 5192 an implicit operator of the form 5193 5194 $ shift*M + J 5195 5196 where J is the Jacobian of -F(U). Support may be added in a future version of PETSc, but for now, the user must store 5197 a copy of M or reassemble it when requested. 5198 5199 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear() 5200 @*/ 5201 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx) 5202 { 5203 PetscErrorCode ierr; 5204 5205 PetscFunctionBegin; 5206 ierr = MatScale(A, shift / ts->ijacobian.shift);CHKERRQ(ierr); 5207 ts->ijacobian.shift = shift; 5208 PetscFunctionReturn(0); 5209 } 5210 5211 /*@ 5212 TSGetEquationType - Gets the type of the equation that TS is solving. 5213 5214 Not Collective 5215 5216 Input Parameter: 5217 . ts - the TS context 5218 5219 Output Parameter: 5220 . equation_type - see TSEquationType 5221 5222 Level: beginner 5223 5224 .seealso: TSSetEquationType(), TSEquationType 5225 @*/ 5226 PetscErrorCode TSGetEquationType(TS ts,TSEquationType *equation_type) 5227 { 5228 PetscFunctionBegin; 5229 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5230 PetscValidPointer(equation_type,2); 5231 *equation_type = ts->equation_type; 5232 PetscFunctionReturn(0); 5233 } 5234 5235 /*@ 5236 TSSetEquationType - Sets the type of the equation that TS is solving. 5237 5238 Not Collective 5239 5240 Input Parameter: 5241 + ts - the TS context 5242 - equation_type - see TSEquationType 5243 5244 Level: advanced 5245 5246 .seealso: TSGetEquationType(), TSEquationType 5247 @*/ 5248 PetscErrorCode TSSetEquationType(TS ts,TSEquationType equation_type) 5249 { 5250 PetscFunctionBegin; 5251 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5252 ts->equation_type = equation_type; 5253 PetscFunctionReturn(0); 5254 } 5255 5256 /*@ 5257 TSGetConvergedReason - Gets the reason the TS iteration was stopped. 5258 5259 Not Collective 5260 5261 Input Parameter: 5262 . ts - the TS context 5263 5264 Output Parameter: 5265 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 5266 manual pages for the individual convergence tests for complete lists 5267 5268 Level: beginner 5269 5270 Notes: 5271 Can only be called after the call to TSSolve() is complete. 5272 5273 .seealso: TSSetConvergenceTest(), TSConvergedReason 5274 @*/ 5275 PetscErrorCode TSGetConvergedReason(TS ts,TSConvergedReason *reason) 5276 { 5277 PetscFunctionBegin; 5278 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5279 PetscValidPointer(reason,2); 5280 *reason = ts->reason; 5281 PetscFunctionReturn(0); 5282 } 5283 5284 /*@ 5285 TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve. 5286 5287 Logically Collective; reason must contain common value 5288 5289 Input Parameters: 5290 + ts - the TS context 5291 - reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 5292 manual pages for the individual convergence tests for complete lists 5293 5294 Level: advanced 5295 5296 Notes: 5297 Can only be called while TSSolve() is active. 5298 5299 .seealso: TSConvergedReason 5300 @*/ 5301 PetscErrorCode TSSetConvergedReason(TS ts,TSConvergedReason reason) 5302 { 5303 PetscFunctionBegin; 5304 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5305 ts->reason = reason; 5306 PetscFunctionReturn(0); 5307 } 5308 5309 /*@ 5310 TSGetSolveTime - Gets the time after a call to TSSolve() 5311 5312 Not Collective 5313 5314 Input Parameter: 5315 . ts - the TS context 5316 5317 Output Parameter: 5318 . ftime - the final time. This time corresponds to the final time set with TSSetMaxTime() 5319 5320 Level: beginner 5321 5322 Notes: 5323 Can only be called after the call to TSSolve() is complete. 5324 5325 .seealso: TSSetConvergenceTest(), TSConvergedReason 5326 @*/ 5327 PetscErrorCode TSGetSolveTime(TS ts,PetscReal *ftime) 5328 { 5329 PetscFunctionBegin; 5330 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5331 PetscValidPointer(ftime,2); 5332 *ftime = ts->solvetime; 5333 PetscFunctionReturn(0); 5334 } 5335 5336 /*@ 5337 TSGetSNESIterations - Gets the total number of nonlinear iterations 5338 used by the time integrator. 5339 5340 Not Collective 5341 5342 Input Parameter: 5343 . ts - TS context 5344 5345 Output Parameter: 5346 . nits - number of nonlinear iterations 5347 5348 Notes: 5349 This counter is reset to zero for each successive call to TSSolve(). 5350 5351 Level: intermediate 5352 5353 .seealso: TSGetKSPIterations() 5354 @*/ 5355 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits) 5356 { 5357 PetscFunctionBegin; 5358 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5359 PetscValidIntPointer(nits,2); 5360 *nits = ts->snes_its; 5361 PetscFunctionReturn(0); 5362 } 5363 5364 /*@ 5365 TSGetKSPIterations - Gets the total number of linear iterations 5366 used by the time integrator. 5367 5368 Not Collective 5369 5370 Input Parameter: 5371 . ts - TS context 5372 5373 Output Parameter: 5374 . lits - number of linear iterations 5375 5376 Notes: 5377 This counter is reset to zero for each successive call to TSSolve(). 5378 5379 Level: intermediate 5380 5381 .seealso: TSGetSNESIterations(), SNESGetKSPIterations() 5382 @*/ 5383 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits) 5384 { 5385 PetscFunctionBegin; 5386 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5387 PetscValidIntPointer(lits,2); 5388 *lits = ts->ksp_its; 5389 PetscFunctionReturn(0); 5390 } 5391 5392 /*@ 5393 TSGetStepRejections - Gets the total number of rejected steps. 5394 5395 Not Collective 5396 5397 Input Parameter: 5398 . ts - TS context 5399 5400 Output Parameter: 5401 . rejects - number of steps rejected 5402 5403 Notes: 5404 This counter is reset to zero for each successive call to TSSolve(). 5405 5406 Level: intermediate 5407 5408 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails() 5409 @*/ 5410 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects) 5411 { 5412 PetscFunctionBegin; 5413 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5414 PetscValidIntPointer(rejects,2); 5415 *rejects = ts->reject; 5416 PetscFunctionReturn(0); 5417 } 5418 5419 /*@ 5420 TSGetSNESFailures - Gets the total number of failed SNES solves 5421 5422 Not Collective 5423 5424 Input Parameter: 5425 . ts - TS context 5426 5427 Output Parameter: 5428 . fails - number of failed nonlinear solves 5429 5430 Notes: 5431 This counter is reset to zero for each successive call to TSSolve(). 5432 5433 Level: intermediate 5434 5435 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures() 5436 @*/ 5437 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails) 5438 { 5439 PetscFunctionBegin; 5440 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5441 PetscValidIntPointer(fails,2); 5442 *fails = ts->num_snes_failures; 5443 PetscFunctionReturn(0); 5444 } 5445 5446 /*@ 5447 TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails 5448 5449 Not Collective 5450 5451 Input Parameter: 5452 + ts - TS context 5453 - rejects - maximum number of rejected steps, pass -1 for unlimited 5454 5455 Notes: 5456 The counter is reset to zero for each step 5457 5458 Options Database Key: 5459 . -ts_max_reject - Maximum number of step rejections before a step fails 5460 5461 Level: intermediate 5462 5463 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 5464 @*/ 5465 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects) 5466 { 5467 PetscFunctionBegin; 5468 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5469 ts->max_reject = rejects; 5470 PetscFunctionReturn(0); 5471 } 5472 5473 /*@ 5474 TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves 5475 5476 Not Collective 5477 5478 Input Parameter: 5479 + ts - TS context 5480 - fails - maximum number of failed nonlinear solves, pass -1 for unlimited 5481 5482 Notes: 5483 The counter is reset to zero for each successive call to TSSolve(). 5484 5485 Options Database Key: 5486 . -ts_max_snes_failures - Maximum number of nonlinear solve failures 5487 5488 Level: intermediate 5489 5490 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason() 5491 @*/ 5492 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails) 5493 { 5494 PetscFunctionBegin; 5495 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5496 ts->max_snes_failures = fails; 5497 PetscFunctionReturn(0); 5498 } 5499 5500 /*@ 5501 TSSetErrorIfStepFails - Error if no step succeeds 5502 5503 Not Collective 5504 5505 Input Parameter: 5506 + ts - TS context 5507 - err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure 5508 5509 Options Database Key: 5510 . -ts_error_if_step_fails - Error if no step succeeds 5511 5512 Level: intermediate 5513 5514 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 5515 @*/ 5516 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err) 5517 { 5518 PetscFunctionBegin; 5519 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5520 ts->errorifstepfailed = err; 5521 PetscFunctionReturn(0); 5522 } 5523 5524 /*@C 5525 TSMonitorSolution - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file or a PetscDraw object 5526 5527 Collective on TS 5528 5529 Input Parameters: 5530 + ts - the TS context 5531 . step - current time-step 5532 . ptime - current time 5533 . u - current state 5534 - vf - viewer and its format 5535 5536 Level: intermediate 5537 5538 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5539 @*/ 5540 PetscErrorCode TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf) 5541 { 5542 PetscErrorCode ierr; 5543 5544 PetscFunctionBegin; 5545 ierr = PetscViewerPushFormat(vf->viewer,vf->format);CHKERRQ(ierr); 5546 ierr = VecView(u,vf->viewer);CHKERRQ(ierr); 5547 ierr = PetscViewerPopFormat(vf->viewer);CHKERRQ(ierr); 5548 PetscFunctionReturn(0); 5549 } 5550 5551 /*@C 5552 TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep. 5553 5554 Collective on TS 5555 5556 Input Parameters: 5557 + ts - the TS context 5558 . step - current time-step 5559 . ptime - current time 5560 . u - current state 5561 - filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 5562 5563 Level: intermediate 5564 5565 Notes: 5566 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. 5567 These are named according to the file name template. 5568 5569 This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy(). 5570 5571 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5572 @*/ 5573 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate) 5574 { 5575 PetscErrorCode ierr; 5576 char filename[PETSC_MAX_PATH_LEN]; 5577 PetscViewer viewer; 5578 5579 PetscFunctionBegin; 5580 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 5581 ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr); 5582 ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); 5583 ierr = VecView(u,viewer);CHKERRQ(ierr); 5584 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 5585 PetscFunctionReturn(0); 5586 } 5587 5588 /*@C 5589 TSMonitorSolutionVTKDestroy - Destroy context for monitoring 5590 5591 Collective on TS 5592 5593 Input Parameters: 5594 . filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 5595 5596 Level: intermediate 5597 5598 Note: 5599 This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK(). 5600 5601 .seealso: TSMonitorSet(), TSMonitorSolutionVTK() 5602 @*/ 5603 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate) 5604 { 5605 PetscErrorCode ierr; 5606 5607 PetscFunctionBegin; 5608 ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr); 5609 PetscFunctionReturn(0); 5610 } 5611 5612 /*@ 5613 TSGetAdapt - Get the adaptive controller context for the current method 5614 5615 Collective on TS if controller has not been created yet 5616 5617 Input Arguments: 5618 . ts - time stepping context 5619 5620 Output Arguments: 5621 . adapt - adaptive controller 5622 5623 Level: intermediate 5624 5625 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose() 5626 @*/ 5627 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt) 5628 { 5629 PetscErrorCode ierr; 5630 5631 PetscFunctionBegin; 5632 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5633 PetscValidPointer(adapt,2); 5634 if (!ts->adapt) { 5635 ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr); 5636 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr); 5637 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr); 5638 } 5639 *adapt = ts->adapt; 5640 PetscFunctionReturn(0); 5641 } 5642 5643 /*@ 5644 TSSetTolerances - Set tolerances for local truncation error when using adaptive controller 5645 5646 Logically Collective 5647 5648 Input Arguments: 5649 + ts - time integration context 5650 . atol - scalar absolute tolerances, PETSC_DECIDE to leave current value 5651 . vatol - vector of absolute tolerances or NULL, used in preference to atol if present 5652 . rtol - scalar relative tolerances, PETSC_DECIDE to leave current value 5653 - vrtol - vector of relative tolerances or NULL, used in preference to atol if present 5654 5655 Options Database keys: 5656 + -ts_rtol <rtol> - relative tolerance for local truncation error 5657 - -ts_atol <atol> Absolute tolerance for local truncation error 5658 5659 Notes: 5660 With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error 5661 (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be 5662 computed only for the differential or the algebraic part then this can be done using the vector of 5663 tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the 5664 differential part and infinity for the algebraic part, the LTE calculation will include only the 5665 differential variables. 5666 5667 Level: beginner 5668 5669 .seealso: TS, TSAdapt, TSErrorWeightedNorm(), TSGetTolerances() 5670 @*/ 5671 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol) 5672 { 5673 PetscErrorCode ierr; 5674 5675 PetscFunctionBegin; 5676 if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol; 5677 if (vatol) { 5678 ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr); 5679 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 5680 ts->vatol = vatol; 5681 } 5682 if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol; 5683 if (vrtol) { 5684 ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr); 5685 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 5686 ts->vrtol = vrtol; 5687 } 5688 PetscFunctionReturn(0); 5689 } 5690 5691 /*@ 5692 TSGetTolerances - Get tolerances for local truncation error when using adaptive controller 5693 5694 Logically Collective 5695 5696 Input Arguments: 5697 . ts - time integration context 5698 5699 Output Arguments: 5700 + atol - scalar absolute tolerances, NULL to ignore 5701 . vatol - vector of absolute tolerances, NULL to ignore 5702 . rtol - scalar relative tolerances, NULL to ignore 5703 - vrtol - vector of relative tolerances, NULL to ignore 5704 5705 Level: beginner 5706 5707 .seealso: TS, TSAdapt, TSErrorWeightedNorm(), TSSetTolerances() 5708 @*/ 5709 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol) 5710 { 5711 PetscFunctionBegin; 5712 if (atol) *atol = ts->atol; 5713 if (vatol) *vatol = ts->vatol; 5714 if (rtol) *rtol = ts->rtol; 5715 if (vrtol) *vrtol = ts->vrtol; 5716 PetscFunctionReturn(0); 5717 } 5718 5719 /*@ 5720 TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors 5721 5722 Collective on TS 5723 5724 Input Arguments: 5725 + ts - time stepping context 5726 . U - state vector, usually ts->vec_sol 5727 - Y - state vector to be compared to U 5728 5729 Output Arguments: 5730 + norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5731 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5732 - normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5733 5734 Level: developer 5735 5736 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNormInfinity() 5737 @*/ 5738 PetscErrorCode TSErrorWeightedNorm2(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5739 { 5740 PetscErrorCode ierr; 5741 PetscInt i,n,N,rstart; 5742 PetscInt n_loc,na_loc,nr_loc; 5743 PetscReal n_glb,na_glb,nr_glb; 5744 const PetscScalar *u,*y; 5745 PetscReal sum,suma,sumr,gsum,gsuma,gsumr,diff; 5746 PetscReal tol,tola,tolr; 5747 PetscReal err_loc[6],err_glb[6]; 5748 5749 PetscFunctionBegin; 5750 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5751 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5752 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 5753 PetscValidType(U,2); 5754 PetscValidType(Y,3); 5755 PetscCheckSameComm(U,2,Y,3); 5756 PetscValidPointer(norm,4); 5757 PetscValidPointer(norma,5); 5758 PetscValidPointer(normr,6); 5759 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 5760 5761 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 5762 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 5763 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 5764 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5765 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5766 sum = 0.; n_loc = 0; 5767 suma = 0.; na_loc = 0; 5768 sumr = 0.; nr_loc = 0; 5769 if (ts->vatol && ts->vrtol) { 5770 const PetscScalar *atol,*rtol; 5771 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5772 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5773 for (i=0; i<n; i++) { 5774 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5775 diff = PetscAbsScalar(y[i] - u[i]); 5776 tola = PetscRealPart(atol[i]); 5777 if (tola>0.){ 5778 suma += PetscSqr(diff/tola); 5779 na_loc++; 5780 } 5781 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5782 if (tolr>0.){ 5783 sumr += PetscSqr(diff/tolr); 5784 nr_loc++; 5785 } 5786 tol=tola+tolr; 5787 if (tol>0.){ 5788 sum += PetscSqr(diff/tol); 5789 n_loc++; 5790 } 5791 } 5792 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5793 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5794 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5795 const PetscScalar *atol; 5796 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5797 for (i=0; i<n; i++) { 5798 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5799 diff = PetscAbsScalar(y[i] - u[i]); 5800 tola = PetscRealPart(atol[i]); 5801 if (tola>0.){ 5802 suma += PetscSqr(diff/tola); 5803 na_loc++; 5804 } 5805 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5806 if (tolr>0.){ 5807 sumr += PetscSqr(diff/tolr); 5808 nr_loc++; 5809 } 5810 tol=tola+tolr; 5811 if (tol>0.){ 5812 sum += PetscSqr(diff/tol); 5813 n_loc++; 5814 } 5815 } 5816 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5817 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5818 const PetscScalar *rtol; 5819 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5820 for (i=0; i<n; i++) { 5821 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5822 diff = PetscAbsScalar(y[i] - u[i]); 5823 tola = ts->atol; 5824 if (tola>0.){ 5825 suma += PetscSqr(diff/tola); 5826 na_loc++; 5827 } 5828 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5829 if (tolr>0.){ 5830 sumr += PetscSqr(diff/tolr); 5831 nr_loc++; 5832 } 5833 tol=tola+tolr; 5834 if (tol>0.){ 5835 sum += PetscSqr(diff/tol); 5836 n_loc++; 5837 } 5838 } 5839 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5840 } else { /* scalar atol, scalar rtol */ 5841 for (i=0; i<n; i++) { 5842 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5843 diff = PetscAbsScalar(y[i] - u[i]); 5844 tola = ts->atol; 5845 if (tola>0.){ 5846 suma += PetscSqr(diff/tola); 5847 na_loc++; 5848 } 5849 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5850 if (tolr>0.){ 5851 sumr += PetscSqr(diff/tolr); 5852 nr_loc++; 5853 } 5854 tol=tola+tolr; 5855 if (tol>0.){ 5856 sum += PetscSqr(diff/tol); 5857 n_loc++; 5858 } 5859 } 5860 } 5861 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5862 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5863 5864 err_loc[0] = sum; 5865 err_loc[1] = suma; 5866 err_loc[2] = sumr; 5867 err_loc[3] = (PetscReal)n_loc; 5868 err_loc[4] = (PetscReal)na_loc; 5869 err_loc[5] = (PetscReal)nr_loc; 5870 5871 ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 5872 5873 gsum = err_glb[0]; 5874 gsuma = err_glb[1]; 5875 gsumr = err_glb[2]; 5876 n_glb = err_glb[3]; 5877 na_glb = err_glb[4]; 5878 nr_glb = err_glb[5]; 5879 5880 *norm = 0.; 5881 if (n_glb>0.){*norm = PetscSqrtReal(gsum / n_glb);} 5882 *norma = 0.; 5883 if (na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);} 5884 *normr = 0.; 5885 if (nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);} 5886 5887 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5888 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 5889 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 5890 PetscFunctionReturn(0); 5891 } 5892 5893 /*@ 5894 TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors 5895 5896 Collective on TS 5897 5898 Input Arguments: 5899 + ts - time stepping context 5900 . U - state vector, usually ts->vec_sol 5901 - Y - state vector to be compared to U 5902 5903 Output Arguments: 5904 + norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5905 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5906 - normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5907 5908 Level: developer 5909 5910 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNorm2() 5911 @*/ 5912 PetscErrorCode TSErrorWeightedNormInfinity(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5913 { 5914 PetscErrorCode ierr; 5915 PetscInt i,n,N,rstart; 5916 const PetscScalar *u,*y; 5917 PetscReal max,gmax,maxa,gmaxa,maxr,gmaxr; 5918 PetscReal tol,tola,tolr,diff; 5919 PetscReal err_loc[3],err_glb[3]; 5920 5921 PetscFunctionBegin; 5922 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5923 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5924 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 5925 PetscValidType(U,2); 5926 PetscValidType(Y,3); 5927 PetscCheckSameComm(U,2,Y,3); 5928 PetscValidPointer(norm,4); 5929 PetscValidPointer(norma,5); 5930 PetscValidPointer(normr,6); 5931 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 5932 5933 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 5934 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 5935 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 5936 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5937 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5938 5939 max=0.; 5940 maxa=0.; 5941 maxr=0.; 5942 5943 if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */ 5944 const PetscScalar *atol,*rtol; 5945 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5946 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5947 5948 for (i=0; i<n; i++) { 5949 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5950 diff = PetscAbsScalar(y[i] - u[i]); 5951 tola = PetscRealPart(atol[i]); 5952 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5953 tol = tola+tolr; 5954 if (tola>0.){ 5955 maxa = PetscMax(maxa,diff / tola); 5956 } 5957 if (tolr>0.){ 5958 maxr = PetscMax(maxr,diff / tolr); 5959 } 5960 if (tol>0.){ 5961 max = PetscMax(max,diff / tol); 5962 } 5963 } 5964 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5965 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5966 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5967 const PetscScalar *atol; 5968 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5969 for (i=0; i<n; i++) { 5970 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5971 diff = PetscAbsScalar(y[i] - u[i]); 5972 tola = PetscRealPart(atol[i]); 5973 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5974 tol = tola+tolr; 5975 if (tola>0.){ 5976 maxa = PetscMax(maxa,diff / tola); 5977 } 5978 if (tolr>0.){ 5979 maxr = PetscMax(maxr,diff / tolr); 5980 } 5981 if (tol>0.){ 5982 max = PetscMax(max,diff / tol); 5983 } 5984 } 5985 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5986 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5987 const PetscScalar *rtol; 5988 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5989 5990 for (i=0; i<n; i++) { 5991 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5992 diff = PetscAbsScalar(y[i] - u[i]); 5993 tola = ts->atol; 5994 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5995 tol = tola+tolr; 5996 if (tola>0.){ 5997 maxa = PetscMax(maxa,diff / tola); 5998 } 5999 if (tolr>0.){ 6000 maxr = PetscMax(maxr,diff / tolr); 6001 } 6002 if (tol>0.){ 6003 max = PetscMax(max,diff / tol); 6004 } 6005 } 6006 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6007 } else { /* scalar atol, scalar rtol */ 6008 6009 for (i=0; i<n; i++) { 6010 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6011 diff = PetscAbsScalar(y[i] - u[i]); 6012 tola = ts->atol; 6013 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6014 tol = tola+tolr; 6015 if (tola>0.){ 6016 maxa = PetscMax(maxa,diff / tola); 6017 } 6018 if (tolr>0.){ 6019 maxr = PetscMax(maxr,diff / tolr); 6020 } 6021 if (tol>0.){ 6022 max = PetscMax(max,diff / tol); 6023 } 6024 } 6025 } 6026 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 6027 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 6028 err_loc[0] = max; 6029 err_loc[1] = maxa; 6030 err_loc[2] = maxr; 6031 ierr = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6032 gmax = err_glb[0]; 6033 gmaxa = err_glb[1]; 6034 gmaxr = err_glb[2]; 6035 6036 *norm = gmax; 6037 *norma = gmaxa; 6038 *normr = gmaxr; 6039 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6040 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 6041 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 6042 PetscFunctionReturn(0); 6043 } 6044 6045 /*@ 6046 TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors based on supplied absolute and relative tolerances 6047 6048 Collective on TS 6049 6050 Input Arguments: 6051 + ts - time stepping context 6052 . U - state vector, usually ts->vec_sol 6053 . Y - state vector to be compared to U 6054 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 6055 6056 Output Arguments: 6057 + norm - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances 6058 . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user 6059 - normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user 6060 6061 Options Database Keys: 6062 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 6063 6064 Level: developer 6065 6066 .seealso: TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2(), TSErrorWeightedENorm 6067 @*/ 6068 PetscErrorCode TSErrorWeightedNorm(TS ts,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6069 { 6070 PetscErrorCode ierr; 6071 6072 PetscFunctionBegin; 6073 if (wnormtype == NORM_2) { 6074 ierr = TSErrorWeightedNorm2(ts,U,Y,norm,norma,normr);CHKERRQ(ierr); 6075 } else if (wnormtype == NORM_INFINITY) { 6076 ierr = TSErrorWeightedNormInfinity(ts,U,Y,norm,norma,normr);CHKERRQ(ierr); 6077 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 6078 PetscFunctionReturn(0); 6079 } 6080 6081 6082 /*@ 6083 TSErrorWeightedENorm2 - compute a weighted 2 error norm based on supplied absolute and relative tolerances 6084 6085 Collective on TS 6086 6087 Input Arguments: 6088 + ts - time stepping context 6089 . E - error vector 6090 . U - state vector, usually ts->vec_sol 6091 - Y - state vector, previous time step 6092 6093 Output Arguments: 6094 + norm - weighted norm, a value of 1.0 means that the error matches the tolerances 6095 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 6096 - normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 6097 6098 Level: developer 6099 6100 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENormInfinity() 6101 @*/ 6102 PetscErrorCode TSErrorWeightedENorm2(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6103 { 6104 PetscErrorCode ierr; 6105 PetscInt i,n,N,rstart; 6106 PetscInt n_loc,na_loc,nr_loc; 6107 PetscReal n_glb,na_glb,nr_glb; 6108 const PetscScalar *e,*u,*y; 6109 PetscReal err,sum,suma,sumr,gsum,gsuma,gsumr; 6110 PetscReal tol,tola,tolr; 6111 PetscReal err_loc[6],err_glb[6]; 6112 6113 PetscFunctionBegin; 6114 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6115 PetscValidHeaderSpecific(E,VEC_CLASSID,2); 6116 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 6117 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 6118 PetscValidType(E,2); 6119 PetscValidType(U,3); 6120 PetscValidType(Y,4); 6121 PetscCheckSameComm(E,2,U,3); 6122 PetscCheckSameComm(U,2,Y,3); 6123 PetscValidPointer(norm,5); 6124 PetscValidPointer(norma,6); 6125 PetscValidPointer(normr,7); 6126 6127 ierr = VecGetSize(E,&N);CHKERRQ(ierr); 6128 ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr); 6129 ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr); 6130 ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr); 6131 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 6132 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 6133 sum = 0.; n_loc = 0; 6134 suma = 0.; na_loc = 0; 6135 sumr = 0.; nr_loc = 0; 6136 if (ts->vatol && ts->vrtol) { 6137 const PetscScalar *atol,*rtol; 6138 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6139 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6140 for (i=0; i<n; i++) { 6141 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6142 err = PetscAbsScalar(e[i]); 6143 tola = PetscRealPart(atol[i]); 6144 if (tola>0.){ 6145 suma += PetscSqr(err/tola); 6146 na_loc++; 6147 } 6148 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6149 if (tolr>0.){ 6150 sumr += PetscSqr(err/tolr); 6151 nr_loc++; 6152 } 6153 tol=tola+tolr; 6154 if (tol>0.){ 6155 sum += PetscSqr(err/tol); 6156 n_loc++; 6157 } 6158 } 6159 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6160 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6161 } else if (ts->vatol) { /* vector atol, scalar rtol */ 6162 const PetscScalar *atol; 6163 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6164 for (i=0; i<n; i++) { 6165 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6166 err = PetscAbsScalar(e[i]); 6167 tola = PetscRealPart(atol[i]); 6168 if (tola>0.){ 6169 suma += PetscSqr(err/tola); 6170 na_loc++; 6171 } 6172 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6173 if (tolr>0.){ 6174 sumr += PetscSqr(err/tolr); 6175 nr_loc++; 6176 } 6177 tol=tola+tolr; 6178 if (tol>0.){ 6179 sum += PetscSqr(err/tol); 6180 n_loc++; 6181 } 6182 } 6183 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6184 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 6185 const PetscScalar *rtol; 6186 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6187 for (i=0; i<n; i++) { 6188 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6189 err = PetscAbsScalar(e[i]); 6190 tola = ts->atol; 6191 if (tola>0.){ 6192 suma += PetscSqr(err/tola); 6193 na_loc++; 6194 } 6195 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6196 if (tolr>0.){ 6197 sumr += PetscSqr(err/tolr); 6198 nr_loc++; 6199 } 6200 tol=tola+tolr; 6201 if (tol>0.){ 6202 sum += PetscSqr(err/tol); 6203 n_loc++; 6204 } 6205 } 6206 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6207 } else { /* scalar atol, scalar rtol */ 6208 for (i=0; i<n; i++) { 6209 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6210 err = PetscAbsScalar(e[i]); 6211 tola = ts->atol; 6212 if (tola>0.){ 6213 suma += PetscSqr(err/tola); 6214 na_loc++; 6215 } 6216 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6217 if (tolr>0.){ 6218 sumr += PetscSqr(err/tolr); 6219 nr_loc++; 6220 } 6221 tol=tola+tolr; 6222 if (tol>0.){ 6223 sum += PetscSqr(err/tol); 6224 n_loc++; 6225 } 6226 } 6227 } 6228 ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr); 6229 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 6230 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 6231 6232 err_loc[0] = sum; 6233 err_loc[1] = suma; 6234 err_loc[2] = sumr; 6235 err_loc[3] = (PetscReal)n_loc; 6236 err_loc[4] = (PetscReal)na_loc; 6237 err_loc[5] = (PetscReal)nr_loc; 6238 6239 ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6240 6241 gsum = err_glb[0]; 6242 gsuma = err_glb[1]; 6243 gsumr = err_glb[2]; 6244 n_glb = err_glb[3]; 6245 na_glb = err_glb[4]; 6246 nr_glb = err_glb[5]; 6247 6248 *norm = 0.; 6249 if (n_glb>0.){*norm = PetscSqrtReal(gsum / n_glb);} 6250 *norma = 0.; 6251 if (na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);} 6252 *normr = 0.; 6253 if (nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);} 6254 6255 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6256 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 6257 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 6258 PetscFunctionReturn(0); 6259 } 6260 6261 /*@ 6262 TSErrorWeightedENormInfinity - compute a weighted infinity error norm based on supplied absolute and relative tolerances 6263 Collective on TS 6264 6265 Input Arguments: 6266 + ts - time stepping context 6267 . E - error vector 6268 . U - state vector, usually ts->vec_sol 6269 - Y - state vector, previous time step 6270 6271 Output Arguments: 6272 + norm - weighted norm, a value of 1.0 means that the error matches the tolerances 6273 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 6274 - normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 6275 6276 Level: developer 6277 6278 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENorm2() 6279 @*/ 6280 PetscErrorCode TSErrorWeightedENormInfinity(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6281 { 6282 PetscErrorCode ierr; 6283 PetscInt i,n,N,rstart; 6284 const PetscScalar *e,*u,*y; 6285 PetscReal err,max,gmax,maxa,gmaxa,maxr,gmaxr; 6286 PetscReal tol,tola,tolr; 6287 PetscReal err_loc[3],err_glb[3]; 6288 6289 PetscFunctionBegin; 6290 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6291 PetscValidHeaderSpecific(E,VEC_CLASSID,2); 6292 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 6293 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 6294 PetscValidType(E,2); 6295 PetscValidType(U,3); 6296 PetscValidType(Y,4); 6297 PetscCheckSameComm(E,2,U,3); 6298 PetscCheckSameComm(U,2,Y,3); 6299 PetscValidPointer(norm,5); 6300 PetscValidPointer(norma,6); 6301 PetscValidPointer(normr,7); 6302 6303 ierr = VecGetSize(E,&N);CHKERRQ(ierr); 6304 ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr); 6305 ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr); 6306 ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr); 6307 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 6308 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 6309 6310 max=0.; 6311 maxa=0.; 6312 maxr=0.; 6313 6314 if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */ 6315 const PetscScalar *atol,*rtol; 6316 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6317 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6318 6319 for (i=0; i<n; i++) { 6320 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6321 err = PetscAbsScalar(e[i]); 6322 tola = PetscRealPart(atol[i]); 6323 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6324 tol = tola+tolr; 6325 if (tola>0.){ 6326 maxa = PetscMax(maxa,err / tola); 6327 } 6328 if (tolr>0.){ 6329 maxr = PetscMax(maxr,err / tolr); 6330 } 6331 if (tol>0.){ 6332 max = PetscMax(max,err / tol); 6333 } 6334 } 6335 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6336 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6337 } else if (ts->vatol) { /* vector atol, scalar rtol */ 6338 const PetscScalar *atol; 6339 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6340 for (i=0; i<n; i++) { 6341 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6342 err = PetscAbsScalar(e[i]); 6343 tola = PetscRealPart(atol[i]); 6344 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6345 tol = tola+tolr; 6346 if (tola>0.){ 6347 maxa = PetscMax(maxa,err / tola); 6348 } 6349 if (tolr>0.){ 6350 maxr = PetscMax(maxr,err / tolr); 6351 } 6352 if (tol>0.){ 6353 max = PetscMax(max,err / tol); 6354 } 6355 } 6356 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6357 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 6358 const PetscScalar *rtol; 6359 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6360 6361 for (i=0; i<n; i++) { 6362 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6363 err = PetscAbsScalar(e[i]); 6364 tola = ts->atol; 6365 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6366 tol = tola+tolr; 6367 if (tola>0.){ 6368 maxa = PetscMax(maxa,err / tola); 6369 } 6370 if (tolr>0.){ 6371 maxr = PetscMax(maxr,err / tolr); 6372 } 6373 if (tol>0.){ 6374 max = PetscMax(max,err / tol); 6375 } 6376 } 6377 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6378 } else { /* scalar atol, scalar rtol */ 6379 6380 for (i=0; i<n; i++) { 6381 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 6382 err = PetscAbsScalar(e[i]); 6383 tola = ts->atol; 6384 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6385 tol = tola+tolr; 6386 if (tola>0.){ 6387 maxa = PetscMax(maxa,err / tola); 6388 } 6389 if (tolr>0.){ 6390 maxr = PetscMax(maxr,err / tolr); 6391 } 6392 if (tol>0.){ 6393 max = PetscMax(max,err / tol); 6394 } 6395 } 6396 } 6397 ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr); 6398 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 6399 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 6400 err_loc[0] = max; 6401 err_loc[1] = maxa; 6402 err_loc[2] = maxr; 6403 ierr = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6404 gmax = err_glb[0]; 6405 gmaxa = err_glb[1]; 6406 gmaxr = err_glb[2]; 6407 6408 *norm = gmax; 6409 *norma = gmaxa; 6410 *normr = gmaxr; 6411 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6412 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 6413 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 6414 PetscFunctionReturn(0); 6415 } 6416 6417 /*@ 6418 TSErrorWeightedENorm - compute a weighted error norm based on supplied absolute and relative tolerances 6419 6420 Collective on TS 6421 6422 Input Arguments: 6423 + ts - time stepping context 6424 . E - error vector 6425 . U - state vector, usually ts->vec_sol 6426 . Y - state vector, previous time step 6427 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 6428 6429 Output Arguments: 6430 + norm - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances 6431 . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user 6432 - normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user 6433 6434 Options Database Keys: 6435 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 6436 6437 Level: developer 6438 6439 .seealso: TSErrorWeightedENormInfinity(), TSErrorWeightedENorm2(), TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2() 6440 @*/ 6441 PetscErrorCode TSErrorWeightedENorm(TS ts,Vec E,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6442 { 6443 PetscErrorCode ierr; 6444 6445 PetscFunctionBegin; 6446 if (wnormtype == NORM_2) { 6447 ierr = TSErrorWeightedENorm2(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr); 6448 } else if (wnormtype == NORM_INFINITY) { 6449 ierr = TSErrorWeightedENormInfinity(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr); 6450 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 6451 PetscFunctionReturn(0); 6452 } 6453 6454 6455 /*@ 6456 TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler 6457 6458 Logically Collective on TS 6459 6460 Input Arguments: 6461 + ts - time stepping context 6462 - cfltime - maximum stable time step if using forward Euler (value can be different on each process) 6463 6464 Note: 6465 After calling this function, the global CFL time can be obtained by calling TSGetCFLTime() 6466 6467 Level: intermediate 6468 6469 .seealso: TSGetCFLTime(), TSADAPTCFL 6470 @*/ 6471 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime) 6472 { 6473 PetscFunctionBegin; 6474 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6475 ts->cfltime_local = cfltime; 6476 ts->cfltime = -1.; 6477 PetscFunctionReturn(0); 6478 } 6479 6480 /*@ 6481 TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler 6482 6483 Collective on TS 6484 6485 Input Arguments: 6486 . ts - time stepping context 6487 6488 Output Arguments: 6489 . cfltime - maximum stable time step for forward Euler 6490 6491 Level: advanced 6492 6493 .seealso: TSSetCFLTimeLocal() 6494 @*/ 6495 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime) 6496 { 6497 PetscErrorCode ierr; 6498 6499 PetscFunctionBegin; 6500 if (ts->cfltime < 0) { 6501 ierr = MPIU_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6502 } 6503 *cfltime = ts->cfltime; 6504 PetscFunctionReturn(0); 6505 } 6506 6507 /*@ 6508 TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu 6509 6510 Input Parameters: 6511 + ts - the TS context. 6512 . xl - lower bound. 6513 - xu - upper bound. 6514 6515 Notes: 6516 If this routine is not called then the lower and upper bounds are set to 6517 PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp(). 6518 6519 Level: advanced 6520 6521 @*/ 6522 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu) 6523 { 6524 PetscErrorCode ierr; 6525 SNES snes; 6526 6527 PetscFunctionBegin; 6528 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 6529 ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr); 6530 PetscFunctionReturn(0); 6531 } 6532 6533 /*@C 6534 TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector 6535 in a time based line graph 6536 6537 Collective on TS 6538 6539 Input Parameters: 6540 + ts - the TS context 6541 . step - current time-step 6542 . ptime - current time 6543 . u - current solution 6544 - dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate() 6545 6546 Options Database: 6547 . -ts_monitor_lg_solution_variables 6548 6549 Level: intermediate 6550 6551 Notes: 6552 Each process in a parallel run displays its component solutions in a separate window 6553 6554 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(), 6555 TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(), 6556 TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(), 6557 TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop() 6558 @*/ 6559 PetscErrorCode TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 6560 { 6561 PetscErrorCode ierr; 6562 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dctx; 6563 const PetscScalar *yy; 6564 Vec v; 6565 6566 PetscFunctionBegin; 6567 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 6568 if (!step) { 6569 PetscDrawAxis axis; 6570 PetscInt dim; 6571 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6572 ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr); 6573 if (!ctx->names) { 6574 PetscBool flg; 6575 /* user provides names of variables to plot but no names has been set so assume names are integer values */ 6576 ierr = PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg);CHKERRQ(ierr); 6577 if (flg) { 6578 PetscInt i,n; 6579 char **names; 6580 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 6581 ierr = PetscMalloc1(n+1,&names);CHKERRQ(ierr); 6582 for (i=0; i<n; i++) { 6583 ierr = PetscMalloc1(5,&names[i]);CHKERRQ(ierr); 6584 ierr = PetscSNPrintf(names[i],5,"%D",i);CHKERRQ(ierr); 6585 } 6586 names[n] = NULL; 6587 ctx->names = names; 6588 } 6589 } 6590 if (ctx->names && !ctx->displaynames) { 6591 char **displaynames; 6592 PetscBool flg; 6593 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6594 ierr = PetscCalloc1(dim+1,&displaynames);CHKERRQ(ierr); 6595 ierr = PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg);CHKERRQ(ierr); 6596 if (flg) { 6597 ierr = TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames);CHKERRQ(ierr); 6598 } 6599 ierr = PetscStrArrayDestroy(&displaynames);CHKERRQ(ierr); 6600 } 6601 if (ctx->displaynames) { 6602 ierr = PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables);CHKERRQ(ierr); 6603 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames);CHKERRQ(ierr); 6604 } else if (ctx->names) { 6605 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6606 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6607 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names);CHKERRQ(ierr); 6608 } else { 6609 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6610 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6611 } 6612 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6613 } 6614 6615 if (!ctx->transform) v = u; 6616 else {ierr = (*ctx->transform)(ctx->transformctx,u,&v);CHKERRQ(ierr);} 6617 ierr = VecGetArrayRead(v,&yy);CHKERRQ(ierr); 6618 if (ctx->displaynames) { 6619 PetscInt i; 6620 for (i=0; i<ctx->ndisplayvariables; i++) 6621 ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]); 6622 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues);CHKERRQ(ierr); 6623 } else { 6624 #if defined(PETSC_USE_COMPLEX) 6625 PetscInt i,n; 6626 PetscReal *yreal; 6627 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 6628 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 6629 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 6630 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 6631 ierr = PetscFree(yreal);CHKERRQ(ierr); 6632 #else 6633 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 6634 #endif 6635 } 6636 ierr = VecRestoreArrayRead(v,&yy);CHKERRQ(ierr); 6637 if (ctx->transform) {ierr = VecDestroy(&v);CHKERRQ(ierr);} 6638 6639 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 6640 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6641 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 6642 } 6643 PetscFunctionReturn(0); 6644 } 6645 6646 /*@C 6647 TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 6648 6649 Collective on TS 6650 6651 Input Parameters: 6652 + ts - the TS context 6653 - names - the names of the components, final string must be NULL 6654 6655 Level: intermediate 6656 6657 Notes: 6658 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6659 6660 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames() 6661 @*/ 6662 PetscErrorCode TSMonitorLGSetVariableNames(TS ts,const char * const *names) 6663 { 6664 PetscErrorCode ierr; 6665 PetscInt i; 6666 6667 PetscFunctionBegin; 6668 for (i=0; i<ts->numbermonitors; i++) { 6669 if (ts->monitor[i] == TSMonitorLGSolution) { 6670 ierr = TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names);CHKERRQ(ierr); 6671 break; 6672 } 6673 } 6674 PetscFunctionReturn(0); 6675 } 6676 6677 /*@C 6678 TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 6679 6680 Collective on TS 6681 6682 Input Parameters: 6683 + ts - the TS context 6684 - names - the names of the components, final string must be NULL 6685 6686 Level: intermediate 6687 6688 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames() 6689 @*/ 6690 PetscErrorCode TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names) 6691 { 6692 PetscErrorCode ierr; 6693 6694 PetscFunctionBegin; 6695 ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr); 6696 ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr); 6697 PetscFunctionReturn(0); 6698 } 6699 6700 /*@C 6701 TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot 6702 6703 Collective on TS 6704 6705 Input Parameter: 6706 . ts - the TS context 6707 6708 Output Parameter: 6709 . names - the names of the components, final string must be NULL 6710 6711 Level: intermediate 6712 6713 Notes: 6714 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6715 6716 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 6717 @*/ 6718 PetscErrorCode TSMonitorLGGetVariableNames(TS ts,const char *const **names) 6719 { 6720 PetscInt i; 6721 6722 PetscFunctionBegin; 6723 *names = NULL; 6724 for (i=0; i<ts->numbermonitors; i++) { 6725 if (ts->monitor[i] == TSMonitorLGSolution) { 6726 TSMonitorLGCtx ctx = (TSMonitorLGCtx) ts->monitorcontext[i]; 6727 *names = (const char *const *)ctx->names; 6728 break; 6729 } 6730 } 6731 PetscFunctionReturn(0); 6732 } 6733 6734 /*@C 6735 TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor 6736 6737 Collective on TS 6738 6739 Input Parameters: 6740 + ctx - the TSMonitorLG context 6741 - displaynames - the names of the components, final string must be NULL 6742 6743 Level: intermediate 6744 6745 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 6746 @*/ 6747 PetscErrorCode TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames) 6748 { 6749 PetscInt j = 0,k; 6750 PetscErrorCode ierr; 6751 6752 PetscFunctionBegin; 6753 if (!ctx->names) PetscFunctionReturn(0); 6754 ierr = PetscStrArrayDestroy(&ctx->displaynames);CHKERRQ(ierr); 6755 ierr = PetscStrArrayallocpy(displaynames,&ctx->displaynames);CHKERRQ(ierr); 6756 while (displaynames[j]) j++; 6757 ctx->ndisplayvariables = j; 6758 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables);CHKERRQ(ierr); 6759 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues);CHKERRQ(ierr); 6760 j = 0; 6761 while (displaynames[j]) { 6762 k = 0; 6763 while (ctx->names[k]) { 6764 PetscBool flg; 6765 ierr = PetscStrcmp(displaynames[j],ctx->names[k],&flg);CHKERRQ(ierr); 6766 if (flg) { 6767 ctx->displayvariables[j] = k; 6768 break; 6769 } 6770 k++; 6771 } 6772 j++; 6773 } 6774 PetscFunctionReturn(0); 6775 } 6776 6777 /*@C 6778 TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor 6779 6780 Collective on TS 6781 6782 Input Parameters: 6783 + ts - the TS context 6784 - displaynames - the names of the components, final string must be NULL 6785 6786 Notes: 6787 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6788 6789 Level: intermediate 6790 6791 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 6792 @*/ 6793 PetscErrorCode TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames) 6794 { 6795 PetscInt i; 6796 PetscErrorCode ierr; 6797 6798 PetscFunctionBegin; 6799 for (i=0; i<ts->numbermonitors; i++) { 6800 if (ts->monitor[i] == TSMonitorLGSolution) { 6801 ierr = TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames);CHKERRQ(ierr); 6802 break; 6803 } 6804 } 6805 PetscFunctionReturn(0); 6806 } 6807 6808 /*@C 6809 TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed 6810 6811 Collective on TS 6812 6813 Input Parameters: 6814 + ts - the TS context 6815 . transform - the transform function 6816 . destroy - function to destroy the optional context 6817 - ctx - optional context used by transform function 6818 6819 Notes: 6820 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6821 6822 Level: intermediate 6823 6824 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform() 6825 @*/ 6826 PetscErrorCode TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 6827 { 6828 PetscInt i; 6829 PetscErrorCode ierr; 6830 6831 PetscFunctionBegin; 6832 for (i=0; i<ts->numbermonitors; i++) { 6833 if (ts->monitor[i] == TSMonitorLGSolution) { 6834 ierr = TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx);CHKERRQ(ierr); 6835 } 6836 } 6837 PetscFunctionReturn(0); 6838 } 6839 6840 /*@C 6841 TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed 6842 6843 Collective on TSLGCtx 6844 6845 Input Parameters: 6846 + ts - the TS context 6847 . transform - the transform function 6848 . destroy - function to destroy the optional context 6849 - ctx - optional context used by transform function 6850 6851 Level: intermediate 6852 6853 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform() 6854 @*/ 6855 PetscErrorCode TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 6856 { 6857 PetscFunctionBegin; 6858 ctx->transform = transform; 6859 ctx->transformdestroy = destroy; 6860 ctx->transformctx = tctx; 6861 PetscFunctionReturn(0); 6862 } 6863 6864 /*@C 6865 TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the error 6866 in a time based line graph 6867 6868 Collective on TS 6869 6870 Input Parameters: 6871 + ts - the TS context 6872 . step - current time-step 6873 . ptime - current time 6874 . u - current solution 6875 - dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate() 6876 6877 Level: intermediate 6878 6879 Notes: 6880 Each process in a parallel run displays its component errors in a separate window 6881 6882 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 6883 6884 Options Database Keys: 6885 . -ts_monitor_lg_error - create a graphical monitor of error history 6886 6887 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 6888 @*/ 6889 PetscErrorCode TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 6890 { 6891 PetscErrorCode ierr; 6892 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 6893 const PetscScalar *yy; 6894 Vec y; 6895 6896 PetscFunctionBegin; 6897 if (!step) { 6898 PetscDrawAxis axis; 6899 PetscInt dim; 6900 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6901 ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Error");CHKERRQ(ierr); 6902 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6903 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6904 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6905 } 6906 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 6907 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 6908 ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr); 6909 ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr); 6910 #if defined(PETSC_USE_COMPLEX) 6911 { 6912 PetscReal *yreal; 6913 PetscInt i,n; 6914 ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr); 6915 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 6916 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 6917 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 6918 ierr = PetscFree(yreal);CHKERRQ(ierr); 6919 } 6920 #else 6921 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 6922 #endif 6923 ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr); 6924 ierr = VecDestroy(&y);CHKERRQ(ierr); 6925 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 6926 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6927 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 6928 } 6929 PetscFunctionReturn(0); 6930 } 6931 6932 /*@C 6933 TSMonitorSPSwarmSolution - Graphically displays phase plots of DMSwarm particles on a scatter plot 6934 6935 Input Parameters: 6936 + ts - the TS context 6937 . step - current time-step 6938 . ptime - current time 6939 . u - current solution 6940 - dctx - the TSMonitorSPCtx object that contains all the options for the monitoring, this is created with TSMonitorSPCtxCreate() 6941 6942 Options Database: 6943 . -ts_monitor_sp_swarm 6944 6945 Level: intermediate 6946 6947 @*/ 6948 PetscErrorCode TSMonitorSPSwarmSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 6949 { 6950 PetscErrorCode ierr; 6951 TSMonitorSPCtx ctx = (TSMonitorSPCtx)dctx; 6952 const PetscScalar *yy; 6953 PetscReal *y,*x; 6954 PetscInt Np, p, dim=2; 6955 DM dm; 6956 6957 PetscFunctionBegin; 6958 6959 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 6960 if (!step) { 6961 PetscDrawAxis axis; 6962 ierr = PetscDrawSPGetAxis(ctx->sp,&axis);CHKERRQ(ierr); 6963 ierr = PetscDrawAxisSetLabels(axis,"Particles","X","Y");CHKERRQ(ierr); 6964 ierr = PetscDrawAxisSetLimits(axis, -5, 5, -5, 5);CHKERRQ(ierr); 6965 ierr = PetscDrawAxisSetHoldLimits(axis, PETSC_TRUE);CHKERRQ(ierr); 6966 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 6967 ierr = DMGetDimension(dm, &dim); 6968 if (dim!=2) SETERRQ(PETSC_COMM_SELF, ierr, "Dimensions improper for monitor arguments! Current support: two dimensions.");CHKERRQ(ierr); 6969 ierr = VecGetLocalSize(u, &Np);CHKERRQ(ierr); 6970 Np /= 2*dim; 6971 ierr = PetscDrawSPSetDimension(ctx->sp, Np);CHKERRQ(ierr); 6972 ierr = PetscDrawSPReset(ctx->sp);CHKERRQ(ierr); 6973 } 6974 6975 ierr = VecGetLocalSize(u, &Np);CHKERRQ(ierr); 6976 Np /= 2*dim; 6977 ierr = VecGetArrayRead(u,&yy);CHKERRQ(ierr); 6978 ierr = PetscMalloc2(Np, &x, Np, &y);CHKERRQ(ierr); 6979 /* get points from solution vector */ 6980 for (p=0; p<Np; ++p){ 6981 x[p] = PetscRealPart(yy[2*dim*p]); 6982 y[p] = PetscRealPart(yy[2*dim*p+1]); 6983 } 6984 ierr = VecRestoreArrayRead(u,&yy);CHKERRQ(ierr); 6985 6986 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 6987 ierr = PetscDrawSPAddPoint(ctx->sp,x,y);CHKERRQ(ierr); 6988 ierr = PetscDrawSPDraw(ctx->sp,PETSC_FALSE);CHKERRQ(ierr); 6989 ierr = PetscDrawSPSave(ctx->sp);CHKERRQ(ierr); 6990 } 6991 6992 ierr = PetscFree2(x, y);CHKERRQ(ierr); 6993 6994 PetscFunctionReturn(0); 6995 } 6996 6997 6998 6999 /*@C 7000 TSMonitorError - Monitors progress of the TS solvers by printing the 2 norm of the error at each timestep 7001 7002 Collective on TS 7003 7004 Input Parameters: 7005 + ts - the TS context 7006 . step - current time-step 7007 . ptime - current time 7008 . u - current solution 7009 - dctx - unused context 7010 7011 Level: intermediate 7012 7013 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 7014 7015 Options Database Keys: 7016 . -ts_monitor_error - create a graphical monitor of error history 7017 7018 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 7019 @*/ 7020 PetscErrorCode TSMonitorError(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf) 7021 { 7022 PetscErrorCode ierr; 7023 Vec y; 7024 PetscReal nrm; 7025 PetscBool flg; 7026 7027 PetscFunctionBegin; 7028 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 7029 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 7030 ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr); 7031 ierr = PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERASCII,&flg);CHKERRQ(ierr); 7032 if (flg) { 7033 ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 7034 ierr = PetscViewerASCIIPrintf(vf->viewer,"2-norm of error %g\n",(double)nrm);CHKERRQ(ierr); 7035 } 7036 ierr = PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERDRAW,&flg);CHKERRQ(ierr); 7037 if (flg) { 7038 ierr = VecView(y,vf->viewer);CHKERRQ(ierr); 7039 } 7040 ierr = VecDestroy(&y);CHKERRQ(ierr); 7041 PetscFunctionReturn(0); 7042 } 7043 7044 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 7045 { 7046 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 7047 PetscReal x = ptime,y; 7048 PetscErrorCode ierr; 7049 PetscInt its; 7050 7051 PetscFunctionBegin; 7052 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 7053 if (!n) { 7054 PetscDrawAxis axis; 7055 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 7056 ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr); 7057 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 7058 ctx->snes_its = 0; 7059 } 7060 ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr); 7061 y = its - ctx->snes_its; 7062 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 7063 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 7064 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 7065 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 7066 } 7067 ctx->snes_its = its; 7068 PetscFunctionReturn(0); 7069 } 7070 7071 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 7072 { 7073 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 7074 PetscReal x = ptime,y; 7075 PetscErrorCode ierr; 7076 PetscInt its; 7077 7078 PetscFunctionBegin; 7079 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 7080 if (!n) { 7081 PetscDrawAxis axis; 7082 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 7083 ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr); 7084 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 7085 ctx->ksp_its = 0; 7086 } 7087 ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr); 7088 y = its - ctx->ksp_its; 7089 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 7090 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 7091 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 7092 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 7093 } 7094 ctx->ksp_its = its; 7095 PetscFunctionReturn(0); 7096 } 7097 7098 /*@ 7099 TSComputeLinearStability - computes the linear stability function at a point 7100 7101 Collective on TS 7102 7103 Input Parameters: 7104 + ts - the TS context 7105 - xr,xi - real and imaginary part of input arguments 7106 7107 Output Parameters: 7108 . yr,yi - real and imaginary part of function value 7109 7110 Level: developer 7111 7112 .seealso: TSSetRHSFunction(), TSComputeIFunction() 7113 @*/ 7114 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi) 7115 { 7116 PetscErrorCode ierr; 7117 7118 PetscFunctionBegin; 7119 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7120 if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method"); 7121 ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr); 7122 PetscFunctionReturn(0); 7123 } 7124 7125 /* ------------------------------------------------------------------------*/ 7126 /*@C 7127 TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope() 7128 7129 Collective on TS 7130 7131 Input Parameters: 7132 . ts - the ODE solver object 7133 7134 Output Parameter: 7135 . ctx - the context 7136 7137 Level: intermediate 7138 7139 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError() 7140 7141 @*/ 7142 PetscErrorCode TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx) 7143 { 7144 PetscErrorCode ierr; 7145 7146 PetscFunctionBegin; 7147 ierr = PetscNew(ctx);CHKERRQ(ierr); 7148 PetscFunctionReturn(0); 7149 } 7150 7151 /*@C 7152 TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution 7153 7154 Collective on TS 7155 7156 Input Parameters: 7157 + ts - the TS context 7158 . step - current time-step 7159 . ptime - current time 7160 . u - current solution 7161 - dctx - the envelope context 7162 7163 Options Database: 7164 . -ts_monitor_envelope 7165 7166 Level: intermediate 7167 7168 Notes: 7169 after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope 7170 7171 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxCreate() 7172 @*/ 7173 PetscErrorCode TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 7174 { 7175 PetscErrorCode ierr; 7176 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx; 7177 7178 PetscFunctionBegin; 7179 if (!ctx->max) { 7180 ierr = VecDuplicate(u,&ctx->max);CHKERRQ(ierr); 7181 ierr = VecDuplicate(u,&ctx->min);CHKERRQ(ierr); 7182 ierr = VecCopy(u,ctx->max);CHKERRQ(ierr); 7183 ierr = VecCopy(u,ctx->min);CHKERRQ(ierr); 7184 } else { 7185 ierr = VecPointwiseMax(ctx->max,u,ctx->max);CHKERRQ(ierr); 7186 ierr = VecPointwiseMin(ctx->min,u,ctx->min);CHKERRQ(ierr); 7187 } 7188 PetscFunctionReturn(0); 7189 } 7190 7191 /*@C 7192 TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution 7193 7194 Collective on TS 7195 7196 Input Parameter: 7197 . ts - the TS context 7198 7199 Output Parameter: 7200 + max - the maximum values 7201 - min - the minimum values 7202 7203 Notes: 7204 If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored 7205 7206 Level: intermediate 7207 7208 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 7209 @*/ 7210 PetscErrorCode TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min) 7211 { 7212 PetscInt i; 7213 7214 PetscFunctionBegin; 7215 if (max) *max = NULL; 7216 if (min) *min = NULL; 7217 for (i=0; i<ts->numbermonitors; i++) { 7218 if (ts->monitor[i] == TSMonitorEnvelope) { 7219 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i]; 7220 if (max) *max = ctx->max; 7221 if (min) *min = ctx->min; 7222 break; 7223 } 7224 } 7225 PetscFunctionReturn(0); 7226 } 7227 7228 /*@C 7229 TSMonitorEnvelopeCtxDestroy - Destroys a context that was created with TSMonitorEnvelopeCtxCreate(). 7230 7231 Collective on TSMonitorEnvelopeCtx 7232 7233 Input Parameter: 7234 . ctx - the monitor context 7235 7236 Level: intermediate 7237 7238 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep() 7239 @*/ 7240 PetscErrorCode TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx) 7241 { 7242 PetscErrorCode ierr; 7243 7244 PetscFunctionBegin; 7245 ierr = VecDestroy(&(*ctx)->min);CHKERRQ(ierr); 7246 ierr = VecDestroy(&(*ctx)->max);CHKERRQ(ierr); 7247 ierr = PetscFree(*ctx);CHKERRQ(ierr); 7248 PetscFunctionReturn(0); 7249 } 7250 7251 /*@ 7252 TSRestartStep - Flags the solver to restart the next step 7253 7254 Collective on TS 7255 7256 Input Parameter: 7257 . ts - the TS context obtained from TSCreate() 7258 7259 Level: advanced 7260 7261 Notes: 7262 Multistep methods like BDF or Runge-Kutta methods with FSAL property require restarting the solver in the event of 7263 discontinuities. These discontinuities may be introduced as a consequence of explicitly modifications to the solution 7264 vector (which PETSc attempts to detect and handle) or problem coefficients (which PETSc is not able to detect). For 7265 the sake of correctness and maximum safety, users are expected to call TSRestart() whenever they introduce 7266 discontinuities in callback routines (e.g. prestep and poststep routines, or implicit/rhs function routines with 7267 discontinuous source terms). 7268 7269 .seealso: TSSolve(), TSSetPreStep(), TSSetPostStep() 7270 @*/ 7271 PetscErrorCode TSRestartStep(TS ts) 7272 { 7273 PetscFunctionBegin; 7274 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7275 ts->steprestart = PETSC_TRUE; 7276 PetscFunctionReturn(0); 7277 } 7278 7279 /*@ 7280 TSRollBack - Rolls back one time step 7281 7282 Collective on TS 7283 7284 Input Parameter: 7285 . ts - the TS context obtained from TSCreate() 7286 7287 Level: advanced 7288 7289 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate() 7290 @*/ 7291 PetscErrorCode TSRollBack(TS ts) 7292 { 7293 PetscErrorCode ierr; 7294 7295 PetscFunctionBegin; 7296 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7297 if (ts->steprollback) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"TSRollBack already called"); 7298 if (!ts->ops->rollback) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name); 7299 ierr = (*ts->ops->rollback)(ts);CHKERRQ(ierr); 7300 ts->time_step = ts->ptime - ts->ptime_prev; 7301 ts->ptime = ts->ptime_prev; 7302 ts->ptime_prev = ts->ptime_prev_rollback; 7303 ts->steps--; 7304 ts->steprollback = PETSC_TRUE; 7305 PetscFunctionReturn(0); 7306 } 7307 7308 /*@ 7309 TSGetStages - Get the number of stages and stage values 7310 7311 Input Parameter: 7312 . ts - the TS context obtained from TSCreate() 7313 7314 Output Parameters: 7315 + ns - the number of stages 7316 - Y - the current stage vectors 7317 7318 Level: advanced 7319 7320 Notes: Both ns and Y can be NULL. 7321 7322 .seealso: TSCreate() 7323 @*/ 7324 PetscErrorCode TSGetStages(TS ts,PetscInt *ns,Vec **Y) 7325 { 7326 PetscErrorCode ierr; 7327 7328 PetscFunctionBegin; 7329 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7330 if (ns) PetscValidPointer(ns,2); 7331 if (Y) PetscValidPointer(Y,3); 7332 if (!ts->ops->getstages) { 7333 if (ns) *ns = 0; 7334 if (Y) *Y = NULL; 7335 } else { 7336 ierr = (*ts->ops->getstages)(ts,ns,Y);CHKERRQ(ierr); 7337 } 7338 PetscFunctionReturn(0); 7339 } 7340 7341 /*@C 7342 TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity. 7343 7344 Collective on SNES 7345 7346 Input Parameters: 7347 + ts - the TS context 7348 . t - current timestep 7349 . U - state vector 7350 . Udot - time derivative of state vector 7351 . shift - shift to apply, see note below 7352 - ctx - an optional user context 7353 7354 Output Parameters: 7355 + J - Jacobian matrix (not altered in this routine) 7356 - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J) 7357 7358 Level: intermediate 7359 7360 Notes: 7361 If F(t,U,Udot)=0 is the DAE, the required Jacobian is 7362 7363 dF/dU + shift*dF/dUdot 7364 7365 Most users should not need to explicitly call this routine, as it 7366 is used internally within the nonlinear solvers. 7367 7368 This will first try to get the coloring from the DM. If the DM type has no coloring 7369 routine, then it will try to get the coloring from the matrix. This requires that the 7370 matrix have nonzero entries precomputed. 7371 7372 .seealso: TSSetIJacobian(), MatFDColoringCreate(), MatFDColoringSetFunction() 7373 @*/ 7374 PetscErrorCode TSComputeIJacobianDefaultColor(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat J,Mat B,void *ctx) 7375 { 7376 SNES snes; 7377 MatFDColoring color; 7378 PetscBool hascolor, matcolor = PETSC_FALSE; 7379 PetscErrorCode ierr; 7380 7381 PetscFunctionBegin; 7382 ierr = PetscOptionsGetBool(((PetscObject)ts)->options,((PetscObject) ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL);CHKERRQ(ierr); 7383 ierr = PetscObjectQuery((PetscObject) B, "TSMatFDColoring", (PetscObject *) &color);CHKERRQ(ierr); 7384 if (!color) { 7385 DM dm; 7386 ISColoring iscoloring; 7387 7388 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 7389 ierr = DMHasColoring(dm, &hascolor);CHKERRQ(ierr); 7390 if (hascolor && !matcolor) { 7391 ierr = DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring);CHKERRQ(ierr); 7392 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 7393 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 7394 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 7395 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 7396 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 7397 } else { 7398 MatColoring mc; 7399 7400 ierr = MatColoringCreate(B, &mc);CHKERRQ(ierr); 7401 ierr = MatColoringSetDistance(mc, 2);CHKERRQ(ierr); 7402 ierr = MatColoringSetType(mc, MATCOLORINGSL);CHKERRQ(ierr); 7403 ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); 7404 ierr = MatColoringApply(mc, &iscoloring);CHKERRQ(ierr); 7405 ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); 7406 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 7407 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 7408 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 7409 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 7410 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 7411 } 7412 ierr = PetscObjectCompose((PetscObject) B, "TSMatFDColoring", (PetscObject) color);CHKERRQ(ierr); 7413 ierr = PetscObjectDereference((PetscObject) color);CHKERRQ(ierr); 7414 } 7415 ierr = TSGetSNES(ts, &snes);CHKERRQ(ierr); 7416 ierr = MatFDColoringApply(B, color, U, snes);CHKERRQ(ierr); 7417 if (J != B) { 7418 ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7419 ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7420 } 7421 PetscFunctionReturn(0); 7422 } 7423 7424 /*@ 7425 TSSetFunctionDomainError - Set a function that tests if the current state vector is valid 7426 7427 Input Parameters: 7428 + ts - the TS context 7429 - func - function called within TSFunctionDomainError 7430 7431 Calling sequence of func: 7432 $ PetscErrorCode func(TS ts,PetscReal time,Vec state,PetscBool reject) 7433 7434 + ts - the TS context 7435 . time - the current time (of the stage) 7436 . state - the state to check if it is valid 7437 - reject - (output parameter) PETSC_FALSE if the state is acceptable, PETSC_TRUE if not acceptable 7438 7439 Level: intermediate 7440 7441 Notes: 7442 If an implicit ODE solver is being used then, in addition to providing this routine, the 7443 user's code should call SNESSetFunctionDomainError() when domain errors occur during 7444 function evaluations where the functions are provided by TSSetIFunction() or TSSetRHSFunction(). 7445 Use TSGetSNES() to obtain the SNES object 7446 7447 Developer Notes: 7448 The naming of this function is inconsistent with the SNESSetFunctionDomainError() 7449 since one takes a function pointer and the other does not. 7450 7451 .seealso: TSAdaptCheckStage(), TSFunctionDomainError(), SNESSetFunctionDomainError(), TSGetSNES() 7452 @*/ 7453 7454 PetscErrorCode TSSetFunctionDomainError(TS ts, PetscErrorCode (*func)(TS,PetscReal,Vec,PetscBool*)) 7455 { 7456 PetscFunctionBegin; 7457 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7458 ts->functiondomainerror = func; 7459 PetscFunctionReturn(0); 7460 } 7461 7462 /*@ 7463 TSFunctionDomainError - Checks if the current state is valid 7464 7465 Input Parameters: 7466 + ts - the TS context 7467 . stagetime - time of the simulation 7468 - Y - state vector to check. 7469 7470 Output Parameter: 7471 . accept - Set to PETSC_FALSE if the current state vector is valid. 7472 7473 Note: 7474 This function is called by the TS integration routines and calls the user provided function (set with TSSetFunctionDomainError()) 7475 to check if the current state is valid. 7476 7477 Level: developer 7478 7479 .seealso: TSSetFunctionDomainError() 7480 @*/ 7481 PetscErrorCode TSFunctionDomainError(TS ts,PetscReal stagetime,Vec Y,PetscBool* accept) 7482 { 7483 PetscFunctionBegin; 7484 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7485 *accept = PETSC_TRUE; 7486 if (ts->functiondomainerror) { 7487 PetscStackCallStandard((*ts->functiondomainerror),(ts,stagetime,Y,accept)); 7488 } 7489 PetscFunctionReturn(0); 7490 } 7491 7492 /*@C 7493 TSClone - This function clones a time step object. 7494 7495 Collective 7496 7497 Input Parameter: 7498 . tsin - The input TS 7499 7500 Output Parameter: 7501 . tsout - The output TS (cloned) 7502 7503 Notes: 7504 This function is used to create a clone of a TS object. It is used in ARKIMEX for initializing the slope for first stage explicit methods. It will likely be replaced in the future with a mechanism of switching methods on the fly. 7505 7506 When using TSDestroy() on a clone the user has to first reset the correct TS reference in the embedded SNES object: e.g.: by running SNES snes_dup=NULL; TSGetSNES(ts,&snes_dup); TSSetSNES(ts,snes_dup); 7507 7508 Level: developer 7509 7510 .seealso: TSCreate(), TSSetType(), TSSetUp(), TSDestroy(), TSSetProblemType() 7511 @*/ 7512 PetscErrorCode TSClone(TS tsin, TS *tsout) 7513 { 7514 TS t; 7515 PetscErrorCode ierr; 7516 SNES snes_start; 7517 DM dm; 7518 TSType type; 7519 7520 PetscFunctionBegin; 7521 PetscValidPointer(tsin,1); 7522 *tsout = NULL; 7523 7524 ierr = PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView);CHKERRQ(ierr); 7525 7526 /* General TS description */ 7527 t->numbermonitors = 0; 7528 t->setupcalled = 0; 7529 t->ksp_its = 0; 7530 t->snes_its = 0; 7531 t->nwork = 0; 7532 t->rhsjacobian.time = PETSC_MIN_REAL; 7533 t->rhsjacobian.scale = 1.; 7534 t->ijacobian.shift = 1.; 7535 7536 ierr = TSGetSNES(tsin,&snes_start);CHKERRQ(ierr); 7537 ierr = TSSetSNES(t,snes_start);CHKERRQ(ierr); 7538 7539 ierr = TSGetDM(tsin,&dm);CHKERRQ(ierr); 7540 ierr = TSSetDM(t,dm);CHKERRQ(ierr); 7541 7542 t->adapt = tsin->adapt; 7543 ierr = PetscObjectReference((PetscObject)t->adapt);CHKERRQ(ierr); 7544 7545 t->trajectory = tsin->trajectory; 7546 ierr = PetscObjectReference((PetscObject)t->trajectory);CHKERRQ(ierr); 7547 7548 t->event = tsin->event; 7549 if (t->event) t->event->refct++; 7550 7551 t->problem_type = tsin->problem_type; 7552 t->ptime = tsin->ptime; 7553 t->ptime_prev = tsin->ptime_prev; 7554 t->time_step = tsin->time_step; 7555 t->max_time = tsin->max_time; 7556 t->steps = tsin->steps; 7557 t->max_steps = tsin->max_steps; 7558 t->equation_type = tsin->equation_type; 7559 t->atol = tsin->atol; 7560 t->rtol = tsin->rtol; 7561 t->max_snes_failures = tsin->max_snes_failures; 7562 t->max_reject = tsin->max_reject; 7563 t->errorifstepfailed = tsin->errorifstepfailed; 7564 7565 ierr = TSGetType(tsin,&type);CHKERRQ(ierr); 7566 ierr = TSSetType(t,type);CHKERRQ(ierr); 7567 7568 t->vec_sol = NULL; 7569 7570 t->cfltime = tsin->cfltime; 7571 t->cfltime_local = tsin->cfltime_local; 7572 t->exact_final_time = tsin->exact_final_time; 7573 7574 ierr = PetscMemcpy(t->ops,tsin->ops,sizeof(struct _TSOps));CHKERRQ(ierr); 7575 7576 if (((PetscObject)tsin)->fortran_func_pointers) { 7577 PetscInt i; 7578 ierr = PetscMalloc((10)*sizeof(void(*)(void)),&((PetscObject)t)->fortran_func_pointers);CHKERRQ(ierr); 7579 for (i=0; i<10; i++) { 7580 ((PetscObject)t)->fortran_func_pointers[i] = ((PetscObject)tsin)->fortran_func_pointers[i]; 7581 } 7582 } 7583 *tsout = t; 7584 PetscFunctionReturn(0); 7585 } 7586 7587 static PetscErrorCode RHSWrapperFunction_TSRHSJacobianTest(void* ctx,Vec x,Vec y) 7588 { 7589 PetscErrorCode ierr; 7590 TS ts = (TS) ctx; 7591 7592 PetscFunctionBegin; 7593 ierr = TSComputeRHSFunction(ts,0,x,y);CHKERRQ(ierr); 7594 PetscFunctionReturn(0); 7595 } 7596 7597 /*@ 7598 TSRHSJacobianTest - Compares the multiply routine provided to the MATSHELL with differencing on the TS given RHS function. 7599 7600 Logically Collective on TS 7601 7602 Input Parameters: 7603 TS - the time stepping routine 7604 7605 Output Parameter: 7606 . flg - PETSC_TRUE if the multiply is likely correct 7607 7608 Options Database: 7609 . -ts_rhs_jacobian_test_mult -mat_shell_test_mult_view - run the test at each timestep of the integrator 7610 7611 Level: advanced 7612 7613 Notes: 7614 This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian 7615 7616 .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellTestMultTranspose(), TSRHSJacobianTestTranspose() 7617 @*/ 7618 PetscErrorCode TSRHSJacobianTest(TS ts,PetscBool *flg) 7619 { 7620 Mat J,B; 7621 PetscErrorCode ierr; 7622 TSRHSJacobian func; 7623 void* ctx; 7624 7625 PetscFunctionBegin; 7626 ierr = TSGetRHSJacobian(ts,&J,&B,&func,&ctx);CHKERRQ(ierr); 7627 ierr = (*func)(ts,0.0,ts->vec_sol,J,B,ctx);CHKERRQ(ierr); 7628 ierr = MatShellTestMult(J,RHSWrapperFunction_TSRHSJacobianTest,ts->vec_sol,ts,flg);CHKERRQ(ierr); 7629 PetscFunctionReturn(0); 7630 } 7631 7632 /*@C 7633 TSRHSJacobianTestTranspose - Compares the multiply transpose routine provided to the MATSHELL with differencing on the TS given RHS function. 7634 7635 Logically Collective on TS 7636 7637 Input Parameters: 7638 TS - the time stepping routine 7639 7640 Output Parameter: 7641 . flg - PETSC_TRUE if the multiply is likely correct 7642 7643 Options Database: 7644 . -ts_rhs_jacobian_test_mult_transpose -mat_shell_test_mult_transpose_view - run the test at each timestep of the integrator 7645 7646 Notes: 7647 This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian 7648 7649 Level: advanced 7650 7651 .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellTestMultTranspose(), TSRHSJacobianTest() 7652 @*/ 7653 PetscErrorCode TSRHSJacobianTestTranspose(TS ts,PetscBool *flg) 7654 { 7655 Mat J,B; 7656 PetscErrorCode ierr; 7657 void *ctx; 7658 TSRHSJacobian func; 7659 7660 PetscFunctionBegin; 7661 ierr = TSGetRHSJacobian(ts,&J,&B,&func,&ctx);CHKERRQ(ierr); 7662 ierr = (*func)(ts,0.0,ts->vec_sol,J,B,ctx);CHKERRQ(ierr); 7663 ierr = MatShellTestMultTranspose(J,RHSWrapperFunction_TSRHSJacobianTest,ts->vec_sol,ts,flg);CHKERRQ(ierr); 7664 PetscFunctionReturn(0); 7665 } 7666 7667 /*@ 7668 TSSetUseSplitRHSFunction - Use the split RHSFunction when a multirate method is used. 7669 7670 Logically collective 7671 7672 Input Parameter: 7673 + ts - timestepping context 7674 - use_splitrhsfunction - PETSC_TRUE indicates that the split RHSFunction will be used 7675 7676 Options Database: 7677 . -ts_use_splitrhsfunction - <true,false> 7678 7679 Notes: 7680 This is only useful for multirate methods 7681 7682 Level: intermediate 7683 7684 .seealso: TSGetUseSplitRHSFunction() 7685 @*/ 7686 PetscErrorCode TSSetUseSplitRHSFunction(TS ts, PetscBool use_splitrhsfunction) 7687 { 7688 PetscFunctionBegin; 7689 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7690 ts->use_splitrhsfunction = use_splitrhsfunction; 7691 PetscFunctionReturn(0); 7692 } 7693 7694 /*@ 7695 TSGetUseSplitRHSFunction - Gets whether to use the split RHSFunction when a multirate method is used. 7696 7697 Not collective 7698 7699 Input Parameter: 7700 . ts - timestepping context 7701 7702 Output Parameter: 7703 . use_splitrhsfunction - PETSC_TRUE indicates that the split RHSFunction will be used 7704 7705 Level: intermediate 7706 7707 .seealso: TSSetUseSplitRHSFunction() 7708 @*/ 7709 PetscErrorCode TSGetUseSplitRHSFunction(TS ts, PetscBool *use_splitrhsfunction) 7710 { 7711 PetscFunctionBegin; 7712 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7713 *use_splitrhsfunction = ts->use_splitrhsfunction; 7714 PetscFunctionReturn(0); 7715 } 7716