Пример #1
0
def test_group_by_orientation():
    """Test the group_by_orientation method."""
    pts_1 = (Point3D(0, 0), Point3D(15, 0), Point3D(10, 5), Point3D(5, 5))
    pts_2 = (Point3D(15, 0), Point3D(15, 15), Point3D(10, 10), Point3D(10, 5))
    pts_3 = (Point3D(0, 15), Point3D(5, 10), Point3D(10, 10), Point3D(15, 15))
    pts_4 = (Point3D(0, 0), Point3D(5, 5), Point3D(5, 10), Point3D(0, 15))
    pts_5 = (Point3D(5, 5), Point3D(10, 5), Point3D(10, 10), Point3D(5, 10))
    pf_1 = Polyface3D.from_offset_face(Face3D(pts_1), 3)
    pf_2 = Polyface3D.from_offset_face(Face3D(pts_2), 3)
    pf_3 = Polyface3D.from_offset_face(Face3D(pts_3), 3)
    pf_4 = Polyface3D.from_offset_face(Face3D(pts_4), 3)
    pf_5 = Polyface3D.from_offset_face(Face3D(pts_5), 3)
    room_1 = Room.from_polyface3d('Zone1', pf_1)
    room_2 = Room.from_polyface3d('Zone2', pf_2)
    room_3 = Room.from_polyface3d('Zone3', pf_3)
    room_4 = Room.from_polyface3d('Zone4', pf_4)
    room_5 = Room.from_polyface3d('Zone5', pf_5)

    rooms = [room_1, room_2, room_3, room_4, room_5]
    adj_info = Room.solve_adjacency(rooms, 0.01)
    grouped_rooms, core_rooms, orientations = Room.group_by_orientation(rooms)

    assert len(grouped_rooms) == 4
    assert len(core_rooms) == 1
    assert orientations == [0.0, 90.0, 180.0, 270.0]
Пример #2
0
def test_compute_bounding_box_extents_complex():
    """Test the bounding box extents of ladybug_geometry."""
    # South Room 1: 21 x 10.5 x 3
    szone1 = Face3D(
        [Point3D(0, 0),
         Point3D(21, 0),
         Point3D(21, 10.5),
         Point3D(0, 10.5)])
    sroom1 = Room.from_polyface3d('SouthRoom1',
                                  Polyface3D.from_offset_face(szone1, 3))

    # North Room 1: 21 x 10.5 x 3
    nzone1 = Face3D(
        [Point3D(0, 10.5),
         Point3D(21, 10.5),
         Point3D(21, 21),
         Point3D(0, 21)])
    nroom1 = Room.from_polyface3d('NorthRoom1',
                                  Polyface3D.from_offset_face(nzone1, 3))

    # South Room 2: 21 x 10.5 x 3
    szone2 = Face3D([
        Point3D(0, 0, 3),
        Point3D(21, 0, 3),
        Point3D(21, 10.5, 3),
        Point3D(0, 10.5, 3)
    ])
    sroom2 = Room.from_polyface3d('SouthRoom2',
                                  Polyface3D.from_offset_face(szone2, 3))

    # North Room 2: 21 x 10.5 x 3
    nzone2 = Face3D([
        Point3D(0, 10.5, 3),
        Point3D(21, 10.5, 3),
        Point3D(21, 21, 3),
        Point3D(0, 21, 3)
    ])
    nroom2 = Room.from_polyface3d('NorthRoom2',
                                  Polyface3D.from_offset_face(nzone2, 3))

    rooms = [sroom1, nroom1, sroom2, nroom2]
    model = Model('Four_Zone_Simple', rooms)

    # Rotate the buildings
    theta = 30.0
    model.rotate_xy(theta, rooms[0].geometry.vertices[-1])
    geoms = [room.geometry for room in model.rooms]
    xx, yy, zz = bounding_box_extents(geoms, math.radians(theta))

    assert xx == pytest.approx(21, abs=1e-10)
    assert yy == pytest.approx(21, abs=1e-10)
    assert zz == pytest.approx(6, abs=1e-10)
Пример #3
0
def test_to_dict_air_walls():
    """Test the Model to_dict method with a multi-zone house."""
    pts_1 = [Point3D(0, 0), Point3D(30, 0), Point3D(20, 10), Point3D(10, 10)]
    pts_2 = [Point3D(0, 0), Point3D(10, 10), Point3D(10, 20), Point3D(0, 30)]
    pts_3 = [Point3D(10, 20), Point3D(20, 20), Point3D(30, 30), Point3D(0, 30)]
    pts_4 = [Point3D(30, 0), Point3D(30, 30), Point3D(20, 20), Point3D(20, 10)]
    verts = [pts_1, pts_2, pts_3, pts_4]
    rooms = []
    for i, f_vert in enumerate(verts):
        pface = Polyface3D.from_offset_face(Face3D(f_vert), 3)
        room = Room.from_polyface3d('PerimeterRoom{}'.format(i), pface)
        room.properties.energy.program_type = office_program
        room.properties.energy.add_default_ideal_air()
        rooms.append(room)
    rooms.append(Room.from_box('CoreRoom', 10, 10, 3, origin=Point3D(10, 10)))
    adj_info = Room.solve_adjacency(rooms, 0.01)
    for face_pair in adj_info['adjacent_faces']:
        face_pair[0].type = face_types.air_boundary
        face_pair[1].type = face_types.air_boundary

    model = Model('CorePerimeterOfficeFloor', rooms)
    model_dict = model.to_dict()
    assert model_dict['rooms'][-1]['faces'][1]['face_type'] == 'AirBoundary'
    new_model = Model.from_dict(model_dict)
    air_face_type = new_model.rooms[-1].faces[1]
    assert air_face_type.type == face_types.air_boundary
    assert isinstance(air_face_type.properties.energy.construction, AirBoundaryConstruction)

    model_idf_str = model.to.idf(model)
    assert model_idf_str.count('Construction:AirBoundary') == 1
    assert model_idf_str.count('ZoneMixing') == 16
