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