"""pyscal module for creating crystal structures."""importpyscal.catomaspcimportnumpyasnpimportwarnings
[docs]defmake_crystal(structure,lattice_constant=1.00,repetitions=None,ca_ratio=1.633,noise=0):""" Create a basic crystal structure and return it as a list of `Atom` objects and box dimensions. Parameters ---------- structure : {'sc', 'bcc', 'fcc', 'hcp', 'diamond', 'a15' or 'l12'} type of the crystal structure lattice_constant : float, optional lattice constant of the crystal structure, default 1 repetitions : list of ints of len 3, optional of type `[nx, ny, nz]`, repetions of the unit cell in x, y and z directions. default `[1, 1, 1]`. ca_ratio : float, optional ratio of c/a for hcp structures, default 1.633 noise : float, optional If provided add normally distributed noise with standard deviation `noise` to the atomic positions. Returns ------- atoms : list of `Atom` objects list of all atoms as created by user input box : list of list of floats list of the type `[[xlow, xhigh], [ylow, yhigh], [zlow, zhigh]]` where each of them are the lower and upper limits of the simulation box in x, y and z directions respectively. Examples -------- >>> atoms, box = make_crystal('bcc', lattice_constant=3.48, repetitions=[2,2,2]) >>> sys = System() >>> sys.assign_atoms(atoms, box) """ifrepetitions==None:nx=1ny=1nz=1else:nx=repetitions[0]ny=repetitions[1]nz=repetitions[2]#if noise > 0.1:# warnings.warn("Value of noise is rather high. Atom positions might overlap")ifstructure=='sc':coord_no=1atomtype=[1,]natoms=coord_no*nx*ny*nzxfact=1.yfact=1.zfact=1.unitcellx=np.zeros(coord_no)unitcelly=np.zeros(coord_no)unitcellz=np.zeros(coord_no)elifstructure=='bcc':coord_no=2atomtype=[1,1]natoms=coord_no*nx*ny*nzxfact=1.yfact=1.zfact=1.unitcellx=np.zeros(coord_no)unitcelly=np.zeros(coord_no)unitcellz=np.zeros(coord_no)unitcellx[1]=0.5*lattice_constantunitcelly[1]=0.5*lattice_constantunitcellz[1]=0.5*lattice_constantelifstructure=='fcc':coord_no=4atomtype=[1,1,1,1]natoms=coord_no*nx*ny*nzxfact=1.yfact=1.zfact=1.unitcellx=np.zeros(coord_no)unitcelly=np.zeros(coord_no)unitcellz=np.zeros(coord_no)unitcellx[1]=0.5*lattice_constantunitcellz[1]=0.5*lattice_constantunitcelly[2]=0.5*lattice_constantunitcellz[2]=0.5*lattice_constantunitcellx[3]=0.5*lattice_constantunitcelly[3]=0.5*lattice_constantelifstructure=='hcp':coord_no=4atomtype=[1,1,1,1]natoms=coord_no*nx*ny*nzxfact=1.yfact=np.sqrt(3)zfact=ca_ratiounitcellx=np.zeros(coord_no)unitcelly=np.zeros(coord_no)unitcellz=np.zeros(coord_no)unitcellx[1]=0.5*lattice_constantunitcelly[1]=0.5*lattice_constant*yfactunitcellx[2]=0.5*lattice_constantunitcelly[2]=lattice_constant*(1.0/6.0)*yfactunitcellz[2]=0.5*lattice_constant*zfactunitcelly[3]=2.0*lattice_constant*(1.0/yfact)unitcellz[3]=0.5*lattice_constant*zfactelifstructure=='diamond':coord_no=8atomtype=[1,1,1,1,1,1,1,1]natoms=coord_no*nx*ny*nzxfact=1.yfact=1.zfact=1.unitcellx=np.zeros(coord_no)unitcelly=np.zeros(coord_no)unitcellz=np.zeros(coord_no)unitcellx[1]=0.25*lattice_constantunitcelly[1]=0.25*lattice_constantunitcellz[1]=0.25*lattice_constantunitcellx[2]=0.50*lattice_constantunitcelly[2]=0.50*lattice_constantunitcellz[2]=0.00*lattice_constantunitcellx[3]=0.75*lattice_constantunitcelly[3]=0.75*lattice_constantunitcellz[3]=0.25*lattice_constantunitcellx[4]=0.50*lattice_constantunitcelly[4]=0.00*lattice_constantunitcellz[4]=0.50*lattice_constantunitcellx[5]=0.00*lattice_constantunitcelly[5]=0.50*lattice_constantunitcellz[5]=0.50*lattice_constantunitcellx[6]=0.75*lattice_constantunitcelly[6]=0.25*lattice_constantunitcellz[6]=0.75*lattice_constantunitcellx[7]=0.25*lattice_constantunitcelly[7]=0.75*lattice_constantunitcellz[7]=0.75*lattice_constantelifstructure=='a15':coord_no=8atomtype=[1,1,1,1,1,1,1,1]natoms=coord_no*nx*ny*nzxfact=1.yfact=1.zfact=1.unitcellx=np.zeros(coord_no)unitcelly=np.zeros(coord_no)unitcellz=np.zeros(coord_no)unitcellx[1]=0.50*lattice_constantunitcelly[1]=0.50*lattice_constantunitcellz[1]=0.50*lattice_constantunitcellx[2]=0.25*lattice_constantunitcelly[2]=0.50*lattice_constantunitcellz[2]=0.00*lattice_constantunitcellx[3]=0.75*lattice_constantunitcelly[3]=0.50*lattice_constantunitcellz[3]=0.00*lattice_constantunitcellx[4]=0.00*lattice_constantunitcelly[4]=0.25*lattice_constantunitcellz[4]=0.50*lattice_constantunitcellx[5]=0.00*lattice_constantunitcelly[5]=0.75*lattice_constantunitcellz[5]=0.50*lattice_constantunitcellx[6]=0.50*lattice_constantunitcelly[6]=0.00*lattice_constantunitcellz[6]=0.25*lattice_constantunitcellx[7]=0.50*lattice_constantunitcelly[7]=0.00*lattice_constantunitcellz[7]=0.75*lattice_constantelifstructure=='l12':coord_no=4atomtype=[1,2,2,2]natoms=coord_no*nx*ny*nzxfact=1.yfact=1.zfact=1.unitcellx=np.zeros(coord_no)unitcelly=np.zeros(coord_no)unitcellz=np.zeros(coord_no)unitcellx[1]=0.5*lattice_constantunitcellz[1]=0.5*lattice_constantunitcelly[2]=0.5*lattice_constantunitcellz[2]=0.5*lattice_constantunitcellx[3]=0.5*lattice_constantunitcelly[3]=0.5*lattice_constantelifstructure=='b2':coord_no=2atomtype=[1,2]natoms=coord_no*nx*ny*nzxfact=1.yfact=1.zfact=1.unitcellx=np.zeros(coord_no)unitcelly=np.zeros(coord_no)unitcellz=np.zeros(coord_no)unitcellx[1]=0.5*lattice_constantunitcelly[1]=0.5*lattice_constantunitcellz[1]=0.5*lattice_constantelse:raiseValueError("Unknown crystal structure")m=0co=1atoms=[]xh=nx*lattice_constant*xfactyh=ny*lattice_constant*yfactzh=nz*lattice_constant*zfactbox=[[xh,0,0],[0,yh,0],[0,0,zh]]#create structureforiinrange(1,nx+1):forjinrange(1,ny+1):forkinrange(1,nz+1):forlinrange(1,coord_no+1):m+=1posx=(unitcellx[l-1]+(lattice_constant*xfact*(float(i)-1)))posy=(unitcelly[l-1]+(lattice_constant*yfact*(float(j)-1)))posz=(unitcellz[l-1]+(lattice_constant*zfact*(float(k)-1)))ifnoise>0:posx=np.random.normal(loc=posx,scale=noise)posy=np.random.normal(loc=posy,scale=noise)posz=np.random.normal(loc=posz,scale=noise)atom=pc.Atom()atom.pos=[posx,posy,posz]atom.id=coatom.type=atomtype[l-1]atom.loc=co-1atoms.append(atom)co+=1returnatoms,box