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