minplascalc 1.0.1__tar.gz → 1.0.2__tar.gz

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.
Files changed (32) hide show
  1. {minplascalc-1.0.1 → minplascalc-1.0.2}/PKG-INFO +3 -2
  2. {minplascalc-1.0.1 → minplascalc-1.0.2}/README.rst +1 -1
  3. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/__init__.py +1 -1
  4. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/data/species/C++.json +1 -1
  5. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/data/species/C+.json +1 -1
  6. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/data/species/C.json +1 -1
  7. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/data/species/O++.json +1 -1
  8. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/data/species/O+.json +1 -1
  9. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/data/species/O-.json +1 -1
  10. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/data/species/O.json +1 -1
  11. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/data/species/Si++.json +1 -1
  12. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/data/species/Si+.json +1 -1
  13. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/data/species/Si.json +1 -1
  14. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/functions_transport.py +347 -179
  15. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/mixture.py +1 -1
  16. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/species.py +8 -8
  17. {minplascalc-1.0.1 → minplascalc-1.0.2}/pyproject.toml +8 -12
  18. {minplascalc-1.0.1 → minplascalc-1.0.2}/.gitignore +0 -0
  19. {minplascalc-1.0.1 → minplascalc-1.0.2}/LICENSE +0 -0
  20. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/data/demo/nist/nist_Oplus_emission_lines +0 -0
  21. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/data/demo/nist/nist_Oplus_levels +0 -0
  22. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/data/species/CO+.json +0 -0
  23. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/data/species/CO.json +0 -0
  24. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/data/species/O2+.json +0 -0
  25. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/data/species/O2-.json +0 -0
  26. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/data/species/O2.json +0 -0
  27. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/data/species/SiO+.json +0 -0
  28. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/data/species/SiO.json +0 -0
  29. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/functions_radiation.py +0 -0
  30. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/parsers.py +0 -0
  31. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/units.py +0 -0
  32. {minplascalc-1.0.1 → minplascalc-1.0.2}/minplascalc/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: minplascalc
3
- Version: 1.0.1
3
+ Version: 1.0.2
4
4
  Summary: A simple set of tools for doing calculations of thermal plasma compositions relevant to metallurgical problems using Python 3
5
5
  Project-URL: Homepage, https://github.com/quinnreynolds/minplascalc
6
6
  Author-email: Quinn Reynolds <quinnr@mintek.co.za>
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3.13
16
16
  Classifier: Topic :: Scientific/Engineering :: Chemistry
17
17
  Classifier: Topic :: Scientific/Engineering :: Physics
18
18
  Requires-Python: >=3.11
19
+ Requires-Dist: numba
19
20
  Requires-Dist: numpy
20
21
  Requires-Dist: scipy
21
22
  Description-Content-Type: text/x-rst
@@ -42,7 +43,7 @@ What is this repository for?
42
43
  * You're here because you want to calculate plasma compositions,
43
44
  thermodynamics, and physical and radiative properties. This package will
44
45
  do most of those things for LTE plasmas, to varying degrees of fidelity.
45
- * Version `v1.0.1 <https://github.com/quinnreynolds/minplascalc/releases/latest>`_.
46
+ * Version `v1.0.2 <https://github.com/quinnreynolds/minplascalc/releases/latest>`_.
46
47
 
47
48
 
48
49
  Quick start
@@ -20,7 +20,7 @@ What is this repository for?
20
20
  * You're here because you want to calculate plasma compositions,
21
21
  thermodynamics, and physical and radiative properties. This package will
22
22
  do most of those things for LTE plasmas, to varying degrees of fidelity.
23
- * Version `v1.0.1 <https://github.com/quinnreynolds/minplascalc/releases/latest>`_.
23
+ * Version `v1.0.2 <https://github.com/quinnreynolds/minplascalc/releases/latest>`_.
24
24
 
25
25
 
26
26
  Quick start
@@ -1,4 +1,4 @@
1
- __version__ = "1.0.1"
1
+ __version__ = "1.0.2"
2
2
 
3
3
  from . import mixture, parsers, species
4
4
 
@@ -4212,7 +4212,7 @@
4212
4212
  ]
4213
4213
  ],
4214
4214
  "ionisation_energy": 7.672470887440893e-18,
