1"""Test ``h2ss.capacity`` functions.
2
3References
4----------
5
6.. [#Caglayan20] Caglayan, D. G., Weber, N., Heinrichs, H. U., Linßen, J.,
7 Robinius, M., Kukla, P. A., and Stolten, D. (2020). ‘Technical potential
8 of salt caverns for hydrogen storage in Europe’, International Journal of
9 Hydrogen Energy, 45(11), pp. 6793–6805.
10 https://doi.org/10.1016/j.ijhydene.2019.12.161.
11.. [#PyFluids] Portyanikhin, V. (2023). ‘portyanikhin/PyFluids’. Available at:
12 https://github.com/portyanikhin/PyFluids (Accessed: 1 January 2024).
13"""
14
15import numpy as np
16import pandas as pd
17from pandas.testing import assert_series_equal
18from pyfluids import Fluid, FluidsList, Input
19
20from h2ss import capacity as cap
21
22
[docs]
23def test_cavern_volume():
24 """Test ``h2ss.capacity.cavern_volume``"""
25 h_cylinder = [10, 20, 30, 40, 50]
26 h_cone = [2, 4, 6, 8, 10]
27 roof_angle = [5, 10, 15, 20, 25]
28 v_cavern = []
29 v_cavern_func = []
30 for cyl, con, a in zip(h_cylinder, h_cone, roof_angle):
31 r = con / np.tan(np.deg2rad(a))
32 v_cylinder = np.pi * np.square(r) * cyl
33 v_cone = np.pi * np.square(r) * con / 3
34 v_cavern.append(v_cylinder + v_cone * 2)
35 v_cavern_func.append(
36 cap.cavern_volume(height=cyl + con * 2, diameter=r * 2, theta=a)
37 )
38 v_cavern = [round(x, 5) for x in v_cavern]
39 v_cavern_func = [round(x, 5) for x in v_cavern_func]
40 assert v_cavern_func == v_cavern
41
42
[docs]
43def test_corrected_cavern_volume():
44 """Test ``h2ss.capacity.corrected_cavern_volume``"""
45 correction_factors = [0.61, 0.65, 0.72, 0.75, 0.84]
46 volumes = [1e4, 2.5e4, 3e4, 4.7e4, 5.3e4]
47 v_cavern = []
48 v_cavern_func = []
49 for v, f in zip(volumes, correction_factors):
50 v_cavern.append(v * f)
51 v_cavern_func.append(cap.corrected_cavern_volume(v_cavern=v, scf=f))
52 assert v_cavern_func == v_cavern
53
54
[docs]
55def test_temperature_cavern_mid_point():
56 """Test ``h2ss.capacity.temperature_cavern_mid_point``"""
57 heights = [50, 100, 150, 200, 250]
58 top_depths = [600, 800, 1100, 1300, 1700]
59 delta_t = [35, 37, 39, 41, 43]
60 t_0 = [8, 9, 10, 11, 12]
61 t_mid_point = []
62 t_mid_point_func = []
63 for h, d, dt, t0 in zip(heights, top_depths, delta_t, t_0):
64 t_mid_point.append(t0 + dt * (d + 0.5 * h) / 1000 + 273.15)
65 t_mid_point_func.append(
66 cap.temperature_cavern_mid_point(
67 height=h, depth_top=d, t_0=t0, delta_t=dt
68 )
69 )
70 assert t_mid_point_func == t_mid_point
71
72
[docs]
73def test_pressure_operating():
74 """Test ``h2ss.capacity.pressure_operating``"""
75 thickness_overburden = [550, 650, 750, 850, 950]
76 depth_water = [10, 20, 30, 40, 50]
77 p_operating = []
78 p_operating_func = []
79 for t, d in zip(thickness_overburden, depth_water):
80 p_casing = (1027 * d + 2400 * t + 2200 * 50) * 9.81
81 p_operating.append((0.3 * p_casing, 0.8 * p_casing))
82 p_operating_func.append(
83 cap.pressure_operating(thickness_overburden=t, depth_water=d)
84 )
85 assert p_operating_func == p_operating
86
87
[docs]
88def test_density_hydrogen_gas():
89 """Test ``h2ss.capacity.density_hydrogen_gas``
90
91 Notes
92 -----
93 Use Eqn. (3) of [#Caglayan20]_ to derive the density and compare it with
94 the density obtained from the
95 ``h2ss.capacity.density_hydrogen_gas`` function.
96 The values should be approximately the same (rounded to one decimal place).
97 PyFluids [#PyFluids]_ is used to just derive the compressibility factor,
98 :math:`Z`, for the former. The ``pyproject.toml`` configuration file has
99 been set such that the default units are SI units.
100
101 .. math::
102 \\rho = \\frac{p \\, M}{Z \\, R \\, T}
103
104 where :math:`M` is the molar mass of hydrogen gas [kg mol⁻¹], :math:`R` is
105 the universal gas constant [J K⁻¹ mol⁻¹], :math:`p` is the pressure [Pa],
106 :math:`T` is the temperature [K], and :math:`\\rho` is the hydrogen gas
107 density [kg m⁻³].
108 """
109 p_operating_min = [2.03e7, 3.29e6, 3.29e6, 5.5e6, 1.5e6]
110 p_operating_max = [3.698e7, 2.98e7, 7.62e6, 3.9e7, 2e7]
111 t_mid_point = [327.4, 303.1, 362.75, 300, 358.9]
112 m = 0.00201588 # molar mass of hydrogen gas [kg mol⁻¹]
113 r = 8.314 # universal gas constant [J K⁻¹ mol⁻¹]
114 rho_h2 = []
115 for p_min, p_max, t in zip(p_operating_min, p_operating_max, t_mid_point):
116 h2_min = Fluid(FluidsList.Hydrogen).with_state(
117 Input.pressure(p_min), Input.temperature(t)
118 )
119 h2_max = Fluid(FluidsList.Hydrogen).with_state(
120 Input.pressure(p_max), Input.temperature(t)
121 )
122 rho_approx_min = p_min * m / (h2_min.compressibility * r * t)
123 rho_approx_max = p_max * m / (h2_max.compressibility * r * t)
124 rho_h2.append((rho_approx_min, rho_approx_max))
125 rho_h2_func = cap.density_hydrogen_gas(
126 p_operating_min=p_operating_min,
127 p_operating_max=p_operating_max,
128 t_mid_point=t_mid_point,
129 )
130 rho_h2 = pd.DataFrame(rho_h2)
131 assert_series_equal(round(rho_h2_func[0], 1), round(rho_h2[0], 1))
132 assert_series_equal(round(rho_h2_func[1], 1), round(rho_h2[1], 1))
133
134
[docs]
135def test_mass_hydrogen_working():
136 """Test ``h2ss.capacity.mass_hydrogen_working``"""
137 rho_h2_min = [2.7, 8.5, 6, 4.563, 3.5]
138 rho_h2_max = [20, 12, 16, 6.6, 10.4928]
139 v_cavern = [2.7e5, 3.5e5, 4.1234e5, 6e5, 7.2e5]
140 m_working = []
141 m_working_func = []
142 for mi, ma, v in zip(rho_h2_min, rho_h2_max, v_cavern):
143 m_working.append(((ma - mi) * v, mi * v, ma * v))
144 m_working_func.append(
145 cap.mass_hydrogen_working(rho_h2_min=mi, rho_h2_max=ma, v_cavern=v)
146 )
147 assert m_working_func == m_working
148
149
[docs]
150def test_energy_storage_capacity():
151 """Test ``h2ss.capacity.energy_storage_capacity``"""
152 m_working = [6.4e5, 1.5e6, 2.6e6, 8.2e6, 3.5e6]
153 capacity = []
154 capacity_func = []
155 for m in m_working:
156 capacity.append(m * 119.96 / 3600000)
157 capacity_func.append(cap.energy_storage_capacity(m_working=m))
158 assert capacity_func == capacity