diff --git a/bim2sim/plugins/PluginEnergyPlus/bim2sim_energyplus/examples/e1_simple_project_energyplus.py b/bim2sim/plugins/PluginEnergyPlus/bim2sim_energyplus/examples/e1_simple_project_energyplus.py index d3f58bc580..69c42907b2 100644 --- a/bim2sim/plugins/PluginEnergyPlus/bim2sim_energyplus/examples/e1_simple_project_energyplus.py +++ b/bim2sim/plugins/PluginEnergyPlus/bim2sim_energyplus/examples/e1_simple_project_energyplus.py @@ -38,7 +38,7 @@ def run_example_1(): 'test/resources/weather_files/DEU_NW_Aachen.105010_TMYx.epw') # Set the install path to your EnergyPlus installation according to your # system requirements - # project.sim_settings.ep_install_path = 'C://EnergyPlusV9-4-0/' + project.sim_settings.ep_install_path = 'C://EnergyPlusV9-4-0/' # run annual simulation for EnergyPlus project.sim_settings.run_full_simulation = True diff --git a/bim2sim/plugins/PluginEnergyPlus/bim2sim_energyplus/examples/e2_complex_project_energyplus.py b/bim2sim/plugins/PluginEnergyPlus/bim2sim_energyplus/examples/e2_complex_project_energyplus.py index 234f0f8e8c..4bc508d8a3 100644 --- a/bim2sim/plugins/PluginEnergyPlus/bim2sim_energyplus/examples/e2_complex_project_energyplus.py +++ b/bim2sim/plugins/PluginEnergyPlus/bim2sim_energyplus/examples/e2_complex_project_energyplus.py @@ -34,7 +34,7 @@ def run_example_complex_building_energyplus(): # Set the install path to your EnergyPlus installation according to your # system requirements - # project.sim_settings.ep_install_path = 'C://EnergyPlusV9-4-0/' + project.sim_settings.ep_install_path = Path('C://EnergyPlusV9-4-0/') # combine spaces to thermal zones based on their usage # use cooling diff --git a/bim2sim/plugins/PluginEnergyPlus/bim2sim_energyplus/sim_settings.py b/bim2sim/plugins/PluginEnergyPlus/bim2sim_energyplus/sim_settings.py index c178e65a30..d10c66ad09 100644 --- a/bim2sim/plugins/PluginEnergyPlus/bim2sim_energyplus/sim_settings.py +++ b/bim2sim/plugins/PluginEnergyPlus/bim2sim_energyplus/sim_settings.py @@ -56,7 +56,9 @@ class EnergyPlusSimSettings(BuildingSimSettings): for_frontend=True, any_string=True ) - ep_install_path = PathSetting( + # ep_install_path is instantiated without validation using BaseModel.model_construct + # to enable linux path as default value for CI pipeline + ep_install_path = PathSetting.model_construct( value=Path('/usr/local/EnergyPlus-9-4-0/'), description='Choose EnergyPlus Installation Path', for_frontend=False, diff --git a/bim2sim/plugins/PluginOpenFOAM/bim2sim_openfoam/examples/e2_complex_project_bps_comfort_journal.py b/bim2sim/plugins/PluginOpenFOAM/bim2sim_openfoam/examples/e2_complex_project_bps_comfort_journal.py index 224d02d709..4d59ccfae2 100644 --- a/bim2sim/plugins/PluginOpenFOAM/bim2sim_openfoam/examples/e2_complex_project_bps_comfort_journal.py +++ b/bim2sim/plugins/PluginOpenFOAM/bim2sim_openfoam/examples/e2_complex_project_bps_comfort_journal.py @@ -45,7 +45,7 @@ def run_example_complex_building_openfoam(): # overwrite existing layer structures and materials based on templates project.sim_settings.layers_and_materials = LOD.low # specify templates for the layer and material overwrite - project.sim_settings.construction_class_walls = 'heavy' + project.sim_settings.construction_class_walls = 'iwu_heavy' project.sim_settings.construction_class_windows = \ 'Alu- oder Stahlfenster, Waermeschutzverglasung, zweifach' diff --git a/bim2sim/plugins/PluginTEASER/bim2sim_teaser/examples/e1_simple_project_bps_teaser.py b/bim2sim/plugins/PluginTEASER/bim2sim_teaser/examples/e1_simple_project_bps_teaser.py index 14335681e4..83cfeb5a32 100644 --- a/bim2sim/plugins/PluginTEASER/bim2sim_teaser/examples/e1_simple_project_bps_teaser.py +++ b/bim2sim/plugins/PluginTEASER/bim2sim_teaser/examples/e1_simple_project_bps_teaser.py @@ -5,6 +5,7 @@ from bim2sim import Project, run_project, ConsoleDecisionHandler from bim2sim.utilities.types import IFCDomain, LOD, ZoningCriteria from bim2sim.plugins.PluginTEASER.bim2sim_teaser import PluginTEASER +from bim2sim.utilities.common_functions import download_library def run_example_simple_building_teaser(): """Run a building performance simulation with the TEASER backend. @@ -51,6 +52,17 @@ def run_example_simple_building_teaser(): 'test/resources/weather_files/DEU_NW_Aachen.105010_TMYx.mos') # Run a simulation directly with dymola after model creation project.sim_settings.dymola_simulation = True + # Make sure that AixLib modelica library exist on machine by cloning it and + # setting the path of it as a sim_setting + repo_url = "https://github.com/RWTH-EBC/AixLib.git" + branch_name = "main" + repo_name = "AixLib" + path_aixlib = Path(r"D:\01_Git\bim2sim\local\library_AixLib") + # path_aixlib = ( + # Path(bim2sim.__file__).parent.parent / "local" / f"library_{repo_name}") + download_library(repo_url, branch_name, path_aixlib) + project.sim_settings.path_aixlib = path_aixlib / repo_name / 'package.mo' + project.sim_settings.create_plots = True # Select results to output: project.sim_settings.sim_results = [ diff --git a/bim2sim/plugins/PluginTEASER/bim2sim_teaser/examples/e4_visualize_zone_binding.py b/bim2sim/plugins/PluginTEASER/bim2sim_teaser/examples/e4_visualize_zone_binding.py index 81d884d909..bc2bfe62bb 100644 --- a/bim2sim/plugins/PluginTEASER/bim2sim_teaser/examples/e4_visualize_zone_binding.py +++ b/bim2sim/plugins/PluginTEASER/bim2sim_teaser/examples/e4_visualize_zone_binding.py @@ -47,21 +47,7 @@ def visualize_zoning_of_complex_building(): bps.EnrichUseConditions, bps.CombineThermalZones, ] - # We get the use conditions and usages from predefined templates, look at - # example e2 to get more information how this works - project.sim_settings.prj_use_conditions = (Path( - bim2sim.__file__).parent.parent / - "test/resources/arch/custom_usages/" - "UseConditionsFM_ARC_DigitalHub.json") - project.sim_settings.prj_custom_usages = (Path( - bim2sim.__file__).parent.parent / - "test/resources/arch/custom_usages/" - "customUsagesFM_ARC_DigitalHub_with_SB89.json") - - # set weather file data - project.sim_settings.weather_file_path = ( - Path(bim2sim.__file__).parent.parent / - 'test/resources/weather_files/DEU_NW_Aachen.105010_TMYx.mos') + # Run a simulation directly with dymola after model creation # Run the project with the ConsoleDecisionHandler. This allows interactive space_boundary_genenerator = 'Other' @@ -72,8 +58,26 @@ def visualize_zoning_of_complex_building(): # resulting visualizations. for zoning_criteria in list(ZoningCriteria): + # set the simm settings project.sim_settings.zoning_criteria = zoning_criteria + # We get the use conditions and usages from predefined templates, look at + # example e2 to get more information how this works + project.sim_settings.prj_use_conditions = (Path( + bim2sim.__file__).parent.parent / + "test/resources/arch/custom_usages/" + "UseConditionsFM_ARC_DigitalHub.json") + project.sim_settings.prj_custom_usages = (Path( + bim2sim.__file__).parent.parent / + "test/resources/arch/custom_usages/" + "customUsagesFM_ARC_DigitalHub_with_SB89.json") + + # set weather file data + project.sim_settings.weather_file_path = ( + Path(bim2sim.__file__).parent.parent / + 'test/resources/weather_files/DEU_NW_Aachen.105010_TMYx.mos') + + handler = DebugDecisionHandler(answers) # run the project for each criteria selection diff --git a/bim2sim/plugins/PluginTEASER/bim2sim_teaser/examples/e5_serialize_teaser_prj.py b/bim2sim/plugins/PluginTEASER/bim2sim_teaser/examples/e5_serialize_teaser_prj.py index 05a830ad09..382fc9b749 100644 --- a/bim2sim/plugins/PluginTEASER/bim2sim_teaser/examples/e5_serialize_teaser_prj.py +++ b/bim2sim/plugins/PluginTEASER/bim2sim_teaser/examples/e5_serialize_teaser_prj.py @@ -47,7 +47,7 @@ def run_serialize_teaser_project_example(): # overwrite existing layer structures and materials based on templates project.sim_settings.layers_and_materials = LOD.low # specify templates for the layer and material overwrite - project.sim_settings.construction_class_walls = 'heavy' + project.sim_settings.construction_class_walls = 'iwu_heavy' project.sim_settings.construction_class_windows = \ 'Alu- oder Stahlfenster, Waermeschutzverglasung, zweifach' diff --git a/bim2sim/plugins/PluginTEASER/bim2sim_teaser/examples/e6_load_serialized_teaser_prj.py b/bim2sim/plugins/PluginTEASER/bim2sim_teaser/examples/e6_load_serialized_teaser_prj.py index 2c127c6f4d..da83797e84 100644 --- a/bim2sim/plugins/PluginTEASER/bim2sim_teaser/examples/e6_load_serialized_teaser_prj.py +++ b/bim2sim/plugins/PluginTEASER/bim2sim_teaser/examples/e6_load_serialized_teaser_prj.py @@ -1,9 +1,8 @@ from pathlib import Path from teaser.project import Project -from bim2sim_teaser.task import CreateTEASER from e5_serialize_teaser_prj import run_serialize_teaser_project_example - +import bim2sim.plugins.PluginTEASER.bim2sim_teaser.task as teaser_task def load_serialized_teaser_project(): """This function demonstrates different loading options of TEASER""" @@ -61,7 +60,7 @@ def load_serialized_teaser_project(): # As calc_all_buildings() recalculates the heating loads and thus the max # ideal heater PI-control values, we might reset those as they can be too # low and lead to too low zone temperatures - orig_heat_loads, orig_cool_loads = CreateTEASER.overwrite_heatloads( + orig_heat_loads, orig_cool_loads = teaser_task.CreateTEASER.overwrite_heatloads( prj.buildings) prj.export_aixlib( diff --git a/bim2sim/plugins/PluginTEASER/test/integration/test_teaser.py b/bim2sim/plugins/PluginTEASER/test/integration/test_teaser.py index b02e70cd3a..09adf4d594 100644 --- a/bim2sim/plugins/PluginTEASER/test/integration/test_teaser.py +++ b/bim2sim/plugins/PluginTEASER/test/integration/test_teaser.py @@ -175,7 +175,7 @@ def test_run_kitfzkhaus_spaces_full_layers_full(self): project.sim_settings.zoningCriteria = ZoningCriteria.individual_spaces answers = (True, 'solid_brick_h', True, 'hardwood', True, 'Concrete_DK', True, 'Light_Concrete_DK', - 'heavy', 1, 'Door', 1, 'Brick', 'solid_brick_h', 'EnEv', + 'iwu_heavy', 1, 'Door', 1, 'Brick', 'solid_brick_h', 'EnEv', *(1,) * 8) handler = DebugDecisionHandler(answers) for decision, answer in handler.decision_answer_mapping(project.run()): @@ -193,7 +193,7 @@ def test_run_kitoffice_spaces_full_layers_full(self): answers = ('Glas', True, 'glas_generic', 500, 1.5, 0.2, True, 'air_layer', 'sandstone', True, 'lime_sandstone_1', True, 'aluminium', 0.1, True, 'Concrete_DK', 2015, - "heavy", 1, 'Beton', 'Light_Concrete_DK', 1, 'Door', 1, + "iwu_heavy", 1, 'Beton', 'Light_Concrete_DK', 1, 'Door', 1, 'Beton', 1, 'Beton', 1, 'fenster', 'Glas1995_2015Aluoder' 'StahlfensterWaermeschutzverglasungzweifach', 1, 'Door', 1, 'Beton', 1, 'Beton', *(1,) * 8) diff --git a/bim2sim/sim_settings.py b/bim2sim/sim_settings.py index 9c5a5a67e8..fbbdc16177 100644 --- a/bim2sim/sim_settings.py +++ b/bim2sim/sim_settings.py @@ -8,6 +8,7 @@ import os.path from typing import Union, Optional, List import sys +from pathlib import Path from pydantic import BaseModel, Field, model_validator, field_validator, FilePath, DirectoryPath from pydantic_core import PydanticCustomError from typing_extensions import Self @@ -204,6 +205,25 @@ def check_content(self): class PathSetting(Setting): value: Optional[Union[DirectoryPath, FilePath]] + def __set__(self, bound_simulation_settings, value): + """Creates a new attribute with the name and value of the simulation setting instance, + stored in sim_settings. This makes it easier to access the setting's payload. + + Example: + + sim_settings = {e.g. BuildingSimSettings} + ... + example_setting_name = {bool}True + manager {SettingsManager} + 'example_setting_name' = {BooleanSetting}(name='ahu_heating_overwrite',value=True, ...) + ... + ... + """ + setting = bound_simulation_settings.manager[self.name] + # assign the value without triggering pydantic's + # assignment validation (allows non-existing paths, etc.). + object.__setattr__(setting, "value", value) + class BooleanSetting(Setting): value: Optional[bool] @@ -238,7 +258,12 @@ def load_default_settings(self): for setting in self.manager.values(): default = self.manager.defaults[setting.name] - setting.value = default + # No default set of setting values for PathSettings, since defaults + if isinstance(setting, PathSetting): + object.__setattr__(setting, "value", default) + else: + setting.value = default + def update_from_config(self, config): """Updates the simulation settings specification from the config @@ -1000,35 +1025,35 @@ def __init__(self): any_string=True ) ahu_heating_overwrite = BooleanSetting( - value=None, + value=False, description="Choose if the central AHU should provide heating. " ) ahu_cooling_overwrite = BooleanSetting( - value=None, + value=False, description="Choose if the central AHU should provide cooling." ) ahu_dehumidification_overwrite = BooleanSetting( - value=None, + value=False, description="Choose if the central AHU should provide " "dehumidification." ) ahu_humidification_overwrite = BooleanSetting( - value=None, + value=False, description="Choose if the central AHU should provide humidification." "otherwise this has no effect. " ) ahu_heat_recovery_overwrite = BooleanSetting( - value=None, + value=False, description="Choose if the central AHU should zuse heat recovery." ) ahu_heat_recovery_efficiency_overwrite = NumberSetting( - value=None, + value=0.8, min_value=0.5, max_value=0.99, description="Choose the heat recovery efficiency of the central AHU." ) use_constant_infiltration_overwrite = BooleanSetting( - value=None, + value=False, description="If only constant base infiltration should be used and no " "dynamic ventilation through e.g. windows." ) diff --git a/pyproject.toml b/pyproject.toml index 54de65aaf5..6185329eff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,8 @@ classifiers = [ ] dependencies = [ "pydantic==2.11.7", - "ifcopenshell==0.7.0.240627", + #"ifcopenshell==0.7.0.240627", + "ifcopenshell==0.7.10", "docopt==0.6.2", "numpy==1.26.0", "pandas==2.1.3",