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