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