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