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