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