CoolFace
Apppublic

mabuseif/HVAC

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
calculation_methods.py447 linesDownload Raw Back to root
1"""2Calculation Method Interface for HVAC Load Calculator3 4This module defines the interface for calculation methods in the HVAC Load Calculator.5It provides a base class that all calculation methods should inherit from.6"""7 8from abc import ABC, abstractmethod9 10 11class CalculationMethod(ABC):12    """13    Abstract base class for HVAC load calculation methods.14    15    All calculation methods should inherit from this class and implement16    the required methods.17    """18    19    @property20    @abstractmethod21    def name(self):22        """23        Get the name of the calculation method.24        25        Returns:26            str: Name of the calculation method27        """28        pass29    30    @property31    @abstractmethod32    def description(self):33        """34        Get the description of the calculation method.35        36        Returns:37            str: Description of the calculation method38        """39        pass40    41    @property42    @abstractmethod43    def version(self):44        """45        Get the version of the calculation method.46        47        Returns:48            str: Version of the calculation method49        """50        pass51    52    @abstractmethod53    def calculate(self, input_data):54        """55        Perform the calculation.56        57        Args:58            input_data (dict): Input data for the calculation59            60        Returns:61            dict: Calculation results62        """63        pass64    65    @abstractmethod66    def get_input_schema(self):67        """68        Get the input schema for the calculation method.69        70        Returns:71            dict: JSON schema for input validation72        """73        pass74    75    @abstractmethod76    def get_output_schema(self):77        """78        Get the output schema for the calculation method.79        80        Returns:81            dict: JSON schema for output validation82        """83        pass84 85 86class ASHRAECoolingMethod(CalculationMethod):87    """88    ASHRAE method for cooling load calculation.89    """90    91    @property92    def name(self):93        return "ASHRAE Cooling Load Method"94    95    @property96    def description(self):97        return "Calculates cooling loads using the ASHRAE method for residential buildings."98    99    @property100    def version(self):101        return "1.0"102    103    def calculate(self, input_data):104        """105        Calculate cooling load using the ASHRAE method.106        107        Args:108            input_data (dict): Input data for the calculation109            110        Returns:111            dict: Calculation results112        """113        from cooling_load import CoolingLoadCalculator114        115        calculator = CoolingLoadCalculator()116        117        # Extract input data118        building_components = input_data.get('building_components', [])119        windows = input_data.get('windows', [])120        infiltration = input_data.get('infiltration', {})121        internal_gains = input_data.get('internal_gains', {})122        123        # Perform calculation124        results = calculator.calculate_total_cooling_load(125            building_components=building_components,126            windows=windows,127            infiltration=infiltration,128            internal_gains=internal_gains129        )130        131        return results132    133    def get_input_schema(self):134        """135        Get the input schema for the ASHRAE cooling load method.136        137        Returns:138            dict: JSON schema for input validation139        """140        return {141            "type": "object",142            "properties": {143                "building_components": {144                    "type": "array",145                    "items": {146                        "type": "object",147                        "properties": {148                            "name": {"type": "string"},149                            "area": {"type": "number", "minimum": 0},150                            "u_value": {"type": "number", "minimum": 0},151                            "temp_diff": {"type": "number"}152                        },153                        "required": ["area", "u_value", "temp_diff"]154                    }155                },156                "windows": {157                    "type": "array",158                    "items": {159                        "type": "object",160                        "properties": {161                            "name": {"type": "string"},162                            "area": {"type": "number", "minimum": 0},163                            "u_value": {"type": "number", "minimum": 0},164                            "orientation": {"type": "string", "enum": ["north", "east", "south", "west", "horizontal"]},165                            "glass_type": {"type": "string"},166                            "shading": {"type": "string"},167                            "shade_factor": {"type": "number", "minimum": 0, "maximum": 1},168                            "temp_diff": {"type": "number"}169                        },170                        "required": ["area", "u_value", "orientation", "temp_diff"]171                    }172                },173                "infiltration": {174                    "type": "object",175                    "properties": {176                        "volume": {"type": "number", "minimum": 0},177                        "air_changes": {"type": "number", "minimum": 0},178                        "temp_diff": {"type": "number"}179                    },180                    "required": ["volume", "air_changes", "temp_diff"]181                },182                "internal_gains": {183                    "type": "object",184                    "properties": {185                        "num_people": {"type": "integer", "minimum": 0},186                        "has_kitchen": {"type": "boolean"},187                        "equipment_watts": {"type": "number", "minimum": 0}188                    },189                    "required": ["num_people"]190                }191            },192            "required": ["building_components", "infiltration", "internal_gains"]193        }194    195    def get_output_schema(self):196        """197        Get the output schema for the ASHRAE cooling load method.198        199        Returns:200            dict: JSON schema for output validation201        """202        return {203            "type": "object",204            "properties": {205                "conduction_gain": {"type": "number"},206                "window_conduction_gain": {"type": "number"},207                "window_solar_gain": {"type": "number"},208                "infiltration_gain": {"type": "number"},209                "internal_gain": {"type": "number"},210                "sensible_load": {"type": "number"},211                "latent_load": {"type": "number"},212                "total_load": {"type": "number"}213            },214            "required": ["sensible_load", "latent_load", "total_load"]215        }216 217 218class ASHRAEHeatingMethod(CalculationMethod):219    """220    ASHRAE method for heating load calculation.221    """222    223    @property224    def name(self):225        return "ASHRAE Heating Load Method"226    227    @property228    def description(self):229        return "Calculates heating loads using the ASHRAE method for residential buildings."230    231    @property232    def version(self):233        return "1.0"234    235    def calculate(self, input_data):236        """237        Calculate heating load using the ASHRAE method.238        239        Args:240            input_data (dict): Input data for the calculation241            242        Returns:243            dict: Calculation results244        """245        from heating_load import HeatingLoadCalculator246        247        calculator = HeatingLoadCalculator()248        249        # Extract input data250        building_components = input_data.get('building_components', [])251        infiltration = input_data.get('infiltration', {})252        253        # Perform calculation254        results = calculator.calculate_total_heating_load(255            building_components=building_components,256            infiltration=infiltration257        )258        259        # Calculate annual heating requirement if location and occupancy data are provided260        if 'location' in input_data and 'occupancy_type' in input_data:261            location = input_data.get('location')262            occupancy_type = input_data.get('occupancy_type')263            base_temp = input_data.get('base_temp', 18)264            265            annual_results = calculator.calculate_annual_heating_requirement(266                results['total_load'],267                location,268                occupancy_type,269                base_temp270            )271            272            # Combine results273            results.update(annual_results)274        275        return results276    277    def get_input_schema(self):278        """279        Get the input schema for the ASHRAE heating load method.280        281        Returns:282            dict: JSON schema for input validation283        """284        return {285            "type": "object",286            "properties": {287                "building_components": {288                    "type": "array",289                    "items": {290                        "type": "object",291                        "properties": {292                            "name": {"type": "string"},293                            "area": {"type": "number", "minimum": 0},294                            "u_value": {"type": "number", "minimum": 0},295                            "temp_diff": {"type": "number", "minimum": 0}296                        },297                        "required": ["area", "u_value", "temp_diff"]298                    }299                },300                "infiltration": {301                    "type": "object",302                    "properties": {303                        "volume": {"type": "number", "minimum": 0},304                        "air_changes": {"type": "number", "minimum": 0},305                        "temp_diff": {"type": "number", "minimum": 0}306                    },307                    "required": ["volume", "air_changes", "temp_diff"]308                },309                "location": {"type": "string"},310                "occupancy_type": {"type": "string"},311                "base_temp": {"type": "number"}312            },313            "required": ["building_components", "infiltration"]314        }315    316    def get_output_schema(self):317        """318        Get the output schema for the ASHRAE heating load method.319        320        Returns:321            dict: JSON schema for output validation322        """323        return {324            "type": "object",325            "properties": {326                "component_losses": {327                    "type": "object",328                    "additionalProperties": {"type": "number"}329                },330                "total_conduction_loss": {"type": "number"},331                "infiltration_loss": {"type": "number"},332                "total_load": {"type": "number"},333                "heating_degree_days": {"type": "number"},334                "correction_factor": {"type": "number"},335                "annual_energy_kwh": {"type": "number"},336                "annual_energy_mj": {"type": "number"}337            },338            "required": ["total_load"]339        }340 341 342class CalculationMethodRegistry:343    """344    Registry for calculation methods.345    346    This class maintains a registry of available calculation methods347    and provides methods to access them.348    """349    350    def __init__(self):351        """Initialize the registry."""352        self._methods = {}353    354    def register_method(self, method_id, method_class):355        """356        Register a calculation method.357        358        Args:359            method_id (str): Unique identifier for the method360            method_class (type): Class implementing the CalculationMethod interface361            362        Returns:363            bool: True if registration was successful, False otherwise364        """365        if method_id in self._methods:366            return False367        368        if not issubclass(method_class, CalculationMethod):369            return False370        371        self._methods[method_id] = method_class372        return True373    374    def get_method(self, method_id):375        """376        Get a calculation method by ID.377        378        Args:379            method_id (str): Unique identifier for the method380            381        Returns:382            CalculationMethod: Instance of the calculation method, or None if not found383        """384        if method_id not in self._methods:385            return None386        387        return self._methods[method_id]()388    389    def get_available_methods(self):390        """391        Get a list of available calculation methods.392        393        Returns:394            list: List of dictionaries with method information395        """396        methods = []397        for method_id, method_class in self._methods.items():398            method = method_class()399            methods.append({400                'id': method_id,401                'name': method.name,402                'description': method.description,403                'version': method.version404            })405        406        return methods407 408 409# Create a global registry instance410registry = CalculationMethodRegistry()411 412# Register the built-in calculation methods413registry.register_method('ashrae_cooling', ASHRAECoolingMethod)414registry.register_method('ashrae_heating', ASHRAEHeatingMethod)415 416 417# Example of how to add a new calculation method418"""419class CustomCoolingMethod(CalculationMethod):420    @property421    def name(self):422        return "Custom Cooling Method"423    424    @property425    def description(self):426        return "A custom method for calculating cooling loads."427    428    @property429    def version(self):430        return "1.0"431    432    def calculate(self, input_data):433        # Custom calculation logic434        pass435    436    def get_input_schema(self):437        # Custom input schema438        pass439    440    def get_output_schema(self):441        # Custom output schema442        pass443 444# Register the custom method445registry.register_method('custom_cooling', CustomCoolingMethod)446"""447