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