Ejemplo n.º 1
0
 def test_forces(self):
     for calc in [EAM('Au-Grochola-JCP05.eam.alloy')]:
         a = io.read('Au_923.xyz')
         a.center(vacuum=10.0)
         a.set_calculator(calc)
         f = a.get_forces()
         for i in range(9):
             atindex = i * 100
             fn = [
                 numeric_force(a, atindex, 0, self.disp),
                 numeric_force(a, atindex, 1, self.disp),
                 numeric_force(a, atindex, 2, self.disp)
             ]
             self.assertArrayAlmostEqual(f[atindex], fn, tol=self.tol)
Ejemplo n.º 2
0
    def calculate_numerical_forces(self, atoms, d=0.001):
        """Calculate numerical forces using finite difference.

        All atoms will be displaced by +d and -d in all directions."""

        return np.array([[numeric_force(atoms, a, i, d)
                          for i in range(3)] for a in range(len(atoms))])
Ejemplo n.º 3
0
    def calculate_numerical_forces(self, atoms, d=0.001):
        """Calculate numerical forces using finite difference.

        All atoms will be displaced by +d and -d in all directions."""

        from ase.calculators.test import numeric_force
        return np.array([[numeric_force(atoms, a, i, d) for i in range(3)]
                         for a in range(len(atoms))])
Ejemplo n.º 4
0
    def get_forces(self, atoms=None):
        """Get finite-difference forces"""
        if atoms is None:
            atoms = self.atoms

        if self.calculation_required(atoms, ['F_av']):
            atoms.set_calculator(self)

            # do the ground state calculation to set all
            # ranks to the same density to start with
            self.calculator.calculate(atoms)

            world = self.parallel['world']
            txt = self.txt
            if world.rank > 0:
                txt = sys.stdout

            mycomm = self.parallel['mycomm']
            ncalcs = self.parallel['ncalcs']
            icalc = self.parallel['icalc']
            F_av = np.zeros((len(atoms), 3))
            i = 0
            for ia, a in enumerate(self.atoms):
                for ic in range(3):
# print "ncalcs", ncalcs, "i", i, "icalc",icalc
                    if (i % ncalcs) == icalc:
                        F_av[ia, ic] = numeric_force(
                            atoms, ia, ic, self.d) / mycomm.size
                        prnt('# rank', world.rank, '-> force',
                             (str(ia) + 'xyz'[ic]), file=txt)
                    i += 1
            energy = np.array([0.])  # array needed for world.sum()
            if (i % ncalcs) == icalc:
                self.energy = None
                energy[0] = self.get_potential_energy(atoms) / mycomm.size
                prnt('# rank', world.rank, '-> energy',
                     energy[0] * mycomm.size, file=txt)
            self.set_positions(atoms)
            world.sum(F_av)
            world.sum(energy)
            self.energy = energy[0]
            self.F_av = F_av

            if self.txt:
                prnt('Excited state forces in eV/Ang:', file=self.txt)
                symbols = self.atoms.get_chemical_symbols()
                for a, symbol in enumerate(symbols):
                    prnt(('%3d %-2s %10.5f %10.5f %10.5f' %
                          ((a, symbol) + tuple(self.F_av[a]))),
                         file=self.txt)
        return self.F_av
Ejemplo n.º 5
0
    def get_forces(self, atoms=None):
        """Get finite-difference forces"""
        if atoms is None:
            atoms = self.atoms

        if self.calculation_required(atoms, ['F_av']):
            atoms.set_calculator(self)

            # do the ground state calculation to set all
            # ranks to the same density to start with
            self.calculator.calculate(atoms)

            world = self.parallel['world']
            txt = self.txt
            if world.rank > 0:
                txt = sys.stdout

            mycomm = self.parallel['mycomm']
            ncalcs = self.parallel['ncalcs']
            icalc = self.parallel['icalc']
            F_av = np.zeros((len(atoms), 3))
            i = 0
            for ia, a in enumerate(self.atoms):
                for ic in range(3):
                    if (i % ncalcs) == icalc:
                        F_av[ia, ic] = numeric_force(
                            atoms, ia, ic, self.d) / mycomm.size
                        prnt('# rank', world.rank, '-> force',
                             (str(ia) + 'xyz'[ic]), file=txt)
                    i += 1
            energy = np.array([0.]) # array needed for world.sum()
            if (i % ncalcs) == icalc:
                self.energy = None
                energy[0] = self.get_potential_energy(atoms) / mycomm.size
                prnt('# rank', world.rank, '-> energy', 
                     energy[0] * mycomm.size, file=txt)
            self.set_positions(atoms)
            world.sum(F_av)
            world.sum(energy)
            self.energy = energy[0]
            self.F_av = F_av

            if self.txt:
                prnt('Excited state forces in eV/Ang:', file=self.txt)
                symbols = self.atoms.get_chemical_symbols()
                for a, symbol in enumerate(symbols):
                    prnt(('%3d %-2s %10.5f %10.5f %10.5f' %
                          ((a, symbol) + tuple(self.F_av[a]))), 
                         file=self.txt)
        return self.F_av
Ejemplo n.º 6
0
def get_numeric_force(atoms, eps):
    fn = torch.zeros((len(atoms), 3))
    for i in range(len(atoms)):
        for j in range(3):
            fn[i, j] = numeric_force(atoms, i, j, eps)
    return fn
Ejemplo n.º 7
0
from ase.calculators.test import numeric_force
from gpaw import GPAW, Mixer
from gpaw.test import equal