Пример #4
0
def model_complete_office_floor(directory):
    pts_1 = [Point3D(0, 0), Point3D(30, 0), Point3D(20, 10), Point3D(10, 10)]
    pts_2 = [Point3D(0, 0), Point3D(10, 10), Point3D(10, 20), Point3D(0, 30)]
    pts_3 = [Point3D(10, 20), Point3D(20, 20), Point3D(30, 30), Point3D(0, 30)]
    pts_4 = [Point3D(30, 0), Point3D(30, 30), Point3D(20, 20), Point3D(20, 10)]
    verts = [pts_1, pts_2, pts_3, pts_4]
    rooms = []
    for i, f_vert in enumerate(verts):
        pface = Polyface3D.from_offset_face(Face3D(f_vert), 3)
        room = Room.from_polyface3d('PerimeterRoom{}'.format(i), pface)
        room.properties.energy.program_type = prog_type_lib.office_program
        room.properties.energy.add_default_ideal_air()
        rooms.append(room)
    rooms.append(Room.from_box('CoreRoom', 10, 10, 3, origin=Point3D(10, 10)))
    adj_info = Room.solve_adjacency(rooms, 0.01)
    for face_pair in adj_info['adjacent_faces']:
        face_pair[0].type = face_types.air_boundary
        face_pair[1].type = face_types.air_boundary
    for room in rooms:
        for face in room:
            if isinstance(face.type, (Floor, RoofCeiling)):
                face.boundary_condition = boundary_conditions.adiabatic

    model = Model('Core_Perimeter_Office_Floor', rooms)

    dest_file = os.path.join(directory, 'model_complete_office_floor.json')
    with open(dest_file, 'w') as fp:
        json.dump(model.to_dict(), fp, indent=4)
Пример #5
0
def test_polyface3d_init_from_polyface():
    """Test the initalization of room from a Poyface3D."""
    bound_pts = [Point3D(0, 0), Point3D(3, 0), Point3D(3, 3), Point3D(0, 3)]
    hole_pts = [
        Point3D(1, 1, 0),
        Point3D(2, 1, 0),
        Point3D(2, 2, 0),
        Point3D(1, 2, 0)
    ]
    face = Face3D(bound_pts, None, [hole_pts])
    polyface = Polyface3D.from_offset_face(face, 3)
    room = Room.from_polyface3d('Donut Zone', polyface)

    assert room.name == 'DonutZone'
    assert room.display_name == 'Donut Zone'
    assert isinstance(room.geometry, Polyface3D)
    assert len(room.geometry.vertices) == 16
    assert len(room) == 10
    assert room.center == Point3D(1.5, 1.5, 1.5)
    assert room.volume == 24
    assert room.floor_area == 8
    assert room.exposed_area == 56
    assert room.exterior_wall_area == 48
    assert room.exterior_aperture_area == 0
    assert room.average_floor_height == 0
    assert not room.has_parent
    assert room.check_solid(0.01, 1)
Пример #6
0
def test_envelope_components_by_type():

    zone_pts = Face3D([
        Point3D(0, 0, 0),
        Point3D(20, 0, 0),
        Point3D(20, 10, 0),
        Point3D(0, 10, 0)
    ])
    room = Room.from_polyface3d('SouthRoom',
                                Polyface3D.from_offset_face(zone_pts, 3))

    door_pts = [
        Point3D(2, 10, 0.01),
        Point3D(4, 10, 0.01),
        Point3D(4, 10, 2.50),
        Point3D(2, 10, 2.50)
    ]
    door = Door('FrontDoor', Face3D(door_pts))
    room[3].add_door(door)  # Door to north face
    room[1].apertures_by_ratio(0.3)  # Window on south face

    ext_faces, int_faces = room.properties.energy.envelope_components_by_type()

    walls, roofs, floors, apertures, doors = ext_faces

    assert len(walls) == 4
    assert len(roofs) == 1
    assert len(floors) == 0
    assert len(apertures) == 1
    assert len(doors) == 1

    for types in int_faces:
        assert len(types) == 0
Пример #7
0
def test_afn_plenum_zone():
    """Test case where no infiltration load exists."""
    zone_pts = Face3D(
        [Point3D(0, 0),
         Point3D(20, 0),
         Point3D(20, 10),
         Point3D(0, 10)])
    room = Room.from_polyface3d('PlenumRoom',
                                Polyface3D.from_offset_face(zone_pts, 1))
    room.properties.energy.program_type = prog_type_lib.plenum_program

    # Make model
    model = Model('PlenumSimple', [room])

    # generate afn, w/ average leakage
    afn.generate(model.rooms,
                 leakage_type='Medium',
                 use_room_infiltration=True)
    faces = model.faces

    # check ext wall
    crack = faces[1].properties.energy.vent_crack
    chk_cof = CRACK_TEMPLATE_DATA['external_medium_cracks']['wall_flow_cof']
    chk_exp = CRACK_TEMPLATE_DATA['external_medium_cracks']['wall_flow_exp']
    assert crack.flow_coefficient == pytest.approx(chk_cof * faces[1].area,
                                                   abs=1e-10)
    assert crack.flow_exponent == pytest.approx(chk_exp, abs=1e-10)

    # check roof
    crack = faces[5].properties.energy.vent_crack
    chk_cof = CRACK_TEMPLATE_DATA['external_medium_cracks']['roof_flow_cof']
    chk_exp = CRACK_TEMPLATE_DATA['external_medium_cracks']['roof_flow_exp']
    assert crack.flow_coefficient == pytest.approx(chk_cof * faces[5].area,
                                                   abs=1e-10)
    assert crack.flow_exponent == pytest.approx(chk_exp, abs=1e-10)

    # generate afn, w/ tight leakage
    afn.generate(model.rooms,
                 leakage_type='Excellent',
                 use_room_infiltration=False)
    faces = model.faces

    # check ext wall
    crack = faces[1].properties.energy.vent_crack
    chk_cof = CRACK_TEMPLATE_DATA['external_excellent_cracks']['wall_flow_cof']
    chk_exp = CRACK_TEMPLATE_DATA['external_excellent_cracks']['wall_flow_exp']
    assert crack.flow_coefficient == pytest.approx(chk_cof * faces[1].area,
                                                   abs=1e-10)
    assert crack.flow_exponent == pytest.approx(chk_exp, abs=1e-10)

    # check roof
    crack = faces[5].properties.energy.vent_crack
    chk_cof = CRACK_TEMPLATE_DATA['external_excellent_cracks']['roof_flow_cof']
    chk_exp = CRACK_TEMPLATE_DATA['external_excellent_cracks']['roof_flow_exp']
    assert crack.flow_coefficient == pytest.approx(chk_cof * faces[5].area,
                                                   abs=1e-10)
    assert crack.flow_exponent == pytest.approx(chk_exp, abs=1e-10)
