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