Skip to content

How to apply design days

The DesignDayManager parses DDY files and applies ASHRAE design day conditions to your EnergyPlus models for HVAC sizing.

For design days in the context of a whole model, Simulate an office block sizes a real building against them. This page is the reference for the one step.

Not in JavaScript yet

Design days and ASHRAE sizing conditions is available in Python and is not in JavaScript today. A temporary gap, not a boundary. The port is tracked in idfkit-js#20.

The full entry, including the vocabulary this capability owns, is on the capability parity page.

Basic Usage

from idfkit.weather import DesignDayManager

# Parse a DDY file
ddm = DesignDayManager("chicago.ddy")

# Print summary
print(ddm.summary())

# Apply design days to model
added = ddm.apply_to_model(
    model,
    heating="99.6%",
    cooling="1%",
)
print(f"Added {len(added)} design days")

Quick Apply

Use apply_ashrae_sizing() for a streamlined workflow:

from idfkit.weather import apply_ashrae_sizing

# Apply standard design conditions (downloads DDY from station automatically)
added = apply_ashrae_sizing(
    model,
    station,
    standard="90.1",  # ASHRAE 90.1 criteria
)

Design Day Types

DDY files contain multiple design day types classified by ASHRAE criteria:

Heating Design Days

Type Description Use Case
HEATING_99_6 99.6% heating DB ASHRAE 90.1 (coldest)
HEATING_99 99% heating DB ASHRAE 62.1
HTG_WIND_99_6 Heating wind 99.6% Wind-driven infiltration

Cooling Design Days

Type Description Use Case
COOLING_DB_0_4 0.4% cooling DB=>MWB Extreme cooling
COOLING_DB_1 1% cooling DB=>MWB ASHRAE 90.1
COOLING_DB_2 2% cooling DB=>MWB Less extreme
COOLING_WB_0_4 0.4% cooling WB=>MDB Humidity-driven
COOLING_WB_1 1% cooling WB=>MDB ASHRAE 90.1
COOLING_ENTH_0_4 0.4% enthalpy Peak enthalpy
COOLING_ENTH_1 1% enthalpy Standard enthalpy

Other Types

Type Description
DEHUMID_0_4 0.4% dehumidification
DEHUMID_1 1% dehumidification
HUMIDIFICATION_99_6 99.6% humidification
HUMIDIFICATION_99 99% humidification

Accessing Design Days

By Type

from idfkit.weather import DesignDayManager, DesignDayType

ddm = DesignDayManager("chicago.ddy")

# Get specific design day
htg = ddm.get(DesignDayType.HEATING_99_6)
if htg:
    print(f"Heating 99.6% DB: {htg.maximum_dry_bulb_temperature}°C")

clg = ddm.get(DesignDayType.COOLING_DB_1)
if clg:
    print(f"Cooling 1% DB: {clg.maximum_dry_bulb_temperature}°C")

All Design Days

# All classified annual design days (returns a list of IDFObject)
for dd_obj in ddm.annual:
    print(dd_obj.name)

# Monthly design days
for dd_obj in ddm.monthly:
    print(dd_obj.name)

Applying to Models

Basic Application

added = ddm.apply_to_model(
    model,
    heating="99.6%",  # Use 99.6% heating conditions
    cooling="1%",  # Use 1% cooling conditions
)

With Wet-Bulb Design Day

added = ddm.apply_to_model(
    model,
    heating="99.6%",
    cooling="1%",
    include_wet_bulb=True,  # Also add WB=>MDB cooling design day
)

Skip Site Location Update

By default, apply_to_model also updates the Site:Location object. To skip this, set update_location=False:

added = ddm.apply_to_model(
    model,
    heating="99.6%",
    cooling="1%",
    update_location=False,  # Keep existing Site:Location
)

ASHRAE Standards

Different standards recommend different percentiles:

ASHRAE 90.1 (Energy Standard)

added = ddm.apply_to_model(
    model,
    heating="99.6%",
    cooling="1%",
)

# Or use the convenience function (takes a WeatherStation, not a path)
added = apply_ashrae_sizing(model, station, standard="90.1")

ASHRAE 62.1 (Ventilation)

added = ddm.apply_to_model(
    model,
    heating="99%",  # Less extreme
    cooling="1%",
)

Design Day Object Fields

When you access a design day, it's an IDFObject with these fields:

Field Description
name Design day name
month Month (1-12)
day_of_month Day of month
day_type Day type string
maximum_dry_bulb_temperature Peak dry-bulb temp (°C)
daily_dry_bulb_temperature_range Diurnal range (°C)
humidity_condition_type How humidity is specified
wetbulb_or_dewpoint_at_maximum_dry_bulb Humidity value
wind_speed Design wind speed (m/s)
wind_direction Wind direction (degrees)

Summary Output

ddm = DesignDayManager("chicago.ddy")
print(ddm.summary())

Output:

Design days from: chicago.ddy

  Location: Chicago Ohare Intl AP
  Design days found: 114
  Annual (classified): 18
  Monthly: 96

  [heating_99.6] Chicago Ohare Intl AP Ann Htg 99.6% Condns DB
  [heating_99] Chicago Ohare Intl AP Ann Htg 99% Condns DB
  [cooling_db_0.4] Chicago Ohare Intl AP Ann Clg .4% Condns DB=>MWB
  ...

Location Object

DDY files also contain Site:Location data:

location = ddm.location
if location:
    print(f"Site: {location.name}")
    print(f"Latitude: {location.latitude}")
    print(f"Longitude: {location.longitude}")
    print(f"Time Zone: {location.time_zone}")
    print(f"Elevation: {location.elevation} m")

Complete Workflow

from idfkit import load_idf
from idfkit.weather import (
    StationIndex,
    WeatherDownloader,
    DesignDayManager,
    geocode,
)

# Load model
model = load_idf("building.idf")

# Find nearest station
index = StationIndex.load()
lat, lon = geocode("123 Main St, Chicago, IL")
station = index.nearest(lat, lon)[0].station

# Download weather files
downloader = WeatherDownloader()
files = downloader.download(station)

# Apply design days
ddm = DesignDayManager(files.ddy)
added = ddm.apply_to_model(
    model,
    heating="99.6%",
    cooling="1%",
    include_wet_bulb=True,
    update_location=True,
)

print(f"Added {len(added)} design days")
print(f"Location: {model['Site:Location'][0].name}")

Error Handling

from idfkit.exceptions import NoDesignDaysError

try:
    ddm = DesignDayManager("incomplete.ddy")
    ddm.apply_to_model(model, heating="99.6%", cooling="1%")
except NoDesignDaysError as e:
    print(f"Missing design days: {e}")

See Also