mabuseif commited on
Commit
f87c4c2
·
verified ·
1 Parent(s): 2027ab2

Update data/drapery.py

Browse files
Files changed (1) hide show
  1. data/drapery.py +71 -14
data/drapery.py CHANGED
@@ -888,6 +888,41 @@ class WindowHeatGainCalculator:
888
  cltd_calculator: Instance of CLTDCalculator
889
  """
890
  self.cltd_calculator = cltd_calculator
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
891
 
892
  def calculate_window_heat_gain(self, area: float, glazing_type: GlazingType,
893
  frame_type: FrameType, orientation: str, hour: int,
@@ -906,6 +941,13 @@ class WindowHeatGainCalculator:
906
  Returns:
907
  Tuple of (conduction_heat_gain, solar_heat_gain) in Watts
908
  """
 
 
 
 
 
 
 
909
  # Get U-factor
910
  u_factor = WINDOW_U_FACTORS.get((glazing_type, frame_type), 7.22)
911
 
@@ -919,13 +961,17 @@ class WindowHeatGainCalculator:
919
  conduction_reduction = drapery.get_conduction_reduction() if drapery and drapery.enabled else 0.0
920
  conduction_heat_gain = area * u_factor * cltd * (1.0 - conduction_reduction)
921
 
922
- # Get SCL from ASHRAE tables
923
- scl = self.cltd_calculator.ashrae_tables.get_scl(
924
- latitude=self.cltd_calculator.latitude.value,
925
- orientation=orientation,
926
- hour=hour,
927
- month=self.cltd_calculator.month
928
- )
 
 
 
 
929
 
930
  # Apply drapery shading coefficient
931
  shading_coefficient = drapery.get_shading_coefficient(shgc) if drapery and drapery.enabled else 1.0
@@ -949,6 +995,13 @@ class WindowHeatGainCalculator:
949
  Returns:
950
  Tuple of (conduction_heat_gain, solar_heat_gain) in Watts
951
  """
 
 
 
 
 
 
 
952
  # Get U-factor
953
  u_factor = SKYLIGHT_U_FACTORS.get((glazing_type, frame_type), 7.79)
954
 
@@ -962,13 +1015,17 @@ class WindowHeatGainCalculator:
962
  conduction_reduction = drapery.get_conduction_reduction() if drapery and drapery.enabled else 0.0
963
  conduction_heat_gain = area * u_factor * cltd * (1.0 - conduction_reduction)
964
 
965
- # Get SCL for skylight (horizontal)
966
- scl = self.cltd_calculator.ashrae_tables.get_scl(
967
- latitude=self.cltd_calculator.latitude.value,
968
- orientation='Horizontal',
969
- hour=hour,
970
- month=self.cltd_calculator.month
971
- )
 
 
 
 
972
 
973
  # Apply drapery shading coefficient
974
  shading_coefficient = drapery.get_shading_coefficient(shgc) if drapery and drapery.enabled else 1.0
 
888
  cltd_calculator: Instance of CLTDCalculator
889
  """
890
  self.cltd_calculator = cltd_calculator
891
+
892
+ def _validate_inputs(self, glazing_type: GlazingType, frame_type: FrameType, orientation: str, hour: int, latitude: Any, month: int) -> Tuple[bool, str, float]:
893
+ """Validate inputs for window/skylight heat gain calculations, following ASHRAE."""
894
+ valid_orientations = ['North', 'Northeast', 'East', 'Southeast', 'South', 'Southwest', 'West', 'Northwest', 'Horizontal']
895
+ valid_latitudes = ['24N', '32N', '40N', '48N', '56N']
896
+ valid_months = list(range(1, 13))
897
+ valid_glazing_types = [e.value for e in GlazingType]
898
+ valid_frame_types = [e.value for e in FrameType]
899
+
900
+ if glazing_type.value not in valid_glazing_types:
901
+ return False, f"Invalid glazing type: {glazing_type.value}. Valid types: {valid_glazing_types}", 0.0
902
+ if frame_type.value not in valid_frame_types:
903
+ return False, f"Invalid frame type: {frame_type.value}. Valid types: {valid_frame_types}", 0.0
904
+ if orientation not in valid_orientations:
905
+ return False, f"Invalid orientation: {orientation}. Valid orientations: {valid_orientations}", 0.0
906
+ if hour not in range(24):
907
+ return False, "Hour must be between 0 and 23.", 0.0
908
+ if month not in valid_months:
909
+ return False, f"Invalid month: {month}. Valid months: 1-12", 0.0
910
+
911
+ # Handle latitude input
912
+ try:
913
+ if isinstance(latitude, str):
914
+ lat_str = latitude.upper().strip().replace('°', '').replace(' ', '')
915
+ num_part = ''.join(c for c in lat_str if c.isdigit() or c == '.')
916
+ lat_val = float(num_part)
917
+ if 'S' in lat_str:
918
+ lat_val = -lat_val
919
+ else:
920
+ lat_val = float(latitude)
921
+ abs_lat = abs(lat_val)
922
+ except (ValueError, TypeError):
923
+ return False, f"Invalid latitude: {latitude}. Use number (e.g., 40) or string (e.g., '40N')", 0.0
924
+
925
+ return True, "Valid inputs.", abs_lat
926
 
