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