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