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