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