Exemplo n.º 1
0
def test2(pw=300, kpts=(6, 6, 6), vaspcmd='mr vasp'):
    """Performs a test stress-strain calculation with vasp module for fcc Pt."""

    v = VASP(pw=pw, kpts=kpts, name='fccPt', vaspcmd=vaspcmd)

    from ASE import ListOfAtoms, Atom

    atoms = ListOfAtoms([
        Atom('Pt', [0, 0, 0]),
        Atom('Pt', [0.5, 0.5, 0]),
        Atom('Pt', [0.5, 0, 0.5]),
        Atom('Pt', [0, 0.5, 0.5])
    ])

    uc = [[4.05, 0, 0], [0.0, 4.05, 0], [0.0, 0, 4.05]]

    atoms.SetUnitCell(uc)

    atoms.SetCalculator(v)

    import ASE.Utilities.GeometricTransforms as ASEgeotrans

    initvol = atoms.GetUnitCellVolume()

    vols, energies = [], []

    #for f in [0.8, 0.85, 0.9, 0.95, 1.0, 1.05, 1.1, 1.15]:
    for f in [0.9, 0.95, 1.0, 1.05, 1.1]:
        ASEgeotrans.SetUnitCellVolume(atoms, f * initvol)

        #v.SetName('%1.2f_eos' % f)
        #print v.GetStress()
        vols.append(atoms.GetUnitCellVolume())
        energies.append(atoms.GetPotentialEnergy())

    import pylab as pl

    pl.plot(vols, energies, 'ko ')
    pl.show()

    import ASE.Utilities.EquationOfState as ASEeos

    eos = ASEeos.EquationOfState('Murnaghan', vols, energies)
    # print the minimum volume, energy, bulk modulus and pressure
    print eos
    g = eos.GetPlot()
    eos.SavePlot('murn.png')  #save the figure as a png
    return
Exemplo n.º 2
0
def test1(pw=300, kpts=(6, 6, 6), vaspcmd='mr vasp'):
    """Performs a test single-point energy calculation with vasp module for B2 FeAl."""

    print "Test single-point energy calculation with vasp module for B2 FeAl."

    v = VASP(pw=pw, kpts=kpts, name='FeAl', vaspcmd=vaspcmd)

    from ASE import ListOfAtoms, Atom

    atoms = ListOfAtoms(
        [Atom('Fe', [0.0, 0.0, 0.0]),
         Atom('Al', [0.5, 0.5, 0.5])])

    uc = [[2.87, 0.00, 0.00], [0.00, 2.87, 0.00], [0.00, 0.00, 2.87]]

    atoms.SetUnitCell(uc)
    atoms.SetCalculator(v)

    print "Potential energy: ", v.GetPotentialEnergy()
    return
