Пример #1
0
def test_invalid_areas():

    N = 10
    T = Q(np.linspace(-100, -50, N), 'K')
    P = Q(np.linspace(-1, -2, N), 'bar')

    water = Fluid('water', T=T, P=P)

    assert water.D.check(Density)
    assert isinstance(water.D.m, np.ndarray)

    T = Q(np.linspace(-100, 300, N), 'K')
    P = Q(np.linspace(-1, 2, N), 'bar')

    water = Fluid('water', T=T, P=P)

    assert water.D.check(Density)
    assert isinstance(water.D.m, np.ndarray)
    assert np.isnan(water.D.m[0])
    assert not np.isnan(water.D.m[-1])

    arr1 = np.linspace(-100, 400, N)
    arr2 = np.linspace(-1, 2, N)

    arr1[-2] = np.nan
    arr2[-1] = np.nan
    arr2[-3] = np.nan

    T = Q(arr1, 'K')
    P = Q(arr2, 'bar')

    water = Fluid('water', T=T, P=P)

    assert water.D.m.size == N
Пример #2
0
def mass_from_actual_volume(
        volume: Union[Quantity[Volume], Quantity[VolumeFlow]],
        condition: tuple[Quantity[Pressure], Quantity[Temperature]],
        fluid_name: str = 'Air') -> Union[Quantity[Mass], Quantity[MassFlow]]:
    """
    Convert actual volume to mass.

    Parameters
    ----------
    volume : Union[Quantity[Volume], Quantity[VolumeFlow]]
        Input actual volume or actual volume flow
    condition : tuple[Quantity[Pressure], Quantity[Temperature]]
        Condition at which to calculate the mass
    fluid_name : str, optional
        Name of the fluid, by default 'Air'

    Returns
    -------
    Union[Quantity[Mass], Quantity[MassFlow]]
        Corresponding mass or mass flow
    """

    rho = Fluid(fluid_name, P=condition[0], T=condition[1]).D

    return convert_volume_mass(volume, rho=rho)
Пример #3
0
def mass_to_normal_volume(
        mass: Union[Quantity[Mass], Quantity[MassFlow]],
        fluid_name: str = 'Air'
) -> Union[Quantity[Volume], Quantity[VolumeFlow]]:
    """
    Convert mass to normal volume.

    Parameters
    ----------
    mass : Union[Quantity[Mass], Quantity[MassFlow]]
        Input mass or mass flow
    fluid_name : str, optional
        Name of the fluid, by default 'Air'

    Returns
    -------
    Union[Quantity[Volume], Quantity[VolumeFlow]]
        Corresponding normal volume or normal volume flow
    """

    rho = Fluid(fluid_name,
                P=CONSTANTS.normal_conditions_pressure,
                T=CONSTANTS.normal_conditions_temperature).D

    return convert_volume_mass(mass, rho=rho)
Пример #4
0
def test_properties_Fluid():

    props = Fluid.ALL_PROPERTIES

    fluid_names = ['water', 'methane', 'R134a']

    Ts = [
        25, 0, -1, -100, np.nan, [25, 30], [np.nan, 25], [np.nan, np.nan],
        [np.inf, np.nan],
        np.linspace(0, 10, 10),
        np.linspace(-10, 10, 10)
    ]

    Ps = [
        1, 0, -1, -100, np.nan, [3, 4], [np.nan, 3], [np.nan, np.nan],
        [np.inf, np.nan],
        np.linspace(0, 10, 10),
        np.linspace(-10, 10, 10)
    ]

    for fluid_name in fluid_names:
        for T, P in zip(Ts, Ps):

            fluid = Fluid(fluid_name, T=Q(T, 'C'), P=Q(P, 'bar'))
            repr(fluid)

            for p in props:
                getattr(fluid, p)
Пример #5
0
def test_shapes():

    N = 16

    T = Q(np.linspace(50, 60, N).reshape(4, 4), 'C')
    P = Q(np.linspace(2, 4, N).reshape(4, 4), 'bar')

    water = Fluid('water', T=T, P=P)

    assert water.D.m.shape == P.m.shape
    assert water.D.m.shape == T.m.shape

    N = 27

    T = Q(np.linspace(50, 60, N).reshape(3, 3, 3), 'C')
    P = Q(np.linspace(2, 4, N).reshape(3, 3, 3), 'bar')

    water = Fluid('water', T=T, P=P)

    assert water.D.m.shape == P.m.shape
    assert water.D.m.shape == T.m.shape
