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
Species concentration not conserved
Cause: Mass fractions don't sum correctly
Solution: Ensure mass fractions are physically realistic
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¶
- Global Settings - Ambient conditions (MISC)
- RAMP - Time-varying properties
- Controls - Device-based automation
- Examples - Complex scenarios