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