Exemplo n.º 1
0
    def __init__(self, atoms, restart, logfile, trajectory, master=None):
        """Structure optimizer object.

        Parameters:

        atoms: Atoms object
            The Atoms object to relax.
        
        restart: str
            Filename for restart file.  Default value is *None*.
        
        logfile: file object or str
            If *logfile* is a string, a file with that name will be opened.
            Use '-' for stdout.
        
        trajectory: Trajectory object or str
            Attach trajectory object.  If *trajectory* is a string a
            Trajectory will be constructed.  Use *None* for no
            trajectory.

        master: boolean
            Defaults to None, which causes only rank 0 to save files.  If
            set to true,  this rank will save files.
        """
        Dynamics.__init__(self, atoms, logfile, trajectory, master)
        self.restart = restart

        if restart is None or not isfile(restart):
            self.initialize()
        else:
            self.read()
            barrier()
Exemplo n.º 2
0
    def __init__(self, atoms, restart, logfile, trajectory, master=None):
        """Structure optimizer object.

        Parameters:

        atoms: Atoms object
            The Atoms object to relax.
        
        restart: str
            Filename for restart file.  Default value is *None*.
        
        logfile: file object or str
            If *logfile* is a string, a file with that name will be opened.
            Use '-' for stdout.
        
        trajectory: Trajectory object or str
            Attach trajectory object.  If *trajectory* is a string a
            Trajectory will be constructed.  Use *None* for no
            trajectory.

        master: boolean
            Defaults to None, which causes only rank 0 to save files.  If
            set to true,  this rank will save files.
        """
        Dynamics.__init__(self, atoms, logfile, trajectory, master)
        self.restart = restart

        if restart is None or not isfile(restart):
            self.initialize()
        else:
            self.read()
            barrier()
Exemplo n.º 3
0
 def _open_append(self, atoms):
     if not os.path.exists(self.filename):
         # OK, no old bundle.  Open as for write instead.
         barrier()
         self._open_write(atoms, False)
         return
     if not self.is_bundle(self.filename):
         raise IOError('Not a BundleTrajectory: ' + self.filename)
     self.state = 'read'
     metadata = self._read_metadata()
     self.metadata = metadata
     if metadata['version'] != self.version:
         raise NotImplementedError(
             'Cannot append to a BundleTrajectory version '
             '%s (supported version is %s)' %
             (str(metadata['version']), str(self.version)))
     if metadata['subtype'] not in ('normal', 'split'):
         raise NotImplementedError(
             'This version of ASE cannot append to BundleTrajectory '
             'subtype ' + metadata['subtype'])
     self.subtype = metadata['subtype']
     if metadata['backend'] == 'ulm':
         self.singleprecision = metadata['ulm.singleprecision']
     self._set_backend(metadata['backend'])
     self.nframes = self._read_nframes()
     self._open_log()
     self.log('Opening "%s" in append mode (nframes=%i)' %
              (self.filename, self.nframes))
     self.state = 'write'
     self.atoms = atoms
Exemplo n.º 4
0
    def open(self, filename, mode):
        """Opens the file.

        For internal use only.
        """
        self.fd = filename
        if mode == 'r':
            if isinstance(filename, str):
                self.fd = open(filename, 'rb')
            self.read_header()
        elif mode == 'a':
            exists = True
            if isinstance(filename, str):
                exists = os.path.isfile(filename)
                if exists:
                    self.fd = open(filename, 'rb')
                    self.read_header()
                    self.fd.close()
                barrier()
                if self.master:
                    self.fd = open(filename, 'ab+')
                else:
                    self.fd = devnull
        elif mode == 'w':
            if self.master:
                if isinstance(filename, str):
                    if self.backup and os.path.isfile(filename):
                        os.rename(filename, filename + '.bak')
                    self.fd = open(filename, 'wb')
            else:
                self.fd = devnull
        else:
            raise ValueError('mode must be "r", "w" or "a".')
Exemplo n.º 5
0
    def do_calculations(self, formulas):
        """Perform calculation on molecules, write results to .gpw files."""
        atoms = {}
        for formula in formulas:
            for symbol in string2symbols(formula.split('_')[0]):
                atoms[symbol] = None
        formulas = formulas + atoms.keys()

        for formula in formulas:
            if path.isfile(formula + '.gpw'):
                continue

            barrier()
            open(formula + '.gpw', 'w')
            s = molecule(formula)
            s.center(vacuum=self.vacuum)
            cell = s.get_cell()
            h = self.h
            s.set_cell((cell / (4 * h)).round() * 4 * h)
            s.center()
            calc = GPAW(h=h,
                        xc=self.xc,
                        eigensolver=self.eigensolver,
                        setups=self.setups,
                        basis=self.basis,
                        fixmom=True,
                        txt=formula + '.txt')

            if len(s) == 1:
                calc.set(hund=True)

            s.set_calculator(calc)

            if formula == 'BeH':
                calc.initialize(s)
                calc.nuclei[0].f_si = [(1, 0, 0.5, 0, 0),
                                       (0.5, 0, 0, 0, 0)]

            if formula in ['NO', 'ClO', 'CH']:
                s.positions[:, 1] += h * 1.5

            try:
                energy = s.get_potential_energy()
            except (RuntimeError, ConvergenceError):
                if rank == 0:
                    print >> sys.stderr, 'Error in', formula
                    traceback.print_exc(file=sys.stderr)
            else:
                print >> self.txt, formula, repr(energy)
                self.txt.flush()
                calc.write(formula)

            if formula in diatomic and self.calculate_dimer_bond_lengths:
                traj = PickleTrajectory(formula + '.traj', 'w')
                d = diatomic[formula][1]
                for x in range(-2, 3):
                    s.set_distance(0, 1, d * (1.0 + x * 0.02))
                    traj.write(s)
Exemplo n.º 6
0
    def do_calculations(self, formulas):
        """Perform calculation on molecules, write results to .gpw files."""
        atoms = {}
        for formula in formulas:
            for symbol in string2symbols(formula.split('_')[0]):
                atoms[symbol] = None
        formulas = formulas + atoms.keys()

        for formula in formulas:
            if path.isfile(formula + '.gpw'):
                continue

            barrier()
            open(formula + '.gpw', 'w')
            s = molecule(formula)
            s.center(vacuum=self.vacuum)
            cell = s.get_cell()
            h = self.h
            s.set_cell((cell / (4 * h)).round() * 4 * h)
            s.center()
            calc = GPAW(h=h,
                        xc=self.xc,
                        eigensolver=self.eigensolver,
                        setups=self.setups,
                        basis=self.basis,
                        fixmom=True,
                        txt=formula + '.txt')

            if len(s) == 1:
                calc.set(hund=True)

            s.set_calculator(calc)

            if formula == 'BeH':
                calc.initialize(s)
                calc.nuclei[0].f_si = [(1, 0, 0.5, 0, 0),
                                       (0.5, 0, 0, 0, 0)]

            if formula in ['NO', 'ClO', 'CH']:
                s.positions[:, 1] += h * 1.5

            try:
                energy = s.get_potential_energy()
            except (RuntimeError, ConvergenceError):
                if rank == 0:
                    print >> sys.stderr, 'Error in', formula
                    traceback.print_exc(file=sys.stderr)
            else:
                print >> self.txt, formula, repr(energy)
                self.txt.flush()
                calc.write(formula)

            if formula in diatomic and self.calculate_dimer_bond_lengths:
                traj = PickleTrajectory(formula + '.traj', 'w')
                d = diatomic[formula][1]
                for x in range(-2, 3):
                    s.set_distance(0, 1, d * (1.0 + x * 0.02))
                    traj.write(s)
