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