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