Example #1
0
def parse_BORN( primitive,  filename = "BORN" ):
    file = open( filename, 'r' )

    # Read unit conversion factor, damping factor, ...
    factors = [ float( x ) for x in file.readline().split() ]
    if len( factors ) < 1:
        print "BORN file format of line 1 is incorrect"
        return None
    if len( factors ) < 2:
        factors.append( Damping_Factor )

    # Read dielectric constant
    line = file.readline().split()
    if 9 < len( line ) or len( line ) < 9:
        print "BORN file format of line 2 is incorrect"
        return None
    dielectric = np.reshape( [ float( x ) for x in line ], ( 3, 3 ) )

    # Read Born effective charge
    symmetry = Symmetry( primitive )
    independent_atoms = symmetry.get_independent_atoms()
    born = np.zeros( ( primitive.get_number_of_atoms(), 3, 3 ), dtype=float )

    for i in independent_atoms:
        line = file.readline().split()
        if 9 < len( line ) or len( line ) < 9:
            print "BORN file format of line %d is incorrect" % ( i + 3 )
            return None
        born[ i ] = np.reshape( [ float( x ) for x in line ], ( 3, 3 ) )

    # Expand Born effective charges to all atoms in the primitive cell
    rotations = symmetry.get_symmetry_operations()['rotations']
    map_operations = symmetry.get_map_operations()
    map_atoms = symmetry.get_map_atoms()

    for i in range( primitive.get_number_of_atoms() ):
        # R_cart = L R L^-1
        rot_cartesian = similarity_transformation(
            primitive.get_cell().transpose(), rotations[ map_operations[i] ] )
        # R_cart^T B R_cart^-T ( inverse rotation is required to transform )
        born[i] = similarity_transformation( rot_cartesian.transpose(),
                                             born[ map_atoms[ i ] ] )

    non_anal = {'born': born,
                'factor': factors,
                'dielectric': dielectric }

    return non_anal
Example #2
0
def distribute_forces( supercell, disp, forces, filename, symprec ):
    natom = supercell.get_number_of_atoms()
    lattice = supercell.get_cell()
    symbols = supercell.get_chemical_symbols()
    positions = supercell.get_positions()
    positions[disp[0]] += disp[1]
    cell = Atoms( cell=lattice,
                  positions=positions,
                  symbols=symbols,
                  pbc=True )
    symmetry = Symmetry( cell, symprec )
    independent_atoms = symmetry.get_independent_atoms()

    # Rotation matrices in Cartesian
    rotations = []
    for r in symmetry.get_symmetry_operations()['rotations']:
        rotations.append( similarity_transformation( lattice.T, r ) )

    map_operations = symmetry.get_map_operations()
    map_atoms = symmetry.get_map_atoms()

    atoms_in_dot_scf = get_independent_atoms_in_dot_scf( filename )

    if not len( forces ) == len( atoms_in_dot_scf ):
        print "%s does not contain necessary information." % filename
        print "Plese check if there are \"FGL\" lines with"
        print "\"total forces\" are required." 
        return False
    
    if len( atoms_in_dot_scf ) == natom:
        print "It is assumed that there is no symmetrically-equivalent atoms in "
        print "\'%s\' at wien2k calculation." % filename
        print ""
        force_set = forces
    elif not len( forces ) == len( independent_atoms ):
        print "Non-equivalent atoms of %s could not be recognized by phonopy." % filename
        return False
    else:
        # 1. Transform wien2k forces to those on independent atoms
        indep_atoms_to_wien2k = []
        forces_remap = []
        for i, pos_wien2k in enumerate( atoms_in_dot_scf ):
            for j, pos in enumerate( cell.get_scaled_positions() ):
                diff = pos_wien2k - pos
                diff -= diff.round()
                if ( abs( diff ) < 0.00001 ).all():
                    forces_remap.append(
                        np.dot( forces[ i ], rotations[ map_operations[ j ] ].T ) )
                    indep_atoms_to_wien2k.append( map_atoms[ j ] )
                    break
                
        if not len( forces_remap ) == len( forces ):
            print "Atomic position mapping between Wien2k and phonopy failed."
            print "If you think this is caused by a bug of phonopy"
            print "please report it in the phonopy mainling list."
            return False
 
        # 2. Distribute forces from independent to dependent atoms.
        force_set = []
        for i in range( natom ):
            force_set.append( np.dot(
                    forces_remap[ indep_atoms_to_wien2k.index( map_atoms[i] ) ],
                    rotations[ map_operations[i] ] ) )

    return force_set