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 y = PetscLog10Real(y); 4364 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 4365 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 4366 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 4367 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 4368 } 4369 PetscFunctionReturn(0); 4370 } 4371 4372 /*@C 4373 TSMonitorLGCtxDestroy - Destroys a line graph context that was created 4374 with TSMonitorLGCtxCreate(). 4375 4376 Collective on TSMonitorLGCtx 4377 4378 Input Parameter: 4379 . ctx - the monitor context 4380 4381 Level: intermediate 4382 4383 .keywords: TS, monitor, line graph, destroy 4384 4385 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep(); 4386 @*/ 4387 PetscErrorCode TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx) 4388 { 4389 PetscErrorCode ierr; 4390 4391 PetscFunctionBegin; 4392 if ((*ctx)->transformdestroy) { 4393 ierr = ((*ctx)->transformdestroy)((*ctx)->transformctx);CHKERRQ(ierr); 4394 } 4395 ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr); 4396 ierr = PetscStrArrayDestroy(&(*ctx)->names);CHKERRQ(ierr); 4397 ierr = PetscStrArrayDestroy(&(*ctx)->displaynames);CHKERRQ(ierr); 4398 ierr = PetscFree((*ctx)->displayvariables);CHKERRQ(ierr); 4399 ierr = PetscFree((*ctx)->displayvalues);CHKERRQ(ierr); 4400 ierr = PetscFree(*ctx);CHKERRQ(ierr); 4401 PetscFunctionReturn(0); 4402 } 4403 4404 /*@ 4405 TSGetTime - Gets the time of the most recently completed step. 4406 4407 Not Collective 4408 4409 Input Parameter: 4410 . ts - the TS context obtained from TSCreate() 4411 4412 Output Parameter: 4413 . t - the current time. This time may not corresponds to the final time set with TSSetDuration(), use TSGetSolveTime(). 4414 4415 Level: beginner 4416 4417 Note: 4418 When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(), 4419 TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated. 4420 4421 .seealso: TSSetInitialTimeStep(), TSGetTimeStep(), TSGetSolveTime() 4422 4423 .keywords: TS, get, time 4424 @*/ 4425 PetscErrorCode TSGetTime(TS ts,PetscReal *t) 4426 { 4427 PetscFunctionBegin; 4428 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4429 PetscValidRealPointer(t,2); 4430 *t = ts->ptime; 4431 PetscFunctionReturn(0); 4432 } 4433 4434 /*@ 4435 TSGetPrevTime - Gets the starting time of the previously completed step. 4436 4437 Not Collective 4438 4439 Input Parameter: 4440 . ts - the TS context obtained from TSCreate() 4441 4442 Output Parameter: 4443 . t - the previous time 4444 4445 Level: beginner 4446 4447 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 4448 4449 .keywords: TS, get, time 4450 @*/ 4451 PetscErrorCode TSGetPrevTime(TS ts,PetscReal *t) 4452 { 4453 PetscFunctionBegin; 4454 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4455 PetscValidRealPointer(t,2); 4456 *t = ts->ptime_prev; 4457 PetscFunctionReturn(0); 4458 } 4459 4460 /*@ 4461 TSSetTime - Allows one to reset the time. 4462 4463 Logically Collective on TS 4464 4465 Input Parameters: 4466 + ts - the TS context obtained from TSCreate() 4467 - time - the time 4468 4469 Level: intermediate 4470 4471 .seealso: TSGetTime(), TSSetDuration() 4472 4473 .keywords: TS, set, time 4474 @*/ 4475 PetscErrorCode TSSetTime(TS ts, PetscReal t) 4476 { 4477 PetscFunctionBegin; 4478 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4479 PetscValidLogicalCollectiveReal(ts,t,2); 4480 ts->ptime = t; 4481 PetscFunctionReturn(0); 4482 } 4483 4484 /*@C 4485 TSSetOptionsPrefix - Sets the prefix used for searching for all 4486 TS options in the database. 4487 4488 Logically Collective on TS 4489 4490 Input Parameter: 4491 + ts - The TS context 4492 - prefix - The prefix to prepend to all option names 4493 4494 Notes: 4495 A hyphen (-) must NOT be given at the beginning of the prefix name. 4496 The first character of all runtime options is AUTOMATICALLY the 4497 hyphen. 4498 4499 Level: advanced 4500 4501 .keywords: TS, set, options, prefix, database 4502 4503 .seealso: TSSetFromOptions() 4504 4505 @*/ 4506 PetscErrorCode TSSetOptionsPrefix(TS ts,const char prefix[]) 4507 { 4508 PetscErrorCode ierr; 4509 SNES snes; 4510 4511 PetscFunctionBegin; 4512 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4513 ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4514 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4515 ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4516 PetscFunctionReturn(0); 4517 } 4518 4519 4520 /*@C 4521 TSAppendOptionsPrefix - Appends to the prefix used for searching for all 4522 TS options in the database. 4523 4524 Logically Collective on TS 4525 4526 Input Parameter: 4527 + ts - The TS context 4528 - prefix - The prefix to prepend to all option names 4529 4530 Notes: 4531 A hyphen (-) must NOT be given at the beginning of the prefix name. 4532 The first character of all runtime options is AUTOMATICALLY the 4533 hyphen. 4534 4535 Level: advanced 4536 4537 .keywords: TS, append, options, prefix, database 4538 4539 .seealso: TSGetOptionsPrefix() 4540 4541 @*/ 4542 PetscErrorCode TSAppendOptionsPrefix(TS ts,const char prefix[]) 4543 { 4544 PetscErrorCode ierr; 4545 SNES snes; 4546 4547 PetscFunctionBegin; 4548 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4549 ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4550 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4551 ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4552 PetscFunctionReturn(0); 4553 } 4554 4555 /*@C 4556 TSGetOptionsPrefix - Sets the prefix used for searching for all 4557 TS options in the database. 4558 4559 Not Collective 4560 4561 Input Parameter: 4562 . ts - The TS context 4563 4564 Output Parameter: 4565 . prefix - A pointer to the prefix string used 4566 4567 Notes: On the fortran side, the user should pass in a string 'prifix' of 4568 sufficient length to hold the prefix. 4569 4570 Level: intermediate 4571 4572 .keywords: TS, get, options, prefix, database 4573 4574 .seealso: TSAppendOptionsPrefix() 4575 @*/ 4576 PetscErrorCode TSGetOptionsPrefix(TS ts,const char *prefix[]) 4577 { 4578 PetscErrorCode ierr; 4579 4580 PetscFunctionBegin; 4581 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4582 PetscValidPointer(prefix,2); 4583 ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4584 PetscFunctionReturn(0); 4585 } 4586 4587 /*@C 4588 TSGetRHSJacobian - Returns the Jacobian J at the present timestep. 4589 4590 Not Collective, but parallel objects are returned if TS is parallel 4591 4592 Input Parameter: 4593 . ts - The TS context obtained from TSCreate() 4594 4595 Output Parameters: 4596 + Amat - The (approximate) Jacobian J of G, where U_t = G(U,t) (or NULL) 4597 . Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat (or NULL) 4598 . func - Function to compute the Jacobian of the RHS (or NULL) 4599 - ctx - User-defined context for Jacobian evaluation routine (or NULL) 4600 4601 Notes: You can pass in NULL for any return argument you do not need. 4602 4603 Level: intermediate 4604 4605 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 4606 4607 .keywords: TS, timestep, get, matrix, Jacobian 4608 @*/ 4609 PetscErrorCode TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx) 4610 { 4611 PetscErrorCode ierr; 4612 DM dm; 4613 4614 PetscFunctionBegin; 4615 if (Amat || Pmat) { 4616 SNES snes; 4617 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4618 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4619 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4620 } 4621 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4622 ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr); 4623 PetscFunctionReturn(0); 4624 } 4625 4626 /*@C 4627 TSGetIJacobian - Returns the implicit Jacobian at the present timestep. 4628 4629 Not Collective, but parallel objects are returned if TS is parallel 4630 4631 Input Parameter: 4632 . ts - The TS context obtained from TSCreate() 4633 4634 Output Parameters: 4635 + Amat - The (approximate) Jacobian of F(t,U,U_t) 4636 . Pmat - The matrix from which the preconditioner is constructed, often the same as Amat 4637 . f - The function to compute the matrices 4638 - ctx - User-defined context for Jacobian evaluation routine 4639 4640 Notes: You can pass in NULL for any return argument you do not need. 4641 4642 Level: advanced 4643 4644 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 4645 4646 .keywords: TS, timestep, get, matrix, Jacobian 4647 @*/ 4648 PetscErrorCode TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx) 4649 { 4650 PetscErrorCode ierr; 4651 DM dm; 4652 4653 PetscFunctionBegin; 4654 if (Amat || Pmat) { 4655 SNES snes; 4656 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4657 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4658 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4659 } 4660 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4661 ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr); 4662 PetscFunctionReturn(0); 4663 } 4664 4665 4666 /*@C 4667 TSMonitorDrawSolution - Monitors progress of the TS solvers by calling 4668 VecView() for the solution at each timestep 4669 4670 Collective on TS 4671 4672 Input Parameters: 4673 + ts - the TS context 4674 . step - current time-step 4675 . ptime - current time 4676 - dummy - either a viewer or NULL 4677 4678 Options Database: 4679 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 4680 4681 Notes: the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial 4682 will look bad 4683 4684 Level: intermediate 4685 4686 .keywords: TS, vector, monitor, view 4687 4688 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4689 @*/ 4690 PetscErrorCode TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4691 { 4692 PetscErrorCode ierr; 4693 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 4694 PetscDraw draw; 4695 4696 PetscFunctionBegin; 4697 if (!step && ictx->showinitial) { 4698 if (!ictx->initialsolution) { 4699 ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr); 4700 } 4701 ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr); 4702 } 4703 if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4704 4705 if (ictx->showinitial) { 4706 PetscReal pause; 4707 ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr); 4708 ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr); 4709 ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr); 4710 ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr); 4711 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr); 4712 } 4713 ierr = VecView(u,ictx->viewer);CHKERRQ(ierr); 4714 if (ictx->showtimestepandtime) { 4715 PetscReal xl,yl,xr,yr,h; 4716 char time[32]; 4717 4718 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 4719 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 4720 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 4721 h = yl + .95*(yr - yl); 4722 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 4723 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 4724 } 4725 4726 if (ictx->showinitial) { 4727 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr); 4728 } 4729 PetscFunctionReturn(0); 4730 } 4731 4732 /*@C 4733 TSAdjointMonitorDrawSensi - Monitors progress of the adjoint TS solvers by calling 4734 VecView() for the sensitivities to initial states at each timestep 4735 4736 Collective on TS 4737 4738 Input Parameters: 4739 + ts - the TS context 4740 . step - current time-step 4741 . ptime - current time 4742 . u - current state 4743 . numcost - number of cost functions 4744 . lambda - sensitivities to initial conditions 4745 . mu - sensitivities to parameters 4746 - dummy - either a viewer or NULL 4747 4748 Level: intermediate 4749 4750 .keywords: TS, vector, adjoint, monitor, view 4751 4752 .seealso: TSAdjointMonitorSet(), TSAdjointMonitorDefault(), VecView() 4753 @*/ 4754 PetscErrorCode TSAdjointMonitorDrawSensi(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda,Vec *mu,void *dummy) 4755 { 4756 PetscErrorCode ierr; 4757 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 4758 PetscDraw draw; 4759 PetscReal xl,yl,xr,yr,h; 4760 char time[32]; 4761 4762 PetscFunctionBegin; 4763 if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4764 4765 ierr = VecView(lambda[0],ictx->viewer);CHKERRQ(ierr); 4766 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 4767 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 4768 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 4769 h = yl + .95*(yr - yl); 4770 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 4771 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 4772 PetscFunctionReturn(0); 4773 } 4774 4775 /*@C 4776 TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram 4777 4778 Collective on TS 4779 4780 Input Parameters: 4781 + ts - the TS context 4782 . step - current time-step 4783 . ptime - current time 4784 - dummy - either a viewer or NULL 4785 4786 Level: intermediate 4787 4788 .keywords: TS, vector, monitor, view 4789 4790 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4791 @*/ 4792 PetscErrorCode TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4793 { 4794 PetscErrorCode ierr; 4795 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 4796 PetscDraw draw; 4797 PetscDrawAxis axis; 4798 PetscInt n; 4799 PetscMPIInt size; 4800 PetscReal U0,U1,xl,yl,xr,yr,h; 4801 char time[32]; 4802 const PetscScalar *U; 4803 4804 PetscFunctionBegin; 4805 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size);CHKERRQ(ierr); 4806 if (size != 1) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs"); 4807 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 4808 if (n != 2) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns"); 4809 4810 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 4811 ierr = PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis);CHKERRQ(ierr); 4812 ierr = PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr); 4813 if (!step) { 4814 ierr = PetscDrawClear(draw);CHKERRQ(ierr); 4815 ierr = PetscDrawAxisDraw(axis);CHKERRQ(ierr); 4816 } 4817 4818 ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr); 4819 U0 = PetscRealPart(U[0]); 4820 U1 = PetscRealPart(U[1]); 4821 ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr); 4822 if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0); 4823 4824 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 4825 ierr = PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK);CHKERRQ(ierr); 4826 if (ictx->showtimestepandtime) { 4827 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 4828 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 4829 h = yl + .95*(yr - yl); 4830 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 4831 } 4832 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 4833 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 4834 ierr = PetscDrawSave(draw);CHKERRQ(ierr); 4835 PetscFunctionReturn(0); 4836 } 4837 4838 4839 /*@C 4840 TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution() 4841 4842 Collective on TS 4843 4844 Input Parameters: 4845 . ctx - the monitor context 4846 4847 Level: intermediate 4848 4849 .keywords: TS, vector, monitor, view 4850 4851 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError() 4852 @*/ 4853 PetscErrorCode TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx) 4854 { 4855 PetscErrorCode ierr; 4856 4857 PetscFunctionBegin; 4858 ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr); 4859 ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr); 4860 ierr = PetscFree(*ictx);CHKERRQ(ierr); 4861 PetscFunctionReturn(0); 4862 } 4863 4864 /*@C 4865 TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx 4866 4867 Collective on TS 4868 4869 Input Parameter: 4870 . ts - time-step context 4871 4872 Output Patameter: 4873 . ctx - the monitor context 4874 4875 Options Database: 4876 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 4877 4878 Level: intermediate 4879 4880 .keywords: TS, vector, monitor, view 4881 4882 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx() 4883 @*/ 4884 PetscErrorCode TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx) 4885 { 4886 PetscErrorCode ierr; 4887 4888 PetscFunctionBegin; 4889 ierr = PetscNew(ctx);CHKERRQ(ierr); 4890 ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr); 4891 ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr); 4892 4893 (*ctx)->howoften = howoften; 4894 (*ctx)->showinitial = PETSC_FALSE; 4895 ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr); 4896 4897 (*ctx)->showtimestepandtime = PETSC_FALSE; 4898 ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr); 4899 PetscFunctionReturn(0); 4900 } 4901 4902 /*@C 4903 TSMonitorDrawError - Monitors progress of the TS solvers by calling 4904 VecView() for the error at each timestep 4905 4906 Collective on TS 4907 4908 Input Parameters: 4909 + ts - the TS context 4910 . step - current time-step 4911 . ptime - current time 4912 - dummy - either a viewer or NULL 4913 4914 Level: intermediate 4915 4916 .keywords: TS, vector, monitor, view 4917 4918 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4919 @*/ 4920 PetscErrorCode TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4921 { 4922 PetscErrorCode ierr; 4923 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 4924 PetscViewer viewer = ctx->viewer; 4925 Vec work; 4926 4927 PetscFunctionBegin; 4928 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4929 ierr = VecDuplicate(u,&work);CHKERRQ(ierr); 4930 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 4931 ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr); 4932 ierr = VecView(work,viewer);CHKERRQ(ierr); 4933 ierr = VecDestroy(&work);CHKERRQ(ierr); 4934 PetscFunctionReturn(0); 4935 } 4936 4937 #include <petsc/private/dmimpl.h> 4938 /*@ 4939 TSSetDM - Sets the DM that may be used by some nonlinear solvers or preconditioners under the TS 4940 4941 Logically Collective on TS and DM 4942 4943 Input Parameters: 4944 + ts - the ODE integrator object 4945 - dm - the dm, cannot be NULL 4946 4947 Level: intermediate 4948 4949 4950 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM() 4951 @*/ 4952 PetscErrorCode TSSetDM(TS ts,DM dm) 4953 { 4954 PetscErrorCode ierr; 4955 SNES snes; 4956 DMTS tsdm; 4957 4958 PetscFunctionBegin; 4959 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4960 PetscValidHeaderSpecific(dm,DM_CLASSID,2); 4961 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 4962 if (ts->dm) { /* Move the DMTS context over to the new DM unless the new DM already has one */ 4963 if (ts->dm->dmts && !dm->dmts) { 4964 ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr); 4965 ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr); 4966 if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */ 4967 tsdm->originaldm = dm; 4968 } 4969 } 4970 ierr = DMDestroy(&ts->dm);CHKERRQ(ierr); 4971 } 4972 ts->dm = dm; 4973 4974 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4975 ierr = SNESSetDM(snes,dm);CHKERRQ(ierr); 4976 PetscFunctionReturn(0); 4977 } 4978 4979 /*@ 4980 TSGetDM - Gets the DM that may be used by some preconditioners 4981 4982 Not Collective 4983 4984 Input Parameter: 4985 . ts - the preconditioner context 4986 4987 Output Parameter: 4988 . dm - the dm 4989 4990 Level: intermediate 4991 4992 4993 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM() 4994 @*/ 4995 PetscErrorCode TSGetDM(TS ts,DM *dm) 4996 { 4997 PetscErrorCode ierr; 4998 4999 PetscFunctionBegin; 5000 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5001 if (!ts->dm) { 5002 ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr); 5003 if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 5004 } 5005 *dm = ts->dm; 5006 PetscFunctionReturn(0); 5007 } 5008 5009 /*@ 5010 SNESTSFormFunction - Function to evaluate nonlinear residual 5011 5012 Logically Collective on SNES 5013 5014 Input Parameter: 5015 + snes - nonlinear solver 5016 . U - the current state at which to evaluate the residual 5017 - ctx - user context, must be a TS 5018 5019 Output Parameter: 5020 . F - the nonlinear residual 5021 5022 Notes: 5023 This function is not normally called by users and is automatically registered with the SNES used by TS. 5024 It is most frequently passed to MatFDColoringSetFunction(). 5025 5026 Level: advanced 5027 5028 .seealso: SNESSetFunction(), MatFDColoringSetFunction() 5029 @*/ 5030 PetscErrorCode SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx) 5031 { 5032 TS ts = (TS)ctx; 5033 PetscErrorCode ierr; 5034 5035 PetscFunctionBegin; 5036 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5037 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5038 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 5039 PetscValidHeaderSpecific(ts,TS_CLASSID,4); 5040 ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr); 5041 PetscFunctionReturn(0); 5042 } 5043 5044 /*@ 5045 SNESTSFormJacobian - Function to evaluate the Jacobian 5046 5047 Collective on SNES 5048 5049 Input Parameter: 5050 + snes - nonlinear solver 5051 . U - the current state at which to evaluate the residual 5052 - ctx - user context, must be a TS 5053 5054 Output Parameter: 5055 + A - the Jacobian 5056 . B - the preconditioning matrix (may be the same as A) 5057 - flag - indicates any structure change in the matrix 5058 5059 Notes: 5060 This function is not normally called by users and is automatically registered with the SNES used by TS. 5061 5062 Level: developer 5063 5064 .seealso: SNESSetJacobian() 5065 @*/ 5066 PetscErrorCode SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx) 5067 { 5068 TS ts = (TS)ctx; 5069 PetscErrorCode ierr; 5070 5071 PetscFunctionBegin; 5072 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5073 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5074 PetscValidPointer(A,3); 5075 PetscValidHeaderSpecific(A,MAT_CLASSID,3); 5076 PetscValidPointer(B,4); 5077 PetscValidHeaderSpecific(B,MAT_CLASSID,4); 5078 PetscValidHeaderSpecific(ts,TS_CLASSID,6); 5079 ierr = (ts->ops->snesjacobian)(snes,U,A,B,ts);CHKERRQ(ierr); 5080 PetscFunctionReturn(0); 5081 } 5082 5083 /*@C 5084 TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems Udot = A U only 5085 5086 Collective on TS 5087 5088 Input Arguments: 5089 + ts - time stepping context 5090 . t - time at which to evaluate 5091 . U - state at which to evaluate 5092 - ctx - context 5093 5094 Output Arguments: 5095 . F - right hand side 5096 5097 Level: intermediate 5098 5099 Notes: 5100 This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems. 5101 The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian(). 5102 5103 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 5104 @*/ 5105 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx) 5106 { 5107 PetscErrorCode ierr; 5108 Mat Arhs,Brhs; 5109 5110 PetscFunctionBegin; 5111 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 5112 ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr); 5113 ierr = MatMult(Arhs,U,F);CHKERRQ(ierr); 5114 PetscFunctionReturn(0); 5115 } 5116 5117 /*@C 5118 TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent. 5119 5120 Collective on TS 5121 5122 Input Arguments: 5123 + ts - time stepping context 5124 . t - time at which to evaluate 5125 . U - state at which to evaluate 5126 - ctx - context 5127 5128 Output Arguments: 5129 + A - pointer to operator 5130 . B - pointer to preconditioning matrix 5131 - flg - matrix structure flag 5132 5133 Level: intermediate 5134 5135 Notes: 5136 This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems. 5137 5138 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear() 5139 @*/ 5140 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx) 5141 { 5142 PetscFunctionBegin; 5143 PetscFunctionReturn(0); 5144 } 5145 5146 /*@C 5147 TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only 5148 5149 Collective on TS 5150 5151 Input Arguments: 5152 + ts - time stepping context 5153 . t - time at which to evaluate 5154 . U - state at which to evaluate 5155 . Udot - time derivative of state vector 5156 - ctx - context 5157 5158 Output Arguments: 5159 . F - left hand side 5160 5161 Level: intermediate 5162 5163 Notes: 5164 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 5165 user is required to write their own TSComputeIFunction. 5166 This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems. 5167 The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian(). 5168 5169 Note that using this function is NOT equivalent to using TSComputeRHSFunctionLinear() since that solves Udot = A U 5170 5171 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant(), TSComputeRHSFunctionLinear() 5172 @*/ 5173 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx) 5174 { 5175 PetscErrorCode ierr; 5176 Mat A,B; 5177 5178 PetscFunctionBegin; 5179 ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr); 5180 ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE);CHKERRQ(ierr); 5181 ierr = MatMult(A,Udot,F);CHKERRQ(ierr); 5182 PetscFunctionReturn(0); 5183 } 5184 5185 /*@C 5186 TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE 5187 5188 Collective on TS 5189 5190 Input Arguments: 5191 + ts - time stepping context 5192 . t - time at which to evaluate 5193 . U - state at which to evaluate 5194 . Udot - time derivative of state vector 5195 . shift - shift to apply 5196 - ctx - context 5197 5198 Output Arguments: 5199 + A - pointer to operator 5200 . B - pointer to preconditioning matrix 5201 - flg - matrix structure flag 5202 5203 Level: advanced 5204 5205 Notes: 5206 This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems. 5207 5208 It is only appropriate for problems of the form 5209 5210 $ M Udot = F(U,t) 5211 5212 where M is constant and F is non-stiff. The user must pass M to TSSetIJacobian(). The current implementation only 5213 works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing 5214 an implicit operator of the form 5215 5216 $ shift*M + J 5217 5218 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 5219 a copy of M or reassemble it when requested. 5220 5221 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear() 5222 @*/ 5223 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx) 5224 { 5225 PetscErrorCode ierr; 5226 5227 PetscFunctionBegin; 5228 ierr = MatScale(A, shift / ts->ijacobian.shift);CHKERRQ(ierr); 5229 ts->ijacobian.shift = shift; 5230 PetscFunctionReturn(0); 5231 } 5232 5233 /*@ 5234 TSGetEquationType - Gets the type of the equation that TS is solving. 5235 5236 Not Collective 5237 5238 Input Parameter: 5239 . ts - the TS context 5240 5241 Output Parameter: 5242 . equation_type - see TSEquationType 5243 5244 Level: beginner 5245 5246 .keywords: TS, equation type 5247 5248 .seealso: TSSetEquationType(), TSEquationType 5249 @*/ 5250 PetscErrorCode TSGetEquationType(TS ts,TSEquationType *equation_type) 5251 { 5252 PetscFunctionBegin; 5253 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5254 PetscValidPointer(equation_type,2); 5255 *equation_type = ts->equation_type; 5256 PetscFunctionReturn(0); 5257 } 5258 5259 /*@ 5260 TSSetEquationType - Sets the type of the equation that TS is solving. 5261 5262 Not Collective 5263 5264 Input Parameter: 5265 + ts - the TS context 5266 - equation_type - see TSEquationType 5267 5268 Level: advanced 5269 5270 .keywords: TS, equation type 5271 5272 .seealso: TSGetEquationType(), TSEquationType 5273 @*/ 5274 PetscErrorCode TSSetEquationType(TS ts,TSEquationType equation_type) 5275 { 5276 PetscFunctionBegin; 5277 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5278 ts->equation_type = equation_type; 5279 PetscFunctionReturn(0); 5280 } 5281 5282 /*@ 5283 TSGetConvergedReason - Gets the reason the TS iteration was stopped. 5284 5285 Not Collective 5286 5287 Input Parameter: 5288 . ts - the TS context 5289 5290 Output Parameter: 5291 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 5292 manual pages for the individual convergence tests for complete lists 5293 5294 Level: beginner 5295 5296 Notes: 5297 Can only be called after the call to TSSolve() is complete. 5298 5299 .keywords: TS, nonlinear, set, convergence, test 5300 5301 .seealso: TSSetConvergenceTest(), TSConvergedReason 5302 @*/ 5303 PetscErrorCode TSGetConvergedReason(TS ts,TSConvergedReason *reason) 5304 { 5305 PetscFunctionBegin; 5306 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5307 PetscValidPointer(reason,2); 5308 *reason = ts->reason; 5309 PetscFunctionReturn(0); 5310 } 5311 5312 /*@ 5313 TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve. 5314 5315 Not Collective 5316 5317 Input Parameter: 5318 + ts - the TS context 5319 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 5320 manual pages for the individual convergence tests for complete lists 5321 5322 Level: advanced 5323 5324 Notes: 5325 Can only be called during TSSolve() is active. 5326 5327 .keywords: TS, nonlinear, set, convergence, test 5328 5329 .seealso: TSConvergedReason 5330 @*/ 5331 PetscErrorCode TSSetConvergedReason(TS ts,TSConvergedReason reason) 5332 { 5333 PetscFunctionBegin; 5334 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5335 ts->reason = reason; 5336 PetscFunctionReturn(0); 5337 } 5338 5339 /*@ 5340 TSGetSolveTime - Gets the time after a call to TSSolve() 5341 5342 Not Collective 5343 5344 Input Parameter: 5345 . ts - the TS context 5346 5347 Output Parameter: 5348 . ftime - the final time. This time corresponds to the final time set with TSSetDuration() 5349 5350 Level: beginner 5351 5352 Notes: 5353 Can only be called after the call to TSSolve() is complete. 5354 5355 .keywords: TS, nonlinear, set, convergence, test 5356 5357 .seealso: TSSetConvergenceTest(), TSConvergedReason 5358 @*/ 5359 PetscErrorCode TSGetSolveTime(TS ts,PetscReal *ftime) 5360 { 5361 PetscFunctionBegin; 5362 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5363 PetscValidPointer(ftime,2); 5364 *ftime = ts->solvetime; 5365 PetscFunctionReturn(0); 5366 } 5367 5368 /*@ 5369 TSGetTotalSteps - Gets the total number of steps done since the last call to TSSetUp() or TSCreate() 5370 5371 Not Collective 5372 5373 Input Parameter: 5374 . ts - the TS context 5375 5376 Output Parameter: 5377 . steps - the number of steps 5378 5379 Level: beginner 5380 5381 Notes: 5382 Includes the number of steps for all calls to TSSolve() since TSSetUp() was called 5383 5384 .keywords: TS, nonlinear, set, convergence, test 5385 5386 .seealso: TSSetConvergenceTest(), TSConvergedReason 5387 @*/ 5388 PetscErrorCode TSGetTotalSteps(TS ts,PetscInt *steps) 5389 { 5390 PetscFunctionBegin; 5391 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5392 PetscValidPointer(steps,2); 5393 *steps = ts->total_steps; 5394 PetscFunctionReturn(0); 5395 } 5396 5397 /*@ 5398 TSGetSNESIterations - Gets the total number of nonlinear iterations 5399 used by the time integrator. 5400 5401 Not Collective 5402 5403 Input Parameter: 5404 . ts - TS context 5405 5406 Output Parameter: 5407 . nits - number of nonlinear iterations 5408 5409 Notes: 5410 This counter is reset to zero for each successive call to TSSolve(). 5411 5412 Level: intermediate 5413 5414 .keywords: TS, get, number, nonlinear, iterations 5415 5416 .seealso: TSGetKSPIterations() 5417 @*/ 5418 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits) 5419 { 5420 PetscFunctionBegin; 5421 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5422 PetscValidIntPointer(nits,2); 5423 *nits = ts->snes_its; 5424 PetscFunctionReturn(0); 5425 } 5426 5427 /*@ 5428 TSGetKSPIterations - Gets the total number of linear iterations 5429 used by the time integrator. 5430 5431 Not Collective 5432 5433 Input Parameter: 5434 . ts - TS context 5435 5436 Output Parameter: 5437 . lits - number of linear iterations 5438 5439 Notes: 5440 This counter is reset to zero for each successive call to TSSolve(). 5441 5442 Level: intermediate 5443 5444 .keywords: TS, get, number, linear, iterations 5445 5446 .seealso: TSGetSNESIterations(), SNESGetKSPIterations() 5447 @*/ 5448 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits) 5449 { 5450 PetscFunctionBegin; 5451 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5452 PetscValidIntPointer(lits,2); 5453 *lits = ts->ksp_its; 5454 PetscFunctionReturn(0); 5455 } 5456 5457 /*@ 5458 TSGetStepRejections - Gets the total number of rejected steps. 5459 5460 Not Collective 5461 5462 Input Parameter: 5463 . ts - TS context 5464 5465 Output Parameter: 5466 . rejects - number of steps rejected 5467 5468 Notes: 5469 This counter is reset to zero for each successive call to TSSolve(). 5470 5471 Level: intermediate 5472 5473 .keywords: TS, get, number 5474 5475 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails() 5476 @*/ 5477 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects) 5478 { 5479 PetscFunctionBegin; 5480 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5481 PetscValidIntPointer(rejects,2); 5482 *rejects = ts->reject; 5483 PetscFunctionReturn(0); 5484 } 5485 5486 /*@ 5487 TSGetSNESFailures - Gets the total number of failed SNES solves 5488 5489 Not Collective 5490 5491 Input Parameter: 5492 . ts - TS context 5493 5494 Output Parameter: 5495 . fails - number of failed nonlinear solves 5496 5497 Notes: 5498 This counter is reset to zero for each successive call to TSSolve(). 5499 5500 Level: intermediate 5501 5502 .keywords: TS, get, number 5503 5504 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures() 5505 @*/ 5506 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails) 5507 { 5508 PetscFunctionBegin; 5509 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5510 PetscValidIntPointer(fails,2); 5511 *fails = ts->num_snes_failures; 5512 PetscFunctionReturn(0); 5513 } 5514 5515 /*@ 5516 TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails 5517 5518 Not Collective 5519 5520 Input Parameter: 5521 + ts - TS context 5522 - rejects - maximum number of rejected steps, pass -1 for unlimited 5523 5524 Notes: 5525 The counter is reset to zero for each step 5526 5527 Options Database Key: 5528 . -ts_max_reject - Maximum number of step rejections before a step fails 5529 5530 Level: intermediate 5531 5532 .keywords: TS, set, maximum, number 5533 5534 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 5535 @*/ 5536 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects) 5537 { 5538 PetscFunctionBegin; 5539 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5540 ts->max_reject = rejects; 5541 PetscFunctionReturn(0); 5542 } 5543 5544 /*@ 5545 TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves 5546 5547 Not Collective 5548 5549 Input Parameter: 5550 + ts - TS context 5551 - fails - maximum number of failed nonlinear solves, pass -1 for unlimited 5552 5553 Notes: 5554 The counter is reset to zero for each successive call to TSSolve(). 5555 5556 Options Database Key: 5557 . -ts_max_snes_failures - Maximum number of nonlinear solve failures 5558 5559 Level: intermediate 5560 5561 .keywords: TS, set, maximum, number 5562 5563 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason() 5564 @*/ 5565 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails) 5566 { 5567 PetscFunctionBegin; 5568 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5569 ts->max_snes_failures = fails; 5570 PetscFunctionReturn(0); 5571 } 5572 5573 /*@ 5574 TSSetErrorIfStepFails - Error if no step succeeds 5575 5576 Not Collective 5577 5578 Input Parameter: 5579 + ts - TS context 5580 - err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure 5581 5582 Options Database Key: 5583 . -ts_error_if_step_fails - Error if no step succeeds 5584 5585 Level: intermediate 5586 5587 .keywords: TS, set, error 5588 5589 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 5590 @*/ 5591 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err) 5592 { 5593 PetscFunctionBegin; 5594 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5595 ts->errorifstepfailed = err; 5596 PetscFunctionReturn(0); 5597 } 5598 5599 /*@C 5600 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 5601 5602 Collective on TS 5603 5604 Input Parameters: 5605 + ts - the TS context 5606 . step - current time-step 5607 . ptime - current time 5608 . u - current state 5609 - vf - viewer and its format 5610 5611 Level: intermediate 5612 5613 .keywords: TS, vector, monitor, view 5614 5615 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5616 @*/ 5617 PetscErrorCode TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf) 5618 { 5619 PetscErrorCode ierr; 5620 5621 PetscFunctionBegin; 5622 ierr = PetscViewerPushFormat(vf->viewer,vf->format);CHKERRQ(ierr); 5623 ierr = VecView(u,vf->viewer);CHKERRQ(ierr); 5624 ierr = PetscViewerPopFormat(vf->viewer);CHKERRQ(ierr); 5625 PetscFunctionReturn(0); 5626 } 5627 5628 /*@C 5629 TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep. 5630 5631 Collective on TS 5632 5633 Input Parameters: 5634 + ts - the TS context 5635 . step - current time-step 5636 . ptime - current time 5637 . u - current state 5638 - filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 5639 5640 Level: intermediate 5641 5642 Notes: 5643 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. 5644 These are named according to the file name template. 5645 5646 This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy(). 5647 5648 .keywords: TS, vector, monitor, view 5649 5650 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5651 @*/ 5652 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate) 5653 { 5654 PetscErrorCode ierr; 5655 char filename[PETSC_MAX_PATH_LEN]; 5656 PetscViewer viewer; 5657 5658 PetscFunctionBegin; 5659 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 5660 ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr); 5661 ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); 5662 ierr = VecView(u,viewer);CHKERRQ(ierr); 5663 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 5664 PetscFunctionReturn(0); 5665 } 5666 5667 /*@C 5668 TSMonitorSolutionVTKDestroy - Destroy context for monitoring 5669 5670 Collective on TS 5671 5672 Input Parameters: 5673 . filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 5674 5675 Level: intermediate 5676 5677 Note: 5678 This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK(). 5679 5680 .keywords: TS, vector, monitor, view 5681 5682 .seealso: TSMonitorSet(), TSMonitorSolutionVTK() 5683 @*/ 5684 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate) 5685 { 5686 PetscErrorCode ierr; 5687 5688 PetscFunctionBegin; 5689 ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr); 5690 PetscFunctionReturn(0); 5691 } 5692 5693 /*@ 5694 TSGetAdapt - Get the adaptive controller context for the current method 5695 5696 Collective on TS if controller has not been created yet 5697 5698 Input Arguments: 5699 . ts - time stepping context 5700 5701 Output Arguments: 5702 . adapt - adaptive controller 5703 5704 Level: intermediate 5705 5706 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose() 5707 @*/ 5708 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt) 5709 { 5710 PetscErrorCode ierr; 5711 5712 PetscFunctionBegin; 5713 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5714 PetscValidPointer(adapt,2); 5715 if (!ts->adapt) { 5716 ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr); 5717 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr); 5718 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr); 5719 } 5720 *adapt = ts->adapt; 5721 PetscFunctionReturn(0); 5722 } 5723 5724 /*@ 5725 TSSetTolerances - Set tolerances for local truncation error when using adaptive controller 5726 5727 Logically Collective 5728 5729 Input Arguments: 5730 + ts - time integration context 5731 . atol - scalar absolute tolerances, PETSC_DECIDE to leave current value 5732 . vatol - vector of absolute tolerances or NULL, used in preference to atol if present 5733 . rtol - scalar relative tolerances, PETSC_DECIDE to leave current value 5734 - vrtol - vector of relative tolerances or NULL, used in preference to atol if present 5735 5736 Options Database keys: 5737 + -ts_rtol <rtol> - relative tolerance for local truncation error 5738 - -ts_atol <atol> Absolute tolerance for local truncation error 5739 5740 Notes: 5741 With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error 5742 (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be 5743 computed only for the differential or the algebraic part then this can be done using the vector of 5744 tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the 5745 differential part and infinity for the algebraic part, the LTE calculation will include only the 5746 differential variables. 5747 5748 Level: beginner 5749 5750 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances() 5751 @*/ 5752 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol) 5753 { 5754 PetscErrorCode ierr; 5755 5756 PetscFunctionBegin; 5757 if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol; 5758 if (vatol) { 5759 ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr); 5760 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 5761 ts->vatol = vatol; 5762 } 5763 if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol; 5764 if (vrtol) { 5765 ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr); 5766 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 5767 ts->vrtol = vrtol; 5768 } 5769 PetscFunctionReturn(0); 5770 } 5771 5772 /*@ 5773 TSGetTolerances - Get tolerances for local truncation error when using adaptive controller 5774 5775 Logically Collective 5776 5777 Input Arguments: 5778 . ts - time integration context 5779 5780 Output Arguments: 5781 + atol - scalar absolute tolerances, NULL to ignore 5782 . vatol - vector of absolute tolerances, NULL to ignore 5783 . rtol - scalar relative tolerances, NULL to ignore 5784 - vrtol - vector of relative tolerances, NULL to ignore 5785 5786 Level: beginner 5787 5788 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances() 5789 @*/ 5790 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol) 5791 { 5792 PetscFunctionBegin; 5793 if (atol) *atol = ts->atol; 5794 if (vatol) *vatol = ts->vatol; 5795 if (rtol) *rtol = ts->rtol; 5796 if (vrtol) *vrtol = ts->vrtol; 5797 PetscFunctionReturn(0); 5798 } 5799 5800 /*@ 5801 TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors 5802 5803 Collective on TS 5804 5805 Input Arguments: 5806 + ts - time stepping context 5807 . U - state vector, usually ts->vec_sol 5808 - Y - state vector to be compared to U 5809 5810 Output Arguments: 5811 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5812 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5813 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5814 5815 Level: developer 5816 5817 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNormInfinity() 5818 @*/ 5819 PetscErrorCode TSErrorWeightedNorm2(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5820 { 5821 PetscErrorCode ierr; 5822 PetscInt i,n,N,rstart; 5823 PetscInt n_loc,na_loc,nr_loc; 5824 PetscReal n_glb,na_glb,nr_glb; 5825 const PetscScalar *u,*y; 5826 PetscReal sum,suma,sumr,gsum,gsuma,gsumr,diff; 5827 PetscReal tol,tola,tolr; 5828 PetscReal err_loc[6],err_glb[6]; 5829 5830 PetscFunctionBegin; 5831 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5832 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5833 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 5834 PetscValidType(U,2); 5835 PetscValidType(Y,3); 5836 PetscCheckSameComm(U,2,Y,3); 5837 PetscValidPointer(norm,4); 5838 PetscValidPointer(norma,5); 5839 PetscValidPointer(normr,6); 5840 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 5841 5842 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 5843 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 5844 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 5845 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5846 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5847 sum = 0.; n_loc = 0; 5848 suma = 0.; na_loc = 0; 5849 sumr = 0.; nr_loc = 0; 5850 if (ts->vatol && ts->vrtol) { 5851 const PetscScalar *atol,*rtol; 5852 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5853 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5854 for (i=0; i<n; i++) { 5855 diff = PetscAbsScalar(y[i] - u[i]); 5856 tola = PetscRealPart(atol[i]); 5857 if(tola>0.){ 5858 suma += PetscSqr(diff/tola); 5859 na_loc++; 5860 } 5861 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5862 if(tolr>0.){ 5863 sumr += PetscSqr(diff/tolr); 5864 nr_loc++; 5865 } 5866 tol=tola+tolr; 5867 if(tol>0.){ 5868 sum += PetscSqr(diff/tol); 5869 n_loc++; 5870 } 5871 } 5872 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5873 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5874 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5875 const PetscScalar *atol; 5876 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5877 for (i=0; i<n; i++) { 5878 diff = PetscAbsScalar(y[i] - u[i]); 5879 tola = PetscRealPart(atol[i]); 5880 if(tola>0.){ 5881 suma += PetscSqr(diff/tola); 5882 na_loc++; 5883 } 5884 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5885 if(tolr>0.){ 5886 sumr += PetscSqr(diff/tolr); 5887 nr_loc++; 5888 } 5889 tol=tola+tolr; 5890 if(tol>0.){ 5891 sum += PetscSqr(diff/tol); 5892 n_loc++; 5893 } 5894 } 5895 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5896 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5897 const PetscScalar *rtol; 5898 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5899 for (i=0; i<n; i++) { 5900 diff = PetscAbsScalar(y[i] - u[i]); 5901 tola = ts->atol; 5902 if(tola>0.){ 5903 suma += PetscSqr(diff/tola); 5904 na_loc++; 5905 } 5906 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5907 if(tolr>0.){ 5908 sumr += PetscSqr(diff/tolr); 5909 nr_loc++; 5910 } 5911 tol=tola+tolr; 5912 if(tol>0.){ 5913 sum += PetscSqr(diff/tol); 5914 n_loc++; 5915 } 5916 } 5917 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5918 } else { /* scalar atol, scalar rtol */ 5919 for (i=0; i<n; i++) { 5920 diff = PetscAbsScalar(y[i] - u[i]); 5921 tola = ts->atol; 5922 if(tola>0.){ 5923 suma += PetscSqr(diff/tola); 5924 na_loc++; 5925 } 5926 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5927 if(tolr>0.){ 5928 sumr += PetscSqr(diff/tolr); 5929 nr_loc++; 5930 } 5931 tol=tola+tolr; 5932 if(tol>0.){ 5933 sum += PetscSqr(diff/tol); 5934 n_loc++; 5935 } 5936 } 5937 } 5938 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5939 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5940 5941 err_loc[0] = sum; 5942 err_loc[1] = suma; 5943 err_loc[2] = sumr; 5944 err_loc[3] = (PetscReal)n_loc; 5945 err_loc[4] = (PetscReal)na_loc; 5946 err_loc[5] = (PetscReal)nr_loc; 5947 5948 ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 5949 5950 gsum = err_glb[0]; 5951 gsuma = err_glb[1]; 5952 gsumr = err_glb[2]; 5953 n_glb = err_glb[3]; 5954 na_glb = err_glb[4]; 5955 nr_glb = err_glb[5]; 5956 5957 *norm = 0.; 5958 if(n_glb>0. ){*norm = PetscSqrtReal(gsum / n_glb );} 5959 *norma = 0.; 5960 if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);} 5961 *normr = 0.; 5962 if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);} 5963 5964 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5965 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 5966 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 5967 PetscFunctionReturn(0); 5968 } 5969 5970 /*@ 5971 TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors 5972 5973 Collective on TS 5974 5975 Input Arguments: 5976 + ts - time stepping context 5977 . U - state vector, usually ts->vec_sol 5978 - Y - state vector to be compared to U 5979 5980 Output Arguments: 5981 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5982 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5983 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5984 5985 Level: developer 5986 5987 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNorm2() 5988 @*/ 5989 PetscErrorCode TSErrorWeightedNormInfinity(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5990 { 5991 PetscErrorCode ierr; 5992 PetscInt i,n,N,rstart; 5993 const PetscScalar *u,*y; 5994 PetscReal max,gmax,maxa,gmaxa,maxr,gmaxr; 5995 PetscReal tol,tola,tolr,diff; 5996 PetscReal err_loc[3],err_glb[3]; 5997 5998 PetscFunctionBegin; 5999 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6000 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 6001 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 6002 PetscValidType(U,2); 6003 PetscValidType(Y,3); 6004 PetscCheckSameComm(U,2,Y,3); 6005 PetscValidPointer(norm,4); 6006 PetscValidPointer(norma,5); 6007 PetscValidPointer(normr,6); 6008 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 6009 6010 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 6011 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 6012 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 6013 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 6014 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 6015 6016 max=0.; 6017 maxa=0.; 6018 maxr=0.; 6019 6020 if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */ 6021 const PetscScalar *atol,*rtol; 6022 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6023 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6024 6025 for (i=0; i<n; i++) { 6026 diff = PetscAbsScalar(y[i] - u[i]); 6027 tola = PetscRealPart(atol[i]); 6028 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6029 tol = tola+tolr; 6030 if(tola>0.){ 6031 maxa = PetscMax(maxa,diff / tola); 6032 } 6033 if(tolr>0.){ 6034 maxr = PetscMax(maxr,diff / tolr); 6035 } 6036 if(tol>0.){ 6037 max = PetscMax(max,diff / tol); 6038 } 6039 } 6040 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6041 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6042 } else if (ts->vatol) { /* vector atol, scalar rtol */ 6043 const PetscScalar *atol; 6044 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6045 for (i=0; i<n; i++) { 6046 diff = PetscAbsScalar(y[i] - u[i]); 6047 tola = PetscRealPart(atol[i]); 6048 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6049 tol = tola+tolr; 6050 if(tola>0.){ 6051 maxa = PetscMax(maxa,diff / tola); 6052 } 6053 if(tolr>0.){ 6054 maxr = PetscMax(maxr,diff / tolr); 6055 } 6056 if(tol>0.){ 6057 max = PetscMax(max,diff / tol); 6058 } 6059 } 6060 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6061 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 6062 const PetscScalar *rtol; 6063 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6064 6065 for (i=0; i<n; i++) { 6066 diff = PetscAbsScalar(y[i] - u[i]); 6067 tola = ts->atol; 6068 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6069 tol = tola+tolr; 6070 if(tola>0.){ 6071 maxa = PetscMax(maxa,diff / tola); 6072 } 6073 if(tolr>0.){ 6074 maxr = PetscMax(maxr,diff / tolr); 6075 } 6076 if(tol>0.){ 6077 max = PetscMax(max,diff / tol); 6078 } 6079 } 6080 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6081 } else { /* scalar atol, scalar rtol */ 6082 6083 for (i=0; i<n; i++) { 6084 diff = PetscAbsScalar(y[i] - u[i]); 6085 tola = ts->atol; 6086 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6087 tol = tola+tolr; 6088 if(tola>0.){ 6089 maxa = PetscMax(maxa,diff / tola); 6090 } 6091 if(tolr>0.){ 6092 maxr = PetscMax(maxr,diff / tolr); 6093 } 6094 if(tol>0.){ 6095 max = PetscMax(max,diff / tol); 6096 } 6097 } 6098 } 6099 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 6100 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 6101 err_loc[0] = max; 6102 err_loc[1] = maxa; 6103 err_loc[2] = maxr; 6104 ierr = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6105 gmax = err_glb[0]; 6106 gmaxa = err_glb[1]; 6107 gmaxr = err_glb[2]; 6108 6109 *norm = gmax; 6110 *norma = gmaxa; 6111 *normr = gmaxr; 6112 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6113 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 6114 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 6115 PetscFunctionReturn(0); 6116 } 6117 6118 /*@ 6119 TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors based on supplied absolute and relative tolerances 6120 6121 Collective on TS 6122 6123 Input Arguments: 6124 + ts - time stepping context 6125 . U - state vector, usually ts->vec_sol 6126 . Y - state vector to be compared to U 6127 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 6128 6129 Output Arguments: 6130 . norm - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances 6131 . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user 6132 . normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user 6133 6134 Options Database Keys: 6135 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 6136 6137 Level: developer 6138 6139 .seealso: TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2(), TSErrorWeightedENorm 6140 @*/ 6141 PetscErrorCode TSErrorWeightedNorm(TS ts,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6142 { 6143 PetscErrorCode ierr; 6144 6145 PetscFunctionBegin; 6146 if (wnormtype == NORM_2) { 6147 ierr = TSErrorWeightedNorm2(ts,U,Y,norm,norma,normr);CHKERRQ(ierr); 6148 } else if(wnormtype == NORM_INFINITY) { 6149 ierr = TSErrorWeightedNormInfinity(ts,U,Y,norm,norma,normr);CHKERRQ(ierr); 6150 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 6151 PetscFunctionReturn(0); 6152 } 6153 6154 6155 /*@ 6156 TSErrorWeightedENorm2 - compute a weighted 2 error norm based on supplied absolute and relative tolerances 6157 6158 Collective on TS 6159 6160 Input Arguments: 6161 + ts - time stepping context 6162 . E - error vector 6163 . U - state vector, usually ts->vec_sol 6164 - Y - state vector, previous time step 6165 6166 Output Arguments: 6167 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 6168 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 6169 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 6170 6171 Level: developer 6172 6173 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENormInfinity() 6174 @*/ 6175 PetscErrorCode TSErrorWeightedENorm2(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6176 { 6177 PetscErrorCode ierr; 6178 PetscInt i,n,N,rstart; 6179 PetscInt n_loc,na_loc,nr_loc; 6180 PetscReal n_glb,na_glb,nr_glb; 6181 const PetscScalar *e,*u,*y; 6182 PetscReal err,sum,suma,sumr,gsum,gsuma,gsumr; 6183 PetscReal tol,tola,tolr; 6184 PetscReal err_loc[6],err_glb[6]; 6185 6186 PetscFunctionBegin; 6187 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6188 PetscValidHeaderSpecific(E,VEC_CLASSID,2); 6189 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 6190 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 6191 PetscValidType(E,2); 6192 PetscValidType(U,3); 6193 PetscValidType(Y,4); 6194 PetscCheckSameComm(E,2,U,3); 6195 PetscCheckSameComm(U,2,Y,3); 6196 PetscValidPointer(norm,5); 6197 PetscValidPointer(norma,6); 6198 PetscValidPointer(normr,7); 6199 6200 ierr = VecGetSize(E,&N);CHKERRQ(ierr); 6201 ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr); 6202 ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr); 6203 ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr); 6204 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 6205 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 6206 sum = 0.; n_loc = 0; 6207 suma = 0.; na_loc = 0; 6208 sumr = 0.; nr_loc = 0; 6209 if (ts->vatol && ts->vrtol) { 6210 const PetscScalar *atol,*rtol; 6211 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6212 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6213 for (i=0; i<n; i++) { 6214 err = PetscAbsScalar(e[i]); 6215 tola = PetscRealPart(atol[i]); 6216 if(tola>0.){ 6217 suma += PetscSqr(err/tola); 6218 na_loc++; 6219 } 6220 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6221 if(tolr>0.){ 6222 sumr += PetscSqr(err/tolr); 6223 nr_loc++; 6224 } 6225 tol=tola+tolr; 6226 if(tol>0.){ 6227 sum += PetscSqr(err/tol); 6228 n_loc++; 6229 } 6230 } 6231 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6232 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6233 } else if (ts->vatol) { /* vector atol, scalar rtol */ 6234 const PetscScalar *atol; 6235 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6236 for (i=0; i<n; i++) { 6237 err = PetscAbsScalar(e[i]); 6238 tola = PetscRealPart(atol[i]); 6239 if(tola>0.){ 6240 suma += PetscSqr(err/tola); 6241 na_loc++; 6242 } 6243 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6244 if(tolr>0.){ 6245 sumr += PetscSqr(err/tolr); 6246 nr_loc++; 6247 } 6248 tol=tola+tolr; 6249 if(tol>0.){ 6250 sum += PetscSqr(err/tol); 6251 n_loc++; 6252 } 6253 } 6254 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6255 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 6256 const PetscScalar *rtol; 6257 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6258 for (i=0; i<n; i++) { 6259 err = PetscAbsScalar(e[i]); 6260 tola = ts->atol; 6261 if(tola>0.){ 6262 suma += PetscSqr(err/tola); 6263 na_loc++; 6264 } 6265 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6266 if(tolr>0.){ 6267 sumr += PetscSqr(err/tolr); 6268 nr_loc++; 6269 } 6270 tol=tola+tolr; 6271 if(tol>0.){ 6272 sum += PetscSqr(err/tol); 6273 n_loc++; 6274 } 6275 } 6276 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6277 } else { /* scalar atol, scalar rtol */ 6278 for (i=0; i<n; i++) { 6279 err = PetscAbsScalar(e[i]); 6280 tola = ts->atol; 6281 if(tola>0.){ 6282 suma += PetscSqr(err/tola); 6283 na_loc++; 6284 } 6285 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6286 if(tolr>0.){ 6287 sumr += PetscSqr(err/tolr); 6288 nr_loc++; 6289 } 6290 tol=tola+tolr; 6291 if(tol>0.){ 6292 sum += PetscSqr(err/tol); 6293 n_loc++; 6294 } 6295 } 6296 } 6297 ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr); 6298 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 6299 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 6300 6301 err_loc[0] = sum; 6302 err_loc[1] = suma; 6303 err_loc[2] = sumr; 6304 err_loc[3] = (PetscReal)n_loc; 6305 err_loc[4] = (PetscReal)na_loc; 6306 err_loc[5] = (PetscReal)nr_loc; 6307 6308 ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6309 6310 gsum = err_glb[0]; 6311 gsuma = err_glb[1]; 6312 gsumr = err_glb[2]; 6313 n_glb = err_glb[3]; 6314 na_glb = err_glb[4]; 6315 nr_glb = err_glb[5]; 6316 6317 *norm = 0.; 6318 if(n_glb>0. ){*norm = PetscSqrtReal(gsum / n_glb );} 6319 *norma = 0.; 6320 if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);} 6321 *normr = 0.; 6322 if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);} 6323 6324 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6325 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 6326 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 6327 PetscFunctionReturn(0); 6328 } 6329 6330 /*@ 6331 TSErrorWeightedENormInfinity - compute a weighted infinity error norm based on supplied absolute and relative tolerances 6332 Collective on TS 6333 6334 Input Arguments: 6335 + ts - time stepping context 6336 . E - error vector 6337 . U - state vector, usually ts->vec_sol 6338 - Y - state vector, previous time step 6339 6340 Output Arguments: 6341 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 6342 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 6343 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 6344 6345 Level: developer 6346 6347 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENorm2() 6348 @*/ 6349 PetscErrorCode TSErrorWeightedENormInfinity(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6350 { 6351 PetscErrorCode ierr; 6352 PetscInt i,n,N,rstart; 6353 const PetscScalar *e,*u,*y; 6354 PetscReal err,max,gmax,maxa,gmaxa,maxr,gmaxr; 6355 PetscReal tol,tola,tolr; 6356 PetscReal err_loc[3],err_glb[3]; 6357 6358 PetscFunctionBegin; 6359 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6360 PetscValidHeaderSpecific(E,VEC_CLASSID,2); 6361 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 6362 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 6363 PetscValidType(E,2); 6364 PetscValidType(U,3); 6365 PetscValidType(Y,4); 6366 PetscCheckSameComm(E,2,U,3); 6367 PetscCheckSameComm(U,2,Y,3); 6368 PetscValidPointer(norm,5); 6369 PetscValidPointer(norma,6); 6370 PetscValidPointer(normr,7); 6371 6372 ierr = VecGetSize(E,&N);CHKERRQ(ierr); 6373 ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr); 6374 ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr); 6375 ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr); 6376 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 6377 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 6378 6379 max=0.; 6380 maxa=0.; 6381 maxr=0.; 6382 6383 if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */ 6384 const PetscScalar *atol,*rtol; 6385 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6386 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6387 6388 for (i=0; i<n; i++) { 6389 err = PetscAbsScalar(e[i]); 6390 tola = PetscRealPart(atol[i]); 6391 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6392 tol = tola+tolr; 6393 if(tola>0.){ 6394 maxa = PetscMax(maxa,err / tola); 6395 } 6396 if(tolr>0.){ 6397 maxr = PetscMax(maxr,err / tolr); 6398 } 6399 if(tol>0.){ 6400 max = PetscMax(max,err / tol); 6401 } 6402 } 6403 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6404 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6405 } else if (ts->vatol) { /* vector atol, scalar rtol */ 6406 const PetscScalar *atol; 6407 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6408 for (i=0; i<n; i++) { 6409 err = PetscAbsScalar(e[i]); 6410 tola = PetscRealPart(atol[i]); 6411 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6412 tol = tola+tolr; 6413 if(tola>0.){ 6414 maxa = PetscMax(maxa,err / tola); 6415 } 6416 if(tolr>0.){ 6417 maxr = PetscMax(maxr,err / tolr); 6418 } 6419 if(tol>0.){ 6420 max = PetscMax(max,err / tol); 6421 } 6422 } 6423 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6424 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 6425 const PetscScalar *rtol; 6426 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6427 6428 for (i=0; i<n; i++) { 6429 err = PetscAbsScalar(e[i]); 6430 tola = ts->atol; 6431 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6432 tol = tola+tolr; 6433 if(tola>0.){ 6434 maxa = PetscMax(maxa,err / tola); 6435 } 6436 if(tolr>0.){ 6437 maxr = PetscMax(maxr,err / tolr); 6438 } 6439 if(tol>0.){ 6440 max = PetscMax(max,err / tol); 6441 } 6442 } 6443 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6444 } else { /* scalar atol, scalar rtol */ 6445 6446 for (i=0; i<n; i++) { 6447 err = PetscAbsScalar(e[i]); 6448 tola = ts->atol; 6449 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6450 tol = tola+tolr; 6451 if(tola>0.){ 6452 maxa = PetscMax(maxa,err / tola); 6453 } 6454 if(tolr>0.){ 6455 maxr = PetscMax(maxr,err / tolr); 6456 } 6457 if(tol>0.){ 6458 max = PetscMax(max,err / tol); 6459 } 6460 } 6461 } 6462 ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr); 6463 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 6464 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 6465 err_loc[0] = max; 6466 err_loc[1] = maxa; 6467 err_loc[2] = maxr; 6468 ierr = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6469 gmax = err_glb[0]; 6470 gmaxa = err_glb[1]; 6471 gmaxr = err_glb[2]; 6472 6473 *norm = gmax; 6474 *norma = gmaxa; 6475 *normr = gmaxr; 6476 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6477 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 6478 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 6479 PetscFunctionReturn(0); 6480 } 6481 6482 /*@ 6483 TSErrorWeightedENorm - compute a weighted error norm based on supplied absolute and relative tolerances 6484 6485 Collective on TS 6486 6487 Input Arguments: 6488 + ts - time stepping context 6489 . E - error vector 6490 . U - state vector, usually ts->vec_sol 6491 . Y - state vector, previous time step 6492 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 6493 6494 Output Arguments: 6495 . norm - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances 6496 . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user 6497 . normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user 6498 6499 Options Database Keys: 6500 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 6501 6502 Level: developer 6503 6504 .seealso: TSErrorWeightedENormInfinity(), TSErrorWeightedENorm2(), TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2() 6505 @*/ 6506 PetscErrorCode TSErrorWeightedENorm(TS ts,Vec E,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6507 { 6508 PetscErrorCode ierr; 6509 6510 PetscFunctionBegin; 6511 if (wnormtype == NORM_2) { 6512 ierr = TSErrorWeightedENorm2(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr); 6513 } else if(wnormtype == NORM_INFINITY) { 6514 ierr = TSErrorWeightedENormInfinity(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr); 6515 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 6516 PetscFunctionReturn(0); 6517 } 6518 6519 6520 /*@ 6521 TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler 6522 6523 Logically Collective on TS 6524 6525 Input Arguments: 6526 + ts - time stepping context 6527 - cfltime - maximum stable time step if using forward Euler (value can be different on each process) 6528 6529 Note: 6530 After calling this function, the global CFL time can be obtained by calling TSGetCFLTime() 6531 6532 Level: intermediate 6533 6534 .seealso: TSGetCFLTime(), TSADAPTCFL 6535 @*/ 6536 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime) 6537 { 6538 PetscFunctionBegin; 6539 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6540 ts->cfltime_local = cfltime; 6541 ts->cfltime = -1.; 6542 PetscFunctionReturn(0); 6543 } 6544 6545 /*@ 6546 TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler 6547 6548 Collective on TS 6549 6550 Input Arguments: 6551 . ts - time stepping context 6552 6553 Output Arguments: 6554 . cfltime - maximum stable time step for forward Euler 6555 6556 Level: advanced 6557 6558 .seealso: TSSetCFLTimeLocal() 6559 @*/ 6560 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime) 6561 { 6562 PetscErrorCode ierr; 6563 6564 PetscFunctionBegin; 6565 if (ts->cfltime < 0) { 6566 ierr = MPIU_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6567 } 6568 *cfltime = ts->cfltime; 6569 PetscFunctionReturn(0); 6570 } 6571 6572 /*@ 6573 TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu 6574 6575 Input Parameters: 6576 . ts - the TS context. 6577 . xl - lower bound. 6578 . xu - upper bound. 6579 6580 Notes: 6581 If this routine is not called then the lower and upper bounds are set to 6582 PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp(). 6583 6584 Level: advanced 6585 6586 @*/ 6587 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu) 6588 { 6589 PetscErrorCode ierr; 6590 SNES snes; 6591 6592 PetscFunctionBegin; 6593 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 6594 ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr); 6595 PetscFunctionReturn(0); 6596 } 6597 6598 #if defined(PETSC_HAVE_MATLAB_ENGINE) 6599 #include <mex.h> 6600 6601 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext; 6602 6603 /* 6604 TSComputeFunction_Matlab - Calls the function that has been set with 6605 TSSetFunctionMatlab(). 6606 6607 Collective on TS 6608 6609 Input Parameters: 6610 + snes - the TS context 6611 - u - input vector 6612 6613 Output Parameter: 6614 . y - function vector, as set by TSSetFunction() 6615 6616 Notes: 6617 TSComputeFunction() is typically used within nonlinear solvers 6618 implementations, so most users would not generally call this routine 6619 themselves. 6620 6621 Level: developer 6622 6623 .keywords: TS, nonlinear, compute, function 6624 6625 .seealso: TSSetFunction(), TSGetFunction() 6626 */ 6627 PetscErrorCode TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx) 6628 { 6629 PetscErrorCode ierr; 6630 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 6631 int nlhs = 1,nrhs = 7; 6632 mxArray *plhs[1],*prhs[7]; 6633 long long int lx = 0,lxdot = 0,ly = 0,ls = 0; 6634 6635 PetscFunctionBegin; 6636 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 6637 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 6638 PetscValidHeaderSpecific(udot,VEC_CLASSID,4); 6639 PetscValidHeaderSpecific(y,VEC_CLASSID,5); 6640 PetscCheckSameComm(snes,1,u,3); 6641 PetscCheckSameComm(snes,1,y,5); 6642 6643 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 6644 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 6645 ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr); 6646 ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr); 6647 6648 prhs[0] = mxCreateDoubleScalar((double)ls); 6649 prhs[1] = mxCreateDoubleScalar(time); 6650 prhs[2] = mxCreateDoubleScalar((double)lx); 6651 prhs[3] = mxCreateDoubleScalar((double)lxdot); 6652 prhs[4] = mxCreateDoubleScalar((double)ly); 6653 prhs[5] = mxCreateString(sctx->funcname); 6654 prhs[6] = sctx->ctx; 6655 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr); 6656 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 6657 mxDestroyArray(prhs[0]); 6658 mxDestroyArray(prhs[1]); 6659 mxDestroyArray(prhs[2]); 6660 mxDestroyArray(prhs[3]); 6661 mxDestroyArray(prhs[4]); 6662 mxDestroyArray(prhs[5]); 6663 mxDestroyArray(plhs[0]); 6664 PetscFunctionReturn(0); 6665 } 6666 6667 6668 /* 6669 TSSetFunctionMatlab - Sets the function evaluation routine and function 6670 vector for use by the TS routines in solving ODEs 6671 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 6672 6673 Logically Collective on TS 6674 6675 Input Parameters: 6676 + ts - the TS context 6677 - func - function evaluation routine 6678 6679 Calling sequence of func: 6680 $ func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx); 6681 6682 Level: beginner 6683 6684 .keywords: TS, nonlinear, set, function 6685 6686 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 6687 */ 6688 PetscErrorCode TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx) 6689 { 6690 PetscErrorCode ierr; 6691 TSMatlabContext *sctx; 6692 6693 PetscFunctionBegin; 6694 /* currently sctx is memory bleed */ 6695 ierr = PetscNew(&sctx);CHKERRQ(ierr); 6696 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 6697 /* 6698 This should work, but it doesn't 6699 sctx->ctx = ctx; 6700 mexMakeArrayPersistent(sctx->ctx); 6701 */ 6702 sctx->ctx = mxDuplicateArray(ctx); 6703 6704 ierr = TSSetIFunction(ts,NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr); 6705 PetscFunctionReturn(0); 6706 } 6707 6708 /* 6709 TSComputeJacobian_Matlab - Calls the function that has been set with 6710 TSSetJacobianMatlab(). 6711 6712 Collective on TS 6713 6714 Input Parameters: 6715 + ts - the TS context 6716 . u - input vector 6717 . A, B - the matrices 6718 - ctx - user context 6719 6720 Level: developer 6721 6722 .keywords: TS, nonlinear, compute, function 6723 6724 .seealso: TSSetFunction(), TSGetFunction() 6725 @*/ 6726 PetscErrorCode TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat A,Mat B,void *ctx) 6727 { 6728 PetscErrorCode ierr; 6729 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 6730 int nlhs = 2,nrhs = 9; 6731 mxArray *plhs[2],*prhs[9]; 6732 long long int lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0; 6733 6734 PetscFunctionBegin; 6735 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6736 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 6737 6738 /* call Matlab function in ctx with arguments u and y */ 6739 6740 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 6741 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 6742 ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr); 6743 ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr); 6744 ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr); 6745 6746 prhs[0] = mxCreateDoubleScalar((double)ls); 6747 prhs[1] = mxCreateDoubleScalar((double)time); 6748 prhs[2] = mxCreateDoubleScalar((double)lx); 6749 prhs[3] = mxCreateDoubleScalar((double)lxdot); 6750 prhs[4] = mxCreateDoubleScalar((double)shift); 6751 prhs[5] = mxCreateDoubleScalar((double)lA); 6752 prhs[6] = mxCreateDoubleScalar((double)lB); 6753 prhs[7] = mxCreateString(sctx->funcname); 6754 prhs[8] = sctx->ctx; 6755 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr); 6756 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 6757 mxDestroyArray(prhs[0]); 6758 mxDestroyArray(prhs[1]); 6759 mxDestroyArray(prhs[2]); 6760 mxDestroyArray(prhs[3]); 6761 mxDestroyArray(prhs[4]); 6762 mxDestroyArray(prhs[5]); 6763 mxDestroyArray(prhs[6]); 6764 mxDestroyArray(prhs[7]); 6765 mxDestroyArray(plhs[0]); 6766 mxDestroyArray(plhs[1]); 6767 PetscFunctionReturn(0); 6768 } 6769 6770 6771 /* 6772 TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 6773 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 6774 6775 Logically Collective on TS 6776 6777 Input Parameters: 6778 + ts - the TS context 6779 . A,B - Jacobian matrices 6780 . func - function evaluation routine 6781 - ctx - user context 6782 6783 Calling sequence of func: 6784 $ flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx); 6785 6786 6787 Level: developer 6788 6789 .keywords: TS, nonlinear, set, function 6790 6791 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 6792 */ 6793 PetscErrorCode TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx) 6794 { 6795 PetscErrorCode ierr; 6796 TSMatlabContext *sctx; 6797 6798 PetscFunctionBegin; 6799 /* currently sctx is memory bleed */ 6800 ierr = PetscNew(&sctx);CHKERRQ(ierr); 6801 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 6802 /* 6803 This should work, but it doesn't 6804 sctx->ctx = ctx; 6805 mexMakeArrayPersistent(sctx->ctx); 6806 */ 6807 sctx->ctx = mxDuplicateArray(ctx); 6808 6809 ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 6810 PetscFunctionReturn(0); 6811 } 6812 6813 /* 6814 TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab(). 6815 6816 Collective on TS 6817 6818 .seealso: TSSetFunction(), TSGetFunction() 6819 @*/ 6820 PetscErrorCode TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx) 6821 { 6822 PetscErrorCode ierr; 6823 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 6824 int nlhs = 1,nrhs = 6; 6825 mxArray *plhs[1],*prhs[6]; 6826 long long int lx = 0,ls = 0; 6827 6828 PetscFunctionBegin; 6829 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6830 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 6831 6832 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 6833 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 6834 6835 prhs[0] = mxCreateDoubleScalar((double)ls); 6836 prhs[1] = mxCreateDoubleScalar((double)it); 6837 prhs[2] = mxCreateDoubleScalar((double)time); 6838 prhs[3] = mxCreateDoubleScalar((double)lx); 6839 prhs[4] = mxCreateString(sctx->funcname); 6840 prhs[5] = sctx->ctx; 6841 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr); 6842 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 6843 mxDestroyArray(prhs[0]); 6844 mxDestroyArray(prhs[1]); 6845 mxDestroyArray(prhs[2]); 6846 mxDestroyArray(prhs[3]); 6847 mxDestroyArray(prhs[4]); 6848 mxDestroyArray(plhs[0]); 6849 PetscFunctionReturn(0); 6850 } 6851 6852 6853 /* 6854 TSMonitorSetMatlab - Sets the monitor function from Matlab 6855 6856 Level: developer 6857 6858 .keywords: TS, nonlinear, set, function 6859 6860 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 6861 */ 6862 PetscErrorCode TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx) 6863 { 6864 PetscErrorCode ierr; 6865 TSMatlabContext *sctx; 6866 6867 PetscFunctionBegin; 6868 /* currently sctx is memory bleed */ 6869 ierr = PetscNew(&sctx);CHKERRQ(ierr); 6870 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 6871 /* 6872 This should work, but it doesn't 6873 sctx->ctx = ctx; 6874 mexMakeArrayPersistent(sctx->ctx); 6875 */ 6876 sctx->ctx = mxDuplicateArray(ctx); 6877 6878 ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,NULL);CHKERRQ(ierr); 6879 PetscFunctionReturn(0); 6880 } 6881 #endif 6882 6883 /*@C 6884 TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector 6885 in a time based line graph 6886 6887 Collective on TS 6888 6889 Input Parameters: 6890 + ts - the TS context 6891 . step - current time-step 6892 . ptime - current time 6893 . u - current solution 6894 - dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate() 6895 6896 Options Database: 6897 . -ts_monitor_lg_solution_variables 6898 6899 Level: intermediate 6900 6901 Notes: Each process in a parallel run displays its component solutions in a separate window 6902 6903 .keywords: TS, vector, monitor, view 6904 6905 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(), 6906 TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(), 6907 TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(), 6908 TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop() 6909 @*/ 6910 PetscErrorCode TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 6911 { 6912 PetscErrorCode ierr; 6913 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dctx; 6914 const PetscScalar *yy; 6915 Vec v; 6916 6917 PetscFunctionBegin; 6918 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 6919 if (!step) { 6920 PetscDrawAxis axis; 6921 PetscInt dim; 6922 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6923 ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr); 6924 if (!ctx->names) { 6925 PetscBool flg; 6926 /* user provides names of variables to plot but no names has been set so assume names are integer values */ 6927 ierr = PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg);CHKERRQ(ierr); 6928 if (flg) { 6929 PetscInt i,n; 6930 char **names; 6931 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 6932 ierr = PetscMalloc1(n+1,&names);CHKERRQ(ierr); 6933 for (i=0; i<n; i++) { 6934 ierr = PetscMalloc1(5,&names[i]);CHKERRQ(ierr); 6935 ierr = PetscSNPrintf(names[i],5,"%D",i);CHKERRQ(ierr); 6936 } 6937 names[n] = NULL; 6938 ctx->names = names; 6939 } 6940 } 6941 if (ctx->names && !ctx->displaynames) { 6942 char **displaynames; 6943 PetscBool flg; 6944 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6945 ierr = PetscMalloc1(dim+1,&displaynames);CHKERRQ(ierr); 6946 ierr = PetscMemzero(displaynames,(dim+1)*sizeof(char*));CHKERRQ(ierr); 6947 ierr = PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg);CHKERRQ(ierr); 6948 if (flg) { 6949 ierr = TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames);CHKERRQ(ierr); 6950 } 6951 ierr = PetscStrArrayDestroy(&displaynames);CHKERRQ(ierr); 6952 } 6953 if (ctx->displaynames) { 6954 ierr = PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables);CHKERRQ(ierr); 6955 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames);CHKERRQ(ierr); 6956 } else if (ctx->names) { 6957 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6958 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6959 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names);CHKERRQ(ierr); 6960 } else { 6961 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6962 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6963 } 6964 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6965 } 6966 6967 if (!ctx->transform) v = u; 6968 else {ierr = (*ctx->transform)(ctx->transformctx,u,&v);CHKERRQ(ierr);} 6969 ierr = VecGetArrayRead(v,&yy);CHKERRQ(ierr); 6970 if (ctx->displaynames) { 6971 PetscInt i; 6972 for (i=0; i<ctx->ndisplayvariables; i++) 6973 ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]); 6974 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues);CHKERRQ(ierr); 6975 } else { 6976 #if defined(PETSC_USE_COMPLEX) 6977 PetscInt i,n; 6978 PetscReal *yreal; 6979 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 6980 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 6981 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 6982 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 6983 ierr = PetscFree(yreal);CHKERRQ(ierr); 6984 #else 6985 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 6986 #endif 6987 } 6988 ierr = VecRestoreArrayRead(v,&yy);CHKERRQ(ierr); 6989 if (ctx->transform) {ierr = VecDestroy(&v);CHKERRQ(ierr);} 6990 6991 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 6992 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6993 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 6994 } 6995 PetscFunctionReturn(0); 6996 } 6997 6998 6999 /*@C 7000 TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 7001 7002 Collective on TS 7003 7004 Input Parameters: 7005 + ts - the TS context 7006 - names - the names of the components, final string must be NULL 7007 7008 Level: intermediate 7009 7010 Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 7011 7012 .keywords: TS, vector, monitor, view 7013 7014 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames() 7015 @*/ 7016 PetscErrorCode TSMonitorLGSetVariableNames(TS ts,const char * const *names) 7017 { 7018 PetscErrorCode ierr; 7019 PetscInt i; 7020 7021 PetscFunctionBegin; 7022 for (i=0; i<ts->numbermonitors; i++) { 7023 if (ts->monitor[i] == TSMonitorLGSolution) { 7024 ierr = TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names);CHKERRQ(ierr); 7025 break; 7026 } 7027 } 7028 PetscFunctionReturn(0); 7029 } 7030 7031 /*@C 7032 TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 7033 7034 Collective on TS 7035 7036 Input Parameters: 7037 + ts - the TS context 7038 - names - the names of the components, final string must be NULL 7039 7040 Level: intermediate 7041 7042 .keywords: TS, vector, monitor, view 7043 7044 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames() 7045 @*/ 7046 PetscErrorCode TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names) 7047 { 7048 PetscErrorCode ierr; 7049 7050 PetscFunctionBegin; 7051 ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr); 7052 ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr); 7053 PetscFunctionReturn(0); 7054 } 7055 7056 /*@C 7057 TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot 7058 7059 Collective on TS 7060 7061 Input Parameter: 7062 . ts - the TS context 7063 7064 Output Parameter: 7065 . names - the names of the components, final string must be NULL 7066 7067 Level: intermediate 7068 7069 Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 7070 7071 .keywords: TS, vector, monitor, view 7072 7073 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 7074 @*/ 7075 PetscErrorCode TSMonitorLGGetVariableNames(TS ts,const char *const **names) 7076 { 7077 PetscInt i; 7078 7079 PetscFunctionBegin; 7080 *names = NULL; 7081 for (i=0; i<ts->numbermonitors; i++) { 7082 if (ts->monitor[i] == TSMonitorLGSolution) { 7083 TSMonitorLGCtx ctx = (TSMonitorLGCtx) ts->monitorcontext[i]; 7084 *names = (const char *const *)ctx->names; 7085 break; 7086 } 7087 } 7088 PetscFunctionReturn(0); 7089 } 7090 7091 /*@C 7092 TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor 7093 7094 Collective on TS 7095 7096 Input Parameters: 7097 + ctx - the TSMonitorLG context 7098 . displaynames - the names of the components, final string must be NULL 7099 7100 Level: intermediate 7101 7102 .keywords: TS, vector, monitor, view 7103 7104 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 7105 @*/ 7106 PetscErrorCode TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames) 7107 { 7108 PetscInt j = 0,k; 7109 PetscErrorCode ierr; 7110 7111 PetscFunctionBegin; 7112 if (!ctx->names) PetscFunctionReturn(0); 7113 ierr = PetscStrArrayDestroy(&ctx->displaynames);CHKERRQ(ierr); 7114 ierr = PetscStrArrayallocpy(displaynames,&ctx->displaynames);CHKERRQ(ierr); 7115 while (displaynames[j]) j++; 7116 ctx->ndisplayvariables = j; 7117 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables);CHKERRQ(ierr); 7118 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues);CHKERRQ(ierr); 7119 j = 0; 7120 while (displaynames[j]) { 7121 k = 0; 7122 while (ctx->names[k]) { 7123 PetscBool flg; 7124 ierr = PetscStrcmp(displaynames[j],ctx->names[k],&flg);CHKERRQ(ierr); 7125 if (flg) { 7126 ctx->displayvariables[j] = k; 7127 break; 7128 } 7129 k++; 7130 } 7131 j++; 7132 } 7133 PetscFunctionReturn(0); 7134 } 7135 7136 7137 /*@C 7138 TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor 7139 7140 Collective on TS 7141 7142 Input Parameters: 7143 + ts - the TS context 7144 . displaynames - the names of the components, final string must be NULL 7145 7146 Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 7147 7148 Level: intermediate 7149 7150 .keywords: TS, vector, monitor, view 7151 7152 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 7153 @*/ 7154 PetscErrorCode TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames) 7155 { 7156 PetscInt i; 7157 PetscErrorCode ierr; 7158 7159 PetscFunctionBegin; 7160 for (i=0; i<ts->numbermonitors; i++) { 7161 if (ts->monitor[i] == TSMonitorLGSolution) { 7162 ierr = TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames);CHKERRQ(ierr); 7163 break; 7164 } 7165 } 7166 PetscFunctionReturn(0); 7167 } 7168 7169 /*@C 7170 TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed 7171 7172 Collective on TS 7173 7174 Input Parameters: 7175 + ts - the TS context 7176 . transform - the transform function 7177 . destroy - function to destroy the optional context 7178 - ctx - optional context used by transform function 7179 7180 Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 7181 7182 Level: intermediate 7183 7184 .keywords: TS, vector, monitor, view 7185 7186 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform() 7187 @*/ 7188 PetscErrorCode TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 7189 { 7190 PetscInt i; 7191 PetscErrorCode ierr; 7192 7193 PetscFunctionBegin; 7194 for (i=0; i<ts->numbermonitors; i++) { 7195 if (ts->monitor[i] == TSMonitorLGSolution) { 7196 ierr = TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx);CHKERRQ(ierr); 7197 } 7198 } 7199 PetscFunctionReturn(0); 7200 } 7201 7202 /*@C 7203 TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed 7204 7205 Collective on TSLGCtx 7206 7207 Input Parameters: 7208 + ts - the TS context 7209 . transform - the transform function 7210 . destroy - function to destroy the optional context 7211 - ctx - optional context used by transform function 7212 7213 Level: intermediate 7214 7215 .keywords: TS, vector, monitor, view 7216 7217 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform() 7218 @*/ 7219 PetscErrorCode TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 7220 { 7221 PetscFunctionBegin; 7222 ctx->transform = transform; 7223 ctx->transformdestroy = destroy; 7224 ctx->transformctx = tctx; 7225 PetscFunctionReturn(0); 7226 } 7227 7228 /*@C 7229 TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the solution vector 7230 in a time based line graph 7231 7232 Collective on TS 7233 7234 Input Parameters: 7235 + ts - the TS context 7236 . step - current time-step 7237 . ptime - current time 7238 . u - current solution 7239 - dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate() 7240 7241 Level: intermediate 7242 7243 Notes: Each process in a parallel run displays its component errors in a separate window 7244 7245 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 7246 7247 Options Database Keys: 7248 . -ts_monitor_lg_error - create a graphical monitor of error history 7249 7250 .keywords: TS, vector, monitor, view 7251 7252 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 7253 @*/ 7254 PetscErrorCode TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 7255 { 7256 PetscErrorCode ierr; 7257 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 7258 const PetscScalar *yy; 7259 Vec y; 7260 7261 PetscFunctionBegin; 7262 if (!step) { 7263 PetscDrawAxis axis; 7264 PetscInt dim; 7265 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 7266 ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Solution");CHKERRQ(ierr); 7267 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 7268 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 7269 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 7270 } 7271 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 7272 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 7273 ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr); 7274 ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr); 7275 #if defined(PETSC_USE_COMPLEX) 7276 { 7277 PetscReal *yreal; 7278 PetscInt i,n; 7279 ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr); 7280 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 7281 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 7282 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 7283 ierr = PetscFree(yreal);CHKERRQ(ierr); 7284 } 7285 #else 7286 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 7287 #endif 7288 ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr); 7289 ierr = VecDestroy(&y);CHKERRQ(ierr); 7290 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 7291 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 7292 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 7293 } 7294 PetscFunctionReturn(0); 7295 } 7296 7297 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 7298 { 7299 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 7300 PetscReal x = ptime,y; 7301 PetscErrorCode ierr; 7302 PetscInt its; 7303 7304 PetscFunctionBegin; 7305 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 7306 if (!n) { 7307 PetscDrawAxis axis; 7308 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 7309 ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr); 7310 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 7311 ctx->snes_its = 0; 7312 } 7313 ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr); 7314 y = its - ctx->snes_its; 7315 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 7316 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 7317 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 7318 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 7319 } 7320 ctx->snes_its = its; 7321 PetscFunctionReturn(0); 7322 } 7323 7324 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 7325 { 7326 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 7327 PetscReal x = ptime,y; 7328 PetscErrorCode ierr; 7329 PetscInt its; 7330 7331 PetscFunctionBegin; 7332 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 7333 if (!n) { 7334 PetscDrawAxis axis; 7335 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 7336 ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr); 7337 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 7338 ctx->ksp_its = 0; 7339 } 7340 ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr); 7341 y = its - ctx->ksp_its; 7342 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 7343 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 7344 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 7345 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 7346 } 7347 ctx->ksp_its = its; 7348 PetscFunctionReturn(0); 7349 } 7350 7351 /*@ 7352 TSComputeLinearStability - computes the linear stability function at a point 7353 7354 Collective on TS and Vec 7355 7356 Input Parameters: 7357 + ts - the TS context 7358 - xr,xi - real and imaginary part of input arguments 7359 7360 Output Parameters: 7361 . yr,yi - real and imaginary part of function value 7362 7363 Level: developer 7364 7365 .keywords: TS, compute 7366 7367 .seealso: TSSetRHSFunction(), TSComputeIFunction() 7368 @*/ 7369 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi) 7370 { 7371 PetscErrorCode ierr; 7372 7373 PetscFunctionBegin; 7374 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7375 if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method"); 7376 ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr); 7377 PetscFunctionReturn(0); 7378 } 7379 7380 /* ------------------------------------------------------------------------*/ 7381 /*@C 7382 TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope() 7383 7384 Collective on TS 7385 7386 Input Parameters: 7387 . ts - the ODE solver object 7388 7389 Output Parameter: 7390 . ctx - the context 7391 7392 Level: intermediate 7393 7394 .keywords: TS, monitor, line graph, residual, seealso 7395 7396 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError() 7397 7398 @*/ 7399 PetscErrorCode TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx) 7400 { 7401 PetscErrorCode ierr; 7402 7403 PetscFunctionBegin; 7404 ierr = PetscNew(ctx);CHKERRQ(ierr); 7405 PetscFunctionReturn(0); 7406 } 7407 7408 /*@C 7409 TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution 7410 7411 Collective on TS 7412 7413 Input Parameters: 7414 + ts - the TS context 7415 . step - current time-step 7416 . ptime - current time 7417 . u - current solution 7418 - dctx - the envelope context 7419 7420 Options Database: 7421 . -ts_monitor_envelope 7422 7423 Level: intermediate 7424 7425 Notes: after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope 7426 7427 .keywords: TS, vector, monitor, view 7428 7429 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxCreate() 7430 @*/ 7431 PetscErrorCode TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 7432 { 7433 PetscErrorCode ierr; 7434 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx; 7435 7436 PetscFunctionBegin; 7437 if (!ctx->max) { 7438 ierr = VecDuplicate(u,&ctx->max);CHKERRQ(ierr); 7439 ierr = VecDuplicate(u,&ctx->min);CHKERRQ(ierr); 7440 ierr = VecCopy(u,ctx->max);CHKERRQ(ierr); 7441 ierr = VecCopy(u,ctx->min);CHKERRQ(ierr); 7442 } else { 7443 ierr = VecPointwiseMax(ctx->max,u,ctx->max);CHKERRQ(ierr); 7444 ierr = VecPointwiseMin(ctx->min,u,ctx->min);CHKERRQ(ierr); 7445 } 7446 PetscFunctionReturn(0); 7447 } 7448 7449 7450 /*@C 7451 TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution 7452 7453 Collective on TS 7454 7455 Input Parameter: 7456 . ts - the TS context 7457 7458 Output Parameter: 7459 + max - the maximum values 7460 - min - the minimum values 7461 7462 Notes: If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored 7463 7464 Level: intermediate 7465 7466 .keywords: TS, vector, monitor, view 7467 7468 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 7469 @*/ 7470 PetscErrorCode TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min) 7471 { 7472 PetscInt i; 7473 7474 PetscFunctionBegin; 7475 if (max) *max = NULL; 7476 if (min) *min = NULL; 7477 for (i=0; i<ts->numbermonitors; i++) { 7478 if (ts->monitor[i] == TSMonitorEnvelope) { 7479 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i]; 7480 if (max) *max = ctx->max; 7481 if (min) *min = ctx->min; 7482 break; 7483 } 7484 } 7485 PetscFunctionReturn(0); 7486 } 7487 7488 /*@C 7489 TSMonitorEnvelopeCtxDestroy - Destroys a context that was created with TSMonitorEnvelopeCtxCreate(). 7490 7491 Collective on TSMonitorEnvelopeCtx 7492 7493 Input Parameter: 7494 . ctx - the monitor context 7495 7496 Level: intermediate 7497 7498 .keywords: TS, monitor, line graph, destroy 7499 7500 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep() 7501 @*/ 7502 PetscErrorCode TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx) 7503 { 7504 PetscErrorCode ierr; 7505 7506 PetscFunctionBegin; 7507 ierr = VecDestroy(&(*ctx)->min);CHKERRQ(ierr); 7508 ierr = VecDestroy(&(*ctx)->max);CHKERRQ(ierr); 7509 ierr = PetscFree(*ctx);CHKERRQ(ierr); 7510 PetscFunctionReturn(0); 7511 } 7512 7513 /*@ 7514 TSRollBack - Rolls back one time step 7515 7516 Collective on TS 7517 7518 Input Parameter: 7519 . ts - the TS context obtained from TSCreate() 7520 7521 Level: advanced 7522 7523 .keywords: TS, timestep, rollback 7524 7525 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate() 7526 @*/ 7527 PetscErrorCode TSRollBack(TS ts) 7528 { 7529 PetscErrorCode ierr; 7530 7531 PetscFunctionBegin; 7532 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7533 if (ts->steprollback) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"TSRollBack already called"); 7534 if (!ts->ops->rollback) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name); 7535 ierr = (*ts->ops->rollback)(ts);CHKERRQ(ierr); 7536 ts->time_step = ts->ptime - ts->ptime_prev; 7537 ts->ptime = ts->ptime_prev; 7538 ts->ptime_prev = ts->ptime_prev_rollback; 7539 ts->steps--; ts->total_steps--; 7540 ierr = TSPostEvaluate(ts);CHKERRQ(ierr); 7541 ts->steprollback = PETSC_TRUE; 7542 PetscFunctionReturn(0); 7543 } 7544 7545 /*@ 7546 TSGetStages - Get the number of stages and stage values 7547 7548 Input Parameter: 7549 . ts - the TS context obtained from TSCreate() 7550 7551 Level: advanced 7552 7553 .keywords: TS, getstages 7554 7555 .seealso: TSCreate() 7556 @*/ 7557 PetscErrorCode TSGetStages(TS ts,PetscInt *ns,Vec **Y) 7558 { 7559 PetscErrorCode ierr; 7560 7561 PetscFunctionBegin; 7562 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7563 PetscValidPointer(ns,2); 7564 7565 if (!ts->ops->getstages) *ns=0; 7566 else { 7567 ierr = (*ts->ops->getstages)(ts,ns,Y);CHKERRQ(ierr); 7568 } 7569 PetscFunctionReturn(0); 7570 } 7571 7572 /*@C 7573 TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity. 7574 7575 Collective on SNES 7576 7577 Input Parameters: 7578 + ts - the TS context 7579 . t - current timestep 7580 . U - state vector 7581 . Udot - time derivative of state vector 7582 . shift - shift to apply, see note below 7583 - ctx - an optional user context 7584 7585 Output Parameters: 7586 + J - Jacobian matrix (not altered in this routine) 7587 - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J) 7588 7589 Level: intermediate 7590 7591 Notes: 7592 If F(t,U,Udot)=0 is the DAE, the required Jacobian is 7593 7594 dF/dU + shift*dF/dUdot 7595 7596 Most users should not need to explicitly call this routine, as it 7597 is used internally within the nonlinear solvers. 7598 7599 This will first try to get the coloring from the DM. If the DM type has no coloring 7600 routine, then it will try to get the coloring from the matrix. This requires that the 7601 matrix have nonzero entries precomputed. 7602 7603 .keywords: TS, finite differences, Jacobian, coloring, sparse 7604 .seealso: TSSetIJacobian(), MatFDColoringCreate(), MatFDColoringSetFunction() 7605 @*/ 7606 PetscErrorCode TSComputeIJacobianDefaultColor(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat J,Mat B,void *ctx) 7607 { 7608 SNES snes; 7609 MatFDColoring color; 7610 PetscBool hascolor, matcolor = PETSC_FALSE; 7611 PetscErrorCode ierr; 7612 7613 PetscFunctionBegin; 7614 ierr = PetscOptionsGetBool(((PetscObject)ts)->options,((PetscObject) ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL);CHKERRQ(ierr); 7615 ierr = PetscObjectQuery((PetscObject) B, "TSMatFDColoring", (PetscObject *) &color);CHKERRQ(ierr); 7616 if (!color) { 7617 DM dm; 7618 ISColoring iscoloring; 7619 7620 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 7621 ierr = DMHasColoring(dm, &hascolor);CHKERRQ(ierr); 7622 if (hascolor && !matcolor) { 7623 ierr = DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring);CHKERRQ(ierr); 7624 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 7625 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 7626 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 7627 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 7628 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 7629 } else { 7630 MatColoring mc; 7631 7632 ierr = MatColoringCreate(B, &mc);CHKERRQ(ierr); 7633 ierr = MatColoringSetDistance(mc, 2);CHKERRQ(ierr); 7634 ierr = MatColoringSetType(mc, MATCOLORINGSL);CHKERRQ(ierr); 7635 ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); 7636 ierr = MatColoringApply(mc, &iscoloring);CHKERRQ(ierr); 7637 ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); 7638 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 7639 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 7640 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 7641 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 7642 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 7643 } 7644 ierr = PetscObjectCompose((PetscObject) B, "TSMatFDColoring", (PetscObject) color);CHKERRQ(ierr); 7645 ierr = PetscObjectDereference((PetscObject) color);CHKERRQ(ierr); 7646 } 7647 ierr = TSGetSNES(ts, &snes);CHKERRQ(ierr); 7648 ierr = MatFDColoringApply(B, color, U, snes);CHKERRQ(ierr); 7649 if (J != B) { 7650 ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7651 ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7652 } 7653 PetscFunctionReturn(0); 7654 } 7655 7656 /*@ 7657 TSSetFunctionDomainError - Set the function testing if the current state vector is valid 7658 7659 Input Parameters: 7660 ts - the TS context 7661 func - function called within TSFunctionDomainError 7662 7663 Level: intermediate 7664 7665 .keywords: TS, state, domain 7666 .seealso: TSAdaptCheckStage(), TSFunctionDomainError() 7667 @*/ 7668 7669 PetscErrorCode TSSetFunctionDomainError(TS ts, PetscErrorCode (*func)(TS,PetscReal,Vec,PetscBool*)) 7670 { 7671 PetscFunctionBegin; 7672 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7673 ts->functiondomainerror = func; 7674 PetscFunctionReturn(0); 7675 } 7676 7677 /*@ 7678 TSFunctionDomainError - Check if the current state is valid 7679 7680 Input Parameters: 7681 ts - the TS context 7682 stagetime - time of the simulation 7683 Y - state vector to check. 7684 7685 Output Parameter: 7686 accept - Set to PETSC_FALSE if the current state vector is valid. 7687 7688 Note: 7689 This function should be used to ensure the state is in a valid part of the space. 7690 For example, one can ensure here all values are positive. 7691 7692 Level: advanced 7693 @*/ 7694 PetscErrorCode TSFunctionDomainError(TS ts,PetscReal stagetime,Vec Y,PetscBool* accept) 7695 { 7696 PetscErrorCode ierr; 7697 7698 PetscFunctionBegin; 7699 7700 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7701 *accept = PETSC_TRUE; 7702 if (ts->functiondomainerror) { 7703 PetscStackCallStandard((*ts->functiondomainerror),(ts,stagetime,Y,accept)); 7704 } 7705 PetscFunctionReturn(0); 7706 } 7707 7708 /*@C 7709 TSClone - This function clones a time step object. 7710 7711 Collective on MPI_Comm 7712 7713 Input Parameter: 7714 . tsin - The input TS 7715 7716 Output Parameter: 7717 . tsout - The output TS (cloned) 7718 7719 Notes: 7720 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. 7721 7722 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); 7723 7724 Level: developer 7725 7726 .keywords: TS, clone 7727 .seealso: TSCreate(), TSSetType(), TSSetUp(), TSDestroy(), TSSetProblemType() 7728 @*/ 7729 PetscErrorCode TSClone(TS tsin, TS *tsout) 7730 { 7731 TS t; 7732 PetscErrorCode ierr; 7733 SNES snes_start; 7734 DM dm; 7735 TSType type; 7736 7737 PetscFunctionBegin; 7738 PetscValidPointer(tsin,1); 7739 *tsout = NULL; 7740 7741 ierr = PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView);CHKERRQ(ierr); 7742 7743 /* General TS description */ 7744 t->numbermonitors = 0; 7745 t->setupcalled = 0; 7746 t->ksp_its = 0; 7747 t->snes_its = 0; 7748 t->nwork = 0; 7749 t->rhsjacobian.time = -1e20; 7750 t->rhsjacobian.scale = 1.; 7751 t->ijacobian.shift = 1.; 7752 7753 ierr = TSGetSNES(tsin,&snes_start);CHKERRQ(ierr); 7754 ierr = TSSetSNES(t,snes_start);CHKERRQ(ierr); 7755 7756 ierr = TSGetDM(tsin,&dm);CHKERRQ(ierr); 7757 ierr = TSSetDM(t,dm);CHKERRQ(ierr); 7758 7759 t->adapt = tsin->adapt; 7760 ierr = PetscObjectReference((PetscObject)t->adapt);CHKERRQ(ierr); 7761 7762 t->trajectory = tsin->trajectory; 7763 ierr = PetscObjectReference((PetscObject)t->trajectory);CHKERRQ(ierr); 7764 7765 t->event = tsin->event; 7766 if (t->event) t->event->refct++; 7767 7768 t->problem_type = tsin->problem_type; 7769 t->ptime = tsin->ptime; 7770 t->ptime_prev = tsin->ptime_prev; 7771 t->time_step = tsin->time_step; 7772 t->max_time = tsin->max_time; 7773 t->steps = tsin->steps; 7774 t->total_steps = tsin->total_steps; 7775 t->max_steps = tsin->max_steps; 7776 t->equation_type = tsin->equation_type; 7777 t->atol = tsin->atol; 7778 t->rtol = tsin->rtol; 7779 t->max_snes_failures = tsin->max_snes_failures; 7780 t->max_reject = tsin->max_reject; 7781 t->errorifstepfailed = tsin->errorifstepfailed; 7782 7783 ierr = TSGetType(tsin,&type);CHKERRQ(ierr); 7784 ierr = TSSetType(t,type);CHKERRQ(ierr); 7785 7786 t->vec_sol = NULL; 7787 7788 t->cfltime = tsin->cfltime; 7789 t->cfltime_local = tsin->cfltime_local; 7790 t->exact_final_time = tsin->exact_final_time; 7791 7792 ierr = PetscMemcpy(t->ops,tsin->ops,sizeof(struct _TSOps));CHKERRQ(ierr); 7793 7794 if (((PetscObject)tsin)->fortran_func_pointers) { 7795 PetscInt i; 7796 ierr = PetscMalloc((10)*sizeof(void(*)(void)),&((PetscObject)t)->fortran_func_pointers);CHKERRQ(ierr); 7797 for (i=0; i<10; i++) { 7798 ((PetscObject)t)->fortran_func_pointers[i] = ((PetscObject)tsin)->fortran_func_pointers[i]; 7799 } 7800 } 7801 *tsout = t; 7802 PetscFunctionReturn(0); 7803 } 7804