def read_pwscf(filename): pwscf_in = PwscfIn(open(filename).readlines()) tags = pwscf_in.get_tags() lattice = tags['cell_parameters'] positions = [pos[1] for pos in tags['atomic_positions']] species = [pos[0] for pos in tags['atomic_positions']] mass_map = {} pp_map = {} for vals in tags['atomic_species']: mass_map[vals[0]] = vals[1] pp_map[vals[0]] = vals[2] masses = [mass_map[x] for x in species] pp_all_filenames = [pp_map[x] for x in species] unique_species = [] for x in species: if x not in unique_species: unique_species.append(x) numbers = [] is_unusual = False for x in species: if x in symbol_map: numbers.append(symbol_map[x]) else: numbers.append(-unique_species.index(x)) is_unusual = True if is_unusual: positive_numbers = [] for n in numbers: if n > 0: if n not in positive_numbers: positive_numbers.append(n) available_numbers = range(1, 119) for pn in positive_numbers: available_numbers.remove(pn) for i, n in enumerate(numbers): if n < 1: numbers[i] = available_numbers[-n] cell = Atoms(numbers=numbers, masses=masses, cell=lattice, scaled_positions=positions) else: cell = Atoms(numbers=numbers, cell=lattice, scaled_positions=positions) unique_symbols = [] pp_filenames = {} for i, symbol in enumerate(cell.get_chemical_symbols()): if symbol not in unique_symbols: unique_symbols.append(symbol) pp_filenames[symbol] = pp_all_filenames[i] return cell, pp_filenames
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(Atoms(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(Atoms(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): """Read FHI-aims geometry files in phonopy context.""" lines = open(filename, "r").readlines() cell = [] is_frac = [] positions = [] symbols = [] magmoms = [] for line in lines: fields = line.split() if not len(fields): continue if fields[0] == "lattice_vector": vec = lmap(float, fields[1:4]) cell.append(vec) elif fields[0][0:4] == "atom": if fields[0] == "atom": frac = False elif fields[0] == "atom_frac": frac = True pos = lmap(float, fields[1:4]) sym = fields[4] is_frac.append(frac) positions.append(pos) symbols.append(sym) magmoms.append(None) # implicitly assuming that initial_moments line adhere to FHI-aims geometry.in # specification, i.e. two subsequent initial_moments lines do not occur # if they do, the value specified in the last line is taken here - without # any warning elif fields[0] == "initial_moment": magmoms[-1] = float(fields[1]) for (n, frac) in enumerate(is_frac): if frac: pos = [ sum([positions[n][ll] * cell[ll][i] for ll in range(3)]) for i in range(3) ] positions[n] = pos if None in magmoms: atoms = Atoms(cell=cell, symbols=symbols, positions=positions) else: atoms = Atoms(cell=cell, symbols=symbols, positions=positions, magmoms=magmoms) return atoms
def _build_supercells_with_displacements(self): supercells = [] magmoms = self._supercell.get_magnetic_moments() masses = self._supercell.get_masses() numbers = self._supercell.get_atomic_numbers() lattice = self._supercell.get_cell() for disp1 in self._displacement_dataset['first_atoms']: disp_cart1 = disp1['displacement'] positions = self._supercell.get_positions() positions[disp1['number']] += disp_cart1 supercells.append( Atoms(numbers=numbers, masses=masses, magmoms=magmoms, positions=positions, cell=lattice, pbc=True)) for disp1 in self._displacement_dataset['first_atoms']: for disp2 in disp1['second_atoms']: positions = self._supercell.get_positions() positions[disp1['number']] += disp_cart1 positions[disp2['number']] += disp2['displacement'] supercells.append( Atoms(numbers=numbers, masses=masses, magmoms=magmoms, positions=positions, cell=lattice, pbc=True)) for disp1 in self._displacement_dataset['first_atoms']: for disp2 in disp1['second_atoms']: for disp3 in disp2['third_atoms']: positions = self._supercell.get_positions() positions[disp1['number']] += disp_cart1 positions[disp2['number']] += disp2['displacement'] positions[disp3['number']] += disp3['displacement'] supercells.append( Atoms(numbers=numbers, masses=masses, magmoms=magmoms, positions=positions, cell=lattice, pbc=True)) self._supercells_with_displacements = supercells
def read_abinit(filename): """Read crystal structure.""" with open(filename) as f: abinit_in = AbinitIn(f.readlines()) tags = abinit_in.get_variables() acell = tags["acell"] rprim = tags["rprim"].T scalecart = tags["scalecart"] lattice = rprim * acell if scalecart is not None: for i in range(3): lattice[i] *= scalecart[i] if tags["xcart"] is not None: pos_bohr = np.transpose(tags["xcart"]) positions = np.dot(np.linalg.inv(lattice), pos_bohr).T elif tags["xangst"] is not None: pos_bohr = np.transpose(tags["xangst"]) / Bohr positions = np.dot(np.linalg.inv(lattice), pos_bohr).T elif tags["xred"] is not None: positions = tags["xred"] numbers = [tags["znucl"][x - 1] for x in tags["typat"]] return Atoms(numbers=numbers, cell=lattice.T, scaled_positions=positions)
def read_crystal(filename): f_crystal = open(filename) crystal_in = CrystalIn(f_crystal.readlines()) f_crystal.close() tags = crystal_in.get_tags() cell = Atoms(cell=tags['lattice_vectors'], symbols=tags['atomic_species'], scaled_positions=tags['coordinates']) magmoms = tags['magnetic_moments'] if magmoms is not None: # Print out symmetry information for magnetic cases # Original code from structure/symmetry.py symmetry = Symmetry(cell, symprec=1e-5) print( "CRYSTAL-interface: Magnetic structure, number of operations without spin: %d" % len(symmetry.get_symmetry_operations()['rotations'])) print("CRYSTAL-interface: Spacegroup without spin: %s" % symmetry.get_international_table()) cell.set_magnetic_moments(magmoms) symmetry = Symmetry(cell, symprec=1e-5) print( "CRYSTAL-interface: Magnetic structure, number of operations with spin: %d" % len(symmetry.get_symmetry_operations()['rotations'])) print("") return cell, tags['conv_numbers']
def read_siesta(filename): siesta_in = SiestaIn(open(filename).read()) numbers = siesta_in._tags["atomicnumbers"] lattice = siesta_in._tags["latticevectors"] positions = siesta_in._tags["atomiccoordinates"] atypes = siesta_in._tags["chemicalspecieslabel"] cell = Atoms(numbers=numbers, cell=lattice, scaled_positions=positions) coordformat = siesta_in._tags["atomiccoordinatesformat"] if coordformat == "fractional" or coordformat == "scaledbylatticevectors": cell.set_scaled_positions(positions) elif coordformat == "scaledcartesian": if siesta_in._tags['latticeconstant'] == 'ang': cell.set_positions(np.array(positions) / Bohr) else: cell.set_positions(np.array(positions)) elif coordformat == "notscaledcartesianang" or coordformat == "ang": cell.set_positions(np.array(positions) / Bohr) elif coordformat == "notscaledcartesianbohr" or coordformat == "bohr": cell.set_positions(np.array(positions)) else: print("The format %s for the AtomicCoordinatesFormat is not " "implemented." % coordformat) sys.exit(1) return cell, atypes
def get_born_vasprunxml(filename="vasprun.xml", primitive_matrix=None, supercell_matrix=None, is_symmetry=True, symmetrize_tensors=False, symprec=1e-5): import io borns = [] epsilon = [] with io.open(filename, "rb") as f: vasprun = VasprunxmlExpat(f) if vasprun.parse(): epsilon = vasprun.get_epsilon() borns = vasprun.get_born() lattice = vasprun.get_lattice()[-1] points = vasprun.get_points()[-1] symbols = vasprun.get_symbols() ucell = Atoms(symbols=symbols, scaled_positions=points, cell=lattice) else: return None return elaborate_borns_and_epsilon(ucell, borns, epsilon, primitive_matrix=primitive_matrix, supercell_matrix=supercell_matrix, is_symmetry=is_symmetry, symmetrize_tensors=symmetrize_tensors, symprec=symprec)
def check_symmetry(input_cell, primitive_axis=np.eye(3, dtype=float), symprec=1e-5, phonopy_version=None): cell = Primitive(input_cell, primitive_axis, symprec) symmetry = Symmetry(cell, symprec) print get_symmetry_yaml(cell, symmetry, phonopy_version), if input_cell.get_magnetic_moments() == None: primitive = find_primitive(cell, symprec) if not primitive == None: print "# Primitive cell was found. It is written into PPOSCAR." write_vasp('PPOSCAR', primitive) # Overwrite symmetry and cell symmetry = Symmetry(primitive, symprec) cell = primitive bravais_lattice, bravais_pos, bravais_numbers = \ spg.refine_cell(cell, symprec) bravais = Atoms(numbers=bravais_numbers, scaled_positions=bravais_pos, cell=bravais_lattice, pbc=True) print "# Bravais lattice is written into BPOSCAR." write_vasp('BPOSCAR', bravais)
def _get_supercell(self): """Attention This method will be removed after new get_delta method is well checked. """ dim = self._dimension scaled_positions = [] masses = [] magmoms_prim = self._primitive.get_magnetic_moments() if magmoms_prim is None: magmoms = None else: magmoms = [] symbols = [] for a, b, c in list(np.ndindex(tuple(dim))): for i in range(self._primitive.get_number_of_atoms()): p = self._primitive.get_scaled_positions()[i] scaled_positions.append(p + np.array([a, b, c])) masses.append(self._primitive.get_masses()[i]) symbols.append(self._primitive.get_chemical_symbols()[i]) if magmoms_prim is not None: magmoms.append(magmoms_prim[i]) lattice = np.dot(np.diag(dim), self._primitive.get_cell()) positions = np.dot(scaled_positions, self._primitive.get_cell()) from phonopy.structure.atoms import Atoms return Atoms(cell=lattice, positions=positions, masses=masses, magmoms=magmoms, symbols=symbols, pbc=True)
def read_castep(filename): f_castep = open(filename) castep_in = CastepIn(f_castep.readlines()) f_castep.close() tags = castep_in.get_tags() # 1st stage is to create Atoms object ignoring Spin polarization. General case. cell = Atoms(cell=tags['lattice_vectors'], symbols=tags['atomic_species'], scaled_positions=tags['coordinates']) # Analyse spin states and add data to Atoms instance "cell" if ones exist magmoms = tags['magnetic_moments'] if magmoms is not None: # Print out symmetry information for magnetic cases # Original code from structure/symmetry.py symmetry = Symmetry(cell, symprec=1e-5) print( "CASTEP-interface: Magnetic structure, number of operations without spin: %d" % len(symmetry.get_symmetry_operations()['rotations'])) print("CASTEP-interface: Spacegroup without spin: %s" % symmetry.get_international_table()) cell.set_magnetic_moments(magmoms) symmetry = Symmetry(cell, symprec=1e-5) print( "CASTEP-interface: Magnetic structure, number of operations with spin: %d" % len(symmetry.get_symmetry_operations()['rotations'])) print("") return cell
def gencastep(fn, modenum, basis, natom, typatsym, symprec, atpos): from phonopy import Phonopy import phonopy.structure.spglib as spg from phonopy.structure.atoms import PhonopyAtoms as Atoms from phonopy.structure.symmetry import Symmetry, find_primitive, get_pointgroup fh = open(fn, 'w') unitcell = Atoms(symbols=typatsym, cell=basis, positions=atpos) pbasis = np.eye(3) for i in range(len(basis)): pbasis[i] = basis[i] / np.linalg.norm(basis[i]) symmetry = Symmetry(unitcell, symprec) rotations = symmetry.get_symmetry_operations()['rotations'] translations = symmetry.get_symmetry_operations()['translations'] print('Space group International symbol: %s' % symmetry.get_international_table()) fh.write('%BLOCK LATTICE_CART\n') for bl in basis: fh.write('%s\n' % ''.join(' %12.8f' % b for b in bl)) fh.write('%ENDBLOCK LATTICE_CART\n\n') fh.write('%BLOCK POSITIONS_ABS\n') for i in range(len(typatsym)): fh.write(" %3s " % typatsym[i]) fh.write('%s\n' % ''.join(' %12.8f' % p for p in atpos[i].tolist())) fh.write('%ENDBLOCK POSITIONS_ABS\n\n') fh.write('SYMMETRY_TOL : %f ang\n' % symprec) fh.write('SYMMETRY_GENERATE \n') fh.write('#KPOINT_MP_GRID : 4 4 4\n#KPOINT_MP_OFFSET : 0.5 0.5 0.5\n')
def parse_disp_yaml_with_supercell(filename='disp.yaml'): try: import yaml except ImportError: print "You need to install python-yaml." exit(1) try: from yaml import CLoader as Loader from yaml import CDumper as Dumper except ImportError: from yaml import Loader, Dumper data = yaml.load(open(filename).read(), Loader=Loader) lattice = data['lattice'] displacements = [] for x in data['displacements']: displacements.append([x['atom'] - 1, x['displacement']]) positions = [x['position'] for x in data['atoms']] symbols = [x['symbol'] for x in data['atoms']] cell = Atoms(cell=lattice, scaled_positions=positions, symbols=symbols, pbc=True) return displacements, cell
def _get_atoms_from_atom_config(lines, symbols): num_atoms = int(lines[0].split()[0]) num_lines = len(lines) cell = [] for i in range(2, 5): cell.append([float(x) for x in lines[i].split()[:3]]) cell = np.array(cell) line_at = 6 positions = [] for i in range(line_at, line_at + num_atoms): positions.append([float(x) for x in lines[i].split()[1:4]]) atoms_z = [] expand_symbols = [] for i in range(line_at, line_at + num_atoms): zatom = int(lines[i].split()[0]) atoms_z.append(zatom) expand_symbols.append(atom_data[zatom][1]) atoms = Atoms(symbols=expand_symbols, cell=cell, scaled_positions=positions) return atoms
def ReadBORN(structure, filePath="BORN"): """ Read a Phonopy BORN file, and expand the charges for the supplied structure, and return a list of Born effective-charge tensors for each atom in the structure. Arguments: structure -- a tuple of (lattice_vectors, atomic_symbols, atom_positions) specifying the structure to be used to expand the Born charges to the full set of atoms. Keyword arguments: filePath -- path to the Phonopy BORN-format file to read (default: BORN). Return value: A list of 3x3 Born effective-charge tensors for each atom in the supplied structure. Notes: The atom positions supplied with structure are assumed to be in fractional coordinates. """ # Convert the supplied structure to a Phonopy Atoms object. latticeVectors, atomicSymbols, atomPositions = structure cell = Atoms(symbols=atomicSymbols, cell=latticeVectors, scaled_positions=atomPositions) # Read the BORN file. bornData = parse_BORN(cell, filename=filePath) # Return the Born effective-charge tensors from the dictionary returned by parse_BORN. return [becTensor for becTensor in bornData['born']]
def get_simple_supercell(multi, unitcell): # Scaled positions within the frame, i.e., create a supercell that # is made simply to multiply the input cell. positions = unitcell.get_scaled_positions() numbers = unitcell.get_atomic_numbers() masses = unitcell.get_masses() magmoms = unitcell.get_magnetic_moments() lattice = unitcell.get_cell() positions_multi = [] numbers_multi = [] masses_multi = [] if magmoms == None: magmoms_multi = None else: magmoms_multi = [] for l, pos in enumerate(positions): for i in range(multi[2]): for j in range(multi[1]): for k in range(multi[0]): positions_multi.append([(pos[0] + k) / multi[0], (pos[1] + j) / multi[1], (pos[2] + i) / multi[2]]) numbers_multi.append(numbers[l]) masses_multi.append(masses[l]) if not magmoms == None: magmoms_multi.append(magmoms[l]) return Atoms(numbers = numbers_multi, masses = masses_multi, magmoms = magmoms_multi, scaled_positions = positions_multi, cell = np.dot(np.diag(multi), lattice), pbc=True)
def read_abinit(filename): abinit_in = AbinitIn(open(filename).readlines()) tags = abinit_in.get_variables() acell = tags['acell'] rprim = tags['rprim'].T scalecart = tags['scalecart'] lattice = rprim * acell if scalecart is not None: for i in range(3): lattice[i] *= scalecart[i] if tags['xcart'] is not None: pos_bohr = np.transpose(tags['xcart']) positions = np.dot(np.linalg.inv(lattice), pos_bohr).T elif tags['xangst'] is not None: pos_bohr = np.transpose(tags['xangst']) / Bohr positions = np.dot(np.linalg.inv(lattice), pos_bohr).T elif tags['xred'] is not None: positions = tags['xred'] numbers = [tags['znucl'][x - 1] for x in tags['typat']] return Atoms(numbers=numbers, cell=lattice.T, scaled_positions=positions)
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 Atoms(symbols=_symbols, cell=_lattice, masses=_masses, scaled_positions=_points) else: return None
def check_symmetry(input_cell, primitive_axis=None, symprec=1e-5, distance_to_A=1.0, phonopy_version=None): if primitive_axis is None: cell = get_primitive(input_cell, np.eye(3), symprec=symprec) else: cell = get_primitive(input_cell, primitive_axis, symprec=symprec) lattice = cell.get_cell() * distance_to_A cell.set_cell(lattice) symmetry = Symmetry(cell, symprec) print(_get_symmetry_yaml(cell, symmetry, phonopy_version)) if input_cell.get_magnetic_moments() is None: primitive = find_primitive(cell, symprec) if primitive is not None: print("# Primitive cell was found. It is written into PPOSCAR.") write_vasp('PPOSCAR', primitive) # Overwrite symmetry and cell symmetry = Symmetry(primitive, symprec) cell = primitive (bravais_lattice, bravais_pos, bravais_numbers) = spg.refine_cell(cell, symprec) bravais = Atoms(numbers=bravais_numbers, scaled_positions=bravais_pos, cell=bravais_lattice, pbc=True) print("# Bravais lattice is written into BPOSCAR.") write_vasp('BPOSCAR', bravais)
def get_commensurate_points(supercell_matrix): # wrt primitive cell rec_primitive = Atoms(numbers=[1], scaled_positions=[[0, 0, 0]], cell=np.diag([1, 1, 1]), pbc=True) rec_supercell = get_supercell(rec_primitive, supercell_matrix.T) return rec_supercell.get_scaled_positions()
def read_elk(filename): """Read crystal structure.""" elk_in = ElkIn(open(filename).readlines()) tags = elk_in.get_variables() avec = [tags["scale"][i] * np.array(tags["avec"][i]) for i in range(3)] spfnames = tags["atoms"]["spfnames"] symbols = [x.split(".")[0] for x in spfnames] numbers = [] for s in symbols: if s in symbols: numbers.append(symbol_map[s]) else: numbers.append(0) for i, n in enumerate(numbers): if n == 0: for j in range(1, 119): if not (j in numbers): numbers[i] = j break pos_all = [] num_all = [] for num, pos in zip(numbers, tags["atoms"]["positions"]): pos_all += pos num_all += [num] * len(pos) return Atoms(numbers=num_all, cell=avec, scaled_positions=pos_all), spfnames
def _build_supercells_with_displacements(self): supercells = [] magmoms = self._supercell.get_magnetic_moments() masses = self._supercell.get_masses() numbers = self._supercell.get_atomic_numbers() lattice = self._supercell.get_cell() supercells = self._build_phonon_supercells_with_displacements( self._supercell, self._displacement_dataset) for disp1 in self._displacement_dataset['first_atoms']: disp_cart1 = disp1['displacement'] for disp2 in disp1['second_atoms']: if 'included' in disp2: included = disp2['included'] else: included = True if included: positions = self._supercell.get_positions() positions[disp1['number']] += disp_cart1 positions[disp2['number']] += disp2['displacement'] supercells.append(Atoms(numbers=numbers, masses=masses, magmoms=magmoms, positions=positions, cell=lattice, pbc=True)) else: supercells.append(None) self._supercells_with_displacements = supercells
def _get_supercell(self): dim = self._dimension scaled_positions = [] masses = [] magmoms_prim = self._cell.get_magnetic_moments() if magmoms_prim == None: magmoms = None else: magmoms = [] symbols = [] for a in range(dim[0]): for b in range(dim[1]): for c in range(dim[2]): for i in range(self._cell.get_number_of_atoms()): p = self._cell.get_scaled_positions()[i] scaled_positions.append(p + np.array([a,b,c])) masses.append(self._cell.get_masses()[i]) symbols.append(self._cell.get_chemical_symbols()[i]) if not magmoms_prim == None: magmoms.append(magmoms_prim[i]) lattice = np.dot(np.diag(dim), self._cell.get_cell()) positions = np.dot(scaled_positions, self._cell.get_cell()) return Atoms(cell=lattice, positions=positions, masses=masses, magmoms=magmoms, symbols=symbols, pbc=True)
def read_fleur(filename): fleur_in = FleurIn(open(filename).readlines()) tags = fleur_in.get_variables() avec = [tags['avec'][i] for i in range(3)] speci = tags['atoms']['speci'] symbols = [ list(symbol_map.keys())[list(symbol_map.values()).index( math.floor(float(x)))] for x in speci ] numbers = [math.floor(float(x)) for x in speci] for i, n in enumerate(numbers): if n == 0: for j in range(1, 119): if not (j in numbers): numbers[i] = j break pos_all = [] num_all = [] for num, pos in zip(numbers, tags['atoms']['positions']): pos_all += pos num_all = [symbol_map[s] for s in symbols] return Atoms(numbers=num_all, cell=avec, scaled_positions=pos_all), speci, fleur_in._restlines
def parse_disp_yaml(filename="disp.yaml", return_cell=False): try: import yaml except ImportError: print("You need to install python-yaml.") sys.exit(1) try: from yaml import CLoader as Loader except ImportError: from yaml import Loader from phonopy.structure.atoms import PhonopyAtoms as Atoms with open(filename) as f: dataset = yaml.load(f, Loader=Loader) natom = dataset['natom'] new_dataset = {} new_dataset['natom'] = natom new_first_atoms = [] for first_atoms in dataset['displacements']: first_atoms['atom'] -= 1 atom1 = first_atoms['atom'] disp1 = first_atoms['displacement'] if 'direction' in first_atoms: direct1 = first_atoms['direction'] new_first_atoms.append({ 'number': atom1, 'displacement': disp1, 'direction': direct1 }) else: new_first_atoms.append({ 'number': atom1, 'displacement': disp1 }) new_dataset['first_atoms'] = new_first_atoms if return_cell: 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 positions = [x[pos_key] for x in dataset[data_key]] symbols = [x['symbol'] for x in dataset[data_key]] cell = Atoms(cell=lattice, scaled_positions=positions, symbols=symbols, pbc=True) return new_dataset, cell else: return new_dataset
def get_commensurate_points(primitive, supercell): supercell_matrix = np.linalg.inv(primitive.get_primitive_matrix()).T rec_primitive = Atoms(numbers=[1], scaled_positions=[[0, 0, 0]], cell=np.diag([1, 1, 1]), pbc=True) rec_supercell = get_supercell(rec_primitive, supercell_matrix) return rec_supercell.get_scaled_positions()
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 = Atoms(symbols=expaned_symbols, cell=cell, scaled_positions=positions) else: atoms = Atoms(symbols=expaned_symbols, cell=cell, positions=positions) return atoms
def trim_cell(relative_axes, cell, symprec): """ relative_axes: relative axes to supercell axes Trim positions outside relative axes """ positions = cell.get_scaled_positions() numbers = cell.get_atomic_numbers() masses = cell.get_masses() magmoms = cell.get_magnetic_moments() lattice = cell.get_cell() trimed_lattice = np.dot(relative_axes.T, lattice) trimed_positions = [] trimed_numbers = [] trimed_masses = [] if magmoms is None: trimed_magmoms = None else: trimed_magmoms = [] atom_map = [] positions_in_new_lattice = np.dot(positions, np.linalg.inv(relative_axes).T) positions_in_new_lattice -= np.floor(positions_in_new_lattice) trimed_positions = np.zeros_like(positions_in_new_lattice) num_atom = 0 for i, pos in enumerate(positions_in_new_lattice): is_overlap = False if num_atom > 0: diff = trimed_positions[:num_atom] - pos diff -= np.rint(diff) # axis argument in linalg.norm is relatively new? # distances = np.linalg.norm(np.dot(diff, trimed_lattice), axis=1) distances = np.sqrt(np.sum(np.dot(diff, trimed_lattice)**2, axis=1)) if (distances < symprec).any(): is_overlap = True if not is_overlap: trimed_positions[num_atom] = pos num_atom += 1 trimed_numbers.append(numbers[i]) trimed_masses.append(masses[i]) if magmoms is not None: trimed_magmoms.append(magmoms[i]) atom_map.append(i) trimed_cell = Atoms(numbers=trimed_numbers, masses=trimed_masses, magmoms=trimed_magmoms, scaled_positions=trimed_positions[:num_atom], cell=trimed_lattice, pbc=True) return trimed_cell, atom_map
def setUp(self): 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._cell = Atoms(cell=lattice, scaled_positions=points, symbols=symbols)
def _set_translations(self): pcell = Atoms(numbers=[1], scaled_positions=[[0, 0, 0]], cell=np.diag([1, 1, 1]), pbc=True) smat = self._supercell_matrix self._trans_s = get_supercell(pcell, smat).get_scaled_positions() self._trans_p = np.dot(self._trans_s, self._supercell_matrix.T) self._N = len(self._trans_s)