Exemplo n.º 7
0
 def _rename_bundle(self, oldname, newname):
     "Rename a bundle.  Used to create the .bak"
     if self.master:
         os.rename(oldname, newname)
     else:
         while os.path.exists(oldname):
             time.sleep(1)
     # The master may not proceed before all tasks have seen the
     # directory go away.
     barrier()
Exemplo n.º 8
0
    def is_empty_bundle(filename):
        """Check if a filename is an empty bundle.

        Assumes that it is a bundle."""
        if not os.listdir(filename):
            return True  # Empty folders are empty bundles.
        with open(os.path.join(filename, 'frames'), 'rb') as fd:
            nframes = int(fd.read())

        # File may be removed by the master immediately after this.
        barrier()
        return nframes == 0
Exemplo n.º 9
0
    def __init__(self,
                 atoms,
                 restart,
                 logfile,
                 trajectory,
                 master=None,
                 force_consistent=False):
        """Structure optimizer object.

        Parameters:

        atoms: Atoms object
            The Atoms object to relax.

        restart: str
            Filename for restart file.  Default value is *None*.

        logfile: file object or str
            If *logfile* is a string, a file with that name will be opened.
            Use '-' for stdout.

        trajectory: Trajectory object or str
            Attach trajectory object.  If *trajectory* is a string a
            Trajectory will be constructed.  Use *None* for no
            trajectory.

        master: boolean
            Defaults to None, which causes only rank 0 to save files.  If
            set to true,  this rank will save files.

        force_consistent: boolean or None
            Use force-consistent energy calls (as opposed to the energy
            extrapolated to 0 K).  If force_consistent=None, uses
            force-consistent energies if available in the calculator, but
            falls back to force_consistent=False if not.
        """
        Dynamics.__init__(self, atoms, logfile, trajectory, master)
        self.force_consistent = force_consistent
        if self.force_consistent is None:
            self.set_force_consistent()
        self.restart = restart
        # initialize attribute
        self.fmax = None

        if restart is None or not isfile(restart):
            self.initialize()
        else:
            self.read()
            barrier()
Exemplo n.º 10
0
    def run(self):
        """Run the vibration calculations.

        This will calculate the forces for 6 displacements per atom
        ±x, ±y, ±z.  Only those calculations that are not already done
        will be started. Be aware that an interrupted calculation may
        produce an empty file (ending with .pckl), which must be deleted
        before restarting the job. Otherwise the forces will not be
        calculated for that displacement."""

        if not isfile(self.name + '.eq.pckl'):
            barrier()
            if rank == 0:
                fd = open(self.name + '.eq.pckl', 'w')
            forces = self.atoms.get_forces()
            if self.ir:
                dipole = self.calc.get_dipole_moment(self.atoms)
            if rank == 0:
                if self.ir:
                    pickle.dump([forces, dipole], fd)
                else:
                    pickle.dump(forces, fd)
                fd.close()
        
        p = self.atoms.positions.copy()
        for a in self.indices:
            for i in range(3):
                for sign in [-1, 1]:
                    for ndis in range(1, self.nfree/2+1):
                        filename = '%s.%d%s%s.pckl' % (self.name, a,
                                                       'xyz'[i], ndis*' +-'[sign])
                    if isfile(filename):
                        continue
                    barrier()
                    if rank == 0:
                        fd = open(filename, 'w')
                    self.atoms.positions[a, i] = p[a, i] + ndis * sign * self.delta
                    forces = self.atoms.get_forces()
                    if self.ir:
                        dipole = self.calc.get_dipole_moment(self.atoms)
                    if rank == 0:
                        if self.ir:
                            pickle.dump([forces, dipole], fd)
                        else:
                            pickle.dump(forces, fd)
                        fd.close()
                    self.atoms.positions[a, i] = p[a, i]
        self.atoms.set_positions(p)
Exemplo n.º 11
0
    def run(self):
        """Run the vibration calculations.

        This will calculate the forces for 6 displacements per atom
        ±x, ±y, ±z.  Only those calculations that are not already done
        will be started. Be aware that an interrupted calculation may
        produce an empty file (ending with .pckl), which must be deleted
        before restarting the job. Otherwise the forces will not be
        calculated for that displacement."""

        p = self.atoms.positions.copy()
        # Get forces and dipole moment at zero displacement
        filename = '%s.static.pckl' % self.name
        if not isfile(filename):
            if rank == 0:
                fd = open(filename, 'w')
                print '%s started.' % filename
            forces = self.atoms.get_forces()
            dipole = self.calc.get_dipole_moment(self.atoms)
            barrier()
            if rank == 0:
                pickle.dump([forces, dipole], fd)
                fd.close()
                print '%s done.' % filename
        # Get forces and dipole moments for the finite displacements
        for a in self.indices:
            for i in range(3):
                for sign in [-1, 1]:
                    for n in range(1, self.nfree + 1):
                        filename = '%s.%d%s%s.pckl' % (self.name, a, 'xyz'[i],
                                                       n * ' +-'[sign])
                        if isfile(filename):
                            continue
                        if rank == 0:
                            fd = open(filename, 'w')
                        self.atoms.positions[a,
                                             i] = p[a,
                                                    i] + sign * n * self.delta
                        forces = self.atoms.get_forces()
                        dipole = self.calc.get_dipole_moment(self.atoms)
                        barrier()
                        if rank == 0:
                            pickle.dump([forces, dipole], fd)
                            fd.close()
                        self.atoms.positions[a, i] = p[a, i]
        self.atoms.set_positions(p)
Exemplo n.º 12
0
def test():
    # Generate setup
    symbol = 'He'
    if rank == 0:
        g = Generator(symbol, 'revPBE', scalarrel=True, nofiles=True)
        g.run(exx=True, **parameters[symbol])
    barrier()
    setup_paths.insert(0, '.')

    a = 7.5 * Bohr
    n = 16
    atoms = Atoms([Atom('He', (0.0, 0.0, 0.0))], cell=(a, a, a), pbc=True)
    calc = Calculator(gpts=(n, n, n), nbands=1, xc='revPBE')
    atoms.set_calculator(calc)
    e1 = atoms.get_potential_energy()
    calc.write('He')
    e2 = e1 + calc.get_xc_difference('vdWDF')
    print e1, e2
Exemplo n.º 13
0
def test():
    # Generate setup
    symbol = 'He'
    if rank == 0:
        g = Generator(symbol, 'revPBE', scalarrel=True, nofiles=True)
        g.run(exx=True, **parameters[symbol])
    barrier()
    setup_paths.insert(0, '.')

    a = 7.5 * Bohr
    n = 16
    atoms = Atoms([Atom('He', (0.0, 0.0, 0.0))], cell=(a, a, a), pbc=True)
    calc = Calculator(gpts=(n, n, n), nbands=1, xc='revPBE')
    atoms.set_calculator(calc)
    e1 = atoms.get_potential_energy()
    calc.write('He')
    e2 = e1 + calc.get_xc_difference('vdWDF')
    print e1, e2
