def test_to_honeybee_multiple_models():
    """Test to_honeybee with multiple honeybee models."""
    pts_1 = (Point3D(0, 0, 3), Point3D(10, 0, 3), Point3D(10, 10, 3), Point3D(0, 10, 3))
    pts_2 = (Point3D(10, 0, 3), Point3D(20, 0, 3), Point3D(20, 10, 3), Point3D(10, 10, 3))
    pts_3 = (Point3D(0, 20, 3), Point3D(20, 20, 3), Point3D(20, 30, 3), Point3D(0, 30, 3))
    room2d_1 = Room2D('Office1', Face3D(pts_1), 3)
    room2d_2 = Room2D('Office2', Face3D(pts_2), 3)
    room2d_3 = Room2D('Office3', Face3D(pts_3), 3)
    story_big = Story('OfficeFloorBig', [room2d_3])
    story = Story('OfficeFloor', [room2d_1, room2d_2])
    story.solve_room_2d_adjacency(0.01)
    story.set_outdoor_window_parameters(SimpleWindowRatio(0.4))
    story.multiplier = 4
    building = Building('OfficeBuilding', [story])
    story_big.set_outdoor_window_parameters(SimpleWindowRatio(0.4))
    story_big.multiplier = 4
    building_big = Building('OfficeBuildingBig', [story_big])

    tree_canopy_geo1 = Face3D.from_regular_polygon(6, 6, Plane(o=Point3D(5, -10, 6)))
    tree_canopy_geo2 = Face3D.from_regular_polygon(6, 2, Plane(o=Point3D(-5, -10, 3)))
    tree_canopy = ContextShade('TreeCanopy', [tree_canopy_geo1, tree_canopy_geo2])

    model = Model('NewDevelopment', [building, building_big], [tree_canopy])

    hb_models = model.to_honeybee('Building', 10, False, tolerance=0.01)
    assert len(hb_models) == 2
    assert isinstance(hb_models[0], hb_model.Model)
    assert isinstance(hb_models[-1], hb_model.Model)
    assert len(hb_models[-1].rooms) == 4
    assert len(hb_models[-1].rooms[-1]) == 6
    assert hb_models[-1].rooms[-1].volume == 600
    assert hb_models[-1].rooms[-1].floor_area == 200
    assert hb_models[-1].rooms[-1].exterior_wall_area == 180
    assert len(hb_models[0].orphaned_shades) == 6
    assert len(hb_models[-1].orphaned_shades) == 6
def test_properties():
    """Test various properties on the model."""
    pts_1 = (Point3D(0, 0, 3), Point3D(10, 0, 3), Point3D(10, 10, 3), Point3D(0, 10, 3))
    pts_2 = (Point3D(10, 0, 3), Point3D(20, 0, 3), Point3D(20, 10, 3), Point3D(10, 10, 3))
    pts_3 = (Point3D(0, 20, 3), Point3D(20, 20, 3), Point3D(20, 30, 3), Point3D(0, 30, 3))
    room2d_1 = Room2D('Office1', Face3D(pts_1), 3)
    room2d_2 = Room2D('Office2', Face3D(pts_2), 3)
    room2d_3 = Room2D('Office3', Face3D(pts_3), 3)
    story_big = Story('OfficeFloorBig', [room2d_3])
    story = Story('OfficeFloor', [room2d_1, room2d_2])
    story.solve_room_2d_adjacency(0.01)
    story.set_outdoor_window_parameters(SimpleWindowRatio(0.4))
    story.multiplier = 4
    building = Building('OfficeBuilding', [story])
    story_big.set_outdoor_window_parameters(SimpleWindowRatio(0.4))
    story_big.multiplier = 2
    building_big = Building('OfficeBuildingBig', [story_big])

    model = Model('NewDevelopment', [building, building_big])

    assert model.average_story_count == 3
    assert model.average_story_count_above_ground == 3
    assert model.average_height == 12
    assert model.average_height_above_ground == 9
    assert model.footprint_area == 100 * 4
    assert model.floor_area == (100 * 2 * 4) + (200 * 2)
    assert model.exterior_wall_area == (90 * 2 * 4) + (180 * 2)
    assert model.exterior_aperture_area == (90 * 2 * 4 * 0.4) + (180 * 2 * 0.4)
    assert model.volume == (100 * 2 * 4 * 3) + (200 * 2 * 3)
Example #3
0
def two_buildings():
    pts_1 = (Point3D(0, 0, 3), Point3D(10, 0,
                                       3), Point3D(10, 10,
                                                   3), Point3D(0, 10, 3))
    pts_2 = (Point3D(10, 0, 3), Point3D(20, 0,
                                        3), Point3D(20, 10,
                                                    3), Point3D(10, 10, 3))
    pts_3 = (Point3D(0, 20, 3), Point3D(20, 20,
                                        3), Point3D(20, 30,
                                                    3), Point3D(0, 30, 3))
    room2d_1 = Room2D('Office1', Face3D(pts_1), 3)
    room2d_2 = Room2D('Office2', Face3D(pts_2), 3)
    room2d_3 = Room2D('Office3', Face3D(pts_3), 3)
    story_big = Story('OfficeFloorBig', [room2d_3])
    story = Story('OfficeFloor', [room2d_1, room2d_2])
    story.solve_room_2d_adjacency(0.01)
    story.set_outdoor_window_parameters(SimpleWindowRatio(0.3))
    story.multiplier = 3
    building = Building('OfficeBuilding', [story])
    building.separate_top_bottom_floors()
    story_big.set_outdoor_window_parameters(SimpleWindowRatio(0.6))
    story_big.multiplier = 4
    building_big = Building('OfficeBuildingBig', [story_big])
    building_big.separate_top_bottom_floors()

    tree_canopy_geo1 = Face3D.from_regular_polygon(6, 6,
                                                   Plane(o=Point3D(5, -10, 6)))
    tree_canopy_geo2 = Face3D.from_regular_polygon(
        6, 2, Plane(o=Point3D(-5, -10, 3)))
    tree_canopy = ContextShade('TreeCanopy',
                               [tree_canopy_geo1, tree_canopy_geo2])

    model = Model('NewDevelopment', [building, building_big], [tree_canopy])
    return model
