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