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