def model_complete_multiroom_radiance(directory): triple_pane = Glass.from_single_transmittance('Triple_Pane_0.35', 0.35) first_floor = Room.from_box('First_Floor', 10, 10, 3, origin=Point3D(0, 0, 0)) second_floor = Room.from_box('Second_Floor', 10, 10, 3, origin=Point3D(0, 0, 3)) for face in first_floor[1:5]: face.apertures_by_ratio(0.2, 0.01) face.apertures[0].properties.radiance.modifier = triple_pane for face in second_floor[1:5]: face.apertures_by_ratio(0.2, 0.01) pts_1 = [Point3D(0, 0, 6), Point3D(0, 10, 6), Point3D(10, 10, 6), Point3D(10, 0, 6)] pts_2 = [Point3D(0, 0, 6), Point3D(5, 0, 9), Point3D(5, 10, 9), Point3D(0, 10, 6)] pts_3 = [Point3D(10, 0, 6), Point3D(10, 10, 6), Point3D(5, 10, 9), Point3D(5, 0, 9)] pts_4 = [Point3D(0, 0, 6), Point3D(10, 0, 6), Point3D(5, 0, 9)] pts_5 = [Point3D(10, 10, 6), Point3D(0, 10, 6), Point3D(5, 10, 9)] face_1 = Face('AtticFace1', Face3D(pts_1)) face_2 = Face('AtticFace2', Face3D(pts_2)) face_3 = Face('AtticFace3', Face3D(pts_3)) face_4 = Face('AtticFace4', Face3D(pts_4)) face_5 = Face('AtticFace5', Face3D(pts_5)) attic = Room('Attic', [face_1, face_2, face_3, face_4, face_5], 0.01, 1) mod_set = ModifierSet('Attic_Modifier_Set') polyiso = Plastic.from_single_reflectance('PolyIso', 0.45) mod_set.roof_ceiling_set.exterior_modifier = polyiso attic.properties.radiance.modifier_set = mod_set Room.solve_adjacency([first_floor, second_floor, attic], 0.01) model = Model('Multi_Room_Radiance_House', [first_floor, second_floor, attic]) dest_file = os.path.join(directory, 'model_complete_multiroom_radiance.json') with open(dest_file, 'w') as fp: json.dump(model.to_dict(), fp, indent=4)
def model_radiance_grid_views(directory): room = Room.from_box('Tiny_House_Zone', 5, 10, 3) garage = Room.from_box('Tiny_Garage', 5, 10, 3, origin=Point3D(5, 0, 0)) 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)) north_face = garage[1] north_face.apertures_by_ratio(0.1, 0.01) room_grid = room.properties.radiance.generate_sensor_grid(0.5, 0.5, 1) garage_grid = garage.properties.radiance.generate_sensor_grid(0.5, 0.5, 1) room_view = room.properties.radiance.generate_view((0, -1, 0)) garage_view = garage.properties.radiance.generate_view((0, 1, 0)) Room.solve_adjacency([room, garage], 0.01) model = Model('Tiny_House', [room, garage]) model.properties.radiance.sensor_grids = [room_grid] model.properties.radiance.add_sensor_grids([garage_grid]) model.properties.radiance.views = [room_view] model.properties.radiance.add_views([garage_view]) dest_file = os.path.join(directory, 'model_radiance_grid_views.json') with open(dest_file, 'w') as fp: json.dump(model.to_dict(included_prop=['radiance']), fp, indent=4)
def test_from_honeybee(): """Test the from_honeybee method of Model objects.""" room_south = Room.from_box('SouthZone', 5, 5, 3, origin=Point3D(0, 0, 0)) room_north = Room.from_box('NorthZone', 5, 5, 3, origin=Point3D(0, 5, 0)) room_up = Room.from_box('UpZone', 5, 5, 3, origin=Point3D(0, 5, 3)) room_south[1].apertures_by_ratio(0.4, 0.01) room_south[3].apertures_by_ratio(0.4, 0.01) room_north[3].apertures_by_ratio(0.4, 0.01) Room.solve_adjacency([room_south, room_north], 0.01) pts = (Point3D(0, -3, 0), Point3D(0, -3, 3), Point3D(1, -3, 3), Point3D(1, -3, 0)) shade = Shade('TestShade', Face3D(pts)) model = hb_model.Model('Test_Building', [room_south, room_north, room_up], orphaned_shades=[shade], tolerance=0.01) model = Model.from_honeybee(model) assert len(model.context_shades) == 1 assert len(model.buildings) == 1 bldg = model.buildings[0] assert bldg.identifier == 'Test_Building' assert len(bldg.unique_stories) == 2 bound_cs = [b for room in bldg.unique_room_2ds for b in room.boundary_conditions if isinstance(b, Surface)] assert len(bound_cs) == 2 assert bound_cs[0].boundary_condition_objects == ('NorthZone..Face4', 'NorthZone') assert bound_cs[1].boundary_condition_objects == ('SouthZone..Face2', 'SouthZone')
def test_from_honeybee(): """Test the from_honeybee method of Building objects.""" room_south = Room.from_box('SouthZone', 5, 5, 3, origin=Point3D(0, 0, 0)) room_north = Room.from_box('NorthZone', 5, 5, 3, origin=Point3D(0, 5, 0)) room_up = Room.from_box('UpZone', 5, 5, 3, origin=Point3D(0, 5, 3)) room_south[1].apertures_by_ratio(0.4, 0.01) room_south[3].apertures_by_ratio(0.4, 0.01) room_north[3].apertures_by_ratio(0.4, 0.01) Room.solve_adjacency([room_south, room_north], 0.01) model = Model('Test_Building', [room_south, room_north, room_up], tolerance=0.01) bldg = Building.from_honeybee(model) assert bldg.identifier == 'Test_Building' assert len(bldg.unique_stories) == 2 bound_cs = [ b for room in bldg.unique_room_2ds for b in room.boundary_conditions if isinstance(b, Surface) ] assert len(bound_cs) == 2 assert bound_cs[0].boundary_condition_objects == ('NorthZone..Face4', 'NorthZone') assert bound_cs[1].boundary_condition_objects == ('SouthZone..Face2', 'SouthZone')
def model_energy_window_ac(directory): first_floor = Room.from_box('First_Floor', 10, 10, 3, origin=Point3D(0, 0, 0)) second_floor = Room.from_box('Second_Floor', 10, 10, 3, origin=Point3D(0, 0, 3)) first_floor.properties.energy.program_type = prog_type_lib.office_program second_floor.properties.energy.program_type = prog_type_lib.office_program first_floor.properties.energy.add_default_ideal_air() second_floor.properties.energy.add_default_ideal_air() for face in first_floor[1:5]: face.apertures_by_ratio(0.2, 0.01) for face in second_floor[1:5]: face.apertures_by_ratio(0.2, 0.01) ac_sys = WindowAC('FCU System with DOAS Heat Recovery') ac_sys.equipment_type = 'Window AC with baseboard gas boiler' first_floor.properties.energy.hvac = ac_sys second_floor.properties.energy.hvac = ac_sys Room.solve_adjacency([first_floor, second_floor], 0.01) model = Model('Model_Energy_Window_AC', [first_floor, second_floor]) dest_file = os.path.join(directory, 'model_energy_window_ac.json') with open(dest_file, 'w') as fp: json.dump(model.to_dict(included_prop=['energy']), fp, indent=4)
def model_energy_doas_hvac(directory): first_floor = Room.from_box('First_Floor', 10, 10, 3, origin=Point3D(0, 0, 0)) second_floor = Room.from_box('Second_Floor', 10, 10, 3, origin=Point3D(0, 0, 3)) first_floor.properties.energy.program_type = prog_type_lib.office_program second_floor.properties.energy.program_type = prog_type_lib.office_program first_floor.properties.energy.add_default_ideal_air() second_floor.properties.energy.add_default_ideal_air() for face in first_floor[1:5]: face.apertures_by_ratio(0.2, 0.01) for face in second_floor[1:5]: face.apertures_by_ratio(0.2, 0.01) fcu_sys = FCUwithDOAS('FCU System with DOAS Enthalpy Wheel') fcu_sys.sensible_heat_recovery = 0.81 fcu_sys.latent_heat_recovery = 0.67 first_floor.properties.energy.hvac = fcu_sys second_floor.properties.energy.hvac = fcu_sys Room.solve_adjacency([first_floor, second_floor], 0.01) model = Model('Model_Energy_DOAS_HVAC', [first_floor, second_floor]) dest_file = os.path.join(directory, 'model_energy_doas_hvac.json') with open(dest_file, 'w') as fp: json.dump(model.to_dict(included_prop=['energy']), fp, indent=4)
def model_energy_allair_hvac(directory): first_floor = Room.from_box('First_Floor', 10, 10, 3, origin=Point3D(0, 0, 0)) second_floor = Room.from_box('Second_Floor', 10, 10, 3, origin=Point3D(0, 0, 3)) first_floor.properties.energy.program_type = prog_type_lib.office_program second_floor.properties.energy.program_type = prog_type_lib.office_program first_floor.properties.energy.add_default_ideal_air() second_floor.properties.energy.add_default_ideal_air() for face in first_floor[1:5]: face.apertures_by_ratio(0.2, 0.01) for face in second_floor[1:5]: face.apertures_by_ratio(0.2, 0.01) vav_sys = VAV('VAV System with Glycol Loop') vav_sys.vintage = '90.1-2010' vav_sys.economizer_type = 'DifferentialDryBulb' vav_sys.sensible_heat_recovery = 0.55 vav_sys.latent_heat_recovery = 0 first_floor.properties.energy.hvac = vav_sys second_floor.properties.energy.hvac = vav_sys Room.solve_adjacency([first_floor, second_floor], 0.01) model = Model('Model_Energy_Allair_HVAC', [first_floor, second_floor]) dest_file = os.path.join(directory, 'model_energy_allair_hvac.json') with open(dest_file, 'w') as fp: json.dump(model.to_dict(included_prop=['energy']), fp, indent=4)
def test_assign_stories_by_floor_height(): """Test the Model assign_stories_by_floor_height method.""" first_floor = Room.from_box('First_Floor', 10, 10, 3, origin=Point3D(0, 0, 0)) second_floor = Room.from_box('Second_Floor', 10, 10, 3, origin=Point3D(0, 0, 3)) for face in first_floor[1:5]: face.apertures_by_ratio(0.2, 0.01) for face in second_floor[1:5]: face.apertures_by_ratio(0.2, 0.01) pts_1 = [ Point3D(0, 0, 6), Point3D(0, 10, 6), Point3D(10, 10, 6), Point3D(10, 0, 6) ] pts_2 = [ Point3D(0, 0, 6), Point3D(5, 0, 9), Point3D(5, 10, 9), Point3D(0, 10, 6) ] pts_3 = [ Point3D(10, 0, 6), Point3D(10, 10, 6), Point3D(5, 10, 9), Point3D(5, 0, 9) ] pts_4 = [Point3D(0, 0, 6), Point3D(10, 0, 6), Point3D(5, 0, 9)] pts_5 = [Point3D(10, 10, 6), Point3D(0, 10, 6), Point3D(5, 10, 9)] face_1 = Face('AtticFace1', Face3D(pts_1)) face_2 = Face('AtticFace2', Face3D(pts_2)) face_3 = Face('AtticFace3', Face3D(pts_3)) face_4 = Face('AtticFace4', Face3D(pts_4)) face_5 = Face('AtticFace5', Face3D(pts_5)) attic = Room('Attic', [face_1, face_2, face_3, face_4, face_5], 0.01, 1) Room.solve_adjacency([first_floor, second_floor, attic], 0.01) model = Model('MultiZoneSingleFamilyHouse', [first_floor, second_floor, attic]) assert len(model.stories) == 0 model.assign_stories_by_floor_height(2.0) assert len(model.stories) == 3 assert first_floor.story == 'Floor1' assert second_floor.story == 'Floor2' assert attic.story == 'Floor3' model.assign_stories_by_floor_height(4.0, overwrite=True) assert len(model.stories) == 2 assert first_floor.story == second_floor.story == 'Floor1' assert attic.story == 'Floor2'
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_check_duplicate_room_names(): """Test the check_duplicate_room_names method.""" room_south = Room.from_box('Zone1', 5, 5, 3, origin=Point3D(0, 0, 0)) room_north = Room.from_box('Zone1', 5, 5, 3, origin=Point3D(0, 5, 0)) room_south[3].apertures_by_ratio(0.4, 0.01) Room.solve_adjacency([room_south, room_north], 0.01) model_1 = Model('South House', [room_south]) model_2 = Model('North House', [room_north]) assert model_1.check_duplicate_room_names(False) model_1.add_model(model_2) assert not model_1.check_duplicate_room_names(False) with pytest.raises(ValueError): model_1.check_duplicate_room_names(True)
def test_check_all_air_walls_adjacent(): """Test the check_all_air_walls_adjacent method.""" room_south = Room.from_box('South Zone', 5, 5, 3, origin=Point3D(0, 0, 0)) room_north = Room.from_box('North Zone', 5, 5, 3, origin=Point3D(0, 5, 0)) room_south[3].apertures_by_ratio(0.4, 0.01) room_south[1].type = face_types.air_wall room_north[3].type = face_types.air_wall model = Model('Test House', [room_south, room_north]) assert not model.check_all_air_walls_adjacent(False) with pytest.raises(ValueError): model.check_all_air_walls_adjacent(True) Room.solve_adjacency([room_south, room_north], 0.01) assert model.check_all_air_walls_adjacent(False)
def test_adjacent_zone_model(): """Test the solve adjacency method with an interior aperture.""" room_south = Room.from_box('South Zone', 5, 5, 3, origin=Point3D(0, 0, 0)) room_north = Room.from_box('North Zone', 5, 5, 3, origin=Point3D(0, 5, 0)) room_south[1].apertures_by_ratio(0.4, 0.01) room_north[3].apertures_by_ratio(0.4, 0.01) room_south[3].apertures_by_ratio(0.4, 0.01) room_south[3].apertures[0].overhang(0.5, indoor=False) room_south[3].apertures[0].overhang(0.5, indoor=True) room_south[3].apertures[0].move_shades(Vector3D(0, 0, -0.5)) 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)) room_north[1].add_door(door) aperture = Aperture('Front Aperture', Face3D(aperture_verts)) room_north[1].add_aperture(aperture) Room.solve_adjacency([room_south, room_north], 0.01) model = Model('Two Room House', [room_south, room_north]) assert len(model.rooms) == 2 assert len(model.faces) == 12 assert len(model.shades) == 2 assert len(model.apertures) == 4 assert len(model.doors) == 1 model_dict = model.to_dict() new_model = Model.from_dict(model_dict) assert isinstance(new_model.rooms[0][1].apertures[0].boundary_condition, Surface) assert isinstance(new_model.rooms[1][3].apertures[0].boundary_condition, Surface) assert new_model.rooms[0][1].apertures[0].boundary_condition.boundary_condition_object == \ new_model.rooms[1][3].apertures[0].name assert new_model.rooms[1][3].apertures[0].boundary_condition.boundary_condition_object == \ new_model.rooms[0][1].apertures[0].name
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]
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)
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
def test_from_dict_non_abridged(): """Test the Model from_dict method with non-abridged objects.""" first_floor = Room.from_box('FirstFloor', 10, 10, 3, origin=Point3D(0, 0, 0)) second_floor = Room.from_box('SecondFloor', 10, 10, 3, origin=Point3D(0, 0, 3)) first_floor.properties.energy.program_type = office_program second_floor.properties.energy.program_type = office_program first_floor.properties.energy.add_default_ideal_air() second_floor.properties.energy.add_default_ideal_air() for face in first_floor[1:5]: face.apertures_by_ratio(0.2, 0.01) for face in second_floor[1:5]: face.apertures_by_ratio(0.2, 0.01) pts_1 = [Point3D(0, 0, 6), Point3D(0, 10, 6), Point3D(10, 10, 6), Point3D(10, 0, 6)] pts_2 = [Point3D(0, 0, 6), Point3D(5, 0, 9), Point3D(5, 10, 9), Point3D(0, 10, 6)] pts_3 = [Point3D(10, 0, 6), Point3D(10, 10, 6), Point3D(5, 10, 9), Point3D(5, 0, 9)] pts_4 = [Point3D(0, 0, 6), Point3D(10, 0, 6), Point3D(5, 0, 9)] pts_5 = [Point3D(10, 10, 6), Point3D(0, 10, 6), Point3D(5, 10, 9)] face_1 = Face('AtticFace1', Face3D(pts_1)) face_2 = Face('AtticFace2', Face3D(pts_2)) face_3 = Face('AtticFace3', Face3D(pts_3)) face_4 = Face('AtticFace4', Face3D(pts_4)) face_5 = Face('AtticFace5', Face3D(pts_5)) attic = Room('Attic', [face_1, face_2, face_3, face_4, face_5], 0.01, 1) constr_set = ConstructionSet('Attic Construction Set') polyiso = EnergyMaterial('PolyIso', 0.2, 0.03, 43, 1210, 'MediumRough') roof_constr = OpaqueConstruction('Attic Roof Construction', [roof_membrane, polyiso, wood]) floor_constr = OpaqueConstruction('Attic Floor Construction', [wood, insulation, wood]) constr_set.floor_set.interior_construction = floor_constr constr_set.roof_ceiling_set.exterior_construction = roof_constr attic.properties.energy.construction_set = constr_set Room.solve_adjacency([first_floor, second_floor, attic], 0.01) model = Model('MultiZoneSingleFamilyHouse', [first_floor, second_floor, attic]) model_dict = model.to_dict() model_dict['properties']['energy']['program_types'][0] = office_program.to_dict() model_dict['properties']['energy']['construction_sets'][0] = constr_set.to_dict() rebuilt_model = Model.from_dict(model_dict) assert rebuilt_model.rooms[0].properties.energy.program_type == office_program assert rebuilt_model.rooms[2].properties.energy.construction_set == constr_set
def test_check_duplicate_construction_set_identifiers(): """Test the check_duplicate_construction_set_identifiers method.""" first_floor = Room.from_box('First_Floor', 10, 10, 3, origin=Point3D(0, 0, 0)) second_floor = Room.from_box('Second_Floor', 10, 10, 3, origin=Point3D(0, 0, 3)) for face in first_floor[1:5]: face.apertures_by_ratio(0.2, 0.01) for face in second_floor[1:5]: face.apertures_by_ratio(0.2, 0.01) base_constr_set = ConstructionSet('Lower Floor Construction Set') first_floor.properties.energy.construction_set = base_constr_set second_floor.properties.energy.construction_set = base_constr_set pts_1 = [Point3D(0, 0, 6), Point3D(0, 10, 6), Point3D(10, 10, 6), Point3D(10, 0, 6)] pts_2 = [Point3D(0, 0, 6), Point3D(5, 0, 9), Point3D(5, 10, 9), Point3D(0, 10, 6)] pts_3 = [Point3D(10, 0, 6), Point3D(10, 10, 6), Point3D(5, 10, 9), Point3D(5, 0, 9)] pts_4 = [Point3D(0, 0, 6), Point3D(10, 0, 6), Point3D(5, 0, 9)] pts_5 = [Point3D(10, 10, 6), Point3D(0, 10, 6), Point3D(5, 10, 9)] face_1 = Face('AtticFace1', Face3D(pts_1)) face_2 = Face('AtticFace2', Face3D(pts_2)) face_3 = Face('AtticFace3', Face3D(pts_3)) face_4 = Face('AtticFace4', Face3D(pts_4)) face_5 = Face('AtticFace5', Face3D(pts_5)) attic = Room('Attic', [face_1, face_2, face_3, face_4, face_5], 0.01, 1) constr_set = ConstructionSet('Attic Construction Set') polyiso = EnergyMaterial('PolyIso', 0.2, 0.03, 43, 1210, 'MediumRough') roof_constr = OpaqueConstruction('Attic Roof Construction', [roof_membrane, polyiso, wood]) floor_constr = OpaqueConstruction('Attic Floor Construction', [wood, insulation, wood]) constr_set.floor_set.interior_construction = floor_constr constr_set.roof_ceiling_set.exterior_construction = roof_constr attic.properties.energy.construction_set = constr_set Room.solve_adjacency([first_floor, second_floor, attic], 0.01) model = Model('MultiZoneSingleFamilyHouse', [first_floor, second_floor, attic]) assert model.properties.energy.check_duplicate_construction_set_identifiers(False) constr_set.unlock() constr_set.identifier = 'Lower Floor Construction Set' constr_set.lock() assert not model.properties.energy.check_duplicate_construction_set_identifiers(False) with pytest.raises(ValueError): model.properties.energy.check_duplicate_construction_set_identifiers(True)
def test_writer_to_rad_folder_sensor_grids_views(): """Test the Model to.rad_folder method with assigned sensor grids and views.""" room = Room.from_box('Tiny_House_Zone', 5, 10, 3) garage = Room.from_box('Tiny_Garage', 5, 10, 3, origin=Point3D(5, 0, 0)) 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)) north_face = garage[1] north_face.apertures_by_ratio(0.1, 0.01) room_grid = room.properties.radiance.generate_sensor_grid(0.5, 0.5, 1) garage_grid = garage.properties.radiance.generate_sensor_grid(0.5, 0.5, 1) room_view = room.properties.radiance.generate_view((0, -1, 0)) garage_view = garage.properties.radiance.generate_view((0, 1, 0)) Room.solve_adjacency([room, garage], 0.01) model = Model('Tiny_House', [room, garage]) model.properties.radiance.sensor_grids = [room_grid] model.properties.radiance.add_sensor_grids([garage_grid]) model.properties.radiance.views = [room_view] model.properties.radiance.add_views([garage_view]) folder = os.path.abspath('./tests/assets/model/rad_folder_grids_views') model.to.rad_folder(model, folder) model_folder = ModelFolder(folder) grid_dir = model_folder.grid_folder(full=True) assert os.path.isfile(os.path.join(grid_dir, 'Tiny_House_Zone.pts')) assert os.path.isfile(os.path.join(grid_dir, 'Tiny_House_Zone.json')) assert os.path.isfile(os.path.join(grid_dir, 'Tiny_Garage.pts')) assert os.path.isfile(os.path.join(grid_dir, 'Tiny_Garage.json')) view_dir = model_folder.view_folder(full=True) assert os.path.isfile(os.path.join(view_dir, 'Tiny_House_Zone.vf')) assert os.path.isfile(os.path.join(view_dir, 'Tiny_House_Zone.json')) assert os.path.isfile(os.path.join(view_dir, 'Tiny_Garage.vf')) assert os.path.isfile(os.path.join(view_dir, 'Tiny_Garage.json')) # clean up the folder nukedir(folder, rmdir=True)
def test_to_dict_multizone_house(): """Test the Model to_dict method with a multi-zone house.""" first_floor = Room.from_box('First_Floor', 10, 10, 3, origin=Point3D(0, 0, 0)) second_floor = Room.from_box('Second_Floor', 10, 10, 3, origin=Point3D(0, 0, 3)) for face in first_floor[1:5]: face.apertures_by_ratio(0.2, 0.01) for face in second_floor[1:5]: face.apertures_by_ratio(0.2, 0.01) pts_1 = [Point3D(0, 0, 6), Point3D(0, 10, 6), Point3D(10, 10, 6), Point3D(10, 0, 6)] pts_2 = [Point3D(0, 0, 6), Point3D(5, 0, 9), Point3D(5, 10, 9), Point3D(0, 10, 6)] pts_3 = [Point3D(10, 0, 6), Point3D(10, 10, 6), Point3D(5, 10, 9), Point3D(5, 0, 9)] pts_4 = [Point3D(0, 0, 6), Point3D(10, 0, 6), Point3D(5, 0, 9)] pts_5 = [Point3D(10, 10, 6), Point3D(0, 10, 6), Point3D(5, 10, 9)] face_1 = Face('AtticFace1', Face3D(pts_1)) face_2 = Face('AtticFace2', Face3D(pts_2)) face_3 = Face('AtticFace3', Face3D(pts_3)) face_4 = Face('AtticFace4', Face3D(pts_4)) face_5 = Face('AtticFace5', Face3D(pts_5)) attic = Room('Attic', [face_1, face_2, face_3, face_4, face_5], 0.01, 1) mod_set = ModifierSet('Attic_Construction_Set') mod_set.floor_set.interior_modifier = Plastic('AtticFloor', 0.4) mod_set.roof_ceiling_set.exterior_modifier = Plastic('AtticRoof', 0.6) attic.properties.radiance.modifier_set = mod_set Room.solve_adjacency([first_floor, second_floor, attic], 0.01) model = Model('Multi_Zone_Single_Family_House', [first_floor, second_floor, attic]) model_dict = model.to_dict() assert 'radiance' in model_dict['properties'] assert 'modifiers' in model_dict['properties']['radiance'] assert 'modifier_sets' in model_dict['properties']['radiance'] assert len(model_dict['properties']['radiance']['modifiers']) == 2 assert len(model_dict['properties']['radiance']['modifier_sets']) == 1 assert model_dict['rooms'][0]['faces'][5]['boundary_condition']['type'] == 'Surface' assert model_dict['rooms'][1]['faces'][0]['boundary_condition']['type'] == 'Surface' assert model_dict['rooms'][1]['faces'][5]['boundary_condition']['type'] == 'Surface' assert model_dict['rooms'][2]['faces'][0]['boundary_condition']['type'] == 'Surface' assert model_dict['rooms'][2]['properties']['radiance']['modifier_set'] == \ mod_set.identifier
def model_complete_multi_zone_office(directory): first_floor = Room.from_box('First_Floor', 10, 10, 3, origin=Point3D(0, 0, 0)) second_floor = Room.from_box('Second_Floor', 10, 10, 3, origin=Point3D(0, 0, 3)) first_floor.properties.energy.program_type = prog_type_lib.office_program second_floor.properties.energy.program_type = prog_type_lib.office_program first_floor.properties.energy.add_default_ideal_air() second_floor.properties.energy.add_default_ideal_air() for face in first_floor[1:5]: face.apertures_by_ratio(0.2, 0.01) for face in second_floor[1:5]: face.apertures_by_ratio(0.2, 0.01) pts_1 = [Point3D(0, 0, 6), Point3D(0, 10, 6), Point3D(10, 10, 6), Point3D(10, 0, 6)] pts_2 = [Point3D(0, 0, 6), Point3D(5, 0, 9), Point3D(5, 10, 9), Point3D(0, 10, 6)] pts_3 = [Point3D(10, 0, 6), Point3D(10, 10, 6), Point3D(5, 10, 9), Point3D(5, 0, 9)] pts_4 = [Point3D(0, 0, 6), Point3D(10, 0, 6), Point3D(5, 0, 9)] pts_5 = [Point3D(10, 10, 6), Point3D(0, 10, 6), Point3D(5, 10, 9)] face_1 = Face('AtticFace1', Face3D(pts_1)) face_2 = Face('AtticFace2', Face3D(pts_2)) face_3 = Face('AtticFace3', Face3D(pts_3)) face_4 = Face('AtticFace4', Face3D(pts_4)) face_5 = Face('AtticFace5', Face3D(pts_5)) attic = Room('Attic', [face_1, face_2, face_3, face_4, face_5], 0.01, 1) constr_set = ConstructionSet('Attic Construction Set') polyiso = EnergyMaterial('PolyIso', 0.2, 0.03, 43, 1210, 'MediumRough') roof_constr = OpaqueConstruction('Attic Roof Construction', [roof_membrane, polyiso, wood]) floor_constr = OpaqueConstruction('Attic Floor Construction', [wood, insulation, wood]) constr_set.floor_set.interior_construction = floor_constr constr_set.roof_ceiling_set.exterior_construction = roof_constr attic.properties.energy.construction_set = constr_set Room.solve_adjacency([first_floor, second_floor, attic], 0.01) model = Model('Multi_Zone_Single_Family_House', [first_floor, second_floor, attic]) dest_file = os.path.join(directory, 'model_complete_multi_zone_office.json') with open(dest_file, 'w') as fp: json.dump(model.to_dict(), fp, indent=4)
def test_check_duplicate_modifier_set_identifiers(): """Test the check_duplicate_modifier_set_identifiers method.""" first_floor = Room.from_box('FirstFloor', 10, 10, 3, origin=Point3D(0, 0, 0)) second_floor = Room.from_box('SecondFloor', 10, 10, 3, origin=Point3D(0, 0, 3)) for face in first_floor[1:5]: face.apertures_by_ratio(0.2, 0.01) for face in second_floor[1:5]: face.apertures_by_ratio(0.2, 0.01) mod_set_bottom = ModifierSet('Lower_Floor_Modifier_Set') first_floor.properties.radiance.modifier_set = mod_set_bottom second_floor.properties.radiance.modifier_set = mod_set_bottom pts_1 = [Point3D(0, 0, 6), Point3D(0, 10, 6), Point3D(10, 10, 6), Point3D(10, 0, 6)] pts_2 = [Point3D(0, 0, 6), Point3D(5, 0, 9), Point3D(5, 10, 9), Point3D(0, 10, 6)] pts_3 = [Point3D(10, 0, 6), Point3D(10, 10, 6), Point3D(5, 10, 9), Point3D(5, 0, 9)] pts_4 = [Point3D(0, 0, 6), Point3D(10, 0, 6), Point3D(5, 0, 9)] pts_5 = [Point3D(10, 10, 6), Point3D(0, 10, 6), Point3D(5, 10, 9)] face_1 = Face('AtticFace1', Face3D(pts_1)) face_2 = Face('AtticFace2', Face3D(pts_2)) face_3 = Face('AtticFace3', Face3D(pts_3)) face_4 = Face('AtticFace4', Face3D(pts_4)) face_5 = Face('AtticFace5', Face3D(pts_5)) attic = Room('Attic', [face_1, face_2, face_3, face_4, face_5], 0.01, 1) mod_set = ModifierSet('Attic_Modifier_Set') mod_set.floor_set.interior_modifier = Plastic('AtticFloor', 0.4) mod_set.roof_ceiling_set.exterior_modifier = Plastic('AtticRoof', 0.6) attic.properties.radiance.modifier_set = mod_set Room.solve_adjacency([first_floor, second_floor, attic], 0.01) model = Model('Multi_Zone_Single_Family_House', [first_floor, second_floor, attic]) assert model.properties.radiance.check_duplicate_modifier_set_identifiers(False) == '' mod_set.unlock() mod_set.identifier = 'Lower_Floor_Modifier_Set' mod_set.lock() assert model.properties.radiance.check_duplicate_modifier_set_identifiers(False) != '' with pytest.raises(ValueError): model.properties.radiance.check_duplicate_modifier_set_identifiers(True)
def test_to_dict_sensor_grids_views(): """Test the Model to_dict method with assigned sensor grids and views.""" room = Room.from_box('Tiny_House_Zone', 5, 10, 3) garage = Room.from_box('Tiny_Garage', 5, 10, 3, origin=Point3D(5, 0, 0)) 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)) north_face = garage[1] north_face.apertures_by_ratio(0.1, 0.01) room_grid = room.properties.radiance.generate_sensor_grid(0.5, 0.5, 1) garage_grid = garage.properties.radiance.generate_sensor_grid(0.5, 0.5, 1) room_view = room.properties.radiance.generate_view((0, -1, 0)) garage_view = garage.properties.radiance.generate_view((0, 1, 0)) Room.solve_adjacency([room, garage], 0.01) model = Model('Tiny_House', [room, garage]) model.properties.radiance.sensor_grids = [room_grid] model.properties.radiance.add_sensor_grids([garage_grid]) model.properties.radiance.views = [room_view] model.properties.radiance.add_views([garage_view]) model_dict = model.to_dict(included_prop=['radiance']) assert 'sensor_grids' in model_dict['properties']['radiance'] assert 'views' in model_dict['properties']['radiance'] assert len(model_dict['properties']['radiance']['sensor_grids']) == 2 assert len(model_dict['properties']['radiance']['views']) == 2 new_model = Model.from_dict(model_dict) assert new_model.properties.radiance.has_sensor_grids assert new_model.properties.radiance.has_views assert len(new_model.properties.radiance.sensor_grids) == 2 assert len(new_model.properties.radiance.views) == 2 assert model_dict == new_model.to_dict(included_prop=['radiance'])
def model_5vertex_sub_faces_interior(directory): room1 = Room.from_box('TinyHouseZone1', 5, 10, 3) north_face = room1[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) room2 = Room.from_box('TinyHouseZone2', 5, 10, 3, origin=Point3D(0, 10, 0)) south_face = room2[3] s_aperture = Aperture('BackAperture', Face3D(aperture_verts)) south_face.add_aperture(s_aperture) s_door = Door('BackDoor', Face3D(door_verts)) south_face.add_door(s_door) Room.solve_adjacency([room1, room2], 0.01) model = Model('TinyHouse', [room1, room2]) model_dict = model.to_dict() dest_file = os.path.join(directory, 'model_5vertex_sub_faces_interior.json') with open(dest_file, 'w') as fp: json.dump(model_dict, fp, indent=4)
def test_check_missing_adjacencies(): """Test the check_missing_adjacencies method.""" room_south = Room.from_box('SouthZone', 5, 5, 3, origin=Point3D(0, 0, 0)) room_north = Room.from_box('NorthZone', 5, 5, 3, origin=Point3D(0, 5, 0)) room_south[1].apertures_by_ratio(0.4, 0.01) room_south[3].apertures_by_ratio(0.4, 0.01) room_north[3].apertures_by_ratio(0.4, 0.01) Room.solve_adjacency([room_south, room_north], 0.01) model_1 = Model('SouthHouse', [room_south]) model_2 = Model('NorthHouse', [room_north]) assert len(model_1.rooms) == 1 assert len(model_1.faces) == 6 assert len(model_1.apertures) == 2 with pytest.raises(ValueError): model_1.check_missing_adjacencies() model_1.add_model(model_2) assert len(model_1.rooms) == 2 assert len(model_1.faces) == 12 assert len(model_1.apertures) == 3 assert model_1.check_missing_adjacencies() == ''
def test_color_room(): """Test ColorRoom.""" room_south = Room.from_box('SouthZone', 5, 5, 3, origin=Point3D(0, 0, 0)) room_north = Room.from_box('NorthZone', 5, 5, 3, origin=Point3D(0, 5, 0)) room_south[1].apertures_by_ratio(0.4, 0.01) room_north[3].apertures_by_ratio(0.4, 0.01) room_south[3].apertures_by_ratio(0.4, 0.01) room_south[3].apertures[0].overhang(0.5, indoor=False) room_south[3].apertures[0].overhang(0.5, indoor=True) room_south[3].apertures[0].move_shades(Vector3D(0, 0, -0.5)) 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)) room_north[1].add_door(door) aperture = Aperture('FrontAperture', Face3D(aperture_verts)) room_north[1].add_aperture(aperture) Room.solve_adjacency([room_south, room_north], 0.01) color_room1 = ColorRoom([room_south, room_north], 'display_name') color_room2 = ColorRoom([room_south, room_north], 'multiplier') assert len(color_room1.rooms) == len(color_room2.rooms) == 2 assert color_room1.attr_name == color_room1.attr_name_end == 'display_name' assert color_room2.attr_name == color_room2.attr_name_end == 'multiplier' assert color_room1.attributes == ('SouthZone', 'NorthZone') assert color_room2.attributes == ('1', '1') assert isinstance(color_room1.graphic_container, GraphicContainer) assert len(color_room1.attributes_unique) == \ len(color_room1.graphic_container.legend.segment_colors) == 2 assert len(color_room2.attributes_unique) == \ len(color_room2.graphic_container.legend.segment_colors) == 1 assert len(color_room1.floor_faces) == len(color_room2.floor_faces) == 2 assert isinstance(color_room1.min_point, Point3D) assert isinstance(color_room1.max_point, Point3D)
def solve_adjacency(model_json, wall, surface, no_overwrite, output_file): """Solve adjacency between Rooms of a Model JSON file. \b Args: model_json: Full path to a Model JSON file. """ try: # serialize the Model to Python with open(model_json) as json_file: data = json.load(json_file) parsed_model = Model.from_dict(data) # check the Model tolerance assert parsed_model.tolerance != 0, \ 'Model must have a non-zero tolerance to use solve-adjacency.' tol = parsed_model.tolerance # solve adjacency if no_overwrite: # only assign new adjacencies adj_info = Room.solve_adjacency(parsed_model.rooms, tol) else: # overwrite existing Surface BC adj_faces = Room.find_adjacency(parsed_model.rooms, tol) for face_pair in adj_faces: face_pair[0].set_adjacency(face_pair[1]) adj_info = {'adjacent_faces': adj_faces} # try to assign the air boundary face type if not wall: for face_pair in adj_info['adjacent_faces']: if isinstance(face_pair[0].type, Wall): face_pair[0].type = face_types.air_boundary face_pair[1].type = face_types.air_boundary # try to assign the adiabatic boundary condition if not surface and ad_bc: for face_pair in adj_info['adjacent_faces']: face_pair[0].boundary_condition = ad_bc face_pair[1].boundary_condition = ad_bc # write the new model out to the file or stdout output_file.write(json.dumps(parsed_model.to_dict())) except Exception as e: _logger.exception('Model solve adjacency failed.\n{}'.format(e)) sys.exit(1) else: sys.exit(0)
def test_solve_adjacency(): """Test the solve adjacency method.""" room_south = Room.from_box('South Zone', 5, 5, 3, origin=Point3D(0, 0, 0)) room_north = Room.from_box('North Zone', 5, 5, 3, origin=Point3D(0, 5, 0)) assert room_south[1].boundary_condition == boundary_conditions.outdoors assert room_north[3].boundary_condition == boundary_conditions.outdoors adj_info = Room.solve_adjacency([room_south, room_north], 0.01) assert isinstance(room_south[1].boundary_condition, Surface) assert isinstance(room_north[3].boundary_condition, Surface) assert room_south[1].boundary_condition.boundary_condition_object == room_north[3].name assert room_north[3].boundary_condition.boundary_condition_object == room_south[1].name assert len(adj_info['adjacent_faces']) == 1 assert len(adj_info['adjacent_apertures']) == 0 assert len(adj_info['adjacent_doors']) == 0
def test_find_adjacency(): """Test the find adjacency method.""" room_south = Room.from_box('SouthZone', 5, 5, 3, origin=Point3D(0, 0, 0)) room_north = Room.from_box('NorthZone', 5, 5, 3, origin=Point3D(0, 5, 0)) assert room_south[1].boundary_condition == boundary_conditions.outdoors assert room_north[3].boundary_condition == boundary_conditions.outdoors adj_faces = Room.find_adjacency([room_south, room_north], 0.01) assert len(adj_faces) == 1 assert len(adj_faces[0]) == 2 adj_info = Room.solve_adjacency([room_south, room_north], 0.01) # make sure it all still works after the Surface BC is already set adj_faces = Room.find_adjacency([room_south, room_north], 0.01) assert len(adj_faces) == 1 assert len(adj_faces[0]) == 2
def test_solve_adjacency_aperture(): """Test the solve adjacency method with an interior aperture.""" room_south = Room.from_box('SouthZone', 5, 5, 3, origin=Point3D(0, 0, 0)) room_north = Room.from_box('NorthZone', 5, 5, 3, origin=Point3D(0, 5, 0)) room_south[1].apertures_by_ratio(0.4, 0.01) room_north[3].apertures_by_ratio(0.4, 0.01) assert room_south[1].apertures[0].boundary_condition == boundary_conditions.outdoors assert room_north[3].apertures[0].boundary_condition == boundary_conditions.outdoors adj_info = Room.solve_adjacency([room_south, room_north], 0.01) assert isinstance(room_south[1].apertures[0].boundary_condition, Surface) assert isinstance(room_north[3].apertures[0].boundary_condition, Surface) assert room_south[1].apertures[0].boundary_condition.boundary_condition_object == \ room_north[3].apertures[0].identifier assert room_north[3].apertures[0].boundary_condition.boundary_condition_object == \ room_south[1].apertures[0].identifier assert len(adj_info['adjacent_faces']) == 1 assert len(adj_info['adjacent_apertures']) == 1 assert len(adj_info['adjacent_doors']) == 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