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(), TSSetTimeError() 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__ "TSSetTimeError" 2352 /*@ 2353 TSSetTimeError - Sets the estimated error vector, if the chosen 2354 TSType has an error estimation functionality. This can be used 2355 to restart such a time integrator with a given error vector. 2356 2357 Not Collective, but Vec returned is parallel if TS is parallel 2358 2359 Parameters : 2360 . ts - the TS context obtained from TSCreate() (input parameter). 2361 . v - the vector containing the error (same size as the solution). 2362 2363 Level: intermediate 2364 2365 .seealso: TSSetSolution(), TSGetTimeError) 2366 2367 .keywords: TS, timestep, get, error 2368 @*/ 2369 PetscErrorCode TSSetTimeError(TS ts,Vec v) 2370 { 2371 PetscErrorCode ierr; 2372 2373 PetscFunctionBegin; 2374 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2375 if (ts->ops->settimeerror) { 2376 ierr = (*ts->ops->settimeerror)(ts,v);CHKERRQ(ierr); 2377 } 2378 PetscFunctionReturn(0); 2379 } 2380 2381 #undef __FUNCT__ 2382 #define __FUNCT__ "TSGetCostGradients" 2383 /*@ 2384 TSGetCostGradients - Returns the gradients from the TSAdjointSolve() 2385 2386 Not Collective, but Vec returned is parallel if TS is parallel 2387 2388 Input Parameter: 2389 . ts - the TS context obtained from TSCreate() 2390 2391 Output Parameter: 2392 + lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables 2393 - mu - vectors containing the gradients of the cost functions with respect to the problem parameters 2394 2395 Level: intermediate 2396 2397 .seealso: TSGetTimeStep() 2398 2399 .keywords: TS, timestep, get, sensitivity 2400 @*/ 2401 PetscErrorCode TSGetCostGradients(TS ts,PetscInt *numcost,Vec **lambda,Vec **mu) 2402 { 2403 PetscFunctionBegin; 2404 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2405 if (numcost) *numcost = ts->numcost; 2406 if (lambda) *lambda = ts->vecs_sensi; 2407 if (mu) *mu = ts->vecs_sensip; 2408 PetscFunctionReturn(0); 2409 } 2410 2411 /* ----- Routines to initialize and destroy a timestepper ---- */ 2412 #undef __FUNCT__ 2413 #define __FUNCT__ "TSSetProblemType" 2414 /*@ 2415 TSSetProblemType - Sets the type of problem to be solved. 2416 2417 Not collective 2418 2419 Input Parameters: 2420 + ts - The TS 2421 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 2422 .vb 2423 U_t - A U = 0 (linear) 2424 U_t - A(t) U = 0 (linear) 2425 F(t,U,U_t) = 0 (nonlinear) 2426 .ve 2427 2428 Level: beginner 2429 2430 .keywords: TS, problem type 2431 .seealso: TSSetUp(), TSProblemType, TS 2432 @*/ 2433 PetscErrorCode TSSetProblemType(TS ts, TSProblemType type) 2434 { 2435 PetscErrorCode ierr; 2436 2437 PetscFunctionBegin; 2438 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2439 ts->problem_type = type; 2440 if (type == TS_LINEAR) { 2441 SNES snes; 2442 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2443 ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr); 2444 } 2445 PetscFunctionReturn(0); 2446 } 2447 2448 #undef __FUNCT__ 2449 #define __FUNCT__ "TSGetProblemType" 2450 /*@C 2451 TSGetProblemType - Gets the type of problem to be solved. 2452 2453 Not collective 2454 2455 Input Parameter: 2456 . ts - The TS 2457 2458 Output Parameter: 2459 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 2460 .vb 2461 M U_t = A U 2462 M(t) U_t = A(t) U 2463 F(t,U,U_t) 2464 .ve 2465 2466 Level: beginner 2467 2468 .keywords: TS, problem type 2469 .seealso: TSSetUp(), TSProblemType, TS 2470 @*/ 2471 PetscErrorCode TSGetProblemType(TS ts, TSProblemType *type) 2472 { 2473 PetscFunctionBegin; 2474 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2475 PetscValidIntPointer(type,2); 2476 *type = ts->problem_type; 2477 PetscFunctionReturn(0); 2478 } 2479 2480 #undef __FUNCT__ 2481 #define __FUNCT__ "TSSetUp" 2482 /*@ 2483 TSSetUp - Sets up the internal data structures for the later use 2484 of a timestepper. 2485 2486 Collective on TS 2487 2488 Input Parameter: 2489 . ts - the TS context obtained from TSCreate() 2490 2491 Notes: 2492 For basic use of the TS solvers the user need not explicitly call 2493 TSSetUp(), since these actions will automatically occur during 2494 the call to TSStep(). However, if one wishes to control this 2495 phase separately, TSSetUp() should be called after TSCreate() 2496 and optional routines of the form TSSetXXX(), but before TSStep(). 2497 2498 Level: advanced 2499 2500 .keywords: TS, timestep, setup 2501 2502 .seealso: TSCreate(), TSStep(), TSDestroy() 2503 @*/ 2504 PetscErrorCode TSSetUp(TS ts) 2505 { 2506 PetscErrorCode ierr; 2507 DM dm; 2508 PetscErrorCode (*func)(SNES,Vec,Vec,void*); 2509 PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 2510 TSIFunction ifun; 2511 TSIJacobian ijac; 2512 TSI2Jacobian i2jac; 2513 TSRHSJacobian rhsjac; 2514 2515 PetscFunctionBegin; 2516 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2517 if (ts->setupcalled) PetscFunctionReturn(0); 2518 2519 ts->total_steps = 0; 2520 if (!((PetscObject)ts)->type_name) { 2521 ierr = TSGetIFunction(ts,NULL,&ifun,NULL);CHKERRQ(ierr); 2522 ierr = TSSetType(ts,ifun ? TSBEULER : TSEULER);CHKERRQ(ierr); 2523 } 2524 2525 if (!ts->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first"); 2526 2527 if (ts->rhsjacobian.reuse) { 2528 Mat Amat,Pmat; 2529 SNES snes; 2530 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2531 ierr = SNESGetJacobian(snes,&Amat,&Pmat,NULL,NULL);CHKERRQ(ierr); 2532 /* Matching matrices implies that an IJacobian is NOT set, because if it had been set, the IJacobian's matrix would 2533 * have displaced the RHS matrix */ 2534 if (Amat == ts->Arhs) { 2535 ierr = MatDuplicate(ts->Arhs,MAT_DO_NOT_COPY_VALUES,&Amat);CHKERRQ(ierr); 2536 ierr = SNESSetJacobian(snes,Amat,NULL,NULL,NULL);CHKERRQ(ierr); 2537 ierr = MatDestroy(&Amat);CHKERRQ(ierr); 2538 } 2539 if (Pmat == ts->Brhs) { 2540 ierr = MatDuplicate(ts->Brhs,MAT_DO_NOT_COPY_VALUES,&Pmat);CHKERRQ(ierr); 2541 ierr = SNESSetJacobian(snes,NULL,Pmat,NULL,NULL);CHKERRQ(ierr); 2542 ierr = MatDestroy(&Pmat);CHKERRQ(ierr); 2543 } 2544 } 2545 if (ts->ops->setup) { 2546 ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr); 2547 } 2548 2549 /* In the case where we've set a DMTSFunction or what have you, we need the default SNESFunction 2550 to be set right but can't do it elsewhere due to the overreliance on ctx=ts. 2551 */ 2552 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 2553 ierr = DMSNESGetFunction(dm,&func,NULL);CHKERRQ(ierr); 2554 if (!func) { 2555 ierr = DMSNESSetFunction(dm,SNESTSFormFunction,ts);CHKERRQ(ierr); 2556 } 2557 /* If the SNES doesn't have a jacobian set and the TS has an ijacobian or rhsjacobian set, set the SNES to use it. 2558 Otherwise, the SNES will use coloring internally to form the Jacobian. 2559 */ 2560 ierr = DMSNESGetJacobian(dm,&jac,NULL);CHKERRQ(ierr); 2561 ierr = DMTSGetIJacobian(dm,&ijac,NULL);CHKERRQ(ierr); 2562 ierr = DMTSGetI2Jacobian(dm,&i2jac,NULL);CHKERRQ(ierr); 2563 ierr = DMTSGetRHSJacobian(dm,&rhsjac,NULL);CHKERRQ(ierr); 2564 if (!jac && (ijac || i2jac || rhsjac)) { 2565 ierr = DMSNESSetJacobian(dm,SNESTSFormJacobian,ts);CHKERRQ(ierr); 2566 } 2567 2568 /* if time integration scheme has a starting method, call it */ 2569 if (ts->ops->startingmethod) { 2570 ierr = (*ts->ops->startingmethod)(ts);CHKERRQ(ierr); 2571 } 2572 2573 ts->setupcalled = PETSC_TRUE; 2574 PetscFunctionReturn(0); 2575 } 2576 2577 #undef __FUNCT__ 2578 #define __FUNCT__ "TSAdjointSetUp" 2579 /*@ 2580 TSAdjointSetUp - Sets up the internal data structures for the later use 2581 of an adjoint solver 2582 2583 Collective on TS 2584 2585 Input Parameter: 2586 . ts - the TS context obtained from TSCreate() 2587 2588 Level: advanced 2589 2590 .keywords: TS, timestep, setup 2591 2592 .seealso: TSCreate(), TSAdjointStep(), TSSetCostGradients() 2593 @*/ 2594 PetscErrorCode TSAdjointSetUp(TS ts) 2595 { 2596 PetscErrorCode ierr; 2597 2598 PetscFunctionBegin; 2599 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2600 if (ts->adjointsetupcalled) PetscFunctionReturn(0); 2601 if (!ts->vecs_sensi) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetCostGradients() first"); 2602 2603 if (ts->vec_costintegral) { /* if there is integral in the cost function*/ 2604 ierr = VecDuplicateVecs(ts->vecs_sensi[0],ts->numcost,&ts->vecs_drdy);CHKERRQ(ierr); 2605 if (ts->vecs_sensip){ 2606 ierr = VecDuplicateVecs(ts->vecs_sensip[0],ts->numcost,&ts->vecs_drdp);CHKERRQ(ierr); 2607 } 2608 } 2609 2610 if (ts->ops->adjointsetup) { 2611 ierr = (*ts->ops->adjointsetup)(ts);CHKERRQ(ierr); 2612 } 2613 ts->adjointsetupcalled = PETSC_TRUE; 2614 PetscFunctionReturn(0); 2615 } 2616 2617 #undef __FUNCT__ 2618 #define __FUNCT__ "TSReset" 2619 /*@ 2620 TSReset - Resets a TS context and removes any allocated Vecs and Mats. 2621 2622 Collective on TS 2623 2624 Input Parameter: 2625 . ts - the TS context obtained from TSCreate() 2626 2627 Level: beginner 2628 2629 .keywords: TS, timestep, reset 2630 2631 .seealso: TSCreate(), TSSetup(), TSDestroy() 2632 @*/ 2633 PetscErrorCode TSReset(TS ts) 2634 { 2635 PetscErrorCode ierr; 2636 2637 PetscFunctionBegin; 2638 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2639 2640 if (ts->ops->reset) { 2641 ierr = (*ts->ops->reset)(ts);CHKERRQ(ierr); 2642 } 2643 if (ts->snes) {ierr = SNESReset(ts->snes);CHKERRQ(ierr);} 2644 if (ts->adapt) {ierr = TSAdaptReset(ts->adapt);CHKERRQ(ierr);} 2645 2646 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 2647 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 2648 ierr = VecDestroy(&ts->Frhs);CHKERRQ(ierr); 2649 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 2650 ierr = VecDestroy(&ts->vec_dot);CHKERRQ(ierr); 2651 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 2652 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 2653 ierr = VecDestroyVecs(ts->nwork,&ts->work);CHKERRQ(ierr); 2654 2655 if (ts->vec_costintegral) { 2656 ierr = VecDestroyVecs(ts->numcost,&ts->vecs_drdy);CHKERRQ(ierr); 2657 if (ts->vecs_drdp){ 2658 ierr = VecDestroyVecs(ts->numcost,&ts->vecs_drdp);CHKERRQ(ierr); 2659 } 2660 } 2661 ts->vecs_sensi = NULL; 2662 ts->vecs_sensip = NULL; 2663 ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr); 2664 ierr = VecDestroy(&ts->vec_costintegral);CHKERRQ(ierr); 2665 ierr = VecDestroy(&ts->vec_costintegrand);CHKERRQ(ierr); 2666 ts->setupcalled = PETSC_FALSE; 2667 PetscFunctionReturn(0); 2668 } 2669 2670 #undef __FUNCT__ 2671 #define __FUNCT__ "TSDestroy" 2672 /*@ 2673 TSDestroy - Destroys the timestepper context that was created 2674 with TSCreate(). 2675 2676 Collective on TS 2677 2678 Input Parameter: 2679 . ts - the TS context obtained from TSCreate() 2680 2681 Level: beginner 2682 2683 .keywords: TS, timestepper, destroy 2684 2685 .seealso: TSCreate(), TSSetUp(), TSSolve() 2686 @*/ 2687 PetscErrorCode TSDestroy(TS *ts) 2688 { 2689 PetscErrorCode ierr; 2690 2691 PetscFunctionBegin; 2692 if (!*ts) PetscFunctionReturn(0); 2693 PetscValidHeaderSpecific((*ts),TS_CLASSID,1); 2694 if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; PetscFunctionReturn(0);} 2695 2696 ierr = TSReset((*ts));CHKERRQ(ierr); 2697 2698 /* if memory was published with SAWs then destroy it */ 2699 ierr = PetscObjectSAWsViewOff((PetscObject)*ts);CHKERRQ(ierr); 2700 if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);} 2701 2702 ierr = TSTrajectoryDestroy(&(*ts)->trajectory);CHKERRQ(ierr); 2703 2704 ierr = TSAdaptDestroy(&(*ts)->adapt);CHKERRQ(ierr); 2705 ierr = TSEventDestroy(&(*ts)->event);CHKERRQ(ierr); 2706 2707 ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr); 2708 ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr); 2709 ierr = TSMonitorCancel((*ts));CHKERRQ(ierr); 2710 ierr = TSAdjointMonitorCancel((*ts));CHKERRQ(ierr); 2711 2712 ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr); 2713 PetscFunctionReturn(0); 2714 } 2715 2716 #undef __FUNCT__ 2717 #define __FUNCT__ "TSGetSNES" 2718 /*@ 2719 TSGetSNES - Returns the SNES (nonlinear solver) associated with 2720 a TS (timestepper) context. Valid only for nonlinear problems. 2721 2722 Not Collective, but SNES is parallel if TS is parallel 2723 2724 Input Parameter: 2725 . ts - the TS context obtained from TSCreate() 2726 2727 Output Parameter: 2728 . snes - the nonlinear solver context 2729 2730 Notes: 2731 The user can then directly manipulate the SNES context to set various 2732 options, etc. Likewise, the user can then extract and manipulate the 2733 KSP, KSP, and PC contexts as well. 2734 2735 TSGetSNES() does not work for integrators that do not use SNES; in 2736 this case TSGetSNES() returns NULL in snes. 2737 2738 Level: beginner 2739 2740 .keywords: timestep, get, SNES 2741 @*/ 2742 PetscErrorCode TSGetSNES(TS ts,SNES *snes) 2743 { 2744 PetscErrorCode ierr; 2745 2746 PetscFunctionBegin; 2747 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2748 PetscValidPointer(snes,2); 2749 if (!ts->snes) { 2750 ierr = SNESCreate(PetscObjectComm((PetscObject)ts),&ts->snes);CHKERRQ(ierr); 2751 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 2752 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->snes);CHKERRQ(ierr); 2753 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr); 2754 if (ts->dm) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 2755 if (ts->problem_type == TS_LINEAR) { 2756 ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr); 2757 } 2758 } 2759 *snes = ts->snes; 2760 PetscFunctionReturn(0); 2761 } 2762 2763 #undef __FUNCT__ 2764 #define __FUNCT__ "TSSetSNES" 2765 /*@ 2766 TSSetSNES - Set the SNES (nonlinear solver) to be used by the timestepping context 2767 2768 Collective 2769 2770 Input Parameter: 2771 + ts - the TS context obtained from TSCreate() 2772 - snes - the nonlinear solver context 2773 2774 Notes: 2775 Most users should have the TS created by calling TSGetSNES() 2776 2777 Level: developer 2778 2779 .keywords: timestep, set, SNES 2780 @*/ 2781 PetscErrorCode TSSetSNES(TS ts,SNES snes) 2782 { 2783 PetscErrorCode ierr; 2784 PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*); 2785 2786 PetscFunctionBegin; 2787 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2788 PetscValidHeaderSpecific(snes,SNES_CLASSID,2); 2789 ierr = PetscObjectReference((PetscObject)snes);CHKERRQ(ierr); 2790 ierr = SNESDestroy(&ts->snes);CHKERRQ(ierr); 2791 2792 ts->snes = snes; 2793 2794 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 2795 ierr = SNESGetJacobian(ts->snes,NULL,NULL,&func,NULL);CHKERRQ(ierr); 2796 if (func == SNESTSFormJacobian) { 2797 ierr = SNESSetJacobian(ts->snes,NULL,NULL,SNESTSFormJacobian,ts);CHKERRQ(ierr); 2798 } 2799 PetscFunctionReturn(0); 2800 } 2801 2802 #undef __FUNCT__ 2803 #define __FUNCT__ "TSGetKSP" 2804 /*@ 2805 TSGetKSP - Returns the KSP (linear solver) associated with 2806 a TS (timestepper) context. 2807 2808 Not Collective, but KSP is parallel if TS is parallel 2809 2810 Input Parameter: 2811 . ts - the TS context obtained from TSCreate() 2812 2813 Output Parameter: 2814 . ksp - the nonlinear solver context 2815 2816 Notes: 2817 The user can then directly manipulate the KSP context to set various 2818 options, etc. Likewise, the user can then extract and manipulate the 2819 KSP and PC contexts as well. 2820 2821 TSGetKSP() does not work for integrators that do not use KSP; 2822 in this case TSGetKSP() returns NULL in ksp. 2823 2824 Level: beginner 2825 2826 .keywords: timestep, get, KSP 2827 @*/ 2828 PetscErrorCode TSGetKSP(TS ts,KSP *ksp) 2829 { 2830 PetscErrorCode ierr; 2831 SNES snes; 2832 2833 PetscFunctionBegin; 2834 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2835 PetscValidPointer(ksp,2); 2836 if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first"); 2837 if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()"); 2838 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2839 ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr); 2840 PetscFunctionReturn(0); 2841 } 2842 2843 /* ----------- Routines to set solver parameters ---------- */ 2844 2845 #undef __FUNCT__ 2846 #define __FUNCT__ "TSGetDuration" 2847 /*@ 2848 TSGetDuration - Gets the maximum number of timesteps to use and 2849 maximum time for iteration. 2850 2851 Not Collective 2852 2853 Input Parameters: 2854 + ts - the TS context obtained from TSCreate() 2855 . maxsteps - maximum number of iterations to use, or NULL 2856 - maxtime - final time to iterate to, or NULL 2857 2858 Level: intermediate 2859 2860 .keywords: TS, timestep, get, maximum, iterations, time 2861 @*/ 2862 PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime) 2863 { 2864 PetscFunctionBegin; 2865 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2866 if (maxsteps) { 2867 PetscValidIntPointer(maxsteps,2); 2868 *maxsteps = ts->max_steps; 2869 } 2870 if (maxtime) { 2871 PetscValidScalarPointer(maxtime,3); 2872 *maxtime = ts->max_time; 2873 } 2874 PetscFunctionReturn(0); 2875 } 2876 2877 #undef __FUNCT__ 2878 #define __FUNCT__ "TSSetDuration" 2879 /*@ 2880 TSSetDuration - Sets the maximum number of timesteps to use and 2881 maximum time for iteration. 2882 2883 Logically Collective on TS 2884 2885 Input Parameters: 2886 + ts - the TS context obtained from TSCreate() 2887 . maxsteps - maximum number of iterations to use 2888 - maxtime - final time to iterate to 2889 2890 Options Database Keys: 2891 . -ts_max_steps <maxsteps> - Sets maxsteps 2892 . -ts_final_time <maxtime> - Sets maxtime 2893 2894 Notes: 2895 The default maximum number of iterations is 5000. Default time is 5.0 2896 2897 Level: intermediate 2898 2899 .keywords: TS, timestep, set, maximum, iterations 2900 2901 .seealso: TSSetExactFinalTime() 2902 @*/ 2903 PetscErrorCode TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime) 2904 { 2905 PetscFunctionBegin; 2906 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2907 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 2908 PetscValidLogicalCollectiveReal(ts,maxtime,2); 2909 if (maxsteps >= 0) ts->max_steps = maxsteps; 2910 if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime; 2911 PetscFunctionReturn(0); 2912 } 2913 2914 #undef __FUNCT__ 2915 #define __FUNCT__ "TSSetSolution" 2916 /*@ 2917 TSSetSolution - Sets the initial solution vector 2918 for use by the TS routines. 2919 2920 Logically Collective on TS and Vec 2921 2922 Input Parameters: 2923 + ts - the TS context obtained from TSCreate() 2924 - u - the solution vector 2925 2926 Level: beginner 2927 2928 .keywords: TS, timestep, set, solution, initial conditions 2929 @*/ 2930 PetscErrorCode TSSetSolution(TS ts,Vec u) 2931 { 2932 PetscErrorCode ierr; 2933 DM dm; 2934 2935 PetscFunctionBegin; 2936 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2937 PetscValidHeaderSpecific(u,VEC_CLASSID,2); 2938 ierr = PetscObjectReference((PetscObject)u);CHKERRQ(ierr); 2939 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 2940 ts->vec_sol = u; 2941 2942 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 2943 ierr = DMShellSetGlobalVector(dm,u);CHKERRQ(ierr); 2944 PetscFunctionReturn(0); 2945 } 2946 2947 #undef __FUNCT__ 2948 #define __FUNCT__ "TSAdjointSetSteps" 2949 /*@ 2950 TSAdjointSetSteps - Sets the number of steps the adjoint solver should take backward in time 2951 2952 Logically Collective on TS 2953 2954 Input Parameters: 2955 + ts - the TS context obtained from TSCreate() 2956 . steps - number of steps to use 2957 2958 Level: intermediate 2959 2960 Notes: Normally one does not call this and TSAdjointSolve() integrates back to the original timestep. One can call this 2961 so as to integrate back to less than the original timestep 2962 2963 .keywords: TS, timestep, set, maximum, iterations 2964 2965 .seealso: TSSetExactFinalTime() 2966 @*/ 2967 PetscErrorCode TSAdjointSetSteps(TS ts,PetscInt steps) 2968 { 2969 PetscFunctionBegin; 2970 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2971 PetscValidLogicalCollectiveInt(ts,steps,2); 2972 if (steps < 0) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back a negative number of steps"); 2973 if (steps > ts->total_steps) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back more than the total number of forward steps"); 2974 ts->adjoint_max_steps = steps; 2975 PetscFunctionReturn(0); 2976 } 2977 2978 #undef __FUNCT__ 2979 #define __FUNCT__ "TSSetCostGradients" 2980 /*@ 2981 TSSetCostGradients - Sets the initial value of the gradients of the cost function w.r.t. initial conditions and w.r.t. the problem parameters 2982 for use by the TSAdjoint routines. 2983 2984 Logically Collective on TS and Vec 2985 2986 Input Parameters: 2987 + ts - the TS context obtained from TSCreate() 2988 . 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 2989 - mu - gradients with respect to the parameters, the number of entries in these vectors is the same as the number of parameters 2990 2991 Level: beginner 2992 2993 Notes: the entries in these vectors must be correctly initialized with the values lamda_i = df/dy|finaltime mu_i = df/dp|finaltime 2994 2995 .keywords: TS, timestep, set, sensitivity, initial conditions 2996 @*/ 2997 PetscErrorCode TSSetCostGradients(TS ts,PetscInt numcost,Vec *lambda,Vec *mu) 2998 { 2999 PetscFunctionBegin; 3000 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3001 PetscValidPointer(lambda,2); 3002 ts->vecs_sensi = lambda; 3003 ts->vecs_sensip = mu; 3004 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"); 3005 ts->numcost = numcost; 3006 PetscFunctionReturn(0); 3007 } 3008 3009 #undef __FUNCT__ 3010 #define __FUNCT__ "TSAdjointSetRHSJacobian" 3011 /*@C 3012 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. 3013 3014 Logically Collective on TS 3015 3016 Input Parameters: 3017 + ts - The TS context obtained from TSCreate() 3018 - func - The function 3019 3020 Calling sequence of func: 3021 $ func (TS ts,PetscReal t,Vec y,Mat A,void *ctx); 3022 + t - current timestep 3023 . y - input vector (current ODE solution) 3024 . A - output matrix 3025 - ctx - [optional] user-defined function context 3026 3027 Level: intermediate 3028 3029 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 3030 3031 .keywords: TS, sensitivity 3032 .seealso: 3033 @*/ 3034 PetscErrorCode TSAdjointSetRHSJacobian(TS ts,Mat Amat,PetscErrorCode (*func)(TS,PetscReal,Vec,Mat,void*),void *ctx) 3035 { 3036 PetscErrorCode ierr; 3037 3038 PetscFunctionBegin; 3039 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3040 if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 3041 3042 ts->rhsjacobianp = func; 3043 ts->rhsjacobianpctx = ctx; 3044 if(Amat) { 3045 ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 3046 ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr); 3047 ts->Jacp = Amat; 3048 } 3049 PetscFunctionReturn(0); 3050 } 3051 3052 #undef __FUNCT__ 3053 #define __FUNCT__ "TSAdjointComputeRHSJacobian" 3054 /*@C 3055 TSAdjointComputeRHSJacobian - Runs the user-defined Jacobian function. 3056 3057 Collective on TS 3058 3059 Input Parameters: 3060 . ts - The TS context obtained from TSCreate() 3061 3062 Level: developer 3063 3064 .keywords: TS, sensitivity 3065 .seealso: TSAdjointSetRHSJacobian() 3066 @*/ 3067 PetscErrorCode TSAdjointComputeRHSJacobian(TS ts,PetscReal t,Vec X,Mat Amat) 3068 { 3069 PetscErrorCode ierr; 3070 3071 PetscFunctionBegin; 3072 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3073 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 3074 PetscValidPointer(Amat,4); 3075 3076 PetscStackPush("TS user JacobianP function for sensitivity analysis"); 3077 ierr = (*ts->rhsjacobianp)(ts,t,X,Amat,ts->rhsjacobianpctx); CHKERRQ(ierr); 3078 PetscStackPop; 3079 PetscFunctionReturn(0); 3080 } 3081 3082 #undef __FUNCT__ 3083 #define __FUNCT__ "TSSetCostIntegrand" 3084 /*@C 3085 TSSetCostIntegrand - Sets the routine for evaluating the integral term in one or more cost functions 3086 3087 Logically Collective on TS 3088 3089 Input Parameters: 3090 + ts - the TS context obtained from TSCreate() 3091 . numcost - number of gradients to be computed, this is the number of cost functions 3092 . rf - routine for evaluating the integrand function 3093 . drdyf - function that computes the gradients of the r's with respect to y,NULL if not a function y 3094 . drdpf - function that computes the gradients of the r's with respect to p, NULL if not a function of p 3095 . fwd - flag indicating whether to evaluate cost integral in the forward run or the adjoint run 3096 - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL) 3097 3098 Calling sequence of rf: 3099 $ rf(TS ts,PetscReal t,Vec y,Vec f[],void *ctx); 3100 3101 + t - current timestep 3102 . y - input vector 3103 . f - function result; one vector entry for each cost function 3104 - ctx - [optional] user-defined function context 3105 3106 Calling sequence of drdyf: 3107 $ PetscErroCode drdyf(TS ts,PetscReal t,Vec y,Vec *drdy,void *ctx); 3108 3109 Calling sequence of drdpf: 3110 $ PetscErroCode drdpf(TS ts,PetscReal t,Vec y,Vec *drdp,void *ctx); 3111 3112 Level: intermediate 3113 3114 Notes: For optimization there is generally a single cost function, numcost = 1. For sensitivities there may be multiple cost functions 3115 3116 .keywords: TS, sensitivity analysis, timestep, set, quadrature, function 3117 3118 .seealso: TSAdjointSetRHSJacobian(),TSGetCostGradients(), TSSetCostGradients() 3119 @*/ 3120 PetscErrorCode TSSetCostIntegrand(TS ts,PetscInt numcost,PetscErrorCode (*rf)(TS,PetscReal,Vec,Vec,void*), 3121 PetscErrorCode (*drdyf)(TS,PetscReal,Vec,Vec*,void*), 3122 PetscErrorCode (*drdpf)(TS,PetscReal,Vec,Vec*,void*), 3123 PetscBool fwd,void *ctx) 3124 { 3125 PetscErrorCode ierr; 3126 3127 PetscFunctionBegin; 3128 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3129 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()"); 3130 if (!ts->numcost) ts->numcost=numcost; 3131 3132 ts->costintegralfwd = fwd; /* Evaluate the cost integral in forward run if fwd is true */ 3133 ierr = VecCreateSeq(PETSC_COMM_SELF,numcost,&ts->vec_costintegral);CHKERRQ(ierr); 3134 ierr = VecDuplicate(ts->vec_costintegral,&ts->vec_costintegrand);CHKERRQ(ierr); 3135 ts->costintegrand = rf; 3136 ts->costintegrandctx = ctx; 3137 ts->drdyfunction = drdyf; 3138 ts->drdpfunction = drdpf; 3139 PetscFunctionReturn(0); 3140 } 3141 3142 #undef __FUNCT__ 3143 #define __FUNCT__ "TSGetCostIntegral" 3144 /*@ 3145 TSGetCostIntegral - Returns the values of the integral term in the cost functions. 3146 It is valid to call the routine after a backward run. 3147 3148 Not Collective 3149 3150 Input Parameter: 3151 . ts - the TS context obtained from TSCreate() 3152 3153 Output Parameter: 3154 . v - the vector containing the integrals for each cost function 3155 3156 Level: intermediate 3157 3158 .seealso: TSSetCostIntegrand() 3159 3160 .keywords: TS, sensitivity analysis 3161 @*/ 3162 PetscErrorCode TSGetCostIntegral(TS ts,Vec *v) 3163 { 3164 PetscFunctionBegin; 3165 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3166 PetscValidPointer(v,2); 3167 *v = ts->vec_costintegral; 3168 PetscFunctionReturn(0); 3169 } 3170 3171 #undef __FUNCT__ 3172 #define __FUNCT__ "TSAdjointComputeCostIntegrand" 3173 /*@ 3174 TSAdjointComputeCostIntegrand - Evaluates the integral function in the cost functions. 3175 3176 Input Parameters: 3177 + ts - the TS context 3178 . t - current time 3179 - y - state vector, i.e. current solution 3180 3181 Output Parameter: 3182 . q - vector of size numcost to hold the outputs 3183 3184 Note: 3185 Most users should not need to explicitly call this routine, as it 3186 is used internally within the sensitivity analysis context. 3187 3188 Level: developer 3189 3190 .keywords: TS, compute 3191 3192 .seealso: TSSetCostIntegrand() 3193 @*/ 3194 PetscErrorCode TSAdjointComputeCostIntegrand(TS ts,PetscReal t,Vec y,Vec q) 3195 { 3196 PetscErrorCode ierr; 3197 3198 PetscFunctionBegin; 3199 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3200 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3201 PetscValidHeaderSpecific(q,VEC_CLASSID,4); 3202 3203 ierr = PetscLogEventBegin(TS_FunctionEval,ts,y,q,0);CHKERRQ(ierr); 3204 if (ts->costintegrand) { 3205 PetscStackPush("TS user integrand in the cost function"); 3206 ierr = (*ts->costintegrand)(ts,t,y,q,ts->costintegrandctx);CHKERRQ(ierr); 3207 PetscStackPop; 3208 } else { 3209 ierr = VecZeroEntries(q);CHKERRQ(ierr); 3210 } 3211 3212 ierr = PetscLogEventEnd(TS_FunctionEval,ts,y,q,0);CHKERRQ(ierr); 3213 PetscFunctionReturn(0); 3214 } 3215 3216 #undef __FUNCT__ 3217 #define __FUNCT__ "TSAdjointComputeDRDYFunction" 3218 /*@ 3219 TSAdjointComputeDRDYFunction - Runs the user-defined DRDY function. 3220 3221 Collective on TS 3222 3223 Input Parameters: 3224 . ts - The TS context obtained from TSCreate() 3225 3226 Notes: 3227 TSAdjointComputeDRDYFunction() is typically used for sensitivity implementation, 3228 so most users would not generally call this routine themselves. 3229 3230 Level: developer 3231 3232 .keywords: TS, sensitivity 3233 .seealso: TSAdjointComputeDRDYFunction() 3234 @*/ 3235 PetscErrorCode TSAdjointComputeDRDYFunction(TS ts,PetscReal t,Vec y,Vec *drdy) 3236 { 3237 PetscErrorCode ierr; 3238 3239 PetscFunctionBegin; 3240 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3241 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3242 3243 PetscStackPush("TS user DRDY function for sensitivity analysis"); 3244 ierr = (*ts->drdyfunction)(ts,t,y,drdy,ts->costintegrandctx); CHKERRQ(ierr); 3245 PetscStackPop; 3246 PetscFunctionReturn(0); 3247 } 3248 3249 #undef __FUNCT__ 3250 #define __FUNCT__ "TSAdjointComputeDRDPFunction" 3251 /*@ 3252 TSAdjointComputeDRDPFunction - Runs the user-defined DRDP function. 3253 3254 Collective on TS 3255 3256 Input Parameters: 3257 . ts - The TS context obtained from TSCreate() 3258 3259 Notes: 3260 TSDRDPFunction() is typically used for sensitivity implementation, 3261 so most users would not generally call this routine themselves. 3262 3263 Level: developer 3264 3265 .keywords: TS, sensitivity 3266 .seealso: TSAdjointSetDRDPFunction() 3267 @*/ 3268 PetscErrorCode TSAdjointComputeDRDPFunction(TS ts,PetscReal t,Vec y,Vec *drdp) 3269 { 3270 PetscErrorCode ierr; 3271 3272 PetscFunctionBegin; 3273 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3274 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3275 3276 PetscStackPush("TS user DRDP function for sensitivity analysis"); 3277 ierr = (*ts->drdpfunction)(ts,t,y,drdp,ts->costintegrandctx); CHKERRQ(ierr); 3278 PetscStackPop; 3279 PetscFunctionReturn(0); 3280 } 3281 3282 #undef __FUNCT__ 3283 #define __FUNCT__ "TSSetPreStep" 3284 /*@C 3285 TSSetPreStep - Sets the general-purpose function 3286 called once at the beginning of each time step. 3287 3288 Logically Collective on TS 3289 3290 Input Parameters: 3291 + ts - The TS context obtained from TSCreate() 3292 - func - The function 3293 3294 Calling sequence of func: 3295 . func (TS ts); 3296 3297 Level: intermediate 3298 3299 Note: 3300 If a step is rejected, TSStep() will call this routine again before each attempt. 3301 The last completed time step number can be queried using TSGetTimeStepNumber(), the 3302 size of the step being attempted can be obtained using TSGetTimeStep(). 3303 3304 .keywords: TS, timestep 3305 .seealso: TSSetPreStage(), TSSetPostStage(), TSSetPostStep(), TSStep() 3306 @*/ 3307 PetscErrorCode TSSetPreStep(TS ts, PetscErrorCode (*func)(TS)) 3308 { 3309 PetscFunctionBegin; 3310 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3311 ts->prestep = func; 3312 PetscFunctionReturn(0); 3313 } 3314 3315 #undef __FUNCT__ 3316 #define __FUNCT__ "TSPreStep" 3317 /*@ 3318 TSPreStep - Runs the user-defined pre-step function. 3319 3320 Collective on TS 3321 3322 Input Parameters: 3323 . ts - The TS context obtained from TSCreate() 3324 3325 Notes: 3326 TSPreStep() is typically used within time stepping implementations, 3327 so most users would not generally call this routine themselves. 3328 3329 Level: developer 3330 3331 .keywords: TS, timestep 3332 .seealso: TSSetPreStep(), TSPreStage(), TSPostStage(), TSPostStep() 3333 @*/ 3334 PetscErrorCode TSPreStep(TS ts) 3335 { 3336 PetscErrorCode ierr; 3337 3338 PetscFunctionBegin; 3339 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3340 if (ts->prestep) { 3341 PetscStackCallStandard((*ts->prestep),(ts)); 3342 } 3343 PetscFunctionReturn(0); 3344 } 3345 3346 #undef __FUNCT__ 3347 #define __FUNCT__ "TSSetPreStage" 3348 /*@C 3349 TSSetPreStage - Sets the general-purpose function 3350 called once at the beginning of each stage. 3351 3352 Logically Collective on TS 3353 3354 Input Parameters: 3355 + ts - The TS context obtained from TSCreate() 3356 - func - The function 3357 3358 Calling sequence of func: 3359 . PetscErrorCode func(TS ts, PetscReal stagetime); 3360 3361 Level: intermediate 3362 3363 Note: 3364 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 3365 The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being 3366 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 3367 3368 .keywords: TS, timestep 3369 .seealso: TSSetPostStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3370 @*/ 3371 PetscErrorCode TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal)) 3372 { 3373 PetscFunctionBegin; 3374 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3375 ts->prestage = func; 3376 PetscFunctionReturn(0); 3377 } 3378 3379 #undef __FUNCT__ 3380 #define __FUNCT__ "TSSetPostStage" 3381 /*@C 3382 TSSetPostStage - Sets the general-purpose function 3383 called once at the end of each stage. 3384 3385 Logically Collective on TS 3386 3387 Input Parameters: 3388 + ts - The TS context obtained from TSCreate() 3389 - func - The function 3390 3391 Calling sequence of func: 3392 . PetscErrorCode func(TS ts, PetscReal stagetime, PetscInt stageindex, Vec* Y); 3393 3394 Level: intermediate 3395 3396 Note: 3397 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 3398 The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being 3399 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 3400 3401 .keywords: TS, timestep 3402 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3403 @*/ 3404 PetscErrorCode TSSetPostStage(TS ts, PetscErrorCode (*func)(TS,PetscReal,PetscInt,Vec*)) 3405 { 3406 PetscFunctionBegin; 3407 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3408 ts->poststage = func; 3409 PetscFunctionReturn(0); 3410 } 3411 3412 #undef __FUNCT__ 3413 #define __FUNCT__ "TSSetPostEvaluate" 3414 /*@C 3415 TSSetPostEvaluate - Sets the general-purpose function 3416 called once at the end of each step evaluation. 3417 3418 Logically Collective on TS 3419 3420 Input Parameters: 3421 + ts - The TS context obtained from TSCreate() 3422 - func - The function 3423 3424 Calling sequence of func: 3425 . PetscErrorCode func(TS ts); 3426 3427 Level: intermediate 3428 3429 Note: 3430 Semantically, TSSetPostEvaluate() differs from TSSetPostStep() since the function it sets is called before event-handling 3431 thus guaranteeing the same solution (computed by the time-stepper) will be passed to it. On the other hand, TSPostStep() 3432 may be passed a different solution, possibly changed by the event handler. TSPostEvaluate() is called after the next step 3433 solution is evaluated allowing to modify it, if need be. The solution can be obtained with TSGetSolution(), the time step 3434 with TSGetTimeStep(), and the time at the start of the step is available via TSGetTime() 3435 3436 .keywords: TS, timestep 3437 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3438 @*/ 3439 PetscErrorCode TSSetPostEvaluate(TS ts, PetscErrorCode (*func)(TS)) 3440 { 3441 PetscFunctionBegin; 3442 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3443 ts->postevaluate = func; 3444 PetscFunctionReturn(0); 3445 } 3446 3447 #undef __FUNCT__ 3448 #define __FUNCT__ "TSPreStage" 3449 /*@ 3450 TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage() 3451 3452 Collective on TS 3453 3454 Input Parameters: 3455 . ts - The TS context obtained from TSCreate() 3456 stagetime - The absolute time of the current stage 3457 3458 Notes: 3459 TSPreStage() is typically used within time stepping implementations, 3460 most users would not generally call this routine themselves. 3461 3462 Level: developer 3463 3464 .keywords: TS, timestep 3465 .seealso: TSPostStage(), TSSetPreStep(), TSPreStep(), TSPostStep() 3466 @*/ 3467 PetscErrorCode TSPreStage(TS ts, PetscReal stagetime) 3468 { 3469 PetscErrorCode ierr; 3470 3471 PetscFunctionBegin; 3472 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3473 if (ts->prestage) { 3474 PetscStackCallStandard((*ts->prestage),(ts,stagetime)); 3475 } 3476 PetscFunctionReturn(0); 3477 } 3478 3479 #undef __FUNCT__ 3480 #define __FUNCT__ "TSPostStage" 3481 /*@ 3482 TSPostStage - Runs the user-defined post-stage function set using TSSetPostStage() 3483 3484 Collective on TS 3485 3486 Input Parameters: 3487 . ts - The TS context obtained from TSCreate() 3488 stagetime - The absolute time of the current stage 3489 stageindex - Stage number 3490 Y - Array of vectors (of size = total number 3491 of stages) with the stage solutions 3492 3493 Notes: 3494 TSPostStage() 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: TSPreStage(), TSSetPreStep(), TSPreStep(), TSPostStep() 3501 @*/ 3502 PetscErrorCode TSPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y) 3503 { 3504 PetscErrorCode ierr; 3505 3506 PetscFunctionBegin; 3507 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3508 if (ts->poststage) { 3509 PetscStackCallStandard((*ts->poststage),(ts,stagetime,stageindex,Y)); 3510 } 3511 PetscFunctionReturn(0); 3512 } 3513 3514 #undef __FUNCT__ 3515 #define __FUNCT__ "TSPostEvaluate" 3516 /*@ 3517 TSPostEvaluate - Runs the user-defined post-evaluate function set using TSSetPostEvaluate() 3518 3519 Collective on TS 3520 3521 Input Parameters: 3522 . ts - The TS context obtained from TSCreate() 3523 3524 Notes: 3525 TSPostEvaluate() is typically used within time stepping implementations, 3526 most users would not generally call this routine themselves. 3527 3528 Level: developer 3529 3530 .keywords: TS, timestep 3531 .seealso: TSSetPostEvaluate(), TSSetPreStep(), TSPreStep(), TSPostStep() 3532 @*/ 3533 PetscErrorCode TSPostEvaluate(TS ts) 3534 { 3535 PetscErrorCode ierr; 3536 3537 PetscFunctionBegin; 3538 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3539 if (ts->postevaluate) { 3540 PetscStackCallStandard((*ts->postevaluate),(ts)); 3541 } 3542 PetscFunctionReturn(0); 3543 } 3544 3545 #undef __FUNCT__ 3546 #define __FUNCT__ "TSSetPostStep" 3547 /*@C 3548 TSSetPostStep - Sets the general-purpose function 3549 called once at the end of each time step. 3550 3551 Logically Collective on TS 3552 3553 Input Parameters: 3554 + ts - The TS context obtained from TSCreate() 3555 - func - The function 3556 3557 Calling sequence of func: 3558 $ func (TS ts); 3559 3560 Notes: 3561 The function set by TSSetPostStep() is called after each successful step. The solution vector X 3562 obtained by TSGetSolution() may be different than that computed at the step end if the event handler 3563 locates an event and TSPostEvent() modifies it. Use TSSetPostEvaluate() if an unmodified solution is needed instead. 3564 3565 Level: intermediate 3566 3567 .keywords: TS, timestep 3568 .seealso: TSSetPreStep(), TSSetPreStage(), TSSetPostEvaluate(), TSGetTimeStep(), TSGetTimeStepNumber(), TSGetTime() 3569 @*/ 3570 PetscErrorCode TSSetPostStep(TS ts, PetscErrorCode (*func)(TS)) 3571 { 3572 PetscFunctionBegin; 3573 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3574 ts->poststep = func; 3575 PetscFunctionReturn(0); 3576 } 3577 3578 #undef __FUNCT__ 3579 #define __FUNCT__ "TSPostStep" 3580 /*@ 3581 TSPostStep - Runs the user-defined post-step function. 3582 3583 Collective on TS 3584 3585 Input Parameters: 3586 . ts - The TS context obtained from TSCreate() 3587 3588 Notes: 3589 TSPostStep() is typically used within time stepping implementations, 3590 so most users would not generally call this routine themselves. 3591 3592 Level: developer 3593 3594 .keywords: TS, timestep 3595 @*/ 3596 PetscErrorCode TSPostStep(TS ts) 3597 { 3598 PetscErrorCode ierr; 3599 3600 PetscFunctionBegin; 3601 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3602 if (ts->poststep) { 3603 PetscStackCallStandard((*ts->poststep),(ts)); 3604 } 3605 PetscFunctionReturn(0); 3606 } 3607 3608 /* ------------ Routines to set performance monitoring options ----------- */ 3609 3610 #undef __FUNCT__ 3611 #define __FUNCT__ "TSMonitorSet" 3612 /*@C 3613 TSMonitorSet - Sets an ADDITIONAL function that is to be used at every 3614 timestep to display the iteration's progress. 3615 3616 Logically Collective on TS 3617 3618 Input Parameters: 3619 + ts - the TS context obtained from TSCreate() 3620 . monitor - monitoring routine 3621 . mctx - [optional] user-defined context for private data for the 3622 monitor routine (use NULL if no context is desired) 3623 - monitordestroy - [optional] routine that frees monitor context 3624 (may be NULL) 3625 3626 Calling sequence of monitor: 3627 $ int monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx) 3628 3629 + ts - the TS context 3630 . 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) 3631 . time - current time 3632 . u - current iterate 3633 - mctx - [optional] monitoring context 3634 3635 Notes: 3636 This routine adds an additional monitor to the list of monitors that 3637 already has been loaded. 3638 3639 Fortran notes: Only a single monitor function can be set for each TS object 3640 3641 Level: intermediate 3642 3643 .keywords: TS, timestep, set, monitor 3644 3645 .seealso: TSMonitorDefault(), TSMonitorCancel() 3646 @*/ 3647 PetscErrorCode TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**)) 3648 { 3649 PetscErrorCode ierr; 3650 PetscInt i; 3651 PetscBool identical; 3652 3653 PetscFunctionBegin; 3654 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3655 for (i=0; i<ts->numbermonitors;i++) { 3656 ierr = PetscMonitorCompare((PetscErrorCode (*)(void))monitor,mctx,mdestroy,(PetscErrorCode (*)(void))ts->monitor[i],ts->monitorcontext[i],ts->monitordestroy[i],&identical);CHKERRQ(ierr); 3657 if (identical) PetscFunctionReturn(0); 3658 } 3659 if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3660 ts->monitor[ts->numbermonitors] = monitor; 3661 ts->monitordestroy[ts->numbermonitors] = mdestroy; 3662 ts->monitorcontext[ts->numbermonitors++] = (void*)mctx; 3663 PetscFunctionReturn(0); 3664 } 3665 3666 #undef __FUNCT__ 3667 #define __FUNCT__ "TSMonitorCancel" 3668 /*@C 3669 TSMonitorCancel - Clears all the monitors that have been set on a time-step object. 3670 3671 Logically Collective on TS 3672 3673 Input Parameters: 3674 . ts - the TS context obtained from TSCreate() 3675 3676 Notes: 3677 There is no way to remove a single, specific monitor. 3678 3679 Level: intermediate 3680 3681 .keywords: TS, timestep, set, monitor 3682 3683 .seealso: TSMonitorDefault(), TSMonitorSet() 3684 @*/ 3685 PetscErrorCode TSMonitorCancel(TS ts) 3686 { 3687 PetscErrorCode ierr; 3688 PetscInt i; 3689 3690 PetscFunctionBegin; 3691 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3692 for (i=0; i<ts->numbermonitors; i++) { 3693 if (ts->monitordestroy[i]) { 3694 ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr); 3695 } 3696 } 3697 ts->numbermonitors = 0; 3698 PetscFunctionReturn(0); 3699 } 3700 3701 #undef __FUNCT__ 3702 #define __FUNCT__ "TSMonitorDefault" 3703 /*@C 3704 TSMonitorDefault - The Default monitor, prints the timestep and time for each step 3705 3706 Level: intermediate 3707 3708 .keywords: TS, set, monitor 3709 3710 .seealso: TSMonitorSet() 3711 @*/ 3712 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf) 3713 { 3714 PetscErrorCode ierr; 3715 PetscViewer viewer = vf->viewer; 3716 PetscBool iascii,ibinary; 3717 3718 PetscFunctionBegin; 3719 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 3720 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 3721 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 3722 ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr); 3723 if (iascii) { 3724 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3725 if (step == -1){ /* this indicates it is an interpolated solution */ 3726 ierr = PetscViewerASCIIPrintf(viewer,"Interpolated solution at time %g between steps %D and %D\n",(double)ptime,ts->steps-1,ts->steps);CHKERRQ(ierr); 3727 } else { 3728 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr); 3729 } 3730 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3731 } else if (ibinary) { 3732 PetscMPIInt rank; 3733 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 3734 if (!rank) { 3735 PetscBool skipHeader; 3736 PetscInt classid = REAL_FILE_CLASSID; 3737 3738 ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr); 3739 if (!skipHeader) { 3740 ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 3741 } 3742 ierr = PetscRealView(1,&ptime,viewer);CHKERRQ(ierr); 3743 } else { 3744 ierr = PetscRealView(0,&ptime,viewer);CHKERRQ(ierr); 3745 } 3746 } 3747 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 3748 PetscFunctionReturn(0); 3749 } 3750 3751 #undef __FUNCT__ 3752 #define __FUNCT__ "TSAdjointMonitorSet" 3753 /*@C 3754 TSAdjointMonitorSet - Sets an ADDITIONAL function that is to be used at every 3755 timestep to display the iteration's progress. 3756 3757 Logically Collective on TS 3758 3759 Input Parameters: 3760 + ts - the TS context obtained from TSCreate() 3761 . adjointmonitor - monitoring routine 3762 . adjointmctx - [optional] user-defined context for private data for the 3763 monitor routine (use NULL if no context is desired) 3764 - adjointmonitordestroy - [optional] routine that frees monitor context 3765 (may be NULL) 3766 3767 Calling sequence of monitor: 3768 $ int adjointmonitor(TS ts,PetscInt steps,PetscReal time,Vec u,PetscInt numcost,Vec *lambda, Vec *mu,void *adjointmctx) 3769 3770 + ts - the TS context 3771 . 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 3772 been interpolated to) 3773 . time - current time 3774 . u - current iterate 3775 . numcost - number of cost functionos 3776 . lambda - sensitivities to initial conditions 3777 . mu - sensitivities to parameters 3778 - adjointmctx - [optional] adjoint monitoring context 3779 3780 Notes: 3781 This routine adds an additional monitor to the list of monitors that 3782 already has been loaded. 3783 3784 Fortran notes: Only a single monitor function can be set for each TS object 3785 3786 Level: intermediate 3787 3788 .keywords: TS, timestep, set, adjoint, monitor 3789 3790 .seealso: TSAdjointMonitorCancel() 3791 @*/ 3792 PetscErrorCode TSAdjointMonitorSet(TS ts,PetscErrorCode (*adjointmonitor)(TS,PetscInt,PetscReal,Vec,PetscInt,Vec*,Vec*,void*),void *adjointmctx,PetscErrorCode (*adjointmdestroy)(void**)) 3793 { 3794 PetscErrorCode ierr; 3795 PetscInt i; 3796 PetscBool identical; 3797 3798 PetscFunctionBegin; 3799 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3800 for (i=0; i<ts->numbermonitors;i++) { 3801 ierr = PetscMonitorCompare((PetscErrorCode (*)(void))adjointmonitor,adjointmctx,adjointmdestroy,(PetscErrorCode (*)(void))ts->adjointmonitor[i],ts->adjointmonitorcontext[i],ts->adjointmonitordestroy[i],&identical);CHKERRQ(ierr); 3802 if (identical) PetscFunctionReturn(0); 3803 } 3804 if (ts->numberadjointmonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many adjoint monitors set"); 3805 ts->adjointmonitor[ts->numberadjointmonitors] = adjointmonitor; 3806 ts->adjointmonitordestroy[ts->numberadjointmonitors] = adjointmdestroy; 3807 ts->adjointmonitorcontext[ts->numberadjointmonitors++] = (void*)adjointmctx; 3808 PetscFunctionReturn(0); 3809 } 3810 3811 #undef __FUNCT__ 3812 #define __FUNCT__ "TSAdjointMonitorCancel" 3813 /*@C 3814 TSAdjointMonitorCancel - Clears all the adjoint monitors that have been set on a time-step object. 3815 3816 Logically Collective on TS 3817 3818 Input Parameters: 3819 . ts - the TS context obtained from TSCreate() 3820 3821 Notes: 3822 There is no way to remove a single, specific monitor. 3823 3824 Level: intermediate 3825 3826 .keywords: TS, timestep, set, adjoint, monitor 3827 3828 .seealso: TSAdjointMonitorSet() 3829 @*/ 3830 PetscErrorCode TSAdjointMonitorCancel(TS ts) 3831 { 3832 PetscErrorCode ierr; 3833 PetscInt i; 3834 3835 PetscFunctionBegin; 3836 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3837 for (i=0; i<ts->numberadjointmonitors; i++) { 3838 if (ts->adjointmonitordestroy[i]) { 3839 ierr = (*ts->adjointmonitordestroy[i])(&ts->adjointmonitorcontext[i]);CHKERRQ(ierr); 3840 } 3841 } 3842 ts->numberadjointmonitors = 0; 3843 PetscFunctionReturn(0); 3844 } 3845 3846 #undef __FUNCT__ 3847 #define __FUNCT__ "TSAdjointMonitorDefault" 3848 /*@C 3849 TSAdjointMonitorDefault - the default monitor of adjoint computations 3850 3851 Level: intermediate 3852 3853 .keywords: TS, set, monitor 3854 3855 .seealso: TSAdjointMonitorSet() 3856 @*/ 3857 PetscErrorCode TSAdjointMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscInt numcost,Vec *lambda,Vec *mu,PetscViewerAndFormat *vf) 3858 { 3859 PetscErrorCode ierr; 3860 PetscViewer viewer = vf->viewer; 3861 3862 PetscFunctionBegin; 3863 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 3864 ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr); 3865 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3866 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr); 3867 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3868 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 3869 PetscFunctionReturn(0); 3870 } 3871 3872 #undef __FUNCT__ 3873 #define __FUNCT__ "TSInterpolate" 3874 /*@ 3875 TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval 3876 3877 Collective on TS 3878 3879 Input Argument: 3880 + ts - time stepping context 3881 - t - time to interpolate to 3882 3883 Output Argument: 3884 . U - state at given time 3885 3886 Level: intermediate 3887 3888 Developer Notes: 3889 TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints. 3890 3891 .keywords: TS, set 3892 3893 .seealso: TSSetExactFinalTime(), TSSolve() 3894 @*/ 3895 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U) 3896 { 3897 PetscErrorCode ierr; 3898 3899 PetscFunctionBegin; 3900 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3901 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 3902 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); 3903 if (!ts->ops->interpolate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name); 3904 ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr); 3905 PetscFunctionReturn(0); 3906 } 3907 3908 #undef __FUNCT__ 3909 #define __FUNCT__ "TSStep" 3910 /*@ 3911 TSStep - Steps one time step 3912 3913 Collective on TS 3914 3915 Input Parameter: 3916 . ts - the TS context obtained from TSCreate() 3917 3918 Level: developer 3919 3920 Notes: 3921 The public interface for the ODE/DAE solvers is TSSolve(), you should almost for sure be using that routine and not this routine. 3922 3923 The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may 3924 be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages. 3925 3926 This may over-step the final time provided in TSSetDuration() depending on the time-step used. TSSolve() interpolates to exactly the 3927 time provided in TSSetDuration(). One can use TSInterpolate() to determine an interpolated solution within the final timestep. 3928 3929 .keywords: TS, timestep, solve 3930 3931 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSInterpolate() 3932 @*/ 3933 PetscErrorCode TSStep(TS ts) 3934 { 3935 PetscErrorCode ierr; 3936 static PetscBool cite = PETSC_FALSE; 3937 PetscReal ptime; 3938 3939 PetscFunctionBegin; 3940 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3941 ierr = PetscCitationsRegister("@techreport{tspaper,\n" 3942 " title = {{PETSc/TS}: A Modern Scalable {DAE/ODE} Solver Library},\n" 3943 " author = {Shrirang Abhyankar and Jed Brown and Emil Constantinescu and Debojyoti Ghosh and Barry F. Smith},\n" 3944 " type = {Preprint},\n" 3945 " number = {ANL/MCS-P5061-0114},\n" 3946 " institution = {Argonne National Laboratory},\n" 3947 " year = {2014}\n}\n",&cite);CHKERRQ(ierr); 3948 3949 ierr = TSSetUp(ts);CHKERRQ(ierr); 3950 ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr); 3951 3952 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()"); 3953 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"); 3954 3955 if (!ts->steps) ts->ptime_prev = ts->ptime; 3956 ts->reason = TS_CONVERGED_ITERATING; 3957 ptime = ts->ptime; ts->ptime_prev_rollback = ts->ptime_prev; 3958 if (!ts->ops->step) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSStep not implemented for type '%s'",((PetscObject)ts)->type_name); 3959 ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3960 ierr = (*ts->ops->step)(ts);CHKERRQ(ierr); 3961 ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3962 ts->ptime_prev = ptime; 3963 ts->steps++; ts->total_steps++; 3964 ts->steprollback = PETSC_FALSE; 3965 ts->steprestart = PETSC_FALSE; 3966 3967 if (ts->reason < 0) { 3968 if (ts->errorifstepfailed) { 3969 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]); 3970 else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]); 3971 } 3972 } else if (!ts->reason) { 3973 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 3974 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 3975 } 3976 PetscFunctionReturn(0); 3977 } 3978 3979 #undef __FUNCT__ 3980 #define __FUNCT__ "TSAdjointStep" 3981 /*@ 3982 TSAdjointStep - Steps one time step backward in the adjoint run 3983 3984 Collective on TS 3985 3986 Input Parameter: 3987 . ts - the TS context obtained from TSCreate() 3988 3989 Level: intermediate 3990 3991 .keywords: TS, adjoint, step 3992 3993 .seealso: TSAdjointSetUp(), TSAdjointSolve() 3994 @*/ 3995 PetscErrorCode TSAdjointStep(TS ts) 3996 { 3997 DM dm; 3998 PetscErrorCode ierr; 3999 4000 PetscFunctionBegin; 4001 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4002 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4003 ierr = TSAdjointSetUp(ts);CHKERRQ(ierr); 4004 4005 ierr = VecViewFromOptions(ts->vec_sol,(PetscObject)ts,"-ts_view_solution");CHKERRQ(ierr); 4006 4007 ts->reason = TS_CONVERGED_ITERATING; 4008 ts->ptime_prev = ts->ptime; 4009 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); 4010 ierr = PetscLogEventBegin(TS_AdjointStep,ts,0,0,0);CHKERRQ(ierr); 4011 ierr = (*ts->ops->adjointstep)(ts);CHKERRQ(ierr); 4012 ierr = PetscLogEventEnd(TS_AdjointStep,ts,0,0,0);CHKERRQ(ierr); 4013 ts->steps++; ts->total_steps--; 4014 4015 if (ts->reason < 0) { 4016 if (ts->errorifstepfailed) { 4017 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]); 4018 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]); 4019 else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]); 4020 } 4021 } else if (!ts->reason) { 4022 if (ts->steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS; 4023 } 4024 PetscFunctionReturn(0); 4025 } 4026 4027 #undef __FUNCT__ 4028 #define __FUNCT__ "TSEvaluateWLTE" 4029 /*@ 4030 TSEvaluateWLTE - Evaluate the weighted local truncation error norm 4031 at the end of a time step with a given order of accuracy. 4032 4033 Collective on TS 4034 4035 Input Arguments: 4036 + ts - time stepping context 4037 . wnormtype - norm type, either NORM_2 or NORM_INFINITY 4038 - order - optional, desired order for the error evaluation or PETSC_DECIDE 4039 4040 Output Arguments: 4041 + order - optional, the actual order of the error evaluation 4042 - wlte - the weighted local truncation error norm 4043 4044 Level: advanced 4045 4046 Notes: 4047 If the timestepper cannot evaluate the error in a particular step 4048 (eg. in the first step or restart steps after event handling), 4049 this routine returns wlte=-1.0 . 4050 4051 .seealso: TSStep(), TSAdapt, TSErrorWeightedNorm() 4052 @*/ 4053 PetscErrorCode TSEvaluateWLTE(TS ts,NormType wnormtype,PetscInt *order,PetscReal *wlte) 4054 { 4055 PetscErrorCode ierr; 4056 4057 PetscFunctionBegin; 4058 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4059 PetscValidType(ts,1); 4060 PetscValidLogicalCollectiveEnum(ts,wnormtype,4); 4061 if (order) PetscValidIntPointer(order,3); 4062 if (order) PetscValidLogicalCollectiveInt(ts,*order,3); 4063 PetscValidRealPointer(wlte,4); 4064 if (wnormtype != NORM_2 && wnormtype != NORM_INFINITY) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 4065 if (!ts->ops->evaluatewlte) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateWLTE not implemented for type '%s'",((PetscObject)ts)->type_name); 4066 ierr = (*ts->ops->evaluatewlte)(ts,wnormtype,order,wlte);CHKERRQ(ierr); 4067 PetscFunctionReturn(0); 4068 } 4069 4070 #undef __FUNCT__ 4071 #define __FUNCT__ "TSEvaluateStep" 4072 /*@ 4073 TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy. 4074 4075 Collective on TS 4076 4077 Input Arguments: 4078 + ts - time stepping context 4079 . order - desired order of accuracy 4080 - done - whether the step was evaluated at this order (pass NULL to generate an error if not available) 4081 4082 Output Arguments: 4083 . U - state at the end of the current step 4084 4085 Level: advanced 4086 4087 Notes: 4088 This function cannot be called until all stages have been evaluated. 4089 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. 4090 4091 .seealso: TSStep(), TSAdapt 4092 @*/ 4093 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done) 4094 { 4095 PetscErrorCode ierr; 4096 4097 PetscFunctionBegin; 4098 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4099 PetscValidType(ts,1); 4100 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 4101 if (!ts->ops->evaluatestep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name); 4102 ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr); 4103 PetscFunctionReturn(0); 4104 } 4105 4106 #undef __FUNCT__ 4107 #define __FUNCT__ "TSForwardCostIntegral" 4108 /*@ 4109 TSForwardCostIntegral - Evaluate the cost integral in the forward run. 4110 4111 Collective on TS 4112 4113 Input Arguments: 4114 . ts - time stepping context 4115 4116 Level: advanced 4117 4118 Notes: 4119 This function cannot be called until TSStep() has been completed. 4120 4121 .seealso: TSSolve(), TSAdjointCostIntegral() 4122 @*/ 4123 PetscErrorCode TSForwardCostIntegral(TS ts) 4124 { 4125 PetscErrorCode ierr; 4126 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4127 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); 4128 ierr = (*ts->ops->forwardintegral)(ts);CHKERRQ(ierr); 4129 PetscFunctionReturn(0); 4130 } 4131 4132 #undef __FUNCT__ 4133 #define __FUNCT__ "TSSolve" 4134 /*@ 4135 TSSolve - Steps the requested number of timesteps. 4136 4137 Collective on TS 4138 4139 Input Parameter: 4140 + ts - the TS context obtained from TSCreate() 4141 - u - the solution vector (can be null if TSSetSolution() was used and TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP) was not used, 4142 otherwise must contain the initial conditions and will contain the solution at the final requested time 4143 4144 Level: beginner 4145 4146 Notes: 4147 The final time returned by this function may be different from the time of the internally 4148 held state accessible by TSGetSolution() and TSGetTime() because the method may have 4149 stepped over the final time. 4150 4151 .keywords: TS, timestep, solve 4152 4153 .seealso: TSCreate(), TSSetSolution(), TSStep(), TSGetTime(), TSGetSolveTime() 4154 @*/ 4155 PetscErrorCode TSSolve(TS ts,Vec u) 4156 { 4157 Vec solution; 4158 PetscErrorCode ierr; 4159 4160 PetscFunctionBegin; 4161 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4162 if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2); 4163 4164 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 */ 4165 PetscValidHeaderSpecific(u,VEC_CLASSID,2); 4166 if (!ts->vec_sol || u == ts->vec_sol) { 4167 ierr = VecDuplicate(u,&solution);CHKERRQ(ierr); 4168 ierr = TSSetSolution(ts,solution);CHKERRQ(ierr); 4169 ierr = VecDestroy(&solution);CHKERRQ(ierr); /* grant ownership */ 4170 } 4171 ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr); 4172 } else if (u) { 4173 ierr = TSSetSolution(ts,u);CHKERRQ(ierr); 4174 } 4175 ierr = TSSetUp(ts);CHKERRQ(ierr); 4176 ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr); 4177 4178 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()"); 4179 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"); 4180 4181 /* reset time step and iteration counters */ 4182 ts->steps = 0; 4183 ts->ksp_its = 0; 4184 ts->snes_its = 0; 4185 ts->num_snes_failures = 0; 4186 ts->reject = 0; 4187 ts->reason = TS_CONVERGED_ITERATING; 4188 4189 ierr = TSViewFromOptions(ts,NULL,"-ts_view_pre");CHKERRQ(ierr); 4190 4191 if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */ 4192 ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr); 4193 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 4194 ts->solvetime = ts->ptime; 4195 solution = ts->vec_sol; 4196 } else { /* Step the requested number of timesteps. */ 4197 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 4198 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 4199 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4200 ierr = TSEventInitialize(ts->event,ts,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4201 ts->steprollback = PETSC_FALSE; 4202 ts->steprestart = PETSC_TRUE; 4203 4204 while (!ts->reason) { 4205 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4206 if (!ts->steprollback) { 4207 ierr = TSPreStep(ts);CHKERRQ(ierr); 4208 } 4209 ierr = TSStep(ts);CHKERRQ(ierr); 4210 if (ts->vec_costintegral && ts->costintegralfwd) { /* Must evaluate the cost integral before event is handled. The cost integral value can also be rolled back. */ 4211 ierr = TSForwardCostIntegral(ts);CHKERRQ(ierr); 4212 } 4213 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. */ 4214 if (!ts->steprollback) { 4215 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4216 ierr = TSPostStep(ts);CHKERRQ(ierr); 4217 } 4218 } 4219 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4220 4221 if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) { 4222 ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr); 4223 ts->solvetime = ts->max_time; 4224 solution = u; 4225 ierr = TSMonitor(ts,-1,ts->solvetime,solution);CHKERRQ(ierr); 4226 } else { 4227 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 4228 ts->solvetime = ts->ptime; 4229 solution = ts->vec_sol; 4230 } 4231 } 4232 4233 ierr = TSViewFromOptions(ts,NULL,"-ts_view");CHKERRQ(ierr); 4234 ierr = VecViewFromOptions(solution,NULL,"-ts_view_solution");CHKERRQ(ierr); 4235 ierr = PetscObjectSAWsBlock((PetscObject)ts);CHKERRQ(ierr); 4236 if (ts->adjoint_solve) { 4237 ierr = TSAdjointSolve(ts);CHKERRQ(ierr); 4238 } 4239 PetscFunctionReturn(0); 4240 } 4241 4242 #undef __FUNCT__ 4243 #define __FUNCT__ "TSAdjointCostIntegral" 4244 /*@ 4245 TSAdjointCostIntegral - Evaluate the cost integral in the adjoint run. 4246 4247 Collective on TS 4248 4249 Input Arguments: 4250 . ts - time stepping context 4251 4252 Level: advanced 4253 4254 Notes: 4255 This function cannot be called until TSAdjointStep() has been completed. 4256 4257 .seealso: TSAdjointSolve(), TSAdjointStep 4258 @*/ 4259 PetscErrorCode TSAdjointCostIntegral(TS ts) 4260 { 4261 PetscErrorCode ierr; 4262 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4263 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); 4264 ierr = (*ts->ops->adjointintegral)(ts);CHKERRQ(ierr); 4265 PetscFunctionReturn(0); 4266 } 4267 4268 #undef __FUNCT__ 4269 #define __FUNCT__ "TSAdjointSolve" 4270 /*@ 4271 TSAdjointSolve - Solves the discrete ajoint problem for an ODE/DAE 4272 4273 Collective on TS 4274 4275 Input Parameter: 4276 . ts - the TS context obtained from TSCreate() 4277 4278 Options Database: 4279 . -ts_adjoint_view_solution <viewerinfo> - views the first gradient with respect to the initial conditions 4280 4281 Level: intermediate 4282 4283 Notes: 4284 This must be called after a call to TSSolve() that solves the forward problem 4285 4286 By default this will integrate back to the initial time, one can use TSAdjointSetSteps() to step back to a later time 4287 4288 .keywords: TS, timestep, solve 4289 4290 .seealso: TSCreate(), TSSetCostGradients(), TSSetSolution(), TSAdjointStep() 4291 @*/ 4292 PetscErrorCode TSAdjointSolve(TS ts) 4293 { 4294 PetscErrorCode ierr; 4295 4296 PetscFunctionBegin; 4297 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4298 ierr = TSAdjointSetUp(ts);CHKERRQ(ierr); 4299 4300 /* reset time step and iteration counters */ 4301 ts->steps = 0; 4302 ts->ksp_its = 0; 4303 ts->snes_its = 0; 4304 ts->num_snes_failures = 0; 4305 ts->reject = 0; 4306 ts->reason = TS_CONVERGED_ITERATING; 4307 4308 if (!ts->adjoint_max_steps) ts->adjoint_max_steps = ts->total_steps; 4309 4310 if (ts->steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS; 4311 while (!ts->reason) { 4312 ierr = TSTrajectoryGet(ts->trajectory,ts,ts->total_steps,&ts->ptime);CHKERRQ(ierr); 4313 ierr = TSAdjointMonitor(ts,ts->total_steps,ts->ptime,ts->vec_sol,ts->numcost,ts->vecs_sensi,ts->vecs_sensip);CHKERRQ(ierr); 4314 ierr = TSAdjointEventHandler(ts);CHKERRQ(ierr); 4315 ierr = TSAdjointStep(ts);CHKERRQ(ierr); 4316 if (ts->vec_costintegral && !ts->costintegralfwd) { 4317 ierr = TSAdjointCostIntegral(ts);CHKERRQ(ierr); 4318 } 4319 } 4320 ierr = TSTrajectoryGet(ts->trajectory,ts,ts->total_steps,&ts->ptime);CHKERRQ(ierr); 4321 ierr = TSAdjointMonitor(ts,ts->total_steps,ts->ptime,ts->vec_sol,ts->numcost,ts->vecs_sensi,ts->vecs_sensip);CHKERRQ(ierr); 4322 ts->solvetime = ts->ptime; 4323 ierr = TSTrajectoryViewFromOptions(ts->trajectory,NULL,"-ts_trajectory_view");CHKERRQ(ierr); 4324 ierr = VecViewFromOptions(ts->vecs_sensi[0],(PetscObject) ts, "-ts_adjoint_view_solution");CHKERRQ(ierr); 4325 PetscFunctionReturn(0); 4326 } 4327 4328 #undef __FUNCT__ 4329 #define __FUNCT__ "TSMonitor" 4330 /*@C 4331 TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet() 4332 4333 Collective on TS 4334 4335 Input Parameters: 4336 + ts - time stepping context obtained from TSCreate() 4337 . step - step number that has just completed 4338 . ptime - model time of the state 4339 - u - state at the current model time 4340 4341 Notes: 4342 TSMonitor() is typically used automatically within the time stepping implementations. 4343 Users would almost never call this routine directly. 4344 4345 A step of -1 indicates that the monitor is being called on a solution obtained by interpolating from computed solutions 4346 4347 Level: developer 4348 4349 .keywords: TS, timestep 4350 @*/ 4351 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u) 4352 { 4353 DM dm; 4354 PetscInt i,n = ts->numbermonitors; 4355 PetscErrorCode ierr; 4356 4357 PetscFunctionBegin; 4358 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4359 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 4360 4361 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4362 ierr = DMSetOutputSequenceNumber(dm,step,ptime);CHKERRQ(ierr); 4363 4364 ierr = VecLockPush(u);CHKERRQ(ierr); 4365 for (i=0; i<n; i++) { 4366 ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr); 4367 } 4368 ierr = VecLockPop(u);CHKERRQ(ierr); 4369 PetscFunctionReturn(0); 4370 } 4371 4372 #undef __FUNCT__ 4373 #define __FUNCT__ "TSAdjointMonitor" 4374 /*@C 4375 TSAdjointMonitor - Runs all user-provided adjoint monitor routines set using TSAdjointMonitorSet() 4376 4377 Collective on TS 4378 4379 Input Parameters: 4380 + ts - time stepping context obtained from TSCreate() 4381 . step - step number that has just completed 4382 . ptime - model time of the state 4383 . u - state at the current model time 4384 . numcost - number of cost functions (dimension of lambda or mu) 4385 . lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables 4386 - mu - vectors containing the gradients of the cost functions with respect to the problem parameters 4387 4388 Notes: 4389 TSAdjointMonitor() is typically used automatically within the time stepping implementations. 4390 Users would almost never call this routine directly. 4391 4392 Level: developer 4393 4394 .keywords: TS, timestep 4395 @*/ 4396 PetscErrorCode TSAdjointMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda, Vec *mu) 4397 { 4398 PetscErrorCode ierr; 4399 PetscInt i,n = ts->numberadjointmonitors; 4400 4401 PetscFunctionBegin; 4402 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4403 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 4404 ierr = VecLockPush(u);CHKERRQ(ierr); 4405 for (i=0; i<n; i++) { 4406 ierr = (*ts->adjointmonitor[i])(ts,step,ptime,u,numcost,lambda,mu,ts->adjointmonitorcontext[i]);CHKERRQ(ierr); 4407 } 4408 ierr = VecLockPop(u);CHKERRQ(ierr); 4409 PetscFunctionReturn(0); 4410 } 4411 4412 /* ------------------------------------------------------------------------*/ 4413 #undef __FUNCT__ 4414 #define __FUNCT__ "TSMonitorLGCtxCreate" 4415 /*@C 4416 TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with 4417 TS to monitor the solution process graphically in various ways 4418 4419 Collective on TS 4420 4421 Input Parameters: 4422 + host - the X display to open, or null for the local machine 4423 . label - the title to put in the title bar 4424 . x, y - the screen coordinates of the upper left coordinate of the window 4425 . m, n - the screen width and height in pixels 4426 - howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time 4427 4428 Output Parameter: 4429 . ctx - the context 4430 4431 Options Database Key: 4432 + -ts_monitor_lg_timestep - automatically sets line graph monitor 4433 . -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables()) 4434 . -ts_monitor_lg_error - monitor the error 4435 . -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep 4436 . -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep 4437 - -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true 4438 4439 Notes: 4440 Use TSMonitorLGCtxDestroy() to destroy. 4441 4442 One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform() 4443 4444 Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a TS object as the 4445 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 4446 as the first argument. 4447 4448 One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames() 4449 4450 4451 Level: intermediate 4452 4453 .keywords: TS, monitor, line graph, residual 4454 4455 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError(), TSMonitorDefault(), VecView(), 4456 TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(), 4457 TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(), 4458 TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(), 4459 TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop() 4460 4461 @*/ 4462 PetscErrorCode TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx) 4463 { 4464 PetscDraw draw; 4465 PetscErrorCode ierr; 4466 4467 PetscFunctionBegin; 4468 ierr = PetscNew(ctx);CHKERRQ(ierr); 4469 ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr); 4470 ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr); 4471 ierr = PetscDrawLGCreate(draw,1,&(*ctx)->lg);CHKERRQ(ierr); 4472 ierr = PetscDrawLGSetFromOptions((*ctx)->lg);CHKERRQ(ierr); 4473 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 4474 (*ctx)->howoften = howoften; 4475 PetscFunctionReturn(0); 4476 } 4477 4478 #undef __FUNCT__ 4479 #define __FUNCT__ "TSMonitorLGTimeStep" 4480 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx) 4481 { 4482 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 4483 PetscReal x = ptime,y; 4484 PetscErrorCode ierr; 4485 4486 PetscFunctionBegin; 4487 if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */ 4488 if (!step) { 4489 PetscDrawAxis axis; 4490 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 4491 ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time","Time Step");CHKERRQ(ierr); 4492 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 4493 } 4494 ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr); 4495 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 4496 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 4497 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 4498 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 4499 } 4500 PetscFunctionReturn(0); 4501 } 4502 4503 #undef __FUNCT__ 4504 #define __FUNCT__ "TSMonitorLGCtxDestroy" 4505 /*@C 4506 TSMonitorLGCtxDestroy - Destroys a line graph context that was created 4507 with TSMonitorLGCtxCreate(). 4508 4509 Collective on TSMonitorLGCtx 4510 4511 Input Parameter: 4512 . ctx - the monitor context 4513 4514 Level: intermediate 4515 4516 .keywords: TS, monitor, line graph, destroy 4517 4518 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep(); 4519 @*/ 4520 PetscErrorCode TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx) 4521 { 4522 PetscErrorCode ierr; 4523 4524 PetscFunctionBegin; 4525 if ((*ctx)->transformdestroy) { 4526 ierr = ((*ctx)->transformdestroy)((*ctx)->transformctx);CHKERRQ(ierr); 4527 } 4528 ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr); 4529 ierr = PetscStrArrayDestroy(&(*ctx)->names);CHKERRQ(ierr); 4530 ierr = PetscStrArrayDestroy(&(*ctx)->displaynames);CHKERRQ(ierr); 4531 ierr = PetscFree((*ctx)->displayvariables);CHKERRQ(ierr); 4532 ierr = PetscFree((*ctx)->displayvalues);CHKERRQ(ierr); 4533 ierr = PetscFree(*ctx);CHKERRQ(ierr); 4534 PetscFunctionReturn(0); 4535 } 4536 4537 #undef __FUNCT__ 4538 #define __FUNCT__ "TSGetTime" 4539 /*@ 4540 TSGetTime - Gets the time of the most recently completed step. 4541 4542 Not Collective 4543 4544 Input Parameter: 4545 . ts - the TS context obtained from TSCreate() 4546 4547 Output Parameter: 4548 . t - the current time. This time may not corresponds to the final time set with TSSetDuration(), use TSGetSolveTime(). 4549 4550 Level: beginner 4551 4552 Note: 4553 When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(), 4554 TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated. 4555 4556 .seealso: TSSetInitialTimeStep(), TSGetTimeStep(), TSGetSolveTime() 4557 4558 .keywords: TS, get, time 4559 @*/ 4560 PetscErrorCode TSGetTime(TS ts,PetscReal *t) 4561 { 4562 PetscFunctionBegin; 4563 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4564 PetscValidRealPointer(t,2); 4565 *t = ts->ptime; 4566 PetscFunctionReturn(0); 4567 } 4568 4569 #undef __FUNCT__ 4570 #define __FUNCT__ "TSGetPrevTime" 4571 /*@ 4572 TSGetPrevTime - Gets the starting time of the previously completed step. 4573 4574 Not Collective 4575 4576 Input Parameter: 4577 . ts - the TS context obtained from TSCreate() 4578 4579 Output Parameter: 4580 . t - the previous time 4581 4582 Level: beginner 4583 4584 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 4585 4586 .keywords: TS, get, time 4587 @*/ 4588 PetscErrorCode TSGetPrevTime(TS ts,PetscReal *t) 4589 { 4590 PetscFunctionBegin; 4591 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4592 PetscValidRealPointer(t,2); 4593 *t = ts->ptime_prev; 4594 PetscFunctionReturn(0); 4595 } 4596 4597 #undef __FUNCT__ 4598 #define __FUNCT__ "TSSetTime" 4599 /*@ 4600 TSSetTime - Allows one to reset the time. 4601 4602 Logically Collective on TS 4603 4604 Input Parameters: 4605 + ts - the TS context obtained from TSCreate() 4606 - time - the time 4607 4608 Level: intermediate 4609 4610 .seealso: TSGetTime(), TSSetDuration() 4611 4612 .keywords: TS, set, time 4613 @*/ 4614 PetscErrorCode TSSetTime(TS ts, PetscReal t) 4615 { 4616 PetscFunctionBegin; 4617 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4618 PetscValidLogicalCollectiveReal(ts,t,2); 4619 ts->ptime = t; 4620 PetscFunctionReturn(0); 4621 } 4622 4623 #undef __FUNCT__ 4624 #define __FUNCT__ "TSSetOptionsPrefix" 4625 /*@C 4626 TSSetOptionsPrefix - Sets the prefix used for searching for all 4627 TS options in the database. 4628 4629 Logically Collective on TS 4630 4631 Input Parameter: 4632 + ts - The TS context 4633 - prefix - The prefix to prepend to all option names 4634 4635 Notes: 4636 A hyphen (-) must NOT be given at the beginning of the prefix name. 4637 The first character of all runtime options is AUTOMATICALLY the 4638 hyphen. 4639 4640 Level: advanced 4641 4642 .keywords: TS, set, options, prefix, database 4643 4644 .seealso: TSSetFromOptions() 4645 4646 @*/ 4647 PetscErrorCode TSSetOptionsPrefix(TS ts,const char prefix[]) 4648 { 4649 PetscErrorCode ierr; 4650 SNES snes; 4651 4652 PetscFunctionBegin; 4653 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4654 ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4655 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4656 ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4657 PetscFunctionReturn(0); 4658 } 4659 4660 4661 #undef __FUNCT__ 4662 #define __FUNCT__ "TSAppendOptionsPrefix" 4663 /*@C 4664 TSAppendOptionsPrefix - Appends to the prefix used for searching for all 4665 TS options in the database. 4666 4667 Logically Collective on TS 4668 4669 Input Parameter: 4670 + ts - The TS context 4671 - prefix - The prefix to prepend to all option names 4672 4673 Notes: 4674 A hyphen (-) must NOT be given at the beginning of the prefix name. 4675 The first character of all runtime options is AUTOMATICALLY the 4676 hyphen. 4677 4678 Level: advanced 4679 4680 .keywords: TS, append, options, prefix, database 4681 4682 .seealso: TSGetOptionsPrefix() 4683 4684 @*/ 4685 PetscErrorCode TSAppendOptionsPrefix(TS ts,const char prefix[]) 4686 { 4687 PetscErrorCode ierr; 4688 SNES snes; 4689 4690 PetscFunctionBegin; 4691 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4692 ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4693 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4694 ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4695 PetscFunctionReturn(0); 4696 } 4697 4698 #undef __FUNCT__ 4699 #define __FUNCT__ "TSGetOptionsPrefix" 4700 /*@C 4701 TSGetOptionsPrefix - Sets the prefix used for searching for all 4702 TS options in the database. 4703 4704 Not Collective 4705 4706 Input Parameter: 4707 . ts - The TS context 4708 4709 Output Parameter: 4710 . prefix - A pointer to the prefix string used 4711 4712 Notes: On the fortran side, the user should pass in a string 'prifix' of 4713 sufficient length to hold the prefix. 4714 4715 Level: intermediate 4716 4717 .keywords: TS, get, options, prefix, database 4718 4719 .seealso: TSAppendOptionsPrefix() 4720 @*/ 4721 PetscErrorCode TSGetOptionsPrefix(TS ts,const char *prefix[]) 4722 { 4723 PetscErrorCode ierr; 4724 4725 PetscFunctionBegin; 4726 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4727 PetscValidPointer(prefix,2); 4728 ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4729 PetscFunctionReturn(0); 4730 } 4731 4732 #undef __FUNCT__ 4733 #define __FUNCT__ "TSGetRHSJacobian" 4734 /*@C 4735 TSGetRHSJacobian - Returns the Jacobian J at the present timestep. 4736 4737 Not Collective, but parallel objects are returned if TS is parallel 4738 4739 Input Parameter: 4740 . ts - The TS context obtained from TSCreate() 4741 4742 Output Parameters: 4743 + Amat - The (approximate) Jacobian J of G, where U_t = G(U,t) (or NULL) 4744 . Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat (or NULL) 4745 . func - Function to compute the Jacobian of the RHS (or NULL) 4746 - ctx - User-defined context for Jacobian evaluation routine (or NULL) 4747 4748 Notes: You can pass in NULL for any return argument you do not need. 4749 4750 Level: intermediate 4751 4752 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 4753 4754 .keywords: TS, timestep, get, matrix, Jacobian 4755 @*/ 4756 PetscErrorCode TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx) 4757 { 4758 PetscErrorCode ierr; 4759 SNES snes; 4760 DM dm; 4761 4762 PetscFunctionBegin; 4763 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4764 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4765 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4766 ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr); 4767 PetscFunctionReturn(0); 4768 } 4769 4770 #undef __FUNCT__ 4771 #define __FUNCT__ "TSGetIJacobian" 4772 /*@C 4773 TSGetIJacobian - Returns the implicit Jacobian at the present timestep. 4774 4775 Not Collective, but parallel objects are returned if TS is parallel 4776 4777 Input Parameter: 4778 . ts - The TS context obtained from TSCreate() 4779 4780 Output Parameters: 4781 + Amat - The (approximate) Jacobian of F(t,U,U_t) 4782 . Pmat - The matrix from which the preconditioner is constructed, often the same as Amat 4783 . f - The function to compute the matrices 4784 - ctx - User-defined context for Jacobian evaluation routine 4785 4786 Notes: You can pass in NULL for any return argument you do not need. 4787 4788 Level: advanced 4789 4790 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 4791 4792 .keywords: TS, timestep, get, matrix, Jacobian 4793 @*/ 4794 PetscErrorCode TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx) 4795 { 4796 PetscErrorCode ierr; 4797 SNES snes; 4798 DM dm; 4799 4800 PetscFunctionBegin; 4801 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4802 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4803 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4804 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4805 ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr); 4806 PetscFunctionReturn(0); 4807 } 4808 4809 4810 #undef __FUNCT__ 4811 #define __FUNCT__ "TSMonitorDrawSolution" 4812 /*@C 4813 TSMonitorDrawSolution - Monitors progress of the TS solvers by calling 4814 VecView() for the solution at each timestep 4815 4816 Collective on TS 4817 4818 Input Parameters: 4819 + ts - the TS context 4820 . step - current time-step 4821 . ptime - current time 4822 - dummy - either a viewer or NULL 4823 4824 Options Database: 4825 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 4826 4827 Notes: the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial 4828 will look bad 4829 4830 Level: intermediate 4831 4832 .keywords: TS, vector, monitor, view 4833 4834 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4835 @*/ 4836 PetscErrorCode TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4837 { 4838 PetscErrorCode ierr; 4839 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 4840 PetscDraw draw; 4841 4842 PetscFunctionBegin; 4843 if (!step && ictx->showinitial) { 4844 if (!ictx->initialsolution) { 4845 ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr); 4846 } 4847 ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr); 4848 } 4849 if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4850 4851 if (ictx->showinitial) { 4852 PetscReal pause; 4853 ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr); 4854 ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr); 4855 ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr); 4856 ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr); 4857 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr); 4858 } 4859 ierr = VecView(u,ictx->viewer);CHKERRQ(ierr); 4860 if (ictx->showtimestepandtime) { 4861 PetscReal xl,yl,xr,yr,h; 4862 char time[32]; 4863 4864 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 4865 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 4866 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 4867 h = yl + .95*(yr - yl); 4868 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 4869 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 4870 } 4871 4872 if (ictx->showinitial) { 4873 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr); 4874 } 4875 PetscFunctionReturn(0); 4876 } 4877 4878 #undef __FUNCT__ 4879 #define __FUNCT__ "TSAdjointMonitorDrawSensi" 4880 /*@C 4881 TSAdjointMonitorDrawSensi - Monitors progress of the adjoint TS solvers by calling 4882 VecView() for the sensitivities to initial states at each timestep 4883 4884 Collective on TS 4885 4886 Input Parameters: 4887 + ts - the TS context 4888 . step - current time-step 4889 . ptime - current time 4890 . u - current state 4891 . numcost - number of cost functions 4892 . lambda - sensitivities to initial conditions 4893 . mu - sensitivities to parameters 4894 - dummy - either a viewer or NULL 4895 4896 Level: intermediate 4897 4898 .keywords: TS, vector, adjoint, monitor, view 4899 4900 .seealso: TSAdjointMonitorSet(), TSAdjointMonitorDefault(), VecView() 4901 @*/ 4902 PetscErrorCode TSAdjointMonitorDrawSensi(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda,Vec *mu,void *dummy) 4903 { 4904 PetscErrorCode ierr; 4905 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 4906 PetscDraw draw; 4907 PetscReal xl,yl,xr,yr,h; 4908 char time[32]; 4909 4910 PetscFunctionBegin; 4911 if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4912 4913 ierr = VecView(lambda[0],ictx->viewer);CHKERRQ(ierr); 4914 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 4915 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 4916 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 4917 h = yl + .95*(yr - yl); 4918 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 4919 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 4920 PetscFunctionReturn(0); 4921 } 4922 4923 #undef __FUNCT__ 4924 #define __FUNCT__ "TSMonitorDrawSolutionPhase" 4925 /*@C 4926 TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram 4927 4928 Collective on TS 4929 4930 Input Parameters: 4931 + ts - the TS context 4932 . step - current time-step 4933 . ptime - current time 4934 - dummy - either a viewer or NULL 4935 4936 Level: intermediate 4937 4938 .keywords: TS, vector, monitor, view 4939 4940 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4941 @*/ 4942 PetscErrorCode TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4943 { 4944 PetscErrorCode ierr; 4945 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 4946 PetscDraw draw; 4947 PetscDrawAxis axis; 4948 PetscInt n; 4949 PetscMPIInt size; 4950 PetscReal U0,U1,xl,yl,xr,yr,h; 4951 char time[32]; 4952 const PetscScalar *U; 4953 4954 PetscFunctionBegin; 4955 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size);CHKERRQ(ierr); 4956 if (size != 1) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs"); 4957 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 4958 if (n != 2) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns"); 4959 4960 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 4961 ierr = PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis);CHKERRQ(ierr); 4962 ierr = PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr); 4963 if (!step) { 4964 ierr = PetscDrawClear(draw);CHKERRQ(ierr); 4965 ierr = PetscDrawAxisDraw(axis);CHKERRQ(ierr); 4966 } 4967 4968 ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr); 4969 U0 = PetscRealPart(U[0]); 4970 U1 = PetscRealPart(U[1]); 4971 ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr); 4972 if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0); 4973 4974 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 4975 ierr = PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK);CHKERRQ(ierr); 4976 if (ictx->showtimestepandtime) { 4977 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 4978 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 4979 h = yl + .95*(yr - yl); 4980 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 4981 } 4982 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 4983 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 4984 ierr = PetscDrawSave(draw);CHKERRQ(ierr); 4985 PetscFunctionReturn(0); 4986 } 4987 4988 4989 #undef __FUNCT__ 4990 #define __FUNCT__ "TSMonitorDrawCtxDestroy" 4991 /*@C 4992 TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution() 4993 4994 Collective on TS 4995 4996 Input Parameters: 4997 . ctx - the monitor context 4998 4999 Level: intermediate 5000 5001 .keywords: TS, vector, monitor, view 5002 5003 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError() 5004 @*/ 5005 PetscErrorCode TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx) 5006 { 5007 PetscErrorCode ierr; 5008 5009 PetscFunctionBegin; 5010 ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr); 5011 ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr); 5012 ierr = PetscFree(*ictx);CHKERRQ(ierr); 5013 PetscFunctionReturn(0); 5014 } 5015 5016 #undef __FUNCT__ 5017 #define __FUNCT__ "TSMonitorDrawCtxCreate" 5018 /*@C 5019 TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx 5020 5021 Collective on TS 5022 5023 Input Parameter: 5024 . ts - time-step context 5025 5026 Output Patameter: 5027 . ctx - the monitor context 5028 5029 Options Database: 5030 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 5031 5032 Level: intermediate 5033 5034 .keywords: TS, vector, monitor, view 5035 5036 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx() 5037 @*/ 5038 PetscErrorCode TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx) 5039 { 5040 PetscErrorCode ierr; 5041 5042 PetscFunctionBegin; 5043 ierr = PetscNew(ctx);CHKERRQ(ierr); 5044 ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr); 5045 ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr); 5046 5047 (*ctx)->howoften = howoften; 5048 (*ctx)->showinitial = PETSC_FALSE; 5049 ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr); 5050 5051 (*ctx)->showtimestepandtime = PETSC_FALSE; 5052 ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr); 5053 PetscFunctionReturn(0); 5054 } 5055 5056 #undef __FUNCT__ 5057 #define __FUNCT__ "TSMonitorDrawError" 5058 /*@C 5059 TSMonitorDrawError - Monitors progress of the TS solvers by calling 5060 VecView() for the error at each timestep 5061 5062 Collective on TS 5063 5064 Input Parameters: 5065 + ts - the TS context 5066 . step - current time-step 5067 . ptime - current time 5068 - dummy - either a viewer or NULL 5069 5070 Level: intermediate 5071 5072 .keywords: TS, vector, monitor, view 5073 5074 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5075 @*/ 5076 PetscErrorCode TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 5077 { 5078 PetscErrorCode ierr; 5079 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 5080 PetscViewer viewer = ctx->viewer; 5081 Vec work; 5082 5083 PetscFunctionBegin; 5084 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 5085 ierr = VecDuplicate(u,&work);CHKERRQ(ierr); 5086 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 5087 ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr); 5088 ierr = VecView(work,viewer);CHKERRQ(ierr); 5089 ierr = VecDestroy(&work);CHKERRQ(ierr); 5090 PetscFunctionReturn(0); 5091 } 5092 5093 #include <petsc/private/dmimpl.h> 5094 #undef __FUNCT__ 5095 #define __FUNCT__ "TSSetDM" 5096 /*@ 5097 TSSetDM - Sets the DM that may be used by some nonlinear solvers or preconditioners under the TS 5098 5099 Logically Collective on TS and DM 5100 5101 Input Parameters: 5102 + ts - the ODE integrator object 5103 - dm - the dm, cannot be NULL 5104 5105 Level: intermediate 5106 5107 5108 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM() 5109 @*/ 5110 PetscErrorCode TSSetDM(TS ts,DM dm) 5111 { 5112 PetscErrorCode ierr; 5113 SNES snes; 5114 DMTS tsdm; 5115 5116 PetscFunctionBegin; 5117 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5118 PetscValidHeaderSpecific(dm,DM_CLASSID,2); 5119 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 5120 if (ts->dm) { /* Move the DMTS context over to the new DM unless the new DM already has one */ 5121 if (ts->dm->dmts && !dm->dmts) { 5122 ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr); 5123 ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr); 5124 if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */ 5125 tsdm->originaldm = dm; 5126 } 5127 } 5128 ierr = DMDestroy(&ts->dm);CHKERRQ(ierr); 5129 } 5130 ts->dm = dm; 5131 5132 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 5133 ierr = SNESSetDM(snes,dm);CHKERRQ(ierr); 5134 PetscFunctionReturn(0); 5135 } 5136 5137 #undef __FUNCT__ 5138 #define __FUNCT__ "TSGetDM" 5139 /*@ 5140 TSGetDM - Gets the DM that may be used by some preconditioners 5141 5142 Not Collective 5143 5144 Input Parameter: 5145 . ts - the preconditioner context 5146 5147 Output Parameter: 5148 . dm - the dm 5149 5150 Level: intermediate 5151 5152 5153 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM() 5154 @*/ 5155 PetscErrorCode TSGetDM(TS ts,DM *dm) 5156 { 5157 PetscErrorCode ierr; 5158 5159 PetscFunctionBegin; 5160 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5161 if (!ts->dm) { 5162 ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr); 5163 if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 5164 } 5165 *dm = ts->dm; 5166 PetscFunctionReturn(0); 5167 } 5168 5169 #undef __FUNCT__ 5170 #define __FUNCT__ "SNESTSFormFunction" 5171 /*@ 5172 SNESTSFormFunction - Function to evaluate nonlinear residual 5173 5174 Logically Collective on SNES 5175 5176 Input Parameter: 5177 + snes - nonlinear solver 5178 . U - the current state at which to evaluate the residual 5179 - ctx - user context, must be a TS 5180 5181 Output Parameter: 5182 . F - the nonlinear residual 5183 5184 Notes: 5185 This function is not normally called by users and is automatically registered with the SNES used by TS. 5186 It is most frequently passed to MatFDColoringSetFunction(). 5187 5188 Level: advanced 5189 5190 .seealso: SNESSetFunction(), MatFDColoringSetFunction() 5191 @*/ 5192 PetscErrorCode SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx) 5193 { 5194 TS ts = (TS)ctx; 5195 PetscErrorCode ierr; 5196 5197 PetscFunctionBegin; 5198 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5199 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5200 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 5201 PetscValidHeaderSpecific(ts,TS_CLASSID,4); 5202 ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr); 5203 PetscFunctionReturn(0); 5204 } 5205 5206 #undef __FUNCT__ 5207 #define __FUNCT__ "SNESTSFormJacobian" 5208 /*@ 5209 SNESTSFormJacobian - Function to evaluate the Jacobian 5210 5211 Collective on SNES 5212 5213 Input Parameter: 5214 + snes - nonlinear solver 5215 . U - the current state at which to evaluate the residual 5216 - ctx - user context, must be a TS 5217 5218 Output Parameter: 5219 + A - the Jacobian 5220 . B - the preconditioning matrix (may be the same as A) 5221 - flag - indicates any structure change in the matrix 5222 5223 Notes: 5224 This function is not normally called by users and is automatically registered with the SNES used by TS. 5225 5226 Level: developer 5227 5228 .seealso: SNESSetJacobian() 5229 @*/ 5230 PetscErrorCode SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx) 5231 { 5232 TS ts = (TS)ctx; 5233 PetscErrorCode ierr; 5234 5235 PetscFunctionBegin; 5236 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5237 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5238 PetscValidPointer(A,3); 5239 PetscValidHeaderSpecific(A,MAT_CLASSID,3); 5240 PetscValidPointer(B,4); 5241 PetscValidHeaderSpecific(B,MAT_CLASSID,4); 5242 PetscValidHeaderSpecific(ts,TS_CLASSID,6); 5243 ierr = (ts->ops->snesjacobian)(snes,U,A,B,ts);CHKERRQ(ierr); 5244 PetscFunctionReturn(0); 5245 } 5246 5247 #undef __FUNCT__ 5248 #define __FUNCT__ "TSComputeRHSFunctionLinear" 5249 /*@C 5250 TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems Udot = A U only 5251 5252 Collective on TS 5253 5254 Input Arguments: 5255 + ts - time stepping context 5256 . t - time at which to evaluate 5257 . U - state at which to evaluate 5258 - ctx - context 5259 5260 Output Arguments: 5261 . F - right hand side 5262 5263 Level: intermediate 5264 5265 Notes: 5266 This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems. 5267 The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian(). 5268 5269 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 5270 @*/ 5271 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx) 5272 { 5273 PetscErrorCode ierr; 5274 Mat Arhs,Brhs; 5275 5276 PetscFunctionBegin; 5277 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 5278 ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr); 5279 ierr = MatMult(Arhs,U,F);CHKERRQ(ierr); 5280 PetscFunctionReturn(0); 5281 } 5282 5283 #undef __FUNCT__ 5284 #define __FUNCT__ "TSComputeRHSJacobianConstant" 5285 /*@C 5286 TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent. 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 - ctx - context 5295 5296 Output Arguments: 5297 + A - pointer to operator 5298 . B - pointer to preconditioning matrix 5299 - flg - matrix structure flag 5300 5301 Level: intermediate 5302 5303 Notes: 5304 This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems. 5305 5306 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear() 5307 @*/ 5308 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx) 5309 { 5310 PetscFunctionBegin; 5311 PetscFunctionReturn(0); 5312 } 5313 5314 #undef __FUNCT__ 5315 #define __FUNCT__ "TSComputeIFunctionLinear" 5316 /*@C 5317 TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only 5318 5319 Collective on TS 5320 5321 Input Arguments: 5322 + ts - time stepping context 5323 . t - time at which to evaluate 5324 . U - state at which to evaluate 5325 . Udot - time derivative of state vector 5326 - ctx - context 5327 5328 Output Arguments: 5329 . F - left hand side 5330 5331 Level: intermediate 5332 5333 Notes: 5334 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 5335 user is required to write their own TSComputeIFunction. 5336 This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems. 5337 The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian(). 5338 5339 Note that using this function is NOT equivalent to using TSComputeRHSFunctionLinear() since that solves Udot = A U 5340 5341 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant(), TSComputeRHSFunctionLinear() 5342 @*/ 5343 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx) 5344 { 5345 PetscErrorCode ierr; 5346 Mat A,B; 5347 5348 PetscFunctionBegin; 5349 ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr); 5350 ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE);CHKERRQ(ierr); 5351 ierr = MatMult(A,Udot,F);CHKERRQ(ierr); 5352 PetscFunctionReturn(0); 5353 } 5354 5355 #undef __FUNCT__ 5356 #define __FUNCT__ "TSComputeIJacobianConstant" 5357 /*@C 5358 TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE 5359 5360 Collective on TS 5361 5362 Input Arguments: 5363 + ts - time stepping context 5364 . t - time at which to evaluate 5365 . U - state at which to evaluate 5366 . Udot - time derivative of state vector 5367 . shift - shift to apply 5368 - ctx - context 5369 5370 Output Arguments: 5371 + A - pointer to operator 5372 . B - pointer to preconditioning matrix 5373 - flg - matrix structure flag 5374 5375 Level: advanced 5376 5377 Notes: 5378 This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems. 5379 5380 It is only appropriate for problems of the form 5381 5382 $ M Udot = F(U,t) 5383 5384 where M is constant and F is non-stiff. The user must pass M to TSSetIJacobian(). The current implementation only 5385 works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing 5386 an implicit operator of the form 5387 5388 $ shift*M + J 5389 5390 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 5391 a copy of M or reassemble it when requested. 5392 5393 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear() 5394 @*/ 5395 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx) 5396 { 5397 PetscErrorCode ierr; 5398 5399 PetscFunctionBegin; 5400 ierr = MatScale(A, shift / ts->ijacobian.shift);CHKERRQ(ierr); 5401 ts->ijacobian.shift = shift; 5402 PetscFunctionReturn(0); 5403 } 5404 5405 #undef __FUNCT__ 5406 #define __FUNCT__ "TSGetEquationType" 5407 /*@ 5408 TSGetEquationType - Gets the type of the equation that TS is solving. 5409 5410 Not Collective 5411 5412 Input Parameter: 5413 . ts - the TS context 5414 5415 Output Parameter: 5416 . equation_type - see TSEquationType 5417 5418 Level: beginner 5419 5420 .keywords: TS, equation type 5421 5422 .seealso: TSSetEquationType(), TSEquationType 5423 @*/ 5424 PetscErrorCode TSGetEquationType(TS ts,TSEquationType *equation_type) 5425 { 5426 PetscFunctionBegin; 5427 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5428 PetscValidPointer(equation_type,2); 5429 *equation_type = ts->equation_type; 5430 PetscFunctionReturn(0); 5431 } 5432 5433 #undef __FUNCT__ 5434 #define __FUNCT__ "TSSetEquationType" 5435 /*@ 5436 TSSetEquationType - Sets the type of the equation that TS is solving. 5437 5438 Not Collective 5439 5440 Input Parameter: 5441 + ts - the TS context 5442 - equation_type - see TSEquationType 5443 5444 Level: advanced 5445 5446 .keywords: TS, equation type 5447 5448 .seealso: TSGetEquationType(), TSEquationType 5449 @*/ 5450 PetscErrorCode TSSetEquationType(TS ts,TSEquationType equation_type) 5451 { 5452 PetscFunctionBegin; 5453 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5454 ts->equation_type = equation_type; 5455 PetscFunctionReturn(0); 5456 } 5457 5458 #undef __FUNCT__ 5459 #define __FUNCT__ "TSGetConvergedReason" 5460 /*@ 5461 TSGetConvergedReason - Gets the reason the TS iteration was stopped. 5462 5463 Not Collective 5464 5465 Input Parameter: 5466 . ts - the TS context 5467 5468 Output Parameter: 5469 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 5470 manual pages for the individual convergence tests for complete lists 5471 5472 Level: beginner 5473 5474 Notes: 5475 Can only be called after the call to TSSolve() is complete. 5476 5477 .keywords: TS, nonlinear, set, convergence, test 5478 5479 .seealso: TSSetConvergenceTest(), TSConvergedReason 5480 @*/ 5481 PetscErrorCode TSGetConvergedReason(TS ts,TSConvergedReason *reason) 5482 { 5483 PetscFunctionBegin; 5484 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5485 PetscValidPointer(reason,2); 5486 *reason = ts->reason; 5487 PetscFunctionReturn(0); 5488 } 5489 5490 #undef __FUNCT__ 5491 #define __FUNCT__ "TSSetConvergedReason" 5492 /*@ 5493 TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve. 5494 5495 Not Collective 5496 5497 Input Parameter: 5498 + ts - the TS context 5499 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 5500 manual pages for the individual convergence tests for complete lists 5501 5502 Level: advanced 5503 5504 Notes: 5505 Can only be called during TSSolve() is active. 5506 5507 .keywords: TS, nonlinear, set, convergence, test 5508 5509 .seealso: TSConvergedReason 5510 @*/ 5511 PetscErrorCode TSSetConvergedReason(TS ts,TSConvergedReason reason) 5512 { 5513 PetscFunctionBegin; 5514 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5515 ts->reason = reason; 5516 PetscFunctionReturn(0); 5517 } 5518 5519 #undef __FUNCT__ 5520 #define __FUNCT__ "TSGetSolveTime" 5521 /*@ 5522 TSGetSolveTime - Gets the time after a call to TSSolve() 5523 5524 Not Collective 5525 5526 Input Parameter: 5527 . ts - the TS context 5528 5529 Output Parameter: 5530 . ftime - the final time. This time corresponds to the final time set with TSSetDuration() 5531 5532 Level: beginner 5533 5534 Notes: 5535 Can only be called after the call to TSSolve() is complete. 5536 5537 .keywords: TS, nonlinear, set, convergence, test 5538 5539 .seealso: TSSetConvergenceTest(), TSConvergedReason 5540 @*/ 5541 PetscErrorCode TSGetSolveTime(TS ts,PetscReal *ftime) 5542 { 5543 PetscFunctionBegin; 5544 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5545 PetscValidPointer(ftime,2); 5546 *ftime = ts->solvetime; 5547 PetscFunctionReturn(0); 5548 } 5549 5550 #undef __FUNCT__ 5551 #define __FUNCT__ "TSGetTotalSteps" 5552 /*@ 5553 TSGetTotalSteps - Gets the total number of steps done since the last call to TSSetUp() or TSCreate() 5554 5555 Not Collective 5556 5557 Input Parameter: 5558 . ts - the TS context 5559 5560 Output Parameter: 5561 . steps - the number of steps 5562 5563 Level: beginner 5564 5565 Notes: 5566 Includes the number of steps for all calls to TSSolve() since TSSetUp() was called 5567 5568 .keywords: TS, nonlinear, set, convergence, test 5569 5570 .seealso: TSSetConvergenceTest(), TSConvergedReason 5571 @*/ 5572 PetscErrorCode TSGetTotalSteps(TS ts,PetscInt *steps) 5573 { 5574 PetscFunctionBegin; 5575 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5576 PetscValidPointer(steps,2); 5577 *steps = ts->total_steps; 5578 PetscFunctionReturn(0); 5579 } 5580 5581 #undef __FUNCT__ 5582 #define __FUNCT__ "TSGetSNESIterations" 5583 /*@ 5584 TSGetSNESIterations - Gets the total number of nonlinear iterations 5585 used by the time integrator. 5586 5587 Not Collective 5588 5589 Input Parameter: 5590 . ts - TS context 5591 5592 Output Parameter: 5593 . nits - number of nonlinear iterations 5594 5595 Notes: 5596 This counter is reset to zero for each successive call to TSSolve(). 5597 5598 Level: intermediate 5599 5600 .keywords: TS, get, number, nonlinear, iterations 5601 5602 .seealso: TSGetKSPIterations() 5603 @*/ 5604 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits) 5605 { 5606 PetscFunctionBegin; 5607 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5608 PetscValidIntPointer(nits,2); 5609 *nits = ts->snes_its; 5610 PetscFunctionReturn(0); 5611 } 5612 5613 #undef __FUNCT__ 5614 #define __FUNCT__ "TSGetKSPIterations" 5615 /*@ 5616 TSGetKSPIterations - Gets the total number of linear iterations 5617 used by the time integrator. 5618 5619 Not Collective 5620 5621 Input Parameter: 5622 . ts - TS context 5623 5624 Output Parameter: 5625 . lits - number of linear iterations 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, linear, iterations 5633 5634 .seealso: TSGetSNESIterations(), SNESGetKSPIterations() 5635 @*/ 5636 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits) 5637 { 5638 PetscFunctionBegin; 5639 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5640 PetscValidIntPointer(lits,2); 5641 *lits = ts->ksp_its; 5642 PetscFunctionReturn(0); 5643 } 5644 5645 #undef __FUNCT__ 5646 #define __FUNCT__ "TSGetStepRejections" 5647 /*@ 5648 TSGetStepRejections - Gets the total number of rejected steps. 5649 5650 Not Collective 5651 5652 Input Parameter: 5653 . ts - TS context 5654 5655 Output Parameter: 5656 . rejects - number of steps rejected 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(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails() 5666 @*/ 5667 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects) 5668 { 5669 PetscFunctionBegin; 5670 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5671 PetscValidIntPointer(rejects,2); 5672 *rejects = ts->reject; 5673 PetscFunctionReturn(0); 5674 } 5675 5676 #undef __FUNCT__ 5677 #define __FUNCT__ "TSGetSNESFailures" 5678 /*@ 5679 TSGetSNESFailures - Gets the total number of failed SNES solves 5680 5681 Not Collective 5682 5683 Input Parameter: 5684 . ts - TS context 5685 5686 Output Parameter: 5687 . fails - number of failed nonlinear solves 5688 5689 Notes: 5690 This counter is reset to zero for each successive call to TSSolve(). 5691 5692 Level: intermediate 5693 5694 .keywords: TS, get, number 5695 5696 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures() 5697 @*/ 5698 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails) 5699 { 5700 PetscFunctionBegin; 5701 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5702 PetscValidIntPointer(fails,2); 5703 *fails = ts->num_snes_failures; 5704 PetscFunctionReturn(0); 5705 } 5706 5707 #undef __FUNCT__ 5708 #define __FUNCT__ "TSSetMaxStepRejections" 5709 /*@ 5710 TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails 5711 5712 Not Collective 5713 5714 Input Parameter: 5715 + ts - TS context 5716 - rejects - maximum number of rejected steps, pass -1 for unlimited 5717 5718 Notes: 5719 The counter is reset to zero for each step 5720 5721 Options Database Key: 5722 . -ts_max_reject - Maximum number of step rejections before a step fails 5723 5724 Level: intermediate 5725 5726 .keywords: TS, set, maximum, number 5727 5728 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 5729 @*/ 5730 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects) 5731 { 5732 PetscFunctionBegin; 5733 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5734 ts->max_reject = rejects; 5735 PetscFunctionReturn(0); 5736 } 5737 5738 #undef __FUNCT__ 5739 #define __FUNCT__ "TSSetMaxSNESFailures" 5740 /*@ 5741 TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves 5742 5743 Not Collective 5744 5745 Input Parameter: 5746 + ts - TS context 5747 - fails - maximum number of failed nonlinear solves, pass -1 for unlimited 5748 5749 Notes: 5750 The counter is reset to zero for each successive call to TSSolve(). 5751 5752 Options Database Key: 5753 . -ts_max_snes_failures - Maximum number of nonlinear solve failures 5754 5755 Level: intermediate 5756 5757 .keywords: TS, set, maximum, number 5758 5759 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason() 5760 @*/ 5761 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails) 5762 { 5763 PetscFunctionBegin; 5764 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5765 ts->max_snes_failures = fails; 5766 PetscFunctionReturn(0); 5767 } 5768 5769 #undef __FUNCT__ 5770 #define __FUNCT__ "TSSetErrorIfStepFails" 5771 /*@ 5772 TSSetErrorIfStepFails - Error if no step succeeds 5773 5774 Not Collective 5775 5776 Input Parameter: 5777 + ts - TS context 5778 - err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure 5779 5780 Options Database Key: 5781 . -ts_error_if_step_fails - Error if no step succeeds 5782 5783 Level: intermediate 5784 5785 .keywords: TS, set, error 5786 5787 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 5788 @*/ 5789 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err) 5790 { 5791 PetscFunctionBegin; 5792 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5793 ts->errorifstepfailed = err; 5794 PetscFunctionReturn(0); 5795 } 5796 5797 #undef __FUNCT__ 5798 #define __FUNCT__ "TSMonitorSolution" 5799 /*@C 5800 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 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 - vf - viewer and its format 5810 5811 Level: intermediate 5812 5813 .keywords: TS, vector, monitor, view 5814 5815 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5816 @*/ 5817 PetscErrorCode TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf) 5818 { 5819 PetscErrorCode ierr; 5820 5821 PetscFunctionBegin; 5822 ierr = PetscViewerPushFormat(vf->viewer,vf->format);CHKERRQ(ierr); 5823 ierr = VecView(u,vf->viewer);CHKERRQ(ierr); 5824 ierr = PetscViewerPopFormat(vf->viewer);CHKERRQ(ierr); 5825 PetscFunctionReturn(0); 5826 } 5827 5828 #undef __FUNCT__ 5829 #define __FUNCT__ "TSMonitorSolutionVTK" 5830 /*@C 5831 TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep. 5832 5833 Collective on TS 5834 5835 Input Parameters: 5836 + ts - the TS context 5837 . step - current time-step 5838 . ptime - current time 5839 . u - current state 5840 - filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 5841 5842 Level: intermediate 5843 5844 Notes: 5845 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. 5846 These are named according to the file name template. 5847 5848 This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy(). 5849 5850 .keywords: TS, vector, monitor, view 5851 5852 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5853 @*/ 5854 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate) 5855 { 5856 PetscErrorCode ierr; 5857 char filename[PETSC_MAX_PATH_LEN]; 5858 PetscViewer viewer; 5859 5860 PetscFunctionBegin; 5861 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 5862 ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr); 5863 ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); 5864 ierr = VecView(u,viewer);CHKERRQ(ierr); 5865 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 5866 PetscFunctionReturn(0); 5867 } 5868 5869 #undef __FUNCT__ 5870 #define __FUNCT__ "TSMonitorSolutionVTKDestroy" 5871 /*@C 5872 TSMonitorSolutionVTKDestroy - Destroy context for monitoring 5873 5874 Collective on TS 5875 5876 Input Parameters: 5877 . filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 5878 5879 Level: intermediate 5880 5881 Note: 5882 This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK(). 5883 5884 .keywords: TS, vector, monitor, view 5885 5886 .seealso: TSMonitorSet(), TSMonitorSolutionVTK() 5887 @*/ 5888 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate) 5889 { 5890 PetscErrorCode ierr; 5891 5892 PetscFunctionBegin; 5893 ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr); 5894 PetscFunctionReturn(0); 5895 } 5896 5897 #undef __FUNCT__ 5898 #define __FUNCT__ "TSGetAdapt" 5899 /*@ 5900 TSGetAdapt - Get the adaptive controller context for the current method 5901 5902 Collective on TS if controller has not been created yet 5903 5904 Input Arguments: 5905 . ts - time stepping context 5906 5907 Output Arguments: 5908 . adapt - adaptive controller 5909 5910 Level: intermediate 5911 5912 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose() 5913 @*/ 5914 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt) 5915 { 5916 PetscErrorCode ierr; 5917 5918 PetscFunctionBegin; 5919 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5920 PetscValidPointer(adapt,2); 5921 if (!ts->adapt) { 5922 ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr); 5923 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr); 5924 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr); 5925 } 5926 *adapt = ts->adapt; 5927 PetscFunctionReturn(0); 5928 } 5929 5930 #undef __FUNCT__ 5931 #define __FUNCT__ "TSSetTolerances" 5932 /*@ 5933 TSSetTolerances - Set tolerances for local truncation error when using adaptive controller 5934 5935 Logically Collective 5936 5937 Input Arguments: 5938 + ts - time integration context 5939 . atol - scalar absolute tolerances, PETSC_DECIDE to leave current value 5940 . vatol - vector of absolute tolerances or NULL, used in preference to atol if present 5941 . rtol - scalar relative tolerances, PETSC_DECIDE to leave current value 5942 - vrtol - vector of relative tolerances or NULL, used in preference to atol if present 5943 5944 Options Database keys: 5945 + -ts_rtol <rtol> - relative tolerance for local truncation error 5946 - -ts_atol <atol> Absolute tolerance for local truncation error 5947 5948 Notes: 5949 With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error 5950 (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be 5951 computed only for the differential or the algebraic part then this can be done using the vector of 5952 tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the 5953 differential part and infinity for the algebraic part, the LTE calculation will include only the 5954 differential variables. 5955 5956 Level: beginner 5957 5958 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances() 5959 @*/ 5960 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol) 5961 { 5962 PetscErrorCode ierr; 5963 5964 PetscFunctionBegin; 5965 if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol; 5966 if (vatol) { 5967 ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr); 5968 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 5969 ts->vatol = vatol; 5970 } 5971 if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol; 5972 if (vrtol) { 5973 ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr); 5974 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 5975 ts->vrtol = vrtol; 5976 } 5977 PetscFunctionReturn(0); 5978 } 5979 5980 #undef __FUNCT__ 5981 #define __FUNCT__ "TSGetTolerances" 5982 /*@ 5983 TSGetTolerances - Get tolerances for local truncation error when using adaptive controller 5984 5985 Logically Collective 5986 5987 Input Arguments: 5988 . ts - time integration context 5989 5990 Output Arguments: 5991 + atol - scalar absolute tolerances, NULL to ignore 5992 . vatol - vector of absolute tolerances, NULL to ignore 5993 . rtol - scalar relative tolerances, NULL to ignore 5994 - vrtol - vector of relative tolerances, NULL to ignore 5995 5996 Level: beginner 5997 5998 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances() 5999 @*/ 6000 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol) 6001 { 6002 PetscFunctionBegin; 6003 if (atol) *atol = ts->atol; 6004 if (vatol) *vatol = ts->vatol; 6005 if (rtol) *rtol = ts->rtol; 6006 if (vrtol) *vrtol = ts->vrtol; 6007 PetscFunctionReturn(0); 6008 } 6009 6010 #undef __FUNCT__ 6011 #define __FUNCT__ "TSErrorWeightedNorm2" 6012 /*@ 6013 TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors 6014 6015 Collective on TS 6016 6017 Input Arguments: 6018 + ts - time stepping context 6019 . U - state vector, usually ts->vec_sol 6020 - Y - state vector to be compared to U 6021 6022 Output Arguments: 6023 . norm - weighted norm, a value of 1.0 is considered small 6024 6025 Level: developer 6026 6027 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNormInfinity() 6028 @*/ 6029 PetscErrorCode TSErrorWeightedNorm2(TS ts,Vec U,Vec Y,PetscReal *norm) 6030 { 6031 PetscErrorCode ierr; 6032 PetscInt i,n,N,rstart; 6033 const PetscScalar *u,*y; 6034 PetscReal sum,gsum; 6035 PetscReal tol; 6036 6037 PetscFunctionBegin; 6038 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6039 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 6040 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 6041 PetscValidType(U,2); 6042 PetscValidType(Y,3); 6043 PetscCheckSameComm(U,2,Y,3); 6044 PetscValidPointer(norm,4); 6045 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 6046 6047 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 6048 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 6049 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 6050 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 6051 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 6052 sum = 0.; 6053 if (ts->vatol && ts->vrtol) { 6054 const PetscScalar *atol,*rtol; 6055 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6056 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6057 for (i=0; i<n; i++) { 6058 tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6059 sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol); 6060 } 6061 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6062 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6063 } else if (ts->vatol) { /* vector atol, scalar rtol */ 6064 const PetscScalar *atol; 6065 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6066 for (i=0; i<n; i++) { 6067 tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6068 sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol); 6069 } 6070 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6071 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 6072 const PetscScalar *rtol; 6073 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6074 for (i=0; i<n; i++) { 6075 tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6076 sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol); 6077 } 6078 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6079 } else { /* scalar atol, scalar rtol */ 6080 for (i=0; i<n; i++) { 6081 tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6082 sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol); 6083 } 6084 } 6085 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 6086 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 6087 6088 ierr = MPIU_Allreduce(&sum,&gsum,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6089 *norm = PetscSqrtReal(gsum / N); 6090 6091 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6092 PetscFunctionReturn(0); 6093 } 6094 6095 #undef __FUNCT__ 6096 #define __FUNCT__ "TSErrorWeightedNormInfinity" 6097 /*@ 6098 TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors 6099 6100 Collective on TS 6101 6102 Input Arguments: 6103 + ts - time stepping context 6104 . U - state vector, usually ts->vec_sol 6105 - Y - state vector to be compared to U 6106 6107 Output Arguments: 6108 . norm - weighted norm, a value of 1.0 is considered small 6109 6110 Level: developer 6111 6112 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNorm2() 6113 @*/ 6114 PetscErrorCode TSErrorWeightedNormInfinity(TS ts,Vec U,Vec Y,PetscReal *norm) 6115 { 6116 PetscErrorCode ierr; 6117 PetscInt i,n,N,rstart,k; 6118 const PetscScalar *u,*y; 6119 PetscReal max,gmax; 6120 PetscReal tol; 6121 6122 PetscFunctionBegin; 6123 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6124 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 6125 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 6126 PetscValidType(U,2); 6127 PetscValidType(Y,3); 6128 PetscCheckSameComm(U,2,Y,3); 6129 PetscValidPointer(norm,4); 6130 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 6131 6132 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 6133 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 6134 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 6135 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 6136 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 6137 if (ts->vatol && ts->vrtol) { 6138 const PetscScalar *atol,*rtol; 6139 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6140 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6141 k = 0; 6142 tol = PetscRealPart(atol[k]) + PetscRealPart(rtol[k]) * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k])); 6143 max = PetscAbsScalar(y[k] - u[k]) / tol; 6144 for (i=1; i<n; i++) { 6145 tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6146 max = PetscMax(max,PetscAbsScalar(y[i] - u[i]) / tol); 6147 } 6148 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6149 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6150 } else if (ts->vatol) { /* vector atol, scalar rtol */ 6151 const PetscScalar *atol; 6152 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6153 k = 0; 6154 tol = PetscRealPart(atol[k]) + ts->rtol * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k])); 6155 max = PetscAbsScalar(y[k] - u[k]) / tol; 6156 for (i=1; i<n; i++) { 6157 tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6158 max = PetscMax(max,PetscAbsScalar(y[i] - u[i]) / tol); 6159 } 6160 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6161 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 6162 const PetscScalar *rtol; 6163 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6164 k = 0; 6165 tol = ts->atol + PetscRealPart(rtol[k]) * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k])); 6166 max = PetscAbsScalar(y[k] - u[k]) / tol; 6167 for (i=1; i<n; i++) { 6168 tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6169 max = PetscMax(max,PetscAbsScalar(y[i] - u[i]) / tol); 6170 } 6171 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6172 } else { /* scalar atol, scalar rtol */ 6173 k = 0; 6174 tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k])); 6175 max = PetscAbsScalar(y[k] - u[k]) / tol; 6176 for (i=1; i<n; i++) { 6177 tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6178 max = PetscMax(max,PetscAbsScalar(y[i] - u[i]) / tol); 6179 } 6180 } 6181 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 6182 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 6183 6184 ierr = MPIU_Allreduce(&max,&gmax,1,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6185 *norm = gmax; 6186 6187 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6188 PetscFunctionReturn(0); 6189 } 6190 6191 #undef __FUNCT__ 6192 #define __FUNCT__ "TSErrorWeightedNorm" 6193 /*@ 6194 TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors 6195 6196 Collective on TS 6197 6198 Input Arguments: 6199 + ts - time stepping context 6200 . U - state vector, usually ts->vec_sol 6201 . Y - state vector to be compared to U 6202 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 6203 6204 Output Arguments: 6205 . norm - weighted norm, a value of 1.0 is considered small 6206 6207 6208 Options Database Keys: 6209 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 6210 6211 Level: developer 6212 6213 .seealso: TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2() 6214 @*/ 6215 PetscErrorCode TSErrorWeightedNorm(TS ts,Vec U,Vec Y,NormType wnormtype,PetscReal *norm) 6216 { 6217 PetscErrorCode ierr; 6218 6219 PetscFunctionBegin; 6220 if (wnormtype == NORM_2) { 6221 ierr = TSErrorWeightedNorm2(ts,U,Y,norm);CHKERRQ(ierr); 6222 } else if(wnormtype == NORM_INFINITY) { 6223 ierr = TSErrorWeightedNormInfinity(ts,U,Y,norm);CHKERRQ(ierr); 6224 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 6225 PetscFunctionReturn(0); 6226 } 6227 6228 #undef __FUNCT__ 6229 #define __FUNCT__ "TSSetCFLTimeLocal" 6230 /*@ 6231 TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler 6232 6233 Logically Collective on TS 6234 6235 Input Arguments: 6236 + ts - time stepping context 6237 - cfltime - maximum stable time step if using forward Euler (value can be different on each process) 6238 6239 Note: 6240 After calling this function, the global CFL time can be obtained by calling TSGetCFLTime() 6241 6242 Level: intermediate 6243 6244 .seealso: TSGetCFLTime(), TSADAPTCFL 6245 @*/ 6246 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime) 6247 { 6248 PetscFunctionBegin; 6249 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6250 ts->cfltime_local = cfltime; 6251 ts->cfltime = -1.; 6252 PetscFunctionReturn(0); 6253 } 6254 6255 #undef __FUNCT__ 6256 #define __FUNCT__ "TSGetCFLTime" 6257 /*@ 6258 TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler 6259 6260 Collective on TS 6261 6262 Input Arguments: 6263 . ts - time stepping context 6264 6265 Output Arguments: 6266 . cfltime - maximum stable time step for forward Euler 6267 6268 Level: advanced 6269 6270 .seealso: TSSetCFLTimeLocal() 6271 @*/ 6272 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime) 6273 { 6274 PetscErrorCode ierr; 6275 6276 PetscFunctionBegin; 6277 if (ts->cfltime < 0) { 6278 ierr = MPIU_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6279 } 6280 *cfltime = ts->cfltime; 6281 PetscFunctionReturn(0); 6282 } 6283 6284 #undef __FUNCT__ 6285 #define __FUNCT__ "TSVISetVariableBounds" 6286 /*@ 6287 TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu 6288 6289 Input Parameters: 6290 . ts - the TS context. 6291 . xl - lower bound. 6292 . xu - upper bound. 6293 6294 Notes: 6295 If this routine is not called then the lower and upper bounds are set to 6296 PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp(). 6297 6298 Level: advanced 6299 6300 @*/ 6301 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu) 6302 { 6303 PetscErrorCode ierr; 6304 SNES snes; 6305 6306 PetscFunctionBegin; 6307 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 6308 ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr); 6309 PetscFunctionReturn(0); 6310 } 6311 6312 #if defined(PETSC_HAVE_MATLAB_ENGINE) 6313 #include <mex.h> 6314 6315 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext; 6316 6317 #undef __FUNCT__ 6318 #define __FUNCT__ "TSComputeFunction_Matlab" 6319 /* 6320 TSComputeFunction_Matlab - Calls the function that has been set with 6321 TSSetFunctionMatlab(). 6322 6323 Collective on TS 6324 6325 Input Parameters: 6326 + snes - the TS context 6327 - u - input vector 6328 6329 Output Parameter: 6330 . y - function vector, as set by TSSetFunction() 6331 6332 Notes: 6333 TSComputeFunction() is typically used within nonlinear solvers 6334 implementations, so most users would not generally call this routine 6335 themselves. 6336 6337 Level: developer 6338 6339 .keywords: TS, nonlinear, compute, function 6340 6341 .seealso: TSSetFunction(), TSGetFunction() 6342 */ 6343 PetscErrorCode TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx) 6344 { 6345 PetscErrorCode ierr; 6346 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 6347 int nlhs = 1,nrhs = 7; 6348 mxArray *plhs[1],*prhs[7]; 6349 long long int lx = 0,lxdot = 0,ly = 0,ls = 0; 6350 6351 PetscFunctionBegin; 6352 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 6353 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 6354 PetscValidHeaderSpecific(udot,VEC_CLASSID,4); 6355 PetscValidHeaderSpecific(y,VEC_CLASSID,5); 6356 PetscCheckSameComm(snes,1,u,3); 6357 PetscCheckSameComm(snes,1,y,5); 6358 6359 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 6360 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 6361 ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr); 6362 ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr); 6363 6364 prhs[0] = mxCreateDoubleScalar((double)ls); 6365 prhs[1] = mxCreateDoubleScalar(time); 6366 prhs[2] = mxCreateDoubleScalar((double)lx); 6367 prhs[3] = mxCreateDoubleScalar((double)lxdot); 6368 prhs[4] = mxCreateDoubleScalar((double)ly); 6369 prhs[5] = mxCreateString(sctx->funcname); 6370 prhs[6] = sctx->ctx; 6371 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr); 6372 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 6373 mxDestroyArray(prhs[0]); 6374 mxDestroyArray(prhs[1]); 6375 mxDestroyArray(prhs[2]); 6376 mxDestroyArray(prhs[3]); 6377 mxDestroyArray(prhs[4]); 6378 mxDestroyArray(prhs[5]); 6379 mxDestroyArray(plhs[0]); 6380 PetscFunctionReturn(0); 6381 } 6382 6383 6384 #undef __FUNCT__ 6385 #define __FUNCT__ "TSSetFunctionMatlab" 6386 /* 6387 TSSetFunctionMatlab - Sets the function evaluation routine and function 6388 vector for use by the TS routines in solving ODEs 6389 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 6390 6391 Logically Collective on TS 6392 6393 Input Parameters: 6394 + ts - the TS context 6395 - func - function evaluation routine 6396 6397 Calling sequence of func: 6398 $ func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx); 6399 6400 Level: beginner 6401 6402 .keywords: TS, nonlinear, set, function 6403 6404 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 6405 */ 6406 PetscErrorCode TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx) 6407 { 6408 PetscErrorCode ierr; 6409 TSMatlabContext *sctx; 6410 6411 PetscFunctionBegin; 6412 /* currently sctx is memory bleed */ 6413 ierr = PetscNew(&sctx);CHKERRQ(ierr); 6414 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 6415 /* 6416 This should work, but it doesn't 6417 sctx->ctx = ctx; 6418 mexMakeArrayPersistent(sctx->ctx); 6419 */ 6420 sctx->ctx = mxDuplicateArray(ctx); 6421 6422 ierr = TSSetIFunction(ts,NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr); 6423 PetscFunctionReturn(0); 6424 } 6425 6426 #undef __FUNCT__ 6427 #define __FUNCT__ "TSComputeJacobian_Matlab" 6428 /* 6429 TSComputeJacobian_Matlab - Calls the function that has been set with 6430 TSSetJacobianMatlab(). 6431 6432 Collective on TS 6433 6434 Input Parameters: 6435 + ts - the TS context 6436 . u - input vector 6437 . A, B - the matrices 6438 - ctx - user context 6439 6440 Level: developer 6441 6442 .keywords: TS, nonlinear, compute, function 6443 6444 .seealso: TSSetFunction(), TSGetFunction() 6445 @*/ 6446 PetscErrorCode TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat A,Mat B,void *ctx) 6447 { 6448 PetscErrorCode ierr; 6449 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 6450 int nlhs = 2,nrhs = 9; 6451 mxArray *plhs[2],*prhs[9]; 6452 long long int lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0; 6453 6454 PetscFunctionBegin; 6455 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6456 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 6457 6458 /* call Matlab function in ctx with arguments u and y */ 6459 6460 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 6461 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 6462 ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr); 6463 ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr); 6464 ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr); 6465 6466 prhs[0] = mxCreateDoubleScalar((double)ls); 6467 prhs[1] = mxCreateDoubleScalar((double)time); 6468 prhs[2] = mxCreateDoubleScalar((double)lx); 6469 prhs[3] = mxCreateDoubleScalar((double)lxdot); 6470 prhs[4] = mxCreateDoubleScalar((double)shift); 6471 prhs[5] = mxCreateDoubleScalar((double)lA); 6472 prhs[6] = mxCreateDoubleScalar((double)lB); 6473 prhs[7] = mxCreateString(sctx->funcname); 6474 prhs[8] = sctx->ctx; 6475 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr); 6476 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 6477 mxDestroyArray(prhs[0]); 6478 mxDestroyArray(prhs[1]); 6479 mxDestroyArray(prhs[2]); 6480 mxDestroyArray(prhs[3]); 6481 mxDestroyArray(prhs[4]); 6482 mxDestroyArray(prhs[5]); 6483 mxDestroyArray(prhs[6]); 6484 mxDestroyArray(prhs[7]); 6485 mxDestroyArray(plhs[0]); 6486 mxDestroyArray(plhs[1]); 6487 PetscFunctionReturn(0); 6488 } 6489 6490 6491 #undef __FUNCT__ 6492 #define __FUNCT__ "TSSetJacobianMatlab" 6493 /* 6494 TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 6495 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 6496 6497 Logically Collective on TS 6498 6499 Input Parameters: 6500 + ts - the TS context 6501 . A,B - Jacobian matrices 6502 . func - function evaluation routine 6503 - ctx - user context 6504 6505 Calling sequence of func: 6506 $ flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx); 6507 6508 6509 Level: developer 6510 6511 .keywords: TS, nonlinear, set, function 6512 6513 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 6514 */ 6515 PetscErrorCode TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx) 6516 { 6517 PetscErrorCode ierr; 6518 TSMatlabContext *sctx; 6519 6520 PetscFunctionBegin; 6521 /* currently sctx is memory bleed */ 6522 ierr = PetscNew(&sctx);CHKERRQ(ierr); 6523 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 6524 /* 6525 This should work, but it doesn't 6526 sctx->ctx = ctx; 6527 mexMakeArrayPersistent(sctx->ctx); 6528 */ 6529 sctx->ctx = mxDuplicateArray(ctx); 6530 6531 ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 6532 PetscFunctionReturn(0); 6533 } 6534 6535 #undef __FUNCT__ 6536 #define __FUNCT__ "TSMonitor_Matlab" 6537 /* 6538 TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab(). 6539 6540 Collective on TS 6541 6542 .seealso: TSSetFunction(), TSGetFunction() 6543 @*/ 6544 PetscErrorCode TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx) 6545 { 6546 PetscErrorCode ierr; 6547 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 6548 int nlhs = 1,nrhs = 6; 6549 mxArray *plhs[1],*prhs[6]; 6550 long long int lx = 0,ls = 0; 6551 6552 PetscFunctionBegin; 6553 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6554 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 6555 6556 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 6557 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 6558 6559 prhs[0] = mxCreateDoubleScalar((double)ls); 6560 prhs[1] = mxCreateDoubleScalar((double)it); 6561 prhs[2] = mxCreateDoubleScalar((double)time); 6562 prhs[3] = mxCreateDoubleScalar((double)lx); 6563 prhs[4] = mxCreateString(sctx->funcname); 6564 prhs[5] = sctx->ctx; 6565 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr); 6566 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 6567 mxDestroyArray(prhs[0]); 6568 mxDestroyArray(prhs[1]); 6569 mxDestroyArray(prhs[2]); 6570 mxDestroyArray(prhs[3]); 6571 mxDestroyArray(prhs[4]); 6572 mxDestroyArray(plhs[0]); 6573 PetscFunctionReturn(0); 6574 } 6575 6576 6577 #undef __FUNCT__ 6578 #define __FUNCT__ "TSMonitorSetMatlab" 6579 /* 6580 TSMonitorSetMatlab - Sets the monitor function from Matlab 6581 6582 Level: developer 6583 6584 .keywords: TS, nonlinear, set, function 6585 6586 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 6587 */ 6588 PetscErrorCode TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx) 6589 { 6590 PetscErrorCode ierr; 6591 TSMatlabContext *sctx; 6592 6593 PetscFunctionBegin; 6594 /* currently sctx is memory bleed */ 6595 ierr = PetscNew(&sctx);CHKERRQ(ierr); 6596 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 6597 /* 6598 This should work, but it doesn't 6599 sctx->ctx = ctx; 6600 mexMakeArrayPersistent(sctx->ctx); 6601 */ 6602 sctx->ctx = mxDuplicateArray(ctx); 6603 6604 ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,NULL);CHKERRQ(ierr); 6605 PetscFunctionReturn(0); 6606 } 6607 #endif 6608 6609 #undef __FUNCT__ 6610 #define __FUNCT__ "TSMonitorLGSolution" 6611 /*@C 6612 TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector 6613 in a time based line graph 6614 6615 Collective on TS 6616 6617 Input Parameters: 6618 + ts - the TS context 6619 . step - current time-step 6620 . ptime - current time 6621 . u - current solution 6622 - dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate() 6623 6624 Options Database: 6625 . -ts_monitor_lg_solution_variables 6626 6627 Level: intermediate 6628 6629 Notes: Each process in a parallel run displays its component solutions in a separate window 6630 6631 .keywords: TS, vector, monitor, view 6632 6633 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(), 6634 TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(), 6635 TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(), 6636 TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop() 6637 @*/ 6638 PetscErrorCode TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 6639 { 6640 PetscErrorCode ierr; 6641 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dctx; 6642 const PetscScalar *yy; 6643 Vec v; 6644 6645 PetscFunctionBegin; 6646 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 6647 if (!step) { 6648 PetscDrawAxis axis; 6649 PetscInt dim; 6650 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6651 ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr); 6652 if (!ctx->names) { 6653 PetscBool flg; 6654 /* user provides names of variables to plot but no names has been set so assume names are integer values */ 6655 ierr = PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg);CHKERRQ(ierr); 6656 if (flg) { 6657 PetscInt i,n; 6658 char **names; 6659 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 6660 ierr = PetscMalloc1(n+1,&names);CHKERRQ(ierr); 6661 for (i=0; i<n; i++) { 6662 ierr = PetscMalloc1(5,&names[i]);CHKERRQ(ierr); 6663 ierr = PetscSNPrintf(names[i],5,"%D",i);CHKERRQ(ierr); 6664 } 6665 names[n] = NULL; 6666 ctx->names = names; 6667 } 6668 } 6669 if (ctx->names && !ctx->displaynames) { 6670 char **displaynames; 6671 PetscBool flg; 6672 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6673 ierr = PetscMalloc1(dim+1,&displaynames);CHKERRQ(ierr); 6674 ierr = PetscMemzero(displaynames,(dim+1)*sizeof(char*));CHKERRQ(ierr); 6675 ierr = PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg);CHKERRQ(ierr); 6676 if (flg) { 6677 ierr = TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames);CHKERRQ(ierr); 6678 } 6679 ierr = PetscStrArrayDestroy(&displaynames);CHKERRQ(ierr); 6680 } 6681 if (ctx->displaynames) { 6682 ierr = PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables);CHKERRQ(ierr); 6683 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames);CHKERRQ(ierr); 6684 } else if (ctx->names) { 6685 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6686 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6687 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names);CHKERRQ(ierr); 6688 } else { 6689 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6690 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6691 } 6692 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6693 } 6694 6695 if (!ctx->transform) v = u; 6696 else {ierr = (*ctx->transform)(ctx->transformctx,u,&v);CHKERRQ(ierr);} 6697 ierr = VecGetArrayRead(v,&yy);CHKERRQ(ierr); 6698 if (ctx->displaynames) { 6699 PetscInt i; 6700 for (i=0; i<ctx->ndisplayvariables; i++) 6701 ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]); 6702 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues);CHKERRQ(ierr); 6703 } else { 6704 #if defined(PETSC_USE_COMPLEX) 6705 PetscInt i,n; 6706 PetscReal *yreal; 6707 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 6708 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 6709 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 6710 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 6711 ierr = PetscFree(yreal);CHKERRQ(ierr); 6712 #else 6713 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 6714 #endif 6715 } 6716 ierr = VecRestoreArrayRead(v,&yy);CHKERRQ(ierr); 6717 if (ctx->transform) {ierr = VecDestroy(&v);CHKERRQ(ierr);} 6718 6719 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 6720 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6721 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 6722 } 6723 PetscFunctionReturn(0); 6724 } 6725 6726 6727 #undef __FUNCT__ 6728 #define __FUNCT__ "TSMonitorLGSetVariableNames" 6729 /*@C 6730 TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 6731 6732 Collective on TS 6733 6734 Input Parameters: 6735 + ts - the TS context 6736 - names - the names of the components, final string must be NULL 6737 6738 Level: intermediate 6739 6740 Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6741 6742 .keywords: TS, vector, monitor, view 6743 6744 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames() 6745 @*/ 6746 PetscErrorCode TSMonitorLGSetVariableNames(TS ts,const char * const *names) 6747 { 6748 PetscErrorCode ierr; 6749 PetscInt i; 6750 6751 PetscFunctionBegin; 6752 for (i=0; i<ts->numbermonitors; i++) { 6753 if (ts->monitor[i] == TSMonitorLGSolution) { 6754 ierr = TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names);CHKERRQ(ierr); 6755 break; 6756 } 6757 } 6758 PetscFunctionReturn(0); 6759 } 6760 6761 #undef __FUNCT__ 6762 #define __FUNCT__ "TSMonitorLGCtxSetVariableNames" 6763 /*@C 6764 TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 6765 6766 Collective on TS 6767 6768 Input Parameters: 6769 + ts - the TS context 6770 - names - the names of the components, final string must be NULL 6771 6772 Level: intermediate 6773 6774 .keywords: TS, vector, monitor, view 6775 6776 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames() 6777 @*/ 6778 PetscErrorCode TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names) 6779 { 6780 PetscErrorCode ierr; 6781 6782 PetscFunctionBegin; 6783 ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr); 6784 ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr); 6785 PetscFunctionReturn(0); 6786 } 6787 6788 #undef __FUNCT__ 6789 #define __FUNCT__ "TSMonitorLGGetVariableNames" 6790 /*@C 6791 TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot 6792 6793 Collective on TS 6794 6795 Input Parameter: 6796 . ts - the TS context 6797 6798 Output Parameter: 6799 . names - the names of the components, final string must be NULL 6800 6801 Level: intermediate 6802 6803 Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6804 6805 .keywords: TS, vector, monitor, view 6806 6807 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 6808 @*/ 6809 PetscErrorCode TSMonitorLGGetVariableNames(TS ts,const char *const **names) 6810 { 6811 PetscInt i; 6812 6813 PetscFunctionBegin; 6814 *names = NULL; 6815 for (i=0; i<ts->numbermonitors; i++) { 6816 if (ts->monitor[i] == TSMonitorLGSolution) { 6817 TSMonitorLGCtx ctx = (TSMonitorLGCtx) ts->monitorcontext[i]; 6818 *names = (const char *const *)ctx->names; 6819 break; 6820 } 6821 } 6822 PetscFunctionReturn(0); 6823 } 6824 6825 #undef __FUNCT__ 6826 #define __FUNCT__ "TSMonitorLGCtxSetDisplayVariables" 6827 /*@C 6828 TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor 6829 6830 Collective on TS 6831 6832 Input Parameters: 6833 + ctx - the TSMonitorLG context 6834 . displaynames - the names of the components, final string must be NULL 6835 6836 Level: intermediate 6837 6838 .keywords: TS, vector, monitor, view 6839 6840 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 6841 @*/ 6842 PetscErrorCode TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames) 6843 { 6844 PetscInt j = 0,k; 6845 PetscErrorCode ierr; 6846 6847 PetscFunctionBegin; 6848 if (!ctx->names) PetscFunctionReturn(0); 6849 ierr = PetscStrArrayDestroy(&ctx->displaynames);CHKERRQ(ierr); 6850 ierr = PetscStrArrayallocpy(displaynames,&ctx->displaynames);CHKERRQ(ierr); 6851 while (displaynames[j]) j++; 6852 ctx->ndisplayvariables = j; 6853 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables);CHKERRQ(ierr); 6854 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues);CHKERRQ(ierr); 6855 j = 0; 6856 while (displaynames[j]) { 6857 k = 0; 6858 while (ctx->names[k]) { 6859 PetscBool flg; 6860 ierr = PetscStrcmp(displaynames[j],ctx->names[k],&flg);CHKERRQ(ierr); 6861 if (flg) { 6862 ctx->displayvariables[j] = k; 6863 break; 6864 } 6865 k++; 6866 } 6867 j++; 6868 } 6869 PetscFunctionReturn(0); 6870 } 6871 6872 6873 #undef __FUNCT__ 6874 #define __FUNCT__ "TSMonitorLGSetDisplayVariables" 6875 /*@C 6876 TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor 6877 6878 Collective on TS 6879 6880 Input Parameters: 6881 + ts - the TS context 6882 . displaynames - the names of the components, final string must be NULL 6883 6884 Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6885 6886 Level: intermediate 6887 6888 .keywords: TS, vector, monitor, view 6889 6890 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 6891 @*/ 6892 PetscErrorCode TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames) 6893 { 6894 PetscInt i; 6895 PetscErrorCode ierr; 6896 6897 PetscFunctionBegin; 6898 for (i=0; i<ts->numbermonitors; i++) { 6899 if (ts->monitor[i] == TSMonitorLGSolution) { 6900 ierr = TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames);CHKERRQ(ierr); 6901 break; 6902 } 6903 } 6904 PetscFunctionReturn(0); 6905 } 6906 6907 #undef __FUNCT__ 6908 #define __FUNCT__ "TSMonitorLGSetTransform" 6909 /*@C 6910 TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed 6911 6912 Collective on TS 6913 6914 Input Parameters: 6915 + ts - the TS context 6916 . transform - the transform function 6917 . destroy - function to destroy the optional context 6918 - ctx - optional context used by transform function 6919 6920 Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 6921 6922 Level: intermediate 6923 6924 .keywords: TS, vector, monitor, view 6925 6926 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform() 6927 @*/ 6928 PetscErrorCode TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 6929 { 6930 PetscInt i; 6931 PetscErrorCode ierr; 6932 6933 PetscFunctionBegin; 6934 for (i=0; i<ts->numbermonitors; i++) { 6935 if (ts->monitor[i] == TSMonitorLGSolution) { 6936 ierr = TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx);CHKERRQ(ierr); 6937 } 6938 } 6939 PetscFunctionReturn(0); 6940 } 6941 6942 #undef __FUNCT__ 6943 #define __FUNCT__ "TSMonitorLGCtxSetTransform" 6944 /*@C 6945 TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed 6946 6947 Collective on TSLGCtx 6948 6949 Input Parameters: 6950 + ts - the TS context 6951 . transform - the transform function 6952 . destroy - function to destroy the optional context 6953 - ctx - optional context used by transform function 6954 6955 Level: intermediate 6956 6957 .keywords: TS, vector, monitor, view 6958 6959 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform() 6960 @*/ 6961 PetscErrorCode TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 6962 { 6963 PetscFunctionBegin; 6964 ctx->transform = transform; 6965 ctx->transformdestroy = destroy; 6966 ctx->transformctx = tctx; 6967 PetscFunctionReturn(0); 6968 } 6969 6970 #undef __FUNCT__ 6971 #define __FUNCT__ "TSMonitorLGError" 6972 /*@C 6973 TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the solution vector 6974 in a time based line graph 6975 6976 Collective on TS 6977 6978 Input Parameters: 6979 + ts - the TS context 6980 . step - current time-step 6981 . ptime - current time 6982 . u - current solution 6983 - dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate() 6984 6985 Level: intermediate 6986 6987 Notes: Each process in a parallel run displays its component errors in a separate window 6988 6989 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 6990 6991 Options Database Keys: 6992 . -ts_monitor_lg_error - create a graphical monitor of error history 6993 6994 .keywords: TS, vector, monitor, view 6995 6996 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 6997 @*/ 6998 PetscErrorCode TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 6999 { 7000 PetscErrorCode ierr; 7001 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 7002 const PetscScalar *yy; 7003 Vec y; 7004 7005 PetscFunctionBegin; 7006 if (!step) { 7007 PetscDrawAxis axis; 7008 PetscInt dim; 7009 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 7010 ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Solution");CHKERRQ(ierr); 7011 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 7012 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 7013 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 7014 } 7015 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 7016 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 7017 ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr); 7018 ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr); 7019 #if defined(PETSC_USE_COMPLEX) 7020 { 7021 PetscReal *yreal; 7022 PetscInt i,n; 7023 ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr); 7024 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 7025 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 7026 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 7027 ierr = PetscFree(yreal);CHKERRQ(ierr); 7028 } 7029 #else 7030 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 7031 #endif 7032 ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr); 7033 ierr = VecDestroy(&y);CHKERRQ(ierr); 7034 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 7035 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 7036 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 7037 } 7038 PetscFunctionReturn(0); 7039 } 7040 7041 #undef __FUNCT__ 7042 #define __FUNCT__ "TSMonitorLGSNESIterations" 7043 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 7044 { 7045 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 7046 PetscReal x = ptime,y; 7047 PetscErrorCode ierr; 7048 PetscInt its; 7049 7050 PetscFunctionBegin; 7051 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 7052 if (!n) { 7053 PetscDrawAxis axis; 7054 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 7055 ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr); 7056 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 7057 ctx->snes_its = 0; 7058 } 7059 ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr); 7060 y = its - ctx->snes_its; 7061 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 7062 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 7063 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 7064 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 7065 } 7066 ctx->snes_its = its; 7067 PetscFunctionReturn(0); 7068 } 7069 7070 #undef __FUNCT__ 7071 #define __FUNCT__ "TSMonitorLGKSPIterations" 7072 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 7073 { 7074 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 7075 PetscReal x = ptime,y; 7076 PetscErrorCode ierr; 7077 PetscInt its; 7078 7079 PetscFunctionBegin; 7080 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 7081 if (!n) { 7082 PetscDrawAxis axis; 7083 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 7084 ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr); 7085 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 7086 ctx->ksp_its = 0; 7087 } 7088 ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr); 7089 y = its - ctx->ksp_its; 7090 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 7091 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 7092 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 7093 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 7094 } 7095 ctx->ksp_its = its; 7096 PetscFunctionReturn(0); 7097 } 7098 7099 #undef __FUNCT__ 7100 #define __FUNCT__ "TSComputeLinearStability" 7101 /*@ 7102 TSComputeLinearStability - computes the linear stability function at a point 7103 7104 Collective on TS and Vec 7105 7106 Input Parameters: 7107 + ts - the TS context 7108 - xr,xi - real and imaginary part of input arguments 7109 7110 Output Parameters: 7111 . yr,yi - real and imaginary part of function value 7112 7113 Level: developer 7114 7115 .keywords: TS, compute 7116 7117 .seealso: TSSetRHSFunction(), TSComputeIFunction() 7118 @*/ 7119 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi) 7120 { 7121 PetscErrorCode ierr; 7122 7123 PetscFunctionBegin; 7124 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7125 if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method"); 7126 ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr); 7127 PetscFunctionReturn(0); 7128 } 7129 7130 /* ------------------------------------------------------------------------*/ 7131 #undef __FUNCT__ 7132 #define __FUNCT__ "TSMonitorEnvelopeCtxCreate" 7133 /*@C 7134 TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope() 7135 7136 Collective on TS 7137 7138 Input Parameters: 7139 . ts - the ODE solver object 7140 7141 Output Parameter: 7142 . ctx - the context 7143 7144 Level: intermediate 7145 7146 .keywords: TS, monitor, line graph, residual, seealso 7147 7148 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError() 7149 7150 @*/ 7151 PetscErrorCode TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx) 7152 { 7153 PetscErrorCode ierr; 7154 7155 PetscFunctionBegin; 7156 ierr = PetscNew(ctx);CHKERRQ(ierr); 7157 PetscFunctionReturn(0); 7158 } 7159 7160 #undef __FUNCT__ 7161 #define __FUNCT__ "TSMonitorEnvelope" 7162 /*@C 7163 TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution 7164 7165 Collective on TS 7166 7167 Input Parameters: 7168 + ts - the TS context 7169 . step - current time-step 7170 . ptime - current time 7171 . u - current solution 7172 - dctx - the envelope context 7173 7174 Options Database: 7175 . -ts_monitor_envelope 7176 7177 Level: intermediate 7178 7179 Notes: after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope 7180 7181 .keywords: TS, vector, monitor, view 7182 7183 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxCreate() 7184 @*/ 7185 PetscErrorCode TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 7186 { 7187 PetscErrorCode ierr; 7188 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx; 7189 7190 PetscFunctionBegin; 7191 if (!ctx->max) { 7192 ierr = VecDuplicate(u,&ctx->max);CHKERRQ(ierr); 7193 ierr = VecDuplicate(u,&ctx->min);CHKERRQ(ierr); 7194 ierr = VecCopy(u,ctx->max);CHKERRQ(ierr); 7195 ierr = VecCopy(u,ctx->min);CHKERRQ(ierr); 7196 } else { 7197 ierr = VecPointwiseMax(ctx->max,u,ctx->max);CHKERRQ(ierr); 7198 ierr = VecPointwiseMin(ctx->min,u,ctx->min);CHKERRQ(ierr); 7199 } 7200 PetscFunctionReturn(0); 7201 } 7202 7203 7204 #undef __FUNCT__ 7205 #define __FUNCT__ "TSMonitorEnvelopeGetBounds" 7206 /*@C 7207 TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution 7208 7209 Collective on TS 7210 7211 Input Parameter: 7212 . ts - the TS context 7213 7214 Output Parameter: 7215 + max - the maximum values 7216 - min - the minimum values 7217 7218 Notes: If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored 7219 7220 Level: intermediate 7221 7222 .keywords: TS, vector, monitor, view 7223 7224 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 7225 @*/ 7226 PetscErrorCode TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min) 7227 { 7228 PetscInt i; 7229 7230 PetscFunctionBegin; 7231 if (max) *max = NULL; 7232 if (min) *min = NULL; 7233 for (i=0; i<ts->numbermonitors; i++) { 7234 if (ts->monitor[i] == TSMonitorEnvelope) { 7235 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i]; 7236 if (max) *max = ctx->max; 7237 if (min) *min = ctx->min; 7238 break; 7239 } 7240 } 7241 PetscFunctionReturn(0); 7242 } 7243 7244 #undef __FUNCT__ 7245 #define __FUNCT__ "TSMonitorEnvelopeCtxDestroy" 7246 /*@C 7247 TSMonitorEnvelopeCtxDestroy - Destroys a context that was created with TSMonitorEnvelopeCtxCreate(). 7248 7249 Collective on TSMonitorEnvelopeCtx 7250 7251 Input Parameter: 7252 . ctx - the monitor context 7253 7254 Level: intermediate 7255 7256 .keywords: TS, monitor, line graph, destroy 7257 7258 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep() 7259 @*/ 7260 PetscErrorCode TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx) 7261 { 7262 PetscErrorCode ierr; 7263 7264 PetscFunctionBegin; 7265 ierr = VecDestroy(&(*ctx)->min);CHKERRQ(ierr); 7266 ierr = VecDestroy(&(*ctx)->max);CHKERRQ(ierr); 7267 ierr = PetscFree(*ctx);CHKERRQ(ierr); 7268 PetscFunctionReturn(0); 7269 } 7270 7271 #undef __FUNCT__ 7272 #define __FUNCT__ "TSRollBack" 7273 /*@ 7274 TSRollBack - Rolls back one time step 7275 7276 Collective on TS 7277 7278 Input Parameter: 7279 . ts - the TS context obtained from TSCreate() 7280 7281 Level: advanced 7282 7283 .keywords: TS, timestep, rollback 7284 7285 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate() 7286 @*/ 7287 PetscErrorCode TSRollBack(TS ts) 7288 { 7289 PetscErrorCode ierr; 7290 7291 PetscFunctionBegin; 7292 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7293 if (ts->steprollback) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"TSRollBack already called"); 7294 if (!ts->ops->rollback) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name); 7295 ierr = (*ts->ops->rollback)(ts);CHKERRQ(ierr); 7296 ts->time_step = ts->ptime - ts->ptime_prev; 7297 ts->ptime = ts->ptime_prev; 7298 ts->ptime_prev = ts->ptime_prev_rollback; 7299 ts->steps--; ts->total_steps--; 7300 ts->steprollback = PETSC_TRUE; 7301 PetscFunctionReturn(0); 7302 } 7303 7304 #undef __FUNCT__ 7305 #define __FUNCT__ "TSGetStages" 7306 /*@ 7307 TSGetStages - Get the number of stages and stage values 7308 7309 Input Parameter: 7310 . ts - the TS context obtained from TSCreate() 7311 7312 Level: advanced 7313 7314 .keywords: TS, getstages 7315 7316 .seealso: TSCreate() 7317 @*/ 7318 PetscErrorCode TSGetStages(TS ts,PetscInt *ns,Vec **Y) 7319 { 7320 PetscErrorCode ierr; 7321 7322 PetscFunctionBegin; 7323 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7324 PetscValidPointer(ns,2); 7325 7326 if (!ts->ops->getstages) *ns=0; 7327 else { 7328 ierr = (*ts->ops->getstages)(ts,ns,Y);CHKERRQ(ierr); 7329 } 7330 PetscFunctionReturn(0); 7331 } 7332 7333 #undef __FUNCT__ 7334 #define __FUNCT__ "TSComputeIJacobianDefaultColor" 7335 /*@C 7336 TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity. 7337 7338 Collective on SNES 7339 7340 Input Parameters: 7341 + ts - the TS context 7342 . t - current timestep 7343 . U - state vector 7344 . Udot - time derivative of state vector 7345 . shift - shift to apply, see note below 7346 - ctx - an optional user context 7347 7348 Output Parameters: 7349 + J - Jacobian matrix (not altered in this routine) 7350 - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J) 7351 7352 Level: intermediate 7353 7354 Notes: 7355 If F(t,U,Udot)=0 is the DAE, the required Jacobian is 7356 7357 dF/dU + shift*dF/dUdot 7358 7359 Most users should not need to explicitly call this routine, as it 7360 is used internally within the nonlinear solvers. 7361 7362 This will first try to get the coloring from the DM. If the DM type has no coloring 7363 routine, then it will try to get the coloring from the matrix. This requires that the 7364 matrix have nonzero entries precomputed. 7365 7366 .keywords: TS, finite differences, Jacobian, coloring, sparse 7367 .seealso: TSSetIJacobian(), MatFDColoringCreate(), MatFDColoringSetFunction() 7368 @*/ 7369 PetscErrorCode TSComputeIJacobianDefaultColor(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat J,Mat B,void *ctx) 7370 { 7371 SNES snes; 7372 MatFDColoring color; 7373 PetscBool hascolor, matcolor = PETSC_FALSE; 7374 PetscErrorCode ierr; 7375 7376 PetscFunctionBegin; 7377 ierr = PetscOptionsGetBool(((PetscObject)ts)->options,((PetscObject) ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL);CHKERRQ(ierr); 7378 ierr = PetscObjectQuery((PetscObject) B, "TSMatFDColoring", (PetscObject *) &color);CHKERRQ(ierr); 7379 if (!color) { 7380 DM dm; 7381 ISColoring iscoloring; 7382 7383 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 7384 ierr = DMHasColoring(dm, &hascolor);CHKERRQ(ierr); 7385 if (hascolor && !matcolor) { 7386 ierr = DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring);CHKERRQ(ierr); 7387 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 7388 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 7389 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 7390 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 7391 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 7392 } else { 7393 MatColoring mc; 7394 7395 ierr = MatColoringCreate(B, &mc);CHKERRQ(ierr); 7396 ierr = MatColoringSetDistance(mc, 2);CHKERRQ(ierr); 7397 ierr = MatColoringSetType(mc, MATCOLORINGSL);CHKERRQ(ierr); 7398 ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); 7399 ierr = MatColoringApply(mc, &iscoloring);CHKERRQ(ierr); 7400 ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); 7401 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 7402 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 7403 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 7404 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 7405 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 7406 } 7407 ierr = PetscObjectCompose((PetscObject) B, "TSMatFDColoring", (PetscObject) color);CHKERRQ(ierr); 7408 ierr = PetscObjectDereference((PetscObject) color);CHKERRQ(ierr); 7409 } 7410 ierr = TSGetSNES(ts, &snes);CHKERRQ(ierr); 7411 ierr = MatFDColoringApply(B, color, U, snes);CHKERRQ(ierr); 7412 if (J != B) { 7413 ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7414 ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7415 } 7416 PetscFunctionReturn(0); 7417 } 7418 7419 #undef __FUNCT__ 7420 #define __FUNCT__ "TSSetFunctionDomainError" 7421 /*@ 7422 TSSetFunctionDomainError - Set the function testing if the current state vector is valid 7423 7424 Input Parameters: 7425 ts - the TS context 7426 func - function called within TSFunctionDomainError 7427 7428 Level: intermediate 7429 7430 .keywords: TS, state, domain 7431 .seealso: TSAdaptCheckStage(), TSFunctionDomainError() 7432 @*/ 7433 7434 PetscErrorCode TSSetFunctionDomainError(TS ts, PetscErrorCode (*func)(TS,PetscReal,Vec,PetscBool*)) 7435 { 7436 PetscFunctionBegin; 7437 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7438 ts->functiondomainerror = func; 7439 PetscFunctionReturn(0); 7440 } 7441 7442 #undef __FUNCT__ 7443 #define __FUNCT__ "TSFunctionDomainError" 7444 /*@ 7445 TSFunctionDomainError - Check if the current state is valid 7446 7447 Input Parameters: 7448 ts - the TS context 7449 stagetime - time of the simulation 7450 Y - state vector to check. 7451 7452 Output Parameter: 7453 accept - Set to PETSC_FALSE if the current state vector is valid. 7454 7455 Note: 7456 This function should be used to ensure the state is in a valid part of the space. 7457 For example, one can ensure here all values are positive. 7458 7459 Level: advanced 7460 @*/ 7461 PetscErrorCode TSFunctionDomainError(TS ts,PetscReal stagetime,Vec Y,PetscBool* accept) 7462 { 7463 PetscErrorCode ierr; 7464 7465 PetscFunctionBegin; 7466 7467 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7468 *accept = PETSC_TRUE; 7469 if (ts->functiondomainerror) { 7470 PetscStackCallStandard((*ts->functiondomainerror),(ts,stagetime,Y,accept)); 7471 } 7472 PetscFunctionReturn(0); 7473 } 7474 7475 #undef __FUNCT__ 7476 #define __FUNCT__ "TSClone" 7477 /*@C 7478 TSClone - This function clones a time step object. 7479 7480 Collective on MPI_Comm 7481 7482 Input Parameter: 7483 . tsin - The input TS 7484 7485 Output Parameter: 7486 . tsout - The output TS (cloned) 7487 7488 Notes: 7489 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. 7490 7491 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); 7492 7493 Level: developer 7494 7495 .keywords: TS, clone 7496 .seealso: TSCreate(), TSSetType(), TSSetUp(), TSDestroy(), TSSetProblemType() 7497 @*/ 7498 PetscErrorCode TSClone(TS tsin, TS *tsout) 7499 { 7500 TS t; 7501 PetscErrorCode ierr; 7502 SNES snes_start; 7503 DM dm; 7504 TSType type; 7505 7506 PetscFunctionBegin; 7507 PetscValidPointer(tsin,1); 7508 *tsout = NULL; 7509 7510 ierr = PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView);CHKERRQ(ierr); 7511 7512 /* General TS description */ 7513 t->numbermonitors = 0; 7514 t->setupcalled = 0; 7515 t->ksp_its = 0; 7516 t->snes_its = 0; 7517 t->nwork = 0; 7518 t->rhsjacobian.time = -1e20; 7519 t->rhsjacobian.scale = 1.; 7520 t->ijacobian.shift = 1.; 7521 7522 ierr = TSGetSNES(tsin,&snes_start);CHKERRQ(ierr); 7523 ierr = TSSetSNES(t,snes_start);CHKERRQ(ierr); 7524 7525 ierr = TSGetDM(tsin,&dm);CHKERRQ(ierr); 7526 ierr = TSSetDM(t,dm);CHKERRQ(ierr); 7527 7528 t->adapt = tsin->adapt; 7529 ierr = PetscObjectReference((PetscObject)t->adapt);CHKERRQ(ierr); 7530 7531 t->problem_type = tsin->problem_type; 7532 t->ptime = tsin->ptime; 7533 t->time_step = tsin->time_step; 7534 t->max_time = tsin->max_time; 7535 t->steps = tsin->steps; 7536 t->max_steps = tsin->max_steps; 7537 t->equation_type = tsin->equation_type; 7538 t->atol = tsin->atol; 7539 t->rtol = tsin->rtol; 7540 t->max_snes_failures = tsin->max_snes_failures; 7541 t->max_reject = tsin->max_reject; 7542 t->errorifstepfailed = tsin->errorifstepfailed; 7543 7544 ierr = TSGetType(tsin,&type);CHKERRQ(ierr); 7545 ierr = TSSetType(t,type);CHKERRQ(ierr); 7546 7547 t->vec_sol = NULL; 7548 7549 t->cfltime = tsin->cfltime; 7550 t->cfltime_local = tsin->cfltime_local; 7551 t->exact_final_time = tsin->exact_final_time; 7552 7553 ierr = PetscMemcpy(t->ops,tsin->ops,sizeof(struct _TSOps));CHKERRQ(ierr); 7554 7555 if (((PetscObject)tsin)->fortran_func_pointers) { 7556 PetscInt i; 7557 ierr = PetscMalloc((10)*sizeof(void(*)(void)),&((PetscObject)t)->fortran_func_pointers);CHKERRQ(ierr); 7558 for (i=0; i<10; i++) { 7559 ((PetscObject)t)->fortran_func_pointers[i] = ((PetscObject)tsin)->fortran_func_pointers[i]; 7560 } 7561 } 7562 *tsout = t; 7563 PetscFunctionReturn(0); 7564 } 7565