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