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