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