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.
|