Exemplo n.º 14
0
    def run(self):
        """Run the vibration calculations.

        This will calculate the forces for 6 displacements per atom
        ±x, ±y, ±z.  Only those calculations that are not already done
        will be started. Be aware that an interrupted calculation may
        produce an empty file (ending with .pckl), which must be deleted
        before restarting the job. Otherwise the forces will not be
        calculated for that displacement."""

        p = self.atoms.positions.copy()
        # Get forces and dipole moment at zero displacement
        filename = '%s.static.pckl' % self.name
        if not isfile(filename):
            if rank == 0:
                fd = open(filename, 'w')
                print '%s started.' % filename
            forces = self.atoms.get_forces()
            dipole = self.calc.get_dipole_moment(self.atoms)
            barrier()
            if rank == 0:
                pickle.dump([forces, dipole], fd)
                fd.close()
                print '%s done.' % filename
        # Get forces and dipole moments for the finite displacements
        for a in self.indices:
            for i in range(3):
                for sign in [-1, 1]:
                    for n in range(1, self.nfree+1):
                        filename = '%s.%d%s%s.pckl' % (self.name, a,
                                                   'xyz'[i], n*' +-'[sign])
                        if isfile(filename):
                            continue
                        if rank == 0:
                            fd = open(filename, 'w')
                        self.atoms.positions[a, i] = p[a, i]+sign*n*self.delta
                        forces = self.atoms.get_forces()
                        dipole = self.calc.get_dipole_moment(self.atoms)
                        barrier()
                        if rank == 0:
                            pickle.dump([forces, dipole], fd)
                            fd.close()
                        self.atoms.positions[a, i] = p[a, i]
        self.atoms.set_positions(p)
Exemplo n.º 15
0
    def _make_bundledir(self, filename):
        """Make the main bundle directory.

        Since all MPI tasks might write to it, all tasks must wait for
        the directory to appear.
        """
        self.log('Making directory ' + filename)
        assert not os.path.isdir(filename)
        barrier()
        if self.master:
            os.mkdir(filename)
        else:
            i = 0
            while not os.path.isdir(filename):
                time.sleep(1)
                i += 1
            if i > 10:
                self.log('Waiting %d seconds for %s to appear!' %
                         (i, filename))
Exemplo n.º 16
0
    def open(self, filename, mode):
        """Opens the file.

        For internal use only.
        """
        self.fd = filename
        if mode == 'r':
            if isinstance(filename, basestring):
                self.fd = open(filename, 'rb')
            self.read_header()
        elif mode == 'a':
            exists = True
            if isinstance(filename, basestring):
                exists = os.path.isfile(filename)
                if exists:
                    exists = os.path.getsize(filename) > 0
                if exists:
                    self.fd = open(filename, 'rb')
                    self.read_header()
                    self.fd.close()
                barrier()
                if self.master:
                    self.fd = open(filename, 'ab+')
                else:
                    self.fd = devnull
        elif mode == 'w':
            if self.master:
                if isinstance(filename, basestring):
                    if self.backup and os.path.isfile(filename):
                        try:
                            os.rename(filename, filename + '.bak')
                        except WindowsError as e:
                            # this must run on Win only! Not atomic!
                            if e.errno != errno.EEXIST:
                                raise
                            os.unlink(filename + '.bak')
                            os.rename(filename, filename + '.bak')
                    self.fd = open(filename, 'wb')
            else:
                self.fd = devnull
        else:
            raise ValueError('mode must be "r", "w" or "a".')
Exemplo n.º 17
0
    def open(self, filename, mode):
        """Opens the file.

        For internal use only.
        """
        self.fd = filename
        if mode == 'r':
            if isinstance(filename, basestring):
                self.fd = open(filename, 'rb')
            self.read_header()
        elif mode == 'a':
            exists = True
            if isinstance(filename, basestring):
                exists = os.path.isfile(filename)
                if exists:
                    exists = os.path.getsize(filename) > 0
                if exists:
                    self.fd = open(filename, 'rb')
                    self.read_header()
                    self.fd.close()
                barrier()
                if self.master:
                    self.fd = open(filename, 'ab+')
                else:
                    self.fd = devnull
        elif mode == 'w':
            if self.master:
                if isinstance(filename, basestring):
                    if self.backup and os.path.isfile(filename):
                        try:
                            os.rename(filename, filename + '.bak')
                        except WindowsError as e:
                            # this must run on Win only! Not atomic!
                            if e.errno != errno.EEXIST:
                                raise
                            os.unlink(filename + '.bak')
                            os.rename(filename, filename + '.bak')
                    self.fd = open(filename, 'wb')
            else:
                self.fd = devnull
        else:
            raise ValueError('mode must be "r", "w" or "a".')
Exemplo n.º 18
0
    def __init__(self, atoms, restart, logfile, trajectory, master=None,
                 force_consistent=False):
        """Structure optimizer object.

        Parameters:

        atoms: Atoms object
            The Atoms object to relax.

        restart: str
            Filename for restart file.  Default value is *None*.

        logfile: file object or str
            If *logfile* is a string, a file with that name will be opened.
            Use '-' for stdout.

        trajectory: Trajectory object or str
            Attach trajectory object.  If *trajectory* is a string a
            Trajectory will be constructed.  Use *None* for no
            trajectory.

        master: boolean
            Defaults to None, which causes only rank 0 to save files.  If
            set to true,  this rank will save files.

        force_consistent: boolean or None
            Use force-consistent energy calls (as opposed to the energy
            extrapolated to 0 K).  If force_consistent=None, uses
            force-consistent energies if available in the calculator, but
            falls back to force_consistent=False if not.
        """
        Dynamics.__init__(self, atoms, logfile, trajectory, master)
        self.force_consistent = force_consistent
        self.restart = restart

        if restart is None or not isfile(restart):
            self.initialize()
        else:
            self.read()
            barrier()
Exemplo n.º 19
0
    def open(self, filename, mode):
        """Opens the file.

        For internal use only.
        """
        self.fd = filename
        if mode == "r":
            if isinstance(filename, str):
                self.fd = open(filename, "rb")
            self.read_header()
        elif mode == "a":
            exists = True
            if isinstance(filename, str):
                exists = os.path.isfile(filename)
                if exists:
                    exists = os.path.getsize(filename) > 0
                if exists:
                    self.fd = open(filename, "rb")
                    self.read_header()
                    self.fd.close()
                barrier()
                if self.master:
                    self.fd = open(filename, "ab+")
                else:
                    self.fd = devnull
        elif mode == "w":
            if self.master:
                if isinstance(filename, str):
                    if self.backup and os.path.isfile(filename):
                        try:
                            os.rename(filename, filename + ".bak")
                        except WindowsError, e:
                            # this must run on Win only! Not atomic!
                            if e.errno != errno.EEXIST:
                                raise
                            os.unlink(filename + ".bak")
                            os.rename(filename, filename + ".bak")
                    self.fd = open(filename, "wb")
            else:
                self.fd = devnull
Exemplo n.º 20
0
 def delete_bundle(cls, filename):
     "Deletes a bundle."
     if world.rank == 0:
         # Only the master deletes
         if not cls.is_bundle(filename, allowempty=True):
             raise IOError(
                 'Cannot remove "%s" as it is not a bundle trajectory.' %
                 (filename, ))
         if os.path.islink(filename):
             # A symbolic link to a bundle.  Only remove the link.
             os.remove(filename)
         else:
             # A real bundle
             shutil.rmtree(filename)
     else:
         # All other tasks wait for the directory to go away.
         while os.path.exists(filename):
             time.sleep(1)
     # The master may not proceed before all tasks have seen the
     # directory go away, as it might otherwise create a new bundle
     # with the same name, fooling the wait loop in _make_bundledir.
     barrier()
Exemplo n.º 21
0
    def __init__(self, atoms, restart, logfile, trajectory):
        """Structure optimizer object.

        atoms: Atoms object
            The Atoms object to relax.
        restart: str
            Filename for restart file.  Default value is *None*.
        logfile: file object or str
            If *logfile* is a string, a file with that name will be opened.
            Use '-' for stdout.
        trajectory: Trajectory object or str
            Attach trajectory object.  If *trajectory* is a string a
            PickleTrajectory will be constructed.  Use *None* for no
            trajectory.
        """
        Dynamics.__init__(self, atoms, logfile, trajectory)
        self.restart = restart

        if restart is None or not isfile(restart):
            self.initialize()
        else:
            self.read()
            barrier()
