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