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