def _calculate(self): unique_first_atom_nums = np.unique( [x['number'] for x in self._dataset['first_atoms']]) for first_atom_num in unique_first_atom_nums: disp_pairs = [] sets_of_forces = [] for dataset_1st in self._dataset['first_atoms']: if first_atom_num != dataset_1st['number']: continue d, f = self._collect_disp_pairs_and_forces(dataset_1st) disp_pairs.append(d) sets_of_forces.append(f) self._fit(first_atom_num, disp_pairs, sets_of_forces) rotations = self._symmetry.get_symmetry_operations()['rotations'] translations = self._symmetry.get_symmetry_operations()['translations'] print "ditributing fc3..." distribute_fc3(self._fc3, unique_first_atom_nums, self._lattice, self._positions, rotations, translations, self._symprec, self._verbose)
def _calculate(self): unique_first_atom_nums = np.unique( [x['number'] for x in self._dataset['first_atoms']]) for first_atom_num in unique_first_atom_nums: disp_triplets = [] sets_of_forces = [] for dataset_1st in self._dataset['first_atoms']: if first_atom_num != dataset_1st['number']: continue d1 = dataset_1st['displacement'] d3, f = self._collect_forces_and_disps(dataset_1st) disp_triplets.append(d3) sets_of_forces.append(f) self._fit(first_atom_num, disp_triplets, sets_of_forces) rotations = self._symmetry.get_symmetry_operations()['rotations'] translations = self._symmetry.get_symmetry_operations()['translations'] print "ditributing fc4..." distribute_fc4(self._fc4, unique_first_atom_nums, self._lattice, self._positions, rotations, translations, self._symprec, self._verbose) print "ditributing fc3..." distribute_fc3(self._fc3, unique_first_atom_nums, self._lattice, self._positions, rotations, translations, self._symprec, self._verbose) print "ditributing fc2..." distribute_force_constants(self._fc2, range(self._num_atom), unique_first_atom_nums, self._lattice, self._positions, rotations, translations, self._symprec)
def _calculate(self): unique_first_atom_nums = np.unique( [x['number'] for x in self._dataset['first_atoms']]) for first_atom_num in unique_first_atom_nums: disp_pairs = [] sets_of_forces = [] for dataset_1st in self._dataset['first_atoms']: if first_atom_num != dataset_1st['number']: continue d, f = self._collect_disp_pairs_and_forces(dataset_1st) disp_pairs.append(d) sets_of_forces.append(f) self._fit(first_atom_num, disp_pairs, sets_of_forces) rotations = self._symmetry.get_symmetry_operations()['rotations'] translations = self._symmetry.get_symmetry_operations()['translations'] print "ditributing fc3..." fc3 = distribute_fc3(self._fc3, unique_first_atom_nums, self._lattice, self._positions, rotations, translations, self._symprec, self._verbose) self._fc3 = 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
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