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