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