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