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