Example #4
0
def test_dict_to_object_win_par():
    """Test the dict_to_object method with window parameters."""
    simple_window = SingleWindow(5, 2, 0.8)
    ashrae_base1 = SimpleWindowRatio(0.4)
    ashrae_base2 = RepeatingWindowRatio(0.4, 2, 0.8, 3)
    bod_windows = RepeatingWindowWidthHeight(2, 1.5, 0.8, 3)

    origins = (Point2D(2, 1), Point2D(5, 0.5))
    widths = (1, 3)
    heights = (1, 2)
    detailed_window1 = RectangularWindows(origins, widths, heights)

    pts_1 = (Point2D(2, 1), Point2D(3, 1), Point2D(3, 2), Point2D(2, 2))
    pts_2 = (Point2D(5, 0.5), Point2D(8, 0.5), Point2D(8,
                                                       2.5), Point2D(5, 2.5))
    detailed_window2 = DetailedWindows((Polygon2D(pts_1), Polygon2D(pts_2)))

    assert isinstance(dict_to_object(simple_window.to_dict()), SingleWindow)
    assert isinstance(dict_to_object(ashrae_base1.to_dict()),
                      SimpleWindowRatio)
    assert isinstance(dict_to_object(ashrae_base2.to_dict()),
                      RepeatingWindowRatio)
    assert isinstance(dict_to_object(bod_windows.to_dict()),
                      RepeatingWindowWidthHeight)
    assert isinstance(dict_to_object(detailed_window1.to_dict()),
                      RectangularWindows)
    assert isinstance(dict_to_object(detailed_window2.to_dict()),
                      DetailedWindows)
def test_simple_window_ratio_dict_methods():
    """Test the to/from dict methods."""
    ashrae_base = SimpleWindowRatio(0.4)

    glz_dict = ashrae_base.to_dict()
    new_ashrae_base = SimpleWindowRatio.from_dict(glz_dict)
    assert new_ashrae_base == ashrae_base
    assert glz_dict == new_ashrae_base.to_dict()
Example #6
0
def urban_district(directory):
    com_poly_file = './scripts/geometry/urban_commercial_geo.json'
    res_poly_file = './scripts/geometry/urban_residential_geo.json'
    with open(com_poly_file, 'r') as fp:
        com_geo_dict = json.load(fp)
    with open(res_poly_file, 'r') as fp:
        res_geo_dict = json.load(fp)

    # get all of the programs and construction sets
    c_set = constr_set_lib.construction_set_by_identifier('2013::ClimateZone5::SteelFramed')
    office = prog_type_lib.program_type_by_identifier('2013::MediumOffice::ClosedOffice')
    apartment = prog_type_lib.program_type_by_identifier('2013::MidriseApartment::Apartment')
    retail = prog_type_lib.program_type_by_identifier('2013::Retail::Retail')

    # create the Room2Ds
    rooms = []
    for bldg in com_geo_dict:
        for i, floor in enumerate(bldg):
            room_geo = Face3D.from_dict(floor)
            if i < 3:
                hgt = 5 if i == 0 else 4
            else:
                hgt = 3
            program = retail if i == 0 else office
            room = Room2D('Commercial_{}'.format(i), room_geo, hgt)
            room.properties.energy.program_type = program
            room.properties.energy.construction_set = c_set
            room.properties.energy.add_default_ideal_air()
            ratio = 0.8 if i == 0 else 0.4
            room.set_outdoor_window_parameters(SimpleWindowRatio(ratio))
            if i == 0:
                room.is_ground_contact = True
            rooms.append(room)

    for bldg in res_geo_dict:
        for i, floor in enumerate(bldg):
            room_geo = Face3D.from_dict(floor)
            room = Room2D('Residential_{}'.format(i), room_geo, 4)
            room.properties.energy.program_type = apartment
            room.properties.energy.construction_set = c_set
            room.properties.energy.add_default_ideal_air()
            room.set_outdoor_window_parameters(SimpleWindowRatio(0.35))
            if i == 0:
                room.is_ground_contact = True
            rooms.append(room)

    # create honeybee Rooms
    hb_rooms = [room.to_honeybee()[0] for room in rooms]
    model = Model('Mass_Pike_District', rooms=hb_rooms,
                  units='Meters', tolerance=0.01, angle_tolerance=1.0)

    # write the model to a JSON
    dest_file = os.path.join(directory, 'urban_district.hbjson')
    with open(dest_file, 'w') as fp:
        json.dump(model.to_dict(), fp, indent=4)
def test_simple_window_ratio_equality():
    """Test the equality of SimpleWindowRatio objects."""
    ashrae_base = SimpleWindowRatio(0.4)
    ashrae_base_dup = ashrae_base.duplicate()
    ashrae_base_alt = SimpleWindowRatio(0.25)

    assert ashrae_base is ashrae_base
    assert ashrae_base is not ashrae_base_dup
    assert ashrae_base == ashrae_base_dup
    assert hash(ashrae_base) == hash(ashrae_base_dup)
    assert ashrae_base != ashrae_base_alt
    assert hash(ashrae_base) != hash(ashrae_base_alt)
def test_simple_window_ratio_add_window_to_face():
    """Test the add_window_to_face method."""
    ashrae_base = SimpleWindowRatio(0.4)
    height = 3
    width = 10
    seg = LineSegment3D.from_end_points(Point3D(0, 0, 2), Point3D(width, 0, 2))
    face = Face('test_face', Face3D.from_extrusion(seg, Vector3D(0, 0, height)))
    ashrae_base.add_window_to_face(face, 0.01)

    assert len(face.apertures) == 1
    assert face.center == face.apertures[0].center
    assert ashrae_base.area_from_segment(seg, height) == face.apertures[0].area == \
        width * height * 0.4