Пример #8
0
def model_complete_holes(directory):
    bound_pts = [Point3D(0, 0), Point3D(9, 0), Point3D(9, 9), Point3D(0, 9)]
    hole_pts = [
        Point3D(3, 3, 0),
        Point3D(6, 3, 0),
        Point3D(6, 6, 0),
        Point3D(3, 6, 0)
    ]
    face = Face3D(bound_pts, None, [hole_pts])
    polyface = Polyface3D.from_offset_face(face, 3)
    room = Room.from_polyface3d('DonutZone', polyface)

    ap_bound_pts = [
        Point3D(0.5, 0, 0.5),
        Point3D(2.5, 0, 0.5),
        Point3D(2.5, 0, 2.5),
        Point3D(0.5, 0, 2.5)
    ]
    ap_hole_pts = [
        Point3D(1, 0, 1),
        Point3D(2, 0, 1),
        Point3D(2, 0, 2),
        Point3D(1, 0, 2)
    ]
    ap_face = Face3D(ap_bound_pts, None, [ap_hole_pts])
    ap = Aperture('HoleAperture', ap_face)
    for face in room.faces:
        if face.geometry.is_sub_face(ap_face, 0.01, 1.0):
            face.add_aperture(ap)

    shd_bound_pts = [
        Point3D(0, 0, 6),
        Point3D(9, 0, 6),
        Point3D(9, 9, 6),
        Point3D(0, 9, 6)
    ]
    shd_hole_pts1 = [
        Point3D(2, 2, 6),
        Point3D(4, 2, 6),
        Point3D(4, 4, 6),
        Point3D(2, 4, 6)
    ]
    shd_hole_pts2 = [
        Point3D(5, 5, 6),
        Point3D(7, 5, 6),
        Point3D(7, 7, 6),
        Point3D(5, 7, 6)
    ]
    s_face = Face3D(shd_bound_pts, None, [shd_hole_pts1, shd_hole_pts2])
    shd = Shade('Canopy', s_face)

    model = Model('Donut_Building', [room], orphaned_shades=[shd])

    dest_file = os.path.join(directory, 'model_complete_holes.json')
    with open(dest_file, 'w') as fp:
        json.dump(model.to_dict(), fp, indent=4)
Пример #9
0
def single_family_home(directory):
    poly_file = './scripts/geometry/single_family_geo.json'
    with open(poly_file, 'r') as fp:
        geo_dict = json.load(fp)

    # create the basic Room objects
    program = prog_type_lib.program_type_by_identifier('2013::MidriseApartment::Apartment')
    c_set = constr_set_lib.construction_set_by_identifier('2013::ClimateZone5::SteelFramed')
    rooms = []
    for i, room_geo_dict in enumerate(geo_dict['rooms']):
        room_geo = Polyface3D.from_dict(room_geo_dict)
        room_geo.merge_overlapping_edges(0.01, math.radians(1))
        room = Room.from_polyface3d('House_Room_{}'.format(i), room_geo)
        room.properties.energy.program_type = program
        room.properties.energy.construction_set = c_set
        room.properties.energy.add_default_ideal_air()
        rooms.append(room)

    # make some of the rooms different to make it interesting
    program2 = prog_type_lib.program_type_by_identifier('2013::MidriseApartment::Corridor')
    rooms[6].properties.energy.program_type = program2
    cook_vals = [0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 1.0, 0, 0, 0, 0, 0, 0, 0]
    cook_meals = ScheduleRuleset.from_daily_values('Cooking_Meals', cook_vals)
    kitchen_equip = GasEquipment('Kitchen Stove', 20, cook_meals)
    rooms[0].properties.energy.gas_equipment = kitchen_equip

    # add the apertures to the rooms
    apertures = []
    for i, ap_geo in enumerate(geo_dict['apertures']):
        ap_face = Face3D.from_dict(ap_geo)
        hb_ap = Aperture('House_Aperture_{}'.format(i), ap_face)
        hb_ap.extruded_border(0.3)
        apertures.append(hb_ap)

    # assign apertures and solve adjacency
    for room in rooms:
        for face in room.faces:
            for sf in apertures:
                if face.geometry.is_sub_face(sf.geometry, 0.5, 1.0):
                    face.add_aperture(sf)
    Room.solve_adjacency(rooms, 0.01)

    # load up the context shades
    shades = []
    for i, shd_geo in enumerate(geo_dict['shades']):
        shd_face = Face3D.from_dict(shd_geo)
        shades.append(Shade('Context_Shade_{}'.format(i), shd_face))

    # put it all together in a Model and write out the JSON
    model = Model('Single_Family_Home', rooms=rooms, orphaned_shades=shades,
                  units='Meters', tolerance=0.01, angle_tolerance=1.0)
    dest_file = os.path.join(directory, 'single_family_home.hbjson')
    with open(dest_file, 'w') as fp:
        json.dump(model.to_dict(), fp, indent=4)