Exemplo n.º 3
0
class OldASECalculatorWrapper:
    def __init__(self, calc, atoms=None):
        self.calc = calc
            
        if atoms is None:
            try:
                self.atoms = calc.GetListOfAtoms()
            except AttributeError:
                self.atoms = None
        else:
            from ASE import Atom, ListOfAtoms
            
            numbers = atoms.get_atomic_numbers()
            positions = atoms.get_positions()
            magmoms = atoms.get_initial_magnetic_moments()
            self.atoms = ListOfAtoms(
                [Atom(Z=numbers[a], position=positions[a], magmom=magmoms[a])
                 for a in range(len(atoms))],
                cell=npy2num(atoms.get_cell()),
                periodic=tuple(atoms.get_pbc()))
            self.atoms.SetCalculator(calc)

    def get_atoms(self):
        return OldASEListOfAtomsWrapper(self.atoms)
            
    def get_potential_energy(self, atoms):
        self.atoms.SetCartesianPositions(npy2num(atoms.get_positions()))
        self.atoms.SetUnitCell(npy2num(atoms.get_cell()), fix=True)
        return self.calc.GetPotentialEnergy()

    def get_forces(self, atoms):
        self.atoms.SetCartesianPositions(npy2num(atoms.get_positions()))
        self.atoms.SetUnitCell(npy2num(atoms.get_cell()), fix=True)
        return np.array(self.calc.GetCartesianForces())

    def get_stress(self, atoms):
        self.atoms.SetCartesianPositions(npy2num(atoms.get_positions()))
        self.atoms.SetUnitCell(npy2num(atoms.get_cell()), fix=True)
        return np.array(self.calc.GetStress())

    def get_number_of_bands(self):
        return self.calc.GetNumberOfBands()

    def get_kpoint_weights(self):
        return np.array(self.calc.GetIBZKPointWeights())

    def get_number_of_spins(self):
        return 1 + int(self.calc.GetSpinPolarized())

    def get_eigenvalues(self, kpt=0, spin=0):
        return np.array(self.calc.GetEigenvalues(kpt, spin))

    def get_fermi_level(self):
        return self.calc.GetFermiLevel()

    def get_number_of_grid_points(self):
        return np.array(self.get_pseudo_wave_function(0, 0, 0).shape)

    def get_pseudo_wave_function(self, n=0, k=0, s=0, pad=True):
        kpt = self.get_bz_k_points()[k]
        state = self.calc.GetElectronicStates().GetState(band=n, spin=s,
                                                         kptindex=k)

        # Get wf, without bolch phase (Phase = True doesn't do anything!)
        wave = state.GetWavefunctionOnGrid(phase=False)

        # Add bloch phase if this is not the Gamma point
        if np.all(kpt == 0):
            return wave
        coord = state.GetCoordinates()
        phase = coord[0] * kpt[0] + coord[1] * kpt[1] + coord[2] * kpt[2]
        return np.array(wave) * np.exp(-2.j * np.pi * phase) # sign! XXX

        #return np.array(self.calc.GetWaveFunctionArray(n, k, s)) # No phase!

    def get_bz_k_points(self):
        return np.array(self.calc.GetBZKPoints())

    def get_ibz_k_points(self):
        return np.array(self.calc.GetIBZKPoints())

    def get_wannier_localization_matrix(self, nbands, dirG, kpoint,
                                        nextkpoint, G_I, spin):
        return np.array(self.calc.GetWannierLocalizationMatrix(
            G_I=G_I.tolist(), nbands=nbands, dirG=dirG.tolist(),
            kpoint=kpoint, nextkpoint=nextkpoint, spin=spin))
    
    def initial_wannier(self, initialwannier, kpointgrid, fixedstates,
                        edf, spin):
        # Use initial guess to determine U and C
        init = self.calc.InitialWannier(initialwannier, self.atoms,
                                        npy2num(kpointgrid, num.Int))

        states = self.calc.GetElectronicStates()
        waves = [[state.GetWaveFunction()
                  for state in states.GetStatesKPoint(k, spin)]
                 for k in self.calc.GetIBZKPoints()] 

        init.SetupMMatrix(waves, self.calc.GetBZKPoints())
        c, U = init.GetListOfCoefficientsAndRotationMatrices(
            (self.calc.GetNumberOfBands(), fixedstates, edf))
        U = np.array(U)
        for k in range(len(c)):
            c[k] = np.array(c[k])
        return c, U
