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