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