Exemple #1
0
def test_bader():
    import os
    from ase.build import molecule
    from ase.io.bader import attach_charges

    fname = 'ACF.dat'
    f = open(fname, 'w')
    print("""
       #         X           Y           Z        CHARGE     MIN DIST
     ----------------------------------------------------------------
       1      7.0865      8.5038      9.0672      9.0852      1.3250
       2      7.0865      9.9461      7.9403      0.4574      0.3159
       3      7.0865      7.0615      7.9403      0.4574      0.3159
     ----------------------------------------------------------------
      NUMBER OF ELECTRONS:        9.99999
    """,
          file=f)
    f.close()

    atoms = molecule('H2O')
    atoms.set_cell([7.5, 9, 9])
    atoms.center()

    attach_charges(atoms)
    attach_charges(atoms, fname)
    os.remove(fname)

    for atom in atoms:
        print('Atom', atom.symbol, 'Bader charge', atom.charge)

    # O is negatively charged
    assert (atoms[0].charge < -1 and atoms[0].charge > -2)
Exemple #2
0
def print_bader(dir_path = '.', atoms_file = 'CONTCAR'):
    #Prints the bader charges using the atoms_file (usually CONTCAR) and ACF.dat
    atoms = read('%s/%s' % (dir_path, atoms_file))
    attach_charges(atoms, '%s/ACF.dat' % dir_path)
    buf = []    
    print "i\tSymbol\tCharge\tx\ty\tz"
    print "-"*30
    for atom in atoms:
        print "%d\t%s\t%f\t%f\t%f\t%f" % (atom.index, atom.symbol, atom.charge, atom.x, atom.y, atom.z)
        buf = buf.append((atom.index, atom.symbol, atom.charge, atom.x, atom.y, atom.z))        
    dtype = [('i', int), ('symbol', str) ('x', float), ('y', float), ('z', float)]
    data = np.array(buf, dtype = dtype)
    return data
Exemple #3
0
 def get_bader_charge(self, inpfile=None):
     '''
     '''
     from ase.io.bader import attach_charges
     if not inpfile:
         inpfile = '%s.cube' % self.prefix
     command = 'bader %s' % inpfile
     print(command)
     try:
         proc = subprocess.Popen(command, shell=True, cwd=self.directory)
     except OSError as err:
         msg = 'Failed to execute "{}"'.format(command)
         raise EnvironmentError(msg) from err
     acf = os.path.join(self.directory, 'ACF.dat')
     attach_charges(self.results['atoms'], acf)
Exemple #4
0
def compare_bader(dir1, dir2):
    #Uses the CONTCARs located in dir1 and dir2 and takes the difference between the two charges
    atoms1 = read('%s/CONTCAR' % dir1)
    attach_charges(atoms1, '%s/ACF.dat' % dir1)
    atoms2 = read('%s/CONTCAR' % dir2)
    attach_charges(atoms2, '%s/ACF.dat' % dir2)
    max_len = max([len(atoms1, atoms2)])

    len1 = len(atom1)
    len2 = len(atom2)

    if len1 >= len2:
        print("Using properties of atom1.")
        max_len = len1
        atoms_long = atoms1
        atoms_short = atoms2
    else:
        print("Using properties of atom2 since it is longer.")
        max_len = len2
        atoms_long = atoms2
        atoms_short = atoms1

    print("i\tSymbol\tCharge 1\t Charge 2\t ΔCharge")
    for i in range(max_len):
        try:
            atom_short = atoms_short[i]
        except IndexError:
            print(("%d\t%s\t%f\t%f\t%f" %
                   (atom1.index, atom1.symbol, atom1.charge, atom2.charge,
                    atom2.charge - atom1.charge)))
        else:
            print(("%d\t%s\t%f\t%f\t%f" %
                   (atom1.index, atom1.symbol, atom1.charge, atom2.charge,
                    atom2.charge - atom1.charge)))
        buf = buf.append((atom1.index, atom1.symbol, atom1.charge, atom1.x,
                          atom1.y, atom1.z))
        if atom1.symbol != atom2.symbol:
            print("Symbol mismatch!")
    dtype = [('i', int), ('symbol', str)('x', float), ('y', float),
             ('z', float)]
    data = np.array(buf, dtype=dtype)
    return data
