HP Friedrichs's homemade diode and holder |

Specifying crystals, I've learned, is a pretty neat vector operation, and one which lends itself to programming pretty well. There's a basic unit which is repeated at each point of a cube. That unit isn't necessarily as many atoms as you might think: for a body-centered cubic lattice, it's a set of points at (relative coordinates) (0,0,0) and

*a*(.5,.5,.5), where*a*is the lattice constant, which is the edge length of the cube. hen you replicate this two-atoms basis at each of the corners of a cube of side-length*a*, you get a body-centered cubic lattice (doing it just once gives some extra atoms; the unit cell consists of just those atoms within the unit cube. Doing it infinitely, though, will give an infinite BCC lattice). It's a little harder to picture the FCC lattice, but its basis consists of (0,0,0),*a*(0,.5,.5),*a*(.5,0,.5), and*a*(.5,.5,0).
So we have a set of atom positions (2 or 4, depending on the lattice) that we want to iterate over all point of the form

*a*(*x*,*y*,*z*), with all coordinates in the integers. That's a perfect setup for VPython/Glowscript. It's easy enough, using some*for*loops, to iterate over an area of desired dimensions, and then it can all be zoomed and rotated by the user with VPython/Gloscript's native controls. I added a box showing the unit cube for orientation, and.. voila (click image or here to see animation)!GlowScript 1.1 VPython scene.background = color.white def makeLattice(cubic,basis,offset,color,rad): # apply basis atoms to each site in cubic lattice atoms = [] for site in cubic: for atom in basis: atoms.append(sphere(color= color, radius = rad, pos = site+atom+offset)) return atoms def makeCellLattice(cubic,basis,offset,color,rad): # apply basis atoms to each site in cubic lattice atoms = [] for site in cubic: for atom in basis: if 0 <= (site+atom+offset).x <= a and 0 <= (site+atom+offset).y <= a and 0 <= (site+atom+offset).z <= a: atoms.append(sphere(color= color, radius = rad, pos = site+atom+offset)) return atoms def cubeDraw(color): # draw lines around the unit (not primitive) cell curve(pos = [a*vector(0,0,0),a*vector(1,0,0),a*vector(1,1,0),a*vector(0,1,0),a*vector(0,0,0)], color = color) curve(pos = [a*vector(0,0,0),a*vector(0,0,1),a*vector(0,1,1),a*vector(0,1,0),a*vector(0,0,0)], color = color) curve(pos = [a*vector(0,0,1),a*vector(1,0,1),a*vector(1,1,1),a*vector(0,1,1),a*vector(0,0,1)], color = color) curve(pos = [a*vector(1,0,0),a*vector(1,0,1),a*vector(1,1,1),a*vector(1,1,0),a*vector(1,0,0)], color = color) a = 1 # lattice constant # Lattice maker # basis vectors bcc = [vector(0,0,0), vector(.5*a,.5*a,.5*a)] fcc = [vector(0,0,0), vector(0,.5*a,.5*a), vector(.5*a,0,.5*a), vector(.5*a,.5*a,0)] # Create unit cubic lattice # horizontal extent (will go from -x to x) xmin = -1.5 xmax = 1.5 # vertical extent (will go from -y to y) ymin = -1.5 ymax = 1.5 #in-out extent (will go from -z to z) zmin = -1.5 zmax = 1.5 cubic = [] for i in arange(xmin,xmax+1,1): for j in arange(ymin,ymax+1,1): for k in arange(zmin,zmax+1,1): cubic.append(a*vector(i,j,k)) # Use this to show a single unit cell #CuAtoms = makeCellLattice(cubic,bcc,vector(0,0,0),color.red,a/15) #OAtoms = makeCellLattice(cubic,fcc,(sqrt(3)/8)*a*vector(-1,-1,-1),color.blue,a/20) #Use this to show a bigger lattice CuAtoms = makeLattice(cubic,bcc,vector(0,0,0),color.red,a/15) OAtoms = makeLattice(cubic,fcc,(sqrt(3)/8)*a*vector(-1,-1,-1),color.blue,a/20) scene.center = a*vector(.5,.5,-.5) cubeDraw(color.red)