Exemplo n.º 22
0
    def __init__(self, atoms, restart, logfile, trajectory):
        """Structure optimizer object.

        atoms: Atoms object
            The Atoms object to relax.
        restart: str
            Filename for restart file.  Default value is *None*.
        logfile: file object or str
            If *logfile* is a string, a file with that name will be opened.
            Use '-' for stdout.
        trajectory: Trajectory object or str
            Attach trajectory object.  If *trajectory* is a string a
            PickleTrajectory will be constructed.  Use *None* for no
            trajectory.
        """
        Dynamics.__init__(self, atoms, logfile, trajectory)
        self.restart = restart

        if restart is None or not isfile(restart):
            self.initialize()
        else:
            self.read()
            barrier()
Exemplo n.º 23
0
    def run(self):
        """Run the total energy calculations for the required displacements.

        This will calculate the forces for 6 displacements per atom, +-x, +-y,
        and +-z. Only those calculations that are not already done will be
        started. Be aware that an interrupted calculation may produce an empty
        file (ending with .pckl), which must be deleted before restarting the
        job. Otherwise the forces will not be calculated for that displacement.

        """

        # Atoms in the supercell -- repeated in the lattice vector directions
        # beginning with the last
        atoms_lmn = self.atoms * self.N_c
        
        # Set calculator if provided
        assert self.calc is not None, "Provide calculator in __init__ method"
        atoms_lmn.set_calculator(self.calc)
        
        # Calculate forces in equilibrium structure
        filename = self.name + '.eq.pckl'
        
        if not isfile(filename):
            # Wait for all ranks to enter
            barrier()
            # Create file
            if rank == 0:
                fd = open(filename, 'w')
                fd.close()

            # Call derived class implementation of __call__
            output = self.__call__(atoms_lmn)
            # Write output to file
            if rank == 0:
                fd = open(filename, 'w')
                pickle.dump(output, fd)
                sys.stdout.write('Writing %s\n' % filename)
                fd.close()
            sys.stdout.flush()

        # Positions of atoms to be displaced in the small unit cell
        pos = self.atoms.positions.copy()
        
        # Loop over all displacements and calculate forces
        for a in self.indices:
            for i in range(3):
                for sign in [-1, 1]:
                    # Filename for atomic displacement
                    filename = '%s.%d%s%s.pckl' % \
                               (self.name, a, 'xyz'[i], ' +-'[sign])
                    # Wait for ranks before checking for file
                    # barrier()                    
                    if isfile(filename):
                        # Skip if already done
                        continue
                    # Wait for ranks
                    barrier()
                    if rank == 0:
                        fd = open(filename, 'w')
                        fd.close()

                    # Update atomic positions and calculate forces
                    atoms_lmn.positions[a, i] = \
                        pos[a, i] + sign * self.delta

                    # Call derived class implementation of __call__
                    output = self.__call__(atoms_lmn)
                    # Write output to file    
                    if rank == 0:
                        fd = open(filename, 'w')
                        pickle.dump(output, fd)
                        sys.stdout.write('Writing %s\n' % filename)
                        fd.close()
                    sys.stdout.flush()
                    # Return to initial positions
                    atoms_lmn.positions[a, i] = pos[a, i]
Exemplo n.º 24
0
    def run(self):
        """Run the calculations for the required displacements.

        This will do a calculation for 6 displacements per atom, +-x, +-y, and
        +-z. Only those calculations that are not already done will be
        started. Be aware that an interrupted calculation may produce an empty
        file (ending with .pckl), which must be deleted before restarting the
        job. Otherwise the calculation for that displacement will not be done.

        """

        # Atoms in the supercell -- repeated in the lattice vector directions
        # beginning with the last
        atoms_N = self.atoms * self.N_c
        
        # Set calculator if provided
        assert self.calc is not None, "Provide calculator in __init__ method"
        atoms_N.set_calculator(self.calc)
        
        # Do calculation on equilibrium structure
        filename = self.name + '.eq.pckl'
        
        if not isfile(filename):
            # Wait for all ranks to enter
            barrier()
            # Create file
            if rank == 0:
                fd = open(filename, 'w')
                fd.close()

            # Call derived class implementation of __call__
            output = self.__call__(atoms_N)
            # Write output to file
            if rank == 0:
                fd = open(filename, 'w')
                pickle.dump(output, fd)
                sys.stdout.write('Writing %s\n' % filename)
                fd.close()
            sys.stdout.flush()

        # Positions of atoms to be displaced in the reference cell
        natoms = len(self.atoms)
        offset = natoms * self.offset
        pos = atoms_N.positions[offset: offset + natoms].copy()
        
        # Loop over all displacements
        for a in self.indices:
            for i in range(3):
                for sign in [-1, 1]:
                    # Filename for atomic displacement
                    filename = '%s.%d%s%s.pckl' % \
                               (self.name, a, 'xyz'[i], ' +-'[sign])
                    # Wait for ranks before checking for file
                    # barrier()                    
                    if isfile(filename):
                        # Skip if already done
                        continue
                    # Wait for ranks
                    barrier()
                    if rank == 0:
                        fd = open(filename, 'w')
                        fd.close()

                    # Update atomic positions
                    atoms_N.positions[offset + a, i] = \
                        pos[a, i] + sign * self.delta
                    
                    # Call derived class implementation of __call__
                    output = self.__call__(atoms_N)
                    # Write output to file    
                    if rank == 0:
                        fd = open(filename, 'w')
                        pickle.dump(output, fd)
                        sys.stdout.write('Writing %s\n' % filename)
                        fd.close()
                    sys.stdout.flush()
                    # Return to initial positions
                    atoms_N.positions[offset + a, i] = pos[a, i]
Exemplo n.º 25
0
 def _open_write(self, atoms, backup, backend):
     "Open a bundle trajectory for writing."
     self._set_backend(backend)
     self.logfile = None  # enable delayed logging
     self.atoms = atoms
     if os.path.exists(self.filename):
         # The output directory already exists.
         barrier()  # all must have time to see it exists
         if not self.is_bundle(self.filename, allowempty=True):
             raise IOError(
                 'Filename "' + self.filename +
                 '" already exists, but is not a BundleTrajectory.' +
                 'Cowardly refusing to remove it.')
         if self.is_empty_bundle(self.filename):
             barrier()
             self.log('Deleting old "%s" as it is empty' %
                      (self.filename, ))
             self.delete_bundle(self.filename)
         elif not backup:
             barrier()
             self.log('Deleting old "%s" as backup is turned off.' %
                      (self.filename, ))
             self.delete_bundle(self.filename)
         else:
             barrier()
             # Make a backup file
             bakname = self.filename + '.bak'
             if os.path.exists(bakname):
                 barrier()  # All must see it exists
                 self.log('Deleting old backup file "%s"' % (bakname, ))
                 self.delete_bundle(bakname)
             self.log('Renaming "%s" to "%s"' % (self.filename, bakname))
             self._rename_bundle(self.filename, bakname)
     # Ready to create a new bundle.
     barrier()
     self.log('Creating new "%s"' % (self.filename, ))
     self._make_bundledir(self.filename)
     self.state = 'prewrite'
     self._write_metadata({})
     self._write_nframes(0)  # Mark new bundle as empty
     self._open_log()
     self.nframes = 0
