mabuseif commited on
Commit
4d43eee
·
verified ·
1 Parent(s): 0db3a37

Upload cooling_load.py

Browse files
Files changed (1) hide show
  1. utils/cooling_load.py +15 -59
utils/cooling_load.py CHANGED
@@ -4,8 +4,8 @@ Implements ASHRAE steady-state methods with Cooling Load Temperature Difference
4
  Reference: ASHRAE Handbook—Fundamentals (2017), Chapter 18, Section 18.5.
5
 
6
  Author: Dr Majed Abuseif
7
- Date: May 2025
8
- Version: 1.0.8
9
  """
10
 
11
  from typing import Dict, List, Any, Optional, Tuple
@@ -279,8 +279,6 @@ class CoolingLoadCalculator:
279
  for window in building_components.get('windows', []):
280
  for hour in range(24):
281
  adjusted_shgc = getattr(window, 'adjusted_shgc', None)
282
- glazing_type = getattr(window, 'glazing_type', None)
283
- frame_type = getattr(window, 'frame_type', None)
284
  load_dict = self.calculate_window_cooling_load(
285
  window=window,
286
  outdoor_temp=outdoor_conditions['temperature'],
@@ -289,9 +287,7 @@ class CoolingLoadCalculator:
289
  hour=hour,
290
  latitude=latitude,
291
  shading_coefficient=window.shading_coefficient,
292
- adjusted_shgc=adjusted_shgc,
293
- glazing_type=glazing_type,
294
- frame_type=frame_type
295
  )
296
  hourly_loads['windows_conduction'][hour + 1] += load_dict['conduction']
297
  hourly_loads['windows_solar'][hour + 1] += load_dict['solar']
@@ -300,8 +296,6 @@ class CoolingLoadCalculator:
300
  for skylight in building_components.get('skylights', []):
301
  for hour in range(24):
302
  adjusted_shgc = getattr(skylight, 'adjusted_shgc', None)
303
- glazing_type = getattr(skylight, 'glazing_type', None)
304
- frame_type = getattr(skylight, 'frame_type', None)
305
  load_dict = self.calculate_skylight_cooling_load(
306
  skylight=skylight,
307
  outdoor_temp=outdoor_conditions['temperature'],
@@ -310,9 +304,7 @@ class CoolingLoadCalculator:
310
  hour=hour,
311
  latitude=latitude,
312
  shading_coefficient=skylight.shading_coefficient,
313
- adjusted_shgc=adjusted_shgc,
314
- glazing_type=glazing_type,
315
- frame_type=frame_type
316
  )
317
  hourly_loads['skylights_conduction'][hour + 1] += load_dict['conduction']
318
  hourly_loads['skylights_solar'][hour + 1] += load_dict['solar']
@@ -670,9 +662,7 @@ class CoolingLoadCalculator:
670
  hour: int,
671
  latitude: str,
672
  shading_coefficient: float,
673
- adjusted_shgc: Optional[float] = None,
674
- glazing_type: Optional[str] = None,
675
- frame_type: Optional[str] = None
676
  ) -> Dict[str, float]:
677
  """
678
  Calculate cooling load for a window (conduction and solar).
@@ -687,8 +677,6 @@ class CoolingLoadCalculator:
687
  latitude: Latitude (e.g., '24N')
688
  shading_coefficient: Default shading coefficient
689
  adjusted_shgc: Adjusted SHGC from external drapery calculation (optional)
690
- glazing_type: Type of glazing (e.g., 'Single Clear', 'Double Tinted') (optional)
691
- frame_type: Type of frame (e.g., 'Aluminum', 'Vinyl') (optional)
692
 
693
  Returns:
694
  Dictionary with conduction, solar, and total loads in Watts
@@ -698,31 +686,17 @@ class CoolingLoadCalculator:
698
  month = self.validate_month(month)
699
  hour = self.validate_hour(hour)
700
  if self.debug_mode:
