コード例 #1
0
def test_magmom(convcell_cr: PhonopyAtoms):
    """Test symmetry search with hmagnetic moments."""
    symprec = 1e-5
    symmetry_nonspin = Symmetry(convcell_cr, symprec=symprec)
    atom_map_nonspin = symmetry_nonspin.get_map_atoms()
    len_sym_nonspin = len(symmetry_nonspin.symmetry_operations["rotations"])

    spin = [1, -1]
    cell_withspin = convcell_cr.copy()
    cell_withspin.magnetic_moments = spin
    symmetry_withspin = Symmetry(cell_withspin, symprec=symprec)
    atom_map_withspin = symmetry_withspin.get_map_atoms()
    len_sym_withspin = len(symmetry_withspin.symmetry_operations["rotations"])

    broken_spin = [1, -2]
    cell_brokenspin = convcell_cr.copy()
    cell_brokenspin = convcell_cr.copy()
    cell_brokenspin.magnetic_moments = broken_spin
    symmetry_brokenspin = Symmetry(cell_brokenspin, symprec=symprec)
    atom_map_brokenspin = symmetry_brokenspin.get_map_atoms()
    len_sym_brokenspin = len(
        symmetry_brokenspin.symmetry_operations["rotations"])

    assert (atom_map_nonspin == atom_map_withspin).all()
    assert (atom_map_nonspin != atom_map_brokenspin).any()
    assert len_sym_nonspin == len_sym_withspin
    assert len_sym_nonspin != len_sym_brokenspin
コード例 #2
0
ファイル: test_symmetry.py プロジェクト: zkyuan/phonopy
    def test_magmom(self):
        symprec = 1e-5
        cell = read_cell_yaml(os.path.join(data_dir, "Cr.yaml"))
        symmetry_nonspin = Symmetry(cell, symprec=symprec)
        atom_map_nonspin = symmetry_nonspin.get_map_atoms()
        len_sym_nonspin = len(
            symmetry_nonspin.get_symmetry_operations()['rotations'])

        spin = [1, -1]
        cell_withspin = cell.copy()
        cell_withspin.set_magnetic_moments(spin)
        symmetry_withspin = Symmetry(cell_withspin, symprec=symprec)
        atom_map_withspin = symmetry_withspin.get_map_atoms()
        len_sym_withspin = len(
            symmetry_withspin.get_symmetry_operations()['rotations'])

        broken_spin = [1, -2]
        cell_brokenspin = cell.copy()
        cell_brokenspin = cell.copy()
        cell_brokenspin.set_magnetic_moments(broken_spin)
        symmetry_brokenspin = Symmetry(cell_brokenspin, symprec=symprec)
        atom_map_brokenspin = symmetry_brokenspin.get_map_atoms()
        len_sym_brokenspin = len(
            symmetry_brokenspin.get_symmetry_operations()['rotations'])

        self.assertTrue((atom_map_nonspin == atom_map_withspin).all())
        self.assertFalse((atom_map_nonspin == atom_map_brokenspin).all())
        self.assertTrue(len_sym_nonspin == len_sym_withspin)
        self.assertFalse(len_sym_nonspin == len_sym_brokenspin)
コード例 #3
0
def test_magmom(convcell_cr):
    symprec = 1e-5
    cell = convcell_cr
    symmetry_nonspin = Symmetry(cell, symprec=symprec)
    atom_map_nonspin = symmetry_nonspin.get_map_atoms()
    len_sym_nonspin = len(
        symmetry_nonspin.get_symmetry_operations()['rotations'])

    spin = [1, -1]
    cell_withspin = cell.copy()
    cell_withspin.set_magnetic_moments(spin)
    symmetry_withspin = Symmetry(cell_withspin, symprec=symprec)
    atom_map_withspin = symmetry_withspin.get_map_atoms()
    len_sym_withspin = len(
        symmetry_withspin.get_symmetry_operations()['rotations'])

    broken_spin = [1, -2]
    cell_brokenspin = cell.copy()
    cell_brokenspin = cell.copy()
    cell_brokenspin.set_magnetic_moments(broken_spin)
    symmetry_brokenspin = Symmetry(cell_brokenspin, symprec=symprec)
    atom_map_brokenspin = symmetry_brokenspin.get_map_atoms()
    len_sym_brokenspin = len(
        symmetry_brokenspin.get_symmetry_operations()['rotations'])

    assert (atom_map_nonspin == atom_map_withspin).all()
    assert (atom_map_nonspin != atom_map_brokenspin).any()
    assert len_sym_nonspin == len_sym_withspin
    assert len_sym_nonspin != len_sym_brokenspin