def main():
    atoms = build.bulk("Al")
    atoms = atoms * (2, 2, 2)
    print(len(atoms))

    nRuns = 10
    optimizerFname = "optimizer.pck"
    for i in range(nRuns):
        nMgAtoms = np.random.randint(0, len(atoms) / 2)

        # Insert Mg atoms
        system = cp.copy(atoms)
        if (parallel.rank == 0):
            for j in range(nMgAtoms):
                system[i].symbol = "Mg"

            # Shuffle the list
            for j in range(10 * len(system)):
                first = np.random.randint(0, len(system))
                second = np.random.randint(0, len(system))
                symb1 = system[first].symbol
                system[first].symbol = system[second].symbol
                system[second].symbol = symb1
        system = parallel.broadcast(system)

        # Initialize the calculator
        calc = gp.GPAW(mode=gp.PW(400), xc="PBE", kpts=(4, 4, 4), nbands=-10)
        system.set_calculator(calc)

        traj = Trajectory("trajectoryResuse.traj", 'w', atoms)

        if (i == 0):
            relaxer = PreconLBFGS(UnitCellFilter(system), logfile="resuse.log")
        else:
            relaxer = None
            relaxParams = None
            if (parallel.rank == 0):
                with open(optimizerFname, 'rb') as infile:
                    relaxParams = pck.load(infile)
            relaxParams = parallel.broadcast(relaxParams)
            precon = Exp(r_cut=relaxParams["r_cut"],
                         r_NN=relaxParams["r_NN"],
                         mu=relaxParams["mu"],
                         mu_c=relaxParams["mu_c"])
            relaxer = PreconLBFGS(UnitCellFilter(system),
                                  logfile="resuse.log",
                                  precon=precon)

        relaxer.attach(traj)

        relaxer.run(fmax=0.05)
        print(relaxer.iteration)
        if (parallel.rank == 0):
            with open(optimizerFname, 'wb') as outfile:
                relaxParams = {
                    "r_cut": relaxer.precon.r_cut,
                    "r_NN": relaxer.precon.r_NN,
                    "mu": relaxer.precon.mu,
                    "mu_c": relaxer.precon.mu_c
                }
                pck.dump(relaxParams, outfile, pck.HIGHEST_PROTOCOL)
        parallel.barrier()
Exemplo n.º 27
0
for ending in endings:
    restart = 'gpaw-restart.' + ending
    restart_wf = 'gpaw-restart-wf.' + ending
    # H2
    H = Atoms([Atom('H', (0, 0, 0)), Atom('H', (0, 0, 1))])
    H.center(vacuum=2.0)

    wfdir = 'wfs_tmp'
    mode = ending + ':' + wfdir + '/psit_s%dk%dn%d'

    if 1:
        calc = GPAW(nbands=2, convergence={'eigenstates': 1e-3})
        H.set_calculator(calc)
        H.get_potential_energy()
        barrier()
        calc.write(restart_wf, 'all')
        calc.write(restart, mode)
        barrier()

    # refine the restart file containing the wfs
    E1 = GPAW(restart_wf, convergence={
        'eigenstates': 1.e-5
    }).get_atoms().get_potential_energy()

    # refine the restart file and separate wfs
    calc = GPAW(restart, convergence={'eigenstates': 1.e-5})
    calc.read_wave_functions(mode)
    E2 = calc.get_atoms().get_potential_energy()

    print E1, E2
Exemplo n.º 28
0
def read_atat_input(filename='str.out',
                    pbc=(1, 1, 1),
                    verbosity=0,
                    minimize_tilt=False,
                    niggli_reduce=False):
    """ Reads an ATAT structure file (str.out) and returns the
    corresponding ASE Atoms object """
    if verbosity > 1:
        parprint("read_atat_input called with options:\n\t filename: {}\n"
                 "\t pbc: {} \n\t verbosity: {} \n\t minimize_tilt: {}\n"
                 "\t niggli_reduce: {}".format(filename, pbc, verbosity,
                                               minimize_tilt, niggli_reduce))
    ifile = open(filename, 'rb')
    # Read coordinate system
    cs = np.zeros((3, 3), dtype=float)
    l1 = ifile.readline()
    items = [float(i) for i in l1.split()]
    if len(items) == 3:
        cs[0, :] = np.array(items)
        cs[1, :] = np.array(ifile.readline().split())
        cs[2, :] = np.array(ifile.readline().split())
    else:
        # print("WARNING: [a, b, c, alpha, beta, gamma] format" +
        #       " not well tested")
        a, b, c, alpha, beta, gamma = items
        alpha, beta, gamma = [
            angle * np.pi / 180. for angle in [alpha, beta, gamma]
        ]
        (ca, sa) = (math.cos(alpha), math.sin(alpha))
        (cb, sb) = (math.cos(beta), math.sin(beta))
        (cg, sg) = (math.cos(gamma), math.sin(gamma))
        # v_unit is a volume of unit cell with a=b=c=1
        v_unit = math.sqrt(1.0 + 2.0 * ca * cb * cg - ca * ca - cb * cb -
                           cg * cg)
        # from the reciprocal lattice
        ar = sa / (a * v_unit)
        cgr = (ca * cb - cg) / (sa * sb)
        sgr = math.sqrt(1.0 - cgr**2)
        cs[0, :] = np.array([1.0 / ar, -cgr / sgr / ar, cb * a])
        cs[1, :] = np.array([0.0, b * sa, b * ca])
        cs[2, :] = np.array([0.0, 0.0, c])

    if verbosity > 0:
        parprint("Coordinate system:\n {}".format(cs))

    # Read unit cell
    cell = np.zeros((3, 3), dtype=float)
    for i in range(3):
        cell[i, :] = np.array(ifile.readline().split())
    if verbosity > 1:
        parprint("Initial cell:\n {}".format(cell))

    cell = np.dot(cell, cs)
    if verbosity > 0:
        parprint("Cell:\n {}".format(cell))
        parprint("Cell volume: {}".format(np.linalg.det(cell)))

    # Read atoms positions
    rest = ifile.readlines()
    ifile.close()
    positions = []
    atom_symbols = []
    for line in rest:
        split = line.split()
        positions.append(np.dot(np.array(split[:3], dtype=float), cs))
        atom_symbols.append(split[3])

    if verbosity > 0:
        parprint("Positions:\n {}".format(positions))

    # Create atoms object
    atoms = Atoms(symbols=atom_symbols,
                  positions=positions,
                  cell=cell,
                  pbc=pbc)

    # Modify cell to the maximally-reduced Niggli unit cell or minimize tilt
    #    angle between cell axes. Niggli takes precedence.
    if niggli_reduce:
        ase.build.niggli_reduce(atoms)
        if verbosity > 0:
            parprint("Niggli cell:\n {}".format(atoms.get_cell()))
            parprint("N. cell volume: {}".format(
                np.linalg.det(atoms.get_cell())))
        write_atat_input(atoms, filename='str_niggli.out')
        barrier()
        if rank == 0:
            if not os.path.isfile('str_atat.out'):
                copyfile('str.out', 'str_atat.out')
            copyfile('str_niggli.out', 'str.out')
        barrier()
    elif minimize_tilt:
        ase.build.minimize_tilt(atoms)
        if verbosity > 0:
            parprint("Minimum tilt cell:\n {}".format(atoms.cell))
            parprint("M. T. cell volume: {}".format(np.linalg.det(atoms.cell)))
        write_atat_input(atoms, filename='str_mintilt.out')
        barrier()
        if rank == 0:
            if not os.path.isfile('str_atat.out'):
                copyfile('str.out', 'str_atat.out')
            copyfile('str_mintilt.out', 'str.out')
        barrier()

    return atoms
