def get_constrained_fc2(supercell, dataset_second_atoms, atom1, forces1, reduced_site_sym, symprec): """ dataset_second_atoms: [{'number': 7, 'displacement': [], 'forces': []}, ...] """ lattice = supercell.get_cell().T positions = supercell.get_scaled_positions() num_atom = supercell.get_number_of_atoms() fc2 = np.zeros((num_atom, num_atom, 3, 3), dtype='double') atom_list = np.unique([x['number'] for x in dataset_second_atoms]) for atom2 in atom_list: disps2 = [] sets_of_forces = [] for disps_second in dataset_second_atoms: if atom2 != disps_second['number']: continue bond_sym = get_bond_symmetry( reduced_site_sym, lattice, positions, atom1, atom2, symprec) disps2.append(disps_second['displacement']) sets_of_forces.append(disps_second['forces'] - forces1) solve_force_constants(fc2, atom2, disps2, sets_of_forces, supercell, bond_sym, symprec) # Shift positions according to set atom1 is at origin pos_center = positions[atom1].copy() positions -= pos_center rotations = np.array(reduced_site_sym, dtype='intc', order='C') translations = np.zeros((len(reduced_site_sym), 3), dtype='double', order='C') permutations = compute_all_sg_permutations(positions, rotations, translations, lattice, symprec) distribute_force_constants(fc2, atom_list, lattice, rotations, permutations) return fc2
def get_constrained_fc2(supercell, dataset_second_atoms, atom1, reduced_site_sym, translational_symmetry_type, is_permutation_symmetry, symprec): """ dataset_second_atoms: [{'number': 7, 'displacement': [], 'delta_forces': []}, ...] """ num_atom = supercell.get_number_of_atoms() fc2 = np.zeros((num_atom, num_atom, 3, 3), dtype='double') atom_list = np.unique([x['number'] for x in dataset_second_atoms]) for atom2 in atom_list: disps2 = [] sets_of_forces = [] for disps_second in dataset_second_atoms: if atom2 != disps_second['number']: continue bond_sym = get_bond_symmetry(reduced_site_sym, supercell.get_scaled_positions(), atom1, atom2, symprec) disps2.append(disps_second['displacement']) sets_of_forces.append(disps_second['delta_forces']) solve_force_constants(fc2, atom2, disps2, sets_of_forces, supercell, bond_sym, 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 distribute_force_constants( fc2, range(num_atom), atom_list, lattice, positions, np.array(reduced_site_sym, dtype='intc', order='C'), np.zeros((len(reduced_site_sym), 3), dtype='double'), symprec) if translational_symmetry_type: set_translational_invariance( fc2, translational_symmetry_type=translational_symmetry_type) if is_permutation_symmetry: set_permutation_symmetry(fc2) return fc2
def _get_constrained_fc2(supercell, dataset_second_atoms, atom1, forces1, reduced_site_sym, symprec): """Return fc2 under reduced (broken) site symmetry by first displacement. dataset_second_atoms: [{'number': 7, 'displacement': [], 'forces': []}, ...] """ lattice = supercell.cell.T positions = supercell.scaled_positions num_atom = len(supercell) fc2 = np.zeros((num_atom, num_atom, 3, 3), dtype="double") atom_list = np.unique([x["number"] for x in dataset_second_atoms]) for atom2 in atom_list: disps2 = [] sets_of_forces = [] for disps_second in dataset_second_atoms: if atom2 != disps_second["number"]: continue bond_sym = get_bond_symmetry(reduced_site_sym, lattice, positions, atom1, atom2, symprec) disps2.append(disps_second["displacement"]) sets_of_forces.append(disps_second["forces"] - forces1) solve_force_constants(fc2, atom2, disps2, sets_of_forces, supercell, bond_sym, symprec) # Shift positions according to set atom1 is at origin pos_center = positions[atom1].copy() positions -= pos_center rotations = np.array(reduced_site_sym, dtype="intc", order="C") translations = np.zeros((len(reduced_site_sym), 3), dtype="double", order="C") permutations = compute_all_sg_permutations(positions, rotations, translations, lattice, symprec) distribute_force_constants(fc2, atom_list, lattice, rotations, permutations) return fc2