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