def test_building_geometry(ureg, res_folder):
    expected_file_path = os.path.dirname(__file__) / Path("./expected_results/idf_expected_geometry.idf")
    site_vertices_file = os.path.dirname(__file__) / Path("./testfixture/SiteVertices.csv")
    main_bldg_fid = 2
    glazing_ratio = 0.16
    infiltration_rate = 0.71 * ureg.ACH
    flat_vertices = cesarp.geometry.csv_input_parser.read_sitevertices_from_csv(site_vertices_file, __sitevertices_labels)
    site_bldgs = vertices_basics.convert_flat_site_vertices_to_per_bldg_footprint(flat_vertices)
    bldg_geometry = GeometryBuilder(main_bldg_fid, site_bldgs, glazing_ratio)
    bldg_shape = bldg_geometry.get_bldg_shape_detailed()

    idf_file_path = res_folder / Path("idf_geometry.idf")
    aux_files_handler = RelativeAuxiliaryFilesHandler()
    aux_files_handler.set_destination(res_folder, "profiles")
    my_idf_writer = CesarIDFWriter(idf_file_path, ureg, aux_files_handler)

    bldg_constr = __get_constr_for(main_bldg_fid, 1930, ureg)
    bldg_constr.infiltration_rate = infiltration_rate # overwrite because the default has higher precision than what was written with the matlab version
    idf = IDF(str(idf_file_path))
    my_idf_writer.add_building_geometry(idf, bldg_shape, ConstructionIDFWritingHandler(bldg_constr, None, ureg))
    idf.save()
    assert are_files_equal(idf_file_path, expected_file_path, ignore_line_nrs=[1])

    # test wrong infiltration rate unit
    bldg_constr.infiltration_rate = 3 * ureg.m ** 3 / ureg.sec
    with pytest.raises(Exception):
        my_idf_writer.add_building_geometry(idf, bldg_shape, ConstructionIDFWritingHandler(bldg_constr, None, ureg))
示例#2
0
    def test_save_copy(self):
        """Test savecopy with a new filename.

        IDF.savecopy(fname) doesn't change the filename. The next save should
        save with the original name.

        Fails if on a following save, the copy is changed.

        """
        idf = IDF(self.startfile)
        idf.savecopy(self.copyfile)
        setversion(idf, "7.5")
        idf.save()
        idf2 = IDF(self.copyfile)

        result = getversion(idf2)
        expected = "7.3"  # unchanged since version was changed after savecopy

        assert result == expected

        idf3 = IDF(self.startfile)
        result = getversion(idf3)
        expected = "7.5"  # should be changed in the original file

        assert result == expected
示例#3
0
    def test_save_copy(self):
        """Test savecopy with a new filename.

        IDF.savecopy(fname) doesn't change the filename. The next save should
        save with the original name.
        
        Fails if on a following save, the copy is changed.

        """
        idf = IDF(self.startfile)
        idf.savecopy(self.copyfile)
        setversion(idf, '7.5')
        idf.save()
        idf2 = IDF(self.copyfile)

        result = getversion(idf2)
        expected = '7.3'  # unchanged since version was changed after savecopy
        
        assert result == expected
        
        idf3 = IDF(self.startfile)
        result = getversion(idf3)
        expected = '7.5' # should be changed in the original file

        assert result == expected
示例#4
0
def auto_generate_from_template(cop, number, base_idf_dir, final_idf_dir,
                                idd_file_dir):
    IDF.setiddname(idd_file_dir)
    idf = IDF(base_idf_dir)
    idf.idfobjects['ChillerHeaterPerformance:Electric:EIR'][
        0].Reference_Cooling_Mode_COP = cop
    idf.idfobjects['CentralHeatPumpSystem'][
        0].Number_of_Chiller_Heater_Modules_1 = number
    idf.save(final_idf_dir)
示例#5
0
def auto_generate_from_template(peak_heating_w, peak_cooling_w, heating_cop,
                                cooling_cop, n_borehole, soil_k, base_idf_dir,
                                final_idf_dir, idd_file_dir):

    IDF.setiddname(idd_file_dir)
    idf = IDF(base_idf_dir)

    idf = auto_update_LP_flow_rates(idf, peak_heating_w, peak_cooling_w)
    idf = auto_update_ghex_system(idf, peak_heating_w, peak_cooling_w,
                                  heating_cop, cooling_cop, n_borehole, soil_k)

    idf.save(final_idf_dir)
def test_simulations_basic_settings(ureg, res_folder):
    expected_file_path = os.path.dirname(__file__) / Path(
        "./expected_results/idf_expected_simulation_basics.idf")

    os.makedirs(res_folder, exist_ok=True)
    aux_files_handler = RelativeAuxiliaryFilesHandler()
    aux_files_handler.set_destination(res_folder, "profiles")

    idf_file_path = res_folder / Path("idf_simulation_basics.idf")
    my_idf_writer = CesarIDFWriter(idf_file_path, ureg, aux_files_handler)
    idf = IDF(str(idf_file_path))
    my_idf_writer.add_basic_simulation_settings(idf, SiteGroundTemperatureFactory(ureg).get_ground_temperatures())
    idf.save()
    assert are_files_equal(idf_file_path, expected_file_path, ignore_line_nrs=[1]) == True
示例#7
0
def test_save():
    """
    Test the IDF.save() function using a filehandle to avoid external effects.
    """
    file_text = "Material,TestMaterial,  !- Name"
    idf = IDF(StringIO(file_text))
    # test save with just a filehandle
    file_handle = StringIO()
    idf.save(file_handle)
    expected = "TestMaterial"
    file_handle.seek(0)
    result = file_handle.read()
    # minimal test that TestMaterial is being written to the file handle
    assert expected in result
示例#8
0
def test_save():
    """
    Test the IDF.save() function using a filehandle to avoid external effects.
    """
    file_text = "Material,TestMaterial,  !- Name"
    idf = IDF(StringIO(file_text))
    # test save with just a filehandle
    file_handle = StringIO()
    idf.save(file_handle)
    expected = "TestMaterial"
    file_handle.seek(0)
    result = file_handle.read()
    # minimal test that TestMaterial is being written to the file handle
    assert expected in result
示例#9
0
    def test_save(self):
        """Test save with a changed version number.

        Fails if the version number has not been changed.

        """
        idf = IDF(self.startfile)
        setversion(idf, "7.4")
        idf.save()
        idf2 = IDF(self.startfile)
        assert idf is not idf2  # be sure we don't just have an in-memory copy

        result = getversion(idf2)
        expected = "7.4"

        assert result == expected
示例#10
0
 def test_save(self):
     """Test save with a changed version number.
     
     Fails if the version number has not been changed.
     
     """
     idf = IDF(self.startfile)
     setversion(idf, '7.4')
     idf.save()
     idf2 = IDF(self.startfile)
     assert idf is not idf2  # be sure we don't just have an in-memory copy
     
     result = getversion(idf2)
     expected = '7.4'
     
     assert result == expected
示例#11
0
 def test_lineendings(self):
     """Test lineendings are set correctly on each platform."""
     idf = IDF(self.startfile)
     idf.save(lineendings="windows")
     with open(self.startfile, "rb") as sf:
         txt = sf.read()
     print(txt.count(b"\r\n"))
     lines = txt.splitlines()
     numlines = len(lines)
     assert numlines == txt.count(b"\r\n") + 1  # no CR on last line
     idf.save(lineendings="unix")
     with open(self.origfile, "rb") as of:
         txt = of.read()
     lines = txt.splitlines()
     numlines = len(lines)
     assert numlines == txt.count(b"\n") + 1  # no CR on last line
示例#12
0
 def test_lineendings(self):
     """Test lineendings are set correctly on each platform.
     """
     idf = IDF(self.startfile)
     idf.save(lineendings='windows')
     with open(self.startfile, 'rb') as sf:
         txt = sf.read()
     print(txt.count(b'\r\n'))
     lines = txt.splitlines()
     numlines = len(lines)
     assert numlines == txt.count(b'\r\n') + 1 # no CR on last line
     idf.save(lineendings='unix')
     with open(self.origfile, 'rb') as of:
         txt = of.read()
     lines = txt.splitlines()
     numlines = len(lines)
     assert numlines == txt.count(b'\n') + 1 # no CR on last line
示例#13
0
    def test_save_as(self):
        """Test saveas with a changed filename.
        
        IDF.saveas(fname) changes the filename. The next save should save with 
        new name.
        
        Fails if the filename isn't changed on the file with the new name.
        """
        idf = IDF(self.startfile)
        idf.saveas(self.saveasfile)  # sets the new filename
        setversion(idf, '7.4')
        idf.save()  # should also save with the new filename
        idf2 = IDF(self.saveasfile)
        
        result = getversion(idf2)
        expected = '7.4'

        assert result == expected
示例#14
0
    def test_save_as(self):
        """Test saveas with a changed filename.

        IDF.saveas(fname) changes the filename. The next save should save with
        new name.

        Fails if the filename isn't changed on the file with the new name.
        """
        idf = IDF(self.startfile)
        idf.saveas(self.saveasfile)  # sets the new filename
        setversion(idf, "7.4")
        idf.save()  # should also save with the new filename
        idf2 = IDF(self.saveasfile)

        result = getversion(idf2)
        expected = "7.4"

        assert result == expected
示例#15
0
    def write_bldg_model(self, bldg_model: BuildingModel) -> None:
        """
        :param bldg_model: Building model to write to IDF
        :type bldg_model: BuildingModel
        """
        idf = IDF(str(self.idf_file_path))
        self.add_basic_simulation_settings(idf, bldg_model.site.site_ground_temperatures)
        constr_handler = ConstructionIDFWritingHandler(bldg_model.bldg_construction, bldg_model.neighbours_construction_props, self.unit_registry)
        self.add_building_geometry(idf, bldg_model.bldg_shape, constr_handler)

        self.add_neighbours(idf, bldg_model.neighbours, constr_handler)
        self.add_building_properties(
            idf,
            bldg_model.bldg_operation_mapping,
            bldg_model.bldg_construction.installation_characteristics,
            bldg_model.bldg_construction.infiltration_rate,
            self.__handle_profile_file(bldg_model.bldg_construction.infiltration_profile),
            bldg_model.bldg_construction.window_constr.shade,
        )
        idf = self.add_output_settings(idf)
        idf.save(filename=str(self.idf_file_path))
