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