Source code for ipymd.data_input.crystal

# -*- coding: utf-8 -*-
"""
Created on Mon May 16 01:23:11 2016

@author: cjs14

Adapted from chemlab which, in turn, was adapted from
ASE https://wiki.fysik.dtu.dk/ase/
Copyright (C) 2010, Jesper Friis

"""
import numpy as np
import pandas as pd

from ..shared import get_data_path
from . import spacegroup
from .spacegroup.spacegroup import Spacegroup
from .spacegroup.cell import cellpar_to_cell

from .base import DataInput

[docs]def get_spacegroup_df(): """ dataframe of spacegroup mappings """ sg_path = get_data_path('spacegroups.csv',module=spacegroup) return pd.read_csv(sg_path, index_col=0)
[docs]class Crystal(DataInput): """Build a crystal from atomic positions, space group and cell parameters. """
[docs] def setup_data(self, positions, atom_type, group, cellpar=[1.0, 1.0, 1.0, 90, 90, 90], repetitions=[1, 1, 1], mass_map={}, charge_map={}): """Build a crystal from atomic positions, space group and cell parameters (in Angstroms) Parameters ----------- positions : list of coordinates A list of the fractional atomic positions atom_type : list of atom type The atom types corresponding to the positions, the atoms will be translated in all the equivalent positions. group : int | str Space group given as its number in International Tables NB: to see mappings from Hermann–Mauguin notation, etc, use the get_spacegroup_df function in this module repetitions : Repetition of the unit cell in each direction cellpar : Unit cell parameters (in Angstroms and degrees) mass_map : dict of atom masses mapping of atom masses to atom types charge_map : dict of atom charges mapping of atom charges to atom types This function was taken and adapted from the *spacegroup* module found in `ASE <https://wiki.fysik.dtu.dk/ase/>`_. The module *spacegroup* module was originally developed by Jesper Frills. Example ------- from ipymd.data_input import crystal c = crystal.Crystal([[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]], ['Na', 'Cl'], 225, cellpar = [5.4, 5.4, 5.4, 90, 90, 90], repetitions = [5, 5, 5]) c.get_atom_data() c.get_simulation_box() """ sp = Spacegroup(group) sites, kind = sp.equivalent_sites(positions) nx, ny, nz = repetitions atoms = [] aid = 1 c1,c2,c3,c4,c5,c6 = cellpar a,b,c = cellpar_to_cell([c1,c2,c3,c4,c5,c6]) self._meta = pd.Series([(0.,0.,0.), tuple(a*nx), tuple(b*ny), tuple(c*nz)], index=['origin','a','b','c']) for rx in range(nx): for ry in range(ny): for rz in range(nz): for s, ki in zip(sites, kind): atype = atom_type[ki] x,y,z = s[0]*a +s[1]*b + s[2]*c + a*rx + b*ry + c*rz atoms.append([aid,atype,x,y,z]) aid+=1 self._atoms = pd.DataFrame(atoms,columns=['id','type','x','y','z']) if mass_map: self._atoms['mass'] = np.nan for typ in atom_type: self._atoms.loc[self._atoms['type']== typ,'mass'] = mass_map[typ] if charge_map: self._atoms['q'] = np.nan for typ in atom_type: self._atoms.loc[self._atoms['type']== typ,'q'] = charge_map[typ] self._add_colors(self._atoms) self._add_radii(self._atoms) self._data_set = True
def _get_atom_data(self,step): """ return atom data """ return self._atoms.copy() def _get_meta_data(self,step): """ return pandas.Series of coordinates origin, a, b & c """ return self._meta.copy() def _count_configs(self): """ return int of total number of atomic configurations """ return 1