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