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