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