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