def test_to_geojson():
    """Test the Model to_geojson method."""
    pts_1 = (Point3D(50, 50, 3), Point3D(60, 50, 3), Point3D(60, 60, 3), Point3D(50, 60, 3))
    pts_2 = (Point3D(60, 50, 3), Point3D(70, 50, 3), Point3D(70, 60, 3), Point3D(60, 60, 3))
    pts_3 = (Point3D(50, 70, 3), Point3D(70, 70, 3), Point3D(70, 80, 3), Point3D(50, 80, 3))
    room2d_1 = Room2D('Residence1', Face3D(pts_1), 3)
    room2d_2 = Room2D('Residence2', Face3D(pts_2), 3)
    room2d_3 = Room2D('Retail', Face3D(pts_3), 3)
    story_big = Story('RetailFloor', [room2d_3])
    story = Story('ResidenceFloor', [room2d_1, room2d_2])
    story.solve_room_2d_adjacency(0.01)
    story.set_outdoor_window_parameters(SimpleWindowRatio(0.4))
    story.multiplier = 3
    building = Building('ResidenceBuilding', [story])
    story_big.set_outdoor_window_parameters(SimpleWindowRatio(0.4))
    story_big.multiplier = 1
    building_big = Building('RetailBuildingBig', [story_big])

    pts_1 = (Point3D(0, 0, 3), Point3D(0, 5, 3), Point3D(15, 5, 3), Point3D(15, 0, 3))
    pts_2 = (Point3D(15, 0, 3), Point3D(15, 15, 3), Point3D(20, 15, 3), Point3D(20, 0, 3))
    pts_3 = (Point3D(0, 5, 3), Point3D(0, 20, 3), Point3D(5, 20, 3), Point3D(5, 5, 3))
    pts_4 = (Point3D(5, 15, 3), Point3D(5, 20, 3), Point3D(20, 20, 3), Point3D(20, 15, 3))
    pts_5 = (Point3D(-5, -5, 3), Point3D(-10, -5, 3), Point3D(-10, -10, 3), Point3D(-5, -10, 3))
    room2d_1 = Room2D('Office1', Face3D(pts_1), 3)
    room2d_2 = Room2D('Office2', Face3D(pts_2), 3)
    room2d_3 = Room2D('Office3', Face3D(pts_3), 3)
    room2d_4 = Room2D('Office4', Face3D(pts_4), 3)
    room2d_5 = Room2D('Office5', Face3D(pts_5), 3)
    int_rms = Room2D.intersect_adjacency(
        [room2d_1, room2d_2, room2d_3, room2d_4, room2d_5], 0.01)
    story = Story('OfficeFloor', int_rms)
    story.rotate_xy(5, Point3D(0, 0, 0))
    story.solve_room_2d_adjacency(0.01)
    story.set_outdoor_window_parameters(SimpleWindowRatio(0.4))
    story.multiplier = 5
    building_mult = Building('OfficeBuilding', [story])

    tree_canopy_geo1 = Face3D.from_regular_polygon(6, 6, Plane(o=Point3D(5, -10, 6)))
    tree_canopy_geo2 = Face3D.from_regular_polygon(6, 2, Plane(o=Point3D(-5, -10, 3)))
    tree_canopy = ContextShade('TreeCanopy', [tree_canopy_geo1, tree_canopy_geo2])

    model = Model('TestGeoJSON', [building, building_big, building_mult], [tree_canopy])

    location = Location('Boston', 'MA', 'USA', 42.366151, -71.019357)
    geojson_folder = './tests/geojson/'
    model.to_geojson(location, folder=geojson_folder)

    geo_fp = os.path.join(
        geojson_folder, model.identifier, '{}.geojson'.format(model.identifier))
    assert os.path.isfile(geo_fp)
    nukedir(os.path.join(geojson_folder, model.identifier), True)
def test_buildings_to_honeybee():
    """Test the buildings_to_honeybee method."""
    pts_1 = (Point3D(0, 0, 3), Point3D(10, 0,
                                       3), Point3D(10, 10,
                                                   3), Point3D(0, 10, 3))
    pts_2 = (Point3D(10, 0, 3), Point3D(20, 0,
                                        3), Point3D(20, 10,
                                                    3), Point3D(10, 10, 3))
    pts_3 = (Point3D(0, 20, 3), Point3D(20, 20,
                                        3), Point3D(20, 30,
                                                    3), Point3D(0, 30, 3))
    room2d_1 = Room2D('Office1', Face3D(pts_1), 3)
    room2d_2 = Room2D('Office2', Face3D(pts_2), 3)
    room2d_3 = Room2D('Office3', Face3D(pts_3), 3)
    story_big = Story('Office_Floor_Big', [room2d_3])
    story = Story('Office_Floor', [room2d_1, room2d_2])
    story.solve_room_2d_adjacency(0.01)
    story.set_outdoor_window_parameters(SimpleWindowRatio(0.4))
    story.multiplier = 4
    building = Building('Office_Building', [story])
    story_big.set_outdoor_window_parameters(SimpleWindowRatio(0.4))
    story_big.multiplier = 4
    building_big = Building('Office_Building_Big', [story_big])

    hb_models = Building.buildings_to_honeybee([building, building_big], None,
                                               None, False)
    assert len(hb_models) == 2
    assert isinstance(hb_models[0], Model)
    assert len(hb_models[0].orphaned_shades) == 4
    assert isinstance(hb_models[-1], Model)
    assert len(hb_models[-1].rooms) == 4
    assert len(hb_models[-1].rooms[-1]) == 6
    assert hb_models[-1].rooms[-1].volume == 600
    assert hb_models[-1].rooms[-1].floor_area == 200
    assert hb_models[-1].rooms[-1].exterior_wall_area == 180

    hb_models = Building.buildings_to_honeybee([building, building_big], None,
                                               5, True)
    assert len(hb_models) == 2
    assert isinstance(hb_models[0], Model)
    assert len(hb_models[0].orphaned_shades) == 0
    assert len(hb_models[0].rooms) == 2
    for room in hb_models[0].rooms:
        assert room.multiplier == 4

    hb_models = Building.buildings_to_honeybee([building, building_big],
                                               cap=True)
    assert len(hb_models) == 2
    assert isinstance(hb_models[0], Model)
    assert len(hb_models[0].orphaned_shades) == 5
def test_to_from_dfpkl_methods():
    """Test the to/from dfpkl methods."""
    pts_1 = (Point3D(0, 0, 3), Point3D(0, 10, 3), Point3D(10, 10, 3), Point3D(10, 0, 3))
    pts_2 = (Point3D(10, 0, 3), Point3D(10, 10, 3), Point3D(20, 10, 3), Point3D(20, 0, 3))
    pts_3 = (Point3D(0, 10, 3), Point3D(0, 20, 3), Point3D(10, 20, 3), Point3D(10, 10, 3))
    pts_4 = (Point3D(10, 10, 3), Point3D(10, 20, 3), Point3D(20, 20, 3), Point3D(20, 10, 3))
    room2d_1 = Room2D('Office1', Face3D(pts_1), 3)
    room2d_2 = Room2D('Office2', Face3D(pts_2), 3)
    room2d_3 = Room2D('Office3', Face3D(pts_3), 3)
    room2d_4 = Room2D('Office4', Face3D(pts_4), 3)
    story = Story('OfficeFloor', [room2d_1, room2d_2, room2d_3, room2d_4])
    story.solve_room_2d_adjacency(0.01)
    story.set_outdoor_window_parameters(SimpleWindowRatio(0.4))
    story.multiplier = 4
    building = Building('OfficeBuilding', [story])

    tree_canopy_geo1 = Face3D.from_regular_polygon(6, 6, Plane(o=Point3D(5, -10, 6)))
    tree_canopy_geo2 = Face3D.from_regular_polygon(6, 2, Plane(o=Point3D(-5, -10, 3)))
    tree_canopy = ContextShade('TreeCanopy', [tree_canopy_geo1, tree_canopy_geo2])

    model = Model('NewDevelopment', [building], [tree_canopy])

    model_dfpkl = model.to_dfpkl('test')
    assert os.path.isfile(model_dfpkl)
    new_model = Model.from_dfpkl(model_dfpkl)
    assert isinstance(new_model, Model)
    os.remove(model_dfpkl)
