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