def test_from_hdf5(self): """Test from_hdf5.""" with tempfile.TemporaryFile() as tmp_file: with h5py.File(tmp_file, "w") as file: self.prop.to_hdf5(file) with h5py.File(tmp_file, "r") as file: read_prop = VibrationalEnergy.from_hdf5( file["VibrationalEnergy"]) self.assertEqual(self.prop, read_prop)
def get_vibrational_energy(self, normalize: bool = True) -> VibrationalEnergy: """ Get the force constants as a VibrationalEnergy property. Args: normalize: Whether to normalize the factors or not Returns: A VibrationalEnergy property. """ sorted_integrals: dict[int, list[tuple[float, tuple[int, ...]]]] = { 1: [], 2: [], 3: [] } for entry in self.quadratic_force_constants: indices = self._process_entry_indices(list(entry)) if indices: factor = 2.0 factor *= self._multinomial(indices) if normalize else 1.0 coeff = entry[2] / factor num_body = len(set(indices)) sorted_integrals[num_body].append((coeff, tuple(indices))) sorted_integrals[num_body].append( (-coeff, tuple(-i for i in indices))) for entry_c in self.cubic_force_constants: indices = self._process_entry_indices(list(entry_c)) if indices: factor = 2.0 * math.sqrt(2.0) factor *= self._multinomial(indices) if normalize else 1.0 coeff = entry_c[3] / factor num_body = len(set(indices)) sorted_integrals[num_body].append((coeff, tuple(indices))) for entry_q in self.quartic_force_constants: indices = self._process_entry_indices(list(entry_q)) if indices: factor = 4.0 factor *= self._multinomial(indices) if normalize else 1.0 coeff = entry_q[4] / factor num_body = len(set(indices)) sorted_integrals[num_body].append((coeff, tuple(indices))) return VibrationalEnergy([ VibrationalIntegrals(num_body, ints) for num_body, ints in sorted_integrals.items() ])
def _check_driver_result(self, expected_watson_data, prop): with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=DeprecationWarning) expected_watson = WatsonHamiltonian(expected_watson_data, 4) expected = VibrationalEnergy.from_legacy_driver_result(expected_watson) true_vib_energy = cast(VibrationalEnergy, prop.get_property(VibrationalEnergy)) with self.subTest("one-body terms"): expected_one_body = expected.get_vibrational_integral(1) true_one_body = true_vib_energy.get_vibrational_integral(1) self._check_integrals_are_close(expected_one_body, true_one_body) with self.subTest("two-body terms"): expected_two_body = expected.get_vibrational_integral(2) true_two_body = true_vib_energy.get_vibrational_integral(2) self._check_integrals_are_close(expected_two_body, true_two_body) with self.subTest("three-body terms"): expected_three_body = expected.get_vibrational_integral(3) true_three_body = true_vib_energy.get_vibrational_integral(3) self._check_integrals_are_close(expected_three_body, true_three_body)
def setUp(self): """Setup basis.""" super().setUp() basis = HarmonicBasis([2, 2, 2, 2]) with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=DeprecationWarning) watson = WatsonHamiltonian( [ [352.3005875, 2, 2], [-352.3005875, -2, -2], [631.6153975, 1, 1], [-631.6153975, -1, -1], [115.653915, 4, 4], [-115.653915, -4, -4], [115.653915, 3, 3], [-115.653915, -3, -3], [-15.341901966295344, 2, 2, 2], [-88.2017421687633, 1, 1, 2], [42.40478531359112, 4, 4, 2], [26.25167512727164, 4, 3, 2], [2.2874639206341865, 3, 3, 2], [0.4207357291666667, 2, 2, 2, 2], [4.9425425, 1, 1, 2, 2], [1.6122932291666665, 1, 1, 1, 1], [-4.194299375, 4, 4, 2, 2], [-4.194299375, 3, 3, 2, 2], [-10.20589125, 4, 4, 1, 1], [-10.20589125, 3, 3, 1, 1], [2.2973803125, 4, 4, 4, 4], [2.7821204166666664, 4, 4, 4, 3], [7.329224375, 4, 4, 3, 3], [-2.7821200000000004, 4, 3, 3, 3], [2.2973803125, 3, 3, 3, 3], ], 4, ) self.prop = VibrationalEnergy.from_legacy_driver_result(watson) self.prop.basis = basis