Пример #6
0
def convert_gas_volume(
        V1: Union[Quantity[Volume], Quantity[VolumeFlow]],
        condition_1: Union[tuple[Quantity[Pressure], Quantity[Temperature]],
                           Literal['N', 'S']] = 'N',
        condition_2: Union[tuple[Quantity[Pressure], Quantity[Temperature]],
                           Literal['N', 'S']] = 'N',
        fluid_name: str = 'Air'
) -> Union[Quantity[Volume], Quantity[VolumeFlow]]:
    """
    Converts the volume :math:`V_1` (at :math:`T_1, P_1`) to
    :math:`V_2` (at :math:`T_1, P_1`).
    Uses compressibility factors from CoolProp.

    The values for :math:`T_i, P_i` are passed as a tuple using the parameter ``conditions_i``.
    Optionally, the literal 'N' or 'S' can be passed to indicate normal and standard conditions.

    Parameters
    ----------
    V1 : Union[Quantity[Volume], Quantity[VolumeFlow]]
        Volume or volume flow :math:`V_1` at condition 1
    condition_1 : Union[tuple[Quantity[Pressure], Quantity[Temperature]], Literal['N', 'S']], optional
        Pressure and temperature at condition 1, by default 'N'
    condition_2 : Union[tuple[Quantity[Pressure], Quantity[Temperature]], Literal['N', 'S']], optional
        Pressure and temperature at condition 2, by default 'N'
    fluid_name : str, optional
        CoolProp name of the fluid, by default 'Air'

    Returns
    -------
    Union[Quantity[Volume], Quantity[VolumeFlow]]
        Volume or volume flow :math:`V_2` at condition 2
    """

    n_s_conditions = {
        'N': (CONSTANTS.normal_conditions_pressure,
              CONSTANTS.normal_conditions_temperature),
        'S': (CONSTANTS.standard_conditions_pressure,
              CONSTANTS.standard_conditions_temperature)
    }

    if isinstance(condition_1, str) and condition_1 in n_s_conditions:
        condition_1 = n_s_conditions[condition_1]

    if isinstance(condition_2, str) and condition_2 in n_s_conditions:
        condition_2 = n_s_conditions[condition_2]

    if isinstance(condition_1, tuple):
        P1, T1 = condition_1
    else:
        raise ValueError(f'Incorrect value for condition 1: {condition_1}')

    if isinstance(condition_2, tuple):
        P2, T2 = condition_2
    else:
        raise ValueError(f'Incorrect value for condition 2: {condition_2}')

    Z1 = Fluid(fluid_name, T=T1, P=P1).Z
    Z2 = Fluid(fluid_name, T=T2, P=P2).Z

    # from ideal gas law PV = nRT: n and R are constant
    # also considers compressibility factor Z
    V2: Quantity = V1 * (P1 / P2) * (T2 / T1) * (Z2 / Z1)

    # volume at P2, T2 in same units as V1
    return V2.to(V1.u)
