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