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