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