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