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