コード例 #4
0
ファイル: test_symmetry.py プロジェクト: gcgs1/phonopy
    def test_magmom(self):
        symprec = 1e-5
        cell = get_unitcell_from_phonopy_yaml(os.path.join(data_dir,"Cr.yaml"))
        symmetry_nonspin = Symmetry(cell, symprec=symprec)
        atom_map_nonspin = symmetry_nonspin.get_map_atoms()
        len_sym_nonspin = len(
            symmetry_nonspin.get_symmetry_operations()['rotations'])
        
        spin = [1, -1]
        cell_withspin = cell.copy()
        cell_withspin.set_magnetic_moments(spin)
        symmetry_withspin = Symmetry(cell_withspin, symprec=symprec)
        atom_map_withspin = symmetry_withspin.get_map_atoms()
        len_sym_withspin = len(
            symmetry_withspin.get_symmetry_operations()['rotations'])

        broken_spin = [1, -2]
        cell_brokenspin = cell.copy()
        cell_brokenspin = cell.copy()
        cell_brokenspin.set_magnetic_moments(broken_spin)
        symmetry_brokenspin = Symmetry(cell_brokenspin, symprec=symprec)
        atom_map_brokenspin = symmetry_brokenspin.get_map_atoms()
        len_sym_brokenspin = len(
            symmetry_brokenspin.get_symmetry_operations()['rotations'])

        self.assertTrue((atom_map_nonspin == atom_map_withspin).all())
        self.assertFalse((atom_map_nonspin == atom_map_brokenspin).all())
        self.assertTrue(len_sym_nonspin == len_sym_withspin)
        self.assertFalse(len_sym_nonspin == len_sym_brokenspin)
コード例 #5
0
ファイル: wien2k.py プロジェクト: atztogo/phonopy
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 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)
        force_set = forces
    elif 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 -= np.rint(diff)
                if (abs(diff) < symprec).all():
                    forces_remap.append(np.dot(rotations[map_operations[j]], forces[i]))
                    indep_atoms_to_wien2k.append(map_atoms[j])
                    break

        if 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):
            j = indep_atoms_to_wien2k.index(map_atoms[i])
            force_set.append(np.dot(rotations[map_operations[i]].T, forces_remap[j]))

    return force_set
コード例 #6
0
def _expand_borns(borns, primitive: PhonopyAtoms, prim_symmetry: Symmetry):
    # Expand Born effective charges to all atoms in the primitive cell
    rotations = prim_symmetry.symmetry_operations["rotations"]
    map_operations = prim_symmetry.get_map_operations()
    map_atoms = prim_symmetry.get_map_atoms()

    for i in range(len(primitive)):
        # R_cart = L R L^-1
        rot_cartesian = similarity_transformation(primitive.cell.T,
                                                  rotations[map_operations[i]])
        # R_cart^T B R_cart^-T (inverse rotation is required to transform)
        borns[i] = similarity_transformation(rot_cartesian.T,
                                             borns[map_atoms[i]])
コード例 #7
0
ファイル: file_IO.py プロジェクト: Johnson-Wang/phonopy
def get_born_parameters(f, primitive, is_symmetry):
    # Read unit conversion factor, damping factor, ...
    factors = [float(x) for x in f.readline().split()]
    if len(factors) < 1:
        print "BORN file format of line 1 is incorrect"
        return False
    if len(factors) < 2:
        factors = factors[0]

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

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

    for i in independent_atoms:
        line = f.readline().split()
        if len(line) == 0:
            print "Number of lines for Born effect charge is not enough."
            return False
        if not len(line) == 9:
            print "BORN file format of line %d is incorrect" % (i + 3)
            return False
        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
コード例 #8
0
ファイル: file_IO.py プロジェクト: jasonlarkin/ntpl
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
コード例 #9
0
def get_born_parameters(f, primitive, is_symmetry):
    # Read unit conversion factor, damping factor, ...
    factors = [float(x) for x in f.readline().split()]
    if len(factors) < 1:
        print "BORN file format of line 1 is incorrect"
        return False
    if len(factors) < 2:
        factors = factors[0]

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

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

    for i in independent_atoms:
        line = f.readline().split()
        if len(line) == 0:
            print "Number of lines for Born effect charge is not enough."
            return False
        if not len(line) == 9:
            print "BORN file format of line %d is incorrect" % (i + 3)
            return False
        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
