def view_cellpars(filename='POSCAR'): atoms = read(filename) print('CELLPARS: %s' % cell_to_cellpar(atoms.get_cell())) print('Volume: %s' % atoms.get_volume()) CELLPARS = cell_to_cellpar(atoms.get_cell()) Volume = atoms.get_volume() return CELLPARS, Volume
def estimate_nearest_neighbour_distance(atoms, neighbor_list=neighbor_list): """ Estimate nearest neighbour distance r_NN Args: atoms: Atoms object neighbor_list: function (optional). Optionally replace the built-in ASE neighbour list with an alternative with the same call signature, e.g. `matscipy.neighbours.neighbour_list`. Returns: rNN: float Nearest neighbour distance """ if isinstance(atoms, Filter): atoms = atoms.atoms # start_time = time.time() # compute number of neighbours of each atom. If any atom doesn't # have a neighbour we increase the cutoff and try again, until our # cutoff exceeds the size of the system r_cut = 1.0 phi = (1.0 + np.sqrt(5.0)) / 2.0 # Golden ratio # cell lengths and angles a, b, c, alpha, beta, gamma = cell_to_cellpar(atoms.cell) extent = [a, b, c] # print('estimate_nearest_neighbour_distance(): extent=%r' % extent) while r_cut < 2.0 * max(extent): # print('estimate_nearest_neighbour_distance(): ' # 'calling neighbour_list with r_cut=%.2f A' % r_cut) i, j, rij, fixed_atoms = get_neighbours(atoms, r_cut, self_interaction=True, neighbor_list=neighbor_list) if len(i) != 0: nn_i = np.bincount(i, minlength=len(atoms)) if (nn_i != 0).all(): break r_cut *= phi else: raise RuntimeError('increased r_cut to twice system extent without ' 'finding neighbours for all atoms. This can ' 'happen if your system is too small; try ' 'setting r_cut manually') # maximum of nearest neighbour distances nn_distances = [np.min(rij[i == I]) for I in range(len(atoms))] r_NN = np.max(nn_distances) # print('estimate_nearest_neighbour_distance(): got r_NN=%.3f in %s s' % # (r_NN, time.time() - start_time)) return r_NN
def cellpar(self, radians=False): """Get unit cell parameters. Sequence of 6 numbers. First three are unit cell vector lengths and second three are angles between them:: [len(a), len(b), len(c), angle(b,c), angle(a,c), angle(a,b)] in degrees. See also :func:`ase.geometry.cell.cell_to_cellpar`.""" from ase.geometry.cell import cell_to_cellpar return cell_to_cellpar(self.array, radians)
def estimate_nearest_neighbour_distance(atoms): """ Estimate nearest neighbour distance r_NN Args: atoms: Atoms object Returns: rNN: float Nearest neighbour distance """ if isinstance(atoms, Filter): atoms = atoms.atoms start_time = time.time() # compute number of neighbours of each atom. If any atom doesn't # have a neighbour we increase the cutoff and try again, until our # cutoff exceeds the size of the sytem r_cut = 1.0 phi = (1.0 + np.sqrt(5.0)) / 2.0 # Golden ratio # cell lengths and angles a, b, c, alpha, beta, gamma = cell_to_cellpar(atoms.cell) extent = [a, b, c] logger.debug('estimate_nearest_neighbour_distance(): extent=%r', extent) while r_cut < 2.0 * max(extent): logger.info('estimate_nearest_neighbour_distance(): ' 'calling neighbour_list with r_cut=%.2f A', r_cut) i, j, rij, fixed_atoms = get_neighbours( atoms, r_cut, self_interaction=True) if len(i) != 0: nn_i = np.bincount(i, minlength=len(atoms)) if (nn_i != 0).all(): break r_cut *= phi else: raise RuntimeError('increased r_cut to twice system extent without ' 'finding neighbours for all atoms. This can ' 'happen if your system is too small; try ' 'setting r_cut manually') # maximum of nearest neigbour distances nn_distances = [np.min(rij[i == I]) for I in range(len(atoms))] r_NN = np.max(nn_distances) logger.info('estimate_nearest_neighbour_distance(): got r_NN=%.3f in %s s', r_NN, time.time() - start_time) return r_NN
def get_cell_angles_lengths(cell): ''' Returns cell vectors lengths (a,b,c) as well as different angles (alpha, beta, gamma, phi, chi, psi) (in radians). ''' cellpar = cell_to_cellpar(cell) cellpar[3:] *= np.pi / 180 # convert angles to radians parnames = ['a', 'b', 'c', 'alpha', 'beta', 'gamma'] values = {n: p for n, p in zip(parnames, cellpar)} volume = abs(np.linalg.det(cell)) for i, param in enumerate(['phi', 'chi', 'psi']): ab = np.linalg.norm( np.cross(cell[(i + 1) % 3, :], cell[(i + 2) % 3, :])) c = np.linalg.norm(cell[i, :]) values[param] = np.arcsin(np.abs(volume / (ab * c))) return values
def write_dmol_car(filename, atoms): """ Write a dmol car-file from an Atoms object Notes ----- The positions written to file are rotated as to align with the cell when reading (due to cellpar information) Can not handle multiple images. Only allows for pbc 111 or 000. """ f = open(filename, 'w') f.write('!BIOSYM archive 3\n') dt = datetime.now() symbols = atoms.get_chemical_symbols() if np.all(atoms.pbc): # Rotate positions so they will align with cellpar cell cellpar = cell_to_cellpar(atoms.cell) new_cell = cellpar_to_cell(cellpar) lstsq_fit = np.linalg.lstsq(atoms.cell, new_cell, rcond=-1) # rcond=-1 silences FutureWarning in numpy 1.14 R = lstsq_fit[0] positions = np.dot(atoms.positions, R) f.write('PBC=ON\n\n') f.write('!DATE %s\n' % dt.strftime('%b %d %H:%m:%S %Y')) f.write('PBC %9.5f %9.5f %9.5f %9.5f %9.5f %9.5f\n' % tuple(cellpar)) elif not np.any(atoms.pbc): # [False,False,False] f.write('PBC=OFF\n\n') f.write('!DATE %s\n' % dt.strftime('%b %d %H:%m:%S %Y')) positions = atoms.positions else: raise ValueError('PBC must be all true or all false for .car format') for i, (sym, pos) in enumerate(zip(symbols, positions)): f.write('%-6s %12.8f %12.8f %12.8f XXXX 1 xx %-2s ' '0.000\n' % (sym + str(i + 1), pos[0], pos[1], pos[2], sym)) f.write('end\nend\n') f.close()
def write_dmol_arc(filename, images): """ Writes all images to file filename in arc format. Similar to the .car format only pbc 111 or 000 is supported. """ f = open(filename, 'w') f.write('!BIOSYM archive 3\n') if np.all(images[0].pbc): f.write('PBC=ON\n\n') # Rotate positions so they will align with cellpar cell elif not np.any(images[0].pbc): f.write('PBC=OFF\n\n') else: raise ValueError('PBC must be all true or all false for .arc format') for atoms in images: dt = datetime.now() symbols = atoms.get_chemical_symbols() if np.all(atoms.pbc): cellpar = cell_to_cellpar(atoms.cell) new_cell = cellpar_to_cell(cellpar) lstsq_fit = np.linalg.lstsq(atoms.cell, new_cell, rcond=-1) R = lstsq_fit[0] f.write('!DATE %s\n' % dt.strftime('%b %d %H:%m:%S %Y')) f.write('PBC %9.5f %9.5f %9.5f %9.5f %9.5f %9.5f\n' % tuple(cellpar)) positions = np.dot(atoms.positions, R) elif not np.any(atoms.pbc): # [False,False,False] f.write('!DATE %s\n' % dt.strftime('%b %d %H:%m:%S %Y')) positions = atoms.positions else: raise ValueError( 'PBC must be all true or all false for .arc format') for i, (sym, pos) in enumerate(zip(symbols, positions)): f.write('%-6s %12.8f %12.8f %12.8f XXXX 1 xx %-2s ' '0.000\n' % (sym + str(i + 1), pos[0], pos[1], pos[2], sym)) f.write('end\nend\n') f.write('\n') f.close()
def cellpar(self, radians=False): """Get cell lengths and angles of this cell. See also :func:`ase.geometry.cell.cell_to_cellpar`.""" from ase.geometry.cell import cell_to_cellpar return cell_to_cellpar(self.array, radians)