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 ierr = MatDestroy(&ts->mat_sensip);CHKERRQ(ierr); 2765 2766 ts->setupcalled = PETSC_FALSE; 2767 PetscFunctionReturn(0); 2768 } 2769 2770 /*@ 2771 TSDestroy - Destroys the timestepper context that was created 2772 with TSCreate(). 2773 2774 Collective on TS 2775 2776 Input Parameter: 2777 . ts - the TS context obtained from TSCreate() 2778 2779 Level: beginner 2780 2781 .keywords: TS, timestepper, destroy 2782 2783 .seealso: TSCreate(), TSSetUp(), TSSolve() 2784 @*/ 2785 PetscErrorCode TSDestroy(TS *ts) 2786 { 2787 PetscErrorCode ierr; 2788 2789 PetscFunctionBegin; 2790 if (!*ts) PetscFunctionReturn(0); 2791 PetscValidHeaderSpecific((*ts),TS_CLASSID,1); 2792 if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; PetscFunctionReturn(0);} 2793 2794 ierr = TSReset((*ts));CHKERRQ(ierr); 2795 2796 /* if memory was published with SAWs then destroy it */ 2797 ierr = PetscObjectSAWsViewOff((PetscObject)*ts);CHKERRQ(ierr); 2798 if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);} 2799 2800 ierr = TSTrajectoryDestroy(&(*ts)->trajectory);CHKERRQ(ierr); 2801 2802 ierr = TSAdaptDestroy(&(*ts)->adapt);CHKERRQ(ierr); 2803 ierr = TSEventDestroy(&(*ts)->event);CHKERRQ(ierr); 2804 2805 ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr); 2806 ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr); 2807 ierr = TSMonitorCancel((*ts));CHKERRQ(ierr); 2808 ierr = TSAdjointMonitorCancel((*ts));CHKERRQ(ierr); 2809 2810 ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr); 2811 PetscFunctionReturn(0); 2812 } 2813 2814 /*@ 2815 TSGetSNES - Returns the SNES (nonlinear solver) associated with 2816 a TS (timestepper) context. Valid only for nonlinear problems. 2817 2818 Not Collective, but SNES is parallel if TS is parallel 2819 2820 Input Parameter: 2821 . ts - the TS context obtained from TSCreate() 2822 2823 Output Parameter: 2824 . snes - the nonlinear solver context 2825 2826 Notes: 2827 The user can then directly manipulate the SNES context to set various 2828 options, etc. Likewise, the user can then extract and manipulate the 2829 KSP, KSP, and PC contexts as well. 2830 2831 TSGetSNES() does not work for integrators that do not use SNES; in 2832 this case TSGetSNES() returns NULL in snes. 2833 2834 Level: beginner 2835 2836 .keywords: timestep, get, SNES 2837 @*/ 2838 PetscErrorCode TSGetSNES(TS ts,SNES *snes) 2839 { 2840 PetscErrorCode ierr; 2841 2842 PetscFunctionBegin; 2843 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2844 PetscValidPointer(snes,2); 2845 if (!ts->snes) { 2846 ierr = SNESCreate(PetscObjectComm((PetscObject)ts),&ts->snes);CHKERRQ(ierr); 2847 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 2848 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->snes);CHKERRQ(ierr); 2849 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr); 2850 if (ts->dm) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 2851 if (ts->problem_type == TS_LINEAR) { 2852 ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr); 2853 } 2854 } 2855 *snes = ts->snes; 2856 PetscFunctionReturn(0); 2857 } 2858 2859 /*@ 2860 TSSetSNES - Set the SNES (nonlinear solver) to be used by the timestepping context 2861 2862 Collective 2863 2864 Input Parameter: 2865 + ts - the TS context obtained from TSCreate() 2866 - snes - the nonlinear solver context 2867 2868 Notes: 2869 Most users should have the TS created by calling TSGetSNES() 2870 2871 Level: developer 2872 2873 .keywords: timestep, set, SNES 2874 @*/ 2875 PetscErrorCode TSSetSNES(TS ts,SNES snes) 2876 { 2877 PetscErrorCode ierr; 2878 PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*); 2879 2880 PetscFunctionBegin; 2881 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2882 PetscValidHeaderSpecific(snes,SNES_CLASSID,2); 2883 ierr = PetscObjectReference((PetscObject)snes);CHKERRQ(ierr); 2884 ierr = SNESDestroy(&ts->snes);CHKERRQ(ierr); 2885 2886 ts->snes = snes; 2887 2888 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 2889 ierr = SNESGetJacobian(ts->snes,NULL,NULL,&func,NULL);CHKERRQ(ierr); 2890 if (func == SNESTSFormJacobian) { 2891 ierr = SNESSetJacobian(ts->snes,NULL,NULL,SNESTSFormJacobian,ts);CHKERRQ(ierr); 2892 } 2893 PetscFunctionReturn(0); 2894 } 2895 2896 /*@ 2897 TSGetKSP - Returns the KSP (linear solver) associated with 2898 a TS (timestepper) context. 2899 2900 Not Collective, but KSP is parallel if TS is parallel 2901 2902 Input Parameter: 2903 . ts - the TS context obtained from TSCreate() 2904 2905 Output Parameter: 2906 . ksp - the nonlinear solver context 2907 2908 Notes: 2909 The user can then directly manipulate the KSP context to set various 2910 options, etc. Likewise, the user can then extract and manipulate the 2911 KSP and PC contexts as well. 2912 2913 TSGetKSP() does not work for integrators that do not use KSP; 2914 in this case TSGetKSP() returns NULL in ksp. 2915 2916 Level: beginner 2917 2918 .keywords: timestep, get, KSP 2919 @*/ 2920 PetscErrorCode TSGetKSP(TS ts,KSP *ksp) 2921 { 2922 PetscErrorCode ierr; 2923 SNES snes; 2924 2925 PetscFunctionBegin; 2926 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2927 PetscValidPointer(ksp,2); 2928 if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first"); 2929 if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()"); 2930 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2931 ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr); 2932 PetscFunctionReturn(0); 2933 } 2934 2935 /* ----------- Routines to set solver parameters ---------- */ 2936 2937 /*@ 2938 TSSetMaxSteps - Sets the maximum number of steps to use. 2939 2940 Logically Collective on TS 2941 2942 Input Parameters: 2943 + ts - the TS context obtained from TSCreate() 2944 - maxsteps - maximum number of steps to use 2945 2946 Options Database Keys: 2947 . -ts_max_steps <maxsteps> - Sets maxsteps 2948 2949 Notes: 2950 The default maximum number of steps is 5000 2951 2952 Level: intermediate 2953 2954 .keywords: TS, timestep, set, maximum, steps 2955 2956 .seealso: TSGetMaxSteps(), TSSetMaxTime(), TSSetExactFinalTime() 2957 @*/ 2958 PetscErrorCode TSSetMaxSteps(TS ts,PetscInt maxsteps) 2959 { 2960 PetscFunctionBegin; 2961 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2962 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 2963 if (maxsteps < 0 ) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of steps must be non-negative"); 2964 ts->max_steps = maxsteps; 2965 PetscFunctionReturn(0); 2966 } 2967 2968 /*@ 2969 TSGetMaxSteps - Gets the maximum number of steps to use. 2970 2971 Not Collective 2972 2973 Input Parameters: 2974 . ts - the TS context obtained from TSCreate() 2975 2976 Output Parameter: 2977 . maxsteps - maximum number of steps to use 2978 2979 Level: advanced 2980 2981 .keywords: TS, timestep, get, maximum, steps 2982 2983 .seealso: TSSetMaxSteps(), TSGetMaxTime(), TSSetMaxTime() 2984 @*/ 2985 PetscErrorCode TSGetMaxSteps(TS ts,PetscInt *maxsteps) 2986 { 2987 PetscFunctionBegin; 2988 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2989 PetscValidIntPointer(maxsteps,2); 2990 *maxsteps = ts->max_steps; 2991 PetscFunctionReturn(0); 2992 } 2993 2994 /*@ 2995 TSSetMaxTime - Sets the maximum (or final) time for timestepping. 2996 2997 Logically Collective on TS 2998 2999 Input Parameters: 3000 + ts - the TS context obtained from TSCreate() 3001 - maxtime - final time to step to 3002 3003 Options Database Keys: 3004 . -ts_max_time <maxtime> - Sets maxtime 3005 3006 Notes: 3007 The default maximum time is 5.0 3008 3009 Level: intermediate 3010 3011 .keywords: TS, timestep, set, maximum, time 3012 3013 .seealso: TSGetMaxTime(), TSSetMaxSteps(), TSSetExactFinalTime() 3014 @*/ 3015 PetscErrorCode TSSetMaxTime(TS ts,PetscReal maxtime) 3016 { 3017 PetscFunctionBegin; 3018 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3019 PetscValidLogicalCollectiveReal(ts,maxtime,2); 3020 ts->max_time = maxtime; 3021 PetscFunctionReturn(0); 3022 } 3023 3024 /*@ 3025 TSGetMaxTime - Gets the maximum (or final) time for timestepping. 3026 3027 Not Collective 3028 3029 Input Parameters: 3030 . ts - the TS context obtained from TSCreate() 3031 3032 Output Parameter: 3033 . maxtime - final time to step to 3034 3035 Level: advanced 3036 3037 .keywords: TS, timestep, get, maximum, time 3038 3039 .seealso: TSSetMaxTime(), TSGetMaxSteps(), TSSetMaxSteps() 3040 @*/ 3041 PetscErrorCode TSGetMaxTime(TS ts,PetscReal *maxtime) 3042 { 3043 PetscFunctionBegin; 3044 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3045 PetscValidRealPointer(maxtime,2); 3046 *maxtime = ts->max_time; 3047 PetscFunctionReturn(0); 3048 } 3049 3050 /*@ 3051 TSSetInitialTimeStep - Deprecated, use TSSetTime() and TSSetTimeStep(). 3052 3053 Level: deprecated 3054 3055 @*/ 3056 PetscErrorCode TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step) 3057 { 3058 PetscErrorCode ierr; 3059 PetscFunctionBegin; 3060 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3061 ierr = TSSetTime(ts,initial_time);CHKERRQ(ierr); 3062 ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr); 3063 PetscFunctionReturn(0); 3064 } 3065 3066 /*@ 3067 TSGetDuration - Deprecated, use TSGetMaxSteps() and TSGetMaxTime(). 3068 3069 Level: deprecated 3070 3071 @*/ 3072 PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime) 3073 { 3074 PetscFunctionBegin; 3075 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3076 if (maxsteps) { 3077 PetscValidIntPointer(maxsteps,2); 3078 *maxsteps = ts->max_steps; 3079 } 3080 if (maxtime) { 3081 PetscValidScalarPointer(maxtime,3); 3082 *maxtime = ts->max_time; 3083 } 3084 PetscFunctionReturn(0); 3085 } 3086 3087 /*@ 3088 TSSetDuration - Deprecated, use TSSetMaxSteps() and TSSetMaxTime(). 3089 3090 Level: deprecated 3091 3092 @*/ 3093 PetscErrorCode TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime) 3094 { 3095 PetscFunctionBegin; 3096 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3097 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 3098 PetscValidLogicalCollectiveReal(ts,maxtime,2); 3099 if (maxsteps >= 0) ts->max_steps = maxsteps; 3100 if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime; 3101 PetscFunctionReturn(0); 3102 } 3103 3104 /*@ 3105 TSGetTimeStepNumber - Deprecated, use TSGetStepNumber(). 3106 3107 Level: deprecated 3108 3109 @*/ 3110 PetscErrorCode TSGetTimeStepNumber(TS ts,PetscInt *steps) { return TSGetStepNumber(ts,steps); } 3111 3112 /*@ 3113 TSGetTotalSteps - Deprecated, use TSGetStepNumber(). 3114 3115 Level: deprecated 3116 3117 @*/ 3118 PetscErrorCode TSGetTotalSteps(TS ts,PetscInt *steps) { return TSGetStepNumber(ts,steps); } 3119 3120 /*@ 3121 TSSetSolution - Sets the initial solution vector 3122 for use by the TS routines. 3123 3124 Logically Collective on TS and Vec 3125 3126 Input Parameters: 3127 + ts - the TS context obtained from TSCreate() 3128 - u - the solution vector 3129 3130 Level: beginner 3131 3132 .keywords: TS, timestep, set, solution, initial values 3133 3134 .seealso: TSSetSolutionFunction(), TSGetSolution(), TSCreate() 3135 @*/ 3136 PetscErrorCode TSSetSolution(TS ts,Vec u) 3137 { 3138 PetscErrorCode ierr; 3139 DM dm; 3140 3141 PetscFunctionBegin; 3142 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3143 PetscValidHeaderSpecific(u,VEC_CLASSID,2); 3144 ierr = PetscObjectReference((PetscObject)u);CHKERRQ(ierr); 3145 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 3146 ts->vec_sol = u; 3147 3148 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 3149 ierr = DMShellSetGlobalVector(dm,u);CHKERRQ(ierr); 3150 PetscFunctionReturn(0); 3151 } 3152 3153 /*@ 3154 TSAdjointSetSteps - Sets the number of steps the adjoint solver should take backward in time 3155 3156 Logically Collective on TS 3157 3158 Input Parameters: 3159 + ts - the TS context obtained from TSCreate() 3160 . steps - number of steps to use 3161 3162 Level: intermediate 3163 3164 Notes: Normally one does not call this and TSAdjointSolve() integrates back to the original timestep. One can call this 3165 so as to integrate back to less than the original timestep 3166 3167 .keywords: TS, timestep, set, maximum, iterations 3168 3169 .seealso: TSSetExactFinalTime() 3170 @*/ 3171 PetscErrorCode TSAdjointSetSteps(TS ts,PetscInt steps) 3172 { 3173 PetscFunctionBegin; 3174 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3175 PetscValidLogicalCollectiveInt(ts,steps,2); 3176 if (steps < 0) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back a negative number of steps"); 3177 if (steps > ts->steps) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back more than the total number of forward steps"); 3178 ts->adjoint_max_steps = steps; 3179 PetscFunctionReturn(0); 3180 } 3181 3182 /*@ 3183 TSSetCostGradients - Sets the initial value of the gradients of the cost function w.r.t. initial values and w.r.t. the problem parameters 3184 for use by the TSAdjoint routines. 3185 3186 Logically Collective on TS and Vec 3187 3188 Input Parameters: 3189 + ts - the TS context obtained from TSCreate() 3190 . 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 3191 - mu - gradients with respect to the parameters, the number of entries in these vectors is the same as the number of parameters 3192 3193 Level: beginner 3194 3195 Notes: the entries in these vectors must be correctly initialized with the values lamda_i = df/dy|finaltime mu_i = df/dp|finaltime 3196 3197 After TSAdjointSolve() is called the lamba and the mu contain the computed sensitivities 3198 3199 .keywords: TS, timestep, set, sensitivity, initial values 3200 @*/ 3201 PetscErrorCode TSSetCostGradients(TS ts,PetscInt numcost,Vec *lambda,Vec *mu) 3202 { 3203 PetscFunctionBegin; 3204 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3205 PetscValidPointer(lambda,2); 3206 ts->vecs_sensi = lambda; 3207 ts->vecs_sensip = mu; 3208 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"); 3209 ts->numcost = numcost; 3210 PetscFunctionReturn(0); 3211 } 3212 3213 /*@C 3214 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. 3215 3216 Logically Collective on TS 3217 3218 Input Parameters: 3219 + ts - The TS context obtained from TSCreate() 3220 - func - The function 3221 3222 Calling sequence of func: 3223 $ func (TS ts,PetscReal t,Vec y,Mat A,void *ctx); 3224 + t - current timestep 3225 . y - input vector (current ODE solution) 3226 . A - output matrix 3227 - ctx - [optional] user-defined function context 3228 3229 Level: intermediate 3230 3231 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 3232 3233 .keywords: TS, sensitivity 3234 .seealso: 3235 @*/ 3236 PetscErrorCode TSAdjointSetRHSJacobian(TS ts,Mat Amat,PetscErrorCode (*func)(TS,PetscReal,Vec,Mat,void*),void *ctx) 3237 { 3238 PetscErrorCode ierr; 3239 3240 PetscFunctionBegin; 3241 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3242 PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 3243 3244 ts->rhsjacobianp = func; 3245 ts->rhsjacobianpctx = ctx; 3246 if(Amat) { 3247 ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 3248 ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr); 3249 ts->Jacp = Amat; 3250 } 3251 PetscFunctionReturn(0); 3252 } 3253 3254 /*@C 3255 TSAdjointComputeRHSJacobian - Runs the user-defined Jacobian function. 3256 3257 Collective on TS 3258 3259 Input Parameters: 3260 . ts - The TS context obtained from TSCreate() 3261 3262 Level: developer 3263 3264 .keywords: TS, sensitivity 3265 .seealso: TSAdjointSetRHSJacobian() 3266 @*/ 3267 PetscErrorCode TSAdjointComputeRHSJacobian(TS ts,PetscReal t,Vec X,Mat Amat) 3268 { 3269 PetscErrorCode ierr; 3270 3271 PetscFunctionBegin; 3272 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3273 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 3274 PetscValidPointer(Amat,4); 3275 3276 PetscStackPush("TS user JacobianP function for sensitivity analysis"); 3277 ierr = (*ts->rhsjacobianp)(ts,t,X,Amat,ts->rhsjacobianpctx); CHKERRQ(ierr); 3278 PetscStackPop; 3279 PetscFunctionReturn(0); 3280 } 3281 3282 /*@C 3283 TSSetCostIntegrand - Sets the routine for evaluating the integral term in one or more cost functions 3284 3285 Logically Collective on TS 3286 3287 Input Parameters: 3288 + ts - the TS context obtained from TSCreate() 3289 . numcost - number of gradients to be computed, this is the number of cost functions 3290 . costintegral - vector that stores the integral values 3291 . rf - routine for evaluating the integrand function 3292 . drdyf - function that computes the gradients of the r's with respect to y,NULL if not a function y 3293 . drdpf - function that computes the gradients of the r's with respect to p, NULL if not a function of p 3294 . fwd - flag indicating whether to evaluate cost integral in the forward run or the adjoint run 3295 - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL) 3296 3297 Calling sequence of rf: 3298 $ PetscErrorCode rf(TS ts,PetscReal t,Vec y,Vec f,void *ctx); 3299 3300 Calling sequence of drdyf: 3301 $ PetscErroCode drdyf(TS ts,PetscReal t,Vec y,Vec *drdy,void *ctx); 3302 3303 Calling sequence of drdpf: 3304 $ PetscErroCode drdpf(TS ts,PetscReal t,Vec y,Vec *drdp,void *ctx); 3305 3306 Level: intermediate 3307 3308 Notes: For optimization there is usually a single cost function (numcost = 1). For sensitivities there may be multiple cost functions 3309 3310 .keywords: TS, sensitivity analysis, timestep, set, quadrature, function 3311 3312 .seealso: TSAdjointSetRHSJacobian(),TSGetCostGradients(), TSSetCostGradients() 3313 @*/ 3314 PetscErrorCode TSSetCostIntegrand(TS ts,PetscInt numcost,Vec costintegral,PetscErrorCode (*rf)(TS,PetscReal,Vec,Vec,void*), 3315 PetscErrorCode (*drdyf)(TS,PetscReal,Vec,Vec*,void*), 3316 PetscErrorCode (*drdpf)(TS,PetscReal,Vec,Vec*,void*), 3317 PetscBool fwd,void *ctx) 3318 { 3319 PetscErrorCode ierr; 3320 3321 PetscFunctionBegin; 3322 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3323 if (costintegral) PetscValidHeaderSpecific(costintegral,VEC_CLASSID,3); 3324 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()"); 3325 if (!ts->numcost) ts->numcost=numcost; 3326 3327 if (costintegral) { 3328 ierr = PetscObjectReference((PetscObject)costintegral);CHKERRQ(ierr); 3329 ierr = VecDestroy(&ts->vec_costintegral);CHKERRQ(ierr); 3330 ts->vec_costintegral = costintegral; 3331 } else { 3332 if (!ts->vec_costintegral) { /* Create a seq vec if user does not provide one */ 3333 ierr = VecCreateSeq(PETSC_COMM_SELF,numcost,&ts->vec_costintegral);CHKERRQ(ierr); 3334 } else { 3335 ierr = VecSet(ts->vec_costintegral,0.0);CHKERRQ(ierr); 3336 } 3337 } 3338 if (!ts->vec_costintegrand) { 3339 ierr = VecDuplicate(ts->vec_costintegral,&ts->vec_costintegrand);CHKERRQ(ierr); 3340 } else { 3341 ierr = VecSet(ts->vec_costintegrand,0.0);CHKERRQ(ierr); 3342 } 3343 ts->costintegralfwd = fwd; /* Evaluate the cost integral in forward run if fwd is true */ 3344 ts->costintegrand = rf; 3345 ts->costintegrandctx = ctx; 3346 ts->drdyfunction = drdyf; 3347 ts->drdpfunction = drdpf; 3348 PetscFunctionReturn(0); 3349 } 3350 3351 /*@ 3352 TSGetCostIntegral - Returns the values of the integral term in the cost functions. 3353 It is valid to call the routine after a backward run. 3354 3355 Not Collective 3356 3357 Input Parameter: 3358 . ts - the TS context obtained from TSCreate() 3359 3360 Output Parameter: 3361 . v - the vector containing the integrals for each cost function 3362 3363 Level: intermediate 3364 3365 .seealso: TSSetCostIntegrand() 3366 3367 .keywords: TS, sensitivity analysis 3368 @*/ 3369 PetscErrorCode TSGetCostIntegral(TS ts,Vec *v) 3370 { 3371 PetscFunctionBegin; 3372 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3373 PetscValidPointer(v,2); 3374 *v = ts->vec_costintegral; 3375 PetscFunctionReturn(0); 3376 } 3377 3378 /*@ 3379 TSComputeCostIntegrand - Evaluates the integral function in the cost functions. 3380 3381 Input Parameters: 3382 + ts - the TS context 3383 . t - current time 3384 - y - state vector, i.e. current solution 3385 3386 Output Parameter: 3387 . q - vector of size numcost to hold the outputs 3388 3389 Note: 3390 Most users should not need to explicitly call this routine, as it 3391 is used internally within the sensitivity analysis context. 3392 3393 Level: developer 3394 3395 .keywords: TS, compute 3396 3397 .seealso: TSSetCostIntegrand() 3398 @*/ 3399 PetscErrorCode TSComputeCostIntegrand(TS ts,PetscReal t,Vec y,Vec q) 3400 { 3401 PetscErrorCode ierr; 3402 3403 PetscFunctionBegin; 3404 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3405 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3406 PetscValidHeaderSpecific(q,VEC_CLASSID,4); 3407 3408 ierr = PetscLogEventBegin(TS_FunctionEval,ts,y,q,0);CHKERRQ(ierr); 3409 if (ts->costintegrand) { 3410 PetscStackPush("TS user integrand in the cost function"); 3411 ierr = (*ts->costintegrand)(ts,t,y,q,ts->costintegrandctx);CHKERRQ(ierr); 3412 PetscStackPop; 3413 } else { 3414 ierr = VecZeroEntries(q);CHKERRQ(ierr); 3415 } 3416 3417 ierr = PetscLogEventEnd(TS_FunctionEval,ts,y,q,0);CHKERRQ(ierr); 3418 PetscFunctionReturn(0); 3419 } 3420 3421 /*@ 3422 TSAdjointComputeDRDYFunction - Runs the user-defined DRDY function. 3423 3424 Collective on TS 3425 3426 Input Parameters: 3427 . ts - The TS context obtained from TSCreate() 3428 3429 Notes: 3430 TSAdjointComputeDRDYFunction() is typically used for sensitivity implementation, 3431 so most users would not generally call this routine themselves. 3432 3433 Level: developer 3434 3435 .keywords: TS, sensitivity 3436 .seealso: TSAdjointComputeDRDYFunction() 3437 @*/ 3438 PetscErrorCode TSAdjointComputeDRDYFunction(TS ts,PetscReal t,Vec y,Vec *drdy) 3439 { 3440 PetscErrorCode ierr; 3441 3442 PetscFunctionBegin; 3443 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3444 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3445 3446 PetscStackPush("TS user DRDY function for sensitivity analysis"); 3447 ierr = (*ts->drdyfunction)(ts,t,y,drdy,ts->costintegrandctx); CHKERRQ(ierr); 3448 PetscStackPop; 3449 PetscFunctionReturn(0); 3450 } 3451 3452 /*@ 3453 TSAdjointComputeDRDPFunction - Runs the user-defined DRDP function. 3454 3455 Collective on TS 3456 3457 Input Parameters: 3458 . ts - The TS context obtained from TSCreate() 3459 3460 Notes: 3461 TSDRDPFunction() is typically used for sensitivity implementation, 3462 so most users would not generally call this routine themselves. 3463 3464 Level: developer 3465 3466 .keywords: TS, sensitivity 3467 .seealso: TSAdjointSetDRDPFunction() 3468 @*/ 3469 PetscErrorCode TSAdjointComputeDRDPFunction(TS ts,PetscReal t,Vec y,Vec *drdp) 3470 { 3471 PetscErrorCode ierr; 3472 3473 PetscFunctionBegin; 3474 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3475 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3476 3477 PetscStackPush("TS user DRDP function for sensitivity analysis"); 3478 ierr = (*ts->drdpfunction)(ts,t,y,drdp,ts->costintegrandctx); CHKERRQ(ierr); 3479 PetscStackPop; 3480 PetscFunctionReturn(0); 3481 } 3482 3483 /*@C 3484 TSSetPreStep - Sets the general-purpose function 3485 called once at the beginning of each time step. 3486 3487 Logically Collective on TS 3488 3489 Input Parameters: 3490 + ts - The TS context obtained from TSCreate() 3491 - func - The function 3492 3493 Calling sequence of func: 3494 . func (TS ts); 3495 3496 Level: intermediate 3497 3498 .keywords: TS, timestep 3499 .seealso: TSSetPreStage(), TSSetPostStage(), TSSetPostStep(), TSStep(), TSRestartStep() 3500 @*/ 3501 PetscErrorCode TSSetPreStep(TS ts, PetscErrorCode (*func)(TS)) 3502 { 3503 PetscFunctionBegin; 3504 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3505 ts->prestep = func; 3506 PetscFunctionReturn(0); 3507 } 3508 3509 /*@ 3510 TSPreStep - Runs the user-defined pre-step function. 3511 3512 Collective on TS 3513 3514 Input Parameters: 3515 . ts - The TS context obtained from TSCreate() 3516 3517 Notes: 3518 TSPreStep() is typically used within time stepping implementations, 3519 so most users would not generally call this routine themselves. 3520 3521 Level: developer 3522 3523 .keywords: TS, timestep 3524 .seealso: TSSetPreStep(), TSPreStage(), TSPostStage(), TSPostStep() 3525 @*/ 3526 PetscErrorCode TSPreStep(TS ts) 3527 { 3528 PetscErrorCode ierr; 3529 3530 PetscFunctionBegin; 3531 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3532 if (ts->prestep) { 3533 Vec U; 3534 PetscObjectState sprev,spost; 3535 3536 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3537 ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr); 3538 PetscStackCallStandard((*ts->prestep),(ts)); 3539 ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr); 3540 if (sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);} 3541 } 3542 PetscFunctionReturn(0); 3543 } 3544 3545 /*@C 3546 TSSetPreStage - Sets the general-purpose function 3547 called once at the beginning of each stage. 3548 3549 Logically Collective on TS 3550 3551 Input Parameters: 3552 + ts - The TS context obtained from TSCreate() 3553 - func - The function 3554 3555 Calling sequence of func: 3556 . PetscErrorCode func(TS ts, PetscReal stagetime); 3557 3558 Level: intermediate 3559 3560 Note: 3561 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 3562 The time step number being computed can be queried using TSGetStepNumber() and the total size of the step being 3563 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 3564 3565 .keywords: TS, timestep 3566 .seealso: TSSetPostStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3567 @*/ 3568 PetscErrorCode TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal)) 3569 { 3570 PetscFunctionBegin; 3571 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3572 ts->prestage = func; 3573 PetscFunctionReturn(0); 3574 } 3575 3576 /*@C 3577 TSSetPostStage - Sets the general-purpose function 3578 called once at the end of each stage. 3579 3580 Logically Collective on TS 3581 3582 Input Parameters: 3583 + ts - The TS context obtained from TSCreate() 3584 - func - The function 3585 3586 Calling sequence of func: 3587 . PetscErrorCode func(TS ts, PetscReal stagetime, PetscInt stageindex, Vec* Y); 3588 3589 Level: intermediate 3590 3591 Note: 3592 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 3593 The time step number being computed can be queried using TSGetStepNumber() and the total size of the step being 3594 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 3595 3596 .keywords: TS, timestep 3597 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3598 @*/ 3599 PetscErrorCode TSSetPostStage(TS ts, PetscErrorCode (*func)(TS,PetscReal,PetscInt,Vec*)) 3600 { 3601 PetscFunctionBegin; 3602 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3603 ts->poststage = func; 3604 PetscFunctionReturn(0); 3605 } 3606 3607 /*@C 3608 TSSetPostEvaluate - Sets the general-purpose function 3609 called once at the end of each step evaluation. 3610 3611 Logically Collective on TS 3612 3613 Input Parameters: 3614 + ts - The TS context obtained from TSCreate() 3615 - func - The function 3616 3617 Calling sequence of func: 3618 . PetscErrorCode func(TS ts); 3619 3620 Level: intermediate 3621 3622 Note: 3623 Semantically, TSSetPostEvaluate() differs from TSSetPostStep() since the function it sets is called before event-handling 3624 thus guaranteeing the same solution (computed by the time-stepper) will be passed to it. On the other hand, TSPostStep() 3625 may be passed a different solution, possibly changed by the event handler. TSPostEvaluate() is called after the next step 3626 solution is evaluated allowing to modify it, if need be. The solution can be obtained with TSGetSolution(), the time step 3627 with TSGetTimeStep(), and the time at the start of the step is available via TSGetTime() 3628 3629 .keywords: TS, timestep 3630 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3631 @*/ 3632 PetscErrorCode TSSetPostEvaluate(TS ts, PetscErrorCode (*func)(TS)) 3633 { 3634 PetscFunctionBegin; 3635 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3636 ts->postevaluate = func; 3637 PetscFunctionReturn(0); 3638 } 3639 3640 /*@ 3641 TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage() 3642 3643 Collective on TS 3644 3645 Input Parameters: 3646 . ts - The TS context obtained from TSCreate() 3647 stagetime - The absolute time of the current stage 3648 3649 Notes: 3650 TSPreStage() is typically used within time stepping implementations, 3651 most users would not generally call this routine themselves. 3652 3653 Level: developer 3654 3655 .keywords: TS, timestep 3656 .seealso: TSPostStage(), TSSetPreStep(), TSPreStep(), TSPostStep() 3657 @*/ 3658 PetscErrorCode TSPreStage(TS ts, PetscReal stagetime) 3659 { 3660 PetscErrorCode ierr; 3661 3662 PetscFunctionBegin; 3663 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3664 if (ts->prestage) { 3665 PetscStackCallStandard((*ts->prestage),(ts,stagetime)); 3666 } 3667 PetscFunctionReturn(0); 3668 } 3669 3670 /*@ 3671 TSPostStage - Runs the user-defined post-stage function set using TSSetPostStage() 3672 3673 Collective on TS 3674 3675 Input Parameters: 3676 . ts - The TS context obtained from TSCreate() 3677 stagetime - The absolute time of the current stage 3678 stageindex - Stage number 3679 Y - Array of vectors (of size = total number 3680 of stages) with the stage solutions 3681 3682 Notes: 3683 TSPostStage() is typically used within time stepping implementations, 3684 most users would not generally call this routine themselves. 3685 3686 Level: developer 3687 3688 .keywords: TS, timestep 3689 .seealso: TSPreStage(), TSSetPreStep(), TSPreStep(), TSPostStep() 3690 @*/ 3691 PetscErrorCode TSPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y) 3692 { 3693 PetscErrorCode ierr; 3694 3695 PetscFunctionBegin; 3696 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3697 if (ts->poststage) { 3698 PetscStackCallStandard((*ts->poststage),(ts,stagetime,stageindex,Y)); 3699 } 3700 PetscFunctionReturn(0); 3701 } 3702 3703 /*@ 3704 TSPostEvaluate - Runs the user-defined post-evaluate function set using TSSetPostEvaluate() 3705 3706 Collective on TS 3707 3708 Input Parameters: 3709 . ts - The TS context obtained from TSCreate() 3710 3711 Notes: 3712 TSPostEvaluate() is typically used within time stepping implementations, 3713 most users would not generally call this routine themselves. 3714 3715 Level: developer 3716 3717 .keywords: TS, timestep 3718 .seealso: TSSetPostEvaluate(), TSSetPreStep(), TSPreStep(), TSPostStep() 3719 @*/ 3720 PetscErrorCode TSPostEvaluate(TS ts) 3721 { 3722 PetscErrorCode ierr; 3723 3724 PetscFunctionBegin; 3725 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3726 if (ts->postevaluate) { 3727 Vec U; 3728 PetscObjectState sprev,spost; 3729 3730 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3731 ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr); 3732 PetscStackCallStandard((*ts->postevaluate),(ts)); 3733 ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr); 3734 if (sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);} 3735 } 3736 PetscFunctionReturn(0); 3737 } 3738 3739 /*@C 3740 TSSetPostStep - Sets the general-purpose function 3741 called once at the end of each time step. 3742 3743 Logically Collective on TS 3744 3745 Input Parameters: 3746 + ts - The TS context obtained from TSCreate() 3747 - func - The function 3748 3749 Calling sequence of func: 3750 $ func (TS ts); 3751 3752 Notes: 3753 The function set by TSSetPostStep() is called after each successful step. The solution vector X 3754 obtained by TSGetSolution() may be different than that computed at the step end if the event handler 3755 locates an event and TSPostEvent() modifies it. Use TSSetPostEvaluate() if an unmodified solution is needed instead. 3756 3757 Level: intermediate 3758 3759 .keywords: TS, timestep 3760 .seealso: TSSetPreStep(), TSSetPreStage(), TSSetPostEvaluate(), TSGetTimeStep(), TSGetStepNumber(), TSGetTime(), TSRestartStep() 3761 @*/ 3762 PetscErrorCode TSSetPostStep(TS ts, PetscErrorCode (*func)(TS)) 3763 { 3764 PetscFunctionBegin; 3765 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3766 ts->poststep = func; 3767 PetscFunctionReturn(0); 3768 } 3769 3770 /*@ 3771 TSPostStep - Runs the user-defined post-step function. 3772 3773 Collective on TS 3774 3775 Input Parameters: 3776 . ts - The TS context obtained from TSCreate() 3777 3778 Notes: 3779 TSPostStep() is typically used within time stepping implementations, 3780 so most users would not generally call this routine themselves. 3781 3782 Level: developer 3783 3784 .keywords: TS, timestep 3785 @*/ 3786 PetscErrorCode TSPostStep(TS ts) 3787 { 3788 PetscErrorCode ierr; 3789 3790 PetscFunctionBegin; 3791 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3792 if (ts->poststep) { 3793 Vec U; 3794 PetscObjectState sprev,spost; 3795 3796 ierr = TSGetSolution(ts,&U);CHKERRQ(ierr); 3797 ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr); 3798 PetscStackCallStandard((*ts->poststep),(ts)); 3799 ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr); 3800 if (sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);} 3801 } 3802 PetscFunctionReturn(0); 3803 } 3804 3805 /* ------------ Routines to set performance monitoring options ----------- */ 3806 3807 /*@C 3808 TSMonitorSet - Sets an ADDITIONAL function that is to be used at every 3809 timestep to display the iteration's progress. 3810 3811 Logically Collective on TS 3812 3813 Input Parameters: 3814 + ts - the TS context obtained from TSCreate() 3815 . monitor - monitoring routine 3816 . mctx - [optional] user-defined context for private data for the 3817 monitor routine (use NULL if no context is desired) 3818 - monitordestroy - [optional] routine that frees monitor context 3819 (may be NULL) 3820 3821 Calling sequence of monitor: 3822 $ PetscErrorCode monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx) 3823 3824 + ts - the TS context 3825 . 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) 3826 . time - current time 3827 . u - current iterate 3828 - mctx - [optional] monitoring context 3829 3830 Notes: 3831 This routine adds an additional monitor to the list of monitors that 3832 already has been loaded. 3833 3834 Fortran notes: Only a single monitor function can be set for each TS object 3835 3836 Level: intermediate 3837 3838 .keywords: TS, timestep, set, monitor 3839 3840 .seealso: TSMonitorDefault(), TSMonitorCancel() 3841 @*/ 3842 PetscErrorCode TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**)) 3843 { 3844 PetscErrorCode ierr; 3845 PetscInt i; 3846 PetscBool identical; 3847 3848 PetscFunctionBegin; 3849 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3850 for (i=0; i<ts->numbermonitors;i++) { 3851 ierr = PetscMonitorCompare((PetscErrorCode (*)(void))monitor,mctx,mdestroy,(PetscErrorCode (*)(void))ts->monitor[i],ts->monitorcontext[i],ts->monitordestroy[i],&identical);CHKERRQ(ierr); 3852 if (identical) PetscFunctionReturn(0); 3853 } 3854 if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3855 ts->monitor[ts->numbermonitors] = monitor; 3856 ts->monitordestroy[ts->numbermonitors] = mdestroy; 3857 ts->monitorcontext[ts->numbermonitors++] = (void*)mctx; 3858 PetscFunctionReturn(0); 3859 } 3860 3861 /*@C 3862 TSMonitorCancel - Clears all the monitors that have been set on a time-step object. 3863 3864 Logically Collective on TS 3865 3866 Input Parameters: 3867 . ts - the TS context obtained from TSCreate() 3868 3869 Notes: 3870 There is no way to remove a single, specific monitor. 3871 3872 Level: intermediate 3873 3874 .keywords: TS, timestep, set, monitor 3875 3876 .seealso: TSMonitorDefault(), TSMonitorSet() 3877 @*/ 3878 PetscErrorCode TSMonitorCancel(TS ts) 3879 { 3880 PetscErrorCode ierr; 3881 PetscInt i; 3882 3883 PetscFunctionBegin; 3884 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3885 for (i=0; i<ts->numbermonitors; i++) { 3886 if (ts->monitordestroy[i]) { 3887 ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr); 3888 } 3889 } 3890 ts->numbermonitors = 0; 3891 PetscFunctionReturn(0); 3892 } 3893 3894 /*@C 3895 TSMonitorDefault - The Default monitor, prints the timestep and time for each step 3896 3897 Level: intermediate 3898 3899 .keywords: TS, set, monitor 3900 3901 .seealso: TSMonitorSet() 3902 @*/ 3903 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf) 3904 { 3905 PetscErrorCode ierr; 3906 PetscViewer viewer = vf->viewer; 3907 PetscBool iascii,ibinary; 3908 3909 PetscFunctionBegin; 3910 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 3911 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 3912 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 3913 ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr); 3914 if (iascii) { 3915 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3916 if (step == -1){ /* this indicates it is an interpolated solution */ 3917 ierr = PetscViewerASCIIPrintf(viewer,"Interpolated solution at time %g between steps %D and %D\n",(double)ptime,ts->steps-1,ts->steps);CHKERRQ(ierr); 3918 } else { 3919 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr); 3920 } 3921 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3922 } else if (ibinary) { 3923 PetscMPIInt rank; 3924 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 3925 if (!rank) { 3926 PetscBool skipHeader; 3927 PetscInt classid = REAL_FILE_CLASSID; 3928 3929 ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr); 3930 if (!skipHeader) { 3931 ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 3932 } 3933 ierr = PetscRealView(1,&ptime,viewer);CHKERRQ(ierr); 3934 } else { 3935 ierr = PetscRealView(0,&ptime,viewer);CHKERRQ(ierr); 3936 } 3937 } 3938 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 3939 PetscFunctionReturn(0); 3940 } 3941 3942 /*@C 3943 TSAdjointMonitorSet - Sets an ADDITIONAL function that is to be used at every 3944 timestep to display the iteration's progress. 3945 3946 Logically Collective on TS 3947 3948 Input Parameters: 3949 + ts - the TS context obtained from TSCreate() 3950 . adjointmonitor - monitoring routine 3951 . adjointmctx - [optional] user-defined context for private data for the 3952 monitor routine (use NULL if no context is desired) 3953 - adjointmonitordestroy - [optional] routine that frees monitor context 3954 (may be NULL) 3955 3956 Calling sequence of monitor: 3957 $ int adjointmonitor(TS ts,PetscInt steps,PetscReal time,Vec u,PetscInt numcost,Vec *lambda, Vec *mu,void *adjointmctx) 3958 3959 + ts - the TS context 3960 . 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 3961 been interpolated to) 3962 . time - current time 3963 . u - current iterate 3964 . numcost - number of cost functionos 3965 . lambda - sensitivities to initial conditions 3966 . mu - sensitivities to parameters 3967 - adjointmctx - [optional] adjoint monitoring context 3968 3969 Notes: 3970 This routine adds an additional monitor to the list of monitors that 3971 already has been loaded. 3972 3973 Fortran notes: Only a single monitor function can be set for each TS object 3974 3975 Level: intermediate 3976 3977 .keywords: TS, timestep, set, adjoint, monitor 3978 3979 .seealso: TSAdjointMonitorCancel() 3980 @*/ 3981 PetscErrorCode TSAdjointMonitorSet(TS ts,PetscErrorCode (*adjointmonitor)(TS,PetscInt,PetscReal,Vec,PetscInt,Vec*,Vec*,void*),void *adjointmctx,PetscErrorCode (*adjointmdestroy)(void**)) 3982 { 3983 PetscErrorCode ierr; 3984 PetscInt i; 3985 PetscBool identical; 3986 3987 PetscFunctionBegin; 3988 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3989 for (i=0; i<ts->numbermonitors;i++) { 3990 ierr = PetscMonitorCompare((PetscErrorCode (*)(void))adjointmonitor,adjointmctx,adjointmdestroy,(PetscErrorCode (*)(void))ts->adjointmonitor[i],ts->adjointmonitorcontext[i],ts->adjointmonitordestroy[i],&identical);CHKERRQ(ierr); 3991 if (identical) PetscFunctionReturn(0); 3992 } 3993 if (ts->numberadjointmonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many adjoint monitors set"); 3994 ts->adjointmonitor[ts->numberadjointmonitors] = adjointmonitor; 3995 ts->adjointmonitordestroy[ts->numberadjointmonitors] = adjointmdestroy; 3996 ts->adjointmonitorcontext[ts->numberadjointmonitors++] = (void*)adjointmctx; 3997 PetscFunctionReturn(0); 3998 } 3999 4000 /*@C 4001 TSAdjointMonitorCancel - Clears all the adjoint monitors that have been set on a time-step object. 4002 4003 Logically Collective on TS 4004 4005 Input Parameters: 4006 . ts - the TS context obtained from TSCreate() 4007 4008 Notes: 4009 There is no way to remove a single, specific monitor. 4010 4011 Level: intermediate 4012 4013 .keywords: TS, timestep, set, adjoint, monitor 4014 4015 .seealso: TSAdjointMonitorSet() 4016 @*/ 4017 PetscErrorCode TSAdjointMonitorCancel(TS ts) 4018 { 4019 PetscErrorCode ierr; 4020 PetscInt i; 4021 4022 PetscFunctionBegin; 4023 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4024 for (i=0; i<ts->numberadjointmonitors; i++) { 4025 if (ts->adjointmonitordestroy[i]) { 4026 ierr = (*ts->adjointmonitordestroy[i])(&ts->adjointmonitorcontext[i]);CHKERRQ(ierr); 4027 } 4028 } 4029 ts->numberadjointmonitors = 0; 4030 PetscFunctionReturn(0); 4031 } 4032 4033 /*@C 4034 TSAdjointMonitorDefault - the default monitor of adjoint computations 4035 4036 Level: intermediate 4037 4038 .keywords: TS, set, monitor 4039 4040 .seealso: TSAdjointMonitorSet() 4041 @*/ 4042 PetscErrorCode TSAdjointMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscInt numcost,Vec *lambda,Vec *mu,PetscViewerAndFormat *vf) 4043 { 4044 PetscErrorCode ierr; 4045 PetscViewer viewer = vf->viewer; 4046 4047 PetscFunctionBegin; 4048 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 4049 ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr); 4050 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 4051 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr); 4052 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 4053 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 4054 PetscFunctionReturn(0); 4055 } 4056 4057 /*@ 4058 TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval 4059 4060 Collective on TS 4061 4062 Input Argument: 4063 + ts - time stepping context 4064 - t - time to interpolate to 4065 4066 Output Argument: 4067 . U - state at given time 4068 4069 Level: intermediate 4070 4071 Developer Notes: 4072 TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints. 4073 4074 .keywords: TS, set 4075 4076 .seealso: TSSetExactFinalTime(), TSSolve() 4077 @*/ 4078 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U) 4079 { 4080 PetscErrorCode ierr; 4081 4082 PetscFunctionBegin; 4083 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4084 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 4085 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); 4086 if (!ts->ops->interpolate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name); 4087 ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr); 4088 PetscFunctionReturn(0); 4089 } 4090 4091 /*@ 4092 TSStep - Steps one time step 4093 4094 Collective on TS 4095 4096 Input Parameter: 4097 . ts - the TS context obtained from TSCreate() 4098 4099 Level: developer 4100 4101 Notes: 4102 The public interface for the ODE/DAE solvers is TSSolve(), you should almost for sure be using that routine and not this routine. 4103 4104 The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may 4105 be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages. 4106 4107 This may over-step the final time provided in TSSetMaxTime() depending on the time-step used. TSSolve() interpolates to exactly the 4108 time provided in TSSetMaxTime(). One can use TSInterpolate() to determine an interpolated solution within the final timestep. 4109 4110 .keywords: TS, timestep, solve 4111 4112 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSInterpolate() 4113 @*/ 4114 PetscErrorCode TSStep(TS ts) 4115 { 4116 PetscErrorCode ierr; 4117 static PetscBool cite = PETSC_FALSE; 4118 PetscReal ptime; 4119 4120 PetscFunctionBegin; 4121 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4122 ierr = PetscCitationsRegister("@techreport{tspaper,\n" 4123 " title = {{PETSc/TS}: A Modern Scalable {DAE/ODE} Solver Library},\n" 4124 " author = {Shrirang Abhyankar and Jed Brown and Emil Constantinescu and Debojyoti Ghosh and Barry F. Smith},\n" 4125 " type = {Preprint},\n" 4126 " number = {ANL/MCS-P5061-0114},\n" 4127 " institution = {Argonne National Laboratory},\n" 4128 " year = {2014}\n}\n",&cite);CHKERRQ(ierr); 4129 4130 ierr = TSSetUp(ts);CHKERRQ(ierr); 4131 ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr); 4132 4133 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>"); 4134 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()"); 4135 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"); 4136 4137 if (!ts->steps) ts->ptime_prev = ts->ptime; 4138 ptime = ts->ptime; ts->ptime_prev_rollback = ts->ptime_prev; 4139 ts->reason = TS_CONVERGED_ITERATING; 4140 if (!ts->ops->step) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSStep not implemented for type '%s'",((PetscObject)ts)->type_name); 4141 ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr); 4142 ierr = (*ts->ops->step)(ts);CHKERRQ(ierr); 4143 ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr); 4144 ts->ptime_prev = ptime; 4145 ts->steps++; 4146 ts->steprollback = PETSC_FALSE; 4147 ts->steprestart = PETSC_FALSE; 4148 4149 if (ts->reason < 0) { 4150 if (ts->errorifstepfailed) { 4151 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]); 4152 else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]); 4153 } 4154 } else if (!ts->reason) { 4155 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 4156 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 4157 } 4158 PetscFunctionReturn(0); 4159 } 4160 4161 /*@ 4162 TSAdjointStep - Steps one time step backward in the adjoint run 4163 4164 Collective on TS 4165 4166 Input Parameter: 4167 . ts - the TS context obtained from TSCreate() 4168 4169 Level: intermediate 4170 4171 .keywords: TS, adjoint, step 4172 4173 .seealso: TSAdjointSetUp(), TSAdjointSolve() 4174 @*/ 4175 PetscErrorCode TSAdjointStep(TS ts) 4176 { 4177 DM dm; 4178 PetscErrorCode ierr; 4179 4180 PetscFunctionBegin; 4181 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4182 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4183 ierr = TSAdjointSetUp(ts);CHKERRQ(ierr); 4184 4185 ierr = VecViewFromOptions(ts->vec_sol,(PetscObject)ts,"-ts_view_solution");CHKERRQ(ierr); 4186 4187 ts->reason = TS_CONVERGED_ITERATING; 4188 ts->ptime_prev = ts->ptime; 4189 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); 4190 ierr = PetscLogEventBegin(TS_AdjointStep,ts,0,0,0);CHKERRQ(ierr); 4191 ierr = (*ts->ops->adjointstep)(ts);CHKERRQ(ierr); 4192 ierr = PetscLogEventEnd(TS_AdjointStep,ts,0,0,0);CHKERRQ(ierr); 4193 ts->adjoint_steps++; ts->steps--; 4194 4195 if (ts->reason < 0) { 4196 if (ts->errorifstepfailed) { 4197 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]); 4198 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]); 4199 else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]); 4200 } 4201 } else if (!ts->reason) { 4202 if (ts->adjoint_steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS; 4203 } 4204 PetscFunctionReturn(0); 4205 } 4206 4207 /*@ 4208 TSEvaluateWLTE - Evaluate the weighted local truncation error norm 4209 at the end of a time step with a given order of accuracy. 4210 4211 Collective on TS 4212 4213 Input Arguments: 4214 + ts - time stepping context 4215 . wnormtype - norm type, either NORM_2 or NORM_INFINITY 4216 - order - optional, desired order for the error evaluation or PETSC_DECIDE 4217 4218 Output Arguments: 4219 + order - optional, the actual order of the error evaluation 4220 - wlte - the weighted local truncation error norm 4221 4222 Level: advanced 4223 4224 Notes: 4225 If the timestepper cannot evaluate the error in a particular step 4226 (eg. in the first step or restart steps after event handling), 4227 this routine returns wlte=-1.0 . 4228 4229 .seealso: TSStep(), TSAdapt, TSErrorWeightedNorm() 4230 @*/ 4231 PetscErrorCode TSEvaluateWLTE(TS ts,NormType wnormtype,PetscInt *order,PetscReal *wlte) 4232 { 4233 PetscErrorCode ierr; 4234 4235 PetscFunctionBegin; 4236 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4237 PetscValidType(ts,1); 4238 PetscValidLogicalCollectiveEnum(ts,wnormtype,4); 4239 if (order) PetscValidIntPointer(order,3); 4240 if (order) PetscValidLogicalCollectiveInt(ts,*order,3); 4241 PetscValidRealPointer(wlte,4); 4242 if (wnormtype != NORM_2 && wnormtype != NORM_INFINITY) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 4243 if (!ts->ops->evaluatewlte) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateWLTE not implemented for type '%s'",((PetscObject)ts)->type_name); 4244 ierr = (*ts->ops->evaluatewlte)(ts,wnormtype,order,wlte);CHKERRQ(ierr); 4245 PetscFunctionReturn(0); 4246 } 4247 4248 /*@ 4249 TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy. 4250 4251 Collective on TS 4252 4253 Input Arguments: 4254 + ts - time stepping context 4255 . order - desired order of accuracy 4256 - done - whether the step was evaluated at this order (pass NULL to generate an error if not available) 4257 4258 Output Arguments: 4259 . U - state at the end of the current step 4260 4261 Level: advanced 4262 4263 Notes: 4264 This function cannot be called until all stages have been evaluated. 4265 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. 4266 4267 .seealso: TSStep(), TSAdapt 4268 @*/ 4269 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done) 4270 { 4271 PetscErrorCode ierr; 4272 4273 PetscFunctionBegin; 4274 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4275 PetscValidType(ts,1); 4276 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 4277 if (!ts->ops->evaluatestep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name); 4278 ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr); 4279 PetscFunctionReturn(0); 4280 } 4281 4282 /*@ 4283 TSForwardCostIntegral - Evaluate the cost integral in the forward run. 4284 4285 Collective on TS 4286 4287 Input Arguments: 4288 . ts - time stepping context 4289 4290 Level: advanced 4291 4292 Notes: 4293 This function cannot be called until TSStep() has been completed. 4294 4295 .seealso: TSSolve(), TSAdjointCostIntegral() 4296 @*/ 4297 PetscErrorCode TSForwardCostIntegral(TS ts) 4298 { 4299 PetscErrorCode ierr; 4300 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4301 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); 4302 ierr = (*ts->ops->forwardintegral)(ts);CHKERRQ(ierr); 4303 PetscFunctionReturn(0); 4304 } 4305 4306 /*@ 4307 TSSolve - Steps the requested number of timesteps. 4308 4309 Collective on TS 4310 4311 Input Parameter: 4312 + ts - the TS context obtained from TSCreate() 4313 - u - the solution vector (can be null if TSSetSolution() was used and TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP) was not used, 4314 otherwise must contain the initial conditions and will contain the solution at the final requested time 4315 4316 Level: beginner 4317 4318 Notes: 4319 The final time returned by this function may be different from the time of the internally 4320 held state accessible by TSGetSolution() and TSGetTime() because the method may have 4321 stepped over the final time. 4322 4323 .keywords: TS, timestep, solve 4324 4325 .seealso: TSCreate(), TSSetSolution(), TSStep(), TSGetTime(), TSGetSolveTime() 4326 @*/ 4327 PetscErrorCode TSSolve(TS ts,Vec u) 4328 { 4329 Vec solution; 4330 PetscErrorCode ierr; 4331 4332 PetscFunctionBegin; 4333 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4334 if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2); 4335 4336 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 */ 4337 if (!ts->vec_sol || u == ts->vec_sol) { 4338 ierr = VecDuplicate(u,&solution);CHKERRQ(ierr); 4339 ierr = TSSetSolution(ts,solution);CHKERRQ(ierr); 4340 ierr = VecDestroy(&solution);CHKERRQ(ierr); /* grant ownership */ 4341 } 4342 ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr); 4343 if (ts->forward_solve) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Sensitivity analysis does not support the mode TS_EXACTFINALTIME_INTERPOLATE"); 4344 } else if (u) { 4345 ierr = TSSetSolution(ts,u);CHKERRQ(ierr); 4346 } 4347 ierr = TSSetUp(ts);CHKERRQ(ierr); 4348 ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr); 4349 4350 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>"); 4351 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()"); 4352 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"); 4353 4354 if (ts->forward_solve) { 4355 ierr = TSForwardSetUp(ts);CHKERRQ(ierr); 4356 } 4357 4358 /* reset number of steps only when the step is not restarted. ARKIMEX 4359 restarts the step after an event. Resetting these counters in such case causes 4360 TSTrajectory to incorrectly save the output files 4361 */ 4362 /* reset time step and iteration counters */ 4363 if (!ts->steps) { 4364 ts->ksp_its = 0; 4365 ts->snes_its = 0; 4366 ts->num_snes_failures = 0; 4367 ts->reject = 0; 4368 ts->steprestart = PETSC_TRUE; 4369 ts->steprollback = PETSC_FALSE; 4370 } 4371 if (ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP && ts->ptime + ts->time_step > ts->max_time) ts->time_step = ts->max_time - ts->ptime; 4372 ts->reason = TS_CONVERGED_ITERATING; 4373 4374 ierr = TSViewFromOptions(ts,NULL,"-ts_view_pre");CHKERRQ(ierr); 4375 4376 if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */ 4377 ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr); 4378 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 4379 ts->solvetime = ts->ptime; 4380 solution = ts->vec_sol; 4381 } else { /* Step the requested number of timesteps. */ 4382 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 4383 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 4384 4385 if (!ts->steps) { 4386 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4387 ierr = TSEventInitialize(ts->event,ts,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4388 } 4389 4390 while (!ts->reason) { 4391 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4392 if (!ts->steprollback) { 4393 ierr = TSPreStep(ts);CHKERRQ(ierr); 4394 } 4395 ierr = TSStep(ts);CHKERRQ(ierr); 4396 if (ts->vec_costintegral && ts->costintegralfwd) { /* Must evaluate the cost integral before event is handled. The cost integral value can also be rolled back. */ 4397 ierr = TSForwardCostIntegral(ts);CHKERRQ(ierr); 4398 } 4399 if (ts->forward_solve) { /* compute forward sensitivities before event handling because postevent() may change RHS and jump conditions may have to be applied */ 4400 ierr = TSForwardStep(ts);CHKERRQ(ierr); 4401 } 4402 ierr = TSPostEvaluate(ts);CHKERRQ(ierr); 4403 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. */ 4404 if (ts->steprollback) { 4405 ierr = TSPostEvaluate(ts);CHKERRQ(ierr); 4406 } 4407 if (!ts->steprollback) { 4408 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4409 ierr = TSPostStep(ts);CHKERRQ(ierr); 4410 } 4411 } 4412 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4413 4414 if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) { 4415 ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr); 4416 ts->solvetime = ts->max_time; 4417 solution = u; 4418 ierr = TSMonitor(ts,-1,ts->solvetime,solution);CHKERRQ(ierr); 4419 } else { 4420 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 4421 ts->solvetime = ts->ptime; 4422 solution = ts->vec_sol; 4423 } 4424 } 4425 4426 ierr = TSViewFromOptions(ts,NULL,"-ts_view");CHKERRQ(ierr); 4427 ierr = VecViewFromOptions(solution,NULL,"-ts_view_solution");CHKERRQ(ierr); 4428 ierr = PetscObjectSAWsBlock((PetscObject)ts);CHKERRQ(ierr); 4429 if (ts->adjoint_solve) { 4430 ierr = TSAdjointSolve(ts);CHKERRQ(ierr); 4431 } 4432 PetscFunctionReturn(0); 4433 } 4434 4435 /*@ 4436 TSAdjointCostIntegral - Evaluate the cost integral in the adjoint run. 4437 4438 Collective on TS 4439 4440 Input Arguments: 4441 . ts - time stepping context 4442 4443 Level: advanced 4444 4445 Notes: 4446 This function cannot be called until TSAdjointStep() has been completed. 4447 4448 .seealso: TSAdjointSolve(), TSAdjointStep 4449 @*/ 4450 PetscErrorCode TSAdjointCostIntegral(TS ts) 4451 { 4452 PetscErrorCode ierr; 4453 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4454 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); 4455 ierr = (*ts->ops->adjointintegral)(ts);CHKERRQ(ierr); 4456 PetscFunctionReturn(0); 4457 } 4458 4459 /*@ 4460 TSAdjointSolve - Solves the discrete ajoint problem for an ODE/DAE 4461 4462 Collective on TS 4463 4464 Input Parameter: 4465 . ts - the TS context obtained from TSCreate() 4466 4467 Options Database: 4468 . -ts_adjoint_view_solution <viewerinfo> - views the first gradient with respect to the initial values 4469 4470 Level: intermediate 4471 4472 Notes: 4473 This must be called after a call to TSSolve() that solves the forward problem 4474 4475 By default this will integrate back to the initial time, one can use TSAdjointSetSteps() to step back to a later time 4476 4477 .keywords: TS, timestep, solve 4478 4479 .seealso: TSCreate(), TSSetCostGradients(), TSSetSolution(), TSAdjointStep() 4480 @*/ 4481 PetscErrorCode TSAdjointSolve(TS ts) 4482 { 4483 PetscErrorCode ierr; 4484 4485 PetscFunctionBegin; 4486 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4487 ierr = TSAdjointSetUp(ts);CHKERRQ(ierr); 4488 4489 /* reset time step and iteration counters */ 4490 ts->adjoint_steps = 0; 4491 ts->ksp_its = 0; 4492 ts->snes_its = 0; 4493 ts->num_snes_failures = 0; 4494 ts->reject = 0; 4495 ts->reason = TS_CONVERGED_ITERATING; 4496 4497 if (!ts->adjoint_max_steps) ts->adjoint_max_steps = ts->steps; 4498 if (ts->adjoint_steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS; 4499 4500 while (!ts->reason) { 4501 ierr = TSTrajectoryGet(ts->trajectory,ts,ts->steps,&ts->ptime);CHKERRQ(ierr); 4502 ierr = TSAdjointMonitor(ts,ts->steps,ts->ptime,ts->vec_sol,ts->numcost,ts->vecs_sensi,ts->vecs_sensip);CHKERRQ(ierr); 4503 ierr = TSAdjointEventHandler(ts);CHKERRQ(ierr); 4504 ierr = TSAdjointStep(ts);CHKERRQ(ierr); 4505 if (ts->vec_costintegral && !ts->costintegralfwd) { 4506 ierr = TSAdjointCostIntegral(ts);CHKERRQ(ierr); 4507 } 4508 } 4509 ierr = TSTrajectoryGet(ts->trajectory,ts,ts->steps,&ts->ptime);CHKERRQ(ierr); 4510 ierr = TSAdjointMonitor(ts,ts->steps,ts->ptime,ts->vec_sol,ts->numcost,ts->vecs_sensi,ts->vecs_sensip);CHKERRQ(ierr); 4511 ts->solvetime = ts->ptime; 4512 ierr = TSTrajectoryViewFromOptions(ts->trajectory,NULL,"-ts_trajectory_view");CHKERRQ(ierr); 4513 ierr = VecViewFromOptions(ts->vecs_sensi[0],(PetscObject) ts, "-ts_adjoint_view_solution");CHKERRQ(ierr); 4514 ts->adjoint_max_steps = 0; 4515 PetscFunctionReturn(0); 4516 } 4517 4518 /*@C 4519 TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet() 4520 4521 Collective on TS 4522 4523 Input Parameters: 4524 + ts - time stepping context obtained from TSCreate() 4525 . step - step number that has just completed 4526 . ptime - model time of the state 4527 - u - state at the current model time 4528 4529 Notes: 4530 TSMonitor() is typically used automatically within the time stepping implementations. 4531 Users would almost never call this routine directly. 4532 4533 A step of -1 indicates that the monitor is being called on a solution obtained by interpolating from computed solutions 4534 4535 Level: developer 4536 4537 .keywords: TS, timestep 4538 @*/ 4539 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u) 4540 { 4541 DM dm; 4542 PetscInt i,n = ts->numbermonitors; 4543 PetscErrorCode ierr; 4544 4545 PetscFunctionBegin; 4546 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4547 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 4548 4549 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4550 ierr = DMSetOutputSequenceNumber(dm,step,ptime);CHKERRQ(ierr); 4551 4552 ierr = VecLockPush(u);CHKERRQ(ierr); 4553 for (i=0; i<n; i++) { 4554 ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr); 4555 } 4556 ierr = VecLockPop(u);CHKERRQ(ierr); 4557 PetscFunctionReturn(0); 4558 } 4559 4560 /*@C 4561 TSAdjointMonitor - Runs all user-provided adjoint monitor routines set using TSAdjointMonitorSet() 4562 4563 Collective on TS 4564 4565 Input Parameters: 4566 + ts - time stepping context obtained from TSCreate() 4567 . step - step number that has just completed 4568 . ptime - model time of the state 4569 . u - state at the current model time 4570 . numcost - number of cost functions (dimension of lambda or mu) 4571 . lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables 4572 - mu - vectors containing the gradients of the cost functions with respect to the problem parameters 4573 4574 Notes: 4575 TSAdjointMonitor() is typically used automatically within the time stepping implementations. 4576 Users would almost never call this routine directly. 4577 4578 Level: developer 4579 4580 .keywords: TS, timestep 4581 @*/ 4582 PetscErrorCode TSAdjointMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda, Vec *mu) 4583 { 4584 PetscErrorCode ierr; 4585 PetscInt i,n = ts->numberadjointmonitors; 4586 4587 PetscFunctionBegin; 4588 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4589 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 4590 ierr = VecLockPush(u);CHKERRQ(ierr); 4591 for (i=0; i<n; i++) { 4592 ierr = (*ts->adjointmonitor[i])(ts,step,ptime,u,numcost,lambda,mu,ts->adjointmonitorcontext[i]);CHKERRQ(ierr); 4593 } 4594 ierr = VecLockPop(u);CHKERRQ(ierr); 4595 PetscFunctionReturn(0); 4596 } 4597 4598 /* ------------------------------------------------------------------------*/ 4599 /*@C 4600 TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with 4601 TS to monitor the solution process graphically in various ways 4602 4603 Collective on TS 4604 4605 Input Parameters: 4606 + host - the X display to open, or null for the local machine 4607 . label - the title to put in the title bar 4608 . x, y - the screen coordinates of the upper left coordinate of the window 4609 . m, n - the screen width and height in pixels 4610 - howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time 4611 4612 Output Parameter: 4613 . ctx - the context 4614 4615 Options Database Key: 4616 + -ts_monitor_lg_timestep - automatically sets line graph monitor 4617 + -ts_monitor_lg_timestep_log - automatically sets line graph monitor 4618 . -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables()) 4619 . -ts_monitor_lg_error - monitor the error 4620 . -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep 4621 . -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep 4622 - -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true 4623 4624 Notes: 4625 Use TSMonitorLGCtxDestroy() to destroy. 4626 4627 One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform() 4628 4629 Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a TS object as the 4630 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 4631 as the first argument. 4632 4633 One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames() 4634 4635 Level: intermediate 4636 4637 .keywords: TS, monitor, line graph, residual 4638 4639 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError(), TSMonitorDefault(), VecView(), 4640 TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(), 4641 TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(), 4642 TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(), 4643 TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop() 4644 4645 @*/ 4646 PetscErrorCode TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx) 4647 { 4648 PetscDraw draw; 4649 PetscErrorCode ierr; 4650 4651 PetscFunctionBegin; 4652 ierr = PetscNew(ctx);CHKERRQ(ierr); 4653 ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr); 4654 ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr); 4655 ierr = PetscDrawLGCreate(draw,1,&(*ctx)->lg);CHKERRQ(ierr); 4656 ierr = PetscDrawLGSetFromOptions((*ctx)->lg);CHKERRQ(ierr); 4657 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 4658 (*ctx)->howoften = howoften; 4659 PetscFunctionReturn(0); 4660 } 4661 4662 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx) 4663 { 4664 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 4665 PetscReal x = ptime,y; 4666 PetscErrorCode ierr; 4667 4668 PetscFunctionBegin; 4669 if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */ 4670 if (!step) { 4671 PetscDrawAxis axis; 4672 const char *ylabel = ctx->semilogy ? "Log Time Step" : "Time Step"; 4673 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 4674 ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time",ylabel);CHKERRQ(ierr); 4675 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 4676 } 4677 ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr); 4678 if (ctx->semilogy) y = PetscLog10Real(y); 4679 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 4680 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 4681 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 4682 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 4683 } 4684 PetscFunctionReturn(0); 4685 } 4686 4687 /*@C 4688 TSMonitorLGCtxDestroy - Destroys a line graph context that was created 4689 with TSMonitorLGCtxCreate(). 4690 4691 Collective on TSMonitorLGCtx 4692 4693 Input Parameter: 4694 . ctx - the monitor context 4695 4696 Level: intermediate 4697 4698 .keywords: TS, monitor, line graph, destroy 4699 4700 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep(); 4701 @*/ 4702 PetscErrorCode TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx) 4703 { 4704 PetscErrorCode ierr; 4705 4706 PetscFunctionBegin; 4707 if ((*ctx)->transformdestroy) { 4708 ierr = ((*ctx)->transformdestroy)((*ctx)->transformctx);CHKERRQ(ierr); 4709 } 4710 ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr); 4711 ierr = PetscStrArrayDestroy(&(*ctx)->names);CHKERRQ(ierr); 4712 ierr = PetscStrArrayDestroy(&(*ctx)->displaynames);CHKERRQ(ierr); 4713 ierr = PetscFree((*ctx)->displayvariables);CHKERRQ(ierr); 4714 ierr = PetscFree((*ctx)->displayvalues);CHKERRQ(ierr); 4715 ierr = PetscFree(*ctx);CHKERRQ(ierr); 4716 PetscFunctionReturn(0); 4717 } 4718 4719 /*@ 4720 TSGetTime - Gets the time of the most recently completed step. 4721 4722 Not Collective 4723 4724 Input Parameter: 4725 . ts - the TS context obtained from TSCreate() 4726 4727 Output Parameter: 4728 . t - the current time. This time may not corresponds to the final time set with TSSetMaxTime(), use TSGetSolveTime(). 4729 4730 Level: beginner 4731 4732 Note: 4733 When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(), 4734 TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated. 4735 4736 .seealso: TSGetSolveTime(), TSSetTime(), TSGetTimeStep() 4737 4738 .keywords: TS, get, time 4739 @*/ 4740 PetscErrorCode TSGetTime(TS ts,PetscReal *t) 4741 { 4742 PetscFunctionBegin; 4743 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4744 PetscValidRealPointer(t,2); 4745 *t = ts->ptime; 4746 PetscFunctionReturn(0); 4747 } 4748 4749 /*@ 4750 TSGetPrevTime - Gets the starting time of the previously completed step. 4751 4752 Not Collective 4753 4754 Input Parameter: 4755 . ts - the TS context obtained from TSCreate() 4756 4757 Output Parameter: 4758 . t - the previous time 4759 4760 Level: beginner 4761 4762 .seealso: TSGetTime(), TSGetSolveTime(), TSGetTimeStep() 4763 4764 .keywords: TS, get, time 4765 @*/ 4766 PetscErrorCode TSGetPrevTime(TS ts,PetscReal *t) 4767 { 4768 PetscFunctionBegin; 4769 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4770 PetscValidRealPointer(t,2); 4771 *t = ts->ptime_prev; 4772 PetscFunctionReturn(0); 4773 } 4774 4775 /*@ 4776 TSSetTime - Allows one to reset the time. 4777 4778 Logically Collective on TS 4779 4780 Input Parameters: 4781 + ts - the TS context obtained from TSCreate() 4782 - time - the time 4783 4784 Level: intermediate 4785 4786 .seealso: TSGetTime(), TSSetMaxSteps() 4787 4788 .keywords: TS, set, time 4789 @*/ 4790 PetscErrorCode TSSetTime(TS ts, PetscReal t) 4791 { 4792 PetscFunctionBegin; 4793 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4794 PetscValidLogicalCollectiveReal(ts,t,2); 4795 ts->ptime = t; 4796 PetscFunctionReturn(0); 4797 } 4798 4799 /*@C 4800 TSSetOptionsPrefix - Sets the prefix used for searching for all 4801 TS options in the database. 4802 4803 Logically Collective on TS 4804 4805 Input Parameter: 4806 + ts - The TS context 4807 - prefix - The prefix to prepend to all option names 4808 4809 Notes: 4810 A hyphen (-) must NOT be given at the beginning of the prefix name. 4811 The first character of all runtime options is AUTOMATICALLY the 4812 hyphen. 4813 4814 Level: advanced 4815 4816 .keywords: TS, set, options, prefix, database 4817 4818 .seealso: TSSetFromOptions() 4819 4820 @*/ 4821 PetscErrorCode TSSetOptionsPrefix(TS ts,const char prefix[]) 4822 { 4823 PetscErrorCode ierr; 4824 SNES snes; 4825 4826 PetscFunctionBegin; 4827 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4828 ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4829 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4830 ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4831 PetscFunctionReturn(0); 4832 } 4833 4834 /*@C 4835 TSAppendOptionsPrefix - Appends to the prefix used for searching for all 4836 TS options in the database. 4837 4838 Logically Collective on TS 4839 4840 Input Parameter: 4841 + ts - The TS context 4842 - prefix - The prefix to prepend to all option names 4843 4844 Notes: 4845 A hyphen (-) must NOT be given at the beginning of the prefix name. 4846 The first character of all runtime options is AUTOMATICALLY the 4847 hyphen. 4848 4849 Level: advanced 4850 4851 .keywords: TS, append, options, prefix, database 4852 4853 .seealso: TSGetOptionsPrefix() 4854 4855 @*/ 4856 PetscErrorCode TSAppendOptionsPrefix(TS ts,const char prefix[]) 4857 { 4858 PetscErrorCode ierr; 4859 SNES snes; 4860 4861 PetscFunctionBegin; 4862 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4863 ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4864 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4865 ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4866 PetscFunctionReturn(0); 4867 } 4868 4869 /*@C 4870 TSGetOptionsPrefix - Sets the prefix used for searching for all 4871 TS options in the database. 4872 4873 Not Collective 4874 4875 Input Parameter: 4876 . ts - The TS context 4877 4878 Output Parameter: 4879 . prefix - A pointer to the prefix string used 4880 4881 Notes: On the fortran side, the user should pass in a string 'prifix' of 4882 sufficient length to hold the prefix. 4883 4884 Level: intermediate 4885 4886 .keywords: TS, get, options, prefix, database 4887 4888 .seealso: TSAppendOptionsPrefix() 4889 @*/ 4890 PetscErrorCode TSGetOptionsPrefix(TS ts,const char *prefix[]) 4891 { 4892 PetscErrorCode ierr; 4893 4894 PetscFunctionBegin; 4895 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4896 PetscValidPointer(prefix,2); 4897 ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4898 PetscFunctionReturn(0); 4899 } 4900 4901 /*@C 4902 TSGetRHSJacobian - Returns the Jacobian J at the present timestep. 4903 4904 Not Collective, but parallel objects are returned if TS is parallel 4905 4906 Input Parameter: 4907 . ts - The TS context obtained from TSCreate() 4908 4909 Output Parameters: 4910 + Amat - The (approximate) Jacobian J of G, where U_t = G(U,t) (or NULL) 4911 . Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat (or NULL) 4912 . func - Function to compute the Jacobian of the RHS (or NULL) 4913 - ctx - User-defined context for Jacobian evaluation routine (or NULL) 4914 4915 Notes: You can pass in NULL for any return argument you do not need. 4916 4917 Level: intermediate 4918 4919 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetStepNumber() 4920 4921 .keywords: TS, timestep, get, matrix, Jacobian 4922 @*/ 4923 PetscErrorCode TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx) 4924 { 4925 PetscErrorCode ierr; 4926 DM dm; 4927 4928 PetscFunctionBegin; 4929 if (Amat || Pmat) { 4930 SNES snes; 4931 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4932 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4933 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4934 } 4935 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4936 ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr); 4937 PetscFunctionReturn(0); 4938 } 4939 4940 /*@C 4941 TSGetIJacobian - Returns the implicit Jacobian at the present timestep. 4942 4943 Not Collective, but parallel objects are returned if TS is parallel 4944 4945 Input Parameter: 4946 . ts - The TS context obtained from TSCreate() 4947 4948 Output Parameters: 4949 + Amat - The (approximate) Jacobian of F(t,U,U_t) 4950 . Pmat - The matrix from which the preconditioner is constructed, often the same as Amat 4951 . f - The function to compute the matrices 4952 - ctx - User-defined context for Jacobian evaluation routine 4953 4954 Notes: You can pass in NULL for any return argument you do not need. 4955 4956 Level: advanced 4957 4958 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetStepNumber() 4959 4960 .keywords: TS, timestep, get, matrix, Jacobian 4961 @*/ 4962 PetscErrorCode TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx) 4963 { 4964 PetscErrorCode ierr; 4965 DM dm; 4966 4967 PetscFunctionBegin; 4968 if (Amat || Pmat) { 4969 SNES snes; 4970 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4971 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4972 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4973 } 4974 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4975 ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr); 4976 PetscFunctionReturn(0); 4977 } 4978 4979 /*@C 4980 TSMonitorDrawSolution - Monitors progress of the TS solvers by calling 4981 VecView() for the solution at each timestep 4982 4983 Collective on TS 4984 4985 Input Parameters: 4986 + ts - the TS context 4987 . step - current time-step 4988 . ptime - current time 4989 - dummy - either a viewer or NULL 4990 4991 Options Database: 4992 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 4993 4994 Notes: the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial 4995 will look bad 4996 4997 Level: intermediate 4998 4999 .keywords: TS, vector, monitor, view 5000 5001 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5002 @*/ 5003 PetscErrorCode TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 5004 { 5005 PetscErrorCode ierr; 5006 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 5007 PetscDraw draw; 5008 5009 PetscFunctionBegin; 5010 if (!step && ictx->showinitial) { 5011 if (!ictx->initialsolution) { 5012 ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr); 5013 } 5014 ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr); 5015 } 5016 if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 5017 5018 if (ictx->showinitial) { 5019 PetscReal pause; 5020 ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr); 5021 ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr); 5022 ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr); 5023 ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr); 5024 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr); 5025 } 5026 ierr = VecView(u,ictx->viewer);CHKERRQ(ierr); 5027 if (ictx->showtimestepandtime) { 5028 PetscReal xl,yl,xr,yr,h; 5029 char time[32]; 5030 5031 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 5032 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 5033 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 5034 h = yl + .95*(yr - yl); 5035 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 5036 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 5037 } 5038 5039 if (ictx->showinitial) { 5040 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr); 5041 } 5042 PetscFunctionReturn(0); 5043 } 5044 5045 /*@C 5046 TSAdjointMonitorDrawSensi - Monitors progress of the adjoint TS solvers by calling 5047 VecView() for the sensitivities to initial states at each timestep 5048 5049 Collective on TS 5050 5051 Input Parameters: 5052 + ts - the TS context 5053 . step - current time-step 5054 . ptime - current time 5055 . u - current state 5056 . numcost - number of cost functions 5057 . lambda - sensitivities to initial conditions 5058 . mu - sensitivities to parameters 5059 - dummy - either a viewer or NULL 5060 5061 Level: intermediate 5062 5063 .keywords: TS, vector, adjoint, monitor, view 5064 5065 .seealso: TSAdjointMonitorSet(), TSAdjointMonitorDefault(), VecView() 5066 @*/ 5067 PetscErrorCode TSAdjointMonitorDrawSensi(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda,Vec *mu,void *dummy) 5068 { 5069 PetscErrorCode ierr; 5070 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 5071 PetscDraw draw; 5072 PetscReal xl,yl,xr,yr,h; 5073 char time[32]; 5074 5075 PetscFunctionBegin; 5076 if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 5077 5078 ierr = VecView(lambda[0],ictx->viewer);CHKERRQ(ierr); 5079 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 5080 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 5081 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 5082 h = yl + .95*(yr - yl); 5083 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 5084 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 5085 PetscFunctionReturn(0); 5086 } 5087 5088 /*@C 5089 TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram 5090 5091 Collective on TS 5092 5093 Input Parameters: 5094 + ts - the TS context 5095 . step - current time-step 5096 . ptime - current time 5097 - dummy - either a viewer or NULL 5098 5099 Level: intermediate 5100 5101 .keywords: TS, vector, monitor, view 5102 5103 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5104 @*/ 5105 PetscErrorCode TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 5106 { 5107 PetscErrorCode ierr; 5108 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 5109 PetscDraw draw; 5110 PetscDrawAxis axis; 5111 PetscInt n; 5112 PetscMPIInt size; 5113 PetscReal U0,U1,xl,yl,xr,yr,h; 5114 char time[32]; 5115 const PetscScalar *U; 5116 5117 PetscFunctionBegin; 5118 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size);CHKERRQ(ierr); 5119 if (size != 1) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs"); 5120 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 5121 if (n != 2) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns"); 5122 5123 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 5124 ierr = PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis);CHKERRQ(ierr); 5125 ierr = PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr); 5126 if (!step) { 5127 ierr = PetscDrawClear(draw);CHKERRQ(ierr); 5128 ierr = PetscDrawAxisDraw(axis);CHKERRQ(ierr); 5129 } 5130 5131 ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr); 5132 U0 = PetscRealPart(U[0]); 5133 U1 = PetscRealPart(U[1]); 5134 ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr); 5135 if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0); 5136 5137 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 5138 ierr = PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK);CHKERRQ(ierr); 5139 if (ictx->showtimestepandtime) { 5140 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 5141 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 5142 h = yl + .95*(yr - yl); 5143 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 5144 } 5145 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 5146 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 5147 ierr = PetscDrawPause(draw);CHKERRQ(ierr); 5148 ierr = PetscDrawSave(draw);CHKERRQ(ierr); 5149 PetscFunctionReturn(0); 5150 } 5151 5152 /*@C 5153 TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution() 5154 5155 Collective on TS 5156 5157 Input Parameters: 5158 . ctx - the monitor context 5159 5160 Level: intermediate 5161 5162 .keywords: TS, vector, monitor, view 5163 5164 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError() 5165 @*/ 5166 PetscErrorCode TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx) 5167 { 5168 PetscErrorCode ierr; 5169 5170 PetscFunctionBegin; 5171 ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr); 5172 ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr); 5173 ierr = PetscFree(*ictx);CHKERRQ(ierr); 5174 PetscFunctionReturn(0); 5175 } 5176 5177 /*@C 5178 TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx 5179 5180 Collective on TS 5181 5182 Input Parameter: 5183 . ts - time-step context 5184 5185 Output Patameter: 5186 . ctx - the monitor context 5187 5188 Options Database: 5189 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 5190 5191 Level: intermediate 5192 5193 .keywords: TS, vector, monitor, view 5194 5195 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx() 5196 @*/ 5197 PetscErrorCode TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx) 5198 { 5199 PetscErrorCode ierr; 5200 5201 PetscFunctionBegin; 5202 ierr = PetscNew(ctx);CHKERRQ(ierr); 5203 ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr); 5204 ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr); 5205 5206 (*ctx)->howoften = howoften; 5207 (*ctx)->showinitial = PETSC_FALSE; 5208 ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr); 5209 5210 (*ctx)->showtimestepandtime = PETSC_FALSE; 5211 ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr); 5212 PetscFunctionReturn(0); 5213 } 5214 5215 /*@C 5216 TSMonitorDrawSolutionFunction - Monitors progress of the TS solvers by calling 5217 VecView() for the solution provided by TSSetSolutionFunction() at each timestep 5218 5219 Collective on TS 5220 5221 Input Parameters: 5222 + ts - the TS context 5223 . step - current time-step 5224 . ptime - current time 5225 - dummy - either a viewer or NULL 5226 5227 Options Database: 5228 . -ts_monitor_draw_solution_function - Monitor error graphically, requires user to have provided TSSetSolutionFunction() 5229 5230 Level: intermediate 5231 5232 .keywords: TS, vector, monitor, view 5233 5234 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 5235 @*/ 5236 PetscErrorCode TSMonitorDrawSolutionFunction(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 5237 { 5238 PetscErrorCode ierr; 5239 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 5240 PetscViewer viewer = ctx->viewer; 5241 Vec work; 5242 5243 PetscFunctionBegin; 5244 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 5245 ierr = VecDuplicate(u,&work);CHKERRQ(ierr); 5246 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 5247 ierr = VecView(work,viewer);CHKERRQ(ierr); 5248 ierr = VecDestroy(&work);CHKERRQ(ierr); 5249 PetscFunctionReturn(0); 5250 } 5251 5252 /*@C 5253 TSMonitorDrawError - Monitors progress of the TS solvers by calling 5254 VecView() for the error at each timestep 5255 5256 Collective on TS 5257 5258 Input Parameters: 5259 + ts - the TS context 5260 . step - current time-step 5261 . ptime - current time 5262 - dummy - either a viewer or NULL 5263 5264 Options Database: 5265 . -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction() 5266 5267 Level: intermediate 5268 5269 .keywords: TS, vector, monitor, view 5270 5271 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 5272 @*/ 5273 PetscErrorCode TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 5274 { 5275 PetscErrorCode ierr; 5276 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 5277 PetscViewer viewer = ctx->viewer; 5278 Vec work; 5279 5280 PetscFunctionBegin; 5281 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 5282 ierr = VecDuplicate(u,&work);CHKERRQ(ierr); 5283 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 5284 ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr); 5285 ierr = VecView(work,viewer);CHKERRQ(ierr); 5286 ierr = VecDestroy(&work);CHKERRQ(ierr); 5287 PetscFunctionReturn(0); 5288 } 5289 5290 #include <petsc/private/dmimpl.h> 5291 /*@ 5292 TSSetDM - Sets the DM that may be used by some nonlinear solvers or preconditioners under the TS 5293 5294 Logically Collective on TS and DM 5295 5296 Input Parameters: 5297 + ts - the ODE integrator object 5298 - dm - the dm, cannot be NULL 5299 5300 Level: intermediate 5301 5302 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM() 5303 @*/ 5304 PetscErrorCode TSSetDM(TS ts,DM dm) 5305 { 5306 PetscErrorCode ierr; 5307 SNES snes; 5308 DMTS tsdm; 5309 5310 PetscFunctionBegin; 5311 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5312 PetscValidHeaderSpecific(dm,DM_CLASSID,2); 5313 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 5314 if (ts->dm) { /* Move the DMTS context over to the new DM unless the new DM already has one */ 5315 if (ts->dm->dmts && !dm->dmts) { 5316 ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr); 5317 ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr); 5318 if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */ 5319 tsdm->originaldm = dm; 5320 } 5321 } 5322 ierr = DMDestroy(&ts->dm);CHKERRQ(ierr); 5323 } 5324 ts->dm = dm; 5325 5326 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 5327 ierr = SNESSetDM(snes,dm);CHKERRQ(ierr); 5328 PetscFunctionReturn(0); 5329 } 5330 5331 /*@ 5332 TSGetDM - Gets the DM that may be used by some preconditioners 5333 5334 Not Collective 5335 5336 Input Parameter: 5337 . ts - the preconditioner context 5338 5339 Output Parameter: 5340 . dm - the dm 5341 5342 Level: intermediate 5343 5344 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM() 5345 @*/ 5346 PetscErrorCode TSGetDM(TS ts,DM *dm) 5347 { 5348 PetscErrorCode ierr; 5349 5350 PetscFunctionBegin; 5351 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5352 if (!ts->dm) { 5353 ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr); 5354 if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 5355 } 5356 *dm = ts->dm; 5357 PetscFunctionReturn(0); 5358 } 5359 5360 /*@ 5361 SNESTSFormFunction - Function to evaluate nonlinear residual 5362 5363 Logically Collective on SNES 5364 5365 Input Parameter: 5366 + snes - nonlinear solver 5367 . U - the current state at which to evaluate the residual 5368 - ctx - user context, must be a TS 5369 5370 Output Parameter: 5371 . F - the nonlinear residual 5372 5373 Notes: 5374 This function is not normally called by users and is automatically registered with the SNES used by TS. 5375 It is most frequently passed to MatFDColoringSetFunction(). 5376 5377 Level: advanced 5378 5379 .seealso: SNESSetFunction(), MatFDColoringSetFunction() 5380 @*/ 5381 PetscErrorCode SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx) 5382 { 5383 TS ts = (TS)ctx; 5384 PetscErrorCode ierr; 5385 5386 PetscFunctionBegin; 5387 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5388 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5389 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 5390 PetscValidHeaderSpecific(ts,TS_CLASSID,4); 5391 ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr); 5392 PetscFunctionReturn(0); 5393 } 5394 5395 /*@ 5396 SNESTSFormJacobian - Function to evaluate the Jacobian 5397 5398 Collective on SNES 5399 5400 Input Parameter: 5401 + snes - nonlinear solver 5402 . U - the current state at which to evaluate the residual 5403 - ctx - user context, must be a TS 5404 5405 Output Parameter: 5406 + A - the Jacobian 5407 . B - the preconditioning matrix (may be the same as A) 5408 - flag - indicates any structure change in the matrix 5409 5410 Notes: 5411 This function is not normally called by users and is automatically registered with the SNES used by TS. 5412 5413 Level: developer 5414 5415 .seealso: SNESSetJacobian() 5416 @*/ 5417 PetscErrorCode SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx) 5418 { 5419 TS ts = (TS)ctx; 5420 PetscErrorCode ierr; 5421 5422 PetscFunctionBegin; 5423 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5424 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5425 PetscValidPointer(A,3); 5426 PetscValidHeaderSpecific(A,MAT_CLASSID,3); 5427 PetscValidPointer(B,4); 5428 PetscValidHeaderSpecific(B,MAT_CLASSID,4); 5429 PetscValidHeaderSpecific(ts,TS_CLASSID,6); 5430 ierr = (ts->ops->snesjacobian)(snes,U,A,B,ts);CHKERRQ(ierr); 5431 PetscFunctionReturn(0); 5432 } 5433 5434 /*@C 5435 TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems Udot = A U only 5436 5437 Collective on TS 5438 5439 Input Arguments: 5440 + ts - time stepping context 5441 . t - time at which to evaluate 5442 . U - state at which to evaluate 5443 - ctx - context 5444 5445 Output Arguments: 5446 . F - right hand side 5447 5448 Level: intermediate 5449 5450 Notes: 5451 This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems. 5452 The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian(). 5453 5454 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 5455 @*/ 5456 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx) 5457 { 5458 PetscErrorCode ierr; 5459 Mat Arhs,Brhs; 5460 5461 PetscFunctionBegin; 5462 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 5463 ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr); 5464 ierr = MatMult(Arhs,U,F);CHKERRQ(ierr); 5465 PetscFunctionReturn(0); 5466 } 5467 5468 /*@C 5469 TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent. 5470 5471 Collective on TS 5472 5473 Input Arguments: 5474 + ts - time stepping context 5475 . t - time at which to evaluate 5476 . U - state at which to evaluate 5477 - ctx - context 5478 5479 Output Arguments: 5480 + A - pointer to operator 5481 . B - pointer to preconditioning matrix 5482 - flg - matrix structure flag 5483 5484 Level: intermediate 5485 5486 Notes: 5487 This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems. 5488 5489 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear() 5490 @*/ 5491 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx) 5492 { 5493 PetscFunctionBegin; 5494 PetscFunctionReturn(0); 5495 } 5496 5497 /*@C 5498 TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only 5499 5500 Collective on TS 5501 5502 Input Arguments: 5503 + ts - time stepping context 5504 . t - time at which to evaluate 5505 . U - state at which to evaluate 5506 . Udot - time derivative of state vector 5507 - ctx - context 5508 5509 Output Arguments: 5510 . F - left hand side 5511 5512 Level: intermediate 5513 5514 Notes: 5515 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 5516 user is required to write their own TSComputeIFunction. 5517 This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems. 5518 The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian(). 5519 5520 Note that using this function is NOT equivalent to using TSComputeRHSFunctionLinear() since that solves Udot = A U 5521 5522 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant(), TSComputeRHSFunctionLinear() 5523 @*/ 5524 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx) 5525 { 5526 PetscErrorCode ierr; 5527 Mat A,B; 5528 5529 PetscFunctionBegin; 5530 ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr); 5531 ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE);CHKERRQ(ierr); 5532 ierr = MatMult(A,Udot,F);CHKERRQ(ierr); 5533 PetscFunctionReturn(0); 5534 } 5535 5536 /*@C 5537 TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE 5538 5539 Collective on TS 5540 5541 Input Arguments: 5542 + ts - time stepping context 5543 . t - time at which to evaluate 5544 . U - state at which to evaluate 5545 . Udot - time derivative of state vector 5546 . shift - shift to apply 5547 - ctx - context 5548 5549 Output Arguments: 5550 + A - pointer to operator 5551 . B - pointer to preconditioning matrix 5552 - flg - matrix structure flag 5553 5554 Level: advanced 5555 5556 Notes: 5557 This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems. 5558 5559 It is only appropriate for problems of the form 5560 5561 $ M Udot = F(U,t) 5562 5563 where M is constant and F is non-stiff. The user must pass M to TSSetIJacobian(). The current implementation only 5564 works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing 5565 an implicit operator of the form 5566 5567 $ shift*M + J 5568 5569 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 5570 a copy of M or reassemble it when requested. 5571 5572 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear() 5573 @*/ 5574 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx) 5575 { 5576 PetscErrorCode ierr; 5577 5578 PetscFunctionBegin; 5579 ierr = MatScale(A, shift / ts->ijacobian.shift);CHKERRQ(ierr); 5580 ts->ijacobian.shift = shift; 5581 PetscFunctionReturn(0); 5582 } 5583 5584 /*@ 5585 TSGetEquationType - Gets the type of the equation that TS is solving. 5586 5587 Not Collective 5588 5589 Input Parameter: 5590 . ts - the TS context 5591 5592 Output Parameter: 5593 . equation_type - see TSEquationType 5594 5595 Level: beginner 5596 5597 .keywords: TS, equation type 5598 5599 .seealso: TSSetEquationType(), TSEquationType 5600 @*/ 5601 PetscErrorCode TSGetEquationType(TS ts,TSEquationType *equation_type) 5602 { 5603 PetscFunctionBegin; 5604 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5605 PetscValidPointer(equation_type,2); 5606 *equation_type = ts->equation_type; 5607 PetscFunctionReturn(0); 5608 } 5609 5610 /*@ 5611 TSSetEquationType - Sets the type of the equation that TS is solving. 5612 5613 Not Collective 5614 5615 Input Parameter: 5616 + ts - the TS context 5617 - equation_type - see TSEquationType 5618 5619 Level: advanced 5620 5621 .keywords: TS, equation type 5622 5623 .seealso: TSGetEquationType(), TSEquationType 5624 @*/ 5625 PetscErrorCode TSSetEquationType(TS ts,TSEquationType equation_type) 5626 { 5627 PetscFunctionBegin; 5628 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5629 ts->equation_type = equation_type; 5630 PetscFunctionReturn(0); 5631 } 5632 5633 /*@ 5634 TSGetConvergedReason - Gets the reason the TS iteration was stopped. 5635 5636 Not Collective 5637 5638 Input Parameter: 5639 . ts - the TS context 5640 5641 Output Parameter: 5642 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 5643 manual pages for the individual convergence tests for complete lists 5644 5645 Level: beginner 5646 5647 Notes: 5648 Can only be called after the call to TSSolve() is complete. 5649 5650 .keywords: TS, nonlinear, set, convergence, test 5651 5652 .seealso: TSSetConvergenceTest(), TSConvergedReason 5653 @*/ 5654 PetscErrorCode TSGetConvergedReason(TS ts,TSConvergedReason *reason) 5655 { 5656 PetscFunctionBegin; 5657 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5658 PetscValidPointer(reason,2); 5659 *reason = ts->reason; 5660 PetscFunctionReturn(0); 5661 } 5662 5663 /*@ 5664 TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve. 5665 5666 Not Collective 5667 5668 Input Parameter: 5669 + ts - the TS context 5670 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 5671 manual pages for the individual convergence tests for complete lists 5672 5673 Level: advanced 5674 5675 Notes: 5676 Can only be called during TSSolve() is active. 5677 5678 .keywords: TS, nonlinear, set, convergence, test 5679 5680 .seealso: TSConvergedReason 5681 @*/ 5682 PetscErrorCode TSSetConvergedReason(TS ts,TSConvergedReason reason) 5683 { 5684 PetscFunctionBegin; 5685 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5686 ts->reason = reason; 5687 PetscFunctionReturn(0); 5688 } 5689 5690 /*@ 5691 TSGetSolveTime - Gets the time after a call to TSSolve() 5692 5693 Not Collective 5694 5695 Input Parameter: 5696 . ts - the TS context 5697 5698 Output Parameter: 5699 . ftime - the final time. This time corresponds to the final time set with TSSetMaxTime() 5700 5701 Level: beginner 5702 5703 Notes: 5704 Can only be called after the call to TSSolve() is complete. 5705 5706 .keywords: TS, nonlinear, set, convergence, test 5707 5708 .seealso: TSSetConvergenceTest(), TSConvergedReason 5709 @*/ 5710 PetscErrorCode TSGetSolveTime(TS ts,PetscReal *ftime) 5711 { 5712 PetscFunctionBegin; 5713 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5714 PetscValidPointer(ftime,2); 5715 *ftime = ts->solvetime; 5716 PetscFunctionReturn(0); 5717 } 5718 5719 /*@ 5720 TSGetSNESIterations - Gets the total number of nonlinear iterations 5721 used by the time integrator. 5722 5723 Not Collective 5724 5725 Input Parameter: 5726 . ts - TS context 5727 5728 Output Parameter: 5729 . nits - number of nonlinear iterations 5730 5731 Notes: 5732 This counter is reset to zero for each successive call to TSSolve(). 5733 5734 Level: intermediate 5735 5736 .keywords: TS, get, number, nonlinear, iterations 5737 5738 .seealso: TSGetKSPIterations() 5739 @*/ 5740 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits) 5741 { 5742 PetscFunctionBegin; 5743 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5744 PetscValidIntPointer(nits,2); 5745 *nits = ts->snes_its; 5746 PetscFunctionReturn(0); 5747 } 5748 5749 /*@ 5750 TSGetKSPIterations - Gets the total number of linear iterations 5751 used by the time integrator. 5752 5753 Not Collective 5754 5755 Input Parameter: 5756 . ts - TS context 5757 5758 Output Parameter: 5759 . lits - number of linear iterations 5760 5761 Notes: 5762 This counter is reset to zero for each successive call to TSSolve(). 5763 5764 Level: intermediate 5765 5766 .keywords: TS, get, number, linear, iterations 5767 5768 .seealso: TSGetSNESIterations(), SNESGetKSPIterations() 5769 @*/ 5770 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits) 5771 { 5772 PetscFunctionBegin; 5773 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5774 PetscValidIntPointer(lits,2); 5775 *lits = ts->ksp_its; 5776 PetscFunctionReturn(0); 5777 } 5778 5779 /*@ 5780 TSGetStepRejections - Gets the total number of rejected steps. 5781 5782 Not Collective 5783 5784 Input Parameter: 5785 . ts - TS context 5786 5787 Output Parameter: 5788 . rejects - number of steps rejected 5789 5790 Notes: 5791 This counter is reset to zero for each successive call to TSSolve(). 5792 5793 Level: intermediate 5794 5795 .keywords: TS, get, number 5796 5797 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails() 5798 @*/ 5799 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects) 5800 { 5801 PetscFunctionBegin; 5802 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5803 PetscValidIntPointer(rejects,2); 5804 *rejects = ts->reject; 5805 PetscFunctionReturn(0); 5806 } 5807 5808 /*@ 5809 TSGetSNESFailures - Gets the total number of failed SNES solves 5810 5811 Not Collective 5812 5813 Input Parameter: 5814 . ts - TS context 5815 5816 Output Parameter: 5817 . fails - number of failed nonlinear solves 5818 5819 Notes: 5820 This counter is reset to zero for each successive call to TSSolve(). 5821 5822 Level: intermediate 5823 5824 .keywords: TS, get, number 5825 5826 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures() 5827 @*/ 5828 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails) 5829 { 5830 PetscFunctionBegin; 5831 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5832 PetscValidIntPointer(fails,2); 5833 *fails = ts->num_snes_failures; 5834 PetscFunctionReturn(0); 5835 } 5836 5837 /*@ 5838 TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails 5839 5840 Not Collective 5841 5842 Input Parameter: 5843 + ts - TS context 5844 - rejects - maximum number of rejected steps, pass -1 for unlimited 5845 5846 Notes: 5847 The counter is reset to zero for each step 5848 5849 Options Database Key: 5850 . -ts_max_reject - Maximum number of step rejections before a step fails 5851 5852 Level: intermediate 5853 5854 .keywords: TS, set, maximum, number 5855 5856 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 5857 @*/ 5858 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects) 5859 { 5860 PetscFunctionBegin; 5861 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5862 ts->max_reject = rejects; 5863 PetscFunctionReturn(0); 5864 } 5865 5866 /*@ 5867 TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves 5868 5869 Not Collective 5870 5871 Input Parameter: 5872 + ts - TS context 5873 - fails - maximum number of failed nonlinear solves, pass -1 for unlimited 5874 5875 Notes: 5876 The counter is reset to zero for each successive call to TSSolve(). 5877 5878 Options Database Key: 5879 . -ts_max_snes_failures - Maximum number of nonlinear solve failures 5880 5881 Level: intermediate 5882 5883 .keywords: TS, set, maximum, number 5884 5885 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason() 5886 @*/ 5887 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails) 5888 { 5889 PetscFunctionBegin; 5890 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5891 ts->max_snes_failures = fails; 5892 PetscFunctionReturn(0); 5893 } 5894 5895 /*@ 5896 TSSetErrorIfStepFails - Error if no step succeeds 5897 5898 Not Collective 5899 5900 Input Parameter: 5901 + ts - TS context 5902 - err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure 5903 5904 Options Database Key: 5905 . -ts_error_if_step_fails - Error if no step succeeds 5906 5907 Level: intermediate 5908 5909 .keywords: TS, set, error 5910 5911 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 5912 @*/ 5913 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err) 5914 { 5915 PetscFunctionBegin; 5916 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5917 ts->errorifstepfailed = err; 5918 PetscFunctionReturn(0); 5919 } 5920 5921 /*@C 5922 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 5923 5924 Collective on TS 5925 5926 Input Parameters: 5927 + ts - the TS context 5928 . step - current time-step 5929 . ptime - current time 5930 . u - current state 5931 - vf - viewer and its format 5932 5933 Level: intermediate 5934 5935 .keywords: TS, vector, monitor, view 5936 5937 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5938 @*/ 5939 PetscErrorCode TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf) 5940 { 5941 PetscErrorCode ierr; 5942 5943 PetscFunctionBegin; 5944 ierr = PetscViewerPushFormat(vf->viewer,vf->format);CHKERRQ(ierr); 5945 ierr = VecView(u,vf->viewer);CHKERRQ(ierr); 5946 ierr = PetscViewerPopFormat(vf->viewer);CHKERRQ(ierr); 5947 PetscFunctionReturn(0); 5948 } 5949 5950 /*@C 5951 TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep. 5952 5953 Collective on TS 5954 5955 Input Parameters: 5956 + ts - the TS context 5957 . step - current time-step 5958 . ptime - current time 5959 . u - current state 5960 - filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 5961 5962 Level: intermediate 5963 5964 Notes: 5965 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. 5966 These are named according to the file name template. 5967 5968 This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy(). 5969 5970 .keywords: TS, vector, monitor, view 5971 5972 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5973 @*/ 5974 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate) 5975 { 5976 PetscErrorCode ierr; 5977 char filename[PETSC_MAX_PATH_LEN]; 5978 PetscViewer viewer; 5979 5980 PetscFunctionBegin; 5981 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 5982 ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr); 5983 ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); 5984 ierr = VecView(u,viewer);CHKERRQ(ierr); 5985 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 5986 PetscFunctionReturn(0); 5987 } 5988 5989 /*@C 5990 TSMonitorSolutionVTKDestroy - Destroy context for monitoring 5991 5992 Collective on TS 5993 5994 Input Parameters: 5995 . filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 5996 5997 Level: intermediate 5998 5999 Note: 6000 This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK(). 6001 6002 .keywords: TS, vector, monitor, view 6003 6004 .seealso: TSMonitorSet(), TSMonitorSolutionVTK() 6005 @*/ 6006 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate) 6007 { 6008 PetscErrorCode ierr; 6009 6010 PetscFunctionBegin; 6011 ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr); 6012 PetscFunctionReturn(0); 6013 } 6014 6015 /*@ 6016 TSGetAdapt - Get the adaptive controller context for the current method 6017 6018 Collective on TS if controller has not been created yet 6019 6020 Input Arguments: 6021 . ts - time stepping context 6022 6023 Output Arguments: 6024 . adapt - adaptive controller 6025 6026 Level: intermediate 6027 6028 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose() 6029 @*/ 6030 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt) 6031 { 6032 PetscErrorCode ierr; 6033 6034 PetscFunctionBegin; 6035 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6036 PetscValidPointer(adapt,2); 6037 if (!ts->adapt) { 6038 ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr); 6039 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr); 6040 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr); 6041 } 6042 *adapt = ts->adapt; 6043 PetscFunctionReturn(0); 6044 } 6045 6046 /*@ 6047 TSSetTolerances - Set tolerances for local truncation error when using adaptive controller 6048 6049 Logically Collective 6050 6051 Input Arguments: 6052 + ts - time integration context 6053 . atol - scalar absolute tolerances, PETSC_DECIDE to leave current value 6054 . vatol - vector of absolute tolerances or NULL, used in preference to atol if present 6055 . rtol - scalar relative tolerances, PETSC_DECIDE to leave current value 6056 - vrtol - vector of relative tolerances or NULL, used in preference to atol if present 6057 6058 Options Database keys: 6059 + -ts_rtol <rtol> - relative tolerance for local truncation error 6060 - -ts_atol <atol> Absolute tolerance for local truncation error 6061 6062 Notes: 6063 With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error 6064 (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be 6065 computed only for the differential or the algebraic part then this can be done using the vector of 6066 tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the 6067 differential part and infinity for the algebraic part, the LTE calculation will include only the 6068 differential variables. 6069 6070 Level: beginner 6071 6072 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances() 6073 @*/ 6074 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol) 6075 { 6076 PetscErrorCode ierr; 6077 6078 PetscFunctionBegin; 6079 if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol; 6080 if (vatol) { 6081 ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr); 6082 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 6083 ts->vatol = vatol; 6084 } 6085 if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol; 6086 if (vrtol) { 6087 ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr); 6088 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 6089 ts->vrtol = vrtol; 6090 } 6091 PetscFunctionReturn(0); 6092 } 6093 6094 /*@ 6095 TSGetTolerances - Get tolerances for local truncation error when using adaptive controller 6096 6097 Logically Collective 6098 6099 Input Arguments: 6100 . ts - time integration context 6101 6102 Output Arguments: 6103 + atol - scalar absolute tolerances, NULL to ignore 6104 . vatol - vector of absolute tolerances, NULL to ignore 6105 . rtol - scalar relative tolerances, NULL to ignore 6106 - vrtol - vector of relative tolerances, NULL to ignore 6107 6108 Level: beginner 6109 6110 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances() 6111 @*/ 6112 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol) 6113 { 6114 PetscFunctionBegin; 6115 if (atol) *atol = ts->atol; 6116 if (vatol) *vatol = ts->vatol; 6117 if (rtol) *rtol = ts->rtol; 6118 if (vrtol) *vrtol = ts->vrtol; 6119 PetscFunctionReturn(0); 6120 } 6121 6122 /*@ 6123 TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors 6124 6125 Collective on TS 6126 6127 Input Arguments: 6128 + ts - time stepping context 6129 . U - state vector, usually ts->vec_sol 6130 - Y - state vector to be compared to U 6131 6132 Output Arguments: 6133 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 6134 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 6135 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 6136 6137 Level: developer 6138 6139 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNormInfinity() 6140 @*/ 6141 PetscErrorCode TSErrorWeightedNorm2(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6142 { 6143 PetscErrorCode ierr; 6144 PetscInt i,n,N,rstart; 6145 PetscInt n_loc,na_loc,nr_loc; 6146 PetscReal n_glb,na_glb,nr_glb; 6147 const PetscScalar *u,*y; 6148 PetscReal sum,suma,sumr,gsum,gsuma,gsumr,diff; 6149 PetscReal tol,tola,tolr; 6150 PetscReal err_loc[6],err_glb[6]; 6151 6152 PetscFunctionBegin; 6153 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6154 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 6155 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 6156 PetscValidType(U,2); 6157 PetscValidType(Y,3); 6158 PetscCheckSameComm(U,2,Y,3); 6159 PetscValidPointer(norm,4); 6160 PetscValidPointer(norma,5); 6161 PetscValidPointer(normr,6); 6162 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 6163 6164 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 6165 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 6166 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 6167 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 6168 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 6169 sum = 0.; n_loc = 0; 6170 suma = 0.; na_loc = 0; 6171 sumr = 0.; nr_loc = 0; 6172 if (ts->vatol && ts->vrtol) { 6173 const PetscScalar *atol,*rtol; 6174 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6175 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6176 for (i=0; i<n; i++) { 6177 diff = PetscAbsScalar(y[i] - u[i]); 6178 tola = PetscRealPart(atol[i]); 6179 if(tola>0.){ 6180 suma += PetscSqr(diff/tola); 6181 na_loc++; 6182 } 6183 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6184 if(tolr>0.){ 6185 sumr += PetscSqr(diff/tolr); 6186 nr_loc++; 6187 } 6188 tol=tola+tolr; 6189 if(tol>0.){ 6190 sum += PetscSqr(diff/tol); 6191 n_loc++; 6192 } 6193 } 6194 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6195 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6196 } else if (ts->vatol) { /* vector atol, scalar rtol */ 6197 const PetscScalar *atol; 6198 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6199 for (i=0; i<n; i++) { 6200 diff = PetscAbsScalar(y[i] - u[i]); 6201 tola = PetscRealPart(atol[i]); 6202 if(tola>0.){ 6203 suma += PetscSqr(diff/tola); 6204 na_loc++; 6205 } 6206 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6207 if(tolr>0.){ 6208 sumr += PetscSqr(diff/tolr); 6209 nr_loc++; 6210 } 6211 tol=tola+tolr; 6212 if(tol>0.){ 6213 sum += PetscSqr(diff/tol); 6214 n_loc++; 6215 } 6216 } 6217 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6218 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 6219 const PetscScalar *rtol; 6220 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6221 for (i=0; i<n; i++) { 6222 diff = PetscAbsScalar(y[i] - u[i]); 6223 tola = ts->atol; 6224 if(tola>0.){ 6225 suma += PetscSqr(diff/tola); 6226 na_loc++; 6227 } 6228 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6229 if(tolr>0.){ 6230 sumr += PetscSqr(diff/tolr); 6231 nr_loc++; 6232 } 6233 tol=tola+tolr; 6234 if(tol>0.){ 6235 sum += PetscSqr(diff/tol); 6236 n_loc++; 6237 } 6238 } 6239 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6240 } else { /* scalar atol, scalar rtol */ 6241 for (i=0; i<n; i++) { 6242 diff = PetscAbsScalar(y[i] - u[i]); 6243 tola = ts->atol; 6244 if(tola>0.){ 6245 suma += PetscSqr(diff/tola); 6246 na_loc++; 6247 } 6248 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6249 if(tolr>0.){ 6250 sumr += PetscSqr(diff/tolr); 6251 nr_loc++; 6252 } 6253 tol=tola+tolr; 6254 if(tol>0.){ 6255 sum += PetscSqr(diff/tol); 6256 n_loc++; 6257 } 6258 } 6259 } 6260 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 6261 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 6262 6263 err_loc[0] = sum; 6264 err_loc[1] = suma; 6265 err_loc[2] = sumr; 6266 err_loc[3] = (PetscReal)n_loc; 6267 err_loc[4] = (PetscReal)na_loc; 6268 err_loc[5] = (PetscReal)nr_loc; 6269 6270 ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6271 6272 gsum = err_glb[0]; 6273 gsuma = err_glb[1]; 6274 gsumr = err_glb[2]; 6275 n_glb = err_glb[3]; 6276 na_glb = err_glb[4]; 6277 nr_glb = err_glb[5]; 6278 6279 *norm = 0.; 6280 if(n_glb>0. ){*norm = PetscSqrtReal(gsum / n_glb );} 6281 *norma = 0.; 6282 if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);} 6283 *normr = 0.; 6284 if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);} 6285 6286 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6287 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 6288 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 6289 PetscFunctionReturn(0); 6290 } 6291 6292 /*@ 6293 TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors 6294 6295 Collective on TS 6296 6297 Input Arguments: 6298 + ts - time stepping context 6299 . U - state vector, usually ts->vec_sol 6300 - Y - state vector to be compared to U 6301 6302 Output Arguments: 6303 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 6304 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 6305 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 6306 6307 Level: developer 6308 6309 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNorm2() 6310 @*/ 6311 PetscErrorCode TSErrorWeightedNormInfinity(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6312 { 6313 PetscErrorCode ierr; 6314 PetscInt i,n,N,rstart; 6315 const PetscScalar *u,*y; 6316 PetscReal max,gmax,maxa,gmaxa,maxr,gmaxr; 6317 PetscReal tol,tola,tolr,diff; 6318 PetscReal err_loc[3],err_glb[3]; 6319 6320 PetscFunctionBegin; 6321 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6322 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 6323 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 6324 PetscValidType(U,2); 6325 PetscValidType(Y,3); 6326 PetscCheckSameComm(U,2,Y,3); 6327 PetscValidPointer(norm,4); 6328 PetscValidPointer(norma,5); 6329 PetscValidPointer(normr,6); 6330 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 6331 6332 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 6333 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 6334 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 6335 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 6336 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 6337 6338 max=0.; 6339 maxa=0.; 6340 maxr=0.; 6341 6342 if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */ 6343 const PetscScalar *atol,*rtol; 6344 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6345 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6346 6347 for (i=0; i<n; i++) { 6348 diff = PetscAbsScalar(y[i] - u[i]); 6349 tola = PetscRealPart(atol[i]); 6350 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6351 tol = tola+tolr; 6352 if(tola>0.){ 6353 maxa = PetscMax(maxa,diff / tola); 6354 } 6355 if(tolr>0.){ 6356 maxr = PetscMax(maxr,diff / tolr); 6357 } 6358 if(tol>0.){ 6359 max = PetscMax(max,diff / tol); 6360 } 6361 } 6362 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6363 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6364 } else if (ts->vatol) { /* vector atol, scalar rtol */ 6365 const PetscScalar *atol; 6366 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6367 for (i=0; i<n; i++) { 6368 diff = PetscAbsScalar(y[i] - u[i]); 6369 tola = PetscRealPart(atol[i]); 6370 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6371 tol = tola+tolr; 6372 if(tola>0.){ 6373 maxa = PetscMax(maxa,diff / tola); 6374 } 6375 if(tolr>0.){ 6376 maxr = PetscMax(maxr,diff / tolr); 6377 } 6378 if(tol>0.){ 6379 max = PetscMax(max,diff / tol); 6380 } 6381 } 6382 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6383 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 6384 const PetscScalar *rtol; 6385 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6386 6387 for (i=0; i<n; i++) { 6388 diff = PetscAbsScalar(y[i] - u[i]); 6389 tola = ts->atol; 6390 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6391 tol = tola+tolr; 6392 if(tola>0.){ 6393 maxa = PetscMax(maxa,diff / tola); 6394 } 6395 if(tolr>0.){ 6396 maxr = PetscMax(maxr,diff / tolr); 6397 } 6398 if(tol>0.){ 6399 max = PetscMax(max,diff / tol); 6400 } 6401 } 6402 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6403 } else { /* scalar atol, scalar rtol */ 6404 6405 for (i=0; i<n; i++) { 6406 diff = PetscAbsScalar(y[i] - u[i]); 6407 tola = ts->atol; 6408 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6409 tol = tola+tolr; 6410 if(tola>0.){ 6411 maxa = PetscMax(maxa,diff / tola); 6412 } 6413 if(tolr>0.){ 6414 maxr = PetscMax(maxr,diff / tolr); 6415 } 6416 if(tol>0.){ 6417 max = PetscMax(max,diff / tol); 6418 } 6419 } 6420 } 6421 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 6422 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 6423 err_loc[0] = max; 6424 err_loc[1] = maxa; 6425 err_loc[2] = maxr; 6426 ierr = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6427 gmax = err_glb[0]; 6428 gmaxa = err_glb[1]; 6429 gmaxr = err_glb[2]; 6430 6431 *norm = gmax; 6432 *norma = gmaxa; 6433 *normr = gmaxr; 6434 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6435 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 6436 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 6437 PetscFunctionReturn(0); 6438 } 6439 6440 /*@ 6441 TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors based on supplied absolute and relative tolerances 6442 6443 Collective on TS 6444 6445 Input Arguments: 6446 + ts - time stepping context 6447 . U - state vector, usually ts->vec_sol 6448 . Y - state vector to be compared to U 6449 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 6450 6451 Output Arguments: 6452 . norm - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances 6453 . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user 6454 . normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user 6455 6456 Options Database Keys: 6457 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 6458 6459 Level: developer 6460 6461 .seealso: TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2(), TSErrorWeightedENorm 6462 @*/ 6463 PetscErrorCode TSErrorWeightedNorm(TS ts,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6464 { 6465 PetscErrorCode ierr; 6466 6467 PetscFunctionBegin; 6468 if (wnormtype == NORM_2) { 6469 ierr = TSErrorWeightedNorm2(ts,U,Y,norm,norma,normr);CHKERRQ(ierr); 6470 } else if(wnormtype == NORM_INFINITY) { 6471 ierr = TSErrorWeightedNormInfinity(ts,U,Y,norm,norma,normr);CHKERRQ(ierr); 6472 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 6473 PetscFunctionReturn(0); 6474 } 6475 6476 6477 /*@ 6478 TSErrorWeightedENorm2 - compute a weighted 2 error norm based on supplied absolute and relative tolerances 6479 6480 Collective on TS 6481 6482 Input Arguments: 6483 + ts - time stepping context 6484 . E - error vector 6485 . U - state vector, usually ts->vec_sol 6486 - Y - state vector, previous time step 6487 6488 Output Arguments: 6489 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 6490 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 6491 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 6492 6493 Level: developer 6494 6495 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENormInfinity() 6496 @*/ 6497 PetscErrorCode TSErrorWeightedENorm2(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6498 { 6499 PetscErrorCode ierr; 6500 PetscInt i,n,N,rstart; 6501 PetscInt n_loc,na_loc,nr_loc; 6502 PetscReal n_glb,na_glb,nr_glb; 6503 const PetscScalar *e,*u,*y; 6504 PetscReal err,sum,suma,sumr,gsum,gsuma,gsumr; 6505 PetscReal tol,tola,tolr; 6506 PetscReal err_loc[6],err_glb[6]; 6507 6508 PetscFunctionBegin; 6509 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6510 PetscValidHeaderSpecific(E,VEC_CLASSID,2); 6511 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 6512 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 6513 PetscValidType(E,2); 6514 PetscValidType(U,3); 6515 PetscValidType(Y,4); 6516 PetscCheckSameComm(E,2,U,3); 6517 PetscCheckSameComm(U,2,Y,3); 6518 PetscValidPointer(norm,5); 6519 PetscValidPointer(norma,6); 6520 PetscValidPointer(normr,7); 6521 6522 ierr = VecGetSize(E,&N);CHKERRQ(ierr); 6523 ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr); 6524 ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr); 6525 ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr); 6526 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 6527 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 6528 sum = 0.; n_loc = 0; 6529 suma = 0.; na_loc = 0; 6530 sumr = 0.; nr_loc = 0; 6531 if (ts->vatol && ts->vrtol) { 6532 const PetscScalar *atol,*rtol; 6533 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6534 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6535 for (i=0; i<n; i++) { 6536 err = PetscAbsScalar(e[i]); 6537 tola = PetscRealPart(atol[i]); 6538 if(tola>0.){ 6539 suma += PetscSqr(err/tola); 6540 na_loc++; 6541 } 6542 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6543 if(tolr>0.){ 6544 sumr += PetscSqr(err/tolr); 6545 nr_loc++; 6546 } 6547 tol=tola+tolr; 6548 if(tol>0.){ 6549 sum += PetscSqr(err/tol); 6550 n_loc++; 6551 } 6552 } 6553 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6554 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6555 } else if (ts->vatol) { /* vector atol, scalar rtol */ 6556 const PetscScalar *atol; 6557 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6558 for (i=0; i<n; i++) { 6559 err = PetscAbsScalar(e[i]); 6560 tola = PetscRealPart(atol[i]); 6561 if(tola>0.){ 6562 suma += PetscSqr(err/tola); 6563 na_loc++; 6564 } 6565 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6566 if(tolr>0.){ 6567 sumr += PetscSqr(err/tolr); 6568 nr_loc++; 6569 } 6570 tol=tola+tolr; 6571 if(tol>0.){ 6572 sum += PetscSqr(err/tol); 6573 n_loc++; 6574 } 6575 } 6576 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6577 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 6578 const PetscScalar *rtol; 6579 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6580 for (i=0; i<n; i++) { 6581 err = PetscAbsScalar(e[i]); 6582 tola = ts->atol; 6583 if(tola>0.){ 6584 suma += PetscSqr(err/tola); 6585 na_loc++; 6586 } 6587 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6588 if(tolr>0.){ 6589 sumr += PetscSqr(err/tolr); 6590 nr_loc++; 6591 } 6592 tol=tola+tolr; 6593 if(tol>0.){ 6594 sum += PetscSqr(err/tol); 6595 n_loc++; 6596 } 6597 } 6598 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6599 } else { /* scalar atol, scalar rtol */ 6600 for (i=0; i<n; i++) { 6601 err = PetscAbsScalar(e[i]); 6602 tola = ts->atol; 6603 if(tola>0.){ 6604 suma += PetscSqr(err/tola); 6605 na_loc++; 6606 } 6607 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6608 if(tolr>0.){ 6609 sumr += PetscSqr(err/tolr); 6610 nr_loc++; 6611 } 6612 tol=tola+tolr; 6613 if(tol>0.){ 6614 sum += PetscSqr(err/tol); 6615 n_loc++; 6616 } 6617 } 6618 } 6619 ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr); 6620 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 6621 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 6622 6623 err_loc[0] = sum; 6624 err_loc[1] = suma; 6625 err_loc[2] = sumr; 6626 err_loc[3] = (PetscReal)n_loc; 6627 err_loc[4] = (PetscReal)na_loc; 6628 err_loc[5] = (PetscReal)nr_loc; 6629 6630 ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6631 6632 gsum = err_glb[0]; 6633 gsuma = err_glb[1]; 6634 gsumr = err_glb[2]; 6635 n_glb = err_glb[3]; 6636 na_glb = err_glb[4]; 6637 nr_glb = err_glb[5]; 6638 6639 *norm = 0.; 6640 if(n_glb>0. ){*norm = PetscSqrtReal(gsum / n_glb );} 6641 *norma = 0.; 6642 if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);} 6643 *normr = 0.; 6644 if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);} 6645 6646 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6647 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 6648 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 6649 PetscFunctionReturn(0); 6650 } 6651 6652 /*@ 6653 TSErrorWeightedENormInfinity - compute a weighted infinity error norm based on supplied absolute and relative tolerances 6654 Collective on TS 6655 6656 Input Arguments: 6657 + ts - time stepping context 6658 . E - error vector 6659 . U - state vector, usually ts->vec_sol 6660 - Y - state vector, previous time step 6661 6662 Output Arguments: 6663 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 6664 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 6665 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 6666 6667 Level: developer 6668 6669 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENorm2() 6670 @*/ 6671 PetscErrorCode TSErrorWeightedENormInfinity(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6672 { 6673 PetscErrorCode ierr; 6674 PetscInt i,n,N,rstart; 6675 const PetscScalar *e,*u,*y; 6676 PetscReal err,max,gmax,maxa,gmaxa,maxr,gmaxr; 6677 PetscReal tol,tola,tolr; 6678 PetscReal err_loc[3],err_glb[3]; 6679 6680 PetscFunctionBegin; 6681 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6682 PetscValidHeaderSpecific(E,VEC_CLASSID,2); 6683 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 6684 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 6685 PetscValidType(E,2); 6686 PetscValidType(U,3); 6687 PetscValidType(Y,4); 6688 PetscCheckSameComm(E,2,U,3); 6689 PetscCheckSameComm(U,2,Y,3); 6690 PetscValidPointer(norm,5); 6691 PetscValidPointer(norma,6); 6692 PetscValidPointer(normr,7); 6693 6694 ierr = VecGetSize(E,&N);CHKERRQ(ierr); 6695 ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr); 6696 ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr); 6697 ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr); 6698 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 6699 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 6700 6701 max=0.; 6702 maxa=0.; 6703 maxr=0.; 6704 6705 if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */ 6706 const PetscScalar *atol,*rtol; 6707 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6708 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6709 6710 for (i=0; i<n; i++) { 6711 err = PetscAbsScalar(e[i]); 6712 tola = PetscRealPart(atol[i]); 6713 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6714 tol = tola+tolr; 6715 if(tola>0.){ 6716 maxa = PetscMax(maxa,err / tola); 6717 } 6718 if(tolr>0.){ 6719 maxr = PetscMax(maxr,err / tolr); 6720 } 6721 if(tol>0.){ 6722 max = PetscMax(max,err / tol); 6723 } 6724 } 6725 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6726 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6727 } else if (ts->vatol) { /* vector atol, scalar rtol */ 6728 const PetscScalar *atol; 6729 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6730 for (i=0; i<n; i++) { 6731 err = PetscAbsScalar(e[i]); 6732 tola = PetscRealPart(atol[i]); 6733 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6734 tol = tola+tolr; 6735 if(tola>0.){ 6736 maxa = PetscMax(maxa,err / tola); 6737 } 6738 if(tolr>0.){ 6739 maxr = PetscMax(maxr,err / tolr); 6740 } 6741 if(tol>0.){ 6742 max = PetscMax(max,err / tol); 6743 } 6744 } 6745 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6746 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 6747 const PetscScalar *rtol; 6748 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6749 6750 for (i=0; i<n; i++) { 6751 err = PetscAbsScalar(e[i]); 6752 tola = ts->atol; 6753 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6754 tol = tola+tolr; 6755 if(tola>0.){ 6756 maxa = PetscMax(maxa,err / tola); 6757 } 6758 if(tolr>0.){ 6759 maxr = PetscMax(maxr,err / tolr); 6760 } 6761 if(tol>0.){ 6762 max = PetscMax(max,err / tol); 6763 } 6764 } 6765 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6766 } else { /* scalar atol, scalar rtol */ 6767 6768 for (i=0; i<n; i++) { 6769 err = PetscAbsScalar(e[i]); 6770 tola = ts->atol; 6771 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6772 tol = tola+tolr; 6773 if(tola>0.){ 6774 maxa = PetscMax(maxa,err / tola); 6775 } 6776 if(tolr>0.){ 6777 maxr = PetscMax(maxr,err / tolr); 6778 } 6779 if(tol>0.){ 6780 max = PetscMax(max,err / tol); 6781 } 6782 } 6783 } 6784 ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr); 6785 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 6786 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 6787 err_loc[0] = max; 6788 err_loc[1] = maxa; 6789 err_loc[2] = maxr; 6790 ierr = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6791 gmax = err_glb[0]; 6792 gmaxa = err_glb[1]; 6793 gmaxr = err_glb[2]; 6794 6795 *norm = gmax; 6796 *norma = gmaxa; 6797 *normr = gmaxr; 6798 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6799 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 6800 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 6801 PetscFunctionReturn(0); 6802 } 6803 6804 /*@ 6805 TSErrorWeightedENorm - compute a weighted error norm based on supplied absolute and relative tolerances 6806 6807 Collective on TS 6808 6809 Input Arguments: 6810 + ts - time stepping context 6811 . E - error vector 6812 . U - state vector, usually ts->vec_sol 6813 . Y - state vector, previous time step 6814 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 6815 6816 Output Arguments: 6817 . norm - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances 6818 . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user 6819 . normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user 6820 6821 Options Database Keys: 6822 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 6823 6824 Level: developer 6825 6826 .seealso: TSErrorWeightedENormInfinity(), TSErrorWeightedENorm2(), TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2() 6827 @*/ 6828 PetscErrorCode TSErrorWeightedENorm(TS ts,Vec E,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6829 { 6830 PetscErrorCode ierr; 6831 6832 PetscFunctionBegin; 6833 if (wnormtype == NORM_2) { 6834 ierr = TSErrorWeightedENorm2(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr); 6835 } else if(wnormtype == NORM_INFINITY) { 6836 ierr = TSErrorWeightedENormInfinity(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr); 6837 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 6838 PetscFunctionReturn(0); 6839 } 6840 6841 6842 /*@ 6843 TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler 6844 6845 Logically Collective on TS 6846 6847 Input Arguments: 6848 + ts - time stepping context 6849 - cfltime - maximum stable time step if using forward Euler (value can be different on each process) 6850 6851 Note: 6852 After calling this function, the global CFL time can be obtained by calling TSGetCFLTime() 6853 6854 Level: intermediate 6855 6856 .seealso: TSGetCFLTime(), TSADAPTCFL 6857 @*/ 6858 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime) 6859 { 6860 PetscFunctionBegin; 6861 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6862 ts->cfltime_local = cfltime; 6863 ts->cfltime = -1.; 6864 PetscFunctionReturn(0); 6865 } 6866 6867 /*@ 6868 TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler 6869 6870 Collective on TS 6871 6872 Input Arguments: 6873 . ts - time stepping context 6874 6875 Output Arguments: 6876 . cfltime - maximum stable time step for forward Euler 6877 6878 Level: advanced 6879 6880 .seealso: TSSetCFLTimeLocal() 6881 @*/ 6882 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime) 6883 { 6884 PetscErrorCode ierr; 6885 6886 PetscFunctionBegin; 6887 if (ts->cfltime < 0) { 6888 ierr = MPIU_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6889 } 6890 *cfltime = ts->cfltime; 6891 PetscFunctionReturn(0); 6892 } 6893 6894 /*@ 6895 TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu 6896 6897 Input Parameters: 6898 . ts - the TS context. 6899 . xl - lower bound. 6900 . xu - upper bound. 6901 6902 Notes: 6903 If this routine is not called then the lower and upper bounds are set to 6904 PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp(). 6905 6906 Level: advanced 6907 6908 @*/ 6909 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu) 6910 { 6911 PetscErrorCode ierr; 6912 SNES snes; 6913 6914 PetscFunctionBegin; 6915 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 6916 ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr); 6917 PetscFunctionReturn(0); 6918 } 6919 6920 #if defined(PETSC_HAVE_MATLAB_ENGINE) 6921 #include <mex.h> 6922 6923 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext; 6924 6925 /* 6926 TSComputeFunction_Matlab - Calls the function that has been set with 6927 TSSetFunctionMatlab(). 6928 6929 Collective on TS 6930 6931 Input Parameters: 6932 + snes - the TS context 6933 - u - input vector 6934 6935 Output Parameter: 6936 . y - function vector, as set by TSSetFunction() 6937 6938 Notes: 6939 TSComputeFunction() is typically used within nonlinear solvers 6940 implementations, so most users would not generally call this routine 6941 themselves. 6942 6943 Level: developer 6944 6945 .keywords: TS, nonlinear, compute, function 6946 6947 .seealso: TSSetFunction(), TSGetFunction() 6948 */ 6949 PetscErrorCode TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx) 6950 { 6951 PetscErrorCode ierr; 6952 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 6953 int nlhs = 1,nrhs = 7; 6954 mxArray *plhs[1],*prhs[7]; 6955 long long int lx = 0,lxdot = 0,ly = 0,ls = 0; 6956 6957 PetscFunctionBegin; 6958 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 6959 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 6960 PetscValidHeaderSpecific(udot,VEC_CLASSID,4); 6961 PetscValidHeaderSpecific(y,VEC_CLASSID,5); 6962 PetscCheckSameComm(snes,1,u,3); 6963 PetscCheckSameComm(snes,1,y,5); 6964 6965 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 6966 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 6967 ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr); 6968 ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr); 6969 6970 prhs[0] = mxCreateDoubleScalar((double)ls); 6971 prhs[1] = mxCreateDoubleScalar(time); 6972 prhs[2] = mxCreateDoubleScalar((double)lx); 6973 prhs[3] = mxCreateDoubleScalar((double)lxdot); 6974 prhs[4] = mxCreateDoubleScalar((double)ly); 6975 prhs[5] = mxCreateString(sctx->funcname); 6976 prhs[6] = sctx->ctx; 6977 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr); 6978 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 6979 mxDestroyArray(prhs[0]); 6980 mxDestroyArray(prhs[1]); 6981 mxDestroyArray(prhs[2]); 6982 mxDestroyArray(prhs[3]); 6983 mxDestroyArray(prhs[4]); 6984 mxDestroyArray(prhs[5]); 6985 mxDestroyArray(plhs[0]); 6986 PetscFunctionReturn(0); 6987 } 6988 6989 /* 6990 TSSetFunctionMatlab - Sets the function evaluation routine and function 6991 vector for use by the TS routines in solving ODEs 6992 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 6993 6994 Logically Collective on TS 6995 6996 Input Parameters: 6997 + ts - the TS context 6998 - func - function evaluation routine 6999 7000 Calling sequence of func: 7001 $ func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx); 7002 7003 Level: beginner 7004 7005 .keywords: TS, nonlinear, set, function 7006 7007 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 7008 */ 7009 PetscErrorCode TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx) 7010 { 7011 PetscErrorCode ierr; 7012 TSMatlabContext *sctx; 7013 7014 PetscFunctionBegin; 7015 /* currently sctx is memory bleed */ 7016 ierr = PetscNew(&sctx);CHKERRQ(ierr); 7017 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 7018 /* 7019 This should work, but it doesn't 7020 sctx->ctx = ctx; 7021 mexMakeArrayPersistent(sctx->ctx); 7022 */ 7023 sctx->ctx = mxDuplicateArray(ctx); 7024 7025 ierr = TSSetIFunction(ts,NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr); 7026 PetscFunctionReturn(0); 7027 } 7028 7029 /* 7030 TSComputeJacobian_Matlab - Calls the function that has been set with 7031 TSSetJacobianMatlab(). 7032 7033 Collective on TS 7034 7035 Input Parameters: 7036 + ts - the TS context 7037 . u - input vector 7038 . A, B - the matrices 7039 - ctx - user context 7040 7041 Level: developer 7042 7043 .keywords: TS, nonlinear, compute, function 7044 7045 .seealso: TSSetFunction(), TSGetFunction() 7046 @*/ 7047 PetscErrorCode TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat A,Mat B,void *ctx) 7048 { 7049 PetscErrorCode ierr; 7050 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 7051 int nlhs = 2,nrhs = 9; 7052 mxArray *plhs[2],*prhs[9]; 7053 long long int lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0; 7054 7055 PetscFunctionBegin; 7056 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7057 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 7058 7059 /* call Matlab function in ctx with arguments u and y */ 7060 7061 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 7062 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 7063 ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr); 7064 ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr); 7065 ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr); 7066 7067 prhs[0] = mxCreateDoubleScalar((double)ls); 7068 prhs[1] = mxCreateDoubleScalar((double)time); 7069 prhs[2] = mxCreateDoubleScalar((double)lx); 7070 prhs[3] = mxCreateDoubleScalar((double)lxdot); 7071 prhs[4] = mxCreateDoubleScalar((double)shift); 7072 prhs[5] = mxCreateDoubleScalar((double)lA); 7073 prhs[6] = mxCreateDoubleScalar((double)lB); 7074 prhs[7] = mxCreateString(sctx->funcname); 7075 prhs[8] = sctx->ctx; 7076 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr); 7077 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 7078 mxDestroyArray(prhs[0]); 7079 mxDestroyArray(prhs[1]); 7080 mxDestroyArray(prhs[2]); 7081 mxDestroyArray(prhs[3]); 7082 mxDestroyArray(prhs[4]); 7083 mxDestroyArray(prhs[5]); 7084 mxDestroyArray(prhs[6]); 7085 mxDestroyArray(prhs[7]); 7086 mxDestroyArray(plhs[0]); 7087 mxDestroyArray(plhs[1]); 7088 PetscFunctionReturn(0); 7089 } 7090 7091 /* 7092 TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 7093 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 7094 7095 Logically Collective on TS 7096 7097 Input Parameters: 7098 + ts - the TS context 7099 . A,B - Jacobian matrices 7100 . func - function evaluation routine 7101 - ctx - user context 7102 7103 Calling sequence of func: 7104 $ flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx); 7105 7106 Level: developer 7107 7108 .keywords: TS, nonlinear, set, function 7109 7110 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 7111 */ 7112 PetscErrorCode TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx) 7113 { 7114 PetscErrorCode ierr; 7115 TSMatlabContext *sctx; 7116 7117 PetscFunctionBegin; 7118 /* currently sctx is memory bleed */ 7119 ierr = PetscNew(&sctx);CHKERRQ(ierr); 7120 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 7121 /* 7122 This should work, but it doesn't 7123 sctx->ctx = ctx; 7124 mexMakeArrayPersistent(sctx->ctx); 7125 */ 7126 sctx->ctx = mxDuplicateArray(ctx); 7127 7128 ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 7129 PetscFunctionReturn(0); 7130 } 7131 7132 /* 7133 TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab(). 7134 7135 Collective on TS 7136 7137 .seealso: TSSetFunction(), TSGetFunction() 7138 @*/ 7139 PetscErrorCode TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx) 7140 { 7141 PetscErrorCode ierr; 7142 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 7143 int nlhs = 1,nrhs = 6; 7144 mxArray *plhs[1],*prhs[6]; 7145 long long int lx = 0,ls = 0; 7146 7147 PetscFunctionBegin; 7148 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7149 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 7150 7151 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 7152 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 7153 7154 prhs[0] = mxCreateDoubleScalar((double)ls); 7155 prhs[1] = mxCreateDoubleScalar((double)it); 7156 prhs[2] = mxCreateDoubleScalar((double)time); 7157 prhs[3] = mxCreateDoubleScalar((double)lx); 7158 prhs[4] = mxCreateString(sctx->funcname); 7159 prhs[5] = sctx->ctx; 7160 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr); 7161 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 7162 mxDestroyArray(prhs[0]); 7163 mxDestroyArray(prhs[1]); 7164 mxDestroyArray(prhs[2]); 7165 mxDestroyArray(prhs[3]); 7166 mxDestroyArray(prhs[4]); 7167 mxDestroyArray(plhs[0]); 7168 PetscFunctionReturn(0); 7169 } 7170 7171 /* 7172 TSMonitorSetMatlab - Sets the monitor function from Matlab 7173 7174 Level: developer 7175 7176 .keywords: TS, nonlinear, set, function 7177 7178 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 7179 */ 7180 PetscErrorCode TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx) 7181 { 7182 PetscErrorCode ierr; 7183 TSMatlabContext *sctx; 7184 7185 PetscFunctionBegin; 7186 /* currently sctx is memory bleed */ 7187 ierr = PetscNew(&sctx);CHKERRQ(ierr); 7188 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 7189 /* 7190 This should work, but it doesn't 7191 sctx->ctx = ctx; 7192 mexMakeArrayPersistent(sctx->ctx); 7193 */ 7194 sctx->ctx = mxDuplicateArray(ctx); 7195 7196 ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,NULL);CHKERRQ(ierr); 7197 PetscFunctionReturn(0); 7198 } 7199 #endif 7200 7201 /*@C 7202 TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector 7203 in a time based line graph 7204 7205 Collective on TS 7206 7207 Input Parameters: 7208 + ts - the TS context 7209 . step - current time-step 7210 . ptime - current time 7211 . u - current solution 7212 - dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate() 7213 7214 Options Database: 7215 . -ts_monitor_lg_solution_variables 7216 7217 Level: intermediate 7218 7219 Notes: Each process in a parallel run displays its component solutions in a separate window 7220 7221 .keywords: TS, vector, monitor, view 7222 7223 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(), 7224 TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(), 7225 TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(), 7226 TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop() 7227 @*/ 7228 PetscErrorCode TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 7229 { 7230 PetscErrorCode ierr; 7231 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dctx; 7232 const PetscScalar *yy; 7233 Vec v; 7234 7235 PetscFunctionBegin; 7236 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 7237 if (!step) { 7238 PetscDrawAxis axis; 7239 PetscInt dim; 7240 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 7241 ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr); 7242 if (!ctx->names) { 7243 PetscBool flg; 7244 /* user provides names of variables to plot but no names has been set so assume names are integer values */ 7245 ierr = PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg);CHKERRQ(ierr); 7246 if (flg) { 7247 PetscInt i,n; 7248 char **names; 7249 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 7250 ierr = PetscMalloc1(n+1,&names);CHKERRQ(ierr); 7251 for (i=0; i<n; i++) { 7252 ierr = PetscMalloc1(5,&names[i]);CHKERRQ(ierr); 7253 ierr = PetscSNPrintf(names[i],5,"%D",i);CHKERRQ(ierr); 7254 } 7255 names[n] = NULL; 7256 ctx->names = names; 7257 } 7258 } 7259 if (ctx->names && !ctx->displaynames) { 7260 char **displaynames; 7261 PetscBool flg; 7262 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 7263 ierr = PetscMalloc1(dim+1,&displaynames);CHKERRQ(ierr); 7264 ierr = PetscMemzero(displaynames,(dim+1)*sizeof(char*));CHKERRQ(ierr); 7265 ierr = PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg);CHKERRQ(ierr); 7266 if (flg) { 7267 ierr = TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames);CHKERRQ(ierr); 7268 } 7269 ierr = PetscStrArrayDestroy(&displaynames);CHKERRQ(ierr); 7270 } 7271 if (ctx->displaynames) { 7272 ierr = PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables);CHKERRQ(ierr); 7273 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames);CHKERRQ(ierr); 7274 } else if (ctx->names) { 7275 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 7276 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 7277 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names);CHKERRQ(ierr); 7278 } else { 7279 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 7280 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 7281 } 7282 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 7283 } 7284 7285 if (!ctx->transform) v = u; 7286 else {ierr = (*ctx->transform)(ctx->transformctx,u,&v);CHKERRQ(ierr);} 7287 ierr = VecGetArrayRead(v,&yy);CHKERRQ(ierr); 7288 if (ctx->displaynames) { 7289 PetscInt i; 7290 for (i=0; i<ctx->ndisplayvariables; i++) 7291 ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]); 7292 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues);CHKERRQ(ierr); 7293 } else { 7294 #if defined(PETSC_USE_COMPLEX) 7295 PetscInt i,n; 7296 PetscReal *yreal; 7297 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 7298 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 7299 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 7300 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 7301 ierr = PetscFree(yreal);CHKERRQ(ierr); 7302 #else 7303 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 7304 #endif 7305 } 7306 ierr = VecRestoreArrayRead(v,&yy);CHKERRQ(ierr); 7307 if (ctx->transform) {ierr = VecDestroy(&v);CHKERRQ(ierr);} 7308 7309 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 7310 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 7311 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 7312 } 7313 PetscFunctionReturn(0); 7314 } 7315 7316 /*@C 7317 TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 7318 7319 Collective on TS 7320 7321 Input Parameters: 7322 + ts - the TS context 7323 - names - the names of the components, final string must be NULL 7324 7325 Level: intermediate 7326 7327 Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 7328 7329 .keywords: TS, vector, monitor, view 7330 7331 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames() 7332 @*/ 7333 PetscErrorCode TSMonitorLGSetVariableNames(TS ts,const char * const *names) 7334 { 7335 PetscErrorCode ierr; 7336 PetscInt i; 7337 7338 PetscFunctionBegin; 7339 for (i=0; i<ts->numbermonitors; i++) { 7340 if (ts->monitor[i] == TSMonitorLGSolution) { 7341 ierr = TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names);CHKERRQ(ierr); 7342 break; 7343 } 7344 } 7345 PetscFunctionReturn(0); 7346 } 7347 7348 /*@C 7349 TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 7350 7351 Collective on TS 7352 7353 Input Parameters: 7354 + ts - the TS context 7355 - names - the names of the components, final string must be NULL 7356 7357 Level: intermediate 7358 7359 .keywords: TS, vector, monitor, view 7360 7361 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames() 7362 @*/ 7363 PetscErrorCode TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names) 7364 { 7365 PetscErrorCode ierr; 7366 7367 PetscFunctionBegin; 7368 ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr); 7369 ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr); 7370 PetscFunctionReturn(0); 7371 } 7372 7373 /*@C 7374 TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot 7375 7376 Collective on TS 7377 7378 Input Parameter: 7379 . ts - the TS context 7380 7381 Output Parameter: 7382 . names - the names of the components, final string must be NULL 7383 7384 Level: intermediate 7385 7386 Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 7387 7388 .keywords: TS, vector, monitor, view 7389 7390 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 7391 @*/ 7392 PetscErrorCode TSMonitorLGGetVariableNames(TS ts,const char *const **names) 7393 { 7394 PetscInt i; 7395 7396 PetscFunctionBegin; 7397 *names = NULL; 7398 for (i=0; i<ts->numbermonitors; i++) { 7399 if (ts->monitor[i] == TSMonitorLGSolution) { 7400 TSMonitorLGCtx ctx = (TSMonitorLGCtx) ts->monitorcontext[i]; 7401 *names = (const char *const *)ctx->names; 7402 break; 7403 } 7404 } 7405 PetscFunctionReturn(0); 7406 } 7407 7408 /*@C 7409 TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor 7410 7411 Collective on TS 7412 7413 Input Parameters: 7414 + ctx - the TSMonitorLG context 7415 . displaynames - the names of the components, final string must be NULL 7416 7417 Level: intermediate 7418 7419 .keywords: TS, vector, monitor, view 7420 7421 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 7422 @*/ 7423 PetscErrorCode TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames) 7424 { 7425 PetscInt j = 0,k; 7426 PetscErrorCode ierr; 7427 7428 PetscFunctionBegin; 7429 if (!ctx->names) PetscFunctionReturn(0); 7430 ierr = PetscStrArrayDestroy(&ctx->displaynames);CHKERRQ(ierr); 7431 ierr = PetscStrArrayallocpy(displaynames,&ctx->displaynames);CHKERRQ(ierr); 7432 while (displaynames[j]) j++; 7433 ctx->ndisplayvariables = j; 7434 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables);CHKERRQ(ierr); 7435 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues);CHKERRQ(ierr); 7436 j = 0; 7437 while (displaynames[j]) { 7438 k = 0; 7439 while (ctx->names[k]) { 7440 PetscBool flg; 7441 ierr = PetscStrcmp(displaynames[j],ctx->names[k],&flg);CHKERRQ(ierr); 7442 if (flg) { 7443 ctx->displayvariables[j] = k; 7444 break; 7445 } 7446 k++; 7447 } 7448 j++; 7449 } 7450 PetscFunctionReturn(0); 7451 } 7452 7453 /*@C 7454 TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor 7455 7456 Collective on TS 7457 7458 Input Parameters: 7459 + ts - the TS context 7460 . displaynames - the names of the components, final string must be NULL 7461 7462 Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 7463 7464 Level: intermediate 7465 7466 .keywords: TS, vector, monitor, view 7467 7468 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 7469 @*/ 7470 PetscErrorCode TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames) 7471 { 7472 PetscInt i; 7473 PetscErrorCode ierr; 7474 7475 PetscFunctionBegin; 7476 for (i=0; i<ts->numbermonitors; i++) { 7477 if (ts->monitor[i] == TSMonitorLGSolution) { 7478 ierr = TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames);CHKERRQ(ierr); 7479 break; 7480 } 7481 } 7482 PetscFunctionReturn(0); 7483 } 7484 7485 /*@C 7486 TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed 7487 7488 Collective on TS 7489 7490 Input Parameters: 7491 + ts - the TS context 7492 . transform - the transform function 7493 . destroy - function to destroy the optional context 7494 - ctx - optional context used by transform function 7495 7496 Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 7497 7498 Level: intermediate 7499 7500 .keywords: TS, vector, monitor, view 7501 7502 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform() 7503 @*/ 7504 PetscErrorCode TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 7505 { 7506 PetscInt i; 7507 PetscErrorCode ierr; 7508 7509 PetscFunctionBegin; 7510 for (i=0; i<ts->numbermonitors; i++) { 7511 if (ts->monitor[i] == TSMonitorLGSolution) { 7512 ierr = TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx);CHKERRQ(ierr); 7513 } 7514 } 7515 PetscFunctionReturn(0); 7516 } 7517 7518 /*@C 7519 TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed 7520 7521 Collective on TSLGCtx 7522 7523 Input Parameters: 7524 + ts - the TS context 7525 . transform - the transform function 7526 . destroy - function to destroy the optional context 7527 - ctx - optional context used by transform function 7528 7529 Level: intermediate 7530 7531 .keywords: TS, vector, monitor, view 7532 7533 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform() 7534 @*/ 7535 PetscErrorCode TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 7536 { 7537 PetscFunctionBegin; 7538 ctx->transform = transform; 7539 ctx->transformdestroy = destroy; 7540 ctx->transformctx = tctx; 7541 PetscFunctionReturn(0); 7542 } 7543 7544 /*@C 7545 TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the error 7546 in a time based line graph 7547 7548 Collective on TS 7549 7550 Input Parameters: 7551 + ts - the TS context 7552 . step - current time-step 7553 . ptime - current time 7554 . u - current solution 7555 - dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate() 7556 7557 Level: intermediate 7558 7559 Notes: Each process in a parallel run displays its component errors in a separate window 7560 7561 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 7562 7563 Options Database Keys: 7564 . -ts_monitor_lg_error - create a graphical monitor of error history 7565 7566 .keywords: TS, vector, monitor, view 7567 7568 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 7569 @*/ 7570 PetscErrorCode TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 7571 { 7572 PetscErrorCode ierr; 7573 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 7574 const PetscScalar *yy; 7575 Vec y; 7576 7577 PetscFunctionBegin; 7578 if (!step) { 7579 PetscDrawAxis axis; 7580 PetscInt dim; 7581 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 7582 ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Error");CHKERRQ(ierr); 7583 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 7584 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 7585 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 7586 } 7587 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 7588 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 7589 ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr); 7590 ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr); 7591 #if defined(PETSC_USE_COMPLEX) 7592 { 7593 PetscReal *yreal; 7594 PetscInt i,n; 7595 ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr); 7596 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 7597 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 7598 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 7599 ierr = PetscFree(yreal);CHKERRQ(ierr); 7600 } 7601 #else 7602 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 7603 #endif 7604 ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr); 7605 ierr = VecDestroy(&y);CHKERRQ(ierr); 7606 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 7607 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 7608 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 7609 } 7610 PetscFunctionReturn(0); 7611 } 7612 7613 /*@C 7614 TSMonitorError - Monitors progress of the TS solvers by printing the 2 norm of the error at each timestep 7615 7616 Collective on TS 7617 7618 Input Parameters: 7619 + ts - the TS context 7620 . step - current time-step 7621 . ptime - current time 7622 . u - current solution 7623 - dctx - unused context 7624 7625 Level: intermediate 7626 7627 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 7628 7629 Options Database Keys: 7630 . -ts_monitor_error - create a graphical monitor of error history 7631 7632 .keywords: TS, vector, monitor, view 7633 7634 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 7635 @*/ 7636 PetscErrorCode TSMonitorError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 7637 { 7638 PetscErrorCode ierr; 7639 Vec y; 7640 PetscReal nrm; 7641 7642 PetscFunctionBegin; 7643 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 7644 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 7645 ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr); 7646 ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 7647 ierr = PetscPrintf(PetscObjectComm((PetscObject)ts),"2-norm of error %g\n",(double)nrm);CHKERRQ(ierr); 7648 PetscFunctionReturn(0); 7649 } 7650 7651 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 7652 { 7653 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 7654 PetscReal x = ptime,y; 7655 PetscErrorCode ierr; 7656 PetscInt its; 7657 7658 PetscFunctionBegin; 7659 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 7660 if (!n) { 7661 PetscDrawAxis axis; 7662 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 7663 ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr); 7664 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 7665 ctx->snes_its = 0; 7666 } 7667 ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr); 7668 y = its - ctx->snes_its; 7669 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 7670 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 7671 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 7672 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 7673 } 7674 ctx->snes_its = its; 7675 PetscFunctionReturn(0); 7676 } 7677 7678 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 7679 { 7680 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 7681 PetscReal x = ptime,y; 7682 PetscErrorCode ierr; 7683 PetscInt its; 7684 7685 PetscFunctionBegin; 7686 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 7687 if (!n) { 7688 PetscDrawAxis axis; 7689 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 7690 ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr); 7691 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 7692 ctx->ksp_its = 0; 7693 } 7694 ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr); 7695 y = its - ctx->ksp_its; 7696 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 7697 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 7698 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 7699 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 7700 } 7701 ctx->ksp_its = its; 7702 PetscFunctionReturn(0); 7703 } 7704 7705 /*@ 7706 TSComputeLinearStability - computes the linear stability function at a point 7707 7708 Collective on TS and Vec 7709 7710 Input Parameters: 7711 + ts - the TS context 7712 - xr,xi - real and imaginary part of input arguments 7713 7714 Output Parameters: 7715 . yr,yi - real and imaginary part of function value 7716 7717 Level: developer 7718 7719 .keywords: TS, compute 7720 7721 .seealso: TSSetRHSFunction(), TSComputeIFunction() 7722 @*/ 7723 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi) 7724 { 7725 PetscErrorCode ierr; 7726 7727 PetscFunctionBegin; 7728 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7729 if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method"); 7730 ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr); 7731 PetscFunctionReturn(0); 7732 } 7733 7734 /* ------------------------------------------------------------------------*/ 7735 /*@C 7736 TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope() 7737 7738 Collective on TS 7739 7740 Input Parameters: 7741 . ts - the ODE solver object 7742 7743 Output Parameter: 7744 . ctx - the context 7745 7746 Level: intermediate 7747 7748 .keywords: TS, monitor, line graph, residual, seealso 7749 7750 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError() 7751 7752 @*/ 7753 PetscErrorCode TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx) 7754 { 7755 PetscErrorCode ierr; 7756 7757 PetscFunctionBegin; 7758 ierr = PetscNew(ctx);CHKERRQ(ierr); 7759 PetscFunctionReturn(0); 7760 } 7761 7762 /*@C 7763 TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution 7764 7765 Collective on TS 7766 7767 Input Parameters: 7768 + ts - the TS context 7769 . step - current time-step 7770 . ptime - current time 7771 . u - current solution 7772 - dctx - the envelope context 7773 7774 Options Database: 7775 . -ts_monitor_envelope 7776 7777 Level: intermediate 7778 7779 Notes: after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope 7780 7781 .keywords: TS, vector, monitor, view 7782 7783 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxCreate() 7784 @*/ 7785 PetscErrorCode TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 7786 { 7787 PetscErrorCode ierr; 7788 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx; 7789 7790 PetscFunctionBegin; 7791 if (!ctx->max) { 7792 ierr = VecDuplicate(u,&ctx->max);CHKERRQ(ierr); 7793 ierr = VecDuplicate(u,&ctx->min);CHKERRQ(ierr); 7794 ierr = VecCopy(u,ctx->max);CHKERRQ(ierr); 7795 ierr = VecCopy(u,ctx->min);CHKERRQ(ierr); 7796 } else { 7797 ierr = VecPointwiseMax(ctx->max,u,ctx->max);CHKERRQ(ierr); 7798 ierr = VecPointwiseMin(ctx->min,u,ctx->min);CHKERRQ(ierr); 7799 } 7800 PetscFunctionReturn(0); 7801 } 7802 7803 /*@C 7804 TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution 7805 7806 Collective on TS 7807 7808 Input Parameter: 7809 . ts - the TS context 7810 7811 Output Parameter: 7812 + max - the maximum values 7813 - min - the minimum values 7814 7815 Notes: If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored 7816 7817 Level: intermediate 7818 7819 .keywords: TS, vector, monitor, view 7820 7821 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 7822 @*/ 7823 PetscErrorCode TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min) 7824 { 7825 PetscInt i; 7826 7827 PetscFunctionBegin; 7828 if (max) *max = NULL; 7829 if (min) *min = NULL; 7830 for (i=0; i<ts->numbermonitors; i++) { 7831 if (ts->monitor[i] == TSMonitorEnvelope) { 7832 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i]; 7833 if (max) *max = ctx->max; 7834 if (min) *min = ctx->min; 7835 break; 7836 } 7837 } 7838 PetscFunctionReturn(0); 7839 } 7840 7841 /*@C 7842 TSMonitorEnvelopeCtxDestroy - Destroys a context that was created with TSMonitorEnvelopeCtxCreate(). 7843 7844 Collective on TSMonitorEnvelopeCtx 7845 7846 Input Parameter: 7847 . ctx - the monitor context 7848 7849 Level: intermediate 7850 7851 .keywords: TS, monitor, line graph, destroy 7852 7853 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep() 7854 @*/ 7855 PetscErrorCode TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx) 7856 { 7857 PetscErrorCode ierr; 7858 7859 PetscFunctionBegin; 7860 ierr = VecDestroy(&(*ctx)->min);CHKERRQ(ierr); 7861 ierr = VecDestroy(&(*ctx)->max);CHKERRQ(ierr); 7862 ierr = PetscFree(*ctx);CHKERRQ(ierr); 7863 PetscFunctionReturn(0); 7864 } 7865 7866 /*@ 7867 TSRestartStep - Flags the solver to restart the next step 7868 7869 Collective on TS 7870 7871 Input Parameter: 7872 . ts - the TS context obtained from TSCreate() 7873 7874 Level: advanced 7875 7876 Notes: 7877 Multistep methods like BDF or Runge-Kutta methods with FSAL property require restarting the solver in the event of 7878 discontinuities. These discontinuities may be introduced as a consequence of explicitly modifications to the solution 7879 vector (which PETSc attempts to detect and handle) or problem coefficients (which PETSc is not able to detect). For 7880 the sake of correctness and maximum safety, users are expected to call TSRestart() whenever they introduce 7881 discontinuities in callback routines (e.g. prestep and poststep routines, or implicit/rhs function routines with 7882 discontinuous source terms). 7883 7884 .keywords: TS, timestep, restart 7885 7886 .seealso: TSSolve(), TSSetPreStep(), TSSetPostStep() 7887 @*/ 7888 PetscErrorCode TSRestartStep(TS ts) 7889 { 7890 PetscFunctionBegin; 7891 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7892 ts->steprestart = PETSC_TRUE; 7893 PetscFunctionReturn(0); 7894 } 7895 7896 /*@ 7897 TSRollBack - Rolls back one time step 7898 7899 Collective on TS 7900 7901 Input Parameter: 7902 . ts - the TS context obtained from TSCreate() 7903 7904 Level: advanced 7905 7906 .keywords: TS, timestep, rollback 7907 7908 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate() 7909 @*/ 7910 PetscErrorCode TSRollBack(TS ts) 7911 { 7912 PetscErrorCode ierr; 7913 7914 PetscFunctionBegin; 7915 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7916 if (ts->steprollback) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"TSRollBack already called"); 7917 if (!ts->ops->rollback) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name); 7918 ierr = (*ts->ops->rollback)(ts);CHKERRQ(ierr); 7919 ts->time_step = ts->ptime - ts->ptime_prev; 7920 ts->ptime = ts->ptime_prev; 7921 ts->ptime_prev = ts->ptime_prev_rollback; 7922 ts->steps--; 7923 ts->steprollback = PETSC_TRUE; 7924 PetscFunctionReturn(0); 7925 } 7926 7927 /*@ 7928 TSGetStages - Get the number of stages and stage values 7929 7930 Input Parameter: 7931 . ts - the TS context obtained from TSCreate() 7932 7933 Level: advanced 7934 7935 .keywords: TS, getstages 7936 7937 .seealso: TSCreate() 7938 @*/ 7939 PetscErrorCode TSGetStages(TS ts,PetscInt *ns,Vec **Y) 7940 { 7941 PetscErrorCode ierr; 7942 7943 PetscFunctionBegin; 7944 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7945 PetscValidPointer(ns,2); 7946 7947 if (!ts->ops->getstages) *ns=0; 7948 else { 7949 ierr = (*ts->ops->getstages)(ts,ns,Y);CHKERRQ(ierr); 7950 } 7951 PetscFunctionReturn(0); 7952 } 7953 7954 /*@C 7955 TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity. 7956 7957 Collective on SNES 7958 7959 Input Parameters: 7960 + ts - the TS context 7961 . t - current timestep 7962 . U - state vector 7963 . Udot - time derivative of state vector 7964 . shift - shift to apply, see note below 7965 - ctx - an optional user context 7966 7967 Output Parameters: 7968 + J - Jacobian matrix (not altered in this routine) 7969 - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J) 7970 7971 Level: intermediate 7972 7973 Notes: 7974 If F(t,U,Udot)=0 is the DAE, the required Jacobian is 7975 7976 dF/dU + shift*dF/dUdot 7977 7978 Most users should not need to explicitly call this routine, as it 7979 is used internally within the nonlinear solvers. 7980 7981 This will first try to get the coloring from the DM. If the DM type has no coloring 7982 routine, then it will try to get the coloring from the matrix. This requires that the 7983 matrix have nonzero entries precomputed. 7984 7985 .keywords: TS, finite differences, Jacobian, coloring, sparse 7986 .seealso: TSSetIJacobian(), MatFDColoringCreate(), MatFDColoringSetFunction() 7987 @*/ 7988 PetscErrorCode TSComputeIJacobianDefaultColor(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat J,Mat B,void *ctx) 7989 { 7990 SNES snes; 7991 MatFDColoring color; 7992 PetscBool hascolor, matcolor = PETSC_FALSE; 7993 PetscErrorCode ierr; 7994 7995 PetscFunctionBegin; 7996 ierr = PetscOptionsGetBool(((PetscObject)ts)->options,((PetscObject) ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL);CHKERRQ(ierr); 7997 ierr = PetscObjectQuery((PetscObject) B, "TSMatFDColoring", (PetscObject *) &color);CHKERRQ(ierr); 7998 if (!color) { 7999 DM dm; 8000 ISColoring iscoloring; 8001 8002 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 8003 ierr = DMHasColoring(dm, &hascolor);CHKERRQ(ierr); 8004 if (hascolor && !matcolor) { 8005 ierr = DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring);CHKERRQ(ierr); 8006 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 8007 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 8008 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 8009 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 8010 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 8011 } else { 8012 MatColoring mc; 8013 8014 ierr = MatColoringCreate(B, &mc);CHKERRQ(ierr); 8015 ierr = MatColoringSetDistance(mc, 2);CHKERRQ(ierr); 8016 ierr = MatColoringSetType(mc, MATCOLORINGSL);CHKERRQ(ierr); 8017 ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); 8018 ierr = MatColoringApply(mc, &iscoloring);CHKERRQ(ierr); 8019 ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); 8020 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 8021 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 8022 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 8023 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 8024 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 8025 } 8026 ierr = PetscObjectCompose((PetscObject) B, "TSMatFDColoring", (PetscObject) color);CHKERRQ(ierr); 8027 ierr = PetscObjectDereference((PetscObject) color);CHKERRQ(ierr); 8028 } 8029 ierr = TSGetSNES(ts, &snes);CHKERRQ(ierr); 8030 ierr = MatFDColoringApply(B, color, U, snes);CHKERRQ(ierr); 8031 if (J != B) { 8032 ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 8033 ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 8034 } 8035 PetscFunctionReturn(0); 8036 } 8037 8038 /*@ 8039 TSSetFunctionDomainError - Set the function testing if the current state vector is valid 8040 8041 Input Parameters: 8042 ts - the TS context 8043 func - function called within TSFunctionDomainError 8044 8045 Level: intermediate 8046 8047 .keywords: TS, state, domain 8048 .seealso: TSAdaptCheckStage(), TSFunctionDomainError() 8049 @*/ 8050 8051 PetscErrorCode TSSetFunctionDomainError(TS ts, PetscErrorCode (*func)(TS,PetscReal,Vec,PetscBool*)) 8052 { 8053 PetscFunctionBegin; 8054 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 8055 ts->functiondomainerror = func; 8056 PetscFunctionReturn(0); 8057 } 8058 8059 /*@ 8060 TSFunctionDomainError - Check if the current state is valid 8061 8062 Input Parameters: 8063 ts - the TS context 8064 stagetime - time of the simulation 8065 Y - state vector to check. 8066 8067 Output Parameter: 8068 accept - Set to PETSC_FALSE if the current state vector is valid. 8069 8070 Note: 8071 This function should be used to ensure the state is in a valid part of the space. 8072 For example, one can ensure here all values are positive. 8073 8074 Level: advanced 8075 @*/ 8076 PetscErrorCode TSFunctionDomainError(TS ts,PetscReal stagetime,Vec Y,PetscBool* accept) 8077 { 8078 PetscErrorCode ierr; 8079 8080 PetscFunctionBegin; 8081 8082 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 8083 *accept = PETSC_TRUE; 8084 if (ts->functiondomainerror) { 8085 PetscStackCallStandard((*ts->functiondomainerror),(ts,stagetime,Y,accept)); 8086 } 8087 PetscFunctionReturn(0); 8088 } 8089 8090 /*@C 8091 TSClone - This function clones a time step object. 8092 8093 Collective on MPI_Comm 8094 8095 Input Parameter: 8096 . tsin - The input TS 8097 8098 Output Parameter: 8099 . tsout - The output TS (cloned) 8100 8101 Notes: 8102 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. 8103 8104 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); 8105 8106 Level: developer 8107 8108 .keywords: TS, clone 8109 .seealso: TSCreate(), TSSetType(), TSSetUp(), TSDestroy(), TSSetProblemType() 8110 @*/ 8111 PetscErrorCode TSClone(TS tsin, TS *tsout) 8112 { 8113 TS t; 8114 PetscErrorCode ierr; 8115 SNES snes_start; 8116 DM dm; 8117 TSType type; 8118 8119 PetscFunctionBegin; 8120 PetscValidPointer(tsin,1); 8121 *tsout = NULL; 8122 8123 ierr = PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView);CHKERRQ(ierr); 8124 8125 /* General TS description */ 8126 t->numbermonitors = 0; 8127 t->setupcalled = 0; 8128 t->ksp_its = 0; 8129 t->snes_its = 0; 8130 t->nwork = 0; 8131 t->rhsjacobian.time = -1e20; 8132 t->rhsjacobian.scale = 1.; 8133 t->ijacobian.shift = 1.; 8134 8135 ierr = TSGetSNES(tsin,&snes_start);CHKERRQ(ierr); 8136 ierr = TSSetSNES(t,snes_start);CHKERRQ(ierr); 8137 8138 ierr = TSGetDM(tsin,&dm);CHKERRQ(ierr); 8139 ierr = TSSetDM(t,dm);CHKERRQ(ierr); 8140 8141 t->adapt = tsin->adapt; 8142 ierr = PetscObjectReference((PetscObject)t->adapt);CHKERRQ(ierr); 8143 8144 t->trajectory = tsin->trajectory; 8145 ierr = PetscObjectReference((PetscObject)t->trajectory);CHKERRQ(ierr); 8146 8147 t->event = tsin->event; 8148 if (t->event) t->event->refct++; 8149 8150 t->problem_type = tsin->problem_type; 8151 t->ptime = tsin->ptime; 8152 t->ptime_prev = tsin->ptime_prev; 8153 t->time_step = tsin->time_step; 8154 t->max_time = tsin->max_time; 8155 t->steps = tsin->steps; 8156 t->max_steps = tsin->max_steps; 8157 t->equation_type = tsin->equation_type; 8158 t->atol = tsin->atol; 8159 t->rtol = tsin->rtol; 8160 t->max_snes_failures = tsin->max_snes_failures; 8161 t->max_reject = tsin->max_reject; 8162 t->errorifstepfailed = tsin->errorifstepfailed; 8163 8164 ierr = TSGetType(tsin,&type);CHKERRQ(ierr); 8165 ierr = TSSetType(t,type);CHKERRQ(ierr); 8166 8167 t->vec_sol = NULL; 8168 8169 t->cfltime = tsin->cfltime; 8170 t->cfltime_local = tsin->cfltime_local; 8171 t->exact_final_time = tsin->exact_final_time; 8172 8173 ierr = PetscMemcpy(t->ops,tsin->ops,sizeof(struct _TSOps));CHKERRQ(ierr); 8174 8175 if (((PetscObject)tsin)->fortran_func_pointers) { 8176 PetscInt i; 8177 ierr = PetscMalloc((10)*sizeof(void(*)(void)),&((PetscObject)t)->fortran_func_pointers);CHKERRQ(ierr); 8178 for (i=0; i<10; i++) { 8179 ((PetscObject)t)->fortran_func_pointers[i] = ((PetscObject)tsin)->fortran_func_pointers[i]; 8180 } 8181 } 8182 *tsout = t; 8183 PetscFunctionReturn(0); 8184 } 8185