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