Пример #10
0
def test_afn_single_zone_delta_pressure():
    """Test adding afn to single zone with custome delta pressure."""
    zone_pts = Face3D(
        [Point3D(0, 0),
         Point3D(20, 0),
         Point3D(20, 10),
         Point3D(0, 10)])
    room = Room.from_polyface3d('SouthRoom',
                                Polyface3D.from_offset_face(zone_pts, 3))

    # Make model
    room.properties.energy.program_type = prog_type_lib.office_program
    model = Model('Single_Zone_Simple', [room])
    afn.generate(model.rooms, delta_pressure=8)

    # Check that walls have AFNCrack in face
    room = model.rooms[0]
    faces = room.faces

    # Test that no cracks to floors were added
    assert faces[0].properties.energy.vent_crack is None

    # Test that we have cracks in walls
    assert isinstance(faces[1].properties.energy.vent_crack, AFNCrack)
    assert isinstance(faces[2].properties.energy.vent_crack, AFNCrack)
    assert isinstance(faces[3].properties.energy.vent_crack, AFNCrack)
    assert isinstance(faces[4].properties.energy.vent_crack, AFNCrack)
    assert isinstance(faces[5].properties.energy.vent_crack, AFNCrack)

    # Calculate parameters for checks
    qv = room.properties.energy.infiltration.flow_per_exterior_area
    n = 0.65
    dP = 8
    d = afn._air_density_from_pressure()

    # Test flow coefficients and exponents
    for i in range(1, 6):
        # check opaque areas
        chk_cq = (qv * d) / (dP**n) * faces[i].area
        cq = faces[i].properties.energy.vent_crack.flow_coefficient
        n = faces[i].properties.energy.vent_crack.flow_exponent
        assert chk_cq == pytest.approx(cq, abs=1e-10)
        assert 0.65 == pytest.approx(n, abs=1e-10)

    # confirm that auto-calculated flow coefficients produce room.infiltration rate
    total_room_flow = 0
    for i in range(1, 6):
        crack = faces[i].properties.energy.vent_crack
        cq = crack.flow_coefficient
        total_room_flow += cq * (dP**crack.flow_exponent) / d

    chk_infil = total_room_flow / room.exposed_area  # m3/s/m2
    assert qv == pytest.approx(chk_infil, abs=1e-10)
Пример #11
0
def test_afn_multizone_air_boundary():
    """Test adding afn to multiple zones with an AirBoundary between them."""
    # South Room
    szone_pts = Face3D(
        [Point3D(0, 0),
         Point3D(20, 0),
         Point3D(20, 10),
         Point3D(0, 10)])
    sroom = Room.from_polyface3d('SouthRoom',
                                 Polyface3D.from_offset_face(szone_pts, 3))

    # North Room
    nzone_pts = Face3D(
        [Point3D(0, 10),
         Point3D(20, 10),
         Point3D(20, 20),
         Point3D(0, 20)])
    nroom = Room.from_polyface3d('NorthRoom',
                                 Polyface3D.from_offset_face(nzone_pts, 3))

    # Make interior faces
    rooms = [sroom, nroom]
    adj_info = Room.solve_adjacency(rooms, 0.01)
    inter_sface3 = adj_info['adjacent_faces'][0][0]
    inter_nface1 = adj_info['adjacent_faces'][0][1]
    inter_sface3.type = face_types.air_boundary
    inter_nface1.type = face_types.air_boundary

    # Make afn
    afn.generate(rooms)

    sface3_crack = inter_sface3.properties.energy.vent_crack
    nface1_crack = inter_nface1.properties.energy.vent_crack
    assert sface3_crack is not None
    assert nface1_crack is not None
    assert sface3_crack.flow_coefficient > 50  # ensure it's nice and large
    assert nface1_crack.flow_coefficient > 50  # ensure it's nice and large
    assert sface3_crack.flow_exponent == 0.5
    assert nface1_crack.flow_exponent == 0.5
Пример #12
0
def test_remove_colinear_vertices_envelope():
    """Test the remove_colinear_vertices_envelope method."""
    pts_1 = (Point3D(0, 0), Point3D(1, 0), Point3D(2, 0), Point3D(2, 2),
             Point3D(0, 2))
    pf_1 = Polyface3D.from_offset_face(Face3D(pts_1), 3)
    room_1 = Room.from_polyface3d('Zone1', pf_1)
    pts_2 = (Point3D(0.5, 2, 0.5), Point3D(1, 2, 0.5), Point3D(1.5, 2, 0.5),
             Point3D(1.5, 2, 2), Point3D(0.5, 2, 2))
    ap_2 = Aperture('TestAperture1', Face3D(pts_2))
    room_1[-3].add_aperture(ap_2)

    assert len(room_1[0].geometry.vertices) == 5
    assert len(ap_2.geometry.vertices) == 5
    room_1.remove_colinear_vertices_envelope(0.0001)
    assert len(room_1[0].geometry.vertices) == 4
    assert len(ap_2.geometry.vertices) == 4
Пример #13
0
def test_compute_bounding_box_extents_simple():
    """Test the bounding box extents calculation of ladybug_geometry."""
    # South Room 1: 20 x 6 x 3
    szone1 = Face3D(
        [Point3D(-10, -3),
         Point3D(10, -3),
         Point3D(10, 3),
         Point3D(-10, 3)])
    sroom1 = Room.from_polyface3d('SouthRoom1',
                                  Polyface3D.from_offset_face(szone1, 3))
    theta = 90.0
    sroom1.rotate_xy(theta, Point3D(0, 0, 0))
    xx, yy, zz = bounding_box_extents([sroom1.geometry], math.radians(theta))

    assert xx == pytest.approx(20, abs=1e-10)
    assert yy == pytest.approx(6, abs=1e-10)
    assert zz == pytest.approx(3, abs=1e-10)
