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