4215
- "energylevels": [
4215
+ "energy_levels": [
4216
4216
  [
4217
4217
  0.0,
4218
4218
  0.0
@@ -7172,7 +7172,7 @@
7172
7172
  ]
7173
7173
  ],
7174
7174
  "ionisation_energy": 3.90683772578823e-18,
7175
- "energylevels": [
7175
+ "energy_levels": [
7176
7176
  [
7177
7177
  0.5,
7178
7178
  0.0
@@ -8052,7 +8052,7 @@
8052
8052
  ]
8053
8053
  ],
8054
8054
  "ionisation_energy": 1.8040996647411364e-18,
8055
- "energylevels": [
8055
+ "energy_levels": [
8056
8056
  [
8057
8057
  0.0,
8058
8058
  0.0
@@ -4822,7 +4822,7 @@
4822
4822
  ]
4823
4823
  ],
4824
4824
  "ionisation_energy": 8.801646544933729e-18,
4825
- "energylevels": [
4825
+ "energy_levels": [
4826
4826
  [
4827
4827
  0.0,
4828
4828
  0.0
@@ -4297,7 +4297,7 @@
4297
4297
  ]
4298
4298
  ],
4299
4299
  "ionisation_energy": 5.627024923581859e-18,
4300
- "energylevels": [
4300
+ "energy_levels": [
4301
4301
  [
4302
4302
  1.5,
4303
4303
  0.0
@@ -11,7 +11,7 @@
11
11
  "electron_cross_section": null,
12
12
  "emission_lines": [],
13
13
  "ionisation_energy": 2.340780062274e-19,
14
- "energylevels": [
14
+ "energy_levels": [
15
15
  [
16
16
  0.5,
17
17
  0
@@ -597,7 +597,7 @@
597
597
  ]
598
598
  ],
599
599
  "ionisation_energy": 2.1818536569480278e-18,
600
- "energylevels": [
600
+ "energy_levels": [
601
601
  [
602
602
  2.0,
603
603
  0.0
@@ -5222,7 +5222,7 @@
5222
5222
  ]
5223
5223
  ],
5224
5224
  "ionisation_energy": 5.3661727129011726e-18,
5225
- "energylevels": [
5225
+ "energy_levels": [
5226
5226
  [
5227
5227
  0.0,
5228
5228
  0.0
@@ -2132,7 +2132,7 @@
2132
2132
  ]
2133
2133
  ],
2134
2134
  "ionisation_energy": 2.6188941386449313e-18,
2135
- "energylevels": [
2135
+ "energy_levels": [
2136
2136
  [
2137
2137
  0.5,
2138
2138
  0.0
@@ -2982,7 +2982,7 @@
2982
2982
  ]
2983
2983
  ],
2984
2984
  "ionisation_energy": 1.3060440877960931e-18,
2985
- "energylevels": [
2985
+ "energy_levels": [
2986
2986
  [
2987
2987
  0.0,
2988
2988
  0.0
@@ -3,8 +3,10 @@
3
3
  from typing import TYPE_CHECKING
4
4
 
5
5
  import numpy as np
6
- from scipy import constants # type: ignore
7
- from scipy.special import gamma # type: ignore
6
+ import scipy.linalg as scl # type: ignore[import-untyped]
7
+ from numba import njit # type: ignore[import-untyped]
8
+ from scipy import constants # type: ignore[import-untyped]
9
+ from scipy.special import gamma # type: ignore[import-untyped]
8
10
 
9
11
  from minplascalc import units as u
10
12
 
@@ -1076,6 +1078,7 @@ def sum2(s: int) -> float:
1076
1078
  return np.sum(1 / np.arange(1, s + 2) ** 2)
1077
1079
 
1078
1080
 
1081
+ @njit
1079
1082
  def delta(i: int, j: int) -> int:
1080
1083
  """Kronecker delta.
1081
1084
 
@@ -1715,6 +1718,124 @@ def q(mixture: "LTE") -> np.ndarray:
1715
1718
  Q35 = Qij_mix(mixture, 3, 5)
1716
1719
  Q44 = Qij_mix(mixture, 4, 4)
1717
1720
 
1721
+ q00 = _q00_jit(Q11, masses, nb_species, number_densities)
1722
+
1723
+ q01 = _q01_jit(Q11, Q12, masses, nb_species, number_densities)
1724
+
1725
+ q11 = _q11_jit(Q11, Q12, Q13, Q22, masses, nb_species, number_densities)
1726
+
1727
+ q02 = _q02_jit(Q11, Q12, Q13, masses, nb_species, number_densities)
1728
+
1729
+ q12 = _q12_jit(
1730
+ Q11, Q12, Q13, Q14, Q22, Q23, masses, nb_species, number_densities
1731
+ )
1732
+
1733
+ q22 = _q22_jit(
1734
+ Q11,
1735
+ Q12,
1736
+ Q13,
1737
+ Q14,
1738
+ Q15,
1739
+ Q22,
1740
+ Q23,
1741
+ Q24,
1742
+ Q33,
1743
+ masses,
1744
+ nb_species,
1745
+ number_densities,
1746
+ )
1747
+
1748
+ q03 = _q03_jit(Q11, Q12, Q13, Q14, masses, nb_species, number_densities)
1749
+
1750
+ q13 = _q13_jit(
1751
+ Q11,
1752
+ Q12,
1753
+ Q13,
1754
+ Q14,
1755
+ Q15,
1756
+ Q22,
1757
+ Q23,
1758
+ Q24,
1759
+ masses,
1760
+ nb_species,
1761
+ number_densities,
1762
+ )
1763
+
1764
+ q23 = _q23_jit(
1765
+ Q11,
1766
+ Q12,
1767
+ Q13,
1768
+ Q14,
1769
+ Q15,
1770
+ Q16,
1771
+ Q22,
1772
+ Q23,
1773
+ Q24,
1774
+ Q25,
1775
+ Q33,
1776
+ Q34,
1777
+ masses,
1778
+ nb_species,
1779
+ number_densities,
1780
+ )
1781
+
1782
+ q33 = _q33_jit(
1783
+ Q11,
1784
+ Q12,
1785
+ Q13,
1786
+ Q14,
1787
+ Q15,
1788
+ Q16,
1789
+ Q17,
1790
+ Q22,
1791
+ Q23,
1792
+ Q24,
1793
+ Q25,
1794
+ Q26,
1795
+ Q33,
1796
+ Q34,
1797
+ Q35,
1798
+ Q44,
1799
+ masses,
1800
+ nb_species,
1801
+ number_densities,
1802
+ )
1803
+
1804
+ mass_ratio = masses[np.newaxis, :] / masses[:, np.newaxis]
1805
+
1806
+ # Equation A5 of [Devoto1966]_.
1807
+ q10 = mass_ratio * q01
1808
+
1809
+ # Equation A8 of [Devoto1966]_.
1810
+ q20 = mass_ratio**2 * q02
1811
+
1812
+ # Equation A10 of [Devoto1966]_.
1813
+ q21 = mass_ratio * q12
1814
+
1815
+ # Equation A13 of [Devoto1966]_.
1816
+ q30 = mass_ratio**3 * q03
1817
+
1818
+ # Equation A15 of [Devoto1966]_.
1819
+ q31 = mass_ratio**2 * q13
1820
+
1821
+ # Equation A17 of [Devoto1966]_.
1822
+ q32 = mass_ratio * q23
1823
+
1824
+ # Combine the q-matrix elements into a single matrix.
1825
+ qq = np.block(
1826
+ [
1827
+ [q00, q01, q02, q03],
1828
+ [q10, q11, q12, q13],
1829
+ [q20, q21, q22, q23],
1830
+ [q30, q31, q32, q33],
1831
+ ]
1832
+ )
1833
+
1834
+ return qq
1835
+
1836
+
1837
+ @njit
1838
+ def _q00_jit(Q11, masses, nb_species, number_densities):
1718
1839
  # Equation A3 of [Devoto1966]_.
1719
1840
  q00 = np.zeros((nb_species, nb_species))
1720
1841
  for i in range(nb_species):
@@ -1733,7 +1854,11 @@ def q(mixture: "LTE") -> np.ndarray:
1733
1854
  ) ** (1 / 2) / masses[i] * (1 - delta(i, l))
1734
1855
  sumval += term1 * Q11[i, l] * term2
1735
1856
  q00[i, j] = 8 * sumval
1857
+ return q00
1858
+
1736
1859
 
1860
+ @njit
1861
+ def _q01_jit(Q11, Q12, masses, nb_species, number_densities):
1737
1862
  # Equation A4 of [Devoto1966]_.
1738
1863
  q01 = np.zeros((nb_species, nb_species))
1739
1864
  for i in range(nb_species):
@@ -1755,58 +1880,101 @@ def q(mixture: "LTE") -> np.ndarray:
1755
1880
  * (masses[i] / masses[j]) ** (3 / 2)
1756
1881
  * sumval
1757
1882
  )
1883
+ return q01
1758
1884
 
1759
- # Equation A6 of [Devoto1966]_.
1760
- q11 = np.zeros((nb_species, nb_species))
1885
+
1886
+ @njit
1887
+ def _q02_jit(Q11, Q12, Q13, masses, nb_species, number_densities):
1888
+ # Equation A7 of [Devoto1966]_.
1889
+ q02 = np.zeros((nb_species, nb_species))
1761
1890
  for i in range(nb_species):
1762
1891
  for j in range(nb_species):
1763
1892
  sumval = 0
1764
1893
  for l in range(nb_species):
1765
1894
  term1 = (
1766
1895
  number_densities[l]
1767
- * masses[l] ** (1 / 2)
1896
+ * masses[l] ** (5 / 2)
1768
1897
  / (masses[i] + masses[l]) ** (5 / 2)
1769
1898
  )
1770
1899
  term2 = (delta(i, j) - delta(j, l)) * (
1771
- 5
1772
- / 4
1773
- * (6 * masses[j] ** 2 + 5 * masses[l] ** 2)
1774
- * Q11[i, l]
1775
- - 15 * masses[l] ** 2 * Q12[i, l]
1776
- + 12 * masses[l] ** 2 * Q13[i, l]
1777
- ) + (delta(i, j) + delta(j, l)) * 4 * masses[j] * masses[
1778
- l
1779
- ] * Q22[i, l]
1900
+ 35 / 8 * Q11[i, l] - 21 / 2 * Q12[i, l] + 6 * Q13[i, l]
1901
+ )
1780
1902
  sumval += term1 * term2
1781
- q11[i, j] = (
1903
+ q02[i, j] = (
1782
1904
  8
1783
1905
  * number_densities[i]
1784
- * (masses[i] / masses[j]) ** (3 / 2)
1906
+ * (masses[i] / masses[j]) ** (5 / 2)
1785
1907
  * sumval
1786
1908
  )
1909
+ return q02
1787
1910
 
1788
- # Equation A7 of [Devoto1966]_.
1789
- q02 = np.zeros((nb_species, nb_species))
1911
+
1912
+ @njit
1913
+ def _q03_jit(Q11, Q12, Q13, Q14, masses, nb_species, number_densities):
1914
+ # Equation A12 of [Devoto1966]_.
1915
+ q03 = np.zeros((nb_species, nb_species))
1790
1916
  for i in range(nb_species):
1791
1917
  for j in range(nb_species):
1792
1918
  sumval = 0
1793
1919
  for l in range(nb_species):
1794
1920
  term1 = (
1795
1921
  number_densities[l]
1796
- * masses[l] ** (5 / 2)
1797
- / (masses[i] + masses[l]) ** (5 / 2)
1922
+ * masses[l] ** (7 / 2)
1923
+ / (masses[i] + masses[l]) ** (7 / 2)
1798
1924
  )
1799
1925
  term2 = (delta(i, j) - delta(j, l)) * (
1800
- 35 / 8 * Q11[i, l] - 21 / 2 * Q12[i, l] + 6 * Q13[i, l]
1926
+ 105 / 16 * Q11[i, l]
1927
+ - 189 / 8 * Q12[i, l]
1928
+ + 27 * Q13[i, l]
1929
+ - 10 * Q14[i, l]
1801
1930
  )
1802
1931
  sumval += term1 * term2
1803
- q02[i, j] = (
1932
+ q03[i, j] = (
1804
1933
  8
1805
1934
  * number_densities[i]
1806
- * (masses[i] / masses[j]) ** (5 / 2)
1935
+ * (masses[i] / masses[j]) ** (7 / 2)
1936
+ * sumval
1937
+ )
1938
+ return q03
1939
+
1940
+
1941
+ @njit
1942
+ def _q11_jit(Q11, Q12, Q13, Q22, masses, nb_species, number_densities):
1943
+ # Equation A6 of [Devoto1966]_.
1944
+ q11 = np.zeros((nb_species, nb_species))
1945
+ for i in range(nb_species):
1946
+ for j in range(nb_species):
1947
+ sumval = 0
1948
+ for l in range(nb_species):
1949
+ term1 = (
1950
+ number_densities[l]
1951
+ * masses[l] ** (1 / 2)
1952
+ / (masses[i] + masses[l]) ** (5 / 2)
1953
+ )
1954
+ term2 = (delta(i, j) - delta(j, l)) * (
1955
+ 5
1956
+ / 4
1957
+ * (6 * masses[j] ** 2 + 5 * masses[l] ** 2)
1958
+ * Q11[i, l]
1959
+ - 15 * masses[l] ** 2 * Q12[i, l]
1960
+ + 12 * masses[l] ** 2 * Q13[i, l]
1961
+ ) + (delta(i, j) + delta(j, l)) * 4 * masses[j] * masses[
1962
+ l
1963
+ ] * Q22[i, l]
1964
+ sumval += term1 * term2
1965
+ q11[i, j] = (
1966
+ 8
1967
+ * number_densities[i]
1968
+ * (masses[i] / masses[j]) ** (3 / 2)
1807
1969
  * sumval
1808
1970
  )
1971
+ return q11
1972
+
1809
1973
 
1974
+ @njit
1975
+ def _q12_jit(
1976
+ Q11, Q12, Q13, Q14, Q22, Q23, masses, nb_species, number_densities
1977
+ ):
1810
1978
  # Equation A9 of [Devoto1966]_.
1811
1979
  q12 = np.zeros((nb_species, nb_species))
1812
1980
  for i in range(nb_species):
@@ -1840,7 +2008,74 @@ def q(mixture: "LTE") -> np.ndarray:
1840
2008
  * (masses[i] / masses[j]) ** (5 / 2)
1841
2009
  * sumval
1842
2010
  )
1843
-
2011
+ return q12
2012
+
2013
+
2014
+ @njit
2015
+ def _q13_jit(
2016
+ Q11,
2017
+ Q12,
2018
+ Q13,
2019
+ Q14,
2020
+ Q15,
2021
+ Q22,
2022
+ Q23,
2023
+ Q24,
2024
+ masses,
2025
+ nb_species,
2026
+ number_densities,
2027
+ ):
2028
+ # Equation A14 of [Devoto1966]_.
2029
+ q13 = np.zeros((nb_species, nb_species))
2030
+ for i in range(nb_species):
2031
+ for j in range(nb_species):
2032
+ sumval = 0
2033
+ for l in range(nb_species):
2034
+ term1 = (
2035
+ number_densities[l]
2036
+ * masses[l] ** (5 / 2)
2037
+ / (masses[i] + masses[l]) ** (9 / 2)
2038
+ )
2039
+ term2 = (delta(i, j) - delta(j, l)) * (
2040
+ 105
2041
+ / 32
2042
+ * (18 * masses[j] ** 2 + 5 * masses[l] ** 2)
2043
+ * Q11[i, l]
2044
+ - 63
2045
+ / 4
2046
+ * (9 * masses[j] ** 2 + 5 * masses[l] ** 2)
2047
+ * Q12[i, l]
2048
+ + 81 * (masses[j] ** 2 + 2 * masses[l] ** 2) * Q13[i, l]
2049
+ - 160 * masses[l] ** 2 * Q14[i, l]
2050
+ + 60 * masses[l] ** 2 * Q15[i, l]
2051
+ ) + (delta(i, j) + delta(j, l)) * masses[j] * masses[l] * (
2052
+ 63 / 2 * Q22[i, l] - 72 * Q23[i, l] + 40 * Q24[i, l]
2053
+ )
2054
+ sumval += term1 * term2
2055
+ q13[i, j] = (
2056
+ 8
2057
+ * number_densities[i]
2058
+ * (masses[i] / masses[j]) ** (7 / 2)
2059
+ * sumval
2060
+ )
2061
+ return q13
2062
+
2063
+
2064
+ @njit
2065
+ def _q22_jit(
2066
+ Q11,
2067
+ Q12,
2068
+ Q13,
2069
+ Q14,
2070
+ Q15,
2071
+ Q22,
2072
+ Q23,
2073
+ Q24,
2074
+ Q33,
2075
+ masses,
2076
+ nb_species,
2077
+ number_densities,
2078
+ ):
1844
2079
  # Equation A11 of [Devoto1966]_.
1845
2080
  q22 = np.zeros((nb_species, nb_species))
1846
2081
  for i in range(nb_species):
@@ -1890,66 +2125,27 @@ def q(mixture: "LTE") -> np.ndarray:
1890
2125
  * (masses[i] / masses[j]) ** (5 / 2)
1891
2126
  * sumval
1892
2127
  )
1893
-
1894
- # Equation A12 of [Devoto1966]_.
1895
- q03 = np.zeros((nb_species, nb_species))
1896
- for i in range(nb_species):
1897
- for j in range(nb_species):
1898
- sumval = 0
1899
- for l in range(nb_species):
1900
- term1 = (
1901
- number_densities[l]
1902
- * masses[l] ** (7 / 2)
1903
- / (masses[i] + masses[l]) ** (7 / 2)
1904
- )
1905
- term2 = (delta(i, j) - delta(j, l)) * (
1906
- 105 / 16 * Q11[i, l]
1907
- - 189 / 8 * Q12[i, l]
1908
- + 27 * Q13[i, l]
1909
- - 10 * Q14[i, l]
1910
- )
1911
- sumval += term1 * term2
1912
- q03[i, j] = (
1913
- 8
1914
- * number_densities[i]
1915
- * (masses[i] / masses[j]) ** (7 / 2)
1916
- * sumval
1917
- )
1918
-
1919
- # Equation A14 of [Devoto1966]_.
1920
- q13 = np.zeros((nb_species, nb_species))
1921
- for i in range(nb_species):
1922
- for j in range(nb_species):
1923
- sumval = 0
1924
- for l in range(nb_species):
1925
- term1 = (
1926
- number_densities[l]
1927
- * masses[l] ** (5 / 2)
1928
- / (masses[i] + masses[l]) ** (9 / 2)
1929
- )
1930
- term2 = (delta(i, j) - delta(j, l)) * (
1931
- 105
1932
- / 32
1933
- * (18 * masses[j] ** 2 + 5 * masses[l] ** 2)
1934
- * Q11[i, l]
1935
- - 63
1936
- / 4
1937
- * (9 * masses[j] ** 2 + 5 * masses[l] ** 2)
1938
- * Q12[i, l]
1939
- + 81 * (masses[j] ** 2 + 2 * masses[l] ** 2) * Q13[i, l]
1940
- - 160 * masses[l] ** 2 * Q14[i, l]
1941
- + 60 * masses[l] ** 2 * Q15[i, l]
1942
- ) + (delta(i, j) + delta(j, l)) * masses[j] * masses[l] * (
1943
- 63 / 2 * Q22[i, l] - 72 * Q23[i, l] + 40 * Q24[i, l]
1944
- )
1945
- sumval += term1 * term2
1946
- q13[i, j] = (
1947
- 8
1948
- * number_densities[i]
1949
- * (masses[i] / masses[j]) ** (7 / 2)
1950
- * sumval
1951
- )
1952
-
2128
+ return q22
2129
+
2130
+
2131
+ @njit
2132
+ def _q23_jit(
2133
+ Q11,
2134
+ Q12,
2135
+ Q13,
2136
+ Q14,
2137
+ Q15,
2138
+ Q16,
2139
+ Q22,
2140
+ Q23,
2141
+ Q24,
2142
+ Q25,
2143
+ Q33,
2144
+ Q34,
2145
+ masses,
2146
+ nb_species,
2147
+ number_densities,
2148
+ ):
1953
2149
  # Equation A16 of [Devoto1966]_.
1954
2150
  q23 = np.zeros((nb_species, nb_species))
1955
2151
  for i in range(nb_species):
@@ -2014,7 +2210,31 @@ def q(mixture: "LTE") -> np.ndarray:
2014
2210
  * (masses[i] / masses[j]) ** (7 / 2)
2015
2211
  * sumval
2016
2212
  )
2017
-
2213
+ return q23
2214
+
2215
+
2216
+ @njit
2217
+ def _q33_jit(
2218
+ Q11,
2219
+ Q12,
2220
+ Q13,
2221
+ Q14,
2222
+ Q15,
2223
+ Q16,
2224
+ Q17,
2225
+ Q22,
2226
+ Q23,
2227
+ Q24,
2228
+ Q25,
2229
+ Q26,
2230
+ Q33,
2231
+ Q34,
2232
+ Q35,
2233
+ Q44,
2234
+ masses,
2235
+ nb_species,
2236
+ number_densities,
2237
+ ):
2018
2238
  # Equation A18 of [Devoto1966]_.
2019
2239
  q33 = np.zeros((nb_species, nb_species))
2020
2240
  for i in range(nb_species):
@@ -2104,67 +2324,7 @@ def q(mixture: "LTE") -> np.ndarray:
2104
2324
  * (masses[i] / masses[j]) ** (7 / 2)
2105
2325
  * sumval
2106
2326
  )
2107
-
2108
- # Equation A5 of [Devoto1966]_.
2109
- q10 = np.zeros((nb_species, nb_species))
2110
- for i in range(nb_species):
2111
- for j in range(nb_species):
2112
- q10[i, j] = masses[j] / masses[i] * q01[i, j]
2113
-
2114
- # Equation A8 of [Devoto1966]_.
2115
- q20 = np.zeros((nb_species, nb_species))
2116
- for i in range(nb_species):
2117
- for j in range(nb_species):
2118
- q20[i, j] = (masses[j] / masses[i]) ** 2 * q02[i, j]
2119
-
2120
- # Equation A10 of [Devoto1966]_.
2121
- q21 = np.zeros((nb_species, nb_species))
2122
- for i in range(nb_species):
2123
- for j in range(nb_species):
2124
- q21[i, j] = masses[j] / masses[i] * q12[i, j]
2125
-
2126
- # Equation A13 of [Devoto1966]_.
2127
- q30 = np.zeros((nb_species, nb_species))
2128
- for i in range(nb_species):
2129
- for j in range(nb_species):
2130
- q30[i, j] = (masses[j] / masses[i]) ** 3 * q03[i, j]
2131
-
2132
- # Equation A15 of [Devoto1966]_.
2133
- q31 = np.zeros((nb_species, nb_species))
2134
- for i in range(nb_species):
2135
- for j in range(nb_species):
2136
- q31[i, j] = (masses[j] / masses[i]) ** 2 * q13[i, j]
2137
-
2138
- # Equation A17 of [Devoto1966]_.
2139
- q32 = np.zeros((nb_species, nb_species))
2140
- for i in range(nb_species):
2141
- for j in range(nb_species):
2142
- q32[i, j] = masses[j] / masses[i] * q23[i, j]
2143
-
2144
- # Combine the q-matrix elements into a single matrix.
2145
- qq = np.zeros((4 * nb_species, 4 * nb_species))
2146
-
2147
- qq[0 * nb_species : 1 * nb_species, 0 * nb_species : 1 * nb_species] = q00
2148
- qq[0 * nb_species : 1 * nb_species, 1 * nb_species : 2 * nb_species] = q01
2149
- qq[0 * nb_species : 1 * nb_species, 2 * nb_species : 3 * nb_species] = q02
2150
- qq[0 * nb_species : 1 * nb_species, 3 * nb_species : 4 * nb_species] = q03
2151
-
2152
- qq[1 * nb_species : 2 * nb_species, 0 * nb_species : 1 * nb_species] = q10
2153
- qq[1 * nb_species : 2 * nb_species, 1 * nb_species : 2 * nb_species] = q11
2154
- qq[1 * nb_species : 2 * nb_species, 2 * nb_species : 3 * nb_species] = q12
2155
- qq[1 * nb_species : 2 * nb_species, 3 * nb_species : 4 * nb_species] = q13
2156
-
2157
- qq[2 * nb_species : 3 * nb_species, 0 * nb_species : 1 * nb_species] = q20
2158
- qq[2 * nb_species : 3 * nb_species, 1 * nb_species : 2 * nb_species] = q21
2159
- qq[2 * nb_species : 3 * nb_species, 2 * nb_species : 3 * nb_species] = q22
2160
- qq[2 * nb_species : 3 * nb_species, 3 * nb_species : 4 * nb_species] = q23
2161
-
2162
- qq[3 * nb_species : 4 * nb_species, 0 * nb_species : 1 * nb_species] = q30
2163
- qq[3 * nb_species : 4 * nb_species, 1 * nb_species : 2 * nb_species] = q31
2164
- qq[3 * nb_species : 4 * nb_species, 2 * nb_species : 3 * nb_species] = q32
2165
- qq[3 * nb_species : 4 * nb_species, 3 * nb_species : 4 * nb_species] = q33
2166
-
2167
- return qq
2327
+ return q33
2168
2328
 
2169
2329
 
2170
2330
  def qhat(mixture: "LTE") -> np.ndarray:
@@ -2197,6 +2357,31 @@ def qhat(mixture: "LTE") -> np.ndarray:
2197
2357
  Q24 = Qij_mix(mixture, 2, 4)
2198
2358
  Q33 = Qij_mix(mixture, 3, 3)
2199
2359
 
2360
+ qhat00 = _qhat00_jit(Q11, Q22, masses, nb_species, number_densities)
2361
+
2362
+ qhat01 = _qhat01_jit(
2363
+ Q11, Q12, Q22, Q23, masses, nb_species, number_densities
2364
+ )
2365
+
2366
+ qhat11 = _qhat11_jit(
2367
+ Q11, Q12, Q13, Q22, Q23, Q24, Q33, masses, nb_species, number_densities
2368
+ )
2369
+
2370
+ # Equation A21 of [Devoto1966]_.
2371
+ qhat10 = masses[np.newaxis, :] / masses[:, np.newaxis] * qhat01
2372
+
2373
+ qq = np.block(
2374
+ [
2375
+ [qhat00, qhat01],
2376
+ [qhat10, qhat11],
2377
+ ]
2378
+ )
2379
+
2380
+ return qq
2381
+
2382
+
2383
+ @njit
2384
+ def _qhat00_jit(Q11, Q22, masses, nb_species, number_densities):
2200
2385
  # Equation A19 of [Devoto1966]_.
2201
2386
  qhat00 = np.zeros((nb_species, nb_species))
2202
2387
  for i in range(nb_species):
@@ -2215,7 +2400,11 @@ def qhat(mixture: "LTE") -> np.ndarray:
2215
2400
  qhat00[i, j] = (
2216
2401
  8 * number_densities[i] * (masses[i] / masses[j]) * sumval
2217
2402
  )
2403
+ return qhat00
2404
+
2218
2405
 
2406
+ @njit
2407
+ def _qhat01_jit(Q11, Q12, Q22, Q23, masses, nb_species, number_densities):
2219
2408
  # Equation A20 of [Devoto1966]_.
2220
2409
  qhat01 = np.zeros((nb_species, nb_species))
2221
2410
  for i in range(nb_species):
@@ -2236,7 +2425,13 @@ def qhat(mixture: "LTE") -> np.ndarray:
2236
2425
  qhat01[i, j] = (
2237
2426
  8 * number_densities[i] * (masses[i] / masses[j]) ** 2 * sumval
2238
2427
  )
2428
+ return qhat01
2239
2429
 
2430
+
2431
+ @njit
2432
+ def _qhat11_jit(
2433
+ Q11, Q12, Q13, Q22, Q23, Q24, Q33, masses, nb_species, number_densities
2434
+ ):
2240
2435
  # Equation A22 of [Devoto1966]_.
2241
2436
  qhat11 = np.zeros((nb_species, nb_species))
2242
2437
  for i in range(nb_species):
@@ -2266,30 +2461,7 @@ def qhat(mixture: "LTE") -> np.ndarray:
2266
2461
  qhat11[i, j] = (
2267
2462
  8 * number_densities[i] * (masses[i] / masses[j]) ** 2 * sumval
2268
2463
  )
2269
-
2270
- # Equation A21 of [Devoto1966]_.
2271
- qhat10 = np.zeros((nb_species, nb_species))
2272
- for i in range(nb_species):
2273
- for j in range(nb_species):
2274
- qhat10[i, j] = masses[j] / masses[i] * qhat01[i, j]
2275
-
2276
- qq = np.zeros((2 * nb_species, 2 * nb_species))
2277
-
2278
- qq[0 * nb_species : 1 * nb_species, 0 * nb_species : 1 * nb_species] = (
2279
- qhat00
2280
- )
2281
- qq[0 * nb_species : 1 * nb_species, 1 * nb_species : 2 * nb_species] = (
2282
- qhat01
2283
- )
2284
-
2285
- qq[1 * nb_species : 2 * nb_species, 0 * nb_species : 1 * nb_species] = (
2286
- qhat10
2287
- )
2288
- qq[1 * nb_species : 2 * nb_species, 1 * nb_species : 2 * nb_species] = (
2289
- qhat11
2290
- )
2291
-
2292
- return qq
2464
+ return qhat11
2293
2465
 
2294
2466
 
2295
2467
  ### Transport property calculations ###########################################
@@ -2365,7 +2537,7 @@ def Dij(mixture: "LTE") -> np.ndarray:
2365
2537
  diffusion_matrix = np.zeros((nb_species, nb_species))
2366
2538
  qq = q(mixture) # Size (4*nb_species, 4*nb_species)
2367
2539
 
2368
- inverse_q = np.linalg.inv(qq)
2540
+ lu_piv_q = scl.lu_factor(qq)
2369
2541
  b_vec = np.zeros(4 * nb_species) # 4 for 4th order approximation
2370
2542
 
2371
2543
  for i in range(nb_species):
@@ -2376,7 +2548,7 @@ def Dij(mixture: "LTE") -> np.ndarray:
2376
2548
  [delta(h, i) - delta(h, j) for h in range(0, nb_species)]
2377
2549
  )
2378
2550
  b_vec[:nb_species] = 3 * np.sqrt(np.pi) * dij
2379
- cflat = inverse_q.dot(b_vec)
2551
+ cflat = scl.lu_solve(lu_piv_q, b_vec)
2380
2552
  cip = cflat.reshape(4, nb_species)
2381
2553
 
2382
2554
  # Diffusion coefficient, equation 3 of [Devoto1966]_.
@@ -2451,14 +2623,12 @@ def DTi(mixture: "LTE") -> float:
2451
2623
  masses = np.array([sp.molar_mass / u.N_a for sp in mixture.species])
2452
2624
 
2453
2625
  qq = q(mixture)
2454
-
2455
- inverse_q = np.linalg.inv(qq)
2456
2626
  b_vec = np.zeros(4 * nb_species) # 4 for 4th order approximation
2457
2627
  # Only the first element is non-zero
2458
2628
  b_vec[nb_species : 2 * nb_species] = (
2459
2629
  -15 / 2 * np.sqrt(np.pi) * number_densities
2460
2630
  )
2461
- aflat = inverse_q.dot(b_vec)
2631
+ aflat = np.linalg.solve(qq, b_vec)
2462
2632
  aip = aflat.reshape(4, nb_species)
2463
2633
 
2464
2634
  return (
@@ -2528,14 +2698,13 @@ def viscosity(mixture: "LTE") -> float:
2528
2698
 
2529
2699
  qqhat = qhat(mixture)
2530
2700
 
2531
- inverse_qhat = np.linalg.inv(qqhat)
2532
2701
  b_vec = np.zeros(2 * nb_species) # 2 for 2nd order approximation
2533
2702
  b_vec[:nb_species] = (
2534
2703
  5
2535
2704
  * number_densities
2536
2705
  * np.sqrt(2 * np.pi * masses / (u.k_b * mixture.T))
2537
2706
  )
2538
- bflat = inverse_qhat.dot(b_vec)
2707
+ bflat = np.linalg.solve(qqhat, b_vec)
2539
2708
  bip = bflat.reshape(2, nb_species)
2540
2709
 
2541
2710
  return 0.5 * u.k_b * mixture.T * np.sum(number_densities * bip[0])
@@ -2736,12 +2905,11 @@ def thermal_conductivity(
2736
2905
  # Solve equation 5 of [Devoto1966]_ to get the `a` matrix.
2737
2906
  qq = q(mixture)
2738
2907
 
2739
- inverse_q = np.linalg.inv(qq)
2740
2908
  b_vec = np.zeros(4 * nb_species)
2741
2909
  b_vec[nb_species : 2 * nb_species] = (
2742
2910
  -15 / 2 * np.sqrt(np.pi) * number_densities
2743
2911
  )
2744
- aflat = inverse_q.dot(b_vec)
2912
+ aflat = np.linalg.solve(qq, b_vec)
2745
2913
  aip = aflat.reshape(4, nb_species)
2746
2914
  # Equation 13 of [Devoto1966]_.
2747
2915
  k_dash = (
@@ -645,7 +645,7 @@ class LTE:
645
645
  * :math:`M_i` is the molar mass of species :math:`i`,
646
646
  in :math:`\text{kg.mol}^{-1}`.
647
647
  """
648
- number_densities = self.calculate_composition() # particules/m^3
648
+ number_densities = self.calculate_composition() # particles/m^3
649
649
  molar_masses = [sp.molar_mass for sp in self.species] # kg/mol
650
650
  return (
651
651
  sum(n_i * M_i for n_i, M_i in zip(number_densities, molar_masses))
@@ -188,7 +188,7 @@ class Monatomic(Species):
188
188
  molar_mass: float,
189
189
  charge_number: int,
190
190
  ionisation_energy: float,
191
- energylevels: list[tuple[float, float]],
191
+ energy_levels: list[tuple[float, float]],
192
192
  polarisability: float,
193
193
  multiplicity: float,
194
194
  effective_electrons: float | None,
@@ -213,7 +213,7 @@ class Monatomic(Species):
213
213
  Charge on the species (in integer units of the fundamental charge).
214
214
  ionisation_energy : float
215
215
  Ionisation energy of the species, in :math:`\text{J}`.
216
- energylevels : list[tuple[float, float]]
216
+ energy_levels : list[tuple[float, float]]
217
217
  Atomic energy level data - each entry in the list contains a pair
218
218
  of values giving the level's quantum number and its energy
219
219
  respectively, with energy in :math:`\text{J}`.
@@ -253,7 +253,7 @@ class Monatomic(Species):
253
253
  )
254
254
 
255
255
  self.ionisation_energy = ionisation_energy
256
- self.energylevels = deepcopy(energylevels)
256
+ self.energy_levels = deepcopy(energy_levels)
257
257
  self.sources = deepcopy(sources)
258
258
 
259
259
  def __repr__(self):
@@ -262,7 +262,7 @@ class Monatomic(Species):
262
262
  f"stoichiometry={self.stoichiometry},"
263
263
  f"molar_mass={self.molar_mass},charge_number={self.charge_number},"
264
264
  f"ionisation_energy={self.ionisation_energy},"
265
- f"energylevels={self.energylevels},"
265
+ f"energy_levels={self.energy_levels},"
266
266
  f"polarisability={self.polarisability},"
267
267
  f"multiplicity={self.multiplicity},"
268
268
  f"effective_electrons={self.effective_electrons},"
@@ -281,7 +281,7 @@ class Monatomic(Species):
281
281
  f"Molar mass: {self.molar_mass} kg/mol\n"
282
282
  f"Charge number: {self.charge_number}\n"
283
283
  f"Ionisation energy: {self.ionisation_energy} J\n"
284
- f"Energy levels: {len(self.energylevels)}\n"
284
+ f"Energy levels: {len(self.energy_levels)}\n"
285
285
  f"Polarisability: {self.polarisability} m^3\n"
286
286
  f"Multiplicity: {self.multiplicity}\n"
287
287
  f"Effective valence electrons: {self.effective_electrons}\n"
@@ -336,7 +336,7 @@ class Monatomic(Species):
336
336
  # Calculate the electronic partition function.
337
337
  electron_partition_function = 0.0
338
338
 
339
- for J_i, E_i in self.energylevels:
339
+ for J_i, E_i in self.energy_levels:
340
340
  if E_i < (self.ionisation_energy - dE):
341
341
  # Only include energy levels below the ionisation energy.
342
342
  g_i = 2 * J_i + 1 # Degeneracy of the energy level.
@@ -399,7 +399,7 @@ class Monatomic(Species):
399
399
 
400
400
  # Calculate the electronic energy.
401
401
  electronic_energy = 0.0
402
- for J_i, E_i in self.energylevels:
402
+ for J_i, E_i in self.energy_levels:
403
403
  if E_i < (self.ionisation_energy - dE):
404
404
  # Only include energy levels below the ionisation energy.
405
405
  g_i = 2 * J_i + 1 # Degeneracy of the energy level.
@@ -1162,7 +1162,7 @@ def from_file(datafile: str | Path) -> Monatomic | Diatomic | Polyatomic:
1162
1162
  species_data["molar_mass"],
1163
1163
  species_data["charge_number"],
1164
1164
  species_data["ionisation_energy"],
1165
- species_data["energylevels"],
1165
+ species_data["energy_levels"],
1166
1166
  species_data["polarisability"],
1167
1167
  species_data["multiplicity"],
1168
1168
  species_data["effective_electrons"],
@@ -41,6 +41,7 @@ classifiers = [
41
41
  "Programming Language :: Python :: 3.13"
42
42
  ]
43
43
  dependencies = [
44
+ "numba",
44
45
  "numpy",
45
46
  "scipy"
46
47
  ]
@@ -55,25 +56,20 @@ urls = {"Homepage" = "https://github.com/quinnreynolds/minplascalc"}
55
56
 
56
57
  [tool.hatch.build.targets.sdist]
57
58
  include = [
58
- "minplascalc/*.py",
59
- "minplascalc/data/*/*.json",
60
- "minplascalc/data/demo/nist/*"
61
- ]
62
-
63
- [tool.hatch.build.targets.wheel]
64
- packages = [
65
- "minplascalc"
59
+ "src/minplascalc/*.py",
60
+ "src/minplascalc/data/*/*.json",
61
+ "src/minplascalc/data/demo/nist/*"
66
62
  ]
63
+ packages = ["src/minplascalc"]
67
64
 
68
65
  [tool.hatch.metadata]
69
66
  allow-direct-references = true
70
67
 
71
68
  [tool.hatch.version]
72
- path = "minplascalc/__init__.py"
69
+ path = "src/minplascalc/__init__.py"
73
70
 
74
71
  [tool.ruff]
75
72
  indent-width = 4
76
- # See https://github.com/quinnreynolds/minplascalc/pull/66#discussion_r1986715810
77
73
  line-length = 79
78
74
 
79
75
  [tool.ruff.lint]
@@ -95,8 +91,8 @@ select = [
95
91
  ]
96
92
 
97
93
  [tool.ruff.lint.pycodestyle]
98
- # See https://github.com/quinnreynolds/minplascalc/pull/66#discussion_r1986715810
99
94
  max-line-length = 79
100
95
 
101
96
  [tool.ruff.lint.pydocstyle]
102
- convention = "numpy" # See https://numpydoc.readthedocs.io/en/latest/format.html
97
+ # See https://numpydoc.readthedocs.io/en/latest/format.html
98
+ convention = "numpy"
File without changes
File without changes