示例#16
0
    def test_save_with_lineendings_and_encodings(self):
        """
        Test the IDF.save() function with combinations of encodings and line
        endings.

        """
        idf = IDF(self.startfile)
        lineendings = ("windows", "unix", "default")
        encodings = ("ascii", "latin-1", "UTF-8")

        for le, enc in product(lineendings, encodings):
            idf.save(lineendings=le, encoding=enc)

            with open(self.startfile, "rb") as sf:
                result = sf.read()
            if le == "windows":
                assert b"\r\n" in result
            elif le == "unix":
                assert b"\r\n" not in result
            elif le == "default":
                assert os.linesep.encode(enc) in result
示例#17
0
    def test_save_with_lineendings_and_encodings(self):
        """
        Test the IDF.save() function with combinations of encodings and line 
        endings.
    
        """
        idf = IDF(self.startfile)
        lineendings = ('windows', 'unix', 'default')
        encodings = ('ascii', 'latin-1', 'UTF-8')

        for le, enc in product(lineendings, encodings):
            idf.save(lineendings=le, encoding=enc)

            with open(self.startfile, 'rb') as sf:
                result = sf.read()
            if le == 'windows':
                assert b'\r\n' in result
            elif le == 'unix':
                assert b'\r\n' not in result
            elif le == 'default':
                assert os.linesep.encode(enc) in result
示例#18
0
 def test_save_with_lineendings_and_encodings(self):
     """
     Test the IDF.save() function with combinations of encodings and line 
     endings.
 
     """
     idf = IDF(self.startfile)
     lineendings = ('windows', 'unix', 'default')
     encodings = ('ascii', 'latin-1', 'UTF-8')
 
     for le, enc in product(lineendings, encodings):
         idf.save(lineendings=le, encoding=enc)
         
         with open(self.startfile, 'rb') as sf:
             result = sf.read()
         if le == 'windows':
             assert b'\r\n' in result
         elif le == 'unix':
             assert b'\r\n' not in result
         elif le == 'default':
             assert os.linesep.encode(enc) in result
示例#19
0
def test_save_with_lineendings_and_encodings():
    """
    Test the IDF.save() function with combinations of encodings and line
    endings.

    """
    file_text = "Material,TestMaterial,  !- Name"
    idf = IDF(StringIO(file_text))
    lineendings = ('windows', 'unix', 'default')
    encodings = ('ascii', 'latin-1', 'UTF-8')

    for le, enc in product(lineendings, encodings):
        file_handle = StringIO()
        idf.save(file_handle, encoding=enc, lineendings=le)
        file_handle.seek(0)
        result = file_handle.read().encode(enc)
        if le == 'windows':
            assert b'\r\n' in result
        elif le == 'unix':
            assert b'\r\n' not in result
        elif le == 'default':
            assert os.linesep.encode(enc) in result
示例#20
0
def test_save_with_lineendings_and_encodings():
    """
    Test the IDF.save() function with combinations of encodings and line
    endings.

    """
    file_text = "Material,TestMaterial,  !- Name"
    idf = IDF(StringIO(file_text))
    lineendings = ('windows', 'unix', 'default')
    encodings = ('ascii', 'latin-1', 'UTF-8')

    for le, enc in product(lineendings, encodings):
        file_handle = StringIO()
        idf.save(file_handle, encoding=enc, lineendings=le)
        file_handle.seek(0)
        result = file_handle.read().encode(enc)
        if le == 'windows':
            assert b'\r\n' in result
        elif le == 'unix':
            assert b'\r\n' not in result
        elif le == 'default':
            assert os.linesep.encode(enc) in result
示例#21
0
def test_save_with_lineendings_and_encodings():
    """
    Test the IDF.save() function with combinations of encodings and line
    endings.

    """
    file_text = "Material,TestMaterial,  !- Name"
    idf = IDF(StringIO(file_text))
    lineendings = ("windows", "unix", "default")
    encodings = ("ascii", "latin-1", "UTF-8")

    for le, enc in product(lineendings, encodings):
        file_handle = StringIO()
        idf.save(file_handle, encoding=enc, lineendings=le)
        file_handle.seek(0)
        result = file_handle.read().encode(enc)
        if le == "windows":
            assert b"\r\n" in result
        elif le == "unix":
            assert b"\r\n" not in result
        elif le == "default":
            assert os.linesep.encode(enc) in result
def test_neighbour_shading_objects(ureg, res_folder):
    expected_file_path = os.path.dirname(__file__) / Path("./expected_results/idf_expected_neighbours.idf")
    site_vertices_file = os.path.dirname(__file__) / Path("./testfixture/SiteVertices_minimized.csv")
    main_bldg_fid = 2
    glazing_ratio = 0.16

    flat_vertices = cesarp.geometry.csv_input_parser.read_sitevertices_from_csv(site_vertices_file, __sitevertices_labels)
    site_bldgs = vertices_basics.convert_flat_site_vertices_to_per_bldg_footprint(flat_vertices)
    bldg_geometry = GeometryBuilder(main_bldg_fid, site_bldgs, glazing_ratio)
    neighbours = bldg_geometry.get_bldg_shape_of_neighbours()

    idf_file_path = res_folder / Path("idf_neighbours.idf")

    aux_files_handler = RelativeAuxiliaryFilesHandler()
    aux_files_handler.set_destination(res_folder, "profiles")
    my_idf_writer = CesarIDFWriter(idf_file_path, ureg, aux_files_handler)

    win_glass_constr = __get_constr_for(main_bldg_fid, 1930, ureg).window_constr.glass
    neigh_constr = __get_shading_constr(win_glass_constr, ureg)
    idf = IDF(str(idf_file_path))
    my_idf_writer.add_neighbours(idf, neighbours, ConstructionIDFWritingHandler(None, neigh_constr, ureg))
    idf.save()
    assert are_files_equal(idf_file_path, expected_file_path, ignore_line_nrs=[1])
    def __init__(self, config):

        self.directory = os.path.dirname(
            os.path.dirname(os.path.realpath(__file__)))

        self.idf_name = 'eplusModel'

        # directory where csv of each episode are saved
        if 'res_directory' in config:
            self.res_directory = config['res_directory']
        else:
            self.res_directory = ''

        print("File directory: ", self.directory)
        # EnergyPlus weather file

        if "idf_directory_name" in config:
            self.idf_directory_name = config["idf_directory_name"]
        else:
            self.idf_directory_name = 'StorageTank_Model'

        if "weather_file" in config:
            self.weather_file = config["weather_file"]
        else:
            self.weather_file = 'weatherFiles/ITA_TORINO-CASELLE_IGDG'

        # EnergyPlus TimeStep as specified in .idf file
        if "ep_time_step" in config:
            self.ep_time_step = config["ep_time_step"]
        else:
            self.ep_time_step = 12

        # Number of days of a simulation as specified in the RunPeriod object of the .idf file
        if "simulation_days" in config:
            self.simulation_days = config["simulation_days"]
        else:
            self.simulation_days = 90

        if "reward_multiplier" in config:
            self.reward_multiplier = config["reward_multiplier"]
        else:
            self.reward_multiplier = 10

        # Tank properties
        if "tank_volume" in config:
            self.tank_volume = config["tank_volume"]
        else:
            self.tank_volume = 10

        if "tank_heat_gain_coefficient" in config:
            self.tank_heat_gain_coefficient = config[
                "tank_heat_gain_coefficient"]
        else:
            self.tank_heat_gain_coefficient = 12

        # Minimum Temperature allowed for water in the thermal storage tank.
        if "tank_min_temperature" in config:
            self.tank_min_temperature = config["tank_min_temperature"]
        else:
            self.tank_min_temperature = 10

        # Maximum Temperature allowed for water in the thermal storage tank.
        if "tank_max_temperature" in config:
            self.tank_max_temperature = config["tank_max_temperature"]
        else:
            self.tank_max_temperature = 18

        if "begin_month" in config:
            self.begin_month = config["begin_month"]
        else:
            self.begin_month = 6

        if "end_month" in config:
            self.end_month = config["end_month"]
        else:
            self.end_month = 8

        if "begin_day_of_month" in config:
            self.begin_day_of_month = config["begin_day_of_month"]
        else:
            self.begin_day_of_month = 1

        if "end_day_of_month" in config:
            self.end_day_of_month = config["end_day_of_month"]
        else:
            self.end_day_of_month = 29

        if "day_shift" in config:
            self.day_shift = config["day_shift"]
        else:
            self.day_shift = 152

        if "pv_nominal_power" in config:
            self.pv_nominal_power = config["pv_nominal_power"]
        else:
            self.pv_nominal_power = 1500

        if "battery_size" in config:
            self.battery_size = config["battery_size"]
        else:
            self.battery_size = 2400

        if "horizon" in config:
            self.horizon = config["horizon"]
        else:
            self.horizon = 24

        self.price_schedule_name = config["price_schedule_name"]

        idd_file = 'supportFiles\\Energy+9-2-0.idd'
        file_name = 'EplusModels\\' + self.idf_directory_name + '\\eplusModel.idf'

        IDF.setiddname(idd_file)
        idf_file = IDF(file_name)

        runperiod = idf_file.idfobjects['RUNPERIOD'][0]
        runperiod.Begin_Month = self.begin_month
        runperiod.Begin_Day_of_Month = self.begin_day_of_month
        runperiod.End_Month = self.end_month
        runperiod.End_Day_of_Month = self.end_day_of_month

        storage_tank = idf_file.idfobjects[
            'ThermalStorage:ChilledWater:Mixed'][0]
        storage_tank.Tank_Volume = self.tank_volume
        storage_tank.Heat_Gain_Coefficient_from_Ambient_Temperature = self.tank_heat_gain_coefficient

        idf_file.save('eplusModels\\' + self.idf_directory_name +
                      '\\eplusModel.idf',
                      encoding='UTF-8')

        # EnergyPlus path in the local machine
        self.eplus_path = 'C:/EnergyPlusV9-2-0/'

        # Number of steps per day
        self.DAYSTEPS = int(24 * self.ep_time_step)

        # Total number of steps
        self.MAXSTEPS = int(self.simulation_days * self.DAYSTEPS)

        # Time difference between each step in seconds
        self.deltaT = (60 / self.ep_time_step) * 60

        # Outputs given by EnergyPlus, defined in variables.cfg
        self.outputs = []

        # Inputs expected by EnergyPlus, defined in variables.cfg
        self.inputs = []

        # Current step of the simulation
        self.kStep = 0
        self.hStep = 0

        # Instance of EnergyPlus simulation
        self.ep = None

        # state can be all the inputs required to make a control decision
        # getting all the outputs coming from EnergyPlus for the time being
        with open(self.directory +
                  '\\supportFiles\\state_space_variables.json') as json_file:
            buildings_states = json.load(json_file)

        with open(self.directory +
                  '\\supportFiles\\state_rescaling_table.json') as json_file:
            rescaling_table = json.load(json_file)

        self.state_types, self.state_names, self.state_mins, self.state_maxs = \
            get_state_variables(data=buildings_states,
                                rescaling_table=rescaling_table)

        self.state_mins = np.array(self.state_mins)
        self.state_maxs = np.array(self.state_maxs)

        self.observation_space = spaces.Box(np.repeat(0, len(self.state_mins)),
                                            np.repeat(0, len(self.state_maxs)),
                                            dtype=np.float32)

        self.action_space = spaces.Box(low=-1,
                                       high=1,
                                       shape=(1, ),
                                       dtype=np.float32)

        self.episode_number = 1

        # Price of the electricity schedule
        self.electricity_price_schedule = pd.read_csv(
            self.directory + '\\supportFiles\\' + self.price_schedule_name,
            header=None)
        self.cooling_load_predictions = pd.read_csv(
            self.directory +
            '\\supportFiles\\prediction-cooling_load_perfect.csv')
        self.electricity_price_predictions = pd.read_csv(
            self.directory +
            '\\supportFiles\\prediction-electricity_price_perfect.csv')
        self.pv_power_generation_predictions = pd.read_csv(
            self.directory +
            '\\supportFiles\\prediction-pv_power_generation_perfect.csv')
        self.max_price = self.electricity_price_schedule.values.max()
        self.min_price = self.electricity_price_schedule.values.min()

        # PV & Battery Initialization
        self.pv = PV(nominal_power=self.pv_nominal_power,
                     tilt_angle=33,
                     azimuth=180 - 64)

        self.battery = Battery(max_capacity=self.battery_size, rte=0.96)

        self.eta_ac_dc = 0.9

        self.SOC = 1

        # Lists for adding variables to eplus output (.csv)
        self.action_list = []
        self.reward_list = []
        self.price_list = []
        self.tank_soc_list = []
        self.battery_soc_list = []
        self.incidence_list = []
        self.zenith_list = []
        self.efficiency_list = []
        self.pv_power_generation_list = []
        self.pv_energy_production_list = []
        self.pv_energy_to_building_list = []
        self.pv_energy_to_grid_list = []
        self.pv_energy_to_battery_list = []
        self.grid_energy_list = []
        self.grid_energy_to_building_list = []
        self.grid_energy_to_battery_list = []
        self.battery_energy_to_building_list = []
        self.p_cool_list = []
        self.building_energy_consumption_list = []
        self.savings_list = []
        self.grid_list = []
        self.energy_cost_from_grid_list = []
        self.energy_cost_to_grid_list = []

        self.episode_electricity_cost = 0
