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