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