def setUp(self): self._cells = [] symbols = ['Si'] * 2 + ['O'] * 4 lattice = [[4.65, 0, 0], [0, 4.75, 0], [0, 0, 3.25]] points = [[0.0, 0.0, 0.0], [0.5, 0.5, 0.5], [0.3, 0.3, 0.0], [0.7, 0.7, 0.0], [0.2, 0.8, 0.5], [0.8, 0.2, 0.5]] self._cells.append( PhonopyAtoms(cell=lattice, scaled_positions=points, symbols=symbols)) symbols = ['Si'] * 2 lattice = [[0, 2.73, 2.73], [2.73, 0, 2.73], [2.73, 2.73, 0]] points = [[0.75, 0.75, 0.75], [0.5, 0.5, 0.5]] self._cells.append( PhonopyAtoms(cell=lattice, scaled_positions=points, symbols=symbols)) self._smats = [] self._smats.append(np.diag([1, 2, 3])) self._smats.append([[-1, 1, 1], [1, -1, 1], [1, 1, -1]]) self._fnames = ("SiO2-123.yaml", "Si-conv.yaml")
def read_aims(filename): '''Method to read FHI-aims geometry files in phonopy context.''' cell = [] positions = [] fractional = [] symbols = [] magmoms = [] with open(filename) as f: while True: line = f.readline() if not line: break line = line.split() if line[0] == 'lattice_vector': cell.append([float(x) for x in line[1:4]]) elif line[0].startswith('atom'): fractional.append(line[0] == 'atom_frac') positions.append([float(x) for x in line[1:4]]) symbols.append(line[4]) elif line[0] == 'initial_moment': magmoms.append(float(line[1])) for n, pos in enumerate(positions): if fractional[n]: positions[n] = [ sum([pos[j] * cell[j][i] for j in range(3)]) for i in range(3) ] if len(magmoms) == len(positions): return PhonopyAtoms(cell=cell, symbols=symbols, positions=positions, magmoms=magmoms) else: return PhonopyAtoms(cell=cell, symbols=symbols, positions=positions)
def standardize_cell(structure): import spglib from phonopy.structure.atoms import Atoms as PhonopyAtoms from phonopy.structure.atoms import atom_data bulk = PhonopyAtoms(symbols=[site.kind_name for site in structure.sites], positions=[site.position for site in structure.sites], cell=structure.cell) structure_data = (structure.cell, bulk.get_scaled_positions(), bulk.get_atomic_numbers()) #lattice, refined_positions, numbers = spglib.refine_cell(structure_data, symprec=1e-5) lattice, standardized_positions, numbers = spglib.standardize_cell(structure_data, symprec=1e-5, to_primitive=False, no_idealize=False) symbols = [atom_data[i][1] for i in numbers] # print lattice, standardized_positions, numbers # print [site.kind_name for site in structure.sites] standardized_bulk = PhonopyAtoms(symbols=symbols, scaled_positions=standardized_positions, cell=lattice) # create new aiida structure object standarized = StructureData(cell=standardized_bulk.get_cell()) for position, symbol in zip(standardized_bulk.get_positions(), standardized_bulk.get_chemical_symbols()): standarized.append_atom(position=position, symbols=symbol) return {'standardized_structure': standarized}
def get_cell_settings( supercell_matrix=None, primitive_matrix=None, unitcell=None, supercell=None, unitcell_filename=None, supercell_filename=None, calculator=None, symprec=1e-5, log_level=0, ): """Return crystal structures.""" optional_structure_info = None if primitive_matrix is None or (type(primitive_matrix) is str and primitive_matrix == "auto"): # noqa E129 pmat = "auto" else: pmat = primitive_matrix if unitcell_filename is not None: cell, optional_structure_info = _read_crystal_structure( filename=unitcell_filename, interface_mode=calculator) smat = supercell_matrix if log_level: print('Unit cell structure was read from "%s".' % optional_structure_info[0]) elif supercell_filename is not None: cell, optional_structure_info = read_crystal_structure( filename=supercell_filename, interface_mode=calculator) smat = np.eye(3, dtype="intc", order="C") if log_level: print('Supercell structure was read from "%s".' % optional_structure_info[0]) elif unitcell is not None: cell = PhonopyAtoms(atoms=unitcell) smat = supercell_matrix elif supercell is not None: cell = PhonopyAtoms(atoms=supercell) smat = np.eye(3, dtype="intc", order="C") else: raise RuntimeError("Cell has to be specified.") if optional_structure_info is not None and cell is None: filename = optional_structure_info[0] msg = "'%s' could not be found." % filename raise FileNotFoundError(msg) pmat = get_primitive_matrix(pmat, symprec=symprec) return cell, smat, pmat
def get_cell_settings(phonopy_yaml=None, supercell_matrix=None, primitive_matrix=None, unitcell=None, supercell=None, unitcell_filename=None, supercell_filename=None, calculator=None, symprec=1e-5, log_level=0): optional_structure_info = None if (primitive_matrix is None or (type(primitive_matrix) is str and primitive_matrix == "auto")): pmat = 'auto' else: pmat = primitive_matrix if unitcell_filename is not None: cell, optional_structure_info = _read_crystal_structure( filename=unitcell_filename, interface_mode=calculator) smat = supercell_matrix if log_level: print("Unit cell structure was read from \"%s\"." % optional_structure_info[0]) elif supercell_filename is not None: cell, optional_structure_info = read_crystal_structure( filename=supercell_filename, interface_mode=calculator) smat = np.eye(3, dtype='intc', order='C') if log_level: print("Supercell structure was read from \"%s\"." % optional_structure_info[0]) elif unitcell is not None: cell = PhonopyAtoms(atoms=unitcell) smat = supercell_matrix elif supercell is not None: cell = PhonopyAtoms(atoms=supercell) smat = np.eye(3, dtype='intc', order='C') else: raise RuntimeError("Cell has to be specified.") if optional_structure_info is not None and cell is None: filename = optional_structure_info[0] msg = "'%s' could not be found." % filename raise FileNotFoundError(msg) pmat = _get_primitive_matrix(pmat, cell, symprec) return cell, smat, pmat
def get_properties_from_phonopy(structure, phonopy_input, force_constants): """ Calculate DOS and thermal properties using phonopy (locally) :param structure: Aiida StructureData Object :param phonopy_input: Aiida Parametersdata object containing a dictionary with the data needed to run phonopy: supercells matrix, primitive matrix and q-points mesh. :param force_constants: :return: """ from phonopy.structure.atoms import Atoms as PhonopyAtoms from phonopy import Phonopy # Generate phonopy phonon object bulk = PhonopyAtoms(symbols=[site.kind_name for site in structure.sites], positions=[site.position for site in structure.sites], cell=structure.cell) phonopy_input = phonopy_input.get_dict() force_constants = force_constants.get_array('force_constants') phonon = Phonopy(bulk, phonopy_input['supercell'], primitive_matrix=phonopy_input['primitive']) phonon.set_force_constants(force_constants) #Normalization factor primitive to unit cell normalization_factor = phonon.unitcell.get_number_of_atoms( ) / phonon.primitive.get_number_of_atoms() phonon.set_mesh(phonopy_input['mesh'], is_eigenvectors=True, is_mesh_symmetry=False) phonon.set_total_DOS() phonon.set_partial_DOS() # get DOS (normalized to unit cell) total_dos = phonon.get_total_DOS() * normalization_factor partial_dos = phonon.get_partial_DOS() * normalization_factor # Stores DOS data in DB as a workflow result dos = ArrayData() dos.set_array('frequency', total_dos[0]) dos.set_array('total_dos', total_dos[1]) dos.set_array('partial_dos', partial_dos[1]) #THERMAL PROPERTIES (per primtive cell) phonon.set_thermal_properties() t, free_energy, entropy, cv = phonon.get_thermal_properties() # Stores thermal properties (per unit cell) data in DB as a workflow result thermal_properties = ArrayData() thermal_properties.set_array('temperature', t) thermal_properties.set_array('free_energy', free_energy * normalization_factor) thermal_properties.set_array('entropy', entropy * normalization_factor) thermal_properties.set_array('cv', cv * normalization_factor) return {'thermal_properties': thermal_properties, 'dos': dos}
def get_cell_from_disp_yaml(dataset): """Read cell from disp.yaml like file.""" if "lattice" in dataset: lattice = dataset["lattice"] if "points" in dataset: data_key = "points" pos_key = "coordinates" elif "atoms" in dataset: data_key = "atoms" pos_key = "position" else: data_key = None pos_key = None try: positions = [x[pos_key] for x in dataset[data_key]] except KeyError: msg = ('"disp.yaml" format is too old. ' 'Please re-create it as "phonopy_disp.yaml" to contain ' "supercell crystal structure information.") raise RuntimeError(msg) symbols = [x["symbol"] for x in dataset[data_key]] cell = PhonopyAtoms(cell=lattice, scaled_positions=positions, symbols=symbols, pbc=True) return cell else: return get_cell_from_disp_yaml(dataset["supercell"])
def get_phonon(structure, NAC=False, setup_forces=True, custom_supercell=None): super_cell_phonon = structure.get_supercell_phonon() if not(isinstance(custom_supercell, type(None))): super_cell_phonon = custom_supercell #Preparing the bulk type object bulk = PhonopyAtoms(symbols=structure.get_atomic_types(), scaled_positions=structure.get_scaled_positions(), cell=structure.get_cell().T) phonon = Phonopy(bulk, super_cell_phonon, primitive_matrix=structure.get_primitive_matrix()) # Non Analytical Corrections (NAC) from Phonopy [Frequencies only, eigenvectors no affected by this option] if NAC: print("Phonopy warning: Using Non Analytical Corrections") get_is_symmetry = True #from phonopy: settings.get_is_symmetry() primitive = phonon.get_primitive() nac_params = parse_BORN(primitive, get_is_symmetry) phonon.set_nac_params(nac_params=nac_params) if setup_forces: if not structure.forces_available(): # if not np.array(structure.get_force_constants()).any() and not np.array(structure.get_force_sets()).any(): print('No force sets/constants available!') exit() if np.array(structure.get_force_constants()).any(): phonon.set_force_constants(structure.get_force_constants()) else: phonon.set_displacement_dataset(structure.get_force_sets()) phonon.produce_force_constants(computation_algorithm="svd") return phonon
def analyse_phonopy_equivalent_atoms(atoms, symprec=1e-5, angle_tolerance=-1.0): """ Args: (read phonopy.structure.spglib for more details) symprec: float: Symmetry search tolerance in the unit of length. angle_tolerance: float: Symmetry search tolerance in the unit of angle deg. If the value is negative, an internally optimized routine is used to judge symmetry. """ s.publication_add(publication()) positions = atoms.get_scaled_positions() cell = atoms.cell types = atoms.get_chemical_symbols() types = list(types) natom = len(types) positions = np.reshape(np.array(positions), (natom, 3)) cell = np.reshape(np.array(cell), (3, 3)) unitcell = PhonopyAtoms(symbols=types, cell=cell, scaled_positions=positions) ops = spg.get_symmetry(unitcell, symprec=symprec, angle_tolerance=angle_tolerance) return ops['equivalent_atoms']
def get_phonon_configs(calc, at, disps, scell, config_type): cell = PhonopyAtoms(symbols=at.get_chemical_symbols(), cell=at.get_cell(), positions=at.get_positions()) phonon = Phonopy(cell, np.eye(3) * scell) al = [] for disp in disps: print(disp, config_type) phonon.generate_displacements(distance=disp) supercells = phonon.get_supercells_with_displacements() for (i, scell) in enumerate(supercells): at = ase.Atoms(symbols=scell.get_chemical_symbols(), scaled_positions=scell.get_scaled_positions(), cell=scell.get_cell(), pbc=True) at.set_calculator(calc) e = at.get_potential_energy() f = at.get_forces() v = -1.0 * at.get_volume() * at.get_stress(voigt=False) at.arrays["force"] = f at.info["virial"] = v at.info["config_type"] = "PH_" + config_type at.info["energy_TB"] = e #write("PH_{}_{}_scell_{}.xyz".format(config_type, i, disp), at) al.append(at) return al
def get_data_from_dir(directory, i_volume): data_sets = file_IO.parse_FORCE_SETS( filename=directory + '/phonon-{0:02d}/FORCE_SETS'.format(i_volume)) yaml_file = open( directory + '/phonon-{0:02d}/phonon.yaml'.format(i_volume), 'r') data = yaml.load_all(yaml_file).next() unit_cell = PhonopyAtoms( symbols=[item['symbol'] for item in data['points']], scaled_positions=[item['coordinates'] for item in data['points']], cell=data['lattice']) phonon = Phonopy(unit_cell, data['supercell_matrix']) phonon.set_displacement_dataset(data_sets) phonon.produce_force_constants() force_constants = phonon.get_force_constants() supercell = phonon.get_supercell() volume = unit_cell.get_volume() energy = data['electric_total_energy'] return supercell, volume, energy, force_constants, data['supercell_matrix']
def cell(self): """Return cell in PhonopyAtoms.""" return PhonopyAtoms( symbols=self.symbols, scaled_positions=self.points[-1], cell=self.lattice[-1], )
def get_structure_from_poscar(file_name, number_of_dimensions=3): """ Read crystal structure from a VASP POSCAR type file :param file_name: POSCAR filename :param number_of_dimensions: number of dimensions of the crystal structure :return: Atoms (phonopy) type object containing the crystal structure """ # Check file exists if not os.path.isfile(file_name): print('Structure file does not exist!') exit() # Read from VASP POSCAR file poscar_file = open(file_name, 'r') data_lines = poscar_file.read().split('\n') poscar_file.close() multiply = float(data_lines[1]) direct_cell = np.array([data_lines[i].split() for i in range(2, 2+number_of_dimensions)], dtype=float) direct_cell *= multiply scaled_positions = None positions = None try: number_of_types = np.array(data_lines[3+number_of_dimensions].split(),dtype=int) coordinates_type = data_lines[4+number_of_dimensions][0] if coordinates_type == 'D' or coordinates_type == 'd' : scaled_positions = np.array([data_lines[8+k].split()[0:3] for k in range(np.sum(number_of_types))],dtype=float) else: positions = np.array([data_lines[8+k].split()[0:3] for k in range(np.sum(number_of_types))],dtype=float) atomic_types = [] for i,j in enumerate(data_lines[5].split()): atomic_types.append([j]*number_of_types[i]) atomic_types = [item for sublist in atomic_types for item in sublist] # Old style POSCAR format except ValueError: number_of_types = np.array(data_lines[5].split(), dtype=int) coordinates_type = data_lines[6][0] if coordinates_type == 'D' or coordinates_type == 'd': scaled_positions = np.array([data_lines[7+k].split()[0:3] for k in range(np.sum(number_of_types))], dtype=float) else: positions = np.array([data_lines[7+k].split()[0:3] for k in range(np.sum(number_of_types))], dtype=float) atomic_types = [] for i,j in enumerate(data_lines[0].split()): atomic_types.append([j]*number_of_types[i]) atomic_types = [item for sublist in atomic_types for item in sublist] return PhonopyAtoms(symbols=atomic_types, scaled_positions=scaled_positions, cell=direct_cell)
def convcell_cr() -> PhonopyAtoms: """Return PhonopyAtoms class instance of primitive cell of Cr.""" symbols = ["Cr"] * 2 a = 2.812696943681890 lattice = [[a, 0, 0], [0, a, 0], [0, 0, a]] points = [[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]] return PhonopyAtoms(cell=lattice, scaled_positions=points, symbols=symbols)
def primcell_nacl() -> PhonopyAtoms: """Return PhonopyAtoms class instance of primitive cell of NaCl.""" symbols = ["Na", "Cl"] x = 5.6903014761756712 / 2 lattice = [[0, x, x], [x, 0, x], [x, x, 0]] points = [[0, 0, 0], [0.5, 0.5, 0.5]] return PhonopyAtoms(cell=lattice, scaled_positions=points, symbols=symbols)
def read_phonopy(sposcar='SPOSCAR', sc_mat=np.eye(3), force_constants=None, disp_yaml=None, force_sets=None): if force_constants is None and (disp_yaml is None or force_sets is None): raise ValueError( "Either FORCE_CONSTANTS or (disp.yaml&FORCE_SETS) file should be provided." ) atoms = read(sposcar) #vesta_view(atoms) primitive_matrix = inv(sc_mat) bulk = PhonopyAtoms(symbols=atoms.get_chemical_symbols(), scaled_positions=atoms.get_scaled_positions(), cell=atoms.get_cell()) phonon = Phonopy( bulk, supercell_matrix=np.eye(3), primitive_matrix=primitive_matrix, #factor=factor, #symprec=symprec ) if disp_yaml is not None: disp = parse_disp_yaml(filename=disp_yaml) phonon.set_displacement_dataset(disp) if force_sets is not None: fc = parse_FORCE_SETS(filename=force_sets) phonon.set_forces(fc) fc = parse_FORCE_CONSTANTS(force_constants) phonon.set_force_constants(fc) return phonon
def test_structure_to_phonopy_atoms(sc_structure): actual = structure_to_phonopy_atoms(sc_structure) expected = PhonopyAtoms(symbols=["H"], cell=np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]), scaled_positions=np.array([[0.0, 0.0, 0.0]])) assert_same_phonopy_atoms(actual, expected)
def write_yaml(self, labels=None, comment=None, filename="band.yaml"): with open(filename, 'w') as w: natom = self._cell.get_number_of_atoms() rec_lattice = np.linalg.inv( self._cell.get_cell()) # column vectors smat = self._supercell.get_supercell_matrix() pmat = self._cell.get_primitive_matrix() tmat = np.rint(np.dot(np.linalg.inv(pmat), smat)).astype(int) nq_paths = [] for qpoints in self._paths: nq_paths.append(len(qpoints)) text = [] if comment is not None: try: import yaml text.append( yaml.dump(comment, default_flow_style=False).rstrip()) except ImportError: print("You need to install python-yaml.") print("Additional comments were not written in %s." % filename) text.append("nqpoint: %-7d" % np.sum(nq_paths)) text.append("npath: %-7d" % len(self._paths)) text.append("segment_nqpoint:") text += ["- %d" % nq for nq in nq_paths] text.append("reciprocal_lattice:") for vec, axis in zip(rec_lattice.T, ('a*', 'b*', 'c*')): text.append("- [ %12.8f, %12.8f, %12.8f ] # %2s" % (tuple(vec) + (axis, ))) text.append("natom: %-7d" % (natom)) text.append(str(PhonopyAtoms(atoms=self._cell))) text.append("supercell_matrix:") for v in tmat: text.append("- [ %4d, %4d, %4d ]" % tuple(v)) text.append('') text.append("phonon:") text.append('') w.write("\n".join(text)) for i in range(len(self._paths)): qpoints = self._paths[i] distances = self._distances[i] frequencies = self._frequencies[i] if self._group_velocities is None: group_velocities = None else: group_velocities = self._group_velocities[i] if self._eigenvectors is None: eigenvectors = None else: eigenvectors = self._eigenvectors[i] _labels = None if labels is not None: if len(labels) == len(self._paths) + 1: _labels = (labels[i], labels[i + 1]) w.write("\n".join( self._get_q_segment_yaml(qpoints, distances, frequencies, eigenvectors, group_velocities, _labels)))
def get_cell_from_disp_yaml(dataset): if 'lattice' in dataset: lattice = dataset['lattice'] if 'points' in dataset: data_key = 'points' pos_key = 'coordinates' elif 'atoms' in dataset: data_key = 'atoms' pos_key = 'position' else: data_key = None pos_key = None try: positions = [x[pos_key] for x in dataset[data_key]] except KeyError: msg = ("\"disp.yaml\" format is too old. " "Please re-create it as \"phonopy_disp.yaml\" to contain " "supercell crystal structure information.") raise RuntimeError(msg) symbols = [x['symbol'] for x in dataset[data_key]] cell = PhonopyAtoms(cell=lattice, scaled_positions=positions, symbols=symbols, pbc=True) return cell else: return get_cell_from_disp_yaml(dataset['supercell'])
def check_symmetry(phonon, optional_structure_info): # Assumed that primitive cell is the cell that user is interested in. print(_get_symmetry_yaml(phonon.primitive, phonon.primitive_symmetry, phonon.version)) if phonon.unitcell.magnetic_moments is None: base_fname = get_default_cell_filename(phonon.calculator) symprec = phonon.primitive_symmetry.get_symmetry_tolerance() (bravais_lattice, bravais_pos, bravais_numbers) = spglib.refine_cell(phonon.primitive, symprec) bravais = PhonopyAtoms(numbers=bravais_numbers, scaled_positions=bravais_pos, cell=bravais_lattice) filename = 'B' + base_fname print("# Symmetrized conventional unit cell is written into %s." % filename) trans_mat = guess_primitive_matrix(bravais, symprec=symprec) primitive = get_primitive(bravais, trans_mat, symprec=symprec) write_crystal_structure( filename, bravais, interface_mode=phonon.calculator, optional_structure_info=optional_structure_info) filename = 'P' + base_fname print("# Symmetrized primitive is written into %s." % filename) write_crystal_structure( filename, primitive, interface_mode=phonon.calculator, optional_structure_info=optional_structure_info)
def get_commensurate_points(supercell_matrix): # wrt primitive cell """Commensurate q-points are returned. Parameters ---------- supercell_matrix : array_like Supercell matrix with respect to primitive cell basis vectors. shape=(3, 3), dtype=int Returns ------- commensurate_points : ndarray Commensurate points corresponding to supercell matrix. shape=(N, 3), dtype='double', order='C' where N = det(supercell_matrix) """ smat = np.array(supercell_matrix, dtype=int) rec_primitive = PhonopyAtoms(numbers=[1], scaled_positions=[[0, 0, 0]], cell=np.diag([1, 1, 1]), pbc=True) rec_supercell = get_supercell(rec_primitive, smat.T) q_pos = rec_supercell.scaled_positions return np.array(np.where(q_pos > 1 - 1e-15, q_pos - 1, q_pos), dtype='double', order='C')
def get_equivalent_q_points_by_symmetry(q_point, structure): from phonopy.structure.symmetry import Symmetry bulk = PhonopyAtoms(symbols=structure.get_atomic_elements(), scaled_positions=structure.get_scaled_positions(), cell=structure.get_cell().T) tot_points = [] for operation_matrix in Symmetry(bulk).get_reciprocal_operations(): operation_matrix_q = np.dot( np.linalg.inv(structure.get_primitive_matrix()), operation_matrix.T) operation_matrix_q = np.dot(operation_matrix_q, structure.get_primitive_matrix()) q_point_test = np.dot(q_point, operation_matrix_q) if (q_point_test >= 0).all(): tot_points.append(q_point_test) # print tot_points # print(np.vstack({tuple(row) for row in tot_points})) return np.vstack({tuple(row) for row in tot_points})
def phonons(model, bulk, supercell, dx, mesh=None, points=None, n_points=50): import model unitcell = PhonopyAtoms(symbols=bulk.get_chemical_symbols(), cell=bulk.get_cell(), scaled_positions=bulk.get_scaled_positions()) phonon = Phonopy(unitcell, supercell) phonon.generate_displacements(distance=dx) sets_of_forces = [] for s in phonon.get_supercells_with_displacements(): at = Atoms(cell=s.get_cell(), symbols=s.get_chemical_symbols(), scaled_positions=s.get_scaled_positions(), pbc=3 * [True]) at.set_calculator(model.calculator) sets_of_forces.append(at.get_forces()) phonon.set_forces(sets_of_forces=sets_of_forces) phonon.produce_force_constants() properties = {} if mesh is not None: phonon.set_mesh(mesh, is_gamma_center=True) qpoints, weights, frequencies, eigvecs = phonon.get_mesh() properties["frequencies"] = frequencies.tolist() properties["weights"] = weights.tolist() if points is not None: bands = [] for i in range(len(points) - 1): band = [] for r in np.linspace(0, 1, n_points): band.append(points[i] + (points[i + 1] - points[i]) * r) bands.append(band) phonon.set_band_structure(bands, is_eigenvectors=True, is_band_connection=False) band_q_points, band_distances, band_frequencies, band_eigvecs = phonon.get_band_structure( ) band_distance_max = np.max(band_distances) band_distances = [(_b / band_distance_max).tolist() for _b in band_distances] band_frequencies = [_b.tolist() for _b in band_frequencies] properties["band_q_points"] = band_q_points properties["band_distances"] = band_distances properties["band_frequencies"] = band_frequencies properties["band_eigvecs"] = band_eigvecs properties["phonopy"] = phonon return properties
def get_force_sets_inline(**kwargs): from phonopy.structure.atoms import Atoms as PhonopyAtoms from phonopy import Phonopy structure = kwargs.pop('structure') phonopy_input = kwargs.pop('phonopy_input').get_dict() # Generate phonopy phonon object bulk = PhonopyAtoms(symbols=[site.kind_name for site in structure.sites], positions=[site.position for site in structure.sites], cell=structure.cell) phonon = Phonopy(bulk, phonopy_input['supercell'], primitive_matrix=phonopy_input['primitive'], symprec=phonopy_input['symmetry_precision']) phonon.generate_displacements(distance=phonopy_input['distance']) # Build data_sets from forces of supercells with displacments data_sets = phonon.get_displacement_dataset() for i, first_atoms in enumerate(data_sets['first_atoms']): first_atoms['forces'] = kwargs.pop( 'force_{}'.format(i)).get_array('forces')[-1] data = ArrayData() data.set_array('force_sets', np.array(data_sets)) return {'phonopy_output': data}
def create_supercells_with_displacements_inline(**kwargs): from phonopy.structure.atoms import Atoms as PhonopyAtoms from phonopy import Phonopy structure = kwargs.pop('structure') phonopy_input = kwargs.pop('phonopy_input').get_dict() # Generate phonopy phonon object bulk = PhonopyAtoms(symbols=[site.kind_name for site in structure.sites], positions=[site.position for site in structure.sites], cell=structure.cell) phonon = Phonopy(bulk, phonopy_input['supercell'], primitive_matrix=phonopy_input['primitive'], symprec=phonopy_input['symmetry_precision']) phonon.generate_displacements(distance=phonopy_input['distance']) cells_with_disp = phonon.get_supercells_with_displacements() # Transform cells to StructureData and set them ready to return disp_cells = {} for i, phonopy_supercell in enumerate(cells_with_disp): supercell = StructureData(cell=phonopy_supercell.get_cell()) for symbol, position in zip(phonopy_supercell.get_chemical_symbols(), phonopy_supercell.get_positions()): supercell.append_atom(position=position, symbols=symbol) disp_cells["structure_{}".format(i)] = supercell return disp_cells
def _get_cell(self, lattice, points, symbols, masses=None): if lattice: _lattice = lattice else: _lattice = None if points: _points = points else: _points = None if symbols: _symbols = symbols else: _symbols = None if masses: _masses = masses else: _masses = None if _lattice and _points and _symbols: return PhonopyAtoms(symbols=_symbols, cell=_lattice, masses=_masses, scaled_positions=_points) else: return None
def get_structure_from_lammps(command_list, show_log=False): """ Get the crystal structure from lammps input :param command_list: LAMMPS input commands in list (one item for line) :return: numpy array matrix with forces of atoms [Natoms x 3] """ from lammps import lammps cmd_list = ['-log', 'none'] if not show_log: cmd_list += ['-echo', 'none', '-screen', 'none'] lmp = lammps() for l in command_list: lmp.command(l) #lmp.commands_list(command_list) lmp.command('run 0') na = lmp.get_natoms() try: xlo =lmp.extract_global("boxxlo", 1) xhi =lmp.extract_global("boxxhi", 1) ylo =lmp.extract_global("boxylo", 1) yhi =lmp.extract_global("boxyhi", 1) zlo =lmp.extract_global("boxzlo", 1) zhi =lmp.extract_global("boxzhi", 1) xy =lmp.extract_global("xy", 1) yz =lmp.extract_global("yz", 1) xz =lmp.extract_global("xz", 1) except UnboundLocalError: boxlo, boxhi, xy, yz, xz, periodicity, box_change = lmp.extract_box() xlo, ylo, zlo = boxlo xhi, yhi, zhi = boxhi unitcell = np.array([[xhi-xlo, xy, xz], [0, yhi-ylo, yz], [0, 0, zhi-zlo]]).T # positions = lmp.gather_atoms("x", 1, 3) # positions = np.array([positions[i] for i in range(na * 3)]).reshape((na, 3)) type_mass = lmp.extract_atom("mass", 2) type = lmp.gather_atoms("type", 0, 1) masses = np.array([type_mass[type[i]] for i in range(na)], dtype=float) symbols = [mass_to_symbol(masses[i]) for i in range(na)] xp = lmp.extract_atom("x", 3) positions = np.array([[xp[i][0], xp[i][1], xp[i][2]] for i in range(na)], dtype=float) return PhonopyAtoms(positions=positions, masses=masses, symbols=symbols, cell=unitcell)
def _get_atoms_from_poscar(lines, symbols): line1 = [x for x in lines[0].split()] if _is_exist_symbols(line1): symbols = line1 scale = float(lines[1]) cell = [] for i in range(2, 5): cell.append([float(x) for x in lines[i].split()[:3]]) cell = np.array(cell) * scale try: num_atoms = np.array([int(x) for x in lines[5].split()]) line_at = 6 except ValueError: symbols = [x for x in lines[5].split()] num_atoms = np.array([int(x) for x in lines[6].split()]) line_at = 7 expaned_symbols = _expand_symbols(num_atoms, symbols) if lines[line_at][0].lower() == 's': line_at += 1 is_scaled = True if (lines[line_at][0].lower() == 'c' or lines[line_at][0].lower() == 'k'): is_scaled = False line_at += 1 positions = [] for i in range(line_at, line_at + num_atoms.sum()): positions.append([float(x) for x in lines[i].split()[:3]]) if is_scaled: atoms = PhonopyAtoms(symbols=expaned_symbols, cell=cell, scaled_positions=positions) else: atoms = PhonopyAtoms(symbols=expaned_symbols, cell=cell, positions=positions) return atoms
def get_commensurate_points(supercell_matrix): # wrt primitive cell rec_primitive = PhonopyAtoms(numbers=[1], scaled_positions=[[0, 0, 0]], cell=np.diag([1, 1, 1]), pbc=True) rec_supercell = get_supercell(rec_primitive, supercell_matrix.T) q_pos = rec_supercell.get_scaled_positions() return np.array(np.where(q_pos > 1 - 1e-15, q_pos - 1, q_pos), dtype='double', order='C')
def standarize_structure(structure): from phonopy.structure.spglib import standardize_cell lattice, positions, numbers = standardize_cell(structure, to_primitive=False, no_idealize=False, symprec=1e-5) return PhonopyAtoms(positions=positions, numbers=numbers, cell=lattice)