Exemplo n.º 29
0
    def run(self):
        if not isfile(self.name + '.eq.pckl'):

            self.calc.calculate(self.atoms)
            Vt_G = self.calc.get_effective_potential(pad=False)
            Vt_G = self.calc.wfs.gd.collect(Vt_G, broadcast=True) / Hartree
            dH_asp = self.calc.hamiltonian.dH_asp
            setups = self.calc.wfs.setups
            nspins = self.calc.wfs.nspins
            gd_comm = self.calc.wfs.gd.comm

            alldH_asp = {}
            for a, setup in enumerate(setups):
                ni = setup.ni
                nii = ni * (ni + 1) // 2
                tmpdH_sp = np.zeros((nspins, nii))
                if a in dH_asp:
                    tmpdH_sp[:] = dH_asp[a]
                gd_comm.sum(tmpdH_sp)
                alldH_asp[a] = tmpdH_sp

            forces = self.atoms.get_forces()
            self.calc.write('eq.gpw')

            barrier()
            if rank == 0:
                vd = open(self.name + '.eq.pckl', 'wb')
                fd = open('vib.eq.pckl', 'wb')
                pickle.dump((Vt_G, alldH_asp), vd, 2)
                pickle.dump(forces, fd)
                vd.close()
                fd.close()
            barrier()

        p = self.atoms.positions.copy()
        for a in self.indices:
            for j in range(3):
                for sign in [-1, 1]:
                    for ndis in range(1, self.nfree / 2 + 1):
                        name = '.%d%s%s.pckl' % (a, 'xyz'[j],
                                                 ndis * ' +-'[sign])
                        if isfile(self.name + name):
                            continue
                        self.atoms.positions[
                            a, j] = p[a, j] + sign * ndis * self.delta
                        self.calc.calculate(self.atoms)
                        Vt_G = self.calc.get_effective_potential(pad=False)
                        Vt_G = self.calc.wfs.gd.collect(
                            Vt_G, broadcast=True) / Hartree
                        dH_asp = self.calc.hamiltonian.dH_asp

                        alldH_asp = {}
                        for a2, setup in enumerate(setups):
                            ni = setup.ni
                            nii = ni * (ni + 1) // 2
                            tmpdH_sp = np.zeros((nspins, nii))
                            if a2 in dH_asp:
                                tmpdH_sp[:] = dH_asp[a2]
                            gd_comm.sum(tmpdH_sp)
                            alldH_asp[a2] = tmpdH_sp

                        forces = self.atoms.get_forces()
                        barrier()
                        if rank == 0:
                            vd = open(self.name + name, 'wb')
                            fd = open('vib' + name, 'wb')
                            pickle.dump((Vt_G, alldH_asp), vd)
                            pickle.dump(forces, fd)
                            vd.close()
                            fd.close()
                        barrier()
                        self.atoms.positions[a, j] = p[a, j]
        self.atoms.set_positions(p)
Exemplo n.º 30
0
def get_bader_charges(atoms,
                      calc,
                      charge_source="all-electron",
                      gridrefinement=4):
    """This function uses an external Bader charge calculator from
        http://theory.cm.utexas.edu/henkelman/code/bader/. This tool is
        provided also in pysic/tools. Before using this function the bader
        executable directory has to be added to PATH.

        Parameters:
            atoms: ASE Atoms
                The structure from which we want to calculate the charges from.
            calc: ASE calculator
            charge_source: string
                Indicates the electron density that is used in charge calculation.
                Can be "pseudo" or "all-electron".
            gridrefinement: int
                The factor by which the calculation grid is densified in charge
                calculation.

        Returns: numpy array of the atomic charges
        """
    # First check that the bader executable is in PATH
    if spawn.find_executable("bader") is None:
        error((
            "Cannot find the \"bader\" executable in PATH. The bader "
            "executable is provided in the pysic/tools folder, or it can be "
            "downloaded from http://theory.cm.utexas.edu/henkelman/code/bader/. "
            "Ensure that the executable is named \"bader\", place it in any "
            "directory you want and then add that directory to your system"
            "PATH."))

    atoms_copy = atoms.copy()
    calc.set_atoms(atoms_copy)

    if charge_source == "pseudo":
        try:
            density = np.array(calc.get_pseudo_density())
        except AttributeError:
            error("The calculator doesn't provide pseudo density.")

    if charge_source == "all-electron":
        try:
            density = np.array(
                calc.get_all_electron_density(gridrefinement=gridrefinement))
        except AttributeError:
            error("The calculator doesn't provide all electron density.")

    wrk_dir = os.getcwd() + "/.BADERTEMP"
    dir_created = False

    # Write the density in bader supported units and format
    if rank == 0:

        # Create temporary folder for calculations
        if not os.path.exists(wrk_dir):
            os.makedirs(wrk_dir)
            dir_created = True
        else:
            error(
                "Tried to create a temporary folder in " + wrk_dir +
                ", but the folder already existed. Please remove it manually first."
            )

        rho = density * Bohr**3
        write(wrk_dir + '/electron_density.cube', atoms, data=rho)

        # Run the bader executable in terminal. The bader executable included
        # int pysic/tools has to be in the PATH/PYTHONPATH
        command = "cd " + wrk_dir + "; bader electron_density.cube"
        subprocess.check_output(command, shell=True)
        #os.system("gnome-terminal --disable-factory -e '"+command+"'")

    # Wait for the main process to write the file
    barrier()

    # ASE provides an existing function for attaching the charges to the
    # atoms (safe because using a copy). Although we don't want to actually
    # attach the charges to anything, we use this function and extract the
    # charges later.
    bader.attach_charges(atoms_copy, wrk_dir + "/ACF.dat")

    # The call for charges was changed between
    # ASE 3.6 and 3.7
    try:
        bader_charges = np.array(atoms_copy.get_initial_charges())
    except:
        bader_charges = np.array(atoms_copy.get_charges())

    # Remove the temporary files
    if rank == 0:
        if dir_created:
            shutil.rmtree(wrk_dir)

    return bader_charges
