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 if (n != 4) SETERRQ(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 if (!monfilename[0]) SETERRQ(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 if (!ptr) SETERRQ(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 if (!ptr2 && (*ptr < '0' || '9' < *ptr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Invalid file template argument to -ts_monitor_solution_vtk, should look like filename-%%03D.vts"); 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 if (dir[1] != '=') SETERRQ1(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 SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir); 323 sscanf(dir+2,"%d",&ray); 324 325 ierr = PetscInfo2(((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 if (dir[1] != '=') SETERRQ1(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 SETERRQ1(PetscObjectComm((PetscObject) ts), PETSC_ERR_ARG_WRONG, "Unknown ray direction %s", dir); 348 sscanf(dir+2, "%d", &ray); 349 350 ierr = PetscInfo2(((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 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 if (ts->rhsjacobian.shift && ts->rhsjacobian.reuse) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Should not call TSComputeRHSJacobian() on a shifted matrix (shift=%lf) when RHSJacobian is reusable.",ts->rhsjacobian.shift); 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 if (!rhsfunction && !ifunction) SETERRQ(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 if (!rhsfunction && !ifunction) SETERRQ(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 if (A != ts->Arhs) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Invalid Amat"); 882 if (B != ts->Brhs) SETERRQ(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 if (!rhsjacobian && !ijacobian) SETERRQ(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 if (rhsjacobian == TSComputeRHSJacobianConstant) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Unsupported operation! cannot use TSComputeRHSJacobianConstant"); /* there is no way to reconstruct shift*M-J since J cannot be reevaluated */ 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 if (!isbinary) SETERRQ(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 if (classid != TS_FILE_CLASSID) SETERRQ(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 if (steps < 0) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Step number must be non-negative"); 2311 ts->steps = steps; 2312 PetscFunctionReturn(0); 2313 } 2314 2315 /*@ 2316 TSSetTimeStep - Allows one to reset the timestep at any time, 2317 useful for simple pseudo-timestepping codes. 2318 2319 Logically Collective on TS 2320 2321 Input Parameters: 2322 + ts - the TS context obtained from TSCreate() 2323 - time_step - the size of the timestep 2324 2325 Level: intermediate 2326 2327 .seealso: TSGetTimeStep(), TSSetTime() 2328 2329 @*/ 2330 PetscErrorCode TSSetTimeStep(TS ts,PetscReal time_step) 2331 { 2332 PetscFunctionBegin; 2333 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2334 PetscValidLogicalCollectiveReal(ts,time_step,2); 2335 ts->time_step = time_step; 2336 PetscFunctionReturn(0); 2337 } 2338 2339 /*@ 2340 TSSetExactFinalTime - Determines whether to adapt the final time step to 2341 match the exact final time, interpolate solution to the exact final time, 2342 or just return at the final time TS computed. 2343 2344 Logically Collective on TS 2345 2346 Input 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 if (!ts->setupcalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetUp() first"); 2572 if (ts->ops->settimeerror) { 2573 ierr = (*ts->ops->settimeerror)(ts,v);CHKERRQ(ierr); 2574 } 2575 PetscFunctionReturn(0); 2576 } 2577 2578 /* ----- Routines to initialize and destroy a timestepper ---- */ 2579 /*@ 2580 TSSetProblemType - Sets the type of problem to be solved. 2581 2582 Not collective 2583 2584 Input Parameters: 2585 + ts - The TS 2586 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 2587 .vb 2588 U_t - A U = 0 (linear) 2589 U_t - A(t) U = 0 (linear) 2590 F(t,U,U_t) = 0 (nonlinear) 2591 .ve 2592 2593 Level: beginner 2594 2595 .seealso: TSSetUp(), TSProblemType, TS 2596 @*/ 2597 PetscErrorCode TSSetProblemType(TS ts, TSProblemType type) 2598 { 2599 PetscErrorCode ierr; 2600 2601 PetscFunctionBegin; 2602 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2603 ts->problem_type = type; 2604 if (type == TS_LINEAR) { 2605 SNES snes; 2606 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2607 ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr); 2608 } 2609 PetscFunctionReturn(0); 2610 } 2611 2612 /*@C 2613 TSGetProblemType - Gets the type of problem to be solved. 2614 2615 Not collective 2616 2617 Input Parameter: 2618 . ts - The TS 2619 2620 Output Parameter: 2621 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 2622 .vb 2623 M U_t = A U 2624 M(t) U_t = A(t) U 2625 F(t,U,U_t) 2626 .ve 2627 2628 Level: beginner 2629 2630 .seealso: TSSetUp(), TSProblemType, TS 2631 @*/ 2632 PetscErrorCode TSGetProblemType(TS ts, TSProblemType *type) 2633 { 2634 PetscFunctionBegin; 2635 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2636 PetscValidIntPointer(type,2); 2637 *type = ts->problem_type; 2638 PetscFunctionReturn(0); 2639 } 2640 2641 /* 2642 Attempt to check/preset a default value for the exact final time option. This is needed at the beginning of TSSolve() and in TSSetUp() 2643 */ 2644 static PetscErrorCode TSSetExactFinalTimeDefault(TS ts) 2645 { 2646 PetscErrorCode ierr; 2647 PetscBool isnone; 2648 2649 PetscFunctionBegin; 2650 ierr = TSGetAdapt(ts,&ts->adapt);CHKERRQ(ierr); 2651 ierr = TSAdaptSetDefaultType(ts->adapt,ts->default_adapt_type);CHKERRQ(ierr); 2652 2653 ierr = PetscObjectTypeCompare((PetscObject)ts->adapt,TSADAPTNONE,&isnone);CHKERRQ(ierr); 2654 if (!isnone && ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) { 2655 ts->exact_final_time = TS_EXACTFINALTIME_MATCHSTEP; 2656 } else if (ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) { 2657 ts->exact_final_time = TS_EXACTFINALTIME_INTERPOLATE; 2658 } 2659 PetscFunctionReturn(0); 2660 } 2661 2662 /*@ 2663 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 if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first"); 2993 if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()"); 2994 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2995 ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr); 2996 PetscFunctionReturn(0); 2997 } 2998 2999 /* ----------- Routines to set solver parameters ---------- */ 3000 3001 /*@ 3002 TSSetMaxSteps - Sets the maximum number of steps to use. 3003 3004 Logically Collective on TS 3005 3006 Input Parameters: 3007 + ts - the TS context obtained from TSCreate() 3008 - maxsteps - maximum number of steps to use 3009 3010 Options Database Keys: 3011 . -ts_max_steps <maxsteps> - Sets maxsteps 3012 3013 Notes: 3014 The default maximum number of steps is 5000 3015 3016 Level: intermediate 3017 3018 .seealso: TSGetMaxSteps(), TSSetMaxTime(), TSSetExactFinalTime() 3019 @*/ 3020 PetscErrorCode TSSetMaxSteps(TS ts,PetscInt maxsteps) 3021 { 3022 PetscFunctionBegin; 3023 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3024 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 3025 if (maxsteps < 0) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of steps must be non-negative"); 3026 ts->max_steps = maxsteps; 3027 PetscFunctionReturn(0); 3028 } 3029 3030 /*@ 3031 TSGetMaxSteps - Gets the maximum number of steps to use. 3032 3033 Not Collective 3034 3035 Input Parameters: 3036 . ts - the TS context obtained from TSCreate() 3037 3038 Output Parameter: 3039 . maxsteps - maximum number of steps to use 3040 3041 Level: advanced 3042 3043 .seealso: TSSetMaxSteps(), TSGetMaxTime(), TSSetMaxTime() 3044 @*/ 3045 PetscErrorCode TSGetMaxSteps(TS ts,PetscInt *maxsteps) 3046 { 3047 PetscFunctionBegin; 3048 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3049 PetscValidIntPointer(maxsteps,2); 3050 *maxsteps = ts->max_steps; 3051 PetscFunctionReturn(0); 3052 } 3053 3054 /*@ 3055 TSSetMaxTime - Sets the maximum (or final) time for timestepping. 3056 3057 Logically Collective on TS 3058 3059 Input Parameters: 3060 + ts - the TS context obtained from TSCreate() 3061 - maxtime - final time to step to 3062 3063 Options Database Keys: 3064 . -ts_max_time <maxtime> - Sets maxtime 3065 3066 Notes: 3067 The default maximum time is 5.0 3068 3069 Level: intermediate 3070 3071 .seealso: TSGetMaxTime(), TSSetMaxSteps(), TSSetExactFinalTime() 3072 @*/ 3073 PetscErrorCode TSSetMaxTime(TS ts,PetscReal maxtime) 3074 { 3075 PetscFunctionBegin; 3076 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3077 PetscValidLogicalCollectiveReal(ts,maxtime,2); 3078 ts->max_time = maxtime; 3079 PetscFunctionReturn(0); 3080 } 3081 3082 /*@ 3083 TSGetMaxTime - Gets the maximum (or final) time for timestepping. 3084 3085 Not Collective 3086 3087 Input Parameters: 3088 . ts - the TS context obtained from TSCreate() 3089 3090 Output Parameter: 3091 . maxtime - final time to step to 3092 3093 Level: advanced 3094 3095 .seealso: TSSetMaxTime(), TSGetMaxSteps(), TSSetMaxSteps() 3096 @*/ 3097 PetscErrorCode TSGetMaxTime(TS ts,PetscReal *maxtime) 3098 { 3099 PetscFunctionBegin; 3100 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3101 PetscValidRealPointer(maxtime,2); 3102 *maxtime = ts->max_time; 3103 PetscFunctionReturn(0); 3104 } 3105 3106 /*@ 3107 TSSetInitialTimeStep - Deprecated, use TSSetTime() and TSSetTimeStep(). 3108 3109 Level: deprecated 3110 3111 @*/ 3112 PetscErrorCode TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step) 3113 { 3114 PetscErrorCode ierr; 3115 PetscFunctionBegin; 3116 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3117 ierr = TSSetTime(ts,initial_time);CHKERRQ(ierr); 3118 ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr); 3119 PetscFunctionReturn(0); 3120 } 3121 3122 /*@ 3123 TSGetDuration - Deprecated, use TSGetMaxSteps() and TSGetMaxTime(). 3124 3125 Level: deprecated 3126 3127 @*/ 3128 PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime) 3129 { 3130 PetscFunctionBegin; 3131 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3132 if (maxsteps) { 3133 PetscValidIntPointer(maxsteps,2); 3134 *maxsteps = ts->max_steps; 3135 } 3136 if (maxtime) { 3137 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 . PetscErrorCode func (TS ts); 3219 3220 Level: intermediate 3221 3222 .seealso: TSSetPreStage(), TSSetPostStage(), TSSetPostStep(), TSStep(), TSRestartStep() 3223 @*/ 3224 PetscErrorCode TSSetPreStep(TS ts, PetscErrorCode (*func)(TS)) 3225 { 3226 PetscFunctionBegin; 3227 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3228 ts->prestep = func; 3229 PetscFunctionReturn(0); 3230 } 3231 3232 /*@ 3233 TSPreStep - Runs the user-defined pre-step function. 3234 3235 Collective on TS 3236 3237 Input Parameters: 3238 . ts - The TS context obtained from TSCreate() 3239 3240 Notes: 3241 TSPreStep() is typically used within time stepping implementations, 3242 so most users would not generally call this routine themselves. 3243 3244 Level: developer 3245 3246 .seealso: TSSetPreStep(), TSPreStage(), TSPostStage(), TSPostStep() 3247 @*/ 3248 PetscErrorCode TSPreStep(TS ts) 3249 { 3250 PetscErrorCode ierr; 3251 3252 PetscFunctionBegin; 3253 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3254 if (ts->prestep) { 3255 Vec U; 3256 PetscObjectId idprev; 3257 PetscBool sameObject; 3258 PetscObjectState sprev,spost; 3259 3260 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3261 ierr = PetscObjectGetId((PetscObject)U,&idprev);CHKERRQ(ierr); 3262 ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr); 3263 PetscStackCallStandard((*ts->prestep),(ts)); 3264 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3265 ierr = PetscObjectCompareId((PetscObject)U,idprev,&sameObject);CHKERRQ(ierr); 3266 ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr); 3267 if (!sameObject || sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);} 3268 } 3269 PetscFunctionReturn(0); 3270 } 3271 3272 /*@C 3273 TSSetPreStage - Sets the general-purpose function 3274 called once at the beginning of each stage. 3275 3276 Logically Collective on TS 3277 3278 Input Parameters: 3279 + ts - The TS context obtained from TSCreate() 3280 - func - The function 3281 3282 Calling sequence of func: 3283 . PetscErrorCode func(TS ts, PetscReal stagetime); 3284 3285 Level: intermediate 3286 3287 Note: 3288 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 3289 The time step number being computed can be queried using TSGetStepNumber() and the total size of the step being 3290 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 3291 3292 .seealso: TSSetPostStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3293 @*/ 3294 PetscErrorCode TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal)) 3295 { 3296 PetscFunctionBegin; 3297 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3298 ts->prestage = func; 3299 PetscFunctionReturn(0); 3300 } 3301 3302 /*@C 3303 TSSetPostStage - Sets the general-purpose function 3304 called once at the end of each stage. 3305 3306 Logically Collective on TS 3307 3308 Input Parameters: 3309 + ts - The TS context obtained from TSCreate() 3310 - func - The function 3311 3312 Calling sequence of func: 3313 . PetscErrorCode func(TS ts, PetscReal stagetime, PetscInt stageindex, Vec* Y); 3314 3315 Level: intermediate 3316 3317 Note: 3318 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 3319 The time step number being computed can be queried using TSGetStepNumber() and the total size of the step being 3320 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 3321 3322 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3323 @*/ 3324 PetscErrorCode TSSetPostStage(TS ts, PetscErrorCode (*func)(TS,PetscReal,PetscInt,Vec*)) 3325 { 3326 PetscFunctionBegin; 3327 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3328 ts->poststage = func; 3329 PetscFunctionReturn(0); 3330 } 3331 3332 /*@C 3333 TSSetPostEvaluate - Sets the general-purpose function 3334 called once at the end of each step evaluation. 3335 3336 Logically Collective on TS 3337 3338 Input Parameters: 3339 + ts - The TS context obtained from TSCreate() 3340 - func - The function 3341 3342 Calling sequence of func: 3343 . PetscErrorCode func(TS ts); 3344 3345 Level: intermediate 3346 3347 Note: 3348 Semantically, TSSetPostEvaluate() differs from TSSetPostStep() since the function it sets is called before event-handling 3349 thus guaranteeing the same solution (computed by the time-stepper) will be passed to it. On the other hand, TSPostStep() 3350 may be passed a different solution, possibly changed by the event handler. TSPostEvaluate() is called after the next step 3351 solution is evaluated allowing to modify it, if need be. The solution can be obtained with TSGetSolution(), the time step 3352 with TSGetTimeStep(), and the time at the start of the step is available via TSGetTime() 3353 3354 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3355 @*/ 3356 PetscErrorCode TSSetPostEvaluate(TS ts, PetscErrorCode (*func)(TS)) 3357 { 3358 PetscFunctionBegin; 3359 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3360 ts->postevaluate = func; 3361 PetscFunctionReturn(0); 3362 } 3363 3364 /*@ 3365 TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage() 3366 3367 Collective on TS 3368 3369 Input Parameters: 3370 . ts - The TS context obtained from TSCreate() 3371 stagetime - The absolute time of the current stage 3372 3373 Notes: 3374 TSPreStage() is typically used within time stepping implementations, 3375 most users would not generally call this routine themselves. 3376 3377 Level: developer 3378 3379 .seealso: TSPostStage(), TSSetPreStep(), TSPreStep(), TSPostStep() 3380 @*/ 3381 PetscErrorCode TSPreStage(TS ts, PetscReal stagetime) 3382 { 3383 PetscFunctionBegin; 3384 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3385 if (ts->prestage) { 3386 PetscStackCallStandard((*ts->prestage),(ts,stagetime)); 3387 } 3388 PetscFunctionReturn(0); 3389 } 3390 3391 /*@ 3392 TSPostStage - Runs the user-defined post-stage function set using TSSetPostStage() 3393 3394 Collective on TS 3395 3396 Input Parameters: 3397 . ts - The TS context obtained from TSCreate() 3398 stagetime - The absolute time of the current stage 3399 stageindex - Stage number 3400 Y - Array of vectors (of size = total number 3401 of stages) with the stage solutions 3402 3403 Notes: 3404 TSPostStage() is typically used within time stepping implementations, 3405 most users would not generally call this routine themselves. 3406 3407 Level: developer 3408 3409 .seealso: TSPreStage(), TSSetPreStep(), TSPreStep(), TSPostStep() 3410 @*/ 3411 PetscErrorCode TSPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y) 3412 { 3413 PetscFunctionBegin; 3414 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3415 if (ts->poststage) { 3416 PetscStackCallStandard((*ts->poststage),(ts,stagetime,stageindex,Y)); 3417 } 3418 PetscFunctionReturn(0); 3419 } 3420 3421 /*@ 3422 TSPostEvaluate - Runs the user-defined post-evaluate function set using TSSetPostEvaluate() 3423 3424 Collective on TS 3425 3426 Input Parameters: 3427 . ts - The TS context obtained from TSCreate() 3428 3429 Notes: 3430 TSPostEvaluate() is typically used within time stepping implementations, 3431 most users would not generally call this routine themselves. 3432 3433 Level: developer 3434 3435 .seealso: TSSetPostEvaluate(), TSSetPreStep(), TSPreStep(), TSPostStep() 3436 @*/ 3437 PetscErrorCode TSPostEvaluate(TS ts) 3438 { 3439 PetscErrorCode ierr; 3440 3441 PetscFunctionBegin; 3442 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3443 if (ts->postevaluate) { 3444 Vec U; 3445 PetscObjectState sprev,spost; 3446 3447 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3448 ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr); 3449 PetscStackCallStandard((*ts->postevaluate),(ts)); 3450 ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr); 3451 if (sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);} 3452 } 3453 PetscFunctionReturn(0); 3454 } 3455 3456 /*@C 3457 TSSetPostStep - Sets the general-purpose function 3458 called once at the end of each time step. 3459 3460 Logically Collective on TS 3461 3462 Input Parameters: 3463 + ts - The TS context obtained from TSCreate() 3464 - func - The function 3465 3466 Calling sequence of func: 3467 $ func (TS ts); 3468 3469 Notes: 3470 The function set by TSSetPostStep() is called after each successful step. The solution vector X 3471 obtained by TSGetSolution() may be different than that computed at the step end if the event handler 3472 locates an event and TSPostEvent() modifies it. Use TSSetPostEvaluate() if an unmodified solution is needed instead. 3473 3474 Level: intermediate 3475 3476 .seealso: TSSetPreStep(), TSSetPreStage(), TSSetPostEvaluate(), TSGetTimeStep(), TSGetStepNumber(), TSGetTime(), TSRestartStep() 3477 @*/ 3478 PetscErrorCode TSSetPostStep(TS ts, PetscErrorCode (*func)(TS)) 3479 { 3480 PetscFunctionBegin; 3481 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3482 ts->poststep = func; 3483 PetscFunctionReturn(0); 3484 } 3485 3486 /*@ 3487 TSPostStep - Runs the user-defined post-step function. 3488 3489 Collective on TS 3490 3491 Input Parameters: 3492 . ts - The TS context obtained from TSCreate() 3493 3494 Notes: 3495 TSPostStep() is typically used within time stepping implementations, 3496 so most users would not generally call this routine themselves. 3497 3498 Level: developer 3499 3500 @*/ 3501 PetscErrorCode TSPostStep(TS ts) 3502 { 3503 PetscErrorCode ierr; 3504 3505 PetscFunctionBegin; 3506 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3507 if (ts->poststep) { 3508 Vec U; 3509 PetscObjectId idprev; 3510 PetscBool sameObject; 3511 PetscObjectState sprev,spost; 3512 3513 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3514 ierr = PetscObjectGetId((PetscObject)U,&idprev);CHKERRQ(ierr); 3515 ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr); 3516 PetscStackCallStandard((*ts->poststep),(ts)); 3517 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3518 ierr = PetscObjectCompareId((PetscObject)U,idprev,&sameObject);CHKERRQ(ierr); 3519 ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr); 3520 if (!sameObject || sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);} 3521 } 3522 PetscFunctionReturn(0); 3523 } 3524 3525 /*@ 3526 TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval 3527 3528 Collective on TS 3529 3530 Input Parameters: 3531 + ts - time stepping context 3532 - t - time to interpolate to 3533 3534 Output Parameter: 3535 . U - state at given time 3536 3537 Level: intermediate 3538 3539 Developer Notes: 3540 TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints. 3541 3542 .seealso: TSSetExactFinalTime(), TSSolve() 3543 @*/ 3544 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U) 3545 { 3546 PetscErrorCode ierr; 3547 3548 PetscFunctionBegin; 3549 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3550 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 3551 if (t < ts->ptime_prev || t > ts->ptime) SETERRQ3(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Requested time %g not in last time steps [%g,%g]",t,(double)ts->ptime_prev,(double)ts->ptime); 3552 if (!ts->ops->interpolate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name); 3553 ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr); 3554 PetscFunctionReturn(0); 3555 } 3556 3557 /*@ 3558 TSStep - Steps one time step 3559 3560 Collective on TS 3561 3562 Input Parameter: 3563 . ts - the TS context obtained from TSCreate() 3564 3565 Level: developer 3566 3567 Notes: 3568 The public interface for the ODE/DAE solvers is TSSolve(), you should almost for sure be using that routine and not this routine. 3569 3570 The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may 3571 be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages. 3572 3573 This may over-step the final time provided in TSSetMaxTime() depending on the time-step used. TSSolve() interpolates to exactly the 3574 time provided in TSSetMaxTime(). One can use TSInterpolate() to determine an interpolated solution within the final timestep. 3575 3576 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSInterpolate() 3577 @*/ 3578 PetscErrorCode TSStep(TS ts) 3579 { 3580 PetscErrorCode ierr; 3581 static PetscBool cite = PETSC_FALSE; 3582 PetscReal ptime; 3583 3584 PetscFunctionBegin; 3585 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3586 ierr = PetscCitationsRegister("@article{tspaper,\n" 3587 " title = {{PETSc/TS}: A Modern Scalable {DAE/ODE} Solver Library},\n" 3588 " author = {Abhyankar, Shrirang and Brown, Jed and Constantinescu, Emil and Ghosh, Debojyoti and Smith, Barry F. and Zhang, Hong},\n" 3589 " journal = {arXiv e-preprints},\n" 3590 " eprint = {1806.01437},\n" 3591 " archivePrefix = {arXiv},\n" 3592 " year = {2018}\n}\n",&cite);CHKERRQ(ierr); 3593 3594 ierr = TSSetUp(ts);CHKERRQ(ierr); 3595 ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr); 3596 3597 if (!ts->ops->step) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSStep not implemented for type '%s'",((PetscObject)ts)->type_name); 3598 if (ts->max_time >= PETSC_MAX_REAL && ts->max_steps == PETSC_MAX_INT) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"You must call TSSetMaxTime() or TSSetMaxSteps(), or use -ts_max_time <time> or -ts_max_steps <steps>"); 3599 if (ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"You must call TSSetExactFinalTime() or use -ts_exact_final_time <stepover,interpolate,matchstep> before calling TSStep()"); 3600 if (ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP && !ts->adapt) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Since TS is not adaptive you cannot use TS_EXACTFINALTIME_MATCHSTEP, suggest TS_EXACTFINALTIME_INTERPOLATE"); 3601 3602 if (!ts->steps) ts->ptime_prev = ts->ptime; 3603 ptime = ts->ptime; ts->ptime_prev_rollback = ts->ptime_prev; 3604 ts->reason = TS_CONVERGED_ITERATING; 3605 3606 ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3607 ierr = (*ts->ops->step)(ts);CHKERRQ(ierr); 3608 ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3609 3610 if (ts->reason >= 0) { 3611 ts->ptime_prev = ptime; 3612 ts->steps++; 3613 ts->steprollback = PETSC_FALSE; 3614 ts->steprestart = PETSC_FALSE; 3615 } 3616 3617 if (!ts->reason) { 3618 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 3619 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 3620 } 3621 3622 if (ts->reason < 0 && ts->errorifstepfailed && ts->reason == TS_DIVERGED_NONLINEAR_SOLVE) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s, increase -ts_max_snes_failures or make negative to attempt recovery",TSConvergedReasons[ts->reason]); 3623 if (ts->reason < 0 && ts->errorifstepfailed) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]); 3624 PetscFunctionReturn(0); 3625 } 3626 3627 /*@ 3628 TSEvaluateWLTE - Evaluate the weighted local truncation error norm 3629 at the end of a time step with a given order of accuracy. 3630 3631 Collective on TS 3632 3633 Input Parameters: 3634 + ts - time stepping context 3635 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 3636 3637 Input/Output Parameter: 3638 . order - optional, desired order for the error evaluation or PETSC_DECIDE; 3639 on output, the actual order of the error evaluation 3640 3641 Output Parameter: 3642 . wlte - the weighted local truncation error norm 3643 3644 Level: advanced 3645 3646 Notes: 3647 If the timestepper cannot evaluate the error in a particular step 3648 (eg. in the first step or restart steps after event handling), 3649 this routine returns wlte=-1.0 . 3650 3651 .seealso: TSStep(), TSAdapt, TSErrorWeightedNorm() 3652 @*/ 3653 PetscErrorCode TSEvaluateWLTE(TS ts,NormType wnormtype,PetscInt *order,PetscReal *wlte) 3654 { 3655 PetscErrorCode ierr; 3656 3657 PetscFunctionBegin; 3658 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3659 PetscValidType(ts,1); 3660 PetscValidLogicalCollectiveEnum(ts,wnormtype,2); 3661 if (order) PetscValidIntPointer(order,3); 3662 if (order) PetscValidLogicalCollectiveInt(ts,*order,3); 3663 PetscValidRealPointer(wlte,4); 3664 if (wnormtype != NORM_2 && wnormtype != NORM_INFINITY) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 3665 if (!ts->ops->evaluatewlte) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateWLTE not implemented for type '%s'",((PetscObject)ts)->type_name); 3666 ierr = (*ts->ops->evaluatewlte)(ts,wnormtype,order,wlte);CHKERRQ(ierr); 3667 PetscFunctionReturn(0); 3668 } 3669 3670 /*@ 3671 TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy. 3672 3673 Collective on TS 3674 3675 Input Parameters: 3676 + ts - time stepping context 3677 . order - desired order of accuracy 3678 - done - whether the step was evaluated at this order (pass NULL to generate an error if not available) 3679 3680 Output Parameter: 3681 . U - state at the end of the current step 3682 3683 Level: advanced 3684 3685 Notes: 3686 This function cannot be called until all stages have been evaluated. 3687 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. 3688 3689 .seealso: TSStep(), TSAdapt 3690 @*/ 3691 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done) 3692 { 3693 PetscErrorCode ierr; 3694 3695 PetscFunctionBegin; 3696 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3697 PetscValidType(ts,1); 3698 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 3699 if (!ts->ops->evaluatestep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name); 3700 ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr); 3701 PetscFunctionReturn(0); 3702 } 3703 3704 /*@C 3705 TSGetComputeInitialCondition - Get the function used to automatically compute an initial condition for the timestepping. 3706 3707 Not collective 3708 3709 Input Parameter: 3710 . ts - time stepping context 3711 3712 Output Parameter: 3713 . initConditions - The function which computes an initial condition 3714 3715 Level: advanced 3716 3717 Notes: 3718 The calling sequence for the function is 3719 $ initCondition(TS ts, Vec u) 3720 $ ts - The timestepping context 3721 $ u - The input vector in which the initial condition is stored 3722 3723 .seealso: TSSetComputeInitialCondition(), TSComputeInitialCondition() 3724 @*/ 3725 PetscErrorCode TSGetComputeInitialCondition(TS ts, PetscErrorCode (**initCondition)(TS, Vec)) 3726 { 3727 PetscFunctionBegin; 3728 PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 3729 PetscValidPointer(initCondition, 2); 3730 *initCondition = ts->ops->initcondition; 3731 PetscFunctionReturn(0); 3732 } 3733 3734 /*@C 3735 TSSetComputeInitialCondition - Set the function used to automatically compute an initial condition for the timestepping. 3736 3737 Logically collective on ts 3738 3739 Input Parameters: 3740 + ts - time stepping context 3741 - initCondition - The function which computes an initial condition 3742 3743 Level: advanced 3744 3745 Calling sequence for initCondition: 3746 $ PetscErrorCode initCondition(TS ts, Vec u) 3747 3748 + ts - The timestepping context 3749 - u - The input vector in which the initial condition is to be stored 3750 3751 .seealso: TSGetComputeInitialCondition(), TSComputeInitialCondition() 3752 @*/ 3753 PetscErrorCode TSSetComputeInitialCondition(TS ts, PetscErrorCode (*initCondition)(TS, Vec)) 3754 { 3755 PetscFunctionBegin; 3756 PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 3757 PetscValidFunction(initCondition, 2); 3758 ts->ops->initcondition = initCondition; 3759 PetscFunctionReturn(0); 3760 } 3761 3762 /*@ 3763 TSComputeInitialCondition - Compute an initial condition for the timestepping using the function previously set. 3764 3765 Collective on ts 3766 3767 Input Parameters: 3768 + ts - time stepping context 3769 - u - The Vec to store the condition in which will be used in TSSolve() 3770 3771 Level: advanced 3772 3773 .seealso: TSGetComputeInitialCondition(), TSSetComputeInitialCondition(), TSSolve() 3774 @*/ 3775 PetscErrorCode TSComputeInitialCondition(TS ts, Vec u) 3776 { 3777 PetscErrorCode ierr; 3778 3779 PetscFunctionBegin; 3780 PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 3781 PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 3782 if (ts->ops->initcondition) {ierr = (*ts->ops->initcondition)(ts, u);CHKERRQ(ierr);} 3783 PetscFunctionReturn(0); 3784 } 3785 3786 /*@C 3787 TSGetComputeExactError - Get the function used to automatically compute the exact error for the timestepping. 3788 3789 Not collective 3790 3791 Input Parameter: 3792 . ts - time stepping context 3793 3794 Output Parameter: 3795 . exactError - The function which computes the solution error 3796 3797 Level: advanced 3798 3799 Calling sequence for exactError: 3800 $ PetscErrorCode exactError(TS ts, Vec u) 3801 3802 + ts - The timestepping context 3803 . u - The approximate solution vector 3804 - e - The input vector in which the error is stored 3805 3806 .seealso: TSGetComputeExactError(), TSComputeExactError() 3807 @*/ 3808 PetscErrorCode TSGetComputeExactError(TS ts, PetscErrorCode (**exactError)(TS, Vec, Vec)) 3809 { 3810 PetscFunctionBegin; 3811 PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 3812 PetscValidPointer(exactError, 2); 3813 *exactError = ts->ops->exacterror; 3814 PetscFunctionReturn(0); 3815 } 3816 3817 /*@C 3818 TSSetComputeExactError - Set the function used to automatically compute the exact error for the timestepping. 3819 3820 Logically collective on ts 3821 3822 Input Parameters: 3823 + ts - time stepping context 3824 - exactError - The function which computes the solution error 3825 3826 Level: advanced 3827 3828 Calling sequence for exactError: 3829 $ PetscErrorCode exactError(TS ts, Vec u) 3830 3831 + ts - The timestepping context 3832 . u - The approximate solution vector 3833 - e - The input vector in which the error is stored 3834 3835 .seealso: TSGetComputeExactError(), TSComputeExactError() 3836 @*/ 3837 PetscErrorCode TSSetComputeExactError(TS ts, PetscErrorCode (*exactError)(TS, Vec, Vec)) 3838 { 3839 PetscFunctionBegin; 3840 PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 3841 PetscValidFunction(exactError, 2); 3842 ts->ops->exacterror = exactError; 3843 PetscFunctionReturn(0); 3844 } 3845 3846 /*@ 3847 TSComputeExactError - Compute the solution error for the timestepping using the function previously set. 3848 3849 Collective on ts 3850 3851 Input Parameters: 3852 + ts - time stepping context 3853 . u - The approximate solution 3854 - e - The Vec used to store the error 3855 3856 Level: advanced 3857 3858 .seealso: TSGetComputeInitialCondition(), TSSetComputeInitialCondition(), TSSolve() 3859 @*/ 3860 PetscErrorCode TSComputeExactError(TS ts, Vec u, Vec e) 3861 { 3862 PetscErrorCode ierr; 3863 3864 PetscFunctionBegin; 3865 PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 3866 PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 3867 PetscValidHeaderSpecific(e, VEC_CLASSID, 3); 3868 if (ts->ops->exacterror) {ierr = (*ts->ops->exacterror)(ts, u, e);CHKERRQ(ierr);} 3869 PetscFunctionReturn(0); 3870 } 3871 3872 /*@ 3873 TSSolve - Steps the requested number of timesteps. 3874 3875 Collective on TS 3876 3877 Input Parameters: 3878 + ts - the TS context obtained from TSCreate() 3879 - u - the solution vector (can be null if TSSetSolution() was used and TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP) was not used, 3880 otherwise must contain the initial conditions and will contain the solution at the final requested time 3881 3882 Level: beginner 3883 3884 Notes: 3885 The final time returned by this function may be different from the time of the internally 3886 held state accessible by TSGetSolution() and TSGetTime() because the method may have 3887 stepped over the final time. 3888 3889 .seealso: TSCreate(), TSSetSolution(), TSStep(), TSGetTime(), TSGetSolveTime() 3890 @*/ 3891 PetscErrorCode TSSolve(TS ts,Vec u) 3892 { 3893 Vec solution; 3894 PetscErrorCode ierr; 3895 3896 PetscFunctionBegin; 3897 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3898 if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2); 3899 3900 ierr = TSSetExactFinalTimeDefault(ts);CHKERRQ(ierr); 3901 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 */ 3902 if (!ts->vec_sol || u == ts->vec_sol) { 3903 ierr = VecDuplicate(u,&solution);CHKERRQ(ierr); 3904 ierr = TSSetSolution(ts,solution);CHKERRQ(ierr); 3905 ierr = VecDestroy(&solution);CHKERRQ(ierr); /* grant ownership */ 3906 } 3907 ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr); 3908 if (ts->forward_solve) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Sensitivity analysis does not support the mode TS_EXACTFINALTIME_INTERPOLATE"); 3909 } else if (u) { 3910 ierr = TSSetSolution(ts,u);CHKERRQ(ierr); 3911 } 3912 ierr = TSSetUp(ts);CHKERRQ(ierr); 3913 ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr); 3914 3915 if (ts->max_time >= PETSC_MAX_REAL && ts->max_steps == PETSC_MAX_INT) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"You must call TSSetMaxTime() or TSSetMaxSteps(), or use -ts_max_time <time> or -ts_max_steps <steps>"); 3916 if (ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"You must call TSSetExactFinalTime() or use -ts_exact_final_time <stepover,interpolate,matchstep> before calling TSSolve()"); 3917 if (ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP && !ts->adapt) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Since TS is not adaptive you cannot use TS_EXACTFINALTIME_MATCHSTEP, suggest TS_EXACTFINALTIME_INTERPOLATE"); 3918 3919 if (ts->forward_solve) { 3920 ierr = TSForwardSetUp(ts);CHKERRQ(ierr); 3921 } 3922 3923 /* reset number of steps only when the step is not restarted. ARKIMEX 3924 restarts the step after an event. Resetting these counters in such case causes 3925 TSTrajectory to incorrectly save the output files 3926 */ 3927 /* reset time step and iteration counters */ 3928 if (!ts->steps) { 3929 ts->ksp_its = 0; 3930 ts->snes_its = 0; 3931 ts->num_snes_failures = 0; 3932 ts->reject = 0; 3933 ts->steprestart = PETSC_TRUE; 3934 ts->steprollback = PETSC_FALSE; 3935 ts->rhsjacobian.time = PETSC_MIN_REAL; 3936 } 3937 3938 /* make sure initial time step does not overshoot final time */ 3939 if (ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP) { 3940 PetscReal maxdt = ts->max_time-ts->ptime; 3941 PetscReal dt = ts->time_step; 3942 3943 ts->time_step = dt >= maxdt ? maxdt : (PetscIsCloseAtTol(dt,maxdt,10*PETSC_MACHINE_EPSILON,0) ? maxdt : dt); 3944 } 3945 ts->reason = TS_CONVERGED_ITERATING; 3946 3947 { 3948 PetscViewer viewer; 3949 PetscViewerFormat format; 3950 PetscBool flg; 3951 static PetscBool incall = PETSC_FALSE; 3952 3953 if (!incall) { 3954 /* Estimate the convergence rate of the time discretization */ 3955 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) ts),((PetscObject)ts)->options, ((PetscObject) ts)->prefix, "-ts_convergence_estimate", &viewer, &format, &flg);CHKERRQ(ierr); 3956 if (flg) { 3957 PetscConvEst conv; 3958 DM dm; 3959 PetscReal *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */ 3960 PetscInt Nf; 3961 PetscBool checkTemporal = PETSC_TRUE; 3962 3963 incall = PETSC_TRUE; 3964 ierr = PetscOptionsGetBool(((PetscObject)ts)->options, ((PetscObject) ts)->prefix, "-ts_convergence_temporal", &checkTemporal, &flg);CHKERRQ(ierr); 3965 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 3966 ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 3967 ierr = PetscCalloc1(PetscMax(Nf, 1), &alpha);CHKERRQ(ierr); 3968 ierr = PetscConvEstCreate(PetscObjectComm((PetscObject) ts), &conv);CHKERRQ(ierr); 3969 ierr = PetscConvEstUseTS(conv, checkTemporal);CHKERRQ(ierr); 3970 ierr = PetscConvEstSetSolver(conv, (PetscObject) ts);CHKERRQ(ierr); 3971 ierr = PetscConvEstSetFromOptions(conv);CHKERRQ(ierr); 3972 ierr = PetscConvEstSetUp(conv);CHKERRQ(ierr); 3973 ierr = PetscConvEstGetConvRate(conv, alpha);CHKERRQ(ierr); 3974 ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr); 3975 ierr = PetscConvEstRateView(conv, alpha, viewer);CHKERRQ(ierr); 3976 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 3977 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3978 ierr = PetscConvEstDestroy(&conv);CHKERRQ(ierr); 3979 ierr = PetscFree(alpha);CHKERRQ(ierr); 3980 incall = PETSC_FALSE; 3981 } 3982 } 3983 } 3984 3985 ierr = TSViewFromOptions(ts,NULL,"-ts_view_pre");CHKERRQ(ierr); 3986 3987 if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */ 3988 ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr); 3989 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 3990 ts->solvetime = ts->ptime; 3991 solution = ts->vec_sol; 3992 } else { /* Step the requested number of timesteps. */ 3993 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 3994 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 3995 3996 if (!ts->steps) { 3997 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3998 ierr = TSEventInitialize(ts->event,ts,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3999 } 4000 4001 while (!ts->reason) { 4002 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4003 if (!ts->steprollback) { 4004 ierr = TSPreStep(ts);CHKERRQ(ierr); 4005 } 4006 ierr = TSStep(ts);CHKERRQ(ierr); 4007 if (ts->testjacobian) { 4008 ierr = TSRHSJacobianTest(ts,NULL);CHKERRQ(ierr); 4009 } 4010 if (ts->testjacobiantranspose) { 4011 ierr = TSRHSJacobianTestTranspose(ts,NULL);CHKERRQ(ierr); 4012 } 4013 if (ts->quadraturets && ts->costintegralfwd) { /* Must evaluate the cost integral before event is handled. The cost integral value can also be rolled back. */ 4014 if (ts->reason >= 0) ts->steps--; /* Revert the step number changed by TSStep() */ 4015 ierr = TSForwardCostIntegral(ts);CHKERRQ(ierr); 4016 if (ts->reason >= 0) ts->steps++; 4017 } 4018 if (ts->forward_solve) { /* compute forward sensitivities before event handling because postevent() may change RHS and jump conditions may have to be applied */ 4019 if (ts->reason >= 0) ts->steps--; /* Revert the step number changed by TSStep() */ 4020 ierr = TSForwardStep(ts);CHKERRQ(ierr); 4021 if (ts->reason >= 0) ts->steps++; 4022 } 4023 ierr = TSPostEvaluate(ts);CHKERRQ(ierr); 4024 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. */ 4025 if (ts->steprollback) { 4026 ierr = TSPostEvaluate(ts);CHKERRQ(ierr); 4027 } 4028 if (!ts->steprollback) { 4029 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4030 ierr = TSPostStep(ts);CHKERRQ(ierr); 4031 } 4032 } 4033 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4034 4035 if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) { 4036 ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr); 4037 ts->solvetime = ts->max_time; 4038 solution = u; 4039 ierr = TSMonitor(ts,-1,ts->solvetime,solution);CHKERRQ(ierr); 4040 } else { 4041 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 4042 ts->solvetime = ts->ptime; 4043 solution = ts->vec_sol; 4044 } 4045 } 4046 4047 ierr = TSViewFromOptions(ts,NULL,"-ts_view");CHKERRQ(ierr); 4048 ierr = VecViewFromOptions(solution,(PetscObject)ts,"-ts_view_solution");CHKERRQ(ierr); 4049 ierr = PetscObjectSAWsBlock((PetscObject)ts);CHKERRQ(ierr); 4050 if (ts->adjoint_solve) { 4051 ierr = TSAdjointSolve(ts);CHKERRQ(ierr); 4052 } 4053 PetscFunctionReturn(0); 4054 } 4055 4056 /*@ 4057 TSGetTime - Gets the time of the most recently completed step. 4058 4059 Not Collective 4060 4061 Input Parameter: 4062 . ts - the TS context obtained from TSCreate() 4063 4064 Output Parameter: 4065 . t - the current time. This time may not corresponds to the final time set with TSSetMaxTime(), use TSGetSolveTime(). 4066 4067 Level: beginner 4068 4069 Note: 4070 When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(), 4071 TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated. 4072 4073 .seealso: TSGetSolveTime(), TSSetTime(), TSGetTimeStep(), TSGetStepNumber() 4074 4075 @*/ 4076 PetscErrorCode TSGetTime(TS ts,PetscReal *t) 4077 { 4078 PetscFunctionBegin; 4079 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4080 PetscValidRealPointer(t,2); 4081 *t = ts->ptime; 4082 PetscFunctionReturn(0); 4083 } 4084 4085 /*@ 4086 TSGetPrevTime - Gets the starting time of the previously completed step. 4087 4088 Not Collective 4089 4090 Input Parameter: 4091 . ts - the TS context obtained from TSCreate() 4092 4093 Output Parameter: 4094 . t - the previous time 4095 4096 Level: beginner 4097 4098 .seealso: TSGetTime(), TSGetSolveTime(), TSGetTimeStep() 4099 4100 @*/ 4101 PetscErrorCode TSGetPrevTime(TS ts,PetscReal *t) 4102 { 4103 PetscFunctionBegin; 4104 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4105 PetscValidRealPointer(t,2); 4106 *t = ts->ptime_prev; 4107 PetscFunctionReturn(0); 4108 } 4109 4110 /*@ 4111 TSSetTime - Allows one to reset the time. 4112 4113 Logically Collective on TS 4114 4115 Input Parameters: 4116 + ts - the TS context obtained from TSCreate() 4117 - time - the time 4118 4119 Level: intermediate 4120 4121 .seealso: TSGetTime(), TSSetMaxSteps() 4122 4123 @*/ 4124 PetscErrorCode TSSetTime(TS ts, PetscReal t) 4125 { 4126 PetscFunctionBegin; 4127 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4128 PetscValidLogicalCollectiveReal(ts,t,2); 4129 ts->ptime = t; 4130 PetscFunctionReturn(0); 4131 } 4132 4133 /*@C 4134 TSSetOptionsPrefix - Sets the prefix used for searching for all 4135 TS options in the database. 4136 4137 Logically Collective on TS 4138 4139 Input Parameters: 4140 + ts - The TS context 4141 - prefix - The prefix to prepend to all option names 4142 4143 Notes: 4144 A hyphen (-) must NOT be given at the beginning of the prefix name. 4145 The first character of all runtime options is AUTOMATICALLY the 4146 hyphen. 4147 4148 Level: advanced 4149 4150 .seealso: TSSetFromOptions() 4151 4152 @*/ 4153 PetscErrorCode TSSetOptionsPrefix(TS ts,const char prefix[]) 4154 { 4155 PetscErrorCode ierr; 4156 SNES snes; 4157 4158 PetscFunctionBegin; 4159 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4160 ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4161 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4162 ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4163 PetscFunctionReturn(0); 4164 } 4165 4166 /*@C 4167 TSAppendOptionsPrefix - Appends to the prefix used for searching for all 4168 TS options in the database. 4169 4170 Logically Collective on TS 4171 4172 Input Parameters: 4173 + ts - The TS context 4174 - prefix - The prefix to prepend to all option names 4175 4176 Notes: 4177 A hyphen (-) must NOT be given at the beginning of the prefix name. 4178 The first character of all runtime options is AUTOMATICALLY the 4179 hyphen. 4180 4181 Level: advanced 4182 4183 .seealso: TSGetOptionsPrefix() 4184 4185 @*/ 4186 PetscErrorCode TSAppendOptionsPrefix(TS ts,const char prefix[]) 4187 { 4188 PetscErrorCode ierr; 4189 SNES snes; 4190 4191 PetscFunctionBegin; 4192 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4193 ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4194 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4195 ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4196 PetscFunctionReturn(0); 4197 } 4198 4199 /*@C 4200 TSGetOptionsPrefix - Sets the prefix used for searching for all 4201 TS options in the database. 4202 4203 Not Collective 4204 4205 Input Parameter: 4206 . ts - The TS context 4207 4208 Output Parameter: 4209 . prefix - A pointer to the prefix string used 4210 4211 Notes: 4212 On the fortran side, the user should pass in a string 'prifix' of 4213 sufficient length to hold the prefix. 4214 4215 Level: intermediate 4216 4217 .seealso: TSAppendOptionsPrefix() 4218 @*/ 4219 PetscErrorCode TSGetOptionsPrefix(TS ts,const char *prefix[]) 4220 { 4221 PetscErrorCode ierr; 4222 4223 PetscFunctionBegin; 4224 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4225 PetscValidPointer(prefix,2); 4226 ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4227 PetscFunctionReturn(0); 4228 } 4229 4230 /*@C 4231 TSGetRHSJacobian - Returns the Jacobian J at the present timestep. 4232 4233 Not Collective, but parallel objects are returned if TS is parallel 4234 4235 Input Parameter: 4236 . ts - The TS context obtained from TSCreate() 4237 4238 Output Parameters: 4239 + Amat - The (approximate) Jacobian J of G, where U_t = G(U,t) (or NULL) 4240 . Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat (or NULL) 4241 . func - Function to compute the Jacobian of the RHS (or NULL) 4242 - ctx - User-defined context for Jacobian evaluation routine (or NULL) 4243 4244 Notes: 4245 You can pass in NULL for any return argument you do not need. 4246 4247 Level: intermediate 4248 4249 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetStepNumber() 4250 4251 @*/ 4252 PetscErrorCode TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx) 4253 { 4254 PetscErrorCode ierr; 4255 DM dm; 4256 4257 PetscFunctionBegin; 4258 if (Amat || Pmat) { 4259 SNES snes; 4260 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4261 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4262 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4263 } 4264 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4265 ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr); 4266 PetscFunctionReturn(0); 4267 } 4268 4269 /*@C 4270 TSGetIJacobian - Returns the implicit Jacobian at the present timestep. 4271 4272 Not Collective, but parallel objects are returned if TS is parallel 4273 4274 Input Parameter: 4275 . ts - The TS context obtained from TSCreate() 4276 4277 Output Parameters: 4278 + Amat - The (approximate) Jacobian of F(t,U,U_t) 4279 . Pmat - The matrix from which the preconditioner is constructed, often the same as Amat 4280 . f - The function to compute the matrices 4281 - ctx - User-defined context for Jacobian evaluation routine 4282 4283 Notes: 4284 You can pass in NULL for any return argument you do not need. 4285 4286 Level: advanced 4287 4288 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetStepNumber() 4289 4290 @*/ 4291 PetscErrorCode TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx) 4292 { 4293 PetscErrorCode ierr; 4294 DM dm; 4295 4296 PetscFunctionBegin; 4297 if (Amat || Pmat) { 4298 SNES snes; 4299 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4300 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4301 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4302 } 4303 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4304 ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr); 4305 PetscFunctionReturn(0); 4306 } 4307 4308 #include <petsc/private/dmimpl.h> 4309 /*@ 4310 TSSetDM - Sets the DM that may be used by some nonlinear solvers or preconditioners under the TS 4311 4312 Logically Collective on ts 4313 4314 Input Parameters: 4315 + ts - the ODE integrator object 4316 - dm - the dm, cannot be NULL 4317 4318 Notes: 4319 A DM can only be used for solving one problem at a time because information about the problem is stored on the DM, 4320 even when not using interfaces like DMTSSetIFunction(). Use DMClone() to get a distinct DM when solving 4321 different problems using the same function space. 4322 4323 Level: intermediate 4324 4325 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM() 4326 @*/ 4327 PetscErrorCode TSSetDM(TS ts,DM dm) 4328 { 4329 PetscErrorCode ierr; 4330 SNES snes; 4331 DMTS tsdm; 4332 4333 PetscFunctionBegin; 4334 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4335 PetscValidHeaderSpecific(dm,DM_CLASSID,2); 4336 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 4337 if (ts->dm) { /* Move the DMTS context over to the new DM unless the new DM already has one */ 4338 if (ts->dm->dmts && !dm->dmts) { 4339 ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr); 4340 ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr); 4341 if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */ 4342 tsdm->originaldm = dm; 4343 } 4344 } 4345 ierr = DMDestroy(&ts->dm);CHKERRQ(ierr); 4346 } 4347 ts->dm = dm; 4348 4349 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4350 ierr = SNESSetDM(snes,dm);CHKERRQ(ierr); 4351 PetscFunctionReturn(0); 4352 } 4353 4354 /*@ 4355 TSGetDM - Gets the DM that may be used by some preconditioners 4356 4357 Not Collective 4358 4359 Input Parameter: 4360 . ts - the preconditioner context 4361 4362 Output Parameter: 4363 . dm - the dm 4364 4365 Level: intermediate 4366 4367 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM() 4368 @*/ 4369 PetscErrorCode TSGetDM(TS ts,DM *dm) 4370 { 4371 PetscErrorCode ierr; 4372 4373 PetscFunctionBegin; 4374 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4375 if (!ts->dm) { 4376 ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr); 4377 if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 4378 } 4379 *dm = ts->dm; 4380 PetscFunctionReturn(0); 4381 } 4382 4383 /*@ 4384 SNESTSFormFunction - Function to evaluate nonlinear residual 4385 4386 Logically Collective on SNES 4387 4388 Input Parameters: 4389 + snes - nonlinear solver 4390 . U - the current state at which to evaluate the residual 4391 - ctx - user context, must be a TS 4392 4393 Output Parameter: 4394 . F - the nonlinear residual 4395 4396 Notes: 4397 This function is not normally called by users and is automatically registered with the SNES used by TS. 4398 It is most frequently passed to MatFDColoringSetFunction(). 4399 4400 Level: advanced 4401 4402 .seealso: SNESSetFunction(), MatFDColoringSetFunction() 4403 @*/ 4404 PetscErrorCode SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx) 4405 { 4406 TS ts = (TS)ctx; 4407 PetscErrorCode ierr; 4408 4409 PetscFunctionBegin; 4410 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4411 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 4412 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 4413 PetscValidHeaderSpecific(ts,TS_CLASSID,4); 4414 ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr); 4415 PetscFunctionReturn(0); 4416 } 4417 4418 /*@ 4419 SNESTSFormJacobian - Function to evaluate the Jacobian 4420 4421 Collective on SNES 4422 4423 Input Parameters: 4424 + snes - nonlinear solver 4425 . U - the current state at which to evaluate the residual 4426 - ctx - user context, must be a TS 4427 4428 Output Parameters: 4429 + A - the Jacobian 4430 - B - the preconditioning matrix (may be the same as A) 4431 4432 Notes: 4433 This function is not normally called by users and is automatically registered with the SNES used by TS. 4434 4435 Level: developer 4436 4437 .seealso: SNESSetJacobian() 4438 @*/ 4439 PetscErrorCode SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx) 4440 { 4441 TS ts = (TS)ctx; 4442 PetscErrorCode ierr; 4443 4444 PetscFunctionBegin; 4445 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4446 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 4447 PetscValidPointer(A,3); 4448 PetscValidHeaderSpecific(A,MAT_CLASSID,3); 4449 PetscValidPointer(B,4); 4450 PetscValidHeaderSpecific(B,MAT_CLASSID,4); 4451 PetscValidHeaderSpecific(ts,TS_CLASSID,5); 4452 ierr = (ts->ops->snesjacobian)(snes,U,A,B,ts);CHKERRQ(ierr); 4453 PetscFunctionReturn(0); 4454 } 4455 4456 /*@C 4457 TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems Udot = A U only 4458 4459 Collective on TS 4460 4461 Input Parameters: 4462 + ts - time stepping context 4463 . t - time at which to evaluate 4464 . U - state at which to evaluate 4465 - ctx - context 4466 4467 Output Parameter: 4468 . F - right hand side 4469 4470 Level: intermediate 4471 4472 Notes: 4473 This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems. 4474 The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian(). 4475 4476 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 4477 @*/ 4478 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx) 4479 { 4480 PetscErrorCode ierr; 4481 Mat Arhs,Brhs; 4482 4483 PetscFunctionBegin; 4484 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 4485 /* undo the damage caused by shifting */ 4486 ierr = TSRecoverRHSJacobian(ts,Arhs,Brhs);CHKERRQ(ierr); 4487 ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr); 4488 ierr = MatMult(Arhs,U,F);CHKERRQ(ierr); 4489 PetscFunctionReturn(0); 4490 } 4491 4492 /*@C 4493 TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent. 4494 4495 Collective on TS 4496 4497 Input Parameters: 4498 + ts - time stepping context 4499 . t - time at which to evaluate 4500 . U - state at which to evaluate 4501 - ctx - context 4502 4503 Output Parameters: 4504 + A - pointer to operator 4505 - B - pointer to preconditioning matrix 4506 4507 Level: intermediate 4508 4509 Notes: 4510 This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems. 4511 4512 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear() 4513 @*/ 4514 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx) 4515 { 4516 PetscFunctionBegin; 4517 PetscFunctionReturn(0); 4518 } 4519 4520 /*@C 4521 TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only 4522 4523 Collective on TS 4524 4525 Input Parameters: 4526 + ts - time stepping context 4527 . t - time at which to evaluate 4528 . U - state at which to evaluate 4529 . Udot - time derivative of state vector 4530 - ctx - context 4531 4532 Output Parameter: 4533 . F - left hand side 4534 4535 Level: intermediate 4536 4537 Notes: 4538 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 4539 user is required to write their own TSComputeIFunction. 4540 This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems. 4541 The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian(). 4542 4543 Note that using this function is NOT equivalent to using TSComputeRHSFunctionLinear() since that solves Udot = A U 4544 4545 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant(), TSComputeRHSFunctionLinear() 4546 @*/ 4547 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx) 4548 { 4549 PetscErrorCode ierr; 4550 Mat A,B; 4551 4552 PetscFunctionBegin; 4553 ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr); 4554 ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE);CHKERRQ(ierr); 4555 ierr = MatMult(A,Udot,F);CHKERRQ(ierr); 4556 PetscFunctionReturn(0); 4557 } 4558 4559 /*@C 4560 TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE 4561 4562 Collective on TS 4563 4564 Input Parameters: 4565 + ts - time stepping context 4566 . t - time at which to evaluate 4567 . U - state at which to evaluate 4568 . Udot - time derivative of state vector 4569 . shift - shift to apply 4570 - ctx - context 4571 4572 Output Parameters: 4573 + A - pointer to operator 4574 - B - pointer to preconditioning matrix 4575 4576 Level: advanced 4577 4578 Notes: 4579 This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems. 4580 4581 It is only appropriate for problems of the form 4582 4583 $ M Udot = F(U,t) 4584 4585 where M is constant and F is non-stiff. The user must pass M to TSSetIJacobian(). The current implementation only 4586 works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing 4587 an implicit operator of the form 4588 4589 $ shift*M + J 4590 4591 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 4592 a copy of M or reassemble it when requested. 4593 4594 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear() 4595 @*/ 4596 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx) 4597 { 4598 PetscErrorCode ierr; 4599 4600 PetscFunctionBegin; 4601 ierr = MatScale(A, shift / ts->ijacobian.shift);CHKERRQ(ierr); 4602 ts->ijacobian.shift = shift; 4603 PetscFunctionReturn(0); 4604 } 4605 4606 /*@ 4607 TSGetEquationType - Gets the type of the equation that TS is solving. 4608 4609 Not Collective 4610 4611 Input Parameter: 4612 . ts - the TS context 4613 4614 Output Parameter: 4615 . equation_type - see TSEquationType 4616 4617 Level: beginner 4618 4619 .seealso: TSSetEquationType(), TSEquationType 4620 @*/ 4621 PetscErrorCode TSGetEquationType(TS ts,TSEquationType *equation_type) 4622 { 4623 PetscFunctionBegin; 4624 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4625 PetscValidPointer(equation_type,2); 4626 *equation_type = ts->equation_type; 4627 PetscFunctionReturn(0); 4628 } 4629 4630 /*@ 4631 TSSetEquationType - Sets the type of the equation that TS is solving. 4632 4633 Not Collective 4634 4635 Input Parameters: 4636 + ts - the TS context 4637 - equation_type - see TSEquationType 4638 4639 Level: advanced 4640 4641 .seealso: TSGetEquationType(), TSEquationType 4642 @*/ 4643 PetscErrorCode TSSetEquationType(TS ts,TSEquationType equation_type) 4644 { 4645 PetscFunctionBegin; 4646 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4647 ts->equation_type = equation_type; 4648 PetscFunctionReturn(0); 4649 } 4650 4651 /*@ 4652 TSGetConvergedReason - Gets the reason the TS iteration was stopped. 4653 4654 Not Collective 4655 4656 Input Parameter: 4657 . ts - the TS context 4658 4659 Output Parameter: 4660 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 4661 manual pages for the individual convergence tests for complete lists 4662 4663 Level: beginner 4664 4665 Notes: 4666 Can only be called after the call to TSSolve() is complete. 4667 4668 .seealso: TSSetConvergenceTest(), TSConvergedReason 4669 @*/ 4670 PetscErrorCode TSGetConvergedReason(TS ts,TSConvergedReason *reason) 4671 { 4672 PetscFunctionBegin; 4673 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4674 PetscValidPointer(reason,2); 4675 *reason = ts->reason; 4676 PetscFunctionReturn(0); 4677 } 4678 4679 /*@ 4680 TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve. 4681 4682 Logically Collective; reason must contain common value 4683 4684 Input Parameters: 4685 + ts - the TS context 4686 - reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 4687 manual pages for the individual convergence tests for complete lists 4688 4689 Level: advanced 4690 4691 Notes: 4692 Can only be called while TSSolve() is active. 4693 4694 .seealso: TSConvergedReason 4695 @*/ 4696 PetscErrorCode TSSetConvergedReason(TS ts,TSConvergedReason reason) 4697 { 4698 PetscFunctionBegin; 4699 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4700 ts->reason = reason; 4701 PetscFunctionReturn(0); 4702 } 4703 4704 /*@ 4705 TSGetSolveTime - Gets the time after a call to TSSolve() 4706 4707 Not Collective 4708 4709 Input Parameter: 4710 . ts - the TS context 4711 4712 Output Parameter: 4713 . ftime - the final time. This time corresponds to the final time set with TSSetMaxTime() 4714 4715 Level: beginner 4716 4717 Notes: 4718 Can only be called after the call to TSSolve() is complete. 4719 4720 .seealso: TSSetConvergenceTest(), TSConvergedReason 4721 @*/ 4722 PetscErrorCode TSGetSolveTime(TS ts,PetscReal *ftime) 4723 { 4724 PetscFunctionBegin; 4725 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4726 PetscValidPointer(ftime,2); 4727 *ftime = ts->solvetime; 4728 PetscFunctionReturn(0); 4729 } 4730 4731 /*@ 4732 TSGetSNESIterations - Gets the total number of nonlinear iterations 4733 used by the time integrator. 4734 4735 Not Collective 4736 4737 Input Parameter: 4738 . ts - TS context 4739 4740 Output Parameter: 4741 . nits - number of nonlinear iterations 4742 4743 Notes: 4744 This counter is reset to zero for each successive call to TSSolve(). 4745 4746 Level: intermediate 4747 4748 .seealso: TSGetKSPIterations() 4749 @*/ 4750 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits) 4751 { 4752 PetscFunctionBegin; 4753 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4754 PetscValidIntPointer(nits,2); 4755 *nits = ts->snes_its; 4756 PetscFunctionReturn(0); 4757 } 4758 4759 /*@ 4760 TSGetKSPIterations - Gets the total number of linear iterations 4761 used by the time integrator. 4762 4763 Not Collective 4764 4765 Input Parameter: 4766 . ts - TS context 4767 4768 Output Parameter: 4769 . lits - number of linear iterations 4770 4771 Notes: 4772 This counter is reset to zero for each successive call to TSSolve(). 4773 4774 Level: intermediate 4775 4776 .seealso: TSGetSNESIterations(), SNESGetKSPIterations() 4777 @*/ 4778 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits) 4779 { 4780 PetscFunctionBegin; 4781 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4782 PetscValidIntPointer(lits,2); 4783 *lits = ts->ksp_its; 4784 PetscFunctionReturn(0); 4785 } 4786 4787 /*@ 4788 TSGetStepRejections - Gets the total number of rejected steps. 4789 4790 Not Collective 4791 4792 Input Parameter: 4793 . ts - TS context 4794 4795 Output Parameter: 4796 . rejects - number of steps rejected 4797 4798 Notes: 4799 This counter is reset to zero for each successive call to TSSolve(). 4800 4801 Level: intermediate 4802 4803 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails() 4804 @*/ 4805 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects) 4806 { 4807 PetscFunctionBegin; 4808 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4809 PetscValidIntPointer(rejects,2); 4810 *rejects = ts->reject; 4811 PetscFunctionReturn(0); 4812 } 4813 4814 /*@ 4815 TSGetSNESFailures - Gets the total number of failed SNES solves 4816 4817 Not Collective 4818 4819 Input Parameter: 4820 . ts - TS context 4821 4822 Output Parameter: 4823 . fails - number of failed nonlinear solves 4824 4825 Notes: 4826 This counter is reset to zero for each successive call to TSSolve(). 4827 4828 Level: intermediate 4829 4830 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures() 4831 @*/ 4832 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails) 4833 { 4834 PetscFunctionBegin; 4835 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4836 PetscValidIntPointer(fails,2); 4837 *fails = ts->num_snes_failures; 4838 PetscFunctionReturn(0); 4839 } 4840 4841 /*@ 4842 TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails 4843 4844 Not Collective 4845 4846 Input Parameters: 4847 + ts - TS context 4848 - rejects - maximum number of rejected steps, pass -1 for unlimited 4849 4850 Notes: 4851 The counter is reset to zero for each step 4852 4853 Options Database Key: 4854 . -ts_max_reject - Maximum number of step rejections before a step fails 4855 4856 Level: intermediate 4857 4858 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 4859 @*/ 4860 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects) 4861 { 4862 PetscFunctionBegin; 4863 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4864 ts->max_reject = rejects; 4865 PetscFunctionReturn(0); 4866 } 4867 4868 /*@ 4869 TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves 4870 4871 Not Collective 4872 4873 Input Parameters: 4874 + ts - TS context 4875 - fails - maximum number of failed nonlinear solves, pass -1 for unlimited 4876 4877 Notes: 4878 The counter is reset to zero for each successive call to TSSolve(). 4879 4880 Options Database Key: 4881 . -ts_max_snes_failures - Maximum number of nonlinear solve failures 4882 4883 Level: intermediate 4884 4885 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason() 4886 @*/ 4887 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails) 4888 { 4889 PetscFunctionBegin; 4890 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4891 ts->max_snes_failures = fails; 4892 PetscFunctionReturn(0); 4893 } 4894 4895 /*@ 4896 TSSetErrorIfStepFails - Error if no step succeeds 4897 4898 Not Collective 4899 4900 Input Parameters: 4901 + ts - TS context 4902 - err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure 4903 4904 Options Database Key: 4905 . -ts_error_if_step_fails - Error if no step succeeds 4906 4907 Level: intermediate 4908 4909 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 4910 @*/ 4911 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err) 4912 { 4913 PetscFunctionBegin; 4914 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4915 ts->errorifstepfailed = err; 4916 PetscFunctionReturn(0); 4917 } 4918 4919 /*@ 4920 TSGetAdapt - Get the adaptive controller context for the current method 4921 4922 Collective on TS if controller has not been created yet 4923 4924 Input Parameter: 4925 . ts - time stepping context 4926 4927 Output Parameter: 4928 . adapt - adaptive controller 4929 4930 Level: intermediate 4931 4932 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose() 4933 @*/ 4934 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt) 4935 { 4936 PetscErrorCode ierr; 4937 4938 PetscFunctionBegin; 4939 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4940 PetscValidPointer(adapt,2); 4941 if (!ts->adapt) { 4942 ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr); 4943 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr); 4944 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr); 4945 } 4946 *adapt = ts->adapt; 4947 PetscFunctionReturn(0); 4948 } 4949 4950 /*@ 4951 TSSetTolerances - Set tolerances for local truncation error when using adaptive controller 4952 4953 Logically Collective 4954 4955 Input Parameters: 4956 + ts - time integration context 4957 . atol - scalar absolute tolerances, PETSC_DECIDE to leave current value 4958 . vatol - vector of absolute tolerances or NULL, used in preference to atol if present 4959 . rtol - scalar relative tolerances, PETSC_DECIDE to leave current value 4960 - vrtol - vector of relative tolerances or NULL, used in preference to atol if present 4961 4962 Options Database keys: 4963 + -ts_rtol <rtol> - relative tolerance for local truncation error 4964 - -ts_atol <atol> Absolute tolerance for local truncation error 4965 4966 Notes: 4967 With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error 4968 (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be 4969 computed only for the differential or the algebraic part then this can be done using the vector of 4970 tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the 4971 differential part and infinity for the algebraic part, the LTE calculation will include only the 4972 differential variables. 4973 4974 Level: beginner 4975 4976 .seealso: TS, TSAdapt, TSErrorWeightedNorm(), TSGetTolerances() 4977 @*/ 4978 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol) 4979 { 4980 PetscErrorCode ierr; 4981 4982 PetscFunctionBegin; 4983 if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol; 4984 if (vatol) { 4985 ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr); 4986 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 4987 ts->vatol = vatol; 4988 } 4989 if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol; 4990 if (vrtol) { 4991 ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr); 4992 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 4993 ts->vrtol = vrtol; 4994 } 4995 PetscFunctionReturn(0); 4996 } 4997 4998 /*@ 4999 TSGetTolerances - Get tolerances for local truncation error when using adaptive controller 5000 5001 Logically Collective 5002 5003 Input Parameter: 5004 . ts - time integration context 5005 5006 Output Parameters: 5007 + atol - scalar absolute tolerances, NULL to ignore 5008 . vatol - vector of absolute tolerances, NULL to ignore 5009 . rtol - scalar relative tolerances, NULL to ignore 5010 - vrtol - vector of relative tolerances, NULL to ignore 5011 5012 Level: beginner 5013 5014 .seealso: TS, TSAdapt, TSErrorWeightedNorm(), TSSetTolerances() 5015 @*/ 5016 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol) 5017 { 5018 PetscFunctionBegin; 5019 if (atol) *atol = ts->atol; 5020 if (vatol) *vatol = ts->vatol; 5021 if (rtol) *rtol = ts->rtol; 5022 if (vrtol) *vrtol = ts->vrtol; 5023 PetscFunctionReturn(0); 5024 } 5025 5026 /*@ 5027 TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors 5028 5029 Collective on TS 5030 5031 Input Parameters: 5032 + ts - time stepping context 5033 . U - state vector, usually ts->vec_sol 5034 - Y - state vector to be compared to U 5035 5036 Output Parameters: 5037 + norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5038 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5039 - normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5040 5041 Level: developer 5042 5043 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNormInfinity() 5044 @*/ 5045 PetscErrorCode TSErrorWeightedNorm2(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5046 { 5047 PetscErrorCode ierr; 5048 PetscInt i,n,N,rstart; 5049 PetscInt n_loc,na_loc,nr_loc; 5050 PetscReal n_glb,na_glb,nr_glb; 5051 const PetscScalar *u,*y; 5052 PetscReal sum,suma,sumr,gsum,gsuma,gsumr,diff; 5053 PetscReal tol,tola,tolr; 5054 PetscReal err_loc[6],err_glb[6]; 5055 5056 PetscFunctionBegin; 5057 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5058 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5059 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 5060 PetscValidType(U,2); 5061 PetscValidType(Y,3); 5062 PetscCheckSameComm(U,2,Y,3); 5063 PetscValidPointer(norm,4); 5064 PetscValidPointer(norma,5); 5065 PetscValidPointer(normr,6); 5066 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 5067 5068 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 5069 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 5070 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 5071 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5072 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5073 sum = 0.; n_loc = 0; 5074 suma = 0.; na_loc = 0; 5075 sumr = 0.; nr_loc = 0; 5076 if (ts->vatol && ts->vrtol) { 5077 const PetscScalar *atol,*rtol; 5078 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5079 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5080 for (i=0; i<n; i++) { 5081 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5082 diff = PetscAbsScalar(y[i] - u[i]); 5083 tola = PetscRealPart(atol[i]); 5084 if (tola>0.) { 5085 suma += PetscSqr(diff/tola); 5086 na_loc++; 5087 } 5088 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5089 if (tolr>0.) { 5090 sumr += PetscSqr(diff/tolr); 5091 nr_loc++; 5092 } 5093 tol=tola+tolr; 5094 if (tol>0.) { 5095 sum += PetscSqr(diff/tol); 5096 n_loc++; 5097 } 5098 } 5099 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5100 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5101 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5102 const PetscScalar *atol; 5103 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5104 for (i=0; i<n; i++) { 5105 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5106 diff = PetscAbsScalar(y[i] - u[i]); 5107 tola = PetscRealPart(atol[i]); 5108 if (tola>0.) { 5109 suma += PetscSqr(diff/tola); 5110 na_loc++; 5111 } 5112 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5113 if (tolr>0.) { 5114 sumr += PetscSqr(diff/tolr); 5115 nr_loc++; 5116 } 5117 tol=tola+tolr; 5118 if (tol>0.) { 5119 sum += PetscSqr(diff/tol); 5120 n_loc++; 5121 } 5122 } 5123 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5124 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5125 const PetscScalar *rtol; 5126 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5127 for (i=0; i<n; i++) { 5128 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5129 diff = PetscAbsScalar(y[i] - u[i]); 5130 tola = ts->atol; 5131 if (tola>0.) { 5132 suma += PetscSqr(diff/tola); 5133 na_loc++; 5134 } 5135 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5136 if (tolr>0.) { 5137 sumr += PetscSqr(diff/tolr); 5138 nr_loc++; 5139 } 5140 tol=tola+tolr; 5141 if (tol>0.) { 5142 sum += PetscSqr(diff/tol); 5143 n_loc++; 5144 } 5145 } 5146 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5147 } else { /* scalar atol, scalar rtol */ 5148 for (i=0; i<n; i++) { 5149 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5150 diff = PetscAbsScalar(y[i] - u[i]); 5151 tola = ts->atol; 5152 if (tola>0.) { 5153 suma += PetscSqr(diff/tola); 5154 na_loc++; 5155 } 5156 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5157 if (tolr>0.) { 5158 sumr += PetscSqr(diff/tolr); 5159 nr_loc++; 5160 } 5161 tol=tola+tolr; 5162 if (tol>0.) { 5163 sum += PetscSqr(diff/tol); 5164 n_loc++; 5165 } 5166 } 5167 } 5168 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5169 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5170 5171 err_loc[0] = sum; 5172 err_loc[1] = suma; 5173 err_loc[2] = sumr; 5174 err_loc[3] = (PetscReal)n_loc; 5175 err_loc[4] = (PetscReal)na_loc; 5176 err_loc[5] = (PetscReal)nr_loc; 5177 5178 ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRMPI(ierr); 5179 5180 gsum = err_glb[0]; 5181 gsuma = err_glb[1]; 5182 gsumr = err_glb[2]; 5183 n_glb = err_glb[3]; 5184 na_glb = err_glb[4]; 5185 nr_glb = err_glb[5]; 5186 5187 *norm = 0.; 5188 if (n_glb>0.) {*norm = PetscSqrtReal(gsum / n_glb);} 5189 *norma = 0.; 5190 if (na_glb>0.) {*norma = PetscSqrtReal(gsuma / na_glb);} 5191 *normr = 0.; 5192 if (nr_glb>0.) {*normr = PetscSqrtReal(gsumr / nr_glb);} 5193 5194 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5195 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 5196 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 5197 PetscFunctionReturn(0); 5198 } 5199 5200 /*@ 5201 TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors 5202 5203 Collective on TS 5204 5205 Input Parameters: 5206 + ts - time stepping context 5207 . U - state vector, usually ts->vec_sol 5208 - Y - state vector to be compared to U 5209 5210 Output Parameters: 5211 + norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5212 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5213 - normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5214 5215 Level: developer 5216 5217 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNorm2() 5218 @*/ 5219 PetscErrorCode TSErrorWeightedNormInfinity(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5220 { 5221 PetscErrorCode ierr; 5222 PetscInt i,n,N,rstart; 5223 const PetscScalar *u,*y; 5224 PetscReal max,gmax,maxa,gmaxa,maxr,gmaxr; 5225 PetscReal tol,tola,tolr,diff; 5226 PetscReal err_loc[3],err_glb[3]; 5227 5228 PetscFunctionBegin; 5229 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5230 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5231 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 5232 PetscValidType(U,2); 5233 PetscValidType(Y,3); 5234 PetscCheckSameComm(U,2,Y,3); 5235 PetscValidPointer(norm,4); 5236 PetscValidPointer(norma,5); 5237 PetscValidPointer(normr,6); 5238 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 5239 5240 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 5241 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 5242 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 5243 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5244 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5245 5246 max=0.; 5247 maxa=0.; 5248 maxr=0.; 5249 5250 if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */ 5251 const PetscScalar *atol,*rtol; 5252 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5253 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5254 5255 for (i=0; i<n; i++) { 5256 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5257 diff = PetscAbsScalar(y[i] - u[i]); 5258 tola = PetscRealPart(atol[i]); 5259 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5260 tol = tola+tolr; 5261 if (tola>0.) { 5262 maxa = PetscMax(maxa,diff / tola); 5263 } 5264 if (tolr>0.) { 5265 maxr = PetscMax(maxr,diff / tolr); 5266 } 5267 if (tol>0.) { 5268 max = PetscMax(max,diff / tol); 5269 } 5270 } 5271 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5272 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5273 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5274 const PetscScalar *atol; 5275 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5276 for (i=0; i<n; i++) { 5277 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5278 diff = PetscAbsScalar(y[i] - u[i]); 5279 tola = PetscRealPart(atol[i]); 5280 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5281 tol = tola+tolr; 5282 if (tola>0.) { 5283 maxa = PetscMax(maxa,diff / tola); 5284 } 5285 if (tolr>0.) { 5286 maxr = PetscMax(maxr,diff / tolr); 5287 } 5288 if (tol>0.) { 5289 max = PetscMax(max,diff / tol); 5290 } 5291 } 5292 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5293 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5294 const PetscScalar *rtol; 5295 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5296 5297 for (i=0; i<n; i++) { 5298 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5299 diff = PetscAbsScalar(y[i] - u[i]); 5300 tola = ts->atol; 5301 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5302 tol = tola+tolr; 5303 if (tola>0.) { 5304 maxa = PetscMax(maxa,diff / tola); 5305 } 5306 if (tolr>0.) { 5307 maxr = PetscMax(maxr,diff / tolr); 5308 } 5309 if (tol>0.) { 5310 max = PetscMax(max,diff / tol); 5311 } 5312 } 5313 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5314 } else { /* scalar atol, scalar rtol */ 5315 5316 for (i=0; i<n; i++) { 5317 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5318 diff = PetscAbsScalar(y[i] - u[i]); 5319 tola = ts->atol; 5320 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5321 tol = tola+tolr; 5322 if (tola>0.) { 5323 maxa = PetscMax(maxa,diff / tola); 5324 } 5325 if (tolr>0.) { 5326 maxr = PetscMax(maxr,diff / tolr); 5327 } 5328 if (tol>0.) { 5329 max = PetscMax(max,diff / tol); 5330 } 5331 } 5332 } 5333 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5334 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5335 err_loc[0] = max; 5336 err_loc[1] = maxa; 5337 err_loc[2] = maxr; 5338 ierr = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRMPI(ierr); 5339 gmax = err_glb[0]; 5340 gmaxa = err_glb[1]; 5341 gmaxr = err_glb[2]; 5342 5343 *norm = gmax; 5344 *norma = gmaxa; 5345 *normr = gmaxr; 5346 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5347 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 5348 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 5349 PetscFunctionReturn(0); 5350 } 5351 5352 /*@ 5353 TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors based on supplied absolute and relative tolerances 5354 5355 Collective on TS 5356 5357 Input Parameters: 5358 + ts - time stepping context 5359 . U - state vector, usually ts->vec_sol 5360 . Y - state vector to be compared to U 5361 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 5362 5363 Output Parameters: 5364 + norm - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances 5365 . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user 5366 - normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user 5367 5368 Options Database Keys: 5369 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 5370 5371 Level: developer 5372 5373 .seealso: TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2(), TSErrorWeightedENorm 5374 @*/ 5375 PetscErrorCode TSErrorWeightedNorm(TS ts,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5376 { 5377 PetscErrorCode ierr; 5378 5379 PetscFunctionBegin; 5380 if (wnormtype == NORM_2) { 5381 ierr = TSErrorWeightedNorm2(ts,U,Y,norm,norma,normr);CHKERRQ(ierr); 5382 } else if (wnormtype == NORM_INFINITY) { 5383 ierr = TSErrorWeightedNormInfinity(ts,U,Y,norm,norma,normr);CHKERRQ(ierr); 5384 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 5385 PetscFunctionReturn(0); 5386 } 5387 5388 /*@ 5389 TSErrorWeightedENorm2 - compute a weighted 2 error norm based on supplied absolute and relative tolerances 5390 5391 Collective on TS 5392 5393 Input Parameters: 5394 + ts - time stepping context 5395 . E - error vector 5396 . U - state vector, usually ts->vec_sol 5397 - Y - state vector, previous time step 5398 5399 Output Parameters: 5400 + norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5401 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5402 - normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5403 5404 Level: developer 5405 5406 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENormInfinity() 5407 @*/ 5408 PetscErrorCode TSErrorWeightedENorm2(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5409 { 5410 PetscErrorCode ierr; 5411 PetscInt i,n,N,rstart; 5412 PetscInt n_loc,na_loc,nr_loc; 5413 PetscReal n_glb,na_glb,nr_glb; 5414 const PetscScalar *e,*u,*y; 5415 PetscReal err,sum,suma,sumr,gsum,gsuma,gsumr; 5416 PetscReal tol,tola,tolr; 5417 PetscReal err_loc[6],err_glb[6]; 5418 5419 PetscFunctionBegin; 5420 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5421 PetscValidHeaderSpecific(E,VEC_CLASSID,2); 5422 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 5423 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 5424 PetscValidType(E,2); 5425 PetscValidType(U,3); 5426 PetscValidType(Y,4); 5427 PetscCheckSameComm(E,2,U,3); 5428 PetscCheckSameComm(U,3,Y,4); 5429 PetscValidPointer(norm,5); 5430 PetscValidPointer(norma,6); 5431 PetscValidPointer(normr,7); 5432 5433 ierr = VecGetSize(E,&N);CHKERRQ(ierr); 5434 ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr); 5435 ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr); 5436 ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr); 5437 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5438 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5439 sum = 0.; n_loc = 0; 5440 suma = 0.; na_loc = 0; 5441 sumr = 0.; nr_loc = 0; 5442 if (ts->vatol && ts->vrtol) { 5443 const PetscScalar *atol,*rtol; 5444 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5445 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5446 for (i=0; i<n; i++) { 5447 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5448 err = PetscAbsScalar(e[i]); 5449 tola = PetscRealPart(atol[i]); 5450 if (tola>0.) { 5451 suma += PetscSqr(err/tola); 5452 na_loc++; 5453 } 5454 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5455 if (tolr>0.) { 5456 sumr += PetscSqr(err/tolr); 5457 nr_loc++; 5458 } 5459 tol=tola+tolr; 5460 if (tol>0.) { 5461 sum += PetscSqr(err/tol); 5462 n_loc++; 5463 } 5464 } 5465 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5466 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5467 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5468 const PetscScalar *atol; 5469 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5470 for (i=0; i<n; i++) { 5471 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5472 err = PetscAbsScalar(e[i]); 5473 tola = PetscRealPart(atol[i]); 5474 if (tola>0.) { 5475 suma += PetscSqr(err/tola); 5476 na_loc++; 5477 } 5478 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5479 if (tolr>0.) { 5480 sumr += PetscSqr(err/tolr); 5481 nr_loc++; 5482 } 5483 tol=tola+tolr; 5484 if (tol>0.) { 5485 sum += PetscSqr(err/tol); 5486 n_loc++; 5487 } 5488 } 5489 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5490 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5491 const PetscScalar *rtol; 5492 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5493 for (i=0; i<n; i++) { 5494 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5495 err = PetscAbsScalar(e[i]); 5496 tola = ts->atol; 5497 if (tola>0.) { 5498 suma += PetscSqr(err/tola); 5499 na_loc++; 5500 } 5501 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5502 if (tolr>0.) { 5503 sumr += PetscSqr(err/tolr); 5504 nr_loc++; 5505 } 5506 tol=tola+tolr; 5507 if (tol>0.) { 5508 sum += PetscSqr(err/tol); 5509 n_loc++; 5510 } 5511 } 5512 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5513 } else { /* scalar atol, scalar rtol */ 5514 for (i=0; i<n; i++) { 5515 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5516 err = PetscAbsScalar(e[i]); 5517 tola = ts->atol; 5518 if (tola>0.) { 5519 suma += PetscSqr(err/tola); 5520 na_loc++; 5521 } 5522 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5523 if (tolr>0.) { 5524 sumr += PetscSqr(err/tolr); 5525 nr_loc++; 5526 } 5527 tol=tola+tolr; 5528 if (tol>0.) { 5529 sum += PetscSqr(err/tol); 5530 n_loc++; 5531 } 5532 } 5533 } 5534 ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr); 5535 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5536 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5537 5538 err_loc[0] = sum; 5539 err_loc[1] = suma; 5540 err_loc[2] = sumr; 5541 err_loc[3] = (PetscReal)n_loc; 5542 err_loc[4] = (PetscReal)na_loc; 5543 err_loc[5] = (PetscReal)nr_loc; 5544 5545 ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRMPI(ierr); 5546 5547 gsum = err_glb[0]; 5548 gsuma = err_glb[1]; 5549 gsumr = err_glb[2]; 5550 n_glb = err_glb[3]; 5551 na_glb = err_glb[4]; 5552 nr_glb = err_glb[5]; 5553 5554 *norm = 0.; 5555 if (n_glb>0.) {*norm = PetscSqrtReal(gsum / n_glb);} 5556 *norma = 0.; 5557 if (na_glb>0.) {*norma = PetscSqrtReal(gsuma / na_glb);} 5558 *normr = 0.; 5559 if (nr_glb>0.) {*normr = PetscSqrtReal(gsumr / nr_glb);} 5560 5561 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5562 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 5563 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 5564 PetscFunctionReturn(0); 5565 } 5566 5567 /*@ 5568 TSErrorWeightedENormInfinity - compute a weighted infinity error norm based on supplied absolute and relative tolerances 5569 Collective on TS 5570 5571 Input Parameters: 5572 + ts - time stepping context 5573 . E - error vector 5574 . U - state vector, usually ts->vec_sol 5575 - Y - state vector, previous time step 5576 5577 Output Parameters: 5578 + norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5579 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5580 - normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5581 5582 Level: developer 5583 5584 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENorm2() 5585 @*/ 5586 PetscErrorCode TSErrorWeightedENormInfinity(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5587 { 5588 PetscErrorCode ierr; 5589 PetscInt i,n,N,rstart; 5590 const PetscScalar *e,*u,*y; 5591 PetscReal err,max,gmax,maxa,gmaxa,maxr,gmaxr; 5592 PetscReal tol,tola,tolr; 5593 PetscReal err_loc[3],err_glb[3]; 5594 5595 PetscFunctionBegin; 5596 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5597 PetscValidHeaderSpecific(E,VEC_CLASSID,2); 5598 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 5599 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 5600 PetscValidType(E,2); 5601 PetscValidType(U,3); 5602 PetscValidType(Y,4); 5603 PetscCheckSameComm(E,2,U,3); 5604 PetscCheckSameComm(U,3,Y,4); 5605 PetscValidPointer(norm,5); 5606 PetscValidPointer(norma,6); 5607 PetscValidPointer(normr,7); 5608 5609 ierr = VecGetSize(E,&N);CHKERRQ(ierr); 5610 ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr); 5611 ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr); 5612 ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr); 5613 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5614 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5615 5616 max=0.; 5617 maxa=0.; 5618 maxr=0.; 5619 5620 if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */ 5621 const PetscScalar *atol,*rtol; 5622 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5623 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5624 5625 for (i=0; i<n; i++) { 5626 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5627 err = PetscAbsScalar(e[i]); 5628 tola = PetscRealPart(atol[i]); 5629 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5630 tol = tola+tolr; 5631 if (tola>0.) { 5632 maxa = PetscMax(maxa,err / tola); 5633 } 5634 if (tolr>0.) { 5635 maxr = PetscMax(maxr,err / tolr); 5636 } 5637 if (tol>0.) { 5638 max = PetscMax(max,err / tol); 5639 } 5640 } 5641 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5642 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5643 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5644 const PetscScalar *atol; 5645 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5646 for (i=0; i<n; i++) { 5647 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5648 err = PetscAbsScalar(e[i]); 5649 tola = PetscRealPart(atol[i]); 5650 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5651 tol = tola+tolr; 5652 if (tola>0.) { 5653 maxa = PetscMax(maxa,err / tola); 5654 } 5655 if (tolr>0.) { 5656 maxr = PetscMax(maxr,err / tolr); 5657 } 5658 if (tol>0.) { 5659 max = PetscMax(max,err / tol); 5660 } 5661 } 5662 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5663 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5664 const PetscScalar *rtol; 5665 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5666 5667 for (i=0; i<n; i++) { 5668 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5669 err = PetscAbsScalar(e[i]); 5670 tola = ts->atol; 5671 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5672 tol = tola+tolr; 5673 if (tola>0.) { 5674 maxa = PetscMax(maxa,err / tola); 5675 } 5676 if (tolr>0.) { 5677 maxr = PetscMax(maxr,err / tolr); 5678 } 5679 if (tol>0.) { 5680 max = PetscMax(max,err / tol); 5681 } 5682 } 5683 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5684 } else { /* scalar atol, scalar rtol */ 5685 5686 for (i=0; i<n; i++) { 5687 SkipSmallValue(y[i],u[i],ts->adapt->ignore_max); 5688 err = PetscAbsScalar(e[i]); 5689 tola = ts->atol; 5690 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5691 tol = tola+tolr; 5692 if (tola>0.) { 5693 maxa = PetscMax(maxa,err / tola); 5694 } 5695 if (tolr>0.) { 5696 maxr = PetscMax(maxr,err / tolr); 5697 } 5698 if (tol>0.) { 5699 max = PetscMax(max,err / tol); 5700 } 5701 } 5702 } 5703 ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr); 5704 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5705 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5706 err_loc[0] = max; 5707 err_loc[1] = maxa; 5708 err_loc[2] = maxr; 5709 ierr = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRMPI(ierr); 5710 gmax = err_glb[0]; 5711 gmaxa = err_glb[1]; 5712 gmaxr = err_glb[2]; 5713 5714 *norm = gmax; 5715 *norma = gmaxa; 5716 *normr = gmaxr; 5717 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5718 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 5719 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 5720 PetscFunctionReturn(0); 5721 } 5722 5723 /*@ 5724 TSErrorWeightedENorm - compute a weighted error norm based on supplied absolute and relative tolerances 5725 5726 Collective on TS 5727 5728 Input Parameters: 5729 + ts - time stepping context 5730 . E - error vector 5731 . U - state vector, usually ts->vec_sol 5732 . Y - state vector, previous time step 5733 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 5734 5735 Output Parameters: 5736 + norm - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances 5737 . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user 5738 - normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user 5739 5740 Options Database Keys: 5741 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 5742 5743 Level: developer 5744 5745 .seealso: TSErrorWeightedENormInfinity(), TSErrorWeightedENorm2(), TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2() 5746 @*/ 5747 PetscErrorCode TSErrorWeightedENorm(TS ts,Vec E,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5748 { 5749 PetscErrorCode ierr; 5750 5751 PetscFunctionBegin; 5752 if (wnormtype == NORM_2) { 5753 ierr = TSErrorWeightedENorm2(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr); 5754 } else if (wnormtype == NORM_INFINITY) { 5755 ierr = TSErrorWeightedENormInfinity(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr); 5756 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 5757 PetscFunctionReturn(0); 5758 } 5759 5760 /*@ 5761 TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler 5762 5763 Logically Collective on TS 5764 5765 Input Parameters: 5766 + ts - time stepping context 5767 - cfltime - maximum stable time step if using forward Euler (value can be different on each process) 5768 5769 Note: 5770 After calling this function, the global CFL time can be obtained by calling TSGetCFLTime() 5771 5772 Level: intermediate 5773 5774 .seealso: TSGetCFLTime(), TSADAPTCFL 5775 @*/ 5776 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime) 5777 { 5778 PetscFunctionBegin; 5779 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5780 ts->cfltime_local = cfltime; 5781 ts->cfltime = -1.; 5782 PetscFunctionReturn(0); 5783 } 5784 5785 /*@ 5786 TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler 5787 5788 Collective on TS 5789 5790 Input Parameter: 5791 . ts - time stepping context 5792 5793 Output Parameter: 5794 . cfltime - maximum stable time step for forward Euler 5795 5796 Level: advanced 5797 5798 .seealso: TSSetCFLTimeLocal() 5799 @*/ 5800 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime) 5801 { 5802 PetscErrorCode ierr; 5803 5804 PetscFunctionBegin; 5805 if (ts->cfltime < 0) { 5806 ierr = MPIU_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRMPI(ierr); 5807 } 5808 *cfltime = ts->cfltime; 5809 PetscFunctionReturn(0); 5810 } 5811 5812 /*@ 5813 TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu 5814 5815 Input Parameters: 5816 + ts - the TS context. 5817 . xl - lower bound. 5818 - xu - upper bound. 5819 5820 Notes: 5821 If this routine is not called then the lower and upper bounds are set to 5822 PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp(). 5823 5824 Level: advanced 5825 5826 @*/ 5827 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu) 5828 { 5829 PetscErrorCode ierr; 5830 SNES snes; 5831 5832 PetscFunctionBegin; 5833 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 5834 ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr); 5835 PetscFunctionReturn(0); 5836 } 5837 5838 /*@ 5839 TSComputeLinearStability - computes the linear stability function at a point 5840 5841 Collective on TS 5842 5843 Input Parameters: 5844 + ts - the TS context 5845 - xr,xi - real and imaginary part of input arguments 5846 5847 Output Parameters: 5848 . yr,yi - real and imaginary part of function value 5849 5850 Level: developer 5851 5852 .seealso: TSSetRHSFunction(), TSComputeIFunction() 5853 @*/ 5854 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi) 5855 { 5856 PetscErrorCode ierr; 5857 5858 PetscFunctionBegin; 5859 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5860 if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method"); 5861 ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr); 5862 PetscFunctionReturn(0); 5863 } 5864 5865 /*@ 5866 TSRestartStep - Flags the solver to restart the next step 5867 5868 Collective on TS 5869 5870 Input Parameter: 5871 . ts - the TS context obtained from TSCreate() 5872 5873 Level: advanced 5874 5875 Notes: 5876 Multistep methods like BDF or Runge-Kutta methods with FSAL property require restarting the solver in the event of 5877 discontinuities. These discontinuities may be introduced as a consequence of explicitly modifications to the solution 5878 vector (which PETSc attempts to detect and handle) or problem coefficients (which PETSc is not able to detect). For 5879 the sake of correctness and maximum safety, users are expected to call TSRestart() whenever they introduce 5880 discontinuities in callback routines (e.g. prestep and poststep routines, or implicit/rhs function routines with 5881 discontinuous source terms). 5882 5883 .seealso: TSSolve(), TSSetPreStep(), TSSetPostStep() 5884 @*/ 5885 PetscErrorCode TSRestartStep(TS ts) 5886 { 5887 PetscFunctionBegin; 5888 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5889 ts->steprestart = PETSC_TRUE; 5890 PetscFunctionReturn(0); 5891 } 5892 5893 /*@ 5894 TSRollBack - Rolls back one time step 5895 5896 Collective on TS 5897 5898 Input Parameter: 5899 . ts - the TS context obtained from TSCreate() 5900 5901 Level: advanced 5902 5903 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate() 5904 @*/ 5905 PetscErrorCode TSRollBack(TS ts) 5906 { 5907 PetscErrorCode ierr; 5908 5909 PetscFunctionBegin; 5910 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 5911 if (ts->steprollback) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"TSRollBack already called"); 5912 if (!ts->ops->rollback) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name); 5913 ierr = (*ts->ops->rollback)(ts);CHKERRQ(ierr); 5914 ts->time_step = ts->ptime - ts->ptime_prev; 5915 ts->ptime = ts->ptime_prev; 5916 ts->ptime_prev = ts->ptime_prev_rollback; 5917 ts->steps--; 5918 ts->steprollback = PETSC_TRUE; 5919 PetscFunctionReturn(0); 5920 } 5921 5922 /*@ 5923 TSGetStages - Get the number of stages and stage values 5924 5925 Input Parameter: 5926 . ts - the TS context obtained from TSCreate() 5927 5928 Output Parameters: 5929 + ns - the number of stages 5930 - Y - the current stage vectors 5931 5932 Level: advanced 5933 5934 Notes: Both ns and Y can be NULL. 5935 5936 .seealso: TSCreate() 5937 @*/ 5938 PetscErrorCode TSGetStages(TS ts,PetscInt *ns,Vec **Y) 5939 { 5940 PetscErrorCode ierr; 5941 5942 PetscFunctionBegin; 5943 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 5944 if (ns) PetscValidPointer(ns,2); 5945 if (Y) PetscValidPointer(Y,3); 5946 if (!ts->ops->getstages) { 5947 if (ns) *ns = 0; 5948 if (Y) *Y = NULL; 5949 } else { 5950 ierr = (*ts->ops->getstages)(ts,ns,Y);CHKERRQ(ierr); 5951 } 5952 PetscFunctionReturn(0); 5953 } 5954 5955 /*@C 5956 TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity. 5957 5958 Collective on SNES 5959 5960 Input Parameters: 5961 + ts - the TS context 5962 . t - current timestep 5963 . U - state vector 5964 . Udot - time derivative of state vector 5965 . shift - shift to apply, see note below 5966 - ctx - an optional user context 5967 5968 Output Parameters: 5969 + J - Jacobian matrix (not altered in this routine) 5970 - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J) 5971 5972 Level: intermediate 5973 5974 Notes: 5975 If F(t,U,Udot)=0 is the DAE, the required Jacobian is 5976 5977 dF/dU + shift*dF/dUdot 5978 5979 Most users should not need to explicitly call this routine, as it 5980 is used internally within the nonlinear solvers. 5981 5982 This will first try to get the coloring from the DM. If the DM type has no coloring 5983 routine, then it will try to get the coloring from the matrix. This requires that the 5984 matrix have nonzero entries precomputed. 5985 5986 .seealso: TSSetIJacobian(), MatFDColoringCreate(), MatFDColoringSetFunction() 5987 @*/ 5988 PetscErrorCode TSComputeIJacobianDefaultColor(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat J,Mat B,void *ctx) 5989 { 5990 SNES snes; 5991 MatFDColoring color; 5992 PetscBool hascolor, matcolor = PETSC_FALSE; 5993 PetscErrorCode ierr; 5994 5995 PetscFunctionBegin; 5996 ierr = PetscOptionsGetBool(((PetscObject)ts)->options,((PetscObject) ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL);CHKERRQ(ierr); 5997 ierr = PetscObjectQuery((PetscObject) B, "TSMatFDColoring", (PetscObject *) &color);CHKERRQ(ierr); 5998 if (!color) { 5999 DM dm; 6000 ISColoring iscoloring; 6001 6002 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 6003 ierr = DMHasColoring(dm, &hascolor);CHKERRQ(ierr); 6004 if (hascolor && !matcolor) { 6005 ierr = DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring);CHKERRQ(ierr); 6006 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 6007 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 6008 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 6009 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 6010 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 6011 } else { 6012 MatColoring mc; 6013 6014 ierr = MatColoringCreate(B, &mc);CHKERRQ(ierr); 6015 ierr = MatColoringSetDistance(mc, 2);CHKERRQ(ierr); 6016 ierr = MatColoringSetType(mc, MATCOLORINGSL);CHKERRQ(ierr); 6017 ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); 6018 ierr = MatColoringApply(mc, &iscoloring);CHKERRQ(ierr); 6019 ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); 6020 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 6021 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 6022 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 6023 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 6024 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 6025 } 6026 ierr = PetscObjectCompose((PetscObject) B, "TSMatFDColoring", (PetscObject) color);CHKERRQ(ierr); 6027 ierr = PetscObjectDereference((PetscObject) color);CHKERRQ(ierr); 6028 } 6029 ierr = TSGetSNES(ts, &snes);CHKERRQ(ierr); 6030 ierr = MatFDColoringApply(B, color, U, snes);CHKERRQ(ierr); 6031 if (J != B) { 6032 ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6033 ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6034 } 6035 PetscFunctionReturn(0); 6036 } 6037 6038 /*@ 6039 TSSetFunctionDomainError - Set a function that tests if the current state vector is valid 6040 6041 Input Parameters: 6042 + ts - the TS context 6043 - func - function called within TSFunctionDomainError 6044 6045 Calling sequence of func: 6046 $ PetscErrorCode func(TS ts,PetscReal time,Vec state,PetscBool reject) 6047 6048 + ts - the TS context 6049 . time - the current time (of the stage) 6050 . state - the state to check if it is valid 6051 - reject - (output parameter) PETSC_FALSE if the state is acceptable, PETSC_TRUE if not acceptable 6052 6053 Level: intermediate 6054 6055 Notes: 6056 If an implicit ODE solver is being used then, in addition to providing this routine, the 6057 user's code should call SNESSetFunctionDomainError() when domain errors occur during 6058 function evaluations where the functions are provided by TSSetIFunction() or TSSetRHSFunction(). 6059 Use TSGetSNES() to obtain the SNES object 6060 6061 Developer Notes: 6062 The naming of this function is inconsistent with the SNESSetFunctionDomainError() 6063 since one takes a function pointer and the other does not. 6064 6065 .seealso: TSAdaptCheckStage(), TSFunctionDomainError(), SNESSetFunctionDomainError(), TSGetSNES() 6066 @*/ 6067 6068 PetscErrorCode TSSetFunctionDomainError(TS ts, PetscErrorCode (*func)(TS,PetscReal,Vec,PetscBool*)) 6069 { 6070 PetscFunctionBegin; 6071 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 6072 ts->functiondomainerror = func; 6073 PetscFunctionReturn(0); 6074 } 6075 6076 /*@ 6077 TSFunctionDomainError - Checks if the current state is valid 6078 6079 Input Parameters: 6080 + ts - the TS context 6081 . stagetime - time of the simulation 6082 - Y - state vector to check. 6083 6084 Output Parameter: 6085 . accept - Set to PETSC_FALSE if the current state vector is valid. 6086 6087 Note: 6088 This function is called by the TS integration routines and calls the user provided function (set with TSSetFunctionDomainError()) 6089 to check if the current state is valid. 6090 6091 Level: developer 6092 6093 .seealso: TSSetFunctionDomainError() 6094 @*/ 6095 PetscErrorCode TSFunctionDomainError(TS ts,PetscReal stagetime,Vec Y,PetscBool* accept) 6096 { 6097 PetscFunctionBegin; 6098 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6099 *accept = PETSC_TRUE; 6100 if (ts->functiondomainerror) { 6101 PetscStackCallStandard((*ts->functiondomainerror),(ts,stagetime,Y,accept)); 6102 } 6103 PetscFunctionReturn(0); 6104 } 6105 6106 /*@C 6107 TSClone - This function clones a time step object. 6108 6109 Collective 6110 6111 Input Parameter: 6112 . tsin - The input TS 6113 6114 Output Parameter: 6115 . tsout - The output TS (cloned) 6116 6117 Notes: 6118 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. 6119 6120 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); 6121 6122 Level: developer 6123 6124 .seealso: TSCreate(), TSSetType(), TSSetUp(), TSDestroy(), TSSetProblemType() 6125 @*/ 6126 PetscErrorCode TSClone(TS tsin, TS *tsout) 6127 { 6128 TS t; 6129 PetscErrorCode ierr; 6130 SNES snes_start; 6131 DM dm; 6132 TSType type; 6133 6134 PetscFunctionBegin; 6135 PetscValidPointer(tsin,1); 6136 *tsout = NULL; 6137 6138 ierr = PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView);CHKERRQ(ierr); 6139 6140 /* General TS description */ 6141 t->numbermonitors = 0; 6142 t->monitorFrequency = 1; 6143 t->setupcalled = 0; 6144 t->ksp_its = 0; 6145 t->snes_its = 0; 6146 t->nwork = 0; 6147 t->rhsjacobian.time = PETSC_MIN_REAL; 6148 t->rhsjacobian.scale = 1.; 6149 t->ijacobian.shift = 1.; 6150 6151 ierr = TSGetSNES(tsin,&snes_start);CHKERRQ(ierr); 6152 ierr = TSSetSNES(t,snes_start);CHKERRQ(ierr); 6153 6154 ierr = TSGetDM(tsin,&dm);CHKERRQ(ierr); 6155 ierr = TSSetDM(t,dm);CHKERRQ(ierr); 6156 6157 t->adapt = tsin->adapt; 6158 ierr = PetscObjectReference((PetscObject)t->adapt);CHKERRQ(ierr); 6159 6160 t->trajectory = tsin->trajectory; 6161 ierr = PetscObjectReference((PetscObject)t->trajectory);CHKERRQ(ierr); 6162 6163 t->event = tsin->event; 6164 if (t->event) t->event->refct++; 6165 6166 t->problem_type = tsin->problem_type; 6167 t->ptime = tsin->ptime; 6168 t->ptime_prev = tsin->ptime_prev; 6169 t->time_step = tsin->time_step; 6170 t->max_time = tsin->max_time; 6171 t->steps = tsin->steps; 6172 t->max_steps = tsin->max_steps; 6173 t->equation_type = tsin->equation_type; 6174 t->atol = tsin->atol; 6175 t->rtol = tsin->rtol; 6176 t->max_snes_failures = tsin->max_snes_failures; 6177 t->max_reject = tsin->max_reject; 6178 t->errorifstepfailed = tsin->errorifstepfailed; 6179 6180 ierr = TSGetType(tsin,&type);CHKERRQ(ierr); 6181 ierr = TSSetType(t,type);CHKERRQ(ierr); 6182 6183 t->vec_sol = NULL; 6184 6185 t->cfltime = tsin->cfltime; 6186 t->cfltime_local = tsin->cfltime_local; 6187 t->exact_final_time = tsin->exact_final_time; 6188 6189 ierr = PetscMemcpy(t->ops,tsin->ops,sizeof(struct _TSOps));CHKERRQ(ierr); 6190 6191 if (((PetscObject)tsin)->fortran_func_pointers) { 6192 PetscInt i; 6193 ierr = PetscMalloc((10)*sizeof(void(*)(void)),&((PetscObject)t)->fortran_func_pointers);CHKERRQ(ierr); 6194 for (i=0; i<10; i++) { 6195 ((PetscObject)t)->fortran_func_pointers[i] = ((PetscObject)tsin)->fortran_func_pointers[i]; 6196 } 6197 } 6198 *tsout = t; 6199 PetscFunctionReturn(0); 6200 } 6201 6202 static PetscErrorCode RHSWrapperFunction_TSRHSJacobianTest(void* ctx,Vec x,Vec y) 6203 { 6204 PetscErrorCode ierr; 6205 TS ts = (TS) ctx; 6206 6207 PetscFunctionBegin; 6208 ierr = TSComputeRHSFunction(ts,0,x,y);CHKERRQ(ierr); 6209 PetscFunctionReturn(0); 6210 } 6211 6212 /*@ 6213 TSRHSJacobianTest - Compares the multiply routine provided to the MATSHELL with differencing on the TS given RHS function. 6214 6215 Logically Collective on TS 6216 6217 Input Parameters: 6218 TS - the time stepping routine 6219 6220 Output Parameter: 6221 . flg - PETSC_TRUE if the multiply is likely correct 6222 6223 Options Database: 6224 . -ts_rhs_jacobian_test_mult -mat_shell_test_mult_view - run the test at each timestep of the integrator 6225 6226 Level: advanced 6227 6228 Notes: 6229 This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian 6230 6231 .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellTestMultTranspose(), TSRHSJacobianTestTranspose() 6232 @*/ 6233 PetscErrorCode TSRHSJacobianTest(TS ts,PetscBool *flg) 6234 { 6235 Mat J,B; 6236 PetscErrorCode ierr; 6237 TSRHSJacobian func; 6238 void* ctx; 6239 6240 PetscFunctionBegin; 6241 ierr = TSGetRHSJacobian(ts,&J,&B,&func,&ctx);CHKERRQ(ierr); 6242 ierr = (*func)(ts,0.0,ts->vec_sol,J,B,ctx);CHKERRQ(ierr); 6243 ierr = MatShellTestMult(J,RHSWrapperFunction_TSRHSJacobianTest,ts->vec_sol,ts,flg);CHKERRQ(ierr); 6244 PetscFunctionReturn(0); 6245 } 6246 6247 /*@C 6248 TSRHSJacobianTestTranspose - Compares the multiply transpose routine provided to the MATSHELL with differencing on the TS given RHS function. 6249 6250 Logically Collective on TS 6251 6252 Input Parameters: 6253 TS - the time stepping routine 6254 6255 Output Parameter: 6256 . flg - PETSC_TRUE if the multiply is likely correct 6257 6258 Options Database: 6259 . -ts_rhs_jacobian_test_mult_transpose -mat_shell_test_mult_transpose_view - run the test at each timestep of the integrator 6260 6261 Notes: 6262 This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian 6263 6264 Level: advanced 6265 6266 .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellTestMultTranspose(), TSRHSJacobianTest() 6267 @*/ 6268 PetscErrorCode TSRHSJacobianTestTranspose(TS ts,PetscBool *flg) 6269 { 6270 Mat J,B; 6271 PetscErrorCode ierr; 6272 void *ctx; 6273 TSRHSJacobian func; 6274 6275 PetscFunctionBegin; 6276 ierr = TSGetRHSJacobian(ts,&J,&B,&func,&ctx);CHKERRQ(ierr); 6277 ierr = (*func)(ts,0.0,ts->vec_sol,J,B,ctx);CHKERRQ(ierr); 6278 ierr = MatShellTestMultTranspose(J,RHSWrapperFunction_TSRHSJacobianTest,ts->vec_sol,ts,flg);CHKERRQ(ierr); 6279 PetscFunctionReturn(0); 6280 } 6281 6282 /*@ 6283 TSSetUseSplitRHSFunction - Use the split RHSFunction when a multirate method is used. 6284 6285 Logically collective 6286 6287 Input Parameters: 6288 + ts - timestepping context 6289 - use_splitrhsfunction - PETSC_TRUE indicates that the split RHSFunction will be used 6290 6291 Options Database: 6292 . -ts_use_splitrhsfunction - <true,false> 6293 6294 Notes: 6295 This is only useful for multirate methods 6296 6297 Level: intermediate 6298 6299 .seealso: TSGetUseSplitRHSFunction() 6300 @*/ 6301 PetscErrorCode TSSetUseSplitRHSFunction(TS ts, PetscBool use_splitrhsfunction) 6302 { 6303 PetscFunctionBegin; 6304 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6305 ts->use_splitrhsfunction = use_splitrhsfunction; 6306 PetscFunctionReturn(0); 6307 } 6308 6309 /*@ 6310 TSGetUseSplitRHSFunction - Gets whether to use the split RHSFunction when a multirate method is used. 6311 6312 Not collective 6313 6314 Input Parameter: 6315 . ts - timestepping context 6316 6317 Output Parameter: 6318 . use_splitrhsfunction - PETSC_TRUE indicates that the split RHSFunction will be used 6319 6320 Level: intermediate 6321 6322 .seealso: TSSetUseSplitRHSFunction() 6323 @*/ 6324 PetscErrorCode TSGetUseSplitRHSFunction(TS ts, PetscBool *use_splitrhsfunction) 6325 { 6326 PetscFunctionBegin; 6327 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6328 *use_splitrhsfunction = ts->use_splitrhsfunction; 6329 PetscFunctionReturn(0); 6330 } 6331 6332 /*@ 6333 TSSetMatStructure - sets the relationship between the nonzero structure of the RHS Jacobian matrix to the IJacobian matrix. 6334 6335 Logically Collective on ts 6336 6337 Input Parameters: 6338 + ts - the time-stepper 6339 - str - the structure (the default is UNKNOWN_NONZERO_PATTERN) 6340 6341 Level: intermediate 6342 6343 Notes: 6344 When the relationship between the nonzero structures is known and supplied the solution process can be much faster 6345 6346 .seealso: MatAXPY(), MatStructure 6347 @*/ 6348 PetscErrorCode TSSetMatStructure(TS ts,MatStructure str) 6349 { 6350 PetscFunctionBegin; 6351 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6352 ts->axpy_pattern = str; 6353 PetscFunctionReturn(0); 6354 } 6355