예제 #1
0
파일: POSCARsym.py 프로젝트: zyjdxtc/handy
def sym_ana(fname):
    #	tol=float(sys.argv[2])
    atoms = read_vasp(fname)
    dataset0 = sp.get_symmetry_dataset(atoms, symprec=1e-5)
    tempsg = dataset0
    print '1e-5 precision', tempsg['international']
    print '1e-5 precision', tempsg['origin_shift']
    for i in range(800):
        tol = 0.001 * i + 0.001
        dataset = sp.get_symmetry_dataset(atoms, symprec=tol)
        #	sym=sp.get_spacegroup(atoms,symprec=tol)
        #	print sym
        if tempsg['international'] != dataset['international']:
            print 'group\t supergroup'
            print tempsg['hall'], ';', dataset['hall']
            print tempsg['international'], '\t', dataset['international']
            print tempsg['number'], '\t', dataset['number']
            print 'origin', tempsg['origin_shift'], '\t', dataset[
                'origin_shift']
            print 'wyckoff', tempsg['wyckoffs']
            print 'new_wyckoff', dataset['wyckoffs']
            print 'equivalent atoms old', tempsg['equivalent_atoms']
            print 'equivalent atoms new', dataset['equivalent_atoms']
            print 'tolerance', tol
            print '--------------------------------------------------------------------------------------\n'
            tempsg = dataset
        if i == 800 - 1 and dataset0['international'] == dataset[
                'international']:
            print 'cannot find superSG, but initial sym is', dataset0[
                'international'], dataset0['number']
예제 #2
0
def get_periodic_symmetry_group(atoms, error_tolerance=0.01, debug=False):
    from pyspglib import spglib
    print atoms
    dataset = spglib.get_symmetry_dataset(atoms, symprec=error_tolerance)
    print dataset['equivalent_atoms']
    print dataset['international']
    print dataset['hall']
    print dataset['wyckoffs']
    print dataset['transformation_matrix']
    print "Number of symmetry operations %i" % len(dataset['rotations'])
    return dataset['international']
예제 #3
0
파일: vasp2boltz.py 프로젝트: zyjdxtc/handy
def get_kspace_operations(ao,
                          methods=['atoms_info', 'spglib'],
                          symprec_spglib=1e-5):
    # returns k-space operations for the atoms object ao
    kops = None
    for method in methods:
        if method == 'atoms_info':
            # get operations from ao.info
            if ('spacegroup' in ao.info) and (ao.info['spacegroup'] != None):
                if ('unit_cell' in ao.info):
                    if (ao.info['unit_cell'] == 'conventional'):
                        primitive_cell = False
                    else:
                        primitive_cell = True
                else:
                    primitive_cell = True
                    print 'get_kspace_operations(): Warning, assuming primitive cell'
                rot = ao.info['spacegroup'].rotations
                p2c_dir = ao.info['spacegroup'].scaled_primitive_cell
                p2c_rec = ao.info['spacegroup'].reciprocal_cell
                kops = []
                for iop in range(len(rot)):
                    if primitive_cell:
                        mat = dot(p2c_rec.T, dot(rot[iop], p2c_dir))
                    else:
                        mat = rot[iop]
                    newop = True
                    for i in range(len(kops)):
                        if cmp_mat(kops[i], mat):
                            newop = False
                            break
                    if newop:
                        kops.append(mat)
                return kops
            else:
                print 'get_kspace_operations(): atoms object has no space group information'
        if method == 'spglib':
            if has_spglib:
                rot = spglib.get_symmetry_dataset(
                    ao, symprec=symprec_spglib)['rotations']
                kops = []
                for iop in range(len(rot)):
                    mat = rot[iop]
                    newop = True
                    for i in range(len(kops)):
                        if cmp_mat(kops[i], mat):
                            newop = False
                            break
                    if newop:
                        kops.append(mat)
                return kops
            else:
                print 'get_kspace_operations(): spglib not found'
예제 #4
0
def get_kspace_operations(ao, methods=['atoms_info','spglib'], symprec_spglib=1e-5):
    # returns k-space operations for the atoms object ao
    kops=None
    for method in methods:
        if method=='atoms_info':
            # get operations from ao.info
            if ('spacegroup' in ao.info) and (ao.info['spacegroup'] is not None):
                if ('unit_cell' in ao.info):
                    if (ao.info['unit_cell']=='conventional'):
                        primitive_cell=False
                    else:
                        primitive_cell=True
                else:
                    primitive_cell=True
                    print 'get_kspace_operations(): Warning, assuming primitive cell'
                rot=ao.info['spacegroup'].rotations
                p2c_dir=ao.info['spacegroup'].scaled_primitive_cell
                p2c_rec=ao.info['spacegroup'].reciprocal_cell 
                kops=[]
                for iop in range(len(rot)):
                    if primitive_cell:
                        mat=dot(p2c_rec.T, dot(rot[iop],p2c_dir))
                    else:
                        mat=rot[iop]
                    newop=True
                    for i in range(len(kops)):
                        if cmp_mat(kops[i],mat):
                            newop=False
                            break
                    if newop:
                        kops.append(mat)
                return kops
            else:
                print 'get_kspace_operations(): atoms object has no space group information'
        if method=='spglib':
            if has_spglib:
                rot=spglib.get_symmetry_dataset(ao, symprec=symprec_spglib)['rotations']
                kops=[]
                for iop in range(len(rot)):
                    mat=rot[iop]
                    newop=True
                    for i in range(len(kops)):
                        if cmp_mat(kops[i],mat):
                            newop=False
                            break
                    if newop:
                        kops.append(mat)
                return kops
            else:
                print 'get_kspace_operations(): spglib not found'
예제 #5
0
for i in range(symmetry['rotations'].shape[0]):
    print "  --------------- %4d ---------------" % (i + 1)
    rot = symmetry['rotations'][i]
    trans = symmetry['translations'][i]
    print "  rotation:"
    for x in rot:
        print "     [%2d %2d %2d]" % (x[0], x[1], x[2])
    print "  translation:"
    print "     (%8.5f %8.5f %8.5f)" % (trans[0], trans[1], trans[2])
print ""
print "[get_pointgroup]"
print "  Pointgroup of Rutile is", spglib.get_pointgroup(
    symmetry['rotations'])[0]
print ""

dataset = spglib.get_symmetry_dataset(rutile)
print "[get_symmetry_dataset] ['international']"
print "  Spacegroup of Rutile is ", dataset['international']
print ""
print "[get_symmetry_dataset] ['wyckoffs']"
alphabet = "abcdefghijklmnopqrstuvwxyz"
print "  Wyckoff letters of Rutile are: ", dataset['wyckoffs']
print ""
print "[get_symmetry_dataset] ['equivalent_atoms']"
print "  Mapping to equivalent atoms of Rutile are: "
for i, x in enumerate(dataset['equivalent_atoms']):
    print "  %d -> %d" % (i + 1, x + 1)
