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