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