def test_imaginary_energies(self, n2_unstable_data): vib_data = VibrationsData(n2_unstable_data['atoms'], n2_unstable_data['hessian']) assert vib_data.tabulate() == ('\n'.join( VibrationsData._tabulate_from_energies(vib_data.get_energies())) + '\n')
def test_todict(self, n2_data): vib_data = VibrationsData(n2_data['atoms'], n2_data['hessian']) vib_data_dict = vib_data.todict() assert vib_data_dict['indices'] is None assert_array_almost_equal(vib_data_dict['atoms'].positions, n2_data['atoms'].positions) assert_array_almost_equal(vib_data_dict['hessian'], n2_data['hessian'])
def test_bad_hessian2d(self, n2_data): bad_hessians = (None, 'fish', 1, np.array([1, 2, 3]), n2_data['hessian'], np.array([[[1, 0, 0]], [[0, 0, 1]]])) for bad_hessian in bad_hessians: with pytest.raises(ValueError): VibrationsData.from_2d(n2_data['atoms'], bad_hessian)
def test_new_mass(self, n2_data): vib_data = VibrationsData(n2_data['atoms'], n2_data['hessian']) original_masses = vib_data.get_atoms().get_masses() new_masses = original_masses * 3 new_vib_data = vib_data.with_new_masses(new_masses) assert_array_almost_equal(new_vib_data.get_atoms().get_masses(), new_masses) assert_array_almost_equal(vib_data.get_energies() / np.sqrt(3), new_vib_data.get_energies())
def test_pdos(self, n2_data): vib_data = VibrationsData(n2_data['atoms'], n2_data['hessian']) with pytest.warns(np.ComplexWarning): pdos = vib_data.get_pdos() assert_array_almost_equal(pdos[0].get_energies(), vib_data.get_energies()) assert_array_almost_equal(pdos[1].get_energies(), vib_data.get_energies()) assert sum(pdos[0].get_weights()) == pytest.approx(3.0)
def test_fixed_atoms(self, n2_data): vib_data = VibrationsData(n2_data['atoms'], n2_data['hessian'][1:, :, 1:, :], indices=[ 1, ]) assert vib_data.get_indices() == [ 1, ] assert vib_data.get_mask().tolist() == [False, True]
def test_dict_roundtrip(self, n2_data): vib_data = VibrationsData(n2_data['atoms'], n2_data['hessian']) vib_data_dict = vib_data.todict() vib_data_roundtrip = VibrationsData.fromdict(vib_data_dict) for getter in ('get_atoms', ): assert (getattr(vib_data, getter)() == getattr(vib_data_roundtrip, getter)()) for array_getter in ('get_hessian', 'get_hessian_2d', 'get_mask', 'get_indices'): assert_array_almost_equal( getattr(vib_data, array_getter)(), getattr(vib_data_roundtrip, array_getter)())
def test_dict_indices(self, n2_data, indices, expected_mask): vib_data = VibrationsData(n2_data['atoms'], n2_data['hessian']) vib_data_dict = vib_data.todict() vib_data_dict['indices'] = indices # Reduce size of Hessian if necessary if indices is not None: n_active = len(indices) vib_data_dict['hessian'] = (np.asarray( vib_data_dict['hessian'])[:n_active, :, :n_active, :].tolist()) vib_data_fromdict = VibrationsData.fromdict(vib_data_dict) assert_array_almost_equal(vib_data_fromdict.get_mask(), expected_mask)
def test_energies_and_modes(self, n2_data): vib_data = VibrationsData(n2_data['atoms'], n2_data['hessian']) energies, modes = vib_data.get_energies_and_modes() assert_array_almost_equal(n2_data['ref_frequencies'], energies / units.invcm, decimal=5) assert_array_almost_equal(n2_data['ref_frequencies'], vib_data.get_energies() / units.invcm, decimal=5) assert_array_almost_equal(n2_data['ref_frequencies'], vib_data.get_frequencies(), decimal=5) assert (vib_data.get_zero_point_energy() == pytest.approx( n2_data['ref_zpe'])) assert vib_data.tabulate() == vibrations_n2_log atoms_with_forces = vib_data.show_as_force(-1, show=False) try: assert_array_almost_equal(atoms_with_forces.get_forces(), n2_data['ref_forces']) except AssertionError: # Eigenvectors may be off by a sign change, which is allowed assert_array_almost_equal(atoms_with_forces.get_forces(), -n2_data['ref_forces'])
def test_tabulate_energies(self): # Test the private classmethod _tabulate_from_energies # used by public tabulate() method energies = np.array([1., complex(2., 1.), complex(1., 1e-3)]) table = VibrationsData._tabulate_from_energies(energies, im_tol=1e-2) for sep_row in 0, 2, 6: assert table[sep_row] == '-' * 21 assert tuple(table[1].strip().split()) == ('#', 'meV', 'cm^-1') expected_rows = [ # energy in eV should be converted to meV and cm-1 ('0', '1000.0', '8065.5'), # Imaginary component over threshold detected ('1', '1000.0i', '8065.5i'), # Small imaginary component ignored ('2', '1000.0', '8065.5') ] for row, expected in zip(table[3:6], expected_rows): assert tuple(row.split()) == expected # ZPE = (1 + 2 + 1) / 2 - currently we keep all real parts assert table[7].split()[2] == '2.000' assert len(table) == 8
def test_energies_and_modes(self, n2_data, n2_vibdata): energies, modes = n2_vibdata.get_energies_and_modes() assert_array_almost_equal(n2_data['ref_frequencies'], energies / units.invcm, decimal=5) assert_array_almost_equal(n2_data['ref_frequencies'], n2_vibdata.get_energies() / units.invcm, decimal=5) assert_array_almost_equal(n2_data['ref_frequencies'], n2_vibdata.get_frequencies(), decimal=5) assert (n2_vibdata.get_zero_point_energy() == pytest.approx( n2_data['ref_zpe'])) assert n2_vibdata.tabulate() == ( '\n'.join(VibrationsData._tabulate_from_energies(energies)) + '\n') atoms_with_forces = n2_vibdata.show_as_force(-1, show=False) try: assert_array_almost_equal(atoms_with_forces.get_forces(), n2_data['ref_forces']) except AssertionError: # Eigenvectors may be off by a sign change, which is allowed assert_array_almost_equal(atoms_with_forces.get_forces(), -n2_data['ref_forces'])
def create_ase_object(objtype, dct): # We just try each object type one after another and instantiate # them manually, depending on which kind it is. # We can formalize this later if it ever becomes necessary. if objtype == 'cell': from ase.cell import Cell dct.pop('pbc', None) # compatibility; we once had pbc obj = Cell(**dct) elif objtype == 'bandstructure': from ase.spectrum.band_structure import BandStructure obj = BandStructure(**dct) elif objtype == 'bandpath': from ase.dft.kpoints import BandPath obj = BandPath(path=dct.pop('labelseq'), **dct) elif objtype == 'atoms': from ase import Atoms obj = Atoms.fromdict(dct) elif objtype == 'vibrationsdata': from ase.vibrations import VibrationsData obj = VibrationsData.fromdict(dct) else: raise ValueError('Do not know how to decode object type {} ' 'into an actual object'.format(objtype)) assert obj.ase_objtype == objtype return obj
def test_vibrations_methods(self, testdir, random_dimer): vib = Vibrations(random_dimer) vib.run() vib_energies = vib.get_energies() for image in vib.iterimages(): assert len(image) == 2 thermo = IdealGasThermo(vib_energies=vib_energies, geometry='linear', atoms=vib.atoms, symmetrynumber=2, spin=0) thermo.get_gibbs_energy(temperature=298.15, pressure=2 * 101325., verbose=False) with open(self.logfile, 'w') as fd: vib.summary(log=fd) with open(self.logfile, 'rt') as fd: log_txt = fd.read() assert log_txt == '\n'.join( VibrationsData._tabulate_from_energies(vib_energies)) + '\n' last_mode = vib.get_mode(-1) scale = 0.5 assert_array_almost_equal( vib.show_as_force(-1, scale=scale, show=False).get_forces(), last_mode * 3 * len(vib.atoms) * scale) vib.write_mode(n=3, nimages=5) for i in range(3): assert not Path('vib.{}.traj'.format(i)).is_file() mode_traj = ase.io.read('vib.3.traj', index=':') assert len(mode_traj) == 5 assert_array_almost_equal(mode_traj[0].get_all_distances(), random_dimer.get_all_distances()) with pytest.raises(AssertionError): assert_array_almost_equal(mode_traj[4].get_all_distances(), random_dimer.get_all_distances()) assert vib.clean(empty_files=True) == 0 assert vib.clean() == 13 assert len(list(vib.iterimages())) == 13 d = dict(vib.iterdisplace(inplace=False)) for name, image in vib.iterdisplace(inplace=True): assert d[name] == random_dimer
def test_get_jmol_images(self, kwargs, expected): # Test the private staticmethod _get_jmol_images # used by the public write_jmol_images() method from ase.calculators.calculator import compare_atoms jmol_images = list(VibrationsData._get_jmol_images(**kwargs)) assert len(jmol_images) == len(expected) for image, reference in zip(jmol_images, expected): assert compare_atoms(image, reference) == [] for key, value in reference.info.items(): if key == 'frequency_cm-1': assert float(image.info[key]) == pytest.approx(value, abs=0.1) else: assert image.info[key] == value
def test_jmol_roundtrip(self, testdir, n2_data): ir_intensities = np.random.random(6) vib_data = VibrationsData(n2_data['atoms'], n2_data['hessian']) vib_data.write_jmol(self.jmol_file, ir_intensities=ir_intensities) images = ase.io.read(self.jmol_file, index=':') for i, image in enumerate(images): assert_array_almost_equal(image.positions, vib_data.get_atoms().positions) assert (image.info['IR_intensity'] == pytest.approx( ir_intensities[i])) assert_array_almost_equal(image.arrays['mode'], vib_data.get_modes()[i])
def test_zero_mass(self, n2_data): atoms = n2_data['atoms'] atoms.set_masses([0., 1.]) vib_data = VibrationsData(atoms, n2_data['hessian']) with pytest.raises(ValueError): vib_data.get_energies_and_modes()
def n2_vibdata(self, n2_data): return VibrationsData(n2_data['atoms'], n2_data['hessian'])
def test_init(self, n2_data): # Check that init runs without error; properties are checked in other # methods using the (identical) n2_vibdata fixture VibrationsData(n2_data['atoms'], n2_data['hessian'])
def test_indices_from_mask(self, mask, expected_indices): assert VibrationsData.indices_from_mask(mask) == expected_indices
def test_imaginary_energies(self, n2_unstable_data): vib_data = VibrationsData(n2_unstable_data['atoms'], n2_unstable_data['hessian']) assert vib_data.tabulate() == unstable_n2_log
def test_dos(self, n2_data): vib_data = VibrationsData(n2_data['atoms'], n2_data['hessian']) with pytest.warns(np.ComplexWarning): dos = vib_data.get_dos() assert_array_almost_equal(dos.get_energies(), vib_data.get_energies())