Spaces:
Sleeping
Sleeping
Update utils/cooling_load.py
Browse files- utils/cooling_load.py +34 -38
utils/cooling_load.py
CHANGED
|
@@ -669,6 +669,21 @@ class CoolingLoadCalculator:
|
|
| 669 |
"""
|
| 670 |
Calculate cooling load for a window (conduction and solar).
|
| 671 |
Reference: ASHRAE Handbook—Fundamentals (2017), Chapter 18, Equations 18.12-18.13.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 672 |
"""
|
| 673 |
try:
|
| 674 |
# Validate inputs
|
|
@@ -685,24 +700,12 @@ class CoolingLoadCalculator:
|
|
| 685 |
if self.debug_mode:
|
| 686 |
logger.debug(f"Month converted: {month} -> {month_int}")
|
| 687 |
|
| 688 |
-
#
|
| 689 |
-
try:
|
| 690 |
-
lat_value = float(latitude.replace('N', ''))
|
| 691 |
-
if self.debug_mode:
|
| 692 |
-
logger.debug(f"Converted latitude {latitude} to {lat_value} for CLTDCalculator")
|
| 693 |
-
except ValueError:
|
| 694 |
-
if self.debug_mode:
|
| 695 |
-
logger.error(f"Invalid latitude format: {latitude}. Defaulting to 32.0")
|
| 696 |
-
lat_value = 32.0
|
| 697 |
-
|
| 698 |
-
# Initialize CLTDCalculator with numerical latitude
|
| 699 |
-
if self.debug_mode:
|
| 700 |
-
logger.debug(f"Initializing CLTDCalculator with lat_value={lat_value}")
|
| 701 |
cltd_calculator = CLTDCalculator(
|
| 702 |
indoor_temp=indoor_temp,
|
| 703 |
outdoor_max_temp=outdoor_temp,
|
| 704 |
outdoor_daily_range=11.7, # Default from drapery.py
|
| 705 |
-
latitude=
|
| 706 |
month=month_int
|
| 707 |
)
|
| 708 |
|
|
@@ -724,8 +727,6 @@ class CoolingLoadCalculator:
|
|
| 724 |
# Conduction load using CLTD
|
| 725 |
try:
|
| 726 |
glazing_key = glazing_type if glazing_type in ['Single Clear', 'Double Tinted', 'Low-E', 'Reflective'] else 'SingleClear'
|
| 727 |
-
if self.debug_mode:
|
| 728 |
-
logger.debug(f"Calling get_cltd_window with glazing_type={glazing_key}, orientation={window.orientation.value}, hour={hour}")
|
| 729 |
cltd = cltd_calculator.get_cltd_window(
|
| 730 |
glazing_type=glazing_key,
|
| 731 |
orientation=window.orientation.value,
|
|
@@ -757,22 +758,19 @@ class CoolingLoadCalculator:
|
|
| 757 |
|
| 758 |
# Solar load with latitude interpolation
|
| 759 |
try:
|
|
|
|
| 760 |
latitudes = [24, 32, 40, 48, 56]
|
| 761 |
lat1 = max([lat for lat in latitudes if lat <= lat_value], default=24)
|
| 762 |
lat2 = min([lat for lat in latitudes if lat >= lat_value], default=56)
|
| 763 |
-
lat1_str = f"{lat1}N"
|
| 764 |
-
lat2_str = f"{lat2}N"
|
| 765 |
|
| 766 |
-
if self.debug_mode:
|
| 767 |
-
logger.debug(f"Calling get_scl with lat1_str={lat1_str}, lat2_str={lat2_str}, orientation={window.orientation.value}, hour={hour}, month={month_int}")
|
| 768 |
scl1 = cltd_calculator.ashrae_tables.get_scl(
|
| 769 |
-
latitude=
|
| 770 |
orientation=window.orientation.value,
|
| 771 |
hour=hour,
|
| 772 |
month=month_int
|
| 773 |
)
|
| 774 |
scl2 = cltd_calculator.ashrae_tables.get_scl(
|
| 775 |
-
latitude=
|
| 776 |
orientation=window.orientation.value,
|
| 777 |
hour=hour,
|
| 778 |
month=month_int
|
|
@@ -849,14 +847,14 @@ class CoolingLoadCalculator:
|
|
| 849 |
hour = self.validate_hour(hour)
|
| 850 |
if self.debug_mode:
|
| 851 |
logger.debug(f"calculate_skylight_cooling_load: latitude={latitude}, month={month}, hour={hour}, orientation=Horizontal, glazing_type={glazing_type}, frame_type={frame_type}")
|
| 852 |
-
|
| 853 |
# Convert month string to integer for CLTDCalculator
|
| 854 |
month_map = {'JAN': 1, 'FEB': 2, 'MAR': 3, 'APR': 4, 'MAY': 5, 'JUN': 6,
|
| 855 |
'JUL': 7, 'AUG': 8, 'SEP': 9, 'OCT': 10, 'NOV': 11, 'DEC': 12}
|
| 856 |
month_int = month_map.get(month.upper(), 7) # Default to July
|
| 857 |
if self.debug_mode:
|
| 858 |
logger.debug(f"Month converted: {month} -> {month_int}")
|
| 859 |
-
|
| 860 |
# Initialize CLTDCalculator
|
| 861 |
cltd_calculator = CLTDCalculator(
|
| 862 |
indoor_temp=indoor_temp,
|
|
@@ -865,7 +863,7 @@ class CoolingLoadCalculator:
|
|
| 865 |
latitude=latitude,
|
| 866 |
month=month_int
|
| 867 |
)
|
| 868 |
-
|
| 869 |
# Determine U-factor and SHGC
|
| 870 |
u_value = skylight.u_value
|
| 871 |
shgc = skylight.shgc
|
|
@@ -880,7 +878,7 @@ class CoolingLoadCalculator:
|
|
| 880 |
except StopIteration:
|
| 881 |
if self.debug_mode:
|
| 882 |
logger.warning(f"Invalid glazing_type={glazing_type} or frame_type={frame_type}. Using default u_value={u_value}, shgc={shgc}")
|
| 883 |
-
|
| 884 |
# Conduction load using CLTD
|
| 885 |
try:
|
| 886 |
glazing_key = glazing_type if glazing_type in ['Single Clear', 'Double Tinted', 'Low-E', 'Reflective'] else 'SingleClear'
|
|
@@ -895,9 +893,9 @@ class CoolingLoadCalculator:
|
|
| 895 |
logger.error(f"get_cltd_skylight failed for glazing_type={glazing_key}: {str(e)}")
|
| 896 |
logger.warning("Using default CLTD=8.0°C")
|
| 897 |
cltd = 8.0
|
| 898 |
-
|
| 899 |
conduction_load = u_value * skylight.area * cltd
|
| 900 |
-
|
| 901 |
# Determine shading coefficient
|
| 902 |
effective_shading_coefficient = adjusted_shgc if adjusted_shgc is not None else shading_coefficient
|
| 903 |
if adjusted_shgc is None and hasattr(skylight, 'drapery') and skylight.drapery and skylight.drapery.enabled:
|
|
@@ -911,29 +909,27 @@ class CoolingLoadCalculator:
|
|
| 911 |
else:
|
| 912 |
if self.debug_mode:
|
| 913 |
logger.debug(f"Using shading coefficient: {effective_shading_coefficient} (adjusted_shgc={adjusted_shgc}, drapery={'enabled' if hasattr(skylight, 'drapery') and skylight.drapery and skylight.drapery.enabled else 'disabled'})")
|
| 914 |
-
|
| 915 |
# Solar load with latitude interpolation
|
| 916 |
try:
|
| 917 |
lat_value = float(latitude.replace('N', ''))
|
| 918 |
latitudes = [24, 32, 40, 48, 56]
|
| 919 |
lat1 = max([lat for lat in latitudes if lat <= lat_value], default=24)
|
| 920 |
lat2 = min([lat for lat in latitudes if lat >= lat_value], default=56)
|
| 921 |
-
|
| 922 |
-
lat2_str = f"{lat2}N"
|
| 923 |
-
|
| 924 |
scl1 = cltd_calculator.ashrae_tables.get_scl(
|
| 925 |
-
latitude=
|
| 926 |
orientation='Horizontal',
|
| 927 |
hour=hour,
|
| 928 |
month=month_int
|
| 929 |
)
|
| 930 |
scl2 = cltd_calculator.ashrae_tables.get_scl(
|
| 931 |
-
latitude=
|
| 932 |
orientation='Horizontal',
|
| 933 |
hour=hour,
|
| 934 |
month=month_int
|
| 935 |
)
|
| 936 |
-
|
| 937 |
# Interpolate SCL
|
| 938 |
if lat1 == lat2:
|
| 939 |
scl = scl1
|
|
@@ -948,13 +944,13 @@ class CoolingLoadCalculator:
|
|
| 948 |
logger.error(f"get_scl failed for latitude={latitude}, month={month}, orientation=Horizontal: {str(e)}")
|
| 949 |
logger.warning("Using default SCL=100 W/m²")
|
| 950 |
scl = 100.0
|
| 951 |
-
|
| 952 |
solar_load = skylight.area * shgc * effective_shading_coefficient * scl
|
| 953 |
-
|
| 954 |
total_load = conduction_load + solar_load
|
| 955 |
if self.debug_mode:
|
| 956 |
logger.debug(f"Skylight load: conduction={conduction_load}, solar={solar_load}, total={total_load}, u_value={u_value}, shgc={shgc}, cltd={cltd}, effective_shading_coefficient={effective_shading_coefficient}")
|
| 957 |
-
|
| 958 |
return {
|
| 959 |
'conduction': max(conduction_load, 0.0),
|
| 960 |
'solar': max(solar_load, 0.0),
|
|
|
|
| 669 |
"""
|
| 670 |
Calculate cooling load for a window (conduction and solar).
|
| 671 |
Reference: ASHRAE Handbook—Fundamentals (2017), Chapter 18, Equations 18.12-18.13.
|
| 672 |
+
|
| 673 |
+
Args:
|
| 674 |
+
window: Window component
|
| 675 |
+
outdoor_temp: Outdoor temperature (°C)
|
| 676 |
+
indoor_temp: Indoor temperature (°C)
|
| 677 |
+
month: Design month (e.g., 'JUL')
|
| 678 |
+
hour: Hour of the day
|
| 679 |
+
latitude: Latitude (e.g., '40N')
|
| 680 |
+
shading_coefficient: Default shading coefficient
|
| 681 |
+
adjusted_shgc: Adjusted SHGC from external drapery calculation (optional)
|
| 682 |
+
glazing_type: Glazing type (e.g., 'Single Clear') (optional)
|
| 683 |
+
frame_type: Frame type (e.g., 'Aluminum without Thermal Break') (optional)
|
| 684 |
+
|
| 685 |
+
Returns:
|
| 686 |
+
Dictionary with conduction, solar, and total loads in Watts
|
| 687 |
"""
|
| 688 |
try:
|
| 689 |
# Validate inputs
|
|
|
|
| 700 |
if self.debug_mode:
|
| 701 |
logger.debug(f"Month converted: {month} -> {month_int}")
|
| 702 |
|
| 703 |
+
# Initialize CLTDCalculator
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 704 |
cltd_calculator = CLTDCalculator(
|
| 705 |
indoor_temp=indoor_temp,
|
| 706 |
outdoor_max_temp=outdoor_temp,
|
| 707 |
outdoor_daily_range=11.7, # Default from drapery.py
|
| 708 |
+
latitude=latitude,
|
| 709 |
month=month_int
|
| 710 |
)
|
| 711 |
|
|
|
|
| 727 |
# Conduction load using CLTD
|
| 728 |
try:
|
| 729 |
glazing_key = glazing_type if glazing_type in ['Single Clear', 'Double Tinted', 'Low-E', 'Reflective'] else 'SingleClear'
|
|
|
|
|
|
|
| 730 |
cltd = cltd_calculator.get_cltd_window(
|
| 731 |
glazing_type=glazing_key,
|
| 732 |
orientation=window.orientation.value,
|
|
|
|
| 758 |
|
| 759 |
# Solar load with latitude interpolation
|
| 760 |
try:
|
| 761 |
+
lat_value = float(latitude.replace('N', ''))
|
| 762 |
latitudes = [24, 32, 40, 48, 56]
|
| 763 |
lat1 = max([lat for lat in latitudes if lat <= lat_value], default=24)
|
| 764 |
lat2 = min([lat for lat in latitudes if lat >= lat_value], default=56)
|
|
|
|
|
|
|
| 765 |
|
|
|
|
|
|
|
| 766 |
scl1 = cltd_calculator.ashrae_tables.get_scl(
|
| 767 |
+
latitude=float(lat1), # Use numerical latitude
|
| 768 |
orientation=window.orientation.value,
|
| 769 |
hour=hour,
|
| 770 |
month=month_int
|
| 771 |
)
|
| 772 |
scl2 = cltd_calculator.ashrae_tables.get_scl(
|
| 773 |
+
latitude=float(lat2), # Use numerical latitude
|
| 774 |
orientation=window.orientation.value,
|
| 775 |
hour=hour,
|
| 776 |
month=month_int
|
|
|
|
| 847 |
hour = self.validate_hour(hour)
|
| 848 |
if self.debug_mode:
|
| 849 |
logger.debug(f"calculate_skylight_cooling_load: latitude={latitude}, month={month}, hour={hour}, orientation=Horizontal, glazing_type={glazing_type}, frame_type={frame_type}")
|
| 850 |
+
|
| 851 |
# Convert month string to integer for CLTDCalculator
|
| 852 |
month_map = {'JAN': 1, 'FEB': 2, 'MAR': 3, 'APR': 4, 'MAY': 5, 'JUN': 6,
|
| 853 |
'JUL': 7, 'AUG': 8, 'SEP': 9, 'OCT': 10, 'NOV': 11, 'DEC': 12}
|
| 854 |
month_int = month_map.get(month.upper(), 7) # Default to July
|
| 855 |
if self.debug_mode:
|
| 856 |
logger.debug(f"Month converted: {month} -> {month_int}")
|
| 857 |
+
|
| 858 |
# Initialize CLTDCalculator
|
| 859 |
cltd_calculator = CLTDCalculator(
|
| 860 |
indoor_temp=indoor_temp,
|
|
|
|
| 863 |
latitude=latitude,
|
| 864 |
month=month_int
|
| 865 |
)
|
| 866 |
+
|
| 867 |
# Determine U-factor and SHGC
|
| 868 |
u_value = skylight.u_value
|
| 869 |
shgc = skylight.shgc
|
|
|
|
| 878 |
except StopIteration:
|
| 879 |
if self.debug_mode:
|
| 880 |
logger.warning(f"Invalid glazing_type={glazing_type} or frame_type={frame_type}. Using default u_value={u_value}, shgc={shgc}")
|
| 881 |
+
|
| 882 |
# Conduction load using CLTD
|
| 883 |
try:
|
| 884 |
glazing_key = glazing_type if glazing_type in ['Single Clear', 'Double Tinted', 'Low-E', 'Reflective'] else 'SingleClear'
|
|
|
|
| 893 |
logger.error(f"get_cltd_skylight failed for glazing_type={glazing_key}: {str(e)}")
|
| 894 |
logger.warning("Using default CLTD=8.0°C")
|
| 895 |
cltd = 8.0
|
| 896 |
+
|
| 897 |
conduction_load = u_value * skylight.area * cltd
|
| 898 |
+
|
| 899 |
# Determine shading coefficient
|
| 900 |
effective_shading_coefficient = adjusted_shgc if adjusted_shgc is not None else shading_coefficient
|
| 901 |
if adjusted_shgc is None and hasattr(skylight, 'drapery') and skylight.drapery and skylight.drapery.enabled:
|
|
|
|
| 909 |
else:
|
| 910 |
if self.debug_mode:
|
| 911 |
logger.debug(f"Using shading coefficient: {effective_shading_coefficient} (adjusted_shgc={adjusted_shgc}, drapery={'enabled' if hasattr(skylight, 'drapery') and skylight.drapery and skylight.drapery.enabled else 'disabled'})")
|
| 912 |
+
|
| 913 |
# Solar load with latitude interpolation
|
| 914 |
try:
|
| 915 |
lat_value = float(latitude.replace('N', ''))
|
| 916 |
latitudes = [24, 32, 40, 48, 56]
|
| 917 |
lat1 = max([lat for lat in latitudes if lat <= lat_value], default=24)
|
| 918 |
lat2 = min([lat for lat in latitudes if lat >= lat_value], default=56)
|
| 919 |
+
|
|
|
|
|
|
|
| 920 |
scl1 = cltd_calculator.ashrae_tables.get_scl(
|
| 921 |
+
latitude=float(lat1), # Use numerical latitude
|
| 922 |
orientation='Horizontal',
|
| 923 |
hour=hour,
|
| 924 |
month=month_int
|
| 925 |
)
|
| 926 |
scl2 = cltd_calculator.ashrae_tables.get_scl(
|
| 927 |
+
latitude=float(lat2), # Use numerical latitude
|
| 928 |
orientation='Horizontal',
|
| 929 |
hour=hour,
|
| 930 |
month=month_int
|
| 931 |
)
|
| 932 |
+
|
| 933 |
# Interpolate SCL
|
| 934 |
if lat1 == lat2:
|
| 935 |
scl = scl1
|
|
|
|
| 944 |
logger.error(f"get_scl failed for latitude={latitude}, month={month}, orientation=Horizontal: {str(e)}")
|
| 945 |
logger.warning("Using default SCL=100 W/m²")
|
| 946 |
scl = 100.0
|
| 947 |
+
|
| 948 |
solar_load = skylight.area * shgc * effective_shading_coefficient * scl
|
| 949 |
+
|
| 950 |
total_load = conduction_load + solar_load
|
| 951 |
if self.debug_mode:
|
| 952 |
logger.debug(f"Skylight load: conduction={conduction_load}, solar={solar_load}, total={total_load}, u_value={u_value}, shgc={shgc}, cltd={cltd}, effective_shading_coefficient={effective_shading_coefficient}")
|
| 953 |
+
|
| 954 |
return {
|
| 955 |
'conduction': max(conduction_load, 0.0),
|
| 956 |
'solar': max(solar_load, 0.0),
|