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