Пример #7
0
def test_Fluid():

    fld = Fluid('R123', P=Q(2, 'bar'), T=Q(25, '°C'))

    assert fld.get('S') == Q(1087.7758824621442, 'J/(K kg)')
    assert fld.D == fld.get('D')

    water = Fluid('water', P=Q(2, 'bar'), T=Q(25, '°C'))
    assert water.T.u == Q.get_unit('degC')
    assert water.T.m == 25

    HumidAir(T=Q(25, 'degC'), P=Q(125, 'kPa'), R=Q(0.2, 'dimensionless'))

    Water(P=Q(1, 'bar'), Q=Q(0.9, ''))
    Water(P=Q(1, 'bar'), T=Q(0.9, 'degC'))
    Water(T=Q(1, 'bar'), Q=Q(0.9, ''))

    with pytest.raises(Exception):

        # cannot fix all of P, T, Q
        Water(P=Q(1, 'bar'), T=Q(150, 'degC'), Q=(0.4, ''))

        # incorrect argument name
        Water(T=Q(1, 'bar'), P=Q(9, 'degC'))

    Fluid('water', T=Q([25, 95], 'C'), P=Q([1, 2], 'bar')).H
    Fluid('water', T=Q([25, np.nan], 'C'), P=Q([1, 2], 'bar')).H
    Fluid('water', T=Q([np.nan, np.nan], 'C'), P=Q([1, 2], 'bar')).H
    Fluid('water', T=Q([np.nan, np.nan], 'C'), P=Q([np.nan, np.nan], 'bar')).H
    Fluid('water', T=Q(23, 'C'), P=Q([1, 2], 'bar')).H
    Fluid('water', T=Q(23, 'C'), P=Q([1], 'bar')).H
    Fluid('water', T=Q([23, 25], 'C'), P=Q([1], 'bar')).H
    Fluid('water', T=Q([23, 25], 'C'), P=Q(np.nan, 'bar')).H
    Fluid('water', T=Q([23, 25], 'C'), P=Q([1, np.nan], 'bar')).H

    Water(T=Q([25, 25, 63], 'C'), Q=Q([np.nan, np.nan, 0.4], '')).H
    Water(T=Q([25, np.nan, 63], 'C'), Q=Q([np.nan, 0.2, 0.5], '')).H
    Water(T=Q([25, np.nan, np.nan], 'C'), Q=Q([np.nan, 0.2, np.nan], '')).H

    # returns empty array (not nan)
    ret = Fluid('water', T=Q([], 'C'), P=Q([], 'bar')).H.m
    assert isinstance(ret, np.ndarray) and ret.size == 0
    ret = Fluid('water', T=Q([], 'C'), P=Q((), 'bar')).H.m
    assert isinstance(ret, np.ndarray) and ret.size == 0
    ret = Fluid('water', T=Q([], 'C'), P=Q(np.array([]), 'bar')).H.m
    assert isinstance(ret, np.ndarray) and ret.size == 0

    # 1-element list or array works in the same way as scalar,
    # except that the output is also a 1-element list or array
    ret = Water(P=Q([2, 3], 'bar'), Q=Q([0.5])).D.m

    assert isinstance(ret, np.ndarray) and ret.size == 2

    ret = Water(P=Q([2, 3], 'bar'), Q=Q(0.5)).D.m

    assert isinstance(ret, np.ndarray) and ret.size == 2

    ret = Water(P=Q([2], 'bar'), Q=Q([0.5])).D.m

    assert isinstance(ret, np.ndarray) and ret.size == 1

    ret = Water(P=Q([2], 'bar'), Q=Q(0.5)).D.m

    assert isinstance(ret, np.ndarray) and ret.size == 1

    ret = Water(P=Q(2, 'bar'), Q=Q([0.5])).D.m

    assert isinstance(ret, np.ndarray) and ret.size == 1

    ret = Water(P=Q(2, 'bar'), Q=Q(0.5)).D.m

    assert isinstance(ret, float)

    ret = Water(P=Q([], 'bar'), Q=Q([0.5])).D.m

    assert isinstance(ret, np.ndarray) and ret.size == 0

    ret = Water(P=Q([], 'bar'), Q=Q([])).D.m

    assert isinstance(ret, np.ndarray) and ret.size == 0

    ret = Water(P=Q(np.array([]), 'bar'), Q=Q(np.array([]))).D.m

    assert isinstance(ret, np.ndarray) and ret.size == 0

    # returns 1-element list
    assert isinstance(
        Fluid('water', T=Q([23], 'C'), P=Q([1], 'bar')).H.m, np.ndarray)

    assert isinstance(
        Fluid('water', T=Q(23, 'C'), P=Q([1], 'bar')).H.m, np.ndarray)

    assert isinstance(
        Fluid('water', T=Q([23], 'C'), P=Q(1, 'bar')).H.m, np.ndarray)

    # returns float
    assert isinstance(Fluid('water', T=Q(23, 'C'), P=Q(1, 'bar')).H.m, float)

    with pytest.raises(ValueError):

        Fluid('water',
              T=Q([np.nan, np.nan], 'C'),
              P=Q([np.nan, np.nan, np.nan], 'bar')).H
        Fluid('water', T=Q([np.nan, np.nan], 'C'), P=Q([], 'bar')).H