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