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