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