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