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