Spaces:
Sleeping
Sleeping
Update data/ashrae_tables.py
Browse files- data/ashrae_tables.py +72 -18
data/ashrae_tables.py
CHANGED
|
@@ -189,6 +189,55 @@ class ASHRAETables:
|
|
| 189 |
0.9: 1.15 # Dark surfaces
|
| 190 |
}
|
| 191 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 192 |
def _load_heat_gain_table(self) -> pd.DataFrame:
|
| 193 |
"""
|
| 194 |
Load heat gain table for internal sources based on ASHRAE Handbook—Fundamentals (2017, Chapter 18).
|
|
@@ -200,10 +249,10 @@ class ASHRAETables:
|
|
| 200 |
# Get occupancy and equipment heat gain tables
|
| 201 |
occupancy_df = self._load_occupancy_heat_gain_table()
|
| 202 |
equipment_df = self._load_equipment_heat_gain_table()
|
| 203 |
-
|
| 204 |
# Prepare data for consolidated table
|
| 205 |
data = []
|
| 206 |
-
|
| 207 |
# People: Map occupancy types to heat gains
|
| 208 |
for _, row in occupancy_df.iterrows():
|
| 209 |
data.append({
|
|
@@ -213,38 +262,43 @@ class ASHRAETables:
|
|
| 213 |
'latent': row['latent_gain']
|
| 214 |
})
|
| 215 |
|
| 216 |
-
# Lighting:
|
| 217 |
-
|
| 218 |
-
'
|
| 219 |
-
'subcategory': '
|
| 220 |
-
'sensible':
|
| 221 |
-
'latent': 0.0
|
| 222 |
-
|
| 223 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 224 |
# Equipment: Use a generic value (adjustable in cooling_load.py via radiation_fraction)
|
| 225 |
-
# Aggregate equipment gains as a baseline (e.g., average or typical office equipment)
|
| 226 |
-
equipment_sensible = equipment_df['sensible_gain'].mean() # Example: mean sensible gain
|
| 227 |
-
equipment_latent = equipment_df['latent_gain'].mean() # Example: mean latent gain
|
| 228 |
data.append({
|
| 229 |
'category': 'equipment',
|
| 230 |
'subcategory': 'office',
|
| 231 |
'sensible': 1.0, # 1 W/W sensible, scalable by power in cooling_load.py
|
| 232 |
'latent': 0.0 # Assume no latent gain for generic equipment
|
| 233 |
})
|
| 234 |
-
|
| 235 |
return pd.DataFrame(data)
|
| 236 |
-
|
| 237 |
def get_heat_gain(self, source: str, subcategory: Optional[str] = None) -> Tuple[float, float]:
|
| 238 |
"""
|
| 239 |
Get sensible and latent heat gain for an internal source.
|
| 240 |
|
| 241 |
Args:
|
| 242 |
source (str): Source type ('people', 'lighting', 'equipment').
|
| 243 |
-
subcategory (str, optional): Subcategory (e.g., 'Seated, resting' for people, '
|
| 244 |
-
|
| 245 |
Returns:
|
| 246 |
Tuple[float, float]: Sensible and latent heat gain values (Watts).
|
| 247 |
-
|
| 248 |
Raises:
|
| 249 |
ValueError: If source or subcategory is invalid.
|
| 250 |
"""
|
|
|
|
| 189 |
0.9: 1.15 # Dark surfaces
|
| 190 |
}
|
| 191 |
|
| 192 |
+
def _load_occupancy_heat_gain_table(self) -> pd.DataFrame:
|
| 193 |
+
"""
|
| 194 |
+
Load heat gain table for occupancy types based on ASHRAE Handbook—Fundamentals (2017, Chapter 18).
|
| 195 |
+
|
| 196 |
+
Returns:
|
| 197 |
+
pd.DataFrame: DataFrame with columns 'occupancy_type', 'sensible_gain' (W), 'latent_gain' (W).
|
| 198 |
+
"""
|
| 199 |
+
BTUH_TO_W = 0.293071 # Conversion factor: 1 Btu/h = 0.293071 W
|
| 200 |
+
data = [
|
| 201 |
+
{'occupancy_type': 'Seated, resting', 'sensible_gain': 240 * BTUH_TO_W, 'latent_gain': 100 * BTUH_TO_W},
|
| 202 |
+
{'occupancy_type': 'Seated, light work', 'sensible_gain': 275 * BTUH_TO_W, 'latent_gain': 150 * BTUH_TO_W},
|
| 203 |
+
{'occupancy_type': 'Seated, typing', 'sensible_gain': 300 * BTUH_TO_W, 'latent_gain': 200 * BTUH_TO_W},
|
| 204 |
+
{'occupancy_type': 'Standing, light work', 'sensible_gain': 350 * BTUH_TO_W, 'latent_gain': 250 * BTUH_TO_W},
|
| 205 |
+
{'occupancy_type': 'Standing, medium work', 'sensible_gain': 400 * BTUH_TO_W, 'latent_gain': 300 * BTUH_TO_W},
|
| 206 |
+
{'occupancy_type': 'Walking', 'sensible_gain': 450 * BTUH_TO_W, 'latent_gain': 350 * BTUH_TO_W},
|
| 207 |
+
{'occupancy_type': 'Light exercise', 'sensible_gain': 500 * BTUH_TO_W, 'latent_gain': 400 * BTUH_TO_W},
|
| 208 |
+
{'occupancy_type': 'Medium exercise', 'sensible_gain': 600 * BTUH_TO_W, 'latent_gain': 500 * BTUH_TO_W},
|
| 209 |
+
{'occupancy_type': 'Heavy exercise', 'sensible_gain': 800 * BTUH_TO_W, 'latent_gain': 600 * BTUH_TO_W},
|
| 210 |
+
{'occupancy_type': 'Dancing', 'sensible_gain': 900 * BTUH_TO_W, 'latent_gain': 700 * BTUH_TO_W}
|
| 211 |
+
]
|
| 212 |
+
return pd.DataFrame(data)
|
| 213 |
+
|
| 214 |
+
def _load_equipment_heat_gain_table(self) -> pd.DataFrame:
|
| 215 |
+
"""
|
| 216 |
+
Load heat gain table for equipment types based on ASHRAE Handbook—Fundamentals (2017, Chapter 18).
|
| 217 |
+
|
| 218 |
+
Returns:
|
| 219 |
+
pd.DataFrame: DataFrame with columns 'equipment_type', 'sensible_gain' (W), 'latent_gain' (W).
|
| 220 |
+
"""
|
| 221 |
+
BTUH_TO_W = 0.293071 # Conversion factor: 1 Btu/h = 0.293071 W
|
| 222 |
+
data = [
|
| 223 |
+
{'equipment_type': 'Computer', 'sensible_gain': 500 * BTUH_TO_W, 'latent_gain': 0.0},
|
| 224 |
+
{'equipment_type': 'Monitor', 'sensible_gain': 200 * BTUH_TO_W, 'latent_gain': 0.0},
|
| 225 |
+
{'equipment_type': 'Printer (small)', 'sensible_gain': 300 * BTUH_TO_W, 'latent_gain': 0.0},
|
| 226 |
+
{'equipment_type': 'Printer (large)', 'sensible_gain': 1000 * BTUH_TO_W, 'latent_gain': 0.0},
|
| 227 |
+
{'equipment_type': 'Copier (small)', 'sensible_gain': 600 * BTUH_TO_W, 'latent_gain': 0.0},
|
| 228 |
+
{'equipment_type': 'Copier (large)', 'sensible_gain': 1500 * BTUH_TO_W, 'latent_gain': 0.0},
|
| 229 |
+
{'equipment_type': 'Server', 'sensible_gain': 2000 * BTUH_TO_W, 'latent_gain': 0.0},
|
| 230 |
+
{'equipment_type': 'Refrigerator (small)', 'sensible_gain': 800 * BTUH_TO_W, 'latent_gain': 200 * BTUH_TO_W},
|
| 231 |
+
{'equipment_type': 'Refrigerator (large)', 'sensible_gain': 1200 * BTUH_TO_W, 'latent_gain': 300 * BTUH_TO_W},
|
| 232 |
+
{'equipment_type': 'Microwave', 'sensible_gain': 500 * BTUH_TO_W, 'latent_gain': 100 * BTUH_TO_W},
|
| 233 |
+
{'equipment_type': 'Coffee maker', 'sensible_gain': 400 * BTUH_TO_W, 'latent_gain': 100 * BTUH_TO_W},
|
| 234 |
+
{'equipment_type': 'TV (small)', 'sensible_gain': 300 * BTUH_TO_W, 'latent_gain': 0.0},
|
| 235 |
+
{'equipment_type': 'TV (large)', 'sensible_gain': 600 * BTUH_TO_W, 'latent_gain': 0.0},
|
| 236 |
+
{'equipment_type': 'Projector', 'sensible_gain': 700 * BTUH_TO_W, 'latent_gain': 0.0},
|
| 237 |
+
{'equipment_type': 'Lab equipment', 'sensible_gain': 1500 * BTUH_TO_W, 'latent_gain': 0.0}
|
| 238 |
+
]
|
| 239 |
+
return pd.DataFrame(data)
|
| 240 |
+
|
| 241 |
def _load_heat_gain_table(self) -> pd.DataFrame:
|
| 242 |
"""
|
| 243 |
Load heat gain table for internal sources based on ASHRAE Handbook—Fundamentals (2017, Chapter 18).
|
|
|
|
| 249 |
# Get occupancy and equipment heat gain tables
|
| 250 |
occupancy_df = self._load_occupancy_heat_gain_table()
|
| 251 |
equipment_df = self._load_equipment_heat_gain_table()
|
| 252 |
+
|
| 253 |
# Prepare data for consolidated table
|
| 254 |
data = []
|
| 255 |
+
|
| 256 |
# People: Map occupancy types to heat gains
|
| 257 |
for _, row in occupancy_df.iterrows():
|
| 258 |
data.append({
|
|
|
|
| 262 |
'latent': row['latent_gain']
|
| 263 |
})
|
| 264 |
|
| 265 |
+
# Lighting: Add categories for different lighting technologies
|
| 266 |
+
lighting_types = [
|
| 267 |
+
{'subcategory': 'general', 'sensible': 1.0, 'latent': 0.0}, # Fallback for total lighting power
|
| 268 |
+
{'subcategory': 'LED', 'sensible': 0.80, 'latent': 0.0}, # 80% sensible heat
|
| 269 |
+
{'subcategory': 'Fluorescent', 'sensible': 0.85, 'latent': 0.0}, # Includes ballast losses
|
| 270 |
+
{'subcategory': 'Halogen', 'sensible': 0.95, 'latent': 0.0}, # High thermal output
|
| 271 |
+
{'subcategory': 'Incandescent', 'sensible': 0.98, 'latent': 0.0} # Nearly all heat
|
| 272 |
+
]
|
| 273 |
+
for lt in lighting_types:
|
| 274 |
+
data.append({
|
| 275 |
+
'category': 'lighting',
|
| 276 |
+
'subcategory': lt['subcategory'],
|
| 277 |
+
'sensible': lt['sensible'],
|
| 278 |
+
'latent': lt['latent']
|
| 279 |
+
})
|
| 280 |
+
|
| 281 |
# Equipment: Use a generic value (adjustable in cooling_load.py via radiation_fraction)
|
|
|
|
|
|
|
|
|
|
| 282 |
data.append({
|
| 283 |
'category': 'equipment',
|
| 284 |
'subcategory': 'office',
|
| 285 |
'sensible': 1.0, # 1 W/W sensible, scalable by power in cooling_load.py
|
| 286 |
'latent': 0.0 # Assume no latent gain for generic equipment
|
| 287 |
})
|
| 288 |
+
|
| 289 |
return pd.DataFrame(data)
|
| 290 |
+
|
| 291 |
def get_heat_gain(self, source: str, subcategory: Optional[str] = None) -> Tuple[float, float]:
|
| 292 |
"""
|
| 293 |
Get sensible and latent heat gain for an internal source.
|
| 294 |
|
| 295 |
Args:
|
| 296 |
source (str): Source type ('people', 'lighting', 'equipment').
|
| 297 |
+
subcategory (str, optional): Subcategory (e.g., 'Seated, resting' for people, 'LED' for lighting).
|
| 298 |
+
|
| 299 |
Returns:
|
| 300 |
Tuple[float, float]: Sensible and latent heat gain values (Watts).
|
| 301 |
+
|
| 302 |
Raises:
|
| 303 |
ValueError: If source or subcategory is invalid.
|
| 304 |
"""
|