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