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