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