コード例 #10
0
ファイル: test_symmetry.py プロジェクト: zkyuan/phonopy
 def test_get_map_operations(self):
     symprec = 1e-5
     cell = read_cell_yaml(os.path.join(data_dir, "..", "NaCl.yaml"))
     scell = get_supercell(cell, np.diag([2, 2, 2]), symprec=symprec)
     symmetry = Symmetry(scell, symprec=symprec)
     # start = time.time()
     symmetry._set_map_operations()
     # end = time.time()
     # print(end - start)
     map_ops = symmetry.get_map_operations()
     map_atoms = symmetry.get_map_atoms()
     positions = scell.get_scaled_positions()
     rotations = symmetry.get_symmetry_operations()['rotations']
     translations = symmetry.get_symmetry_operations()['translations']
     for i, (op_i, atom_i) in enumerate(zip(map_ops, map_atoms)):
         r_pos = np.dot(rotations[op_i], positions[i]) + translations[op_i]
         diff = positions[atom_i] - r_pos
         diff -= np.rint(diff)
         self.assertTrue((diff < symprec).all())
コード例 #11
0
ファイル: test_symmetry.py プロジェクト: gcgs1/phonopy
 def test_get_map_operations(self):
     symprec = 1e-5
     cell = get_unitcell_from_phonopy_yaml(
         os.path.join(data_dir,"../NaCl.yaml"))
     scell = get_supercell(cell, np.diag([2, 2, 2]), symprec=symprec)
     symmetry = Symmetry(scell, symprec=symprec)
     start = time.time()
     symmetry._set_map_operations()
     end = time.time()
     # print(end - start)
     map_ops = symmetry.get_map_operations()
     map_atoms = symmetry.get_map_atoms()
     positions = scell.get_scaled_positions()
     rotations = symmetry.get_symmetry_operations()['rotations']
     translations = symmetry.get_symmetry_operations()['translations']
     for i, (op_i, atom_i) in enumerate(zip(map_ops, map_atoms)):
         r_pos = np.dot(rotations[op_i], positions[i]) + translations[op_i]
         diff = positions[atom_i] - r_pos
         diff -= np.rint(diff)
         self.assertTrue((diff < symprec).all())
コード例 #12
0
def test_get_map_operations(convcell_nacl):
    symprec = 1e-5
    cell = convcell_nacl
    scell = get_supercell(cell, np.diag([2, 2, 2]), symprec=symprec)
    symmetry = Symmetry(scell, symprec=symprec)
    map_ops = symmetry.get_map_operations().copy()
    # start = time.time()
    # symmetry._set_map_operations()
    # end = time.time()
    # print(end - start)
    # map_ops_old = symmetry.get_map_operations().copy()
    # assert (map_ops == map_ops_old).all()
    map_atoms = symmetry.get_map_atoms()
    positions = scell.scaled_positions
    rotations = symmetry.symmetry_operations['rotations']
    translations = symmetry.symmetry_operations['translations']
    for i, (op_i, atom_i) in enumerate(zip(map_ops, map_atoms)):
        r_pos = np.dot(rotations[op_i], positions[i]) + translations[op_i]
        diff = positions[atom_i] - r_pos
        diff -= np.rint(diff)
        assert (diff < symprec).all()
コード例 #13
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 -= np.rint(diff)
                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
コード例 #14
0
        magmom = []
        for numxmag in text.split():
            if '*' in numxmag:
                num, mag = numxmag.split('*')
                magmom += [float(mag)] * int(num)
            else:
                magmom.append(float(numxmag))
        return magmom
    
    def parse_incar(filename):
        for line in open(filename):
            for conf in line.split(';'):
                if 'MAGMOM' in conf:
                    return get_magmom(conf.split('=')[1])
    
    cell = read_vasp("POSCAR")
    symmetry = Symmetry(cell, symprec=1e-3)
    map_nonspin = symmetry.get_map_atoms()
    print "Number of operations w/o spin", len(symmetry.get_symmetry_operations()['rotations'])
    magmoms = parse_incar("INCAR")
    cell.set_magnetic_moments(magmoms)
    symmetry = Symmetry(cell, symprec=1e-3)
    print "Number of operations w spin", len(symmetry.get_symmetry_operations()['rotations'])
    map_withspin = symmetry.get_map_atoms()
    if ((map_nonspin - map_withspin) == 0).all():
        print True
    else:
        print False
        print map_nonspin
        print map_withspin
