mabuseif commited on
Commit
1981e07
·
verified ·
1 Parent(s): 16925ec

Update data/ashrae_tables.py

Browse files
Files changed (1) hide show
  1. 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.