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