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