print ""
print "[get_symmetry_dataset] ['rotations'], ['translations']"
print "  Symmetry operations of Rutile unitcell are:"
for i, (rot,
예제 #6
0
symmetry = spglib.get_symmetry( rutile )
for i in range(symmetry['rotations'].shape[0]):
  print "  --------------- %4d ---------------" % (i+1)
  rot = symmetry['rotations'][i]
  trans = symmetry['translations'][i]
  print "  rotation:"
  for x in rot:
    print "     [%2d %2d %2d]" % (x[0], x[1], x[2])
  print "  translation:"
  print "     (%8.5f %8.5f %8.5f)" % (trans[0], trans[1], trans[2])
print ""
print "[get_pointgroup]"
print "  Pointgroup of Rutile is", spglib.get_pointgroup(symmetry['rotations'])[0]
print ""

dataset = spglib.get_symmetry_dataset( rutile )
print "[get_symmetry_dataset] ['international']"
print "  Spacegroup of Rutile is ", dataset['international']
print ""
print "[get_symmetry_dataset] ['wyckoffs']"
alphabet = "abcdefghijklmnopqrstuvwxyz"
print "  Wyckoff letters of Rutile are: ", dataset['wyckoffs']
print ""
print "[get_symmetry_dataset] ['equivalent_atoms']"
print "  Mapping to equivalent atoms of Rutile are: "
for i, x in enumerate( dataset['equivalent_atoms'] ):
  print "  %d -> %d" % ( i+1, x+1 )
print ""
print "[get_symmetry_dataset] ['rotations'], ['translations']"
print "  Symmetry operations of Rutile unitcell are:"
for i, (rot,trans) in enumerate( zip( dataset['rotations'], dataset['translations'] ) ):
parser.set_defaults(mesh=None, qpoints=None)
parser.add_option("-m", "--mesh", dest="mesh", type="string", help="Mesh numbers")
parser.add_option("-q", "--qpoints", dest="qpoints", type="string", help="Stabilizers")
(options, args) = parser.parse_args()

if options.mesh == None:
    mesh = [4, 4, 4]
else:
    mesh = [int(x) for x in options.mesh.split()]

if options.qpoints == None:
    qpoints = np.array([[0, 0, 0]], dtype=float)
else:
    qpoints = np.array([float(x) for x in options.qpoints.split()]).reshape(-1, 3)

cell = read_vasp(args[0])

mapping_g, grid_point = spglib.get_ir_reciprocal_mesh(mesh, cell)

print mapping_g

dataset = spglib.get_symmetry_dataset(cell)

mapping, grid_point = spglib.get_stabilized_reciprocal_mesh(mesh, dataset["rotations"], qpoints=qpoints)

print mapping
print "%d / %d" % (np.sum((mapping_g == mapping) * 1), len(mapping))

# for i, m in enumerate(mapping):
#   print i, grid_point[m]
예제 #8
0
def get_periodic_symmetry_operations(atoms, error_tolerance=0.01, debug=False):
    from ase.utils import irotate
    from ase.visualize import view
    from pyspglib import spglib
    #symmetry = spglib.get_symmetry(atoms, symprec=1e-5)
    symmetry = spglib.get_symmetry(atoms, symprec=1e-2)
    dataset = spglib.get_symmetry_dataset(atoms, symprec=1e-2)

    result = []
    if debug:
        cell, scaled_positions, numbers = spglib.find_primitive(atoms,
                                                                symprec=1e-5)
        a = Atoms(symbols='O4',
                  cell=cell,
                  scaled_positions=scaled_positions,
                  pbc=True)
        #symmetry = spglib.get_symmetry(a, symprec=1e-2)
        #dataset = spglib.get_symmetry_dataset(a, symprec=1e-2)
        print dataset['equivalent_atoms']
        print dataset['international']
        print dataset['hall']
        print dataset['wyckoffs']
        print dataset['transformation_matrix']
        print "Number of symmetry operations %i" % len(dataset['rotations'])
    for i in range(dataset['rotations'].shape[0]):

        new_atoms = atoms.copy()
        test = atoms.copy()
        rot = dataset['rotations'][i]
        trans = dataset['translations'][i]
        if debug:
            x, y, z = irotate(rot)
            #print x, y, z
            print "------------------- %i -----------------------" % i
            print "Rotation"
            print rot
            print "Translation"
            print trans
        new_pos = new_atoms.get_scaled_positions()

        for l, pos in enumerate(new_atoms.get_scaled_positions()):
            #print new_pos[l]
            new_pos[l] = (numpy.dot(rot, pos))
            new_pos[l] += trans
            #print new_pos[l]
        new_atoms.set_scaled_positions(new_pos)
        equals = get_equals_periodic(atoms,
                                     new_atoms,
                                     error_tolerance=error_tolerance,
                                     debug=debug)
        if equals != None:
            so = SymmetryOperation(str(i),
                                   equals,
                                   None,
                                   vector=None,
                                   magnitude=1,
                                   rotation_matrix=rot,
                                   translation_vector=trans)
            #if debug:
            #    print so
            result.append(so)
        else:
            print "Equivalent not found"
            #view(test)
            #view(new_atoms)
            #raw_input()

    return result
예제 #9
0
def main(argv=None):
    print '========================================================='
    print '||             CASTEP 2 BoltzTraP Interface            ||'
    print '||                     version 1.0                     ||'
    print '||                    14 April 2016                    ||'
    print '||-----------------------------------------------------||'
    if argv is None:
        argv = sys.argv
    if len(argv) < 2:
        # Avoid ugly errors
        print '|| Usage: castep2boltz <seedname> <optional arguments> ||'
        print '|| optional arguments: "so" (for SOC runs) ...         ||'
        print '||          and "down" (for spin down calculations)    ||'
        print '||-----------------------------------------------------||'
        print '|| UNSUCCESSFUL! READ Usage above                      ||'
        print '...'
        sys.exit()

    # Define <seedname>
    prefix = argv[1]

    # Help menu, it shows the message and stops the process
    help = ['h', '-h', '--h', 'help', '-help', '--help']
    for i in help:
        if i in argv:
            print '|| Usage: castep2boltz <seedname> <optional arguments> ||'
            print '|| optional arguments: "so" (for SOC runs) ...         ||'
            print '||          and "down" (for spin down calculations)    ||'
            print '========================================================='
            sys.exit()

    # Check if an argument for SOC is given
    # so_on is defined here because it is used multiple times
    if 'so' in argv or '-so' in argv:
        so_on = 'so'
    else:
        so_on = None

    # Set a proper suffix for the .energy file
    if so_on == 'so':
        energy_file = prefix + '.energyso'
    else:
        energy_file = prefix + '.energy'

    # Names of output files
    def_file = 'BoltzTraP.def'
    intrans_file = prefix + '.intrans'
    struct_file = prefix + '.struct'

    #========================================================================================#
    #                         Begin initial extraction of data from
    #                         <seedname>.castep and <seedname>.bands
    #========================================================================================#

    # Open the .castep file and read it
    castep_file = prefix + '.castep'
    castep_file = open(castep_file, 'r')
    castep_data = castep_file.readlines()
    castep_file.close()

    # Check if there are any symmetry operations.
    for index, line in enumerate(castep_data):
        if 'Number of symmetry operations' in line:
            n_symm_ops = int(float(line.split()[5]))
            symmetry = True

        elif 'There are no symmetry operations specified' in line:
            symmetry = False

    # Open the .bands file and read it
    bands_file = prefix + '.bands'
    bands_file = open(bands_file, 'r')
    bands_data = bands_file.readlines()
    bands_file.close()

    # Here we will store some of the data
    kpoints_frac_coordinates = []
    eigenenergies = []  # spin 1 (up)
    eigenenergies_spin2 = []  # spin 2 (down)
    unit_cell = []  # Crystal lattice

    # Extract number of kpoints, spin components,
    # electrons, eigenvalues from the <seedname>.bands file
    # Extract values for Fermi energy, kpoints frac coordinates.
    for line in bands_data:
        if 'Number of k-points' in line:
            n_kpoints = float(line.split()[3])
        elif 'Number of spin components' in line:
            spin_components = float(line.split()[4])
        elif 'Number of electrons' in line:
            if spin_components == 1:
                n_electrons = float(line.split()[3])
                n_electrons_down = None
            elif spin_components == 2:
                n_electrons = float(line.split()[3])
                n_electrons_down = float(line.split()[4])

        # Can you have different number of eigenvalues for
        # spin up and down channels? If yes, this part
        # should be rewritten. n_eigenvalues is used when
        # the .energy file is cooked and might give
        # wrong results if n_eigenvalues != n_eigenvalues_down
        elif 'Number of eigenvalues' in line:
            n_eigenvalues = float(line.split()[3])

        # This is present when there is 1 spin component
        elif 'Fermi energy' in line:
            # castep output is in Hartree, this converts
            # Fermi energy into Rydberg; Ry=2*Hartree
            efermi = float(line.split()[5]) * 2
            # Set Fermi energy for spin down electrons to None
            # This might be used later for a quick check
            efermi_down = None
        # This is present when there are 2 spin components
        elif 'Fermi energies' in line:
            efermi_up = float(line.split()[5]) * 2
            efermi_down = float(line.split()[6]) * 2
            efermi = efermi_up
        elif 'K-point' in line:
            kpoints_frac_coordinates.append([
                float(line.split()[2]),
                float(line.split()[3]),
                float(line.split()[4])
            ])

    # Get eigenenergies and unit cell from .bands file
    for index, line in enumerate(bands_data):
        if 'Spin component 1' in line:
            eigenenergy_starting_line = index + 1
            for i in range(int(n_eigenvalues)):
                eigenenergies.append('{:3.10f}'.format(
                    float(bands_data[eigenenergy_starting_line].split()[0]) *
                    2))
                eigenenergy_starting_line += 1
        elif 'Spin component 2' in line:
            eigenenergy_starting_line2 = index + 1
            for i in range(int(n_eigenvalues)):
                eigenenergies_spin2.append('{:3.10f}'.format(
                    float(bands_data[eigenenergy_starting_line2].split()[0]) *
                    2))
                eigenenergy_starting_line2 += 1
        elif 'Unit cell vectors' in line:
            start = index + 1
            for j in range(3):
                unit_cell.append([
                    '{:3.10f}'.format(float(bands_data[start].split()[0])),
                    '{:3.10f}'.format(float(bands_data[start].split()[1])),
                    '{:3.10f}'.format(float(bands_data[start].split()[2]))
                ])
                start += 1
#========================================================================================#
#========================================================================================#

#========================================================================================#
#                                    SPGLIB SECTION                                      #
#----------------------------------------------------------------------------------------#
# spglib will generate symmetry operations even if CASTEP doesn't use symmetry_generate  #
#----------------------------------------------------------------------------------------#
#          If symmetry_generate IS used in CASTEP, spglib SYMMETRY OPERATIONS            #
#                            will be added to the .struct file.                          #
#                                                                                        #
#                If symmetry_generate is NOT used, then the IDENTITY MATRIX              #
#                             will be added to the .struct file.                         #
#----------------------------------------------------------------------------------------#
#  At the end of the section there is an if clause which checks if the number of CASTEP  #
#     symmetry operations is the same as the number of the ones generated by spglib.     #
#                      If they are different, a warning will pop up.                     #
#========================================================================================#

    positions = []
    a_symbols = []
    unit_cell_from_castep = []

    # Find the total number of ions
    for line in castep_data:
        if 'Total number of ions' in line:
            num_ions = int(line.split()[7])

    # Get unit cell from <seedname>.castep.
    for index, line in enumerate(castep_data):
        # Crystal lattice in (A) units. <seedname>.bands file also contains
        # this information. However, it uses Bohr units and this creates
        # some problems when symmetry operations are generated with spglib.
        if 'Real Lattice(A)' in line:
            start = index + 1
            for j in range(3):
                unit_cell_from_castep.append([
                    float(castep_data[start].split()[0]),
                    float(castep_data[start].split()[1]),
                    float(castep_data[start].split()[2])
                ])
                start += 1
            break  # avoid double counting

    # Get atomic positions and symbols from .castep
    # Use the total number of ions and append the position of every atom to positions = []
    for index, line in enumerate(castep_data):
        if 'Cell Contents' in line:
            for i in range(0, num_ions):
                positions.append([
                    float(castep_data[index + 10 + i].split()[3]),
                    float(castep_data[index + 10 + i].split()[4]),
                    float(castep_data[index + 10 + i].split()[5])
                ])
                a_symbols.append(str(castep_data[index + 10 + i].split()[1]))
            break  # avoid double counting
            # if multiple castep runs are present in one .castep file

# For debugging
# print 'positions',positions, 'atoms_symbols',a_symbols,'total num of ions', num_ions
# print 'Unit cell', unit_cell
# print 'unit_cell_from_castep' ,unit_cell_from_castep

# Create an argument needed by spglib to generate symmetries
    all_atoms = Atoms(symbols=a_symbols,
                      cell=unit_cell_from_castep,
                      scaled_positions=positions,
                      pbc=True)

    # Taken from the VASP interface, it checks if two symm ops are identical.
    # If they are, then don't add them to the list of operations.
    def cmp_mat(mat1, mat2):
        absdiff = abs(mat1 - mat2)
        value = sum(sum(absdiff))
        if value > 1.0e-10:
            return False
        else:
            return True

############################################################################################
# Debugging part
#    dataset = spglib.get_symmetry_dataset( all_atoms )
#    for i, (rot,trans) in enumerate( zip( dataset['rotations'], dataset['translations'] ) ):
#     print "  --------------- %4d ---------------" % (i+1)
#     print "  rotation:"
#     for x in rot:
#      print "     [%2d %2d %2d]" % (x[0], x[1], x[2])
#     print "  translation:"
#     print "     (%8.5f %8.5f %8.5f)" % (trans[0], trans[1], trans[2])
#############################################################################################

# Time for spglib
# Check if spglib is present.

    if has_spglib and symmetry:
        # Use spglib and get rotational operations
        print '|| spglib found.                                       ||'
        rotations = spglib.get_symmetry_dataset(all_atoms,
                                                symprec=1e-5)['rotations']
        symm_ops_spglib = []

        # Append every value from rotations to symm_ops_spglib ...
        for i in range(len(rotations)):
            new_rot = rotations[i]
            newop = True
            # ... but first use the VASP function to see
            # if the symmetry operation is unique ...
            # [I don't think this is needed but it doesn't hurt to have it]
            for k in range(len(symm_ops_spglib)):
                if cmp_mat(symm_ops_spglib[k], new_rot):
                    # If the operation is not unique don't add it
                    newop = False
                    break
            # ... eventually when a new operation is found
            # append it symm_ops_spglib
            if newop:
                symm_ops_spglib.append(new_rot)
        if len(symm_ops_spglib) < 10:
            print '||', len(
                symm_ops_spglib
            ), 'symmetry operations generated by spglib.          ||'
        elif len(symm_ops_spglib) >= 10:
            print '||', len(
                symm_ops_spglib
            ), 'symmetry operations generated by spglib.         ||'

        # Check if the number of symmetry operations generated by spglib
        # is the same as the number of symmetry operations in CASTEP
        if len(symm_ops_spglib) != n_symm_ops:
            print '||                                                     ||'
            print '||                     WARNING:                        ||'
            if n_symm_ops < 10:
                print '||', n_symm_ops, 'symmetry operations found in %s.castep.     ||' % prefix
            elif n_symm_ops >= 10:
                print '||', n_symm_ops, 'symmetry operations found in %s.castep.    ||' % prefix
            print '||', len(
                symm_ops_spglib
            ), 'symmetry operations generated by spglib.          ||'
            print '|| CASTEP tolerance might be too loose.                ||'
            print '|| Proceed with CAUTION.                               ||'
    # If spglib is not found pop a warning
    else:
        if symmetry:
            print '||                                                     ||'
            print '||                     WARNING:                        ||'
            print '|| Symmetry operations ARE present...                  ||'
            print '|| ...but spglib was NOT found.                        ||'
            print '|| Proceed with CAUTION.                               ||'
            print '|| TRY installing spglib: sudo pip install pyspglib    ||'
        if not symmetry:
            print '||                                                     ||'
            print '||                     MESSAGE:                        ||'
            print '|| Symmetry operations NOT used in CASTEP calculation. ||'
            print '|| Continue NORMALLY.                                  ||'
#========================================================================================#
#========================================================================================#

#========================================================================================#
#
#                          Create the <seedname>.energy file
#
#========================================================================================#

#---------------------------------- Spin 1/ Spin up PART --------------------------------#

# First line is a comment, in this case it is the name of the structure
    f_energy = prefix + '\n'

    # Number of k-points
    f_energy += str(int(n_kpoints)) + '\n'

    # K-point coordinates and number of eigenvalues
    for ik in range(int(n_kpoints)):
        for j in range(3):
            f_energy += str(kpoints_frac_coordinates[ik][j]) + ' '
        f_energy += str(int(n_eigenvalues)) + '\n'
        start_pos_for_next_k_point = ik * int(n_eigenvalues)

        # Eigenvalues for a given k-point

        # if you want to exclude bands change range to
        # range(int(n_excluded:n_eigenvalues)) and
        # add this as offset to start_pos ------> this would only exclude the bottom bands
        for ib in range(int(n_eigenvalues)):
            f_energy += str(eigenenergies[start_pos_for_next_k_point]) + '\n'
            start_pos_for_next_k_point += 1

#------------------------------- Spin 2/ Spin down PART ---------------------------------#
# Similar to Spin 1 PART
    if spin_components == 2:
        f_energy_down = prefix + ' down ' + '\n'
        f_energy_down += str(int(n_kpoints)) + '\n'
        for ik in range(int(n_kpoints)):
            for j in range(3):
                f_energy_down += str(kpoints_frac_coordinates[ik][j]) + ' '
            f_energy_down += str(int(n_eigenvalues)) + '\n'
            start_pos_for_next_k_point = ik * int(n_eigenvalues)

            # if you want to exclude bands change range to
            # range(int(n_excluded:n_eigenvalues)) and
            # add this as offset to start_pos ------> this would only exclude the bottom bands
            for ib in range(int(n_eigenvalues)):
                f_energy_down += str(
                    eigenenergies_spin2[start_pos_for_next_k_point]) + '\n'
                start_pos_for_next_k_point += 1
    else:
        pass

    f = open(energy_file, 'w')

    # Choose whether spin up or spin down energies
    # will be written to the .energy file
    if 'down' in argv or '-down' in argv:
        # Check if there are spin down eigenvalues...
        if spin_components == 2:
            f.write(f_energy_down)
            f.close()
            print '||                                                     ||'
            print '|| Spin down energy file cooked and ready to go.       ||'
        # ...if not, use normal values.
        else:
            print '||                                                     ||'
            print '|| Spin polarisation not present, no spin down values. ||'
            print '|| Default settings used instead.                      ||'
            f.write(f_energy)
            f.close()
    else:
        f.write(f_energy)
        f.close()


# IMPORTANT: If a kpoint is repeated BoltzTraP will give an error,
# CASTEP BS calculations might have such point defined in the path
# and it needs to be removed.
#========================================================================================#
#========================================================================================#

#========================================================================================#
#
#                          Create the BoltzTraP.def file
#
#========================================================================================#

    f_def = '5, \'' + prefix + '.intrans\',      \'old\',    \'formatted\',0\n'
    f_def += '6,\'' + prefix + '.outputtrans\',      \'unknown\',    \'formatted\',0\n'
    f_def += '20,\'' + prefix + '.struct\',         \'old\',    \'formatted\',0\n'
    if so_on == 'so':
        f_def += '10,\'' + prefix + '.energyso\',         \'old\',    \'formatted\',0\n'
    else:
        f_def += '10,\'' + prefix + '.energy\',         \'old\',    \'formatted\',0\n'
    f_def += '48,\'' + prefix + '.engre\',         \'unknown\',    \'unformatted\',0\n'
    f_def += '49,\'' + prefix + '.transdos\',        \'unknown\',    \'formatted\',0\n'
    f_def += '50,\'' + prefix + '.sigxx\',        \'unknown\',    \'formatted\',0\n'
    f_def += '51,\'' + prefix + '.sigxxx\',        \'unknown\',    \'formatted\',0\n'
    f_def += '21,\'' + prefix + '.trace\',           \'unknown\',    \'formatted\',0\n'
    f_def += '22,\'' + prefix + '.condtens\',           \'unknown\',    \'formatted\',0\n'
    f_def += '24,\'' + prefix + '.halltens\',           \'unknown\',    \'formatted\',0\n'
    f_def += '30,\'' + prefix + '_BZ.dx\',           \'unknown\',    \'formatted\',0\n'
    f_def += '31,\'' + prefix + '_fermi.dx\',           \'unknown\',    \'formatted\',0\n'
    f_def += '32,\'' + prefix + '_sigxx.dx\',           \'unknown\',    \'formatted\',0\n'
    f_def += '33,\'' + prefix + '_sigyy.dx\',           \'unknown\',    \'formatted\',0\n'
    f_def += '34,\'' + prefix + '_sigzz.dx\',           \'unknown\',    \'formatted\',0\n'
    f_def += '35,\'' + prefix + '_band.dat\',           \'unknown\',    \'formatted\',0\n'
    f_def += '36,\'' + prefix + '_band.gpl\',           \'unknown\',    \'formatted\',0\n'
    f_def += '37,\'' + prefix + '_deriv.dat\',           \'unknown\',    \'formatted\',0\n'
    f_def += '38,\'' + prefix + '_mass.dat\',           \'unknown\',    \'formatted\',0\n'

    f = open(def_file, 'w')
    f.write(f_def)
    f.close()
    #========================================================================================#
    #========================================================================================#

    #========================================================================================#
    #
    #                          Create the <seedname>.intrans file
    #
    #========================================================================================#

    deltae = 0.0005
    ecut = 0.4
    lpfac = 5
    efcut = 0.15
    tmax = 800.0
    deltat = 50.0
    ecut2 = -1.0

    # efermi is only for spin up at the moment, add an if statement if spin down is present
    f_intrans = 'GENE                      # Format of DOS\n'
    f_intrans += '0 0 0 0.0                 # iskip (not presently used) idebug setgap shiftgap\n'

    if 'down' in argv or '-down' in argv:
        if spin_components == 2:
            f_intrans += str(efermi_down) + ' ' + str(deltae) + ' ' + str(
                ecut
            ) + ' ' + str(
                n_electrons_down
            ) + '    # Fermilevel (Ry), energygrid, energy span around Fermilevel, number of electrons\n'
        else:
            # This could be regarded as an error or a typo.
            # This part is also present in the .energy file section and should pop a warning if triggered.
            f_intrans += str(efermi) + ' ' + str(deltae) + ' ' + str(
                ecut
            ) + ' ' + str(
                n_electrons
            ) + '    # Fermilevel (Ry), energygrid, energy span around Fermilevel, number of electrons\n'

    else:
        f_intrans += str(efermi) + ' ' + str(deltae) + ' ' + str(
            ecut
        ) + ' ' + str(
            n_electrons
        ) + '    # Fermilevel (Ry), energygrid, energy span around Fermilevel, number of electrons\n'
    f_intrans += 'CALC                      # CALC (calculate expansion coeff), NOCALC read from file\n'
    f_intrans += str(
        lpfac
    ) + '                         # lpfac, number of latt-points per k-point\n'
    f_intrans += 'BOLTZ                     # run mode (only BOLTZ is supported)\n'
    f_intrans += str(
        efcut
    ) + '                      # (efcut) energy range of chemical potential\n'
    f_intrans += str(tmax) + ' ' + str(
        deltat) + '                # Tmax, temperature grid\n'
    f_intrans += str(
        ecut2
    ) + '                      # energyrange of bands given individual DOS output sig_xxx and dos_xxx (xxx is band number)\n'
    f_intrans += 'HISTO                      #Scheme to obtain DOS. HISTO/TETRA: histogram/thetrahedron sampling\n'

    f = open(intrans_file, 'w')
    f.write(f_intrans)
    f.close()
    #========================================================================================#
    #========================================================================================#

    #========================================================================================#
    #
    #                          Create the <seedname>.struct file
    #
    #========================================================================================#

    # First line is a comment, name of the structure in this case.
    f_struct = prefix + '\n'

    # Crystal lattice from <seedname>.bands file
    for i in range(3):
        for j in range(3):
            f_struct += str(unit_cell[i][j]) + ' '
        f_struct += '\n'

    # Check if symmetry operations and spglib are present
    if symmetry is True and has_spglib:
        f_struct += str(len(symm_ops_spglib)) + '\n'
        for i in range(int(len(symm_ops_spglib))):
            for j in range(3):
                for k in range(3):
                    f_struct += str(symm_ops_spglib[i][j][k]) + ' '
            f_struct += '\n'

    # If there are no symmetry operations, append an identity matrix
    # to the .struct file. BoltzTraP doesn't run otherwise.
    elif symmetry is False or not has_spglib:
        f_struct += '1' + '\n'
        f_struct += '1 0 0 0 1 0 0 0 1'

    f = open(struct_file, 'w')
    f.write(f_struct)
    f.close()
    #========================================================================================#
    #========================================================================================#

    if so_on == 'so':
        print '||                                                     ||'
        print '|| SOC .energyso file cooked and ready to go.          ||'

    print '||                                                     ||'
    print '|| Done.                                               ||'
    print '========================================================='
예제 #10
0
def main(argv = None):
    print '========================================================='
    print '||             CASTEP 2 BoltzTraP Interface            ||'
    print '||                     version 1.2                     ||'
    print '||                     30 Jan 2018                     ||'
    print '||-----------------------------------------------------||'
    if not ase_atoms:
       print '|| ase library not found.                              ||'
       print '|| TRY installing ase: sudo pip install --upgrade ase  ||'
       print '|| UNSUCCESSFUL!                                       ||'
       print '...'
       sys.exit()

    if argv is None:
        argv = sys.argv
    if len(argv) < 2:
       # Avoid ugly errors
       print '|| Usage: castep2boltz.py <seedname> <opt. arguments>  ||'
       print '|| optional arguments: "so" (for SOC runs) ...         ||'
       print '||          and "up/dn" (for spin polarised calc.)     ||'
       print '||-----------------------------------------------------||'
       print '|| Needed input:<seedname>.bands and <seedname>.castep ||'
       print '|| UNSUCCESSFUL! READ Usage above                      ||'
       print '...'
       sys.exit()
       
    # Define <seedname>
    prefix = argv[1]

    # Help menu, it shows the message and stops the process
    help = ['h', '-h','--h', 'help', '-help', '--help']
    for i in help:
      if i in argv:
            print '|| Usage: castep2boltz.py <seedname> <opt. arguments>  ||'
            print '|| optional arguments: "so" (for SOC runs) ...         ||'
            print '||          and "up/dn" (for spin polarised calc.)     ||'
	    print '|| Needed input:<seedname>.bands and <seedname>.castep ||'
            print '========================================================='
            sys.exit()
        

    # Check if an argument for SOC is given
    # so_on is defined here because it is used multiple times 
    if 'so' in argv or '-so' in argv:
     so_on = True
    else  :
     so_on = False

      
    # Check if an argument for spin down calculations is given 
    if 'down' in argv or '-down' in argv or 'dn' in argv or '-dn' in argv:
     spin_dn = True
    else  :
     spin_dn = False

    # Check if an argument for spin down calculations is given 
    if 'up' in argv or '-up' in argv:
     spin_up = True
    else  :
     spin_up = False

    # Set a proper suffix for the .energy file
    if so_on:
      energy_file = prefix + '.energyso' 
    elif spin_up:
      energy_file = prefix + '.energyup'    
    elif spin_dn:
      energy_file = prefix + '.energydn'    
    else:
      energy_file = prefix + '.energy'

    # Names of output files
    def_file = 'BoltzTraP.def'  
    intrans_file = prefix + '.intrans'
    struct_file = prefix + '.struct' 

#========================================================================================#
#                         Begin initial extraction of data from
#                         <seedname>.castep and <seedname>.bands 
#========================================================================================#
  
    # Open the .castep file and read it
    castep_file = prefix + '.castep'
    castep_file = open(castep_file, 'r')
    castep_data = castep_file.readlines()
    castep_file.close()
  
    # Check if there are any symmetry operations. 
    for index, line in enumerate(castep_data):
       if 'Number of symmetry operations' in line:
          n_symm_ops = int(float(line.split()[5]))
	  if n_symm_ops != 1:
          		symmetry = True
	  else:	
			symmetry = False
          
       elif 'There are no symmetry operations specified' in line:
          symmetry = False

    # Open the .bands file and read it
    bands_file = prefix + '.bands'
    bands_file = open(bands_file, 'r')
    bands_data = bands_file.readlines()
    bands_file.close()

    # Here we will store some of the data
    kpoints_frac_coordinates = []
    eigenenergies = []  # spin 1 (up)
    eigenenergies_spin2 = [] # spin 2 (down)
    unit_cell = [] # Crystal lattice
    
    # Extract number of kpoints, spin components, 
    # electrons, eigenvalues from the <seedname>.bands file
    # Extract values for Fermi energy, kpoints frac coordinates.
    for line in bands_data:
        if 'Number of k-points' in line:
            n_kpoints = float(line.split()[3])
        elif 'Number of spin components' in line:
            spin_components = float(line.split()[4])
        elif 'Number of electrons' in line:
           if spin_components == 1:
              n_electrons = float(line.split()[3])
              n_electrons_down = None
           elif spin_components == 2:
              n_electrons_up = float(line.split()[3])
              n_electrons_down = float(line.split()[4])
              n_electrons = n_electrons_up + n_electrons_down

        # Can you have different number of eigenvalues for
        # spin up and down channels? If yes, this part
        # should be rewritten. n_eigenvalues is used when
        # the .energy file is cooked and might give
        # wrong results if n_eigenvalues != n_eigenvalues_down
        elif 'Number of eigenvalues' in line:
            n_eigenvalues = float(line.split()[3]) 

        # This is present when there is 1 spin component
        elif 'Fermi energy' in line: 
            # castep output is in Hartree, this converts 
            # Fermi energy into Rydberg; Ry=2*Hartree
            efermi = float(line.split()[5])*2 
            # Set Fermi energy for spin down electrons to None
            # This might be used later for a quick check
            efermi_down = None
        # This is present when there are 2 spin components
        elif 'Fermi energies' in line: 
            efermi_up = float(line.split()[5])*2
            efermi_down = float(line.split()[6])*2 
            efermi=efermi_up  
        elif 'K-point' in line:
            kpoints_frac_coordinates.append([float(line.split()[2]),
                                             float(line.split()[3]),
                                             float(line.split()[4])]) 
                  
    # Get eigenenergies and unit cell from .bands file
    for index, line in enumerate(bands_data):
        if 'Spin component 1' in line:         
             eigenenergy_starting_line = index + 1
             for i in range(int(n_eigenvalues)):                        
                eigenenergies.append('{0:3.10f}'.format(
                float(bands_data[eigenenergy_starting_line].split()[0])*2))
                eigenenergy_starting_line += 1  
        elif 'Spin component 2' in line:         
             eigenenergy_starting_line2 = index + 1
             for i in range(int(n_eigenvalues)):                        
                eigenenergies_spin2.append('{0:3.10f}'.format(
                float(bands_data[eigenenergy_starting_line2].split()[0])*2))
                eigenenergy_starting_line2 += 1  
        elif 'Unit cell vectors' in line:  
              start = index + 1
              for j in range (3):
                   unit_cell.append(['{0:3.10f}'.format(float(bands_data[start].split()[0])), 
                                     '{0:3.10f}'.format(float(bands_data[start].split()[1])),
                                     '{0:3.10f}'.format(float(bands_data[start].split()[2]))])
                   start += 1
#========================================================================================#                  
#========================================================================================#



#========================================================================================#
#                                    SPGLIB SECTION                                      #
#----------------------------------------------------------------------------------------#
# spglib will generate symmetry operations even if CASTEP doesn't use symmetry_generate  #
#----------------------------------------------------------------------------------------#
#          If symmetry_generate IS used in CASTEP, spglib SYMMETRY OPERATIONS            #
#                            will be added to the .struct file.                          #
#                                                                                        #
#                If symmetry_generate is NOT used, then the IDENTITY MATRIX              #
#                             will be added to the .struct file.                         #
#----------------------------------------------------------------------------------------#
#  At the end of the section there is an if clause which checks if the number of CASTEP  #
#     symmetry operations is the same as the number of the ones generated by spglib.     #
#                      If they are different, a warning will pop up.                     # 
#========================================================================================#
   
    positions = []
    a_symbols = []
    unit_cell_from_castep = []
        
    # Find the total number of ions
    for line in castep_data:
        if 'Total number of ions' in line:
           num_ions = int(line.split()[7])
	elif 'Cell is a supercell' in line:
		sup_cell = True
		num_sup_cells = int(line.split()[5])
		sup_cell_msg = line
		#print num_sup_cells
    
    # Get unit cell from <seedname>.castep.
    for index, line in enumerate(castep_data):
         # Crystal lattice in (A) units. <seedname>.bands file also contains
         # this information. However, it uses Bohr units and this creates 
         # some problems when symmetry operations are generated with spglib. 
         if 'Real Lattice(A)' in line:  
                           start = index + 1
                           for j in range (3):
                             unit_cell_from_castep.append(
                                              [float(castep_data[start].split()[0]), 
                                               float(castep_data[start].split()[1]),
                                               float(castep_data[start].split()[2])])
                             start += 1  
                           break # avoid double counting  

    # Get atomic positions and symbols from .castep
    # Use the total number of ions and append the position of every atom to positions = []        
    for index, line in enumerate(castep_data):
         if 'Cell Contents' in line:
            for i in range(0, num_ions):
                positions.append([float(castep_data[index+10+i].split()[3]), 
                                  float(castep_data[index+10+i].split()[4]), 
                                  float(castep_data[index+10+i].split()[5])])
                a_symbols.append(str(castep_data[index+10+i].split()[1]))
            break # avoid double counting   
                  # if multiple castep runs are present in one .castep file 
    

    # Create an argument needed by spglib to generate symmetries
    all_atoms = Atoms(symbols = a_symbols,
                cell=unit_cell_from_castep,
                scaled_positions=positions,
                pbc=True)
    # Translational symm ops are not considered by boltztrap
    # Add only unique rotational symm ops
    def compare_elements(element1, element2):
    	absdiff = abs(element1 - element2)
   	value = sum(sum(absdiff))
    	if value > 1.0e-10:
        	return False
    	else:
        	return True

    # Check if spglib is present.
    if has_spglib and symmetry:
                # Use spglib and get rotational operations
                print '|| spglib found.                                       ||'
		# used for debugging
		#cell_symm = spglib.get_symmetry(all_atoms, symprec=symmetry_tol)
		#translations = spglib.get_symmetry_dataset(all_atoms, symprec=symmetry_tol)['translations']
                rotations = spglib.get_symmetry_dataset(all_atoms, symprec=symmetry_tol)['rotations']
		
                symm_ops_spglib = []

                for i in range(len(rotations)):
                    new_rot = rotations[i]
    
                    newop=True
                    for i in range(len(symm_ops_spglib)):
                        if compare_elements(symm_ops_spglib[i],new_rot):
                            newop=False
                            break
                    if newop:
                        symm_ops_spglib.append(new_rot)
                
                
		def max_length(msg):
			max_length1 = abs(57-len(msg))
			return max_length1

                # print number of symmetry operations generated by spglib.
                mess = '|| %s ' %len(symm_ops_spglib) + 'symmetry operations generated by spglib. '
                
                print '%s' %mess + '{0:>{width}}'.format("||", width=max_length(mess))

                # Check if the number of symmetry operations generated by spglib
                # is the same as the number of symmetry operations in CASTEP
                if len(symm_ops_spglib) != n_symm_ops:
                  print '||                                                     ||'
                  print '||                     WARNING:                        ||'
                  err_mess = '|| %s ' %n_symm_ops + 'symmetry operations found in %s.castep. ' % prefix                  
                  print '%s' %err_mess + '{0:>{width}}'.format("||", width=max_length(err_mess))
                  err_mess = '|| %s ' %len(symm_ops_spglib) + 'symmetry operations generated by spglib. '
                  print '%s' %err_mess + '{0:>{width}}'.format("||", width=max_length(err_mess))
                  if sup_cell:
			if len(symm_ops_spglib)*num_sup_cells == n_symm_ops: 
			  sup_cell_msg = '|| Cell is a supercell containing %s ' %num_sup_cells + 'primitive cells '
			  print '||                                                     ||'
			  print '%s' %sup_cell_msg + '{0:>{width}}'.format("||", width=max_length(sup_cell_msg))
			  print '|| and translational sym. ops. are not needed.         ||'
			  print '|| Everything should be fine.                          ||'
			else:
			  sup_cell_msg = '|| Cell is a supercell containing %s ' %num_sup_cells + 'primitive cells. '
			  print '||                                                     ||'
			  print '%s' %sup_cell_msg + '{0:>{width}}'.format("||", width=max_length(sup_cell_msg))
			  print '|| However, the number of sym. ops. is unexpected.     ||'
                  	  print '|| Check symmetry operations tolerance in CASTEP.      ||'
                  	  print '|| Proceed with CAUTION.                               ||'

				
                  else:
                  	  print '|| Check symmetry operations tolerance in CASTEP.      ||'
                  	  print '|| Proceed with CAUTION.                               ||'
    # If spglib is not found pop a warning            
    else:
       if symmetry:
                print '||                                                     ||'
                print '||                     WARNING:                        ||'
                print '|| Symmetry operations ARE present...                  ||'
                print '|| ...but spglib was NOT found.                        ||'
                print '|| Proceed with CAUTION.                               ||'
                print '|| TRY installing spglib: sudo pip install pyspglib    ||'
       if not symmetry:
                print '||                                                     ||'
                print '||                     MESSAGE:                        ||'
                print '|| Symmetry operations NOT used in CASTEP calculation. ||'
                print '|| Continue NORMALLY.                                  ||'
#========================================================================================#    
#========================================================================================#
          
    

#========================================================================================#
#
#                          Create the <seedname>.energy file
#
#========================================================================================#         

#---------------------------------- Spin 1/ Spin up PART --------------------------------# 

    # First line is a comment, in this case it is the name of the structure   
    f_energy = prefix + '\n'

    # Number of k-points
    f_energy += str(int(n_kpoints)) + '\n'

    # K-point coordinates and number of eigenvalues
    for ik in range(int(n_kpoints)):
        for j in range(3):
          f_energy += str(kpoints_frac_coordinates[ik][j]) + ' '
        f_energy += str(int(n_eigenvalues)) + '\n'     
        start_pos_for_next_k_point = ik*int(n_eigenvalues)

        # Eigenvalues for a given k-point

        # if you want to exclude bands change range to
        # range(int(n_excluded:n_eigenvalues)) and 
        # add this as offset to start_pos ------> this would only exclude the bottom bands
        for ib in range(int(n_eigenvalues)): 
            f_energy += str(eigenenergies[start_pos_for_next_k_point]) + '\n'
            start_pos_for_next_k_point += 1 
 

#------------------------------- Spin 2/ Spin down PART ---------------------------------#
    # Similar to Spin 1 PART  
    if spin_components == 2:
     f_energy_down = prefix + ' down ' + '\n'
     f_energy_down += str(int(n_kpoints)) + '\n'
     for ik in range(int(n_kpoints)):
        for j in range(3):
          f_energy_down += str(kpoints_frac_coordinates[ik][j]) + ' ' 
        f_energy_down += str(int(n_eigenvalues)) + '\n'     
        start_pos_for_next_k_point = ik*int(n_eigenvalues) 

        # if you want to exclude bands change range to
        # range(int(n_excluded:n_eigenvalues)) and 
        # add this as offset to start_pos ------> this would only exclude the bottom bands
        for ib in range(int(n_eigenvalues)):
            f_energy_down += str(eigenenergies_spin2[start_pos_for_next_k_point]) + '\n'
            start_pos_for_next_k_point += 1 
    else:
     pass

     
    f = open(energy_file, 'w')
    
    # Choose whether spin up or spin down energies
    # will be written to the .energy file
    if 'down' in argv or '-down' in argv or 'dn' in argv or '-dn' in argv:
     # Check if there are spin down eigenvalues...
     if spin_components == 2:
       f.write(f_energy_down)
       f.close()
       print '||                                                     ||'
       print '|| Spin down energy file cooked and ready to go.       ||'
     # ...if not, use normal values.
     else:
       print '||                                                     ||'
       print '|| Spin polarisation not present, no spin down values. ||'
       print '|| Default settings used instead.                      ||' 
       f.write(f_energy)
       f.close()
    else:
       f.write(f_energy)
       f.close()
       

# IMPORTANT: If a kpoint is repeated BoltzTraP will give an error, 
# CASTEP BS calculations might have a such point defined in the path
# and it needs to be removed.
#========================================================================================#
#========================================================================================#



#========================================================================================#
#
#                          Create the BoltzTraP.def file
#
#========================================================================================#

    f_def = '5, \'' + prefix + '.intrans\',      \'old\',    \'formatted\',0\n'
    f_def += '6,\'' + prefix + '.outputtrans\',      \'unknown\',    \'formatted\',0\n'
    f_def += '20,\'' + prefix + '.struct\',         \'old\',    \'formatted\',0\n'
    if so_on:
       f_def += '10,\'' + prefix + '.energyso\',         \'old\',    \'formatted\',0\n'
    elif spin_up:
       f_def += '10,\'' + prefix + '.energyup\',         \'old\',    \'formatted\',0\n'
    elif spin_dn:
       f_def += '10,\'' + prefix + '.energydn\',         \'old\',    \'formatted\',0\n'
    else:
       f_def += '10,\'' + prefix + '.energy\',         \'old\',    \'formatted\',0\n'
    f_def += '48,\'' + prefix + '.engre\',         \'unknown\',    \'unformatted\',0\n'
    f_def += '49,\'' + prefix + '.transdos\',        \'unknown\',    \'formatted\',0\n'
    f_def += '50,\'' + prefix + '.sigxx\',        \'unknown\',    \'formatted\',0\n'
    f_def += '51,\'' + prefix + '.sigxxx\',        \'unknown\',    \'formatted\',0\n'
    f_def += '21,\'' + prefix + '.trace\',           \'unknown\',    \'formatted\',0\n'
    f_def += '22,\'' + prefix + '.condtens\',           \'unknown\',    \'formatted\',0\n'
    f_def += '24,\'' + prefix + '.halltens\',           \'unknown\',    \'formatted\',0\n'
    f_def += '30,\'' + prefix + '_BZ.dx\',           \'unknown\',    \'formatted\',0\n'
    f_def += '31,\'' + prefix + '_fermi.dx\',           \'unknown\',    \'formatted\',0\n'
    f_def += '32,\'' + prefix + '_sigxx.dx\',           \'unknown\',    \'formatted\',0\n'
    f_def += '33,\'' + prefix + '_sigyy.dx\',           \'unknown\',    \'formatted\',0\n'
    f_def += '34,\'' + prefix + '_sigzz.dx\',           \'unknown\',    \'formatted\',0\n'
    f_def += '35,\'' + prefix + '_band.dat\',           \'unknown\',    \'formatted\',0\n'
    f_def += '36,\'' + prefix + '_band.gpl\',           \'unknown\',    \'formatted\',0\n'
    f_def += '37,\'' + prefix + '_deriv.dat\',           \'unknown\',    \'formatted\',0\n'
    f_def += '38,\'' + prefix + '_mass.dat\',           \'unknown\',    \'formatted\',0\n'

    f = open(def_file, 'w')
    f.write(f_def)
    f.close()
#========================================================================================#
#========================================================================================#



#========================================================================================#
#
#                          Create the <seedname>.intrans file
#
#========================================================================================#

    deltae = 0.0005
    ecut = 0.4
    lpfac = 5
    efcut = 0.15
    tmax = 800.0
    deltat = 50.0
    ecut2 = -1.0

    # efermi is only for spin up at the moment, add an if statement if spin down is present
    f_intrans = 'GENE                      # Format of DOS\n'
    f_intrans += '0 0 0 0.0                 # iskip (not presently used) idebug setgap shiftgap\n'
    


    if 'down' in argv or '-down' in argv:
        if spin_components == 2:
            f_intrans += str(efermi_down) + ' ' + str(deltae) + ' ' + str(ecut) + ' ' + str(n_electrons) + '    # Fermilevel (Ry), energygrid, energy span around Fermilevel, number of electrons\n'
        else:
            # This could be regarded as an error or a typo. 
            # This part is also present in the .energy file section and should pop a warning if triggered.
            f_intrans += str(efermi) + ' ' + str(deltae) + ' ' + str(ecut) + ' ' + str(n_electrons) + '    # Fermilevel (Ry), energygrid, energy span around Fermilevel, number of electrons\n'

    else:
    	f_intrans += str(efermi) + ' ' + str(deltae) + ' ' + str(ecut) + ' ' + str(n_electrons) + '    # Fermilevel (Ry), energygrid, energy span around Fermilevel, number of electrons\n'
    f_intrans += 'CALC                      # CALC (calculate expansion coeff), NOCALC read from file\n'
    f_intrans += str(lpfac) + '                         # lpfac, number of latt-points per k-point\n'
    f_intrans += 'BOLTZ                     # run mode (only BOLTZ is supported)\n'
    f_intrans += str(efcut) + '                      # (efcut) energy range of chemical potential\n'
    f_intrans += str(tmax) + ' ' + str(deltat) + '                # Tmax, temperature grid\n'
    f_intrans += str(ecut2) + '                      # energyrange of bands given individual DOS output sig_xxx and dos_xxx (xxx is band number)\n'
    f_intrans += 'HISTO                     # Scheme to obtain DOS. HISTO/TETRA: histogram/thetrahedron sampling\n'
    f_intrans += '#0 0 0 0 0                # tau-model. Not documented\n'
    f_intrans += '#14                       # number of fixed dopings\n'
    f_intrans += '#1E20 5E20 1E21 2E21 3E21 5E21 1E22 5E22 -1E20 -5E20 -1E21 -2.5E21 -5E21 -1E22 # example of fixed doping levels in cm^3\n'

    f = open(intrans_file, 'w')
    f.write(f_intrans)
    f.close()
#========================================================================================#
#========================================================================================#
 


#========================================================================================#
#
#                          Create the <seedname>.struct file
#
#========================================================================================#

    # First line is a comment, name of the structure in this case.
    f_struct = prefix + '\n'
    
    # Crystal lattice from <seedname>.bands file
    for i in range(3):
     for j in range(3):
        f_struct += str(unit_cell[i][j]) + ' ' 
     f_struct +='\n'

    # Check if symmetry operations and spglib are present
    if symmetry is True and has_spglib:
         f_struct += str(len(symm_ops_spglib)) + '\n'
         for i in range(int(len(symm_ops_spglib))):
          for j in range(3):
           for k in range(3):
            f_struct += str(symm_ops_spglib[i][j][k]) + ' '
          f_struct += '\n'
        
    
    # If there are no symmetry operations, append an identity matrix
    # to the .struct file. BoltzTraP doesn't run otherwise.
    elif symmetry is False or not has_spglib:
            f_struct += '1' + '\n'
            f_struct += '1 0 0 0 1 0 0 0 1'
    
      
    f = open(struct_file, 'w')
    f.write(f_struct)
    f.close() 
#========================================================================================#
#========================================================================================#

    if so_on:
       print '||                                                     ||'
       print '|| SOC .energyso file cooked and ready to go.          ||'

    print '||                                                     ||'
    print '|| Done.                                               ||'
    print '========================================================='
예제 #11
0
                  help="Mesh numbers")
parser.add_option("-f",
                  dest="filename",
                  type="string",
                  help="Filename of triplets at q")
parser.add_option("-g", dest="grid_point", type="int", help="A grid point")
(options, args) = parser.parse_args()

if options.mesh == None:
    mesh = [4, 4, 4]
else:
    mesh = [int(x) for x in options.mesh.split()]

cell = read_vasp(args[0])

dataset = spglib.get_symmetry_dataset(cell)

weights, third_q, grid_points = \
    spglib.get_triplets_reciprocal_mesh_at_q(options.grid_point,
                                             mesh,
                                             dataset['rotations'])
if options.filename == None:
    for i, (w, q) in enumerate(zip(weights, third_q)):
        if w > 0:
            print options.grid_point, i, q, w
else:
    triplets_in, weights_in = parse_triplets(options.filename)
    count = 0
    for i, (w, q) in enumerate(zip(weights, third_q)):
        if w > 0:
            if triplets_in[count][0] == options.grid_point and \