Пример #14
0
def _rooms_from_footprint(
        footprint, room_ids, unique_id, floor_to_floor_height, orientation_angle,
        story_count, outdoor_roof, ground_floor):
    """Function to convert footprint geometry into full honeybee rooms."""
    # extrude the footprint into solids
    first_floor = [Polyface3D.from_offset_face(geo, floor_to_floor_height)
                   for geo in footprint]

    # rotate the geometries if an orientation angle is specified
    if orientation_angle != 0:
        angle, origin = math.radians(orientation_angle), Point3D()
        first_floor = [geo.rotate_xy(angle, origin) for geo in first_floor]

    # create the initial rooms for the first floor
    rooms = []
    for polyface, rmid in zip(first_floor, room_ids):
        rooms.append(Room.from_polyface3d('{}_{}'.format(rmid, unique_id), polyface))

    # if there are multiple stories, duplicate the first floor rooms
    if story_count != 1:
        all_rooms = []
        for i in range(story_count):
            for room in rooms:
                new_room = room.duplicate()
                new_room.add_prefix('Floor{}'.format(i + 1))
                m_vec = Vector3D(0, 0, floor_to_floor_height * i)
                new_room.move(m_vec)
                all_rooms.append(new_room)
        rooms = all_rooms

    # assign readable names for the display_name (without the UUID)
    for room in rooms:
        room.display_name = room.identifier[:-9]

    # assign adiabatic boundary conditions if requested
    if not outdoor_roof and ad_bc:
        for room in rooms[-len(first_floor):]:
            room[-1].boundary_condition = ad_bc  # make the roof adiabatic
    if not ground_floor and ad_bc:
        for room in rooms[:len(first_floor)]:
            room[0].boundary_condition = ad_bc  # make the floor adiabatic
    return rooms
Пример #15
0
def rectangle_plan(width, length, floor_to_floor_height, perimeter_offset,
                   story_count, orientation_angle, outdoor_roof, ground_floor,
                   units, tolerance, output_file):
    """Create a model with a rectangular floor plan.\n
    Note that the resulting Rooms in the model won't have any windows or solved
    adjacencies and the edit commands should be used for this purpose.\n
    \n
    Args:\n
        width: Number for the width of the plan (in the X direction).\n
        depth: Number for the depth of the plan (in the Y direction).\n
        floor_to_floor_height: Number for the height of each floor of the model
            (in the Z direction).
    """
    try:
        unique_id = str(uuid.uuid4())[:8]  # unique identifier for the rooms

        # create the geometry of the rooms for the first floor
        footprint = Face3D.from_rectangle(width, length)
        if perimeter_offset != 0:  # use the straight skeleton methods
            assert perimeter_offset > 0, 'perimeter_offset cannot be less than than 0.'
            try:
                footprint = []
                base = Polygon2D.from_rectangle(Point2D(), Vector2D(0, 1),
                                                width, length)
                sub_polys_perim, sub_polys_core = perimeter_core_subpolygons(
                    polygon=base, distance=perimeter_offset, tol=tolerance)
                for s_poly in sub_polys_perim + sub_polys_core:
                    sub_face = Face3D(
                        [Point3D(pt.x, pt.y, 0) for pt in s_poly])
                    footprint.append(sub_face)
            except RuntimeError as e:
                footprint = [Face3D.from_rectangle(width, length)]
        else:
            footprint = [Face3D.from_rectangle(width, length)]
        first_floor = [
            Polyface3D.from_offset_face(geo, floor_to_floor_height)
            for geo in footprint
        ]

        # rotate the geometries if an orientation angle is specified
        if orientation_angle != 0:
            angle, origin = math.radians(orientation_angle), Point3D()
            first_floor = [geo.rotate_xy(angle, origin) for geo in first_floor]

        # create the initial rooms for the first floor
        rmids = ['Room'] if len(first_floor) == 1 else [
            'Front', 'Right', 'Back', 'Left'
        ]
        if len(first_floor) == 5:
            rmids.append('Core')
        rooms = []
        for polyface, rmid in zip(first_floor, rmids):
            rooms.append(
                Room.from_polyface3d('{}_{}'.format(rmid, unique_id),
                                     polyface))

        # if there are multiple stories, duplicate the first floor rooms
        if story_count != 1:
            all_rooms = []
            for i in range(story_count):
                for room in rooms:
                    new_room = room.duplicate()
                    new_room.add_prefix('Floor{}'.format(i + 1))
                    m_vec = Vector3D(0, 0, floor_to_floor_height * i)
                    new_room.move(m_vec)
                    all_rooms.append(new_room)
            rooms = all_rooms

        # assign adiabatic boundary conditions if requested
        if not outdoor_roof and ad_bc:
            for room in rooms[-len(first_floor):]:
                room[-1].boundary_condition = ad_bc  # make the roof adiabatic
        if not ground_floor and ad_bc:
            for room in rooms[:len(first_floor)]:
                room[0].boundary_condition = ad_bc  # make the floor adiabatic

        # create the model object
        model_id = 'Rectangle_Plan_Model_{}'.format(unique_id)
        model = Model(model_id,
                      rooms,
                      units=units,
                      tolerance=tolerance,
                      angle_tolerance=1)

        # write the model out to the file or stdout
        output_file.write(json.dumps(model.to_dict()))
    except Exception as e:
        _logger.exception(
            'Rectangle plan model creation failed.\n{}'.format(e))
        sys.exit(1)
    else:
        sys.exit(0)