示例#24
0
idf_notemptyfile = IDF(fhandle) # initialize the IDF object with the file handle

idf_notemptyfile.printidf()

# <markdowncell>

# Aha !
# 
# Now let us give it a file name

# <codecell>

# - give it a file name
idf_notemptyfile.idfname = "notemptyfile.idf"
# - Save it to the disk
idf_notemptyfile.save()

# <markdowncell>

# Let us confirm that the file was saved to disk

# <codecell>

txt = open("notemptyfile.idf", 'r').read()# read the file from the disk
print(txt)

# <markdowncell>

# Yup ! that file was saved. Let us delete it since we were just playing

# <codecell>
示例#25
0
def auto_generate_from_template(peak_heating_w, peak_cooling_w, base_idf_dir,
                                final_idf_dir, idd_file_dir):
    IDF.setiddname(idd_file_dir)
    idf = IDF(base_idf_dir)
    idf = auto_update_LP_flow_rates(idf, peak_heating_w, peak_cooling_w)
    idf.save(final_idf_dir)
示例#26
0
 def __create_empty_idf(self):
     idfstring = idf_strings.version.format(get_eplus_version(ep_config=self._cfg))
     fhandle = StringIO(idfstring)
     idf = IDF(fhandle)
     idf.save(str(self.idf_file_path))
示例#27
0
archivoIDD = sys.argv[1]
archivoIDF = sys.argv[2]
rutaMateriales = sys.argv[3]
IDF.setiddname(archivoIDD)
idf = IDF(archivoIDF)
materiales = idf.idfobjects['MATERIAL']

modificaciones = []

for argumento in sys.argv[4:]:
    modificaciones.append(argumento)

archivoMateriales = open(rutaMateriales, "r")
listaMateriales = archivoMateriales.read().splitlines()
i = 0
for linea in listaMateriales:
    for material in materiales:
        if (str(material.Name) == linea):
            material.Thickness = modificaciones[i]
            material.Conductivity = modificaciones[i + 1]
            material.Density = modificaciones[i + 2]
            material.Specific_Heat = modificaciones[i + 3]
            material.Thermal_Absorptance = modificaciones[i + 4]
            material.Solar_Absorptance = modificaciones[i + 5]
            material.Visible_Absorptance = modificaciones[i + 6]
    i += 7

archivoMateriales.close()
idf.save()
示例#28
0
def createrectshading(idd_filename, idf_filename, base_surface, shading_str,
                      start_point, end_point, depths):
    ##########################################
    # loading base surface data from idf file
    ##########################################

    # check if IDD has been already set
    try:
        IDF.setiddname(idd_filename)
    except modeleditor.IDDAlreadySetError as e:
        pass

    # load idf file into idf collection
    idf_collection = IDF(idf_filename)

    # find the named base_surface in idf collection
    walls = idf_collection.idfobjects['BuildingSurface:Detailed'.upper()]
    for wall in walls:
        if wall.Name == base_surface:
            # named base_surface is now contained in wall
            break
    else:
        # named base_surface was not found in idf file
        print('epnurbs.createrectshading: unable to find the base surface',
              base_surface, 'in', idf_filename)
        return

    ##############################################################################
    # feet of perpendiculars from the start and the end point to the base surface
    ##############################################################################

    # getting the found base_surface's coordinates
    coord = wall.coords
    ulc = coord[0]
    blc = coord[1]
    brc = coord[2]

    # find the base_surface's plane normal and normalize it
    N = crossproduct( (blc[0]-ulc[0], blc[1]-ulc[1], blc[2]-ulc[2]), \
                      (brc[0]-ulc[0], brc[1]-ulc[1], brc[2]-ulc[2]) )
    N = normalize(N)

    # calculate feet of perpendiculars
    start_foot = foot(start_point, ulc, N)
    end_foot = foot(end_point, ulc, N)

    # steps between the start and the end point
    num = len(depths)
    step = [(end_foot[0] - start_foot[0]) / num,
            (end_foot[1] - start_foot[1]) / num,
            (end_foot[2] - start_foot[2]) / num]

    ########################################################################
    # create string of idf definitions for a sequence of shading rectangles
    ########################################################################
    idf_total_shading_def = ""
    for i in range(num):
        if depths[i] > 0.01:
            # two base_surface vertices are start_foot + i*step and start_foot + (i+1)*step
            # the other two vertices are at depth[i] distance from the base surface
            v1 = [
                start_foot[0] + i * step[0], start_foot[1] + i * step[1],
                start_foot[2] + i * step[2]
            ]
            v2 = [
                v1[0] + depths[i] * N[0], v1[1] + depths[i] * N[1],
                v1[2] + depths[i] * N[2]
            ]

            v4 = [
                start_foot[0] + (i + 1) * step[0],
                start_foot[1] + (i + 1) * step[1],
                start_foot[2] + (i + 1) * step[2]
            ]
            v3 = [
                v4[0] + depths[i] * N[0], v4[1] + depths[i] * N[1],
                v4[2] + depths[i] * N[2]
            ]

            vertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format(
                v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], v3[0], v3[1], v3[2],
                v4[0], v4[1], v4[2])
            countervertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format(
                v4[0], v4[1], v4[2], v3[0], v3[1], v3[2], v2[0], v2[1], v2[2],
                v1[0], v1[1], v1[2])
            single_shading_def = shading_str.replace('<IDX>', str(i)).replace(
                '<BASESURFACE>',
                base_surface).replace('<VERTICES>', vertices_str).replace(
                    '<COUNTERVERTICES>', countervertices_str)
            idf_total_shading_def = idf_total_shading_def + single_shading_def
        else:
            # we do not have a shading rectangle if it is not deep enough
            pass

    # create idf shading objects from the string containing shading definitions
    from io import StringIO
    idf_shading = IDF(StringIO(idf_total_shading_def))

    # copy idf shading objects to the existing idf file
    shadings = idf_shading.idfobjects["SHADING:ZONE:DETAILED"]
    for shading in shadings:
        idf_collection.copyidfobject(shading)

    ###############################
    # at the end, save the changes
    ###############################
    idf_collection.save()
示例#29
0
# <markdowncell>

# There are 3 fruits in the list.

# <headingcell level=2>

# Saving an idf file

# <markdowncell>

# This is easy:

# <codecell>

idf1.save()

# <markdowncell>

# If you'd like to do a "Save as..." use this:

# <codecell>

idf1.saveas("something.idf")

# <headingcell level=2>

# Working with E+ objects

