Initial Conditions

Initialisation

Initial conditions are used to set the flow variable values in all cells at the start of a simulation. The initial conditions default to the reference state (above) if not specified

# Initial conditions
'initial' : 'IC_2',

See `Initial Conditions`_. A function which defines the initial fields may be supplied

# Initial conditions
'initial' : {
              # Name of initial condition
              'name' : 'IC_1',
              # Optional: User defined function
              'func' : my_initialisation,
            },

Example User Defined Initialisation Function

def my_initialisation(**kwargs):

    # Dimensional primitive variables
    pressure = kwargs['pressure']
    temperature = kwargs['temperature']
    velocity = kwargs['velocity']
    wall_distance = kwargs['wall_distance']
    location = kwargs['location']

    if location[0] > 10.0:
      velocity[0] *= 2.0

    # Return a dictionary with user defined quantity.
    # Same schema as above
    return { 'velocity' : velocity }

Initial Conditions

The initial condition properties are defined using consecutively numbered blocks

'IC_1' : {....},
'IC_2' : {....},
'IC_3' : {....},

Each block can contain the following options

# Required: Static temperature in Kelvin
'temperature': 293.0,
# Required: Static pressure in Pascals
'pressure':101325.0,
# Fluid velocity
'V': {
        # Velocity vector
        'vector' : [1.0,0.0,0.0],
        # Optional: specifies velocity magnitude
        'Mach' : 0.20,
      },

Dynamic (shear, absolute or molecular) viscosity should be defined at the static temperature previously specified. This can be specified either as a dimensional quantity or by a Reynolds number and reference length

# Dynamic viscosity in dimensional units
'viscosity' : 1.83e-5,

or

# Reynolds number
'Reynolds No' : 5.0e6,
# Reference length
'Reference Length' : 1.0,

