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