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