Example #12
0
def test_set_window_opening():
    """Test the setting of window openings on a Room2D."""
    pts = (Point3D(0, 0, 3), Point3D(10, 0, 3), Point3D(10, 10,
                                                        3), Point3D(0, 10, 3))
    ashrae_base = SimpleWindowRatio(0.4)
    room = Room2D('SquareShoebox', Face3D(pts), 3)
    room.set_outdoor_window_parameters(ashrae_base)

    ventilation = VentilationControl()
    ventilation.min_indoor_temperature = 22
    ventilation.max_indoor_temperature = 28
    ventilation.min_outdoor_temperature = 12
    ventilation.max_outdoor_temperature = 32
    ventilation.delta_temperature = 0

    opening = VentilationOpening()
    opening.fraction_area_operable = 0.25
    opening.fraction_height_operable = 0.5
    opening.wind_cross_vent = True

    room.properties.energy.window_vent_control = ventilation
    room.properties.energy.window_vent_opening = opening

    hb_room, adj = room.to_honeybee()
    assert hb_room.properties.energy.window_vent_control == ventilation
    assert hb_room[1].apertures[0].properties.energy.vent_opening == opening
def test_building_footprint_courtyard():
    """Test the building footprint method with courtyard geometry."""
    pts_1 = (Point3D(0, 0, 3), Point3D(0, 5, 3), Point3D(15, 5,
                                                         3), Point3D(15, 0, 3))
    pts_2 = (Point3D(15, 0, 3), Point3D(15, 15,
                                        3), Point3D(20, 15,
                                                    3), Point3D(20, 0, 3))
    pts_3 = (Point3D(0, 5, 3), Point3D(0, 20, 3), Point3D(5, 20,
                                                          3), Point3D(5, 5, 3))
    pts_4 = (Point3D(5, 15, 3), Point3D(5, 20,
                                        3), Point3D(20, 20,
                                                    3), Point3D(20, 15, 3))
    room2d_1 = Room2D('Office1', Face3D(pts_1), 3)
    room2d_2 = Room2D('Office2', Face3D(pts_2), 3)
    room2d_3 = Room2D('Office3', Face3D(pts_3), 3)
    room2d_4 = Room2D('Office4', Face3D(pts_4), 3)
    int_rms = Room2D.intersect_adjacency(
        [room2d_1, room2d_2, room2d_3, room2d_4], 0.01)
    story = Story('Office_Floor', int_rms)
    story.rotate_xy(5, Point3D(0, 0, 0))
    story.solve_room_2d_adjacency(0.01)
    story.set_outdoor_window_parameters(SimpleWindowRatio(0.4))
    story.multiplier = 4
    building = Building('Office_Building', [story])

    footprint = building.footprint(0.01)
    assert len(footprint) == 1
    assert isinstance(footprint[0], Face3D)
    assert len(footprint[0].boundary) == 8
    assert len(footprint[0].holes) == 1
    assert len(footprint[0].holes[0]) == 4
Example #14
0
def test_from_dict():
    """Test the Story from_dict method with energy properties."""
    pts_1 = (Point3D(0, 0, 3), Point3D(0, 10,
                                       3), Point3D(10, 10,
                                                   3), Point3D(10, 0, 3))
    pts_2 = (Point3D(10, 0, 3), Point3D(10, 10,
                                        3), Point3D(20, 10,
                                                    3), Point3D(20, 0, 3))
    pts_3 = (Point3D(0, 10, 3), Point3D(0, 20,
                                        3), Point3D(10, 20,
                                                    3), Point3D(10, 10, 3))
    pts_4 = (Point3D(10, 10, 3), Point3D(10, 20,
                                         3), Point3D(20, 20,
                                                     3), Point3D(20, 10, 3))
    room2d_1 = Room2D('Office1', Face3D(pts_1), 3)
    room2d_2 = Room2D('Office2', Face3D(pts_2), 3)
    room2d_3 = Room2D('Office3', Face3D(pts_3), 3)
    room2d_4 = Room2D('Office4', Face3D(pts_4), 3)
    story = Story('OfficeFloor', [room2d_1, room2d_2, room2d_3, room2d_4])
    story.solve_room_2d_adjacency(0.01)
    story.set_outdoor_window_parameters(SimpleWindowRatio(0.4))

    mass_set = ConstructionSet('Thermal Mass Construction Set')
    story.properties.energy.construction_set = mass_set

    sd = story.to_dict()
    new_story = Story.from_dict(sd)
    assert new_story.properties.energy.construction_set.identifier == \
        'Thermal Mass Construction Set'
    assert new_story.to_dict() == sd
