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