701
- logger.debug(f"calculate_window_cooling_load: latitude={latitude}, month={month}, hour={hour}, orientation={window.orientation.value}, glazing_type={glazing_type}, frame_type={frame_type}")
702
-
703
- # Fetch U-factor and SHGC from Drapery if glazing_type and frame_type are provided
704
- u_value = window.u_value
705
- shgc = window.shgc
706
- if glazing_type and frame_type:
707
- try:
708
- drapery = Drapery()
709
- u_value = drapery.WINDOW_U_FACTORS.get((glazing_type, frame_type), window.u_value)
710
- shgc = drapery.WINDOW_SHGC.get((glazing_type, frame_type), window.shgc)
711
- if self.debug_mode:
712
- logger.debug(f"Using Drapery values: u_value={u_value}, shgc={shgc} for glazing_type={glazing_type}, frame_type={frame_type}")
713
- except Exception as e:
714
- if self.debug_mode:
715
- logger.warning(f"Error fetching Drapery values for glazing_type={glazing_type}, frame_type={frame_type}: {str(e)}. Using default u_value={u_value}, shgc={shgc}")
716
 
717
  # Conduction load
718
  cltd = outdoor_temp - indoor_temp
719
- conduction_load = u_value * window.area * cltd
720
 
721
  # Determine shading coefficient
722
  effective_shading_coefficient = adjusted_shgc if adjusted_shgc is not None else shading_coefficient
723
  if adjusted_shgc is None and hasattr(window, 'drapery') and window.drapery and window.drapery.enabled:
724
  try:
725
- effective_shading_coefficient = window.drapery.get_shading_coefficient(shgc)
726
  if self.debug_mode:
727
  logger.debug(f"Using drapery shading coefficient: {effective_shading_coefficient}")
728
  except Exception as e:
@@ -746,7 +720,7 @@ class CoolingLoadCalculator:
746
  logger.warning("Using default SCL=100 W/m²")
747
  scl = 100.0
748
 
749
- solar_load = window.area * shgc * effective_shading_coefficient * scl
750
 
751
  total_load = conduction_load + solar_load
752
  if self.debug_mode:
@@ -772,9 +746,7 @@ class CoolingLoadCalculator:
772
  hour: int,
773
  latitude: str,
774
  shading_coefficient: float,
775
- adjusted_shgc: Optional[float] = None,
776
- glazing_type: Optional[str] = None,
777
- frame_type: Optional[str] = None
778
  ) -> Dict[str, float]:
