def get_fourth_order_displacements(cell, symmetry, is_plusminus='auto', is_diagonal=False): # Atoms 1, 2, and 3 are defined as follows: # # Atom 1: The first displaced atom. Fourth order force constant # between Atoms 1, 2, 3, and 4 is calculated. # Atom 2: The second displaced atom. Third order force constant # between Atoms 2, 3, and 4 is calculated. # Atom 3: The third displaced atom. Second order force constant # between Atoms 3 and 4 is calculated. # Atom 4: Force is mesuared on this atom. # Least displacements for third order force constants # # Data structure # [{'number': atom1, # 'displacement': [0.00000, 0.007071, 0.007071], # 'second_atoms': [ {'number': atom2, # 'displacement': [0.007071, 0.000000, 0.007071], # 'third_atoms': [ {'number': atom3, # 'displacements': # [[-0.007071, 0.000000, -0.007071], # ,...]}, {...}, ... ]}, # Least displacements of first atoms (Atom 1) are searched by # using respective site symmetries of the original crystal. disps_first = get_least_displacements(symmetry, is_plusminus=is_plusminus, is_diagonal=False) symprec = symmetry.get_symmetry_tolerance() dds = [] for disp in disps_first: atom1 = disp[0] disp1 = disp[1:4] site_sym = symmetry.get_site_symmetry(atom1) dds_atom1 = {'number': atom1, 'direction': disp1, 'second_atoms': []} reduced_site_sym = get_reduced_site_symmetry(site_sym, disp1, symprec) second_atoms = get_least_orbits(atom1, cell, reduced_site_sym, symprec) for atom2 in second_atoms: reduced_bond_sym = get_bond_symmetry(reduced_site_sym, cell.get_scaled_positions(), atom1, atom2, symprec) for disp2 in _get_displacements_second(reduced_bond_sym, symprec, is_diagonal): dds_atom2 = _get_second_displacements(atom2, disp2, cell, reduced_bond_sym, symprec, is_diagonal) dds_atom1['second_atoms'].append(dds_atom2) dds.append(dds_atom1) write_supercells_with_three_displacements(cell, dds) return dds
def _distribute_displacements_and_forces(self, set_of_disps, sets_of_forces, first_atom_num, disp1, unique_second_atom_nums): site_symmetry = self._symmetry.get_site_symmetry(first_atom_num) direction = np.dot(np.linalg.inv(self._lattice), disp1) reduced_site_sym = get_reduced_site_symmetry(site_symmetry, direction, self._symprec) positions = self._positions.copy() - self._positions[first_atom_num] rot_map_syms = get_positions_sent_by_rot_inv(self._lattice, positions, reduced_site_sym, self._symprec) disp_pairs = [] for second_atom_num in range(self._num_atom): if set_of_disps[second_atom_num] is None: (sets_of_forces_atom2, set_of_disps_atom2) = self._copy_dataset_2nd( second_atom_num, set_of_disps, sets_of_forces, unique_second_atom_nums, reduced_site_sym, rot_map_syms) disp_pairs.append([[disp1, d] for d in set_of_disps_atom2]) sets_of_forces[second_atom_num] = sets_of_forces_atom2 else: disp_pairs.append([[disp1, d] for d in set_of_disps[second_atom_num]]) return disp_pairs, sets_of_forces
def _get_second_displacements(atom2, disp2, cell, reduced_bond_sym, symprec, is_diagonal): positions = cell.get_scaled_positions() dds_atom2 = {'number': atom2, 'direction': disp2, 'third_atoms': []} reduced_bond_sym2 = get_reduced_site_symmetry(reduced_bond_sym, disp2, symprec) third_atoms = get_least_orbits(atom2, cell, reduced_bond_sym2, symprec) for atom3 in third_atoms: reduced_plane_sym = get_bond_symmetry( reduced_bond_sym2, cell.get_scaled_positions(), atom2, atom3, symprec) dds_atom3 = get_next_displacements(atom2, atom3, reduced_plane_sym, positions, symprec, is_diagonal) dds_atom2['third_atoms'].append(dds_atom3) return dds_atom2
def _distribute_displacements_and_forces(self, set_of_disps, sets_of_forces, first_atom_num, disp1, unique_second_atom_nums): site_symmetry = self._symmetry.get_site_symmetry(first_atom_num) direction = np.dot(np.linalg.inv(self._lattice), disp1) reduced_site_sym = get_reduced_site_symmetry( site_symmetry, direction, self._symprec) positions = self._positions.copy() - self._positions[first_atom_num] rot_map_syms = get_positions_sent_by_rot_inv(positions, reduced_site_sym, self._symprec) disp_pairs = [] for second_atom_num in range(self._num_atom): if set_of_disps[second_atom_num] is None: (sets_of_forces_atom2, set_of_disps_atom2) = self._copy_dataset_2nd( second_atom_num, set_of_disps, sets_of_forces, unique_second_atom_nums, reduced_site_sym, rot_map_syms) disp_pairs.append( [[disp1, d] for d in set_of_disps_atom2]) sets_of_forces[second_atom_num] = sets_of_forces_atom2 else: disp_pairs.append( [[disp1, d] for d in set_of_disps[second_atom_num]]) return disp_pairs, sets_of_forces
def _get_fc3_one_atom(fc3, supercell, disp_dataset, fc2, first_atom_num, site_symmetry, translational_symmetry_type, is_permutation_symmetry, symprec, verbose): displacements_first = [] delta_fc2s = [] for dataset_first_atom in disp_dataset['first_atoms']: if first_atom_num != dataset_first_atom['number']: continue displacements_first.append(dataset_first_atom['displacement']) if 'delta_fc2' in dataset_first_atom: delta_fc2s.append(dataset_first_atom['delta_fc2']) else: direction = np.dot(dataset_first_atom['displacement'], np.linalg.inv(supercell.get_cell())) reduced_site_sym = get_reduced_site_symmetry( site_symmetry, direction, symprec) delta_fc2s.append( get_delta_fc2(dataset_first_atom['second_atoms'], dataset_first_atom['number'], fc2, supercell, reduced_site_sym, translational_symmetry_type, is_permutation_symmetry, symprec)) solve_fc3(fc3, first_atom_num, supercell, site_symmetry, displacements_first, delta_fc2s, symprec, verbose=verbose)
def _get_reduced_site_sym(self, dataset_1st): disp1 = dataset_1st['displacement'] first_atom_num = dataset_1st['number'] site_symmetry = self._symmetry.get_site_symmetry(first_atom_num) direction = np.dot(np.linalg.inv(self._lattice), disp1) reduced_site_sym = get_reduced_site_symmetry(site_symmetry, direction, self._symprec) return reduced_site_sym
def _get_fc4_one_atom(fc4, supercell, disp_dataset, fc3, first_atom_num, site_symmetry, translational_symmetry_type, is_permutation_symmetry, symprec, verbose): displacements_first = [] delta_fc3s = [] for dataset_first_atom in disp_dataset['first_atoms']: if first_atom_num != dataset_first_atom['number']: continue displacements_first.append(dataset_first_atom['displacement']) direction = np.dot(dataset_first_atom['displacement'], np.linalg.inv(supercell.get_cell())) reduced_site_sym = get_reduced_site_symmetry( site_symmetry, direction, symprec) if verbose: print "Solving fc4[ %d, x, x, x ] with" % (first_atom_num + 1), if len(displacements_first) > 1: print "displacements:" else: print "a displacement:" for i, v in enumerate(displacements_first): print " [%7.4f %7.4f %7.4f]" % tuple(v) sys.stdout.flush() delta_fc3s.append(_get_delta_fc3( dataset_first_atom, fc3, supercell, reduced_site_sym, translational_symmetry_type, is_permutation_symmetry, symprec, verbose)) _solve_fc4(fc4, first_atom_num, supercell, site_symmetry, displacements_first, np.array(delta_fc3s, dtype='double', order='C'), symprec) if verbose > 2: print "Site symmetry:" for i, v in enumerate(site_symmetry): print " [%2d %2d %2d] #%2d" % tuple(list(v[0])+[i+1]) print " [%2d %2d %2d]" % tuple(v[1]) print " [%2d %2d %2d]\n" % tuple(v[2]) sys.stdout.flush()
def _get_reduced_site_sym(self, dataset_1st): disp1 = dataset_1st['displacement'] first_atom_num = dataset_1st['number'] site_symmetry = self._symmetry.get_site_symmetry(first_atom_num) direction = np.dot(np.linalg.inv(self._lattice), disp1) reduced_site_sym = get_reduced_site_symmetry(site_symmetry, direction, self._symprec) return reduced_site_sym
def _get_reduced_bond_sym(self, reduced_site_sym, first_atom_num, second_atom_num, disp2): bond_sym = get_bond_symmetry(reduced_site_sym, self._positions, first_atom_num, second_atom_num, self._symprec) direction = np.dot(np.linalg.inv(self._lattice), disp2) reduced_bond_sym = get_reduced_site_symmetry(bond_sym, direction, self._symprec) return reduced_bond_sym
def _get_fc4_one_atom(fc4, supercell, disp_dataset, fc3, first_atom_num, site_symmetry, is_translational_symmetry, is_permutation_symmetry, symprec, verbose): displacements_first = [] delta_fc3s = [] for dataset_first_atom in disp_dataset['first_atoms']: if first_atom_num != dataset_first_atom['number']: continue displacements_first.append(dataset_first_atom['displacement']) direction = np.dot(dataset_first_atom['displacement'], np.linalg.inv(supercell.get_cell())) reduced_site_sym = get_reduced_site_symmetry( site_symmetry, direction, symprec) if verbose: print ("First displacements for fc4[ %d, x, x, x ]" % (first_atom_num + 1)) for i, v in enumerate(displacements_first): print " [%7.4f %7.4f %7.4f]" % tuple(v) sys.stdout.flush() delta_fc3s.append(_get_delta_fc3( dataset_first_atom, fc3, supercell, reduced_site_sym, is_translational_symmetry, is_permutation_symmetry, symprec, verbose)) _solve_fc4(fc4, first_atom_num, supercell, site_symmetry, displacements_first, np.double(delta_fc3s), symprec) if verbose > 2: print "Site symmetry:" for i, v in enumerate(site_symmetry): print " [%2d %2d %2d] #%2d" % tuple(list(v[0])+[i+1]) print " [%2d %2d %2d]" % tuple(v[1]) print " [%2d %2d %2d]\n" % tuple(v[2]) sys.stdout.flush()
def _get_fc3_one_atom(fc3, supercell, disp_dataset, fc2, first_atom_num, site_symmetry, is_translational_symmetry, is_permutation_symmetry, symprec, verbose): displacements_first = [] delta_fc2s = [] for dataset_first_atom in disp_dataset['first_atoms']: if first_atom_num != dataset_first_atom['number']: continue displacements_first.append(dataset_first_atom['displacement']) if 'delta_fc2' in dataset_first_atom: delta_fc2s.append(dataset_first_atom['delta_fc2']) else: direction = np.dot(dataset_first_atom['displacement'], np.linalg.inv(supercell.get_cell())) reduced_site_sym = get_reduced_site_symmetry( site_symmetry, direction, symprec) delta_fc2s.append(get_delta_fc2( dataset_first_atom['second_atoms'], dataset_first_atom['number'], fc2, supercell, reduced_site_sym, is_translational_symmetry, is_permutation_symmetry, symprec)) solve_fc3(fc3, first_atom_num, supercell, site_symmetry, displacements_first, delta_fc2s, symprec) if verbose: print "Displacements for fc3[ %d, x, x ]" % (first_atom_num + 1) for i, v in enumerate(displacements_first): print " [%7.4f %7.4f %7.4f]" % tuple(v) sys.stdout.flush() if verbose > 2: print "Site symmetry:" for i, v in enumerate(site_symmetry): print " [%2d %2d %2d] #%2d" % tuple(list(v[0])+[i+1]) print " [%2d %2d %2d]" % tuple(v[1]) print " [%2d %2d %2d]\n" % tuple(v[2]) sys.stdout.flush()
def get_fourth_order_displacements(cell, symmetry, is_plusminus="auto", is_diagonal=False): # Atoms 1, 2, and 3 are defined as follows: # # Atom 1: The first displaced atom. Fourth order force constant # between Atoms 1, 2, 3, and 4 is calculated. # Atom 2: The second displaced atom. Third order force constant # between Atoms 2, 3, and 4 is calculated. # Atom 3: The third displaced atom. Second order force constant # between Atoms 3 and 4 is calculated. # Atom 4: Force is mesuared on this atom. # Least displacements for third order force constants # # Data structure # [{'number': atom1, # 'displacement': [0.00000, 0.007071, 0.007071], # 'second_atoms': [ {'number': atom2, # 'displacement': [0.007071, 0.000000, 0.007071], # 'third_atoms': [ {'number': atom3, # 'displacements': # [[-0.007071, 0.000000, -0.007071], # ,...]}, {...}, ... ]}, # Least displacements of first atoms (Atom 1) are searched by # using respective site symmetries of the original crystal. disps_first = get_least_displacements(symmetry, is_plusminus=is_plusminus, is_diagonal=False) symprec = symmetry.get_symmetry_tolerance() dds = [] for disp in disps_first: atom1 = disp[0] disp1 = disp[1:4] site_sym = symmetry.get_site_symmetry(atom1) dds_atom1 = {"number": atom1, "direction": disp1, "second_atoms": []} reduced_site_sym = get_reduced_site_symmetry(site_sym, disp1, symprec) second_atoms = get_least_orbits(atom1, cell, reduced_site_sym, symprec) for atom2 in second_atoms: reduced_bond_sym = get_bond_symmetry(reduced_site_sym, cell.get_scaled_positions(), atom1, atom2, symprec) for disp2 in _get_displacements_second(reduced_bond_sym, symprec, is_diagonal): dds_atom2 = _get_second_displacements(atom2, disp2, cell, reduced_bond_sym, symprec, is_diagonal) dds_atom1["second_atoms"].append(dds_atom2) dds.append(dds_atom1) write_supercells_with_three_displacements(cell, dds) return dds
def _get_fc3_done(supercell, disp_dataset, symmetry): num_atom = supercell.get_number_of_atoms() fc3_done = np.zeros((num_atom, num_atom, num_atom), dtype='byte') symprec = symmetry.get_symmetry_tolerance() positions = supercell.get_scaled_positions() rotations = symmetry.get_symmetry_operations()['rotations'] translations = symmetry.get_symmetry_operations()['translations'] atom_mapping = [] for rot, trans in zip(rotations, translations): atom_indices = [] for rot_pos in (np.dot(positions, rot.T) + trans): diff = positions - rot_pos diff -= np.rint(diff) atom_indices.append( np.where((np.abs(diff) < symprec).all(axis=1))[0][0]) atom_mapping.append(atom_indices) for dataset_first_atom in disp_dataset['first_atoms']: first_atom_num = dataset_first_atom['number'] site_symmetry = symmetry.get_site_symmetry(first_atom_num) direction = np.dot(dataset_first_atom['displacement'], np.linalg.inv(supercell.get_cell())) reduced_site_sym = get_reduced_site_symmetry( site_symmetry, direction, symprec) least_second_atom_nums = [] for second_atoms in dataset_first_atom['second_atoms']: if second_atoms['included']: least_second_atom_nums.append(second_atoms['number']) positions_shifted = positions - positions[first_atom_num] least_second_atom_nums = np.unique(least_second_atom_nums) second_atom_nums = [] for red_rot in reduced_site_sym: for i in least_second_atom_nums: second_atom_nums.append( get_atom_by_symmetry(positions_shifted, red_rot, np.zeros(3, dtype='double'), i, symprec)) second_atom_nums = np.unique(second_atom_nums) for i in range(len(rotations)): rotated_atom1 = atom_mapping[i][first_atom_num] for j in second_atom_nums: fc3_done[rotated_atom1, atom_mapping[i][j]] = 1 return fc3_done
def _get_reduced_bond_sym(self, reduced_site_sym, first_atom_num, second_atom_num, disp2): bond_sym = get_bond_symmetry( reduced_site_sym, self._positions, first_atom_num, second_atom_num, self._symprec) direction = np.dot(np.linalg.inv(self._lattice), disp2) reduced_bond_sym = get_reduced_site_symmetry( bond_sym, direction, self._symprec) return reduced_bond_sym
def _get_second_displacements(atom2, disp2, cell, reduced_bond_sym, symprec, is_diagonal): positions = cell.get_scaled_positions() dds_atom2 = {'number': atom2, 'direction': disp2, 'third_atoms': []} reduced_bond_sym2 = get_reduced_site_symmetry(reduced_bond_sym, disp2, symprec) third_atoms = get_least_orbits(atom2, cell, reduced_bond_sym2, symprec) for atom3 in third_atoms: reduced_plane_sym = get_bond_symmetry(reduced_bond_sym2, cell.get_scaled_positions(), atom2, atom3, symprec) dds_atom3 = get_next_displacements(atom2, atom3, reduced_plane_sym, positions, symprec, is_diagonal) dds_atom2['third_atoms'].append(dds_atom3) return dds_atom2
def _get_fc3_one_atom(fc3, supercell, disp_dataset, fc2, first_atom_num, site_symmetry, translational_symmetry_type, is_permutation_symmetry, symprec, verbose): displacements_first = [] delta_fc2s = [] for dataset_first_atom in disp_dataset['first_atoms']: if first_atom_num != dataset_first_atom['number']: continue displacements_first.append(dataset_first_atom['displacement']) if 'delta_fc2' in dataset_first_atom: delta_fc2s.append(dataset_first_atom['delta_fc2']) else: direction = np.dot(dataset_first_atom['displacement'], np.linalg.inv(supercell.get_cell())) reduced_site_sym = get_reduced_site_symmetry( site_symmetry, direction, symprec) delta_fc2s.append(get_delta_fc2( dataset_first_atom['second_atoms'], dataset_first_atom['number'], fc2, supercell, reduced_site_sym, translational_symmetry_type, is_permutation_symmetry, symprec)) solve_fc3(fc3, first_atom_num, supercell, site_symmetry, displacements_first, delta_fc2s, symprec, verbose=verbose)
def _get_fc3_one_atom(fc3, supercell, disp_dataset, fc2, first_atom_num, site_symmetry, translational_symmetry_type, is_permutation_symmetry, symprec, verbose): displacements_first = [] delta_fc2s = [] for dataset_first_atom in disp_dataset['first_atoms']: if first_atom_num != dataset_first_atom['number']: continue displacements_first.append(dataset_first_atom['displacement']) if 'delta_fc2' in dataset_first_atom: delta_fc2s.append(dataset_first_atom['delta_fc2']) else: direction = np.dot(dataset_first_atom['displacement'], np.linalg.inv(supercell.get_cell())) reduced_site_sym = get_reduced_site_symmetry( site_symmetry, direction, symprec) delta_fc2s.append( get_delta_fc2(dataset_first_atom['second_atoms'], dataset_first_atom['number'], fc2, supercell, reduced_site_sym, translational_symmetry_type, is_permutation_symmetry, symprec)) solve_fc3(fc3, first_atom_num, supercell, site_symmetry, displacements_first, delta_fc2s, symprec) if verbose: print "- Displacements for fc3[ %d, x, x ]" % (first_atom_num + 1) for i, v in enumerate(displacements_first): print " [%7.4f %7.4f %7.4f]" % tuple(v) sys.stdout.flush() if verbose > 2: print " Site symmetry:" for i, v in enumerate(site_symmetry): print " [%2d %2d %2d] #%2d" % tuple(list(v[0]) + [i + 1]) print " [%2d %2d %2d]" % tuple(v[1]) print " [%2d %2d %2d]\n" % tuple(v[2]) sys.stdout.flush()
def _get_constrained_fc3(supercell, displacements, reduced_site_sym, is_translational_symmetry, is_permutation_symmetry, symprec, verbose): """ Two displacements and force constants calculation (e.g. DFPT) displacements = {'number': 3, 'displacement': [0.01, 0.00, 0.01] 'second_atoms': [{'number': 7, 'displacement': [], 'delta_fc2': }]} Three displacements and force calculation displacements = {'number': 3, 'displacement': [0.01, 0.00, 0.01] 'second_atoms': [{'number': 7, 'displacement': [], 'third_atoms': ... }]} third_atoms is like: 'third_atoms': [{'number': 56, 'displacement': [], 'delta_forces': ... }]} """ num_atom = supercell.get_number_of_atoms() atom1 = displacements['number'] disp1 = displacements['displacement'] fc3 = np.zeros((num_atom, num_atom, num_atom, 3, 3, 3), dtype='double') atom_list_done = [] if 'delta_forces' in displacements['second_atoms'][0]: fc2_with_one_disp = get_constrained_fc2(supercell, displacements['second_atoms'], atom1, reduced_site_sym, is_translational_symmetry, is_permutation_symmetry, symprec) atom_list = np.unique([x['number'] for x in displacements['second_atoms']]) for atom2 in atom_list: disps2 = [] delta_fc2s = [] for disps_second in displacements['second_atoms']: if atom2 != disps_second['number']: continue atom_list_done.append(atom2) bond_sym = get_bond_symmetry( reduced_site_sym, supercell.get_scaled_positions(), atom1, atom2, symprec) disps2.append(disps_second['displacement']) if 'delta_fc2' in disps_second: delta_fc2s.append(disps_second['delta_fc2']) else: direction = np.dot(disps_second['displacement'], np.linalg.inv(supercell.get_cell())) reduced_bond_sym = get_reduced_site_symmetry( bond_sym, direction, symprec) delta_fc2s.append(get_delta_fc2( disps_second['third_atoms'], atom2, fc2_with_one_disp, supercell, reduced_bond_sym, is_translational_symmetry, is_permutation_symmetry, symprec)) if verbose > 1: print ("Second displacements for fc4[ %d, %d, x, x ]" % (atom1 + 1, atom2 + 1)) for i, v in enumerate(disps2): print " [%7.4f %7.4f %7.4f]" % tuple(v) solve_fc3(fc3, atom2, supercell, bond_sym, disps2, delta_fc2s, symprec=symprec) # Shift positions according to set atom1 is at origin lattice = supercell.get_cell().T positions = supercell.get_scaled_positions() pos_center = positions[atom1].copy() positions -= pos_center if verbose: print "(Copying delta fc3...)" distribute_fc3(fc3, atom_list_done, lattice, positions, np.intc(reduced_site_sym).copy(), np.zeros((len(reduced_site_sym), 3), dtype='double'), symprec, verbose) if is_translational_symmetry: set_translational_invariance_fc3_per_index(fc3) if is_permutation_symmetry: set_permutation_symmetry_fc3(fc3) return fc3
def _get_constrained_fc3(supercell, displacements, reduced_site_sym, translational_symmetry_type, is_permutation_symmetry, symprec, verbose): """ Two displacements and force constants calculation (e.g. DFPT) displacements = {'number': 3, 'displacement': [0.01, 0.00, 0.01] 'second_atoms': [{'number': 7, 'displacement': [], 'delta_fc2': }]} Three displacements and force calculation displacements = {'number': 3, 'displacement': [0.01, 0.00, 0.01] 'second_atoms': [{'number': 7, 'displacement': [], 'third_atoms': ... }]} third_atoms is like: 'third_atoms': [{'number': 56, 'displacement': [], 'delta_forces': ... }]} """ num_atom = supercell.get_number_of_atoms() atom1 = displacements['number'] disp1 = displacements['displacement'] delta_fc3 = np.zeros((num_atom, num_atom, num_atom, 3, 3, 3), dtype='double') if 'delta_forces' in displacements['second_atoms'][0]: fc2_with_one_disp = get_constrained_fc2( supercell, displacements['second_atoms'], atom1, reduced_site_sym, translational_symmetry_type, is_permutation_symmetry, symprec) atom_list = np.unique([x['number'] for x in displacements['second_atoms']]) for atom2 in atom_list: bond_sym = get_bond_symmetry(reduced_site_sym, supercell.get_scaled_positions(), atom1, atom2, symprec) disps2 = [] delta_fc2s = [] for disps_second in displacements['second_atoms']: if atom2 != disps_second['number']: continue disps2.append(disps_second['displacement']) if 'delta_fc2' in disps_second: delta_fc2s.append(disps_second['delta_fc2']) else: direction = np.dot(disps_second['displacement'], np.linalg.inv(supercell.get_cell())) reduced_bond_sym = get_reduced_site_symmetry( bond_sym, direction, symprec) delta_fc2s.append( get_delta_fc2(disps_second['third_atoms'], atom2, fc2_with_one_disp, supercell, reduced_bond_sym, translational_symmetry_type, is_permutation_symmetry, symprec)) if verbose > 1: print("Second displacements for fc4[ %d, %d, x, x ]" % (atom1 + 1, atom2 + 1)) for i, v in enumerate(disps2): print " [%7.4f %7.4f %7.4f]" % tuple(v) solve_fc3(delta_fc3, atom2, supercell, bond_sym, disps2, delta_fc2s, symprec=symprec, verbose=False) # Shift positions according to set atom1 is at origin lattice = supercell.get_cell().T positions = supercell.get_scaled_positions() pos_center = positions[atom1].copy() positions -= pos_center if verbose: print "Expanding delta fc3" distribute_fc3(delta_fc3, atom_list, lattice, positions, np.array(reduced_site_sym, dtype='intc', order='C'), np.zeros((len(reduced_site_sym), 3), dtype='double'), symprec, verbose=verbose) if translational_symmetry_type > 0: set_translational_invariance_fc3_per_index(delta_fc3) if is_permutation_symmetry: set_permutation_symmetry_fc3(delta_fc3) return delta_fc3