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