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