# <markdowncell>
示例#30
0
    fhandle)  # initialize the IDF object with the file handle

idf_notemptyfile.printidf()

# <markdowncell>

# Aha !
#
# Now let us give it a file name

# <codecell>

# - give it a file name
idf_notemptyfile.idfname = "notemptyfile.idf"
# - Save it to the disk
idf_notemptyfile.save()

# <markdowncell>

# Let us confirm that the file was saved to disk

# <codecell>

txt = open("notemptyfile.idf", "r").read()  # read the file from the disk
print(txt)

# <markdowncell>

# Yup ! that file was saved. Let us delete it since we were just playing

# <codecell>
def createnurbsshading(idd_filename, idf_filename, base_surface, shading_str, ctrl_points, evaluated_points=20):
    ##########################################
    # loading base surface data from idf file 
    ##########################################
    
    # check if IDD has been already set
    try:
        IDF.setiddname(idd_filename)
    except modeleditor.IDDAlreadySetError as e:
        pass

    # load idf file into idf collection
    idf_collection = IDF(idf_filename)

    # find the named base_surface in idf collection
    walls = idf_collection.idfobjects['BuildingSurface:Detailed'.upper()]
    for wall in walls:
        if wall.Name == base_surface:
            # named base_surface is now contained in wall
            break
    else:
        # named base_surface was not found in idf file
        print('epnurbs.createshading: unable to find the base surface', base_surface, 'in', idf_filename)
        return

    #################################
    # calculating NURBS curve points
    #################################
    from geomdl import NURBS
    from geomdl import utilities

    curve = NURBS.Curve()

    # 1/delta corresponds to the number of trapezoids used in approximation of NURBS shading
    curve.delta = 1/evaluated_points
    curve.degree = 3

    # add weight 1 to each control point
    # unless it has been already weighted
    for cpt in ctrl_points:
        if len(cpt)<4:
            cpt.append(1.0)

    # sets curve control points
    curve.set_ctrlpts(ctrl_points)

    # sets curve knot vector
    curve.knotvector = utilities.generate_knot_vector(curve.degree, len(curve.ctrlpts))

    # evaluates curve points
    curve.evaluate()

    # make a local copy of evaluated curve points
    crv_points = curve.curvepts

    ###################################################################################
    # feet of perpendiculars from the remaining NURBS curve points to the base surface
    ###################################################################################

    # getting the found base_surface's coordinates
    coord = wall.coords
    ulc = coord[0]
    blc = coord[1]
    brc = coord[2]

    # find the base_surface's plane normal and normalize it
    N = crossproduct( (blc[0]-ulc[0], blc[1]-ulc[1], blc[2]-ulc[2]), \
                      (brc[0]-ulc[0], brc[1]-ulc[1], brc[2]-ulc[2]) )
    N = normalize(N)

    # calculate feet of perpendiculars
    feet_points = [foot(crv_points[i], ulc, N) for i in range(len(crv_points))]

    #################################################################################
    # create string of idf definitions for trapezoids that approximate NURBS shading
    #################################################################################
    idf_total_shading_def = ""
    for i in range(1, len(crv_points)):
        # the width of a trapezoid must be at least 0.01
        if distance(crv_points[i-1], crv_points[i])>=0.01 and \
           distance(feet_points[i-1], feet_points[i])>=0.01:
            # are trapezoid arms at least 0.01 or do we have a triangle?
            if distance(crv_points[i-1], feet_points[i-1])>=0.01:
                if distance(crv_points[i], feet_points[i])>=0.01:
                    # both arms are at least 0.01, so we have a trapezoid
                    vertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format(
                                   feet_points[i-1][0], feet_points[i-1][1], feet_points[i-1][2],
                                   crv_points[i-1][0],  crv_points[i-1][1],  crv_points[i-1][2],
                                   crv_points[i][0],    crv_points[i][1],    crv_points[i][2],
                                   feet_points[i][0],   feet_points[i][1],   feet_points[i][2])
                    countervertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format(
                                          feet_points[i][0],   feet_points[i][1],   feet_points[i][2],
                                          crv_points[i][0],    crv_points[i][1],    crv_points[i][2],
                                          crv_points[i-1][0],  crv_points[i-1][1],  crv_points[i-1][2],
                                          feet_points[i-1][0], feet_points[i-1][1], feet_points[i-1][2])
                    single_shading_def = shading_str.replace('<IDX>', str(i)).replace('<BASESURFACE>', base_surface).replace('<VERTICES>', vertices_str).replace('<COUNTERVERTICES>', countervertices_str)
                    idf_total_shading_def = idf_total_shading_def + single_shading_def
                else: 
                    # arm i is less than 0.01, so we have a triangle
                    vertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format(
                                   feet_points[i-1][0], feet_points[i-1][1], feet_points[i-1][2],
                                   crv_points[i-1][0],  crv_points[i-1][1],  crv_points[i-1][2],
                                   feet_points[i][0],   feet_points[i][1],   feet_points[i][2])
                    countervertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format(
                                          feet_points[i][0],   feet_points[i][1],   feet_points[i][2], 
                                          crv_points[i-1][0],  crv_points[i-1][1],  crv_points[i-1][2],
                                          feet_points[i-1][0], feet_points[i-1][1], feet_points[i-1][2])               
                    single_shading_def = shading_str.replace('<IDX>', str(i)).replace('<BASESURFACE>', base_surface).replace('<VERTICES>', vertices_str).replace('<COUNTERVERTICES>', countervertices_str)
                    idf_total_shading_def = idf_total_shading_def + single_shading_def
            else:
                # arm i-1 is less than 0.01, but do we still have a triangle?
                if distance(crv_points[i], feet_points[i])>=0.01:
                    # we have a triangle
                    vertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format(
                                   feet_points[i-1][0], feet_points[i-1][1], feet_points[i-1][2],
                                   crv_points[i][0],    crv_points[i][1],    crv_points[i][2],
                                   feet_points[i][0],   feet_points[i][1],   feet_points[i][2])
                    countervertices_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format(
                                          feet_points[i][0],   feet_points[i][1],   feet_points[i][2],
                                          crv_points[i][0],    crv_points[i][1],    crv_points[i][2],
                                          feet_points[i-1][0], feet_points[i-1][1], feet_points[i-1][2])              
                    single_shading_def = shading_str.replace('<IDX>', str(i)).replace('<BASESURFACE>', base_surface).replace('<VERTICES>', vertices_str).replace('<COUNTERVERTICES>', countervertices_str)
                    idf_total_shading_def = idf_total_shading_def + single_shading_def
                else:
                    # we do not have a shading element in this case
                    pass
    
    # create idf shading objects from the string containing shading definitions   
    from io import StringIO
    idf_shading = IDF(StringIO(idf_total_shading_def))

    # copy idf shading objects to the existing idf file
    shadings = idf_shading.idfobjects["SHADING:ZONE:DETAILED"]
    for shading in shadings:
        idf_collection.copyidfobject(shading)

    ###############################
    # at the end, save the changes
    ###############################
    idf_collection.save()