Example #15
0
def test_to_honeybee_different_heights():
    """Test the to_honeybee method with different floor and ceiling heights."""
    pts_1 = (Point3D(0, 0, 2), Point3D(10, 0, 2), Point3D(10, 10, 2), Point3D(0, 10, 2))
    pts_2 = (Point3D(10, 0, 3), Point3D(20, 0, 3), Point3D(20, 10, 3), Point3D(10, 10, 3))
    room2d_1 = Room2D('Office1', Face3D(pts_1), 5)
    room2d_2 = Room2D('Office2', Face3D(pts_2), 3)
    story = Story('OfficeFloor', [room2d_1, room2d_2])
    story.set_outdoor_window_parameters(SimpleWindowRatio(0.4))
    story.solve_room_2d_adjacency(0.01)

    rooms = story.to_honeybee(True, tolerance=0.01)
    assert len(rooms) == 2
    assert len(rooms[0]) == 8
    assert rooms[0].volume == 500
    assert rooms[0].floor_area == 100
    assert rooms[0].exterior_wall_area >= 150
    assert rooms[0].exterior_aperture_area == pytest.approx(150 * 0.4, rel=1e-3)
    assert rooms[0].average_floor_height == 2
    assert rooms[0].check_solid(0.01, 1)

    assert isinstance(rooms[0][1].boundary_condition, Outdoors)
    assert not isinstance(rooms[0][2].boundary_condition, Surface)  # bottom
    assert isinstance(rooms[0][3].boundary_condition, Surface)  # middle
    assert not isinstance(rooms[0][4].boundary_condition, Surface)  # top

    assert len(rooms[0][3].apertures) == 1
    assert len(rooms[1][4].apertures) == 1
    rm1_ap = rooms[0][3].apertures[0]
    rm2_ap = rooms[1][4].apertures[0]
    assert isinstance(rm1_ap.boundary_condition, Surface)
    assert isinstance(rm2_ap.boundary_condition, Surface)
    assert rm1_ap.area == pytest.approx(rm2_ap.area, rel=1e-3)
Example #16
0
def test_to_honeybee():
    """Test the to_honeybee method."""
    pts_1 = (Point3D(0, 0, 3), Point3D(10, 0, 3), Point3D(10, 10, 3), Point3D(0, 10, 3))
    pts_2 = (Point3D(10, 0, 3), Point3D(20, 0, 3), Point3D(20, 10, 3), Point3D(10, 10, 3))
    room2d_1 = Room2D('Office1', Face3D(pts_1), 3)
    room2d_2 = Room2D('Office2', Face3D(pts_2), 3)
    story = Story('OfficeFloor', [room2d_1, room2d_2])
    story.solve_room_2d_adjacency(0.01)
    story.set_outdoor_window_parameters(SimpleWindowRatio(0.4))

    rooms = story.to_honeybee(0.01)
    assert len(rooms) == 2
    assert len(rooms[0]) == 6
    assert rooms[0].story == story.identifier
    assert rooms[0].multiplier == story.multiplier
    assert rooms[0].volume == 300
    assert rooms[0].floor_area == 100
    assert rooms[0].exterior_wall_area == 90
    assert rooms[0].exterior_aperture_area == pytest.approx(90 * 0.4, rel=1e-3)
    assert rooms[0].average_floor_height == 3
    assert rooms[0].check_solid(0.01, 1)

    assert isinstance(rooms[0][1].boundary_condition, Outdoors)
    assert isinstance(rooms[0][2].boundary_condition, Surface)
    assert rooms[0][2].boundary_condition.boundary_condition_object == \
        rooms[1][4].identifier
    assert len(rooms[0][1].apertures) == 1
    assert len(rooms[0][2].apertures) == 0
Example #17
0
def test_story_init():
    """Test the initialization of Story objects and basic properties."""
    pts_1 = (Point3D(0, 0, 3), Point3D(0, 10, 3), Point3D(10, 10, 3), Point3D(10, 0, 3))
    pts_2 = (Point3D(10, 0, 3), Point3D(10, 10, 3), Point3D(20, 10, 3), Point3D(20, 0, 3))
    pts_3 = (Point3D(0, 10, 3), Point3D(0, 20, 3), Point3D(10, 20, 3), Point3D(10, 10, 3))
    pts_4 = (Point3D(10, 10, 3), Point3D(10, 20, 3), Point3D(20, 20, 3), Point3D(20, 10, 3))
    room2d_1 = Room2D('Office1', Face3D(pts_1), 3)
    room2d_2 = Room2D('Office2', Face3D(pts_2), 3)
    room2d_3 = Room2D('Office3', Face3D(pts_3), 3)
    room2d_4 = Room2D('Office4', Face3D(pts_4), 3)
    story = Story('OfficeFloor', [room2d_1, room2d_2, room2d_3, room2d_4])
    story.solve_room_2d_adjacency(0.01)
    story.set_outdoor_window_parameters(SimpleWindowRatio(0.4))

    str(story)  # test the string representation
    assert story.identifier == 'OfficeFloor'
    assert story.display_name == 'OfficeFloor'
    assert len(story.room_2ds) == 4
    for room in story.room_2ds:
        assert isinstance(room, Room2D)
        assert room.has_parent
    assert story.floor_to_floor_height == 3
    assert story.multiplier == 1
    assert story.parent is None
    assert not story.has_parent
    assert story.floor_height == 3
    assert story.volume == 100 * 3 * 4
    assert story.floor_area == 400
    assert story.exterior_wall_area == 60 * 4
    assert story.exterior_aperture_area == 60 * 4 * 0.4
    assert story.is_above_ground
Example #18
0
def test_set_construction_set():
    """Test the setting of a ConstructionSet on a Room2D."""
    pts = (Point3D(0, 0, 3), Point3D(10, 0, 3), Point3D(10, 10,
                                                        3), Point3D(0, 10, 3))
    ashrae_base = SimpleWindowRatio(0.4)
    overhang = Overhang(1)
    boundarycs = (bcs.outdoors, bcs.ground, bcs.outdoors, bcs.ground)
    window = (ashrae_base, None, ashrae_base, None)
    shading = (overhang, None, None, None)
    room = Room2D('SquareShoebox', Face3D(pts), 3, boundarycs, window, shading)

    mass_set = ConstructionSet('Thermal Mass Construction Set')
    concrete20 = EnergyMaterial('20cm Concrete', 0.2, 2.31, 2322, 832,
                                'MediumRough', 0.95, 0.75, 0.8)
    concrete10 = EnergyMaterial('10cm Concrete', 0.1, 2.31, 2322, 832,
                                'MediumRough', 0.95, 0.75, 0.8)
    thick_constr = OpaqueConstruction('Thick Concrete Construction',
                                      [concrete20])
    thin_constr = OpaqueConstruction('Thin Concrete Construction',
                                     [concrete10])
    shade_constr = ShadeConstruction('Light Shelf', 0.5, 0.5)
    mass_set.wall_set.exterior_construction = thick_constr
    mass_set.roof_ceiling_set.interior_construction = thin_constr
    mass_set.shade_construction = shade_constr

    room.properties.energy.construction_set = mass_set
    assert room.properties.energy.construction_set == mass_set

    hb_room, adj = room.to_honeybee()
    assert hb_room.properties.energy.construction_set == mass_set
    assert hb_room[1].properties.energy.construction == thick_constr
    assert hb_room[5].properties.energy.construction == thin_constr
    assert hb_room[1].shades[0].properties.energy.construction == shade_constr
