Esempio n. 1
0
def curve_constant_humidity_ratio(
        dry_temps: Iterable[float],
        rh_percentage: Union[float, Iterable[float]]=100.,
        p_atm_kpa: float=PRESSURE_STD_ATM_KPA, mode_sat=1) -> List[float]:
    """Generate a curve (numpy array) of constant humidity ratio."""
    if isinstance(rh_percentage, Iterable):
        return [1000 * humidity_ratio(
            saturation_pressure_water_vapor(t, mode=mode_sat)
            * rh / 100., p_atm_kpa)
                for t, rh in zip(dry_temps, rh_percentage)]
    return [1000 * humidity_ratio(
        saturation_pressure_water_vapor(t, mode=mode_sat)
        * rh_percentage / 100., p_atm_kpa)
            for t in dry_temps]
Esempio n. 2
0
def curve_constant_humidity_ratio(
        dry_temps: List[float], rh_percentage: float=100.,
        p_atm_kpa: float=PRESSURE_STD_ATM_KPA, mode_sat=1) -> List[float]:
    """Generate a curve (numpy array) of constant humidity ratio."""
    return [1000 * humidity_ratio(
        saturation_pressure_water_vapor(t, mode=mode_sat)
        * rh_percentage / 100., p_atm_kpa)
            for t in dry_temps]
Esempio n. 3
0
    def test_max_specific_humid(self):
        """Max Specific humidity from dry bulb temperature."""
        from psychrochart.equations import (
            humidity_ratio, saturation_pressure_water_vapor)

        for t, (ps_ref, xmax_ref) in TEMP_SAT_PRESS_HUMID_RATIO.items():
            psat = saturation_pressure_water_vapor(t)
            xmax = humidity_ratio(psat)
            # print(t, psat, ps_ref / 1000, xmax, xmax_ref)
            self.assertAlmostEqual(psat, ps_ref / 1000, delta=0.05)
            self.assertAlmostEqual(xmax, xmax_ref, delta=0.0005)
Esempio n. 4
0
    def plot_vertical_dry_bulb_temp_line(
            self, temp: float,
            style: dict=None,
            label: str=None,
            reverse: bool=False,
            **label_params) -> None:
        """Append a vertical line from w_min to w_sat."""
        w_max = 1000 * humidity_ratio(
            saturation_pressure_water_vapor(temp), self.p_atm_kpa)

        style_curve = style or self.d_config.get("constant_dry_temp")
        path_y = [w_max, self.w_min] if reverse else [self.w_min, w_max]
        curve = PsychroCurve(
            [temp, temp], path_y, style=style_curve, logger=self._logger)
        curve.plot(self.axes)
        if label is not None:
            curve.add_label(self.axes, label, **label_params)
Esempio n. 5
0
    def test_enthalpy_moist_air(self):
        """Check the enthalpy of humid air."""
        from psychrochart.equations import (
            PRESSURE_STD_ATM_KPA, saturation_pressure_water_vapor,
            humidity_ratio, enthalpy_moist_air)

        # From http://www.engineeringtoolbox.com/enthalpy-moist-air-d_683.html
        # Check the enthalpy of humid air at 25ºC with specific
        # moisture content x = 0.0203 kg/kg (saturation).
        press = PRESSURE_STD_ATM_KPA
        dry_temp_c, w_kg_kga = 25, 0.0203

        p_sat = saturation_pressure_water_vapor(dry_temp_c)
        w_max = humidity_ratio(p_sat, press)
        ratio_humid = w_kg_kga / w_max
        p_w_kpa = ratio_humid * p_sat

        h_m = enthalpy_moist_air(dry_temp_c, p_w_kpa, press)
        h_m_bis = enthalpy_moist_air(dry_temp_c, p_w_kpa, press)
        self.assertEqual(h_m, h_m_bis)
        self.assertEqual(round(h_m, 1), 76.9)
Esempio n. 6
0
    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)