Spaces:
Sleeping
Sleeping
| """ | |
| Cooling load calculation module for HVAC Load Calculator. | |
| This module implements the CLTD/CLF method for calculating cooling loads. | |
| """ | |
| from typing import Dict, List, Any, Optional, Tuple | |
| import math | |
| import numpy as np | |
| import pandas as pd | |
| import os | |
| from datetime import datetime, timedelta | |
| from enum import Enum | |
| # Import data models and utilities | |
| from data.building_components import Wall, Roof, Floor, Window, Door, Orientation, ComponentType | |
| from data.ashrae_tables import ashrae_tables | |
| from utils.psychrometrics import Psychrometrics | |
| from utils.heat_transfer import HeatTransferCalculations | |
| # Define paths | |
| DATA_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |
| class CoolingLoadCalculator: | |
| """Class for calculating cooling loads using the CLTD/CLF method.""" | |
| def __init__(self): | |
| """Initialize cooling load calculator.""" | |
| self.heat_transfer = HeatTransferCalculations() | |
| self.psychrometrics = Psychrometrics() | |
| self.ashrae_tables = ashrae_tables | |
| def calculate_wall_cooling_load(self, wall: Wall, outdoor_temp: float, indoor_temp: float, | |
| month: str, hour: int, latitude: str = "40N", | |
| color: str = "Dark") -> float: | |
| """ | |
| Calculate cooling load through a wall using the CLTD method. | |
| Args: | |
| wall: Wall object | |
| outdoor_temp: Outdoor temperature in °C | |
| indoor_temp: Indoor temperature in °C | |
| month: Month (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec) | |
| hour: Hour of the day (0-23) | |
| latitude: Latitude (24N, 32N, 40N, 48N, 56N) | |
| color: Surface color (Dark, Medium, Light) | |
| Returns: | |
| Cooling load in W | |
| """ | |
| # Get wall properties | |
| u_value = wall.u_value | |
| area = wall.area | |
| orientation = wall.orientation.value | |
| wall_group = wall.wall_group | |
| # Calculate corrected CLTD | |
| cltd = self.ashrae_tables.calculate_corrected_cltd_wall( | |
| wall_group=wall_group, | |
| orientation=orientation, | |
| hour=hour, | |
| color=color, | |
| month=month, | |
| latitude=latitude, | |
| indoor_temp=indoor_temp, | |
| outdoor_temp=outdoor_temp | |
| ) | |
| # Calculate cooling load | |
| cooling_load = u_value * area * cltd | |
| return cooling_load | |
| def calculate_roof_cooling_load(self, roof: Roof, outdoor_temp: float, indoor_temp: float, | |
| month: str, hour: int, latitude: str = "40N", | |
| color: str = "Dark") -> float: | |
| """ | |
| Calculate cooling load through a roof using the CLTD method. | |
| Args: | |
| roof: Roof object | |
| outdoor_temp: Outdoor temperature in °C | |
| indoor_temp: Indoor temperature in °C | |
| month: Month (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec) | |
| hour: Hour of the day (0-23) | |
| latitude: Latitude (24N, 32N, 40N, 48N, 56N) | |
| color: Surface color (Dark, Medium, Light) | |
| Returns: | |
| Cooling load in W | |
| """ | |
| # Get roof properties | |
| u_value = roof.u_value | |
| area = roof.area | |
| roof_group = roof.roof_group | |
| # Calculate corrected CLTD | |
| cltd = self.ashrae_tables.calculate_corrected_cltd_roof( | |
| roof_group=roof_group, | |
| hour=hour, | |
| color=color, | |
| month=month, | |
| latitude=latitude, | |
| indoor_temp=indoor_temp, | |
| outdoor_temp=outdoor_temp | |
| ) | |
| # Calculate cooling load | |
| cooling_load = u_value * area * cltd | |
| return cooling_load | |
| def calculate_window_cooling_load(self, window: Window, outdoor_temp: float, indoor_temp: float, | |
| month: str, hour: int, latitude: str = "40N_JUL", | |
| shading_coefficient: float = 1.0) -> Dict[str, float]: | |
| """ | |
| Calculate cooling load through a window using the CLTD/SCL method. | |
| Args: | |
| window: Window object | |
| outdoor_temp: Outdoor temperature in °C | |
| indoor_temp: Indoor temperature in °C | |
| month: Month (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec) | |
| hour: Hour of the day (0-23) | |
| latitude: Latitude and month key (default: "40N_JUL") | |
| shading_coefficient: Shading coefficient (0-1) | |
| Returns: | |
| Dictionary with conduction, solar, and total cooling loads in W | |
| """ | |
| # Get window properties | |
| u_value = window.u_value | |
| area = window.area | |
| orientation = window.orientation.value | |
| shgc = window.shgc | |
| # Calculate conduction cooling load | |
| delta_t = outdoor_temp - indoor_temp | |
| conduction_load = u_value * area * delta_t | |
| # Calculate solar cooling load | |
| scl = self.ashrae_tables.get_scl(orientation, hour, latitude) | |
| solar_load = area * shgc * shading_coefficient * scl | |
| # Calculate total cooling load | |
| total_load = conduction_load + solar_load | |
| return { | |
| "conduction": conduction_load, | |
| "solar": solar_load, | |
| "total": total_load | |
| } | |
| def calculate_door_cooling_load(self, door: Door, outdoor_temp: float, indoor_temp: float) -> float: | |
| """ | |
| Calculate cooling load through a door using simple conduction. | |
| Args: | |
| door: Door object | |
| outdoor_temp: Outdoor temperature in °C | |
| indoor_temp: Indoor temperature in °C | |
| Returns: | |
| Cooling load in W | |
| """ | |
| # Get door properties | |
| u_value = door.u_value | |
| area = door.area | |
| # Calculate cooling load | |
| delta_t = outdoor_temp - indoor_temp | |
| cooling_load = u_value * area * delta_t | |
| return cooling_load | |
| def calculate_floor_cooling_load(self, floor: Floor, ground_temp: float, indoor_temp: float) -> float: | |
| """ | |
| Calculate cooling load through a floor. | |
| Args: | |
| floor: Floor object | |
| ground_temp: Ground or adjacent space temperature in °C | |
| indoor_temp: Indoor temperature in °C | |
| Returns: | |
| Cooling load in W | |
| """ | |
| # Get floor properties | |
| u_value = floor.u_value | |
| area = floor.area | |
| # Calculate cooling load | |
| delta_t = ground_temp - indoor_temp | |
| cooling_load = u_value * area * delta_t | |
| # Return positive value for heat gain, zero for heat loss | |
| return max(0, cooling_load) | |
| def calculate_infiltration_cooling_load(self, flow_rate: float, outdoor_temp: float, indoor_temp: float, | |
| outdoor_rh: float, indoor_rh: float) -> Dict[str, float]: | |
| """ | |
| Calculate sensible and latent cooling loads due to infiltration. | |
| Args: | |
| flow_rate: Infiltration flow rate in m³/s | |
| outdoor_temp: Outdoor temperature in °C | |
| indoor_temp: Indoor temperature in °C | |
| outdoor_rh: Outdoor relative humidity in % | |
| indoor_rh: Indoor relative humidity in % | |
| Returns: | |
| Dictionary with sensible, latent, and total cooling loads in W | |
| """ | |
| # Calculate sensible cooling load | |
| sensible_load = self.heat_transfer.infiltration_heat_transfer( | |
| flow_rate=flow_rate, | |
| delta_t=outdoor_temp - indoor_temp | |
| ) | |
| # Calculate humidity ratios | |
| w_outdoor = self.psychrometrics.humidity_ratio(outdoor_temp, outdoor_rh) | |
| w_indoor = self.psychrometrics.humidity_ratio(indoor_temp, indoor_rh) | |
| # Calculate latent cooling load | |
| latent_load = self.heat_transfer.infiltration_latent_heat_transfer( | |
| flow_rate=flow_rate, | |
| delta_w=w_outdoor - w_indoor | |
| ) | |
| # Calculate total cooling load | |
| total_load = sensible_load + latent_load | |
| return { | |
| "sensible": sensible_load, | |
| "latent": latent_load, | |
| "total": total_load | |
| } | |
| def calculate_ventilation_cooling_load(self, flow_rate: float, outdoor_temp: float, indoor_temp: float, | |
| outdoor_rh: float, indoor_rh: float) -> Dict[str, float]: | |
| """ | |
| Calculate sensible and latent cooling loads due to ventilation. | |
| Args: | |
| flow_rate: Ventilation flow rate in m³/s | |
| outdoor_temp: Outdoor temperature in °C | |
| indoor_temp: Indoor temperature in °C | |
| outdoor_rh: Outdoor relative humidity in % | |
| indoor_rh: Indoor relative humidity in % | |
| Returns: | |
| Dictionary with sensible, latent, and total cooling loads in W | |
| """ | |
| # Ventilation load calculation is the same as infiltration | |
| return self.calculate_infiltration_cooling_load( | |
| flow_rate=flow_rate, | |
| outdoor_temp=outdoor_temp, | |
| indoor_temp=indoor_temp, | |
| outdoor_rh=outdoor_rh, | |
| indoor_rh=indoor_rh | |
| ) | |
| def calculate_people_cooling_load(self, num_people: int, activity_level: str, | |
| hours_occupancy: str, hour: int) -> Dict[str, float]: | |
| """ | |
| Calculate sensible and latent cooling loads due to people. | |
| Args: | |
| num_people: Number of people | |
| activity_level: Activity level (Seated/Resting, Light work, Medium work, Heavy work) | |
| hours_occupancy: Hours of occupancy (8h, 10h, 12h, 14h, 16h, 18h, 24h) | |
| hour: Hour of the day (0-23) | |
| Returns: | |
| Dictionary with sensible, latent, and total cooling loads in W | |
| """ | |
| # Define heat gains for different activity levels | |
| activity_gains = { | |
| "Seated/Resting": {"sensible": 70, "latent": 45}, | |
| "Light work": {"sensible": 75, "latent": 55}, | |
| "Medium work": {"sensible": 85, "latent": 80}, | |
| "Heavy work": {"sensible": 95, "latent": 145} | |
| } | |
| # Get heat gains for the specified activity level | |
| if activity_level not in activity_gains: | |
| raise ValueError(f"Invalid activity level: {activity_level}") | |
| sensible_gain = activity_gains[activity_level]["sensible"] | |
| latent_gain = activity_gains[activity_level]["latent"] | |
| # Get CLF for the specified hour and occupancy | |
| clf = self.ashrae_tables.get_clf_people(hour, hours_occupancy) | |
| # Calculate cooling loads | |
| sensible_load = num_people * sensible_gain * clf | |
| latent_load = num_people * latent_gain # Latent load is not affected by CLF | |
| total_load = sensible_load + latent_load | |
| return { | |
| "sensible": sensible_load, | |
| "latent": latent_load, | |
| "total": total_load | |
| } | |
| def calculate_lights_cooling_load(self, power: float, use_factor: float, | |
| special_allowance: float, hours_operation: str, | |
| hour: int) -> float: | |
| """ | |
| Calculate cooling load due to lights. | |
| Args: | |
| power: Installed lighting power in W | |
| use_factor: Usage factor (0-1) | |
| special_allowance: Special allowance factor for fixtures (0-1) | |
| hours_operation: Hours of operation (8h, 10h, 12h, 14h, 16h, 18h, 24h) | |
| hour: Hour of the day (0-23) | |
| Returns: | |
| Cooling load in W | |
| """ | |
| # Get CLF for the specified hour and operation | |
| clf = self.ashrae_tables.get_clf_lights(hour, hours_operation) | |
| # Calculate cooling load | |
| cooling_load = power * use_factor * (1 + special_allowance) * clf | |
| return cooling_load | |
| def calculate_equipment_cooling_load(self, power: float, use_factor: float, | |
| radiation_factor: float, hours_operation: str, | |
| hour: int) -> Dict[str, float]: | |
| """ | |
| Calculate sensible and latent cooling loads due to equipment. | |
| Args: | |
| power: Equipment power in W | |
| use_factor: Usage factor (0-1) | |
| radiation_factor: Radiation factor (0-1) | |
| hours_operation: Hours of operation (8h, 10h, 12h, 14h, 16h, 18h, 24h) | |
| hour: Hour of the day (0-23) | |
| Returns: | |
| Dictionary with sensible, latent, and total cooling loads in W | |
| """ | |
| # Get CLF for the specified hour and operation | |
| clf = self.ashrae_tables.get_clf_equipment(hour, hours_operation) | |
| # Calculate sensible cooling load | |
| sensible_load = power * use_factor * radiation_factor * clf | |
| # Calculate latent cooling load (if any) | |
| latent_load = power * use_factor * (1 - radiation_factor) | |
| # Calculate total cooling load | |
| total_load = sensible_load + latent_load | |
| return { | |
| "sensible": sensible_load, | |
| "latent": latent_load, | |
| "total": total_load | |
| } | |
| def calculate_hourly_cooling_loads(self, building_components: Dict[str, List[Any]], | |
| outdoor_conditions: Dict[str, Any], | |
| indoor_conditions: Dict[str, Any], | |
| internal_loads: Dict[str, Any]) -> Dict[int, Dict[str, float]]: | |
| """ | |
| Calculate hourly cooling loads for a building. | |
| Args: | |
| building_components: Dictionary with lists of building components | |
| outdoor_conditions: Dictionary with outdoor conditions | |
| indoor_conditions: Dictionary with indoor conditions | |
| internal_loads: Dictionary with internal loads | |
| Returns: | |
| Dictionary with hourly cooling loads | |
| """ | |
| # Extract building components | |
| walls = building_components.get("walls", []) | |
| roofs = building_components.get("roofs", []) | |
| floors = building_components.get("floors", []) | |
| windows = building_components.get("windows", []) | |
| doors = building_components.get("doors", []) | |
| # Extract outdoor conditions | |
| outdoor_temp = outdoor_conditions.get("temperature", 35.0) | |
| outdoor_rh = outdoor_conditions.get("relative_humidity", 50.0) | |
| ground_temp = outdoor_conditions.get("ground_temperature", 20.0) | |
| month = outdoor_conditions.get("month", "Jul") | |
| latitude = outdoor_conditions.get("latitude", "40N") | |
| # Extract indoor conditions | |
| indoor_temp = indoor_conditions.get("temperature", 24.0) | |
| indoor_rh = indoor_conditions.get("relative_humidity", 50.0) | |
| # Extract internal loads | |
| people = internal_loads.get("people", {}) | |
| lights = internal_loads.get("lights", {}) | |
| equipment = internal_loads.get("equipment", {}) | |
| infiltration = internal_loads.get("infiltration", {}) | |
| ventilation = internal_loads.get("ventilation", {}) | |
| # Initialize hourly cooling loads | |
| hourly_loads = {} | |
| # Calculate cooling loads for each hour | |
| for hour in range(24): | |
| # Initialize loads for this hour | |
| loads = { | |
| "walls": 0, | |
| "roofs": 0, | |
| "floors": 0, | |
| "windows_conduction": 0, | |
| "windows_solar": 0, | |
| "doors": 0, | |
| "infiltration_sensible": 0, | |
| "infiltration_latent": 0, | |
| "ventilation_sensible": 0, | |
| "ventilation_latent": 0, | |
| "people_sensible": 0, | |
| "people_latent": 0, | |
| "lights": 0, | |
| "equipment_sensible": 0, | |
| "equipment_latent": 0, | |
| "total_sensible": 0, | |
| "total_latent": 0, | |
| "total": 0 | |
| } | |
| # Calculate wall loads | |
| for wall in walls: | |
| wall_load = self.calculate_wall_cooling_load( | |
| wall=wall, | |
| outdoor_temp=outdoor_temp, | |
| indoor_temp=indoor_temp, | |
| month=month, | |
| hour=hour, | |
| latitude=latitude, | |
| color=wall.color if hasattr(wall, "color") else "Dark" | |
| ) | |
| loads["walls"] += wall_load | |
| # Calculate roof loads | |
| for roof in roofs: | |
| roof_load = self.calculate_roof_cooling_load( | |
| roof=roof, | |
| outdoor_temp=outdoor_temp, | |
| indoor_temp=indoor_temp, | |
| month=month, | |
| hour=hour, | |
| latitude=latitude, | |
| color=roof.color if hasattr(roof, "color") else "Dark" | |
| ) | |
| loads["roofs"] += roof_load | |
| # Calculate floor loads | |
| for floor in floors: | |
| floor_load = self.calculate_floor_cooling_load( | |
| floor=floor, | |
| ground_temp=ground_temp, | |
| indoor_temp=indoor_temp | |
| ) | |
| loads["floors"] += floor_load | |
| # Calculate window loads | |
| for window in windows: | |
| window_loads = self.calculate_window_cooling_load( | |
| window=window, | |
| outdoor_temp=outdoor_temp, | |
| indoor_temp=indoor_temp, | |
| month=month, | |
| hour=hour, | |
| latitude=f"{latitude}_{month.upper()}", | |
| shading_coefficient=window.shading_coefficient if hasattr(window, "shading_coefficient") else 1.0 | |
| ) | |
| loads["windows_conduction"] += window_loads["conduction"] | |
| loads["windows_solar"] += window_loads["solar"] | |
| # Calculate door loads | |
| for door in doors: | |
| door_load = self.calculate_door_cooling_load( | |
| door=door, | |
| outdoor_temp=outdoor_temp, | |
| indoor_temp=indoor_temp | |
| ) | |
| loads["doors"] += door_load | |
| # Calculate infiltration loads | |
| if infiltration: | |
| flow_rate = infiltration.get("flow_rate", 0.0) | |
| infiltration_loads = self.calculate_infiltration_cooling_load( | |
| flow_rate=flow_rate, | |
| outdoor_temp=outdoor_temp, | |
| indoor_temp=indoor_temp, | |
| outdoor_rh=outdoor_rh, | |
| indoor_rh=indoor_rh | |
| ) | |
| loads["infiltration_sensible"] = infiltration_loads["sensible"] | |
| loads["infiltration_latent"] = infiltration_loads["latent"] | |
| # Calculate ventilation loads | |
| if ventilation: | |
| flow_rate = ventilation.get("flow_rate", 0.0) | |
| ventilation_loads = self.calculate_ventilation_cooling_load( | |
| flow_rate=flow_rate, | |
| outdoor_temp=outdoor_temp, | |
| indoor_temp=indoor_temp, | |
| outdoor_rh=outdoor_rh, | |
| indoor_rh=indoor_rh | |
| ) | |
| loads["ventilation_sensible"] = ventilation_loads["sensible"] | |
| loads["ventilation_latent"] = ventilation_loads["latent"] | |
| # Calculate people loads | |
| if people: | |
| num_people = people.get("number", 0) | |
| activity_level = people.get("activity_level", "Seated/Resting") | |
| hours_occupancy = people.get("hours_occupancy", "8h") | |
| people_loads = self.calculate_people_cooling_load( | |
| num_people=num_people, | |
| activity_level=activity_level, | |
| hours_occupancy=hours_occupancy, | |
| hour=hour | |
| ) | |
| loads["people_sensible"] = people_loads["sensible"] | |
| loads["people_latent"] = people_loads["latent"] | |
| # Calculate lights loads | |
| if lights: | |
| power = lights.get("power", 0.0) | |
| use_factor = lights.get("use_factor", 1.0) | |
| special_allowance = lights.get("special_allowance", 0.0) | |
| hours_operation = lights.get("hours_operation", "8h") | |
| lights_load = self.calculate_lights_cooling_load( | |
| power=power, | |
| use_factor=use_factor, | |
| special_allowance=special_allowance, | |
| hours_operation=hours_operation, | |
| hour=hour | |
| ) | |
| loads["lights"] = lights_load | |
| # Calculate equipment loads | |
| if equipment: | |
| power = equipment.get("power", 0.0) | |
| use_factor = equipment.get("use_factor", 1.0) | |
| radiation_factor = equipment.get("radiation_factor", 0.7) | |
| hours_operation = equipment.get("hours_operation", "8h") | |
| equipment_loads = self.calculate_equipment_cooling_load( | |
| power=power, | |
| use_factor=use_factor, | |
| radiation_factor=radiation_factor, | |
| hours_operation=hours_operation, | |
| hour=hour | |
| ) | |
| loads["equipment_sensible"] = equipment_loads["sensible"] | |
| loads["equipment_latent"] = equipment_loads["latent"] | |
| # Calculate total loads | |
| loads["total_sensible"] = ( | |
| loads["walls"] + loads["roofs"] + loads["floors"] + | |
| loads["windows_conduction"] + loads["windows_solar"] + | |
| loads["doors"] + loads["infiltration_sensible"] + | |
| loads["ventilation_sensible"] + loads["people_sensible"] + | |
| loads["lights"] + loads["equipment_sensible"] | |
| ) | |
| loads["total_latent"] = ( | |
| loads["infiltration_latent"] + loads["ventilation_latent"] + | |
| loads["people_latent"] + loads["equipment_latent"] | |
| ) | |
| loads["total"] = loads["total_sensible"] + loads["total_latent"] | |
| # Store loads for this hour | |
| hourly_loads[hour] = loads | |
| return hourly_loads | |
| def calculate_design_cooling_load(self, hourly_loads: Dict[int, Dict[str, float]]) -> Dict[str, float]: | |
| """ | |
| Calculate design cooling load based on hourly loads. | |
| Args: | |
| hourly_loads: Dictionary with hourly cooling loads | |
| Returns: | |
| Dictionary with design cooling loads | |
| """ | |
| # Find hour with maximum total load | |
| max_hour = max(hourly_loads.keys(), key=lambda h: hourly_loads[h]["total"]) | |
| # Get loads for the design hour | |
| design_loads = hourly_loads[max_hour].copy() | |
| # Add design hour information | |
| design_loads["design_hour"] = max_hour | |
| return design_loads | |
| def calculate_cooling_load_summary(self, design_loads: Dict[str, float]) -> Dict[str, float]: | |
| """ | |
| Calculate cooling load summary. | |
| Args: | |
| design_loads: Dictionary with design cooling loads | |
| Returns: | |
| Dictionary with cooling load summary | |
| """ | |
| # Calculate envelope loads | |
| envelope_loads = ( | |
| design_loads["walls"] + design_loads["roofs"] + design_loads["floors"] + | |
| design_loads["windows_conduction"] + design_loads["windows_solar"] + | |
| design_loads["doors"] | |
| ) | |
| # Calculate ventilation and infiltration loads | |
| ventilation_loads = design_loads["ventilation_sensible"] + design_loads["ventilation_latent"] | |
| infiltration_loads = design_loads["infiltration_sensible"] + design_loads["infiltration_latent"] | |
| # Calculate internal loads | |
| internal_loads = ( | |
| design_loads["people_sensible"] + design_loads["people_latent"] + | |
| design_loads["lights"] + design_loads["equipment_sensible"] + design_loads["equipment_latent"] | |
| ) | |
| # Calculate sensible heat ratio | |
| shr = design_loads["total_sensible"] / design_loads["total"] if design_loads["total"] > 0 else 1.0 | |
| # Create summary | |
| summary = { | |
| "envelope_loads": envelope_loads, | |
| "ventilation_loads": ventilation_loads, | |
| "infiltration_loads": infiltration_loads, | |
| "internal_loads": internal_loads, | |
| "total_sensible": design_loads["total_sensible"], | |
| "total_latent": design_loads["total_latent"], | |
| "total": design_loads["total"], | |
| "sensible_heat_ratio": shr, | |
| "design_hour": design_loads["design_hour"] | |
| } | |
| return summary | |
| # Create a singleton instance | |
| cooling_load_calculator = CoolingLoadCalculator() | |
| # Example usage | |
| if __name__ == "__main__": | |
| # Create sample building components | |
| from data.building_components import Wall, Roof, Window, Door, Orientation, ComponentType | |
| # Create a sample wall | |
| wall = Wall( | |
| id="wall1", | |
| name="Exterior Wall", | |
| component_type=ComponentType.WALL, | |
| u_value=0.5, | |
| area=20.0, | |
| orientation=Orientation.SOUTH, | |
| wall_type="Brick", | |
| wall_group="B" | |
| ) | |
| # Create a sample roof | |
| roof = Roof( | |
| id="roof1", | |
| name="Flat Roof", | |
| component_type=ComponentType.ROOF, | |
| u_value=0.3, | |
| area=50.0, | |
| orientation=Orientation.HORIZONTAL, | |
| roof_type="Concrete", | |
| roof_group="C" | |
| ) | |
| # Create a sample window | |
| window = Window( | |
| id="window1", | |
| name="South Window", | |
| component_type=ComponentType.WINDOW, | |
| u_value=2.8, | |
| area=5.0, | |
| orientation=Orientation.SOUTH, | |
| shgc=0.7, | |
| vt=0.8, | |
| window_type="Double Glazed", | |
| glazing_layers=2, | |
| gas_fill="Air", | |
| low_e_coating=False | |
| ) | |
| # Define building components | |
| building_components = { | |
| "walls": [wall], | |
| "roofs": [roof], | |
| "windows": [window], | |
| "doors": [], | |
| "floors": [] | |
| } | |
| # Define conditions | |
| outdoor_conditions = { | |
| "temperature": 35.0, | |
| "relative_humidity": 50.0, | |
| "ground_temperature": 20.0, | |
| "month": "Jul", | |
| "latitude": "40N" | |
| } | |
| indoor_conditions = { | |
| "temperature": 24.0, | |
| "relative_humidity": 50.0 | |
| } | |
| # Define internal loads | |
| internal_loads = { | |
| "people": { | |
| "number": 3, | |
| "activity_level": "Seated/Resting", | |
| "hours_occupancy": "8h" | |
| }, | |
| "lights": { | |
| "power": 500.0, | |
| "use_factor": 0.9, | |
| "special_allowance": 0.1, | |
| "hours_operation": "8h" | |
| }, | |
| "equipment": { | |
| "power": 1000.0, | |
| "use_factor": 0.7, | |
| "radiation_factor": 0.7, | |
| "hours_operation": "8h" | |
| }, | |
| "infiltration": { | |
| "flow_rate": 0.05 | |
| }, | |
| "ventilation": { | |
| "flow_rate": 0.1 | |
| } | |
| } | |
| # Calculate hourly cooling loads | |
| hourly_loads = cooling_load_calculator.calculate_hourly_cooling_loads( | |
| building_components=building_components, | |
| outdoor_conditions=outdoor_conditions, | |
| indoor_conditions=indoor_conditions, | |
| internal_loads=internal_loads | |
| ) | |
| # Calculate design cooling load | |
| design_loads = cooling_load_calculator.calculate_design_cooling_load(hourly_loads) | |
| # Calculate cooling load summary | |
| summary = cooling_load_calculator.calculate_cooling_load_summary(design_loads) | |
| # Print results | |
| print("Cooling Load Summary:") | |
| print(f"Envelope Loads: {summary['envelope_loads']:.2f} W") | |
| print(f"Ventilation Loads: {summary['ventilation_loads']:.2f} W") | |
| print(f"Infiltration Loads: {summary['infiltration_loads']:.2f} W") | |
| print(f"Internal Loads: {summary['internal_loads']:.2f} W") | |
| print(f"Total Sensible: {summary['total_sensible']:.2f} W") | |
| print(f"Total Latent: {summary['total_latent']:.2f} W") | |
| print(f"Total: {summary['total']:.2f} W") | |
| print(f"Sensible Heat Ratio: {summary['sensible_heat_ratio']:.2f}") | |
| print(f"Design Hour: {summary['design_hour']}") | |