metablate 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.
- metablate/__init__.py +16 -0
- metablate/ablation_model.py +40 -0
- metablate/atmosphere/__init__.py +8 -0
- metablate/atmosphere/atm_msise00.py +67 -0
- metablate/atmosphere/atm_pymsis.py +114 -0
- metablate/atmosphere/atmosphere.py +80 -0
- metablate/coordinates.py +149 -0
- metablate/material.py +155 -0
- metablate/models/__init__.py +5 -0
- metablate/models/dimant_oppenheim_2017.py +293 -0
- metablate/models/kero_szasz_2008.py +348 -0
- metablate/ode.py +82 -0
- metablate/physics/__init__.py +5 -0
- metablate/physics/alpha_beta.py +679 -0
- metablate/physics/ballistic.py +104 -0
- metablate/physics/luminosity.py +78 -0
- metablate/physics/sputtering.py +219 -0
- metablate/physics/thermal_ablation.py +616 -0
- metablate/py.typed +0 -0
- metablate/version.py +3 -0
- metablate-0.1.0.dist-info/METADATA +766 -0
- metablate-0.1.0.dist-info/RECORD +25 -0
- metablate-0.1.0.dist-info/WHEEL +5 -0
- metablate-0.1.0.dist-info/licenses/LICENSE +674 -0
- metablate-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,616 @@
|
|
|
1
|
+
"""
|
|
2
|
+
# Thermal ablation physics
|
|
3
|
+
|
|
4
|
+
## Examples
|
|
5
|
+
|
|
6
|
+
Calculate thermal ablation:
|
|
7
|
+
|
|
8
|
+
```python
|
|
9
|
+
import numpy as np
|
|
10
|
+
import ablate.functions as func
|
|
11
|
+
|
|
12
|
+
dmdt_th = func.ablation.thermal_ablation(
|
|
13
|
+
mass = np.array([0.5, 0.2]),
|
|
14
|
+
temperature = 3700,
|
|
15
|
+
material = 'ast',
|
|
16
|
+
A = 1.21,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
print(f'Thermal ablation {dmdt_th} kg/s')
|
|
20
|
+
```
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
import logging
|
|
24
|
+
from scipy import constants
|
|
25
|
+
import numpy as np
|
|
26
|
+
|
|
27
|
+
logger = logging.getLogger(__name__)
|
|
28
|
+
|
|
29
|
+
Kn_LIM = 5.0
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def temperature_rate_hill_et_al_2005(
|
|
33
|
+
mass,
|
|
34
|
+
velocity,
|
|
35
|
+
temperature,
|
|
36
|
+
material_data,
|
|
37
|
+
shape_factor,
|
|
38
|
+
atm_total_mass_density,
|
|
39
|
+
mass_loss_thermal_ablation,
|
|
40
|
+
Lambda,
|
|
41
|
+
atm_temperature=280,
|
|
42
|
+
emissivity=0.9,
|
|
43
|
+
):
|
|
44
|
+
"""Calculates the rate of change of temperature of the meteoroid.
|
|
45
|
+
A homogeneous metoroid experiencing an isotropic heat flux is assumed as
|
|
46
|
+
well as the meteoroid undergoing isothermal heating. (isothermal heating:
|
|
47
|
+
here: dTdS = 0 i.e. same spatial temperature).
|
|
48
|
+
|
|
49
|
+
Parameters
|
|
50
|
+
----------
|
|
51
|
+
mass : float or numpy.ndarray
|
|
52
|
+
Meteoroid mass [kg]
|
|
53
|
+
velocity : float or numpy.ndarray
|
|
54
|
+
Meteoroid velocity [m/s]
|
|
55
|
+
temperature : float or numpy.ndarray
|
|
56
|
+
Meteoroid temperature [K]
|
|
57
|
+
material_data : dict
|
|
58
|
+
Meteoroid material data, see [`material_data`][ablate.functions.material.material_data].
|
|
59
|
+
shape_factor : float or numpy.ndarray
|
|
60
|
+
Shape factor [1]
|
|
61
|
+
atm_total_mass_density : float or numpy.ndarray
|
|
62
|
+
Total atmospheric mass density [kg/m^3]
|
|
63
|
+
mass_loss_thermal_ablation : float or numpy.ndarray
|
|
64
|
+
Mass loss due to thermal ablation, i.e. -dm_dt [kg/s]
|
|
65
|
+
Lambda : float or numpy.ndarray
|
|
66
|
+
Heat transfer coefficient [1]
|
|
67
|
+
atm_temperature : float or numpy.ndarray
|
|
68
|
+
Effective atmospheric temperature [K]. Default = 280 K
|
|
69
|
+
emissivity : float or numpy.ndarray
|
|
70
|
+
Electromagnetic emissivity of meteoroid [1]. Default = 0.9
|
|
71
|
+
|
|
72
|
+
Returns
|
|
73
|
+
-------
|
|
74
|
+
float or numpy.ndarray
|
|
75
|
+
Rate of change of temperature [K/s]
|
|
76
|
+
|
|
77
|
+
Notes
|
|
78
|
+
-----
|
|
79
|
+
The default emissivity 0.9 is taken from [^1], [^2] report 1.0 (todo: check), 0.2 is
|
|
80
|
+
characteristic for a metal, oxides are between 0.4 and 0.8.
|
|
81
|
+
|
|
82
|
+
Changes pre-python port: See [matlab-version](https://gitlab.irf.se/kero/ablation_matlab)
|
|
83
|
+
|
|
84
|
+
Heat balance equation per cross-sectional area symbols:
|
|
85
|
+
|
|
86
|
+
- `A` = shape factor
|
|
87
|
+
- `c` = specific heat of meteoroid
|
|
88
|
+
- `mass` = meteoroid mass
|
|
89
|
+
- `rho_m` = meteoroid density
|
|
90
|
+
- `Lambda` = heat transfer coefficient
|
|
91
|
+
- `rho_tot`= total atmospheric mass density
|
|
92
|
+
- `vel` = meteoroid velocity
|
|
93
|
+
- `kb` = Stefan-Bolzmann constant
|
|
94
|
+
- `T` = meteoroid temperature
|
|
95
|
+
- `Ta` = effective atmospheric temperature
|
|
96
|
+
- `L` = latent heat of fusion + vapourization
|
|
97
|
+
- `thermal_ablation` = mass loss due to thermal ablation
|
|
98
|
+
|
|
99
|
+
[1^]: Hill et al.: High geocentric velocity meteor ablation, A&A 444 p. 615-624 (2005)
|
|
100
|
+
[2^]: Love & Brownlee (? todo)
|
|
101
|
+
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
# -- variables
|
|
105
|
+
kB = constants.value("Boltzmann constant") # [J/K]
|
|
106
|
+
|
|
107
|
+
rho_m = material_data["rho_m"]
|
|
108
|
+
c = material_data["c"]
|
|
109
|
+
L = material_data["L"]
|
|
110
|
+
|
|
111
|
+
coef0 = 0.5 * Lambda * atm_total_mass_density * velocity**3
|
|
112
|
+
coef0 -= 4 * kB * emissivity * (temperature**4 - atm_temperature**4)
|
|
113
|
+
coef0 += L / shape_factor * (rho_m / mass) ** (2.0 / 3.0) * (-mass_loss_thermal_ablation)
|
|
114
|
+
|
|
115
|
+
coef1 = c * mass ** (1.0 / 3.0) * rho_m ** (2.0 / 3.0)
|
|
116
|
+
|
|
117
|
+
dTdt = (shape_factor / coef1) * coef0
|
|
118
|
+
return dTdt
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def heat_transfer_bronshten_1983(
|
|
122
|
+
mass,
|
|
123
|
+
velocity,
|
|
124
|
+
temperature,
|
|
125
|
+
material_data,
|
|
126
|
+
atm_total_number_density,
|
|
127
|
+
mass_loss_thermal_ablation,
|
|
128
|
+
atm_mean_mass,
|
|
129
|
+
res=100,
|
|
130
|
+
):
|
|
131
|
+
"""Calculates the heat transfer coefficient Lambda. Information taken from [^1] [^2] [^3] [^4] [^5].
|
|
132
|
+
|
|
133
|
+
Changes pre-python port: See [matlab-version](https://gitlab.irf.se/kero/ablation_matlab)
|
|
134
|
+
|
|
135
|
+
[^1]: V. A. Bronshten; Physics of meteoric phenomena (1983)
|
|
136
|
+
[^2]: A. Westman et al.: Meteor head echo altitude distributions and the
|
|
137
|
+
height cutoff effect sudied with the EISCAT HPLA UHF and VHF radars;
|
|
138
|
+
Annales Geophysicae 22: 1575-1584 (2004)
|
|
139
|
+
[^3]: Tielens et al.: The physics of grain-grain collisions and gas-grain
|
|
140
|
+
sputtering in interstellar shocks, The Astrophisicsl Journal 431, p. 321-340 (1994)
|
|
141
|
+
[^4]: Rogers et al.: Mass loss due to sputtering and thermal processes in
|
|
142
|
+
meteoroid ablation, Planetary and Space Science 53 p. 1341-1354 (2005)
|
|
143
|
+
[^5]: Salby: Fundamentals of atmospheric physics, Academic Press (1996)
|
|
144
|
+
|
|
145
|
+
Parameters
|
|
146
|
+
----------
|
|
147
|
+
mass : float or numpy.ndarray
|
|
148
|
+
Meteoroid mass [kg]
|
|
149
|
+
velocity : float or numpy.ndarray
|
|
150
|
+
Meteoroid velocity [m/s]
|
|
151
|
+
temperature : float or numpy.ndarray
|
|
152
|
+
Meteoroid temperature [K]
|
|
153
|
+
material_data : dict
|
|
154
|
+
Meteoroid material data, see [`material_data`][ablate.functions.material.material_data].
|
|
155
|
+
atm_total_number_density : float or numpy.ndarray
|
|
156
|
+
Total atmospheric number density [1/m^3]
|
|
157
|
+
mass_loss_thermal_ablation : float or numpy.ndarray
|
|
158
|
+
Mass loss due to thermal ablation, i.e. -dm_dt [kg/s]
|
|
159
|
+
atm_mean_mass : float or numpy.ndarray
|
|
160
|
+
Mean mass of atmospheric constituents [kg]
|
|
161
|
+
res : int
|
|
162
|
+
Resolution used for the numerical integration.
|
|
163
|
+
|
|
164
|
+
Returns
|
|
165
|
+
-------
|
|
166
|
+
float or numpy.ndarray
|
|
167
|
+
Heat transfer coefficient
|
|
168
|
+
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
# Universal constants
|
|
172
|
+
kB = constants.value("Boltzmann constant") # [J/K]
|
|
173
|
+
|
|
174
|
+
# Meteoroid constituents
|
|
175
|
+
met_mean_mass = material_data["m2"]
|
|
176
|
+
met_density = material_data["rho_m"]
|
|
177
|
+
|
|
178
|
+
# angle between the normal to the surface and the molecular flow, theta0 is a row vector
|
|
179
|
+
theta0 = np.linspace(0, np.pi / 2, num=res, dtype=np.float64) # [radians]
|
|
180
|
+
|
|
181
|
+
a_e = thermal_accommodation_bronshten_1983(atm_mean_mass, met_mean_mass)
|
|
182
|
+
u_s = nomalized_evaporated_velocity_bronshten_1983(velocity, temperature, atm_mean_mass)
|
|
183
|
+
Kn_inf, L = Knudsen_number_kero_szasz_2008(mass, met_density, atm_total_number_density)
|
|
184
|
+
|
|
185
|
+
# parameter... Bronshten p. 69 eq. 10.7
|
|
186
|
+
h_star = atm_mean_mass * velocity**2 / (2.0 * kB * temperature) # [dimensionless]
|
|
187
|
+
|
|
188
|
+
# ####### Lambda ##########
|
|
189
|
+
|
|
190
|
+
# Shielding effects of a meteoroid surface due to reflected molecules:
|
|
191
|
+
epsilon_q = 1.6 # [dimensionless]
|
|
192
|
+
|
|
193
|
+
_G = np.sin(theta0) * np.cos(theta0) * (1 - u_s**2)
|
|
194
|
+
|
|
195
|
+
_Gp = (
|
|
196
|
+
np.sin(theta0)
|
|
197
|
+
* 4
|
|
198
|
+
/ np.sqrt(2 * np.pi)
|
|
199
|
+
* np.sqrt(1 - 2 * u_s * np.cos(theta0) + u_s**2)
|
|
200
|
+
* np.cos(theta0)
|
|
201
|
+
)
|
|
202
|
+
_Gp *= np.cos(theta0) * (1 - u_s**2) / 2 - (
|
|
203
|
+
1.0 / 48.0 * (1 + np.cos(theta0)) ** 3 * (3 - np.cos(theta0))
|
|
204
|
+
- u_s
|
|
205
|
+
/ 48.0
|
|
206
|
+
* (1 + np.cos(theta0)) ** 2
|
|
207
|
+
* (8 - 7 * np.cos(theta0) + 2 * np.cos(theta0) ** 2 - np.cos(theta0) ** 3)
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
Q0 = np.trapz(theta0, _G)
|
|
211
|
+
|
|
212
|
+
# integrating q_prim over theta0 from 0 - pi/2; Bronshten p. 69, eq. 10.10 and Bronshten I eq. 11
|
|
213
|
+
Q_prim = np.trapz(theta0, _Gp)
|
|
214
|
+
|
|
215
|
+
# the energy flux shielding coeff, Bronshten p. 71, same as a_Lambda but with
|
|
216
|
+
# the integrated vectors; Bronshten p. 69 eq. 10.8
|
|
217
|
+
A_Lambda_r = 1 - epsilon_q * np.sqrt(h_star) / Kn_inf * Q_prim / Q0 # [dimensionless]
|
|
218
|
+
|
|
219
|
+
# Shielding effects of a meteoroid surface due to evaporated molecules:
|
|
220
|
+
|
|
221
|
+
# scattering cross section for meteor atoms and ions on N2 and O2 molecules;
|
|
222
|
+
# Bronshten p. 84 eq. 11.29, Bronshten II. eq. 40; the actual equation is for
|
|
223
|
+
# v in [cm/s] and gives the cross section in cm^2 ->
|
|
224
|
+
# sigmaD = 5.6E-11 [cm^2] *(v [cm/s])^-0.8 = 5.6E-11*(1E-2[m])^2*(v [m/s]*1E2)^-0.8 =
|
|
225
|
+
# 5.6E-11*1E-4*(1E2)^-0.8*v^-0.8 = 5.6E-15*10^-1.6*v^-0.8
|
|
226
|
+
sigmaD = 5.6e-15 * 10 ** (-1.6) * velocity ** (-0.8) # [m^2]
|
|
227
|
+
|
|
228
|
+
# the velocity of molecules evaporated from the meteor body, Bronshten eq. 7.2 p. 37
|
|
229
|
+
v_e = np.sqrt(8 * kB * temperature / (np.pi * met_mean_mass)) # [m/s]
|
|
230
|
+
|
|
231
|
+
# mean free path of the evaporated molecules, Bronshten p. 79 eq. 11.8; Bronshten II. eq. 2
|
|
232
|
+
mfp_e = v_e / (atm_total_number_density * velocity * sigmaD) # [m]
|
|
233
|
+
|
|
234
|
+
# the toatal fraction of evaporated molecules from the entire front surface
|
|
235
|
+
# of the meteoroid, Bronshten II. eq. 35
|
|
236
|
+
eta = (L / mfp_e) ** 2 / (1 + 2 * np.sqrt(L / mfp_e)) # [dimensionless]
|
|
237
|
+
|
|
238
|
+
# the total number of molecules evaporated from a certain area of cross section
|
|
239
|
+
# and which takes part in shielding, Bronshten II. eq. 42 and eq. 1
|
|
240
|
+
N_i = eta / met_mean_mass * mass_loss_thermal_ablation # [number]
|
|
241
|
+
|
|
242
|
+
# cross section area of meteoroid (L = characteristic length, but here it is
|
|
243
|
+
# equal to the meteoroid radius)
|
|
244
|
+
S_m = np.pi * L**2 # [m^2]
|
|
245
|
+
|
|
246
|
+
# the number of molecules advancing on the area S, Bronshten II. p. 135
|
|
247
|
+
N_a = atm_total_number_density * velocity * S_m # [number]
|
|
248
|
+
|
|
249
|
+
# average velocity of evaporated molecules from the meteoroid surface, see
|
|
250
|
+
# v_s which is the same thing but for reflected molecules
|
|
251
|
+
v_s_e = np.sqrt(
|
|
252
|
+
3
|
|
253
|
+
* constants.value("molar gas constant")
|
|
254
|
+
* temperature
|
|
255
|
+
/ (met_mean_mass * constants.value("Avogadro constant"))
|
|
256
|
+
) # [m/s]
|
|
257
|
+
|
|
258
|
+
# nomalized velocity of evaporated molecules, compare to u_s
|
|
259
|
+
u_e = v_s_e / velocity # [dimensionless]
|
|
260
|
+
|
|
261
|
+
_H = np.sin(theta0) * 1.0 / 48.0 * (1 + np.cos(theta0)) ** 3 * (
|
|
262
|
+
3 - np.cos(theta0)
|
|
263
|
+
) - u_e / 48.0 * (1 + np.cos(theta0)) ** 2 * (
|
|
264
|
+
8 - 7 * np.cos(theta0) + 2 * np.cos(theta0) ** 2 - np.cos(theta0) ** 3
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
# same as Q_star but for evaporated molecules, i.e. using u_e instead of u_s
|
|
268
|
+
Q_star_e = np.trapz(theta0, _H)
|
|
269
|
+
# same as Q0 but for evaporated molecues, i.e. using u_e instead of u_s
|
|
270
|
+
Q0_e = np.trapz(theta0, np.sin(theta0) * np.cos(theta0) * (1 - u_e**2))
|
|
271
|
+
|
|
272
|
+
# determines how many of the reflected molecules that are thrown back, Bronshten I. eq. 17
|
|
273
|
+
zeta = 1 - 2 * Q_star_e / Q0_e
|
|
274
|
+
|
|
275
|
+
# the energy flux shielding by evaporation coeff for a sphere, Bronshten II. eq. 43
|
|
276
|
+
A_Lambda_e = 1 - zeta * N_i / N_a # [dimensionless]
|
|
277
|
+
|
|
278
|
+
# How to add the shielding effects by reflection and evaporation? A_Lambda_r and A_Lambda_e
|
|
279
|
+
# is defined as the probability that an incoing molecule reaches the surface of the body and
|
|
280
|
+
# transfers its momentum or energy respectively to it. Thus 1 - A_Lambda_r and 1 - A_Lambda_e
|
|
281
|
+
# is the probability that an incoming molecule does not reach the surface of the body, i.e.,
|
|
282
|
+
# is shielded. So, to add how many of the incoming molecules contributes to the shielding both
|
|
283
|
+
# by reflection and evaporation, we need to add the probability that the incoming molecules
|
|
284
|
+
# does not reach the surface: 1 - ( (1 - A_Lambda_r) + (1 - A_Lambda_e) ) =
|
|
285
|
+
# = 1 - 1 + A_Lambda_r - 1 + A_Lambda_e = A_lambda_r + A_lambda_e -1
|
|
286
|
+
|
|
287
|
+
Lambda = (A_Lambda_r + A_Lambda_e - 1) * a_e # [dimensionless] heat transfer coeff
|
|
288
|
+
|
|
289
|
+
# We don't want Gamma or Lambda to be > 1, searching for those and setting them = 1
|
|
290
|
+
if isinstance(Lambda, np.ndarray):
|
|
291
|
+
Lambda[Lambda > 1] = 1.0
|
|
292
|
+
else:
|
|
293
|
+
if Lambda > 1:
|
|
294
|
+
Lambda = 1.0
|
|
295
|
+
|
|
296
|
+
return Lambda
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
def thermal_accommodation_bronshten_1983(atm_mean_mass, met_mean_mass):
|
|
300
|
+
"""Calculate thermal accommodation coefficient [^1].
|
|
301
|
+
|
|
302
|
+
[^1]: Bronshten p. 40 eq. 7.11
|
|
303
|
+
|
|
304
|
+
Parameters
|
|
305
|
+
----------
|
|
306
|
+
met_mean_mass : float or numpy.ndarray
|
|
307
|
+
Mean mass of meteoroid constituents [kg]
|
|
308
|
+
atm_mean_mass : float or numpy.ndarray
|
|
309
|
+
Mean mass of atmospheric constituents [kg]
|
|
310
|
+
|
|
311
|
+
Returns
|
|
312
|
+
-------
|
|
313
|
+
float or numpy.ndarray
|
|
314
|
+
Thermal accommodation coefficient
|
|
315
|
+
|
|
316
|
+
"""
|
|
317
|
+
|
|
318
|
+
# the relative masses of the molecules of the air and of the meteoroid, Bronshten p. 40
|
|
319
|
+
mu_star = atm_mean_mass / met_mean_mass # [dimensionless]
|
|
320
|
+
|
|
321
|
+
# thermal accommodation coefficient, Bronshten p. 40 eq. 7.11
|
|
322
|
+
a_e = (3.0 + mu_star) * mu_star / (1.0 + mu_star) ** 2 # [dimensionless]
|
|
323
|
+
|
|
324
|
+
return a_e
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
def nomalized_evaporated_velocity_bronshten_1983(velocity, temperature, atm_mean_mass):
|
|
328
|
+
"""Calculate the nomalized reflected and evaporated velocity [^1].
|
|
329
|
+
|
|
330
|
+
[^1]: Bronshten p. 69
|
|
331
|
+
|
|
332
|
+
Parameters
|
|
333
|
+
----------
|
|
334
|
+
velocity : float or numpy.ndarray
|
|
335
|
+
Meteoroid velocity [m/s]
|
|
336
|
+
temperature : float or numpy.ndarray
|
|
337
|
+
Meteoroid temperature [K]
|
|
338
|
+
atm_mean_mass : float or numpy.ndarray
|
|
339
|
+
Mean mass of atmospheric constituents [kg]
|
|
340
|
+
|
|
341
|
+
Returns
|
|
342
|
+
-------
|
|
343
|
+
float or numpy.ndarray
|
|
344
|
+
Nomalized reflected and evaporated velocity
|
|
345
|
+
|
|
346
|
+
"""
|
|
347
|
+
|
|
348
|
+
# Universal constants
|
|
349
|
+
R = constants.value("molar gas constant") # [J/(mol K)]
|
|
350
|
+
NA = constants.value("Avogadro constant") # [molecules/mol]
|
|
351
|
+
|
|
352
|
+
# average velocity of reflected molecules near the meteoroid surface, Bronshten p. 37 eq. 7.1 (and 7.2)
|
|
353
|
+
v_s = np.sqrt(3 * R * temperature / (atm_mean_mass * NA)) # [m/s]
|
|
354
|
+
|
|
355
|
+
# nomalized reflected and evaporated velocity, Bronshten p. 69 but uncorrect in the book...
|
|
356
|
+
u_s = v_s / velocity # [dimensionless]
|
|
357
|
+
|
|
358
|
+
return u_s
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
def thermal_ablation_hill_et_al_2005(mass, temperature, material_data, shape_factor):
|
|
362
|
+
"""Calculates the mass loss for meteoroids due to thermal ablation [^1][^2].
|
|
363
|
+
|
|
364
|
+
Changes pre-python port: See [matlab-version](https://gitlab.irf.se/kero/ablation_matlab)
|
|
365
|
+
|
|
366
|
+
[^1]: Rogers et al.: Mass loss due to sputtering and thermal processes in
|
|
367
|
+
meteoroid ablation, Planetary and Space Science 53 p. 1341-1354 (2005)
|
|
368
|
+
[^2]: Hill et al.: High geocentric velocity meteor ablation, A&A 444 p. 615-624 (2005)
|
|
369
|
+
|
|
370
|
+
Parameters
|
|
371
|
+
----------
|
|
372
|
+
mass : float or numpy.ndarray
|
|
373
|
+
Meteoroid mass [kg]
|
|
374
|
+
temperature : float or numpy.ndarray
|
|
375
|
+
Meteoroid temperature [K]
|
|
376
|
+
material_data : dict
|
|
377
|
+
Meteoroid material data, see [`material_data`][ablate.functions.material.material_data].
|
|
378
|
+
shape_factor : float or numpy.ndarray
|
|
379
|
+
Shape factor [1]
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
Returns
|
|
383
|
+
-------
|
|
384
|
+
float or numpy.ndarray
|
|
385
|
+
Mass loss due to thermal ablation [kg/s]
|
|
386
|
+
|
|
387
|
+
Notes
|
|
388
|
+
-----
|
|
389
|
+
Symbol definitions:
|
|
390
|
+
|
|
391
|
+
- `Pv`: vapour pressure of meteoroid [N/m^2]
|
|
392
|
+
- `CA`, CB: Clausius-Clapeyron coeff [K]
|
|
393
|
+
- `mu`: mean molecular mass of ablated vapour [kg]
|
|
394
|
+
- `rho_m`: meteoroid density [kg/m3]
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
"""
|
|
398
|
+
|
|
399
|
+
CA = material_data["CA"]
|
|
400
|
+
CB = material_data["CB"]
|
|
401
|
+
mu = material_data["mu"]
|
|
402
|
+
rho_m = material_data["rho_m"]
|
|
403
|
+
|
|
404
|
+
# 2007-03-21 Ed suggests that the vapor pressure should be lowered by a factor of 0.8 or 0.7
|
|
405
|
+
# due to the large ram pressure forcing the evaporated atoms and molecules back on to the surface
|
|
406
|
+
# thus leading to evaporation at a pressure that is lower than the equilibrium vapor pressure.
|
|
407
|
+
|
|
408
|
+
Pv = 10.0 ** (CA - CB / temperature)
|
|
409
|
+
# in [d/cm2]...; d=dyne=10-5 Newton: the force required to accelearte a
|
|
410
|
+
# mass of one g at a rate of one cm per s^2
|
|
411
|
+
Pv = Pv * 1e-5 / 1e-4 # Convert to [N/m2]
|
|
412
|
+
|
|
413
|
+
coef0 = np.sqrt(mu / (2.0 * np.pi * constants.k * temperature))
|
|
414
|
+
dmdt = -4.0 * shape_factor * (mass / rho_m) ** (2.0 / 3.0) * Pv * coef0 # [kg/s]
|
|
415
|
+
|
|
416
|
+
return dmdt
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
def drag_coefficient_bronshten_1983(
|
|
420
|
+
mass,
|
|
421
|
+
velocity,
|
|
422
|
+
temperature,
|
|
423
|
+
material_data,
|
|
424
|
+
atm_total_number_density,
|
|
425
|
+
atm_mean_mass,
|
|
426
|
+
res=100,
|
|
427
|
+
):
|
|
428
|
+
"""Calculates the drag coefficient Gamma[^1] [^2] [^3] [^4] [^5].
|
|
429
|
+
|
|
430
|
+
Changes pre-python port: See [matlab-version](https://gitlab.irf.se/kero/ablation_matlab)
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
[^1]: V. A. Bronshten; Physics of meteoric phenomena (1983)
|
|
434
|
+
[^2]: A. Westman et al.: Meteor head echo altitude distributions and the
|
|
435
|
+
height cutoff effect sudied with the EISCAT HPLA UHF and VHF radars;
|
|
436
|
+
Annales Geophysicae 22: 1575-1584 (2004)
|
|
437
|
+
[^3]: Tielens et al.: The physics of grain-grain collisions and gas-grain
|
|
438
|
+
sputtering in interstellar shocks, The Astrophisicsl Journal 431, p. 321-340 (1994)
|
|
439
|
+
[^4]: Rogers et al.: Mass loss due to sputtering and thermal processes in
|
|
440
|
+
meteoroid ablation, Planetary and Space Science 53 p. 1341-1354 (2005)
|
|
441
|
+
[^5]: Salby: Fundamentals of atmospheric physics, Academic Press (1996)
|
|
442
|
+
|
|
443
|
+
Parameters
|
|
444
|
+
----------
|
|
445
|
+
mass : float or numpy.ndarray
|
|
446
|
+
Meteoroid mass [kg]
|
|
447
|
+
velocity : float or numpy.ndarray
|
|
448
|
+
Meteoroid velocity [m/s]
|
|
449
|
+
temperature : float or numpy.ndarray
|
|
450
|
+
Meteoroid temperature [K]
|
|
451
|
+
material_data : dict
|
|
452
|
+
Meteoroid material data, see [`material_data`][ablate.functions.material.material_data].
|
|
453
|
+
atm_total_number_density : float or numpy.ndarray
|
|
454
|
+
Total atmospheric number density [1/m^3]
|
|
455
|
+
atm_mean_mass : float or numpy.ndarray
|
|
456
|
+
Mean mass of atmospheric constituents [kg]
|
|
457
|
+
res : int
|
|
458
|
+
Resolution used for the numerical integration.
|
|
459
|
+
|
|
460
|
+
Returns
|
|
461
|
+
-------
|
|
462
|
+
float or numpy.ndarray
|
|
463
|
+
Drag coefficient
|
|
464
|
+
|
|
465
|
+
"""
|
|
466
|
+
# Universal constants
|
|
467
|
+
kB = constants.value("Boltzmann constant") # [J/K]
|
|
468
|
+
|
|
469
|
+
# Meteoroid constituents
|
|
470
|
+
met_mean_mass = material_data["m2"]
|
|
471
|
+
met_density = material_data["rho_m"]
|
|
472
|
+
|
|
473
|
+
# angle between the normal to the surface and the molecular flow, theta0 is a row vector
|
|
474
|
+
theta0 = np.linspace(0, np.pi / 2, num=res, dtype=np.float64) # [radians]
|
|
475
|
+
|
|
476
|
+
# parameter... Bronshten p. 69 eq. 10.7
|
|
477
|
+
h_star = atm_mean_mass * velocity**2 / (2.0 * kB * temperature) # [dimensionless]
|
|
478
|
+
|
|
479
|
+
a_e = thermal_accommodation_bronshten_1983(atm_mean_mass, met_mean_mass)
|
|
480
|
+
u_s = nomalized_evaporated_velocity_bronshten_1983(velocity, temperature, atm_mean_mass)
|
|
481
|
+
Kn_inf, _ = Knudsen_number_kero_szasz_2008(mass, met_density, atm_total_number_density)
|
|
482
|
+
|
|
483
|
+
# ####### Gamma ##########
|
|
484
|
+
epsilon_p = 0.86 # [dimensionless] Bronshten p. 69 eq. 10.7 and p. 71
|
|
485
|
+
|
|
486
|
+
# integrating p0, Bronshten p. 71
|
|
487
|
+
_F = np.sin(theta0) * np.cos(theta0) * (1.0 - u_s)
|
|
488
|
+
|
|
489
|
+
_Fp = (
|
|
490
|
+
np.sin(theta0)
|
|
491
|
+
* 4
|
|
492
|
+
/ np.sqrt(2 * np.pi)
|
|
493
|
+
* np.sqrt(1 - 2 * u_s * np.cos(theta0) + u_s**2)
|
|
494
|
+
* np.cos(theta0)
|
|
495
|
+
)
|
|
496
|
+
_Fp *= (
|
|
497
|
+
np.cos(theta0) * (1 - u_s) / 2
|
|
498
|
+
- 1.0 / 24.0 * (1 + np.cos(theta0)) ** 3
|
|
499
|
+
+ u_s / 24.0 * (1 + np.cos(theta0)) ** 2 * (4 - 2 * np.cos(theta0) + np.cos(theta0) ** 2)
|
|
500
|
+
)
|
|
501
|
+
|
|
502
|
+
P0 = np.trapz(theta0, _F)
|
|
503
|
+
|
|
504
|
+
# integrating p_prim over theta0 from 0 - pi/2, Bronshten p. 71
|
|
505
|
+
P_prim = np.trapz(theta0, _Fp)
|
|
506
|
+
|
|
507
|
+
# the momentum flux shielding coeff, Bronshten p. 71 same as a_Gamma but with the integrated vectors
|
|
508
|
+
if isinstance(Kn_inf, np.ndarray):
|
|
509
|
+
A_Gamma_r = np.zeros_like(Kn_inf)
|
|
510
|
+
inds = Kn_inf > Kn_LIM
|
|
511
|
+
A_Gamma_r[inds] = (
|
|
512
|
+
1 - epsilon_p * np.sqrt(h_star) / Kn_inf[inds] * P_prim / P0
|
|
513
|
+
) # [dimensionless]
|
|
514
|
+
Gamma = A_Gamma_r * a_e # [dimensionless] drag coeff
|
|
515
|
+
|
|
516
|
+
# TODO: replace this with actual cont. flow dynamics during ablation
|
|
517
|
+
Gamma[np.logical_not(inds)] = (
|
|
518
|
+
0.47 * 0.5
|
|
519
|
+
) # [dimensionless] drag coeff of sphere in cont. flow
|
|
520
|
+
else:
|
|
521
|
+
if Kn_inf > Kn_LIM:
|
|
522
|
+
A_Gamma_r = 1 - epsilon_p * np.sqrt(h_star) / Kn_inf * P_prim / P0 # [dimensionless]
|
|
523
|
+
Gamma = A_Gamma_r * a_e # [dimensionless] drag coeff
|
|
524
|
+
else:
|
|
525
|
+
# TODO: replace this with actual cont. flow dynamics during ablation
|
|
526
|
+
Gamma = 0.47 * 0.5 # [dimensionless] drag coeff of sphere in cont. flow
|
|
527
|
+
|
|
528
|
+
# We don't want Gamma or Lambda to be > 1, searching for those and setting them = 1
|
|
529
|
+
if isinstance(Gamma, np.ndarray):
|
|
530
|
+
Gamma[Gamma > 1] = 1.0
|
|
531
|
+
else:
|
|
532
|
+
if Gamma > 1:
|
|
533
|
+
Gamma = 1.0
|
|
534
|
+
|
|
535
|
+
return Gamma
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
def Knudsen_number_kero_szasz_2008(met_mass, met_density, atm_total_number_density):
|
|
539
|
+
"""Calculate the Knudsen number.
|
|
540
|
+
|
|
541
|
+
Parameters
|
|
542
|
+
----------
|
|
543
|
+
met_mass : float or numpy.ndarray
|
|
544
|
+
Meteoroid mass [kg]
|
|
545
|
+
met_density : float or numpy.ndarray
|
|
546
|
+
Meteoroid density [kg/m^3]
|
|
547
|
+
atm_total_number_density : float or numpy.ndarray
|
|
548
|
+
Total atmospheric number density [1/m^3]
|
|
549
|
+
|
|
550
|
+
Returns
|
|
551
|
+
-------
|
|
552
|
+
tuple(float/numpy.ndarray, float/numpy.ndarray)
|
|
553
|
+
Knudsen number, Body characteristic dimension
|
|
554
|
+
|
|
555
|
+
"""
|
|
556
|
+
|
|
557
|
+
# Atmospheric mean free path, source: Westman et al.
|
|
558
|
+
# Physics Handbook p. 186 This is the one used!
|
|
559
|
+
mfp_inf = 1.0 / (np.pi * (3.62e-10) ** 2 * atm_total_number_density) # [m]
|
|
560
|
+
|
|
561
|
+
# The Knudsen number
|
|
562
|
+
# Calculating the radius of the meteoroid at different altutude to get L
|
|
563
|
+
# characteristic dimension of the body (the meteoroid); in particular, for a
|
|
564
|
+
# sphere L = the radius; Bronshten p. 31
|
|
565
|
+
L = ((met_mass / met_density) / (4 * np.pi / 3)) ** (1.0 / 3.0) # [m]
|
|
566
|
+
|
|
567
|
+
# [dimensionless] the Knudsen no; calculated from 'mfp_inf'
|
|
568
|
+
Kn_inf = mfp_inf / L
|
|
569
|
+
|
|
570
|
+
return Kn_inf, L
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
def ionization_probability_Jones_1997(velocity, meteoroid_bulk_density):
|
|
574
|
+
"""Calculate ionization probability according to [^1].
|
|
575
|
+
|
|
576
|
+
[^1]: William Jones; Theoretical and observational determinations
|
|
577
|
+
of the ionization coefficient of meteors; MNRAS 288, p. 995-1003 (1997)
|
|
578
|
+
|
|
579
|
+
"""
|
|
580
|
+
raise NotImplementedError()
|
|
581
|
+
# v_km = v / 1000.0
|
|
582
|
+
"""
|
|
583
|
+
# Table 1 from Jones:
|
|
584
|
+
# % : procentage composition by weight
|
|
585
|
+
# p : proportion by atom number
|
|
586
|
+
# v0 : minimum velocity at which ionization can take place
|
|
587
|
+
# (below this velocity, the ionization energy is greater than
|
|
588
|
+
# the total energy of the colliding atoms in the centre-of-mass frame)
|
|
589
|
+
# c : empirically derived coeff
|
|
590
|
+
# mu : ratio of atom mass to a nitrogen molecule
|
|
591
|
+
# % p v0 c mu element
|
|
592
|
+
ion_param = [
|
|
593
|
+
[45, 0.617, 16.7, 4.66E-6, 0.57], # O
|
|
594
|
+
[15, 0.059, 9.4, 34.5E-6, 2.0], # Fe
|
|
595
|
+
[9, 0.082, 11.1, 9.29E-6, 0.86], # Mg
|
|
596
|
+
[31, 0.242, 11.0, 18.5E-6, 1.0], # Si
|
|
597
|
+
]
|
|
598
|
+
|
|
599
|
+
# beta0 = c .* (v - v0).^2 .* v.^0.8 ./ (1 + c .* (v - v0).^2 .* v.^0.8); primary ionization probability, eq. 33 in Jones
|
|
600
|
+
# v is needed in km/s!
|
|
601
|
+
|
|
602
|
+
if rho_m == 7800:
|
|
603
|
+
# Then we calculate the ionization probability for pure Fe
|
|
604
|
+
beta0 = ion_param(2,4) .* (v_km - ion_param(2,3)).^2 .* v_km.^0.8 ./ (1 + ion_param(2,4) .* (v_km - ion_param(2,3)).^2 .* v_km.^0.8);
|
|
605
|
+
beta0(find(v_km<ion_param(2,3))) = 0;
|
|
606
|
+
else
|
|
607
|
+
# Otherwise we use Jones' cometary composition (for porous, cometary as well as asteroidal densities)
|
|
608
|
+
# It is faster not to use repmat.m but to generate the necessary matrices with more simple tools!
|
|
609
|
+
c = [ion_param(1,4)*ones(length(v),1) ion_param(2,4)*ones(length(v),1) ion_param(3,4)*ones(length(v),1) ion_param(4,4)*ones(length(v),1)];
|
|
610
|
+
v0 = [ion_param(1,3)*ones(length(v),1) ion_param(2,3)*ones(length(v),1) ion_param(3,3)*ones(length(v),1) ion_param(4,3)*ones(length(v),1)];
|
|
611
|
+
p = [ion_param(1,2)*ones(length(v),1) ion_param(2,2)*ones(length(v),1) ion_param(3,2)*ones(length(v),1) ion_param(4,2)*ones(length(v),1)];
|
|
612
|
+
v_km = [v_km v_km v_km v_km];
|
|
613
|
+
beta0_1 = c .* (v_km - v0).^2 .* v_km.^0.8 ./ (1 + c .* (v_km - v0).^2 .* v_km.^0.8);
|
|
614
|
+
beta0_1(find(v_km<v0)) = 0;
|
|
615
|
+
beta0 = sum(beta0_1 .* p , 2);
|
|
616
|
+
"""
|
metablate/py.typed
ADDED
|
File without changes
|
metablate/version.py
ADDED