def test_to_geojson(): """Test the Model to_geojson method.""" pts_1 = (Point3D(50, 50, 3), Point3D(60, 50, 3), Point3D(60, 60, 3), Point3D(50, 60, 3)) pts_2 = (Point3D(60, 50, 3), Point3D(70, 50, 3), Point3D(70, 60, 3), Point3D(60, 60, 3)) pts_3 = (Point3D(50, 70, 3), Point3D(70, 70, 3), Point3D(70, 80, 3), Point3D(50, 80, 3)) room2d_1 = Room2D('Residence1', Face3D(pts_1), 3) room2d_2 = Room2D('Residence2', Face3D(pts_2), 3) room2d_3 = Room2D('Retail', Face3D(pts_3), 3) story_big = Story('RetailFloor', [room2d_3]) story = Story('ResidenceFloor', [room2d_1, room2d_2]) story.solve_room_2d_adjacency(0.01) story.set_outdoor_window_parameters(SimpleWindowRatio(0.4)) story.multiplier = 3 building = Building('ResidenceBuilding', [story]) story_big.set_outdoor_window_parameters(SimpleWindowRatio(0.4)) story_big.multiplier = 1 building_big = Building('RetailBuildingBig', [story_big]) pts_1 = (Point3D(0, 0, 3), Point3D(0, 5, 3), Point3D(15, 5, 3), Point3D(15, 0, 3)) pts_2 = (Point3D(15, 0, 3), Point3D(15, 15, 3), Point3D(20, 15, 3), Point3D(20, 0, 3)) pts_3 = (Point3D(0, 5, 3), Point3D(0, 20, 3), Point3D(5, 20, 3), Point3D(5, 5, 3)) pts_4 = (Point3D(5, 15, 3), Point3D(5, 20, 3), Point3D(20, 20, 3), Point3D(20, 15, 3)) pts_5 = (Point3D(-5, -5, 3), Point3D(-10, -5, 3), Point3D(-10, -10, 3), Point3D(-5, -10, 3)) room2d_1 = Room2D('Office1', Face3D(pts_1), 3) room2d_2 = Room2D('Office2', Face3D(pts_2), 3) room2d_3 = Room2D('Office3', Face3D(pts_3), 3) room2d_4 = Room2D('Office4', Face3D(pts_4), 3) room2d_5 = Room2D('Office5', Face3D(pts_5), 3) int_rms = Room2D.intersect_adjacency( [room2d_1, room2d_2, room2d_3, room2d_4, room2d_5], 0.01) story = Story('OfficeFloor', int_rms) story.rotate_xy(5, Point3D(0, 0, 0)) story.solve_room_2d_adjacency(0.01) story.set_outdoor_window_parameters(SimpleWindowRatio(0.4)) story.multiplier = 5 building_mult = Building('OfficeBuilding', [story]) tree_canopy_geo1 = Face3D.from_regular_polygon(6, 6, Plane(o=Point3D(5, -10, 6))) tree_canopy_geo2 = Face3D.from_regular_polygon(6, 2, Plane(o=Point3D(-5, -10, 3))) tree_canopy = ContextShade('TreeCanopy', [tree_canopy_geo1, tree_canopy_geo2]) model = Model('TestGeoJSON', [building, building_big, building_mult], [tree_canopy]) location = Location('Boston', 'MA', 'USA', 42.366151, -71.019357) geojson_folder = './tests/geojson/' model.to_geojson(location, folder=geojson_folder) geo_fp = os.path.join( geojson_folder, model.identifier, '{}.geojson'.format(model.identifier)) assert os.path.isfile(geo_fp) nukedir(os.path.join(geojson_folder, model.identifier), True)
def test_to_from_dict(): """Test the Model to_dict and from_dict method with a single zone model.""" room = Room.from_box('Tiny House Zone', 5, 10, 3) room.properties.energy.program_type = office_program room.properties.energy.hvac = IdealAirSystem() 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.apertures[0].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].shades[ 0].properties.energy.construction = light_shelf_out south_face.apertures[0].shades[ 1].properties.energy.construction = 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('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)) aperture.is_operable = True 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) tree_trans = ScheduleRuleset.from_constant_value('Tree Transmittance', 0.75, schedule_types.fractional) tree_canopy.properties.energy.transmittance_schedule = tree_trans model = Model('Tiny House', [room], orphaned_shades=[tree_canopy]) model.north_angle = 15 model_dict = model.to_dict() new_model = Model.from_dict(model_dict) assert model_dict == new_model.to_dict() assert stone in new_model.properties.energy.materials assert thermal_mass_constr in new_model.properties.energy.constructions assert new_model.rooms[0][ 0].properties.energy.construction == thermal_mass_constr assert new_model.rooms[0][3].apertures[0].indoor_shades[ 0].properties.energy.construction == light_shelf_in assert new_model.rooms[0][3].apertures[0].outdoor_shades[ 0].properties.energy.construction == light_shelf_out assert triple_pane in new_model.properties.energy.constructions assert new_model.rooms[0][1].apertures[ 0].properties.energy.construction == triple_pane assert new_model.rooms[0][1].apertures[0].is_operable assert len(new_model.orphaned_shades) == 1 assert new_model.north_angle == 15 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.rooms[0].properties.energy.program_type == office_program assert len(new_model.properties.energy.schedule_type_limits) == 3 assert len(model.properties.energy.schedules) == 8 assert new_model.rooms[0].properties.energy.is_conditioned assert new_model.rooms[0].properties.energy.hvac == IdealAirSystem() assert new_model.orphaned_shades[ 0].properties.energy.transmittance_schedule == tree_trans
def test_to_dict_single_zone_schedule_fixed_interval(): """Test the Model to_dict method with a single zone model and fixed interval schedules.""" room = Room.from_box('Tiny House Zone', 5, 10, 3) room.properties.energy.program_type = office_program room.properties.energy.hvac = IdealAirSystem() occ_sched = ScheduleFixedInterval( 'Random Occupancy', [round(random.random(), 4) for i in range(8760)], schedule_types.fractional) new_people = room.properties.energy.people.duplicate() new_people.occupancy_schedule = occ_sched room.properties.energy.people = new_people 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)) 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) winter = [0.75] * 2190 spring = [0.75 - ((x / 2190) * 0.5) for x in range(2190)] summer = [0.25] * 2190 fall = [0.25 + ((x / 2190) * 0.5) for x in range(2190)] trans_sched = ScheduleFixedInterval('Seasonal Tree Transmittance', winter + spring + summer + fall, schedule_types.fractional) tree_canopy.properties.energy.transmittance_schedule = trans_sched model = Model('Tiny House', [room], orphaned_shades=[tree_canopy]) model.north_angle = 15 model_dict = model.to_dict() assert 'energy' in model_dict['properties'] assert 'schedules' in model_dict['properties']['energy'] assert 'program_types' in model_dict['properties']['energy'] assert len(model_dict['properties']['energy']['program_types']) == 1 assert len(model_dict['properties']['energy']['schedules']) == 9 assert 'people' in model_dict['rooms'][0]['properties']['energy'] assert model_dict['rooms'][0]['properties']['energy']['people']['occupancy_schedule'] \ == 'Random Occupancy' assert model_dict['orphaned_shades'][0]['properties']['energy']['transmittance_schedule'] \ == 'Seasonal Tree Transmittance' assert model_dict['rooms'][0]['properties']['energy']['program_type'] == \ office_program.name """
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_scale(): """Test the Polyline3D scale method.""" pts_1 = (Point3D(0, 0), Point3D(2, 0), Point3D(2, 2), Point3D(0, 2)) pline_1 = Polyline3D(pts_1) pts_2 = (Point3D(1, 1), Point3D(2, 1), Point3D(2, 2), Point3D(1, 2)) pline_2 = Polyline3D(pts_2) origin_1 = Point3D(2, 0) origin_2 = Point3D(1, 1) new_pline_1 = pline_1.scale(2, origin_1) assert new_pline_1[0] == Point3D(-2, 0) assert new_pline_1[1] == Point3D(2, 0) assert new_pline_1[2] == Point3D(2, 4) assert new_pline_1[3] == Point3D(-2, 4) assert new_pline_1.length == pline_1.length * 2 new_pline_2 = pline_2.scale(2, origin_2) assert new_pline_2[0] == Point3D(1, 1) assert new_pline_2[1] == Point3D(3, 1) assert new_pline_2[2] == Point3D(3, 3) assert new_pline_2[3] == Point3D(1, 3) assert new_pline_2.length == pline_2.length * 2
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)
def _point3d(point): """Ladybug Point3D from Rhino Point3d.""" return Point3D(point.X, point.Y, point.Z)
def test_check_planar(): """Test the check_planar method.""" pts_1 = [ Point3D(0, 0, 0), Point3D(0, 10, 0), Point3D(10, 10, 0), Point3D(10, 0, 0) ] pts_2 = [ Point3D(0, 0, 0), Point3D(0, 0, 3), Point3D(0, 10, 3), Point3D(0, 10, 0) ] pts_3 = [ Point3D(0, 0, 0), Point3D(10, 0, 0), Point3D(10, 0, 3), Point3D(0, 0, 3) ] pts_4 = [ Point3D(10, 10, 0), Point3D(0, 10, 0), Point3D(0, 10, 3), Point3D(10, 10, 3) ] pts_5 = [ Point3D(10, 10, 0), Point3D(10, 0, 0), Point3D(10, 0, 3), Point3D(10, 10, 3) ] pts_6 = [ Point3D(10, 0, 3), Point3D(10, 10, 3), Point3D(0, 10, 3), Point3D(0, 0, 3) ] pts_7 = [ Point3D(10, 0, 3), Point3D(10, 10, 3.1), Point3D(0, 10, 3), Point3D(0, 0, 3) ] face_1 = Face('Face1', Face3D(pts_1)) face_2 = Face('Face2', Face3D(pts_2)) face_3 = Face('Face3', Face3D(pts_3)) face_4 = Face('Face4', Face3D(pts_4)) face_5 = Face('Face5', Face3D(pts_5)) face_6 = Face('Face6', Face3D(pts_6)) face_7 = Face('Face7', Face3D(pts_7)) room_1 = Room('ZoneSHOE_BOX920980', [face_1, face_2, face_3, face_4, face_5, face_6], 0.01, 1) room_2 = Room('ZoneSHOE_BOX920980', [face_1, face_2, face_3, face_4, face_5, face_7], 0.01, 1) model_1 = Model('SouthHouse', [room_1]) model_2 = Model('NorthHouse', [room_2]) assert model_1.check_planar(0.01, False) == '' assert model_2.check_planar(0.01, False) != '' with pytest.raises(ValueError): model_2.check_planar(0.01, True)
from ladybug_rhino.text import text_objects from ladybug_rhino.fromobjects import legend_objects from ladybug_rhino.grasshopper import all_required_inputs, list_to_data_tree except ImportError as e: raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e)) if all_required_inputs(ghenv.Component): # apply any analysis periods and conditional statements to the input collections if period_ is not None: _data = [coll.filter_by_analysis_period(period_) for coll in _data] if statement_ is not None: _data = HourlyContinuousCollection.filter_collections_by_statement( _data, statement_) # set default values for the chart dimensions _base_pt_ = to_point3d(_base_pt_) if _base_pt_ is not None else Point3D() _x_dim_ = _x_dim_ if _x_dim_ is not None else 1.0 / conversion_to_meters() _y_dim_ = _y_dim_ if _y_dim_ is not None else 4.0 / conversion_to_meters() _z_dim_ = _z_dim_ if _z_dim_ is not None else 0 reverse_y_ = reverse_y_ if reverse_y_ is not None else False # set up empty lists of objects to be filled mesh = [] title = [] all_legends = [] all_borders = [] all_labels = [] for i, data_coll in enumerate(_data): try: # sense when several legend parameters are connected lpar = legend_par_[i]
def __init__(self, values, min_point, max_point, legend_parameters=None, data_type=None, unit=None): """Initialize graphic container. """ # check the inputs assert isinstance(min_point, Point3D), \ 'min_point should be a ladybug Point3D. Got {}'.format(type(min_point)) assert isinstance(max_point, Point3D), \ 'max_point should be a ladybug Point3D. Got {}'.format(type(max_point)) self._legend = Legend(values, legend_parameters) self._min_point = min_point self._max_point = max_point # set default legend parameters based on input data_type and unit self._data_type = data_type self._unit = unit if data_type is not None: # TODO: Have data types reference Colorsets, which override default colors assert isinstance(data_type, DataTypeBase), \ 'data_type should be a ladybug DataType. Got {}'.format(type(data_type)) if self.legend_parameters.is_title_default: unit = data_type.units[0] if unit is None else unit data_type.is_unit_acceptable(unit) self.legend_parameters.title = unit if \ self.legend_parameters.vertical is True \ else '{} ({})'.format(data_type.name, unit) if data_type.unit_descr is not None and \ self.legend_parameters.ordinal_dictionary is None: self.legend_parameters.ordinal_dictionary = data_type.unit_descr sorted_keys = sorted(data_type.unit_descr.keys()) if self.legend.is_min_default is True: self.legend_parameters.min = sorted_keys[0] if self.legend.is_max_default is True: self.legend_parameters.max = sorted_keys[-1] if self.legend_parameters.is_segment_count_default: try: # try to set the number of segments to align with ordinal text min_i = sorted_keys.index(self.legend_parameters.min) max_i = sorted_keys.index(self.legend_parameters.max) self.legend_parameters.segment_count = \ len(sorted_keys[min_i:max_i + 1]) except IndexError: pass elif unit is not None and self.legend_parameters.is_title_default: assert isinstance(unit, str), \ 'Expected string for unit. Got {}.'.format(type(unit)) self.legend_parameters.title = unit # set the default segment_height if self.legend_parameters.is_segment_height_default: if self.legend_parameters.vertical: seg_height = float( (self._max_point.y - self._min_point.y) / 20) else: seg_height = float( (self._max_point.x - self._min_point.x) / 20) self.legend_parameters.segment_height = seg_height # set the default base point if self.legend_parameters.is_base_plane_default: if self.legend_parameters.vertical: base_pt = Point3D( self._max_point.x + self.legend_parameters.segment_width, self._min_point.y, self._min_point.z) else: base_pt = Point3D( self._max_point.x, self._max_point.y + 3 * self.legend_parameters.text_height, self._min_point.z) self.legend_parameters.base_plane = Plane(o=base_pt)
def test_check_planar(): """Test the check_planar method.""" pts_1 = (Point3D(0, 0, 2), Point3D(2, 0, 2), Point3D(2, 2, 2), Point3D(0, 2, 2)) pts_2 = (Point3D(0, 0, 0), Point3D(2, 0, 2), Point3D(2, 2, 2), Point3D(0, 2, 2)) pts_3 = (Point3D(0, 0, 2.0001), Point3D(2, 0, 2), Point3D(2, 2, 2), Point3D(0, 2, 2)) plane_1 = Plane(Vector3D(0, 0, 1), Point3D(0, 0, 2)) door_1 = Door('Door1', Face3D(pts_1, plane_1)) door_2 = Door('Door2', Face3D(pts_2, plane_1)) door_3 = Door('Door3', Face3D(pts_3, plane_1)) assert door_1.check_planar(0.001) == '' assert door_2.check_planar(0.001, False) != '' with pytest.raises(Exception): door_2.check_planar(0.0001) assert door_3.check_planar(0.001) == '' assert door_3.check_planar(0.000001, False) != '' with pytest.raises(Exception): door_3.check_planar(0.000001)
def upper_title_location(self): """A Plane for the upper location of title text.""" return Plane(o=Point3D( self._min_point.x, self._max_point.y + self._legend.legend_parameters.text_height, self._min_point.z))
def test_from_geojson_coordinates_simple_location(): """Test the Model coordinates from_geojson method with different location inputs. """ # Test 1: The location is equal to the point (0, 0) in model space. # Construct Model pts_1 = (Point3D(50, 50, 0), Point3D(60, 50, 0), Point3D(60, 60, 0), Point3D(50, 60, 0)) pts_2 = (Point3D(60, 50, 0), Point3D(70, 50, 0), Point3D(70, 60, 0), Point3D(60, 60, 0)) room2d_1 = Room2D('Residence1', Face3D(pts_1), 3) room2d_2 = Room2D('Residence2', Face3D(pts_2), 3) story = Story('ResidenceFloor', [room2d_1, room2d_2]) story.solve_room_2d_adjacency(0.01) story.set_outdoor_window_parameters(SimpleWindowRatio(0.4)) story.multiplier = 3 test_building = Building('ResidenceBuilding', [story]) # Convert to geojson. Location defines the origin of the model space. test_model = Model('TestGeoJSON_coords1', [test_building]) location = Location('Boston', 'MA', 'USA', 42.366151, -71.019357) # bottom-left geojson_folder = './tests/geojson/' test_model.to_geojson(location, folder=geojson_folder) geo_fp = os.path.join(geojson_folder, test_model.identifier, '{}.geojson'.format(test_model.identifier)) # Convert back to Model. Location defines the origin. model = Model.from_geojson(geo_fp, location=location, point=Point2D(0, 0)) assert len(model.buildings) == 1 # Test geometric properties of building bldg1 = model.buildings[0] # Check story height for story in bldg1.unique_stories: assert 3.0 == pytest.approx(story.floor_to_floor_height, abs=1e-10) assert pytest.approx(bldg1.footprint_area, test_building.footprint_area, abs=1e-10) vertices = bldg1.footprint()[0].vertices test_vertices = test_building.footprint()[0].vertices for point, test_point in zip(vertices, test_vertices): assert point.is_equivalent(test_point, 1e-5) # Test 2: Change the location to equal to the point (70, 60) in model space, which is # the top-right corner of the building footprints. # Construct model with a new location that defines the top-right corner in lon/lat degrees. location2 = Location('Boston', 'MA', 'USA', 42.366690813294774, -71.01850462247945) # We define the point at the top-right corner in model units. model = Model.from_geojson(geo_fp, location=location2, point=Point2D(70, 60)) assert len(model.buildings) == 1 # Test geometric properties of building bldg1 = model.buildings[0] assert test_building.footprint_area == pytest.approx(bldg1.footprint_area, abs=1e-5) vertices = bldg1.footprint()[0].vertices test_vertices = test_building.footprint()[0].vertices for point, test_point in zip(vertices, test_vertices): assert point.is_equivalent(test_point, 1e-3) # reduce precision due to conversion nukedir(os.path.join(geojson_folder, test_model.identifier), True)
def test_properties(): """Test various properties on the model.""" pts_1 = (Point3D(0, 0, 3), Point3D(10, 0, 3), Point3D(10, 10, 3), Point3D(0, 10, 3)) pts_2 = (Point3D(10, 0, 3), Point3D(20, 0, 3), Point3D(20, 10, 3), Point3D(10, 10, 3)) pts_3 = (Point3D(0, 20, 3), Point3D(20, 20, 3), Point3D(20, 30, 3), Point3D(0, 30, 3)) room2d_1 = Room2D('Office1', Face3D(pts_1), 3) room2d_2 = Room2D('Office2', Face3D(pts_2), 3) room2d_3 = Room2D('Office3', Face3D(pts_3), 3) story_big = Story('OfficeFloorBig', [room2d_3]) story = Story('OfficeFloor', [room2d_1, room2d_2]) story.solve_room_2d_adjacency(0.01) story.set_outdoor_window_parameters(SimpleWindowRatio(0.4)) story.multiplier = 4 building = Building('OfficeBuilding', [story]) story_big.set_outdoor_window_parameters(SimpleWindowRatio(0.4)) story_big.multiplier = 2 building_big = Building('OfficeBuildingBig', [story_big]) model = Model('NewDevelopment', [building, building_big]) assert model.average_story_count == 3 assert model.average_story_count_above_ground == 3 assert model.average_height == 12 assert model.average_height_above_ground == 9 assert model.footprint_area == 100 * 4 assert model.floor_area == (100 * 2 * 4) + (200 * 2) assert model.exterior_wall_area == (90 * 2 * 4) + (180 * 2) assert model.exterior_aperture_area == (90 * 2 * 4 * 0.4) + (180 * 2 * 0.4) assert model.volume == (100 * 2 * 4 * 3) + (200 * 2 * 3)
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'
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 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
def test_check_duplicate_face_identifiers(): """Test the check_duplicate_face_identifiers method.""" pts_1 = [ Point3D(0, 0, 0), Point3D(0, 10, 0), Point3D(10, 10, 0), Point3D(10, 0, 0) ] pts_2 = [ Point3D(0, 0, 0), Point3D(0, 0, 3), Point3D(0, 10, 3), Point3D(0, 10, 0) ] pts_3 = [ Point3D(0, 0, 0), Point3D(10, 0, 0), Point3D(10, 0, 3), Point3D(0, 0, 3) ] pts_4 = [ Point3D(10, 10, 0), Point3D(0, 10, 0), Point3D(0, 10, 3), Point3D(10, 10, 3) ] pts_5 = [ Point3D(10, 10, 0), Point3D(10, 0, 0), Point3D(10, 0, 3), Point3D(10, 10, 3) ] pts_6 = [ Point3D(10, 0, 3), Point3D(10, 10, 3), Point3D(0, 10, 3), Point3D(0, 0, 3) ] face_1 = Face('Face1', Face3D(pts_1)) face_2 = Face('Face2', Face3D(pts_2)) face_3 = Face('Face3', Face3D(pts_3)) face_4 = Face('Face4', Face3D(pts_4)) face_5 = Face('Face5', Face3D(pts_5)) face_6 = Face('Face6', Face3D(pts_6)) face_7 = Face('Face1', Face3D(pts_6)) room_1 = Room('TestRoom', [face_1, face_2, face_3, face_4, face_5, face_6]) room_2 = Room('TestRoom', [face_1, face_2, face_3, face_4, face_5, face_7]) model_1 = Model('TestHouse', [room_1]) model_2 = Model('TestHouse', [room_2]) assert model_1.check_duplicate_face_identifiers(False) assert not model_2.check_duplicate_face_identifiers(False) with pytest.raises(ValueError): model_2.check_duplicate_face_identifiers(True)
def test_check_planar(): """Test the check_planar method.""" pts_1 = (Point3D(0, 0, 2), Point3D(2, 0, 2), Point3D(2, 2, 2), Point3D(0, 2, 2)) pts_2 = (Point3D(0, 0, 0), Point3D(2, 0, 2), Point3D(2, 2, 2), Point3D(0, 2, 2)) pts_3 = (Point3D(0, 0, 2.0001), Point3D(2, 0, 2), Point3D(2, 2, 2), Point3D(0, 2, 2)) plane_1 = Plane(Vector3D(0, 0, 1), Point3D(0, 0, 2)) shade_1 = Shade('Shade1', Face3D(pts_1, plane_1)) shade_2 = Shade('Shade2', Face3D(pts_2, plane_1)) shade_3 = Shade('Shade3', Face3D(pts_3, plane_1)) assert shade_1.check_planar(0.001) == '' assert shade_2.check_planar(0.001, False) != '' with pytest.raises(Exception): shade_2.check_planar(0.0001) assert shade_3.check_planar(0.001) == '' assert shade_3.check_planar(0.000001, False) != '' with pytest.raises(Exception): shade_3.check_planar(0.000001)
def test_model_init_orphaned_objects(): """Test the initialization of the Model with orphaned objects.""" pts_1 = [ Point3D(0, 0, 0), Point3D(0, 10, 0), Point3D(10, 10, 0), Point3D(10, 0, 0) ] pts_2 = [ Point3D(0, 0, 0), Point3D(0, 0, 3), Point3D(0, 10, 3), Point3D(0, 10, 0) ] pts_3 = [ Point3D(0, 0, 0), Point3D(10, 0, 0), Point3D(10, 0, 3), Point3D(0, 0, 3) ] pts_4 = [ Point3D(10, 10, 0), Point3D(0, 10, 0), Point3D(0, 10, 3), Point3D(10, 10, 3) ] pts_5 = [ Point3D(10, 10, 0), Point3D(10, 0, 0), Point3D(10, 0, 3), Point3D(10, 10, 3) ] pts_6 = [ Point3D(10, 0, 3), Point3D(10, 10, 3), Point3D(0, 10, 3), Point3D(0, 0, 3) ] face_1 = Face('Face1', Face3D(pts_1)) face_2 = Face('Face2', Face3D(pts_2)) face_3 = Face('Face3', Face3D(pts_3)) face_4 = Face('Face4', Face3D(pts_4)) face_5 = Face('Face5', Face3D(pts_5)) face_6 = Face('Face6', Face3D(pts_6)) face_2.apertures_by_ratio(0.4, 0.01) face_2.apertures[0].overhang(0.5, indoor=False) face_2.apertures[0].overhang(0.5, indoor=True) face_2.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, 5, 1), Point3D(2.5, 5, 1), Point3D(2.5, 5, 2.5), Point3D(4.5, 5, 2.5) ] door = Door('FrontDoor', Face3D(door_verts)) aperture = Aperture('Partition', Face3D(aperture_verts)) table_geo = Face3D.from_rectangle(2, 2, Plane(o=Point3D(1.5, 4, 1))) table = Shade('Table', table_geo) tree_canopy_geo = Face3D.from_regular_polygon(6, 2, Plane(o=Point3D(5, -3, 4))) tree_canopy = Shade('TreeCanopy', tree_canopy_geo) model = Model('TinyHouse', [], [face_1, face_2, face_3, face_4, face_5, face_6], [table, tree_canopy], [aperture], [door]) assert len(model.rooms) == 0 assert len(model.faces) == 6 assert isinstance(model.faces[0], Face) assert len(model.shades) == 4 assert isinstance(model.shades[0], Shade) 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.orphaned_faces) == 6 assert len(model.orphaned_shades) == 2 assert len(model.orphaned_apertures) == 1 assert len(model.orphaned_doors) == 1
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_check_self_intersecting(): """Test the check_self_intersecting method.""" pts_1 = [ Point3D(0, 0, 0), Point3D(0, 10, 0), Point3D(10, 10, 0), Point3D(10, 0, 0) ] pts_2 = [ Point3D(0, 0, 0), Point3D(0, 0, 3), Point3D(0, 10, 3), Point3D(0, 10, 0) ] pts_3 = [ Point3D(0, 0, 0), Point3D(10, 0, 0), Point3D(10, 0, 3), Point3D(0, 0, 3) ] pts_4 = [ Point3D(10, 10, 0), Point3D(0, 10, 0), Point3D(0, 10, 3), Point3D(10, 10, 3) ] pts_5 = [ Point3D(10, 10, 0), Point3D(10, 0, 0), Point3D(10, 0, 3), Point3D(10, 10, 3) ] pts_6 = [ Point3D(10, 0, 3), Point3D(10, 10, 3), Point3D(0, 10, 3), Point3D(0, 0, 3) ] pts_7 = [ Point3D(10, 0, 3), Point3D(0, 5, 3), Point3D(10, 10, 3), Point3D(0, 0, 3) ] pts_8 = [Point3D(0, 5, 3), Point3D(10, 10, 3), Point3D(10, 0, 3)] face_1 = Face('Face1', Face3D(pts_1)) face_2 = Face('Face2', Face3D(pts_2)) face_3 = Face('Face3', Face3D(pts_3)) face_4 = Face('Face4', Face3D(pts_4)) face_5 = Face('Face5', Face3D(pts_5)) face_6 = Face('Face6', Face3D(pts_6)) face_7 = Face('Face7', Face3D(pts_7)) face_8 = Face('Face8', Face3D(pts_8)) room_1 = Room('ZoneSHOE_BOX920980', [face_1, face_2, face_3, face_4, face_5, face_6], 0.01, 1) room_2 = Room('ZoneSHOE_BOX920980', [face_1, face_2, face_3, face_4, face_5, face_7, face_8], 0.01, 1) model_1 = Model('SouthHouse', [room_1]) model_2 = Model('NorthHouse', [room_2]) assert model_1.check_self_intersecting(False) assert not model_2.check_self_intersecting(False) with pytest.raises(ValueError): model_2.check_self_intersecting(True)
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_adjustable_postion(): """Test if correct adjustable position is being returned.""" bounds = [ Point3D(-7.00, -4.00, 1.00), Point3D(12.00, 9.00, 5.00), Point3D(-8.00, -4.00, 0.00), Point3D(13.00, 9.00, 5.00), Point3D(-8.00, -7.00, 0.00), Point3D(12.00, 20.00, 15.00), Point3D(-8.00, -4.00, 0.00), Point3D(13.00, 9.00, 0.00), Point3D(-8.00, -4.00, 3.00), Point3D(13.00, 9.00, 5.00) ] camera = Camera(position=(0, 0, 5000), direction=(0, 0, -1)) assert camera._outermost_point(bounds=bounds) == Point3D( 12.00, 20.00, 15.00) assert camera._adjusted_position(bounds=bounds) == (0, 0, 16)
if all_required_inputs(ghenv.Component): # process all of the global inputs for the sunpath if north_ is not None: # process the north_ try: north_ = math.degrees( to_vector2d(north_).angle_clockwise(Vector2D(0, 1))) except AttributeError: # north angle instead of vector north_ = float(north_) else: north_ = 0 if _center_pt_ is not None: # process the center point into a Point2D center_pt, center_pt3d = to_point2d(_center_pt_), to_point3d( _center_pt_) z = center_pt3d.z else: center_pt, center_pt3d = Point2D(), Point3D() z = 0 _scale_ = 1 if _scale_ is None else _scale_ # process the scale into a radius radius = (100 * _scale_) / conversion_to_meters() solar_time_ = False if solar_time_ is None else solar_time_ # process solar time projection_ = projection_.title() if projection_ is not None else None # create a intersection of the input hoys_ and the data hoys if len(data_) > 0 and data_[0] is not None and len(hoys_) > 0: all_aligned = all(data_[0].is_collection_aligned(d) for d in data_[1:]) assert all_aligned, 'All collections input to data_ must be aligned for ' \ 'each Sunpath.\nGrafting the data_ and suplying multiple grafted ' \ '_center_pt_ can be used to view each data on its own path.' if statement_ is not None: data_ = HourlyContinuousCollection.filter_collections_by_statement( data_, statement_)
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)
def test_to_dict_single_zone(): """Test the Model to_dict method with a single zone model.""" room = Room.from_box('Tiny House Zone', 5, 10, 3) room.properties.energy.program_type = office_program room.properties.energy.hvac = IdealAirSystem() 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]) model.north_angle = 15 model_dict = model.to_dict() assert 'energy' in model_dict['properties'] assert 'materials' in model_dict['properties']['energy'] assert 'constructions' in model_dict['properties']['energy'] assert 'construction_sets' in model_dict['properties']['energy'] assert 'global_construction_set' in model_dict['properties']['energy'] assert len(model_dict['properties']['energy']['materials']) == 16 assert len(model_dict['properties']['energy']['constructions']) == 18 assert len(model_dict['properties']['energy']['construction_sets']) == 1 assert model_dict['rooms'][0]['faces'][0]['properties']['energy']['construction'] == \ thermal_mass_constr.name south_ap_dict = model_dict['rooms'][0]['faces'][3]['apertures'][0] assert south_ap_dict['outdoor_shades'][0]['properties']['energy']['construction'] == \ light_shelf_out.name assert south_ap_dict['indoor_shades'][0]['properties']['energy']['construction'] == \ light_shelf_in.name assert model_dict['rooms'][0]['faces'][1]['apertures'][0]['properties']['energy']['construction'] == \ triple_pane.name assert model_dict['rooms'][0]['properties']['energy']['program_type'] == \ office_program.name assert model_dict['rooms'][0]['properties']['energy']['hvac'] == \ IdealAirSystem().to_dict() """
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)
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)) first_floor.properties.energy.program_type = office_program second_floor.properties.energy.program_type = office_program first_floor.properties.energy.hvac = IdealAirSystem() second_floor.properties.energy.hvac = IdealAirSystem() 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('Attic Face 1', Face3D(pts_1)) face_2 = Face('Attic Face 2', Face3D(pts_2)) face_3 = Face('Attic Face 3', Face3D(pts_3)) face_4 = Face('Attic Face 4', Face3D(pts_4)) face_5 = Face('Attic Face 5', 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]) model_dict = model.to_dict() assert 'energy' in model_dict['properties'] assert 'materials' in model_dict['properties']['energy'] assert 'constructions' in model_dict['properties']['energy'] assert 'construction_sets' in model_dict['properties']['energy'] assert 'global_construction_set' in model_dict['properties']['energy'] assert len(model_dict['properties']['energy']['materials']) == 16 assert len(model_dict['properties']['energy']['constructions']) == 16 assert len(model_dict['properties']['energy']['construction_sets']) == 2 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']['energy']['construction_set'] == \ constr_set.name assert model_dict['rooms'][0]['properties']['energy']['program_type'] == \ model_dict['rooms'][1]['properties']['energy']['program_type'] == \ office_program.name assert model_dict['rooms'][0]['properties']['energy']['hvac'] == \ model_dict['rooms'][1]['properties']['energy']['hvac'] == \ IdealAirSystem().to_dict() """
def test_to_from_dict_methods(): """Test the to/from dict methods.""" pts_1 = (Point3D(0, 0, 3), Point3D(0, 10, 3), Point3D(10, 10, 3), Point3D(10, 0, 3)) pts_2 = (Point3D(10, 0, 3), Point3D(10, 10, 3), Point3D(20, 10, 3), Point3D(20, 0, 3)) pts_3 = (Point3D(0, 10, 3), Point3D(0, 20, 3), Point3D(10, 20, 3), Point3D(10, 10, 3)) pts_4 = (Point3D(10, 10, 3), Point3D(10, 20, 3), Point3D(20, 20, 3), Point3D(20, 10, 3)) room2d_1 = Room2D('Office1', Face3D(pts_1), 3) room2d_2 = Room2D('Office2', Face3D(pts_2), 3) room2d_3 = Room2D('Office3', Face3D(pts_3), 3) room2d_4 = Room2D('Office4', Face3D(pts_4), 3) story = Story('OfficeFloor', [room2d_1, room2d_2, room2d_3, room2d_4]) story.solve_room_2d_adjacency(0.01) story.set_outdoor_window_parameters(SimpleWindowRatio(0.4)) story.multiplier = 4 building = Building('OfficeBuilding', [story]) tree_canopy_geo1 = Face3D.from_regular_polygon(6, 6, Plane(o=Point3D(5, -10, 6))) tree_canopy_geo2 = Face3D.from_regular_polygon(6, 2, Plane(o=Point3D(-5, -10, 3))) tree_canopy = ContextShade('TreeCanopy', [tree_canopy_geo1, tree_canopy_geo2]) model = Model('NewDevelopment', [building], [tree_canopy]) model_dict = model.to_dict() new_model = Model.from_dict(model_dict) assert model_dict == new_model.to_dict()