Example #19
0
def test_from_dict_vent_opening():
    """Test the Room2D from_dict method with ventilation opening energy properties."""
    pts = (Point3D(0, 0, 3), Point3D(10, 0, 3), Point3D(10, 10,
                                                        3), Point3D(0, 10, 3))
    ashrae_base = SimpleWindowRatio(0.4)
    room = Room2D('SquareShoebox', Face3D(pts), 3)
    room.set_outdoor_window_parameters(ashrae_base)

    ventilation = VentilationControl()
    ventilation.min_indoor_temperature = 22
    ventilation.max_indoor_temperature = 28
    ventilation.min_outdoor_temperature = 12
    ventilation.max_outdoor_temperature = 32
    ventilation.delta_temperature = 0

    opening = VentilationOpening()
    opening.fraction_area_operable = 0.25
    opening.fraction_height_operable = 0.5
    opening.wind_cross_vent = True

    room.properties.energy.window_vent_control = ventilation
    room.properties.energy.window_vent_opening = opening

    rd = room.to_dict()
    new_room = Room2D.from_dict(rd)
    assert new_room.to_dict() == rd
Example #20
0
def test_to_dict():
    """Test the Room2D to_dict method with energy properties."""
    mass_set = ConstructionSet('Thermal Mass Construction Set')
    pts = (Point3D(0, 0, 3), Point3D(10, 0, 3), Point3D(10, 10,
                                                        3), Point3D(0, 10, 3))
    ashrae_base = SimpleWindowRatio(0.4)
    overhang = Overhang(1)
    boundarycs = (bcs.outdoors, bcs.ground, bcs.outdoors, bcs.ground)
    window = (ashrae_base, None, ashrae_base, None)
    shading = (overhang, None, None, None)
    room = Room2D('ShoeBoxZone', Face3D(pts), 3, boundarycs, window, shading)

    rd = room.to_dict()
    assert 'properties' in rd
    assert rd['properties']['type'] == 'Room2DProperties'
    assert 'energy' in rd['properties']
    assert rd['properties']['energy']['type'] == 'Room2DEnergyProperties'
    assert 'program_type' not in rd['properties']['energy'] or \
        rd['properties']['energy']['program_type'] is None
    assert 'construction_set' not in rd['properties']['energy'] or \
        rd['properties']['energy']['construction_set'] is None
    assert 'hvac' not in rd['properties']['energy'] or \
        rd['properties']['energy']['hvac'] is None

    room.properties.energy.construction_set = mass_set
    room.properties.energy.program_type = office_program
    rd = room.to_dict()
    assert rd['properties']['energy']['construction_set'] is not None
    assert rd['properties']['energy']['program_type'] is not None
Example #21
0
def test_duplicate():
    """Test what happens to energy properties when duplicating a Room2D."""
    mass_set = ConstructionSet('Thermal Mass Construction Set')
    pts = (Point3D(0, 0, 3), Point3D(10, 0, 3), Point3D(10, 10,
                                                        3), Point3D(0, 10, 3))
    ashrae_base = SimpleWindowRatio(0.4)
    room_original = Room2D('SquareShoebox', Face3D(pts), 3)
    room_original.set_outdoor_window_parameters(ashrae_base)
    room_dup_1 = room_original.duplicate()

    assert room_original.properties.energy.host is room_original
    assert room_dup_1.properties.energy.host is room_dup_1
    assert room_original.properties.energy.host is not \
        room_dup_1.properties.energy.host

    assert room_original.properties.energy.construction_set == \
        room_dup_1.properties.energy.construction_set
    room_dup_1.properties.energy.construction_set = mass_set
    assert room_original.properties.energy.construction_set != \
        room_dup_1.properties.energy.construction_set

    room_dup_2 = room_dup_1.duplicate()

    assert room_dup_1.properties.energy.construction_set == \
        room_dup_2.properties.energy.construction_set
    room_dup_2.properties.energy.construction_set = None
    assert room_dup_1.properties.energy.construction_set != \
        room_dup_2.properties.energy.construction_set
Example #22
0
def test_energy_properties():
    """Test the existence of the Story energy properties."""
    pts_1 = (Point3D(0, 0, 3), Point3D(0, 10,
                                       3), Point3D(10, 10,
                                                   3), Point3D(10, 0, 3))
    pts_2 = (Point3D(10, 0, 3), Point3D(10, 10,
                                        3), Point3D(20, 10,
                                                    3), Point3D(20, 0, 3))
    pts_3 = (Point3D(0, 10, 3), Point3D(0, 20,
                                        3), Point3D(10, 20,
                                                    3), Point3D(10, 10, 3))
    pts_4 = (Point3D(10, 10, 3), Point3D(10, 20,
                                         3), Point3D(20, 20,
                                                     3), Point3D(20, 10, 3))
    room2d_1 = Room2D('Office1', Face3D(pts_1), 3)
    room2d_2 = Room2D('Office2', Face3D(pts_2), 3)
    room2d_3 = Room2D('Office3', Face3D(pts_3), 3)
    room2d_4 = Room2D('Office4', Face3D(pts_4), 3)
    story = Story('OfficeFloor', [room2d_1, room2d_2, room2d_3, room2d_4])
    story.solve_room_2d_adjacency(0.01)
    story.set_outdoor_window_parameters(SimpleWindowRatio(0.4))

    assert hasattr(story.properties, 'energy')
    assert isinstance(story.properties.energy, StoryEnergyProperties)
    assert isinstance(story.properties.energy.construction_set,
                      ConstructionSet)
