mabuseif commited on
Commit
75cb0a1
·
verified ·
1 Parent(s): 6ab6262

Update app/hvac_loads.py

Browse files
Files changed (1) hide show
  1. app/hvac_loads.py +25 -79
app/hvac_loads.py CHANGED
@@ -181,94 +181,40 @@ class TFMCalculations:
181
  component_name = component.get('name', 'unnamed_component')
182
  component_type = TFMCalculations.get_component_type(component)
183
 
184
- surface_tilt = 90.0
185
- surface_azimuth = 0.0
186
- h_o = 17.0
187
- emissivity = 0.9
188
- absorptivity = 0.6
 
 
189
 
190
  try:
191
- if component_type == ComponentType.ROOF:
192
- surface_tilt = component.get('tilt', 0.0)
193
- h_o = 23.0
194
- surface_azimuth = component.get('orientation', 0.0)
195
- logger.debug(f"Roof component {component_name}: using orientation={surface_azimuth}, tilt={surface_tilt}")
196
-
197
- elif component_type == ComponentType.SKYLIGHT:
198
- surface_tilt = component.get('tilt', 0.0)
199
- h_o = 23.0
200
- surface_azimuth = component.get('orientation', 0.0)
201
- logger.debug(f"Skylight component {component_name}: using orientation={surface_azimuth}, tilt={surface_tilt}")
202
-
203
- elif component_type == ComponentType.FLOOR:
204
- surface_tilt = 180.0
205
- h_o = 17.0
206
- surface_azimuth = 0.0
207
- logger.debug(f"Floor component {component_name}: using default azimuth={surface_azimuth}, tilt={surface_tilt}")
208
-
209
- else: # WALL, WINDOW
210
- surface_tilt = 90.0
211
- h_o = 17.0
212
- elevation = component.get('elevation', None)
213
- if not elevation:
214
- logger.warning(f"Component {component_name} ({component_type.value}) is missing 'elevation' field. Using default azimuth=0.")
215
- surface_azimuth = 0.0
216
- else:
217
- base_azimuth = building_info.get("orientation_angle", 0.0)
218
- elevation_angles = {
219
- "A": base_azimuth,
220
- "B": (base_azimuth + 90.0) % 360,
221
- "C": (base_azimuth + 180.0) % 360,
222
- "D": (base_azimuth + 270.0) % 360
223
- }
224
- if elevation not in elevation_angles:
225
- logger.warning(f"Invalid elevation '{elevation}' for {component_name}. Using default azimuth=0.")
226
- surface_azimuth = 0.0
227
- else:
228
- surface_azimuth = (elevation_angles[elevation] + component.get('rotation', 0.0)) % 360
229
- logger.debug(f"Component {component_name}: elevation={elevation}, base_azimuth={elevation_angles[elevation]}, rotation={component.get('rotation', 0.0)}, total_azimuth={surface_azimuth}")
230
-
231
- if component_type in [ComponentType.WALL, ComponentType.ROOF]:
232
- construction_name = component.get('construction', None)
233
- if not construction_name:
234
- logger.warning(f"No construction defined for {component_name}. Using defaults: absorptivity=0.6, emissivity=0.9.")
235
- else:
236
- construction_obj = (project_constructions.get(construction_name) or
237
- material_library.library_constructions.get(construction_name))
238
- if not construction_obj:
239
- logger.warning(f"Construction '{construction_name}' not found for {component_name}. Using defaults: absorptivity=0.6, emissivity=0.9.")
240
- elif not construction_obj.get('layers', []):
241
- logger.warning(f"No layers in construction for {component_name}. Using defaults: absorptivity=0.6, emissivity=0.9.")
242
- else:
243
- first_layer = construction_obj['layers'][0]
244
- material_name = first_layer.get("material")
245
- if material_name:
246
- material_obj = (project_materials.get(material_name) or
247
- material_library.library_materials.get(material_name))
248
- if material_obj:
249
- absorptivity = material_obj.get('absorptivity', 0.6)
250
- emissivity = material_obj.get('emissivity', 0.9)
251
- logger.debug(f"Using first layer material '{material_name}' for {component_name}: absorptivity={absorptivity}, emissivity={emissivity}")
252
-
253
- elif component_type in [ComponentType.WINDOW, ComponentType.SKYLIGHT]:
254
- glazing_material_name = component.get('glazing_material', None)
255
  if not glazing_material_name:
256
- logger.warning(f"No glazing material defined for {component_name}. Using default SHGC=0.7, h_o={h_o}.")
257
- shgc = 0.7
258
  else:
259
  glazing_material_obj = (project_glazing_materials.get(glazing_material_name) or
260
  material_library.library_glazing_materials.get(glazing_material_name))
261
  if not glazing_material_obj:
262
- logger.warning(f"Glazing material '{glazing_material_name}' not found for {component_name}. Using default SHGC=0.7, h_o={h_o}.")
263
- shgc = 0.7
264
  else:
