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_Step, TS_PseudoComputeTimeStep, TS_FunctionEval, TS_JacobianEval; 11 12 const char *const TSExactFinalTimeOptions[] = {"STEPOVER","INTERPOLATE","MATCHSTEP","TSExactFinalTimeOption","TS_EXACTFINALTIME_",0}; 13 14 struct _n_TSMonitorDrawCtx { 15 PetscViewer viewer; 16 PetscDrawAxis axis; 17 Vec initialsolution; 18 PetscBool showinitial; 19 PetscInt howoften; /* when > 0 uses step % howoften, when negative only final solution plotted */ 20 PetscBool showtimestepandtime; 21 int color; 22 }; 23 24 #undef __FUNCT__ 25 #define __FUNCT__ "TSSetFromOptions" 26 /*@ 27 TSSetFromOptions - Sets various TS parameters from user options. 28 29 Collective on TS 30 31 Input Parameter: 32 . ts - the TS context obtained from TSCreate() 33 34 Options Database Keys: 35 + -ts_type <type> - TSEULER, TSBEULER, TSSUNDIALS, TSPSEUDO, TSCN, TSRK, TSTHETA, TSGL, TSSSP 36 . -ts_checkpoint - checkpoint for adjoint sensitivity analysis 37 . -ts_max_steps maxsteps - maximum number of time-steps to take 38 . -ts_final_time time - maximum time to compute to 39 . -ts_dt dt - initial time step 40 . -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 41 . -ts_max_snes_failures <maxfailures> - Maximum number of nonlinear solve failures allowed 42 . -ts_max_reject <maxrejects> - Maximum number of step rejections before step fails 43 . -ts_error_if_step_fails <true,false> - Error if no step succeeds 44 . -ts_rtol <rtol> - relative tolerance for local truncation error 45 . -ts_atol <atol> Absolute tolerance for local truncation error 46 . -ts_fd_color - Use finite differences with coloring to compute IJacobian 47 . -ts_monitor - print information at each timestep 48 . -ts_monitor_lg_timestep - Monitor timestep size graphically 49 . -ts_monitor_lg_solution - Monitor solution graphically 50 . -ts_monitor_lg_error - Monitor error graphically 51 . -ts_monitor_lg_snes_iterations - Monitor number nonlinear iterations for each timestep graphically 52 . -ts_monitor_lg_ksp_iterations - Monitor number nonlinear iterations for each timestep graphically 53 . -ts_monitor_sp_eig - Monitor eigenvalues of linearized operator graphically 54 . -ts_monitor_draw_solution - Monitor solution graphically 55 . -ts_monitor_draw_solution_phase - Monitor solution graphically with phase diagram 56 . -ts_monitor_draw_error - Monitor error graphically 57 . -ts_monitor_solution_binary <filename> - Save each solution to a binary file 58 - -ts_monitor_solution_vtk <filename.vts> - Save each time step to a binary file, use filename-%%03D.vts 59 60 Developer Note: We should unify all the -ts_monitor options in the way that -xxx_view has been unified 61 62 Level: beginner 63 64 .keywords: TS, timestep, set, options, database 65 66 .seealso: TSGetType() 67 @*/ 68 PetscErrorCode TSSetFromOptions(TS ts) 69 { 70 PetscBool opt,flg,tflg; 71 PetscErrorCode ierr; 72 PetscViewer monviewer; 73 char monfilename[PETSC_MAX_PATH_LEN]; 74 SNES snes; 75 TSAdapt adapt; 76 PetscReal time_step; 77 TSExactFinalTimeOption eftopt; 78 char dir[16]; 79 const char *defaultType; 80 char typeName[256]; 81 82 PetscFunctionBegin; 83 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 84 ierr = PetscObjectOptionsBegin((PetscObject)ts);CHKERRQ(ierr); 85 if (((PetscObject)ts)->type_name) defaultType = ((PetscObject)ts)->type_name; 86 else defaultType = TSEULER; 87 88 ierr = TSRegisterAll();CHKERRQ(ierr); 89 ierr = PetscOptionsFList("-ts_type", "TS method"," TSSetType", TSList, defaultType, typeName, 256, &opt);CHKERRQ(ierr); 90 if (opt) { 91 ierr = TSSetType(ts, typeName);CHKERRQ(ierr); 92 } else { 93 ierr = TSSetType(ts, defaultType);CHKERRQ(ierr); 94 } 95 96 /* Handle generic TS options */ 97 if (ts->trajectory) tflg = PETSC_TRUE; 98 else tflg = PETSC_FALSE; 99 ierr = PetscOptionsBool("-ts_save_trajectories","Checkpoint for adjoint sensitivity analysis","TSSetSaveTrajectories",tflg,&tflg,NULL);CHKERRQ(ierr); 100 if (tflg) {ierr = TSSetSaveTrajectory(ts);CHKERRQ(ierr);} 101 ierr = PetscOptionsInt("-ts_max_steps","Maximum number of time steps","TSSetDuration",ts->max_steps,&ts->max_steps,NULL);CHKERRQ(ierr); 102 ierr = PetscOptionsReal("-ts_final_time","Time to run to","TSSetDuration",ts->max_time,&ts->max_time,NULL);CHKERRQ(ierr); 103 ierr = PetscOptionsReal("-ts_init_time","Initial time","TSSetTime",ts->ptime,&ts->ptime,NULL);CHKERRQ(ierr); 104 ierr = PetscOptionsReal("-ts_dt","Initial time step","TSSetTimeStep",ts->time_step,&time_step,&flg);CHKERRQ(ierr); 105 if (flg) { 106 ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr); 107 } 108 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); 109 if (flg) {ierr = TSSetExactFinalTime(ts,eftopt);CHKERRQ(ierr);} 110 ierr = PetscOptionsInt("-ts_max_snes_failures","Maximum number of nonlinear solve failures","TSSetMaxSNESFailures",ts->max_snes_failures,&ts->max_snes_failures,NULL);CHKERRQ(ierr); 111 ierr = PetscOptionsInt("-ts_max_reject","Maximum number of step rejections before step fails","TSSetMaxStepRejections",ts->max_reject,&ts->max_reject,NULL);CHKERRQ(ierr); 112 ierr = PetscOptionsBool("-ts_error_if_step_fails","Error if no step succeeds","TSSetErrorIfStepFails",ts->errorifstepfailed,&ts->errorifstepfailed,NULL);CHKERRQ(ierr); 113 ierr = PetscOptionsReal("-ts_rtol","Relative tolerance for local truncation error","TSSetTolerances",ts->rtol,&ts->rtol,NULL);CHKERRQ(ierr); 114 ierr = PetscOptionsReal("-ts_atol","Absolute tolerance for local truncation error","TSSetTolerances",ts->atol,&ts->atol,NULL);CHKERRQ(ierr); 115 116 #if defined(PETSC_HAVE_SAWS) 117 { 118 PetscBool set; 119 flg = PETSC_FALSE; 120 ierr = PetscOptionsBool("-ts_saws_block","Block for SAWs memory snooper at end of TSSolve","PetscObjectSAWsBlock",((PetscObject)ts)->amspublishblock,&flg,&set);CHKERRQ(ierr); 121 if (set) { 122 ierr = PetscObjectSAWsSetBlock((PetscObject)ts,flg);CHKERRQ(ierr); 123 } 124 } 125 #endif 126 127 /* Monitor options */ 128 ierr = PetscOptionsString("-ts_monitor","Monitor timestep size","TSMonitorDefault","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 129 if (flg) { 130 ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ts),monfilename,&monviewer);CHKERRQ(ierr); 131 ierr = TSMonitorSet(ts,TSMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 132 } 133 ierr = PetscOptionsString("-ts_monitor_python","Use Python function","TSMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 134 if (flg) {ierr = PetscPythonMonitorSet((PetscObject)ts,monfilename);CHKERRQ(ierr);} 135 136 ierr = PetscOptionsName("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",&opt);CHKERRQ(ierr); 137 if (opt) { 138 TSMonitorLGCtx ctx; 139 PetscInt howoften = 1; 140 141 ierr = PetscOptionsInt("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",howoften,&howoften,NULL);CHKERRQ(ierr); 142 ierr = TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 143 ierr = TSMonitorSet(ts,TSMonitorLGTimeStep,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 144 } 145 ierr = PetscOptionsName("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",&opt);CHKERRQ(ierr); 146 if (opt) { 147 TSMonitorLGCtx ctx; 148 PetscInt howoften = 1; 149 150 ierr = PetscOptionsInt("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",howoften,&howoften,NULL);CHKERRQ(ierr); 151 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr); 152 ierr = TSMonitorSet(ts,TSMonitorLGSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 153 } 154 ierr = PetscOptionsName("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",&opt);CHKERRQ(ierr); 155 if (opt) { 156 TSMonitorLGCtx ctx; 157 PetscInt howoften = 1; 158 159 ierr = PetscOptionsInt("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",howoften,&howoften,NULL);CHKERRQ(ierr); 160 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr); 161 ierr = TSMonitorSet(ts,TSMonitorLGError,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 162 } 163 ierr = PetscOptionsName("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",&opt);CHKERRQ(ierr); 164 if (opt) { 165 TSMonitorLGCtx ctx; 166 PetscInt howoften = 1; 167 168 ierr = PetscOptionsInt("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",howoften,&howoften,NULL);CHKERRQ(ierr); 169 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 170 ierr = TSMonitorSet(ts,TSMonitorLGSNESIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 171 } 172 ierr = PetscOptionsName("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",&opt);CHKERRQ(ierr); 173 if (opt) { 174 TSMonitorLGCtx ctx; 175 PetscInt howoften = 1; 176 177 ierr = PetscOptionsInt("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",howoften,&howoften,NULL);CHKERRQ(ierr); 178 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr); 179 ierr = TSMonitorSet(ts,TSMonitorLGKSPIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); 180 } 181 ierr = PetscOptionsName("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",&opt);CHKERRQ(ierr); 182 if (opt) { 183 TSMonitorSPEigCtx ctx; 184 PetscInt howoften = 1; 185 186 ierr = PetscOptionsInt("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",howoften,&howoften,NULL);CHKERRQ(ierr); 187 ierr = TSMonitorSPEigCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr); 188 ierr = TSMonitorSet(ts,TSMonitorSPEig,ctx,(PetscErrorCode (*)(void**))TSMonitorSPEigCtxDestroy);CHKERRQ(ierr); 189 } 190 opt = PETSC_FALSE; 191 ierr = PetscOptionsName("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",&opt);CHKERRQ(ierr); 192 if (opt) { 193 TSMonitorDrawCtx ctx; 194 PetscInt howoften = 1; 195 196 ierr = PetscOptionsInt("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",howoften,&howoften,NULL);CHKERRQ(ierr); 197 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr); 198 ierr = TSMonitorSet(ts,TSMonitorDrawSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 199 } 200 opt = PETSC_FALSE; 201 ierr = PetscOptionsName("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",&opt);CHKERRQ(ierr); 202 if (opt) { 203 TSMonitorDrawCtx ctx; 204 PetscReal bounds[4]; 205 PetscInt n = 4; 206 PetscDraw draw; 207 208 ierr = PetscOptionsRealArray("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",bounds,&n,NULL);CHKERRQ(ierr); 209 if (n != 4) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Must provide bounding box of phase field"); 210 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,1,&ctx);CHKERRQ(ierr); 211 ierr = PetscViewerDrawGetDraw(ctx->viewer,0,&draw);CHKERRQ(ierr); 212 ierr = PetscDrawClear(draw);CHKERRQ(ierr); 213 ierr = PetscDrawAxisCreate(draw,&ctx->axis);CHKERRQ(ierr); 214 ierr = PetscDrawAxisSetLimits(ctx->axis,bounds[0],bounds[2],bounds[1],bounds[3]);CHKERRQ(ierr); 215 ierr = PetscDrawAxisSetLabels(ctx->axis,"Phase Diagram","Variable 1","Variable 2");CHKERRQ(ierr); 216 ierr = PetscDrawAxisDraw(ctx->axis);CHKERRQ(ierr); 217 /* ierr = PetscDrawSetCoordinates(draw,bounds[0],bounds[1],bounds[2],bounds[3]);CHKERRQ(ierr); */ 218 ierr = TSMonitorSet(ts,TSMonitorDrawSolutionPhase,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 219 } 220 opt = PETSC_FALSE; 221 ierr = PetscOptionsName("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",&opt);CHKERRQ(ierr); 222 if (opt) { 223 TSMonitorDrawCtx ctx; 224 PetscInt howoften = 1; 225 226 ierr = PetscOptionsInt("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",howoften,&howoften,NULL);CHKERRQ(ierr); 227 ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr); 228 ierr = TSMonitorSet(ts,TSMonitorDrawError,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr); 229 } 230 opt = PETSC_FALSE; 231 ierr = PetscOptionsString("-ts_monitor_solution_binary","Save each solution to a binary file","TSMonitorSolutionBinary",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 232 if (flg) { 233 PetscViewer ctx; 234 if (monfilename[0]) { 235 ierr = PetscViewerBinaryOpen(PetscObjectComm((PetscObject)ts),monfilename,FILE_MODE_WRITE,&ctx);CHKERRQ(ierr); 236 ierr = TSMonitorSet(ts,TSMonitorSolutionBinary,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 237 } else { 238 ctx = PETSC_VIEWER_BINARY_(PetscObjectComm((PetscObject)ts)); 239 ierr = TSMonitorSet(ts,TSMonitorSolutionBinary,ctx,(PetscErrorCode (*)(void**))NULL);CHKERRQ(ierr); 240 } 241 } 242 opt = PETSC_FALSE; 243 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); 244 if (flg) { 245 const char *ptr,*ptr2; 246 char *filetemplate; 247 if (!monfilename[0]) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts"); 248 /* Do some cursory validation of the input. */ 249 ierr = PetscStrstr(monfilename,"%",(char**)&ptr);CHKERRQ(ierr); 250 if (!ptr) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts"); 251 for (ptr++; ptr && *ptr; ptr++) { 252 ierr = PetscStrchr("DdiouxX",*ptr,(char**)&ptr2);CHKERRQ(ierr); 253 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"); 254 if (ptr2) break; 255 } 256 ierr = PetscStrallocpy(monfilename,&filetemplate);CHKERRQ(ierr); 257 ierr = TSMonitorSet(ts,TSMonitorSolutionVTK,filetemplate,(PetscErrorCode (*)(void**))TSMonitorSolutionVTKDestroy);CHKERRQ(ierr); 258 } 259 260 ierr = PetscOptionsString("-ts_monitor_dmda_ray","Display a ray of the solution","None","y=0",dir,16,&flg);CHKERRQ(ierr); 261 if (flg) { 262 TSMonitorDMDARayCtx *rayctx; 263 int ray = 0; 264 DMDADirection ddir; 265 DM da; 266 PetscMPIInt rank; 267 268 if (dir[1] != '=') SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir); 269 if (dir[0] == 'x') ddir = DMDA_X; 270 else if (dir[0] == 'y') ddir = DMDA_Y; 271 else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir); 272 sscanf(dir+2,"%d",&ray); 273 274 ierr = PetscInfo2(((PetscObject)ts),"Displaying DMDA ray %c = %D\n",dir[0],ray);CHKERRQ(ierr); 275 ierr = PetscNew(&rayctx);CHKERRQ(ierr); 276 ierr = TSGetDM(ts,&da);CHKERRQ(ierr); 277 ierr = DMDAGetRay(da,ddir,ray,&rayctx->ray,&rayctx->scatter);CHKERRQ(ierr); 278 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)ts),&rank);CHKERRQ(ierr); 279 if (!rank) { 280 ierr = PetscViewerDrawOpen(PETSC_COMM_SELF,0,0,0,0,600,300,&rayctx->viewer);CHKERRQ(ierr); 281 } 282 rayctx->lgctx = NULL; 283 ierr = TSMonitorSet(ts,TSMonitorDMDARay,rayctx,TSMonitorDMDARayDestroy);CHKERRQ(ierr); 284 } 285 ierr = PetscOptionsString("-ts_monitor_lg_dmda_ray","Display a ray of the solution","None","x=0",dir,16,&flg);CHKERRQ(ierr); 286 if (flg) { 287 TSMonitorDMDARayCtx *rayctx; 288 int ray = 0; 289 DMDADirection ddir; 290 DM da; 291 PetscInt howoften = 1; 292 293 if (dir[1] != '=') SETERRQ1(PetscObjectComm((PetscObject) ts), PETSC_ERR_ARG_WRONG, "Malformed ray %s", dir); 294 if (dir[0] == 'x') ddir = DMDA_X; 295 else if (dir[0] == 'y') ddir = DMDA_Y; 296 else SETERRQ1(PetscObjectComm((PetscObject) ts), PETSC_ERR_ARG_WRONG, "Unknown ray direction %s", dir); 297 sscanf(dir+2, "%d", &ray); 298 299 ierr = PetscInfo2(((PetscObject) ts),"Displaying LG DMDA ray %c = %D\n", dir[0], ray);CHKERRQ(ierr); 300 ierr = PetscNew(&rayctx);CHKERRQ(ierr); 301 ierr = TSGetDM(ts, &da);CHKERRQ(ierr); 302 ierr = DMDAGetRay(da, ddir, ray, &rayctx->ray, &rayctx->scatter);CHKERRQ(ierr); 303 ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&rayctx->lgctx);CHKERRQ(ierr); 304 ierr = TSMonitorSet(ts, TSMonitorLGDMDARay, rayctx, TSMonitorDMDARayDestroy);CHKERRQ(ierr); 305 } 306 307 flg = PETSC_FALSE; 308 ierr = PetscOptionsBool("-ts_fd_color", "Use finite differences with coloring to compute IJacobian", "TSComputeJacobianDefaultColor", flg, &flg, NULL);CHKERRQ(ierr); 309 if (flg) { 310 DM dm; 311 DMTS tdm; 312 313 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 314 ierr = DMGetDMTS(dm, &tdm);CHKERRQ(ierr); 315 tdm->ijacobianctx = NULL; 316 ierr = TSSetIJacobian(ts, NULL, NULL, TSComputeIJacobianDefaultColor, 0);CHKERRQ(ierr); 317 ierr = PetscInfo(ts, "Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr); 318 } 319 320 /* 321 This code is all wrong. One is creating objects inside the TSSetFromOptions() so if run with the options gui 322 will bleed memory. Also one is using a PetscOptionsBegin() inside a PetscOptionsBegin() 323 */ 324 ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr); 325 ierr = TSAdaptSetFromOptions(PetscOptionsObject,adapt);CHKERRQ(ierr); 326 327 /* Handle specific TS options */ 328 if (ts->ops->setfromoptions) { 329 ierr = (*ts->ops->setfromoptions)(PetscOptionsObject,ts);CHKERRQ(ierr); 330 } 331 ierr = PetscOptionsEnd();CHKERRQ(ierr); 332 333 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 334 ierr = PetscObjectProcessOptionsHandlers((PetscObject)ts);CHKERRQ(ierr); 335 336 if (ts->trajectory) { 337 ierr = TSTrajectorySetFromOptions(ts->trajectory);CHKERRQ(ierr); 338 } 339 340 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 341 if (snes) { 342 if (ts->problem_type == TS_LINEAR) {ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);} 343 ierr = SNESSetFromOptions(ts->snes);CHKERRQ(ierr); 344 } 345 PetscFunctionReturn(0); 346 } 347 348 #undef __FUNCT__ 349 #define __FUNCT__ "TSSetSaveTrajectory" 350 /*@ 351 TSSetSaveTrajectory - Causes the TS to save its solutions as it iterates forward in time in a TSTrajectory object 352 353 Collective on TS 354 355 Input Parameters: 356 . ts - the TS context obtained from TSCreate() 357 358 359 Level: intermediate 360 361 .seealso: TSGetTrajectory(), TSAdjointSolve() 362 363 .keywords: TS, set, checkpoint, 364 @*/ 365 PetscErrorCode TSSetSaveTrajectory(TS ts) 366 { 367 PetscErrorCode ierr; 368 369 PetscFunctionBegin; 370 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 371 if (!ts->trajectory) { 372 ierr = TSTrajectoryCreate(PetscObjectComm((PetscObject)ts),&ts->trajectory);CHKERRQ(ierr); 373 /* should it set a default trajectory? */ 374 } 375 PetscFunctionReturn(0); 376 } 377 378 #undef __FUNCT__ 379 #define __FUNCT__ "TSComputeRHSJacobian" 380 /*@ 381 TSComputeRHSJacobian - Computes the Jacobian matrix that has been 382 set with TSSetRHSJacobian(). 383 384 Collective on TS and Vec 385 386 Input Parameters: 387 + ts - the TS context 388 . t - current timestep 389 - U - input vector 390 391 Output Parameters: 392 + A - Jacobian matrix 393 . B - optional preconditioning matrix 394 - flag - flag indicating matrix structure 395 396 Notes: 397 Most users should not need to explicitly call this routine, as it 398 is used internally within the nonlinear solvers. 399 400 See KSPSetOperators() for important information about setting the 401 flag parameter. 402 403 Level: developer 404 405 .keywords: SNES, compute, Jacobian, matrix 406 407 .seealso: TSSetRHSJacobian(), KSPSetOperators() 408 @*/ 409 PetscErrorCode TSComputeRHSJacobian(TS ts,PetscReal t,Vec U,Mat A,Mat B) 410 { 411 PetscErrorCode ierr; 412 PetscObjectState Ustate; 413 DM dm; 414 DMTS tsdm; 415 TSRHSJacobian rhsjacobianfunc; 416 void *ctx; 417 TSIJacobian ijacobianfunc; 418 419 PetscFunctionBegin; 420 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 421 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 422 PetscCheckSameComm(ts,1,U,3); 423 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 424 ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); 425 ierr = DMTSGetRHSJacobian(dm,&rhsjacobianfunc,&ctx);CHKERRQ(ierr); 426 ierr = DMTSGetIJacobian(dm,&ijacobianfunc,NULL);CHKERRQ(ierr); 427 ierr = PetscObjectStateGet((PetscObject)U,&Ustate);CHKERRQ(ierr); 428 if (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.X == U && ts->rhsjacobian.Xstate == Ustate))) { 429 PetscFunctionReturn(0); 430 } 431 432 if (!rhsjacobianfunc && !ijacobianfunc) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()"); 433 434 if (ts->rhsjacobian.reuse) { 435 ierr = MatShift(A,-ts->rhsjacobian.shift);CHKERRQ(ierr); 436 ierr = MatScale(A,1./ts->rhsjacobian.scale);CHKERRQ(ierr); 437 if (A != B) { 438 ierr = MatShift(B,-ts->rhsjacobian.shift);CHKERRQ(ierr); 439 ierr = MatScale(B,1./ts->rhsjacobian.scale);CHKERRQ(ierr); 440 } 441 ts->rhsjacobian.shift = 0; 442 ts->rhsjacobian.scale = 1.; 443 } 444 445 if (rhsjacobianfunc) { 446 ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr); 447 PetscStackPush("TS user Jacobian function"); 448 ierr = (*rhsjacobianfunc)(ts,t,U,A,B,ctx);CHKERRQ(ierr); 449 PetscStackPop; 450 ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr); 451 /* make sure user returned a correct Jacobian and preconditioner */ 452 PetscValidHeaderSpecific(A,MAT_CLASSID,4); 453 PetscValidHeaderSpecific(B,MAT_CLASSID,5); 454 } else { 455 ierr = MatZeroEntries(A);CHKERRQ(ierr); 456 if (A != B) {ierr = MatZeroEntries(B);CHKERRQ(ierr);} 457 } 458 ts->rhsjacobian.time = t; 459 ts->rhsjacobian.X = U; 460 ierr = PetscObjectStateGet((PetscObject)U,&ts->rhsjacobian.Xstate);CHKERRQ(ierr); 461 PetscFunctionReturn(0); 462 } 463 464 #undef __FUNCT__ 465 #define __FUNCT__ "TSComputeRHSFunction" 466 /*@ 467 TSComputeRHSFunction - Evaluates the right-hand-side function. 468 469 Collective on TS and Vec 470 471 Input Parameters: 472 + ts - the TS context 473 . t - current time 474 - U - state vector 475 476 Output Parameter: 477 . y - right hand side 478 479 Note: 480 Most users should not need to explicitly call this routine, as it 481 is used internally within the nonlinear solvers. 482 483 Level: developer 484 485 .keywords: TS, compute 486 487 .seealso: TSSetRHSFunction(), TSComputeIFunction() 488 @*/ 489 PetscErrorCode TSComputeRHSFunction(TS ts,PetscReal t,Vec U,Vec y) 490 { 491 PetscErrorCode ierr; 492 TSRHSFunction rhsfunction; 493 TSIFunction ifunction; 494 void *ctx; 495 DM dm; 496 497 PetscFunctionBegin; 498 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 499 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 500 PetscValidHeaderSpecific(y,VEC_CLASSID,4); 501 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 502 ierr = DMTSGetRHSFunction(dm,&rhsfunction,&ctx);CHKERRQ(ierr); 503 ierr = DMTSGetIFunction(dm,&ifunction,NULL);CHKERRQ(ierr); 504 505 if (!rhsfunction && !ifunction) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 506 507 ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr); 508 if (rhsfunction) { 509 PetscStackPush("TS user right-hand-side function"); 510 ierr = (*rhsfunction)(ts,t,U,y,ctx);CHKERRQ(ierr); 511 PetscStackPop; 512 } else { 513 ierr = VecZeroEntries(y);CHKERRQ(ierr); 514 } 515 516 ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr); 517 PetscFunctionReturn(0); 518 } 519 520 #undef __FUNCT__ 521 #define __FUNCT__ "TSComputeSolutionFunction" 522 /*@ 523 TSComputeSolutionFunction - Evaluates the solution function. 524 525 Collective on TS and Vec 526 527 Input Parameters: 528 + ts - the TS context 529 - t - current time 530 531 Output Parameter: 532 . U - the solution 533 534 Note: 535 Most users should not need to explicitly call this routine, as it 536 is used internally within the nonlinear solvers. 537 538 Level: developer 539 540 .keywords: TS, compute 541 542 .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction() 543 @*/ 544 PetscErrorCode TSComputeSolutionFunction(TS ts,PetscReal t,Vec U) 545 { 546 PetscErrorCode ierr; 547 TSSolutionFunction solutionfunction; 548 void *ctx; 549 DM dm; 550 551 PetscFunctionBegin; 552 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 553 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 554 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 555 ierr = DMTSGetSolutionFunction(dm,&solutionfunction,&ctx);CHKERRQ(ierr); 556 557 if (solutionfunction) { 558 PetscStackPush("TS user solution function"); 559 ierr = (*solutionfunction)(ts,t,U,ctx);CHKERRQ(ierr); 560 PetscStackPop; 561 } 562 PetscFunctionReturn(0); 563 } 564 #undef __FUNCT__ 565 #define __FUNCT__ "TSComputeForcingFunction" 566 /*@ 567 TSComputeForcingFunction - Evaluates the forcing function. 568 569 Collective on TS and Vec 570 571 Input Parameters: 572 + ts - the TS context 573 - t - current time 574 575 Output Parameter: 576 . U - the function value 577 578 Note: 579 Most users should not need to explicitly call this routine, as it 580 is used internally within the nonlinear solvers. 581 582 Level: developer 583 584 .keywords: TS, compute 585 586 .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction() 587 @*/ 588 PetscErrorCode TSComputeForcingFunction(TS ts,PetscReal t,Vec U) 589 { 590 PetscErrorCode ierr, (*forcing)(TS,PetscReal,Vec,void*); 591 void *ctx; 592 DM dm; 593 594 PetscFunctionBegin; 595 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 596 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 597 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 598 ierr = DMTSGetForcingFunction(dm,&forcing,&ctx);CHKERRQ(ierr); 599 600 if (forcing) { 601 PetscStackPush("TS user forcing function"); 602 ierr = (*forcing)(ts,t,U,ctx);CHKERRQ(ierr); 603 PetscStackPop; 604 } 605 PetscFunctionReturn(0); 606 } 607 608 #undef __FUNCT__ 609 #define __FUNCT__ "TSGetRHSVec_Private" 610 static PetscErrorCode TSGetRHSVec_Private(TS ts,Vec *Frhs) 611 { 612 Vec F; 613 PetscErrorCode ierr; 614 615 PetscFunctionBegin; 616 *Frhs = NULL; 617 ierr = TSGetIFunction(ts,&F,NULL,NULL);CHKERRQ(ierr); 618 if (!ts->Frhs) { 619 ierr = VecDuplicate(F,&ts->Frhs);CHKERRQ(ierr); 620 } 621 *Frhs = ts->Frhs; 622 PetscFunctionReturn(0); 623 } 624 625 #undef __FUNCT__ 626 #define __FUNCT__ "TSGetRHSMats_Private" 627 static PetscErrorCode TSGetRHSMats_Private(TS ts,Mat *Arhs,Mat *Brhs) 628 { 629 Mat A,B; 630 PetscErrorCode ierr; 631 632 PetscFunctionBegin; 633 if (Arhs) *Arhs = NULL; 634 if (Brhs) *Brhs = NULL; 635 ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr); 636 if (Arhs) { 637 if (!ts->Arhs) { 638 ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&ts->Arhs);CHKERRQ(ierr); 639 } 640 *Arhs = ts->Arhs; 641 } 642 if (Brhs) { 643 if (!ts->Brhs) { 644 if (A != B) { 645 ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&ts->Brhs);CHKERRQ(ierr); 646 } else { 647 ts->Brhs = ts->Arhs; 648 ierr = PetscObjectReference((PetscObject)ts->Arhs);CHKERRQ(ierr); 649 } 650 } 651 *Brhs = ts->Brhs; 652 } 653 PetscFunctionReturn(0); 654 } 655 656 #undef __FUNCT__ 657 #define __FUNCT__ "TSComputeIFunction" 658 /*@ 659 TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,U,Udot)=0 660 661 Collective on TS and Vec 662 663 Input Parameters: 664 + ts - the TS context 665 . t - current time 666 . U - state vector 667 . Udot - time derivative of state vector 668 - imex - flag indicates if the method is IMEX so that the RHSFunction should be kept separate 669 670 Output Parameter: 671 . Y - right hand side 672 673 Note: 674 Most users should not need to explicitly call this routine, as it 675 is used internally within the nonlinear solvers. 676 677 If the user did did not write their equations in implicit form, this 678 function recasts them in implicit form. 679 680 Level: developer 681 682 .keywords: TS, compute 683 684 .seealso: TSSetIFunction(), TSComputeRHSFunction() 685 @*/ 686 PetscErrorCode TSComputeIFunction(TS ts,PetscReal t,Vec U,Vec Udot,Vec Y,PetscBool imex) 687 { 688 PetscErrorCode ierr; 689 TSIFunction ifunction; 690 TSRHSFunction rhsfunction; 691 void *ctx; 692 DM dm; 693 694 PetscFunctionBegin; 695 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 696 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 697 PetscValidHeaderSpecific(Udot,VEC_CLASSID,4); 698 PetscValidHeaderSpecific(Y,VEC_CLASSID,5); 699 700 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 701 ierr = DMTSGetIFunction(dm,&ifunction,&ctx);CHKERRQ(ierr); 702 ierr = DMTSGetRHSFunction(dm,&rhsfunction,NULL);CHKERRQ(ierr); 703 704 if (!rhsfunction && !ifunction) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()"); 705 706 ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr); 707 if (ifunction) { 708 PetscStackPush("TS user implicit function"); 709 ierr = (*ifunction)(ts,t,U,Udot,Y,ctx);CHKERRQ(ierr); 710 PetscStackPop; 711 } 712 if (imex) { 713 if (!ifunction) { 714 ierr = VecCopy(Udot,Y);CHKERRQ(ierr); 715 } 716 } else if (rhsfunction) { 717 if (ifunction) { 718 Vec Frhs; 719 ierr = TSGetRHSVec_Private(ts,&Frhs);CHKERRQ(ierr); 720 ierr = TSComputeRHSFunction(ts,t,U,Frhs);CHKERRQ(ierr); 721 ierr = VecAXPY(Y,-1,Frhs);CHKERRQ(ierr); 722 } else { 723 ierr = TSComputeRHSFunction(ts,t,U,Y);CHKERRQ(ierr); 724 ierr = VecAYPX(Y,-1,Udot);CHKERRQ(ierr); 725 } 726 } 727 ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr); 728 PetscFunctionReturn(0); 729 } 730 731 #undef __FUNCT__ 732 #define __FUNCT__ "TSComputeIJacobian" 733 /*@ 734 TSComputeIJacobian - Evaluates the Jacobian of the DAE 735 736 Collective on TS and Vec 737 738 Input 739 Input Parameters: 740 + ts - the TS context 741 . t - current timestep 742 . U - state vector 743 . Udot - time derivative of state vector 744 . shift - shift to apply, see note below 745 - imex - flag indicates if the method is IMEX so that the RHSJacobian should be kept separate 746 747 Output Parameters: 748 + A - Jacobian matrix 749 . B - optional preconditioning matrix 750 - flag - flag indicating matrix structure 751 752 Notes: 753 If F(t,U,Udot)=0 is the DAE, the required Jacobian is 754 755 dF/dU + shift*dF/dUdot 756 757 Most users should not need to explicitly call this routine, as it 758 is used internally within the nonlinear solvers. 759 760 Level: developer 761 762 .keywords: TS, compute, Jacobian, matrix 763 764 .seealso: TSSetIJacobian() 765 @*/ 766 PetscErrorCode TSComputeIJacobian(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,PetscBool imex) 767 { 768 PetscErrorCode ierr; 769 TSIJacobian ijacobian; 770 TSRHSJacobian rhsjacobian; 771 DM dm; 772 void *ctx; 773 774 PetscFunctionBegin; 775 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 776 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 777 PetscValidHeaderSpecific(Udot,VEC_CLASSID,4); 778 PetscValidPointer(A,6); 779 PetscValidHeaderSpecific(A,MAT_CLASSID,6); 780 PetscValidPointer(B,7); 781 PetscValidHeaderSpecific(B,MAT_CLASSID,7); 782 783 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 784 ierr = DMTSGetIJacobian(dm,&ijacobian,&ctx);CHKERRQ(ierr); 785 ierr = DMTSGetRHSJacobian(dm,&rhsjacobian,NULL);CHKERRQ(ierr); 786 787 if (!rhsjacobian && !ijacobian) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()"); 788 789 ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr); 790 if (ijacobian) { 791 PetscStackPush("TS user implicit Jacobian"); 792 ierr = (*ijacobian)(ts,t,U,Udot,shift,A,B,ctx);CHKERRQ(ierr); 793 PetscStackPop; 794 /* make sure user returned a correct Jacobian and preconditioner */ 795 PetscValidHeaderSpecific(A,MAT_CLASSID,4); 796 PetscValidHeaderSpecific(B,MAT_CLASSID,5); 797 } 798 if (imex) { 799 if (!ijacobian) { /* system was written as Udot = G(t,U) */ 800 ierr = MatZeroEntries(A);CHKERRQ(ierr); 801 ierr = MatShift(A,shift);CHKERRQ(ierr); 802 if (A != B) { 803 ierr = MatZeroEntries(B);CHKERRQ(ierr); 804 ierr = MatShift(B,shift);CHKERRQ(ierr); 805 } 806 } 807 } else { 808 Mat Arhs = NULL,Brhs = NULL; 809 if (rhsjacobian) { 810 if (ijacobian) { 811 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 812 } else { 813 ierr = TSGetIJacobian(ts,&Arhs,&Brhs,NULL,NULL);CHKERRQ(ierr); 814 } 815 ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr); 816 } 817 if (Arhs == A) { /* No IJacobian, so we only have the RHS matrix */ 818 ts->rhsjacobian.scale = -1; 819 ts->rhsjacobian.shift = shift; 820 ierr = MatScale(A,-1);CHKERRQ(ierr); 821 ierr = MatShift(A,shift);CHKERRQ(ierr); 822 if (A != B) { 823 ierr = MatScale(B,-1);CHKERRQ(ierr); 824 ierr = MatShift(B,shift);CHKERRQ(ierr); 825 } 826 } else if (Arhs) { /* Both IJacobian and RHSJacobian */ 827 MatStructure axpy = DIFFERENT_NONZERO_PATTERN; 828 if (!ijacobian) { /* No IJacobian provided, but we have a separate RHS matrix */ 829 ierr = MatZeroEntries(A);CHKERRQ(ierr); 830 ierr = MatShift(A,shift);CHKERRQ(ierr); 831 if (A != B) { 832 ierr = MatZeroEntries(B);CHKERRQ(ierr); 833 ierr = MatShift(B,shift);CHKERRQ(ierr); 834 } 835 } 836 ierr = MatAXPY(A,-1,Arhs,axpy);CHKERRQ(ierr); 837 if (A != B) { 838 ierr = MatAXPY(B,-1,Brhs,axpy);CHKERRQ(ierr); 839 } 840 } 841 } 842 ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr); 843 PetscFunctionReturn(0); 844 } 845 846 #undef __FUNCT__ 847 #define __FUNCT__ "TSSetRHSFunction" 848 /*@C 849 TSSetRHSFunction - Sets the routine for evaluating the function, 850 where U_t = G(t,u). 851 852 Logically Collective on TS 853 854 Input Parameters: 855 + ts - the TS context obtained from TSCreate() 856 . r - vector to put the computed right hand side (or NULL to have it created) 857 . f - routine for evaluating the right-hand-side function 858 - ctx - [optional] user-defined context for private data for the 859 function evaluation routine (may be NULL) 860 861 Calling sequence of func: 862 $ func (TS ts,PetscReal t,Vec u,Vec F,void *ctx); 863 864 + t - current timestep 865 . u - input vector 866 . F - function vector 867 - ctx - [optional] user-defined function context 868 869 Level: beginner 870 871 Notes: You must call this function or TSSetIFunction() to define your ODE. You cannot use this function when solving a DAE. 872 873 .keywords: TS, timestep, set, right-hand-side, function 874 875 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSSetIFunction() 876 @*/ 877 PetscErrorCode TSSetRHSFunction(TS ts,Vec r,PetscErrorCode (*f)(TS,PetscReal,Vec,Vec,void*),void *ctx) 878 { 879 PetscErrorCode ierr; 880 SNES snes; 881 Vec ralloc = NULL; 882 DM dm; 883 884 PetscFunctionBegin; 885 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 886 if (r) PetscValidHeaderSpecific(r,VEC_CLASSID,2); 887 888 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 889 ierr = DMTSSetRHSFunction(dm,f,ctx);CHKERRQ(ierr); 890 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 891 if (!r && !ts->dm && ts->vec_sol) { 892 ierr = VecDuplicate(ts->vec_sol,&ralloc);CHKERRQ(ierr); 893 r = ralloc; 894 } 895 ierr = SNESSetFunction(snes,r,SNESTSFormFunction,ts);CHKERRQ(ierr); 896 ierr = VecDestroy(&ralloc);CHKERRQ(ierr); 897 PetscFunctionReturn(0); 898 } 899 900 #undef __FUNCT__ 901 #define __FUNCT__ "TSSetSolutionFunction" 902 /*@C 903 TSSetSolutionFunction - Provide a function that computes the solution of the ODE or DAE 904 905 Logically Collective on TS 906 907 Input Parameters: 908 + ts - the TS context obtained from TSCreate() 909 . f - routine for evaluating the solution 910 - ctx - [optional] user-defined context for private data for the 911 function evaluation routine (may be NULL) 912 913 Calling sequence of func: 914 $ func (TS ts,PetscReal t,Vec u,void *ctx); 915 916 + t - current timestep 917 . u - output vector 918 - ctx - [optional] user-defined function context 919 920 Notes: 921 This routine is used for testing accuracy of time integration schemes when you already know the solution. 922 If analytic solutions are not known for your system, consider using the Method of Manufactured Solutions to 923 create closed-form solutions with non-physical forcing terms. 924 925 For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history. 926 927 Level: beginner 928 929 .keywords: TS, timestep, set, right-hand-side, function 930 931 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetForcingFunction() 932 @*/ 933 PetscErrorCode TSSetSolutionFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,void*),void *ctx) 934 { 935 PetscErrorCode ierr; 936 DM dm; 937 938 PetscFunctionBegin; 939 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 940 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 941 ierr = DMTSSetSolutionFunction(dm,f,ctx);CHKERRQ(ierr); 942 PetscFunctionReturn(0); 943 } 944 945 #undef __FUNCT__ 946 #define __FUNCT__ "TSSetForcingFunction" 947 /*@C 948 TSSetForcingFunction - Provide a function that computes a forcing term for a ODE or PDE 949 950 Logically Collective on TS 951 952 Input Parameters: 953 + ts - the TS context obtained from TSCreate() 954 . f - routine for evaluating the forcing function 955 - ctx - [optional] user-defined context for private data for the 956 function evaluation routine (may be NULL) 957 958 Calling sequence of func: 959 $ func (TS ts,PetscReal t,Vec u,void *ctx); 960 961 + t - current timestep 962 . u - output vector 963 - ctx - [optional] user-defined function context 964 965 Notes: 966 This routine is useful for testing accuracy of time integration schemes when using the Method of Manufactured Solutions to 967 create closed-form solutions with a non-physical forcing term. 968 969 For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history. 970 971 Level: beginner 972 973 .keywords: TS, timestep, set, right-hand-side, function 974 975 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetSolutionFunction() 976 @*/ 977 PetscErrorCode TSSetForcingFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,void*),void *ctx) 978 { 979 PetscErrorCode ierr; 980 DM dm; 981 982 PetscFunctionBegin; 983 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 984 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 985 ierr = DMTSSetForcingFunction(dm,f,ctx);CHKERRQ(ierr); 986 PetscFunctionReturn(0); 987 } 988 989 #undef __FUNCT__ 990 #define __FUNCT__ "TSSetRHSJacobian" 991 /*@C 992 TSSetRHSJacobian - Sets the function to compute the Jacobian of G, 993 where U_t = G(U,t), as well as the location to store the matrix. 994 995 Logically Collective on TS 996 997 Input Parameters: 998 + ts - the TS context obtained from TSCreate() 999 . Amat - (approximate) Jacobian matrix 1000 . Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat) 1001 . f - the Jacobian evaluation routine 1002 - ctx - [optional] user-defined context for private data for the 1003 Jacobian evaluation routine (may be NULL) 1004 1005 Calling sequence of f: 1006 $ func (TS ts,PetscReal t,Vec u,Mat A,Mat B,void *ctx); 1007 1008 + t - current timestep 1009 . u - input vector 1010 . Amat - (approximate) Jacobian matrix 1011 . Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat) 1012 - ctx - [optional] user-defined context for matrix evaluation routine 1013 1014 1015 Level: beginner 1016 1017 .keywords: TS, timestep, set, right-hand-side, Jacobian 1018 1019 .seealso: SNESComputeJacobianDefaultColor(), TSSetRHSFunction(), TSRHSJacobianSetReuse(), TSSetIJacobian() 1020 1021 @*/ 1022 PetscErrorCode TSSetRHSJacobian(TS ts,Mat Amat,Mat Pmat,TSRHSJacobian f,void *ctx) 1023 { 1024 PetscErrorCode ierr; 1025 SNES snes; 1026 DM dm; 1027 TSIJacobian ijacobian; 1028 1029 PetscFunctionBegin; 1030 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1031 if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 1032 if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 1033 if (Amat) PetscCheckSameComm(ts,1,Amat,2); 1034 if (Pmat) PetscCheckSameComm(ts,1,Pmat,3); 1035 1036 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1037 ierr = DMTSSetRHSJacobian(dm,f,ctx);CHKERRQ(ierr); 1038 if (f == TSComputeRHSJacobianConstant) { 1039 /* Handle this case automatically for the user; otherwise user should call themselves. */ 1040 ierr = TSRHSJacobianSetReuse(ts,PETSC_TRUE);CHKERRQ(ierr); 1041 } 1042 ierr = DMTSGetIJacobian(dm,&ijacobian,NULL);CHKERRQ(ierr); 1043 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1044 if (!ijacobian) { 1045 ierr = SNESSetJacobian(snes,Amat,Pmat,SNESTSFormJacobian,ts);CHKERRQ(ierr); 1046 } 1047 if (Amat) { 1048 ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 1049 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 1050 1051 ts->Arhs = Amat; 1052 } 1053 if (Pmat) { 1054 ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr); 1055 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 1056 1057 ts->Brhs = Pmat; 1058 } 1059 PetscFunctionReturn(0); 1060 } 1061 1062 1063 #undef __FUNCT__ 1064 #define __FUNCT__ "TSSetIFunction" 1065 /*@C 1066 TSSetIFunction - Set the function to compute F(t,U,U_t) where F() = 0 is the DAE to be solved. 1067 1068 Logically Collective on TS 1069 1070 Input Parameters: 1071 + ts - the TS context obtained from TSCreate() 1072 . r - vector to hold the residual (or NULL to have it created internally) 1073 . f - the function evaluation routine 1074 - ctx - user-defined context for private data for the function evaluation routine (may be NULL) 1075 1076 Calling sequence of f: 1077 $ f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx); 1078 1079 + t - time at step/stage being solved 1080 . u - state vector 1081 . u_t - time derivative of state vector 1082 . F - function vector 1083 - ctx - [optional] user-defined context for matrix evaluation routine 1084 1085 Important: 1086 The user MUST call either this routine or TSSetRHSFunction() to define the ODE. When solving DAEs you must use this function. 1087 1088 Level: beginner 1089 1090 .keywords: TS, timestep, set, DAE, Jacobian 1091 1092 .seealso: TSSetRHSJacobian(), TSSetRHSFunction(), TSSetIJacobian() 1093 @*/ 1094 PetscErrorCode TSSetIFunction(TS ts,Vec res,TSIFunction f,void *ctx) 1095 { 1096 PetscErrorCode ierr; 1097 SNES snes; 1098 Vec resalloc = NULL; 1099 DM dm; 1100 1101 PetscFunctionBegin; 1102 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1103 if (res) PetscValidHeaderSpecific(res,VEC_CLASSID,2); 1104 1105 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1106 ierr = DMTSSetIFunction(dm,f,ctx);CHKERRQ(ierr); 1107 1108 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1109 if (!res && !ts->dm && ts->vec_sol) { 1110 ierr = VecDuplicate(ts->vec_sol,&resalloc);CHKERRQ(ierr); 1111 res = resalloc; 1112 } 1113 ierr = SNESSetFunction(snes,res,SNESTSFormFunction,ts);CHKERRQ(ierr); 1114 ierr = VecDestroy(&resalloc);CHKERRQ(ierr); 1115 PetscFunctionReturn(0); 1116 } 1117 1118 #undef __FUNCT__ 1119 #define __FUNCT__ "TSGetIFunction" 1120 /*@C 1121 TSGetIFunction - Returns the vector where the implicit residual is stored and the function/contex to compute it. 1122 1123 Not Collective 1124 1125 Input Parameter: 1126 . ts - the TS context 1127 1128 Output Parameter: 1129 + r - vector to hold residual (or NULL) 1130 . func - the function to compute residual (or NULL) 1131 - ctx - the function context (or NULL) 1132 1133 Level: advanced 1134 1135 .keywords: TS, nonlinear, get, function 1136 1137 .seealso: TSSetIFunction(), SNESGetFunction() 1138 @*/ 1139 PetscErrorCode TSGetIFunction(TS ts,Vec *r,TSIFunction *func,void **ctx) 1140 { 1141 PetscErrorCode ierr; 1142 SNES snes; 1143 DM dm; 1144 1145 PetscFunctionBegin; 1146 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1147 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1148 ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 1149 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1150 ierr = DMTSGetIFunction(dm,func,ctx);CHKERRQ(ierr); 1151 PetscFunctionReturn(0); 1152 } 1153 1154 #undef __FUNCT__ 1155 #define __FUNCT__ "TSGetRHSFunction" 1156 /*@C 1157 TSGetRHSFunction - Returns the vector where the right hand side is stored and the function/context to compute it. 1158 1159 Not Collective 1160 1161 Input Parameter: 1162 . ts - the TS context 1163 1164 Output Parameter: 1165 + r - vector to hold computed right hand side (or NULL) 1166 . func - the function to compute right hand side (or NULL) 1167 - ctx - the function context (or NULL) 1168 1169 Level: advanced 1170 1171 .keywords: TS, nonlinear, get, function 1172 1173 .seealso: TSSetRHSFunction(), SNESGetFunction() 1174 @*/ 1175 PetscErrorCode TSGetRHSFunction(TS ts,Vec *r,TSRHSFunction *func,void **ctx) 1176 { 1177 PetscErrorCode ierr; 1178 SNES snes; 1179 DM dm; 1180 1181 PetscFunctionBegin; 1182 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1183 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1184 ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr); 1185 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1186 ierr = DMTSGetRHSFunction(dm,func,ctx);CHKERRQ(ierr); 1187 PetscFunctionReturn(0); 1188 } 1189 1190 #undef __FUNCT__ 1191 #define __FUNCT__ "TSSetIJacobian" 1192 /*@C 1193 TSSetIJacobian - Set the function to compute the matrix dF/dU + a*dF/dU_t where F(t,U,U_t) is the function 1194 provided with TSSetIFunction(). 1195 1196 Logically Collective on TS 1197 1198 Input Parameters: 1199 + ts - the TS context obtained from TSCreate() 1200 . Amat - (approximate) Jacobian matrix 1201 . Pmat - matrix used to compute preconditioner (usually the same as Amat) 1202 . f - the Jacobian evaluation routine 1203 - ctx - user-defined context for private data for the Jacobian evaluation routine (may be NULL) 1204 1205 Calling sequence of f: 1206 $ f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat Amat,Mat Pmat,void *ctx); 1207 1208 + t - time at step/stage being solved 1209 . U - state vector 1210 . U_t - time derivative of state vector 1211 . a - shift 1212 . Amat - (approximate) Jacobian of F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t 1213 . Pmat - matrix used for constructing preconditioner, usually the same as Amat 1214 - ctx - [optional] user-defined context for matrix evaluation routine 1215 1216 Notes: 1217 The matrices Amat and Pmat are exactly the matrices that are used by SNES for the nonlinear solve. 1218 1219 The matrix dF/dU + a*dF/dU_t you provide turns out to be 1220 the Jacobian of F(t,U,W+a*U) where F(t,U,U_t) = 0 is the DAE to be solved. 1221 The time integrator internally approximates U_t by W+a*U where the positive "shift" 1222 a and vector W depend on the integration method, step size, and past states. For example with 1223 the backward Euler method a = 1/dt and W = -a*U(previous timestep) so 1224 W + a*U = a*(U - U(previous timestep)) = (U - U(previous timestep))/dt 1225 1226 Level: beginner 1227 1228 .keywords: TS, timestep, DAE, Jacobian 1229 1230 .seealso: TSSetIFunction(), TSSetRHSJacobian(), SNESComputeJacobianDefaultColor(), SNESComputeJacobianDefault(), TSSetRHSFunction() 1231 1232 @*/ 1233 PetscErrorCode TSSetIJacobian(TS ts,Mat Amat,Mat Pmat,TSIJacobian f,void *ctx) 1234 { 1235 PetscErrorCode ierr; 1236 SNES snes; 1237 DM dm; 1238 1239 PetscFunctionBegin; 1240 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1241 if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 1242 if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 1243 if (Amat) PetscCheckSameComm(ts,1,Amat,2); 1244 if (Pmat) PetscCheckSameComm(ts,1,Pmat,3); 1245 1246 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1247 ierr = DMTSSetIJacobian(dm,f,ctx);CHKERRQ(ierr); 1248 1249 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1250 ierr = SNESSetJacobian(snes,Amat,Pmat,SNESTSFormJacobian,ts);CHKERRQ(ierr); 1251 PetscFunctionReturn(0); 1252 } 1253 1254 #undef __FUNCT__ 1255 #define __FUNCT__ "TSRHSJacobianSetReuse" 1256 /*@ 1257 TSRHSJacobianSetReuse - restore RHS Jacobian before re-evaluating. Without this flag, TS will change the sign and 1258 shift the RHS Jacobian for a finite-time-step implicit solve, in which case the user function will need to recompute 1259 the entire Jacobian. The reuse flag must be set if the evaluation function will assume that the matrix entries have 1260 not been changed by the TS. 1261 1262 Logically Collective 1263 1264 Input Arguments: 1265 + ts - TS context obtained from TSCreate() 1266 - reuse - PETSC_TRUE if the RHS Jacobian 1267 1268 Level: intermediate 1269 1270 .seealso: TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 1271 @*/ 1272 PetscErrorCode TSRHSJacobianSetReuse(TS ts,PetscBool reuse) 1273 { 1274 PetscFunctionBegin; 1275 ts->rhsjacobian.reuse = reuse; 1276 PetscFunctionReturn(0); 1277 } 1278 1279 #undef __FUNCT__ 1280 #define __FUNCT__ "TSLoad" 1281 /*@C 1282 TSLoad - Loads a KSP that has been stored in binary with KSPView(). 1283 1284 Collective on PetscViewer 1285 1286 Input Parameters: 1287 + newdm - the newly loaded TS, this needs to have been created with TSCreate() or 1288 some related function before a call to TSLoad(). 1289 - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() 1290 1291 Level: intermediate 1292 1293 Notes: 1294 The type is determined by the data in the file, any type set into the TS before this call is ignored. 1295 1296 Notes for advanced users: 1297 Most users should not need to know the details of the binary storage 1298 format, since TSLoad() and TSView() completely hide these details. 1299 But for anyone who's interested, the standard binary matrix storage 1300 format is 1301 .vb 1302 has not yet been determined 1303 .ve 1304 1305 .seealso: PetscViewerBinaryOpen(), TSView(), MatLoad(), VecLoad() 1306 @*/ 1307 PetscErrorCode TSLoad(TS ts, PetscViewer viewer) 1308 { 1309 PetscErrorCode ierr; 1310 PetscBool isbinary; 1311 PetscInt classid; 1312 char type[256]; 1313 DMTS sdm; 1314 DM dm; 1315 1316 PetscFunctionBegin; 1317 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1318 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1319 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1320 if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 1321 1322 ierr = PetscViewerBinaryRead(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr); 1323 if (classid != TS_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Not TS next in file"); 1324 ierr = PetscViewerBinaryRead(viewer,type,256,PETSC_CHAR);CHKERRQ(ierr); 1325 ierr = TSSetType(ts, type);CHKERRQ(ierr); 1326 if (ts->ops->load) { 1327 ierr = (*ts->ops->load)(ts,viewer);CHKERRQ(ierr); 1328 } 1329 ierr = DMCreate(PetscObjectComm((PetscObject)ts),&dm);CHKERRQ(ierr); 1330 ierr = DMLoad(dm,viewer);CHKERRQ(ierr); 1331 ierr = TSSetDM(ts,dm);CHKERRQ(ierr); 1332 ierr = DMCreateGlobalVector(ts->dm,&ts->vec_sol);CHKERRQ(ierr); 1333 ierr = VecLoad(ts->vec_sol,viewer);CHKERRQ(ierr); 1334 ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr); 1335 ierr = DMTSLoad(sdm,viewer);CHKERRQ(ierr); 1336 PetscFunctionReturn(0); 1337 } 1338 1339 #include <petscdraw.h> 1340 #if defined(PETSC_HAVE_SAWS) 1341 #include <petscviewersaws.h> 1342 #endif 1343 #undef __FUNCT__ 1344 #define __FUNCT__ "TSView" 1345 /*@C 1346 TSView - Prints the TS data structure. 1347 1348 Collective on TS 1349 1350 Input Parameters: 1351 + ts - the TS context obtained from TSCreate() 1352 - viewer - visualization context 1353 1354 Options Database Key: 1355 . -ts_view - calls TSView() at end of TSStep() 1356 1357 Notes: 1358 The available visualization contexts include 1359 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 1360 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 1361 output where only the first processor opens 1362 the file. All other processors send their 1363 data to the first processor to print. 1364 1365 The user can open an alternative visualization context with 1366 PetscViewerASCIIOpen() - output to a specified file. 1367 1368 Level: beginner 1369 1370 .keywords: TS, timestep, view 1371 1372 .seealso: PetscViewerASCIIOpen() 1373 @*/ 1374 PetscErrorCode TSView(TS ts,PetscViewer viewer) 1375 { 1376 PetscErrorCode ierr; 1377 TSType type; 1378 PetscBool iascii,isstring,isundials,isbinary,isdraw; 1379 DMTS sdm; 1380 #if defined(PETSC_HAVE_SAWS) 1381 PetscBool issaws; 1382 #endif 1383 1384 PetscFunctionBegin; 1385 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1386 if (!viewer) { 1387 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ts),&viewer);CHKERRQ(ierr); 1388 } 1389 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1390 PetscCheckSameComm(ts,1,viewer,2); 1391 1392 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1393 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 1394 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1395 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 1396 #if defined(PETSC_HAVE_SAWS) 1397 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 1398 #endif 1399 if (iascii) { 1400 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ts,viewer);CHKERRQ(ierr); 1401 ierr = PetscViewerASCIIPrintf(viewer," maximum steps=%D\n",ts->max_steps);CHKERRQ(ierr); 1402 ierr = PetscViewerASCIIPrintf(viewer," maximum time=%g\n",(double)ts->max_time);CHKERRQ(ierr); 1403 if (ts->problem_type == TS_NONLINEAR) { 1404 ierr = PetscViewerASCIIPrintf(viewer," total number of nonlinear solver iterations=%D\n",ts->snes_its);CHKERRQ(ierr); 1405 ierr = PetscViewerASCIIPrintf(viewer," total number of nonlinear solve failures=%D\n",ts->num_snes_failures);CHKERRQ(ierr); 1406 } 1407 ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",ts->ksp_its);CHKERRQ(ierr); 1408 ierr = PetscViewerASCIIPrintf(viewer," total number of rejected steps=%D\n",ts->reject);CHKERRQ(ierr); 1409 ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr); 1410 ierr = DMTSView(sdm,viewer);CHKERRQ(ierr); 1411 if (ts->ops->view) { 1412 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1413 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 1414 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1415 } 1416 } else if (isstring) { 1417 ierr = TSGetType(ts,&type);CHKERRQ(ierr); 1418 ierr = PetscViewerStringSPrintf(viewer," %-7.7s",type);CHKERRQ(ierr); 1419 } else if (isbinary) { 1420 PetscInt classid = TS_FILE_CLASSID; 1421 MPI_Comm comm; 1422 PetscMPIInt rank; 1423 char type[256]; 1424 1425 ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr); 1426 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 1427 if (!rank) { 1428 ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 1429 ierr = PetscStrncpy(type,((PetscObject)ts)->type_name,256);CHKERRQ(ierr); 1430 ierr = PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 1431 } 1432 if (ts->ops->view) { 1433 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 1434 } 1435 ierr = DMView(ts->dm,viewer);CHKERRQ(ierr); 1436 ierr = VecView(ts->vec_sol,viewer);CHKERRQ(ierr); 1437 ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr); 1438 ierr = DMTSView(sdm,viewer);CHKERRQ(ierr); 1439 } else if (isdraw) { 1440 PetscDraw draw; 1441 char str[36]; 1442 PetscReal x,y,bottom,h; 1443 1444 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 1445 ierr = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr); 1446 ierr = PetscStrcpy(str,"TS: ");CHKERRQ(ierr); 1447 ierr = PetscStrcat(str,((PetscObject)ts)->type_name);CHKERRQ(ierr); 1448 ierr = PetscDrawBoxedString(draw,x,y,PETSC_DRAW_BLACK,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr); 1449 bottom = y - h; 1450 ierr = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr); 1451 if (ts->ops->view) { 1452 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 1453 } 1454 ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr); 1455 #if defined(PETSC_HAVE_SAWS) 1456 } else if (issaws) { 1457 PetscMPIInt rank; 1458 const char *name; 1459 1460 ierr = PetscObjectGetName((PetscObject)ts,&name);CHKERRQ(ierr); 1461 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 1462 if (!((PetscObject)ts)->amsmem && !rank) { 1463 char dir[1024]; 1464 1465 ierr = PetscObjectViewSAWs((PetscObject)ts,viewer);CHKERRQ(ierr); 1466 ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time_step",name);CHKERRQ(ierr); 1467 PetscStackCallSAWs(SAWs_Register,(dir,&ts->steps,1,SAWs_READ,SAWs_INT)); 1468 ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time",name);CHKERRQ(ierr); 1469 PetscStackCallSAWs(SAWs_Register,(dir,&ts->ptime,1,SAWs_READ,SAWs_DOUBLE)); 1470 } 1471 if (ts->ops->view) { 1472 ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr); 1473 } 1474 #endif 1475 } 1476 1477 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1478 ierr = PetscObjectTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials);CHKERRQ(ierr); 1479 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1480 PetscFunctionReturn(0); 1481 } 1482 1483 1484 #undef __FUNCT__ 1485 #define __FUNCT__ "TSSetApplicationContext" 1486 /*@ 1487 TSSetApplicationContext - Sets an optional user-defined context for 1488 the timesteppers. 1489 1490 Logically Collective on TS 1491 1492 Input Parameters: 1493 + ts - the TS context obtained from TSCreate() 1494 - usrP - optional user context 1495 1496 Level: intermediate 1497 1498 .keywords: TS, timestep, set, application, context 1499 1500 .seealso: TSGetApplicationContext() 1501 @*/ 1502 PetscErrorCode TSSetApplicationContext(TS ts,void *usrP) 1503 { 1504 PetscFunctionBegin; 1505 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1506 ts->user = usrP; 1507 PetscFunctionReturn(0); 1508 } 1509 1510 #undef __FUNCT__ 1511 #define __FUNCT__ "TSGetApplicationContext" 1512 /*@ 1513 TSGetApplicationContext - Gets the user-defined context for the 1514 timestepper. 1515 1516 Not Collective 1517 1518 Input Parameter: 1519 . ts - the TS context obtained from TSCreate() 1520 1521 Output Parameter: 1522 . usrP - user context 1523 1524 Level: intermediate 1525 1526 .keywords: TS, timestep, get, application, context 1527 1528 .seealso: TSSetApplicationContext() 1529 @*/ 1530 PetscErrorCode TSGetApplicationContext(TS ts,void *usrP) 1531 { 1532 PetscFunctionBegin; 1533 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1534 *(void**)usrP = ts->user; 1535 PetscFunctionReturn(0); 1536 } 1537 1538 #undef __FUNCT__ 1539 #define __FUNCT__ "TSGetTimeStepNumber" 1540 /*@ 1541 TSGetTimeStepNumber - Gets the number of time steps completed. 1542 1543 Not Collective 1544 1545 Input Parameter: 1546 . ts - the TS context obtained from TSCreate() 1547 1548 Output Parameter: 1549 . iter - number of steps completed so far 1550 1551 Level: intermediate 1552 1553 .keywords: TS, timestep, get, iteration, number 1554 .seealso: TSGetTime(), TSGetTimeStep(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSSetPostStep() 1555 @*/ 1556 PetscErrorCode TSGetTimeStepNumber(TS ts,PetscInt *iter) 1557 { 1558 PetscFunctionBegin; 1559 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1560 PetscValidIntPointer(iter,2); 1561 *iter = ts->steps; 1562 PetscFunctionReturn(0); 1563 } 1564 1565 #undef __FUNCT__ 1566 #define __FUNCT__ "TSSetInitialTimeStep" 1567 /*@ 1568 TSSetInitialTimeStep - Sets the initial timestep to be used, 1569 as well as the initial time. 1570 1571 Logically Collective on TS 1572 1573 Input Parameters: 1574 + ts - the TS context obtained from TSCreate() 1575 . initial_time - the initial time 1576 - time_step - the size of the timestep 1577 1578 Level: intermediate 1579 1580 .seealso: TSSetTimeStep(), TSGetTimeStep() 1581 1582 .keywords: TS, set, initial, timestep 1583 @*/ 1584 PetscErrorCode TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step) 1585 { 1586 PetscErrorCode ierr; 1587 1588 PetscFunctionBegin; 1589 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1590 ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr); 1591 ierr = TSSetTime(ts,initial_time);CHKERRQ(ierr); 1592 PetscFunctionReturn(0); 1593 } 1594 1595 #undef __FUNCT__ 1596 #define __FUNCT__ "TSSetTimeStep" 1597 /*@ 1598 TSSetTimeStep - Allows one to reset the timestep at any time, 1599 useful for simple pseudo-timestepping codes. 1600 1601 Logically Collective on TS 1602 1603 Input Parameters: 1604 + ts - the TS context obtained from TSCreate() 1605 - time_step - the size of the timestep 1606 1607 Level: intermediate 1608 1609 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 1610 1611 .keywords: TS, set, timestep 1612 @*/ 1613 PetscErrorCode TSSetTimeStep(TS ts,PetscReal time_step) 1614 { 1615 PetscFunctionBegin; 1616 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1617 PetscValidLogicalCollectiveReal(ts,time_step,2); 1618 ts->time_step = time_step; 1619 ts->time_step_orig = time_step; 1620 PetscFunctionReturn(0); 1621 } 1622 1623 #undef __FUNCT__ 1624 #define __FUNCT__ "TSSetExactFinalTime" 1625 /*@ 1626 TSSetExactFinalTime - Determines whether to adapt the final time step to 1627 match the exact final time, interpolate solution to the exact final time, 1628 or just return at the final time TS computed. 1629 1630 Logically Collective on TS 1631 1632 Input Parameter: 1633 + ts - the time-step context 1634 - eftopt - exact final time option 1635 1636 Level: beginner 1637 1638 .seealso: TSExactFinalTimeOption 1639 @*/ 1640 PetscErrorCode TSSetExactFinalTime(TS ts,TSExactFinalTimeOption eftopt) 1641 { 1642 PetscFunctionBegin; 1643 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1644 PetscValidLogicalCollectiveEnum(ts,eftopt,2); 1645 ts->exact_final_time = eftopt; 1646 PetscFunctionReturn(0); 1647 } 1648 1649 #undef __FUNCT__ 1650 #define __FUNCT__ "TSGetTimeStep" 1651 /*@ 1652 TSGetTimeStep - Gets the current timestep size. 1653 1654 Not Collective 1655 1656 Input Parameter: 1657 . ts - the TS context obtained from TSCreate() 1658 1659 Output Parameter: 1660 . dt - the current timestep size 1661 1662 Level: intermediate 1663 1664 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 1665 1666 .keywords: TS, get, timestep 1667 @*/ 1668 PetscErrorCode TSGetTimeStep(TS ts,PetscReal *dt) 1669 { 1670 PetscFunctionBegin; 1671 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1672 PetscValidRealPointer(dt,2); 1673 *dt = ts->time_step; 1674 PetscFunctionReturn(0); 1675 } 1676 1677 #undef __FUNCT__ 1678 #define __FUNCT__ "TSGetSolution" 1679 /*@ 1680 TSGetSolution - Returns the solution at the present timestep. It 1681 is valid to call this routine inside the function that you are evaluating 1682 in order to move to the new timestep. This vector not changed until 1683 the solution at the next timestep has been calculated. 1684 1685 Not Collective, but Vec returned is parallel if TS is parallel 1686 1687 Input Parameter: 1688 . ts - the TS context obtained from TSCreate() 1689 1690 Output Parameter: 1691 . v - the vector containing the solution 1692 1693 Level: intermediate 1694 1695 .seealso: TSGetTimeStep() 1696 1697 .keywords: TS, timestep, get, solution 1698 @*/ 1699 PetscErrorCode TSGetSolution(TS ts,Vec *v) 1700 { 1701 PetscFunctionBegin; 1702 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1703 PetscValidPointer(v,2); 1704 *v = ts->vec_sol; 1705 PetscFunctionReturn(0); 1706 } 1707 1708 #undef __FUNCT__ 1709 #define __FUNCT__ "TSAdjointGetGradients" 1710 /*@ 1711 TSAdjointGetGradients - Returns the gradients from the TSAdjointSolve() 1712 1713 Not Collective, but Vec returned is parallel if TS is parallel 1714 1715 Input Parameter: 1716 . ts - the TS context obtained from TSCreate() 1717 1718 Output Parameter: 1719 + v - vectors containing the gradients with respect to the ODE/DAE solution variables 1720 - w - vectors containing the gradients with respect to the problem parameters 1721 1722 Level: intermediate 1723 1724 .seealso: TSGetTimeStep() 1725 1726 .keywords: TS, timestep, get, sensitivity 1727 @*/ 1728 PetscErrorCode TSAdjointGetGradients(TS ts,PetscInt *numberadjs,Vec **v,Vec **w) 1729 { 1730 PetscFunctionBegin; 1731 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1732 if (numberadjs) *numberadjs = ts->numberadjs; 1733 if (v) *v = ts->vecs_sensi; 1734 if (w) *w = ts->vecs_sensip; 1735 PetscFunctionReturn(0); 1736 } 1737 1738 /* ----- Routines to initialize and destroy a timestepper ---- */ 1739 #undef __FUNCT__ 1740 #define __FUNCT__ "TSSetProblemType" 1741 /*@ 1742 TSSetProblemType - Sets the type of problem to be solved. 1743 1744 Not collective 1745 1746 Input Parameters: 1747 + ts - The TS 1748 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 1749 .vb 1750 U_t - A U = 0 (linear) 1751 U_t - A(t) U = 0 (linear) 1752 F(t,U,U_t) = 0 (nonlinear) 1753 .ve 1754 1755 Level: beginner 1756 1757 .keywords: TS, problem type 1758 .seealso: TSSetUp(), TSProblemType, TS 1759 @*/ 1760 PetscErrorCode TSSetProblemType(TS ts, TSProblemType type) 1761 { 1762 PetscErrorCode ierr; 1763 1764 PetscFunctionBegin; 1765 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1766 ts->problem_type = type; 1767 if (type == TS_LINEAR) { 1768 SNES snes; 1769 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1770 ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr); 1771 } 1772 PetscFunctionReturn(0); 1773 } 1774 1775 #undef __FUNCT__ 1776 #define __FUNCT__ "TSGetProblemType" 1777 /*@C 1778 TSGetProblemType - Gets the type of problem to be solved. 1779 1780 Not collective 1781 1782 Input Parameter: 1783 . ts - The TS 1784 1785 Output Parameter: 1786 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms 1787 .vb 1788 M U_t = A U 1789 M(t) U_t = A(t) U 1790 F(t,U,U_t) 1791 .ve 1792 1793 Level: beginner 1794 1795 .keywords: TS, problem type 1796 .seealso: TSSetUp(), TSProblemType, TS 1797 @*/ 1798 PetscErrorCode TSGetProblemType(TS ts, TSProblemType *type) 1799 { 1800 PetscFunctionBegin; 1801 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 1802 PetscValidIntPointer(type,2); 1803 *type = ts->problem_type; 1804 PetscFunctionReturn(0); 1805 } 1806 1807 #undef __FUNCT__ 1808 #define __FUNCT__ "TSSetUp" 1809 /*@ 1810 TSSetUp - Sets up the internal data structures for the later use 1811 of a timestepper. 1812 1813 Collective on TS 1814 1815 Input Parameter: 1816 . ts - the TS context obtained from TSCreate() 1817 1818 Notes: 1819 For basic use of the TS solvers the user need not explicitly call 1820 TSSetUp(), since these actions will automatically occur during 1821 the call to TSStep(). However, if one wishes to control this 1822 phase separately, TSSetUp() should be called after TSCreate() 1823 and optional routines of the form TSSetXXX(), but before TSStep(). 1824 1825 Level: advanced 1826 1827 .keywords: TS, timestep, setup 1828 1829 .seealso: TSCreate(), TSStep(), TSDestroy() 1830 @*/ 1831 PetscErrorCode TSSetUp(TS ts) 1832 { 1833 PetscErrorCode ierr; 1834 DM dm; 1835 PetscErrorCode (*func)(SNES,Vec,Vec,void*); 1836 PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 1837 TSIJacobian ijac; 1838 TSRHSJacobian rhsjac; 1839 1840 PetscFunctionBegin; 1841 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1842 if (ts->setupcalled) PetscFunctionReturn(0); 1843 1844 ts->total_steps = 0; 1845 if (!((PetscObject)ts)->type_name) { 1846 ierr = TSSetType(ts,TSEULER);CHKERRQ(ierr); 1847 } 1848 1849 if (!ts->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first"); 1850 1851 1852 ierr = TSGetAdapt(ts,&ts->adapt);CHKERRQ(ierr); 1853 1854 if (ts->rhsjacobian.reuse) { 1855 Mat Amat,Pmat; 1856 SNES snes; 1857 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1858 ierr = SNESGetJacobian(snes,&Amat,&Pmat,NULL,NULL);CHKERRQ(ierr); 1859 /* Matching matrices implies that an IJacobian is NOT set, because if it had been set, the IJacobian's matrix would 1860 * have displaced the RHS matrix */ 1861 if (Amat == ts->Arhs) { 1862 ierr = MatDuplicate(ts->Arhs,MAT_DO_NOT_COPY_VALUES,&Amat);CHKERRQ(ierr); 1863 ierr = SNESSetJacobian(snes,Amat,NULL,NULL,NULL);CHKERRQ(ierr); 1864 ierr = MatDestroy(&Amat);CHKERRQ(ierr); 1865 } 1866 if (Pmat == ts->Brhs) { 1867 ierr = MatDuplicate(ts->Brhs,MAT_DO_NOT_COPY_VALUES,&Pmat);CHKERRQ(ierr); 1868 ierr = SNESSetJacobian(snes,NULL,Pmat,NULL,NULL);CHKERRQ(ierr); 1869 ierr = MatDestroy(&Pmat);CHKERRQ(ierr); 1870 } 1871 } 1872 if (ts->ops->setup) { 1873 ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr); 1874 } 1875 1876 /* in the case where we've set a DMTSFunction or what have you, we need the default SNESFunction 1877 to be set right but can't do it elsewhere due to the overreliance on ctx=ts. 1878 */ 1879 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 1880 ierr = DMSNESGetFunction(dm,&func,NULL);CHKERRQ(ierr); 1881 if (!func) { 1882 ierr =DMSNESSetFunction(dm,SNESTSFormFunction,ts);CHKERRQ(ierr); 1883 } 1884 /* if the SNES doesn't have a jacobian set and the TS has an ijacobian or rhsjacobian set, set the SNES to use it. 1885 Otherwise, the SNES will use coloring internally to form the Jacobian. 1886 */ 1887 ierr = DMSNESGetJacobian(dm,&jac,NULL);CHKERRQ(ierr); 1888 ierr = DMTSGetIJacobian(dm,&ijac,NULL);CHKERRQ(ierr); 1889 ierr = DMTSGetRHSJacobian(dm,&rhsjac,NULL);CHKERRQ(ierr); 1890 if (!jac && (ijac || rhsjac)) { 1891 ierr = DMSNESSetJacobian(dm,SNESTSFormJacobian,ts);CHKERRQ(ierr); 1892 } 1893 ts->setupcalled = PETSC_TRUE; 1894 PetscFunctionReturn(0); 1895 } 1896 1897 #undef __FUNCT__ 1898 #define __FUNCT__ "TSAdjointSetUp" 1899 /*@ 1900 TSAdjointSetUp - Sets up the internal data structures for the later use 1901 of an adjoint solver 1902 1903 Collective on TS 1904 1905 Input Parameter: 1906 . ts - the TS context obtained from TSCreate() 1907 1908 Notes: 1909 For basic use of the TS solvers the user need not explicitly call 1910 TSSetUp(), since these actions will automatically occur during 1911 the call to TSStep(). However, if one wishes to control this 1912 phase separately, TSSetUp() should be called after TSCreate() 1913 and optional routines of the form TSSetXXX(), but before TSStep(). 1914 1915 Level: advanced 1916 1917 .keywords: TS, timestep, setup 1918 1919 .seealso: TSCreate(), TSStep(), TSDestroy() 1920 @*/ 1921 PetscErrorCode TSAdjointSetUp(TS ts) 1922 { 1923 PetscErrorCode ierr; 1924 1925 PetscFunctionBegin; 1926 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1927 if (ts->adjointsetupcalled) PetscFunctionReturn(0); 1928 if (!ts->vecs_sensi) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSAdjointSetGradients() first"); 1929 if (ts->ops->adjointsetup) { 1930 ierr = (*ts->ops->adjointsetup)(ts);CHKERRQ(ierr); 1931 } 1932 ts->adjointsetupcalled = PETSC_TRUE; 1933 PetscFunctionReturn(0); 1934 } 1935 1936 #undef __FUNCT__ 1937 #define __FUNCT__ "TSReset" 1938 /*@ 1939 TSReset - Resets a TS context and removes any allocated Vecs and Mats. 1940 1941 Collective on TS 1942 1943 Input Parameter: 1944 . ts - the TS context obtained from TSCreate() 1945 1946 Level: beginner 1947 1948 .keywords: TS, timestep, reset 1949 1950 .seealso: TSCreate(), TSSetup(), TSDestroy() 1951 @*/ 1952 PetscErrorCode TSReset(TS ts) 1953 { 1954 PetscErrorCode ierr; 1955 1956 PetscFunctionBegin; 1957 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 1958 1959 if (ts->ops->reset) { 1960 ierr = (*ts->ops->reset)(ts);CHKERRQ(ierr); 1961 } 1962 if (ts->snes) {ierr = SNESReset(ts->snes);CHKERRQ(ierr);} 1963 1964 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 1965 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 1966 ierr = VecDestroy(&ts->Frhs);CHKERRQ(ierr); 1967 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 1968 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 1969 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 1970 ierr = VecDestroyVecs(ts->nwork,&ts->work);CHKERRQ(ierr); 1971 ts->vecs_sensi = 0; 1972 ts->vecs_sensip = 0; 1973 ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr); 1974 ierr = VecDestroy(&ts->vec_costintegral);CHKERRQ(ierr); 1975 ierr = VecDestroy(&ts->vec_costintegrand);CHKERRQ(ierr); 1976 ts->setupcalled = PETSC_FALSE; 1977 PetscFunctionReturn(0); 1978 } 1979 1980 #undef __FUNCT__ 1981 #define __FUNCT__ "TSDestroy" 1982 /*@ 1983 TSDestroy - Destroys the timestepper context that was created 1984 with TSCreate(). 1985 1986 Collective on TS 1987 1988 Input Parameter: 1989 . ts - the TS context obtained from TSCreate() 1990 1991 Level: beginner 1992 1993 .keywords: TS, timestepper, destroy 1994 1995 .seealso: TSCreate(), TSSetUp(), TSSolve() 1996 @*/ 1997 PetscErrorCode TSDestroy(TS *ts) 1998 { 1999 PetscErrorCode ierr; 2000 2001 PetscFunctionBegin; 2002 if (!*ts) PetscFunctionReturn(0); 2003 PetscValidHeaderSpecific((*ts),TS_CLASSID,1); 2004 if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; PetscFunctionReturn(0);} 2005 2006 ierr = TSReset((*ts));CHKERRQ(ierr); 2007 2008 /* if memory was published with SAWs then destroy it */ 2009 ierr = PetscObjectSAWsViewOff((PetscObject)*ts);CHKERRQ(ierr); 2010 if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);} 2011 2012 ierr = TSTrajectoryDestroy(&(*ts)->trajectory);CHKERRQ(ierr); 2013 2014 ierr = TSAdaptDestroy(&(*ts)->adapt);CHKERRQ(ierr); 2015 if ((*ts)->event) { 2016 ierr = TSEventMonitorDestroy(&(*ts)->event);CHKERRQ(ierr); 2017 } 2018 ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr); 2019 ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr); 2020 ierr = TSMonitorCancel((*ts));CHKERRQ(ierr); 2021 2022 ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr); 2023 PetscFunctionReturn(0); 2024 } 2025 2026 #undef __FUNCT__ 2027 #define __FUNCT__ "TSGetSNES" 2028 /*@ 2029 TSGetSNES - Returns the SNES (nonlinear solver) associated with 2030 a TS (timestepper) context. Valid only for nonlinear problems. 2031 2032 Not Collective, but SNES is parallel if TS is parallel 2033 2034 Input Parameter: 2035 . ts - the TS context obtained from TSCreate() 2036 2037 Output Parameter: 2038 . snes - the nonlinear solver context 2039 2040 Notes: 2041 The user can then directly manipulate the SNES context to set various 2042 options, etc. Likewise, the user can then extract and manipulate the 2043 KSP, KSP, and PC contexts as well. 2044 2045 TSGetSNES() does not work for integrators that do not use SNES; in 2046 this case TSGetSNES() returns NULL in snes. 2047 2048 Level: beginner 2049 2050 .keywords: timestep, get, SNES 2051 @*/ 2052 PetscErrorCode TSGetSNES(TS ts,SNES *snes) 2053 { 2054 PetscErrorCode ierr; 2055 2056 PetscFunctionBegin; 2057 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2058 PetscValidPointer(snes,2); 2059 if (!ts->snes) { 2060 ierr = SNESCreate(PetscObjectComm((PetscObject)ts),&ts->snes);CHKERRQ(ierr); 2061 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 2062 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->snes);CHKERRQ(ierr); 2063 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr); 2064 if (ts->dm) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 2065 if (ts->problem_type == TS_LINEAR) { 2066 ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr); 2067 } 2068 } 2069 *snes = ts->snes; 2070 PetscFunctionReturn(0); 2071 } 2072 2073 #undef __FUNCT__ 2074 #define __FUNCT__ "TSSetSNES" 2075 /*@ 2076 TSSetSNES - Set the SNES (nonlinear solver) to be used by the timestepping context 2077 2078 Collective 2079 2080 Input Parameter: 2081 + ts - the TS context obtained from TSCreate() 2082 - snes - the nonlinear solver context 2083 2084 Notes: 2085 Most users should have the TS created by calling TSGetSNES() 2086 2087 Level: developer 2088 2089 .keywords: timestep, set, SNES 2090 @*/ 2091 PetscErrorCode TSSetSNES(TS ts,SNES snes) 2092 { 2093 PetscErrorCode ierr; 2094 PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*); 2095 2096 PetscFunctionBegin; 2097 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2098 PetscValidHeaderSpecific(snes,SNES_CLASSID,2); 2099 ierr = PetscObjectReference((PetscObject)snes);CHKERRQ(ierr); 2100 ierr = SNESDestroy(&ts->snes);CHKERRQ(ierr); 2101 2102 ts->snes = snes; 2103 2104 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 2105 ierr = SNESGetJacobian(ts->snes,NULL,NULL,&func,NULL);CHKERRQ(ierr); 2106 if (func == SNESTSFormJacobian) { 2107 ierr = SNESSetJacobian(ts->snes,NULL,NULL,SNESTSFormJacobian,ts);CHKERRQ(ierr); 2108 } 2109 PetscFunctionReturn(0); 2110 } 2111 2112 #undef __FUNCT__ 2113 #define __FUNCT__ "TSGetKSP" 2114 /*@ 2115 TSGetKSP - Returns the KSP (linear solver) associated with 2116 a TS (timestepper) context. 2117 2118 Not Collective, but KSP is parallel if TS is parallel 2119 2120 Input Parameter: 2121 . ts - the TS context obtained from TSCreate() 2122 2123 Output Parameter: 2124 . ksp - the nonlinear solver context 2125 2126 Notes: 2127 The user can then directly manipulate the KSP context to set various 2128 options, etc. Likewise, the user can then extract and manipulate the 2129 KSP and PC contexts as well. 2130 2131 TSGetKSP() does not work for integrators that do not use KSP; 2132 in this case TSGetKSP() returns NULL in ksp. 2133 2134 Level: beginner 2135 2136 .keywords: timestep, get, KSP 2137 @*/ 2138 PetscErrorCode TSGetKSP(TS ts,KSP *ksp) 2139 { 2140 PetscErrorCode ierr; 2141 SNES snes; 2142 2143 PetscFunctionBegin; 2144 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2145 PetscValidPointer(ksp,2); 2146 if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first"); 2147 if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()"); 2148 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2149 ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr); 2150 PetscFunctionReturn(0); 2151 } 2152 2153 /* ----------- Routines to set solver parameters ---------- */ 2154 2155 #undef __FUNCT__ 2156 #define __FUNCT__ "TSGetDuration" 2157 /*@ 2158 TSGetDuration - Gets the maximum number of timesteps to use and 2159 maximum time for iteration. 2160 2161 Not Collective 2162 2163 Input Parameters: 2164 + ts - the TS context obtained from TSCreate() 2165 . maxsteps - maximum number of iterations to use, or NULL 2166 - maxtime - final time to iterate to, or NULL 2167 2168 Level: intermediate 2169 2170 .keywords: TS, timestep, get, maximum, iterations, time 2171 @*/ 2172 PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime) 2173 { 2174 PetscFunctionBegin; 2175 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2176 if (maxsteps) { 2177 PetscValidIntPointer(maxsteps,2); 2178 *maxsteps = ts->max_steps; 2179 } 2180 if (maxtime) { 2181 PetscValidScalarPointer(maxtime,3); 2182 *maxtime = ts->max_time; 2183 } 2184 PetscFunctionReturn(0); 2185 } 2186 2187 #undef __FUNCT__ 2188 #define __FUNCT__ "TSSetDuration" 2189 /*@ 2190 TSSetDuration - Sets the maximum number of timesteps to use and 2191 maximum time for iteration. 2192 2193 Logically Collective on TS 2194 2195 Input Parameters: 2196 + ts - the TS context obtained from TSCreate() 2197 . maxsteps - maximum number of iterations to use 2198 - maxtime - final time to iterate to 2199 2200 Options Database Keys: 2201 . -ts_max_steps <maxsteps> - Sets maxsteps 2202 . -ts_final_time <maxtime> - Sets maxtime 2203 2204 Notes: 2205 The default maximum number of iterations is 5000. Default time is 5.0 2206 2207 Level: intermediate 2208 2209 .keywords: TS, timestep, set, maximum, iterations 2210 2211 .seealso: TSSetExactFinalTime() 2212 @*/ 2213 PetscErrorCode TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime) 2214 { 2215 PetscFunctionBegin; 2216 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2217 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 2218 PetscValidLogicalCollectiveReal(ts,maxtime,2); 2219 if (maxsteps >= 0) ts->max_steps = maxsteps; 2220 if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime; 2221 PetscFunctionReturn(0); 2222 } 2223 2224 #undef __FUNCT__ 2225 #define __FUNCT__ "TSSetSolution" 2226 /*@ 2227 TSSetSolution - Sets the initial solution vector 2228 for use by the TS routines. 2229 2230 Logically Collective on TS and Vec 2231 2232 Input Parameters: 2233 + ts - the TS context obtained from TSCreate() 2234 - u - the solution vector 2235 2236 Level: beginner 2237 2238 .keywords: TS, timestep, set, solution, initial conditions 2239 @*/ 2240 PetscErrorCode TSSetSolution(TS ts,Vec u) 2241 { 2242 PetscErrorCode ierr; 2243 DM dm; 2244 2245 PetscFunctionBegin; 2246 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2247 PetscValidHeaderSpecific(u,VEC_CLASSID,2); 2248 ierr = PetscObjectReference((PetscObject)u);CHKERRQ(ierr); 2249 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 2250 2251 ts->vec_sol = u; 2252 2253 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 2254 ierr = DMShellSetGlobalVector(dm,u);CHKERRQ(ierr); 2255 PetscFunctionReturn(0); 2256 } 2257 2258 #undef __FUNCT__ 2259 #define __FUNCT__ "TSAdjointSetSteps" 2260 /*@ 2261 TSAdjointSetSteps - Sets the number of steps the adjoint solver should take backward in time 2262 2263 Logically Collective on TS 2264 2265 Input Parameters: 2266 + ts - the TS context obtained from TSCreate() 2267 . steps - number of steps to use 2268 2269 Level: intermediate 2270 2271 Notes: Normally one does not call this and TSAdjointSolve() integrates back to the original timestep. One can call this 2272 so as to integrate back to less than the original timestep 2273 2274 .keywords: TS, timestep, set, maximum, iterations 2275 2276 .seealso: TSSetExactFinalTime() 2277 @*/ 2278 PetscErrorCode TSAdjointSetSteps(TS ts,PetscInt steps) 2279 { 2280 PetscFunctionBegin; 2281 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2282 PetscValidLogicalCollectiveInt(ts,steps,2); 2283 if (steps < 0) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back a negative number of steps"); 2284 if (steps > ts->total_steps) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back more than the total number of forward steps"); 2285 ts->adjoint_max_steps = steps; 2286 PetscFunctionReturn(0); 2287 } 2288 2289 #undef __FUNCT__ 2290 #define __FUNCT__ "TSAdjointSetGradients" 2291 /*@ 2292 TSAdjointSetGradients - Sets the initial value of gradients w.r.t. initial conditions and w.r.t. the problem parameters for use by the TS routines. 2293 2294 Logically Collective on TS and Vec 2295 2296 Input Parameters: 2297 + ts - the TS context obtained from TSCreate() 2298 . u - gradients with respect to the initial condition variables 2299 - w - gradients with respect to the parameters 2300 2301 Level: beginner 2302 2303 .keywords: TS, timestep, set, sensitivity, initial conditions 2304 @*/ 2305 PetscErrorCode TSAdjointSetGradients(TS ts,PetscInt numberadjs,Vec *u,Vec *w) 2306 { 2307 PetscFunctionBegin; 2308 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2309 PetscValidPointer(u,2); 2310 ts->vecs_sensi = u; 2311 ts->vecs_sensip = w; 2312 ts->numberadjs = numberadjs; 2313 PetscFunctionReturn(0); 2314 } 2315 2316 #undef __FUNCT__ 2317 #define __FUNCT__ "TSAdjointSetRHSJacobian" 2318 /*@C 2319 TSAdjointSetRHSJacobian - Sets the function that computes the Jacobian w.r.t. parameters. 2320 2321 Logically Collective on TS 2322 2323 Input Parameters: 2324 + ts - The TS context obtained from TSCreate() 2325 - func - The function 2326 2327 Calling sequence of func: 2328 $ func (TS ts,PetscReal t,Vec u,Mat A,void *ctx); 2329 + t - current timestep 2330 . u - input vector 2331 . A - output matrix 2332 - ctx - [optional] user-defined function context 2333 2334 Level: intermediate 2335 2336 .keywords: TS, sensitivity 2337 .seealso: 2338 @*/ 2339 PetscErrorCode TSAdjointSetRHSJacobian(TS ts,Mat Amat,PetscErrorCode (*func)(TS,PetscReal,Vec,Mat,void*),void *ctx) 2340 { 2341 PetscErrorCode ierr; 2342 2343 PetscFunctionBegin; 2344 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2345 if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 2346 2347 ts->rhsjacobianp = func; 2348 ts->rhsjacobianpctx = ctx; 2349 if(Amat) { 2350 ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 2351 ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr); 2352 2353 ts->Jacp = Amat; 2354 } 2355 PetscFunctionReturn(0); 2356 } 2357 2358 #undef __FUNCT__ 2359 #define __FUNCT__ "TSAdjointComputeRHSJacobian" 2360 /*@ 2361 TSAdjointComputeRHSJacobian - Runs the user-defined Jacobian function. 2362 2363 Collective on TS 2364 2365 Input Parameters: 2366 . ts - The TS context obtained from TSCreate() 2367 2368 Level: developer 2369 2370 .keywords: TS, sensitivity 2371 .seealso: TSAdjointSetRHSJacobian() 2372 @*/ 2373 PetscErrorCode TSAdjointComputeRHSJacobian(TS ts,PetscReal t,Vec X,Mat Amat) 2374 { 2375 PetscErrorCode ierr; 2376 2377 PetscFunctionBegin; 2378 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2379 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 2380 PetscValidPointer(Amat,4); 2381 2382 PetscStackPush("TS user JacobianP function for sensitivity analysis"); 2383 ierr = (*ts->rhsjacobianp)(ts,t,X,Amat,ts->rhsjacobianpctx); CHKERRQ(ierr); 2384 PetscStackPop; 2385 2386 PetscFunctionReturn(0); 2387 } 2388 2389 #undef __FUNCT__ 2390 #define __FUNCT__ "TSAdjointSetCostIntegrand" 2391 /*@C 2392 TSAdjointSetCostIntegrand - Sets the routine for evaluating the integral term in a cost function 2393 2394 Logically Collective on TS 2395 2396 Input Parameters: 2397 + ts - the TS context obtained from TSCreate() 2398 . numberadjs - number of gradients to be computed 2399 . fq - routine for evaluating the right-hand-side function 2400 . drdy - array of vectors to contain the gradient of the r's with respect to y, NULL if not a function of y 2401 . drdyf - function that computes the gradients of the r's with respect to y,NULL if not a function y 2402 . drdp - array of vectors to contain the gradient of the r's with respect to p, NULL if not a function of p 2403 . drdpf - function that computes the gradients of the r's with respect to p, NULL if not a function of p 2404 - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL) 2405 2406 Calling sequence of fq: 2407 $ TSCostIntegrand(TS ts,PetscReal t,Vec u,PetscReal *f,void *ctx); 2408 2409 + t - current timestep 2410 . u - input vector 2411 . f - function vector 2412 - ctx - [optional] user-defined function context 2413 2414 Calling sequence of drdyf: 2415 $ PetscErroCode drdyf(TS ts,PetscReal t,Vec U,Vec *drdy,void *ctx); 2416 2417 Calling sequence of drdpf: 2418 $ PetscErroCode drdpf(TS ts,PetscReal t,Vec U,Vec *drdp,void *ctx); 2419 2420 Level: intermediate 2421 2422 .keywords: TS, sensitivity analysis, timestep, set, quadrature, function 2423 2424 .seealso: TSAdjointSetRHSJacobian(),TSAdjointGetGradients(), TSAdjointSetGradients() 2425 @*/ 2426 PetscErrorCode TSAdjointSetCostIntegrand(TS ts,PetscInt numberadjs, PetscErrorCode (*fq)(TS,PetscReal,Vec,Vec,void*), 2427 Vec *drdy,PetscErrorCode (*drdyf)(TS,PetscReal,Vec,Vec*,void*), 2428 Vec *drdp,PetscErrorCode (*drdpf)(TS,PetscReal,Vec,Vec*,void*),void *ctx) 2429 { 2430 PetscErrorCode ierr; 2431 2432 PetscFunctionBegin; 2433 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2434 if (!ts->numberadjs) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Call TSAdjointSetGradients() first so that the number of cost functions can be determined."); 2435 if (ts->numberadjs && ts->numberadjs!=numberadjs) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"The number of cost functions (2rd parameter of TSAdjointSetCostIntegrand()) is inconsistent with the one set by TSAdjointSetGradients()"); 2436 2437 ierr = VecCreateSeq(PETSC_COMM_SELF,numberadjs,&ts->vec_costintegral);CHKERRQ(ierr); 2438 ierr = VecDuplicate(ts->vec_costintegral,&ts->vec_costintegrand);CHKERRQ(ierr); 2439 ts->costintegrand = fq; 2440 ts->costintegrandctx = ctx; 2441 2442 ts->drdyfunction = drdyf; 2443 ts->vecs_drdy = drdy; 2444 2445 ts->drdpfunction = drdpf; 2446 ts->vecs_drdp = drdp; 2447 2448 PetscFunctionReturn(0); 2449 } 2450 2451 #undef __FUNCT__ 2452 #define __FUNCT__ "TSAdjointGetCostIntegral" 2453 /*@ 2454 TSAdjointGetCostIntegral - Returns the values of the integral term in the cost functions. 2455 It is valid to call the routine after a backward run. 2456 2457 Not Collective 2458 2459 Input Parameter: 2460 . ts - the TS context obtained from TSCreate() 2461 2462 Output Parameter: 2463 . v - the vector containing the integrals for each cost function 2464 2465 Level: intermediate 2466 2467 .seealso: TSAdjointSetCostIntegrand() 2468 2469 .keywords: TS, sensitivity analysis 2470 @*/ 2471 PetscErrorCode TSAdjointGetCostIntegral(TS ts,Vec *v) 2472 { 2473 PetscFunctionBegin; 2474 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2475 PetscValidPointer(v,2); 2476 *v = ts->vec_costintegral; 2477 PetscFunctionReturn(0); 2478 } 2479 2480 #undef __FUNCT__ 2481 #define __FUNCT__ "TSAdjointComputeCostIntegrand" 2482 /*@ 2483 TSAdjointComputeCostIntegrand - Evaluates the integral function in the cost functions. 2484 2485 Input Parameters: 2486 + ts - the TS context 2487 . t - current time 2488 - U - state vector 2489 2490 Output Parameter: 2491 . q - vector of size numberadjs to hold the outputs 2492 2493 Note: 2494 Most users should not need to explicitly call this routine, as it 2495 is used internally within the sensitivity analysis context. 2496 2497 Level: developer 2498 2499 .keywords: TS, compute 2500 2501 .seealso: TSAdjointSetCostIntegrand() 2502 @*/ 2503 PetscErrorCode TSAdjointComputeCostIntegrand(TS ts,PetscReal t,Vec U,Vec q) 2504 { 2505 PetscErrorCode ierr; 2506 2507 PetscFunctionBegin; 2508 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2509 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 2510 PetscValidHeaderSpecific(q,VEC_CLASSID,4); 2511 2512 ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,q,0);CHKERRQ(ierr); 2513 if (ts->costintegrand) { 2514 PetscStackPush("TS user integrand in the cost function"); 2515 ierr = (*ts->costintegrand)(ts,t,U,q,ts->costintegrandctx);CHKERRQ(ierr); 2516 PetscStackPop; 2517 } else { 2518 ierr = VecZeroEntries(q);CHKERRQ(ierr); 2519 } 2520 2521 ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,q,0);CHKERRQ(ierr); 2522 PetscFunctionReturn(0); 2523 } 2524 2525 #undef __FUNCT__ 2526 #define __FUNCT__ "TSAdjointComputeDRDYFunction" 2527 /*@ 2528 TSAdjointComputeDRDYFunction - Runs the user-defined DRDY function. 2529 2530 Collective on TS 2531 2532 Input Parameters: 2533 . ts - The TS context obtained from TSCreate() 2534 2535 Notes: 2536 TSAdjointComputeDRDYFunction() is typically used for sensitivity implementation, 2537 so most users would not generally call this routine themselves. 2538 2539 Level: developer 2540 2541 .keywords: TS, sensitivity 2542 .seealso: TSAdjointComputeDRDYFunction() 2543 @*/ 2544 PetscErrorCode TSAdjointComputeDRDYFunction(TS ts,PetscReal t,Vec X,Vec *drdy) 2545 { 2546 PetscErrorCode ierr; 2547 2548 PetscFunctionBegin; 2549 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2550 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 2551 2552 PetscStackPush("TS user DRDY function for sensitivity analysis"); 2553 ierr = (*ts->drdyfunction)(ts,t,X,drdy,ts->costintegrandctx); CHKERRQ(ierr); 2554 PetscStackPop; 2555 PetscFunctionReturn(0); 2556 } 2557 2558 #undef __FUNCT__ 2559 #define __FUNCT__ "TSAdjointComputeDRDPFunction" 2560 /*@ 2561 TSAdjointComputeDRDPFunction - Runs the user-defined DRDP function. 2562 2563 Collective on TS 2564 2565 Input Parameters: 2566 . ts - The TS context obtained from TSCreate() 2567 2568 Notes: 2569 TSDRDPFunction() is typically used for sensitivity implementation, 2570 so most users would not generally call this routine themselves. 2571 2572 Level: developer 2573 2574 .keywords: TS, sensitivity 2575 .seealso: TSAdjointSetDRDPFunction() 2576 @*/ 2577 PetscErrorCode TSAdjointComputeDRDPFunction(TS ts,PetscReal t,Vec X,Vec *drdp) 2578 { 2579 PetscErrorCode ierr; 2580 2581 PetscFunctionBegin; 2582 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2583 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 2584 2585 PetscStackPush("TS user DRDP function for sensitivity analysis"); 2586 ierr = (*ts->drdpfunction)(ts,t,X,drdp,ts->costintegrandctx); CHKERRQ(ierr); 2587 PetscStackPop; 2588 PetscFunctionReturn(0); 2589 } 2590 2591 #undef __FUNCT__ 2592 #define __FUNCT__ "TSSetPreStep" 2593 /*@C 2594 TSSetPreStep - Sets the general-purpose function 2595 called once at the beginning of each time step. 2596 2597 Logically Collective on TS 2598 2599 Input Parameters: 2600 + ts - The TS context obtained from TSCreate() 2601 - func - The function 2602 2603 Calling sequence of func: 2604 . func (TS ts); 2605 2606 Level: intermediate 2607 2608 Note: 2609 If a step is rejected, TSStep() will call this routine again before each attempt. 2610 The last completed time step number can be queried using TSGetTimeStepNumber(), the 2611 size of the step being attempted can be obtained using TSGetTimeStep(). 2612 2613 .keywords: TS, timestep 2614 .seealso: TSSetPreStage(), TSSetPostStage(), TSSetPostStep(), TSStep() 2615 @*/ 2616 PetscErrorCode TSSetPreStep(TS ts, PetscErrorCode (*func)(TS)) 2617 { 2618 PetscFunctionBegin; 2619 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2620 ts->prestep = func; 2621 PetscFunctionReturn(0); 2622 } 2623 2624 #undef __FUNCT__ 2625 #define __FUNCT__ "TSPreStep" 2626 /*@ 2627 TSPreStep - Runs the user-defined pre-step function. 2628 2629 Collective on TS 2630 2631 Input Parameters: 2632 . ts - The TS context obtained from TSCreate() 2633 2634 Notes: 2635 TSPreStep() is typically used within time stepping implementations, 2636 so most users would not generally call this routine themselves. 2637 2638 Level: developer 2639 2640 .keywords: TS, timestep 2641 .seealso: TSSetPreStep(), TSPreStage(), TSPostStage(), TSPostStep() 2642 @*/ 2643 PetscErrorCode TSPreStep(TS ts) 2644 { 2645 PetscErrorCode ierr; 2646 2647 PetscFunctionBegin; 2648 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2649 if (ts->prestep) { 2650 PetscStackCallStandard((*ts->prestep),(ts)); 2651 } 2652 PetscFunctionReturn(0); 2653 } 2654 2655 #undef __FUNCT__ 2656 #define __FUNCT__ "TSSetPreStage" 2657 /*@C 2658 TSSetPreStage - Sets the general-purpose function 2659 called once at the beginning of each stage. 2660 2661 Logically Collective on TS 2662 2663 Input Parameters: 2664 + ts - The TS context obtained from TSCreate() 2665 - func - The function 2666 2667 Calling sequence of func: 2668 . PetscErrorCode func(TS ts, PetscReal stagetime); 2669 2670 Level: intermediate 2671 2672 Note: 2673 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 2674 The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being 2675 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 2676 2677 .keywords: TS, timestep 2678 .seealso: TSSetPostStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 2679 @*/ 2680 PetscErrorCode TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal)) 2681 { 2682 PetscFunctionBegin; 2683 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2684 ts->prestage = func; 2685 PetscFunctionReturn(0); 2686 } 2687 2688 #undef __FUNCT__ 2689 #define __FUNCT__ "TSSetPostStage" 2690 /*@C 2691 TSSetPostStage - Sets the general-purpose function 2692 called once at the end of each stage. 2693 2694 Logically Collective on TS 2695 2696 Input Parameters: 2697 + ts - The TS context obtained from TSCreate() 2698 - func - The function 2699 2700 Calling sequence of func: 2701 . PetscErrorCode func(TS ts, PetscReal stagetime, PetscInt stageindex, Vec* Y); 2702 2703 Level: intermediate 2704 2705 Note: 2706 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 2707 The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being 2708 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 2709 2710 .keywords: TS, timestep 2711 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 2712 @*/ 2713 PetscErrorCode TSSetPostStage(TS ts, PetscErrorCode (*func)(TS,PetscReal,PetscInt,Vec*)) 2714 { 2715 PetscFunctionBegin; 2716 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2717 ts->poststage = func; 2718 PetscFunctionReturn(0); 2719 } 2720 2721 #undef __FUNCT__ 2722 #define __FUNCT__ "TSPreStage" 2723 /*@ 2724 TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage() 2725 2726 Collective on TS 2727 2728 Input Parameters: 2729 . ts - The TS context obtained from TSCreate() 2730 stagetime - The absolute time of the current stage 2731 2732 Notes: 2733 TSPreStage() is typically used within time stepping implementations, 2734 most users would not generally call this routine themselves. 2735 2736 Level: developer 2737 2738 .keywords: TS, timestep 2739 .seealso: TSPostStage(), TSSetPreStep(), TSPreStep(), TSPostStep() 2740 @*/ 2741 PetscErrorCode TSPreStage(TS ts, PetscReal stagetime) 2742 { 2743 PetscErrorCode ierr; 2744 2745 PetscFunctionBegin; 2746 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2747 if (ts->prestage) { 2748 PetscStackCallStandard((*ts->prestage),(ts,stagetime)); 2749 } 2750 PetscFunctionReturn(0); 2751 } 2752 2753 #undef __FUNCT__ 2754 #define __FUNCT__ "TSPostStage" 2755 /*@ 2756 TSPostStage - Runs the user-defined post-stage function set using TSSetPostStage() 2757 2758 Collective on TS 2759 2760 Input Parameters: 2761 . ts - The TS context obtained from TSCreate() 2762 stagetime - The absolute time of the current stage 2763 stageindex - Stage number 2764 Y - Array of vectors (of size = total number 2765 of stages) with the stage solutions 2766 2767 Notes: 2768 TSPostStage() is typically used within time stepping implementations, 2769 most users would not generally call this routine themselves. 2770 2771 Level: developer 2772 2773 .keywords: TS, timestep 2774 .seealso: TSPreStage(), TSSetPreStep(), TSPreStep(), TSPostStep() 2775 @*/ 2776 PetscErrorCode TSPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y) 2777 { 2778 PetscErrorCode ierr; 2779 2780 PetscFunctionBegin; 2781 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2782 if (ts->poststage) { 2783 PetscStackCallStandard((*ts->poststage),(ts,stagetime,stageindex,Y)); 2784 } 2785 PetscFunctionReturn(0); 2786 } 2787 2788 #undef __FUNCT__ 2789 #define __FUNCT__ "TSSetPostStep" 2790 /*@C 2791 TSSetPostStep - Sets the general-purpose function 2792 called once at the end of each time step. 2793 2794 Logically Collective on TS 2795 2796 Input Parameters: 2797 + ts - The TS context obtained from TSCreate() 2798 - func - The function 2799 2800 Calling sequence of func: 2801 $ func (TS ts); 2802 2803 Level: intermediate 2804 2805 .keywords: TS, timestep 2806 .seealso: TSSetPreStep(), TSSetPreStage(), TSGetTimeStep(), TSGetTimeStepNumber(), TSGetTime() 2807 @*/ 2808 PetscErrorCode TSSetPostStep(TS ts, PetscErrorCode (*func)(TS)) 2809 { 2810 PetscFunctionBegin; 2811 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2812 ts->poststep = func; 2813 PetscFunctionReturn(0); 2814 } 2815 2816 #undef __FUNCT__ 2817 #define __FUNCT__ "TSPostStep" 2818 /*@ 2819 TSPostStep - Runs the user-defined post-step function. 2820 2821 Collective on TS 2822 2823 Input Parameters: 2824 . ts - The TS context obtained from TSCreate() 2825 2826 Notes: 2827 TSPostStep() is typically used within time stepping implementations, 2828 so most users would not generally call this routine themselves. 2829 2830 Level: developer 2831 2832 .keywords: TS, timestep 2833 @*/ 2834 PetscErrorCode TSPostStep(TS ts) 2835 { 2836 PetscErrorCode ierr; 2837 2838 PetscFunctionBegin; 2839 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2840 if (ts->poststep) { 2841 PetscStackCallStandard((*ts->poststep),(ts)); 2842 } 2843 PetscFunctionReturn(0); 2844 } 2845 2846 /* ------------ Routines to set performance monitoring options ----------- */ 2847 2848 #undef __FUNCT__ 2849 #define __FUNCT__ "TSMonitorSet" 2850 /*@C 2851 TSMonitorSet - Sets an ADDITIONAL function that is to be used at every 2852 timestep to display the iteration's progress. 2853 2854 Logically Collective on TS 2855 2856 Input Parameters: 2857 + ts - the TS context obtained from TSCreate() 2858 . monitor - monitoring routine 2859 . mctx - [optional] user-defined context for private data for the 2860 monitor routine (use NULL if no context is desired) 2861 - monitordestroy - [optional] routine that frees monitor context 2862 (may be NULL) 2863 2864 Calling sequence of monitor: 2865 $ int monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx) 2866 2867 + ts - the TS context 2868 . 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 2869 been interpolated to) 2870 . time - current time 2871 . u - current iterate 2872 - mctx - [optional] monitoring context 2873 2874 Notes: 2875 This routine adds an additional monitor to the list of monitors that 2876 already has been loaded. 2877 2878 Fortran notes: Only a single monitor function can be set for each TS object 2879 2880 Level: intermediate 2881 2882 .keywords: TS, timestep, set, monitor 2883 2884 .seealso: TSMonitorDefault(), TSMonitorCancel() 2885 @*/ 2886 PetscErrorCode TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**)) 2887 { 2888 PetscFunctionBegin; 2889 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2890 if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2891 ts->monitor[ts->numbermonitors] = monitor; 2892 ts->monitordestroy[ts->numbermonitors] = mdestroy; 2893 ts->monitorcontext[ts->numbermonitors++] = (void*)mctx; 2894 PetscFunctionReturn(0); 2895 } 2896 2897 #undef __FUNCT__ 2898 #define __FUNCT__ "TSMonitorCancel" 2899 /*@C 2900 TSMonitorCancel - Clears all the monitors that have been set on a time-step object. 2901 2902 Logically Collective on TS 2903 2904 Input Parameters: 2905 . ts - the TS context obtained from TSCreate() 2906 2907 Notes: 2908 There is no way to remove a single, specific monitor. 2909 2910 Level: intermediate 2911 2912 .keywords: TS, timestep, set, monitor 2913 2914 .seealso: TSMonitorDefault(), TSMonitorSet() 2915 @*/ 2916 PetscErrorCode TSMonitorCancel(TS ts) 2917 { 2918 PetscErrorCode ierr; 2919 PetscInt i; 2920 2921 PetscFunctionBegin; 2922 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2923 for (i=0; i<ts->numbermonitors; i++) { 2924 if (ts->monitordestroy[i]) { 2925 ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr); 2926 } 2927 } 2928 ts->numbermonitors = 0; 2929 PetscFunctionReturn(0); 2930 } 2931 2932 #undef __FUNCT__ 2933 #define __FUNCT__ "TSMonitorDefault" 2934 /*@ 2935 TSMonitorDefault - Sets the Default monitor 2936 2937 Level: intermediate 2938 2939 .keywords: TS, set, monitor 2940 2941 .seealso: TSMonitorDefault(), TSMonitorSet() 2942 @*/ 2943 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,void *dummy) 2944 { 2945 PetscErrorCode ierr; 2946 PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)ts)); 2947 2948 PetscFunctionBegin; 2949 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 2950 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g\n",step,(double)ts->time_step,(double)ptime);CHKERRQ(ierr); 2951 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 2952 PetscFunctionReturn(0); 2953 } 2954 2955 #undef __FUNCT__ 2956 #define __FUNCT__ "TSSetRetainStages" 2957 /*@ 2958 TSSetRetainStages - Request that all stages in the upcoming step be stored so that interpolation will be available. 2959 2960 Logically Collective on TS 2961 2962 Input Argument: 2963 . ts - time stepping context 2964 2965 Output Argument: 2966 . flg - PETSC_TRUE or PETSC_FALSE 2967 2968 Level: intermediate 2969 2970 .keywords: TS, set 2971 2972 .seealso: TSInterpolate(), TSSetPostStep() 2973 @*/ 2974 PetscErrorCode TSSetRetainStages(TS ts,PetscBool flg) 2975 { 2976 PetscFunctionBegin; 2977 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2978 ts->retain_stages = flg; 2979 PetscFunctionReturn(0); 2980 } 2981 2982 #undef __FUNCT__ 2983 #define __FUNCT__ "TSInterpolate" 2984 /*@ 2985 TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval 2986 2987 Collective on TS 2988 2989 Input Argument: 2990 + ts - time stepping context 2991 - t - time to interpolate to 2992 2993 Output Argument: 2994 . U - state at given time 2995 2996 Notes: 2997 The user should call TSSetRetainStages() before taking a step in which interpolation will be requested. 2998 2999 Level: intermediate 3000 3001 Developer Notes: 3002 TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints. 3003 3004 .keywords: TS, set 3005 3006 .seealso: TSSetRetainStages(), TSSetPostStep() 3007 @*/ 3008 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U) 3009 { 3010 PetscErrorCode ierr; 3011 3012 PetscFunctionBegin; 3013 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3014 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 3015 if (t < ts->ptime - ts->time_step_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-ts->time_step_prev),(double)ts->ptime); 3016 if (!ts->ops->interpolate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name); 3017 ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr); 3018 PetscFunctionReturn(0); 3019 } 3020 3021 #undef __FUNCT__ 3022 #define __FUNCT__ "TSStep" 3023 /*@ 3024 TSStep - Steps one time step 3025 3026 Collective on TS 3027 3028 Input Parameter: 3029 . ts - the TS context obtained from TSCreate() 3030 3031 Level: developer 3032 3033 Notes: 3034 The public interface for the ODE/DAE solvers is TSSolve(), you should almost for sure be using that routine and not this routine. 3035 3036 The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may 3037 be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages. 3038 3039 This may over-step the final time provided in TSSetDuration() depending on the time-step used. TSSolve() interpolates to exactly the 3040 time provided in TSSetDuration(). One can use TSInterpolate() to determine an interpolated solution within the final timestep. 3041 3042 .keywords: TS, timestep, solve 3043 3044 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSInterpolate() 3045 @*/ 3046 PetscErrorCode TSStep(TS ts) 3047 { 3048 DM dm; 3049 PetscErrorCode ierr; 3050 static PetscBool cite = PETSC_FALSE; 3051 3052 PetscFunctionBegin; 3053 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3054 ierr = PetscCitationsRegister("@techreport{tspaper,\n" 3055 " title = {{PETSc/TS}: A Modern Scalable {DAE/ODE} Solver Library},\n" 3056 " author = {Shrirang Abhyankar and Jed Brown and Emil Constantinescu and Debojyoti Ghosh and Barry F. Smith},\n" 3057 " type = {Preprint},\n" 3058 " number = {ANL/MCS-P5061-0114},\n" 3059 " institution = {Argonne National Laboratory},\n" 3060 " year = {2014}\n}\n",&cite); 3061 3062 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 3063 ierr = TSSetUp(ts);CHKERRQ(ierr); 3064 3065 ts->reason = TS_CONVERGED_ITERATING; 3066 ts->ptime_prev = ts->ptime; 3067 ierr = DMSetOutputSequenceNumber(dm, ts->steps, ts->ptime);CHKERRQ(ierr); 3068 3069 if (!ts->ops->step) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSStep not implemented for type '%s'",((PetscObject)ts)->type_name); 3070 ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3071 ierr = (*ts->ops->step)(ts);CHKERRQ(ierr); 3072 ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3073 3074 ts->time_step_prev = ts->ptime - ts->ptime_prev; 3075 ierr = DMSetOutputSequenceNumber(dm, ts->steps, ts->ptime);CHKERRQ(ierr); 3076 3077 if (ts->reason < 0) { 3078 if (ts->errorifstepfailed) { 3079 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]); 3080 else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]); 3081 } 3082 } else if (!ts->reason) { 3083 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 3084 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 3085 } 3086 ts->total_steps++; 3087 PetscFunctionReturn(0); 3088 } 3089 3090 #undef __FUNCT__ 3091 #define __FUNCT__ "TSAdjointStep" 3092 /*@ 3093 TSAdjointStep - Steps one time step 3094 3095 Collective on TS 3096 3097 Input Parameter: 3098 . ts - the TS context obtained from TSCreate() 3099 3100 Level: intermediate 3101 3102 Notes: 3103 The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may 3104 be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages. 3105 3106 This may over-step the final time provided in TSSetDuration() depending on the time-step used. TSSolve() interpolates to exactly the 3107 time provided in TSSetDuration(). One can use TSInterpolate() to determine an interpolated solution within the final timestep. 3108 3109 .keywords: TS, timestep, solve 3110 3111 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSInterpolate() 3112 @*/ 3113 PetscErrorCode TSAdjointStep(TS ts) 3114 { 3115 DM dm; 3116 PetscErrorCode ierr; 3117 3118 PetscFunctionBegin; 3119 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3120 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 3121 ierr = TSAdjointSetUp(ts);CHKERRQ(ierr); 3122 3123 ts->reason = TS_CONVERGED_ITERATING; 3124 ts->ptime_prev = ts->ptime; 3125 ierr = DMSetOutputSequenceNumber(dm, ts->steps, ts->ptime);CHKERRQ(ierr); 3126 ierr = VecViewFromOptions(ts->vec_sol, ((PetscObject) ts)->prefix, "-ts_view_solution");CHKERRQ(ierr); 3127 3128 ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3129 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); 3130 ierr = (*ts->ops->adjointstep)(ts);CHKERRQ(ierr); 3131 ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3132 3133 ts->time_step_prev = ts->ptime - ts->ptime_prev; 3134 ierr = DMSetOutputSequenceNumber(dm, ts->steps, ts->ptime);CHKERRQ(ierr); 3135 3136 if (ts->reason < 0) { 3137 if (ts->errorifstepfailed) { 3138 if (ts->reason == TS_DIVERGED_NONLINEAR_SOLVE) { 3139 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]); 3140 } else if (ts->reason == TS_DIVERGED_STEP_REJECTED) { 3141 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]); 3142 } else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]); 3143 } 3144 } else if (!ts->reason) { 3145 if (ts->steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS; 3146 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 3147 } 3148 ts->total_steps--; 3149 PetscFunctionReturn(0); 3150 } 3151 3152 #undef __FUNCT__ 3153 #define __FUNCT__ "TSEvaluateStep" 3154 /*@ 3155 TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy. 3156 3157 Collective on TS 3158 3159 Input Arguments: 3160 + ts - time stepping context 3161 . order - desired order of accuracy 3162 - done - whether the step was evaluated at this order (pass NULL to generate an error if not available) 3163 3164 Output Arguments: 3165 . U - state at the end of the current step 3166 3167 Level: advanced 3168 3169 Notes: 3170 This function cannot be called until all stages have been evaluated. 3171 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. 3172 3173 .seealso: TSStep(), TSAdapt 3174 @*/ 3175 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done) 3176 { 3177 PetscErrorCode ierr; 3178 3179 PetscFunctionBegin; 3180 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3181 PetscValidType(ts,1); 3182 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 3183 if (!ts->ops->evaluatestep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name); 3184 ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr); 3185 PetscFunctionReturn(0); 3186 } 3187 3188 3189 #undef __FUNCT__ 3190 #define __FUNCT__ "TSSolve" 3191 /*@ 3192 TSSolve - Steps the requested number of timesteps. 3193 3194 Collective on TS 3195 3196 Input Parameter: 3197 + ts - the TS context obtained from TSCreate() 3198 - u - the solution vector (can be null if TSSetSolution() was used, otherwise must contain the initial conditions) 3199 3200 Level: beginner 3201 3202 Notes: 3203 The final time returned by this function may be different from the time of the internally 3204 held state accessible by TSGetSolution() and TSGetTime() because the method may have 3205 stepped over the final time. 3206 3207 .keywords: TS, timestep, solve 3208 3209 .seealso: TSCreate(), TSSetSolution(), TSStep() 3210 @*/ 3211 PetscErrorCode TSSolve(TS ts,Vec u) 3212 { 3213 Vec solution; 3214 PetscErrorCode ierr; 3215 3216 PetscFunctionBegin; 3217 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3218 if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2); 3219 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 */ 3220 PetscValidHeaderSpecific(u,VEC_CLASSID,2); 3221 if (!ts->vec_sol || u == ts->vec_sol) { 3222 ierr = VecDuplicate(u,&solution);CHKERRQ(ierr); 3223 ierr = TSSetSolution(ts,solution);CHKERRQ(ierr); 3224 ierr = VecDestroy(&solution);CHKERRQ(ierr); /* grant ownership */ 3225 } 3226 ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr); 3227 } else if (u) { 3228 ierr = TSSetSolution(ts,u);CHKERRQ(ierr); 3229 } 3230 ierr = TSSetUp(ts);CHKERRQ(ierr); /*compute adj coefficients if the reverse mode is on*/ 3231 /* reset time step and iteration counters */ 3232 ts->steps = 0; 3233 ts->ksp_its = 0; 3234 ts->snes_its = 0; 3235 ts->num_snes_failures = 0; 3236 ts->reject = 0; 3237 ts->reason = TS_CONVERGED_ITERATING; 3238 3239 ierr = TSViewFromOptions(ts,NULL,"-ts_view_pre");CHKERRQ(ierr); 3240 { 3241 DM dm; 3242 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 3243 ierr = DMSetOutputSequenceNumber(dm, ts->steps, ts->ptime);CHKERRQ(ierr); 3244 } 3245 3246 if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */ 3247 ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr); 3248 ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr); 3249 ts->solvetime = ts->ptime; 3250 } else { 3251 /* steps the requested number of timesteps. */ 3252 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 3253 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 3254 while (!ts->reason) { 3255 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3256 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3257 ierr = TSStep(ts);CHKERRQ(ierr); 3258 if (ts->event) { 3259 ierr = TSEventMonitor(ts);CHKERRQ(ierr); 3260 if (ts->event->status != TSEVENT_PROCESSING) { 3261 ierr = TSPostStep(ts);CHKERRQ(ierr); 3262 } 3263 } else { 3264 ierr = TSPostStep(ts);CHKERRQ(ierr); 3265 } 3266 } 3267 if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) { 3268 ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr); 3269 ts->solvetime = ts->max_time; 3270 solution = u; 3271 } else { 3272 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 3273 ts->solvetime = ts->ptime; 3274 solution = ts->vec_sol; 3275 } 3276 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->solvetime,solution);CHKERRQ(ierr); 3277 ierr = TSMonitor(ts,ts->steps,ts->solvetime,solution);CHKERRQ(ierr); 3278 ierr = VecViewFromOptions(solution, ((PetscObject) ts)->prefix, "-ts_view_solution");CHKERRQ(ierr); 3279 } 3280 3281 ierr = TSViewFromOptions(ts,NULL,"-ts_view");CHKERRQ(ierr); 3282 ierr = PetscObjectSAWsBlock((PetscObject)ts);CHKERRQ(ierr); 3283 PetscFunctionReturn(0); 3284 } 3285 3286 #undef __FUNCT__ 3287 #define __FUNCT__ "TSAdjointSolve" 3288 /*@ 3289 TSAdjointSolve - Solves the discrete ajoint problem for an ODE/DAE 3290 3291 Collective on TS 3292 3293 Input Parameter: 3294 . ts - the TS context obtained from TSCreate() 3295 3296 Level: intermediate 3297 3298 Notes: 3299 This must be called after a call to TSSolve() that solves the forward problem 3300 3301 By default this will integrate back to the initial time, one can use TSAdjointSetSteps() to step back to a later time 3302 3303 .keywords: TS, timestep, solve 3304 3305 .seealso: TSCreate(), TSSetSolution(), TSStep() 3306 @*/ 3307 PetscErrorCode TSAdjointSolve(TS ts) 3308 { 3309 PetscErrorCode ierr; 3310 3311 PetscFunctionBegin; 3312 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3313 ierr = TSAdjointSetUp(ts);CHKERRQ(ierr); 3314 /* reset time step and iteration counters */ 3315 ts->steps = 0; 3316 ts->ksp_its = 0; 3317 ts->snes_its = 0; 3318 ts->num_snes_failures = 0; 3319 ts->reject = 0; 3320 ts->reason = TS_CONVERGED_ITERATING; 3321 3322 if (!ts->adjoint_max_steps) ts->adjoint_max_steps = ts->total_steps; 3323 3324 if (ts->steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS; 3325 while (!ts->reason) { 3326 ierr = TSTrajectoryGet(ts->trajectory,ts,ts->adjoint_max_steps-ts->steps,ts->ptime);CHKERRQ(ierr); 3327 ierr = TSMonitor(ts,ts->adjoint_max_steps-ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 3328 ierr = TSAdjointStep(ts);CHKERRQ(ierr); 3329 if (ts->event) { 3330 ierr = TSEventMonitor(ts);CHKERRQ(ierr); 3331 if (ts->event->status != TSEVENT_PROCESSING) { 3332 ierr = TSPostStep(ts);CHKERRQ(ierr); 3333 } 3334 } else { 3335 ierr = TSPostStep(ts);CHKERRQ(ierr); 3336 } 3337 } 3338 ts->solvetime = ts->ptime; 3339 PetscFunctionReturn(0); 3340 } 3341 3342 #undef __FUNCT__ 3343 #define __FUNCT__ "TSMonitor" 3344 /*@ 3345 TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet() 3346 3347 Collective on TS 3348 3349 Input Parameters: 3350 + ts - time stepping context obtained from TSCreate() 3351 . step - step number that has just completed 3352 . ptime - model time of the state 3353 - u - state at the current model time 3354 3355 Notes: 3356 TSMonitor() is typically used within the time stepping implementations. 3357 Users might call this function when using the TSStep() interface instead of TSSolve(). 3358 3359 Level: advanced 3360 3361 .keywords: TS, timestep 3362 @*/ 3363 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u) 3364 { 3365 PetscErrorCode ierr; 3366 PetscInt i,n = ts->numbermonitors; 3367 3368 PetscFunctionBegin; 3369 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3370 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 3371 ierr = VecLockPush(u);CHKERRQ(ierr); 3372 for (i=0; i<n; i++) { 3373 ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr); 3374 } 3375 ierr = VecLockPop(u);CHKERRQ(ierr); 3376 PetscFunctionReturn(0); 3377 } 3378 3379 /* ------------------------------------------------------------------------*/ 3380 #undef __FUNCT__ 3381 #define __FUNCT__ "TSMonitorLGCtxCreate" 3382 /*@C 3383 TSMonitorLGCtxCreate - Creates a line graph context for use with 3384 TS to monitor the solution process graphically in various ways 3385 3386 Collective on TS 3387 3388 Input Parameters: 3389 + host - the X display to open, or null for the local machine 3390 . label - the title to put in the title bar 3391 . x, y - the screen coordinates of the upper left coordinate of the window 3392 . m, n - the screen width and height in pixels 3393 - howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time 3394 3395 Output Parameter: 3396 . ctx - the context 3397 3398 Options Database Key: 3399 + -ts_monitor_lg_timestep - automatically sets line graph monitor 3400 . -ts_monitor_lg_solution - 3401 . -ts_monitor_lg_error - 3402 . -ts_monitor_lg_ksp_iterations - 3403 . -ts_monitor_lg_snes_iterations - 3404 - -lg_indicate_data_points <true,false> - indicate the data points (at each time step) on the plot; default is true 3405 3406 Notes: 3407 Use TSMonitorLGCtxDestroy() to destroy. 3408 3409 Level: intermediate 3410 3411 .keywords: TS, monitor, line graph, residual, seealso 3412 3413 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError() 3414 3415 @*/ 3416 PetscErrorCode TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx) 3417 { 3418 PetscDraw win; 3419 PetscErrorCode ierr; 3420 3421 PetscFunctionBegin; 3422 ierr = PetscNew(ctx);CHKERRQ(ierr); 3423 ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&win);CHKERRQ(ierr); 3424 ierr = PetscDrawSetFromOptions(win);CHKERRQ(ierr); 3425 ierr = PetscDrawLGCreate(win,1,&(*ctx)->lg);CHKERRQ(ierr); 3426 ierr = PetscLogObjectParent((PetscObject)(*ctx)->lg,(PetscObject)win);CHKERRQ(ierr); 3427 ierr = PetscDrawLGIndicateDataPoints((*ctx)->lg,PETSC_TRUE);CHKERRQ(ierr); 3428 ierr = PetscDrawLGSetFromOptions((*ctx)->lg);CHKERRQ(ierr); 3429 (*ctx)->howoften = howoften; 3430 PetscFunctionReturn(0); 3431 } 3432 3433 #undef __FUNCT__ 3434 #define __FUNCT__ "TSMonitorLGTimeStep" 3435 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx) 3436 { 3437 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 3438 PetscReal x = ptime,y; 3439 PetscErrorCode ierr; 3440 3441 PetscFunctionBegin; 3442 if (!step) { 3443 PetscDrawAxis axis; 3444 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 3445 ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time","Time step");CHKERRQ(ierr); 3446 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 3447 ierr = PetscDrawLGIndicateDataPoints(ctx->lg,PETSC_TRUE);CHKERRQ(ierr); 3448 } 3449 ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr); 3450 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 3451 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 3452 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 3453 } 3454 PetscFunctionReturn(0); 3455 } 3456 3457 #undef __FUNCT__ 3458 #define __FUNCT__ "TSMonitorLGCtxDestroy" 3459 /*@C 3460 TSMonitorLGCtxDestroy - Destroys a line graph context that was created 3461 with TSMonitorLGCtxCreate(). 3462 3463 Collective on TSMonitorLGCtx 3464 3465 Input Parameter: 3466 . ctx - the monitor context 3467 3468 Level: intermediate 3469 3470 .keywords: TS, monitor, line graph, destroy 3471 3472 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep(); 3473 @*/ 3474 PetscErrorCode TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx) 3475 { 3476 PetscDraw draw; 3477 PetscErrorCode ierr; 3478 3479 PetscFunctionBegin; 3480 ierr = PetscDrawLGGetDraw((*ctx)->lg,&draw);CHKERRQ(ierr); 3481 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 3482 ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr); 3483 ierr = PetscFree(*ctx);CHKERRQ(ierr); 3484 PetscFunctionReturn(0); 3485 } 3486 3487 #undef __FUNCT__ 3488 #define __FUNCT__ "TSGetTime" 3489 /*@ 3490 TSGetTime - Gets the time of the most recently completed step. 3491 3492 Not Collective 3493 3494 Input Parameter: 3495 . ts - the TS context obtained from TSCreate() 3496 3497 Output Parameter: 3498 . t - the current time 3499 3500 Level: beginner 3501 3502 Note: 3503 When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(), 3504 TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated. 3505 3506 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 3507 3508 .keywords: TS, get, time 3509 @*/ 3510 PetscErrorCode TSGetTime(TS ts,PetscReal *t) 3511 { 3512 PetscFunctionBegin; 3513 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3514 PetscValidRealPointer(t,2); 3515 *t = ts->ptime; 3516 PetscFunctionReturn(0); 3517 } 3518 3519 #undef __FUNCT__ 3520 #define __FUNCT__ "TSGetPrevTime" 3521 /*@ 3522 TSGetPrevTime - Gets the starting time of the previously completed step. 3523 3524 Not Collective 3525 3526 Input Parameter: 3527 . ts - the TS context obtained from TSCreate() 3528 3529 Output Parameter: 3530 . t - the previous time 3531 3532 Level: beginner 3533 3534 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 3535 3536 .keywords: TS, get, time 3537 @*/ 3538 PetscErrorCode TSGetPrevTime(TS ts,PetscReal *t) 3539 { 3540 PetscFunctionBegin; 3541 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3542 PetscValidRealPointer(t,2); 3543 *t = ts->ptime_prev; 3544 PetscFunctionReturn(0); 3545 } 3546 3547 #undef __FUNCT__ 3548 #define __FUNCT__ "TSSetTime" 3549 /*@ 3550 TSSetTime - Allows one to reset the time. 3551 3552 Logically Collective on TS 3553 3554 Input Parameters: 3555 + ts - the TS context obtained from TSCreate() 3556 - time - the time 3557 3558 Level: intermediate 3559 3560 .seealso: TSGetTime(), TSSetDuration() 3561 3562 .keywords: TS, set, time 3563 @*/ 3564 PetscErrorCode TSSetTime(TS ts, PetscReal t) 3565 { 3566 PetscFunctionBegin; 3567 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3568 PetscValidLogicalCollectiveReal(ts,t,2); 3569 ts->ptime = t; 3570 PetscFunctionReturn(0); 3571 } 3572 3573 #undef __FUNCT__ 3574 #define __FUNCT__ "TSSetOptionsPrefix" 3575 /*@C 3576 TSSetOptionsPrefix - Sets the prefix used for searching for all 3577 TS options in the database. 3578 3579 Logically Collective on TS 3580 3581 Input Parameter: 3582 + ts - The TS context 3583 - prefix - The prefix to prepend to all option names 3584 3585 Notes: 3586 A hyphen (-) must NOT be given at the beginning of the prefix name. 3587 The first character of all runtime options is AUTOMATICALLY the 3588 hyphen. 3589 3590 Level: advanced 3591 3592 .keywords: TS, set, options, prefix, database 3593 3594 .seealso: TSSetFromOptions() 3595 3596 @*/ 3597 PetscErrorCode TSSetOptionsPrefix(TS ts,const char prefix[]) 3598 { 3599 PetscErrorCode ierr; 3600 SNES snes; 3601 3602 PetscFunctionBegin; 3603 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3604 ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 3605 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 3606 ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr); 3607 PetscFunctionReturn(0); 3608 } 3609 3610 3611 #undef __FUNCT__ 3612 #define __FUNCT__ "TSAppendOptionsPrefix" 3613 /*@C 3614 TSAppendOptionsPrefix - Appends to the prefix used for searching for all 3615 TS options in the database. 3616 3617 Logically Collective on TS 3618 3619 Input Parameter: 3620 + ts - The TS context 3621 - prefix - The prefix to prepend to all option names 3622 3623 Notes: 3624 A hyphen (-) must NOT be given at the beginning of the prefix name. 3625 The first character of all runtime options is AUTOMATICALLY the 3626 hyphen. 3627 3628 Level: advanced 3629 3630 .keywords: TS, append, options, prefix, database 3631 3632 .seealso: TSGetOptionsPrefix() 3633 3634 @*/ 3635 PetscErrorCode TSAppendOptionsPrefix(TS ts,const char prefix[]) 3636 { 3637 PetscErrorCode ierr; 3638 SNES snes; 3639 3640 PetscFunctionBegin; 3641 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3642 ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 3643 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 3644 ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr); 3645 PetscFunctionReturn(0); 3646 } 3647 3648 #undef __FUNCT__ 3649 #define __FUNCT__ "TSGetOptionsPrefix" 3650 /*@C 3651 TSGetOptionsPrefix - Sets the prefix used for searching for all 3652 TS options in the database. 3653 3654 Not Collective 3655 3656 Input Parameter: 3657 . ts - The TS context 3658 3659 Output Parameter: 3660 . prefix - A pointer to the prefix string used 3661 3662 Notes: On the fortran side, the user should pass in a string 'prifix' of 3663 sufficient length to hold the prefix. 3664 3665 Level: intermediate 3666 3667 .keywords: TS, get, options, prefix, database 3668 3669 .seealso: TSAppendOptionsPrefix() 3670 @*/ 3671 PetscErrorCode TSGetOptionsPrefix(TS ts,const char *prefix[]) 3672 { 3673 PetscErrorCode ierr; 3674 3675 PetscFunctionBegin; 3676 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3677 PetscValidPointer(prefix,2); 3678 ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 3679 PetscFunctionReturn(0); 3680 } 3681 3682 #undef __FUNCT__ 3683 #define __FUNCT__ "TSGetRHSJacobian" 3684 /*@C 3685 TSGetRHSJacobian - Returns the Jacobian J at the present timestep. 3686 3687 Not Collective, but parallel objects are returned if TS is parallel 3688 3689 Input Parameter: 3690 . ts - The TS context obtained from TSCreate() 3691 3692 Output Parameters: 3693 + Amat - The (approximate) Jacobian J of G, where U_t = G(U,t) (or NULL) 3694 . Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat (or NULL) 3695 . func - Function to compute the Jacobian of the RHS (or NULL) 3696 - ctx - User-defined context for Jacobian evaluation routine (or NULL) 3697 3698 Notes: You can pass in NULL for any return argument you do not need. 3699 3700 Level: intermediate 3701 3702 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 3703 3704 .keywords: TS, timestep, get, matrix, Jacobian 3705 @*/ 3706 PetscErrorCode TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx) 3707 { 3708 PetscErrorCode ierr; 3709 SNES snes; 3710 DM dm; 3711 3712 PetscFunctionBegin; 3713 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 3714 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 3715 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 3716 ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr); 3717 PetscFunctionReturn(0); 3718 } 3719 3720 #undef __FUNCT__ 3721 #define __FUNCT__ "TSGetIJacobian" 3722 /*@C 3723 TSGetIJacobian - Returns the implicit Jacobian at the present timestep. 3724 3725 Not Collective, but parallel objects are returned if TS is parallel 3726 3727 Input Parameter: 3728 . ts - The TS context obtained from TSCreate() 3729 3730 Output Parameters: 3731 + Amat - The (approximate) Jacobian of F(t,U,U_t) 3732 . Pmat - The matrix from which the preconditioner is constructed, often the same as Amat 3733 . f - The function to compute the matrices 3734 - ctx - User-defined context for Jacobian evaluation routine 3735 3736 Notes: You can pass in NULL for any return argument you do not need. 3737 3738 Level: advanced 3739 3740 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 3741 3742 .keywords: TS, timestep, get, matrix, Jacobian 3743 @*/ 3744 PetscErrorCode TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx) 3745 { 3746 PetscErrorCode ierr; 3747 SNES snes; 3748 DM dm; 3749 3750 PetscFunctionBegin; 3751 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 3752 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 3753 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 3754 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 3755 ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr); 3756 PetscFunctionReturn(0); 3757 } 3758 3759 3760 #undef __FUNCT__ 3761 #define __FUNCT__ "TSMonitorDrawSolution" 3762 /*@C 3763 TSMonitorDrawSolution - Monitors progress of the TS solvers by calling 3764 VecView() for the solution at each timestep 3765 3766 Collective on TS 3767 3768 Input Parameters: 3769 + ts - the TS context 3770 . step - current time-step 3771 . ptime - current time 3772 - dummy - either a viewer or NULL 3773 3774 Options Database: 3775 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 3776 3777 Notes: the initial solution and current solution are not displayed with a common axis scaling so generally the option -ts_monitor_draw_solution_initial 3778 will look bad 3779 3780 Level: intermediate 3781 3782 .keywords: TS, vector, monitor, view 3783 3784 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 3785 @*/ 3786 PetscErrorCode TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 3787 { 3788 PetscErrorCode ierr; 3789 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 3790 PetscDraw draw; 3791 3792 PetscFunctionBegin; 3793 if (!step && ictx->showinitial) { 3794 if (!ictx->initialsolution) { 3795 ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr); 3796 } 3797 ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr); 3798 } 3799 if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 3800 3801 if (ictx->showinitial) { 3802 PetscReal pause; 3803 ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr); 3804 ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr); 3805 ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr); 3806 ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr); 3807 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr); 3808 } 3809 ierr = VecView(u,ictx->viewer);CHKERRQ(ierr); 3810 if (ictx->showtimestepandtime) { 3811 PetscReal xl,yl,xr,yr,tw,w,h; 3812 char time[32]; 3813 size_t len; 3814 3815 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 3816 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 3817 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 3818 ierr = PetscStrlen(time,&len);CHKERRQ(ierr); 3819 ierr = PetscDrawStringGetSize(draw,&tw,NULL);CHKERRQ(ierr); 3820 w = xl + .5*(xr - xl) - .5*len*tw; 3821 h = yl + .95*(yr - yl); 3822 ierr = PetscDrawString(draw,w,h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 3823 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 3824 } 3825 3826 if (ictx->showinitial) { 3827 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr); 3828 } 3829 PetscFunctionReturn(0); 3830 } 3831 3832 #undef __FUNCT__ 3833 #define __FUNCT__ "TSMonitorDrawSolutionPhase" 3834 /*@C 3835 TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram 3836 3837 Collective on TS 3838 3839 Input Parameters: 3840 + ts - the TS context 3841 . step - current time-step 3842 . ptime - current time 3843 - dummy - either a viewer or NULL 3844 3845 Level: intermediate 3846 3847 .keywords: TS, vector, monitor, view 3848 3849 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 3850 @*/ 3851 PetscErrorCode TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 3852 { 3853 PetscErrorCode ierr; 3854 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 3855 PetscDraw draw; 3856 MPI_Comm comm; 3857 PetscInt n; 3858 PetscMPIInt size; 3859 PetscReal xl,yl,xr,yr,tw,w,h; 3860 char time[32]; 3861 size_t len; 3862 const PetscScalar *U; 3863 3864 PetscFunctionBegin; 3865 ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr); 3866 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 3867 if (size != 1) SETERRQ(comm,PETSC_ERR_SUP,"Only allowed for sequential runs"); 3868 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 3869 if (n != 2) SETERRQ(comm,PETSC_ERR_SUP,"Only for ODEs with two unknowns"); 3870 3871 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 3872 3873 ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr); 3874 ierr = PetscDrawAxisGetLimits(ictx->axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr); 3875 if ((PetscRealPart(U[0]) < xl) || (PetscRealPart(U[1]) < yl) || (PetscRealPart(U[0]) > xr) || (PetscRealPart(U[1]) > yr)) { 3876 ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr); 3877 PetscFunctionReturn(0); 3878 } 3879 if (!step) ictx->color++; 3880 ierr = PetscDrawPoint(draw,PetscRealPart(U[0]),PetscRealPart(U[1]),ictx->color);CHKERRQ(ierr); 3881 ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr); 3882 3883 if (ictx->showtimestepandtime) { 3884 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 3885 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 3886 ierr = PetscStrlen(time,&len);CHKERRQ(ierr); 3887 ierr = PetscDrawStringGetSize(draw,&tw,NULL);CHKERRQ(ierr); 3888 w = xl + .5*(xr - xl) - .5*len*tw; 3889 h = yl + .95*(yr - yl); 3890 ierr = PetscDrawString(draw,w,h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 3891 } 3892 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 3893 PetscFunctionReturn(0); 3894 } 3895 3896 3897 #undef __FUNCT__ 3898 #define __FUNCT__ "TSMonitorDrawCtxDestroy" 3899 /*@C 3900 TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution() 3901 3902 Collective on TS 3903 3904 Input Parameters: 3905 . ctx - the monitor context 3906 3907 Level: intermediate 3908 3909 .keywords: TS, vector, monitor, view 3910 3911 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError() 3912 @*/ 3913 PetscErrorCode TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx) 3914 { 3915 PetscErrorCode ierr; 3916 3917 PetscFunctionBegin; 3918 ierr = PetscDrawAxisDestroy(&(*ictx)->axis);CHKERRQ(ierr); 3919 ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr); 3920 ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr); 3921 ierr = PetscFree(*ictx);CHKERRQ(ierr); 3922 PetscFunctionReturn(0); 3923 } 3924 3925 #undef __FUNCT__ 3926 #define __FUNCT__ "TSMonitorDrawCtxCreate" 3927 /*@C 3928 TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx 3929 3930 Collective on TS 3931 3932 Input Parameter: 3933 . ts - time-step context 3934 3935 Output Patameter: 3936 . ctx - the monitor context 3937 3938 Options Database: 3939 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 3940 3941 Level: intermediate 3942 3943 .keywords: TS, vector, monitor, view 3944 3945 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx() 3946 @*/ 3947 PetscErrorCode TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx) 3948 { 3949 PetscErrorCode ierr; 3950 3951 PetscFunctionBegin; 3952 ierr = PetscNew(ctx);CHKERRQ(ierr); 3953 ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr); 3954 ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr); 3955 3956 (*ctx)->howoften = howoften; 3957 (*ctx)->showinitial = PETSC_FALSE; 3958 ierr = PetscOptionsGetBool(NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr); 3959 3960 (*ctx)->showtimestepandtime = PETSC_FALSE; 3961 ierr = PetscOptionsGetBool(NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr); 3962 (*ctx)->color = PETSC_DRAW_WHITE; 3963 PetscFunctionReturn(0); 3964 } 3965 3966 #undef __FUNCT__ 3967 #define __FUNCT__ "TSMonitorDrawError" 3968 /*@C 3969 TSMonitorDrawError - Monitors progress of the TS solvers by calling 3970 VecView() for the error at each timestep 3971 3972 Collective on TS 3973 3974 Input Parameters: 3975 + ts - the TS context 3976 . step - current time-step 3977 . ptime - current time 3978 - dummy - either a viewer or NULL 3979 3980 Level: intermediate 3981 3982 .keywords: TS, vector, monitor, view 3983 3984 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 3985 @*/ 3986 PetscErrorCode TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 3987 { 3988 PetscErrorCode ierr; 3989 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 3990 PetscViewer viewer = ctx->viewer; 3991 Vec work; 3992 3993 PetscFunctionBegin; 3994 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 3995 ierr = VecDuplicate(u,&work);CHKERRQ(ierr); 3996 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 3997 ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr); 3998 ierr = VecView(work,viewer);CHKERRQ(ierr); 3999 ierr = VecDestroy(&work);CHKERRQ(ierr); 4000 PetscFunctionReturn(0); 4001 } 4002 4003 #include <petsc-private/dmimpl.h> 4004 #undef __FUNCT__ 4005 #define __FUNCT__ "TSSetDM" 4006 /*@ 4007 TSSetDM - Sets the DM that may be used by some preconditioners 4008 4009 Logically Collective on TS and DM 4010 4011 Input Parameters: 4012 + ts - the preconditioner context 4013 - dm - the dm 4014 4015 Level: intermediate 4016 4017 4018 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM() 4019 @*/ 4020 PetscErrorCode TSSetDM(TS ts,DM dm) 4021 { 4022 PetscErrorCode ierr; 4023 SNES snes; 4024 DMTS tsdm; 4025 4026 PetscFunctionBegin; 4027 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4028 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 4029 if (ts->dm) { /* Move the DMTS context over to the new DM unless the new DM already has one */ 4030 if (ts->dm->dmts && !dm->dmts) { 4031 ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr); 4032 ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr); 4033 if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */ 4034 tsdm->originaldm = dm; 4035 } 4036 } 4037 ierr = DMDestroy(&ts->dm);CHKERRQ(ierr); 4038 } 4039 ts->dm = dm; 4040 4041 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4042 ierr = SNESSetDM(snes,dm);CHKERRQ(ierr); 4043 PetscFunctionReturn(0); 4044 } 4045 4046 #undef __FUNCT__ 4047 #define __FUNCT__ "TSGetDM" 4048 /*@ 4049 TSGetDM - Gets the DM that may be used by some preconditioners 4050 4051 Not Collective 4052 4053 Input Parameter: 4054 . ts - the preconditioner context 4055 4056 Output Parameter: 4057 . dm - the dm 4058 4059 Level: intermediate 4060 4061 4062 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM() 4063 @*/ 4064 PetscErrorCode TSGetDM(TS ts,DM *dm) 4065 { 4066 PetscErrorCode ierr; 4067 4068 PetscFunctionBegin; 4069 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4070 if (!ts->dm) { 4071 ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr); 4072 if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 4073 } 4074 *dm = ts->dm; 4075 PetscFunctionReturn(0); 4076 } 4077 4078 #undef __FUNCT__ 4079 #define __FUNCT__ "SNESTSFormFunction" 4080 /*@ 4081 SNESTSFormFunction - Function to evaluate nonlinear residual 4082 4083 Logically Collective on SNES 4084 4085 Input Parameter: 4086 + snes - nonlinear solver 4087 . U - the current state at which to evaluate the residual 4088 - ctx - user context, must be a TS 4089 4090 Output Parameter: 4091 . F - the nonlinear residual 4092 4093 Notes: 4094 This function is not normally called by users and is automatically registered with the SNES used by TS. 4095 It is most frequently passed to MatFDColoringSetFunction(). 4096 4097 Level: advanced 4098 4099 .seealso: SNESSetFunction(), MatFDColoringSetFunction() 4100 @*/ 4101 PetscErrorCode SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx) 4102 { 4103 TS ts = (TS)ctx; 4104 PetscErrorCode ierr; 4105 4106 PetscFunctionBegin; 4107 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4108 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 4109 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 4110 PetscValidHeaderSpecific(ts,TS_CLASSID,4); 4111 ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr); 4112 PetscFunctionReturn(0); 4113 } 4114 4115 #undef __FUNCT__ 4116 #define __FUNCT__ "SNESTSFormJacobian" 4117 /*@ 4118 SNESTSFormJacobian - Function to evaluate the Jacobian 4119 4120 Collective on SNES 4121 4122 Input Parameter: 4123 + snes - nonlinear solver 4124 . U - the current state at which to evaluate the residual 4125 - ctx - user context, must be a TS 4126 4127 Output Parameter: 4128 + A - the Jacobian 4129 . B - the preconditioning matrix (may be the same as A) 4130 - flag - indicates any structure change in the matrix 4131 4132 Notes: 4133 This function is not normally called by users and is automatically registered with the SNES used by TS. 4134 4135 Level: developer 4136 4137 .seealso: SNESSetJacobian() 4138 @*/ 4139 PetscErrorCode SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx) 4140 { 4141 TS ts = (TS)ctx; 4142 PetscErrorCode ierr; 4143 4144 PetscFunctionBegin; 4145 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4146 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 4147 PetscValidPointer(A,3); 4148 PetscValidHeaderSpecific(A,MAT_CLASSID,3); 4149 PetscValidPointer(B,4); 4150 PetscValidHeaderSpecific(B,MAT_CLASSID,4); 4151 PetscValidHeaderSpecific(ts,TS_CLASSID,6); 4152 ierr = (ts->ops->snesjacobian)(snes,U,A,B,ts);CHKERRQ(ierr); 4153 PetscFunctionReturn(0); 4154 } 4155 4156 #undef __FUNCT__ 4157 #define __FUNCT__ "TSComputeRHSFunctionLinear" 4158 /*@C 4159 TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems only 4160 4161 Collective on TS 4162 4163 Input Arguments: 4164 + ts - time stepping context 4165 . t - time at which to evaluate 4166 . U - state at which to evaluate 4167 - ctx - context 4168 4169 Output Arguments: 4170 . F - right hand side 4171 4172 Level: intermediate 4173 4174 Notes: 4175 This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems. 4176 The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian(). 4177 4178 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 4179 @*/ 4180 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx) 4181 { 4182 PetscErrorCode ierr; 4183 Mat Arhs,Brhs; 4184 4185 PetscFunctionBegin; 4186 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 4187 ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr); 4188 ierr = MatMult(Arhs,U,F);CHKERRQ(ierr); 4189 PetscFunctionReturn(0); 4190 } 4191 4192 #undef __FUNCT__ 4193 #define __FUNCT__ "TSComputeRHSJacobianConstant" 4194 /*@C 4195 TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent. 4196 4197 Collective on TS 4198 4199 Input Arguments: 4200 + ts - time stepping context 4201 . t - time at which to evaluate 4202 . U - state at which to evaluate 4203 - ctx - context 4204 4205 Output Arguments: 4206 + A - pointer to operator 4207 . B - pointer to preconditioning matrix 4208 - flg - matrix structure flag 4209 4210 Level: intermediate 4211 4212 Notes: 4213 This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems. 4214 4215 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear() 4216 @*/ 4217 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx) 4218 { 4219 PetscFunctionBegin; 4220 PetscFunctionReturn(0); 4221 } 4222 4223 #undef __FUNCT__ 4224 #define __FUNCT__ "TSComputeIFunctionLinear" 4225 /*@C 4226 TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only 4227 4228 Collective on TS 4229 4230 Input Arguments: 4231 + ts - time stepping context 4232 . t - time at which to evaluate 4233 . U - state at which to evaluate 4234 . Udot - time derivative of state vector 4235 - ctx - context 4236 4237 Output Arguments: 4238 . F - left hand side 4239 4240 Level: intermediate 4241 4242 Notes: 4243 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 4244 user is required to write their own TSComputeIFunction. 4245 This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems. 4246 The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian(). 4247 4248 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant() 4249 @*/ 4250 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx) 4251 { 4252 PetscErrorCode ierr; 4253 Mat A,B; 4254 4255 PetscFunctionBegin; 4256 ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr); 4257 ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE);CHKERRQ(ierr); 4258 ierr = MatMult(A,Udot,F);CHKERRQ(ierr); 4259 PetscFunctionReturn(0); 4260 } 4261 4262 #undef __FUNCT__ 4263 #define __FUNCT__ "TSComputeIJacobianConstant" 4264 /*@C 4265 TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE 4266 4267 Collective on TS 4268 4269 Input Arguments: 4270 + ts - time stepping context 4271 . t - time at which to evaluate 4272 . U - state at which to evaluate 4273 . Udot - time derivative of state vector 4274 . shift - shift to apply 4275 - ctx - context 4276 4277 Output Arguments: 4278 + A - pointer to operator 4279 . B - pointer to preconditioning matrix 4280 - flg - matrix structure flag 4281 4282 Level: advanced 4283 4284 Notes: 4285 This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems. 4286 4287 It is only appropriate for problems of the form 4288 4289 $ M Udot = F(U,t) 4290 4291 where M is constant and F is non-stiff. The user must pass M to TSSetIJacobian(). The current implementation only 4292 works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing 4293 an implicit operator of the form 4294 4295 $ shift*M + J 4296 4297 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 4298 a copy of M or reassemble it when requested. 4299 4300 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear() 4301 @*/ 4302 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx) 4303 { 4304 PetscErrorCode ierr; 4305 4306 PetscFunctionBegin; 4307 ierr = MatScale(A, shift / ts->ijacobian.shift);CHKERRQ(ierr); 4308 ts->ijacobian.shift = shift; 4309 PetscFunctionReturn(0); 4310 } 4311 4312 #undef __FUNCT__ 4313 #define __FUNCT__ "TSGetEquationType" 4314 /*@ 4315 TSGetEquationType - Gets the type of the equation that TS is solving. 4316 4317 Not Collective 4318 4319 Input Parameter: 4320 . ts - the TS context 4321 4322 Output Parameter: 4323 . equation_type - see TSEquationType 4324 4325 Level: beginner 4326 4327 .keywords: TS, equation type 4328 4329 .seealso: TSSetEquationType(), TSEquationType 4330 @*/ 4331 PetscErrorCode TSGetEquationType(TS ts,TSEquationType *equation_type) 4332 { 4333 PetscFunctionBegin; 4334 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4335 PetscValidPointer(equation_type,2); 4336 *equation_type = ts->equation_type; 4337 PetscFunctionReturn(0); 4338 } 4339 4340 #undef __FUNCT__ 4341 #define __FUNCT__ "TSSetEquationType" 4342 /*@ 4343 TSSetEquationType - Sets the type of the equation that TS is solving. 4344 4345 Not Collective 4346 4347 Input Parameter: 4348 + ts - the TS context 4349 . equation_type - see TSEquationType 4350 4351 Level: advanced 4352 4353 .keywords: TS, equation type 4354 4355 .seealso: TSGetEquationType(), TSEquationType 4356 @*/ 4357 PetscErrorCode TSSetEquationType(TS ts,TSEquationType equation_type) 4358 { 4359 PetscFunctionBegin; 4360 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4361 ts->equation_type = equation_type; 4362 PetscFunctionReturn(0); 4363 } 4364 4365 #undef __FUNCT__ 4366 #define __FUNCT__ "TSGetConvergedReason" 4367 /*@ 4368 TSGetConvergedReason - Gets the reason the TS iteration was stopped. 4369 4370 Not Collective 4371 4372 Input Parameter: 4373 . ts - the TS context 4374 4375 Output Parameter: 4376 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 4377 manual pages for the individual convergence tests for complete lists 4378 4379 Level: beginner 4380 4381 Notes: 4382 Can only be called after the call to TSSolve() is complete. 4383 4384 .keywords: TS, nonlinear, set, convergence, test 4385 4386 .seealso: TSSetConvergenceTest(), TSConvergedReason 4387 @*/ 4388 PetscErrorCode TSGetConvergedReason(TS ts,TSConvergedReason *reason) 4389 { 4390 PetscFunctionBegin; 4391 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4392 PetscValidPointer(reason,2); 4393 *reason = ts->reason; 4394 PetscFunctionReturn(0); 4395 } 4396 4397 #undef __FUNCT__ 4398 #define __FUNCT__ "TSSetConvergedReason" 4399 /*@ 4400 TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve. 4401 4402 Not Collective 4403 4404 Input Parameter: 4405 + ts - the TS context 4406 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 4407 manual pages for the individual convergence tests for complete lists 4408 4409 Level: advanced 4410 4411 Notes: 4412 Can only be called during TSSolve() is active. 4413 4414 .keywords: TS, nonlinear, set, convergence, test 4415 4416 .seealso: TSConvergedReason 4417 @*/ 4418 PetscErrorCode TSSetConvergedReason(TS ts,TSConvergedReason reason) 4419 { 4420 PetscFunctionBegin; 4421 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4422 ts->reason = reason; 4423 PetscFunctionReturn(0); 4424 } 4425 4426 #undef __FUNCT__ 4427 #define __FUNCT__ "TSGetSolveTime" 4428 /*@ 4429 TSGetSolveTime - Gets the time after a call to TSSolve() 4430 4431 Not Collective 4432 4433 Input Parameter: 4434 . ts - the TS context 4435 4436 Output Parameter: 4437 . ftime - the final time. This time should correspond to the final time set with TSSetDuration() 4438 4439 Level: beginner 4440 4441 Notes: 4442 Can only be called after the call to TSSolve() is complete. 4443 4444 .keywords: TS, nonlinear, set, convergence, test 4445 4446 .seealso: TSSetConvergenceTest(), TSConvergedReason 4447 @*/ 4448 PetscErrorCode TSGetSolveTime(TS ts,PetscReal *ftime) 4449 { 4450 PetscFunctionBegin; 4451 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4452 PetscValidPointer(ftime,2); 4453 *ftime = ts->solvetime; 4454 PetscFunctionReturn(0); 4455 } 4456 4457 #undef __FUNCT__ 4458 #define __FUNCT__ "TSGetTotalSteps" 4459 /*@ 4460 TSGetTotalSteps - Gets the total number of steps done since the last call to TSSetUp() or TSCreate() 4461 4462 Not Collective 4463 4464 Input Parameter: 4465 . ts - the TS context 4466 4467 Output Parameter: 4468 . steps - the number of steps 4469 4470 Level: beginner 4471 4472 Notes: 4473 Includes the number of steps for all calls to TSSolve() since TSSetUp() was called 4474 4475 .keywords: TS, nonlinear, set, convergence, test 4476 4477 .seealso: TSSetConvergenceTest(), TSConvergedReason 4478 @*/ 4479 PetscErrorCode TSGetTotalSteps(TS ts,PetscInt *steps) 4480 { 4481 PetscFunctionBegin; 4482 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4483 PetscValidPointer(steps,2); 4484 *steps = ts->total_steps; 4485 PetscFunctionReturn(0); 4486 } 4487 4488 #undef __FUNCT__ 4489 #define __FUNCT__ "TSGetSNESIterations" 4490 /*@ 4491 TSGetSNESIterations - Gets the total number of nonlinear iterations 4492 used by the time integrator. 4493 4494 Not Collective 4495 4496 Input Parameter: 4497 . ts - TS context 4498 4499 Output Parameter: 4500 . nits - number of nonlinear iterations 4501 4502 Notes: 4503 This counter is reset to zero for each successive call to TSSolve(). 4504 4505 Level: intermediate 4506 4507 .keywords: TS, get, number, nonlinear, iterations 4508 4509 .seealso: TSGetKSPIterations() 4510 @*/ 4511 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits) 4512 { 4513 PetscFunctionBegin; 4514 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4515 PetscValidIntPointer(nits,2); 4516 *nits = ts->snes_its; 4517 PetscFunctionReturn(0); 4518 } 4519 4520 #undef __FUNCT__ 4521 #define __FUNCT__ "TSGetKSPIterations" 4522 /*@ 4523 TSGetKSPIterations - Gets the total number of linear iterations 4524 used by the time integrator. 4525 4526 Not Collective 4527 4528 Input Parameter: 4529 . ts - TS context 4530 4531 Output Parameter: 4532 . lits - number of linear iterations 4533 4534 Notes: 4535 This counter is reset to zero for each successive call to TSSolve(). 4536 4537 Level: intermediate 4538 4539 .keywords: TS, get, number, linear, iterations 4540 4541 .seealso: TSGetSNESIterations(), SNESGetKSPIterations() 4542 @*/ 4543 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits) 4544 { 4545 PetscFunctionBegin; 4546 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4547 PetscValidIntPointer(lits,2); 4548 *lits = ts->ksp_its; 4549 PetscFunctionReturn(0); 4550 } 4551 4552 #undef __FUNCT__ 4553 #define __FUNCT__ "TSGetStepRejections" 4554 /*@ 4555 TSGetStepRejections - Gets the total number of rejected steps. 4556 4557 Not Collective 4558 4559 Input Parameter: 4560 . ts - TS context 4561 4562 Output Parameter: 4563 . rejects - number of steps rejected 4564 4565 Notes: 4566 This counter is reset to zero for each successive call to TSSolve(). 4567 4568 Level: intermediate 4569 4570 .keywords: TS, get, number 4571 4572 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails() 4573 @*/ 4574 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects) 4575 { 4576 PetscFunctionBegin; 4577 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4578 PetscValidIntPointer(rejects,2); 4579 *rejects = ts->reject; 4580 PetscFunctionReturn(0); 4581 } 4582 4583 #undef __FUNCT__ 4584 #define __FUNCT__ "TSGetSNESFailures" 4585 /*@ 4586 TSGetSNESFailures - Gets the total number of failed SNES solves 4587 4588 Not Collective 4589 4590 Input Parameter: 4591 . ts - TS context 4592 4593 Output Parameter: 4594 . fails - number of failed nonlinear solves 4595 4596 Notes: 4597 This counter is reset to zero for each successive call to TSSolve(). 4598 4599 Level: intermediate 4600 4601 .keywords: TS, get, number 4602 4603 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures() 4604 @*/ 4605 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails) 4606 { 4607 PetscFunctionBegin; 4608 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4609 PetscValidIntPointer(fails,2); 4610 *fails = ts->num_snes_failures; 4611 PetscFunctionReturn(0); 4612 } 4613 4614 #undef __FUNCT__ 4615 #define __FUNCT__ "TSSetMaxStepRejections" 4616 /*@ 4617 TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails 4618 4619 Not Collective 4620 4621 Input Parameter: 4622 + ts - TS context 4623 - rejects - maximum number of rejected steps, pass -1 for unlimited 4624 4625 Notes: 4626 The counter is reset to zero for each step 4627 4628 Options Database Key: 4629 . -ts_max_reject - Maximum number of step rejections before a step fails 4630 4631 Level: intermediate 4632 4633 .keywords: TS, set, maximum, number 4634 4635 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 4636 @*/ 4637 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects) 4638 { 4639 PetscFunctionBegin; 4640 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4641 ts->max_reject = rejects; 4642 PetscFunctionReturn(0); 4643 } 4644 4645 #undef __FUNCT__ 4646 #define __FUNCT__ "TSSetMaxSNESFailures" 4647 /*@ 4648 TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves 4649 4650 Not Collective 4651 4652 Input Parameter: 4653 + ts - TS context 4654 - fails - maximum number of failed nonlinear solves, pass -1 for unlimited 4655 4656 Notes: 4657 The counter is reset to zero for each successive call to TSSolve(). 4658 4659 Options Database Key: 4660 . -ts_max_snes_failures - Maximum number of nonlinear solve failures 4661 4662 Level: intermediate 4663 4664 .keywords: TS, set, maximum, number 4665 4666 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason() 4667 @*/ 4668 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails) 4669 { 4670 PetscFunctionBegin; 4671 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4672 ts->max_snes_failures = fails; 4673 PetscFunctionReturn(0); 4674 } 4675 4676 #undef __FUNCT__ 4677 #define __FUNCT__ "TSSetErrorIfStepFails" 4678 /*@ 4679 TSSetErrorIfStepFails - Error if no step succeeds 4680 4681 Not Collective 4682 4683 Input Parameter: 4684 + ts - TS context 4685 - err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure 4686 4687 Options Database Key: 4688 . -ts_error_if_step_fails - Error if no step succeeds 4689 4690 Level: intermediate 4691 4692 .keywords: TS, set, error 4693 4694 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 4695 @*/ 4696 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err) 4697 { 4698 PetscFunctionBegin; 4699 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4700 ts->errorifstepfailed = err; 4701 PetscFunctionReturn(0); 4702 } 4703 4704 #undef __FUNCT__ 4705 #define __FUNCT__ "TSMonitorSolutionBinary" 4706 /*@C 4707 TSMonitorSolutionBinary - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file 4708 4709 Collective on TS 4710 4711 Input Parameters: 4712 + ts - the TS context 4713 . step - current time-step 4714 . ptime - current time 4715 . u - current state 4716 - viewer - binary viewer 4717 4718 Level: intermediate 4719 4720 .keywords: TS, vector, monitor, view 4721 4722 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4723 @*/ 4724 PetscErrorCode TSMonitorSolutionBinary(TS ts,PetscInt step,PetscReal ptime,Vec u,void *viewer) 4725 { 4726 PetscErrorCode ierr; 4727 PetscViewer v = (PetscViewer)viewer; 4728 4729 PetscFunctionBegin; 4730 ierr = VecView(u,v);CHKERRQ(ierr); 4731 PetscFunctionReturn(0); 4732 } 4733 4734 #undef __FUNCT__ 4735 #define __FUNCT__ "TSMonitorSolutionVTK" 4736 /*@C 4737 TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep. 4738 4739 Collective on TS 4740 4741 Input Parameters: 4742 + ts - the TS context 4743 . step - current time-step 4744 . ptime - current time 4745 . u - current state 4746 - filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 4747 4748 Level: intermediate 4749 4750 Notes: 4751 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. 4752 These are named according to the file name template. 4753 4754 This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy(). 4755 4756 .keywords: TS, vector, monitor, view 4757 4758 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4759 @*/ 4760 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate) 4761 { 4762 PetscErrorCode ierr; 4763 char filename[PETSC_MAX_PATH_LEN]; 4764 PetscViewer viewer; 4765 4766 PetscFunctionBegin; 4767 ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr); 4768 ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); 4769 ierr = VecView(u,viewer);CHKERRQ(ierr); 4770 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4771 PetscFunctionReturn(0); 4772 } 4773 4774 #undef __FUNCT__ 4775 #define __FUNCT__ "TSMonitorSolutionVTKDestroy" 4776 /*@C 4777 TSMonitorSolutionVTKDestroy - Destroy context for monitoring 4778 4779 Collective on TS 4780 4781 Input Parameters: 4782 . filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 4783 4784 Level: intermediate 4785 4786 Note: 4787 This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK(). 4788 4789 .keywords: TS, vector, monitor, view 4790 4791 .seealso: TSMonitorSet(), TSMonitorSolutionVTK() 4792 @*/ 4793 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate) 4794 { 4795 PetscErrorCode ierr; 4796 4797 PetscFunctionBegin; 4798 ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr); 4799 PetscFunctionReturn(0); 4800 } 4801 4802 #undef __FUNCT__ 4803 #define __FUNCT__ "TSGetAdapt" 4804 /*@ 4805 TSGetAdapt - Get the adaptive controller context for the current method 4806 4807 Collective on TS if controller has not been created yet 4808 4809 Input Arguments: 4810 . ts - time stepping context 4811 4812 Output Arguments: 4813 . adapt - adaptive controller 4814 4815 Level: intermediate 4816 4817 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose() 4818 @*/ 4819 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt) 4820 { 4821 PetscErrorCode ierr; 4822 4823 PetscFunctionBegin; 4824 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4825 PetscValidPointer(adapt,2); 4826 if (!ts->adapt) { 4827 ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr); 4828 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr); 4829 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr); 4830 } 4831 *adapt = ts->adapt; 4832 PetscFunctionReturn(0); 4833 } 4834 4835 #undef __FUNCT__ 4836 #define __FUNCT__ "TSSetTolerances" 4837 /*@ 4838 TSSetTolerances - Set tolerances for local truncation error when using adaptive controller 4839 4840 Logically Collective 4841 4842 Input Arguments: 4843 + ts - time integration context 4844 . atol - scalar absolute tolerances, PETSC_DECIDE to leave current value 4845 . vatol - vector of absolute tolerances or NULL, used in preference to atol if present 4846 . rtol - scalar relative tolerances, PETSC_DECIDE to leave current value 4847 - vrtol - vector of relative tolerances or NULL, used in preference to atol if present 4848 4849 Options Database keys: 4850 + -ts_rtol <rtol> - relative tolerance for local truncation error 4851 - -ts_atol <atol> Absolute tolerance for local truncation error 4852 4853 Level: beginner 4854 4855 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances() 4856 @*/ 4857 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol) 4858 { 4859 PetscErrorCode ierr; 4860 4861 PetscFunctionBegin; 4862 if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol; 4863 if (vatol) { 4864 ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr); 4865 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 4866 4867 ts->vatol = vatol; 4868 } 4869 if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol; 4870 if (vrtol) { 4871 ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr); 4872 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 4873 4874 ts->vrtol = vrtol; 4875 } 4876 PetscFunctionReturn(0); 4877 } 4878 4879 #undef __FUNCT__ 4880 #define __FUNCT__ "TSGetTolerances" 4881 /*@ 4882 TSGetTolerances - Get tolerances for local truncation error when using adaptive controller 4883 4884 Logically Collective 4885 4886 Input Arguments: 4887 . ts - time integration context 4888 4889 Output Arguments: 4890 + atol - scalar absolute tolerances, NULL to ignore 4891 . vatol - vector of absolute tolerances, NULL to ignore 4892 . rtol - scalar relative tolerances, NULL to ignore 4893 - vrtol - vector of relative tolerances, NULL to ignore 4894 4895 Level: beginner 4896 4897 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances() 4898 @*/ 4899 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol) 4900 { 4901 PetscFunctionBegin; 4902 if (atol) *atol = ts->atol; 4903 if (vatol) *vatol = ts->vatol; 4904 if (rtol) *rtol = ts->rtol; 4905 if (vrtol) *vrtol = ts->vrtol; 4906 PetscFunctionReturn(0); 4907 } 4908 4909 #undef __FUNCT__ 4910 #define __FUNCT__ "TSErrorNormWRMS" 4911 /*@ 4912 TSErrorNormWRMS - compute a weighted norm of the difference between a vector and the current state 4913 4914 Collective on TS 4915 4916 Input Arguments: 4917 + ts - time stepping context 4918 - Y - state vector to be compared to ts->vec_sol 4919 4920 Output Arguments: 4921 . norm - weighted norm, a value of 1.0 is considered small 4922 4923 Level: developer 4924 4925 .seealso: TSSetTolerances() 4926 @*/ 4927 PetscErrorCode TSErrorNormWRMS(TS ts,Vec Y,PetscReal *norm) 4928 { 4929 PetscErrorCode ierr; 4930 PetscInt i,n,N; 4931 const PetscScalar *u,*y; 4932 Vec U; 4933 PetscReal sum,gsum; 4934 4935 PetscFunctionBegin; 4936 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4937 PetscValidHeaderSpecific(Y,VEC_CLASSID,2); 4938 PetscValidPointer(norm,3); 4939 U = ts->vec_sol; 4940 PetscCheckSameTypeAndComm(U,1,Y,2); 4941 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"Y cannot be the TS solution vector"); 4942 4943 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 4944 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 4945 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 4946 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 4947 sum = 0.; 4948 if (ts->vatol && ts->vrtol) { 4949 const PetscScalar *atol,*rtol; 4950 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 4951 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 4952 for (i=0; i<n; i++) { 4953 PetscReal tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 4954 sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol); 4955 } 4956 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 4957 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 4958 } else if (ts->vatol) { /* vector atol, scalar rtol */ 4959 const PetscScalar *atol; 4960 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 4961 for (i=0; i<n; i++) { 4962 PetscReal tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 4963 sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol); 4964 } 4965 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 4966 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 4967 const PetscScalar *rtol; 4968 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 4969 for (i=0; i<n; i++) { 4970 PetscReal tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 4971 sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol); 4972 } 4973 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 4974 } else { /* scalar atol, scalar rtol */ 4975 for (i=0; i<n; i++) { 4976 PetscReal tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 4977 sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol); 4978 } 4979 } 4980 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 4981 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 4982 4983 ierr = MPI_Allreduce(&sum,&gsum,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 4984 *norm = PetscSqrtReal(gsum / N); 4985 if (PetscIsInfOrNanReal(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 4986 PetscFunctionReturn(0); 4987 } 4988 4989 #undef __FUNCT__ 4990 #define __FUNCT__ "TSSetCFLTimeLocal" 4991 /*@ 4992 TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler 4993 4994 Logically Collective on TS 4995 4996 Input Arguments: 4997 + ts - time stepping context 4998 - cfltime - maximum stable time step if using forward Euler (value can be different on each process) 4999 5000 Note: 5001 After calling this function, the global CFL time can be obtained by calling TSGetCFLTime() 5002 5003 Level: intermediate 5004 5005 .seealso: TSGetCFLTime(), TSADAPTCFL 5006 @*/ 5007 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime) 5008 { 5009 PetscFunctionBegin; 5010 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5011 ts->cfltime_local = cfltime; 5012 ts->cfltime = -1.; 5013 PetscFunctionReturn(0); 5014 } 5015 5016 #undef __FUNCT__ 5017 #define __FUNCT__ "TSGetCFLTime" 5018 /*@ 5019 TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler 5020 5021 Collective on TS 5022 5023 Input Arguments: 5024 . ts - time stepping context 5025 5026 Output Arguments: 5027 . cfltime - maximum stable time step for forward Euler 5028 5029 Level: advanced 5030 5031 .seealso: TSSetCFLTimeLocal() 5032 @*/ 5033 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime) 5034 { 5035 PetscErrorCode ierr; 5036 5037 PetscFunctionBegin; 5038 if (ts->cfltime < 0) { 5039 ierr = MPI_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 5040 } 5041 *cfltime = ts->cfltime; 5042 PetscFunctionReturn(0); 5043 } 5044 5045 #undef __FUNCT__ 5046 #define __FUNCT__ "TSVISetVariableBounds" 5047 /*@ 5048 TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu 5049 5050 Input Parameters: 5051 . ts - the TS context. 5052 . xl - lower bound. 5053 . xu - upper bound. 5054 5055 Notes: 5056 If this routine is not called then the lower and upper bounds are set to 5057 PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp(). 5058 5059 Level: advanced 5060 5061 @*/ 5062 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu) 5063 { 5064 PetscErrorCode ierr; 5065 SNES snes; 5066 5067 PetscFunctionBegin; 5068 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 5069 ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr); 5070 PetscFunctionReturn(0); 5071 } 5072 5073 #if defined(PETSC_HAVE_MATLAB_ENGINE) 5074 #include <mex.h> 5075 5076 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext; 5077 5078 #undef __FUNCT__ 5079 #define __FUNCT__ "TSComputeFunction_Matlab" 5080 /* 5081 TSComputeFunction_Matlab - Calls the function that has been set with 5082 TSSetFunctionMatlab(). 5083 5084 Collective on TS 5085 5086 Input Parameters: 5087 + snes - the TS context 5088 - u - input vector 5089 5090 Output Parameter: 5091 . y - function vector, as set by TSSetFunction() 5092 5093 Notes: 5094 TSComputeFunction() is typically used within nonlinear solvers 5095 implementations, so most users would not generally call this routine 5096 themselves. 5097 5098 Level: developer 5099 5100 .keywords: TS, nonlinear, compute, function 5101 5102 .seealso: TSSetFunction(), TSGetFunction() 5103 */ 5104 PetscErrorCode TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx) 5105 { 5106 PetscErrorCode ierr; 5107 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 5108 int nlhs = 1,nrhs = 7; 5109 mxArray *plhs[1],*prhs[7]; 5110 long long int lx = 0,lxdot = 0,ly = 0,ls = 0; 5111 5112 PetscFunctionBegin; 5113 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 5114 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 5115 PetscValidHeaderSpecific(udot,VEC_CLASSID,4); 5116 PetscValidHeaderSpecific(y,VEC_CLASSID,5); 5117 PetscCheckSameComm(snes,1,u,3); 5118 PetscCheckSameComm(snes,1,y,5); 5119 5120 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 5121 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 5122 ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr); 5123 ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr); 5124 5125 prhs[0] = mxCreateDoubleScalar((double)ls); 5126 prhs[1] = mxCreateDoubleScalar(time); 5127 prhs[2] = mxCreateDoubleScalar((double)lx); 5128 prhs[3] = mxCreateDoubleScalar((double)lxdot); 5129 prhs[4] = mxCreateDoubleScalar((double)ly); 5130 prhs[5] = mxCreateString(sctx->funcname); 5131 prhs[6] = sctx->ctx; 5132 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr); 5133 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 5134 mxDestroyArray(prhs[0]); 5135 mxDestroyArray(prhs[1]); 5136 mxDestroyArray(prhs[2]); 5137 mxDestroyArray(prhs[3]); 5138 mxDestroyArray(prhs[4]); 5139 mxDestroyArray(prhs[5]); 5140 mxDestroyArray(plhs[0]); 5141 PetscFunctionReturn(0); 5142 } 5143 5144 5145 #undef __FUNCT__ 5146 #define __FUNCT__ "TSSetFunctionMatlab" 5147 /* 5148 TSSetFunctionMatlab - Sets the function evaluation routine and function 5149 vector for use by the TS routines in solving ODEs 5150 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 5151 5152 Logically Collective on TS 5153 5154 Input Parameters: 5155 + ts - the TS context 5156 - func - function evaluation routine 5157 5158 Calling sequence of func: 5159 $ func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx); 5160 5161 Level: beginner 5162 5163 .keywords: TS, nonlinear, set, function 5164 5165 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 5166 */ 5167 PetscErrorCode TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx) 5168 { 5169 PetscErrorCode ierr; 5170 TSMatlabContext *sctx; 5171 5172 PetscFunctionBegin; 5173 /* currently sctx is memory bleed */ 5174 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 5175 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 5176 /* 5177 This should work, but it doesn't 5178 sctx->ctx = ctx; 5179 mexMakeArrayPersistent(sctx->ctx); 5180 */ 5181 sctx->ctx = mxDuplicateArray(ctx); 5182 5183 ierr = TSSetIFunction(ts,NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr); 5184 PetscFunctionReturn(0); 5185 } 5186 5187 #undef __FUNCT__ 5188 #define __FUNCT__ "TSComputeJacobian_Matlab" 5189 /* 5190 TSComputeJacobian_Matlab - Calls the function that has been set with 5191 TSSetJacobianMatlab(). 5192 5193 Collective on TS 5194 5195 Input Parameters: 5196 + ts - the TS context 5197 . u - input vector 5198 . A, B - the matrices 5199 - ctx - user context 5200 5201 Level: developer 5202 5203 .keywords: TS, nonlinear, compute, function 5204 5205 .seealso: TSSetFunction(), TSGetFunction() 5206 @*/ 5207 PetscErrorCode TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat A,Mat B,void *ctx) 5208 { 5209 PetscErrorCode ierr; 5210 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 5211 int nlhs = 2,nrhs = 9; 5212 mxArray *plhs[2],*prhs[9]; 5213 long long int lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0; 5214 5215 PetscFunctionBegin; 5216 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5217 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 5218 5219 /* call Matlab function in ctx with arguments u and y */ 5220 5221 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 5222 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 5223 ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr); 5224 ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr); 5225 ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr); 5226 5227 prhs[0] = mxCreateDoubleScalar((double)ls); 5228 prhs[1] = mxCreateDoubleScalar((double)time); 5229 prhs[2] = mxCreateDoubleScalar((double)lx); 5230 prhs[3] = mxCreateDoubleScalar((double)lxdot); 5231 prhs[4] = mxCreateDoubleScalar((double)shift); 5232 prhs[5] = mxCreateDoubleScalar((double)lA); 5233 prhs[6] = mxCreateDoubleScalar((double)lB); 5234 prhs[7] = mxCreateString(sctx->funcname); 5235 prhs[8] = sctx->ctx; 5236 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr); 5237 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 5238 mxDestroyArray(prhs[0]); 5239 mxDestroyArray(prhs[1]); 5240 mxDestroyArray(prhs[2]); 5241 mxDestroyArray(prhs[3]); 5242 mxDestroyArray(prhs[4]); 5243 mxDestroyArray(prhs[5]); 5244 mxDestroyArray(prhs[6]); 5245 mxDestroyArray(prhs[7]); 5246 mxDestroyArray(plhs[0]); 5247 mxDestroyArray(plhs[1]); 5248 PetscFunctionReturn(0); 5249 } 5250 5251 5252 #undef __FUNCT__ 5253 #define __FUNCT__ "TSSetJacobianMatlab" 5254 /* 5255 TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 5256 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 5257 5258 Logically Collective on TS 5259 5260 Input Parameters: 5261 + ts - the TS context 5262 . A,B - Jacobian matrices 5263 . func - function evaluation routine 5264 - ctx - user context 5265 5266 Calling sequence of func: 5267 $ flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx); 5268 5269 5270 Level: developer 5271 5272 .keywords: TS, nonlinear, set, function 5273 5274 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 5275 */ 5276 PetscErrorCode TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx) 5277 { 5278 PetscErrorCode ierr; 5279 TSMatlabContext *sctx; 5280 5281 PetscFunctionBegin; 5282 /* currently sctx is memory bleed */ 5283 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 5284 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 5285 /* 5286 This should work, but it doesn't 5287 sctx->ctx = ctx; 5288 mexMakeArrayPersistent(sctx->ctx); 5289 */ 5290 sctx->ctx = mxDuplicateArray(ctx); 5291 5292 ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 5293 PetscFunctionReturn(0); 5294 } 5295 5296 #undef __FUNCT__ 5297 #define __FUNCT__ "TSMonitor_Matlab" 5298 /* 5299 TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab(). 5300 5301 Collective on TS 5302 5303 .seealso: TSSetFunction(), TSGetFunction() 5304 @*/ 5305 PetscErrorCode TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx) 5306 { 5307 PetscErrorCode ierr; 5308 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 5309 int nlhs = 1,nrhs = 6; 5310 mxArray *plhs[1],*prhs[6]; 5311 long long int lx = 0,ls = 0; 5312 5313 PetscFunctionBegin; 5314 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5315 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 5316 5317 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 5318 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 5319 5320 prhs[0] = mxCreateDoubleScalar((double)ls); 5321 prhs[1] = mxCreateDoubleScalar((double)it); 5322 prhs[2] = mxCreateDoubleScalar((double)time); 5323 prhs[3] = mxCreateDoubleScalar((double)lx); 5324 prhs[4] = mxCreateString(sctx->funcname); 5325 prhs[5] = sctx->ctx; 5326 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr); 5327 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 5328 mxDestroyArray(prhs[0]); 5329 mxDestroyArray(prhs[1]); 5330 mxDestroyArray(prhs[2]); 5331 mxDestroyArray(prhs[3]); 5332 mxDestroyArray(prhs[4]); 5333 mxDestroyArray(plhs[0]); 5334 PetscFunctionReturn(0); 5335 } 5336 5337 5338 #undef __FUNCT__ 5339 #define __FUNCT__ "TSMonitorSetMatlab" 5340 /* 5341 TSMonitorSetMatlab - Sets the monitor function from Matlab 5342 5343 Level: developer 5344 5345 .keywords: TS, nonlinear, set, function 5346 5347 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 5348 */ 5349 PetscErrorCode TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx) 5350 { 5351 PetscErrorCode ierr; 5352 TSMatlabContext *sctx; 5353 5354 PetscFunctionBegin; 5355 /* currently sctx is memory bleed */ 5356 ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr); 5357 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 5358 /* 5359 This should work, but it doesn't 5360 sctx->ctx = ctx; 5361 mexMakeArrayPersistent(sctx->ctx); 5362 */ 5363 sctx->ctx = mxDuplicateArray(ctx); 5364 5365 ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,NULL);CHKERRQ(ierr); 5366 PetscFunctionReturn(0); 5367 } 5368 #endif 5369 5370 5371 5372 #undef __FUNCT__ 5373 #define __FUNCT__ "TSMonitorLGSolution" 5374 /*@C 5375 TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector 5376 in a time based line graph 5377 5378 Collective on TS 5379 5380 Input Parameters: 5381 + ts - the TS context 5382 . step - current time-step 5383 . ptime - current time 5384 - lg - a line graph object 5385 5386 Level: intermediate 5387 5388 Notes: each process in a parallel run displays its component solutions in a separate window 5389 5390 .keywords: TS, vector, monitor, view 5391 5392 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5393 @*/ 5394 PetscErrorCode TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 5395 { 5396 PetscErrorCode ierr; 5397 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 5398 const PetscScalar *yy; 5399 PetscInt dim; 5400 5401 PetscFunctionBegin; 5402 if (!step) { 5403 PetscDrawAxis axis; 5404 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 5405 ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr); 5406 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 5407 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 5408 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 5409 } 5410 ierr = VecGetArrayRead(u,&yy);CHKERRQ(ierr); 5411 #if defined(PETSC_USE_COMPLEX) 5412 { 5413 PetscReal *yreal; 5414 PetscInt i,n; 5415 ierr = VecGetLocalSize(u,&n);CHKERRQ(ierr); 5416 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 5417 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 5418 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 5419 ierr = PetscFree(yreal);CHKERRQ(ierr); 5420 } 5421 #else 5422 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 5423 #endif 5424 ierr = VecRestoreArrayRead(u,&yy);CHKERRQ(ierr); 5425 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 5426 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 5427 } 5428 PetscFunctionReturn(0); 5429 } 5430 5431 #undef __FUNCT__ 5432 #define __FUNCT__ "TSMonitorLGError" 5433 /*@C 5434 TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the solution vector 5435 in a time based line graph 5436 5437 Collective on TS 5438 5439 Input Parameters: 5440 + ts - the TS context 5441 . step - current time-step 5442 . ptime - current time 5443 - lg - a line graph object 5444 5445 Level: intermediate 5446 5447 Notes: 5448 Only for sequential solves. 5449 5450 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 5451 5452 Options Database Keys: 5453 . -ts_monitor_lg_error - create a graphical monitor of error history 5454 5455 .keywords: TS, vector, monitor, view 5456 5457 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 5458 @*/ 5459 PetscErrorCode TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 5460 { 5461 PetscErrorCode ierr; 5462 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 5463 const PetscScalar *yy; 5464 Vec y; 5465 PetscInt dim; 5466 5467 PetscFunctionBegin; 5468 if (!step) { 5469 PetscDrawAxis axis; 5470 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 5471 ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Solution");CHKERRQ(ierr); 5472 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 5473 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 5474 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 5475 } 5476 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 5477 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 5478 ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr); 5479 ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr); 5480 #if defined(PETSC_USE_COMPLEX) 5481 { 5482 PetscReal *yreal; 5483 PetscInt i,n; 5484 ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr); 5485 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 5486 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 5487 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 5488 ierr = PetscFree(yreal);CHKERRQ(ierr); 5489 } 5490 #else 5491 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 5492 #endif 5493 ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr); 5494 ierr = VecDestroy(&y);CHKERRQ(ierr); 5495 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 5496 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 5497 } 5498 PetscFunctionReturn(0); 5499 } 5500 5501 #undef __FUNCT__ 5502 #define __FUNCT__ "TSMonitorLGSNESIterations" 5503 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 5504 { 5505 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 5506 PetscReal x = ptime,y; 5507 PetscErrorCode ierr; 5508 PetscInt its; 5509 5510 PetscFunctionBegin; 5511 if (!n) { 5512 PetscDrawAxis axis; 5513 5514 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 5515 ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr); 5516 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 5517 5518 ctx->snes_its = 0; 5519 } 5520 ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr); 5521 y = its - ctx->snes_its; 5522 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 5523 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 5524 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 5525 } 5526 ctx->snes_its = its; 5527 PetscFunctionReturn(0); 5528 } 5529 5530 #undef __FUNCT__ 5531 #define __FUNCT__ "TSMonitorLGKSPIterations" 5532 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 5533 { 5534 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 5535 PetscReal x = ptime,y; 5536 PetscErrorCode ierr; 5537 PetscInt its; 5538 5539 PetscFunctionBegin; 5540 if (!n) { 5541 PetscDrawAxis axis; 5542 5543 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 5544 ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr); 5545 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 5546 5547 ctx->ksp_its = 0; 5548 } 5549 ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr); 5550 y = its - ctx->ksp_its; 5551 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 5552 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 5553 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 5554 } 5555 ctx->ksp_its = its; 5556 PetscFunctionReturn(0); 5557 } 5558 5559 #undef __FUNCT__ 5560 #define __FUNCT__ "TSComputeLinearStability" 5561 /*@ 5562 TSComputeLinearStability - computes the linear stability function at a point 5563 5564 Collective on TS and Vec 5565 5566 Input Parameters: 5567 + ts - the TS context 5568 - xr,xi - real and imaginary part of input arguments 5569 5570 Output Parameters: 5571 . yr,yi - real and imaginary part of function value 5572 5573 Level: developer 5574 5575 .keywords: TS, compute 5576 5577 .seealso: TSSetRHSFunction(), TSComputeIFunction() 5578 @*/ 5579 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi) 5580 { 5581 PetscErrorCode ierr; 5582 5583 PetscFunctionBegin; 5584 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5585 if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method"); 5586 ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr); 5587 PetscFunctionReturn(0); 5588 } 5589 5590 #undef __FUNCT__ 5591 #define __FUNCT__ "TSRollBack" 5592 /*@ 5593 TSRollBack - Rolls back one time step 5594 5595 Collective on TS 5596 5597 Input Parameter: 5598 . ts - the TS context obtained from TSCreate() 5599 5600 Level: advanced 5601 5602 .keywords: TS, timestep, rollback 5603 5604 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate() 5605 @*/ 5606 PetscErrorCode TSRollBack(TS ts) 5607 { 5608 PetscErrorCode ierr; 5609 5610 PetscFunctionBegin; 5611 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 5612 5613 if (!ts->ops->rollback) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name); 5614 ierr = (*ts->ops->rollback)(ts);CHKERRQ(ierr); 5615 ts->time_step = ts->ptime - ts->ptime_prev; 5616 ts->ptime = ts->ptime_prev; 5617 PetscFunctionReturn(0); 5618 } 5619 5620 #undef __FUNCT__ 5621 #define __FUNCT__ "TSGetStages" 5622 /*@ 5623 TSGetStages - Get the number of stages and stage values 5624 5625 Input Parameter: 5626 . ts - the TS context obtained from TSCreate() 5627 5628 Level: advanced 5629 5630 .keywords: TS, getstages 5631 5632 .seealso: TSCreate() 5633 @*/ 5634 PetscErrorCode TSGetStages(TS ts,PetscInt *ns, Vec **Y) 5635 { 5636 PetscErrorCode ierr; 5637 5638 PetscFunctionBegin; 5639 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 5640 PetscValidPointer(ns,2); 5641 5642 if (!ts->ops->getstages) *ns=0; 5643 else { 5644 ierr = (*ts->ops->getstages)(ts,ns,Y);CHKERRQ(ierr); 5645 } 5646 PetscFunctionReturn(0); 5647 } 5648 5649 5650 #undef __FUNCT__ 5651 #define __FUNCT__ "TSComputeIJacobianDefaultColor" 5652 /*@C 5653 TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity. 5654 5655 Collective on SNES 5656 5657 Input Parameters: 5658 + ts - the TS context 5659 . t - current timestep 5660 . U - state vector 5661 . Udot - time derivative of state vector 5662 . shift - shift to apply, see note below 5663 - ctx - an optional user context 5664 5665 Output Parameters: 5666 + J - Jacobian matrix (not altered in this routine) 5667 - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J) 5668 5669 Level: intermediate 5670 5671 Notes: 5672 If F(t,U,Udot)=0 is the DAE, the required Jacobian is 5673 5674 dF/dU + shift*dF/dUdot 5675 5676 Most users should not need to explicitly call this routine, as it 5677 is used internally within the nonlinear solvers. 5678 5679 This will first try to get the coloring from the DM. If the DM type has no coloring 5680 routine, then it will try to get the coloring from the matrix. This requires that the 5681 matrix have nonzero entries precomputed. 5682 5683 .keywords: TS, finite differences, Jacobian, coloring, sparse 5684 .seealso: TSSetIJacobian(), MatFDColoringCreate(), MatFDColoringSetFunction() 5685 @*/ 5686 PetscErrorCode TSComputeIJacobianDefaultColor(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat J,Mat B,void *ctx) 5687 { 5688 SNES snes; 5689 MatFDColoring color; 5690 PetscBool hascolor, matcolor = PETSC_FALSE; 5691 PetscErrorCode ierr; 5692 5693 PetscFunctionBegin; 5694 ierr = PetscOptionsGetBool(((PetscObject) ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL);CHKERRQ(ierr); 5695 ierr = PetscObjectQuery((PetscObject) B, "TSMatFDColoring", (PetscObject *) &color);CHKERRQ(ierr); 5696 if (!color) { 5697 DM dm; 5698 ISColoring iscoloring; 5699 5700 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 5701 ierr = DMHasColoring(dm, &hascolor);CHKERRQ(ierr); 5702 if (hascolor && !matcolor) { 5703 ierr = DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring);CHKERRQ(ierr); 5704 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 5705 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 5706 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 5707 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 5708 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 5709 } else { 5710 MatColoring mc; 5711 5712 ierr = MatColoringCreate(B, &mc);CHKERRQ(ierr); 5713 ierr = MatColoringSetDistance(mc, 2);CHKERRQ(ierr); 5714 ierr = MatColoringSetType(mc, MATCOLORINGSL);CHKERRQ(ierr); 5715 ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); 5716 ierr = MatColoringApply(mc, &iscoloring);CHKERRQ(ierr); 5717 ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); 5718 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 5719 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 5720 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 5721 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 5722 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 5723 } 5724 ierr = PetscObjectCompose((PetscObject) B, "TSMatFDColoring", (PetscObject) color);CHKERRQ(ierr); 5725 ierr = PetscObjectDereference((PetscObject) color);CHKERRQ(ierr); 5726 } 5727 ierr = TSGetSNES(ts, &snes);CHKERRQ(ierr); 5728 ierr = MatFDColoringApply(B, color, U, snes);CHKERRQ(ierr); 5729 if (J != B) { 5730 ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5731 ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5732 } 5733 PetscFunctionReturn(0); 5734 } 5735