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