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