Exemplo n.º 31
0
    def run(self):
        """Run the vibration calculations.

        This will calculate the forces for 6 displacements per atom ±x, ±y, ±z.
        Only those calculations that are not already done will be started. Be
        aware that an interrupted calculation may produce an empty file (ending
        with .pckl), which must be deleted before restarting the job. Otherwise
        the forces will not be calculated for that displacement.

        Note that the calculations for the different displacements can be done
        simultaneously by several independent processes. This feature relies on
        the existence of files and the subsequent creation of the file in case
        it is not found.

        """
        
        filename = self.name + '.eq.pckl'
        if not isfile(filename):
            barrier()
            if rank == 0:
                fd = open(filename, 'w')            
            forces = self.atoms.get_forces()
            if self.ir:
                dipole = self.calc.get_dipole_moment(self.atoms)
            if rank == 0:
                if self.ir:
                    pickle.dump([forces, dipole], fd)
                    sys.stdout.write(
                        'Writing %s, dipole moment = (%.6f %.6f %.6f)\n' % 
                        (filename, dipole[0], dipole[1], dipole[2]))
                else:
                    pickle.dump(forces, fd)
                    sys.stdout.write('Writing %s\n' % filename)
                fd.close()
            sys.stdout.flush()
        
        p = self.atoms.positions.copy()
        for a in self.indices:
            for i in range(3):
                for sign in [-1, 1]:
                    for ndis in range(1, self.nfree//2+1):
                        filename = ('%s.%d%s%s.pckl' %
                                    (self.name, a, 'xyz'[i], ndis*' +-'[sign]))
                        if isfile(filename):
                            continue
                        barrier()
                        if rank == 0:
                            fd = open(filename, 'w')                        
                        self.atoms.positions[a, i] = (p[a, i] +
                                                      ndis * sign * self.delta)
                        forces = self.atoms.get_forces()
                        if self.ir:
                            dipole = self.calc.get_dipole_moment(self.atoms)
                        if rank == 0:
                            if self.ir:
                                pickle.dump([forces, dipole], fd)
                                sys.stdout.write(
                                    'Writing %s, ' % filename +
                                    'dipole moment = (%.6f %.6f %.6f)\n' % 
                                    (dipole[0], dipole[1], dipole[2]))
                            else:
                                pickle.dump(forces, fd)
                                sys.stdout.write('Writing %s\n' % filename)
                            fd.close()
                        sys.stdout.flush()
                        self.atoms.positions[a, i] = p[a, i]
        self.atoms.set_positions(p)
Exemplo n.º 32
0
    def run_vdw(self, nonsc_calculation=None):
        """Starts the vdW calculation.

        The method runs only if the pickle corresponding pickle
        file does not exist.

        The vdw_nonsc program is executed in the directory set
        by the environmental variable VDW_PATH where the kernel
        and other data files must exist."""

        if os.path.isfile('%s.pckl' % self.name):
            return
        self.prepare(nonsc_calculation)
        sys.stdout.write('Running non self-consistent vdW-DF calculation... ')
        sys.stdout.flush()
        barrier()
        path = os.path.abspath('.')
        fd = open(path + '/%s.pckl' % self.name, 'w')
        data = pickle.load(open('%s_no-vdw.pckl' % self.name, 'r'))[0]
        E_dft = data['E_dft']
        # Change path to where the vdw data files are
        os.chdir(self.vdw_path)
        # Execute vdw vdw_nonsc program
        tmp_name = path + '/%s' % self.name
        exitcode = os.system('%s %s.atoms.inp %s.chargeden > %s.vdw.out' %
                             (self.vdw_nonsc, tmp_name, tmp_name, tmp_name))
        os.chdir(path)
        if exitcode != 0:
            raise RuntimeError('vdw_nonsc exited with exit code: %d.  ' %
                               exitcode)
        barrier()
        sys.stdout.flush()
        # Extract and pickle the output
        if rank == 0:
            [E_LDAc, E_LDAx, E_PBEc, E_PBEx, E_revPBEx, E_nl] = self.extract()
            pickle.dump([{
                'E_dft': E_dft,
                'E_2': data['E_2'],
                'E_LDA-c': E_LDAc,
                'E_LDA-x': E_LDAx,
                'E_PBE-c': E_PBEc,
                'E_PBE-x': E_PBEx,
                'E_revPBE-x': E_revPBEx,
                'E_nl': E_nl,
                'E_vdW': E_dft - E_PBEc + E_LDAc + E_nl,
                'atoms': data['atoms'],
            }], fd)
            fd.close()
            # Delete input files
            self.clean()

        sys.stdout.write('Done!\n\n')
        self.tf = int(time.time())
        print '================================================================================'
        print 'Finished vdW-DF calculation \'%s\' on %s.\n' % (self.name,
                                                               time.ctime())
        print 'Timings:\n'
        print 'Self-consistent DFT calculation:        %3d hours %2d minutes %2d seconds' % \
            ((self.t2-self.t1)/3600, ((self.t2-self.t1)/60)%60, (self.t2-self.t1)%60)
        if self.nonsc_calculation:
            print 'Non self-consistent DFT calculation:    %3d hours %2d minutes %2d seconds' % \
                ((self.t_nonsc-self.t2)/3600, ((self.t_nonsc-self.t2)/60)%60, (self.t_nonsc-self.t2)%60)
            self.t2 = self.t_nonsc
        print 'Converting charge density:              %3d hours %2d minutes %2d seconds' % \
            ((self.t3-self.t2)/3600, ((self.t3-self.t2)/60)%60, (self.t3-self.t2)%60)
        print 'Non-self-consistent vdW-DF calculation: %3d hours %2d minutes %2d seconds' % \
            ((self.tf-self.t3)/3600, ((self.tf-self.t2)/60)%60, (self.tf-self.t3)%60)
        print '---------------------------------------------------------------------------'
        print 'Total time: %3d hours %2d minutes %2d seconds' % (
            (self.tf - self.t1) / 3600, ((self.tf - self.t1) / 60) % 60,
            (self.tf - self.t1) % 60)
        print '================================================================================\n'
        return
Exemplo n.º 33
0
txt=None

print '--- Comparing LB94 with', ref1
print 'and', ref2

print '**** all electron calculations'
print 'atom [refs] -e_homo diff   all in mHa'
if rank == 0:
    for atom in e_HOMO_cs.keys():
        ae = AllElectron(atom, 'LB94', txt=txt)
        ae.run()
        e_homo = int( ae.e_j[-1] * 10000 + .5 ) / 10.
        diff = e_HOMO_cs[atom] + e_homo
        print '%2s %8g %6.1f %4.1g' % (atom, e_HOMO_cs[atom], -e_homo, diff)
        assert abs(diff) < 6
barrier()

setup_paths.insert(0, '.')
setups = {}

print '**** 3D calculations'
print 'atom [refs] -e_homo diff   all in mHa'

for atom in e_HOMO_cs.keys():
    e_ref = e_HOMO_cs[atom]
    # generate setup for the atom
    if rank == 0 and not setups.has_key(atom):
        g = Generator(atom, 'LB94', nofiles=True, txt=txt)
        g.run(**parameters[atom])
        setups[atom] = 1
    barrier()
Exemplo n.º 34
0
def get_bader_charges(atoms, calc, charge_source="all-electron", gridrefinement=4):
        """This function uses an external Bader charge calculator from
        http://theory.cm.utexas.edu/henkelman/code/bader/. This tool is
        provided also in pysic/tools. Before using this function the bader
        executable directory has to be added to PATH.

        Parameters:
            atoms: ASE Atoms
                The structure from which we want to calculate the charges from.
            calc: ASE calculator
            charge_source: string
                Indicates the electron density that is used in charge calculation.
                Can be "pseudo" or "all-electron".
            gridrefinement: int
                The factor by which the calculation grid is densified in charge
                calculation.

        Returns: numpy array of the atomic charges
        """
        # First check that the bader executable is in PATH
        if spawn.find_executable("bader") is None:
            error((
                "Cannot find the \"bader\" executable in PATH. The bader "
                "executable is provided in the pysic/tools folder, or it can be "
                "downloaded from http://theory.cm.utexas.edu/henkelman/code/bader/. "
                "Ensure that the executable is named \"bader\", place it in any "
                "directory you want and then add that directory to your system"
                "PATH."))

        atoms_copy = atoms.copy()
        calc.set_atoms(atoms_copy)

        if charge_source == "pseudo":
            try:
                density = np.array(calc.get_pseudo_density())
            except AttributeError:
                error("The calculator doesn't provide pseudo density.")

        if charge_source == "all-electron":
            try:
                density = np.array(calc.get_all_electron_density(gridrefinement=gridrefinement))
            except AttributeError:
                error("The calculator doesn't provide all electron density.")

        wrk_dir = os.getcwd()+"/.BADERTEMP"
        dir_created = False

        # Write the density in bader supported units and format
        if rank == 0:

            # Create temporary folder for calculations
            if not os.path.exists(wrk_dir):
                os.makedirs(wrk_dir)
                dir_created = True
            else:
                error("Tried to create a temporary folder in " + wrk_dir + ", but the folder already existed. Please remove it manually first.")

            rho = density * Bohr**3
            write(wrk_dir + '/electron_density.cube', atoms, data=rho)

            # Run the bader executable in terminal. The bader executable included
            # int pysic/tools has to be in the PATH/PYTHONPATH
            command = "cd " + wrk_dir + "; bader electron_density.cube"
            subprocess.check_output(command, shell=True)
            #os.system("gnome-terminal --disable-factory -e '"+command+"'")

        # Wait for the main process to write the file
        barrier()

        # ASE provides an existing function for attaching the charges to the
        # atoms (safe because using a copy). Although we don't want to actually
        # attach the charges to anything, we use this function and extract the
        # charges later.
        bader.attach_charges(atoms_copy, wrk_dir + "/ACF.dat")

        # The call for charges was changed between
        # ASE 3.6 and 3.7
        try:
            bader_charges = np.array(atoms_copy.get_initial_charges())
        except:
            bader_charges = np.array(atoms_copy.get_charges())

        # Remove the temporary files
        if rank == 0:
            if dir_created:
                shutil.rmtree(wrk_dir)

        return bader_charges
Exemplo n.º 35
0
    def run(self):
        if not isfile(self.name + '.eq.pckl'):
            
            self.calc.calculate(self.atoms)
            Vt_G = self.calc.get_effective_potential(pad=False)
            Vt_G = self.calc.wfs.gd.collect(Vt_G, broadcast=True) / Hartree
            dH_asp = self.calc.hamiltonian.dH_asp
            setups = self.calc.wfs.setups
            nspins = self.calc.wfs.nspins
            gd_comm = self.calc.wfs.gd.comm


            alldH_asp = {}
            for a, setup in enumerate(setups):
                ni = setup.ni
                nii = ni * (ni + 1) // 2
                tmpdH_sp = np.zeros((nspins, nii))
                if a in dH_asp:
                    tmpdH_sp[:] = dH_asp[a]
                gd_comm.sum(tmpdH_sp)
                alldH_asp[a] = tmpdH_sp
                
            forces = self.atoms.get_forces()
            self.calc.write('eq.gpw')

            barrier()
            if rank == 0:
                vd = open(self.name + '.eq.pckl', 'wb')
                fd = open('vib.eq.pckl','wb')
                pickle.dump((Vt_G, alldH_asp), vd,2)
                pickle.dump(forces,fd)
                vd.close()
                fd.close()
            barrier()

        p = self.atoms.positions.copy()
        for a in self.indices:
            for j in range(3):
                for sign in [-1,1]:
                    for ndis in range(1,self.nfree/2+1):       
                        name = '.%d%s%s.pckl' % (a, 'xyz'[j], ndis * ' +-'[sign])
                        if isfile(self.name + name):
                            continue
                        self.atoms.positions[a, j] = p[a, j] + sign * ndis * self.delta
                        self.calc.calculate(self.atoms)
                        Vt_G = self.calc.get_effective_potential(pad=False)
                        Vt_G =self.calc.wfs.gd.collect(Vt_G, broadcast=True) / Hartree
                        dH_asp = self.calc.hamiltonian.dH_asp

                        alldH_asp = {}
                        for a2, setup in enumerate(setups):
                            ni = setup.ni
                            nii = ni * (ni + 1) // 2
                            tmpdH_sp = np.zeros((nspins, nii))
                            if a2 in dH_asp:
                                tmpdH_sp[:] = dH_asp[a2]
                            gd_comm.sum(tmpdH_sp)
                            alldH_asp[a2] = tmpdH_sp

                        forces = self.atoms.get_forces()
                        barrier()
                        if rank == 0:
                            vd = open(self.name + name , 'w')
                            fd = open('vib' + name, 'w')
                            pickle.dump((Vt_G, alldH_asp), vd)
                            pickle.dump(forces, fd)
                            vd.close()
                            fd.close()
                        barrier()
                        self.atoms.positions[a, j] = p[a, j]
        self.atoms.set_positions(p)
Exemplo n.º 36
0
    def run_vdw(self, nonsc_calculation=None):
        """Starts the vdW calculation.

        The method runs only if the pickle corresponding pickle
        file does not exist.

        The vdw_nonsc program is executed in the directory set
        by the environmental variable VDW_PATH where the kernel
        and other data files must exist."""

        if os.path.isfile('%s.pckl' % self.name):
            return
        self.prepare(nonsc_calculation)
        sys.stdout.write('Running non self-consistent vdW-DF calculation... ')
        sys.stdout.flush()
        barrier()
        path = os.path.abspath('.')
        fd = open(path + '/%s.pckl' % self.name, 'w')
        data = pickle.load(open('%s_no-vdw.pckl' % self.name, 'r'))[0]
        E_dft = data['E_dft']        
        # Change path to where the vdw data files are
        os.chdir(self.vdw_path)
        # Execute vdw vdw_nonsc program
        tmp_name = path + '/%s' % self.name
        exitcode = os.system('%s %s.atoms.inp %s.chargeden > %s.vdw.out' % (self.vdw_nonsc, tmp_name, tmp_name, tmp_name))
        os.chdir(path)
        if exitcode != 0:
            raise RuntimeError('vdw_nonsc exited with exit code: %d.  ' % exitcode)
        barrier()
        sys.stdout.flush()
        # Extract and pickle the output
        if rank == 0:
            [E_LDAc, E_LDAx, E_PBEc, E_PBEx, E_revPBEx, E_nl] = self.extract()
            pickle.dump([{'E_dft': E_dft,
                          'E_2': data['E_2'],
                          'E_LDA-c': E_LDAc,
                          'E_LDA-x': E_LDAx,
                          'E_PBE-c': E_PBEc,
                          'E_PBE-x': E_PBEx,
                          'E_revPBE-x': E_revPBEx,
                          'E_nl': E_nl,
                          'E_vdW': E_dft-E_PBEc+E_LDAc+E_nl,
                          'atoms': data['atoms'],
                          }],
                        fd)
            fd.close()
            # Delete input files
            self.clean()

        sys.stdout.write('Done!\n\n')
        self.tf = int(time.time())
        print '================================================================================'
        print 'Finished vdW-DF calculation \'%s\' on %s.\n' % (self.name, time.ctime())
        print 'Timings:\n'
        print 'Self-consistent DFT calculation:        %3d hours %2d minutes %2d seconds' % \
            ((self.t2-self.t1)/3600, ((self.t2-self.t1)/60)%60, (self.t2-self.t1)%60)
        if self.nonsc_calculation:
            print 'Non self-consistent DFT calculation:    %3d hours %2d minutes %2d seconds' % \
                ((self.t_nonsc-self.t2)/3600, ((self.t_nonsc-self.t2)/60)%60, (self.t_nonsc-self.t2)%60)
            self.t2 = self.t_nonsc
        print 'Converting charge density:              %3d hours %2d minutes %2d seconds' % \
            ((self.t3-self.t2)/3600, ((self.t3-self.t2)/60)%60, (self.t3-self.t2)%60)
        print 'Non-self-consistent vdW-DF calculation: %3d hours %2d minutes %2d seconds' % \
            ((self.tf-self.t3)/3600, ((self.tf-self.t2)/60)%60, (self.tf-self.t3)%60)
        print '---------------------------------------------------------------------------'
        print 'Total time: %3d hours %2d minutes %2d seconds' % ((self.tf-self.t1)/3600, ((self.tf-self.t1)/60)%60, (self.tf-self.t1)%60)
        print '================================================================================\n'
        return