a = 4.0
n = 16
atoms = Atoms([Atom('H', [1.234, 2.345, 3.456])],
                    cell=(a, a, a), pbc=True)
calc = GPAW(nbands=1,
            gpts=(n, n, n),
            txt=None,
            mixer=Mixer(0.25, 3, 1),
            convergence={'energy': 1e-7})
atoms.set_calculator(calc)
e1 = atoms.get_potential_energy()
niter1 = calc.get_number_of_iterations()
f1 = atoms.get_forces()[0]
for i in range(3):
    f2i = numeric_force(atoms, 0, i)
    print f1[i]-f2i
    equal(f1[i], f2i, 0.00025)

energy_tolerance = 0.00006
force_tolerance = 0.0001
niter_tolerance = 0
equal(e1, -0.531042, energy_tolerance)
f1_ref = [-0.291893, -0.305174, -0.35329]
for i in range(3):
    equal(f1[i], f1_ref[i], force_tolerance)
assert 34 <= niter1 <= 35, niter1
Ejemplo n.º 8
0
                        (0.75, 0.25, 0.75), (0.75, 0.75, 0.25)],
             pbc=True)
bulk.set_cell((a, a, a), scale_atoms=True)
n = 20
calc = GPAW(gpts=(n, n, n),
            nbands=8 * 3,
            occupations=FermiDirac(width=0.01),
            poissonsolver=PoissonSolver(nn='M', relax='J'),
            kpts=(2, 2, 2),
            convergence={'energy': 1e-7})
bulk.set_calculator(calc)
f1 = bulk.get_forces()[0, 2]
e1 = bulk.get_potential_energy()
niter1 = calc.get_number_of_iterations()

f2 = numeric_force(bulk, 0, 2)
print f1, f2, f1 - f2
equal(f1, f2, 0.005)

# Volume per atom:
vol = a**3 / 8
de = calc.get_electrostatic_corrections() / vol
print de
assert abs(de[0] - -2.190) < 0.001

print e1, f1, niter1
energy_tolerance = 0.00025
force_tolerance = 0.0001
niter_tolerance = 0
equal(e1, -46.6596470348, energy_tolerance)  # svnversion 5252
equal(f1, -1.38242356123, force_tolerance)  # svnversion 5252
Ejemplo n.º 9
0
Archivo: 8Si.py Proyecto: qsnake/gpaw
             pbc=True)
bulk.set_cell((a, a, a), scale_atoms=True)
n = 20
calc = GPAW(gpts=(n, n, n),
            nbands=8*3,
            occupations=FermiDirac(width=0.01),
            poissonsolver=PoissonSolver(nn='M', relax='J'),
            kpts=(2, 2, 2),
            convergence={'energy': 1e-7}
            )
bulk.set_calculator(calc)
f1 = bulk.get_forces()[0, 2]
e1 = bulk.get_potential_energy()
niter1 = calc.get_number_of_iterations()

f2 = numeric_force(bulk, 0, 2)
print f1,f2,f1-f2
equal(f1, f2, 0.005)

# Volume per atom:
vol = a**3 / 8
de = calc.get_electrostatic_corrections() / vol
print de
assert abs(de[0] - -2.190) < 0.001

print e1, f1, niter1
energy_tolerance = 0.00025
force_tolerance = 0.0001
niter_tolerance = 0
equal(e1, -46.6596470348, energy_tolerance) # svnversion 5252
equal(f1, -1.38242356123, force_tolerance) # svnversion 5252
Ejemplo n.º 10
0
# High-level test:
lih = Atoms('LiH')
lih[1].y += 1.64
lih.center(vacuum=3)

pos = lih.cell.sum(axis=0)
print(pos)
pc = PointChargePotential([-1.0], [pos])
lih.calc = GPAW(external=pc, txt='lih-pc.txt')
f1 = lih.get_forces()
fpc1 = pc.get_forces(lih.calc)
print(fpc1)
print(fpc1 + f1.sum(0))

f2 = [[numeric_force(lih, a, v) for v in range(3)] for a in range(2)]
print(f1)
print(f1 - f2)
assert abs(f1 - f2).max() < 2e-3

x = 0.0001
for v in range(3):
    pos[v] += x
    pc.set_positions([pos])
    ep = lih.get_potential_energy()
    pos[v] -= 2 * x
    pc.set_positions([pos])
    em = lih.get_potential_energy()
    pos[v] += x
    pc.set_positions([pos])
    error = (em - ep) / (2 * x) - fpc1[0, v]
Ejemplo n.º 11
0
print(F_ac)
print()
print('Reference result')
print(F_ac_ref)
print()
print('Error')
print(err_ac)
print()
print('Max error')
print(err)

# ASE uses dx = [+|-] 0.001 by default,
# error should be around 2e-3.  In fact 4e-3 would probably be acceptable
assert err < 3e-3

# Set boolean to run new FD check
fd = not not False

if fd:
    from ase.calculators.test import numeric_force
    F_ac_fd = np.array([[numeric_force(system, a, i) for i in range(3)]
                        for a in range(len(system))])
    print('Self-consistent forces')
    print(F_ac)
    print('FD')
    print(F_ac_fd)
    print(repr(F_ac_fd))
    print(F_ac - F_ac_fd, np.abs(F_ac - F_ac_fd).max())

    assert np.abs(F_ac - F_ac_fd).max() < 4e-3