Skip to content

Initial Conditions (INIT)

Set initial temperature, velocity, and species distributions in your simulation domain.

Overview

Initial conditions (INIT namelist) specify non-ambient starting states for regions of the domain. This is useful for:

  • Pre-heated zones
  • Initial velocity FdsFields
  • Pre-existing smoke layers
  • Species concentrations
  • Pressure distributions
from pyfds import Init
from pyfds.core.geometry import Bounds3D

# Hot zone at start of simulation
sim.add(Init(
    xb=Bounds3D.of(2, 4, 2, 4, 0, 2),
    temperature=200.0  # Start at 200°C
))

Temperature Initialization

Single Region

# Hot region (industrial process area)
sim.add(Init(
    xb=Bounds3D.of(1, 3, 1, 3, 0, 2),
    temperature=150.0  # °C
)

# Cold region (refrigerated space)
sim.add(Init(
    xb=Bounds3D.of(5, 7, 2, 4, 0, 2),
    temperature=5.0  # °C
)

Layered Temperature

# Hot upper layer (post-flashover)
sim.add(Init(
    xb=Bounds3D.of(0, 8, 0, 6, 2, 3),  # Upper region
    temperature=600.0
)

# Cooler lower layer
sim.add(Init(
    xb=Bounds3D.of(0, 8, 0, 6, 0, 2),  # Lower region
    temperature=100.0
)

Vertical Temperature Gradient

# Create multiple layers with temperature gradient
# Bottom to top: 20°C to 200°C
temps = [20, 60, 100, 140, 180, 200]
z_levels = [(0, 0.5), (0.5, 1.0), (1.0, 1.5), (1.5, 2.0), (2.0, 2.4), (2.4, 3.0)]

for temp, (z_min, z_max) in zip(temps, z_levels):
    sim.add(Init(
        xb=Bounds3D.of(0, 5, 0, 4, z_min, z_max),
        temperature=temp
    )

Velocity Initialization

Horizontal Flow

# Eastward flow (e.g., prevailing wind)
sim.add(Init(
    xb=Bounds3D.of(0, 50, 0, 50, 0, 30),
    u_velocity=5.0,  # 5 m/s in +X direction
    v_velocity=0.0,
    w_velocity=0.0
)

# Northward flow
sim.add(Init(
    xb=Bounds3D.of(0, 50, 0, 50, 0, 30),
    u_velocity=0.0,
    v_velocity=3.0,  # 3 m/s in +Y direction
    w_velocity=0.0
)

Vertical Flow

# Updraft in chimney
sim.add(Init(
    xb=Bounds3D.of(2, 3, 2, 3, 0, 10),
    u_velocity=0.0,
    v_velocity=0.0,
    w_velocity=2.0  # 2 m/s upward
)

# Downdraft
sim.add(Init(
    xb=Bounds3D.of(5, 6, 5, 6, 0, 10),
    w_velocity=-1.5  # 1.5 m/s downward
)

Rotating Flow

# Vortex-like initial condition (simplified)
# Center at (5, 5), tangential velocity
import math

r = 2.0  # Radius
omega = 1.0  # Angular velocity (rad/s)

# Note: This is conceptual - FDS doesn't directly support rotating init
# Would need multiple INIT regions to approximate
sim.add(Init(
    xb=Bounds3D.of(3, 7, 5, 5.2, 0, 3),
    u_velocity=0.0,
    v_velocity=omega * r  # Tangential velocity
)

Species Initialization

Pre-Existing Smoke

# Smoke-filled upper layer
sim.add(Init(
    xb=Bounds3D.of(0, 10, 0, 8, 2, 3),
    mass_fraction={'SOOT': 0.01}  # 1% soot by mass
)

Oxygen-Depleted Zone

# Low oxygen region (post-fire area)
sim.add(Init(
    xb=Bounds3D.of(2, 4, 2, 4, 0, 2.5),
    mass_fraction={'OXYGEN': 0.15}  # 15% O2 (normal ~23%)
)

CO2 Enriched Zone

# High CO2 concentration
sim.add(Init(
    xb=Bounds3D.of(1, 3, 1, 3, 0, 2),
    mass_fraction={'CARBON DIOXIDE': 0.05}  # 5% CO2
)

Multiple Species

# Complex initial composition
sim.add(Init(
    xb=Bounds3D.of(2, 5, 2, 5, 1, 2),
    mass_fraction={
        'OXYGEN': 0.18,
        'CARBON DIOXIDE': 0.03,
        'CARBON MONOXIDE': 0.001,
        'SOOT': 0.005
    }
)

Density and Pressure

Density Initialization

# Low-density hot zone
sim.add(Init(
    xb=Bounds3D.of(2, 4, 2, 4, 2, 3),
    density=0.8  # kg/m³ (normal air ~1.2)
)

# High-density cold zone
sim.add(Init(
    xb=Bounds3D.of(5, 7, 5, 7, 0, 1),
    density=1.4  # kg/m³
)

Pressure Initialization

# Elevated pressure zone
sim.add(Init(
    xb=Bounds3D.of(3, 6, 3, 6, 0, 2.5),
    pressure=101825.0  # Pa (500 Pa above ambient)
)

Complete Examples

Post-Flashover Room

from pyfds import Simulation

sim = Simulation(chid='post_flashover')
sim.add(Time(t_end=300.0))
sim.add(Mesh(ijk=Grid3D.of(60, 50, 30), xb=Bounds3D.of(0, 6, 0, 5, 0, 3)))

# Ambient conditions
sim.set_misc(tmpa=20.0)

# Hot upper layer (post-flashover conditions)
sim.add(Init(
    xb=Bounds3D.of(0, 6, 0, 5, 2, 3),
    temperature=600.0  # Hot layer
)

# Warm lower layer
sim.add(Init(
    xb=Bounds3D.of(0, 6, 0, 5, 0, 2),
    temperature=200.0  # Cooler but still hot
)

# Door for ventilation
sim.add(Vent(xb=Bounds3D.of(6, 6, 2, 3, 0, 2.1), surf_id='OPEN'))

# Temperature devices
for z in [0.5, 1.5, 2.5]:
    sim.add(Device(
        id=f'TEMP_Z{int(z*10)}',
        quantity='TEMPERATURE',
        xyz=Point3D.of(3, 2.5, z)
    )

sim.write('post_flashover.fds')

Wind Tunnel

sim = Simulation(chid='wind_tunnel')
sim.add(Time(t_end=120.0))
sim.add(Mesh(ijk=Grid3D.of(200, 40, 40), xb=Bounds3D.of(0, 20, 0, 4, 0, 4)))

# Initial wind velocity throughout domain
sim.add(Init(
    xb=Bounds3D.of(0, 20, 0, 4, 0, 4),
    u_velocity=10.0,  # 10 m/s wind in +X direction
    v_velocity=0.0,
    w_velocity=0.0
)

# Open boundaries for wind flow
sim.add(Vent(mb='XMIN', surf_id='OPEN'))
sim.add(Vent(mb='XMAX', surf_id='OPEN'))
sim.add(Vent(mb='YMIN', surf_id='OPEN'))
sim.add(Vent(mb='YMAX', surf_id='OPEN'))
sim.add(Vent(mb='ZMAX', surf_id='OPEN'))

# Obstacle in flow
sim.add(Obstruction(xb=Bounds3D.of(8, 10, 1.5, 2.5, 0, 2), surf_id='INERT'))

# Velocity devices downstream
for x in [12, 14, 16]:
    sim.add(Device(
        id=f'VEL_X{x}',
        quantity='VELOCITY',
        xyz=Point3D.of(x, 2, 2)
    )

sim.write('wind_tunnel.fds')

Smoke Layer Evolution

sim = Simulation(chid='smoke_layer')
sim.add(Time(t_end=600.0))
sim.add(Mesh(ijk=Grid3D.of(80, 60, 30), xb=Bounds3D.of(0, 8, 0, 6, 0, 3)))

# Initial smoke layer at ceiling
sim.add(Init(
    xb=Bounds3D.of(0, 8, 0, 6, 2.5, 3),
    temperature=100.0,
    mass_fraction={'SOOT': 0.005}  # Light smoke
)

# Small continued fire source
sim.add(Surface(id='FIRE', hrrpua=200.0))
sim.add(Obstruction(xb=Bounds3D.of(3.5, 4.5, 2.5, 3.5, 0, 0.1), surf_id='FIRE'))

# Door for ventilation
sim.add(Vent(xb=Bounds3D.of(8, 8, 2.5, 3.5, 0, 2.1), surf_id='OPEN'))

# Layer height tracking
sim.add(Device(
    id='LAYER_HEIGHT',
    quantity='LAYER HEIGHT',
    xyz=Point3D.of(4, 3, 1.5)
)

# Visibility at multiple heights
for z in [0.5, 1.5, 2.5]:
    sim.add(Device(
        id=f'VIS_Z{int(z*10)}',
        quantity='VISIBILITY',
        xyz=Point3D.of(4, 3, z)
    )

sim.write('smoke_layer.fds')

Thermal Stratification

sim = Simulation(chid='stratification')
sim.add(Time(t_end=600.0))
sim.add(Mesh(ijk=Grid3D.of(50, 50, 100), xb=Bounds3D.of(0, 5, 0, 5, 0, 10)))

# Create stratified layers (warmer at top)
# Simulate stable atmospheric conditions
z_ranges = [(0, 2), (2, 4), (4, 6), (6, 8), (8, 10)]
temps = [15, 18, 21, 24, 27]  # Temperature increases with height

for (z_min, z_max), temp in zip(z_ranges, temps):
    sim.add(Init(
        xb=Bounds3D.of(0, 5, 0, 5, z_min, z_max),
        temperature=temp
    )

# Fire at ground level
sim.add(Surface(id='FIRE', hrrpua=500.0))
sim.add(Obstruction(xb=Bounds3D.of(2, 3, 2, 3, 0, 0.2), surf_id='FIRE'))

# Vertical temperature profile
for z in [1, 3, 5, 7, 9]:
    sim.add(Device(
        id=f'TEMP_Z{z}',
        quantity='TEMPERATURE',
        xyz=Point3D.of(2.5, 2.5, z)
    )

sim.write('stratification.fds')

Buoyant Plume in Crossflow

sim = Simulation(chid='plume_crossflow')
sim.add(Time(t_end=300.0))
sim.add(Mesh(ijk=Grid3D.of(120, 80, 60), xb=Bounds3D.of(0, 12, 0, 8, 0, 6)))

# Crossflow wind
sim.add(Init(
    xb=Bounds3D.of(0, 12, 0, 8, 0, 6),
    u_velocity=3.0,  # 3 m/s horizontal wind
    v_velocity=0.0,
    w_velocity=0.0
)

# Open boundaries
for mb in ['XMIN', 'XMAX', 'YMIN', 'YMAX', 'ZMAX']:
    sim.add(Vent(mb=mb, surf_id='OPEN'))

# Fire source
sim.add(Surface(id='FIRE', hrrpua=1000.0))
sim.add(Obstruction(xb=Bounds3D.of(2, 3, 3.5, 4.5, 0, 0.1), surf_id='FIRE'))

# Temperature measurements downwind
for x in [4, 6, 8, 10]:
    for z in [1, 2, 3, 4]:
        sim.add(Device(
            id=f'TEMP_X{x}_Z{z}',
            quantity='TEMPERATURE',
            xyz=Point3D.of(x, 4, z)
        )

sim.write('plume_crossflow.fds')

Best Practices

1. Consistent with Ambient Conditions

# Set ambient first
sim.set_misc(tmpa=20.0, p_inf=101325.0)

# Then set initial conditions relative to ambient
sim.add(Init(
    xb=Bounds3D.of(2, 4, 2, 4, 0, 2),
    temperature=100.0  # 100°C, not 80°C above ambient
)

2. Avoid Unrealistic Gradients

# Good: Smooth transition
sim.add(Init(xb=Bounds3D.of(0, 5, 0, 4, 0, 1), temperature=50.0))
sim.add(Init(xb=Bounds3D.of(0, 5, 0, 4, 1, 2), temperature=100.0))
sim.add(Init(xb=Bounds3D.of(0, 5, 0, 4, 2, 3), temperature=150.0))

# Avoid: Extreme jump (will cause numerical instability)
sim.add(Init(xb=Bounds3D.of(0, 5, 0, 4, 0, 1.5), temperature=20.0))
sim.add(Init(xb=Bounds3D.of(0, 5, 0, 4, 1.5, 3), temperature=800.0)  # Too steep!

3. Match Physics

# For hot layer, reduce density appropriately
# FDS will compute density from ideal gas law
sim.add(Init(
    xb=Bounds3D.of(0, 6, 0, 5, 2, 3),
    temperature=600.0  # Density automatically calculated
)

4. Document Initial Conditions

# Clear comments explaining initial state
# Simulating conditions 10 minutes after ignition
# Upper layer at 600°C (post-flashover)
# Lower layer at 200°C (thermal penetration)
sim.add(Init(xb=Bounds3D.of(0, 6, 0, 5, 2, 3), temperature=600.0))
sim.add(Init(xb=Bounds3D.of(0, 6, 0, 5, 0, 2), temperature=200.0))

Common Issues

Simulation unstable at start

Cause: Unrealistic initial conditions or steep gradients

Solution: Use smoother transitions

# Instead of abrupt change
sim.add(Init(xb=Bounds3D.of(0, 5, 0, 4, 0, 1.5), temperature=20.0))
sim.add(Init(xb=Bounds3D.of(0, 5, 0, 4, 1.5, 3), temperature=600.0))

# Use gradual layers
for z, T in [(0, 20), (1, 100), (2, 300), (2.5, 600)]:
    sim.add(Init(xb=Bounds3D.of(0, 5, 0, 4, z, z+0.5), temperature=T))

Initial velocity disappears quickly

Cause: No maintained boundary condition

Solution: Use boundary conditions to sustain flow

# Initial velocity
sim.add(Init(xb=Bounds3D.of(0, 20, 0, 10, 0, 10), u_velocity=5.0))

# Maintain with inflow boundary
sim.add(Vent(mb='XMIN', surf_id='OPEN'))
sim.set_misc(wind_speed=5.0, wind_direction=0.0)

Species concentration not conserved

Cause: Mass fractions don't sum correctly

Solution: Ensure mass fractions are physically realistic

# FDS will normalize, but be explicit
sim.add(Init(
    xb=Bounds3D.of(2, 4, 2, 4, 0, 2),
    mass_fraction={
        'OXYGEN': 0.20,        # Reduced from 0.23
        'NITROGEN': 0.77,      # Normal
        'CARBON DIOXIDE': 0.03  # Added
    }
    # Total = 1.00
)

Use Cases

Research Applications

# Controlled initial conditions for parametric study
initial_temps = [100, 200, 300, 400, 500]

for T_init in initial_temps:
    sim = Simulation(chid=f'init_T{T_init}')
    sim.add(Init(xb=Bounds3D.of(0, 5, 0, 4, 2, 3), temperature=T_init))
    # ... rest of setup

Validation Studies

# Match experimental initial conditions
# Experiment: Pre-heated ceiling to 200°C
sim.add(Init(
    xb=Bounds3D.of(0, 3, 0, 3, 2.4, 2.5),  # Ceiling surface
    temperature=200.0
)

Continuing Simulations

# Approximate state from previous run
# Previous run ended with upper layer at 400°C
sim.add(Init(
    xb=Bounds3D.of(0, 8, 0, 6, 2.5, 3),
    temperature=400.0,
    mass_fraction={'SOOT': 0.008}
)

Combining with Other Features

With RAMP

# Initial condition + time-varying fire
sim.add(Init(xb=Bounds3D.of(0, 5, 0, 4, 2, 3), temperature=200.0))

sim.add(Ramp(id='GROWTH', t=[0, 120], f=[0, 1]))
sim.add(Surface(id='FIRE', hrrpua=1000.0, ramp_q='GROWTH'))

With CTRL

# Pre-heated zone affects control activation
sim.add(Init(xb=Bounds3D.of(2, 4, 2, 4, 0, 3), temperature=150.0))

sim.add(Device(id='TEMP', quantity='TEMPERATURE', xyz=Point3D.of(3, 3, 1.5)))
sim.add(Control(id='CTRL', input_id='TEMP', setpoint=200.0)  # Will activate sooner

Next Steps


Combustion →