Exemple #5
0
def test_bader():
    fname = 'ACF.dat'
    Path(fname).write_text("""
       #         X           Y           Z        CHARGE     MIN DIST
     ----------------------------------------------------------------
       1      7.0865      8.5038      9.0672      9.0852      1.3250
       2      7.0865      9.9461      7.9403      0.4574      0.3159
       3      7.0865      7.0615      7.9403      0.4574      0.3159
     ----------------------------------------------------------------
      NUMBER OF ELECTRONS:        9.99999
    """)

    atoms = molecule('H2O')
    atoms.set_cell([7.5, 9, 9])
    atoms.center()

    attach_charges(atoms)
    attach_charges(atoms, fname)

    for atom in atoms:
        print('Atom', atom.symbol, 'Bader charge', atom.charge)

    # O is negatively charged
    assert (atoms[0].charge < -1 and atoms[0].charge > -2)
Exemple #6
0
    sx, sy, sz = a.cell.diagonal()
    a.set_cell([[sx, 0, 0], [0, sy, 0], [dx, dy, sz]], scale_atoms=False)

if opt.cell is not None:
    cell = map(float, opt.cell.split(','))
    a.set_cell(cell)

if opt.cellfn is not None:
    io.read_cyc(a, opt.cellfn)

if opt.center is not None:
    if opt.center:
        a.center()

if opt.acf is not None:
    attach_charges(a, opt.acf)

if convlen is not None:
    a.set_cell(a.get_cell() * convlen, scale_atoms=True)

if opt.wrap_to_cell:
    a.set_scaled_positions(a.get_scaled_positions())

if opt.clear_velocities:
    a.set_momenta(None)

if opt.supercell is not None:
    supercell = map(int, opt.supercell.split(','))
    a *= supercell

d = {}
Exemple #7
0
from ase.build import molecule
from ase.io.bader import attach_charges

fname = 'ACF.dat'
f = open(fname, 'w')
print("""
   #         X           Y           Z        CHARGE     MIN DIST
 ----------------------------------------------------------------
   1      7.0865      8.5038      9.0672      9.0852      1.3250
   2      7.0865      9.9461      7.9403      0.4574      0.3159
   3      7.0865      7.0615      7.9403      0.4574      0.3159
 ----------------------------------------------------------------
  NUMBER OF ELECTRONS:        9.99999
""",
      file=f)
f.close()

atoms = molecule('H2O')
atoms.set_cell([7.5, 9, 9])
atoms.center()

attach_charges(atoms)
attach_charges(atoms, fname)
os.remove(fname)

for atom in atoms:
    print('Atom', atom.symbol, 'Bader charge', atom.charge)

# O is negatively charged
assert (atoms[0].charge < -1 and atoms[0].charge > -2)
Exemple #8
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
Exemple #9
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
Exemple #10
0
from __future__ import print_function
import os
from ase.structure import molecule
from ase.io.bader import attach_charges

fname = 'ACF.dat'
f = open(fname, 'w')
print("""
   #         X           Y           Z        CHARGE     MIN DIST
 ----------------------------------------------------------------
   1      7.0865      8.5038      9.0672      9.0852      1.3250
   2      7.0865      9.9461      7.9403      0.4574      0.3159
   3      7.0865      7.0615      7.9403      0.4574      0.3159
 ----------------------------------------------------------------
  NUMBER OF ELECTRONS:        9.99999
""", file=f)
f.close()

atoms = molecule('H2O')
atoms.set_cell([7.5, 9, 9])
atoms.center()

attach_charges(atoms)
attach_charges(atoms, fname)
os.remove(fname)

for atom in atoms:
    print('Atom', atom.symbol, 'Bader charge', atom.charge) 

Exemple #11
0
    sx, sy, sz = a.cell.diagonal()
    a.set_cell([[sx,0,0],[0,sy,0],[dx,dy,sz]], scale_atoms=False)
    
if opt.cell is not None:
    cell = map(float, opt.cell.split(','))
    a.set_cell(cell)

if opt.cellfn is not None:
    io.read_cyc(a, opt.cellfn)

if opt.center is not None:
    if opt.center:
        a.center()

if opt.acf is not None:
    attach_charges(a, opt.acf)

if convlen is not None:
    a.set_cell(a.get_cell()*convlen, scale_atoms=True)

if opt.wrap_to_cell:
    a.set_scaled_positions(a.get_scaled_positions())

if opt.clear_velocities:
    a.set_momenta(None)

if opt.supercell is not None:
    supercell  = map(int, opt.supercell.split(','))
    a *= supercell

d = { }
Exemple #12
0
from jasp import *
from ase.io.bader import attach_charges
from ase.units import Bohr