Example #23
0
def test_to_dict():
    """Test the Story to_dict method with energy properties."""
    mass_set = ConstructionSet('Thermal Mass Construction Set')
    pts_1 = (Point3D(0, 0, 3), Point3D(0, 10,
                                       3), Point3D(10, 10,
                                                   3), Point3D(10, 0, 3))
    pts_2 = (Point3D(10, 0, 3), Point3D(10, 10,
                                        3), Point3D(20, 10,
                                                    3), Point3D(20, 0, 3))
    pts_3 = (Point3D(0, 10, 3), Point3D(0, 20,
                                        3), Point3D(10, 20,
                                                    3), Point3D(10, 10, 3))
    pts_4 = (Point3D(10, 10, 3), Point3D(10, 20,
                                         3), Point3D(20, 20,
                                                     3), Point3D(20, 10, 3))
    room2d_1 = Room2D('Office1', Face3D(pts_1), 3)
    room2d_2 = Room2D('Office2', Face3D(pts_2), 3)
    room2d_3 = Room2D('Office3', Face3D(pts_3), 3)
    room2d_4 = Room2D('Office4', Face3D(pts_4), 3)
    story = Story('OfficeFloor', [room2d_1, room2d_2, room2d_3, room2d_4])
    story.solve_room_2d_adjacency(0.01)
    story.set_outdoor_window_parameters(SimpleWindowRatio(0.4))

    sd = story.to_dict()
    assert 'properties' in sd
    assert sd['properties']['type'] == 'StoryProperties'
    assert 'energy' in sd['properties']
    assert sd['properties']['energy']['type'] == 'StoryEnergyProperties'
    assert 'construction_set' not in sd['properties']['energy'] or \
        sd['properties']['energy']['construction_set'] is None

    story.properties.energy.construction_set = mass_set
    sd = story.to_dict()
    assert sd['properties']['energy']['construction_set'] is not None
def test_building_footprint_simple():
    """Test the building footprint method with simple geometry."""
    pts_1 = (Point3D(0, 0, 3), Point3D(0, 10,
                                       3), Point3D(10, 10,
                                                   3), Point3D(10, 0, 3))
    pts_2 = (Point3D(10, 0, 3), Point3D(10, 10,
                                        3), Point3D(20, 10,
                                                    3), Point3D(20, 0, 3))
    pts_3 = (Point3D(0, 10, 3), Point3D(0, 20,
                                        3), Point3D(10, 20,
                                                    3), Point3D(10, 10, 3))
    pts_4 = (Point3D(10, 10, 3), Point3D(10, 20,
                                         3), Point3D(20, 20,
                                                     3), Point3D(20, 10, 3))
    room2d_1 = Room2D('Office1', Face3D(pts_1), 3)
    room2d_2 = Room2D('Office2', Face3D(pts_2), 3)
    room2d_3 = Room2D('Office3', Face3D(pts_3), 3)
    room2d_4 = Room2D('Office4', Face3D(pts_4), 3)
    story = Story('Office_Floor', [room2d_1, room2d_2, room2d_3, room2d_4])
    story.solve_room_2d_adjacency(0.01)
    story.set_outdoor_window_parameters(SimpleWindowRatio(0.4))
    story.multiplier = 4
    building = Building('Office_Building', [story])

    footprint = building.footprint(0.01)
    assert len(footprint) == 1
    assert isinstance(footprint[0], Face3D)
    assert footprint[0].holes is None
    assert len(footprint[0].vertices) == 8
    assert footprint[0].min == Point3D(0, 0, 3)
    assert footprint[0].max == Point3D(20, 20, 3)
Example #25
0
def test_set_all_room_2d_program_type():
    """Test the set_all_room_2d_program_type method on a Story."""
    pts_1 = (Point3D(0, 0, 3), Point3D(0, 10,
                                       3), Point3D(10, 10,
                                                   3), Point3D(10, 0, 3))
    pts_2 = (Point3D(10, 0, 3), Point3D(10, 10,
                                        3), Point3D(20, 10,
                                                    3), Point3D(20, 0, 3))
    pts_3 = (Point3D(0, 10, 3), Point3D(0, 20,
                                        3), Point3D(10, 20,
                                                    3), Point3D(10, 10, 3))
    pts_4 = (Point3D(10, 10, 3), Point3D(10, 20,
                                         3), Point3D(20, 20,
                                                     3), Point3D(20, 10, 3))
    room2d_1 = Room2D('Office1', Face3D(pts_1), 3)
    room2d_2 = Room2D('Office2', Face3D(pts_2), 3)
    room2d_3 = Room2D('Office3', Face3D(pts_3), 3)
    room2d_4 = Room2D('Office4', Face3D(pts_4), 3)
    story = Story('OfficeFloor', [room2d_1, room2d_2, room2d_3, room2d_4])
    story.solve_room_2d_adjacency(0.01)
    story.set_outdoor_window_parameters(SimpleWindowRatio(0.4))

    lab_program = office_program.duplicate()
    lab_program.identifier = 'Bio Laboratory'
    lab_program.electric_equipment.watts_per_area = 50
    lab_program.ventilation.flow_per_person = 0
    lab_program.ventilation.flow_per_area = 0
    lab_program.ventilation.air_changes_per_hour = 6

    story.properties.energy.set_all_room_2d_program_type(lab_program)

    assert all(room_2d.properties.energy.program_type == lab_program
               for room_2d in story.room_2ds)
Example #26
0
def test_set_all_room_2d_hvac():
    """Test the set_all_room_2d_hvac method on a Building."""
    pts_1 = (Point3D(0, 0, 3), Point3D(0, 10, 3), Point3D(10, 10, 3), Point3D(10, 0, 3))
    pts_2 = (Point3D(10, 0, 3), Point3D(10, 10, 3), Point3D(20, 10, 3), Point3D(20, 0, 3))
    pts_3 = (Point3D(0, 10, 3), Point3D(0, 20, 3), Point3D(10, 20, 3), Point3D(10, 10, 3))
    pts_4 = (Point3D(10, 10, 3), Point3D(10, 20, 3), Point3D(20, 20, 3), Point3D(20, 10, 3))
    room2d_1 = Room2D('Office1', Face3D(pts_1), 3)
    room2d_2 = Room2D('Office2', Face3D(pts_2), 3)
    room2d_3 = Room2D('Office3', Face3D(pts_3), 3)
    room2d_4 = Room2D('Office4', Face3D(pts_4), 3)
    story = Story('OfficeFloor', [room2d_1, room2d_2, room2d_3, room2d_4])
    story.solve_room_2d_adjacency(0.01)
    story.set_outdoor_window_parameters(SimpleWindowRatio(0.4))
    story.multiplier = 4
    building = Building('OfficeBuilding', [story])

    sensible = 0.8
    latent = 0.7
    ideal_air_sys = IdealAirSystem('Office Ideal Air', sensible_heat_recovery=sensible,
                                   latent_heat_recovery=latent)

    building.properties.energy.set_all_room_2d_hvac(ideal_air_sys, False)

    assert all(isinstance(room.properties.energy.hvac, IdealAirSystem)
               for room in building.unique_room_2ds)
    assert all(room.properties.energy.hvac.sensible_heat_recovery == sensible
               for room in building.unique_room_2ds)
    assert all(room.properties.energy.hvac.latent_heat_recovery == latent
               for room in building.unique_room_2ds)
