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
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)
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)
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)
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
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)
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