Пример #16
0
def model_energy_afn_multizone(directory):

    # south Room
    szone_pts = Face3D(
        [Point3D(0, 0),
         Point3D(20, 0),
         Point3D(20, 10),
         Point3D(0, 10)])
    sroom = Room.from_polyface3d('SouthRoom',
                                 Polyface3D.from_offset_face(szone_pts, 3))

    # north Room
    nzone_pts = Face3D(
        [Point3D(0, 10),
         Point3D(20, 10),
         Point3D(20, 20),
         Point3D(0, 20)])
    nroom = Room.from_polyface3d('NorthRoom',
                                 Polyface3D.from_offset_face(nzone_pts, 3))

    # add exterior windows on east/west faces
    sroom[2].apertures_by_ratio(0.3)
    nroom[4].apertures_by_ratio(0.3)
    sroom[2].apertures[0].is_operable = True
    nroom[4].apertures[0].is_operable = True

    # add small interior windows on north/south faces
    sroom[3].apertures_by_ratio(0.15)
    nroom[1].apertures_by_ratio(0.15)
    sroom[3].apertures[0].is_operable = True
    nroom[1].apertures[0].is_operable = True

    # ventilation openings
    vent_openings = VentilationOpening(fraction_area_operable=1,
                                       fraction_height_operable=1,
                                       discharge_coefficient=0.6,
                                       wind_cross_vent=False,
                                       flow_coefficient_closed=0.001,
                                       flow_exponent_closed=0.667,
                                       two_way_threshold=0.0001)

    sroom.properties.energy.assign_ventilation_opening(vent_openings)
    nroom.properties.energy.assign_ventilation_opening(
        vent_openings.duplicate())

    # make ventilation control
    heat_setpt = ScheduleRuleset.from_constant_value(
        'House Heating', 20, schedule_types.temperature)
    cool_setpt = ScheduleRuleset.from_constant_value(
        'House Cooling', 28, schedule_types.temperature)
    setpoint = Setpoint('House Setpoint', heat_setpt, cool_setpt)
    sroom.properties.energy.setpoint = setpoint
    nroom.properties.energy.setpoint = setpoint.duplicate()

    vent_control = VentilationControl(22, 27, 12, 30)
    sroom.properties.energy.window_vent_control = vent_control
    nroom.properties.energy.window_vent_control = vent_control.duplicate()

    # rooms
    rooms = [sroom, nroom]
    for room in rooms:
        # Add program and hvac
        room.properties.energy.program_type = prog_type_lib.office_program

    # make model
    model = Model('Two_Zone_Simple', rooms)
    vsc = VentilationSimulationControl(
        vent_control_type='MultiZoneWithoutDistribution',
        building_type='LowRise',
        long_axis_angle=0,
        aspect_ratio=1)
    model.properties.energy.ventilation_simulation_control = vsc

    # make interior faces
    Room.solve_adjacency(rooms, 0.01)

    # make afn
    afn.generate(model.rooms)

    dest_file = os.path.join(directory, 'model_energy_afn.json')
    with open(dest_file, 'w') as fp:
        json.dump(model.to_dict(included_prop=['energy']), fp, indent=4)
    # set the default roof angle
    roof_angle = _roof_angle_ if _roof_angle_ is not None else 30

    rooms = []  # list of rooms that will be returned
    for i, geo in enumerate(_geo):
        # get the name for the Room
        if len(_name_) == 0:  # make a default Room name
            display_name = 'Room_{}'.format(document_counter('room_count'))
        else:
            display_name = '{}_{}'.format(longest_list(_name_, i), i + 1) \
                if len(_name_) != len(_geo) else longest_list(_name_, i)
        name = clean_and_id_string(display_name)

        # create the Room
        room = Room.from_polyface3d(name,
                                    to_polyface3d(geo),
                                    roof_angle,
                                    ground_depth=tolerance)
        room.display_name = display_name

        # check that the Room geometry is closed.
        if room.check_solid(tolerance, angle_tolerance, False) != '':
            give_warning(
                ghenv.Component, 'Input _geo is not a closed volume.\n'
                'Room volume must be closed to access most honeybee features.\n'
                'Preview the output Room to see the holes in your model.')

        # try to assign the modifier set
        if len(_mod_set_) != 0:
            mod_set = longest_list(_mod_set_, i)
            if isinstance(mod_set, str):
                mod_set = modifier_set_by_identifier(mod_set)
Пример #18
0
def test_afn_multizone():
    """Test adding afn to multiple zones with windows."""
    # South Room
    szone_pts = Face3D(
        [Point3D(0, 0),
         Point3D(20, 0),
         Point3D(20, 10),
         Point3D(0, 10)])
    sroom = Room.from_polyface3d('SouthRoom',
                                 Polyface3D.from_offset_face(szone_pts, 3))

    # North Room
    nzone_pts = Face3D(
        [Point3D(0, 10),
         Point3D(20, 10),
         Point3D(20, 20),
         Point3D(0, 20)])
    nroom = Room.from_polyface3d('NorthRoom',
                                 Polyface3D.from_offset_face(nzone_pts, 3))

    # Add adjacent interior windows
    sroom[3].apertures_by_ratio(0.3)  # Window on south face
    nroom[1].apertures_by_ratio(0.3)  # Window on north face

    # rooms
    rooms = [sroom, nroom]
    for room in rooms:
        # Add program and hvac
        room.properties.energy.program_type = prog_type_lib.office_program

    # Make model
    model = Model('Two_Zone_Simple', rooms)

    # Make interior faces
    adj_info = Room.solve_adjacency(rooms, 0.01)

    inter_sface3 = adj_info['adjacent_faces'][0][0]
    inter_nface1 = adj_info['adjacent_faces'][0][1]
    inter_saper3 = adj_info['adjacent_apertures'][0][0]
    inter_naper1 = adj_info['adjacent_apertures'][0][1]

    # confirm face adjacencies
    assert len(adj_info['adjacent_faces']) == 1
    assert isinstance(inter_sface3.boundary_condition, Surface)
    assert isinstance(inter_nface1.boundary_condition, Surface)

    # confirm aper adjacencies
    assert len(adj_info['adjacent_apertures']) == 1
    assert isinstance(inter_saper3.boundary_condition, Surface)
    assert isinstance(inter_naper1.boundary_condition, Surface)

    # Make afn
    afn.generate(model.rooms)

    # get cracks
    int_cracks = CRACK_TEMPLATE_DATA['internal_medium_cracks']

    # Check internal cracks in adjacent faces
    int_crack = sroom[3].properties.energy.vent_crack
    ref_area = sroom[3].area - sroom[3].apertures[0].area
    assert int_crack.flow_coefficient == pytest.approx(
        int_cracks['wall_flow_cof'] * ref_area, abs=1e-10)
    assert int_crack.flow_exponent == pytest.approx(
        int_cracks['wall_flow_exp'], abs=1e-10)

    int_crack = nroom[1].properties.energy.vent_crack
    assert int_crack.flow_coefficient == pytest.approx(
        int_cracks['wall_flow_cof'] * ref_area, abs=1e-10)
    assert int_crack.flow_exponent == pytest.approx(
        int_cracks['wall_flow_exp'], abs=1e-10)

    # Check that there is only one vent opening for interior walls
    assert isinstance(sroom[3].apertures[0].properties.energy.vent_opening,
                      VentilationOpening)
    assert isinstance(nroom[1].apertures[0].properties.energy.vent_opening,
                      VentilationOpening)

    # confirm that auto-calculated flow coefficients produce room.infiltration rate
    d = afn._air_density_from_pressure()
    dP = 4

    for room in model.rooms:

        total_room_flow = 0
        faces = room.faces
        qv = room.properties.energy.infiltration.flow_per_exterior_area

        for face in faces:
            if isinstance(face.boundary_condition, Outdoors):
                crack = face.properties.energy.vent_crack
                cq = crack.flow_coefficient
                total_room_flow += cq * (dP**crack.flow_exponent) / d

        chk_infil = total_room_flow / room.exposed_area  # m3/s/m2
        assert qv == pytest.approx(chk_infil, abs=1e-10)