Exemplo n.º 4
0
class Dacapo:
    def __init__(self,
                 filename=None,
                 stay_alive=False,
                 stress=False,
                 **kwargs):

        self.kwargs = kwargs
        self.stay_alive = stay_alive
        self.stress = stress

        if filename is not None:
            from Dacapo import Dacapo
            self.loa = Dacapo.ReadAtoms(filename, **kwargs)
            self.calc = self.loa.GetCalculator()
        else:
            self.loa = None
            self.calc = None

        self.pps = []

    def set_pp(self, Z, path):
        self.pps.append((Z, path))

    def set_txt(self, txt):
        if self.calc is None:
            self.kwargs['txtout'] = txt
        else:
            self.calc.SetTxtFile(txt)

    def set_nc(self, nc):
        if self.calc is None:
            self.kwargs['out'] = nc
        else:
            self.calc.SetNetCDFFile(nc)

    def update(self, atoms):
        from Dacapo import Dacapo
        if self.calc is None:
            if 'nbands' not in self.kwargs:
                n = sum([valence[atom.symbol] for atom in atoms])
                self.kwargs['nbands'] = int(n * 0.65) + 4

            magmoms = atoms.get_initial_magnetic_moments()
            if magmoms.any():
                self.kwargs['spinpol'] = True

            self.calc = Dacapo(**self.kwargs)

            if self.stay_alive:
                self.calc.StayAliveOn()
            else:
                self.calc.StayAliveOff()

            if self.stress:
                self.calc.CalculateStress()

            for Z, path in self.pps:
                self.calc.SetPseudoPotential(Z, path)

        if self.loa is None:
            from ASE import Atom, ListOfAtoms
            numbers = atoms.get_atomic_numbers()
            positions = atoms.get_positions()
            magmoms = atoms.get_initial_magnetic_moments()
            self.loa = ListOfAtoms([
                Atom(Z=numbers[a], position=positions[a], magmom=magmoms[a])
                for a in range(len(atoms))
            ],
                                   cell=np2num(atoms.get_cell()),
                                   periodic=tuple(atoms.get_pbc()))
            self.loa.SetCalculator(self.calc)
        else:
            self.loa.SetCartesianPositions(np2num(atoms.get_positions()))
            self.loa.SetUnitCell(np2num(atoms.get_cell()), fix=True)

    def get_atoms(self):
        atoms = OldASEListOfAtomsWrapper(self.loa).copy()
        atoms.set_calculator(self)
        return atoms

    def get_potential_energy(self, atoms):
        self.update(atoms)
        return self.calc.GetPotentialEnergy()

    def get_forces(self, atoms):
        self.update(atoms)
        return np.array(self.calc.GetCartesianForces())

    def get_stress(self, atoms):
        self.update(atoms)
        stress = np.array(self.calc.GetStress())
        if stress.ndim == 2:
            return stress.ravel()[[0, 4, 8, 5, 2, 1]]
        else:
            return stress

    def calculation_required(self, atoms, quantities):
        if self.calc is None:
            return True

        if atoms != self.get_atoms():
            return True

        return False

    def get_number_of_bands(self):
        return self.calc.GetNumberOfBands()

    def get_k_point_weights(self):
        return np.array(self.calc.GetIBZKPointWeights())

    def get_number_of_spins(self):
        return 1 + int(self.calc.GetSpinPolarized())

    def get_eigenvalues(self, kpt=0, spin=0):
        return np.array(self.calc.GetEigenvalues(kpt, spin))

    def get_fermi_level(self):
        return self.calc.GetFermiLevel()

    def get_number_of_grid_points(self):
        return np.array(self.get_pseudo_wave_function(0, 0, 0).shape)

    def get_pseudo_density(self, spin=0):
        return np.array(self.calc.GetDensityArray(s))

    def get_pseudo_wave_function(self, band=0, kpt=0, spin=0, pad=True):
        kpt_c = self.get_bz_k_points()[kpt]
        state = self.calc.GetElectronicStates().GetState(band=band,
                                                         spin=spin,
                                                         kptindex=kpt)

        # Get wf, without bloch phase (Phase = True doesn't do anything!)
        wave = state.GetWavefunctionOnGrid(phase=False)

        # Add bloch phase if this is not the Gamma point
        if np.all(kpt_c == 0):
            return wave
        coord = state.GetCoordinates()
        phase = coord[0] * kpt_c[0] + coord[1] * kpt_c[1] + coord[2] * kpt_c[2]
        return np.array(wave) * np.exp(-2.j * np.pi * phase)  # sign! XXX

        #return np.array(self.calc.GetWaveFunctionArray(n, k, s)) # No phase!

    def get_bz_k_points(self):
        return np.array(self.calc.GetBZKPoints())

    def get_ibz_k_points(self):
        return np.array(self.calc.GetIBZKPoints())

    def get_wannier_localization_matrix(self, nbands, dirG, kpoint, nextkpoint,
                                        G_I, spin):
        return np.array(
            self.calc.GetWannierLocalizationMatrix(G_I=G_I.tolist(),
                                                   nbands=nbands,
                                                   dirG=dirG.tolist(),
                                                   kpoint=kpoint,
                                                   nextkpoint=nextkpoint,
                                                   spin=spin))

    def initial_wannier(self, initialwannier, kpointgrid, fixedstates, edf,
                        spin):
        # Use initial guess to determine U and C
        init = self.calc.InitialWannier(initialwannier, self.atoms,
                                        np2num(kpointgrid, num.Int))

        states = self.calc.GetElectronicStates()
        waves = [[
            state.GetWaveFunction()
            for state in states.GetStatesKPoint(k, spin)
        ] for k in self.calc.GetIBZKPoints()]

        init.SetupMMatrix(waves, self.calc.GetBZKPoints())
        c, U = init.GetListOfCoefficientsAndRotationMatrices(
            (self.calc.GetNumberOfBands(), fixedstates, edf))
        U = np.array(U)
        for k in range(len(c)):
            c[k] = np.array(c[k])
        return c, U
