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