Spaces:
Sleeping
Sleeping
Update utils/cooling_load.py
Browse files- utils/cooling_load.py +71 -19
utils/cooling_load.py
CHANGED
|
@@ -63,6 +63,25 @@ class CoolingLoadCalculator:
|
|
| 63 |
}
|
| 64 |
|
| 65 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
# Calculate loads for walls
|
| 67 |
for wall in building_components.get('walls', []):
|
| 68 |
for hour in range(24):
|
|
@@ -70,9 +89,9 @@ class CoolingLoadCalculator:
|
|
| 70 |
wall=wall,
|
| 71 |
outdoor_temp=outdoor_conditions['temperature'],
|
| 72 |
indoor_temp=indoor_conditions['temperature'],
|
| 73 |
-
month=
|
| 74 |
hour=hour,
|
| 75 |
-
latitude=
|
| 76 |
)
|
| 77 |
hourly_loads['walls'][hour + 1] += load
|
| 78 |
|
|
@@ -83,9 +102,9 @@ class CoolingLoadCalculator:
|
|
| 83 |
roof=roof,
|
| 84 |
outdoor_temp=outdoor_conditions['temperature'],
|
| 85 |
indoor_temp=indoor_conditions['temperature'],
|
| 86 |
-
month=
|
| 87 |
hour=hour,
|
| 88 |
-
latitude=
|
| 89 |
)
|
| 90 |
hourly_loads['roofs'][hour + 1] += load
|
| 91 |
|
|
@@ -96,9 +115,9 @@ class CoolingLoadCalculator:
|
|
| 96 |
window=window,
|
| 97 |
outdoor_temp=outdoor_conditions['temperature'],
|
| 98 |
indoor_temp=indoor_conditions['temperature'],
|
| 99 |
-
month=
|
| 100 |
hour=hour,
|
| 101 |
-
latitude=
|
| 102 |
shading_coefficient=window.shading_coefficient
|
| 103 |
)
|
| 104 |
hourly_loads['windows_conduction'][hour + 1] += load_dict['conduction']
|
|
@@ -394,7 +413,7 @@ class CoolingLoadCalculator:
|
|
| 394 |
indoor_temp: Indoor temperature (°C)
|
| 395 |
month: Design month (e.g., 'Jan', 'Jul')
|
| 396 |
hour: Hour of the day
|
| 397 |
-
latitude: Latitude (e.g., '
|
| 398 |
shading_coefficient: Shading coefficient for drapery
|
| 399 |
|
| 400 |
Returns:
|
|
@@ -407,13 +426,11 @@ class CoolingLoadCalculator:
|
|
| 407 |
if month_upper not in valid_months:
|
| 408 |
raise ValueError(f"Invalid month: {month}. Must be one of {valid_months}")
|
| 409 |
|
| 410 |
-
#
|
| 411 |
-
delta_t = outdoor_temp - indoor_temp
|
| 412 |
-
conduction_load = window.u_value * window.area * delta_t
|
| 413 |
-
|
| 414 |
-
# Validate and map latitude for SCL
|
| 415 |
valid_latitudes = ['24N', '36N', '48N']
|
| 416 |
scl_latitude = latitude
|
|
|
|
|
|
|
| 417 |
if latitude not in valid_latitudes:
|
| 418 |
try:
|
| 419 |
lat_value = float(latitude[:-1])
|
|
@@ -422,16 +439,23 @@ class CoolingLoadCalculator:
|
|
| 422 |
scl_latitude = valid_latitudes[nearest_idx]
|
| 423 |
except ValueError:
|
| 424 |
scl_latitude = '24N' # Default to '24N' if parsing fails
|
|
|
|
|
|
|
|
|
|
|
|
|
| 425 |
|
| 426 |
# Solar load
|
| 427 |
# Note: Solar altitude is not computed directly, as ASHRAE SCL tables (via get_scl)
|
| 428 |
# account for solar geometry effects based on month, orientation, hour, and latitude.
|
| 429 |
-
|
| 430 |
-
|
| 431 |
-
|
| 432 |
-
|
| 433 |
-
|
| 434 |
-
|
|
|
|
|
|
|
|
|
|
| 435 |
|
| 436 |
solar_load = window.area * window.shgc * scl * shading_coefficient
|
| 437 |
|
|
@@ -699,4 +723,32 @@ if __name__ == "__main__":
|
|
| 699 |
'month': 'Jul',
|
| 700 |
'latitude': '24N',
|
| 701 |
'wind_speed': 4
|
| 702 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
}
|
| 64 |
|
| 65 |
try:
|
| 66 |
+
# Validate outdoor conditions
|
| 67 |
+
valid_latitudes = ['24N', '36N', '48N']
|
| 68 |
+
latitude = outdoor_conditions.get('latitude', '24N')
|
| 69 |
+
if not isinstance(latitude, str) or '_' in latitude:
|
| 70 |
+
raise ValueError(f"Invalid latitude format: {latitude}. Expected format: '24N', '36N', or '48N'")
|
| 71 |
+
if latitude not in valid_latitudes:
|
| 72 |
+
try:
|
| 73 |
+
lat_value = float(latitude[:-1])
|
| 74 |
+
differences = [abs(lat_value - float(lat[:-1])) for lat in valid_latitudes]
|
| 75 |
+
nearest_idx = differences.index(min(differences))
|
| 76 |
+
latitude = valid_latitudes[nearest_idx]
|
| 77 |
+
except ValueError:
|
| 78 |
+
latitude = '24N' # Default to '24N' if parsing fails
|
| 79 |
+
|
| 80 |
+
valid_months = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC']
|
| 81 |
+
month = outdoor_conditions.get('month', 'JUL').upper()
|
| 82 |
+
if month not in valid_months:
|
| 83 |
+
raise ValueError(f"Invalid month: {month}. Must be one of {valid_months}")
|
| 84 |
+
|
| 85 |
# Calculate loads for walls
|
| 86 |
for wall in building_components.get('walls', []):
|
| 87 |
for hour in range(24):
|
|
|
|
| 89 |
wall=wall,
|
| 90 |
outdoor_temp=outdoor_conditions['temperature'],
|
| 91 |
indoor_temp=indoor_conditions['temperature'],
|
| 92 |
+
month=month,
|
| 93 |
hour=hour,
|
| 94 |
+
latitude=latitude
|
| 95 |
)
|
| 96 |
hourly_loads['walls'][hour + 1] += load
|
| 97 |
|
|
|
|
| 102 |
roof=roof,
|
| 103 |
outdoor_temp=outdoor_conditions['temperature'],
|
| 104 |
indoor_temp=indoor_conditions['temperature'],
|
| 105 |
+
month=month,
|
| 106 |
hour=hour,
|
| 107 |
+
latitude=latitude
|
| 108 |
)
|
| 109 |
hourly_loads['roofs'][hour + 1] += load
|
| 110 |
|
|
|
|
| 115 |
window=window,
|
| 116 |
outdoor_temp=outdoor_conditions['temperature'],
|
| 117 |
indoor_temp=indoor_conditions['temperature'],
|
| 118 |
+
month=month,
|
| 119 |
hour=hour,
|
| 120 |
+
latitude=latitude,
|
| 121 |
shading_coefficient=window.shading_coefficient
|
| 122 |
)
|
| 123 |
hourly_loads['windows_conduction'][hour + 1] += load_dict['conduction']
|
|
|
|
| 413 |
indoor_temp: Indoor temperature (°C)
|
| 414 |
month: Design month (e.g., 'Jan', 'Jul')
|
| 415 |
hour: Hour of the day
|
| 416 |
+
latitude: Latitude (e.g., '24N', '36N', '48N')
|
| 417 |
shading_coefficient: Shading coefficient for drapery
|
| 418 |
|
| 419 |
Returns:
|
|
|
|
| 426 |
if month_upper not in valid_months:
|
| 427 |
raise ValueError(f"Invalid month: {month}. Must be one of {valid_months}")
|
| 428 |
|
| 429 |
+
# Validate latitude
|
|
|
|
|
|
|
|
|
|
|
|
|
| 430 |
valid_latitudes = ['24N', '36N', '48N']
|
| 431 |
scl_latitude = latitude
|
| 432 |
+
if not isinstance(latitude, str) or '_' in latitude:
|
| 433 |
+
raise ValueError(f"Invalid latitude format: {latitude}. Expected format: '24N', '36N', or '48N'")
|
| 434 |
if latitude not in valid_latitudes:
|
| 435 |
try:
|
| 436 |
lat_value = float(latitude[:-1])
|
|
|
|
| 439 |
scl_latitude = valid_latitudes[nearest_idx]
|
| 440 |
except ValueError:
|
| 441 |
scl_latitude = '24N' # Default to '24N' if parsing fails
|
| 442 |
+
|
| 443 |
+
# Conduction load
|
| 444 |
+
delta_t = outdoor_temp - indoor_temp
|
| 445 |
+
conduction_load = window.u_value * window.area * delta_t
|
| 446 |
|
| 447 |
# Solar load
|
| 448 |
# Note: Solar altitude is not computed directly, as ASHRAE SCL tables (via get_scl)
|
| 449 |
# account for solar geometry effects based on month, orientation, hour, and latitude.
|
| 450 |
+
try:
|
| 451 |
+
scl = self.ashrae_tables.get_scl(
|
| 452 |
+
month=month_upper,
|
| 453 |
+
orientation=window.orientation.value,
|
| 454 |
+
hour=hour,
|
| 455 |
+
latitude=scl_latitude
|
| 456 |
+
)
|
| 457 |
+
except Exception as e:
|
| 458 |
+
raise ValueError(f"Failed to retrieve SCL for month={month_upper}, orientation={window.orientation.value}, hour={hour}, latitude={scl_latitude}: {str(e)}")
|
| 459 |
|
| 460 |
solar_load = window.area * window.shgc * scl * shading_coefficient
|
| 461 |
|
|
|
|
| 723 |
'month': 'Jul',
|
| 724 |
'latitude': '24N',
|
| 725 |
'wind_speed': 4
|
| 726 |
+
}
|
| 727 |
+
|
| 728 |
+
indoor_conditions = {
|
| 729 |
+
'temperature': 24.0,
|
| 730 |
+
'relative_humidity': 50.0
|
| 731 |
+
}
|
| 732 |
+
|
| 733 |
+
internal_loads = {
|
| 734 |
+
'people': {'number': 10, 'activity_level': 'Seated/Resting'},
|
| 735 |
+
'lights': {'power': 1000, 'use_factor': 0.8, 'special_allowance': 1.0},
|
| 736 |
+
'equipment': {'power': 500, 'use_factor': 0.7, 'radiation_factor': 0.5},
|
| 737 |
+
'infiltration': {'flow_rate': 0.01},
|
| 738 |
+
'ventilation': {'flow_rate': 0.02}
|
| 739 |
+
}
|
| 740 |
+
|
| 741 |
+
building_volume = 300.0
|
| 742 |
+
|
| 743 |
+
# Calculate loads
|
| 744 |
+
try:
|
| 745 |
+
hourly_loads = calculator.calculate_hourly_cooling_loads(
|
| 746 |
+
building_components,
|
| 747 |
+
outdoor_conditions,
|
| 748 |
+
indoor_conditions,
|
| 749 |
+
internal_loads,
|
| 750 |
+
building_volume
|
| 751 |
+
)
|
| 752 |
+
print("Hourly Loads:", hourly_loads)
|
| 753 |
+
except Exception as e:
|
| 754 |
+
print(f"Error in example calculation: {str(e)}")
|