def test_init_adaptive_collection_mrt(): """Test the initialization of the Adaptive collection with MRT.""" calc_length = 24 prevail_header = Header(PrevailingOutdoorTemperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) prevail_temp = HourlyContinuousCollection(prevail_header, [22] * calc_length) air_temp_header = Header(Temperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) air_temp = HourlyContinuousCollection(air_temp_header, [24] * calc_length) adapt_obj = Adaptive.from_air_and_rad_temp(prevail_temp, air_temp, 28) assert adapt_obj.comfort_model == 'Adaptive' assert adapt_obj.calc_length == calc_length str(adapt_obj) # test that the string representation is ok assert isinstance(adapt_obj.prevailing_outdoor_temperature, HourlyContinuousCollection) assert len(adapt_obj.prevailing_outdoor_temperature.values) == calc_length assert adapt_obj.prevailing_outdoor_temperature[0] == 22 assert isinstance(adapt_obj.operative_temperature, HourlyContinuousCollection) assert len(adapt_obj.operative_temperature.values) == calc_length assert adapt_obj.operative_temperature[0] == 26 assert isinstance(adapt_obj.neutral_temperature, HourlyContinuousCollection) assert len(adapt_obj.neutral_temperature.values) == calc_length assert adapt_obj.neutral_temperature[0] == pytest.approx(24.62, rel=1e-3) assert isinstance(adapt_obj.degrees_from_neutral, HourlyContinuousCollection) assert len(adapt_obj.degrees_from_neutral.values) == calc_length assert adapt_obj.degrees_from_neutral[0] == pytest.approx(1.3799, rel=1e-3)
def test_adaptive_collection_epw_prevailing(): """Test the percent outputs of the Adaptive collection.""" calc_length = 24 relative_path = './tests/epw/chicago.epw' epw = EPW(relative_path) op_temp_header = Header(Temperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) op_temp = HourlyContinuousCollection(op_temp_header, [26] * calc_length) adapt_obj = Adaptive(epw.dry_bulb_temperature, op_temp) assert isinstance(adapt_obj.prevailing_outdoor_temperature, HourlyContinuousCollection) assert len(adapt_obj.prevailing_outdoor_temperature.values) == calc_length assert adapt_obj.prevailing_outdoor_temperature[0] == pytest.approx( -4.64845637, rel=1e-3) assert isinstance(adapt_obj.operative_temperature, HourlyContinuousCollection) assert len(adapt_obj.operative_temperature.values) == calc_length assert adapt_obj.operative_temperature[0] == 26 assert isinstance(adapt_obj.neutral_temperature, HourlyContinuousCollection) assert len(adapt_obj.neutral_temperature.values) == calc_length assert adapt_obj.neutral_temperature[0] == pytest.approx(20.9, rel=1e-3) assert isinstance(adapt_obj.degrees_from_neutral, HourlyContinuousCollection) assert len(adapt_obj.degrees_from_neutral.values) == calc_length assert adapt_obj.degrees_from_neutral[0] == pytest.approx(5.099999, rel=1e-3)
def adaptive(result_sql, enclosure_info, epw_file, total_irradiance, direct_irradiance, ref_irradiance, sun_up_hours, air_speed, run_period, comfort_par, solarcal_par, folder, log_file): """Get CSV files with maps of Adaptive comfort from EnergyPlus and Radiance results. \b Args: result_sql: Path to an SQLite file that was generated by EnergyPlus. This file must contain hourly or sub-hourly results for zone comfort variables. enclosure_info: Path to a JSON file containing information about the radiant enclosure that sensor points belong to. epw_file: Path to an .epw file, used to estimate conditions for any outdoor sensors and to provide prevailing outdoor temperature for the adaptive comfort model. """ try: # load the EPW object, run period, air speed, and other parameters epw_obj = EPW(epw_file) run_period = _load_analysis_period_str(run_period) air_speed = _load_values(air_speed) solarcal_par = _load_solarcal_par_str(solarcal_par) comfort_par = _load_adaptive_par_str(comfort_par) # load and align the thermal results from the result_sql file pt_air_temps, pt_rad_temps, _, pt_speeds, _ = _parse_enclosure_info( enclosure_info, result_sql, epw_obj, run_period, air_speed) # adjust the radiant temperature for shortwave solar pt_rad_temps = shortwave_mrt_map(epw_obj.location, pt_rad_temps, sun_up_hours, total_irradiance, direct_irradiance, ref_irradiance, solarcal_par) # compute previaling outdoor temperature so it's not recomputed for each sensor avg_month = comfort_par.avg_month_or_running_mean \ if comfort_par is not None else True prev_obj = PrevailingTemperature(epw_obj.dry_bulb_temperature, avg_month) prevail_temp = prev_obj.get_aligned_prevailing(pt_air_temps[0]) # run the collections through the Adaptive model and output results temperature, condition, condition_intensity = [], [], [] for t_air, t_rad, vel in zip(pt_air_temps, pt_rad_temps, pt_speeds): adaptive_obj = Adaptive.from_air_and_rad_temp( prevail_temp, t_air, t_rad, vel, comfort_parameter=comfort_par) temperature.append(adaptive_obj.operative_temperature) condition.append(adaptive_obj.thermal_condition) condition_intensity.append(adaptive_obj.degrees_from_neutral) # write out the final results to CSV files result_file_dict = _thermal_map_csv(folder, result_sql, temperature, condition, condition_intensity) log_file.write(json.dumps(result_file_dict)) except Exception as e: _logger.exception( 'Failed to run Adaptive model comfort map.\n{}'.format(e)) sys.exit(1) else: sys.exit(0)
def test_adaptive_collection_immutability(): """Test that the Adaptive collection is immutable.""" calc_length = 24 prevail_header = Header(PrevailingOutdoorTemperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) prevail_temp = HourlyContinuousCollection(prevail_header, [22] * calc_length) op_temp_header = Header(Temperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) op_temp = HourlyContinuousCollection(op_temp_header, [26] * calc_length) adapt_obj = Adaptive(prevail_temp, op_temp) # check that editing the original collection does not mutate the object op_temp[0] = 28 assert adapt_obj.operative_temperature[0] == 26 # check that editing collection properties does not mutate the object with pytest.raises(Exception): adapt_obj.operative_temperature[0] = 28 with pytest.raises(Exception): adapt_obj.operative_temperature.values = [28] * calc_length with pytest.raises(Exception): adapt_obj.degrees_from_neutral[0] = 0.5 with pytest.raises(Exception): adapt_obj.degrees_from_neutral.values = [0.5] * calc_length # check that properties cannot be edited directly with pytest.raises(Exception): adapt_obj.operative_temperature = op_temp with pytest.raises(Exception): adapt_obj.degrees_from_neutral = op_temp with pytest.raises(Exception): adapt_obj.comfort_parameter = AdaptiveParameter(False)
def test_adaptive_collection_comfort_percent_outputs(): """Test the percent outputs of the Adaptive collection.""" relative_path = './tests/epw/chicago.epw' epw = EPW(relative_path) adapt_obj = Adaptive(epw.dry_bulb_temperature, epw.dry_bulb_temperature) assert adapt_obj.percent_comfortable == pytest.approx(12.95662, rel=1e-3) assert adapt_obj.percent_uncomfortable == pytest.approx(87.043378, rel=1e-3) assert adapt_obj.percent_neutral == pytest.approx(12.95662, rel=1e-3) assert adapt_obj.percent_hot == pytest.approx(6.4726027, rel=1e-3) assert adapt_obj.percent_cold == pytest.approx(80.570776, rel=1e-3)
def test_adaptive_collection_cooling_effect_output(): """Test the cooling effect output of the Adaptive collection.""" calc_length = 24 prevail_header = Header(PrevailingOutdoorTemperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) prevail_temp = HourlyContinuousCollection(prevail_header, [22] * calc_length) op_temp_header = Header(Temperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) op_temp = HourlyContinuousCollection(op_temp_header, [26] * calc_length) adapt_obj = Adaptive(prevail_temp, op_temp, air_speed=0.7) assert isinstance(adapt_obj.cooling_effect, HourlyContinuousCollection) assert len(adapt_obj.cooling_effect.values) == calc_length assert adapt_obj.cooling_effect[0] == 1.2
def test_init_adaptive_collection_epw(): """Test the initialization of the Adaptive collection with EPW input.""" calc_length = 8760 relative_path = './tests/epw/chicago.epw' epw = EPW(relative_path) adapt_obj = Adaptive(epw.dry_bulb_temperature, epw.dry_bulb_temperature) assert len(adapt_obj.prevailing_outdoor_temperature.values) == calc_length assert adapt_obj.prevailing_outdoor_temperature[0] == pytest.approx( -4.648456, rel=1e-3) assert len(adapt_obj.operative_temperature.values) == calc_length assert adapt_obj.operative_temperature[0] == -6.1 assert len(adapt_obj.neutral_temperature.values) == calc_length assert adapt_obj.neutral_temperature[0] == pytest.approx(20.9, rel=1e-3) assert len(adapt_obj.degrees_from_neutral.values) == calc_length assert adapt_obj.degrees_from_neutral[0] == pytest.approx(-27.0, rel=1e-1)
def adaptive_by_room(result_sql, epw_file, air_speed, comfort_par, result_type, output_file): """Get data collections for Adaptive comfort in each room from an EnergyPlus sql. \b Args: result_sql: Path to an SQLite file that was generated by EnergyPlus. This file must contain hourly or sub-hourly results for zone comfort variables. epw_file: Path to an .epw file, used to provide prevailing outdoor temperature for the adaptive comfort model. """ try: # load the energyplus results related to thermal comfort and the EPW object epw_obj = EPW(epw_file) out_temp = epw_obj.dry_bulb_temperature sql_obj = SQLiteResult(result_sql) op_temps = sql_obj.data_collections_by_output_name( 'Zone Operative Temperature') # load the air speed data collection if specified assert len(op_temps) != 0, \ 'Input result-sql does not contain "Zone Operative Temperature" output.' air_speed = _load_data(air_speed, op_temps[0], AirSpeed, 'm/s') # run the collections through the Adaptive model and output results param = _load_adaptive_par_str(comfort_par) ad_colls = [] for op_temp in op_temps: ad_obj = Adaptive(out_temp, op_temp, air_speed, comfort_parameter=param) if result_type == 'DegreesFromNeutral': ad_colls.append(ad_obj.degrees_from_neutral) elif result_type == 'Comfort': ad_colls.append(ad_obj.is_comfortable) else: ad_colls.append(ad_obj.thermal_condition) output_file.write(json.dumps([col.to_dict() for col in ad_colls])) except Exception as e: _logger.exception( 'Failed to run Adaptive model from sql file.\n{}'.format(e)) sys.exit(1) else: sys.exit(0)
def test_init_adaptive_collection_full_collection_input(): """Test initialization of the Adaptive collection with inputs as collections.""" calc_length = 24 prevail_header = Header(PrevailingOutdoorTemperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) prevail_temp = HourlyContinuousCollection(prevail_header, [22] * calc_length) op_temp_header = Header(Temperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) op_temp = HourlyContinuousCollection(op_temp_header, [26] * calc_length) air_speed_header = Header(AirSpeed(), 'm/s', AnalysisPeriod(end_month=1, end_day=1)) air_speed = HourlyContinuousCollection(air_speed_header, [0.7] * calc_length) adapt_obj = Adaptive(prevail_temp, op_temp, air_speed) assert adapt_obj.operative_temperature[0] == 26 assert adapt_obj.air_speed[0] == 0.7
def test_init_adaptive_collection_full_input(): """Test the initialization of the Adaptive collection will all inputs.""" calc_length = 24 prevail_header = Header(PrevailingOutdoorTemperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) prevail_temp = HourlyContinuousCollection(prevail_header, [22] * calc_length) op_temp_header = Header(Temperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) op_temp = HourlyContinuousCollection(op_temp_header, [26] * calc_length) custom_par = AdaptiveParameter(True, 2, False, False, 15, 0.25) adapt_obj = Adaptive(prevail_temp, op_temp, 0.7, custom_par) assert adapt_obj.operative_temperature[0] == 26 assert adapt_obj.air_speed[0] == 0.7 assert adapt_obj.comfort_parameter.ashrae55_or_en15251 is True assert adapt_obj.comfort_parameter.neutral_offset == 2 assert adapt_obj.comfort_parameter.avg_month_or_running_mean is False assert adapt_obj.comfort_parameter.discrete_or_continuous_air_speed is False assert adapt_obj.comfort_parameter.cold_prevail_temp_limit == 15 assert adapt_obj.comfort_parameter.conditioning == 0.25
def test_adaptive_collection_comfort_outputs(): """Test the is_comfortable and thermal_condition outputs of the collection.""" calc_length = 24 prevail_header = Header(PrevailingOutdoorTemperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) prevail_temp = HourlyContinuousCollection(prevail_header, [22] * calc_length) op_temp_header = Header(Temperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) op_temp = HourlyContinuousCollection(op_temp_header, range(20, 20 + calc_length)) adapt_obj = Adaptive(prevail_temp, op_temp) assert isinstance(adapt_obj.is_comfortable, HourlyContinuousCollection) assert len(adapt_obj.is_comfortable.values) == calc_length assert adapt_obj.is_comfortable[0] == 0 assert adapt_obj.is_comfortable[5] == 1 assert adapt_obj.is_comfortable[10] == 0 assert isinstance(adapt_obj.thermal_condition, HourlyContinuousCollection) assert len(adapt_obj.thermal_condition.values) == calc_length assert adapt_obj.thermal_condition[0] == -1 assert adapt_obj.thermal_condition[5] == 0 assert adapt_obj.thermal_condition[10] == 1
def test_adaptive_collection_defaults(): """Test the default inputs assigned to the Adaptive collection.""" calc_length = 24 prevail_header = Header(PrevailingOutdoorTemperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) prevail_temp = HourlyContinuousCollection(prevail_header, [22] * calc_length) op_temp_header = Header(Temperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) op_temp = HourlyContinuousCollection(op_temp_header, [26] * calc_length) adapt_obj = Adaptive(prevail_temp, op_temp) assert isinstance(adapt_obj.air_speed, HourlyContinuousCollection) assert len(adapt_obj.air_speed.values) == calc_length assert adapt_obj.air_speed[0] == 0.1 assert isinstance(adapt_obj.comfort_parameter, AdaptiveParameter) default_par = AdaptiveParameter() assert adapt_obj.comfort_parameter.ashrae55_or_en15251 == default_par.ashrae55_or_en15251 assert adapt_obj.comfort_parameter.neutral_offset == default_par.neutral_offset assert adapt_obj.comfort_parameter.avg_month_or_running_mean == default_par.avg_month_or_running_mean assert adapt_obj.comfort_parameter.discrete_or_continuous_air_speed == default_par.discrete_or_continuous_air_speed assert adapt_obj.comfort_parameter.cold_prevail_temp_limit == default_par.cold_prevail_temp_limit assert adapt_obj.comfort_parameter.conditioning == default_par.conditioning
adapt_par.conditioning, adapt_par.standard) elif adapt_par.ashrae55_or_en15251 is True: comf_result = adaptive_comfort_ashrae55(prevail_temp, to) else: comf_result = adaptive_comfort_en15251(prevail_temp, to) # Determine the cooling effect if adapt_par.discrete_or_continuous_air_speed is True: ce = cooling_effect_ashrae55(input[3], to) else: ce = cooling_effect_en15251(input[3], to) # Output results neutral_temp = comf_result['t_comf'] deg_neutral = comf_result['deg_comf'] comfort = adapt_par.is_comfortable(comf_result, ce) condition = adapt_par.thermal_condition(comf_result, ce) else: # The inputs include Data Collections. if not isinstance(_air_temp, BaseCollection): _air_temp = data_colls[0].get_aligned_collection( float(_air_temp), Temperature(), 'C') comf_obj = Adaptive.from_air_and_rad_temp(_out_temp, _air_temp, _mrt_, _air_speed_, adapt_par) prevail_temp = comf_obj.prevailing_outdoor_temperature neutral_temp = comf_obj.neutral_temperature deg_neutral = comf_obj.degrees_from_neutral comfort = comf_obj.is_comfortable condition = comf_obj.thermal_condition