779
  """
780
  Calculate cooling load for a skylight (conduction and solar).
@@ -789,8 +761,6 @@ class CoolingLoadCalculator:
789
  latitude: Latitude (e.g., '24N')
790
  shading_coefficient: Default shading coefficient
791
  adjusted_shgc: Adjusted SHGC from external drapery calculation (optional)
792
- glazing_type: Type of glazing (e.g., 'Single Clear', 'Double Tinted') (optional)
793
- frame_type: Type of frame (e.g., 'Aluminum', 'Vinyl') (optional)
794
 
795
  Returns:
796
  Dictionary with conduction, solar, and total loads in Watts
@@ -800,31 +770,17 @@ class CoolingLoadCalculator:
800
  month = self.validate_month(month)
801
  hour = self.validate_hour(hour)
802
  if self.debug_mode:
803
- logger.debug(f"calculate_skylight_cooling_load: latitude={latitude}, month={month}, hour={hour}, orientation=Horizontal, glazing_type={glazing_type}, frame_type={frame_type}")
804
-
805
- # Fetch U-factor and SHGC from Drapery if glazing_type and frame_type are provided
806
- u_value = skylight.u_value
807
- shgc = skylight.shgc
808
- if glazing_type and frame_type:
809
- try:
810
- drapery = Drapery()
811
- u_value = drapery.SKYLIGHT_U_FACTORS.get((glazing_type, frame_type), skylight.u_value)
812
- shgc = drapery.SKYLIGHT_SHGC.get((glazing_type, frame_type), skylight.shgc)
813
- if self.debug_mode:
814
- logger.debug(f"Using Drapery values: u_value={u_value}, shgc={shgc} for glazing_type={glazing_type}, frame_type={frame_type}")
815
- except Exception as e:
816
- if self.debug_mode:
817
- logger.warning(f"Error fetching Drapery values for glazing_type={glazing_type}, frame_type={frame_type}: {str(e)}. Using default u_value={u_value}, shgc={shgc}")
818
 
819
  # Conduction load
820
  cltd = outdoor_temp - indoor_temp
821
- conduction_load = u_value * skylight.area * cltd
822
 
823
  # Determine shading coefficient
824
  effective_shading_coefficient = adjusted_shgc if adjusted_shgc is not None else shading_coefficient
825
  if adjusted_shgc is None and hasattr(skylight, 'drapery') and skylight.drapery and skylight.drapery.enabled:
826
  try:
827
- effective_shading_coefficient = skylight.drapery.get_shading_coefficient(shgc)
828
  if self.debug_mode:
829
  logger.debug(f"Using drapery shading coefficient: {effective_shading_coefficient}")
830
  except Exception as e:
@@ -848,7 +804,7 @@ class CoolingLoadCalculator:
848
  logger.warning("Using default SCL=100 W/m²")
849
  scl = 100.0
850
 
851
- solar_load = skylight.area * shgc * effective_shading_coefficient * scl
852
 
853
  total_load = conduction_load + solar_load
854
  if self.debug_mode:
@@ -1192,7 +1148,7 @@ if __name__ == "__main__":
1192
  components = {
1193
  'walls': [Wall(id="w1", name="North Wall", area=20.0, u_value=0.5, orientation=Orientation.NORTH, wall_group='A', solar_absorptivity=0.6)],
1194
  'roofs': [Roof(id="r1", name="Main Roof", area=100.0, u_value=0.3, orientation=Orientation.HORIZONTAL, roof_group='A', solar_absorptivity=0.6)],
1195
- 'windows': [Window(id="win1", name="South Window", area=10.0, u_value=2.8, orientation=Orientation.SOUTH, shgc=0.7, shading_coefficient=0.8, glazing_type='Single Clear', frame_type='Aluminum')],
1196
  'doors': [Door(id="d1", name="Main Door", area=2.0, u_value=2.0, orientation=Orientation.NORTH)]
1197
  }
1198
  outdoor_conditions = {
 
4
  Reference: ASHRAE Handbook—Fundamentals (2017), Chapter 18, Section 18.5.
5
 
6
  Author: Dr Majed Abuseif
7
+ Date: April 2025
8
+ Version: 1.0.7
9
  """
10
 
11
  from typing import Dict, List, Any, Optional, Tuple
 
279
  for window in building_components.get('windows', []):
280
  for hour in range(24):
281
  adjusted_shgc = getattr(window, 'adjusted_shgc', None)
 
 
282
  load_dict = self.calculate_window_cooling_load(
283
  window=window,
284
  outdoor_temp=outdoor_conditions['temperature'],
 
287
  hour=hour,
288
  latitude=latitude,
289
  shading_coefficient=window.shading_coefficient,
290
+ adjusted_shgc=adjusted_shgc
 
 
291
  )
292
  hourly_loads['windows_conduction'][hour + 1] += load_dict['conduction']
293
  hourly_loads['windows_solar'][hour + 1] += load_dict['solar']
 
296
  for skylight in building_components.get('skylights', []):
297
  for hour in range(24):
298
  adjusted_shgc = getattr(skylight, 'adjusted_shgc', None)
 
 
299
  load_dict = self.calculate_skylight_cooling_load(
300
  skylight=skylight,
301
  outdoor_temp=outdoor_conditions['temperature'],
 
304
  hour=hour,
305
  latitude=latitude,
306
  shading_coefficient=skylight.shading_coefficient,
307
+ adjusted_shgc=adjusted_shgc
 
 
308
  )
309
  hourly_loads['skylights_conduction'][hour + 1] += load_dict['conduction']
310
  hourly_loads['skylights_solar'][hour + 1] += load_dict['solar']
 
662
  hour: int,
663
  latitude: str,
664
  shading_coefficient: float,
665
+ adjusted_shgc: Optional[float] = None
 
 
666
  ) -> Dict[str, float]:
