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