コード例 #15
0
            if '*' in numxmag:
                num, mag = numxmag.split('*')
                magmom += [float(mag)] * int(num)
            else:
                magmom.append(float(numxmag))
        return magmom

    def parse_incar(filename):
        for line in open(filename):
            for conf in line.split(';'):
                if 'MAGMOM' in conf:
                    return get_magmom(conf.split('=')[1])

    cell = read_vasp("POSCAR")
    symmetry = Symmetry(cell, symprec=1e-3)
    map_nonspin = symmetry.get_map_atoms()
    print("Number of operations w/o spin %d" %
          len(symmetry.get_symmetry_operations()['rotations']))
    magmoms = parse_incar("INCAR")
    cell.set_magnetic_moments(magmoms)
    symmetry = Symmetry(cell, symprec=1e-3)
    print("Number of operations w spin %d" %
          len(symmetry.get_symmetry_operations()['rotations']))
    map_withspin = symmetry.get_map_atoms()
    if ((map_nonspin - map_withspin) == 0).all():
        print(True)
    else:
        print(False)
        print(map_nonspin)
        print(map_withspin)
コード例 #16
0
ファイル: vasp.py プロジェクト: arbegla/phonopy
def get_born_OUTCAR(poscar_filename="POSCAR",
                    outcar_filename="OUTCAR",
                    primitive_axis=np.eye(3),
                    supercell_matrix=np.eye(3, dtype='intc'),
                    is_symmetry=True,
                    symmetrize_tensors=False):
    ucell = read_vasp(poscar_filename)
    scell = get_supercell(ucell, supercell_matrix)
    inv_smat = np.linalg.inv(supercell_matrix)
    pcell = get_primitive(scell, np.dot(inv_smat, primitive_axis))
    u_sym = Symmetry(ucell, is_symmetry=is_symmetry)
    p_sym = Symmetry(pcell, is_symmetry=is_symmetry)
    lattice = ucell.get_cell().T
    outcar = open(outcar_filename)
    
    borns = []
    while True:
        line = outcar.readline()
        if not line:
            break
    
        if "NIONS" in line:
            num_atom = int(line.split()[11])
    
        if "MACROSCOPIC STATIC DIELECTRIC TENSOR" in line:
            epsilon = []
            outcar.readline()
            epsilon.append([float(x) for x in outcar.readline().split()])
            epsilon.append([float(x) for x in outcar.readline().split()])
            epsilon.append([float(x) for x in outcar.readline().split()])
    
        if "BORN" in line:
            outcar.readline()
            line = outcar.readline()
            if "ion" in line:
                for i in range(num_atom):
                    born = []
                    born.append([float(x)
                                 for x in outcar.readline().split()][1:])
                    born.append([float(x)
                                 for x in outcar.readline().split()][1:])
                    born.append([float(x)
                                 for x in outcar.readline().split()][1:])
                    outcar.readline()
                    borns.append(born)

    borns = np.array(borns, dtype='double')
    epsilon = np.array(epsilon, dtype='double')
    if symmetrize_tensors:
        borns_orig = borns.copy()
        point_sym = [similarity_transformation(lattice, r)
                     for r in u_sym.get_pointgroup_operations()]
        epsilon = symmetrize_tensor(epsilon, point_sym)
        for i in range(num_atom):
            z = borns[i]
            site_sym = [similarity_transformation(lattice, r)
                        for r in u_sym.get_site_symmetry(i)]
            borns[i] = symmetrize_tensor(z, site_sym)

        rotations = u_sym.get_symmetry_operations()['rotations']
        map_atoms = u_sym.get_map_atoms()
        borns_copy = np.zeros_like(borns)
        for i, m_i in enumerate(map_atoms):
            count = 0
            for j, r_j in enumerate(u_sym.get_map_operations()):
                if map_atoms[j] == m_i:
                    count += 1
                    r_cart = similarity_transformation(lattice, rotations[r_j])
                    borns_copy[i] += similarity_transformation(r_cart, borns[j])
            borns_copy[i] /= count

        borns = borns_copy
        sum_born = borns.sum(axis=0) / len(borns)
        borns -= sum_born

        if (np.abs(borns_orig - borns) > 0.1).any():
            sys.stderr.write(
                "Born effective charge symmetrization might go wrong.\n")
        
    p2s = np.array(pcell.get_primitive_to_supercell_map(), dtype='intc')
    s_indep_atoms = p2s[p_sym.get_independent_atoms()]
    u2u = scell.get_unitcell_to_unitcell_map()
    u_indep_atoms = [u2u[x] for x in s_indep_atoms]
    reduced_borns = borns[u_indep_atoms].copy()

    return reduced_borns, epsilon