peritheos 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
peritheos/eos/rt/bm.py ADDED
@@ -0,0 +1,281 @@
1
+ """
2
+ Non-thermal equations of state module
3
+
4
+ This module implements various non-thermal equations of state commonly used in
5
+ high-pressure physics and materials science, including:
6
+
7
+ 1. Birch-Murnaghan equation of state (2nd, 3rd, and 4th order)
8
+ 2. Object-oriented implementation with a base class and specific EOS implementations
9
+
10
+ These equations describe the relationship between pressure and volume (or density)
11
+ at constant temperature, and are particularly useful for modeling the behavior of
12
+ solids under compression.
13
+
14
+ References:
15
+ -----------
16
+ 1. Birch, F. (1947). Finite elastic strain of cubic crystals. Physical Review, 71(11), 809.
17
+ 2. Birch, F. (1978). Finite strain isotherm and velocities for single-crystal and
18
+ polycrystalline NaCl at high pressures and 300 K. Journal of Geophysical Research,
19
+ 83(B3), 1257-1268.
20
+ 3. Anderson, O.L. (1995) Equations of State of Solids for Geophysics and Ceramic Science,
21
+ Oxford University Press, Oxford, UK.
22
+ 4. Poirier, J.P., (2000), Introduction to the Physics of the Earth's
23
+ Interior, Cambridge University Press, Cambridge, UK.
24
+ """
25
+
26
+ from peritheos.eos import (
27
+ EosBase,
28
+ NumericType,
29
+ validate_finite_scalar,
30
+ validate_positive_scalar,
31
+ validate_volume,
32
+ )
33
+
34
+
35
+ class BM2(EosBase):
36
+ """
37
+ 2nd-order Birch-Murnaghan equation of state.
38
+
39
+ The 2nd-order Birch-Murnaghan EOS is defined as:
40
+ P(V) = (3/2) * K0 * [(V0/V)^(7/3) - (V0/V)^(5/3)]
41
+
42
+ or in terms of the Eulerian strain f = [(V0/V)^(2/3) - 1]/2:
43
+ P(V) = 3 * K0 * f * (1 + 2f)^(5/2)
44
+
45
+ Equations from:
46
+ Poirier, J.P., 2000, Introduction to the Physics of the Earth's
47
+ Interior, Cambridge University Press, Cambridge, UK.
48
+ """
49
+
50
+ def __init__(self, V0: float, K0: float) -> None:
51
+ """
52
+ Initialize the 2nd-order Birch-Murnaghan EOS.
53
+
54
+ Parameters
55
+ ----------
56
+ V0 : float
57
+ Reference volume (in cubic angstroms or any consistent unit)
58
+ K0 : float
59
+ Bulk modulus at reference volume (in GPa or any consistent unit)
60
+ """
61
+ self.V0 = validate_positive_scalar(V0, "V0")
62
+ self.K0 = validate_positive_scalar(K0, "K0")
63
+
64
+ def pressure(self, V: NumericType) -> NumericType:
65
+ """
66
+ Calculate pressure using the 2nd-order Birch-Murnaghan EOS.
67
+
68
+ Parameters
69
+ ----------
70
+ V : float or numpy.ndarray
71
+ Volume (in the same units as V0)
72
+
73
+ Returns
74
+ -------
75
+ float or numpy.ndarray
76
+ Pressure (in the same units as K0)
77
+ """
78
+ V = validate_volume(V)
79
+ f = ((self.V0 / V) ** (2 / 3) - 1) / 2
80
+ return 3 * self.K0 * f * (1 + 2 * f) ** (5 / 2)
81
+
82
+ def bulk_modulus(self, V: NumericType) -> NumericType:
83
+ """
84
+ Return the bulk modulus at the given volume.
85
+
86
+ Parameters
87
+ ----------
88
+ V : float or numpy.ndarray
89
+ Volume (in the same units as V0)
90
+
91
+ Returns
92
+ -------
93
+ float or numpy.ndarray
94
+ Bulk modulus (in the same units as K0)
95
+ """
96
+ V = validate_volume(V)
97
+ eta = ((self.V0 / V) ** (2 / 3) - 1) / 2
98
+ return self.K0 * (1 + 7 * eta) * (1 + 2 * eta) ** (5 / 2)
99
+
100
+
101
+ class BM3(EosBase):
102
+ """
103
+ 3rd-order Birch-Murnaghan equation of state.
104
+
105
+ The 3rd-order Birch-Murnaghan EOS is defined as:
106
+ P(V) = (3/2) * K0 * [(V0/V)^(7/3) - (V0/V)^(5/3)] *
107
+ {1 + (3/4) * (K0' - 4) * [(V0/V)^(2/3) - 1]}
108
+
109
+ or in terms of the Eulerian strain f = [(V0/V)^(2/3) - 1]/2:
110
+ P(V) = 3 * K0 * f * (1 + 2f)^(5/2) * [1 + (3/2) * (K0' - 4) * f]
111
+
112
+ Equations from:
113
+ Anderson, O.L., (1995) Equations of State of Solids for Geophysics and Ceramic Science,
114
+ Oxford University Press, Oxford, UK.
115
+ """
116
+
117
+ def __init__(self, V0: float, K0: float, K0_prime: float) -> None:
118
+ """
119
+ Initialize the 3rd-order Birch-Murnaghan EOS.
120
+
121
+ Parameters
122
+ ----------
123
+ V0 : float
124
+ Reference volume (in cubic angstroms or any consistent unit)
125
+ K0 : float
126
+ Bulk modulus at reference volume (in GPa or any consistent unit)
127
+ K0_prime : float
128
+ Pressure derivative of the bulk modulus at reference volume (dimensionless)
129
+ """
130
+ self.V0 = validate_positive_scalar(V0, "V0")
131
+ self.K0 = validate_positive_scalar(K0, "K0")
132
+ self.K0_prime = validate_finite_scalar(K0_prime, "K0_prime")
133
+
134
+ def pressure(self, V: NumericType) -> NumericType:
135
+ """
136
+ Calculate pressure using the 3rd-order Birch-Murnaghan EOS.
137
+
138
+ Parameters
139
+ ----------
140
+ V : float or numpy.ndarray
141
+ Volume (in the same units as V0)
142
+
143
+ Returns
144
+ -------
145
+ float or numpy.ndarray
146
+ Pressure (in the same units as K0)
147
+ """
148
+ V = validate_volume(V)
149
+ f = ((self.V0 / V) ** (2 / 3) - 1) / 2
150
+ return (
151
+ 3
152
+ * self.K0
153
+ * f
154
+ * (1 + 2 * f) ** (5 / 2)
155
+ * (1 + (3 / 2) * (self.K0_prime - 4) * f)
156
+ )
157
+
158
+ def bulk_modulus(self, V: NumericType) -> NumericType:
159
+ """
160
+ Calculate the bulk modulus at the given volume.
161
+
162
+ For the 3rd-order Birch-Murnaghan EOS, the bulk modulus at V0 is:
163
+ K(V) = K0 * (1 + 2f)^(5/2) * [K0 + (3K0*K0'-5K0)f + 27/2(K0*K0'-4K0)f^2]
164
+
165
+ Parameters
166
+ ----------
167
+ V : float or numpy.ndarray
168
+ Volume (in the same units as V0)
169
+
170
+ Returns
171
+ -------
172
+ float or numpy.ndarray
173
+ Bulk modulus (in the same units as K0)
174
+ """
175
+ V = validate_volume(V)
176
+ f = ((self.V0 / V) ** (2 / 3) - 1) / 2
177
+ return (1.0 + 2.0 * f) ** (5.0 / 2.0) * (
178
+ self.K0
179
+ + (3.0 * self.K0 * self.K0_prime - 5 * self.K0) * f
180
+ + 27.0 / 2.0 * (self.K0 * self.K0_prime - 4.0 * self.K0) * f * f
181
+ )
182
+
183
+ class BM4(EosBase):
184
+ """
185
+ 4th-order Birch-Murnaghan equation of state.
186
+
187
+ The 4th-order Birch-Murnaghan EOS is defined as:
188
+ P(V) = (3/2) * K0 * [(V0/V)^(-7/3) - (V0/V)^(-5/3)] *
189
+ { 1 + (3/4) * (K0'- 4) * ((V0/V)^(-2/3) - 1) + (3/8) * [K0 * K0'' + (K0'- 4) * (K0' - 3) + (35/9)] * ((V0/V)^(-2/3) - 1)
190
+
191
+ or in terms of the Eulerian strain f = [(V0/V)^(2/3) - 1]/2, zeta = (3/4) * (4 - K0'), and xi = (3/8) * [K0 * K0'' + (K0'- 4) * (K0' - 3) + (35/9)]:
192
+ P(f) = 3 * K0 *f * (1 + 2f)^(5/2) * [1 + 2 * zeta * f + 4 * xi * f ** 2]
193
+
194
+ Equations from:
195
+ Anderson, O.L., (1995) Equations of State of Solids for Geophysics and Ceramic Science,
196
+ Oxford University Press, Oxford, UK.
197
+ """
198
+
199
+ def __init__(self, V0: float, K0: float, K0_prime: float, K0_double_prime: float) -> None:
200
+ """
201
+ Initialize the 4th-order Birch-Murnaghan EOS.
202
+
203
+ Parameters
204
+ ----------
205
+ V0 : float
206
+ Reference volume (in cubic angstroms or any consistent unit)
207
+ K0 : float
208
+ Bulk modulus at reference volume (in GPa or any consistent unit)
209
+ K0_prime : float
210
+ Pressure derivative of the bulk modulus at reference volume (dimensionless)
211
+ K0_double_prime : float
212
+ Second pressure derivative of the bulk modulus at reference volume
213
+ (inverse pressure, e.g. GPa^-1 when K0 is in GPa)
214
+ """
215
+ self.V0 = validate_positive_scalar(V0, "V0")
216
+ self.K0 = validate_positive_scalar(K0, "K0")
217
+ self.K0_prime = validate_finite_scalar(K0_prime, "K0_prime")
218
+ self.K0_double_prime = validate_finite_scalar(
219
+ K0_double_prime, "K0_double_prime"
220
+ )
221
+
222
+ def pressure(self, V: NumericType) -> NumericType:
223
+ """
224
+ Calculate pressure using the 4th-order Birch-Murnaghan EOS.
225
+
226
+ Parameters
227
+ ----------
228
+ V : float or numpy.ndarray
229
+ Volume (in the same units as V0)
230
+
231
+ Returns
232
+ -------
233
+ float or numpy.ndarray
234
+ Pressure (in the same units as K0)
235
+ """
236
+ V = validate_volume(V)
237
+ f = ((self.V0/V) ** (2 / 3) - 1) / 2
238
+ zeta = (3 / 4) * (4 - self.K0_prime)
239
+ xi = (3 / 8) * (self.K0 * self.K0_double_prime + (self.K0_prime - 4) * (self.K0_prime - 3) + (35 / 9))
240
+ return (
241
+ 3
242
+ * self.K0
243
+ * f
244
+ * (1 + 2 * f) ** (5/2)
245
+ * (1 - 2 * zeta * f + 4 * xi * f ** 2)
246
+ )
247
+
248
+ def bulk_modulus(self, V: NumericType) -> NumericType:
249
+ """
250
+ Calculate the bulk modulus at the given volume.
251
+
252
+ For the 4th-order Birch-Murnaghan EOS, the bulk modulus at V0 with f = f = ((V0/V) ** (2 / 3) - 1) / 2
253
+ zeta = (3 / 4) * (4 - K0_prime)
254
+ xi = (3 / 8) * [K0 * K0_double_prime + (K0_prime - 4) * (K0_prime - 3) + (35 / 9)]
255
+ K(f) = 5 * self.K0 * (1 + 2 * f) ** (5 / 2) * (1 - 2 * zeta * f + 4 * xi * f ** 2) + self.K0 * (1 + 2 * f) ** (7 / 2)
256
+ * (1 - 4 * zeta * f + 12 * xi * f ** 2)
257
+
258
+ Parameters
259
+ ----------
260
+ V : float or numpy.ndarray
261
+ Volume (in the same units as V0)
262
+
263
+ Returns
264
+ -------
265
+ float or numpy.ndarray
266
+ Bulk modulus (in the same units as K0)
267
+ """
268
+ V = validate_volume(V)
269
+ f = ((self.V0/V) ** (2 / 3) - 1) / 2
270
+ zeta = (3 / 4) * (4 - self.K0_prime)
271
+ xi = (3 / 8) * (self.K0 * self.K0_double_prime + (self.K0_prime - 4) * (self.K0_prime - 3) + (35 / 9))
272
+ return (
273
+ 5
274
+ * f
275
+ * self.K0
276
+ * (1 + 2 * f) ** (5 / 2)
277
+ * (1 - 2 * zeta * f + 4 * xi * f ** 2)
278
+ + self.K0
279
+ * (1 + 2 * f) ** (7 / 2)
280
+ * (1 - 4 * zeta * f + 12 * xi * f ** 2)
281
+ )
@@ -0,0 +1,196 @@
1
+ import numpy as np
2
+ from peritheos.eos import (
3
+ EosBase,
4
+ NumericType,
5
+ validate_finite_scalar,
6
+ validate_positive_scalar,
7
+ validate_volume,
8
+ )
9
+
10
+
11
+ class Holzapfel(EosBase):
12
+ """
13
+ Holzapfel equation of state. Introduced in Holzapfel et al. 2001. And here implemented as described in
14
+ Sokolova et al. 2016.
15
+ """
16
+
17
+ def __init__(self, V0: float, K0: float, K0_prime: float, n: float, Z: int) -> None:
18
+ """
19
+ Initialize the Holzapfel equation of state.
20
+
21
+ **Note:**
22
+ Contrary to other EOS implementations, the reference values need to be provided in the correct units.
23
+ For consistency with the equation of states, the pressure unit is GPa - contrary to excel spreadsheets from
24
+ Sokolova et al. 2016 where the bulk modulus is given in kbar.
25
+
26
+ Parameters
27
+ ----------
28
+ V0 : float
29
+ Reference volume [JBar^-1] (same as [cm^3/mol]/10)
30
+ K0 : float
31
+ Bulk modulus at reference volume in [GPa]
32
+ K0_prime : float
33
+ Pressure derivative of bulk modulus at reference volume
34
+ n : float
35
+ Number of atoms in a chemical formula
36
+ Z : int
37
+ Atomic number of the forumala unit
38
+ """
39
+ super().__init__()
40
+ self.V0 = validate_positive_scalar(V0, "V0")
41
+ self.K0 = validate_positive_scalar(K0, "K0")
42
+ self.K0_prime = validate_finite_scalar(K0_prime, "K0_prime")
43
+ self.n = validate_positive_scalar(n, "n")
44
+ self.Z = validate_positive_scalar(Z, "Z")
45
+
46
+ self._P_FG0 = 1003.6 * (self.Z * self.n / (self.V0 * 10)) ** (5 / 3)
47
+ self._c0 = -np.log(3 * self.K0 / self._P_FG0)
48
+ self._c2 = 1.5 * (self.K0_prime - 3) - self._c0
49
+
50
+ def pressure(self, V: NumericType) -> NumericType:
51
+ """
52
+ Calculate pressure using the Holzapfel equation of state.
53
+
54
+ Parameters
55
+ ----------
56
+ V : float or np.ndarray
57
+ Volume in [JBar^-1] (same as [cm^3/mol]/10)
58
+
59
+ Returns
60
+ -------
61
+ float or np.ndarray
62
+ Pressure in [GPa]
63
+ """
64
+ V = validate_volume(V)
65
+ x = (V / self.V0) ** (1 / 3)
66
+ return (
67
+ 3
68
+ * self.K0
69
+ * np.exp(self._c0 * (1 - x))
70
+ * (1 / x**5 - 1 / x**4)
71
+ * (1 + self._c2 * x - self._c2 * x**2)
72
+ )
73
+
74
+ def bulk_modulus(self, V: NumericType) -> NumericType:
75
+ """
76
+ Calculate bulk modulus using the Holzapfel equation of state.
77
+
78
+ Parameters
79
+ ----------
80
+ V : float or np.ndarray
81
+ Volume in [JBar^-1] (same as [cm^3/mol]/10)
82
+
83
+ Returns
84
+ -------
85
+ float or np.ndarray
86
+ Bulk modulus in [GPa]
87
+ """
88
+ V = validate_volume(V)
89
+ x = (V / self.V0) ** (1 / 3)
90
+ term1 = self.K0 * x**-5 * np.exp(self._c0 * (1 - x))
91
+
92
+ bracket_1 = (5 - 4 * x) * (1 + self._c2 * x * (1 - x))
93
+ bracket_2 = self._c0 * x * (1 - x) * (1 + self._c2 * x * (1 - x))
94
+ bracket_3 = -(1 - x) * (self._c2 * x - 2 * self._c2 * x**2)
95
+ term2 = bracket_1 + bracket_2 + bracket_3
96
+ return term1 * term2
97
+
98
+ def bulk_modulus_derivative(self, V: NumericType, eps: float = 1e-6) -> NumericType:
99
+ """
100
+ Compute the pressure derivative of the bulk modulus using a
101
+ numerical approximation.
102
+
103
+ This method provides a faster alternative to the analytical approach implemented in
104
+ `bulk_modulus_derivative_analytical`, which is more than twice as slow. The numerical
105
+ derivative is computed using a small relative perturbation in volume with a step size of `eps`.
106
+
107
+ Parameters
108
+ ----------
109
+ V : float or np.ndarray
110
+ Volume in [JBar^-1] (same as [cm^3/mol]/10)
111
+ eps : float
112
+ Step size for the numerical derivative, default is 1e-6. This value is used as the
113
+ relative difference between the two perturbed volumes. The accuracy of the numerical
114
+ derivative is approximately `eps * 100%`.
115
+
116
+ Returns
117
+ -------
118
+ float or np.ndarray
119
+ Pressure derivative of bulk modulus (unitless)
120
+ """
121
+ V = validate_volume(V)
122
+ eps = validate_positive_scalar(eps, "eps")
123
+ if eps >= 1:
124
+ raise ValueError("eps must be smaller than one")
125
+ V = np.array([V * (1 + eps), V * (1 - eps)])
126
+ P = self.pressure(V)
127
+ K = self.bulk_modulus(V)
128
+ return (K[0] - K[1]) / (P[0] - P[1])
129
+
130
+
131
+ def bulk_modulus_derivative_analytical(V0, V, KT, K0, c0, c2):
132
+ """
133
+ Calculate the pressure derivative of bulk modulus using the Holzapfel equation of state.
134
+ Equation have been taken from excel sheets provided in Sokolova et al. 2016. The listed equation (5) on page
135
+ 163 in this paper seems to be incorrect.
136
+ Values have been verified against the excel sheets provided by Sokolova et al. 2016 and the numerical
137
+ derivative (see test_holzapfel.py).
138
+
139
+ Parameters
140
+ ----------
141
+ V : float or np.ndarray
142
+ Volume in [JBar^-1] (same as [cm^3/mol]/10)
143
+ KT : float or np.ndarray
144
+ Bulk modulus in [kbar]
145
+ K0 : float
146
+ Bulk modulus at reference volume in [kbar]
147
+ c0 : float
148
+ Constant in the Holzapfel equation of state
149
+ c2 : float
150
+ Constant in the Holzapfel equation of state
151
+ Returns
152
+ -------
153
+ """
154
+ x = (V / V0) ** (1 / 3)
155
+
156
+ # convert moduli from GPa to bar
157
+ K0 = K0 * 10000
158
+ KT = KT * 10000
159
+
160
+ term1 = (
161
+ 3
162
+ / x**4
163
+ * K0
164
+ * np.exp(c0 * (1 - x))
165
+ * (
166
+ (-5 / x**2 + 4 / x) * (1 + c2 * x - c2 * x**2)
167
+ - (1 / x - 1) * (1 + c2 * x - c2 * x**2) * c0
168
+ + (1 / x - 1) * (c2 - 2 * c2 * x)
169
+ )
170
+ )
171
+ term2 = (
172
+ 1
173
+ / x**3
174
+ * K0
175
+ * np.exp(c0 * (1 - x))
176
+ * c0
177
+ * (
178
+ (-5 / x**2 + 4 / x) * (1 + c2 * x - c2 * x**2)
179
+ - (1 / x - 1) * (1 + c2 * x - c2 * x**2) * c0
180
+ + (1 / x - 1) * (c2 - 2 * c2 * x)
181
+ )
182
+ )
183
+ term3 = (
184
+ K0
185
+ * np.exp(c0 * (1 - x))
186
+ * (
187
+ (10 / x**3 - 4 / x**2) * (1 + c2 * x - c2 * x**2)
188
+ + (-5 / x**2 + 4 / x) * (c2 - 2 * c2 * x)
189
+ + c0 / x**2 * (1 + c2 * x - c2 * x**2)
190
+ - (1 / x - 1) * (c2 - 2 * c2 * x) * c0
191
+ - (c2 - 2 * c2 * x) / x**2
192
+ - 2 * c2 * (1 / x - 1)
193
+ )
194
+ / x**3
195
+ )
196
+ return (term1 + term2 - term3) / (-KT / x) / 3
@@ -0,0 +1,86 @@
1
+ """
2
+ Vinet equation of state
3
+ """
4
+
5
+ import numpy as np
6
+ from peritheos.eos import (
7
+ EosBase,
8
+ NumericType,
9
+ validate_finite_scalar,
10
+ validate_positive_scalar,
11
+ validate_volume,
12
+ )
13
+
14
+
15
+ class Vinet(EosBase):
16
+ """
17
+ Vinet equation of state. It has been presented multiple times in the literature. But has been
18
+ attributed finally to Vinet 1986, 1987. An earlier description can be found in the work of
19
+ Stacey et al. 1981. The Vinet EOS is based on a variant of the Morse potential, the Rydberg
20
+ potential which was introduced by Rydberg in 1932.
21
+
22
+ The Vinet EOS is defined as:
23
+ P(V) = 3 * K0 * (1 - f)/ f^2 * exp(3/2 * (K0_prime - 1) * (1 - f))
24
+ where f = (V / V0)^(1/3)
25
+
26
+ The bulk modulus is given by:
27
+ K(V) = K0 * f^(-2) * (1 + (eta * f + 1) * (1 - f) * exp(eta * (1 - f)))
28
+ where f = (V / V0)^(1/3)
29
+ and eta = 3/2 * (K0_prime - 1)
30
+ """
31
+
32
+ def __init__(self, V0: float, K0: float, K0_prime: float) -> None:
33
+ """
34
+ Initialize the Vinet equation of state.
35
+
36
+ Parameters
37
+ ----------
38
+ V0 : float
39
+ Reference volume (in cubic angstroms or any consistent unit)
40
+ K0 : float
41
+ Bulk modulus at reference volume (in GPa or any consistent unit)
42
+ K0_prime : float
43
+ Pressure derivative of bulk modulus at reference volume
44
+ """
45
+ self.V0 = validate_positive_scalar(V0, "V0")
46
+ self.K0 = validate_positive_scalar(K0, "K0")
47
+ self.K0_prime = validate_finite_scalar(K0_prime, "K0_prime")
48
+
49
+ def pressure(self, V: NumericType) -> NumericType:
50
+ """
51
+ Calculate pressure using the Vinet equation of state.
52
+
53
+ Parameters
54
+ ----------
55
+ V : float or numpy.ndarray
56
+ Volume (in cubic angstroms or any consistent unit)
57
+
58
+ Returns
59
+ -------
60
+ float or numpy.ndarray
61
+ Pressure (in the same units as K0)
62
+ """
63
+ V = validate_volume(V)
64
+ f = (V / self.V0) ** (1 / 3)
65
+ return (
66
+ 3 * self.K0 * (1 - f) / f**2 * np.exp(3 / 2 * (self.K0_prime - 1) * (1 - f))
67
+ )
68
+
69
+ def bulk_modulus(self, V: NumericType) -> NumericType:
70
+ """
71
+ Calculate the bulk modulus using the Vinet equation of state.
72
+
73
+ Parameters
74
+ ----------
75
+ V : float or numpy.ndarray
76
+ Volume (in cubic angstroms or any consistent unit)
77
+
78
+ Returns
79
+ -------
80
+ float or numpy.ndarray
81
+ Bulk modulus (in the same units as K0)
82
+ """
83
+ V = validate_volume(V)
84
+ f = (V / self.V0) ** (1 / 3)
85
+ eta = 3 / 2 * (self.K0_prime - 1)
86
+ return self.K0 * f**-2 * (1 + (eta * f + 1) * (1 - f)) * np.exp(eta * (1 - f))
@@ -0,0 +1,5 @@
1
+ """
2
+ This module contains the thermal equations of state (EOS) implementations.
3
+ """
4
+
5
+ from .sokolova2016 import Sokolova2016