Spaces:
Sleeping
Sleeping
| """ | |
| Reference data structures for HVAC Load Calculator. | |
| This module contains reference data for materials, construction types, and other HVAC-related data. | |
| """ | |
| from typing import Dict, List, Any, Optional | |
| import pandas as pd | |
| import json | |
| import os | |
| # Define paths | |
| DATA_DIR = os.path.dirname(os.path.abspath(__file__)) | |
| class ReferenceData: | |
| """Class for managing reference data for the HVAC calculator.""" | |
| def __init__(self): | |
| """Initialize reference data structures.""" | |
| self.materials = self._load_materials() | |
| self.wall_types = self._load_wall_types() | |
| self.roof_types = self._load_roof_types() | |
| self.floor_types = self._load_floor_types() | |
| self.window_types = self._load_window_types() | |
| self.door_types = self._load_door_types() | |
| self.internal_loads = self._load_internal_loads() | |
| def _load_materials(self) -> Dict[str, Dict[str, Any]]: | |
| """ | |
| Load material properties from reference data. | |
| Returns: | |
| Dictionary of material properties | |
| """ | |
| # This would typically load from a JSON or CSV file | |
| # For now, we'll define some common materials inline | |
| return { | |
| "brick": { | |
| "name": "Common Brick", | |
| "conductivity": 0.72, # W/(m·K) | |
| "density": 1920, # kg/m³ | |
| "specific_heat": 840, # J/(kg·K) | |
| "typical_thickness": 0.1 # m | |
| }, | |
| "concrete": { | |
| "name": "Concrete", | |
| "conductivity": 1.4, # W/(m·K) | |
| "density": 2300, # kg/m³ | |
| "specific_heat": 880, # J/(kg·K) | |
| "typical_thickness": 0.2 # m | |
| }, | |
| "mineral_wool": { | |
| "name": "Mineral Wool Insulation", | |
| "conductivity": 0.04, # W/(m·K) | |
| "density": 30, # kg/m³ | |
| "specific_heat": 840, # J/(kg·K) | |
| "typical_thickness": 0.1 # m | |
| }, | |
| "eps_insulation": { | |
| "name": "EPS Insulation", | |
| "conductivity": 0.035, # W/(m·K) | |
| "density": 25, # kg/m³ | |
| "specific_heat": 1400, # J/(kg·K) | |
| "typical_thickness": 0.1 # m | |
| }, | |
| "gypsum_board": { | |
| "name": "Gypsum Board", | |
| "conductivity": 0.25, # W/(m·K) | |
| "density": 900, # kg/m³ | |
| "specific_heat": 1000, # J/(kg·K) | |
| "typical_thickness": 0.0125 # m | |
| }, | |
| "wood": { | |
| "name": "Wood (Pine)", | |
| "conductivity": 0.14, # W/(m·K) | |
| "density": 500, # kg/m³ | |
| "specific_heat": 1600, # J/(kg·K) | |
| "typical_thickness": 0.025 # m | |
| }, | |
| "steel": { | |
| "name": "Steel", | |
| "conductivity": 50, # W/(m·K) | |
| "density": 7800, # kg/m³ | |
| "specific_heat": 450, # J/(kg·K) | |
| "typical_thickness": 0.005 # m | |
| }, | |
| "glass": { | |
| "name": "Glass", | |
| "conductivity": 1.0, # W/(m·K) | |
| "density": 2500, # kg/m³ | |
| "specific_heat": 840, # J/(kg·K) | |
| "typical_thickness": 0.006 # m | |
| }, | |
| "air_gap": { | |
| "name": "Air Gap", | |
| "conductivity": 0.024, # W/(m·K) | |
| "density": 1.2, # kg/m³ | |
| "specific_heat": 1000, # J/(kg·K) | |
| "typical_thickness": 0.025 # m | |
| }, | |
| "concrete_block": { | |
| "name": "Concrete Block", | |
| "conductivity": 0.51, # W/(m·K) | |
| "density": 1400, # kg/m³ | |
| "specific_heat": 1000, # J/(kg·K) | |
| "typical_thickness": 0.2 # m | |
| }, | |
| "asphalt_shingle": { | |
| "name": "Asphalt Shingle", | |
| "conductivity": 0.7, # W/(m·K) | |
| "density": 1100, # kg/m³ | |
| "specific_heat": 1260, # J/(kg·K) | |
| "typical_thickness": 0.006 # m | |
| }, | |
| "carpet": { | |
| "name": "Carpet", | |
| "conductivity": 0.06, # W/(m·K) | |
| "density": 200, # kg/m³ | |
| "specific_heat": 1300, # J/(kg·K) | |
| "typical_thickness": 0.01 # m | |
| }, | |
| "vinyl_flooring": { | |
| "name": "Vinyl Flooring", | |
| "conductivity": 0.17, # W/(m·K) | |
| "density": 1200, # kg/m³ | |
| "specific_heat": 1460, # J/(kg·K) | |
| "typical_thickness": 0.003 # m | |
| } | |
| } | |
| def _load_wall_types(self) -> Dict[str, Dict[str, Any]]: | |
| """ | |
| Load predefined wall types from reference data. | |
| Returns: | |
| Dictionary of wall types with properties | |
| """ | |
| return { | |
| "brick_veneer_wood_frame": { | |
| "name": "Brick veneer with wood frame", | |
| "description": "Brick veneer with wood frame, insulation, and gypsum board", | |
| "u_value": 0.35, # W/(m²·K) | |
| "wall_group": "B", # ASHRAE wall group | |
| "layers": [ | |
| {"material": "brick", "thickness": 0.1}, | |
| {"material": "air_gap", "thickness": 0.025}, | |
| {"material": "wood", "thickness": 0.038}, | |
| {"material": "mineral_wool", "thickness": 0.089}, | |
| {"material": "gypsum_board", "thickness": 0.0125} | |
| ] | |
| }, | |
| "concrete_block_insulated": { | |
| "name": "Concrete block with interior insulation", | |
| "description": "Concrete block wall with interior insulation and gypsum board", | |
| "u_value": 0.48, # W/(m²·K) | |
| "wall_group": "C", # ASHRAE wall group | |
| "layers": [ | |
| {"material": "concrete_block", "thickness": 0.2}, | |
| {"material": "eps_insulation", "thickness": 0.05}, | |
| {"material": "gypsum_board", "thickness": 0.0125} | |
| ] | |
| }, | |
| "precast_concrete_panel": { | |
| "name": "Precast concrete panel", | |
| "description": "Precast concrete panel with insulation and gypsum board", | |
| "u_value": 0.45, # W/(m²·K) | |
| "wall_group": "D", # ASHRAE wall group | |
| "layers": [ | |
| {"material": "concrete", "thickness": 0.1}, | |
| {"material": "eps_insulation", "thickness": 0.075}, | |
| {"material": "gypsum_board", "thickness": 0.0125} | |
| ] | |
| }, | |
| "metal_panel_insulated": { | |
| "name": "Metal panel with insulation", | |
| "description": "Metal panel wall with insulation and interior finish", | |
| "u_value": 0.4, # W/(m²·K) | |
| "wall_group": "E", # ASHRAE wall group | |
| "layers": [ | |
| {"material": "steel", "thickness": 0.001}, | |
| {"material": "mineral_wool", "thickness": 0.1}, | |
| {"material": "gypsum_board", "thickness": 0.0125} | |
| ] | |
| }, | |
| "wood_frame_wall": { | |
| "name": "Wood frame wall", | |
| "description": "Wood frame wall with insulation and gypsum board", | |
| "u_value": 0.3, # W/(m²·K) | |
| "wall_group": "A", # ASHRAE wall group | |
| "layers": [ | |
| {"material": "wood", "thickness": 0.019}, | |
| {"material": "air_gap", "thickness": 0.025}, | |
| {"material": "wood", "thickness": 0.038}, | |
| {"material": "mineral_wool", "thickness": 0.14}, | |
| {"material": "gypsum_board", "thickness": 0.0125} | |
| ] | |
| } | |
| } | |
| def _load_roof_types(self) -> Dict[str, Dict[str, Any]]: | |
| """ | |
| Load predefined roof types from reference data. | |
| Returns: | |
| Dictionary of roof types with properties | |
| """ | |
| return { | |
| "flat_roof_concrete": { | |
| "name": "Flat concrete roof with insulation", | |
| "description": "Flat concrete roof with insulation and ceiling", | |
| "u_value": 0.25, # W/(m²·K) | |
| "roof_group": "B", # ASHRAE roof group | |
| "layers": [ | |
| {"material": "concrete", "thickness": 0.15}, | |
| {"material": "eps_insulation", "thickness": 0.15}, | |
| {"material": "gypsum_board", "thickness": 0.0125} | |
| ] | |
| }, | |
| "pitched_roof_wood": { | |
| "name": "Pitched wood roof with insulation", | |
| "description": "Pitched wood roof with insulation and ceiling", | |
| "u_value": 0.2, # W/(m²·K) | |
| "roof_group": "A", # ASHRAE roof group | |
| "layers": [ | |
| {"material": "asphalt_shingle", "thickness": 0.006}, | |
| {"material": "wood", "thickness": 0.019}, | |
| {"material": "air_gap", "thickness": 0.025}, | |
| {"material": "mineral_wool", "thickness": 0.2}, | |
| {"material": "gypsum_board", "thickness": 0.0125} | |
| ] | |
| }, | |
| "metal_deck_roof": { | |
| "name": "Metal deck roof with insulation", | |
| "description": "Metal deck roof with insulation and ceiling", | |
| "u_value": 0.3, # W/(m²·K) | |
| "roof_group": "C", # ASHRAE roof group | |
| "layers": [ | |
| {"material": "steel", "thickness": 0.001}, | |
| {"material": "eps_insulation", "thickness": 0.1}, | |
| {"material": "air_gap", "thickness": 0.1}, | |
| {"material": "gypsum_board", "thickness": 0.0125} | |
| ] | |
| } | |
| } | |
| def _load_floor_types(self) -> Dict[str, Dict[str, Any]]: | |
| """ | |
| Load predefined floor types from reference data. | |
| Returns: | |
| Dictionary of floor types with properties | |
| """ | |
| return { | |
| "concrete_slab_on_grade": { | |
| "name": "Concrete slab on grade", | |
| "description": "Concrete slab on grade with insulation", | |
| "u_value": 0.3, # W/(m²·K) | |
| "is_ground_contact": True, | |
| "layers": [ | |
| {"material": "concrete", "thickness": 0.1}, | |
| {"material": "eps_insulation", "thickness": 0.05} | |
| ] | |
| }, | |
| "suspended_concrete_floor": { | |
| "name": "Suspended concrete floor", | |
| "description": "Suspended concrete floor with insulation", | |
| "u_value": 0.25, # W/(m²·K) | |
| "is_ground_contact": False, | |
| "layers": [ | |
| {"material": "concrete", "thickness": 0.15}, | |
| {"material": "eps_insulation", "thickness": 0.1}, | |
| {"material": "gypsum_board", "thickness": 0.0125} | |
| ] | |
| }, | |
| "wood_joist_floor": { | |
| "name": "Wood joist floor", | |
| "description": "Wood joist floor with insulation", | |
| "u_value": 0.22, # W/(m²·K) | |
| "is_ground_contact": False, | |
| "layers": [ | |
| {"material": "wood", "thickness": 0.025}, | |
| {"material": "air_gap", "thickness": 0.15}, | |
| {"material": "mineral_wool", "thickness": 0.15}, | |
| {"material": "gypsum_board", "thickness": 0.0125} | |
| ] | |
| }, | |
| "carpet_on_concrete": { | |
| "name": "Carpet on concrete", | |
| "description": "Carpet on concrete slab with insulation", | |
| "u_value": 0.28, # W/(m²·K) | |
| "is_ground_contact": True, | |
| "layers": [ | |
| {"material": "carpet", "thickness": 0.01}, | |
| {"material": "concrete", "thickness": 0.1}, | |
| {"material": "eps_insulation", "thickness": 0.05} | |
| ] | |
| } | |
| } | |
| def _load_window_types(self) -> Dict[str, Dict[str, Any]]: | |
| """ | |
| Load predefined window types from reference data. | |
| Returns: | |
| Dictionary of window types with properties | |
| """ | |
| return { | |
| "single_glazed": { | |
| "name": "Single glazed window", | |
| "description": "Single glazed window with aluminum frame", | |
| "u_value": 5.8, # W/(m²·K) | |
| "shgc": 0.86, # Solar Heat Gain Coefficient | |
| "vt": 0.9, # Visible Transmittance | |
| "glazing_layers": 1, | |
| "gas_fill": "Air", | |
| "frame_type": "Aluminum", | |
| "low_e_coating": False | |
| }, | |
| "double_glazed_air": { | |
| "name": "Double glazed window with air", | |
| "description": "Double glazed window with air gap and aluminum frame", | |
| "u_value": 2.8, # W/(m²·K) | |
| "shgc": 0.76, # Solar Heat Gain Coefficient | |
| "vt": 0.81, # Visible Transmittance | |
| "glazing_layers": 2, | |
| "gas_fill": "Air", | |
| "frame_type": "Aluminum", | |
| "low_e_coating": False | |
| }, | |
| "double_glazed_argon_low_e": { | |
| "name": "Double glazed window with argon and low-e coating", | |
| "description": "Double glazed window with argon fill, low-e coating, and vinyl frame", | |
| "u_value": 1.4, # W/(m²·K) | |
| "shgc": 0.4, # Solar Heat Gain Coefficient | |
| "vt": 0.7, # Visible Transmittance | |
| "glazing_layers": 2, | |
| "gas_fill": "Argon", | |
| "frame_type": "Vinyl", | |
| "low_e_coating": True | |
| }, | |
| "triple_glazed_argon_low_e": { | |
| "name": "Triple glazed window with argon and low-e coating", | |
| "description": "Triple glazed window with argon fill, low-e coating, and vinyl frame", | |
| "u_value": 0.8, # W/(m²·K) | |
| "shgc": 0.3, # Solar Heat Gain Coefficient | |
| "vt": 0.6, # Visible Transmittance | |
| "glazing_layers": 3, | |
| "gas_fill": "Argon", | |
| "frame_type": "Vinyl", | |
| "low_e_coating": True | |
| } | |
| } | |
| def _load_door_types(self) -> Dict[str, Dict[str, Any]]: | |
| """ | |
| Load predefined door types from reference data. | |
| Returns: | |
| Dictionary of door types with properties | |
| """ | |
| return { | |
| "solid_wood_door": { | |
| "name": "Solid wood door", | |
| "description": "Solid wood door with no glazing", | |
| "u_value": 2.2, # W/(m²·K) | |
| "glazing_percentage": 0, | |
| "door_type": "Solid" | |
| }, | |
| "insulated_steel_door": { | |
| "name": "Insulated steel door", | |
| "description": "Insulated steel door with no glazing", | |
| "u_value": 1.2, # W/(m²·K) | |
| "glazing_percentage": 0, | |
| "door_type": "Solid" | |
| }, | |
| "partially_glazed_door": { | |
| "name": "Partially glazed door", | |
| "description": "Wood door with 25% glazing", | |
| "u_value": 2.8, # W/(m²·K) | |
| "glazing_percentage": 25, | |
| "door_type": "Partially glazed", | |
| "shgc": 0.76, # Solar Heat Gain Coefficient for the glazed portion | |
| "vt": 0.81 # Visible Transmittance for the glazed portion | |
| }, | |
| "glass_door": { | |
| "name": "Glass door", | |
| "description": "Full glass door with aluminum frame", | |
| "u_value": 3.8, # W/(m²·K) | |
| "glazing_percentage": 90, | |
| "door_type": "Glass", | |
| "shgc": 0.76, # Solar Heat Gain Coefficient | |
| "vt": 0.81 # Visible Transmittance | |
| } | |
| } | |
| def _load_internal_loads(self) -> Dict[str, Dict[str, Any]]: | |
| """ | |
| Load internal load data from reference data. | |
| Returns: | |
| Dictionary of internal load types with properties | |
| """ | |
| return { | |
| "occupancy": { | |
| "seated_very_light_work": { | |
| "name": "Seated, very light work", | |
| "sensible_heat": 70, # W per person | |
| "latent_heat": 45 # W per person | |
| }, | |
| "office_work_standing": { | |
| "name": "Office work, standing", | |
| "sensible_heat": 75, # W per person | |
| "latent_heat": 55 # W per person | |
| }, | |
| "light_physical_work": { | |
| "name": "Light physical work", | |
| "sensible_heat": 80, # W per person | |
| "latent_heat": 140 # W per person | |
| }, | |
| "medium_physical_work": { | |
| "name": "Medium physical work", | |
| "sensible_heat": 90, # W per person | |
| "latent_heat": 185 # W per person | |
| }, | |
| "heavy_physical_work": { | |
| "name": "Heavy physical work", | |
| "sensible_heat": 170, # W per person | |
| "latent_heat": 255 # W per person | |
| } | |
| }, | |
| "lighting": { | |
| "led": { | |
| "name": "LED", | |
| "power_density_range": [5, 10], # W/m² | |
| "heat_to_space": 0.9 # Fraction of power that becomes heat | |
| }, | |
| "fluorescent": { | |
| "name": "Fluorescent", | |
| "power_density_range": [10, 15], # W/m² | |
| "heat_to_space": 0.95 # Fraction of power that becomes heat | |
| }, | |
| "incandescent": { | |
| "name": "Incandescent", | |
| "power_density_range": [15, 25], # W/m² | |
| "heat_to_space": 0.98 # Fraction of power that becomes heat | |
| }, | |
| "halogen": { | |
| "name": "Halogen", | |
| "power_density_range": [12, 20], # W/m² | |
| "heat_to_space": 0.97 # Fraction of power that becomes heat | |
| } | |
| }, | |
| "equipment": { | |
| "office_equipment": { | |
| "name": "Office Equipment", | |
| "power_density_range": [10, 20], # W/m² | |
| "sensible_fraction": 0.9, | |
| "latent_fraction": 0.1 | |
| }, | |
| "kitchen_equipment": { | |
| "name": "Kitchen Equipment", | |
| "power_density_range": [30, 200], # W/m² | |
| "sensible_fraction": 0.6, | |
| "latent_fraction": 0.4 | |
| }, | |
| "manufacturing_equipment": { | |
| "name": "Manufacturing Equipment", | |
| "power_density_range": [20, 100], # W/m² | |
| "sensible_fraction": 0.8, | |
| "latent_fraction": 0.2 | |
| } | |
| } | |
| } | |
| def get_material(self, material_id: str) -> Optional[Dict[str, Any]]: | |
| """ | |
| Get material properties by ID. | |
| Args: | |
| material_id: Material identifier | |
| Returns: | |
| Dictionary of material properties or None if not found | |
| """ | |
| return self.materials.get(material_id) | |
| def get_wall_type(self, wall_type_id: str) -> Optional[Dict[str, Any]]: | |
| """ | |
| Get wall type properties by ID. | |
| Args: | |
| wall_type_id: Wall type identifier | |
| Returns: | |
| Dictionary of wall type properties or None if not found | |
| """ | |
| return self.wall_types.get(wall_type_id) | |
| def get_roof_type(self, roof_type_id: str) -> Optional[Dict[str, Any]]: | |
| """ | |
| Get roof type properties by ID. | |
| Args: | |
| roof_type_id: Roof type identifier | |
| Returns: | |
| Dictionary of roof type properties or None if not found | |
| """ | |
| return self.roof_types.get(roof_type_id) | |
| def get_floor_type(self, floor_type_id: str) -> Optional[Dict[str, Any]]: | |
| """ | |
| Get floor type properties by ID. | |
| Args: | |
| floor_type_id: Floor type identifier | |
| Returns: | |
| Dictionary of floor type properties or None if not found | |
| """ | |
| return self.floor_types.get(floor_type_id) | |
| def get_window_type(self, window_type_id: str) -> Optional[Dict[str, Any]]: | |
| """ | |
| Get window type properties by ID. | |
| Args: | |
| window_type_id: Window type identifier | |
| Returns: | |
| Dictionary of window type properties or None if not found | |
| """ | |
| return self.window_types.get(window_type_id) | |
| def get_door_type(self, door_type_id: str) -> Optional[Dict[str, Any]]: | |
| """ | |
| Get door type properties by ID. | |
| Args: | |
| door_type_id: Door type identifier | |
| Returns: | |
| Dictionary of door type properties or None if not found | |
| """ | |
| return self.door_types.get(door_type_id) | |
| def get_internal_load(self, load_type: str, load_id: str) -> Optional[Dict[str, Any]]: | |
| """ | |
| Get internal load properties by type and ID. | |
| Args: | |
| load_type: Type of internal load (occupancy, lighting, equipment) | |
| load_id: Internal load identifier | |
| Returns: | |
| Dictionary of internal load properties or None if not found | |
| """ | |
| if load_type in self.internal_loads: | |
| return self.internal_loads[load_type].get(load_id) | |
| return None | |
| def export_to_json(self, file_path: str) -> None: | |
| """ | |
| Export all reference data to a JSON file. | |
| Args: | |
| file_path: Path to the output JSON file | |
| """ | |
| data = { | |
| "materials": self.materials, | |
| "wall_types": self.wall_types, | |
| "roof_types": self.roof_types, | |
| "floor_types": self.floor_types, | |
| "window_types": self.window_types, | |
| "door_types": self.door_types, | |
| "internal_loads": self.internal_loads | |
| } | |
| with open(file_path, 'w') as f: | |
| json.dump(data, f, indent=4) | |
| def from_json(cls, file_path: str) -> 'ReferenceData': | |
| """ | |
| Create a ReferenceData instance from a JSON file. | |
| Args: | |
| file_path: Path to the input JSON file | |
| Returns: | |
| A new ReferenceData instance | |
| """ | |
| with open(file_path, 'r') as f: | |
| data = json.load(f) | |
| ref_data = cls() | |
| ref_data.materials = data.get("materials", ref_data.materials) | |
| ref_data.wall_types = data.get("wall_types", ref_data.wall_types) | |
| ref_data.roof_types = data.get("roof_types", ref_data.roof_types) | |
| ref_data.floor_types = data.get("floor_types", ref_data.floor_types) | |
| ref_data.window_types = data.get("window_types", ref_data.window_types) | |
| ref_data.door_types = data.get("door_types", ref_data.door_types) | |
| ref_data.internal_loads = data.get("internal_loads", ref_data.internal_loads) | |
| return ref_data | |
| # Create a singleton instance | |
| reference_data = ReferenceData() | |
| # Export reference data to JSON if needed | |
| if __name__ == "__main__": | |
| reference_data.export_to_json(os.path.join(DATA_DIR, "reference_data.json")) | |