diff --git a/src/openfermion/chem/molecular_data.py b/src/openfermion/chem/molecular_data.py index 64dc376b6..bc79e3e28 100644 --- a/src/openfermion/chem/molecular_data.py +++ b/src/openfermion/chem/molecular_data.py @@ -33,7 +33,9 @@ # Define error objects which inherit from Exception. -class MoleculeNameError(Exception): +class MoleculeNameError(ValueError): + """Exception raised when a molecule name is invalid or cannot be generated.""" + pass @@ -273,10 +275,12 @@ def name_molecule(geometry, basis, multiplicity, charge, description): 11: 'undectet', 12: 'duodectet', } - if multiplicity not in multiplicity_dict: - raise MoleculeNameError('Invalid spin multiplicity provided.') - else: + if multiplicity in multiplicity_dict: name += '_{}'.format(multiplicity_dict[multiplicity]) + elif multiplicity > 0: + name += '_{}-multiplet'.format(multiplicity) + else: + raise MoleculeNameError('Invalid spin multiplicity provided.') # Add charge. if charge > 0: @@ -491,7 +495,12 @@ def __init__( # Metadata fields which must be provided. self.geometry = geometry self.basis = basis - self.multiplicity = multiplicity + if isinstance( + multiplicity, (int, float, numpy.integer, numpy.floating) + ) and multiplicity == int(multiplicity): + self.multiplicity = int(multiplicity) + else: + raise MoleculeNameError('Invalid spin multiplicity provided.') # Metadata fields with default values. self.charge = charge @@ -500,7 +509,7 @@ def __init__( self.description = description # Name molecule and get associated filename - self.name = name_molecule(geometry, basis, multiplicity, charge, description) + self.name = name_molecule(geometry, basis, self.multiplicity, charge, description) if filename: if filename[-5:] == '.hdf5': filename = filename[: (len(filename) - 5)] diff --git a/src/openfermion/chem/molecular_data_test.py b/src/openfermion/chem/molecular_data_test.py index d51e6937c..c640f3303 100644 --- a/src/openfermion/chem/molecular_data_test.py +++ b/src/openfermion/chem/molecular_data_test.py @@ -104,6 +104,34 @@ def test_invalid_multiplicity(self): with self.assertRaises(MoleculeNameError): MolecularData(geometry, basis, multiplicity) + # Test non-integer multiplicity + with self.assertRaises(MoleculeNameError): + MolecularData(geometry, basis, multiplicity=1.5) + + # Test zero multiplicity + with self.assertRaises(MoleculeNameError): + MolecularData(geometry, basis, multiplicity=0) + + def test_high_multiplicity(self): + # 12 hydrogens can support multiplicity 13 + geometry = [('H', (0.0, 0.0, i * 1.3)) for i in range(12)] + basis = 'sto-3g' + molecule = MolecularData(geometry, basis, multiplicity=13) + self.assertEqual(molecule.name, 'H12_sto-3g_13-multiplet') + + def test_float_multiplicity(self): + geometry = [('H', (0.0, 0.0, 0.0)), ('H', (0.0, 0.0, 0.7414))] + basis = 'sto-3g' + + # Float multiplicity <= 12 should work and use name + molecule = MolecularData(geometry, basis, multiplicity=2.0) + self.assertEqual(molecule.name, 'H2_sto-3g_doublet') + + # Float multiplicity > 12 should work and use number + geometry_high = [('H', (0.0, 0.0, i * 1.3)) for i in range(12)] + molecule_high = MolecularData(geometry_high, basis, multiplicity=13.0) + self.assertEqual(molecule_high.name, 'H12_sto-3g_13-multiplet') + def test_geometry_from_file(self): water_geometry = [ ('O', (0.0, 0.0, 0.0)),