265
- shgc = glazing_material_obj.get('shgc', 0.7)
266
  h_o = glazing_material_obj.get('h_o', h_o)
267
- logger.debug(f"Using glazing material '{glazing_material_name}' for {component_name}: shgc={shgc}, h_o={h_o}")
268
- emissivity = None
 
 
 
 
269
 
270
  except Exception as e:
271
  logger.error(f"Error retrieving surface parameters for {component_name}: {str(e)}")
 
272
  if component_type == ComponentType.ROOF:
273
  surface_tilt = 0.0
274
  h_o = 23.0
@@ -290,11 +236,11 @@ class TFMCalculations:
290
  absorptivity = 0.6
291
  emissivity = 0.9
292
  else: # WINDOW, SKYLIGHT
293
- shgc = 0.7
294
  emissivity = None
295
 
296
- logger.info(f"Final surface parameters for {component_name}: tilt={surface_tilt:.1f}, azimuth={surface_azimuth:.1f}, h_o={h_o:.1f}")
297
- return surface_tilt, surface_azimuth, h_o, emissivity, absorptivity
298
 
299
  @staticmethod
300
  def calculate_solar_load(component: Dict[str, Any], hourly_data: Dict, hour: int, building_orientation: float, mode: str = "none") -> float:
 
181
  component_name = component.get('name', 'unnamed_component')
182
  component_type = TFMCalculations.get_component_type(component)
183
 
184
+ # Default parameters
185
+ surface_tilt = component.get('surface_tilt', 90.0 if component_type in [ComponentType.WALL, ComponentType.WINDOW] else
186
+ 0.0 if component_type in [ComponentType.ROOF, ComponentType.SKYLIGHT] else 180.0)
187
+ surface_azimuth = component.get('surface_azimuth', 0.0)
188
+ h_o = 17.0 if component_type in [ComponentType.WALL, ComponentType.WINDOW, ComponentType.FLOOR] else 23.0
189
+ emissivity = component.get('emissivity', 0.9 if component_type in [ComponentType.WALL, ComponentType.ROOF] else None)
190
+ absorptivity = component.get('absorptivity', 0.6 if component_type in [ComponentType.WALL, ComponentType.ROOF] else 0.0)
191
 
192
  try:
193
+ # For windows and skylights, adjust h_o and use shgc instead of absorptivity
194
+ if component_type in [ComponentType.WINDOW, ComponentType.SKYLIGHT]:
195
+ glazing_material_name = component.get('fenestration', None)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  if not glazing_material_name:
197
+ logger.warning(f"No fenestration defined for {component_name}. Using default SHGC=0.7, h_o={h_o}.")
198
+ absorptivity = component.get('shgc', 0.7) # Use shgc as absorptivity for consistency
199
  else:
200
  glazing_material_obj = (project_glazing_materials.get(glazing_material_name) or
201
  material_library.library_glazing_materials.get(glazing_material_name))
202
  if not glazing_material_obj:
203
+ logger.warning(f"Fenestration '{glazing_material_name}' not found for {component_name}. Using default SHGC=0.7, h_o={h_o}.")
204
+ absorptivity = component.get('shgc', 0.7)
205
  else:
206
+ absorptivity = glazing_material_obj.get('shgc', component.get('shgc', 0.7))
207
  h_o = glazing_material_obj.get('h_o', h_o)
208
+ logger.debug(f"Using fenestration '{glazing_material_name}' for {component_name}: shgc={absorptivity}, h_o={h_o}")
209
+ emissivity = None # Emissivity not used for fenestrations
210
+
211
+ logger.info(f"Surface parameters for {component_name}: tilt={surface_tilt:.1f}, azimuth={surface_azimuth:.1f}, h_o={h_o:.1f}, "
212
+ f"emissivity={emissivity}, absorptivity={absorptivity}")
213
+ return surface_tilt, surface_azimuth, h_o, emissivity, absorptivity
214
 
215
  except Exception as e:
216
  logger.error(f"Error retrieving surface parameters for {component_name}: {str(e)}")
217
+ # Apply defaults on error
218
  if component_type == ComponentType.ROOF:
219
  surface_tilt = 0.0
220
  h_o = 23.0
 
236
  absorptivity = 0.6
237
  emissivity = 0.9
238
  else: # WINDOW, SKYLIGHT
239
+ absorptivity = 0.7
240
  emissivity = None
241
 
242
+ logger.info(f"Default surface parameters for {component_name}: tilt={surface_tilt:.1f}, azimuth={surface_azimuth:.1f}, h_o={h_o:.1f}")
243
+ return surface_tilt, surface_azimuth, h_o, emissivity, absorptivity
244
 
245
  @staticmethod
246
  def calculate_solar_load(component: Dict[str, Any], hourly_data: Dict, hour: int, building_orientation: float, mode: str = "none") -> float: