Appendix: Time Integration

The run control file variables that control the time integration of the system of governing equations are discussed in the following subsections.

Integration Method

The time-integration method used in Stream is specified with the run control file variable timeIntegrator. Three methods are available. The first method is the standard first-order backward differencing method. This method can be chosen by using the value BDF. If the timeIntegrator variable is not specified in the vars file, the value BDF is chosen by default. This method is commonly used for marching simulations to a steady-state condition, but is not generally acceptable for unsteady flows due to the requirement for excessively small time steps in order to reduce numerical dissipation. For unsteady flows, Stream offers two second-order differencing methods. The first of these methods is the second-order backward differencing method, which can be chosen by using the value BDF2. The second is the Crank-Nicolson method, which can chosen by using the value CN. An example of setting the time integrator in a run control file is shown below.

timeIntegrator: BDF2

Blended Crank-Nicholson Method

While both the BDF2 and CN are formally second-order accurate methods, CN has been found in our experience to be less dissipative than BDF2. However, the pure CN scheme is not always robust for complex flows unless very small timesteps are used, which can lead to prohibitive run times. To mitigate this problem, STREAM provides a blended CN/BDF scheme, which is activated by a blending factor using the run control file variable CNBDFBlend, when using the CN time itegrator. This blending factor can be set anywhere between 0 (resulting scheme is 100% BDF) and 1 (resulting scheme is 100% CN). If this variable is not provided, the value defaults to 1. In practice, it has been found that blending factor above 0.9 can help stabilize the CN scheme at higher time step, while still providing slightly lower dissipation characteristics than BDF2. An example of using the blending factor is shown below.

CNBDFBlend: 0.9

For finite-rate chemistry simulations, Stream uses a second-order Strang-splitting procedure, which is not compatible with the specification of BDF2 for the timeIntegrator variable. For unsteady DES and LES simulations with Stream, one should always use the CN scheme with the highest stable value of the variable CNBDFBlend as possible.

Time Step Selection

The time step for a simulation can be set in two different ways. To run a simulation with a single constant time step value, use the run control file variable timeStep in the following manner:

timeStep: 1.0e-01

If one is interested in only a steady-state solution, often the best approach is to simply eliminate the temporal terms from the governing equations by specifying a large time step value, say 1.0e+30, which is the default value for this variable. One can then control the iterative process by only using the relaxation factors specified via the variables for the individual governing equations. This is the preferred method for steady-state flows. As a measure of last resort however, one can use a finite time step to perform temporal relaxation, which can often be effective at stabilizing a convergence path where iterative relaxation alone is not sufficient.

A second method of setting the time step is also available, whereby one can specify several so-called ramps in which the time step remains at a fixed value for a certain number of time steps before moving to a new ramp value. At the end of this process the time step will take on the value specified by the variable timeStep. Consider the following vars file specification:

time step ramp
timeStep: 1.0e-01
timeStepRamp: <ramp0=[n=1000,dt=1.0e-04],ramp1=[n=100,dt=1.0e-03],
ramp2=[n=10,dt=1.0e-02]>

In this case, the simulation will start off by performing 1000 time steps at \(dt= 10^{-4} s\), followed by 100 time steps at \(dt= 10^{-3} s\), followed by 10 time steps at \(dt= 10^{-2} s\), and then assume the constant value of \(dt= 10^{-1} s\) for the remainder of the simulation. It is important to note that the time step ramp will be active if the time step number in the simulation is lower than the total number of time steps in the ramp. So, for example, using the case above, if one ran a simulation of 1000 time steps and then stopped, upon restart the time step ramp would proceed to immediately do 100 time steps at \(dt= 10^{-3} s\), followed by 10 time steps at \(dt= 10^{-2} s\) and then use the constant value of \(dt= 10^{-1} s\) for the remainder of the restart simulation. On the other hand, if one had run a simulation with 2000 time steps and then stopped, upon restart, the time step ramp would no longer be active, having stopped at time step 1110. One may use an arbitrary number of ramps. In addition, the names of the ramps (ramp0, ramp1, …) are not important. One can choose any names. Only the order of the ramps is important.

Number of Time Steps

The number of time steps to run in the simulation is specified by the run control file variable numTimeSteps, as follows:

numTimeSteps: 1001

Once a simulation is initiated, it will not terminate until the number of specified time steps is run. If one wishes to terminate the solution at an arbitrary point in an orderly manner before the maximum number of time steps specified by numTimeSteps has been executed, one can use the so-called touch stop utility, by simply executing the command touch stop while in the directory from which the simulation was initiated. This will create a file called stop in the directory. When the code detects the presence of this file, it will terminate in an orderly manner, writing both output and restart files at the last time step executed. The code will automatically delete the file stop so that it will not linger around and cause problems with future runs from the same directory.

A maximumRunTime variable is also available in the run control file to specify the maximum wall time for the simulation. If the simulation exceeds this time, it will terminate in an orderly manner and write out restart files. Default units are seconds. Some examples of specifying a maximum run time are shown below.

maximum run time
maximumRunTime: 3600

maximumRunTime: 5 minute

maximumRunTime: 2.5 hour

maximumRunTime: 1 day

A maximumSimulationTime variable is also available in the run control file to specify the maximum simulation time for the simulation. If the simulation exceeds this time, it will terminate in an orderly manner and write out plot and restart files. Default units are seconds, and the variable can be specified with various units as shown in the example above.

Time Step Convergence

To achieve the proper temporal accuracy of a time integration scheme, one must converge the system of equations within each time step to the level required to eliminate the iterative (SIMPLE) or corrective (PIMPLE) error. The topic of convergence estimation is discussed in more detail here. Convergence within any time step is controlled using the run control file convergenceTolerance and maxIterationsPerTimeStep variables. Two type of convergence specification are available. If one wishes to have a single absolute tolerance value for all governing equations, the following specification should be used (default values shown):

convergence tolerance
convergenceTolerance: 1.0e-30
maxIterationsPerTimeStep: 50

Using this form, if the total residuals (the residual values printed to standard output) at an iteration all become lower than the value specified by convergenceTolerance, the code will automatically advance to the next time step after that iteration. If such a convergence level is not obtained within the maximum number of iterations specified by the value of maxIterationsPerTimeStep, the code will in any case advance to the next time step. Note that the variable convergenceTolerance can only be effectively used if residuals have been normalized using reference values, as discussed here. Common practice is normally to forego the usage of convergenceTolerance by setting its value to a small number, say \(10^{-30}\), and simply using the variable maxIterationsPerTimeStep to control convergence within the time step. This is done generally to avoid the complication of having to compute reference values that provide meaningful nondimensionalization of all total residuals simultaneously. In addition, for engineering geometries, it is often impossible to achieve a consistent convergence tolerance limit on all residuals at every time step. For steady-state simulations, one would typically run a fixed number of time steps by setting values like the following:

steady-state simulation
convergenceTolerance: 1.0e-30
maxIterationsPerTimeStep: 1
numTimeSteps: 500

To control convergence within the time step in a more refined manner, one can use the run control file absolute and relative convergence tolerance variables as follows (all possible specifiable tolerances shown):

individual equation convergence criteria
convergenceAbsoluteTolerance: <default=1.0e-03, momentum=1.0e-04, pressure=1.0e-05,
                               energy=1.0e-06, k=1.0e-07, omega=1.0e-03, epsilon=1.0e-04, species=1.0e-02>

convergenceRelativeTolerance: <default=1.0e-03, momentum=1.0e-04, pressure=1.0e-04,
                               energy=1.0e-04, k=1.0e-04, omega=1.0e-04, epsilon=1.0e-04, species=1.0e-04>

maxIterationsPerTimeStep: 100

In the above options, the default value is first assigned to all governing equations. Subsequent entries for each of the specific governing equations are then specified to override the default value, if desired. If one does not specify a default value, the default value for the default value is \(10^{-30}\). One need only specify override tolerance values for the specific equations of interest. For example, one could specify an absolute convergence tolerance of \(10^{-3}\) for all equations, but a tolerance of \(10^{-4}\) for pressure, as follows:

specific absolute tolerance on pressure, generic on all other equations
convergenceAbsoluteTolerance: <default=1.0e-03, pressure=1.0e-04>

One may use convergenceAbsoluteTolerance and convergenceRelativeTolerance either separately or together. For example, to specify that convergence is to be determined by the satisfaction of only relative tolerances, one would specify:

specific relative tolerance on pressure, default on all other equations
convergenceRelativeTolerance: <default=1.0e-03, pressure=1.0e-04>

This specification is equivalent to the following:

convergenceAbsoluteTolerance: <default=1.0e-30>
convergenceRelativeTolerance: <default=1.0e-03, pressure=1.0e-04>

whereby the small default absolute convergence tolerance guarantees that absolute convergence is never satisfied, and only relative convergence determines convergence within the time step. Convergence within a time step is declared when all the active governing equations are individually converged. Convergence for any governing equation is declared when either the absolute tolerance or the relative tolerance is satisfied. If all active governing equations have not converged within the maximum number of iterations specified by the value of maxIterationsPerTimeStep, the code will automatically advance to the next time step.