def test_model_properties_setability():
    """Test the setting of properties on the Model."""
    pts_1 = (Point3D(0, 0, 3), Point3D(0, 10, 3), Point3D(10, 10, 3), Point3D(10, 0, 3))
    pts_2 = (Point3D(10, 0, 3), Point3D(10, 10, 3), Point3D(20, 10, 3), Point3D(20, 0, 3))
    pts_3 = (Point3D(0, 10, 3), Point3D(0, 20, 3), Point3D(10, 20, 3), Point3D(10, 10, 3))
    pts_4 = (Point3D(10, 10, 3), Point3D(10, 20, 3), Point3D(20, 20, 3), Point3D(20, 10, 3))
    room2d_1 = Room2D('Office1', Face3D(pts_1), 3)
    room2d_2 = Room2D('Office2', Face3D(pts_2), 3)
    room2d_3 = Room2D('Office3', Face3D(pts_3), 3)
    room2d_4 = Room2D('Office4', Face3D(pts_4), 3)
    story = Story('OfficeFloor', [room2d_1, room2d_2, room2d_3, room2d_4])
    story.solve_room_2d_adjacency(0.01)
    story.set_outdoor_window_parameters(SimpleWindowRatio(0.4))
    story.multiplier = 4
    building = Building('OfficeBuilding', [story])

    model = Model('NewDevelopment', [building])
    model.to_rectangular_windows()

    model.display_name = 'TestBuilding'
    assert model.display_name == 'TestBuilding'
    model.units = 'Feet'
    assert model.units == 'Feet'
    model.tolerance = 0.1
    assert model.tolerance == 0.1
    model.angle_tolerance = 0.01
    assert model.angle_tolerance == 0.01
    model.tolerance = 0.01
    assert model.tolerance == 0.01
def test_to_dict():
    """Test the Building to_dict method."""
    pts_1 = (Point3D(0, 0, 2), Point3D(10, 0,
                                       2), Point3D(10, 10,
                                                   2), Point3D(0, 10, 2))
    pts_2 = (Point3D(10, 0, 3), Point3D(20, 0,
                                        3), Point3D(20, 10,
                                                    3), Point3D(10, 10, 3))
    room2d_1 = Room2D('Office1', Face3D(pts_1), 5)
    room2d_2 = Room2D('Office2', Face3D(pts_2), 3)
    story = Story('Office_Floor', [room2d_1, room2d_2])
    story.solve_room_2d_adjacency(0.01)
    story.set_outdoor_window_parameters(SimpleWindowRatio(0.4))
    story.set_outdoor_shading_parameters(Overhang(1))
    story.multiplier = 4
    building = Building('Office_Building', [story])
    building.separate_top_bottom_floors()

    bd = building.to_dict()
    assert bd['type'] == 'Building'
    assert bd['identifier'] == 'Office_Building'
    assert bd['display_name'] == 'Office_Building'
    assert 'unique_stories' in bd
    assert len(bd['unique_stories']) == 3
    assert 'properties' in bd
    assert bd['properties']['type'] == 'BuildingProperties'
Example #29
0
def test_story_set_outdoor_window_shading_parameters():
    """Test the Story set_outdoor_window_parameters method."""
    pts_1 = (Point3D(0, 0, 3), Point3D(0, 10, 3), Point3D(10, 10, 3), Point3D(10, 0, 3))
    pts_2 = (Point3D(10, 0, 3), Point3D(10, 10, 3), Point3D(20, 10, 3), Point3D(20, 0, 3))
    pts_3 = (Point3D(0, 10, 3), Point3D(0, 20, 3), Point3D(10, 20, 3), Point3D(10, 10, 3))
    pts_4 = (Point3D(10, 10, 3), Point3D(10, 20, 3), Point3D(20, 20, 3), Point3D(20, 10, 3))
    room2d_1 = Room2D('Office1', Face3D(pts_1), 3)
    room2d_2 = Room2D('Office2', Face3D(pts_2), 3)
    room2d_3 = Room2D('Office3', Face3D(pts_3), 3)
    room2d_4 = Room2D('Office4', Face3D(pts_4), 3)
    story = Story('OfficeFloor', [room2d_1, room2d_2, room2d_3, room2d_4])
    story.solve_room_2d_adjacency(0.01)

    ashrae_base = SimpleWindowRatio(0.4)
    overhang = Overhang(1)
    story.set_outdoor_window_parameters(ashrae_base)
    story.set_outdoor_shading_parameters(overhang)

    assert story.room_2ds[0].window_parameters[1] is None
    assert story.room_2ds[0].window_parameters[2] == ashrae_base
    assert story.room_2ds[0].shading_parameters[1] is None
    assert story.room_2ds[0].shading_parameters[2] == overhang

    assert story.exterior_wall_area == 60 * 4
    assert story.exterior_aperture_area == 60 * 4 * 0.4
def story_simple(directory):
    """Generate simple Story sample."""
    mass_set = ConstructionSet('Thermal Mass Construction Set')
    pts_1 = (Point3D(0, 0, 3), Point3D(0, 10,
                                       3), Point3D(10, 10,
                                                   3), Point3D(10, 0, 3))
    pts_2 = (Point3D(10, 0, 3), Point3D(10, 10,
                                        3), Point3D(20, 10,
                                                    3), Point3D(20, 0, 3))
    pts_3 = (Point3D(0, 10, 3), Point3D(0, 20,
                                        3), Point3D(10, 20,
                                                    3), Point3D(10, 10, 3))
    pts_4 = (Point3D(10, 10, 3), Point3D(10, 20,
                                         3), Point3D(20, 20,
                                                     3), Point3D(20, 10, 3))
    room2d_1 = Room2D('Office 1', Face3D(pts_1), 3)
    room2d_2 = Room2D('Office 2', Face3D(pts_2), 3)
    room2d_3 = Room2D('Office 3', Face3D(pts_3), 3)
    room2d_4 = Room2D('Office 4', Face3D(pts_4), 3)
    story = Story('Office Floor', [room2d_1, room2d_2, room2d_3, room2d_4])
    story.solve_room_2d_adjacency(0.01)
    story.set_outdoor_window_parameters(SimpleWindowRatio(0.4))
    story.properties.energy.construction_set = mass_set

    dest_file = os.path.join(directory, 'story_simple.json')
    with open(dest_file, 'w') as fp:
        json.dump(story.to_dict(True), fp, indent=4)