def reflect_state_shades(): """Check to be sure that dynamic shades are reflected with their parent.""" pts = (Point3D(1, 1, 2), Point3D(2, 1, 2), Point3D(2, 2, 2), Point3D(1, 2, 2)) ap = Aperture('TestWindow', Face3D(pts)) pts_1 = (Point3D(0, 0, 0), Point3D(2, 0, 0), Point3D(2, 2, 0), Point3D(0, 2, 0)) shade = StateGeometry('RectangleShade', Face3D(pts_1)) tint1 = RadianceSubFaceState(shades=[shade]) ap.properties.radiance.dynamic_group_identifier = 'ElectrochromicWindow1' ap.properties.radiance.states = [tint1] tint1.gen_geos_from_tmtx_thickness(0.05) new_ap = ap.duplicate() origin_1 = Point3D(1, 0, 2) normal_1 = Vector3D(1, 0, 0) plane_1 = Plane(normal_1, origin_1) new_ap.reflect(plane_1) new_shd = new_ap.properties.radiance.states[0].shades[0] assert new_shd.geometry[-1].x == pytest.approx(1, rel=1e-3) assert new_shd.geometry[-1].y == pytest.approx(1, rel=1e-3) assert new_shd.geometry[-1].z == pytest.approx(2, rel=1e-3) assert new_shd.geometry[1].x == pytest.approx(0, rel=1e-3) assert new_shd.geometry[1].y == pytest.approx(2, rel=1e-3) assert new_shd.geometry[1].z == pytest.approx(2, rel=1e-3)
def test_check_duplicate_construction_names(): """Test the check_duplicate_construction_names method.""" room = Room.from_box('Tiny House Zone', 5, 10, 3) stone = EnergyMaterial('Thick Stone', 0.3, 2.31, 2322, 832, 'Rough', 0.95, 0.75, 0.8) thermal_mass_constr = OpaqueConstruction('Custom Construction', [stone]) room[0].properties.energy.construction = thermal_mass_constr north_face = room[1] aperture_verts = [ Point3D(4.5, 10, 1), Point3D(2.5, 10, 1), Point3D(2.5, 10, 2.5), Point3D(4.5, 10, 2.5) ] aperture = Aperture('Front Aperture', Face3D(aperture_verts)) aperture.is_operable = True triple_pane = WindowConstruction( 'Custom Window Construction', [clear_glass, air_gap, clear_glass, air_gap, clear_glass]) aperture.properties.energy.construction = triple_pane north_face.add_aperture(aperture) model = Model('Tiny House', [room]) assert model.properties.energy.check_duplicate_construction_names(False) triple_pane.unlock() triple_pane.name = 'Custom Construction' triple_pane.lock() assert not model.properties.energy.check_duplicate_construction_names( False) with pytest.raises(ValueError): model.properties.energy.check_duplicate_construction_names(True)
def test_default_constructions(): """Test the auto-assigning of constructions by boundary condition.""" vertices_parent_wall = [[0, 0, 0], [0, 10, 0], [0, 10, 3], [0, 0, 3]] vertices_parent_wall_2 = list(reversed(vertices_parent_wall)) vertices_wall = [[0, 1, 0], [0, 2, 0], [0, 2, 2], [0, 0, 2]] vertices_wall_2 = list(reversed(vertices_wall)) vertices_floor = [[0, 0, 0], [0, 10, 0], [10, 10, 0], [10, 0, 0]] vertices_roof = [[10, 0, 3], [10, 10, 3], [0, 10, 3], [0, 0, 3]] wf = Face.from_vertices('wall face', vertices_parent_wall) wa = Aperture.from_vertices('wall window', vertices_wall) wf.add_aperture(wa) Room('Test Room 1', [wf]) assert wa.properties.energy.construction.name == 'Generic Double Pane' wf2 = Face.from_vertices('wall face2', vertices_parent_wall_2) wa2 = Aperture.from_vertices('wall window2', vertices_wall_2) wf2.add_aperture(wa2) Room('Test Room 2', [wf2]) wa.set_adjacency(wa2) assert wa.properties.energy.construction.name == 'Generic Single Pane' ra = Aperture.from_vertices('roof window', vertices_roof) assert ra.properties.energy.construction.name == 'Generic Double Pane' fa = Aperture.from_vertices('floor window', vertices_floor) assert fa.properties.energy.construction.name == 'Generic Double Pane'
def test_check_duplicate_modifier_identifiers(): """Test the check_duplicate_modifier_identifiers method.""" room = Room.from_box('Tiny_House_Zone', 5, 10, 3) high_ref_ceil = Plastic.from_single_reflectance('CustomModifier', 0.9) room[-1].properties.radiance.modifier = high_ref_ceil north_face = room[1] aperture_verts = [Point3D(4.5, 10, 1), Point3D(2.5, 10, 1), Point3D(2.5, 10, 2.5), Point3D(4.5, 10, 2.5)] aperture = Aperture('Front_Aperture', Face3D(aperture_verts)) aperture.is_operable = True triple_pane = Glass.from_single_transmittance('CustomTriplePane', 0.3) aperture.properties.radiance.modifier = triple_pane north_face.add_aperture(aperture) model = Model('Tiny_House', [room]) assert model.properties.radiance.check_duplicate_modifier_identifiers(False) == '' triple_pane.unlock() triple_pane.identifier = 'CustomModifier' triple_pane.lock() assert model.properties.radiance.check_duplicate_modifier_identifiers(False) != '' with pytest.raises(ValueError): model.properties.radiance.check_duplicate_modifier_identifiers(True)
def test_sub_faces_invalid(): """Test the adding and removing of invalid sub-faces.""" face_face3d = Face3D.from_rectangle(10, 10, Plane(o=Point3D(0, 0, 3))) ap_face3d = Face3D.from_rectangle(2, 2, Plane(o=Point3D(2, 2, 3))) dr_face3d = Face3D.from_rectangle(2, 2, Plane(o=Point3D(7, 7, 3))) dr_face3d_invalid_1 = Face3D.from_rectangle(2, 2, Plane(o=Point3D(7, 7, 1))) dr_face3d_invalid_2 = \ Face3D([Point3D(0, 0, 0), Point3D(0, 1, 0), Point3D(0, 1, 3), Point3D(0, 0, 3)]) face = Face('Test_Roof', face_face3d) aperture = Aperture('Test_Skylight', ap_face3d) door = Door('Test_Trap_Door', dr_face3d) invalid_aperture_1 = Aperture('Test_Skylight', dr_face3d_invalid_1) invalid_aperture_2 = Aperture('Test_Skylight', dr_face3d_invalid_2) with pytest.raises(AssertionError): face.add_aperture(door) with pytest.raises(AssertionError): face.add_door(aperture) face.add_aperture(invalid_aperture_1) with pytest.raises(ValueError): face.check_apertures_valid(0.01, 1) face.remove_apertures() face.add_aperture(invalid_aperture_2) with pytest.raises(ValueError): face.check_apertures_valid(0.01, 1)
def test_rotate(): """Test the Aperture rotate method.""" pts = (Point3D(0, 0, 2), Point3D(2, 0, 2), Point3D(2, 2, 2), Point3D(0, 2, 2)) plane = Plane(Vector3D(0, 0, 1), Point3D(0, 0, 2)) aperture = Aperture('RectangleWindow', Face3D(pts, plane)) origin = Point3D(0, 0, 0) axis = Vector3D(1, 0, 0) test_1 = aperture.duplicate() test_1.rotate(axis, 180, origin) assert test_1.geometry[0].x == pytest.approx(0, rel=1e-3) assert test_1.geometry[0].y == pytest.approx(0, rel=1e-3) assert test_1.geometry[0].z == pytest.approx(-2, rel=1e-3) assert test_1.geometry[2].x == pytest.approx(2, rel=1e-3) assert test_1.geometry[2].y == pytest.approx(-2, rel=1e-3) assert test_1.geometry[2].z == pytest.approx(-2, rel=1e-3) assert aperture.area == test_1.area assert len(aperture.vertices) == len(test_1.vertices) test_2 = aperture.duplicate() test_2.rotate(axis, 90, origin) assert test_2.geometry[0].x == pytest.approx(0, rel=1e-3) assert test_2.geometry[0].y == pytest.approx(-2, rel=1e-3) assert test_2.geometry[0].z == pytest.approx(0, rel=1e-3) assert test_2.geometry[2].x == pytest.approx(2, rel=1e-3) assert test_2.geometry[2].y == pytest.approx(-2, rel=1e-3) assert test_2.geometry[2].z == pytest.approx(2, rel=1e-3) assert aperture.area == test_2.area assert len(aperture.vertices) == len(test_2.vertices)
def test_rotate_xy(): """Test the Aperture rotate_xy method.""" pts = (Point3D(1, 1, 2), Point3D(2, 1, 2), Point3D(2, 2, 2), Point3D(1, 2, 2)) plane = Plane(Vector3D(0, 0, 1), Point3D(0, 0, 2)) aperture = Aperture('RectangleWindow', Face3D(pts, plane)) origin_1 = Point3D(1, 1, 0) test_1 = aperture.duplicate() test_1.rotate_xy(180, origin_1) assert test_1.geometry[0].x == pytest.approx(1, rel=1e-3) assert test_1.geometry[0].y == pytest.approx(1, rel=1e-3) assert test_1.geometry[0].z == pytest.approx(2, rel=1e-3) assert test_1.geometry[2].x == pytest.approx(0, rel=1e-3) assert test_1.geometry[2].y == pytest.approx(0, rel=1e-3) assert test_1.geometry[2].z == pytest.approx(2, rel=1e-3) test_2 = aperture.duplicate() test_2.rotate_xy(90, origin_1) assert test_2.geometry[0].x == pytest.approx(1, rel=1e-3) assert test_2.geometry[0].y == pytest.approx(1, rel=1e-3) assert test_1.geometry[0].z == pytest.approx(2, rel=1e-3) assert test_2.geometry[2].x == pytest.approx(0, rel=1e-3) assert test_2.geometry[2].y == pytest.approx(2, rel=1e-3) assert test_1.geometry[2].z == pytest.approx(2, rel=1e-3)
def test_default_modifiers(): """Test the auto-assigning of modifiers by face type and boundary condition.""" vertices_parent_wall = [[0, 0, 0], [0, 10, 0], [0, 10, 3], [0, 0, 3]] vertices_parent_wall_2 = list(reversed(vertices_parent_wall)) vertices_wall = [[0, 1, 0], [0, 2, 0], [0, 2, 2], [0, 0, 2]] vertices_wall_2 = list(reversed(vertices_wall)) vertices_floor = [[0, 0, 0], [0, 10, 0], [10, 10, 0], [10, 0, 0]] vertices_roof = [[10, 0, 3], [10, 10, 3], [0, 10, 3], [0, 0, 3]] wf = Face.from_vertices('wall_face', vertices_parent_wall) wa = Aperture.from_vertices('wall_window', vertices_wall) wf.add_aperture(wa) Room('TestRoom1', [wf]) assert wa.properties.radiance.modifier == generic_exterior_window wf2 = Face.from_vertices('wall_face2', vertices_parent_wall_2) wa2 = Aperture.from_vertices('wall_window2', vertices_wall_2) wf2.add_aperture(wa2) Room('TestRoom2', [wf2]) wa.set_adjacency(wa2) assert wa.properties.radiance.modifier == generic_interior_window ra = Aperture.from_vertices('roof_window', vertices_roof) assert ra.properties.radiance.modifier == generic_exterior_window fa = Aperture.from_vertices('floor_window', vertices_floor) assert fa.properties.radiance.modifier == generic_exterior_window
def test_to_from_dict_with_states(): """Test the Aperture from_dict method with radiance properties.""" ap = Aperture.from_vertices( 'wall_aperture', [[0, 0, 0], [10, 0, 0], [10, 0, 10], [0, 0, 10]]) shd1 = StateGeometry.from_vertices( 'wall_overhang1', [[0, 0, 10], [10, 0, 10], [10, 2, 10], [0, 2, 10]]) shd2 = StateGeometry.from_vertices( 'wall_overhang2', [[0, 0, 5], [10, 0, 5], [10, 2, 5], [0, 2, 5]]) ecglass1 = Glass.from_single_transmittance('ElectrochromicState1', 0.4) ecglass2 = Glass.from_single_transmittance('ElectrochromicState2', 0.27) ecglass3 = Glass.from_single_transmittance('ElectrochromicState3', 0.14) ecglass4 = Glass.from_single_transmittance('ElectrochromicState4', 0.01) tint1 = RadianceSubFaceState(ecglass1) tint2 = RadianceSubFaceState(ecglass2) tint3 = RadianceSubFaceState(ecglass3, [shd1]) tint4 = RadianceSubFaceState(ecglass4, [shd1.duplicate(), shd2]) states = (tint1, tint2, tint3, tint4) ap.properties.radiance.dynamic_group_identifier = 'ElectrochromicWindow1' ap.properties.radiance.states = states tint4.gen_geos_from_tmtx_thickness(0.05) ad = ap.to_dict() new_aperture = Aperture.from_dict(ad) assert new_aperture.properties.radiance.dynamic_group_identifier == \ ap.properties.radiance.dynamic_group_identifier state_ids1 = [state.modifier for state in states] state_ids2 = [ state.modifier for state in new_aperture.properties.radiance.states ] assert state_ids1 == state_ids2 assert new_aperture.to_dict() == ad
def test_to_from_dict(): """Test the to/from dict of Aperture objects.""" vertices = [[0, 0, 0], [0, 10, 0], [0, 10, 3], [0, 0, 3]] ap = Aperture.from_vertices('RectangleWindow', vertices) ap_dict = ap.to_dict() new_ap = Aperture.from_dict(ap_dict) assert isinstance(new_ap, Aperture) assert new_ap.to_dict() == ap_dict
def test_to_from_dict(): """Test the Model to_dict and from_dict method with a single zone model.""" room = Room.from_box('Tiny_House_Room', 5, 10, 3) dark_floor = Plastic.from_single_reflectance('DarkFloor', 0.1) room[0].properties.radiance.modifier = dark_floor south_face = room[3] south_face.apertures_by_ratio(0.4, 0.01) south_face.apertures[0].overhang(0.5, indoor=False) south_face.apertures[0].overhang(0.5, indoor=True) south_face.apertures[0].move_shades(Vector3D(0, 0, -0.5)) light_shelf_out = Plastic.from_single_reflectance('OutdoorLightShelf', 0.5) light_shelf_in = Plastic.from_single_reflectance('IndoorLightShelf', 0.7) south_face.apertures[0].shades[0].properties.radiance.modifier = light_shelf_out south_face.apertures[0].shades[1].properties.radiance.modifier = light_shelf_in north_face = room[1] door_verts = [Point3D(2, 10, 0.1), Point3D(1, 10, 0.1), Point3D(1, 10, 2.5), Point3D(2, 10, 2.5)] door = Door('FrontDoor', Face3D(door_verts)) north_face.add_door(door) aperture_verts = [Point3D(4.5, 10, 1), Point3D(2.5, 10, 1), Point3D(2.5, 10, 2.5), Point3D(4.5, 10, 2.5)] aperture = Aperture('FrontAperture', Face3D(aperture_verts)) aperture.is_operable = True triple_pane = Glass.from_single_transmittance('CustomTriplePane', 0.3) aperture.properties.radiance.modifier = triple_pane north_face.add_aperture(aperture) tree_canopy_geo = Face3D.from_regular_polygon( 6, 2, Plane(Vector3D(0, 0, 1), Point3D(5, -3, 4))) tree_canopy = Shade('TreeCanopy', tree_canopy_geo) tree_trans = Glass.from_single_transmittance('TreeTransmittance', 0.75) tree_canopy.properties.radiance.modifier = tree_trans model = Model('TinyHouse', [room], orphaned_shades=[tree_canopy]) model_dict = model.to_dict(included_prop=['radiance']) new_model = Model.from_dict(model_dict) assert model_dict == new_model.to_dict(included_prop=['radiance']) assert dark_floor in new_model.properties.radiance.modifiers assert new_model.rooms[0][0].properties.radiance.modifier == dark_floor assert new_model.rooms[0][3].apertures[0].indoor_shades[0].properties.radiance.modifier == light_shelf_in assert new_model.rooms[0][3].apertures[0].outdoor_shades[0].properties.radiance.modifier == light_shelf_out assert triple_pane in new_model.properties.radiance.modifiers assert new_model.rooms[0][1].apertures[0].properties.radiance.modifier == triple_pane assert new_model.rooms[0][1].apertures[0].is_operable assert len(new_model.orphaned_shades) == 1 assert new_model.rooms[0][0].type == face_types.floor assert new_model.rooms[0][1].type == face_types.wall assert isinstance(new_model.rooms[0][0].boundary_condition, Ground) assert isinstance(new_model.rooms[0][1].boundary_condition, Outdoors) assert new_model.orphaned_shades[0].properties.radiance.modifier == tree_trans
def test_aperture_louvers_by_distance_between(): """Test the creation of a louvers_by_distance_between for Aperture objects.""" pts_1 = (Point3D(0, 0, 0), Point3D(0, 0, 3), Point3D(5, 0, 3), Point3D(5, 0, 0)) aperture = Aperture('Rectangle Window', Face3D(pts_1)) aperture.louvers_by_distance_between(0.5, 0.2, 0.1) assert len(aperture.outdoor_shades) == 6 for louver in aperture.outdoor_shades: assert isinstance(louver, Shade) assert louver.area == 5 * 0.2
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)
def test_to_from_dict(): """Test the Aperture from_dict method with states.""" aperture = Aperture.from_vertices( 'wall_aperture', [[0, 0, 0], [10, 0, 0], [10, 0, 10], [0, 0, 10]]) triple_pane = Glass.from_single_transmittance('TriplePane', 0.45) aperture.properties.radiance.modifier = triple_pane ad = aperture.to_dict() new_aperture = Aperture.from_dict(ad) assert new_aperture.properties.radiance.modifier == triple_pane assert new_aperture.to_dict() == ad
def test_aperture_louvers_by_count(): """Test the creation of a louvers_by_count for Face objects.""" pts_1 = (Point3D(0, 0, 0), Point3D(0, 0, 3), Point3D(5, 0, 3), Point3D(5, 0, 0)) aperture = Aperture('RectangleWindow', Face3D(pts_1)) aperture.louvers_by_count(3, 0.2, 0.1, 5) assert len(aperture.outdoor_shades) == 3 for louver in aperture.outdoor_shades: assert isinstance(louver, Shade) assert louver.area == 5 * 0.2 assert louver.has_parent
def test_set_states(): """Test the setting of states on an Aperture.""" pts = (Point3D(0, 0, 0), Point3D(0, 0, 3), Point3D(1, 0, 3), Point3D(1, 0, 0)) ap = Aperture('TestWindow', Face3D(pts)) shd1 = StateGeometry.from_vertices( 'wall_overhang1', [[0, 0, 10], [10, 0, 10], [10, 2, 10], [0, 2, 10]]) shd2 = StateGeometry.from_vertices( 'wall_overhang2', [[0, 0, 5], [10, 0, 5], [10, 2, 5], [0, 2, 5]]) ecglass1 = Glass.from_single_transmittance('ElectrochromicState1', 0.4) ecglass2 = Glass.from_single_transmittance('ElectrochromicState2', 0.27) ecglass3 = Glass.from_single_transmittance('ElectrochromicState3', 0.14) ecglass4 = Glass.from_single_transmittance('ElectrochromicState4', 0.01) tint1 = RadianceSubFaceState(ecglass1) tint2 = RadianceSubFaceState(ecglass2) tint3 = RadianceSubFaceState(ecglass3) tint4 = RadianceSubFaceState(ecglass4) states = (tint1, tint2, tint3, tint4) tint3.add_shade(shd1) with pytest.raises(AssertionError): tint4.add_shades([shd1, shd2]) tint4.add_shades([shd1.duplicate(), shd2]) with pytest.raises(AssertionError): tint1.gen_geos_from_tmtx_thickness(0.05) with pytest.raises(AssertionError): tint1.gen_geo_from_vmtx_offset(0.1) with pytest.raises(AssertionError): tint1.gen_geo_from_dmtx_offset(0.1) with pytest.raises(AssertionError): ap.properties.radiance.states = states ap.properties.radiance.dynamic_group_identifier = 'ElectrochromicWindow1' ap.properties.radiance.states = states for state in ap.properties.radiance.states: assert state.parent.identifier == 'TestWindow' new_ap = ap.duplicate() assert ap.properties.radiance.dynamic_group_identifier == \ new_ap.properties.radiance.dynamic_group_identifier == 'ElectrochromicWindow1' assert len(new_ap.properties.radiance.states) == 4 for i, state in enumerate(new_ap.properties.radiance.states): assert state.modifier.identifier == 'ElectrochromicState{}'.format(i + 1) assert len(new_ap.properties.radiance.states[2].shades) == 1 assert len(new_ap.properties.radiance.states[3].shades) == 2
def test_aperture_duplicate(): """Test the duplication of Aperture objects.""" pts = (Point3D(0, 0, 0), Point3D(0, 0, 3), Point3D(5, 0, 3), Point3D(5, 0, 0)) ap_1 = Aperture('Test Window', Face3D(pts)) ap_2 = ap_1.duplicate() assert ap_1 is not ap_2 for i, pt in enumerate(ap_1.vertices): assert pt == ap_2.vertices[i] assert ap_1.name == ap_2.name ap_2.move(Vector3D(0, 1, 0)) for i, pt in enumerate(ap_1.vertices): assert pt != ap_2.vertices[i]
def test_face_duplicate(): """Test the duplication of Face objects.""" pts = (Point3D(0, 0, 0), Point3D(0, 0, 3), Point3D(5, 0, 3), Point3D(5, 0, 0)) face_1 = Aperture('Test Face', Face3D(pts)) face_2 = face_1.duplicate() assert face_1 is not face_2 for i, pt in enumerate(face_1.vertices): assert pt == face_2.vertices[i] assert face_1.name == face_2.name face_2.move(Vector3D(0, 1, 0)) for i, pt in enumerate(face_1.vertices): assert pt != face_2.vertices[i]
def test_scale(): """Test the Aperture scale method.""" pts = (Point3D(1, 1, 2), Point3D(2, 1, 2), Point3D(2, 2, 2), Point3D(1, 2, 2)) plane = Plane(Vector3D(0, 0, 1), Point3D(0, 0, 2)) aperture = Aperture('Rectangle Window', Face3D(pts, plane)) new_ap = aperture.duplicate() new_ap.scale(2) assert new_ap.geometry[0] == Point3D(2, 2, 4) assert new_ap.geometry[1] == Point3D(4, 2, 4) assert new_ap.geometry[2] == Point3D(4, 4, 4) assert new_ap.geometry[3] == Point3D(2, 4, 4) assert new_ap.area == aperture.area * 2 ** 2 assert new_ap.perimeter == aperture.perimeter * 2 assert new_ap.normal == aperture.normal
def test_from_dict(): """Test the Aperture from_dict method with energy properties.""" aperture = Aperture.from_vertices( 'wall_window', [[0, 0, 0], [10, 0, 0], [10, 0, 10], [0, 0, 10]]) clear_glass = EnergyWindowMaterialGlazing('Clear Glass', 0.005715, 0.770675, 0.07, 0.8836, 0.0804, 0, 0.84, 0.84, 1.0) gap = EnergyWindowMaterialGas('air gap', thickness=0.0127) triple_pane = WindowConstruction( 'Triple Pane', [clear_glass, gap, clear_glass, gap, clear_glass]) aperture.properties.energy.construction = triple_pane ad = aperture.to_dict() new_aperture = Aperture.from_dict(ad) assert new_aperture.properties.energy.construction == triple_pane assert new_aperture.to_dict() == ad
def test_scale(): """Test the Model scale method.""" room = Room.from_box('Tiny House Zone', 5, 10, 3) south_face = room[3] south_face.apertures_by_ratio(0.4, 0.01) south_face.apertures[0].overhang(0.5, indoor=False) south_face.apertures[0].overhang(0.5, indoor=True) south_face.apertures[0].move_shades(Vector3D(0, 0, -0.5)) north_face = room[1] door_verts = [Point3D(2, 10, 0.1), Point3D(1, 10, 0.1), Point3D(1, 10, 2.5), Point3D(2, 10, 2.5)] aperture_verts = [Point3D(4.5, 10, 1), Point3D(2.5, 10, 1), Point3D(2.5, 10, 2.5), Point3D(4.5, 10, 2.5)] door = Door('Front Door', Face3D(door_verts)) north_face.add_door(door) aperture = Aperture('Front Aperture', Face3D(aperture_verts)) north_face.add_aperture(aperture) new_room = room.duplicate() model = Model('Tiny House', [new_room]) model.scale(0.5) assert room.floor_area == model.rooms[0].floor_area * 2 ** 2 assert room.volume == model.rooms[0].volume * 2 ** 3 assert south_face.apertures[0].indoor_shades[0].area == \ model.rooms[0][3].apertures[0].indoor_shades[0].area * 2 ** 2 assert south_face.apertures[0].outdoor_shades[0].area == \ model.rooms[0][3].apertures[0].outdoor_shades[0].area * 2 ** 2 assert room[3].apertures[0].area == model.rooms[0][3].apertures[0].area * 2 ** 2 assert room[1].doors[0].area == model.rooms[0][1].doors[0].area * 2 ** 2
def test_to_hbpkl(): """Test the Model to_hbpkl method.""" room = Room.from_box('TinyHouseZone', 5, 10, 3) south_face = room[3] south_face.apertures_by_ratio(0.4, 0.01) south_face.apertures[0].overhang(0.5, indoor=False) south_face.apertures[0].overhang(0.5, indoor=True) south_face.apertures[0].move_shades(Vector3D(0, 0, -0.5)) north_face = room[1] door_verts = [ Point3D(2, 10, 0.1), Point3D(1, 10, 0.1), Point3D(1, 10, 2.5), Point3D(2, 10, 2.5) ] aperture_verts = [ Point3D(4.5, 10, 1), Point3D(2.5, 10, 1), Point3D(2.5, 10, 2.5), Point3D(4.5, 10, 2.5) ] door = Door('FrontDoor', Face3D(door_verts)) north_face.add_door(door) aperture = Aperture('FrontAperture', Face3D(aperture_verts)) north_face.add_aperture(aperture) model = Model('TinyHouse', [room]) path = './tests/json' model_hbpkl = model.to_hbpkl('test', path) assert os.path.isfile(model_hbpkl) new_model = Model.from_hbpkl(model_hbpkl) assert isinstance(new_model, Model) os.remove(model_hbpkl)
def test_duplicate(): """Test what happens to radiance properties when duplicating a Aperture.""" verts = [ Point3D(0, 0, 0), Point3D(10, 0, 0), Point3D(10, 0, 10), Point3D(0, 0, 10) ] triple_pane = Glass.from_single_transmittance('TriplePane', 0.45) ap_original = Aperture.from_vertices('wall_aper', Face3D(verts)) ap_dup_1 = ap_original.duplicate() assert ap_original.properties.radiance.host is ap_original assert ap_dup_1.properties.radiance.host is ap_dup_1 assert ap_original.properties.radiance.host is not ap_dup_1.properties.radiance.host assert ap_original.properties.radiance.modifier == \ ap_dup_1.properties.radiance.modifier ap_dup_1.properties.radiance.modifier = triple_pane assert ap_original.properties.radiance.modifier != \ ap_dup_1.properties.radiance.modifier ap_dup_2 = ap_dup_1.duplicate() assert ap_dup_1.properties.radiance.modifier == \ ap_dup_2.properties.radiance.modifier ap_dup_2.properties.radiance.modifier = None assert ap_dup_1.properties.radiance.modifier != \ ap_dup_2.properties.radiance.modifier
def test_move(): """Test the Aperture move method.""" pts_1 = (Point3D(0, 0, 0), Point3D(2, 0, 0), Point3D(2, 2, 0), Point3D(0, 2, 0)) plane_1 = Plane(Vector3D(0, 0, 1), Point3D(0, 0, 0)) aperture = Aperture('Rectangle Window', Face3D(pts_1, plane_1)) vec_1 = Vector3D(2, 2, 2) new_ap = aperture.duplicate() new_ap.move(vec_1) assert new_ap.geometry[0] == Point3D(2, 2, 2) assert new_ap.geometry[1] == Point3D(4, 2, 2) assert new_ap.geometry[2] == Point3D(4, 4, 2) assert new_ap.geometry[3] == Point3D(2, 4, 2) assert new_ap.normal == aperture.normal assert aperture.area == new_ap.area assert aperture.perimeter == new_ap.perimeter
def test_model_init(): """Test the initialization of the Model and basic properties.""" room = Room.from_box('TinyHouseZone', 5, 10, 3) south_face = room[3] south_face.apertures_by_ratio(0.4, 0.01) south_face.apertures[0].overhang(0.5, indoor=False) south_face.apertures[0].overhang(0.5, indoor=True) south_face.apertures[0].move_shades(Vector3D(0, 0, -0.5)) north_face = room[1] door_verts = [ Point3D(2, 10, 0.1), Point3D(1, 10, 0.1), Point3D(1, 10, 2.5), Point3D(2, 10, 2.5) ] aperture_verts = [ Point3D(4.5, 10, 1), Point3D(2.5, 10, 1), Point3D(2.5, 10, 2.5), Point3D(4.5, 10, 2.5) ] door = Door('FrontDoor', Face3D(door_verts)) north_face.add_door(door) aperture = Aperture('FrontAperture', Face3D(aperture_verts)) north_face.add_aperture(aperture) model = Model('TinyHouse', [room]) str(model) # test the string representation of the object assert model.identifier == 'TinyHouse' assert model.display_name == 'TinyHouse' assert model.units == 'Meters' assert model.tolerance == 0.01 assert model.angle_tolerance == 1.0 assert len(model.rooms) == 1 assert isinstance(model.rooms[0], Room) assert len(model.faces) == 6 assert isinstance(model.faces[0], Face) assert len(model.apertures) == 2 assert isinstance(model.apertures[0], Aperture) assert len(model.doors) == 1 assert isinstance(model.doors[0], Door) assert len(model.indoor_shades) == 1 assert isinstance(model.indoor_shades[0], Shade) assert len(model.outdoor_shades) == 1 assert isinstance(model.outdoor_shades[0], Shade) assert len(model.orphaned_faces) == 0 assert len(model.orphaned_shades) == 0 assert len(model.orphaned_apertures) == 0 assert len(model.orphaned_doors) == 0 assert len(model.stories) == 0 assert model.volume == pytest.approx(150, rel=1e-3) assert model.floor_area == pytest.approx(50, rel=1e-3) assert model.exposed_area == pytest.approx(140, rel=1e-3) assert model.exterior_wall_area == pytest.approx(90, rel=1e-3) assert model.exterior_roof_area == pytest.approx(50, rel=1e-3) assert model.exterior_aperture_area == pytest.approx(9, rel=1e-3) assert model.exterior_wall_aperture_area == pytest.approx(9, rel=1e-3) assert model.exterior_skylight_aperture_area == 0
def test_check_duplicate_sub_face_names(): """Test the check_duplicate_sub_face_names method.""" room = Room.from_box('Tiny House Zone', 5, 10, 3) north_face = room[1] door_verts = [ Point3D(2, 10, 0.1), Point3D(1, 10, 0.1), Point3D(1, 10, 2.5), Point3D(2, 10, 2.5) ] aperture_verts = [ Point3D(4.5, 10, 1), Point3D(2.5, 10, 1), Point3D(2.5, 10, 2.5), Point3D(4.5, 10, 2.5) ] door = Door('Front Door', Face3D(door_verts)) north_face.add_door(door) aperture = Aperture('Front Door', Face3D(aperture_verts)) model = Model('Test House', [room]) assert model.check_duplicate_sub_face_names(False) north_face.add_aperture(aperture) assert not model.check_duplicate_sub_face_names(False) with pytest.raises(ValueError): model.check_duplicate_sub_face_names(True)
def model_5vertex_sub_faces(directory): room = Room.from_box('TinyHouseZone', 5, 10, 3) north_face = room[1] aperture_verts = [ Point3D(4.5, 10, 1), Point3D(2.5, 10, 1), Point3D(2.5, 10, 2.5), Point3D(3.5, 10, 2.9), Point3D(4.5, 10, 2.5) ] aperture = Aperture('FrontAperture', Face3D(aperture_verts)) north_face.add_aperture(aperture) door_verts = [ Point3D(2, 10, 0.1), Point3D(1, 10, 0.1), Point3D(1, 10, 2.5), Point3D(1.5, 10, 2.8), Point3D(2, 10, 2.5) ] door = Door('FrontDoor', Face3D(door_verts)) north_face.add_door(door) model = Model('TinyHouse', [room]) model_dict = model.to_dict() dest_file = os.path.join(directory, 'model_5vertex_sub_faces.json') with open(dest_file, 'w') as fp: json.dump(model_dict, fp, indent=4)
def model_complete_single_zone_office(directory): room = Room.from_box('Tiny_House_Office', 5, 10, 3) room.properties.energy.program_type = prog_type_lib.office_program room.properties.energy.add_default_ideal_air() stone = EnergyMaterial('Thick Stone', 0.3, 2.31, 2322, 832, 'Rough', 0.95, 0.75, 0.8) thermal_mass_constr = OpaqueConstruction('Thermal Mass Floor', [stone]) room[0].properties.energy.construction = thermal_mass_constr south_face = room[3] south_face.apertures_by_ratio(0.4, 0.01) south_face.apertures[0].overhang(0.5, indoor=False) south_face.apertures[0].overhang(0.5, indoor=True) south_face.move_shades(Vector3D(0, 0, -0.5)) light_shelf_out = ShadeConstruction('Outdoor_Light_Shelf', 0.5, 0.5) light_shelf_in = ShadeConstruction('Indoor_Light_Shelf', 0.7, 0.7) south_face.apertures[0].outdoor_shades[ 0].properties.energy.construction = light_shelf_out south_face.apertures[0].indoor_shades[ 0].properties.energy.construction = light_shelf_in north_face = room[1] north_face.overhang(0.25, indoor=False) door_verts = [ Point3D(2, 10, 0.1), Point3D(1, 10, 0.1), Point3D(1, 10, 2.5), Point3D(2, 10, 2.5) ] door = Door('Front_Door', Face3D(door_verts)) north_face.add_door(door) aperture_verts = [ Point3D(4.5, 10, 1), Point3D(2.5, 10, 1), Point3D(2.5, 10, 2.5), Point3D(4.5, 10, 2.5) ] aperture = Aperture('Front_Aperture', Face3D(aperture_verts)) triple_pane = WindowConstruction( 'Triple Pane Window', [clear_glass, air_gap, clear_glass, air_gap, clear_glass]) aperture.properties.energy.construction = triple_pane north_face.add_aperture(aperture) tree_canopy_geo = Face3D.from_regular_polygon( 6, 2, Plane(Vector3D(0, 0, 1), Point3D(5, -3, 4))) tree_canopy = Shade('Tree_Canopy', tree_canopy_geo) table_geo = Face3D.from_rectangle(2, 2, Plane(o=Point3D(1.5, 4, 1))) table = Shade('Table', table_geo) room.add_indoor_shade(table) model = Model('Tiny_House', [room], orphaned_shades=[tree_canopy]) dest_file = os.path.join(directory, 'model_complete_single_zone_office.json') with open(dest_file, 'w') as fp: json.dump(model.to_dict(), fp, indent=4)
def test_aperture_add_shade(): """Test the addition of shade Aperture objects.""" pts_1 = (Point3D(0, 0, 0), Point3D(0, 0, 3), Point3D(5, 0, 3), Point3D(5, 0, 0)) pts_2 = (Point3D(0, 0, 3), Point3D(5, 0, 3), Point3D(5, 2, 3)) aperture = Aperture('RectangleWindow', Face3D(pts_1)) shade = Shade('TriangleShade', Face3D(pts_2), is_detached=True) assert shade.is_detached assert not shade.is_indoor aperture.add_indoor_shade(shade) assert shade.has_parent assert shade.parent.identifier == aperture.identifier assert not shade.is_detached assert shade.is_indoor
def test_triangulated_apertures(): """Test the triangulated_apertures method.""" room = Room.from_box('Tiny House Zone', 5, 10, 3) north_face = room[1] aperture_verts = [ Point3D(4.5, 10, 1), Point3D(2.5, 10, 1), Point3D(2.5, 10, 2.5), Point3D(3.5, 10, 2.9), Point3D(4.5, 10, 2.5) ] aperture = Aperture('Front Aperture', Face3D(aperture_verts)) north_face.add_aperture(aperture) model = Model('Tiny House', [room]) triangulated_apertures, parents_to_edit = model.triangulated_apertures() assert len(triangulated_apertures) == 1 assert len(parents_to_edit) == 1 assert len(triangulated_apertures[0]) == 3 assert len(parents_to_edit[0]) == 3 parents_to_edit[0][0] == aperture.name parents_to_edit[0][1] == north_face.name for ap in triangulated_apertures[0]: assert isinstance(ap, Aperture) assert len(ap.geometry) == 3