with jasp("molecules/h2o-bader") as calc:
    atoms = calc.get_atoms()
    symbols = np.array(atoms.get_chemical_symbols())[calc.sort]
    pos = atoms.positions[calc.sort] * Bohr
    newatoms = Atoms(symbols, positions=pos, cell=atoms.get_cell())
    attach_charges(newatoms, "ACF.dat")
    print("#+tblname: bader")
    print("#+caption: Bader charges for a water molecule")
    print("| atom | Bader charge|")
    print("|-")
    for atom in newatoms:
        print("|{0} | {1} |".format(atom.symbol, atom.charge))
Exemple #13
0
'''
import os
from ase.io import read
from ase.io.bader import attach_charges
from glob import glob

try:
    a = read(glob('*.STRUCT_OUT')[0])
except IndexError:
    try:
        a = read(glob('siesta.XSF')[0])
    except IndexError:
        print('need either STRUCT_OUT or siesta.XSF from xv2xsf script!')
        exit()

attach_charges(a, displacement=0.1)

elms = [x for x in os.listdir() if x.endswith('psf')]
elm = []
chg = []
for i in elms:
    with open(i) as f:
        t = 0
        for line in f:
            if t == 0:
                elm.append(line.split()[0])
            elif t == 3:
                chg.append(line.split()[-1])
            elif t > 3:
                break
            t += 1
Exemple #14
0
from jasp import *
from ase.io.bader import attach_charges
from ase.units import Bohr
with jasp('molecules/h2o-bader') as calc:
    atoms = calc.get_atoms()
    symbols = np.array(atoms.get_chemical_symbols())[calc.sort]
    pos = atoms.positions[calc.sort] * Bohr
    newatoms = Atoms(symbols, positions=pos, cell=atoms.get_cell())
    attach_charges(newatoms, 'ACF.dat')
    print '#+tblname: bader'
    print '#+caption: Bader charges for a water molecule'
    print '| atom | Bader charge|'
    print '|-'
    for atom in newatoms:
        print '|{0} | {1} |'.format(atom.symbol, atom.charge)
Exemple #15
0
        print(' ',i,total_charge[i],end='')
    print(' sum {}'.format(sum(total_charge.values())))
    exit()

if not exists:

    # if the data has not been multipled by Bohr**3, uncomment the following.
    # data, atoms = read_cube_data(sys.argv[1])
    # density = data * Bohr**3
    # write('density-temp.cube', atoms, data=density)
    # sys.argv[1] = 'density-temp.cube'
    # res = subprocess.check_output(["bader", sys.argv[1]])
    x = 3

atoms = read(sys.argv[1])
attach_charges(atoms)

elm_set = set(atoms.get_chemical_symbols())
elm = dict.fromkeys(elm_set, 0)

total_charge = elm.copy()

with open(sys.argv[2]) as f:
    for line in f:
        if "-setup:" in line:
            x = line.split('-')[0]
        elif "  Z: " in line:
            elm[x] = int(line.split()[-1])

for i in atoms:
    i.charge = elm[i.symbol] - i.charge
Exemple #16
0
#!/usr/bin/env python
from jasp import *
from ase.io.bader import attach_charges
from ase.units import Bohr
with jasp('molecules/h2o-bader') as calc:
    atoms = calc.get_atoms()
    symbols = np.array(atoms.get_chemical_symbols())[calc.sort]
    pos = atoms.positions[calc.sort] * Bohr
    newatoms = Atoms(symbols, positions=pos, cell=atoms.get_cell())
    attach_charges(newatoms, 'ACF.dat')
    print('#+tblname: bader')
    print('#+caption: Bader charges for a water molecule')
    print('| atom | Bader charge|')
    print('|-')
    for atom in newatoms:
        print('|{0} | {1} |'.format(atom.symbol, atom.charge))
Exemple #17
0
#!/usr/bin/env python3
'''
This script attach charges calculated with bader charge program to xyz 
for visualizing it with ovito.
This requires CONTCAR OUTACR ACF.dat files.
'''

from ase.io import read
from ase.io.bader import attach_charges
import numpy as np

a = read('CONTCAR')
attach_charges(a)

elm = []

# get the elements (elm) and their initial # of electron (chg)
with open('OUTCAR') as f:
    for line in f:
        if len(line.split()) > 2 and line.split()[0] == 'ZVAL':
            chg = line.split()[2:]
        if len(line.split()) > 1 and line.split()[0] == 'VRHFIN':
            elm.append(line.split()[1].strip('=').strip(':'))

elm.append('total')
ech = [0] * len(elm)
all_chg = dict(zip(elm, ech))

print('ZVAL from the OUTACR:', chg)

# calculate the rest charge