예제 #1
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
예제 #2
0
 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)
예제 #3
0
    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)
예제 #4
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
예제 #5
0
    def SortAtomListBySpecies(self):
        """Returns a dictionary with atoms sorted according to species

		The dictionary will have the atomtypes of the different atomic
		species found in the list of atoms as keys. The corresponding
		values will be a list of atoms containing the atoms of the
		given type. 
		"""
        dictofspecies = {}
        for atom in self.GetListOfAtoms():
            if dictofspecies.has_key(atom.GetChemicalSymbol()):
                dictofspecies[atom.GetChemicalSymbol()].append(atom.Copy())
            else:
                atomlist = self.GetListOfAtoms().Copy()
                atomlist.data = ListOfAtoms([atom.Copy()])
                unitcell = copy.copy(atomlist.GetUnitCell())
                atomlist.data.SetUnitCell(unitcell, fix=True)
                dictofspecies[atom.GetChemicalSymbol()] = atomlist.data
        return dictofspecies
예제 #6
0
def afunc(var, data=None):
    rcs, rcp = var[0], var[1]
    f = open("base.fdf", "w")
    f.write("%block PAO.Basis\n  Ga  2\n")
    f.write(" 0   1\n")
    f.write("%10.5f\n1.0\n" % (rcs, ))
    f.write("1   1\n")
    f.write("%10.5f\n1.0\n" % (rcp, ))
    f.write("%endblock PAO.Basis\n")
    f.close()

    atoms = ListOfAtoms([
        Atom('Ga', (0.0, 0.0, 0.0), magmom=0),
        Atom('Ga', (2.0, 0.0, 0.0), magmom=0)
    ])

    a = Siesta(executable="/Users/ag/bin/siesta-xlf")

    a.SetOption("%include", "base.fdf")
    energy = a.run(atoms)

    print rcs, rcp, energy
    return -energy
예제 #7
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
예제 #8
0
     1.00000     1.00000
 n=6   1   2   E     2.50435     0.86601
     6.12615     5.62330
     1.00000     1.00000
 n=6   2   1   E   135.64896     4.82387
     5.14075
     1.00000
%EndBlock PAO.Basis
""")

URLbase = "http://fisica.ehu.es/ag/siesta-psffiles/"
urllib.urlretrieve(URLbase + "Pb.psf", "Pb.psf") 

cell = Num.array([ [0.5,0.5,0.0], [0.5,0.0,0.5], [0.0,0.5,0.5]])
cell = 4.89*cell
atoms = ListOfAtoms([Atom('Pb', (0.0,0.0,0.0))], cell=cell, periodic=1)

for i in range(len(cutoffs)):
  cutoff = cutoffs[i]
  print i, cutoff
  a = Siesta(executable="$HOME/bin/siesta-2.6.9")          # Initialize object
###  a.SetOption("FilterCutoff"," 100.0 Ry")               # Optional Filtering
  a.SetOption("Meshcutoff", str(cutoff)+" Ry")
  a.SetOption("%include"," basis.fdf")
  energy[i], dum, dum2 = a.run(atoms)   # Run Siesta and get the (free)energy

#
# Plot
#
p.add(biggles.Curve(cutoffs[:],energy[:]))
p.show()
예제 #9
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
예제 #10
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
예제 #11
0
# create a work subdirectory
orig_dir = os.getcwd()
dir = "bond_work"
if os.path.isdir(dir):  # does dir exist?
    shutil.rmtree(dir)  # yes, remove old directory
os.mkdir(dir)  # make dir directory
os.chdir(dir)  # move to dir

URLbase = "http://fisica.ehu.es/ag/siesta-psffiles/"
urllib.urlretrieve(URLbase + "H.psf", "H.psf")
urllib.urlretrieve(URLbase + "O.psf", "O.psf")

for i in range(len(bonds)):
    d = bonds[i]
    print i, d
    atoms = ListOfAtoms([
        Atom('H', (d * math.cos(theta), d * math.sin(theta), 0.0), magmom=1),
        Atom('H', (-d * math.cos(theta), d * math.sin(theta), 0.0), magmom=1),
        Atom('O', (0, 0, 0), magmom=1)
    ])
    #                     cell=(4, 4, 4), periodic=1)

    energy[i] = a.run(atoms)  # Run Siesta and get the (free)energy

#
# Plot
#
p.add(biggles.Curve(bonds[:], energy[:]))
p.show()
os.chdir(orig_dir)
예제 #12
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