Exemplo n.º 5
0
    def ReadAtoms(name='.'):
        """Static method to read in the atoms."""

        f = open('POSCAR', 'r')
        lines = f.readlines()
        f.close()

        comment = lines[0]

        uc = []
        uc.append([float(x) for x in lines[2].split()])
        uc.append([float(x) for x in lines[3].split()])
        uc.append([float(x) for x in lines[4].split()])

        scalefactor = float(lines[1].strip())
        if scalefactor < 0:
            #that means this is the volume of the cell
            #vol = determinant of the uc
            vol0 = abs(num.determinant(uc))
            uc = abs(scalefactor) / vol0 * uc
        else:
            uc = scalefactor * num.array(uc)

        atomcounts = [int(x) for x in lines[5].split()]
        natoms = 0
        for count in atomcounts:
            natoms += count

        if lines[6][0] in ['s', 'S']:
            #selective dynamics were chosen, and positions start on line 7
            coordsys = lines[7][0]
            poscounter = 8
        else:
            coordsys = lines[6][0]
            poscounter = 7

        positions = []
        for i in range(natoms):
            pos = num.array([float(x) for x in lines[poscounter + i].split()])
            if coordsys[0] in ['C', 'c', 'K', 'k']:
                #cartesian coordinates, do nothing
                pass
            else:
                #direct coordinates. calculate cartesian coords
                pos = pos[0] * uc[0] + pos[1] * uc[1] + pos[2] * uc[2]

            positions.append(pos)

        positions = num.array(positions)

        #now get the identities from the POTCAR file.
        f = open('POTCAR', 'r')
        lines = f.readlines()
        f.close()
        #the start of each psp is either 'US symbol' 'PAW_GGA symbol
        #comment' or 'PAW_PBE symbol comment'
        tag, symbol = lines[0].split()
        regexp = re.compile('^\s+%s' % tag)

        psps = []
        for line in lines:
            if regexp.search(line):
                psps.append(line)

        #print atomcounts, psps
        if len(atomcounts) != len(psps):
            raise Exception, 'number of atom counts in POSCAR does not equal # of psps in POTCAR'

        from ASE import Atom, ListOfAtoms
        atoms = ListOfAtoms([])
        poscounter = 0
        for i, count in enumerate(atomcounts):
            tag, symbol = psps[i].split()
            for j in range(count):
                atoms.append(Atom(symbol, position=positions[poscounter]))
                poscounter += 1

        atoms.SetUnitCell(uc, fix=True)

        if os.path.exists('OUTCAR'):
            f = open('OUTCAR', 'r')

            regexp = re.compile('TOTAL-FORCE \(eV/Angst\)')
            lines = f.readlines()
            f.close()

            forcei = None
            for i, line in enumerate(lines):
                if regexp.search(line):
                    forcei = i + 2  #linenumber that forces start on
                    break
            if forcei is None:
                raise Exception, 'forcei is none, no forces found!'

            forces = []
            for i in range(len(atoms)):
                posforce = [float(x) for x in lines[forcei + i].split()]
                forces.append(posforce[3:])
        else:
            forces = [None for atom in atoms]

        for atom, force in zip(atoms, forces):
            #print force
            atom._SetCartesianForce(force)

        ### more code must be added to read in the calculator.
        calc = VASP()
        calc.incar = parser2.INPUT2('INCAR')
        return atoms