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