diff --git a/setup.py b/setup.py index d521b2c..fbbd5f6 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setup( name="pyvalem", - version="2.5.10", + version="2.5.11", description="A package for managing simple chemical species and states", long_description=long_description, long_description_content_type="text/x-rst", diff --git a/src/pyvalem/states/atomic_configuration.py b/src/pyvalem/states/atomic_configuration.py index b13bc65..fe5c043 100644 --- a/src/pyvalem/states/atomic_configuration.py +++ b/src/pyvalem/states/atomic_configuration.py @@ -16,6 +16,7 @@ # NB no "j" orbital. atomic_orbital_symbols = tuple("spdfghiklmnoqrtuvwxyz") + noble_gases = ["He", "Ne", "Ar", "Kr", "Xe", "Rn"] noble_gas_configs = { "He": "1s2", @@ -25,6 +26,12 @@ "Xe": "[Kr].4d10.5s2.5p6", "Rn": "[Xe].4f14.5d10.6s2.6p6", } +# Expand out the noble gas configurations to explicitly list all orbitals. +for i, elm in enumerate(noble_gases[1:], start=1): + s = noble_gases[i - 1] + c = noble_gas_configs[s] + noble_gas_configs[elm] = noble_gas_configs[elm].replace(f"[{s}]", c) + noble_gas_nelectrons = {"He": 2, "Ne": 10, "Ar": 18, "Kr": 36, "Xe": 54, "Rn": 86} noble_gas = pp.oneOf(["[{}]".format(symbol) for symbol in noble_gases]) @@ -223,11 +230,11 @@ class AtomicConfiguration(State): """ def __init__(self, state_str): - self.state_str = state_str + self.state_str = self._contract_to_noble_gas_config(state_str) self.orbitals = [] self.noble_gas_config = None self.nelectrons = 0 - self._parse_state(state_str) + self._parse_state(self.state_str) def _parse_state(self, state_str): """Parses the `AtomicConfiguration` instance from the supplied `state_str`. @@ -298,7 +305,7 @@ def latex(self): return "".join(latex_chunks) def _expand_noble_gas_config(self, config): - """Recursively expand out the noble gas notation to orbitals. + """Expand out the noble gas notation to orbitals. For example: '[He].2s1' -> '1s2.2s2', @@ -316,14 +323,20 @@ def _expand_noble_gas_config(self, config): if config[0] != "[": return config - return ( - self._expand_noble_gas_config(noble_gas_configs[config[1:3]]) + config[4:] - ) + return noble_gas_configs[config[1:3]] + config[4:] + + def _contract_to_noble_gas_config(self, state_str): + """Replace explicit atomic orbital sequence with noble gas notation.""" + for noble_gas in noble_gases[::-3]: + config = noble_gas_configs[noble_gas] + if config in state_str: + state_str = state_str.replace(config, f"[{noble_gas}]") + return state_str def __repr__(self): """See the `State` base class.""" if self.noble_gas_config: - state_repr = self._expand_noble_gas_config(self.noble_gas_config) + state_repr = noble_gas_configs[self.noble_gas_config[1:3]] if self.orbitals: state_repr += "." + ".".join(repr(orbital) for orbital in self.orbitals) return state_repr diff --git a/tests/test_atomic_configurations.py b/tests/test_atomic_configurations.py index f994b64..9ac90e5 100644 --- a/tests/test_atomic_configurations.py +++ b/tests/test_atomic_configurations.py @@ -57,11 +57,22 @@ def test_atomic_configuration_equality(self): c1 = AtomicConfiguration("[Ar].4s2.3d10.4p5") c2 = AtomicConfiguration("[Ar].4s2.3d10.4p5") c3 = AtomicConfiguration("1s2.2s2.2p6.3s2.3p6.4s2.3d10.4p5") + self.assertEqual(c3.state_str, "[Ar].4s2.3d10.4p5") + self.assertEqual(c3.html, "[Ar]4s23d104p5") c4 = AtomicConfiguration("[Ar].4s2.3d10.4p6") self.assertEqual(c1, c2) self.assertEqual(c1, c3) self.assertNotEqual(c1, c4) + c5 = AtomicConfiguration("[Ne].3s") + self.assertEqual(repr(c5), "1s2.2s2.2p6.3s") + self.assertEqual(c5.state_str, "[Ne].3s") + self.assertEqual(c5.html, "[Ne]3s") + + c5 = AtomicConfiguration("1s2.2s2.2p6") + self.assertEqual(repr(c5), "1s2.2s2.2p6") + self.assertEqual(c5.state_str, "1s2.2s2.2p6") + def test_excited_atomic_configuration(self): c1 = AtomicConfiguration("5g1") self.assertRaises(AtomicConfigurationError, AtomicConfiguration, "4g1")