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(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetCostGradients() first"); 2560 if (ts->vecs_sensip && !ts->Jacp) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"Must call TSAdjointSetRHSJacobian() first"); 2561 2562 if (ts->vec_costintegral) { /* if there is integral in the cost function */ 2563 ierr = VecDuplicateVecs(ts->vecs_sensi[0],ts->numcost,&ts->vecs_drdy);CHKERRQ(ierr); 2564 if (ts->vecs_sensip){ 2565 ierr = VecDuplicateVecs(ts->vecs_sensip[0],ts->numcost,&ts->vecs_drdp);CHKERRQ(ierr); 2566 } 2567 } 2568 2569 if (ts->ops->adjointsetup) { 2570 ierr = (*ts->ops->adjointsetup)(ts);CHKERRQ(ierr); 2571 } 2572 ts->adjointsetupcalled = PETSC_TRUE; 2573 PetscFunctionReturn(0); 2574 } 2575 2576 /*@ 2577 TSReset - Resets a TS context and removes any allocated Vecs and Mats. 2578 2579 Collective on TS 2580 2581 Input Parameter: 2582 . ts - the TS context obtained from TSCreate() 2583 2584 Level: beginner 2585 2586 .keywords: TS, timestep, reset 2587 2588 .seealso: TSCreate(), TSSetup(), TSDestroy() 2589 @*/ 2590 PetscErrorCode TSReset(TS ts) 2591 { 2592 PetscErrorCode ierr; 2593 2594 PetscFunctionBegin; 2595 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2596 2597 if (ts->ops->reset) { 2598 ierr = (*ts->ops->reset)(ts);CHKERRQ(ierr); 2599 } 2600 if (ts->snes) {ierr = SNESReset(ts->snes);CHKERRQ(ierr);} 2601 if (ts->adapt) {ierr = TSAdaptReset(ts->adapt);CHKERRQ(ierr);} 2602 2603 ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr); 2604 ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr); 2605 ierr = VecDestroy(&ts->Frhs);CHKERRQ(ierr); 2606 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 2607 ierr = VecDestroy(&ts->vec_dot);CHKERRQ(ierr); 2608 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 2609 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 2610 ierr = VecDestroyVecs(ts->nwork,&ts->work);CHKERRQ(ierr); 2611 2612 if (ts->vec_costintegral) { 2613 ierr = VecDestroyVecs(ts->numcost,&ts->vecs_drdy);CHKERRQ(ierr); 2614 if (ts->vecs_drdp){ 2615 ierr = VecDestroyVecs(ts->numcost,&ts->vecs_drdp);CHKERRQ(ierr); 2616 } 2617 } 2618 ts->vecs_sensi = NULL; 2619 ts->vecs_sensip = NULL; 2620 ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr); 2621 ierr = VecDestroy(&ts->vec_costintegral);CHKERRQ(ierr); 2622 ierr = VecDestroy(&ts->vec_costintegrand);CHKERRQ(ierr); 2623 ts->setupcalled = PETSC_FALSE; 2624 PetscFunctionReturn(0); 2625 } 2626 2627 /*@ 2628 TSDestroy - Destroys the timestepper context that was created 2629 with TSCreate(). 2630 2631 Collective on TS 2632 2633 Input Parameter: 2634 . ts - the TS context obtained from TSCreate() 2635 2636 Level: beginner 2637 2638 .keywords: TS, timestepper, destroy 2639 2640 .seealso: TSCreate(), TSSetUp(), TSSolve() 2641 @*/ 2642 PetscErrorCode TSDestroy(TS *ts) 2643 { 2644 PetscErrorCode ierr; 2645 2646 PetscFunctionBegin; 2647 if (!*ts) PetscFunctionReturn(0); 2648 PetscValidHeaderSpecific((*ts),TS_CLASSID,1); 2649 if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; PetscFunctionReturn(0);} 2650 2651 ierr = TSReset((*ts));CHKERRQ(ierr); 2652 2653 /* if memory was published with SAWs then destroy it */ 2654 ierr = PetscObjectSAWsViewOff((PetscObject)*ts);CHKERRQ(ierr); 2655 if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);} 2656 2657 ierr = TSTrajectoryDestroy(&(*ts)->trajectory);CHKERRQ(ierr); 2658 2659 ierr = TSAdaptDestroy(&(*ts)->adapt);CHKERRQ(ierr); 2660 ierr = TSEventDestroy(&(*ts)->event);CHKERRQ(ierr); 2661 2662 ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr); 2663 ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr); 2664 ierr = TSMonitorCancel((*ts));CHKERRQ(ierr); 2665 ierr = TSAdjointMonitorCancel((*ts));CHKERRQ(ierr); 2666 2667 ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr); 2668 PetscFunctionReturn(0); 2669 } 2670 2671 /*@ 2672 TSGetSNES - Returns the SNES (nonlinear solver) associated with 2673 a TS (timestepper) context. Valid only for nonlinear problems. 2674 2675 Not Collective, but SNES is parallel if TS is parallel 2676 2677 Input Parameter: 2678 . ts - the TS context obtained from TSCreate() 2679 2680 Output Parameter: 2681 . snes - the nonlinear solver context 2682 2683 Notes: 2684 The user can then directly manipulate the SNES context to set various 2685 options, etc. Likewise, the user can then extract and manipulate the 2686 KSP, KSP, and PC contexts as well. 2687 2688 TSGetSNES() does not work for integrators that do not use SNES; in 2689 this case TSGetSNES() returns NULL in snes. 2690 2691 Level: beginner 2692 2693 .keywords: timestep, get, SNES 2694 @*/ 2695 PetscErrorCode TSGetSNES(TS ts,SNES *snes) 2696 { 2697 PetscErrorCode ierr; 2698 2699 PetscFunctionBegin; 2700 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2701 PetscValidPointer(snes,2); 2702 if (!ts->snes) { 2703 ierr = SNESCreate(PetscObjectComm((PetscObject)ts),&ts->snes);CHKERRQ(ierr); 2704 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 2705 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->snes);CHKERRQ(ierr); 2706 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr); 2707 if (ts->dm) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 2708 if (ts->problem_type == TS_LINEAR) { 2709 ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr); 2710 } 2711 } 2712 *snes = ts->snes; 2713 PetscFunctionReturn(0); 2714 } 2715 2716 /*@ 2717 TSSetSNES - Set the SNES (nonlinear solver) to be used by the timestepping context 2718 2719 Collective 2720 2721 Input Parameter: 2722 + ts - the TS context obtained from TSCreate() 2723 - snes - the nonlinear solver context 2724 2725 Notes: 2726 Most users should have the TS created by calling TSGetSNES() 2727 2728 Level: developer 2729 2730 .keywords: timestep, set, SNES 2731 @*/ 2732 PetscErrorCode TSSetSNES(TS ts,SNES snes) 2733 { 2734 PetscErrorCode ierr; 2735 PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*); 2736 2737 PetscFunctionBegin; 2738 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2739 PetscValidHeaderSpecific(snes,SNES_CLASSID,2); 2740 ierr = PetscObjectReference((PetscObject)snes);CHKERRQ(ierr); 2741 ierr = SNESDestroy(&ts->snes);CHKERRQ(ierr); 2742 2743 ts->snes = snes; 2744 2745 ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr); 2746 ierr = SNESGetJacobian(ts->snes,NULL,NULL,&func,NULL);CHKERRQ(ierr); 2747 if (func == SNESTSFormJacobian) { 2748 ierr = SNESSetJacobian(ts->snes,NULL,NULL,SNESTSFormJacobian,ts);CHKERRQ(ierr); 2749 } 2750 PetscFunctionReturn(0); 2751 } 2752 2753 /*@ 2754 TSGetKSP - Returns the KSP (linear solver) associated with 2755 a TS (timestepper) context. 2756 2757 Not Collective, but KSP is parallel if TS is parallel 2758 2759 Input Parameter: 2760 . ts - the TS context obtained from TSCreate() 2761 2762 Output Parameter: 2763 . ksp - the nonlinear solver context 2764 2765 Notes: 2766 The user can then directly manipulate the KSP context to set various 2767 options, etc. Likewise, the user can then extract and manipulate the 2768 KSP and PC contexts as well. 2769 2770 TSGetKSP() does not work for integrators that do not use KSP; 2771 in this case TSGetKSP() returns NULL in ksp. 2772 2773 Level: beginner 2774 2775 .keywords: timestep, get, KSP 2776 @*/ 2777 PetscErrorCode TSGetKSP(TS ts,KSP *ksp) 2778 { 2779 PetscErrorCode ierr; 2780 SNES snes; 2781 2782 PetscFunctionBegin; 2783 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2784 PetscValidPointer(ksp,2); 2785 if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first"); 2786 if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()"); 2787 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 2788 ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr); 2789 PetscFunctionReturn(0); 2790 } 2791 2792 /* ----------- Routines to set solver parameters ---------- */ 2793 2794 /*@ 2795 TSGetDuration - Gets the maximum number of timesteps to use and 2796 maximum time for iteration. 2797 2798 Not Collective 2799 2800 Input Parameters: 2801 + ts - the TS context obtained from TSCreate() 2802 . maxsteps - maximum number of iterations to use, or NULL 2803 - maxtime - final time to iterate to, or NULL 2804 2805 Level: intermediate 2806 2807 .keywords: TS, timestep, get, maximum, iterations, time 2808 @*/ 2809 PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime) 2810 { 2811 PetscFunctionBegin; 2812 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2813 if (maxsteps) { 2814 PetscValidIntPointer(maxsteps,2); 2815 *maxsteps = ts->max_steps; 2816 } 2817 if (maxtime) { 2818 PetscValidScalarPointer(maxtime,3); 2819 *maxtime = ts->max_time; 2820 } 2821 PetscFunctionReturn(0); 2822 } 2823 2824 /*@ 2825 TSSetDuration - Sets the maximum number of timesteps to use and 2826 maximum time for iteration. 2827 2828 Logically Collective on TS 2829 2830 Input Parameters: 2831 + ts - the TS context obtained from TSCreate() 2832 . maxsteps - maximum number of iterations to use 2833 - maxtime - final time to iterate to 2834 2835 Options Database Keys: 2836 . -ts_max_steps <maxsteps> - Sets maxsteps 2837 . -ts_final_time <maxtime> - Sets maxtime 2838 2839 Notes: 2840 The default maximum number of iterations is 5000. Default time is 5.0 2841 2842 Level: intermediate 2843 2844 .keywords: TS, timestep, set, maximum, iterations 2845 2846 .seealso: TSSetExactFinalTime() 2847 @*/ 2848 PetscErrorCode TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime) 2849 { 2850 PetscFunctionBegin; 2851 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2852 PetscValidLogicalCollectiveInt(ts,maxsteps,2); 2853 PetscValidLogicalCollectiveReal(ts,maxtime,2); 2854 if (maxsteps >= 0) ts->max_steps = maxsteps; 2855 if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime; 2856 PetscFunctionReturn(0); 2857 } 2858 2859 /*@ 2860 TSSetSolution - Sets the initial solution vector 2861 for use by the TS routines. 2862 2863 Logically Collective on TS and Vec 2864 2865 Input Parameters: 2866 + ts - the TS context obtained from TSCreate() 2867 - u - the solution vector 2868 2869 Level: beginner 2870 2871 .keywords: TS, timestep, set, solution, initial conditions 2872 @*/ 2873 PetscErrorCode TSSetSolution(TS ts,Vec u) 2874 { 2875 PetscErrorCode ierr; 2876 DM dm; 2877 2878 PetscFunctionBegin; 2879 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2880 PetscValidHeaderSpecific(u,VEC_CLASSID,2); 2881 ierr = PetscObjectReference((PetscObject)u);CHKERRQ(ierr); 2882 ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr); 2883 ts->vec_sol = u; 2884 2885 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 2886 ierr = DMShellSetGlobalVector(dm,u);CHKERRQ(ierr); 2887 PetscFunctionReturn(0); 2888 } 2889 2890 /*@ 2891 TSAdjointSetSteps - Sets the number of steps the adjoint solver should take backward in time 2892 2893 Logically Collective on TS 2894 2895 Input Parameters: 2896 + ts - the TS context obtained from TSCreate() 2897 . steps - number of steps to use 2898 2899 Level: intermediate 2900 2901 Notes: Normally one does not call this and TSAdjointSolve() integrates back to the original timestep. One can call this 2902 so as to integrate back to less than the original timestep 2903 2904 .keywords: TS, timestep, set, maximum, iterations 2905 2906 .seealso: TSSetExactFinalTime() 2907 @*/ 2908 PetscErrorCode TSAdjointSetSteps(TS ts,PetscInt steps) 2909 { 2910 PetscFunctionBegin; 2911 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2912 PetscValidLogicalCollectiveInt(ts,steps,2); 2913 if (steps < 0) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back a negative number of steps"); 2914 if (steps > ts->total_steps) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back more than the total number of forward steps"); 2915 ts->adjoint_max_steps = steps; 2916 PetscFunctionReturn(0); 2917 } 2918 2919 /*@ 2920 TSSetCostGradients - Sets the initial value of the gradients of the cost function w.r.t. initial conditions and w.r.t. the problem parameters 2921 for use by the TSAdjoint routines. 2922 2923 Logically Collective on TS and Vec 2924 2925 Input Parameters: 2926 + ts - the TS context obtained from TSCreate() 2927 . 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 2928 - mu - gradients with respect to the parameters, the number of entries in these vectors is the same as the number of parameters 2929 2930 Level: beginner 2931 2932 Notes: the entries in these vectors must be correctly initialized with the values lamda_i = df/dy|finaltime mu_i = df/dp|finaltime 2933 2934 .keywords: TS, timestep, set, sensitivity, initial conditions 2935 @*/ 2936 PetscErrorCode TSSetCostGradients(TS ts,PetscInt numcost,Vec *lambda,Vec *mu) 2937 { 2938 PetscFunctionBegin; 2939 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 2940 PetscValidPointer(lambda,2); 2941 ts->vecs_sensi = lambda; 2942 ts->vecs_sensip = mu; 2943 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"); 2944 ts->numcost = numcost; 2945 PetscFunctionReturn(0); 2946 } 2947 2948 /*@C 2949 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. 2950 2951 Logically Collective on TS 2952 2953 Input Parameters: 2954 + ts - The TS context obtained from TSCreate() 2955 - func - The function 2956 2957 Calling sequence of func: 2958 $ func (TS ts,PetscReal t,Vec y,Mat A,void *ctx); 2959 + t - current timestep 2960 . y - input vector (current ODE solution) 2961 . A - output matrix 2962 - ctx - [optional] user-defined function context 2963 2964 Level: intermediate 2965 2966 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 2967 2968 .keywords: TS, sensitivity 2969 .seealso: 2970 @*/ 2971 PetscErrorCode TSAdjointSetRHSJacobian(TS ts,Mat Amat,PetscErrorCode (*func)(TS,PetscReal,Vec,Mat,void*),void *ctx) 2972 { 2973 PetscErrorCode ierr; 2974 2975 PetscFunctionBegin; 2976 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 2977 PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 2978 2979 ts->rhsjacobianp = func; 2980 ts->rhsjacobianpctx = ctx; 2981 if(Amat) { 2982 ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 2983 ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr); 2984 ts->Jacp = Amat; 2985 } 2986 PetscFunctionReturn(0); 2987 } 2988 2989 /*@C 2990 TSAdjointComputeRHSJacobian - Runs the user-defined Jacobian function. 2991 2992 Collective on TS 2993 2994 Input Parameters: 2995 . ts - The TS context obtained from TSCreate() 2996 2997 Level: developer 2998 2999 .keywords: TS, sensitivity 3000 .seealso: TSAdjointSetRHSJacobian() 3001 @*/ 3002 PetscErrorCode TSAdjointComputeRHSJacobian(TS ts,PetscReal t,Vec X,Mat Amat) 3003 { 3004 PetscErrorCode ierr; 3005 3006 PetscFunctionBegin; 3007 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3008 PetscValidHeaderSpecific(X,VEC_CLASSID,3); 3009 PetscValidPointer(Amat,4); 3010 3011 PetscStackPush("TS user JacobianP function for sensitivity analysis"); 3012 ierr = (*ts->rhsjacobianp)(ts,t,X,Amat,ts->rhsjacobianpctx); CHKERRQ(ierr); 3013 PetscStackPop; 3014 PetscFunctionReturn(0); 3015 } 3016 3017 /*@C 3018 TSSetCostIntegrand - Sets the routine for evaluating the integral term in one or more cost functions 3019 3020 Logically Collective on TS 3021 3022 Input Parameters: 3023 + ts - the TS context obtained from TSCreate() 3024 . numcost - number of gradients to be computed, this is the number of cost functions 3025 . costintegral - vector that stores the integral values 3026 . rf - routine for evaluating the integrand function 3027 . drdyf - function that computes the gradients of the r's with respect to y,NULL if not a function y 3028 . drdpf - function that computes the gradients of the r's with respect to p, NULL if not a function of p 3029 . fwd - flag indicating whether to evaluate cost integral in the forward run or the adjoint run 3030 - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL) 3031 3032 Calling sequence of rf: 3033 $ PetscErrorCode rf(TS ts,PetscReal t,Vec y,Vec f,void *ctx); 3034 3035 Calling sequence of drdyf: 3036 $ PetscErroCode drdyf(TS ts,PetscReal t,Vec y,Vec *drdy,void *ctx); 3037 3038 Calling sequence of drdpf: 3039 $ PetscErroCode drdpf(TS ts,PetscReal t,Vec y,Vec *drdp,void *ctx); 3040 3041 Level: intermediate 3042 3043 Notes: For optimization there is generally a single cost function, numcost = 1. For sensitivities there may be multiple cost functions 3044 3045 .keywords: TS, sensitivity analysis, timestep, set, quadrature, function 3046 3047 .seealso: TSAdjointSetRHSJacobian(),TSGetCostGradients(), TSSetCostGradients() 3048 @*/ 3049 PetscErrorCode TSSetCostIntegrand(TS ts,PetscInt numcost,Vec costintegral,PetscErrorCode (*rf)(TS,PetscReal,Vec,Vec,void*), 3050 PetscErrorCode (*drdyf)(TS,PetscReal,Vec,Vec*,void*), 3051 PetscErrorCode (*drdpf)(TS,PetscReal,Vec,Vec*,void*), 3052 PetscBool fwd,void *ctx) 3053 { 3054 PetscErrorCode ierr; 3055 3056 PetscFunctionBegin; 3057 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3058 if (costintegral) PetscValidHeaderSpecific(costintegral,VEC_CLASSID,3); 3059 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()"); 3060 if (!ts->numcost) ts->numcost=numcost; 3061 3062 if (costintegral) { 3063 ierr = PetscObjectReference((PetscObject)costintegral);CHKERRQ(ierr); 3064 ierr = VecDestroy(&ts->vec_costintegral);CHKERRQ(ierr); 3065 ts->vec_costintegral = costintegral; 3066 } else { ierr = VecCreateSeq(PETSC_COMM_SELF,numcost,&ts->vec_costintegral);CHKERRQ(ierr); /* works for serial only */ } 3067 3068 ts->costintegralfwd = fwd; /* Evaluate the cost integral in forward run if fwd is true */ 3069 ierr = VecDuplicate(ts->vec_costintegral,&ts->vec_costintegrand);CHKERRQ(ierr); 3070 ts->costintegrand = rf; 3071 ts->costintegrandctx = ctx; 3072 ts->drdyfunction = drdyf; 3073 ts->drdpfunction = drdpf; 3074 PetscFunctionReturn(0); 3075 } 3076 3077 /*@ 3078 TSGetCostIntegral - Returns the values of the integral term in the cost functions. 3079 It is valid to call the routine after a backward run. 3080 3081 Not Collective 3082 3083 Input Parameter: 3084 . ts - the TS context obtained from TSCreate() 3085 3086 Output Parameter: 3087 . v - the vector containing the integrals for each cost function 3088 3089 Level: intermediate 3090 3091 .seealso: TSSetCostIntegrand() 3092 3093 .keywords: TS, sensitivity analysis 3094 @*/ 3095 PetscErrorCode TSGetCostIntegral(TS ts,Vec *v) 3096 { 3097 PetscFunctionBegin; 3098 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3099 PetscValidPointer(v,2); 3100 *v = ts->vec_costintegral; 3101 PetscFunctionReturn(0); 3102 } 3103 3104 /*@ 3105 TSAdjointComputeCostIntegrand - Evaluates the integral function in the cost functions. 3106 3107 Input Parameters: 3108 + ts - the TS context 3109 . t - current time 3110 - y - state vector, i.e. current solution 3111 3112 Output Parameter: 3113 . q - vector of size numcost to hold the outputs 3114 3115 Note: 3116 Most users should not need to explicitly call this routine, as it 3117 is used internally within the sensitivity analysis context. 3118 3119 Level: developer 3120 3121 .keywords: TS, compute 3122 3123 .seealso: TSSetCostIntegrand() 3124 @*/ 3125 PetscErrorCode TSAdjointComputeCostIntegrand(TS ts,PetscReal t,Vec y,Vec q) 3126 { 3127 PetscErrorCode ierr; 3128 3129 PetscFunctionBegin; 3130 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3131 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3132 PetscValidHeaderSpecific(q,VEC_CLASSID,4); 3133 3134 ierr = PetscLogEventBegin(TS_FunctionEval,ts,y,q,0);CHKERRQ(ierr); 3135 if (ts->costintegrand) { 3136 PetscStackPush("TS user integrand in the cost function"); 3137 ierr = (*ts->costintegrand)(ts,t,y,q,ts->costintegrandctx);CHKERRQ(ierr); 3138 PetscStackPop; 3139 } else { 3140 ierr = VecZeroEntries(q);CHKERRQ(ierr); 3141 } 3142 3143 ierr = PetscLogEventEnd(TS_FunctionEval,ts,y,q,0);CHKERRQ(ierr); 3144 PetscFunctionReturn(0); 3145 } 3146 3147 /*@ 3148 TSAdjointComputeDRDYFunction - Runs the user-defined DRDY function. 3149 3150 Collective on TS 3151 3152 Input Parameters: 3153 . ts - The TS context obtained from TSCreate() 3154 3155 Notes: 3156 TSAdjointComputeDRDYFunction() is typically used for sensitivity implementation, 3157 so most users would not generally call this routine themselves. 3158 3159 Level: developer 3160 3161 .keywords: TS, sensitivity 3162 .seealso: TSAdjointComputeDRDYFunction() 3163 @*/ 3164 PetscErrorCode TSAdjointComputeDRDYFunction(TS ts,PetscReal t,Vec y,Vec *drdy) 3165 { 3166 PetscErrorCode ierr; 3167 3168 PetscFunctionBegin; 3169 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3170 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3171 3172 PetscStackPush("TS user DRDY function for sensitivity analysis"); 3173 ierr = (*ts->drdyfunction)(ts,t,y,drdy,ts->costintegrandctx); CHKERRQ(ierr); 3174 PetscStackPop; 3175 PetscFunctionReturn(0); 3176 } 3177 3178 /*@ 3179 TSAdjointComputeDRDPFunction - Runs the user-defined DRDP function. 3180 3181 Collective on TS 3182 3183 Input Parameters: 3184 . ts - The TS context obtained from TSCreate() 3185 3186 Notes: 3187 TSDRDPFunction() is typically used for sensitivity implementation, 3188 so most users would not generally call this routine themselves. 3189 3190 Level: developer 3191 3192 .keywords: TS, sensitivity 3193 .seealso: TSAdjointSetDRDPFunction() 3194 @*/ 3195 PetscErrorCode TSAdjointComputeDRDPFunction(TS ts,PetscReal t,Vec y,Vec *drdp) 3196 { 3197 PetscErrorCode ierr; 3198 3199 PetscFunctionBegin; 3200 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3201 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3202 3203 PetscStackPush("TS user DRDP function for sensitivity analysis"); 3204 ierr = (*ts->drdpfunction)(ts,t,y,drdp,ts->costintegrandctx); CHKERRQ(ierr); 3205 PetscStackPop; 3206 PetscFunctionReturn(0); 3207 } 3208 3209 /*@C 3210 TSSetPreStep - Sets the general-purpose function 3211 called once at the beginning of each time step. 3212 3213 Logically Collective on TS 3214 3215 Input Parameters: 3216 + ts - The TS context obtained from TSCreate() 3217 - func - The function 3218 3219 Calling sequence of func: 3220 . func (TS ts); 3221 3222 Level: intermediate 3223 3224 .keywords: TS, timestep 3225 .seealso: TSSetPreStage(), TSSetPostStage(), TSSetPostStep(), TSStep() 3226 @*/ 3227 PetscErrorCode TSSetPreStep(TS ts, PetscErrorCode (*func)(TS)) 3228 { 3229 PetscFunctionBegin; 3230 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3231 ts->prestep = func; 3232 PetscFunctionReturn(0); 3233 } 3234 3235 /*@ 3236 TSPreStep - Runs the user-defined pre-step function. 3237 3238 Collective on TS 3239 3240 Input Parameters: 3241 . ts - The TS context obtained from TSCreate() 3242 3243 Notes: 3244 TSPreStep() is typically used within time stepping implementations, 3245 so most users would not generally call this routine themselves. 3246 3247 Level: developer 3248 3249 .keywords: TS, timestep 3250 .seealso: TSSetPreStep(), TSPreStage(), TSPostStage(), TSPostStep() 3251 @*/ 3252 PetscErrorCode TSPreStep(TS ts) 3253 { 3254 PetscErrorCode ierr; 3255 3256 PetscFunctionBegin; 3257 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3258 if (ts->prestep) { 3259 PetscStackCallStandard((*ts->prestep),(ts)); 3260 } 3261 PetscFunctionReturn(0); 3262 } 3263 3264 /*@C 3265 TSSetPreStage - Sets the general-purpose function 3266 called once at the beginning of each stage. 3267 3268 Logically Collective on TS 3269 3270 Input Parameters: 3271 + ts - The TS context obtained from TSCreate() 3272 - func - The function 3273 3274 Calling sequence of func: 3275 . PetscErrorCode func(TS ts, PetscReal stagetime); 3276 3277 Level: intermediate 3278 3279 Note: 3280 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 3281 The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being 3282 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 3283 3284 .keywords: TS, timestep 3285 .seealso: TSSetPostStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3286 @*/ 3287 PetscErrorCode TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal)) 3288 { 3289 PetscFunctionBegin; 3290 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3291 ts->prestage = func; 3292 PetscFunctionReturn(0); 3293 } 3294 3295 /*@C 3296 TSSetPostStage - Sets the general-purpose function 3297 called once at the end of each stage. 3298 3299 Logically Collective on TS 3300 3301 Input Parameters: 3302 + ts - The TS context obtained from TSCreate() 3303 - func - The function 3304 3305 Calling sequence of func: 3306 . PetscErrorCode func(TS ts, PetscReal stagetime, PetscInt stageindex, Vec* Y); 3307 3308 Level: intermediate 3309 3310 Note: 3311 There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried. 3312 The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being 3313 attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime(). 3314 3315 .keywords: TS, timestep 3316 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3317 @*/ 3318 PetscErrorCode TSSetPostStage(TS ts, PetscErrorCode (*func)(TS,PetscReal,PetscInt,Vec*)) 3319 { 3320 PetscFunctionBegin; 3321 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3322 ts->poststage = func; 3323 PetscFunctionReturn(0); 3324 } 3325 3326 /*@C 3327 TSSetPostEvaluate - Sets the general-purpose function 3328 called once at the end of each step evaluation. 3329 3330 Logically Collective on TS 3331 3332 Input Parameters: 3333 + ts - The TS context obtained from TSCreate() 3334 - func - The function 3335 3336 Calling sequence of func: 3337 . PetscErrorCode func(TS ts); 3338 3339 Level: intermediate 3340 3341 Note: 3342 Semantically, TSSetPostEvaluate() differs from TSSetPostStep() since the function it sets is called before event-handling 3343 thus guaranteeing the same solution (computed by the time-stepper) will be passed to it. On the other hand, TSPostStep() 3344 may be passed a different solution, possibly changed by the event handler. TSPostEvaluate() is called after the next step 3345 solution is evaluated allowing to modify it, if need be. The solution can be obtained with TSGetSolution(), the time step 3346 with TSGetTimeStep(), and the time at the start of the step is available via TSGetTime() 3347 3348 .keywords: TS, timestep 3349 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext() 3350 @*/ 3351 PetscErrorCode TSSetPostEvaluate(TS ts, PetscErrorCode (*func)(TS)) 3352 { 3353 PetscFunctionBegin; 3354 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3355 ts->postevaluate = func; 3356 PetscFunctionReturn(0); 3357 } 3358 3359 /*@ 3360 TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage() 3361 3362 Collective on TS 3363 3364 Input Parameters: 3365 . ts - The TS context obtained from TSCreate() 3366 stagetime - The absolute time of the current stage 3367 3368 Notes: 3369 TSPreStage() is typically used within time stepping implementations, 3370 most users would not generally call this routine themselves. 3371 3372 Level: developer 3373 3374 .keywords: TS, timestep 3375 .seealso: TSPostStage(), TSSetPreStep(), TSPreStep(), TSPostStep() 3376 @*/ 3377 PetscErrorCode TSPreStage(TS ts, PetscReal stagetime) 3378 { 3379 PetscErrorCode ierr; 3380 3381 PetscFunctionBegin; 3382 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3383 if (ts->prestage) { 3384 PetscStackCallStandard((*ts->prestage),(ts,stagetime)); 3385 } 3386 PetscFunctionReturn(0); 3387 } 3388 3389 /*@ 3390 TSPostStage - Runs the user-defined post-stage function set using TSSetPostStage() 3391 3392 Collective on TS 3393 3394 Input Parameters: 3395 . ts - The TS context obtained from TSCreate() 3396 stagetime - The absolute time of the current stage 3397 stageindex - Stage number 3398 Y - Array of vectors (of size = total number 3399 of stages) with the stage solutions 3400 3401 Notes: 3402 TSPostStage() is typically used within time stepping implementations, 3403 most users would not generally call this routine themselves. 3404 3405 Level: developer 3406 3407 .keywords: TS, timestep 3408 .seealso: TSPreStage(), TSSetPreStep(), TSPreStep(), TSPostStep() 3409 @*/ 3410 PetscErrorCode TSPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y) 3411 { 3412 PetscErrorCode ierr; 3413 3414 PetscFunctionBegin; 3415 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3416 if (ts->poststage) { 3417 PetscStackCallStandard((*ts->poststage),(ts,stagetime,stageindex,Y)); 3418 } 3419 PetscFunctionReturn(0); 3420 } 3421 3422 /*@ 3423 TSPostEvaluate - Runs the user-defined post-evaluate function set using TSSetPostEvaluate() 3424 3425 Collective on TS 3426 3427 Input Parameters: 3428 . ts - The TS context obtained from TSCreate() 3429 3430 Notes: 3431 TSPostEvaluate() is typically used within time stepping implementations, 3432 most users would not generally call this routine themselves. 3433 3434 Level: developer 3435 3436 .keywords: TS, timestep 3437 .seealso: TSSetPostEvaluate(), TSSetPreStep(), TSPreStep(), TSPostStep() 3438 @*/ 3439 PetscErrorCode TSPostEvaluate(TS ts) 3440 { 3441 PetscErrorCode ierr; 3442 3443 PetscFunctionBegin; 3444 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3445 if (ts->postevaluate) { 3446 PetscStackCallStandard((*ts->postevaluate),(ts)); 3447 } 3448 PetscFunctionReturn(0); 3449 } 3450 3451 /*@C 3452 TSSetPostStep - Sets the general-purpose function 3453 called once at the end of each time step. 3454 3455 Logically Collective on TS 3456 3457 Input Parameters: 3458 + ts - The TS context obtained from TSCreate() 3459 - func - The function 3460 3461 Calling sequence of func: 3462 $ func (TS ts); 3463 3464 Notes: 3465 The function set by TSSetPostStep() is called after each successful step. The solution vector X 3466 obtained by TSGetSolution() may be different than that computed at the step end if the event handler 3467 locates an event and TSPostEvent() modifies it. Use TSSetPostEvaluate() if an unmodified solution is needed instead. 3468 3469 Level: intermediate 3470 3471 .keywords: TS, timestep 3472 .seealso: TSSetPreStep(), TSSetPreStage(), TSSetPostEvaluate(), TSGetTimeStep(), TSGetTimeStepNumber(), TSGetTime() 3473 @*/ 3474 PetscErrorCode TSSetPostStep(TS ts, PetscErrorCode (*func)(TS)) 3475 { 3476 PetscFunctionBegin; 3477 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 3478 ts->poststep = func; 3479 PetscFunctionReturn(0); 3480 } 3481 3482 /*@ 3483 TSPostStep - Runs the user-defined post-step function. 3484 3485 Collective on TS 3486 3487 Input Parameters: 3488 . ts - The TS context obtained from TSCreate() 3489 3490 Notes: 3491 TSPostStep() is typically used within time stepping implementations, 3492 so most users would not generally call this routine themselves. 3493 3494 Level: developer 3495 3496 .keywords: TS, timestep 3497 @*/ 3498 PetscErrorCode TSPostStep(TS ts) 3499 { 3500 PetscErrorCode ierr; 3501 3502 PetscFunctionBegin; 3503 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3504 if (ts->poststep) { 3505 PetscStackCallStandard((*ts->poststep),(ts)); 3506 } 3507 PetscFunctionReturn(0); 3508 } 3509 3510 /* ------------ Routines to set performance monitoring options ----------- */ 3511 3512 /*@C 3513 TSMonitorSet - Sets an ADDITIONAL function that is to be used at every 3514 timestep to display the iteration's progress. 3515 3516 Logically Collective on TS 3517 3518 Input Parameters: 3519 + ts - the TS context obtained from TSCreate() 3520 . monitor - monitoring routine 3521 . mctx - [optional] user-defined context for private data for the 3522 monitor routine (use NULL if no context is desired) 3523 - monitordestroy - [optional] routine that frees monitor context 3524 (may be NULL) 3525 3526 Calling sequence of monitor: 3527 $ int monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx) 3528 3529 + ts - the TS context 3530 . 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) 3531 . time - current time 3532 . u - current iterate 3533 - mctx - [optional] monitoring context 3534 3535 Notes: 3536 This routine adds an additional monitor to the list of monitors that 3537 already has been loaded. 3538 3539 Fortran notes: Only a single monitor function can be set for each TS object 3540 3541 Level: intermediate 3542 3543 .keywords: TS, timestep, set, monitor 3544 3545 .seealso: TSMonitorDefault(), TSMonitorCancel() 3546 @*/ 3547 PetscErrorCode TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**)) 3548 { 3549 PetscErrorCode ierr; 3550 PetscInt i; 3551 PetscBool identical; 3552 3553 PetscFunctionBegin; 3554 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3555 for (i=0; i<ts->numbermonitors;i++) { 3556 ierr = PetscMonitorCompare((PetscErrorCode (*)(void))monitor,mctx,mdestroy,(PetscErrorCode (*)(void))ts->monitor[i],ts->monitorcontext[i],ts->monitordestroy[i],&identical);CHKERRQ(ierr); 3557 if (identical) PetscFunctionReturn(0); 3558 } 3559 if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3560 ts->monitor[ts->numbermonitors] = monitor; 3561 ts->monitordestroy[ts->numbermonitors] = mdestroy; 3562 ts->monitorcontext[ts->numbermonitors++] = (void*)mctx; 3563 PetscFunctionReturn(0); 3564 } 3565 3566 /*@C 3567 TSMonitorCancel - Clears all the monitors that have been set on a time-step object. 3568 3569 Logically Collective on TS 3570 3571 Input Parameters: 3572 . ts - the TS context obtained from TSCreate() 3573 3574 Notes: 3575 There is no way to remove a single, specific monitor. 3576 3577 Level: intermediate 3578 3579 .keywords: TS, timestep, set, monitor 3580 3581 .seealso: TSMonitorDefault(), TSMonitorSet() 3582 @*/ 3583 PetscErrorCode TSMonitorCancel(TS ts) 3584 { 3585 PetscErrorCode ierr; 3586 PetscInt i; 3587 3588 PetscFunctionBegin; 3589 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3590 for (i=0; i<ts->numbermonitors; i++) { 3591 if (ts->monitordestroy[i]) { 3592 ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr); 3593 } 3594 } 3595 ts->numbermonitors = 0; 3596 PetscFunctionReturn(0); 3597 } 3598 3599 /*@C 3600 TSMonitorDefault - The Default monitor, prints the timestep and time for each step 3601 3602 Level: intermediate 3603 3604 .keywords: TS, set, monitor 3605 3606 .seealso: TSMonitorSet() 3607 @*/ 3608 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf) 3609 { 3610 PetscErrorCode ierr; 3611 PetscViewer viewer = vf->viewer; 3612 PetscBool iascii,ibinary; 3613 3614 PetscFunctionBegin; 3615 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 3616 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 3617 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 3618 ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr); 3619 if (iascii) { 3620 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3621 if (step == -1){ /* this indicates it is an interpolated solution */ 3622 ierr = PetscViewerASCIIPrintf(viewer,"Interpolated solution at time %g between steps %D and %D\n",(double)ptime,ts->steps-1,ts->steps);CHKERRQ(ierr); 3623 } else { 3624 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr); 3625 } 3626 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3627 } else if (ibinary) { 3628 PetscMPIInt rank; 3629 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 3630 if (!rank) { 3631 PetscBool skipHeader; 3632 PetscInt classid = REAL_FILE_CLASSID; 3633 3634 ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr); 3635 if (!skipHeader) { 3636 ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 3637 } 3638 ierr = PetscRealView(1,&ptime,viewer);CHKERRQ(ierr); 3639 } else { 3640 ierr = PetscRealView(0,&ptime,viewer);CHKERRQ(ierr); 3641 } 3642 } 3643 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 3644 PetscFunctionReturn(0); 3645 } 3646 3647 /*@C 3648 TSAdjointMonitorSet - Sets an ADDITIONAL function that is to be used at every 3649 timestep to display the iteration's progress. 3650 3651 Logically Collective on TS 3652 3653 Input Parameters: 3654 + ts - the TS context obtained from TSCreate() 3655 . adjointmonitor - monitoring routine 3656 . adjointmctx - [optional] user-defined context for private data for the 3657 monitor routine (use NULL if no context is desired) 3658 - adjointmonitordestroy - [optional] routine that frees monitor context 3659 (may be NULL) 3660 3661 Calling sequence of monitor: 3662 $ int adjointmonitor(TS ts,PetscInt steps,PetscReal time,Vec u,PetscInt numcost,Vec *lambda, Vec *mu,void *adjointmctx) 3663 3664 + ts - the TS context 3665 . 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 3666 been interpolated to) 3667 . time - current time 3668 . u - current iterate 3669 . numcost - number of cost functionos 3670 . lambda - sensitivities to initial conditions 3671 . mu - sensitivities to parameters 3672 - adjointmctx - [optional] adjoint monitoring context 3673 3674 Notes: 3675 This routine adds an additional monitor to the list of monitors that 3676 already has been loaded. 3677 3678 Fortran notes: Only a single monitor function can be set for each TS object 3679 3680 Level: intermediate 3681 3682 .keywords: TS, timestep, set, adjoint, monitor 3683 3684 .seealso: TSAdjointMonitorCancel() 3685 @*/ 3686 PetscErrorCode TSAdjointMonitorSet(TS ts,PetscErrorCode (*adjointmonitor)(TS,PetscInt,PetscReal,Vec,PetscInt,Vec*,Vec*,void*),void *adjointmctx,PetscErrorCode (*adjointmdestroy)(void**)) 3687 { 3688 PetscErrorCode ierr; 3689 PetscInt i; 3690 PetscBool identical; 3691 3692 PetscFunctionBegin; 3693 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3694 for (i=0; i<ts->numbermonitors;i++) { 3695 ierr = PetscMonitorCompare((PetscErrorCode (*)(void))adjointmonitor,adjointmctx,adjointmdestroy,(PetscErrorCode (*)(void))ts->adjointmonitor[i],ts->adjointmonitorcontext[i],ts->adjointmonitordestroy[i],&identical);CHKERRQ(ierr); 3696 if (identical) PetscFunctionReturn(0); 3697 } 3698 if (ts->numberadjointmonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many adjoint monitors set"); 3699 ts->adjointmonitor[ts->numberadjointmonitors] = adjointmonitor; 3700 ts->adjointmonitordestroy[ts->numberadjointmonitors] = adjointmdestroy; 3701 ts->adjointmonitorcontext[ts->numberadjointmonitors++] = (void*)adjointmctx; 3702 PetscFunctionReturn(0); 3703 } 3704 3705 /*@C 3706 TSAdjointMonitorCancel - Clears all the adjoint monitors that have been set on a time-step object. 3707 3708 Logically Collective on TS 3709 3710 Input Parameters: 3711 . ts - the TS context obtained from TSCreate() 3712 3713 Notes: 3714 There is no way to remove a single, specific monitor. 3715 3716 Level: intermediate 3717 3718 .keywords: TS, timestep, set, adjoint, monitor 3719 3720 .seealso: TSAdjointMonitorSet() 3721 @*/ 3722 PetscErrorCode TSAdjointMonitorCancel(TS ts) 3723 { 3724 PetscErrorCode ierr; 3725 PetscInt i; 3726 3727 PetscFunctionBegin; 3728 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3729 for (i=0; i<ts->numberadjointmonitors; i++) { 3730 if (ts->adjointmonitordestroy[i]) { 3731 ierr = (*ts->adjointmonitordestroy[i])(&ts->adjointmonitorcontext[i]);CHKERRQ(ierr); 3732 } 3733 } 3734 ts->numberadjointmonitors = 0; 3735 PetscFunctionReturn(0); 3736 } 3737 3738 /*@C 3739 TSAdjointMonitorDefault - the default monitor of adjoint computations 3740 3741 Level: intermediate 3742 3743 .keywords: TS, set, monitor 3744 3745 .seealso: TSAdjointMonitorSet() 3746 @*/ 3747 PetscErrorCode TSAdjointMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscInt numcost,Vec *lambda,Vec *mu,PetscViewerAndFormat *vf) 3748 { 3749 PetscErrorCode ierr; 3750 PetscViewer viewer = vf->viewer; 3751 3752 PetscFunctionBegin; 3753 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 3754 ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr); 3755 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3756 ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr); 3757 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr); 3758 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 3759 PetscFunctionReturn(0); 3760 } 3761 3762 /*@ 3763 TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval 3764 3765 Collective on TS 3766 3767 Input Argument: 3768 + ts - time stepping context 3769 - t - time to interpolate to 3770 3771 Output Argument: 3772 . U - state at given time 3773 3774 Level: intermediate 3775 3776 Developer Notes: 3777 TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints. 3778 3779 .keywords: TS, set 3780 3781 .seealso: TSSetExactFinalTime(), TSSolve() 3782 @*/ 3783 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U) 3784 { 3785 PetscErrorCode ierr; 3786 3787 PetscFunctionBegin; 3788 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3789 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 3790 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); 3791 if (!ts->ops->interpolate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name); 3792 ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr); 3793 PetscFunctionReturn(0); 3794 } 3795 3796 /*@ 3797 TSStep - Steps one time step 3798 3799 Collective on TS 3800 3801 Input Parameter: 3802 . ts - the TS context obtained from TSCreate() 3803 3804 Level: developer 3805 3806 Notes: 3807 The public interface for the ODE/DAE solvers is TSSolve(), you should almost for sure be using that routine and not this routine. 3808 3809 The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may 3810 be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages. 3811 3812 This may over-step the final time provided in TSSetDuration() depending on the time-step used. TSSolve() interpolates to exactly the 3813 time provided in TSSetDuration(). One can use TSInterpolate() to determine an interpolated solution within the final timestep. 3814 3815 .keywords: TS, timestep, solve 3816 3817 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSInterpolate() 3818 @*/ 3819 PetscErrorCode TSStep(TS ts) 3820 { 3821 PetscErrorCode ierr; 3822 static PetscBool cite = PETSC_FALSE; 3823 PetscReal ptime; 3824 3825 PetscFunctionBegin; 3826 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3827 ierr = PetscCitationsRegister("@techreport{tspaper,\n" 3828 " title = {{PETSc/TS}: A Modern Scalable {DAE/ODE} Solver Library},\n" 3829 " author = {Shrirang Abhyankar and Jed Brown and Emil Constantinescu and Debojyoti Ghosh and Barry F. Smith},\n" 3830 " type = {Preprint},\n" 3831 " number = {ANL/MCS-P5061-0114},\n" 3832 " institution = {Argonne National Laboratory},\n" 3833 " year = {2014}\n}\n",&cite);CHKERRQ(ierr); 3834 3835 ierr = TSSetUp(ts);CHKERRQ(ierr); 3836 ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr); 3837 3838 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()"); 3839 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"); 3840 3841 if (!ts->steps) ts->ptime_prev = ts->ptime; 3842 ts->reason = TS_CONVERGED_ITERATING; 3843 ptime = ts->ptime; ts->ptime_prev_rollback = ts->ptime_prev; 3844 if (!ts->ops->step) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSStep not implemented for type '%s'",((PetscObject)ts)->type_name); 3845 ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3846 ierr = (*ts->ops->step)(ts);CHKERRQ(ierr); 3847 ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr); 3848 ts->ptime_prev = ptime; 3849 ts->steps++; ts->total_steps++; 3850 ts->steprollback = PETSC_FALSE; 3851 ts->steprestart = PETSC_FALSE; 3852 3853 if (ts->reason < 0) { 3854 if (ts->errorifstepfailed) { 3855 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]); 3856 else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]); 3857 } 3858 } else if (!ts->reason) { 3859 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 3860 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 3861 } 3862 PetscFunctionReturn(0); 3863 } 3864 3865 /*@ 3866 TSAdjointStep - Steps one time step backward in the adjoint run 3867 3868 Collective on TS 3869 3870 Input Parameter: 3871 . ts - the TS context obtained from TSCreate() 3872 3873 Level: intermediate 3874 3875 .keywords: TS, adjoint, step 3876 3877 .seealso: TSAdjointSetUp(), TSAdjointSolve() 3878 @*/ 3879 PetscErrorCode TSAdjointStep(TS ts) 3880 { 3881 DM dm; 3882 PetscErrorCode ierr; 3883 3884 PetscFunctionBegin; 3885 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3886 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 3887 ierr = TSAdjointSetUp(ts);CHKERRQ(ierr); 3888 3889 ierr = VecViewFromOptions(ts->vec_sol,(PetscObject)ts,"-ts_view_solution");CHKERRQ(ierr); 3890 3891 ts->reason = TS_CONVERGED_ITERATING; 3892 ts->ptime_prev = ts->ptime; 3893 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); 3894 ierr = PetscLogEventBegin(TS_AdjointStep,ts,0,0,0);CHKERRQ(ierr); 3895 ierr = (*ts->ops->adjointstep)(ts);CHKERRQ(ierr); 3896 ierr = PetscLogEventEnd(TS_AdjointStep,ts,0,0,0);CHKERRQ(ierr); 3897 ts->steps++; ts->total_steps--; 3898 3899 if (ts->reason < 0) { 3900 if (ts->errorifstepfailed) { 3901 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]); 3902 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]); 3903 else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]); 3904 } 3905 } else if (!ts->reason) { 3906 if (ts->steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS; 3907 } 3908 PetscFunctionReturn(0); 3909 } 3910 3911 /*@ 3912 TSEvaluateWLTE - Evaluate the weighted local truncation error norm 3913 at the end of a time step with a given order of accuracy. 3914 3915 Collective on TS 3916 3917 Input Arguments: 3918 + ts - time stepping context 3919 . wnormtype - norm type, either NORM_2 or NORM_INFINITY 3920 - order - optional, desired order for the error evaluation or PETSC_DECIDE 3921 3922 Output Arguments: 3923 + order - optional, the actual order of the error evaluation 3924 - wlte - the weighted local truncation error norm 3925 3926 Level: advanced 3927 3928 Notes: 3929 If the timestepper cannot evaluate the error in a particular step 3930 (eg. in the first step or restart steps after event handling), 3931 this routine returns wlte=-1.0 . 3932 3933 .seealso: TSStep(), TSAdapt, TSErrorWeightedNorm() 3934 @*/ 3935 PetscErrorCode TSEvaluateWLTE(TS ts,NormType wnormtype,PetscInt *order,PetscReal *wlte) 3936 { 3937 PetscErrorCode ierr; 3938 3939 PetscFunctionBegin; 3940 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3941 PetscValidType(ts,1); 3942 PetscValidLogicalCollectiveEnum(ts,wnormtype,4); 3943 if (order) PetscValidIntPointer(order,3); 3944 if (order) PetscValidLogicalCollectiveInt(ts,*order,3); 3945 PetscValidRealPointer(wlte,4); 3946 if (wnormtype != NORM_2 && wnormtype != NORM_INFINITY) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 3947 if (!ts->ops->evaluatewlte) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateWLTE not implemented for type '%s'",((PetscObject)ts)->type_name); 3948 ierr = (*ts->ops->evaluatewlte)(ts,wnormtype,order,wlte);CHKERRQ(ierr); 3949 PetscFunctionReturn(0); 3950 } 3951 3952 /*@ 3953 TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy. 3954 3955 Collective on TS 3956 3957 Input Arguments: 3958 + ts - time stepping context 3959 . order - desired order of accuracy 3960 - done - whether the step was evaluated at this order (pass NULL to generate an error if not available) 3961 3962 Output Arguments: 3963 . U - state at the end of the current step 3964 3965 Level: advanced 3966 3967 Notes: 3968 This function cannot be called until all stages have been evaluated. 3969 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. 3970 3971 .seealso: TSStep(), TSAdapt 3972 @*/ 3973 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done) 3974 { 3975 PetscErrorCode ierr; 3976 3977 PetscFunctionBegin; 3978 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 3979 PetscValidType(ts,1); 3980 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 3981 if (!ts->ops->evaluatestep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name); 3982 ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr); 3983 PetscFunctionReturn(0); 3984 } 3985 3986 /*@ 3987 TSForwardCostIntegral - Evaluate the cost integral in the forward run. 3988 3989 Collective on TS 3990 3991 Input Arguments: 3992 . ts - time stepping context 3993 3994 Level: advanced 3995 3996 Notes: 3997 This function cannot be called until TSStep() has been completed. 3998 3999 .seealso: TSSolve(), TSAdjointCostIntegral() 4000 @*/ 4001 PetscErrorCode TSForwardCostIntegral(TS ts) 4002 { 4003 PetscErrorCode ierr; 4004 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4005 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); 4006 ierr = (*ts->ops->forwardintegral)(ts);CHKERRQ(ierr); 4007 PetscFunctionReturn(0); 4008 } 4009 4010 /*@ 4011 TSSolve - Steps the requested number of timesteps. 4012 4013 Collective on TS 4014 4015 Input Parameter: 4016 + ts - the TS context obtained from TSCreate() 4017 - u - the solution vector (can be null if TSSetSolution() was used and TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP) was not used, 4018 otherwise must contain the initial conditions and will contain the solution at the final requested time 4019 4020 Level: beginner 4021 4022 Notes: 4023 The final time returned by this function may be different from the time of the internally 4024 held state accessible by TSGetSolution() and TSGetTime() because the method may have 4025 stepped over the final time. 4026 4027 .keywords: TS, timestep, solve 4028 4029 .seealso: TSCreate(), TSSetSolution(), TSStep(), TSGetTime(), TSGetSolveTime() 4030 @*/ 4031 PetscErrorCode TSSolve(TS ts,Vec u) 4032 { 4033 Vec solution; 4034 PetscErrorCode ierr; 4035 4036 PetscFunctionBegin; 4037 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4038 if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2); 4039 4040 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 */ 4041 PetscValidHeaderSpecific(u,VEC_CLASSID,2); 4042 if (!ts->vec_sol || u == ts->vec_sol) { 4043 ierr = VecDuplicate(u,&solution);CHKERRQ(ierr); 4044 ierr = TSSetSolution(ts,solution);CHKERRQ(ierr); 4045 ierr = VecDestroy(&solution);CHKERRQ(ierr); /* grant ownership */ 4046 } 4047 ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr); 4048 } else if (u) { 4049 ierr = TSSetSolution(ts,u);CHKERRQ(ierr); 4050 } 4051 ierr = TSSetUp(ts);CHKERRQ(ierr); 4052 ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr); 4053 4054 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()"); 4055 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"); 4056 4057 /* reset number of steps only when the step is not restarted. ARKIMEX 4058 restarts the step after an event. Resetting these counters in such a case causes 4059 TSTrajectory to incorrectly save the output files 4060 */ 4061 4062 ts->steps = 0; 4063 ts->ksp_its = 0; 4064 ts->snes_its = 0; 4065 ts->num_snes_failures = 0; 4066 ts->reject = 0; 4067 ts->reason = TS_CONVERGED_ITERATING; 4068 4069 ierr = TSViewFromOptions(ts,NULL,"-ts_view_pre");CHKERRQ(ierr); 4070 4071 if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */ 4072 ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr); 4073 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 4074 ts->solvetime = ts->ptime; 4075 solution = ts->vec_sol; 4076 } else { /* Step the requested number of timesteps. */ 4077 if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS; 4078 else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME; 4079 4080 ierr = TSTrajectorySet(ts->trajectory,ts,ts->total_steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4081 ierr = TSEventInitialize(ts->event,ts,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4082 4083 ts->steprollback = PETSC_FALSE; 4084 ts->steprestart = PETSC_TRUE; 4085 4086 while (!ts->reason) { 4087 ierr = TSMonitor(ts,ts->total_steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4088 if (!ts->steprollback) { 4089 ierr = TSPreStep(ts);CHKERRQ(ierr); 4090 } 4091 ierr = TSStep(ts);CHKERRQ(ierr); 4092 if (ts->vec_costintegral && ts->costintegralfwd) { /* Must evaluate the cost integral before event is handled. The cost integral value can also be rolled back. */ 4093 ierr = TSForwardCostIntegral(ts);CHKERRQ(ierr); 4094 } 4095 ierr = TSPostEvaluate(ts);CHKERRQ(ierr); 4096 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. */ 4097 if (!ts->steprollback) { 4098 ierr = TSTrajectorySet(ts->trajectory,ts,ts->total_steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4099 ierr = TSPostStep(ts);CHKERRQ(ierr); 4100 } 4101 } 4102 ierr = TSMonitor(ts,ts->total_steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 4103 4104 if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) { 4105 ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr); 4106 ts->solvetime = ts->max_time; 4107 solution = u; 4108 ierr = TSMonitor(ts,-1,ts->solvetime,solution);CHKERRQ(ierr); 4109 } else { 4110 if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);} 4111 ts->solvetime = ts->ptime; 4112 solution = ts->vec_sol; 4113 } 4114 } 4115 4116 ierr = TSViewFromOptions(ts,NULL,"-ts_view");CHKERRQ(ierr); 4117 ierr = VecViewFromOptions(solution,NULL,"-ts_view_solution");CHKERRQ(ierr); 4118 ierr = PetscObjectSAWsBlock((PetscObject)ts);CHKERRQ(ierr); 4119 if (ts->adjoint_solve) { 4120 ierr = TSAdjointSolve(ts);CHKERRQ(ierr); 4121 } 4122 PetscFunctionReturn(0); 4123 } 4124 4125 /*@ 4126 TSAdjointCostIntegral - Evaluate the cost integral in the adjoint run. 4127 4128 Collective on TS 4129 4130 Input Arguments: 4131 . ts - time stepping context 4132 4133 Level: advanced 4134 4135 Notes: 4136 This function cannot be called until TSAdjointStep() has been completed. 4137 4138 .seealso: TSAdjointSolve(), TSAdjointStep 4139 @*/ 4140 PetscErrorCode TSAdjointCostIntegral(TS ts) 4141 { 4142 PetscErrorCode ierr; 4143 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4144 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); 4145 ierr = (*ts->ops->adjointintegral)(ts);CHKERRQ(ierr); 4146 PetscFunctionReturn(0); 4147 } 4148 4149 /*@ 4150 TSAdjointSolve - Solves the discrete ajoint problem for an ODE/DAE 4151 4152 Collective on TS 4153 4154 Input Parameter: 4155 . ts - the TS context obtained from TSCreate() 4156 4157 Options Database: 4158 . -ts_adjoint_view_solution <viewerinfo> - views the first gradient with respect to the initial conditions 4159 4160 Level: intermediate 4161 4162 Notes: 4163 This must be called after a call to TSSolve() that solves the forward problem 4164 4165 By default this will integrate back to the initial time, one can use TSAdjointSetSteps() to step back to a later time 4166 4167 .keywords: TS, timestep, solve 4168 4169 .seealso: TSCreate(), TSSetCostGradients(), TSSetSolution(), TSAdjointStep() 4170 @*/ 4171 PetscErrorCode TSAdjointSolve(TS ts) 4172 { 4173 PetscErrorCode ierr; 4174 4175 PetscFunctionBegin; 4176 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4177 ierr = TSAdjointSetUp(ts);CHKERRQ(ierr); 4178 4179 /* reset time step and iteration counters */ 4180 ts->steps = 0; 4181 ts->ksp_its = 0; 4182 ts->snes_its = 0; 4183 ts->num_snes_failures = 0; 4184 ts->reject = 0; 4185 ts->reason = TS_CONVERGED_ITERATING; 4186 4187 if (!ts->adjoint_max_steps) ts->adjoint_max_steps = ts->total_steps; 4188 4189 if (ts->steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS; 4190 while (!ts->reason) { 4191 ierr = TSTrajectoryGet(ts->trajectory,ts,ts->total_steps,&ts->ptime);CHKERRQ(ierr); 4192 ierr = TSAdjointMonitor(ts,ts->total_steps,ts->ptime,ts->vec_sol,ts->numcost,ts->vecs_sensi,ts->vecs_sensip);CHKERRQ(ierr); 4193 ierr = TSAdjointEventHandler(ts);CHKERRQ(ierr); 4194 ierr = TSAdjointStep(ts);CHKERRQ(ierr); 4195 if (ts->vec_costintegral && !ts->costintegralfwd) { 4196 ierr = TSAdjointCostIntegral(ts);CHKERRQ(ierr); 4197 } 4198 } 4199 ierr = TSTrajectoryGet(ts->trajectory,ts,ts->total_steps,&ts->ptime);CHKERRQ(ierr); 4200 ierr = TSAdjointMonitor(ts,ts->total_steps,ts->ptime,ts->vec_sol,ts->numcost,ts->vecs_sensi,ts->vecs_sensip);CHKERRQ(ierr); 4201 ts->solvetime = ts->ptime; 4202 ierr = TSTrajectoryViewFromOptions(ts->trajectory,NULL,"-ts_trajectory_view");CHKERRQ(ierr); 4203 ierr = VecViewFromOptions(ts->vecs_sensi[0],(PetscObject) ts, "-ts_adjoint_view_solution");CHKERRQ(ierr); 4204 PetscFunctionReturn(0); 4205 } 4206 4207 /*@C 4208 TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet() 4209 4210 Collective on TS 4211 4212 Input Parameters: 4213 + ts - time stepping context obtained from TSCreate() 4214 . step - step number that has just completed 4215 . ptime - model time of the state 4216 - u - state at the current model time 4217 4218 Notes: 4219 TSMonitor() is typically used automatically within the time stepping implementations. 4220 Users would almost never call this routine directly. 4221 4222 A step of -1 indicates that the monitor is being called on a solution obtained by interpolating from computed solutions 4223 4224 Level: developer 4225 4226 .keywords: TS, timestep 4227 @*/ 4228 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u) 4229 { 4230 DM dm; 4231 PetscInt i,n = ts->numbermonitors; 4232 PetscErrorCode ierr; 4233 4234 PetscFunctionBegin; 4235 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4236 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 4237 4238 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4239 ierr = DMSetOutputSequenceNumber(dm,step,ptime);CHKERRQ(ierr); 4240 4241 ierr = VecLockPush(u);CHKERRQ(ierr); 4242 for (i=0; i<n; i++) { 4243 ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr); 4244 } 4245 ierr = VecLockPop(u);CHKERRQ(ierr); 4246 PetscFunctionReturn(0); 4247 } 4248 4249 /*@C 4250 TSAdjointMonitor - Runs all user-provided adjoint monitor routines set using TSAdjointMonitorSet() 4251 4252 Collective on TS 4253 4254 Input Parameters: 4255 + ts - time stepping context obtained from TSCreate() 4256 . step - step number that has just completed 4257 . ptime - model time of the state 4258 . u - state at the current model time 4259 . numcost - number of cost functions (dimension of lambda or mu) 4260 . lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables 4261 - mu - vectors containing the gradients of the cost functions with respect to the problem parameters 4262 4263 Notes: 4264 TSAdjointMonitor() is typically used automatically within the time stepping implementations. 4265 Users would almost never call this routine directly. 4266 4267 Level: developer 4268 4269 .keywords: TS, timestep 4270 @*/ 4271 PetscErrorCode TSAdjointMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda, Vec *mu) 4272 { 4273 PetscErrorCode ierr; 4274 PetscInt i,n = ts->numberadjointmonitors; 4275 4276 PetscFunctionBegin; 4277 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4278 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 4279 ierr = VecLockPush(u);CHKERRQ(ierr); 4280 for (i=0; i<n; i++) { 4281 ierr = (*ts->adjointmonitor[i])(ts,step,ptime,u,numcost,lambda,mu,ts->adjointmonitorcontext[i]);CHKERRQ(ierr); 4282 } 4283 ierr = VecLockPop(u);CHKERRQ(ierr); 4284 PetscFunctionReturn(0); 4285 } 4286 4287 /* ------------------------------------------------------------------------*/ 4288 /*@C 4289 TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with 4290 TS to monitor the solution process graphically in various ways 4291 4292 Collective on TS 4293 4294 Input Parameters: 4295 + host - the X display to open, or null for the local machine 4296 . label - the title to put in the title bar 4297 . x, y - the screen coordinates of the upper left coordinate of the window 4298 . m, n - the screen width and height in pixels 4299 - howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time 4300 4301 Output Parameter: 4302 . ctx - the context 4303 4304 Options Database Key: 4305 + -ts_monitor_lg_timestep - automatically sets line graph monitor 4306 . -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables()) 4307 . -ts_monitor_lg_error - monitor the error 4308 . -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep 4309 . -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep 4310 - -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true 4311 4312 Notes: 4313 Use TSMonitorLGCtxDestroy() to destroy. 4314 4315 One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform() 4316 4317 Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a TS object as the 4318 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 4319 as the first argument. 4320 4321 One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames() 4322 4323 4324 Level: intermediate 4325 4326 .keywords: TS, monitor, line graph, residual 4327 4328 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError(), TSMonitorDefault(), VecView(), 4329 TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(), 4330 TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(), 4331 TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(), 4332 TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop() 4333 4334 @*/ 4335 PetscErrorCode TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx) 4336 { 4337 PetscDraw draw; 4338 PetscErrorCode ierr; 4339 4340 PetscFunctionBegin; 4341 ierr = PetscNew(ctx);CHKERRQ(ierr); 4342 ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr); 4343 ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr); 4344 ierr = PetscDrawLGCreate(draw,1,&(*ctx)->lg);CHKERRQ(ierr); 4345 ierr = PetscDrawLGSetFromOptions((*ctx)->lg);CHKERRQ(ierr); 4346 ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 4347 (*ctx)->howoften = howoften; 4348 PetscFunctionReturn(0); 4349 } 4350 4351 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx) 4352 { 4353 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 4354 PetscReal x = ptime,y; 4355 PetscErrorCode ierr; 4356 4357 PetscFunctionBegin; 4358 if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */ 4359 if (!step) { 4360 PetscDrawAxis axis; 4361 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 4362 ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time","Time Step");CHKERRQ(ierr); 4363 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 4364 } 4365 ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr); 4366 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 4367 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 4368 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 4369 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 4370 } 4371 PetscFunctionReturn(0); 4372 } 4373 4374 /*@C 4375 TSMonitorLGCtxDestroy - Destroys a line graph context that was created 4376 with TSMonitorLGCtxCreate(). 4377 4378 Collective on TSMonitorLGCtx 4379 4380 Input Parameter: 4381 . ctx - the monitor context 4382 4383 Level: intermediate 4384 4385 .keywords: TS, monitor, line graph, destroy 4386 4387 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep(); 4388 @*/ 4389 PetscErrorCode TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx) 4390 { 4391 PetscErrorCode ierr; 4392 4393 PetscFunctionBegin; 4394 if ((*ctx)->transformdestroy) { 4395 ierr = ((*ctx)->transformdestroy)((*ctx)->transformctx);CHKERRQ(ierr); 4396 } 4397 ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr); 4398 ierr = PetscStrArrayDestroy(&(*ctx)->names);CHKERRQ(ierr); 4399 ierr = PetscStrArrayDestroy(&(*ctx)->displaynames);CHKERRQ(ierr); 4400 ierr = PetscFree((*ctx)->displayvariables);CHKERRQ(ierr); 4401 ierr = PetscFree((*ctx)->displayvalues);CHKERRQ(ierr); 4402 ierr = PetscFree(*ctx);CHKERRQ(ierr); 4403 PetscFunctionReturn(0); 4404 } 4405 4406 /*@ 4407 TSGetTime - Gets the time of the most recently completed step. 4408 4409 Not Collective 4410 4411 Input Parameter: 4412 . ts - the TS context obtained from TSCreate() 4413 4414 Output Parameter: 4415 . t - the current time. This time may not corresponds to the final time set with TSSetDuration(), use TSGetSolveTime(). 4416 4417 Level: beginner 4418 4419 Note: 4420 When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(), 4421 TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated. 4422 4423 .seealso: TSSetInitialTimeStep(), TSGetTimeStep(), TSGetSolveTime() 4424 4425 .keywords: TS, get, time 4426 @*/ 4427 PetscErrorCode TSGetTime(TS ts,PetscReal *t) 4428 { 4429 PetscFunctionBegin; 4430 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4431 PetscValidRealPointer(t,2); 4432 *t = ts->ptime; 4433 PetscFunctionReturn(0); 4434 } 4435 4436 /*@ 4437 TSGetPrevTime - Gets the starting time of the previously completed step. 4438 4439 Not Collective 4440 4441 Input Parameter: 4442 . ts - the TS context obtained from TSCreate() 4443 4444 Output Parameter: 4445 . t - the previous time 4446 4447 Level: beginner 4448 4449 .seealso: TSSetInitialTimeStep(), TSGetTimeStep() 4450 4451 .keywords: TS, get, time 4452 @*/ 4453 PetscErrorCode TSGetPrevTime(TS ts,PetscReal *t) 4454 { 4455 PetscFunctionBegin; 4456 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4457 PetscValidRealPointer(t,2); 4458 *t = ts->ptime_prev; 4459 PetscFunctionReturn(0); 4460 } 4461 4462 /*@ 4463 TSSetTime - Allows one to reset the time. 4464 4465 Logically Collective on TS 4466 4467 Input Parameters: 4468 + ts - the TS context obtained from TSCreate() 4469 - time - the time 4470 4471 Level: intermediate 4472 4473 .seealso: TSGetTime(), TSSetDuration() 4474 4475 .keywords: TS, set, time 4476 @*/ 4477 PetscErrorCode TSSetTime(TS ts, PetscReal t) 4478 { 4479 PetscFunctionBegin; 4480 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4481 PetscValidLogicalCollectiveReal(ts,t,2); 4482 ts->ptime = t; 4483 PetscFunctionReturn(0); 4484 } 4485 4486 /*@C 4487 TSSetOptionsPrefix - Sets the prefix used for searching for all 4488 TS options in the database. 4489 4490 Logically Collective on TS 4491 4492 Input Parameter: 4493 + ts - The TS context 4494 - prefix - The prefix to prepend to all option names 4495 4496 Notes: 4497 A hyphen (-) must NOT be given at the beginning of the prefix name. 4498 The first character of all runtime options is AUTOMATICALLY the 4499 hyphen. 4500 4501 Level: advanced 4502 4503 .keywords: TS, set, options, prefix, database 4504 4505 .seealso: TSSetFromOptions() 4506 4507 @*/ 4508 PetscErrorCode TSSetOptionsPrefix(TS ts,const char prefix[]) 4509 { 4510 PetscErrorCode ierr; 4511 SNES snes; 4512 4513 PetscFunctionBegin; 4514 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4515 ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4516 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4517 ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4518 PetscFunctionReturn(0); 4519 } 4520 4521 4522 /*@C 4523 TSAppendOptionsPrefix - Appends to the prefix used for searching for all 4524 TS options in the database. 4525 4526 Logically Collective on TS 4527 4528 Input Parameter: 4529 + ts - The TS context 4530 - prefix - The prefix to prepend to all option names 4531 4532 Notes: 4533 A hyphen (-) must NOT be given at the beginning of the prefix name. 4534 The first character of all runtime options is AUTOMATICALLY the 4535 hyphen. 4536 4537 Level: advanced 4538 4539 .keywords: TS, append, options, prefix, database 4540 4541 .seealso: TSGetOptionsPrefix() 4542 4543 @*/ 4544 PetscErrorCode TSAppendOptionsPrefix(TS ts,const char prefix[]) 4545 { 4546 PetscErrorCode ierr; 4547 SNES snes; 4548 4549 PetscFunctionBegin; 4550 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4551 ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4552 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4553 ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr); 4554 PetscFunctionReturn(0); 4555 } 4556 4557 /*@C 4558 TSGetOptionsPrefix - Sets the prefix used for searching for all 4559 TS options in the database. 4560 4561 Not Collective 4562 4563 Input Parameter: 4564 . ts - The TS context 4565 4566 Output Parameter: 4567 . prefix - A pointer to the prefix string used 4568 4569 Notes: On the fortran side, the user should pass in a string 'prifix' of 4570 sufficient length to hold the prefix. 4571 4572 Level: intermediate 4573 4574 .keywords: TS, get, options, prefix, database 4575 4576 .seealso: TSAppendOptionsPrefix() 4577 @*/ 4578 PetscErrorCode TSGetOptionsPrefix(TS ts,const char *prefix[]) 4579 { 4580 PetscErrorCode ierr; 4581 4582 PetscFunctionBegin; 4583 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4584 PetscValidPointer(prefix,2); 4585 ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr); 4586 PetscFunctionReturn(0); 4587 } 4588 4589 /*@C 4590 TSGetRHSJacobian - Returns the Jacobian J at the present timestep. 4591 4592 Not Collective, but parallel objects are returned if TS is parallel 4593 4594 Input Parameter: 4595 . ts - The TS context obtained from TSCreate() 4596 4597 Output Parameters: 4598 + Amat - The (approximate) Jacobian J of G, where U_t = G(U,t) (or NULL) 4599 . Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat (or NULL) 4600 . func - Function to compute the Jacobian of the RHS (or NULL) 4601 - ctx - User-defined context for Jacobian evaluation routine (or NULL) 4602 4603 Notes: You can pass in NULL for any return argument you do not need. 4604 4605 Level: intermediate 4606 4607 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 4608 4609 .keywords: TS, timestep, get, matrix, Jacobian 4610 @*/ 4611 PetscErrorCode TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx) 4612 { 4613 PetscErrorCode ierr; 4614 DM dm; 4615 4616 PetscFunctionBegin; 4617 if (Amat || Pmat) { 4618 SNES snes; 4619 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4620 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4621 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4622 } 4623 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4624 ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr); 4625 PetscFunctionReturn(0); 4626 } 4627 4628 /*@C 4629 TSGetIJacobian - Returns the implicit Jacobian at the present timestep. 4630 4631 Not Collective, but parallel objects are returned if TS is parallel 4632 4633 Input Parameter: 4634 . ts - The TS context obtained from TSCreate() 4635 4636 Output Parameters: 4637 + Amat - The (approximate) Jacobian of F(t,U,U_t) 4638 . Pmat - The matrix from which the preconditioner is constructed, often the same as Amat 4639 . f - The function to compute the matrices 4640 - ctx - User-defined context for Jacobian evaluation routine 4641 4642 Notes: You can pass in NULL for any return argument you do not need. 4643 4644 Level: advanced 4645 4646 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber() 4647 4648 .keywords: TS, timestep, get, matrix, Jacobian 4649 @*/ 4650 PetscErrorCode TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx) 4651 { 4652 PetscErrorCode ierr; 4653 DM dm; 4654 4655 PetscFunctionBegin; 4656 if (Amat || Pmat) { 4657 SNES snes; 4658 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4659 ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr); 4660 ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr); 4661 } 4662 ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 4663 ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr); 4664 PetscFunctionReturn(0); 4665 } 4666 4667 4668 /*@C 4669 TSMonitorDrawSolution - Monitors progress of the TS solvers by calling 4670 VecView() for the solution at each timestep 4671 4672 Collective on TS 4673 4674 Input Parameters: 4675 + ts - the TS context 4676 . step - current time-step 4677 . ptime - current time 4678 - dummy - either a viewer or NULL 4679 4680 Options Database: 4681 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 4682 4683 Notes: the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial 4684 will look bad 4685 4686 Level: intermediate 4687 4688 .keywords: TS, vector, monitor, view 4689 4690 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4691 @*/ 4692 PetscErrorCode TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4693 { 4694 PetscErrorCode ierr; 4695 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 4696 PetscDraw draw; 4697 4698 PetscFunctionBegin; 4699 if (!step && ictx->showinitial) { 4700 if (!ictx->initialsolution) { 4701 ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr); 4702 } 4703 ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr); 4704 } 4705 if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4706 4707 if (ictx->showinitial) { 4708 PetscReal pause; 4709 ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr); 4710 ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr); 4711 ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr); 4712 ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr); 4713 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr); 4714 } 4715 ierr = VecView(u,ictx->viewer);CHKERRQ(ierr); 4716 if (ictx->showtimestepandtime) { 4717 PetscReal xl,yl,xr,yr,h; 4718 char time[32]; 4719 4720 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 4721 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 4722 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 4723 h = yl + .95*(yr - yl); 4724 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 4725 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 4726 } 4727 4728 if (ictx->showinitial) { 4729 ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr); 4730 } 4731 PetscFunctionReturn(0); 4732 } 4733 4734 /*@C 4735 TSAdjointMonitorDrawSensi - Monitors progress of the adjoint TS solvers by calling 4736 VecView() for the sensitivities to initial states at each timestep 4737 4738 Collective on TS 4739 4740 Input Parameters: 4741 + ts - the TS context 4742 . step - current time-step 4743 . ptime - current time 4744 . u - current state 4745 . numcost - number of cost functions 4746 . lambda - sensitivities to initial conditions 4747 . mu - sensitivities to parameters 4748 - dummy - either a viewer or NULL 4749 4750 Level: intermediate 4751 4752 .keywords: TS, vector, adjoint, monitor, view 4753 4754 .seealso: TSAdjointMonitorSet(), TSAdjointMonitorDefault(), VecView() 4755 @*/ 4756 PetscErrorCode TSAdjointMonitorDrawSensi(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda,Vec *mu,void *dummy) 4757 { 4758 PetscErrorCode ierr; 4759 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 4760 PetscDraw draw; 4761 PetscReal xl,yl,xr,yr,h; 4762 char time[32]; 4763 4764 PetscFunctionBegin; 4765 if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4766 4767 ierr = VecView(lambda[0],ictx->viewer);CHKERRQ(ierr); 4768 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 4769 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 4770 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 4771 h = yl + .95*(yr - yl); 4772 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 4773 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 4774 PetscFunctionReturn(0); 4775 } 4776 4777 /*@C 4778 TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram 4779 4780 Collective on TS 4781 4782 Input Parameters: 4783 + ts - the TS context 4784 . step - current time-step 4785 . ptime - current time 4786 - dummy - either a viewer or NULL 4787 4788 Level: intermediate 4789 4790 .keywords: TS, vector, monitor, view 4791 4792 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4793 @*/ 4794 PetscErrorCode TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4795 { 4796 PetscErrorCode ierr; 4797 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 4798 PetscDraw draw; 4799 PetscDrawAxis axis; 4800 PetscInt n; 4801 PetscMPIInt size; 4802 PetscReal U0,U1,xl,yl,xr,yr,h; 4803 char time[32]; 4804 const PetscScalar *U; 4805 4806 PetscFunctionBegin; 4807 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size);CHKERRQ(ierr); 4808 if (size != 1) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs"); 4809 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 4810 if (n != 2) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns"); 4811 4812 ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr); 4813 ierr = PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis);CHKERRQ(ierr); 4814 ierr = PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr); 4815 if (!step) { 4816 ierr = PetscDrawClear(draw);CHKERRQ(ierr); 4817 ierr = PetscDrawAxisDraw(axis);CHKERRQ(ierr); 4818 } 4819 4820 ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr); 4821 U0 = PetscRealPart(U[0]); 4822 U1 = PetscRealPart(U[1]); 4823 ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr); 4824 if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0); 4825 4826 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 4827 ierr = PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK);CHKERRQ(ierr); 4828 if (ictx->showtimestepandtime) { 4829 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 4830 ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr); 4831 h = yl + .95*(yr - yl); 4832 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr); 4833 } 4834 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 4835 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 4836 ierr = PetscDrawSave(draw);CHKERRQ(ierr); 4837 PetscFunctionReturn(0); 4838 } 4839 4840 4841 /*@C 4842 TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution() 4843 4844 Collective on TS 4845 4846 Input Parameters: 4847 . ctx - the monitor context 4848 4849 Level: intermediate 4850 4851 .keywords: TS, vector, monitor, view 4852 4853 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError() 4854 @*/ 4855 PetscErrorCode TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx) 4856 { 4857 PetscErrorCode ierr; 4858 4859 PetscFunctionBegin; 4860 ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr); 4861 ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr); 4862 ierr = PetscFree(*ictx);CHKERRQ(ierr); 4863 PetscFunctionReturn(0); 4864 } 4865 4866 /*@C 4867 TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx 4868 4869 Collective on TS 4870 4871 Input Parameter: 4872 . ts - time-step context 4873 4874 Output Patameter: 4875 . ctx - the monitor context 4876 4877 Options Database: 4878 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 4879 4880 Level: intermediate 4881 4882 .keywords: TS, vector, monitor, view 4883 4884 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx() 4885 @*/ 4886 PetscErrorCode TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx) 4887 { 4888 PetscErrorCode ierr; 4889 4890 PetscFunctionBegin; 4891 ierr = PetscNew(ctx);CHKERRQ(ierr); 4892 ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr); 4893 ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr); 4894 4895 (*ctx)->howoften = howoften; 4896 (*ctx)->showinitial = PETSC_FALSE; 4897 ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr); 4898 4899 (*ctx)->showtimestepandtime = PETSC_FALSE; 4900 ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr); 4901 PetscFunctionReturn(0); 4902 } 4903 4904 /*@C 4905 TSMonitorDrawError - Monitors progress of the TS solvers by calling 4906 VecView() for the error at each timestep 4907 4908 Collective on TS 4909 4910 Input Parameters: 4911 + ts - the TS context 4912 . step - current time-step 4913 . ptime - current time 4914 - dummy - either a viewer or NULL 4915 4916 Level: intermediate 4917 4918 .keywords: TS, vector, monitor, view 4919 4920 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 4921 @*/ 4922 PetscErrorCode TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 4923 { 4924 PetscErrorCode ierr; 4925 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 4926 PetscViewer viewer = ctx->viewer; 4927 Vec work; 4928 4929 PetscFunctionBegin; 4930 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 4931 ierr = VecDuplicate(u,&work);CHKERRQ(ierr); 4932 ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr); 4933 ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr); 4934 ierr = VecView(work,viewer);CHKERRQ(ierr); 4935 ierr = VecDestroy(&work);CHKERRQ(ierr); 4936 PetscFunctionReturn(0); 4937 } 4938 4939 #include <petsc/private/dmimpl.h> 4940 /*@ 4941 TSSetDM - Sets the DM that may be used by some nonlinear solvers or preconditioners under the TS 4942 4943 Logically Collective on TS and DM 4944 4945 Input Parameters: 4946 + ts - the ODE integrator object 4947 - dm - the dm, cannot be NULL 4948 4949 Level: intermediate 4950 4951 4952 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM() 4953 @*/ 4954 PetscErrorCode TSSetDM(TS ts,DM dm) 4955 { 4956 PetscErrorCode ierr; 4957 SNES snes; 4958 DMTS tsdm; 4959 4960 PetscFunctionBegin; 4961 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 4962 PetscValidHeaderSpecific(dm,DM_CLASSID,2); 4963 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 4964 if (ts->dm) { /* Move the DMTS context over to the new DM unless the new DM already has one */ 4965 if (ts->dm->dmts && !dm->dmts) { 4966 ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr); 4967 ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr); 4968 if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */ 4969 tsdm->originaldm = dm; 4970 } 4971 } 4972 ierr = DMDestroy(&ts->dm);CHKERRQ(ierr); 4973 } 4974 ts->dm = dm; 4975 4976 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 4977 ierr = SNESSetDM(snes,dm);CHKERRQ(ierr); 4978 PetscFunctionReturn(0); 4979 } 4980 4981 /*@ 4982 TSGetDM - Gets the DM that may be used by some preconditioners 4983 4984 Not Collective 4985 4986 Input Parameter: 4987 . ts - the preconditioner context 4988 4989 Output Parameter: 4990 . dm - the dm 4991 4992 Level: intermediate 4993 4994 4995 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM() 4996 @*/ 4997 PetscErrorCode TSGetDM(TS ts,DM *dm) 4998 { 4999 PetscErrorCode ierr; 5000 5001 PetscFunctionBegin; 5002 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5003 if (!ts->dm) { 5004 ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr); 5005 if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);} 5006 } 5007 *dm = ts->dm; 5008 PetscFunctionReturn(0); 5009 } 5010 5011 /*@ 5012 SNESTSFormFunction - Function to evaluate nonlinear residual 5013 5014 Logically Collective on SNES 5015 5016 Input Parameter: 5017 + snes - nonlinear solver 5018 . U - the current state at which to evaluate the residual 5019 - ctx - user context, must be a TS 5020 5021 Output Parameter: 5022 . F - the nonlinear residual 5023 5024 Notes: 5025 This function is not normally called by users and is automatically registered with the SNES used by TS. 5026 It is most frequently passed to MatFDColoringSetFunction(). 5027 5028 Level: advanced 5029 5030 .seealso: SNESSetFunction(), MatFDColoringSetFunction() 5031 @*/ 5032 PetscErrorCode SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx) 5033 { 5034 TS ts = (TS)ctx; 5035 PetscErrorCode ierr; 5036 5037 PetscFunctionBegin; 5038 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5039 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5040 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 5041 PetscValidHeaderSpecific(ts,TS_CLASSID,4); 5042 ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr); 5043 PetscFunctionReturn(0); 5044 } 5045 5046 /*@ 5047 SNESTSFormJacobian - Function to evaluate the Jacobian 5048 5049 Collective on SNES 5050 5051 Input Parameter: 5052 + snes - nonlinear solver 5053 . U - the current state at which to evaluate the residual 5054 - ctx - user context, must be a TS 5055 5056 Output Parameter: 5057 + A - the Jacobian 5058 . B - the preconditioning matrix (may be the same as A) 5059 - flag - indicates any structure change in the matrix 5060 5061 Notes: 5062 This function is not normally called by users and is automatically registered with the SNES used by TS. 5063 5064 Level: developer 5065 5066 .seealso: SNESSetJacobian() 5067 @*/ 5068 PetscErrorCode SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx) 5069 { 5070 TS ts = (TS)ctx; 5071 PetscErrorCode ierr; 5072 5073 PetscFunctionBegin; 5074 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5075 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5076 PetscValidPointer(A,3); 5077 PetscValidHeaderSpecific(A,MAT_CLASSID,3); 5078 PetscValidPointer(B,4); 5079 PetscValidHeaderSpecific(B,MAT_CLASSID,4); 5080 PetscValidHeaderSpecific(ts,TS_CLASSID,6); 5081 ierr = (ts->ops->snesjacobian)(snes,U,A,B,ts);CHKERRQ(ierr); 5082 PetscFunctionReturn(0); 5083 } 5084 5085 /*@C 5086 TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems Udot = A U only 5087 5088 Collective on TS 5089 5090 Input Arguments: 5091 + ts - time stepping context 5092 . t - time at which to evaluate 5093 . U - state at which to evaluate 5094 - ctx - context 5095 5096 Output Arguments: 5097 . F - right hand side 5098 5099 Level: intermediate 5100 5101 Notes: 5102 This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems. 5103 The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian(). 5104 5105 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant() 5106 @*/ 5107 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx) 5108 { 5109 PetscErrorCode ierr; 5110 Mat Arhs,Brhs; 5111 5112 PetscFunctionBegin; 5113 ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr); 5114 ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr); 5115 ierr = MatMult(Arhs,U,F);CHKERRQ(ierr); 5116 PetscFunctionReturn(0); 5117 } 5118 5119 /*@C 5120 TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent. 5121 5122 Collective on TS 5123 5124 Input Arguments: 5125 + ts - time stepping context 5126 . t - time at which to evaluate 5127 . U - state at which to evaluate 5128 - ctx - context 5129 5130 Output Arguments: 5131 + A - pointer to operator 5132 . B - pointer to preconditioning matrix 5133 - flg - matrix structure flag 5134 5135 Level: intermediate 5136 5137 Notes: 5138 This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems. 5139 5140 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear() 5141 @*/ 5142 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx) 5143 { 5144 PetscFunctionBegin; 5145 PetscFunctionReturn(0); 5146 } 5147 5148 /*@C 5149 TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only 5150 5151 Collective on TS 5152 5153 Input Arguments: 5154 + ts - time stepping context 5155 . t - time at which to evaluate 5156 . U - state at which to evaluate 5157 . Udot - time derivative of state vector 5158 - ctx - context 5159 5160 Output Arguments: 5161 . F - left hand side 5162 5163 Level: intermediate 5164 5165 Notes: 5166 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 5167 user is required to write their own TSComputeIFunction. 5168 This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems. 5169 The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian(). 5170 5171 Note that using this function is NOT equivalent to using TSComputeRHSFunctionLinear() since that solves Udot = A U 5172 5173 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant(), TSComputeRHSFunctionLinear() 5174 @*/ 5175 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx) 5176 { 5177 PetscErrorCode ierr; 5178 Mat A,B; 5179 5180 PetscFunctionBegin; 5181 ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr); 5182 ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE);CHKERRQ(ierr); 5183 ierr = MatMult(A,Udot,F);CHKERRQ(ierr); 5184 PetscFunctionReturn(0); 5185 } 5186 5187 /*@C 5188 TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE 5189 5190 Collective on TS 5191 5192 Input Arguments: 5193 + ts - time stepping context 5194 . t - time at which to evaluate 5195 . U - state at which to evaluate 5196 . Udot - time derivative of state vector 5197 . shift - shift to apply 5198 - ctx - context 5199 5200 Output Arguments: 5201 + A - pointer to operator 5202 . B - pointer to preconditioning matrix 5203 - flg - matrix structure flag 5204 5205 Level: advanced 5206 5207 Notes: 5208 This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems. 5209 5210 It is only appropriate for problems of the form 5211 5212 $ M Udot = F(U,t) 5213 5214 where M is constant and F is non-stiff. The user must pass M to TSSetIJacobian(). The current implementation only 5215 works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing 5216 an implicit operator of the form 5217 5218 $ shift*M + J 5219 5220 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 5221 a copy of M or reassemble it when requested. 5222 5223 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear() 5224 @*/ 5225 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx) 5226 { 5227 PetscErrorCode ierr; 5228 5229 PetscFunctionBegin; 5230 ierr = MatScale(A, shift / ts->ijacobian.shift);CHKERRQ(ierr); 5231 ts->ijacobian.shift = shift; 5232 PetscFunctionReturn(0); 5233 } 5234 5235 /*@ 5236 TSGetEquationType - Gets the type of the equation that TS is solving. 5237 5238 Not Collective 5239 5240 Input Parameter: 5241 . ts - the TS context 5242 5243 Output Parameter: 5244 . equation_type - see TSEquationType 5245 5246 Level: beginner 5247 5248 .keywords: TS, equation type 5249 5250 .seealso: TSSetEquationType(), TSEquationType 5251 @*/ 5252 PetscErrorCode TSGetEquationType(TS ts,TSEquationType *equation_type) 5253 { 5254 PetscFunctionBegin; 5255 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5256 PetscValidPointer(equation_type,2); 5257 *equation_type = ts->equation_type; 5258 PetscFunctionReturn(0); 5259 } 5260 5261 /*@ 5262 TSSetEquationType - Sets the type of the equation that TS is solving. 5263 5264 Not Collective 5265 5266 Input Parameter: 5267 + ts - the TS context 5268 - equation_type - see TSEquationType 5269 5270 Level: advanced 5271 5272 .keywords: TS, equation type 5273 5274 .seealso: TSGetEquationType(), TSEquationType 5275 @*/ 5276 PetscErrorCode TSSetEquationType(TS ts,TSEquationType equation_type) 5277 { 5278 PetscFunctionBegin; 5279 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5280 ts->equation_type = equation_type; 5281 PetscFunctionReturn(0); 5282 } 5283 5284 /*@ 5285 TSGetConvergedReason - Gets the reason the TS iteration was stopped. 5286 5287 Not Collective 5288 5289 Input Parameter: 5290 . ts - the TS context 5291 5292 Output Parameter: 5293 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 5294 manual pages for the individual convergence tests for complete lists 5295 5296 Level: beginner 5297 5298 Notes: 5299 Can only be called after the call to TSSolve() is complete. 5300 5301 .keywords: TS, nonlinear, set, convergence, test 5302 5303 .seealso: TSSetConvergenceTest(), TSConvergedReason 5304 @*/ 5305 PetscErrorCode TSGetConvergedReason(TS ts,TSConvergedReason *reason) 5306 { 5307 PetscFunctionBegin; 5308 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5309 PetscValidPointer(reason,2); 5310 *reason = ts->reason; 5311 PetscFunctionReturn(0); 5312 } 5313 5314 /*@ 5315 TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve. 5316 5317 Not Collective 5318 5319 Input Parameter: 5320 + ts - the TS context 5321 . reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the 5322 manual pages for the individual convergence tests for complete lists 5323 5324 Level: advanced 5325 5326 Notes: 5327 Can only be called during TSSolve() is active. 5328 5329 .keywords: TS, nonlinear, set, convergence, test 5330 5331 .seealso: TSConvergedReason 5332 @*/ 5333 PetscErrorCode TSSetConvergedReason(TS ts,TSConvergedReason reason) 5334 { 5335 PetscFunctionBegin; 5336 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5337 ts->reason = reason; 5338 PetscFunctionReturn(0); 5339 } 5340 5341 /*@ 5342 TSGetSolveTime - Gets the time after a call to TSSolve() 5343 5344 Not Collective 5345 5346 Input Parameter: 5347 . ts - the TS context 5348 5349 Output Parameter: 5350 . ftime - the final time. This time corresponds to the final time set with TSSetDuration() 5351 5352 Level: beginner 5353 5354 Notes: 5355 Can only be called after the call to TSSolve() is complete. 5356 5357 .keywords: TS, nonlinear, set, convergence, test 5358 5359 .seealso: TSSetConvergenceTest(), TSConvergedReason 5360 @*/ 5361 PetscErrorCode TSGetSolveTime(TS ts,PetscReal *ftime) 5362 { 5363 PetscFunctionBegin; 5364 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5365 PetscValidPointer(ftime,2); 5366 *ftime = ts->solvetime; 5367 PetscFunctionReturn(0); 5368 } 5369 5370 /*@ 5371 TSGetTotalSteps - Gets the total number of steps done since the last call to TSSetUp() or TSCreate() 5372 5373 Not Collective 5374 5375 Input Parameter: 5376 . ts - the TS context 5377 5378 Output Parameter: 5379 . steps - the number of steps 5380 5381 Level: beginner 5382 5383 Notes: 5384 Includes the number of steps for all calls to TSSolve() since TSSetUp() was called 5385 5386 .keywords: TS, nonlinear, set, convergence, test 5387 5388 .seealso: TSSetConvergenceTest(), TSConvergedReason 5389 @*/ 5390 PetscErrorCode TSGetTotalSteps(TS ts,PetscInt *steps) 5391 { 5392 PetscFunctionBegin; 5393 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5394 PetscValidPointer(steps,2); 5395 *steps = ts->total_steps; 5396 PetscFunctionReturn(0); 5397 } 5398 5399 /*@ 5400 TSGetSNESIterations - Gets the total number of nonlinear iterations 5401 used by the time integrator. 5402 5403 Not Collective 5404 5405 Input Parameter: 5406 . ts - TS context 5407 5408 Output Parameter: 5409 . nits - number of nonlinear iterations 5410 5411 Notes: 5412 This counter is reset to zero for each successive call to TSSolve(). 5413 5414 Level: intermediate 5415 5416 .keywords: TS, get, number, nonlinear, iterations 5417 5418 .seealso: TSGetKSPIterations() 5419 @*/ 5420 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits) 5421 { 5422 PetscFunctionBegin; 5423 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5424 PetscValidIntPointer(nits,2); 5425 *nits = ts->snes_its; 5426 PetscFunctionReturn(0); 5427 } 5428 5429 /*@ 5430 TSGetKSPIterations - Gets the total number of linear iterations 5431 used by the time integrator. 5432 5433 Not Collective 5434 5435 Input Parameter: 5436 . ts - TS context 5437 5438 Output Parameter: 5439 . lits - number of linear iterations 5440 5441 Notes: 5442 This counter is reset to zero for each successive call to TSSolve(). 5443 5444 Level: intermediate 5445 5446 .keywords: TS, get, number, linear, iterations 5447 5448 .seealso: TSGetSNESIterations(), SNESGetKSPIterations() 5449 @*/ 5450 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits) 5451 { 5452 PetscFunctionBegin; 5453 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5454 PetscValidIntPointer(lits,2); 5455 *lits = ts->ksp_its; 5456 PetscFunctionReturn(0); 5457 } 5458 5459 /*@ 5460 TSGetStepRejections - Gets the total number of rejected steps. 5461 5462 Not Collective 5463 5464 Input Parameter: 5465 . ts - TS context 5466 5467 Output Parameter: 5468 . rejects - number of steps rejected 5469 5470 Notes: 5471 This counter is reset to zero for each successive call to TSSolve(). 5472 5473 Level: intermediate 5474 5475 .keywords: TS, get, number 5476 5477 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails() 5478 @*/ 5479 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects) 5480 { 5481 PetscFunctionBegin; 5482 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5483 PetscValidIntPointer(rejects,2); 5484 *rejects = ts->reject; 5485 PetscFunctionReturn(0); 5486 } 5487 5488 /*@ 5489 TSGetSNESFailures - Gets the total number of failed SNES solves 5490 5491 Not Collective 5492 5493 Input Parameter: 5494 . ts - TS context 5495 5496 Output Parameter: 5497 . fails - number of failed nonlinear solves 5498 5499 Notes: 5500 This counter is reset to zero for each successive call to TSSolve(). 5501 5502 Level: intermediate 5503 5504 .keywords: TS, get, number 5505 5506 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures() 5507 @*/ 5508 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails) 5509 { 5510 PetscFunctionBegin; 5511 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5512 PetscValidIntPointer(fails,2); 5513 *fails = ts->num_snes_failures; 5514 PetscFunctionReturn(0); 5515 } 5516 5517 /*@ 5518 TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails 5519 5520 Not Collective 5521 5522 Input Parameter: 5523 + ts - TS context 5524 - rejects - maximum number of rejected steps, pass -1 for unlimited 5525 5526 Notes: 5527 The counter is reset to zero for each step 5528 5529 Options Database Key: 5530 . -ts_max_reject - Maximum number of step rejections before a step fails 5531 5532 Level: intermediate 5533 5534 .keywords: TS, set, maximum, number 5535 5536 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 5537 @*/ 5538 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects) 5539 { 5540 PetscFunctionBegin; 5541 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5542 ts->max_reject = rejects; 5543 PetscFunctionReturn(0); 5544 } 5545 5546 /*@ 5547 TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves 5548 5549 Not Collective 5550 5551 Input Parameter: 5552 + ts - TS context 5553 - fails - maximum number of failed nonlinear solves, pass -1 for unlimited 5554 5555 Notes: 5556 The counter is reset to zero for each successive call to TSSolve(). 5557 5558 Options Database Key: 5559 . -ts_max_snes_failures - Maximum number of nonlinear solve failures 5560 5561 Level: intermediate 5562 5563 .keywords: TS, set, maximum, number 5564 5565 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason() 5566 @*/ 5567 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails) 5568 { 5569 PetscFunctionBegin; 5570 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5571 ts->max_snes_failures = fails; 5572 PetscFunctionReturn(0); 5573 } 5574 5575 /*@ 5576 TSSetErrorIfStepFails - Error if no step succeeds 5577 5578 Not Collective 5579 5580 Input Parameter: 5581 + ts - TS context 5582 - err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure 5583 5584 Options Database Key: 5585 . -ts_error_if_step_fails - Error if no step succeeds 5586 5587 Level: intermediate 5588 5589 .keywords: TS, set, error 5590 5591 .seealso: TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason() 5592 @*/ 5593 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err) 5594 { 5595 PetscFunctionBegin; 5596 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5597 ts->errorifstepfailed = err; 5598 PetscFunctionReturn(0); 5599 } 5600 5601 /*@C 5602 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 5603 5604 Collective on TS 5605 5606 Input Parameters: 5607 + ts - the TS context 5608 . step - current time-step 5609 . ptime - current time 5610 . u - current state 5611 - vf - viewer and its format 5612 5613 Level: intermediate 5614 5615 .keywords: TS, vector, monitor, view 5616 5617 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5618 @*/ 5619 PetscErrorCode TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf) 5620 { 5621 PetscErrorCode ierr; 5622 5623 PetscFunctionBegin; 5624 ierr = PetscViewerPushFormat(vf->viewer,vf->format);CHKERRQ(ierr); 5625 ierr = VecView(u,vf->viewer);CHKERRQ(ierr); 5626 ierr = PetscViewerPopFormat(vf->viewer);CHKERRQ(ierr); 5627 PetscFunctionReturn(0); 5628 } 5629 5630 /*@C 5631 TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep. 5632 5633 Collective on TS 5634 5635 Input Parameters: 5636 + ts - the TS context 5637 . step - current time-step 5638 . ptime - current time 5639 . u - current state 5640 - filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 5641 5642 Level: intermediate 5643 5644 Notes: 5645 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. 5646 These are named according to the file name template. 5647 5648 This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy(). 5649 5650 .keywords: TS, vector, monitor, view 5651 5652 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 5653 @*/ 5654 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate) 5655 { 5656 PetscErrorCode ierr; 5657 char filename[PETSC_MAX_PATH_LEN]; 5658 PetscViewer viewer; 5659 5660 PetscFunctionBegin; 5661 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 5662 ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr); 5663 ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); 5664 ierr = VecView(u,viewer);CHKERRQ(ierr); 5665 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 5666 PetscFunctionReturn(0); 5667 } 5668 5669 /*@C 5670 TSMonitorSolutionVTKDestroy - Destroy context for monitoring 5671 5672 Collective on TS 5673 5674 Input Parameters: 5675 . filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 5676 5677 Level: intermediate 5678 5679 Note: 5680 This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK(). 5681 5682 .keywords: TS, vector, monitor, view 5683 5684 .seealso: TSMonitorSet(), TSMonitorSolutionVTK() 5685 @*/ 5686 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate) 5687 { 5688 PetscErrorCode ierr; 5689 5690 PetscFunctionBegin; 5691 ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr); 5692 PetscFunctionReturn(0); 5693 } 5694 5695 /*@ 5696 TSGetAdapt - Get the adaptive controller context for the current method 5697 5698 Collective on TS if controller has not been created yet 5699 5700 Input Arguments: 5701 . ts - time stepping context 5702 5703 Output Arguments: 5704 . adapt - adaptive controller 5705 5706 Level: intermediate 5707 5708 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose() 5709 @*/ 5710 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt) 5711 { 5712 PetscErrorCode ierr; 5713 5714 PetscFunctionBegin; 5715 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5716 PetscValidPointer(adapt,2); 5717 if (!ts->adapt) { 5718 ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr); 5719 ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr); 5720 ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr); 5721 } 5722 *adapt = ts->adapt; 5723 PetscFunctionReturn(0); 5724 } 5725 5726 /*@ 5727 TSSetTolerances - Set tolerances for local truncation error when using adaptive controller 5728 5729 Logically Collective 5730 5731 Input Arguments: 5732 + ts - time integration context 5733 . atol - scalar absolute tolerances, PETSC_DECIDE to leave current value 5734 . vatol - vector of absolute tolerances or NULL, used in preference to atol if present 5735 . rtol - scalar relative tolerances, PETSC_DECIDE to leave current value 5736 - vrtol - vector of relative tolerances or NULL, used in preference to atol if present 5737 5738 Options Database keys: 5739 + -ts_rtol <rtol> - relative tolerance for local truncation error 5740 - -ts_atol <atol> Absolute tolerance for local truncation error 5741 5742 Notes: 5743 With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error 5744 (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be 5745 computed only for the differential or the algebraic part then this can be done using the vector of 5746 tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the 5747 differential part and infinity for the algebraic part, the LTE calculation will include only the 5748 differential variables. 5749 5750 Level: beginner 5751 5752 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances() 5753 @*/ 5754 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol) 5755 { 5756 PetscErrorCode ierr; 5757 5758 PetscFunctionBegin; 5759 if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol; 5760 if (vatol) { 5761 ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr); 5762 ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr); 5763 ts->vatol = vatol; 5764 } 5765 if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol; 5766 if (vrtol) { 5767 ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr); 5768 ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr); 5769 ts->vrtol = vrtol; 5770 } 5771 PetscFunctionReturn(0); 5772 } 5773 5774 /*@ 5775 TSGetTolerances - Get tolerances for local truncation error when using adaptive controller 5776 5777 Logically Collective 5778 5779 Input Arguments: 5780 . ts - time integration context 5781 5782 Output Arguments: 5783 + atol - scalar absolute tolerances, NULL to ignore 5784 . vatol - vector of absolute tolerances, NULL to ignore 5785 . rtol - scalar relative tolerances, NULL to ignore 5786 - vrtol - vector of relative tolerances, NULL to ignore 5787 5788 Level: beginner 5789 5790 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances() 5791 @*/ 5792 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol) 5793 { 5794 PetscFunctionBegin; 5795 if (atol) *atol = ts->atol; 5796 if (vatol) *vatol = ts->vatol; 5797 if (rtol) *rtol = ts->rtol; 5798 if (vrtol) *vrtol = ts->vrtol; 5799 PetscFunctionReturn(0); 5800 } 5801 5802 /*@ 5803 TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors 5804 5805 Collective on TS 5806 5807 Input Arguments: 5808 + ts - time stepping context 5809 . U - state vector, usually ts->vec_sol 5810 - Y - state vector to be compared to U 5811 5812 Output Arguments: 5813 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5814 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5815 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5816 5817 Level: developer 5818 5819 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNormInfinity() 5820 @*/ 5821 PetscErrorCode TSErrorWeightedNorm2(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5822 { 5823 PetscErrorCode ierr; 5824 PetscInt i,n,N,rstart; 5825 PetscInt n_loc,na_loc,nr_loc; 5826 PetscReal n_glb,na_glb,nr_glb; 5827 const PetscScalar *u,*y; 5828 PetscReal sum,suma,sumr,gsum,gsuma,gsumr,diff; 5829 PetscReal tol,tola,tolr; 5830 PetscReal err_loc[6],err_glb[6]; 5831 5832 PetscFunctionBegin; 5833 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5834 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 5835 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 5836 PetscValidType(U,2); 5837 PetscValidType(Y,3); 5838 PetscCheckSameComm(U,2,Y,3); 5839 PetscValidPointer(norm,4); 5840 PetscValidPointer(norma,5); 5841 PetscValidPointer(normr,6); 5842 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 5843 5844 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 5845 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 5846 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 5847 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 5848 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 5849 sum = 0.; n_loc = 0; 5850 suma = 0.; na_loc = 0; 5851 sumr = 0.; nr_loc = 0; 5852 if (ts->vatol && ts->vrtol) { 5853 const PetscScalar *atol,*rtol; 5854 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5855 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5856 for (i=0; i<n; i++) { 5857 diff = PetscAbsScalar(y[i] - u[i]); 5858 tola = PetscRealPart(atol[i]); 5859 if(tola>0.){ 5860 suma += PetscSqr(diff/tola); 5861 na_loc++; 5862 } 5863 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5864 if(tolr>0.){ 5865 sumr += PetscSqr(diff/tolr); 5866 nr_loc++; 5867 } 5868 tol=tola+tolr; 5869 if(tol>0.){ 5870 sum += PetscSqr(diff/tol); 5871 n_loc++; 5872 } 5873 } 5874 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5875 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5876 } else if (ts->vatol) { /* vector atol, scalar rtol */ 5877 const PetscScalar *atol; 5878 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5879 for (i=0; i<n; i++) { 5880 diff = PetscAbsScalar(y[i] - u[i]); 5881 tola = PetscRealPart(atol[i]); 5882 if(tola>0.){ 5883 suma += PetscSqr(diff/tola); 5884 na_loc++; 5885 } 5886 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5887 if(tolr>0.){ 5888 sumr += PetscSqr(diff/tolr); 5889 nr_loc++; 5890 } 5891 tol=tola+tolr; 5892 if(tol>0.){ 5893 sum += PetscSqr(diff/tol); 5894 n_loc++; 5895 } 5896 } 5897 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 5898 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 5899 const PetscScalar *rtol; 5900 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5901 for (i=0; i<n; i++) { 5902 diff = PetscAbsScalar(y[i] - u[i]); 5903 tola = ts->atol; 5904 if(tola>0.){ 5905 suma += PetscSqr(diff/tola); 5906 na_loc++; 5907 } 5908 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5909 if(tolr>0.){ 5910 sumr += PetscSqr(diff/tolr); 5911 nr_loc++; 5912 } 5913 tol=tola+tolr; 5914 if(tol>0.){ 5915 sum += PetscSqr(diff/tol); 5916 n_loc++; 5917 } 5918 } 5919 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 5920 } else { /* scalar atol, scalar rtol */ 5921 for (i=0; i<n; i++) { 5922 diff = PetscAbsScalar(y[i] - u[i]); 5923 tola = ts->atol; 5924 if(tola>0.){ 5925 suma += PetscSqr(diff/tola); 5926 na_loc++; 5927 } 5928 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 5929 if(tolr>0.){ 5930 sumr += PetscSqr(diff/tolr); 5931 nr_loc++; 5932 } 5933 tol=tola+tolr; 5934 if(tol>0.){ 5935 sum += PetscSqr(diff/tol); 5936 n_loc++; 5937 } 5938 } 5939 } 5940 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 5941 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 5942 5943 err_loc[0] = sum; 5944 err_loc[1] = suma; 5945 err_loc[2] = sumr; 5946 err_loc[3] = (PetscReal)n_loc; 5947 err_loc[4] = (PetscReal)na_loc; 5948 err_loc[5] = (PetscReal)nr_loc; 5949 5950 ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 5951 5952 gsum = err_glb[0]; 5953 gsuma = err_glb[1]; 5954 gsumr = err_glb[2]; 5955 n_glb = err_glb[3]; 5956 na_glb = err_glb[4]; 5957 nr_glb = err_glb[5]; 5958 5959 *norm = 0.; 5960 if(n_glb>0. ){*norm = PetscSqrtReal(gsum / n_glb );} 5961 *norma = 0.; 5962 if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);} 5963 *normr = 0.; 5964 if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);} 5965 5966 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 5967 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 5968 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 5969 PetscFunctionReturn(0); 5970 } 5971 5972 /*@ 5973 TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors 5974 5975 Collective on TS 5976 5977 Input Arguments: 5978 + ts - time stepping context 5979 . U - state vector, usually ts->vec_sol 5980 - Y - state vector to be compared to U 5981 5982 Output Arguments: 5983 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 5984 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 5985 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 5986 5987 Level: developer 5988 5989 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNorm2() 5990 @*/ 5991 PetscErrorCode TSErrorWeightedNormInfinity(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 5992 { 5993 PetscErrorCode ierr; 5994 PetscInt i,n,N,rstart; 5995 const PetscScalar *u,*y; 5996 PetscReal max,gmax,maxa,gmaxa,maxr,gmaxr; 5997 PetscReal tol,tola,tolr,diff; 5998 PetscReal err_loc[3],err_glb[3]; 5999 6000 PetscFunctionBegin; 6001 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6002 PetscValidHeaderSpecific(U,VEC_CLASSID,2); 6003 PetscValidHeaderSpecific(Y,VEC_CLASSID,3); 6004 PetscValidType(U,2); 6005 PetscValidType(Y,3); 6006 PetscCheckSameComm(U,2,Y,3); 6007 PetscValidPointer(norm,4); 6008 PetscValidPointer(norma,5); 6009 PetscValidPointer(normr,6); 6010 if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector"); 6011 6012 ierr = VecGetSize(U,&N);CHKERRQ(ierr); 6013 ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr); 6014 ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr); 6015 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 6016 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 6017 6018 max=0.; 6019 maxa=0.; 6020 maxr=0.; 6021 6022 if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */ 6023 const PetscScalar *atol,*rtol; 6024 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6025 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6026 6027 for (i=0; i<n; i++) { 6028 diff = PetscAbsScalar(y[i] - u[i]); 6029 tola = PetscRealPart(atol[i]); 6030 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6031 tol = tola+tolr; 6032 if(tola>0.){ 6033 maxa = PetscMax(maxa,diff / tola); 6034 } 6035 if(tolr>0.){ 6036 maxr = PetscMax(maxr,diff / tolr); 6037 } 6038 if(tol>0.){ 6039 max = PetscMax(max,diff / tol); 6040 } 6041 } 6042 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6043 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6044 } else if (ts->vatol) { /* vector atol, scalar rtol */ 6045 const PetscScalar *atol; 6046 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6047 for (i=0; i<n; i++) { 6048 diff = PetscAbsScalar(y[i] - u[i]); 6049 tola = PetscRealPart(atol[i]); 6050 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6051 tol = tola+tolr; 6052 if(tola>0.){ 6053 maxa = PetscMax(maxa,diff / tola); 6054 } 6055 if(tolr>0.){ 6056 maxr = PetscMax(maxr,diff / tolr); 6057 } 6058 if(tol>0.){ 6059 max = PetscMax(max,diff / tol); 6060 } 6061 } 6062 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6063 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 6064 const PetscScalar *rtol; 6065 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6066 6067 for (i=0; i<n; i++) { 6068 diff = PetscAbsScalar(y[i] - u[i]); 6069 tola = ts->atol; 6070 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6071 tol = tola+tolr; 6072 if(tola>0.){ 6073 maxa = PetscMax(maxa,diff / tola); 6074 } 6075 if(tolr>0.){ 6076 maxr = PetscMax(maxr,diff / tolr); 6077 } 6078 if(tol>0.){ 6079 max = PetscMax(max,diff / tol); 6080 } 6081 } 6082 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6083 } else { /* scalar atol, scalar rtol */ 6084 6085 for (i=0; i<n; i++) { 6086 diff = PetscAbsScalar(y[i] - u[i]); 6087 tola = ts->atol; 6088 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6089 tol = tola+tolr; 6090 if(tola>0.){ 6091 maxa = PetscMax(maxa,diff / tola); 6092 } 6093 if(tolr>0.){ 6094 maxr = PetscMax(maxr,diff / tolr); 6095 } 6096 if(tol>0.){ 6097 max = PetscMax(max,diff / tol); 6098 } 6099 } 6100 } 6101 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 6102 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 6103 err_loc[0] = max; 6104 err_loc[1] = maxa; 6105 err_loc[2] = maxr; 6106 ierr = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6107 gmax = err_glb[0]; 6108 gmaxa = err_glb[1]; 6109 gmaxr = err_glb[2]; 6110 6111 *norm = gmax; 6112 *norma = gmaxa; 6113 *normr = gmaxr; 6114 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6115 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 6116 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 6117 PetscFunctionReturn(0); 6118 } 6119 6120 /*@ 6121 TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors based on supplied absolute and relative tolerances 6122 6123 Collective on TS 6124 6125 Input Arguments: 6126 + ts - time stepping context 6127 . U - state vector, usually ts->vec_sol 6128 . Y - state vector to be compared to U 6129 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 6130 6131 Output Arguments: 6132 . norm - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances 6133 . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user 6134 . normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user 6135 6136 Options Database Keys: 6137 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 6138 6139 Level: developer 6140 6141 .seealso: TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2(), TSErrorWeightedENorm 6142 @*/ 6143 PetscErrorCode TSErrorWeightedNorm(TS ts,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6144 { 6145 PetscErrorCode ierr; 6146 6147 PetscFunctionBegin; 6148 if (wnormtype == NORM_2) { 6149 ierr = TSErrorWeightedNorm2(ts,U,Y,norm,norma,normr);CHKERRQ(ierr); 6150 } else if(wnormtype == NORM_INFINITY) { 6151 ierr = TSErrorWeightedNormInfinity(ts,U,Y,norm,norma,normr);CHKERRQ(ierr); 6152 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 6153 PetscFunctionReturn(0); 6154 } 6155 6156 6157 /*@ 6158 TSErrorWeightedENorm2 - compute a weighted 2 error norm based on supplied absolute and relative tolerances 6159 6160 Collective on TS 6161 6162 Input Arguments: 6163 + ts - time stepping context 6164 . E - error vector 6165 . U - state vector, usually ts->vec_sol 6166 - Y - state vector, previous time step 6167 6168 Output Arguments: 6169 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 6170 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 6171 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 6172 6173 Level: developer 6174 6175 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENormInfinity() 6176 @*/ 6177 PetscErrorCode TSErrorWeightedENorm2(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6178 { 6179 PetscErrorCode ierr; 6180 PetscInt i,n,N,rstart; 6181 PetscInt n_loc,na_loc,nr_loc; 6182 PetscReal n_glb,na_glb,nr_glb; 6183 const PetscScalar *e,*u,*y; 6184 PetscReal err,sum,suma,sumr,gsum,gsuma,gsumr; 6185 PetscReal tol,tola,tolr; 6186 PetscReal err_loc[6],err_glb[6]; 6187 6188 PetscFunctionBegin; 6189 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6190 PetscValidHeaderSpecific(E,VEC_CLASSID,2); 6191 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 6192 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 6193 PetscValidType(E,2); 6194 PetscValidType(U,3); 6195 PetscValidType(Y,4); 6196 PetscCheckSameComm(E,2,U,3); 6197 PetscCheckSameComm(U,2,Y,3); 6198 PetscValidPointer(norm,5); 6199 PetscValidPointer(norma,6); 6200 PetscValidPointer(normr,7); 6201 6202 ierr = VecGetSize(E,&N);CHKERRQ(ierr); 6203 ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr); 6204 ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr); 6205 ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr); 6206 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 6207 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 6208 sum = 0.; n_loc = 0; 6209 suma = 0.; na_loc = 0; 6210 sumr = 0.; nr_loc = 0; 6211 if (ts->vatol && ts->vrtol) { 6212 const PetscScalar *atol,*rtol; 6213 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6214 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6215 for (i=0; i<n; i++) { 6216 err = PetscAbsScalar(e[i]); 6217 tola = PetscRealPart(atol[i]); 6218 if(tola>0.){ 6219 suma += PetscSqr(err/tola); 6220 na_loc++; 6221 } 6222 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6223 if(tolr>0.){ 6224 sumr += PetscSqr(err/tolr); 6225 nr_loc++; 6226 } 6227 tol=tola+tolr; 6228 if(tol>0.){ 6229 sum += PetscSqr(err/tol); 6230 n_loc++; 6231 } 6232 } 6233 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6234 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6235 } else if (ts->vatol) { /* vector atol, scalar rtol */ 6236 const PetscScalar *atol; 6237 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6238 for (i=0; i<n; i++) { 6239 err = PetscAbsScalar(e[i]); 6240 tola = PetscRealPart(atol[i]); 6241 if(tola>0.){ 6242 suma += PetscSqr(err/tola); 6243 na_loc++; 6244 } 6245 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6246 if(tolr>0.){ 6247 sumr += PetscSqr(err/tolr); 6248 nr_loc++; 6249 } 6250 tol=tola+tolr; 6251 if(tol>0.){ 6252 sum += PetscSqr(err/tol); 6253 n_loc++; 6254 } 6255 } 6256 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6257 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 6258 const PetscScalar *rtol; 6259 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6260 for (i=0; i<n; i++) { 6261 err = PetscAbsScalar(e[i]); 6262 tola = ts->atol; 6263 if(tola>0.){ 6264 suma += PetscSqr(err/tola); 6265 na_loc++; 6266 } 6267 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6268 if(tolr>0.){ 6269 sumr += PetscSqr(err/tolr); 6270 nr_loc++; 6271 } 6272 tol=tola+tolr; 6273 if(tol>0.){ 6274 sum += PetscSqr(err/tol); 6275 n_loc++; 6276 } 6277 } 6278 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6279 } else { /* scalar atol, scalar rtol */ 6280 for (i=0; i<n; i++) { 6281 err = PetscAbsScalar(e[i]); 6282 tola = ts->atol; 6283 if(tola>0.){ 6284 suma += PetscSqr(err/tola); 6285 na_loc++; 6286 } 6287 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6288 if(tolr>0.){ 6289 sumr += PetscSqr(err/tolr); 6290 nr_loc++; 6291 } 6292 tol=tola+tolr; 6293 if(tol>0.){ 6294 sum += PetscSqr(err/tol); 6295 n_loc++; 6296 } 6297 } 6298 } 6299 ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr); 6300 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 6301 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 6302 6303 err_loc[0] = sum; 6304 err_loc[1] = suma; 6305 err_loc[2] = sumr; 6306 err_loc[3] = (PetscReal)n_loc; 6307 err_loc[4] = (PetscReal)na_loc; 6308 err_loc[5] = (PetscReal)nr_loc; 6309 6310 ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6311 6312 gsum = err_glb[0]; 6313 gsuma = err_glb[1]; 6314 gsumr = err_glb[2]; 6315 n_glb = err_glb[3]; 6316 na_glb = err_glb[4]; 6317 nr_glb = err_glb[5]; 6318 6319 *norm = 0.; 6320 if(n_glb>0. ){*norm = PetscSqrtReal(gsum / n_glb );} 6321 *norma = 0.; 6322 if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);} 6323 *normr = 0.; 6324 if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);} 6325 6326 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6327 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 6328 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 6329 PetscFunctionReturn(0); 6330 } 6331 6332 /*@ 6333 TSErrorWeightedENormInfinity - compute a weighted infinity error norm based on supplied absolute and relative tolerances 6334 Collective on TS 6335 6336 Input Arguments: 6337 + ts - time stepping context 6338 . E - error vector 6339 . U - state vector, usually ts->vec_sol 6340 - Y - state vector, previous time step 6341 6342 Output Arguments: 6343 . norm - weighted norm, a value of 1.0 means that the error matches the tolerances 6344 . norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances 6345 . normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances 6346 6347 Level: developer 6348 6349 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENorm2() 6350 @*/ 6351 PetscErrorCode TSErrorWeightedENormInfinity(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6352 { 6353 PetscErrorCode ierr; 6354 PetscInt i,n,N,rstart; 6355 const PetscScalar *e,*u,*y; 6356 PetscReal err,max,gmax,maxa,gmaxa,maxr,gmaxr; 6357 PetscReal tol,tola,tolr; 6358 PetscReal err_loc[3],err_glb[3]; 6359 6360 PetscFunctionBegin; 6361 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6362 PetscValidHeaderSpecific(E,VEC_CLASSID,2); 6363 PetscValidHeaderSpecific(U,VEC_CLASSID,3); 6364 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 6365 PetscValidType(E,2); 6366 PetscValidType(U,3); 6367 PetscValidType(Y,4); 6368 PetscCheckSameComm(E,2,U,3); 6369 PetscCheckSameComm(U,2,Y,3); 6370 PetscValidPointer(norm,5); 6371 PetscValidPointer(norma,6); 6372 PetscValidPointer(normr,7); 6373 6374 ierr = VecGetSize(E,&N);CHKERRQ(ierr); 6375 ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr); 6376 ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr); 6377 ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr); 6378 ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr); 6379 ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr); 6380 6381 max=0.; 6382 maxa=0.; 6383 maxr=0.; 6384 6385 if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */ 6386 const PetscScalar *atol,*rtol; 6387 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6388 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6389 6390 for (i=0; i<n; i++) { 6391 err = PetscAbsScalar(e[i]); 6392 tola = PetscRealPart(atol[i]); 6393 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6394 tol = tola+tolr; 6395 if(tola>0.){ 6396 maxa = PetscMax(maxa,err / tola); 6397 } 6398 if(tolr>0.){ 6399 maxr = PetscMax(maxr,err / tolr); 6400 } 6401 if(tol>0.){ 6402 max = PetscMax(max,err / tol); 6403 } 6404 } 6405 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6406 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6407 } else if (ts->vatol) { /* vector atol, scalar rtol */ 6408 const PetscScalar *atol; 6409 ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6410 for (i=0; i<n; i++) { 6411 err = PetscAbsScalar(e[i]); 6412 tola = PetscRealPart(atol[i]); 6413 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6414 tol = tola+tolr; 6415 if(tola>0.){ 6416 maxa = PetscMax(maxa,err / tola); 6417 } 6418 if(tolr>0.){ 6419 maxr = PetscMax(maxr,err / tolr); 6420 } 6421 if(tol>0.){ 6422 max = PetscMax(max,err / tol); 6423 } 6424 } 6425 ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr); 6426 } else if (ts->vrtol) { /* scalar atol, vector rtol */ 6427 const PetscScalar *rtol; 6428 ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6429 6430 for (i=0; i<n; i++) { 6431 err = PetscAbsScalar(e[i]); 6432 tola = ts->atol; 6433 tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6434 tol = tola+tolr; 6435 if(tola>0.){ 6436 maxa = PetscMax(maxa,err / tola); 6437 } 6438 if(tolr>0.){ 6439 maxr = PetscMax(maxr,err / tolr); 6440 } 6441 if(tol>0.){ 6442 max = PetscMax(max,err / tol); 6443 } 6444 } 6445 ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr); 6446 } else { /* scalar atol, scalar rtol */ 6447 6448 for (i=0; i<n; i++) { 6449 err = PetscAbsScalar(e[i]); 6450 tola = ts->atol; 6451 tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i])); 6452 tol = tola+tolr; 6453 if(tola>0.){ 6454 maxa = PetscMax(maxa,err / tola); 6455 } 6456 if(tolr>0.){ 6457 maxr = PetscMax(maxr,err / tolr); 6458 } 6459 if(tol>0.){ 6460 max = PetscMax(max,err / tol); 6461 } 6462 } 6463 } 6464 ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr); 6465 ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr); 6466 ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr); 6467 err_loc[0] = max; 6468 err_loc[1] = maxa; 6469 err_loc[2] = maxr; 6470 ierr = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6471 gmax = err_glb[0]; 6472 gmaxa = err_glb[1]; 6473 gmaxr = err_glb[2]; 6474 6475 *norm = gmax; 6476 *norma = gmaxa; 6477 *normr = gmaxr; 6478 if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm"); 6479 if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma"); 6480 if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr"); 6481 PetscFunctionReturn(0); 6482 } 6483 6484 /*@ 6485 TSErrorWeightedENorm - compute a weighted error norm based on supplied absolute and relative tolerances 6486 6487 Collective on TS 6488 6489 Input Arguments: 6490 + ts - time stepping context 6491 . E - error vector 6492 . U - state vector, usually ts->vec_sol 6493 . Y - state vector, previous time step 6494 - wnormtype - norm type, either NORM_2 or NORM_INFINITY 6495 6496 Output Arguments: 6497 . norm - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances 6498 . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user 6499 . normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user 6500 6501 Options Database Keys: 6502 . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY 6503 6504 Level: developer 6505 6506 .seealso: TSErrorWeightedENormInfinity(), TSErrorWeightedENorm2(), TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2() 6507 @*/ 6508 PetscErrorCode TSErrorWeightedENorm(TS ts,Vec E,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr) 6509 { 6510 PetscErrorCode ierr; 6511 6512 PetscFunctionBegin; 6513 if (wnormtype == NORM_2) { 6514 ierr = TSErrorWeightedENorm2(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr); 6515 } else if(wnormtype == NORM_INFINITY) { 6516 ierr = TSErrorWeightedENormInfinity(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr); 6517 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]); 6518 PetscFunctionReturn(0); 6519 } 6520 6521 6522 /*@ 6523 TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler 6524 6525 Logically Collective on TS 6526 6527 Input Arguments: 6528 + ts - time stepping context 6529 - cfltime - maximum stable time step if using forward Euler (value can be different on each process) 6530 6531 Note: 6532 After calling this function, the global CFL time can be obtained by calling TSGetCFLTime() 6533 6534 Level: intermediate 6535 6536 .seealso: TSGetCFLTime(), TSADAPTCFL 6537 @*/ 6538 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime) 6539 { 6540 PetscFunctionBegin; 6541 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6542 ts->cfltime_local = cfltime; 6543 ts->cfltime = -1.; 6544 PetscFunctionReturn(0); 6545 } 6546 6547 /*@ 6548 TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler 6549 6550 Collective on TS 6551 6552 Input Arguments: 6553 . ts - time stepping context 6554 6555 Output Arguments: 6556 . cfltime - maximum stable time step for forward Euler 6557 6558 Level: advanced 6559 6560 .seealso: TSSetCFLTimeLocal() 6561 @*/ 6562 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime) 6563 { 6564 PetscErrorCode ierr; 6565 6566 PetscFunctionBegin; 6567 if (ts->cfltime < 0) { 6568 ierr = MPIU_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr); 6569 } 6570 *cfltime = ts->cfltime; 6571 PetscFunctionReturn(0); 6572 } 6573 6574 /*@ 6575 TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu 6576 6577 Input Parameters: 6578 . ts - the TS context. 6579 . xl - lower bound. 6580 . xu - upper bound. 6581 6582 Notes: 6583 If this routine is not called then the lower and upper bounds are set to 6584 PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp(). 6585 6586 Level: advanced 6587 6588 @*/ 6589 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu) 6590 { 6591 PetscErrorCode ierr; 6592 SNES snes; 6593 6594 PetscFunctionBegin; 6595 ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 6596 ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr); 6597 PetscFunctionReturn(0); 6598 } 6599 6600 #if defined(PETSC_HAVE_MATLAB_ENGINE) 6601 #include <mex.h> 6602 6603 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext; 6604 6605 /* 6606 TSComputeFunction_Matlab - Calls the function that has been set with 6607 TSSetFunctionMatlab(). 6608 6609 Collective on TS 6610 6611 Input Parameters: 6612 + snes - the TS context 6613 - u - input vector 6614 6615 Output Parameter: 6616 . y - function vector, as set by TSSetFunction() 6617 6618 Notes: 6619 TSComputeFunction() is typically used within nonlinear solvers 6620 implementations, so most users would not generally call this routine 6621 themselves. 6622 6623 Level: developer 6624 6625 .keywords: TS, nonlinear, compute, function 6626 6627 .seealso: TSSetFunction(), TSGetFunction() 6628 */ 6629 PetscErrorCode TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx) 6630 { 6631 PetscErrorCode ierr; 6632 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 6633 int nlhs = 1,nrhs = 7; 6634 mxArray *plhs[1],*prhs[7]; 6635 long long int lx = 0,lxdot = 0,ly = 0,ls = 0; 6636 6637 PetscFunctionBegin; 6638 PetscValidHeaderSpecific(snes,TS_CLASSID,1); 6639 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 6640 PetscValidHeaderSpecific(udot,VEC_CLASSID,4); 6641 PetscValidHeaderSpecific(y,VEC_CLASSID,5); 6642 PetscCheckSameComm(snes,1,u,3); 6643 PetscCheckSameComm(snes,1,y,5); 6644 6645 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 6646 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 6647 ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr); 6648 ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr); 6649 6650 prhs[0] = mxCreateDoubleScalar((double)ls); 6651 prhs[1] = mxCreateDoubleScalar(time); 6652 prhs[2] = mxCreateDoubleScalar((double)lx); 6653 prhs[3] = mxCreateDoubleScalar((double)lxdot); 6654 prhs[4] = mxCreateDoubleScalar((double)ly); 6655 prhs[5] = mxCreateString(sctx->funcname); 6656 prhs[6] = sctx->ctx; 6657 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr); 6658 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 6659 mxDestroyArray(prhs[0]); 6660 mxDestroyArray(prhs[1]); 6661 mxDestroyArray(prhs[2]); 6662 mxDestroyArray(prhs[3]); 6663 mxDestroyArray(prhs[4]); 6664 mxDestroyArray(prhs[5]); 6665 mxDestroyArray(plhs[0]); 6666 PetscFunctionReturn(0); 6667 } 6668 6669 6670 /* 6671 TSSetFunctionMatlab - Sets the function evaluation routine and function 6672 vector for use by the TS routines in solving ODEs 6673 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 6674 6675 Logically Collective on TS 6676 6677 Input Parameters: 6678 + ts - the TS context 6679 - func - function evaluation routine 6680 6681 Calling sequence of func: 6682 $ func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx); 6683 6684 Level: beginner 6685 6686 .keywords: TS, nonlinear, set, function 6687 6688 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 6689 */ 6690 PetscErrorCode TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx) 6691 { 6692 PetscErrorCode ierr; 6693 TSMatlabContext *sctx; 6694 6695 PetscFunctionBegin; 6696 /* currently sctx is memory bleed */ 6697 ierr = PetscNew(&sctx);CHKERRQ(ierr); 6698 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 6699 /* 6700 This should work, but it doesn't 6701 sctx->ctx = ctx; 6702 mexMakeArrayPersistent(sctx->ctx); 6703 */ 6704 sctx->ctx = mxDuplicateArray(ctx); 6705 6706 ierr = TSSetIFunction(ts,NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr); 6707 PetscFunctionReturn(0); 6708 } 6709 6710 /* 6711 TSComputeJacobian_Matlab - Calls the function that has been set with 6712 TSSetJacobianMatlab(). 6713 6714 Collective on TS 6715 6716 Input Parameters: 6717 + ts - the TS context 6718 . u - input vector 6719 . A, B - the matrices 6720 - ctx - user context 6721 6722 Level: developer 6723 6724 .keywords: TS, nonlinear, compute, function 6725 6726 .seealso: TSSetFunction(), TSGetFunction() 6727 @*/ 6728 PetscErrorCode TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat A,Mat B,void *ctx) 6729 { 6730 PetscErrorCode ierr; 6731 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 6732 int nlhs = 2,nrhs = 9; 6733 mxArray *plhs[2],*prhs[9]; 6734 long long int lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0; 6735 6736 PetscFunctionBegin; 6737 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6738 PetscValidHeaderSpecific(u,VEC_CLASSID,3); 6739 6740 /* call Matlab function in ctx with arguments u and y */ 6741 6742 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 6743 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 6744 ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr); 6745 ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr); 6746 ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr); 6747 6748 prhs[0] = mxCreateDoubleScalar((double)ls); 6749 prhs[1] = mxCreateDoubleScalar((double)time); 6750 prhs[2] = mxCreateDoubleScalar((double)lx); 6751 prhs[3] = mxCreateDoubleScalar((double)lxdot); 6752 prhs[4] = mxCreateDoubleScalar((double)shift); 6753 prhs[5] = mxCreateDoubleScalar((double)lA); 6754 prhs[6] = mxCreateDoubleScalar((double)lB); 6755 prhs[7] = mxCreateString(sctx->funcname); 6756 prhs[8] = sctx->ctx; 6757 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr); 6758 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 6759 mxDestroyArray(prhs[0]); 6760 mxDestroyArray(prhs[1]); 6761 mxDestroyArray(prhs[2]); 6762 mxDestroyArray(prhs[3]); 6763 mxDestroyArray(prhs[4]); 6764 mxDestroyArray(prhs[5]); 6765 mxDestroyArray(prhs[6]); 6766 mxDestroyArray(prhs[7]); 6767 mxDestroyArray(plhs[0]); 6768 mxDestroyArray(plhs[1]); 6769 PetscFunctionReturn(0); 6770 } 6771 6772 6773 /* 6774 TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 6775 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 6776 6777 Logically Collective on TS 6778 6779 Input Parameters: 6780 + ts - the TS context 6781 . A,B - Jacobian matrices 6782 . func - function evaluation routine 6783 - ctx - user context 6784 6785 Calling sequence of func: 6786 $ flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx); 6787 6788 6789 Level: developer 6790 6791 .keywords: TS, nonlinear, set, function 6792 6793 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 6794 */ 6795 PetscErrorCode TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx) 6796 { 6797 PetscErrorCode ierr; 6798 TSMatlabContext *sctx; 6799 6800 PetscFunctionBegin; 6801 /* currently sctx is memory bleed */ 6802 ierr = PetscNew(&sctx);CHKERRQ(ierr); 6803 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 6804 /* 6805 This should work, but it doesn't 6806 sctx->ctx = ctx; 6807 mexMakeArrayPersistent(sctx->ctx); 6808 */ 6809 sctx->ctx = mxDuplicateArray(ctx); 6810 6811 ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 6812 PetscFunctionReturn(0); 6813 } 6814 6815 /* 6816 TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab(). 6817 6818 Collective on TS 6819 6820 .seealso: TSSetFunction(), TSGetFunction() 6821 @*/ 6822 PetscErrorCode TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx) 6823 { 6824 PetscErrorCode ierr; 6825 TSMatlabContext *sctx = (TSMatlabContext*)ctx; 6826 int nlhs = 1,nrhs = 6; 6827 mxArray *plhs[1],*prhs[6]; 6828 long long int lx = 0,ls = 0; 6829 6830 PetscFunctionBegin; 6831 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6832 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 6833 6834 ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr); 6835 ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr); 6836 6837 prhs[0] = mxCreateDoubleScalar((double)ls); 6838 prhs[1] = mxCreateDoubleScalar((double)it); 6839 prhs[2] = mxCreateDoubleScalar((double)time); 6840 prhs[3] = mxCreateDoubleScalar((double)lx); 6841 prhs[4] = mxCreateString(sctx->funcname); 6842 prhs[5] = sctx->ctx; 6843 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr); 6844 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 6845 mxDestroyArray(prhs[0]); 6846 mxDestroyArray(prhs[1]); 6847 mxDestroyArray(prhs[2]); 6848 mxDestroyArray(prhs[3]); 6849 mxDestroyArray(prhs[4]); 6850 mxDestroyArray(plhs[0]); 6851 PetscFunctionReturn(0); 6852 } 6853 6854 6855 /* 6856 TSMonitorSetMatlab - Sets the monitor function from Matlab 6857 6858 Level: developer 6859 6860 .keywords: TS, nonlinear, set, function 6861 6862 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction() 6863 */ 6864 PetscErrorCode TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx) 6865 { 6866 PetscErrorCode ierr; 6867 TSMatlabContext *sctx; 6868 6869 PetscFunctionBegin; 6870 /* currently sctx is memory bleed */ 6871 ierr = PetscNew(&sctx);CHKERRQ(ierr); 6872 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 6873 /* 6874 This should work, but it doesn't 6875 sctx->ctx = ctx; 6876 mexMakeArrayPersistent(sctx->ctx); 6877 */ 6878 sctx->ctx = mxDuplicateArray(ctx); 6879 6880 ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,NULL);CHKERRQ(ierr); 6881 PetscFunctionReturn(0); 6882 } 6883 #endif 6884 6885 /*@C 6886 TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector 6887 in a time based line graph 6888 6889 Collective on TS 6890 6891 Input Parameters: 6892 + ts - the TS context 6893 . step - current time-step 6894 . ptime - current time 6895 . u - current solution 6896 - dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate() 6897 6898 Options Database: 6899 . -ts_monitor_lg_solution_variables 6900 6901 Level: intermediate 6902 6903 Notes: Each process in a parallel run displays its component solutions in a separate window 6904 6905 .keywords: TS, vector, monitor, view 6906 6907 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(), 6908 TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(), 6909 TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(), 6910 TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop() 6911 @*/ 6912 PetscErrorCode TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 6913 { 6914 PetscErrorCode ierr; 6915 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dctx; 6916 const PetscScalar *yy; 6917 Vec v; 6918 6919 PetscFunctionBegin; 6920 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 6921 if (!step) { 6922 PetscDrawAxis axis; 6923 PetscInt dim; 6924 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 6925 ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr); 6926 if (!ctx->names) { 6927 PetscBool flg; 6928 /* user provides names of variables to plot but no names has been set so assume names are integer values */ 6929 ierr = PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg);CHKERRQ(ierr); 6930 if (flg) { 6931 PetscInt i,n; 6932 char **names; 6933 ierr = VecGetSize(u,&n);CHKERRQ(ierr); 6934 ierr = PetscMalloc1(n+1,&names);CHKERRQ(ierr); 6935 for (i=0; i<n; i++) { 6936 ierr = PetscMalloc1(5,&names[i]);CHKERRQ(ierr); 6937 ierr = PetscSNPrintf(names[i],5,"%D",i);CHKERRQ(ierr); 6938 } 6939 names[n] = NULL; 6940 ctx->names = names; 6941 } 6942 } 6943 if (ctx->names && !ctx->displaynames) { 6944 char **displaynames; 6945 PetscBool flg; 6946 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6947 ierr = PetscMalloc1(dim+1,&displaynames);CHKERRQ(ierr); 6948 ierr = PetscMemzero(displaynames,(dim+1)*sizeof(char*));CHKERRQ(ierr); 6949 ierr = PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg);CHKERRQ(ierr); 6950 if (flg) { 6951 ierr = TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames);CHKERRQ(ierr); 6952 } 6953 ierr = PetscStrArrayDestroy(&displaynames);CHKERRQ(ierr); 6954 } 6955 if (ctx->displaynames) { 6956 ierr = PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables);CHKERRQ(ierr); 6957 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames);CHKERRQ(ierr); 6958 } else if (ctx->names) { 6959 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6960 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6961 ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names);CHKERRQ(ierr); 6962 } else { 6963 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 6964 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 6965 } 6966 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 6967 } 6968 6969 if (!ctx->transform) v = u; 6970 else {ierr = (*ctx->transform)(ctx->transformctx,u,&v);CHKERRQ(ierr);} 6971 ierr = VecGetArrayRead(v,&yy);CHKERRQ(ierr); 6972 if (ctx->displaynames) { 6973 PetscInt i; 6974 for (i=0; i<ctx->ndisplayvariables; i++) 6975 ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]); 6976 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues);CHKERRQ(ierr); 6977 } else { 6978 #if defined(PETSC_USE_COMPLEX) 6979 PetscInt i,n; 6980 PetscReal *yreal; 6981 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 6982 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 6983 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 6984 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 6985 ierr = PetscFree(yreal);CHKERRQ(ierr); 6986 #else 6987 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 6988 #endif 6989 } 6990 ierr = VecRestoreArrayRead(v,&yy);CHKERRQ(ierr); 6991 if (ctx->transform) {ierr = VecDestroy(&v);CHKERRQ(ierr);} 6992 6993 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 6994 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 6995 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 6996 } 6997 PetscFunctionReturn(0); 6998 } 6999 7000 7001 /*@C 7002 TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 7003 7004 Collective on TS 7005 7006 Input Parameters: 7007 + ts - the TS context 7008 - names - the names of the components, final string must be NULL 7009 7010 Level: intermediate 7011 7012 Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 7013 7014 .keywords: TS, vector, monitor, view 7015 7016 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames() 7017 @*/ 7018 PetscErrorCode TSMonitorLGSetVariableNames(TS ts,const char * const *names) 7019 { 7020 PetscErrorCode ierr; 7021 PetscInt i; 7022 7023 PetscFunctionBegin; 7024 for (i=0; i<ts->numbermonitors; i++) { 7025 if (ts->monitor[i] == TSMonitorLGSolution) { 7026 ierr = TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names);CHKERRQ(ierr); 7027 break; 7028 } 7029 } 7030 PetscFunctionReturn(0); 7031 } 7032 7033 /*@C 7034 TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 7035 7036 Collective on TS 7037 7038 Input Parameters: 7039 + ts - the TS context 7040 - names - the names of the components, final string must be NULL 7041 7042 Level: intermediate 7043 7044 .keywords: TS, vector, monitor, view 7045 7046 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames() 7047 @*/ 7048 PetscErrorCode TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names) 7049 { 7050 PetscErrorCode ierr; 7051 7052 PetscFunctionBegin; 7053 ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr); 7054 ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr); 7055 PetscFunctionReturn(0); 7056 } 7057 7058 /*@C 7059 TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot 7060 7061 Collective on TS 7062 7063 Input Parameter: 7064 . ts - the TS context 7065 7066 Output Parameter: 7067 . names - the names of the components, final string must be NULL 7068 7069 Level: intermediate 7070 7071 Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 7072 7073 .keywords: TS, vector, monitor, view 7074 7075 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 7076 @*/ 7077 PetscErrorCode TSMonitorLGGetVariableNames(TS ts,const char *const **names) 7078 { 7079 PetscInt i; 7080 7081 PetscFunctionBegin; 7082 *names = NULL; 7083 for (i=0; i<ts->numbermonitors; i++) { 7084 if (ts->monitor[i] == TSMonitorLGSolution) { 7085 TSMonitorLGCtx ctx = (TSMonitorLGCtx) ts->monitorcontext[i]; 7086 *names = (const char *const *)ctx->names; 7087 break; 7088 } 7089 } 7090 PetscFunctionReturn(0); 7091 } 7092 7093 /*@C 7094 TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor 7095 7096 Collective on TS 7097 7098 Input Parameters: 7099 + ctx - the TSMonitorLG context 7100 . displaynames - the names of the components, final string must be NULL 7101 7102 Level: intermediate 7103 7104 .keywords: TS, vector, monitor, view 7105 7106 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 7107 @*/ 7108 PetscErrorCode TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames) 7109 { 7110 PetscInt j = 0,k; 7111 PetscErrorCode ierr; 7112 7113 PetscFunctionBegin; 7114 if (!ctx->names) PetscFunctionReturn(0); 7115 ierr = PetscStrArrayDestroy(&ctx->displaynames);CHKERRQ(ierr); 7116 ierr = PetscStrArrayallocpy(displaynames,&ctx->displaynames);CHKERRQ(ierr); 7117 while (displaynames[j]) j++; 7118 ctx->ndisplayvariables = j; 7119 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables);CHKERRQ(ierr); 7120 ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues);CHKERRQ(ierr); 7121 j = 0; 7122 while (displaynames[j]) { 7123 k = 0; 7124 while (ctx->names[k]) { 7125 PetscBool flg; 7126 ierr = PetscStrcmp(displaynames[j],ctx->names[k],&flg);CHKERRQ(ierr); 7127 if (flg) { 7128 ctx->displayvariables[j] = k; 7129 break; 7130 } 7131 k++; 7132 } 7133 j++; 7134 } 7135 PetscFunctionReturn(0); 7136 } 7137 7138 7139 /*@C 7140 TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor 7141 7142 Collective on TS 7143 7144 Input Parameters: 7145 + ts - the TS context 7146 . displaynames - the names of the components, final string must be NULL 7147 7148 Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 7149 7150 Level: intermediate 7151 7152 .keywords: TS, vector, monitor, view 7153 7154 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 7155 @*/ 7156 PetscErrorCode TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames) 7157 { 7158 PetscInt i; 7159 PetscErrorCode ierr; 7160 7161 PetscFunctionBegin; 7162 for (i=0; i<ts->numbermonitors; i++) { 7163 if (ts->monitor[i] == TSMonitorLGSolution) { 7164 ierr = TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames);CHKERRQ(ierr); 7165 break; 7166 } 7167 } 7168 PetscFunctionReturn(0); 7169 } 7170 7171 /*@C 7172 TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed 7173 7174 Collective on TS 7175 7176 Input Parameters: 7177 + ts - the TS context 7178 . transform - the transform function 7179 . destroy - function to destroy the optional context 7180 - ctx - optional context used by transform function 7181 7182 Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 7183 7184 Level: intermediate 7185 7186 .keywords: TS, vector, monitor, view 7187 7188 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform() 7189 @*/ 7190 PetscErrorCode TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 7191 { 7192 PetscInt i; 7193 PetscErrorCode ierr; 7194 7195 PetscFunctionBegin; 7196 for (i=0; i<ts->numbermonitors; i++) { 7197 if (ts->monitor[i] == TSMonitorLGSolution) { 7198 ierr = TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx);CHKERRQ(ierr); 7199 } 7200 } 7201 PetscFunctionReturn(0); 7202 } 7203 7204 /*@C 7205 TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed 7206 7207 Collective on TSLGCtx 7208 7209 Input Parameters: 7210 + ts - the TS context 7211 . transform - the transform function 7212 . destroy - function to destroy the optional context 7213 - ctx - optional context used by transform function 7214 7215 Level: intermediate 7216 7217 .keywords: TS, vector, monitor, view 7218 7219 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform() 7220 @*/ 7221 PetscErrorCode TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 7222 { 7223 PetscFunctionBegin; 7224 ctx->transform = transform; 7225 ctx->transformdestroy = destroy; 7226 ctx->transformctx = tctx; 7227 PetscFunctionReturn(0); 7228 } 7229 7230 /*@C 7231 TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the solution vector 7232 in a time based line graph 7233 7234 Collective on TS 7235 7236 Input Parameters: 7237 + ts - the TS context 7238 . step - current time-step 7239 . ptime - current time 7240 . u - current solution 7241 - dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate() 7242 7243 Level: intermediate 7244 7245 Notes: Each process in a parallel run displays its component errors in a separate window 7246 7247 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 7248 7249 Options Database Keys: 7250 . -ts_monitor_lg_error - create a graphical monitor of error history 7251 7252 .keywords: TS, vector, monitor, view 7253 7254 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 7255 @*/ 7256 PetscErrorCode TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 7257 { 7258 PetscErrorCode ierr; 7259 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 7260 const PetscScalar *yy; 7261 Vec y; 7262 7263 PetscFunctionBegin; 7264 if (!step) { 7265 PetscDrawAxis axis; 7266 PetscInt dim; 7267 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 7268 ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Solution");CHKERRQ(ierr); 7269 ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr); 7270 ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr); 7271 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 7272 } 7273 ierr = VecDuplicate(u,&y);CHKERRQ(ierr); 7274 ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr); 7275 ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr); 7276 ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr); 7277 #if defined(PETSC_USE_COMPLEX) 7278 { 7279 PetscReal *yreal; 7280 PetscInt i,n; 7281 ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr); 7282 ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr); 7283 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 7284 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr); 7285 ierr = PetscFree(yreal);CHKERRQ(ierr); 7286 } 7287 #else 7288 ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr); 7289 #endif 7290 ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr); 7291 ierr = VecDestroy(&y);CHKERRQ(ierr); 7292 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 7293 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 7294 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 7295 } 7296 PetscFunctionReturn(0); 7297 } 7298 7299 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 7300 { 7301 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 7302 PetscReal x = ptime,y; 7303 PetscErrorCode ierr; 7304 PetscInt its; 7305 7306 PetscFunctionBegin; 7307 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 7308 if (!n) { 7309 PetscDrawAxis axis; 7310 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 7311 ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr); 7312 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 7313 ctx->snes_its = 0; 7314 } 7315 ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr); 7316 y = its - ctx->snes_its; 7317 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 7318 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 7319 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 7320 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 7321 } 7322 ctx->snes_its = its; 7323 PetscFunctionReturn(0); 7324 } 7325 7326 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 7327 { 7328 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 7329 PetscReal x = ptime,y; 7330 PetscErrorCode ierr; 7331 PetscInt its; 7332 7333 PetscFunctionBegin; 7334 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 7335 if (!n) { 7336 PetscDrawAxis axis; 7337 ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr); 7338 ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr); 7339 ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr); 7340 ctx->ksp_its = 0; 7341 } 7342 ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr); 7343 y = its - ctx->ksp_its; 7344 ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr); 7345 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 7346 ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr); 7347 ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr); 7348 } 7349 ctx->ksp_its = its; 7350 PetscFunctionReturn(0); 7351 } 7352 7353 /*@ 7354 TSComputeLinearStability - computes the linear stability function at a point 7355 7356 Collective on TS and Vec 7357 7358 Input Parameters: 7359 + ts - the TS context 7360 - xr,xi - real and imaginary part of input arguments 7361 7362 Output Parameters: 7363 . yr,yi - real and imaginary part of function value 7364 7365 Level: developer 7366 7367 .keywords: TS, compute 7368 7369 .seealso: TSSetRHSFunction(), TSComputeIFunction() 7370 @*/ 7371 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi) 7372 { 7373 PetscErrorCode ierr; 7374 7375 PetscFunctionBegin; 7376 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7377 if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method"); 7378 ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr); 7379 PetscFunctionReturn(0); 7380 } 7381 7382 /* ------------------------------------------------------------------------*/ 7383 /*@C 7384 TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope() 7385 7386 Collective on TS 7387 7388 Input Parameters: 7389 . ts - the ODE solver object 7390 7391 Output Parameter: 7392 . ctx - the context 7393 7394 Level: intermediate 7395 7396 .keywords: TS, monitor, line graph, residual, seealso 7397 7398 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError() 7399 7400 @*/ 7401 PetscErrorCode TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx) 7402 { 7403 PetscErrorCode ierr; 7404 7405 PetscFunctionBegin; 7406 ierr = PetscNew(ctx);CHKERRQ(ierr); 7407 PetscFunctionReturn(0); 7408 } 7409 7410 /*@C 7411 TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution 7412 7413 Collective on TS 7414 7415 Input Parameters: 7416 + ts - the TS context 7417 . step - current time-step 7418 . ptime - current time 7419 . u - current solution 7420 - dctx - the envelope context 7421 7422 Options Database: 7423 . -ts_monitor_envelope 7424 7425 Level: intermediate 7426 7427 Notes: after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope 7428 7429 .keywords: TS, vector, monitor, view 7430 7431 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxCreate() 7432 @*/ 7433 PetscErrorCode TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 7434 { 7435 PetscErrorCode ierr; 7436 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx; 7437 7438 PetscFunctionBegin; 7439 if (!ctx->max) { 7440 ierr = VecDuplicate(u,&ctx->max);CHKERRQ(ierr); 7441 ierr = VecDuplicate(u,&ctx->min);CHKERRQ(ierr); 7442 ierr = VecCopy(u,ctx->max);CHKERRQ(ierr); 7443 ierr = VecCopy(u,ctx->min);CHKERRQ(ierr); 7444 } else { 7445 ierr = VecPointwiseMax(ctx->max,u,ctx->max);CHKERRQ(ierr); 7446 ierr = VecPointwiseMin(ctx->min,u,ctx->min);CHKERRQ(ierr); 7447 } 7448 PetscFunctionReturn(0); 7449 } 7450 7451 7452 /*@C 7453 TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution 7454 7455 Collective on TS 7456 7457 Input Parameter: 7458 . ts - the TS context 7459 7460 Output Parameter: 7461 + max - the maximum values 7462 - min - the minimum values 7463 7464 Notes: If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored 7465 7466 Level: intermediate 7467 7468 .keywords: TS, vector, monitor, view 7469 7470 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 7471 @*/ 7472 PetscErrorCode TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min) 7473 { 7474 PetscInt i; 7475 7476 PetscFunctionBegin; 7477 if (max) *max = NULL; 7478 if (min) *min = NULL; 7479 for (i=0; i<ts->numbermonitors; i++) { 7480 if (ts->monitor[i] == TSMonitorEnvelope) { 7481 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i]; 7482 if (max) *max = ctx->max; 7483 if (min) *min = ctx->min; 7484 break; 7485 } 7486 } 7487 PetscFunctionReturn(0); 7488 } 7489 7490 /*@C 7491 TSMonitorEnvelopeCtxDestroy - Destroys a context that was created with TSMonitorEnvelopeCtxCreate(). 7492 7493 Collective on TSMonitorEnvelopeCtx 7494 7495 Input Parameter: 7496 . ctx - the monitor context 7497 7498 Level: intermediate 7499 7500 .keywords: TS, monitor, line graph, destroy 7501 7502 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep() 7503 @*/ 7504 PetscErrorCode TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx) 7505 { 7506 PetscErrorCode ierr; 7507 7508 PetscFunctionBegin; 7509 ierr = VecDestroy(&(*ctx)->min);CHKERRQ(ierr); 7510 ierr = VecDestroy(&(*ctx)->max);CHKERRQ(ierr); 7511 ierr = PetscFree(*ctx);CHKERRQ(ierr); 7512 PetscFunctionReturn(0); 7513 } 7514 7515 /*@ 7516 TSRollBack - Rolls back one time step 7517 7518 Collective on TS 7519 7520 Input Parameter: 7521 . ts - the TS context obtained from TSCreate() 7522 7523 Level: advanced 7524 7525 .keywords: TS, timestep, rollback 7526 7527 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate() 7528 @*/ 7529 PetscErrorCode TSRollBack(TS ts) 7530 { 7531 PetscErrorCode ierr; 7532 7533 PetscFunctionBegin; 7534 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7535 if (ts->steprollback) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"TSRollBack already called"); 7536 if (!ts->ops->rollback) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name); 7537 ierr = (*ts->ops->rollback)(ts);CHKERRQ(ierr); 7538 ts->time_step = ts->ptime - ts->ptime_prev; 7539 ts->ptime = ts->ptime_prev; 7540 ts->ptime_prev = ts->ptime_prev_rollback; 7541 ts->steps--; ts->total_steps--; 7542 ierr = TSPostEvaluate(ts);CHKERRQ(ierr); 7543 ts->steprollback = PETSC_TRUE; 7544 PetscFunctionReturn(0); 7545 } 7546 7547 /*@ 7548 TSGetStages - Get the number of stages and stage values 7549 7550 Input Parameter: 7551 . ts - the TS context obtained from TSCreate() 7552 7553 Level: advanced 7554 7555 .keywords: TS, getstages 7556 7557 .seealso: TSCreate() 7558 @*/ 7559 PetscErrorCode TSGetStages(TS ts,PetscInt *ns,Vec **Y) 7560 { 7561 PetscErrorCode ierr; 7562 7563 PetscFunctionBegin; 7564 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7565 PetscValidPointer(ns,2); 7566 7567 if (!ts->ops->getstages) *ns=0; 7568 else { 7569 ierr = (*ts->ops->getstages)(ts,ns,Y);CHKERRQ(ierr); 7570 } 7571 PetscFunctionReturn(0); 7572 } 7573 7574 /*@C 7575 TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity. 7576 7577 Collective on SNES 7578 7579 Input Parameters: 7580 + ts - the TS context 7581 . t - current timestep 7582 . U - state vector 7583 . Udot - time derivative of state vector 7584 . shift - shift to apply, see note below 7585 - ctx - an optional user context 7586 7587 Output Parameters: 7588 + J - Jacobian matrix (not altered in this routine) 7589 - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J) 7590 7591 Level: intermediate 7592 7593 Notes: 7594 If F(t,U,Udot)=0 is the DAE, the required Jacobian is 7595 7596 dF/dU + shift*dF/dUdot 7597 7598 Most users should not need to explicitly call this routine, as it 7599 is used internally within the nonlinear solvers. 7600 7601 This will first try to get the coloring from the DM. If the DM type has no coloring 7602 routine, then it will try to get the coloring from the matrix. This requires that the 7603 matrix have nonzero entries precomputed. 7604 7605 .keywords: TS, finite differences, Jacobian, coloring, sparse 7606 .seealso: TSSetIJacobian(), MatFDColoringCreate(), MatFDColoringSetFunction() 7607 @*/ 7608 PetscErrorCode TSComputeIJacobianDefaultColor(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat J,Mat B,void *ctx) 7609 { 7610 SNES snes; 7611 MatFDColoring color; 7612 PetscBool hascolor, matcolor = PETSC_FALSE; 7613 PetscErrorCode ierr; 7614 7615 PetscFunctionBegin; 7616 ierr = PetscOptionsGetBool(((PetscObject)ts)->options,((PetscObject) ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL);CHKERRQ(ierr); 7617 ierr = PetscObjectQuery((PetscObject) B, "TSMatFDColoring", (PetscObject *) &color);CHKERRQ(ierr); 7618 if (!color) { 7619 DM dm; 7620 ISColoring iscoloring; 7621 7622 ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 7623 ierr = DMHasColoring(dm, &hascolor);CHKERRQ(ierr); 7624 if (hascolor && !matcolor) { 7625 ierr = DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring);CHKERRQ(ierr); 7626 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 7627 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 7628 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 7629 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 7630 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 7631 } else { 7632 MatColoring mc; 7633 7634 ierr = MatColoringCreate(B, &mc);CHKERRQ(ierr); 7635 ierr = MatColoringSetDistance(mc, 2);CHKERRQ(ierr); 7636 ierr = MatColoringSetType(mc, MATCOLORINGSL);CHKERRQ(ierr); 7637 ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); 7638 ierr = MatColoringApply(mc, &iscoloring);CHKERRQ(ierr); 7639 ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); 7640 ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr); 7641 ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr); 7642 ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); 7643 ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr); 7644 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 7645 } 7646 ierr = PetscObjectCompose((PetscObject) B, "TSMatFDColoring", (PetscObject) color);CHKERRQ(ierr); 7647 ierr = PetscObjectDereference((PetscObject) color);CHKERRQ(ierr); 7648 } 7649 ierr = TSGetSNES(ts, &snes);CHKERRQ(ierr); 7650 ierr = MatFDColoringApply(B, color, U, snes);CHKERRQ(ierr); 7651 if (J != B) { 7652 ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7653 ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7654 } 7655 PetscFunctionReturn(0); 7656 } 7657 7658 /*@ 7659 TSSetFunctionDomainError - Set the function testing if the current state vector is valid 7660 7661 Input Parameters: 7662 ts - the TS context 7663 func - function called within TSFunctionDomainError 7664 7665 Level: intermediate 7666 7667 .keywords: TS, state, domain 7668 .seealso: TSAdaptCheckStage(), TSFunctionDomainError() 7669 @*/ 7670 7671 PetscErrorCode TSSetFunctionDomainError(TS ts, PetscErrorCode (*func)(TS,PetscReal,Vec,PetscBool*)) 7672 { 7673 PetscFunctionBegin; 7674 PetscValidHeaderSpecific(ts, TS_CLASSID,1); 7675 ts->functiondomainerror = func; 7676 PetscFunctionReturn(0); 7677 } 7678 7679 /*@ 7680 TSFunctionDomainError - Check if the current state is valid 7681 7682 Input Parameters: 7683 ts - the TS context 7684 stagetime - time of the simulation 7685 Y - state vector to check. 7686 7687 Output Parameter: 7688 accept - Set to PETSC_FALSE if the current state vector is valid. 7689 7690 Note: 7691 This function should be used to ensure the state is in a valid part of the space. 7692 For example, one can ensure here all values are positive. 7693 7694 Level: advanced 7695 @*/ 7696 PetscErrorCode TSFunctionDomainError(TS ts,PetscReal stagetime,Vec Y,PetscBool* accept) 7697 { 7698 PetscErrorCode ierr; 7699 7700 PetscFunctionBegin; 7701 7702 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 7703 *accept = PETSC_TRUE; 7704 if (ts->functiondomainerror) { 7705 PetscStackCallStandard((*ts->functiondomainerror),(ts,stagetime,Y,accept)); 7706 } 7707 PetscFunctionReturn(0); 7708 } 7709 7710 /*@C 7711 TSClone - This function clones a time step object. 7712 7713 Collective on MPI_Comm 7714 7715 Input Parameter: 7716 . tsin - The input TS 7717 7718 Output Parameter: 7719 . tsout - The output TS (cloned) 7720 7721 Notes: 7722 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. 7723 7724 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); 7725 7726 Level: developer 7727 7728 .keywords: TS, clone 7729 .seealso: TSCreate(), TSSetType(), TSSetUp(), TSDestroy(), TSSetProblemType() 7730 @*/ 7731 PetscErrorCode TSClone(TS tsin, TS *tsout) 7732 { 7733 TS t; 7734 PetscErrorCode ierr; 7735 SNES snes_start; 7736 DM dm; 7737 TSType type; 7738 7739 PetscFunctionBegin; 7740 PetscValidPointer(tsin,1); 7741 *tsout = NULL; 7742 7743 ierr = PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView);CHKERRQ(ierr); 7744 7745 /* General TS description */ 7746 t->numbermonitors = 0; 7747 t->setupcalled = 0; 7748 t->ksp_its = 0; 7749 t->snes_its = 0; 7750 t->nwork = 0; 7751 t->rhsjacobian.time = -1e20; 7752 t->rhsjacobian.scale = 1.; 7753 t->ijacobian.shift = 1.; 7754 7755 ierr = TSGetSNES(tsin,&snes_start);CHKERRQ(ierr); 7756 ierr = TSSetSNES(t,snes_start);CHKERRQ(ierr); 7757 7758 ierr = TSGetDM(tsin,&dm);CHKERRQ(ierr); 7759 ierr = TSSetDM(t,dm);CHKERRQ(ierr); 7760 7761 t->adapt = tsin->adapt; 7762 ierr = PetscObjectReference((PetscObject)t->adapt);CHKERRQ(ierr); 7763 7764 t->trajectory = tsin->trajectory; 7765 ierr = PetscObjectReference((PetscObject)t->trajectory);CHKERRQ(ierr); 7766 7767 t->event = tsin->event; 7768 if (t->event) t->event->refct++; 7769 7770 t->problem_type = tsin->problem_type; 7771 t->ptime = tsin->ptime; 7772 t->ptime_prev = tsin->ptime_prev; 7773 t->time_step = tsin->time_step; 7774 t->max_time = tsin->max_time; 7775 t->steps = tsin->steps; 7776 t->total_steps = tsin->total_steps; 7777 t->max_steps = tsin->max_steps; 7778 t->equation_type = tsin->equation_type; 7779 t->atol = tsin->atol; 7780 t->rtol = tsin->rtol; 7781 t->max_snes_failures = tsin->max_snes_failures; 7782 t->max_reject = tsin->max_reject; 7783 t->errorifstepfailed = tsin->errorifstepfailed; 7784 7785 ierr = TSGetType(tsin,&type);CHKERRQ(ierr); 7786 ierr = TSSetType(t,type);CHKERRQ(ierr); 7787 7788 t->vec_sol = NULL; 7789 7790 t->cfltime = tsin->cfltime; 7791 t->cfltime_local = tsin->cfltime_local; 7792 t->exact_final_time = tsin->exact_final_time; 7793 7794 ierr = PetscMemcpy(t->ops,tsin->ops,sizeof(struct _TSOps));CHKERRQ(ierr); 7795 7796 if (((PetscObject)tsin)->fortran_func_pointers) { 7797 PetscInt i; 7798 ierr = PetscMalloc((10)*sizeof(void(*)(void)),&((PetscObject)t)->fortran_func_pointers);CHKERRQ(ierr); 7799 for (i=0; i<10; i++) { 7800 ((PetscObject)t)->fortran_func_pointers[i] = ((PetscObject)tsin)->fortran_func_pointers[i]; 7801 } 7802 } 7803 *tsout = t; 7804 PetscFunctionReturn(0); 7805 } 7806