927
  def calculate_window_heat_gain(self, area: float, glazing_type: GlazingType,
928
  frame_type: FrameType, orientation: str, hour: int,
 
941
  Returns:
942
  Tuple of (conduction_heat_gain, solar_heat_gain) in Watts
943
  """
944
+ # Validate inputs
945
+ is_valid, error_msg, lat_val = self._validate_inputs(
946
+ glazing_type, frame_type, orientation, hour, self.cltd_calculator.latitude.value, self.cltd_calculator.month
947
+ )
948
+ if not is_valid:
949
+ raise ValueError(error_msg)
950
+
951
  # Get U-factor
952
  u_factor = WINDOW_U_FACTORS.get((glazing_type, frame_type), 7.22)
953
 
 
961
  conduction_reduction = drapery.get_conduction_reduction() if drapery and drapery.enabled else 0.0
962
  conduction_heat_gain = area * u_factor * cltd * (1.0 - conduction_reduction)
963
 
964
+ # Interpolate SCL for latitude
965
+ latitudes = [24, 32, 40, 48, 56]
966
+ lat1 = max([lat for lat in latitudes if lat <= lat_val], default=24)
967
+ lat2 = min([lat for lat in latitudes if lat >= lat_val], default=56)
968
+ scl1 = self.cltd_calculator.ashrae_tables.get_scl(f"{lat1}N", orientation, hour, self.cltd_calculator.month)
969
+ scl2 = self.cltd_calculator.ashrae_tables.get_scl(f"{lat2}N", orientation, hour, self.cltd_calculator.month)
970
+ if lat1 == lat2:
971
+ scl = scl1
972
+ else:
973
+ weight = (lat_val - lat1) / (lat2 - lat1)
974
+ scl = scl1 + weight * (scl2 - scl1)
975
 
976
  # Apply drapery shading coefficient
977
  shading_coefficient = drapery.get_shading_coefficient(shgc) if drapery and drapery.enabled else 1.0
 
995
  Returns:
996
  Tuple of (conduction_heat_gain, solar_heat_gain) in Watts
997
  """
998
+ # Validate inputs
999
+ is_valid, error_msg, lat_val = self._validate_inputs(
1000
+ glazing_type, frame_type, 'Horizontal', hour, self.cltd_calculator.latitude.value, self.cltd_calculator.month
1001
+ )
1002
+ if not is_valid:
1003
+ raise ValueError(error_msg)
1004
+
1005
  # Get U-factor
1006
  u_factor = SKYLIGHT_U_FACTORS.get((glazing_type, frame_type), 7.79)
1007
 
 
1015
  conduction_reduction = drapery.get_conduction_reduction() if drapery and drapery.enabled else 0.0
1016
  conduction_heat_gain = area * u_factor * cltd * (1.0 - conduction_reduction)
1017
 
1018
+ # Interpolate SCL for latitude
1019
+ latitudes = [24, 32, 40, 48, 56]
1020
+ lat1 = max([lat for lat in latitudes if lat <= lat_val], default=24)
1021
+ lat2 = min([lat for lat in latitudes if lat >= lat_val], default=56)
1022
+ scl1 = self.cltd_calculator.ashrae_tables.get_scl(f"{lat1}N", 'Horizontal', hour, self.cltd_calculator.month)
1023
+ scl2 = self.cltd_calculator.ashrae_tables.get_scl(f"{lat2}N", 'Horizontal', hour, self.cltd_calculator.month)
1024
+ if lat1 == lat2:
1025
+ scl = scl1
1026
+ else:
1027
+ weight = (lat_val - lat1) / (lat2 - lat1)
1028
+ scl = scl1 + weight * (scl2 - scl1)
1029
 
1030
  # Apply drapery shading coefficient
1031
  shading_coefficient = drapery.get_shading_coefficient(shgc) if drapery and drapery.enabled else 1.0