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