Пример #19
0
def test_afn_single_zone():
    """Test adding afn to single zone with window and door."""
    zone_pts = Face3D(
        [Point3D(0, 0),
         Point3D(20, 0),
         Point3D(20, 10),
         Point3D(0, 10)])
    room = Room.from_polyface3d('SouthRoom',
                                Polyface3D.from_offset_face(zone_pts, 3))

    # Add door and window
    door_pts = [
        Point3D(2, 10, 0.01),
        Point3D(4, 10, 0.01),
        Point3D(4, 10, 2.50),
        Point3D(2, 10, 2.50)
    ]
    door = Door('FrontDoor', Face3D(door_pts))
    room[3].add_door(door)  # Door to north face
    room[1].apertures_by_ratio(0.3)  # Window on south face
    room.properties.energy.program_type = prog_type_lib.office_program

    # Make model
    model = Model('Single_Zone_Simple', [room])
    afn.generate(model.rooms)

    # Check that walls have AFNCrack in face
    room = model.rooms[0]
    faces = room.faces

    # Test that no cracks to roofs/floors were added
    assert faces[0].properties.energy.vent_crack is None

    # Test that we have cracks in walls
    assert isinstance(faces[1].properties.energy.vent_crack, AFNCrack)
    assert isinstance(faces[2].properties.energy.vent_crack, AFNCrack)
    assert isinstance(faces[3].properties.energy.vent_crack, AFNCrack)
    assert isinstance(faces[4].properties.energy.vent_crack, AFNCrack)
    assert isinstance(faces[5].properties.energy.vent_crack, AFNCrack)

    # Test that we have ventilation openings
    assert isinstance(faces[1].apertures[0].properties.energy.vent_opening,
                      VentilationOpening)
    assert isinstance(faces[3].doors[0].properties.energy.vent_opening,
                      VentilationOpening)

    # Calculate parameters for checks
    qv = room.properties.energy.infiltration.flow_per_exterior_area
    n = 0.65
    dP = 4
    d = afn._air_density_from_pressure()

    # Test flow coefficients and exponents
    for i in range(1, 6):

        opening_area = 0
        # check openings
        if i == 1 or i == 3:
            if i == 1:
                opening_area = faces[i].apertures[0].area
                vface = faces[i].apertures[0]
            elif i == 3:
                opening_area = faces[i].doors[0].area
                vface = faces[i].doors[0]
            v = vface.properties.energy.vent_opening
            chk_cq = qv * d / (dP**n) * vface.area / vface.perimeter
            cq = v.flow_coefficient_closed
            n = v.flow_exponent_closed
            assert chk_cq == pytest.approx(cq, abs=1e-10)
            assert 0.65 == pytest.approx(n, abs=1e-10)

        # check opaque areas
        chk_cq = qv * d / (dP**n) * (faces[i].area - opening_area)
        cq = faces[i].properties.energy.vent_crack.flow_coefficient
        n = faces[i].properties.energy.vent_crack.flow_exponent
        assert chk_cq == pytest.approx(cq, abs=1e-10)
        assert 0.65 == pytest.approx(n, abs=1e-10)

    # confirm that auto-calculated flow coefficients produce room.infiltration rate
    total_room_flow = 0
    for i in range(1, 6):
        if i == 1 or i == 3:
            if i == 1:
                vface = faces[i].apertures[0]
            elif i == 3:
                vface = faces[i].doors[0]
            v = vface.properties.energy.vent_opening
            cq = v.flow_coefficient_closed * vface.perimeter
            total_room_flow += cq * (dP**v.flow_exponent_closed) / d

        crack = faces[i].properties.energy.vent_crack
        cq = crack.flow_coefficient
        total_room_flow += cq * (dP**crack.flow_exponent) / d

    chk_infil = total_room_flow / room.exposed_area  # m3/s/m2
    assert qv == pytest.approx(chk_infil, abs=1e-10)
