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