Turbulence intensity is defined as the ratio of velocity fluctuations \(u^{'}\) to the mean flow velocity. A turbulence intensity of 1% is considered low and greater than 10% is considered high.

# Turbulence intensity %
'turbulence intensity': 0.01,
# Turbulence intensity for sustainment %
'ambient turbulence intensity': 0.01,

The eddy viscosity ratio \((\mu_t/\mu)\) varies depending type of flow. For external flows this ratio varies from 0.1 to 1 (wind tunnel 1 to 10)

For internal flows there is greater dependence on Reynolds number as the largest eddies in the flow are limited by the characteristic lengths of the geometry (e.g. The height of the channel or diameter of the pipe). Typical values are:

Re

3000

5000

10,000

15,000

20,000

> 100,000

eddy

11.6

16.5

26.7

34.0

50.1

100

# Eddy viscosity ratio
'eddy viscosity ratio': 0.1,
# Eddy viscosity ratio for sustainment
'ambient eddy viscosity ratio': 0.1,

The user can also provide functions to specify a ‘wall-function’ - or the turbulence viscosity profile near a boundary. For example an atmospheric boundary layer (ABL) could be specified like this:

'profile' : {
             'ABL' : {
                       'roughness length' : 0.0003,
                       'friction velocity' : 0.4,
                       'surface layer height' : -1.0,
                       'Monin-Obukhov length' : -1.0,
                       # Non dimensional TKE/friction velocity**2
                       'TKE' : 0.928,
                       # ground level (optional if not set wall distance is used)
                       'z0'  : -0.75,
                      },
            },
'profile' : {
             'field' : 'inflow_field.vtp',
             # Localise field using wall distance rather that z coordinate
             'use wall distance' : True,
            },

Note

The conditions in the VTK file are specified by node based arrays with names ‘Pressure’, ‘Temperature’, ‘Velocity’, ‘TI’ and ‘EddyViscosity’. Note the field will override the conditions specified previously therefore the user can specify only the conditions that are different from default.

Certain conditions are specified relative to a reference set of conditions

'reference' : 'IC_1',
# total pressure/reference static pressure
# This can be a single value or VTK field file name with array name 'TotalPressureRatio' or function
'total pressure ratio' : 1.0,
# total temperature/reference static temperature
# This can be a single value or VTK field file name with array name 'TotalTemperatureRatio' or function
'total temperature ratio' : 1.0,
# Mach number
'mach' : 0.5,
# Direction vector or function
'vector' : [1.0,0.0,0.0],
'reference' : 'IC_1',
# static pressure/reference static pressure
# This can be a single value or VTK field file name with array name 'StaticPressureRatio' or function
'static pressure ratio' : 1.0,
'reference' : 'IC_1',
# Mass flow ratio
'mass flow ratio' : 1.0,
# Or mass flow rate
'mass flow rate' : 10.0
# Example pressure ratio function
def total_pressure_ratio(x, y, z):

    ratio = 1.0
    if x < 10.0:
        ratio = 0.9

    return ratio

Note

\(W^* =\frac{\dot{m}}{\rho V}\)

Driven Initial Conditions

Another way of prescribing a farfield initial condition is by defining a ‘driving function’, which on evaluation returns an initial condition dictionary. The driving function is re-evaluated at zCFD’s reporting frequency, meaning that the condition (e.g. inlet velocity) can be programmed to change as the simulation progresses. For a driving function lift_target_ic_func, the IC should be set up as follows in the parameters dictionary.

'IC_2' : lift_target_ic_func

At startup, the function is only provided with the key word arguments RealTimeStep=0, Cycle=0. However, the driving function is subsequently provided with key word arguments containing all the data in the ‘_report.csv’ file, evaluated at the previous timestep. For any driven initial condition, every value in the initial condition dictionary is also appended to the _report.csv file.

This means that the initial condition can be programmed to respond to the flow. An example is shown below, where the driven IC will continually adjust inlet angle of attack until a specified lift coefficient is acheived.

If the driven initial condition has been programmed to respond to changes in the flow, it is important to ensure that the flow has had enough time to propogate from the farfield through to the region of interest and settle before readjusting the driven initial condition. For simulations where the farfield is distant from the geometry, local and implicit time-stepping will likely give the fastest propogation of adjusted farfield conditions through the domain.

def lift_target_ic_func(**kwargs):
   alpha_init = 0 # Initial angle of attack
   lift_target= 0.5 # Targeted lift coefficient
   update_period = 1000 # How often alpha should be updated
   flow_settling_period = 1500

   assumed_d_cL_d_alpha = 0.1 # Used to estimate alpha which would give required lift
   relaxation_factor = 1.15 # <1: under-relaxation, >1: over-relaxation


   if 'lift_target_alpha' in kwargs.keys(): # If timestep > 1
       alpha_current = kwargs['lift_target_alpha']
       F_xyz = [kwargs['wall_Fx'], kwargs['wall_Fy'], kwargs['wall_Fz']]
       F_LDS = zutil.rotate_vector(F_xyz, alpha_current, 0.0)
       lift_current = F_LDS[2] # Lift coefficient, having rotated to account for alpha
   else:
       lift_current = 0 # placeholder value

   if kwargs['Cycle'] < flow_settling_period:
       alpha_new = alpha_init
   else:
       if (kwargs['Cycle'] % update_period) == 0:
           d_cL_required = lift_target - lift_current
           d_alpha = relaxation_factor / assumed_d_cL_d_alpha *  d_cL_required
           alpha_new = alpha_current + d_alpha
           print("Alpha updated from {} to {}".format(alpha_current, alpha_new), flush = True)
       else:
           alpha_new = alpha_current

   dict_out = {
       "temperature": 300,
       "pressure": 101325.0,
       'v': {
           'mach' : 0.15,
           'vector' : zutil.vector_from_angle(alpha_new, 0.0)
           },
       "reynolds no": 6.0e6,
       "eddy viscosity ratio": 1.0,
       "monitor": { # Monitor entries can be floats or lists of floats
                    "prefix": "lift_target",
                    "alpha": alpha_new,   # Extra keys can be added to a driven IC dictionary,
                    "lift": lift_current,  # allowing monitoring of key parameters flow in the _report.csv
                  },
   }

   return dict_out

Note

Driven initial conditions cannot be used as reference conditions, to initialise the flow or within a restarted simulation.