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