Ejemplo n.º 1
0
    def calc_impurity_energy(self, structure, elements):
        if structure not in ['oct38-center', 'oct38-face', 'oct38-edge']:
            raise ValueError("Cannot calculate impurity energy for '%s'" %
                             (structure, ))

        if len(elements) != 2:
            raise ValueError("Tuple of elements must be of length two")

        if self.debug:
            print "Calculating impurity energy..."
            print 40 * "*"
            print "Structure: %s" % (structure, )
            print "Elements: %s\n" % (elements, )

        name, impurity = structure.split('-')
        sym = reference_states[atomic_numbers[elements[1]]]['symmetry']
        latticeconstant = self.get_lattice_constant_a(sym, (elements[1], ))

        if name == 'oct38':
            sites = {'center': 10, 'face': 9, 'edge': 0}

            atoms = Octahedron(elements[1], 4, 1, latticeconstant)
            atoms.set_calculator(self.get_calc())

            dyn = BFGS(atoms, logfile=None, trajectory=None)
            dyn.run(fmax=0.001, steps=100)
            assert dyn.converged()
            s_clean = dyn.get_number_of_steps()
            e_clean = atoms.get_potential_energy()

            atoms[sites[impurity]].symbol = elements[0]

            dyn.run(fmax=0.001, steps=100)
            assert dyn.converged()
            s_impurity = dyn.get_number_of_steps()
            e_impurity = atoms.get_potential_energy()

        self.values[('impurity_energy', structure,
                     elements)] = e_impurity - e_clean

        if self.debug:
            print "BFGS steps: %i    %i" % (s_clean, s_impurity)
            print "Impurity energy: %.5f - %.5f = %.5f eV" % (
                e_impurity, e_clean, e_impurity - e_clean)
            print 40 * "-" + "\n"