Spaces:
Sleeping
Sleeping
Update data/ashrae_tables.py
Browse files- data/ashrae_tables.py +71 -0
data/ashrae_tables.py
CHANGED
|
@@ -189,6 +189,77 @@ class ASHRAETables:
|
|
| 189 |
0.9: 1.15 # Dark surfaces
|
| 190 |
}
|
| 191 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 192 |
def interpolate_cltd(self, latitude: float, cltd_table_low: pd.DataFrame, cltd_table_high: pd.DataFrame, lat_low: float, lat_high: float) -> pd.DataFrame:
|
| 193 |
"""
|
| 194 |
Interpolate CLTD or SCL values between two latitudes.
|
|
|
|
| 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).
|
| 195 |
+
Consolidates occupancy, lighting, and equipment heat gains into a single table.
|
| 196 |
+
|
| 197 |
+
Returns:
|
| 198 |
+
pd.DataFrame: DataFrame with columns 'category', 'subcategory', 'sensible' (W), 'latent' (W).
|
| 199 |
+
"""
|
| 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({
|
| 210 |
+
'category': 'people',
|
| 211 |
+
'subcategory': row['occupancy_type'],
|
| 212 |
+
'sensible': row['sensible_gain'],
|
| 213 |
+
'latent': row['latent_gain']
|
| 214 |
+
})
|
| 215 |
+
|
| 216 |
+
# Lighting: Assume 1 W sensible gain per Watt, no latent gain
|
| 217 |
+
data.append({
|
| 218 |
+
'category': 'lighting',
|
| 219 |
+
'subcategory': 'general',
|
| 220 |
+
'sensible': 1.0, # 1 W/W (100% sensible heat)
|
| 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, 'general' for lighting).
|
| 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 |
+
"""
|
| 251 |
+
if source not in self.heat_gain['category'].values:
|
| 252 |
+
raise ValueError(f"Invalid source: {source}")
|
| 253 |
+
if subcategory:
|
| 254 |
+
if subcategory not in self.heat_gain[self.heat_gain['category'] == source]['subcategory'].values:
|
| 255 |
+
raise ValueError(f"Invalid subcategory for {source}: {subcategory}")
|
| 256 |
+
row = self.heat_gain[(self.heat_gain['category'] == source) & (self.heat_gain['subcategory'] == subcategory)]
|
| 257 |
+
else:
|
| 258 |
+
row = self.heat_gain[self.heat_gain['category'] == source]
|
| 259 |
+
if row.empty:
|
| 260 |
+
raise ValueError(f"No data found for source: {source}, subcategory: {subcategory}")
|
| 261 |
+
return float(row['sensible'].iloc[0]), float(row['latent'].iloc[0])
|
| 262 |
+
|
| 263 |
def interpolate_cltd(self, latitude: float, cltd_table_low: pd.DataFrame, cltd_table_high: pd.DataFrame, lat_low: float, lat_high: float) -> pd.DataFrame:
|
| 264 |
"""
|
| 265 |
Interpolate CLTD or SCL values between two latitudes.
|