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