示例#32
0
def GeoGen(sheet):
    num_of_zones = sheet.Range("A7").Value
    construction_template = sheet.Range("AN7").Value

    #Initialize a blank idf file
    ts = time.time()
    #st = datetime.datetime.fromtimestamp(ts).strftime('%Y%m%d %H%M%S')
    st = datetime.datetime.fromtimestamp(ts).strftime('%Y%m%d-%H%M')
    blankstr = ""
    new_idf = IDF(StringIO(blankstr))
    new_idf.idfname = "NongeoXport " + st + ".idf"

    #Import Constructoin Templates
    const_fname = "ahshrae901_construction_templates.idf"
    my_const = IDF(const_fname)

    #Copy All Construction Templates into New idf file
    materials = my_const.idfobjects['material'.upper()]
    for i in range(len(materials)):
        new_idf.copyidfobject(materials[i])

    materials_nomass = my_const.idfobjects['material:nomass'.upper()]
    for i in range(len(materials_nomass)):
        new_idf.copyidfobject(materials_nomass[i])

    materials_airgap = my_const.idfobjects['material:airgap'.upper()]
    for i in range(len(materials_airgap)):
        new_idf.copyidfobject(materials_airgap[i])

    window_materials_sgs = my_const.idfobjects[
        'windowmaterial:simpleglazingsystem'.upper()]
    for i in range(len(window_materials_sgs)):
        new_idf.copyidfobject(window_materials_sgs[i])

    window_materials_glz = my_const.idfobjects[
        'windowmaterial:glazing'.upper()]
    for i in range(len(window_materials_glz)):
        new_idf.copyidfobject(window_materials_glz[i])

    constructions = my_const.idfobjects['construction'.upper()]
    for i in range(len(constructions)):
        new_idf.copyidfobject(constructions[i])

    #Assign Surface Construction Names Based on User Templates Selections
    interior_floor_const = "Interior Floor"
    interior_wall_const = "Interior Wall"
    interior_ceiling_const = "Interior Ceiling"
    exterior_floor_const = "ExtSlabCarpet 4in ClimateZone 1-8"
    if construction_template == "ASHRAE 90.1 2010 Climate Zone 1":
        exterior_wall_const = "ASHRAE 90.1-2010 ExtWall Mass ClimateZone 1"
        exterior_window_const = "ASHRAE 90.1-2010 ExtWindow Metal ClimateZone 1"
        exterior_roof_const = "ASHRAE 90.1-2010 ExtRoof IEAD ClimateZone 1"

    elif construction_template == "ASHRAE 90.1 2010 Climate Zone 2":
        exterior_wall_const = "ASHRAE 90.1-2010 ExtWall Mass ClimateZone 2"
        exterior_window_const = "ASHRAE 90.1-2010 ExtWindow Metal ClimateZone 2"
        exterior_roof_const = "ASHRAE 90.1-2010 ExtRoof IEAD ClimateZone 2-8"

    elif construction_template == "ASHRAE 90.1 2010 Climate Zone 3":
        exterior_wall_const = "ASHRAE 90.1-2010 ExtWall Mass ClimateZone 3"
        exterior_window_const = "ASHRAE 90.1-2010 ExtWindow Metal ClimateZone 3"
        exterior_roof_const = "ASHRAE 90.1-2010 ExtRoof IEAD ClimateZone 2-8"

    elif construction_template == "ASHRAE 90.1 2010 Climate Zone 4":
        exterior_wall_const = "ASHRAE 90.1-2010 ExtWall Mass ClimateZone 4"
        exterior_window_const = "ASHRAE 90.1-2010 ExtWindow Metal ClimateZone 4-6"
        exterior_roof_const = "ASHRAE 90.1-2010 ExtRoof IEAD ClimateZone 2-8"

    elif construction_template == "ASHRAE 90.1 2010 Climate Zone 5":
        exterior_wall_const = "ASHRAE 90.1-2010 ExtWall Mass ClimateZone 5"
        exterior_window_const = "ASHRAE 90.1-2010 ExtWindow Metal ClimateZone 4-6"
        exterior_roof_const = "ASHRAE 90.1-2010 ExtRoof IEAD ClimateZone 2-8"

    elif construction_template == "ASHRAE 90.1 2010 Climate Zone 6":
        exterior_wall_const = "ASHRAE 90.1-2010 ExtWall Mass ClimateZone 6"
        exterior_window_const = "ASHRAE 90.1-2010 ExtWindow Metal ClimateZone 4-6"
        exterior_roof_const = "ASHRAE 90.1-2010 ExtRoof IEAD ClimateZone 2-8"

    elif construction_template == "ASHRAE 90.1 2010 Climate Zone 7":
        exterior_wall_const = "ASHRAE 90.1-2010 ExtWall Mass ClimateZone 7-8"
        exterior_window_const = "ASHRAE 90.1-2010 ExtWindow Metal ClimateZone 7-8"
        exterior_roof_const = "ASHRAE 90.1-2010 ExtRoof IEAD ClimateZone 2-8"

    elif construction_template == "ASHRAE 90.1 2010 Climate Zone 8":
        exterior_wall_const = "ASHRAE 90.1-2010 ExtWall Mass ClimateZone 7-8"
        exterior_window_const = "ASHRAE 90.1-2010 ExtWindow Metal ClimateZone 7-8"
        exterior_roof_const = "ASHRAE 90.1-2010 ExtRoof IEAD ClimateZone 2-8"

    ####Start Writing idf Objects
    ##General idf Objects for IDFXporter

    #Define Version Objects
    version = new_idf.newidfobject("version".upper())
    version.Version_Identifier = 8.5

    #Define Simulation Control Objects
    simctrl = new_idf.newidfobject("simulationcontrol".upper())
    simctrl.Do_Zone_Sizing_Calculation = "Yes"
    simctrl.Do_System_Sizing_Calculation = "Yes"
    simctrl.Do_Plant_Sizing_Calculation = "Yes"
    simctrl.Run_Simulation_for_Sizing_Periods = "No"
    simctrl.Run_Simulation_for_Weather_File_Run_Periods = "Yes"

    #Define Building Object
    building = new_idf.newidfobject("building".upper())
    building.Name = "My Building"
    building.North_Axis = 0

    #Define Run Periods Object
    run_period = new_idf.newidfobject("runperiod".upper())
    run_period.Name = "Run Period 1"
    run_period.Begin_Month = 1
    run_period.Begin_Day_of_Month = 1
    run_period.End_Month = 12
    run_period.End_Day_of_Month = 31
    run_period.Day_of_Week_for_Start_Day = "Thursday"
    run_period.Use_Weather_File_Rain_Indicators = "Yes"
    run_period.Use_Weather_File_Snow_Indicators = "Yes"

    #Define Schedule Type Limits Objects
    sch_tp_limit_1 = new_idf.newidfobject("scheduletypelimits".upper())
    sch_tp_limit_1.Name = "Any Number"
    sch_tp_limit_2 = new_idf.newidfobject("scheduletypelimits".upper())
    sch_tp_limit_2.Name = "Fraction"
    sch_tp_limit_3 = new_idf.newidfobject("scheduletypelimits".upper())
    sch_tp_limit_3.Name = "Temperature"
    sch_tp_limit_4 = new_idf.newidfobject("scheduletypelimits".upper())
    sch_tp_limit_4.Name = "On/Off"
    sch_tp_limit_5 = new_idf.newidfobject("scheduletypelimits".upper())
    sch_tp_limit_5.Name = "Control Type"
    sch_tp_limit_6 = new_idf.newidfobject("scheduletypelimits".upper())
    sch_tp_limit_6.Name = "Humidity"
    sch_tp_limit_7 = new_idf.newidfobject("scheduletypelimits".upper())
    sch_tp_limit_7.Name = "Number"

    ##Additional idf Objects from Params

    #Define Shadow Calculation Objects
    shadow_calc = new_idf.newidfobject("shadowcalculation".upper())
    shadow_calc.Calculation_Method = "AverageOverDaysInFrequency"

    #Define SurfaceConvectionAlgorithm:Inside Objects
    surf_conv_algorithm_in = new_idf.newidfobject(
        "SurfaceConvectionAlgorithm:Inside".upper())
    surf_conv_algorithm_in.Algorithm = "TARP"

    #Define SurfaceConvectionAlgorithm:Outside Objects
    surf_conv_algorithm_out = new_idf.newidfobject(
        "SurfaceConvectionAlgorithm:Outside".upper())
    surf_conv_algorithm_out.Algorithm = "DOE-2"

    #Define HeatBalanceAlgorithm Objects
    hb_algorithm = new_idf.newidfobject("HeatBalanceAlgorithm".upper())
    hb_algorithm.Algorithm = "ConductionTransferFunction"

    #Define SurfaceProperty:OtherSideConditionsModel Objects
    surf_prop_oscm = new_idf.newidfobject(
        "SurfaceProperty:OtherSideConditionsModel".upper())
    surf_prop_oscm.Name = "GapConvectionModel"

    #Define ConvergenceLimits Objects
    conv_limits = new_idf.newidfobject("ConvergenceLimits".upper())
    conv_limits.Minimum_System_Timestep = 0

    #Define Global Geometry Rules Objects
    rule = new_idf.newidfobject("globalgeometryrules".upper())
    rule.Starting_Vertex_Position = "UpperLeftCorner"
    rule.Vertex_Entry_Direction = "Counterclockwise"
    rule.Coordinate_System = "Relative"
    rule.Daylighting_Reference_Point_Coordinate_System = "Relative"
    rule.Rectangular_Surface_Coordinate_System = "Relative"

    #Define SizingParameters Objects
    szparams = new_idf.newidfobject("sizing:parameters".upper())
    szparams.Heating_Sizing_Factor = 1.25
    szparams.Cooling_Sizing_Factor = 1.15

    ####Non-Geometric Generator Starts

    for id in range(7, int(7 + num_of_zones)):
        zone_name = sheet.Range("B" + str(id)).Value
        #        zone_name = "Thermal Zone: " + zone_name
        #        zone_name = zone_name
        zone_origin_x = sheet.Range("C" + str(id)).Value
        zone_origin_y = sheet.Range("D" + str(id)).Value
        zone_origin_z = sheet.Range("E" + str(id)).Value
        #        prmtr_or_not =  sheet.Range("F"+str(id)).Value
        roof_or_not = sheet.Range("M" + str(id)).Value
        zone_height = sheet.Range("H" + str(id)).Value
        zone_length = sheet.Range("I" + str(id)).Value
        zone_width = sheet.Range("G" +
                                 str(id)).Value / sheet.Range("I" +
                                                              str(id)).Value
        prmtr1_normal = sheet.Range("K" + str(id)).Value
        prmtr2_normal = sheet.Range("L" + str(id)).Value
        grndflr_or_not = sheet.Range("N" + str(id)).Value
        wind2wall_ratio = sheet.Range("O" + str(id)).Value
        wind_sill_height = sheet.Range("P" + str(id)).Value

        #Define Zone Objects
        zone = new_idf.newidfobject("zone".upper())
        zone.Name = zone_name
        zone.X_Origin = zone_origin_x
        zone.Y_Origin = zone_origin_y
        zone.Z_Origin = zone_origin_z
        zone.Ceiling_Height = zone_height

        #Define BuildingSurface:Detailed Objects, default as adiabatic, and interior constructions
        surface_1 = new_idf.newidfobject("buildingsurface:detailed".upper())
        surface_1.Name = zone_name + " Surface 1"
        surface_1.Surface_Type = "Floor"
        surface_1.Construction_Name = interior_floor_const
        surface_1.Zone_Name = zone_name
        surface_1.Outside_Boundary_Condition = "Adiabatic"
        surface_1.Sun_Exposure = "NoSun"
        surface_1.Wind_Exposure = "NoWind"
        surface_1.Vertex_1_Xcoordinate = zone_length
        surface_1.Vertex_1_Ycoordinate = zone_width
        surface_1.Vertex_1_Zcoordinate = 0
        surface_1.Vertex_2_Xcoordinate = zone_length
        surface_1.Vertex_2_Ycoordinate = 0
        surface_1.Vertex_2_Zcoordinate = 0
        surface_1.Vertex_3_Xcoordinate = 0
        surface_1.Vertex_3_Ycoordinate = 0
        surface_1.Vertex_3_Zcoordinate = 0
        surface_1.Vertex_4_Xcoordinate = 0
        surface_1.Vertex_4_Ycoordinate = zone_width
        surface_1.Vertex_4_Zcoordinate = 0

        surface_2 = new_idf.newidfobject("buildingsurface:detailed".upper())
        surface_2.Name = zone_name + " Surface 2"
        surface_2.Surface_Type = "Wall"
        surface_2.Construction_Name = interior_wall_const
        surface_2.Zone_Name = zone_name
        surface_2.Outside_Boundary_Condition = "Adiabatic"
        surface_2.Sun_Exposure = "NoSun"
        surface_2.Wind_Exposure = "NoWind"
        surface_2.Vertex_1_Xcoordinate = 0
        surface_2.Vertex_1_Ycoordinate = zone_width
        surface_2.Vertex_1_Zcoordinate = zone_height
        surface_2.Vertex_2_Xcoordinate = 0
        surface_2.Vertex_2_Ycoordinate = zone_width
        surface_2.Vertex_2_Zcoordinate = 0
        surface_2.Vertex_3_Xcoordinate = 0
        surface_2.Vertex_3_Ycoordinate = 0
        surface_2.Vertex_3_Zcoordinate = 0
        surface_2.Vertex_4_Xcoordinate = 0
        surface_2.Vertex_4_Ycoordinate = 0
        surface_2.Vertex_4_Zcoordinate = zone_height

        surface_3 = new_idf.newidfobject("buildingsurface:detailed".upper())
        surface_3.Name = zone_name + " Surface 3"
        surface_3.Surface_Type = "Wall"
        surface_3.Construction_Name = interior_wall_const
        surface_3.Zone_Name = zone_name
        surface_3.Outside_Boundary_Condition = "Adiabatic"
        surface_3.Sun_Exposure = "NoSun"
        surface_3.Wind_Exposure = "NoWind"
        surface_3.Vertex_1_Xcoordinate = zone_length
        surface_3.Vertex_1_Ycoordinate = zone_width
        surface_3.Vertex_1_Zcoordinate = zone_height
        surface_3.Vertex_2_Xcoordinate = zone_length
        surface_3.Vertex_2_Ycoordinate = zone_width
        surface_3.Vertex_2_Zcoordinate = 0
        surface_3.Vertex_3_Xcoordinate = 0
        surface_3.Vertex_3_Ycoordinate = zone_width
        surface_3.Vertex_3_Zcoordinate = 0
        surface_3.Vertex_4_Xcoordinate = 0
        surface_3.Vertex_4_Ycoordinate = zone_width
        surface_3.Vertex_4_Zcoordinate = zone_height

        surface_4 = new_idf.newidfobject("buildingsurface:detailed".upper())
        surface_4.Name = zone_name + " Surface 4"
        surface_4.Surface_Type = "Wall"
        surface_4.Construction_Name = interior_wall_const
        surface_4.Zone_Name = zone_name
        surface_4.Outside_Boundary_Condition = "Adiabatic"
        surface_4.Sun_Exposure = "NoSun"
        surface_4.Wind_Exposure = "NoWind"
        surface_4.Vertex_1_Xcoordinate = zone_length
        surface_4.Vertex_1_Ycoordinate = 0
        surface_4.Vertex_1_Zcoordinate = zone_height
        surface_4.Vertex_2_Xcoordinate = zone_length
        surface_4.Vertex_2_Ycoordinate = 0
        surface_4.Vertex_2_Zcoordinate = 0
        surface_4.Vertex_3_Xcoordinate = zone_length
        surface_4.Vertex_3_Ycoordinate = zone_width
        surface_4.Vertex_3_Zcoordinate = 0
        surface_4.Vertex_4_Xcoordinate = zone_length
        surface_4.Vertex_4_Ycoordinate = zone_width
        surface_4.Vertex_4_Zcoordinate = zone_height

        surface_5 = new_idf.newidfobject("buildingsurface:detailed".upper())
        surface_5.Name = zone_name + " Surface 5"
        surface_5.Surface_Type = "Wall"
        surface_5.Construction_Name = interior_wall_const
        surface_5.Zone_Name = zone_name
        surface_5.Outside_Boundary_Condition = "Adiabatic"
        surface_5.Sun_Exposure = "NoSun"
        surface_5.Wind_Exposure = "NoWind"
        surface_5.Vertex_1_Xcoordinate = 0
        surface_5.Vertex_1_Ycoordinate = 0
        surface_5.Vertex_1_Zcoordinate = zone_height
        surface_5.Vertex_2_Xcoordinate = 0
        surface_5.Vertex_2_Ycoordinate = 0
        surface_5.Vertex_2_Zcoordinate = 0
        surface_5.Vertex_3_Xcoordinate = zone_length
        surface_5.Vertex_3_Ycoordinate = 0
        surface_5.Vertex_3_Zcoordinate = 0
        surface_5.Vertex_4_Xcoordinate = zone_length
        surface_5.Vertex_4_Ycoordinate = 0
        surface_5.Vertex_4_Zcoordinate = zone_height

        surface_6 = new_idf.newidfobject("buildingsurface:detailed".upper())
        surface_6.Name = zone_name + " Surface 6"
        surface_6.Zone_Name = zone_name
        surface_6.Vertex_1_Xcoordinate = zone_length
        surface_6.Vertex_1_Ycoordinate = 0
        surface_6.Vertex_1_Zcoordinate = zone_height
        surface_6.Vertex_2_Xcoordinate = zone_length
        surface_6.Vertex_2_Ycoordinate = zone_width
        surface_6.Vertex_2_Zcoordinate = zone_height
        surface_6.Vertex_3_Xcoordinate = 0
        surface_6.Vertex_3_Ycoordinate = zone_width
        surface_6.Vertex_3_Zcoordinate = zone_height
        surface_6.Vertex_4_Xcoordinate = 0
        surface_6.Vertex_4_Ycoordinate = 0
        surface_6.Vertex_4_Zcoordinate = zone_height

        #Change Surface Type if Roof
        if roof_or_not == "y":
            surface_6.Surface_Type = "Roof"
            surface_6.Construction_Name = exterior_roof_const
            surface_6.Outside_Boundary_Condition = "Outdoors"
            surface_6.Sun_Exposure = "SunExposed"
            surface_6.Wind_Exposure = "WindExposed"
        else:
            surface_6.Surface_Type = "Ceiling"
            surface_6.Construction_Name = interior_ceiling_const
            surface_6.Outside_Boundary_Condition = "Adiabatic"
            surface_6.Sun_Exposure = "NoSun"
            surface_6.Wind_Exposure = "NoWind"

        #Change Surface Type if Ground Floor
        if grndflr_or_not == "y":
            surface_1.Construction_Name = exterior_floor_const
            surface_1.Outside_Boundary_Condition = "Ground"
        else:
            pass

        #Change Surface Type if Perimeter 1 Normal is non-zero
        if prmtr1_normal == 0:
            surface_3.Construction_Name = exterior_wall_const
            surface_3.Outside_Boundary_Condition = "Outdoors"
            surface_3.Sun_Exposure = "SunExposed"
            surface_3.Wind_Exposure = "WindExposed"
            if wind2wall_ratio > 0:
                sub_surface = new_idf.newidfobject(
                    "FenestrationSurface:Detailed".upper())
                sub_surface.Name = zone_name + " Sub Surface 3"
                sub_surface.Surface_Type = "Window"
                sub_surface.Construction_Name = exterior_window_const
                sub_surface.Building_Surface_Name = surface_3.Name
                sub_surface.Vertex_1_Xcoordinate = zone_length - 0.0254
                sub_surface.Vertex_1_Ycoordinate = zone_width
                sub_surface.Vertex_1_Zcoordinate = zone_length * zone_height * wind2wall_ratio / (
                    zone_length - 0.0254 * 2) + wind_sill_height
                sub_surface.Vertex_2_Xcoordinate = zone_length - 0.0254
                sub_surface.Vertex_2_Ycoordinate = zone_width
                sub_surface.Vertex_2_Zcoordinate = wind_sill_height
                sub_surface.Vertex_3_Xcoordinate = 0.0254
                sub_surface.Vertex_3_Ycoordinate = zone_width
                sub_surface.Vertex_3_Zcoordinate = wind_sill_height
                sub_surface.Vertex_4_Xcoordinate = 0.0254
                sub_surface.Vertex_4_Ycoordinate = zone_width
                sub_surface.Vertex_4_Zcoordinate = sub_surface.Vertex_1_Zcoordinate
            else:
                pass
        elif prmtr1_normal == 90:
            surface_4.Construction_Name = exterior_wall_const
            surface_4.Outside_Boundary_Condition = "Outdoors"
            surface_4.Sun_Exposure = "SunExposed"
            surface_4.Wind_Exposure = "WindExposed"
            if wind2wall_ratio > 0:
                sub_surface = new_idf.newidfobject(
                    "FenestrationSurface:Detailed".upper())
                sub_surface.Name = zone_name + " Sub Surface 4"
                sub_surface.Surface_Type = "Window"
                sub_surface.Construction_Name = exterior_window_const
                sub_surface.Building_Surface_Name = surface_4.Name
                sub_surface.Vertex_1_Xcoordinate = zone_length
                sub_surface.Vertex_1_Ycoordinate = 0.0254
                sub_surface.Vertex_1_Zcoordinate = zone_width * zone_height * wind2wall_ratio / (
                    zone_width - 0.0254 * 2) + wind_sill_height
                #                sub_surface.Vertex_1_Zcoordinate = zone_length*zone_height*wind2wall_ratio/sub_surface.Vertex_1_Xcoordinate+wind_sill_height
                sub_surface.Vertex_2_Xcoordinate = zone_length
                sub_surface.Vertex_2_Ycoordinate = 0.0254
                sub_surface.Vertex_2_Zcoordinate = wind_sill_height
                sub_surface.Vertex_3_Xcoordinate = zone_length
                sub_surface.Vertex_3_Ycoordinate = zone_width - 0.0254
                sub_surface.Vertex_3_Zcoordinate = wind_sill_height
                sub_surface.Vertex_4_Xcoordinate = zone_length
                sub_surface.Vertex_4_Ycoordinate = zone_width - 0.0254
                sub_surface.Vertex_4_Zcoordinate = sub_surface.Vertex_1_Zcoordinate
            else:
                pass
        elif prmtr1_normal == 180:
            surface_5.Construction_Name = exterior_wall_const
            surface_5.Outside_Boundary_Condition = "Outdoors"
            surface_5.Sun_Exposure = "SunExposed"
            surface_5.Wind_Exposure = "WindExposed"
            if wind2wall_ratio > 0:
                sub_surface = new_idf.newidfobject(
                    "FenestrationSurface:Detailed".upper())
                sub_surface.Name = zone_name + " Sub Surface 5"
                sub_surface.Surface_Type = "Window"
                sub_surface.Construction_Name = exterior_window_const
                sub_surface.Building_Surface_Name = surface_5.Name
                sub_surface.Vertex_1_Xcoordinate = 0.0254
                sub_surface.Vertex_1_Ycoordinate = 0
                sub_surface.Vertex_1_Zcoordinate = zone_length * zone_height * wind2wall_ratio / (
                    zone_length - 0.0254 * 2) + wind_sill_height
                #                sub_surface.Vertex_1_Zcoordinate = zone_length*zone_height*wind2wall_ratio/sub_surface.Vertex_1_Xcoordinate+wind_sill_height
                sub_surface.Vertex_2_Xcoordinate = 0.0254
                sub_surface.Vertex_2_Ycoordinate = 0
                sub_surface.Vertex_2_Zcoordinate = wind_sill_height
                sub_surface.Vertex_3_Xcoordinate = zone_length - 0.0254
                sub_surface.Vertex_3_Ycoordinate = 0
                sub_surface.Vertex_3_Zcoordinate = wind_sill_height
                sub_surface.Vertex_4_Xcoordinate = zone_length - 0.0254
                sub_surface.Vertex_4_Ycoordinate = 0
                sub_surface.Vertex_4_Zcoordinate = sub_surface.Vertex_1_Zcoordinate
            else:
                pass
        elif prmtr1_normal == 270:
            surface_2.Construction_Name = exterior_wall_const
            surface_2.Outside_Boundary_Condition = "Outdoors"
            surface_2.Sun_Exposure = "SunExposed"
            surface_2.Wind_Exposure = "WindExposed"
            if wind2wall_ratio > 0:
                sub_surface = new_idf.newidfobject(
                    "FenestrationSurface:Detailed".upper())
                sub_surface.Name = zone_name + " Sub Surface 2"
                sub_surface.Surface_Type = "Window"
                sub_surface.Construction_Name = exterior_window_const
                sub_surface.Building_Surface_Name = surface_2.Name
                sub_surface.Vertex_1_Xcoordinate = 0
                sub_surface.Vertex_1_Ycoordinate = zone_width - 0.0254
                sub_surface.Vertex_1_Zcoordinate = zone_width * zone_height * wind2wall_ratio / (
                    zone_width - 2 * 0.0254) + wind_sill_height
                #                sub_surface.Vertex_1_Zcoordinate = zone_length*zone_height*wind2wall_ratio/sub_surface.Vertex_1_Xcoordinate+wind_sill_height
                sub_surface.Vertex_2_Xcoordinate = 0
                sub_surface.Vertex_2_Ycoordinate = zone_width - 0.0254
                sub_surface.Vertex_2_Zcoordinate = wind_sill_height
                sub_surface.Vertex_3_Xcoordinate = 0
                sub_surface.Vertex_3_Ycoordinate = 0.0254
                sub_surface.Vertex_3_Zcoordinate = wind_sill_height
                sub_surface.Vertex_4_Xcoordinate = 0
                sub_surface.Vertex_4_Ycoordinate = 0.0254
                sub_surface.Vertex_4_Zcoordinate = sub_surface.Vertex_1_Zcoordinate
            else:
                pass
        else:
            pass

        #Change Surface Type if Perimeter 2 Normal is non-zero

        if prmtr2_normal == 0:
            surface_3.Construction_Name = exterior_wall_const
            surface_3.Outside_Boundary_Condition = "Outdoors"
            surface_3.Sun_Exposure = "SunExposed"
            surface_3.Wind_Exposure = "WindExposed"
            if wind2wall_ratio > 0:
                sub_surface = new_idf.newidfobject(
                    "FenestrationSurface:Detailed".upper())
                sub_surface.Name = zone_name + " Sub Surface 3"
                sub_surface.Surface_Type = "Window"
                sub_surface.Construction_Name = exterior_window_const
                sub_surface.Building_Surface_Name = surface_3.Name
                sub_surface.Vertex_1_Xcoordinate = zone_length - 0.0254
                sub_surface.Vertex_1_Ycoordinate = zone_width
                sub_surface.Vertex_1_Zcoordinate = zone_length * zone_height * wind2wall_ratio / (
                    zone_length - 0.0254 * 2) + wind_sill_height
                sub_surface.Vertex_2_Xcoordinate = zone_length - 0.0254
                sub_surface.Vertex_2_Ycoordinate = zone_width
                sub_surface.Vertex_2_Zcoordinate = wind_sill_height
                sub_surface.Vertex_3_Xcoordinate = 0.0254
                sub_surface.Vertex_3_Ycoordinate = zone_width
                sub_surface.Vertex_3_Zcoordinate = wind_sill_height
                sub_surface.Vertex_4_Xcoordinate = 0.0254
                sub_surface.Vertex_4_Ycoordinate = zone_width
                sub_surface.Vertex_4_Zcoordinate = sub_surface.Vertex_1_Zcoordinate
            else:
                pass
        elif prmtr2_normal == 90:
            surface_4.Construction_Name = exterior_wall_const
            surface_4.Outside_Boundary_Condition = "Outdoors"
            surface_4.Sun_Exposure = "SunExposed"
            surface_4.Wind_Exposure = "WindExposed"
            if wind2wall_ratio > 0:
                sub_surface = new_idf.newidfobject(
                    "FenestrationSurface:Detailed".upper())
                sub_surface.Name = zone_name + " Sub Surface 4"
                sub_surface.Surface_Type = "Window"
                sub_surface.Construction_Name = exterior_window_const
                sub_surface.Building_Surface_Name = surface_4.Name
                sub_surface.Vertex_1_Xcoordinate = zone_length
                sub_surface.Vertex_1_Ycoordinate = 0.0254
                sub_surface.Vertex_1_Zcoordinate = zone_width * zone_height * wind2wall_ratio / (
                    zone_width - 0.0254 * 2) + wind_sill_height
                #                sub_surface.Vertex_1_Zcoordinate = zone_length*zone_height*wind2wall_ratio/sub_surface.Vertex_1_Xcoordinate+wind_sill_height
                sub_surface.Vertex_2_Xcoordinate = zone_length
                sub_surface.Vertex_2_Ycoordinate = 0.0254
                sub_surface.Vertex_2_Zcoordinate = wind_sill_height
                sub_surface.Vertex_3_Xcoordinate = zone_length
                sub_surface.Vertex_3_Ycoordinate = zone_width - 0.0254
                sub_surface.Vertex_3_Zcoordinate = wind_sill_height
                sub_surface.Vertex_4_Xcoordinate = zone_length
                sub_surface.Vertex_4_Ycoordinate = zone_width - 0.0254
                sub_surface.Vertex_4_Zcoordinate = sub_surface.Vertex_1_Zcoordinate
            else:
                pass
        elif prmtr2_normal == 180:
            surface_5.Construction_Name = exterior_wall_const
            surface_5.Outside_Boundary_Condition = "Outdoors"
            surface_5.Sun_Exposure = "SunExposed"
            surface_5.Wind_Exposure = "WindExposed"
            if wind2wall_ratio > 0:
                sub_surface = new_idf.newidfobject(
                    "FenestrationSurface:Detailed".upper())
                sub_surface.Name = zone_name + " Sub Surface 5"
                sub_surface.Surface_Type = "Window"
                sub_surface.Construction_Name = exterior_window_const
                sub_surface.Building_Surface_Name = surface_5.Name
                sub_surface.Vertex_1_Xcoordinate = 0.0254
                sub_surface.Vertex_1_Ycoordinate = 0
                sub_surface.Vertex_1_Zcoordinate = zone_length * zone_height * wind2wall_ratio / (
                    zone_length - 0.0254 * 2) + wind_sill_height
                #                sub_surface.Vertex_1_Zcoordinate = zone_length*zone_height*wind2wall_ratio/sub_surface.Vertex_1_Xcoordinate+wind_sill_height
                sub_surface.Vertex_2_Xcoordinate = 0.0254
                sub_surface.Vertex_2_Ycoordinate = 0
                sub_surface.Vertex_2_Zcoordinate = wind_sill_height
                sub_surface.Vertex_3_Xcoordinate = zone_length - 0.0254
                sub_surface.Vertex_3_Ycoordinate = 0
                sub_surface.Vertex_3_Zcoordinate = wind_sill_height
                sub_surface.Vertex_4_Xcoordinate = zone_length - 0.0254
                sub_surface.Vertex_4_Ycoordinate = 0
                sub_surface.Vertex_4_Zcoordinate = sub_surface.Vertex_1_Zcoordinate
            else:
                pass
        elif prmtr2_normal == 270:
            surface_2.Construction_Name = exterior_wall_const
            surface_2.Outside_Boundary_Condition = "Outdoors"
            surface_2.Sun_Exposure = "SunExposed"
            surface_2.Wind_Exposure = "WindExposed"
            if wind2wall_ratio > 0:
                sub_surface = new_idf.newidfobject(
                    "FenestrationSurface:Detailed".upper())
                sub_surface.Name = zone_name + " Sub Surface 2"
                sub_surface.Surface_Type = "Window"
                sub_surface.Construction_Name = exterior_window_const
                sub_surface.Building_Surface_Name = surface_2.Name
                sub_surface.Vertex_1_Xcoordinate = 0
                sub_surface.Vertex_1_Ycoordinate = zone_width - 0.0254
                sub_surface.Vertex_1_Zcoordinate = zone_width * zone_height * wind2wall_ratio / (
                    zone_width - 2 * 0.0254) + wind_sill_height
                #                sub_surface.Vertex_1_Zcoordinate = zone_length*zone_height*wind2wall_ratio/sub_surface.Vertex_1_Xcoordinate+wind_sill_height
                sub_surface.Vertex_2_Xcoordinate = 0
                sub_surface.Vertex_2_Ycoordinate = zone_width - 0.0254
                sub_surface.Vertex_2_Zcoordinate = wind_sill_height
                sub_surface.Vertex_3_Xcoordinate = 0
                sub_surface.Vertex_3_Ycoordinate = 0.0254
                sub_surface.Vertex_3_Zcoordinate = wind_sill_height
                sub_surface.Vertex_4_Xcoordinate = 0
                sub_surface.Vertex_4_Ycoordinate = 0.0254
                sub_surface.Vertex_4_Zcoordinate = sub_surface.Vertex_1_Zcoordinate
            else:
                pass
        else:
            pass

    new_idf.save()
    this_idf = new_idf.idfname
    #    dir_path = os.path.dirname(os.path.realpath(this_idf))
    #
    #    os.chdir('..')
    #    shutil.copy2(dir_path, '/templates/)
    # complete target filename given
    #    shutil.copy2('/src/file.ext', '/dst/dir') # target filename is /dst/dir/file.ext
    pre, ext = os.path.splitext(this_idf)
    os.rename(this_idf, pre + ".pxt")
