def test_wet_bulb_temperature(self): """Wet bulb temperature from dry bulb temp and relative humidity.""" from psychrochart.equations import ( wet_bulb_temperature, relative_humidity_from_temps, PRESSURE_STD_ATM_KPA) from psychrochart.util import f_range precision = 0.00001 p_atm = PRESSURE_STD_ATM_KPA for dry_temp_c in f_range(-10, 60, 2.5): for relative_humid in f_range(0.05, 1.0001, 0.05): wet_temp_c = wet_bulb_temperature( dry_temp_c, relative_humid, p_atm_kpa=p_atm, precision=precision) rh_calc = relative_humidity_from_temps( dry_temp_c, wet_temp_c, p_atm_kpa=p_atm) # print('wet_temp_c(dbt, rh): {:.3f} ºC ({:.1f} ºC, {:.1f} %)' # .format(wet_temp_c, dry_temp_c, relative_humid * 100)) self.assertAlmostEqual(relative_humid, rh_calc, delta=0.01) precision = 0.00001 p_atm = PRESSURE_STD_ATM_KPA * .75 for dry_temp_c in f_range(-5, 50, 5): for relative_humid in f_range(0.05, 1.0001, 0.1): wet_temp_c = wet_bulb_temperature( dry_temp_c, relative_humid, p_atm_kpa=p_atm, precision=precision) rh_calc = relative_humidity_from_temps( dry_temp_c, wet_temp_c, p_atm_kpa=p_atm) # print('wet_temp_c(dbt, rh): {:.3f} ºC ({:.1f} ºC, {:.1f} %)' # .format(wet_temp_c, dry_temp_c, relative_humid * 100)) self.assertAlmostEqual(relative_humid, rh_calc, delta=0.01)
def test_relative_humidity_from_temps(self): from psychrochart.equations import ( relative_humidity_from_temps, PRESSURE_STD_ATM_KPA) p_atm_kpa = PRESSURE_STD_ATM_KPA for dry_temp_c, data in REL_HUMID_WITH_TEMP_WET_DELTA_TEMPS.items(): for delta_t, obj_rel_humid in data.items(): wet_temp_c = dry_temp_c - delta_t rel_humid_calc = relative_humidity_from_temps( dry_temp_c, wet_temp_c, p_atm_kpa=p_atm_kpa) self.assertAlmostEqual( round(100 * rel_humid_calc, 1), obj_rel_humid, delta=0.65)
def _make_chart_data(self, styles: Union[dict, str]=None, zones_file: Union[dict, str]=None) -> None: """Generate the data to plot the psychrometric chart.""" # Get styling config = load_config(styles) self.d_config = config self.temp_step = config['limits']['step_temp'] self.figure_params = config['figure'] self.dbt_min, self.dbt_max = config['limits']['range_temp_c'] self.w_min, self.w_max = config['limits']['range_humidity_g_kg'] self.chart_params = config['chart_params'] # Base pressure if config['limits'].get('pressure_kpa') is not None: self.p_atm_kpa = config['limits']['pressure_kpa'] elif config['limits'].get('altitude_m') is not None: self.altitude_m = config['limits']['altitude_m'] self.p_atm_kpa = pressure_by_altitude(self.altitude_m) # Dry bulb constant lines (vertical): if self.chart_params["with_constant_dry_temp"]: step = self.chart_params["constant_temp_step"] style = config['constant_dry_temp'] temps_vl = f_range(self.dbt_min, self.dbt_max, step) heights = [1000 * humidity_ratio( saturation_pressure_water_vapor(t), p_atm_kpa=self.p_atm_kpa) for t in temps_vl] self.constant_dry_temp_data = PsychroCurves( [PsychroCurve([t, t], [self.w_min, h], style, type_curve='constant_dry_temp_data', label=None, logger=self._logger) for t, h in zip(temps_vl, heights)], family_label=self.chart_params["constant_temp_label"]) # Absolute humidity constant lines (horizontal): if self.chart_params["with_constant_humidity"]: step = self.chart_params["constant_humid_step"] style = config['constant_humidity'] ws_hl = f_range(self.w_min + step, self.w_max + step / 10, step) dew_points = solve_curves_with_iteration( 'DEW POINT', [x / 1000 for x in ws_hl], lambda x: dew_point_temperature( water_vapor_pressure( x, p_atm_kpa=self.p_atm_kpa)), lambda x: humidity_ratio( saturation_pressure_water_vapor(x), p_atm_kpa=self.p_atm_kpa)) self.constant_humidity_data = PsychroCurves( [PsychroCurve([t_dp, self.dbt_max], [w, w], style, type_curve='constant_humidity_data', label=None, logger=self._logger) for w, t_dp in zip(ws_hl, dew_points)], family_label=self.chart_params["constant_humid_label"]) # Constant relative humidity curves: if self.chart_params["with_constant_rh"]: rh_perc_values = self.chart_params["constant_rh_curves"] rh_label_values = self.chart_params.get("constant_rh_labels", []) label_loc = self.chart_params.get("constant_rh_labels_loc", .85) style = config["constant_rh"] temps_ct_rh, curves_ct_rh = _gen_list_curves_range_temps( curve_constant_humidity_ratio, self.dbt_min, self.dbt_max, self.temp_step, rh_perc_values, p_atm_kpa=self.p_atm_kpa) self.constant_rh_data = PsychroCurves( [PsychroCurve( temps_ct_rh, curve_ct_rh, style, type_curve='constant_rh_data', label_loc=label_loc, label='RH {:g} %'.format(rh) if round(rh, 1) in rh_label_values else None, logger=self._logger) for rh, curve_ct_rh in zip(rh_perc_values, curves_ct_rh)], family_label=self.chart_params["constant_rh_label"]) # Constant enthalpy lines: if self.chart_params["with_constant_h"]: step = self.chart_params["constant_h_step"] start, end = self.chart_params["range_h"] enthalpy_values = f_range(start, end, step) h_label_values = self.chart_params.get("constant_h_labels", []) label_loc = self.chart_params.get("constant_h_labels_loc", 1.) style = config["constant_h"] temps_max_constant_h = [ dry_temperature_for_enthalpy_of_moist_air( self.w_min / 1000, h) for h in enthalpy_values] sat_points = solve_curves_with_iteration( 'ENTHALPHY', enthalpy_values, lambda x: dry_temperature_for_enthalpy_of_moist_air( self.w_min / 1000 + 0.1, x), lambda x: enthalpy_moist_air( x, saturation_pressure_water_vapor(x), p_atm_kpa=self.p_atm_kpa)) self.constant_h_data = PsychroCurves( [PsychroCurve( [t_sat, t_max], [1000 * humidity_ratio( saturation_pressure_water_vapor(t_sat), self.p_atm_kpa), self.w_min], style, type_curve='constant_h_data', label_loc=label_loc, label='{:g} kJ/kg_da'.format(h) if round(h, 3) in h_label_values else None, logger=self._logger) for t_sat, t_max, h in zip( sat_points, temps_max_constant_h, enthalpy_values)], family_label=self.chart_params["constant_h_label"]) # Constant specific volume lines: if self.chart_params["with_constant_v"]: step = self.chart_params["constant_v_step"] start, end = self.chart_params["range_vol_m3_kg"] vol_values = f_range(start, end, step) vol_label_values = self.chart_params.get("constant_v_labels", []) label_loc = self.chart_params.get("constant_v_labels_loc", 1.) style = config["constant_v"] temps_max_constant_v = [ dry_temperature_for_specific_volume_of_moist_air( 0, specific_vol, p_atm_kpa=self.p_atm_kpa) for specific_vol in vol_values] sat_points = solve_curves_with_iteration( 'CONSTANT VOLUME', vol_values, lambda x: dry_temperature_for_specific_volume_of_moist_air( 0, x, p_atm_kpa=self.p_atm_kpa), lambda x: specific_volume( x, saturation_pressure_water_vapor(x), p_atm_kpa=self.p_atm_kpa)) self.constant_v_data = PsychroCurves( [PsychroCurve( [t_sat, t_max], [1000 * humidity_ratio( saturation_pressure_water_vapor(t_sat), self.p_atm_kpa), 0], style, type_curve='constant_v_data', label_loc=label_loc, label='{:g} m3/kg_da'.format(vol) if round(vol, 3) in vol_label_values else None, logger=self._logger) for t_sat, t_max, vol in zip( sat_points, temps_max_constant_v, vol_values)], family_label=self.chart_params["constant_v_label"]) # Constant wet bulb temperature lines: if self.chart_params["with_constant_wet_temp"]: step = self.chart_params["constant_wet_temp_step"] start, end = self.chart_params["range_wet_temp"] wbt_values = f_range(start, end, step) wbt_label_values = self.chart_params.get( "constant_wet_temp_labels", []) label_loc = self.chart_params.get( "constant_wet_temp_labels_loc", .05) style = config["constant_wet_temp"] w_max_constant_wbt = [humidity_ratio( saturation_pressure_water_vapor(wbt), self.p_atm_kpa) for wbt in wbt_values] self.constant_wbt_data = PsychroCurves( [PsychroCurve( [wbt, self.dbt_max], [1000 * w_max, 1000 * humidity_ratio( saturation_pressure_water_vapor(self.dbt_max) * relative_humidity_from_temps( self.dbt_max, wbt, p_atm_kpa=self.p_atm_kpa), p_atm_kpa=self.p_atm_kpa)], style, type_curve='constant_wbt_data', label_loc=label_loc, label='{:g} °C'.format(wbt) if wbt in wbt_label_values else None, logger=self._logger) for wbt, w_max in zip(wbt_values, w_max_constant_wbt)], family_label=self.chart_params["constant_wet_temp_label"]) # Saturation line: if True: sat_style = config["saturation"] temps_sat_line, w_sat_line = _gen_list_curves_range_temps( curve_constant_humidity_ratio, self.dbt_min, self.dbt_max, self.temp_step, [100], p_atm_kpa=self.p_atm_kpa) self.saturation = PsychroCurves( [PsychroCurve( temps_sat_line, w_sat_line[0], sat_style, type_curve='saturation', logger=self._logger)]) # Zones if self.chart_params["with_zones"] or zones_file is not None: self.append_zones(zones_file)