def test_orientation_simple(): """Test the simple use of the orientation module.""" # create a Room to assign different propeties by orientation. room = Room.from_box('ShoeBox', 5, 10, 3, 0, Point3D(0, 0, 3)) # list of bcs properties to apply to faces of different orientations bcs = boundary_conditions boundaries = [bcs.outdoors, bcs.ground, bcs.outdoors, bcs.ground] ratios = [0.4, 0, 0.6, 0] # check that the inputs align with one another all_inputs = [boundaries, ratios] all_inputs, num_orient = check_matching_inputs(all_inputs) # assign proeprties based on orientation angles = angles_from_num_orient(num_orient) for face in room.faces: orient_i = face_orient_index(face, angles) if orient_i is not None: bc, ratio = inputs_by_index(orient_i, all_inputs) face.boundary_condition = bc if ratio != 0: face.apertures_by_ratio(ratio, 0.01) assert isinstance(room[1].boundary_condition, Outdoors) assert isinstance(room[2].boundary_condition, Ground) assert isinstance(room[3].boundary_condition, Outdoors) assert isinstance(room[4].boundary_condition, Ground) assert len(room[0].apertures) == 0 assert len(room[1].apertures) == 1 assert len(room[2].apertures) == 0 assert len(room[3].apertures) == 1 assert len(room[4].apertures) == 0 assert len(room[5].apertures) == 0
def group_by_orientation(rooms, group_count=None, north_vector=Vector2D(0, 1)): """Group Rooms with the same average outdoor wall orientation. Args: rooms: A list of honeybee rooms to be grouped by orientation. group_count: An optional positive integer to set the number of orientation groups to use. For example, setting this to 4 will result in rooms being grouped by four orientations (North, East, South, West). If None, the maximum number of unique groups will be used. north_vector: A ladybug_geometry Vector2D for the north direction. Default is the Y-axis (0, 1). Returns: A tuple with three items. - grouped_rooms - A list of lists of honeybee rooms with each sub-list representing a different orientation. - core_rooms - A list of honeybee rooms with no identifiable orientation. - orientations - A list of numbers between 0 and 360 with one orientation for each branch of the output grouped_rooms. This will be a list of angle ranges if a value is input for group_count. """ # loop through each of the rooms and get the orientation orient_dict = {} core_rooms = [] for room in rooms: ori = room.average_orientation(north_vector) if ori is None: core_rooms.append(room) else: try: orient_dict[ori].append(room) except KeyError: orient_dict[ori] = [] orient_dict[ori].append(room) # sort the rooms by orientation values room_mtx = sorted(orient_dict.items(), key=lambda d: float(d[0])) orientations = [r_tup[0] for r_tup in room_mtx] grouped_rooms = [r_tup[1] for r_tup in room_mtx] # group orientations if there is an input group_count if group_count is not None: angs = angles_from_num_orient(group_count) p_rooms = [[] for i in range(group_count)] for ori, rm in zip(orientations, grouped_rooms): or_ind = orient_index(ori, angs) p_rooms[or_ind].extend(rm) orientations = [ '{} - {}'.format(int(angs[i - 1]), int(angs[i])) for i in range(group_count) ] grouped_rooms = p_rooms return grouped_rooms, core_rooms, orientations
def apply_boundary_condition(rooms, bc_list, bc_to_assign): """Apply a boundary condition list to the dragonfly objects.""" angles = angles_from_num_orient(len(bc_list)) rooms = extract_room_2ds(df_obj) for room in rooms: room_bcs, room_glz = [], [] zip_props = zip(room.boundary_conditions, room.window_parameters, room.segment_orientations()) for bc, glz, orient in zip_props: orient_i = orient_index(orient, angles) use_ad = bc_list[orient_i] if isinstance(bc, Outdoors) else None final_bc = bc_to_assign if use_ad else bc room_bcs.append(final_bc) final_glz = None if use_ad else glz room_glz.append(final_glz) room.window_parameters = room_glz room.boundary_conditions = room_bcs
def windows_by_ratio(model_json, ratio, output_file): """Add windows to all outdoor walls of a model given a ratio. Note that this method removes any existing WindowParameters. \b Args: model_json: Full path to a Dragonfly DFJSON or DFpkl file. ratio: A number between 0 and 1 (but not perfectly equal to 1) for the desired ratio between window area and wall area. If multiple values are input here, different WindowParameters will be assigned based on cardinal direction, starting with north and moving clockwise. """ try: # serialize the Model and convert ratios to window parameters model = Model.from_file(model_json) win_par = [SimpleWindowRatio(rat) for rat in ratio] # add the window parameters if len(win_par) == 1: # one window parameter for all model.set_outdoor_window_parameters(win_par[0]) else: # different window parameters by cardinal direction angles = angles_from_num_orient(len(win_par)) rooms = [ room for bldg in model.buildings for room in bldg.unique_room_2ds ] for rm in rooms: room_win_par = [] for bc, orient in zip(rm.boundary_conditions, rm.segment_orientations()): orient_i = orient_index(orient, angles) win_p = win_par[orient_i] if isinstance(bc, Outdoors) else None room_win_par.append(win_p) rm.window_parameters = room_win_par # write the new model out to the file or stdout output_file.write(json.dumps(model.to_dict())) except Exception as e: _logger.exception('Model windows by ratio failed.\n{}'.format(e)) sys.exit(1) else: sys.exit(0)
# error message for unrecognized object error_msg = 'Input _hb_objs must be a Room, Face, Aperture, Door, or Shade. Not {}.' # assign the schedules if len(_trans_sch) == 1: for obj in hb_objs: if isinstance(obj, Shade): obj.properties.energy.transmittance_schedule = _trans_sch[0] elif isinstance(obj, (Aperture, Face, Room, Door)): for shd in obj.shades: shd.properties.energy.transmittance_schedule = _trans_sch[ 0] else: raise TypeError(error_msg.format(type(obj))) else: # assign schedules based on cardinal direction angles = angles_from_num_orient(len(_trans_sch)) for obj in hb_objs: if isinstance(obj, (Aperture, Face, Door)): orient_i = face_orient_index(obj, angles) if orient_i is not None: for shd in obj.shades: shd.properties.energy.transmittance_schedule = _trans_sch[ orient_i] elif isinstance(obj, Shade): obj.properties.energy.transmittance_schedule = _trans_sch[0] elif isinstance(obj, Room): for shd in obj.shades: shd.properties.energy.transmittance_schedule = _trans_sch[ 0] else: raise TypeError(error_msg.format(type(obj)))
) == 1: # assign indiscriminately, even if it's a horizontal object for obj in hb_objs: if isinstance(obj, (Aperture, Door)): obj.properties.energy.construction = _constr[0] elif isinstance(obj, Face): for ap in obj.apertures: ap.properties.energy.construction = _constr[0] elif isinstance(obj, Room): for face in obj.faces: if is_exterior_wall(face): for ap in face.apertures: ap.properties.energy.construction = _constr[0] else: raise TypeError(error_msg.format(type(obj))) else: # assign constructions only to non-horizontal objects based on cardinal direction angles = angles_from_num_orient(len(_constr)) for obj in hb_objs: if isinstance(obj, (Aperture, Door)): orient_i = face_orient_index(obj, angles) if orient_i is not None: obj.properties.energy.construction = _constr[orient_i] elif isinstance(obj, Face): orient_i = face_orient_index(obj, angles) if orient_i is not None: for ap in obj.apertures: ap.properties.energy.construction = _constr[orient_i] elif isinstance(obj, Room): for face in obj.faces: if is_exterior_wall(face): orient_i = face_orient_index(face, angles) if orient_i is not None:
# error message for unrecognized object error_msg = 'Input _hb_objs must be a Room, Face, Aperture, Door, or Shade. Not {}.' # assign the modifiers if len(_mod) == 1: for obj in hb_objs: if isinstance(obj, Shade): obj.properties.radiance.modifier = _mod[0] elif isinstance(obj, (Aperture, Face, Room, Door)): for shd in obj.shades: shd.properties.radiance.modifier = _mod[0] else: raise TypeError(error_msg.format(type(obj))) else: # assign modifiers based on cardinal direction angles = angles_from_num_orient(len(_mod)) for obj in hb_objs: if isinstance(obj, (Aperture, Face, Door)): orient_i = face_orient_index(obj, angles) if orient_i is not None: for shd in obj.shades: shd.properties.radiance.modifier = _mod[orient_i] elif isinstance(obj, Shade): obj.properties.radiance.modifier = _mod[0] elif isinstance(obj, Room): for shd in obj.shades: shd.properties.radiance.modifier = _mod[0] else: raise TypeError(error_msg.format(type(obj)))
# assign the adiabatic property to exposed floors if interior_walls_ and check_type(face, Surface, Wall): face.boundary_condition = boundary_conditions.adiabatic # assign the adiabatic property to exposed floors if interior_floors_ and check_type(face, Surface, (RoofCeiling, Floor)): face.boundary_condition = boundary_conditions.adiabatic if all_required_inputs(ghenv.Component): # duplicate the initial objects hb_objs = [obj.duplicate() for obj in _hb_objs] # assign the adiabatic property to the walls if len(exterior_walls_) > 0: angles = angles_from_num_orient(len(exterior_walls_)) for obj in hb_objs: if isinstance(obj, Room): for face in obj.faces: if check_type(face, Outdoors, Wall): orient_i = face_orient_index(face, angles) if orient_i is not None and exterior_walls_[orient_i]: face.boundary_condition = boundary_conditions.adiabatic else: # assume it is a Face if check_type(obj, Outdoors, Wall): orient_i = face_orient_index(obj, angles) if orient_i is not None and exterior_walls_[orient_i]: obj.boundary_condition = boundary_conditions.adiabatic # assign the adiabatic property to all of the other face types for obj in hb_objs:
if isinstance(mod, str): rad_mod_[i] = modifier_by_identifier(mod) else: rad_mod_ = [None] # gather all of the inputs together all_inputs = [ _depth, _shade_count_, _dist_between_, _facade_offset_, _angle_, vertical_, flip_start_, indoor_, ep_constr_, rad_mod_ ] # ensure matching list lengths across all values all_inputs, num_orient = check_matching_inputs(all_inputs) # get a list of angles used to categorize the faces angles = angles_from_num_orient(num_orient) # loop through the input objects and add apertures for obj in hb_objs: if isinstance(obj, Room): for face in obj.faces: if can_host_louvers(face): orient_i = face_orient_index(face, angles) depth, count, dist, off, angle, vec, flip, indr, con, mod = \ inputs_by_index(orient_i, all_inputs) for ap in face.apertures: assign_louvers(ap, depth, count, dist, off, angle, vec, flip, indr, con, mod) elif isinstance(obj, Face): if can_host_louvers(obj): orient_i = face_orient_index(obj, angles)
rooms.extend(obj.room_2ds) elif isinstance(obj, Room2D): rooms.append(obj) return rooms if all_required_inputs(ghenv.Component): # duplicate the initial objects df_obj = [obj.duplicate() for obj in _df_obj] # add the window parameters if len(_win_par_) == 1: # one window parameter for all for obj in df_obj: obj.set_outdoor_window_parameters(_win_par_[0]) elif len(_win_par_) > 1: # different window parameters by cardinal direction angles = angles_from_num_orient(len(_win_par_)) rooms = extract_room_2ds(df_obj) for room in rooms: room_win_par = [] for bc, orient in zip(room.boundary_conditions, room.segment_orientations()): orient_i = orient_index(orient, angles) win_p = _win_par_[orient_i] if isinstance(bc, Outdoors) else None room_win_par.append(win_p) room.window_parameters = room_win_par # add the shading parameters if len(_shd_par_) == 1: # one shading parameter for all for obj in df_obj: obj.set_outdoor_shading_parameters(_shd_par_[0]) elif len(_shd_par_) > 1: # different shading parameters by cardinal direction angles = angles_from_num_orient(len(_shd_par_))