示例#33
0
# <markdowncell>

# There are 3 fruits in the list.

# <headingcell level=2>

# Saving an idf file

# <markdowncell>

# This is easy:

# <codecell>

idf1.save()

# <markdowncell>

# If you'd like to do a "Save as..." use this:

# <codecell>

idf1.saveas("something.idf")

# <headingcell level=2>

# Working with E+ objects

# <markdowncell>
示例#34
0
def createnurbsopening(idd_filename, idf_filename, base_surface, opening_str, ctrl_points, evaluated_points=50):
    ##########################################
    # loading base surface data from idf file 
    ##########################################
    
    # check if IDD has been already set
    try:
        IDF.setiddname(idd_filename)
    except modeleditor.IDDAlreadySetError as e:
        pass

    # load idf file into idf collection
    idf_collection = IDF(idf_filename)

    # find the named base_surface in idf collection
    walls = idf_collection.idfobjects['BuildingSurface:Detailed'.upper()]
    for wall in walls:
        if wall.Name == base_surface:
            # named base_surface is now contained in wall
            break
    else:
        # named base_surface was not found in idf file
        print('epnurbs.createopening: unable to find the base surface', base_surface, 'in', idf_filename)
        return

    #################################
    # calculating NURBS curve points
    #################################
    from geomdl import NURBS
    from geomdl import utilities

    # one has to exclude checks for leading zeros and trailing ones in geomdl.utilities.check_knot_vector
    # in order for this knotvector to be allowed!
    utilities.check_knot_vector = new_check_knot_vector
    
    curve = NURBS.Curve()

    # 1/delta corresponds to the number of evaluated points of a NURBS curve that defines the opening
    curve.delta = 1/evaluated_points
    curve.degree = 3

    # add weight 1 to each control point
    for cpt in ctrl_points:
        if len(cpt)<4:
            cpt.append(1.0)

    # add copy of the first degree control points in order to close NURBS curve
    extra_points = ctrl_points[:curve.degree]
    ctrl_points.extend(extra_points)

    # sets curve control points
    curve.set_ctrlpts(ctrl_points)

    # sets knot vector for closed NURBS curve
    # note that the length of ctrl_points has increased for curve.degree due to extend operation
    knotstep = 1/(len(ctrl_points) + curve.degree)
    curve.knotvector = [i*knotstep for i in range(len(ctrl_points)+curve.degree+1)]

    # note that for the closed NURBS curve
    # we have to use only the domain [knotvector[curve.degree], knotvector[len(ctrl_points)]]!!!
    # evaluates curve points
    curve.evaluate(curve.degree*knotstep, len(ctrl_points)*knotstep)

    # make a local copy of evaluated curve points
    crv_points = curve.curvepts

    #########################################################################
    # feet of perpendiculars from the NURBS curve points to the base surface,
    # just to make sure we are not getting out of its plane
    #########################################################################

    # getting the found base_surface's coordinates
    coord = wall.coords
    ulc = coord[0]
    blc = coord[1]
    brc = coord[2]

    # find the base_surface's plane normal and normalize it
    u = [ blc[0]-ulc[0], blc[1]-ulc[1], blc[2]-ulc[2] ]
    v = [ brc[0]-blc[0], brc[1]-blc[1], brc[2]-blc[2] ]
    N = crossproduct(u,v)
    N = normalize(N)

    # calculate feet of perpendiculars
    feet_points = [foot(crv_points[i], ulc, N) for i in range(len(crv_points))]

    #######################################################################################
    # create a list of 0.1m squares that partition the whole wall surface
    # !!! it is assumed that the wall surface is a rectangle
    # !!! three of whose vertices are ulc, blc and brc (and the fourth one is ulc+brc-blc)
    #######################################################################################

    # a new orthonormal system for the wall surface
    u = normalize(u)
    v = crossproduct(N,u)
    v = normalize(v)

    # transform feet_point coordinates to the uv system
    # since N, u, v is an orthonormal system we have that
    # for each vector X = <X,N>N + <X,u>u + <X,v>v
    # this will be applied to vectors feet_points-ulc which belong to the wall surface plane
    feet_points_uv = [ [dotproduct(subtract(fp, ulc), u),
                        dotproduct(subtract(fp, ulc), v)] for fp in feet_points]

    # form a list of squares and a list of their centers in uv coordinates
    squaresize = 0.1
    maxi = int(length(subtract(blc, ulc))/squaresize)-1
    maxj = int(length(subtract(brc, blc))/squaresize)-1

    squarelist = [ [ [ ((i+0.5)*squaresize, (j+0.5)*squaresize), ((i+1.5)*squaresize, (j+0.5)*squaresize),
                       ((i+1.5)*squaresize, (j+1.5)*squaresize), ((i+0.5)*squaresize, (j+1.5)*squaresize) ]
                   for j in range(maxj) ]
                 for i in range(maxi)]
    squarecenters = [ ( (i+1)*squaresize, (j+1)*squaresize ) for i in range(maxi) for j in range(maxj) ]

    # for each square check whether its center belongs to the polygon defined by NURBS curve points
    import matplotlib.path as mplPath
    path = mplPath.Path(feet_points_uv)
    inside = path.contains_points(squarecenters)

    # select only those squares whose centers are inside the NURBS curve
    insideindices = [ [ j for j in range(maxj) if inside[i*maxj+j] ] for i in range(maxi) ]

    # now insideindices[i] contains all j such that squarelist[i][j] is inside a NURBS curve

    #################################################################################
    # create string of idf definitions for rectangles that approximate NURBS opening
    #################################################################################
    idf_total_opening_def = ""

    for i in range(maxi):
        # go through all inside squares within i-th column, if there are any
        if len(insideindices[i])>0:
            # pn and kn contain the beginning and the end of
            # subsequences of consecutive numbers within the insideindices[i] list
            pn = insideindices[i][0]
            kn = insideindices[i][0]

            for k in range(1, len(insideindices[i])+1):
                if k<len(insideindices[i]) and insideindices[i][k]==insideindices[i][k-1]+1:
                    # consecutive subsequence goes on
                    kn = insideindices[i][k]
                else:
                    # consecutive subsequence had ended, so create an opening element
                    # squarelist[i][pn][0],[1] contain its first two vertices in uv system,
                    # squarelist[i][kn][2],[3] contain its last two vertices in uv system
                    # recalculate vertices in xyz system first
                    vertex1 = [ ulc[0] + squarelist[i][pn][0][0] * u[0] + squarelist[i][pn][0][1] * v[0],
                                ulc[1] + squarelist[i][pn][0][0] * u[1] + squarelist[i][pn][0][1] * v[1],
                                ulc[2] + squarelist[i][pn][0][0] * u[2] + squarelist[i][pn][0][1] * v[2] ]
                    vertex2 = [ ulc[0] + squarelist[i][pn][1][0] * u[0] + squarelist[i][pn][1][1] * v[0],
                                ulc[1] + squarelist[i][pn][1][0] * u[1] + squarelist[i][pn][1][1] * v[1],
                                ulc[2] + squarelist[i][pn][1][0] * u[2] + squarelist[i][pn][1][1] * v[2] ]
                    vertex3 = [ ulc[0] + squarelist[i][kn][2][0] * u[0] + squarelist[i][kn][2][1] * v[0],
                                ulc[1] + squarelist[i][kn][2][0] * u[1] + squarelist[i][kn][2][1] * v[1],
                                ulc[2] + squarelist[i][kn][2][0] * u[2] + squarelist[i][kn][2][1] * v[2] ]
                    vertex4 = [ ulc[0] + squarelist[i][kn][3][0] * u[0] + squarelist[i][kn][3][1] * v[0],
                                ulc[1] + squarelist[i][kn][3][0] * u[1] + squarelist[i][kn][3][1] * v[1],
                                ulc[2] + squarelist[i][kn][3][0] * u[2] + squarelist[i][kn][3][1] * v[2] ]
                    
                    vert_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format(
                               vertex1[0], vertex1[1], vertex1[2],
                               vertex2[0], vertex2[1], vertex2[2],
                               vertex3[0], vertex3[1], vertex3[2],
                               vertex4[0], vertex4[1], vertex4[2])
                    countervert_str = "{:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}, {:f}".format(
                                      vertex1[0], vertex1[1], vertex1[2],
                                      vertex4[0], vertex4[1], vertex4[2],
                                      vertex3[0], vertex3[1], vertex3[2],
                                      vertex2[0], vertex2[1], vertex2[2])
                    
                    # fill out the entries in the opening string definition
                    single_opening_def = opening_str.replace('<IDX>', str(i)+'_'+str(pn)).replace('<BASESURFACE>', base_surface).replace('<VERTICES>', vert_str).replace('<COUNTERVERTICES>', countervert_str)
                    idf_total_opening_def = idf_total_opening_def + single_opening_def

                    # a new consecutive subsequence has just begun provided that k<len(insideindices[i])
                    if k<len(insideindices[i]):
                        pn = insideindices[i][k]
                        kn = insideindices[i][k]
     
    # create idf opening objects from the string containing opening definitions   
    from io import StringIO
    idf_opening = IDF(StringIO(idf_total_opening_def))

    # copy idf shading objects to the existing idf file
    openings = idf_opening.idfobjects["FENESTRATIONSURFACE:DETAILED"]
    for opening in openings:
        idf_collection.copyidfobject(opening)
    
    ###############################
    # at the end, save the changes
    ###############################
    idf_collection.save()