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