def test_benzene_gradients(benzene_dimer): coords, species, vol_ratios = benzene_dimer[0] ene, gradients = MBDGeom(coords).mbd_energy_species(species, vol_ratios, 0.83, force=True) with MBDGeom(coords) as geom: num_gradients = numerical_gradients(geom, 'mbd_energy_species', species, vol_ratios, 0.83) for i in range(len(coords)): assert gradients[i] == approx(num_gradients[i], rel=1e-10, abs=1e-10)
def test_benzene_rpa(): coords, species, vol_ratios = benzene_dimer[0] alpha_0, C6, R_vdw = from_volumes(species, vol_ratios) ene = MBDGeom(coords, do_rpa=True).mbd_energy( alpha_0, C6, R_vdw, 0.83, variant='plain' ) assert ene == approx(-0.007002398506090302, rel=1e-9)
def test_lithium(): with pytest.raises(MBDFortranException): [ MBDGeom(coords, lattice, k_grid).mbd_energy_species(species, vol_ratios, 0.83) for coords, lattice, k_grid, species, vol_ratios in bulk_lithium ]
def test_ethylcarbamate(): enes = [ MBDGeom(coords, lattice, k_grid).mbd_energy_species(species, vol_ratios, 0.83) for coords, lattice, k_grid, species, vol_ratios in ethylcarbamate ] ene_int = enes[0] - 2 * enes[1] assert ene_int == approx(-0.037040868610822564, rel=1e-10)
def test_argon_dimer_plain(): ene = MBDGeom([(0, 0, 0), (0, 0, 4 * ang)]).mbd_energy([11, 11], [63.525, 63.525], [3.55, 3.55], 0.83, variant='plain') assert ene == approx(-0.00024329110270970844, rel=1e-10)
def test_ethylcarbamate_ts(): enes = [ MBDGeom(coords, lattice).ts_energy_species(species, vol_ratios, 0.83) for coords, lattice, _, species, vol_ratios in ethylcarbamate ] ene_int = enes[0] - 2 * enes[1] assert ene_int == approx(-0.05218213230219945, rel=1e-10)
def test_argon_crystal_gradients(): coords, lattice, k_grid, species, vol_ratios = argon_crystal ene, gradients, latt_gradients = MBDGeom( coords, lattice, k_grid ).mbd_energy_species(species, vol_ratios, 0.83, force=True) with MBDGeom(coords, lattice, k_grid) as geom: num_gradients = numerical_gradients( geom, 'mbd_energy_species', species, vol_ratios, 0.83 ) for i in range(len(coords)): assert gradients[i] == approx(num_gradients[i], rel=1e-10, abs=1e-10) with MBDGeom(coords, lattice, k_grid) as geom: num_latt_gradients = numerical_latt_gradients( geom, 'mbd_energy_species', species, vol_ratios, 0.83 ) for i in range(3): assert latt_gradients[i] == approx(num_latt_gradients[i], rel=1e-10, abs=1e-10)
def test_argon_crystal_rpa(): coords, lattice, k_grid, species, vol_ratios = argon_crystal ene = MBDGeom(coords, lattice, k_grid, do_rpa=True).mbd_energy_species(species, vol_ratios, 0.83, variant='plain') assert ene == approx(-0.0021036969146744147, rel=1e-10)
def test_mbd_coulomb(): a = 14.4 beta = 2.0 enes = [] for coords, species, vol_ratios in peptide_meoh: geom = MBDGeom(coords, get_spectrum=True) _, eigs, C = geom.mbd_energy_species(species, vol_ratios, beta=0.83) omega_t = np.sqrt(eigs) alpha_0, C6, R_vdw = from_volumes(species, vol_ratios) omega = 4 * C6 / (3 * alpha_0 ** 2) charges = np.ones_like(alpha_0) masses = 1 / (alpha_0 * omega ** 2) ecoul = geom.coulomb_energy( charges, masses, omega_t, 'fermi', R_vdw, beta, a, C ) edip = geom.dipole_energy( alpha_0, omega, omega_t, 'fermi,dip', R_vdw, beta, a, C ) C = np.identity(len(omega_t)) omega_non = np.repeat(omega, 3) ecoul_non = geom.coulomb_energy( charges, masses, omega_non, 'fermi', R_vdw, beta, a, C ) edip_non = geom.dipole_energy( alpha_0, omega, omega_t, 'fermi,dip', R_vdw, beta, a, C ) enes.append(ecoul - edip - (ecoul_non - edip_non)) ene_int = enes[2] - enes[0] - enes[1] assert ene_int == approx(0.0002460638172163822 / 627.503, rel=1e-10)
def test_benzene_dimer_python(): mon1, mon2 = benzene_dimer dim = (np.vstack((mon1[0], mon2[0])), mon1[1] + mon2[1], mon1[2] + mon2[2]) enes = [ MBDGeom(coords).mbd_energy_species(species, vol_ratios, 0.83) for coords, species, vol_ratios in (mon1, mon2, dim) ] ene_int = enes[2] - enes[1] - enes[0] assert ene_int == approx(-0.006312323931302544, rel=1e-10)
def test_ethylcarbamate_scs(): enes = [ MBDGeom(coords, lattice, k_grid).mbd_energy_species( species, vol_ratios, 1, a=2.56, variant='scs' ) for coords, lattice, k_grid, species, vol_ratios in ethylcarbamate ] ene_int = enes[0] - 2 * enes[1] assert ene_int == approx(-0.03633331132194684, rel=1e-10)
def test_benzene_dimer_ts(): mon1, mon2 = benzene_dimer dim = (np.vstack((mon1[0], mon2[0])), mon1[1] + mon2[1], mon1[2] + mon2[2]) enes = [ MBDGeom(coords).ts_energy_species(species, vol_ratios, 0.94) for coords, species, vol_ratios in (mon1, mon2, dim) ] ene_int = enes[2] - enes[1] - enes[0] assert ene_int == approx(-0.008490052683234028, rel=1e-10)
def _run_MBD_f(self): """ Run MBD calculation via FORTRAN implementation. """ MBD = MBDcalc_F(self.xyz, lattice=self.UC, k_grid=self.kgrid, n_freq=self.n_omega_SCS, get_spectrum=self.get_MBD_spectrum) res = MBD.mbd_energy(self.alpha0_TS, self.C6_TS, self.RvdW_TS, self.beta, force=self.calc_forces) if self.periodic and self.get_MBD_spectrum and self.calc_forces: # all ((self.results['energy'], self.MBDevals, self.MBDmodes), \ self.results['forces'], self.results['stress']) = res self.results['forces'] *= -1. * Hartree / Bohr self.results['stress'] *= -1. * Hartree / Bohr elif self.periodic and self.get_MBD_spectrum: # no forces (self.results['energy'], self.MBDevals, self.MBDmodes) = res elif self.periodic and self.calc_forces: # no spectrum (self.results['energy'], self.results['forces'], \ self.results['stress']) = res self.results['forces'] *= -1. * Hartree / Bohr self.results['stress'] *= -1. * Hartree / Bohr elif self.get_MBD_spectrum and self.calc_forces: # no PBC ((self.results['energy'], self.MBDevals, self.MBDmodes), \ self.results['forces']) = res self.results['forces'] *= -1. * Hartree / Bohr elif self.get_MBD_spectrum: # no forces and no PBC (self.results['energy'], self.MBDevals, self.MBDmodes) = res elif self.calc_forces: # no spectrum and no PBC (self.results['energy'], self.results['forces']) = res self.results['forces'] *= -1. * Hartree / Bohr else: # only energy (with and without PBC) self.results['energy'] = res self.results['energy'] *= Hartree
def test_benzene_dimer_scs(): mon1, mon2 = benzene_dimer dim = (np.vstack((mon1[0], mon2[0])), mon1[1] + mon2[1], mon1[2] + mon2[2]) enes = [ MBDGeom(coords).mbd_energy_species( species, vol_ratios, 1, a=2.56, variant='scs' ) for coords, species, vol_ratios in (mon1, mon2, dim) ] ene_int = enes[2] - enes[1] - enes[0] assert ene_int == approx(-0.007462380657774048, rel=1e-10)
def run(supercell, k_grid, finite, force, method, early_return, repeat): if with_mpi: from mpi4py import MPI global RANK RANK = MPI.COMM_WORLD.Get_rank() _print('--------------') coords, lattice, species, vol_ratios = make_supercell( *unit_cell, supercell) _print('number of atoms:', len(coords)) _print('Pymbd version:', '.'.join(map(str, _version))) _print('Libmbd version:', '{}.{}.{}-{}'.format(*LIBMBD_VERSION)) _print('--------------') if early_return: return geom = MBDGeom(coords) if finite else MBDGeom(coords, lattice, k_grid) if method == 'mbd@rsscs': func = geom.mbd_energy_species elif method == 'mbd': func = partial(geom.mbd_energy_species, variant='plain') elif method == 'ts': func = geom.ts_energy_species with geom: for _ in range(repeat): res = func(species, vol_ratios, 0.83, force=force) geom.print_timing() if force: ene, grad, *_ = res else: ene = res ene = ene / len(coords) _print('--------------') _print('energy:', ene) if force: _print('grad[0]:', grad[0]) _print('--------------')
def test_argon_dimer_ts(): ene = MBDGeom([(0, 0, 0), (0, 0, 4 * ang)]).ts_energy( [11, 11], [63.525, 63.525], [3.55, 3.55], 0.94 ) assert ene == approx(-0.000318123017869182, rel=1e-10)
def test_argon_crystal(): coords, lattice, k_grid, species, vol_ratios = argon_crystal ene = MBDGeom(coords, lattice, k_grid).mbd_energy_species(species, vol_ratios, 0.83) assert ene == approx(-0.0021037562496878173, rel=1e-10)
def test_argon_dimer_dipole_matrix(): dip = MBDGeom([(0, 0, 0), (0, 0, 4 * ang)]).dipole_matrix('bare') assert (dip != 0).sum() == 6
def test_argon_dimer_rsscs(): ene = MBDGeom([(0, 0, 0), (0, 0, 4 * ang)]).mbd_energy_species( ['Ar', 'Ar'], [1, 1], 0.83 ) assert ene == approx(-0.0002462647623815428, rel=1e-10)
# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. import sys from pymbd import ang from pymbd.fortran import MBDGeom, with_mpi ene_expected = -0.0002462647623815428 ene = MBDGeom([(0, 0, 0), (0, 0, 4 * ang)]).mbd_energy_species(['Ar', 'Ar'], [1, 1], 0.83) if with_mpi: from mpi4py import MPI rank = MPI.COMM_WORLD.Get_rank() else: rank = 0 if rank == 0: print('Expected energy: {ene_expected}') print('Calculated energy: {ene}') if ene - ene_expected > 1e-10: sys.exit(1)
def test_lithium(bulk_lithium): coords, lattice, k_grid, species, vol_ratios = bulk_lithium with pytest.raises(MBDFortranError): MBDGeom(coords, lattice, k_grid).mbd_energy_species(species, vol_ratios, 0.83)