Пример #20
0
def test_compute_aspect_ratio():
    """Test calculation of aspect ratio."""
    # South Room: 21 x 21 x 3
    szone_pts = Face3D(
        [Point3D(0, 0),
         Point3D(21, 0),
         Point3D(21, 21),
         Point3D(0, 10)])
    sroom = Room.from_polyface3d('SouthRoom',
                                 Polyface3D.from_offset_face(szone_pts, 3))

    # add detail and create the Model
    rooms = [sroom]
    model = Model('Test_Zone', rooms)

    # autocalculate the aspect ratio
    model.properties.energy.autocalculate_ventilation_simulation_control()
    ar = model.properties.energy.ventilation_simulation_control.aspect_ratio
    assert ar == pytest.approx(1.0, abs=1e-10)
    axis = model.properties.energy.ventilation_simulation_control.long_axis_angle
    assert axis == 0

    # Test lowrise 15 x 21 x 3
    szone_pts = Face3D(
        [Point3D(0, 0),
         Point3D(21, 0),
         Point3D(21, 10),
         Point3D(0, 10)])
    sroom = Room.from_polyface3d('SouthRoom',
                                 Polyface3D.from_offset_face(szone_pts, 3))

    # North Room: 21 x 15 x 3
    nzone_pts = Face3D(
        [Point3D(0, 10),
         Point3D(21, 10),
         Point3D(21, 15),
         Point3D(0, 15)])
    nroom = Room.from_polyface3d('NorthRoom',
                                 Polyface3D.from_offset_face(nzone_pts, 3))

    # add detail and create the model
    rooms = [sroom, nroom]
    model = Model('Test_Zone', rooms)

    # autocalculate the aspect ratio
    model.properties.energy.autocalculate_ventilation_simulation_control()
    ar = model.properties.energy.ventilation_simulation_control.aspect_ratio
    assert ar == pytest.approx(15.0 / 21.0, abs=1e-10)
    axis = model.properties.energy.ventilation_simulation_control.long_axis_angle
    assert axis == 90

    # Test 21 x 22 x 3
    szone_pts = Face3D(
        [Point3D(0, 0),
         Point3D(21, 0),
         Point3D(21, 10.5),
         Point3D(0, 10.5)])
    sroom = Room.from_polyface3d('SouthRoom',
                                 Polyface3D.from_offset_face(szone_pts, 63.1))

    nzone_pts = Face3D(
        [Point3D(0, 10.5),
         Point3D(21, 10.5),
         Point3D(21, 22),
         Point3D(0, 22)])
    nroom = Room.from_polyface3d('NorthRoom',
                                 Polyface3D.from_offset_face(nzone_pts, 3))

    # add detail and create the model
    rooms = [sroom, nroom]
    model = Model('Test_Zone', rooms)

    # autocalculate the aspect ratio
    model.properties.energy.autocalculate_ventilation_simulation_control()
    ar = model.properties.energy.ventilation_simulation_control.aspect_ratio
    assert ar == pytest.approx(21.0 / 22.0, abs=1e-10)
    axis = model.properties.energy.ventilation_simulation_control.long_axis_angle
    assert axis == 0
Пример #21
0
def test_compute_building_type():
    """Test calculation of building type."""
    # Test lowrise: 21 x 21 x 3

    # South Room: 21 x 10.5
    szone_pts = Face3D(
        [Point3D(0, 0),
         Point3D(21, 0),
         Point3D(21, 10.5),
         Point3D(0, 5)])
    sroom = Room.from_polyface3d('SouthRoom',
                                 Polyface3D.from_offset_face(szone_pts, 3))

    # North Room: 21 x 10.5
    nzone_pts = Face3D(
        [Point3D(0, 10.5),
         Point3D(21, 10.5),
         Point3D(21, 21),
         Point3D(0, 21)])
    nroom = Room.from_polyface3d('NorthRoom',
                                 Polyface3D.from_offset_face(nzone_pts, 3))

    # Add detail and create the model
    sroom[3].apertures_by_ratio(0.3)  # Window on south face
    nroom[1].apertures_by_ratio(0.3)  # Window on north face
    rooms = [sroom, nroom]
    model = Model('Test_Zone', rooms)

    # autocalculate the building type
    model.properties.energy.autocalculate_ventilation_simulation_control()
    btype = model.properties.energy.ventilation_simulation_control.building_type
    assert btype == 'LowRise'

    # Test highrise 21 x 21 x 63

    # South Room: 21 x 10.5
    szone_pts = Face3D(
        [Point3D(0, 0),
         Point3D(21, 0),
         Point3D(21, 10.5),
         Point3D(0, 10.5)])
    sroom = Room.from_polyface3d('SouthRoom',
                                 Polyface3D.from_offset_face(szone_pts, 63))

    # North Room: 21 x 10.5
    nzone_pts = Face3D(
        [Point3D(0, 10.5),
         Point3D(21, 10.5),
         Point3D(21, 21),
         Point3D(0, 21)])
    nroom = Room.from_polyface3d('NorthRoom',
                                 Polyface3D.from_offset_face(nzone_pts, 63))

    # Add detail and create the model
    rooms = [sroom, nroom]
    model = Model('Test_Zone', rooms)
    model.rotate_xy(3, rooms[0].geometry.vertices[0])

    # autocalculate the building type
    model.properties.energy.autocalculate_ventilation_simulation_control()
    btype = model.properties.energy.ventilation_simulation_control.building_type
    assert btype == 'LowRise'

    # Test highrise 21 x 21 x 63.1

    # South Room: 21 x 10.5
    szone_pts = Face3D(
        [Point3D(0, 0),
         Point3D(21, 0),
         Point3D(21, 10.5),
         Point3D(0, 10.5)])
    sroom = Room.from_polyface3d('SouthRoom',
                                 Polyface3D.from_offset_face(szone_pts, 63.1))

    # North Room: 21 x 10.5
    nzone_pts = Face3D(
        [Point3D(0, 10.5),
         Point3D(21, 10.5),
         Point3D(21, 21),
         Point3D(0, 21)])
    nroom = Room.from_polyface3d('NorthRoom',
                                 Polyface3D.from_offset_face(nzone_pts, 63.1))

    # Add detail and create the model
    rooms = [sroom, nroom]
    model = Model('Test_Zone', rooms)

    # autocalculate the building type
    model.properties.energy.autocalculate_ventilation_simulation_control()
    btype = model.properties.energy.ventilation_simulation_control.building_type
    assert btype == 'HighRise'