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