667
  """
668
  Calculate cooling load for a window (conduction and solar).
 
677
  latitude: Latitude (e.g., '24N')
678
  shading_coefficient: Default shading coefficient
679
  adjusted_shgc: Adjusted SHGC from external drapery calculation (optional)
 
 
680
 
681
  Returns:
682
  Dictionary with conduction, solar, and total loads in Watts
 
686
  month = self.validate_month(month)
687
  hour = self.validate_hour(hour)
688
  if self.debug_mode:
689
+ logger.debug(f"calculate_window_cooling_load: latitude={latitude}, month={month}, hour={hour}, orientation={window.orientation.value}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
690
 
691
  # Conduction load
692
  cltd = outdoor_temp - indoor_temp
693
+ conduction_load = window.u_value * window.area * cltd
694
 
695
  # Determine shading coefficient
696
  effective_shading_coefficient = adjusted_shgc if adjusted_shgc is not None else shading_coefficient
697
  if adjusted_shgc is None and hasattr(window, 'drapery') and window.drapery and window.drapery.enabled:
698
  try:
699
+ effective_shading_coefficient = window.drapery.get_shading_coefficient(window.shgc)
700
  if self.debug_mode:
701
  logger.debug(f"Using drapery shading coefficient: {effective_shading_coefficient}")
702
  except Exception as e:
 
720
  logger.warning("Using default SCL=100 W/m²")
721
  scl = 100.0
722
 
723
+ solar_load = window.area * window.shgc * effective_shading_coefficient * scl
724
 
725
  total_load = conduction_load + solar_load
726
  if self.debug_mode:
 
746
  hour: int,
747
  latitude: str,
748
  shading_coefficient: float,
749
+ adjusted_shgc: Optional[float] = None
 
 
750
  ) -> Dict[str, float]:
751
  """
752
  Calculate cooling load for a skylight (conduction and solar).
 
761
  latitude: Latitude (e.g., '24N')
762
  shading_coefficient: Default shading coefficient
763
  adjusted_shgc: Adjusted SHGC from external drapery calculation (optional)
 
 
764
 
765
  Returns:
766
  Dictionary with conduction, solar, and total loads in Watts
 
770
  month = self.validate_month(month)
771
  hour = self.validate_hour(hour)
772
  if self.debug_mode:
773
+ logger.debug(f"calculate_skylight_cooling_load: latitude={latitude}, month={month}, hour={hour}, orientation=Horizontal")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
774
 
775
  # Conduction load
776
  cltd = outdoor_temp - indoor_temp
777
+ conduction_load = skylight.u_value * skylight.area * cltd
778
 
779
  # Determine shading coefficient
780
  effective_shading_coefficient = adjusted_shgc if adjusted_shgc is not None else shading_coefficient
781
  if adjusted_shgc is None and hasattr(skylight, 'drapery') and skylight.drapery and skylight.drapery.enabled:
782
  try:
783
+ effective_shading_coefficient = skylight.drapery.get_shading_coefficient(skylight.shgc)
784
  if self.debug_mode:
785
  logger.debug(f"Using drapery shading coefficient: {effective_shading_coefficient}")
786
  except Exception as e:
 
804
  logger.warning("Using default SCL=100 W/m²")
805
  scl = 100.0
806
 
807
+ solar_load = skylight.area * skylight.shgc * effective_shading_coefficient * scl
808
 
809
  total_load = conduction_load + solar_load
810
  if self.debug_mode:
 
1148
  components = {
1149
  'walls': [Wall(id="w1", name="North Wall", area=20.0, u_value=0.5, orientation=Orientation.NORTH, wall_group='A', solar_absorptivity=0.6)],
1150
  'roofs': [Roof(id="r1", name="Main Roof", area=100.0, u_value=0.3, orientation=Orientation.HORIZONTAL, roof_group='A', solar_absorptivity=0.6)],
1151
+ 'windows': [Window(id="win1", name="South Window", area=10.0, u_value=2.8, orientation=Orientation.SOUTH, shgc=0.7, shading_coefficient=0.8)],
1152
  'doors': [Door(id="d1", name="Main Door", area=2.0, u_value=2.0, orientation=Orientation.NORTH)]
1153
  }
1154
  outdoor_conditions = {