Position and Translation Vectors - the Crystal Lattice

Introduction

This is the first of the Maths Lab sessions for which you will be required to submit a report for marking. You must hand your report for MathsLab 3 and MathsLab 4 in by the end of your last session this term (B1-7 Nov., B2-10 Nov., A1-28 Nov. and A2-1 Dec.). Leave printed versions, with your name on them in the box provided in Nick Davies' office in the Computer Room and remember to email your report to "mathlab@ic.ac.uk". Submission time is given by the date and time on the email. Late reports will be penalised. These reports and the mathematics problem sheets you hand in to your Physical Chemistry tutor represent 10% of your coursework mark. Remember, we are expecting you to write up your mathematics report by using the document preparation facilities built into Mathematica. A lot of code and output, without appropriate accompanying commentary, will not get good marks.

Objectives

In this exercise you are being asked to use what you have learned about vector addition in your maths lectures to create a three-dimensional graphic of unit cell of GaAs.

Preliminaries

Since there is a lot of typed input for this session, and we are also asking you to think quite a bit, we have provided you with a notebook which contains the basic input code. This session's notebook is stored as Crystal.nb in the Maths Lab folder. Once you have opened the notebook make a personal copy of it before you start work. To make sure that the report has your name on every page go to the File pulldown menu and going to Printing Settings and then Headers and Footers.... To put your name in the Footer click on the button for the Left Page Footer and type the folowing in the box entitled Centered: 

Cell[TextData["Your Name"],"Footer"]

Do the same for Right Page Footer and you are done.

The Maths of Crystallography: a Brief Introduction

All crystals can be thought of as having two components. 

There is a basis consisting of a collection of atoms or molecules in a particular spatial arrangement and orientation. This arrangement is sometimes regular, but need not be. Often, there are only one or two atoms, ions or radicals in a basis, though again not always. (The crystalline forms of certain proteins, with their polyatomic, irregular bases, are exceptions to both these rules).

Then you need a space lattice, which is a rule for distributing copies of the basis in a regular pattern through space. Each space lattice can be specified by three primitive vectors, a, b and c; any point in the space lattice can then be obtained by displacements of the form

(Subscript[n, 1])a + (Subscript[n, 2])b + (Subscript[n, 3])c,

where (Subscript[n, 1]), (Subscript[n, 2]) and (Subscript[n, 3]) are integers.

The choice of primitive vectors is not unique: for every space lattice there are many candidates, though often only a few obviously sensible ones. For any given choice of primitive vectors, the points with position vectors

0, a, b, c, a + b, a + c, b + c and a + b + c

form what is called the primitive cell: the smallest repeating unit in the lattice. This may or may not be the same as the conventional unit cell, which is a repeating unit chosen to illustrate the symmetries of the lattice.

1. Cubic Space Lattices

As we have said, for any given space lattice, any of its points can be obtained by adding together whole number multiples of its primitive displacement vectors. In particular, we ought to be able to get all the points in the conventional unit cell that way. That's what this exercise is about.

We will do this for  the conventional unit cells of the cubic space lattices: the simple cubic, the body-centred cubic and the face-centred cubic.

1.1 Some preliminary code

First we show you how you can set up some pictures of the unit cells of two of the three cubic lattices. We do this with the graphic primitive Line, which will draw a line between a pair of position vectors.

First, the body-centred cubic:

unitCell[bcc] = {AbsoluteThickness[2], GrayLevel[0.7], 
          Line[{{0, 0, 0}, {0, 0, 1}}], Line[{{0, 0, 0}, {0, 1, 0}}], 
          Line[{{0, 0, 0}, {1, 0, 0}}], Line[{{0, 0, 0}, {1, 1, 1}}], 
          Line[{{0, 0, 1}, {0, 1, 1}}], Line[{{0, 0, 1}, {1, 0, 1}}], 
          Line[{{0, 0, 1}, {1, 1, 0}}], Line[{{0, 1, 0}, {0, 1, 1}}], 
          Line[{{0, 1, 0}, {1, 0, 1}}], Line[{{0, 1, 0}, {1, 1, 0}}], 
          Line[{{0, 1, 1}, {1, 0, 0}}], Line[{{0, 1, 1}, {1, 1, 1}}], 
          Line[{{1, 0, 0}, {1, 0, 1}}], Line[{{1, 0, 0}, {1, 1, 0}}], 
          Line[{{1, 0, 1}, {1, 1, 1}}], 
          Line[{{1, 1, 0}, {1, 1, 1}}]};

The semi-colon at the end of this line of input suppresses Mathematica's output, which in this case would be rather uninformative. Now the more complicated face-centred cubic:

unitCell[fcc] = {AbsoluteThickness[2], GrayLevel[0.7], 
          Line[{{0, 0, 0}, {0, 0, 1}}], Line[{{0, 0, 0}, {0, 1, 0}}], 
          Line[{{0, 0, 0}, {0, 1, 1}}], Line[{{0, 0, 0}, {1, 0, 0}}], 
          Line[{{0, 0, 0}, {1, 0, 1}}], Line[{{0, 0, 0}, {1, 1, 0}}], 
          Line[{{0, 0, 1}, {0, 1, 0}}], Line[{{0, 0, 1}, {0, 1, 1}}], 
          Line[{{0, 0, 1}, {1, 0, 0}}], Line[{{0, 0, 1}, {1, 0, 1}}], 
          Line[{{0, 0, 1}, {1, 1, 1}}], Line[{{0, 1, 0}, {0, 1, 1}}], 
          Line[{{0, 1, 0}, {1, 0, 0}}], Line[{{0, 1, 0}, {1, 1, 0}}], 
          Line[{{0, 1, 0}, {1, 1, 1}}], Line[{{0, 1, 1}, {1, 0, 1}}], 
          Line[{{0, 1, 1}, {1, 1, 0}}], Line[{{0, 1, 1}, {1, 1, 1}}], 
          Line[{{1, 0, 0}, {1, 0, 1}}], Line[{{1, 0, 0}, {1, 1, 0}}], 
          Line[{{1, 0, 0}, {1, 1, 1}}], Line[{{1, 0, 1}, {1, 1, 0}}], 
          Line[{{1, 0, 1}, {1, 1, 1}}], 
          Line[{{1, 1, 0}, {1, 1, 1}}]};

You can see these pictures by typing

Show[Graphics3D[unitCell[bcc]], Boxed -> False, 
      ViewPoint -> {1.3, -2.4, 1}]

and similarly for the fcc unit cell. The lattice points are where the grey lines cross. The settings for the Boxed and ViewPoint options have been chosen to show the figures off to best advantage.

The other code we'll need at this stage is a way of illustrating the primitive displacement vectors and their sums. To do this we need to load up the following add on package

Needs["Graphics`PlotField3D`"]

and use the function

ListPlotVectorField3D[{{{0, 0, 0}, {1, 1, 1}}}, 
      VectorHeads  ->  True]

which in this example plots a displacement vector (1,1,1) from the point (0,0,0).

We will want to draw linear combinations of the primitive translation vectors on to the unit cell. We will draw the resultant translation vector with its origin at (0,0,0). For the case of the bcc lattice we therefore define the origin and the common choice of primitive vectors.

zero = {0, 0, 0};
a = {1, 1, -1}/2;
b = {-1, 1, 1}/2;
c = {1, -1, 1}/2;

We can now plot the unit cell and the translation vector a + b

Show[Graphics3D[unitCell[bcc]], 
      ListPlotVectorField3D[{{zero, a + b}}, VectorHeads  ->  True] , 
      Boxed -> False, ViewPoint -> {1.3, -2.4, 1}]

Well this is a lattice point, but the whole process of input and display was a bit clumsy. By defining the following function we improve things.

\(\(\(
\)\(bccvector[vector1_, vector2_, vector3_] := 
	
      Show[
		{Graphics3D[
            unitCell[
              bcc]], 
							ListPlotVectorField3D[{{zero, 
                vector1}, {vector1, vector2}, {vector1 + vector2, 
                vector3}}, 
			\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ VectorHeads\  -> \ True, 
            Boxed -> 
              False, 
							\ \ \ \ \ ColorFunction -> \((RGBColor[
                    0, 0, 1] &)\), DisplayFunction -> Identity]}, 
        Boxed -> False, 
        ViewPoint -> {1.3, \(-2.4\), 
            1}, 
\ \ DisplayFunction -> $DisplayFunction]\)\)\)

And now all you need to type in is

bccvector[a, b, 0 c]

and the annoying intermediate vector graphic is suppressed (you should check out how this was done).

Exercises and Explorations 1

1: The bcc lattice

Find all the points of the bcc unit cell in the form of sums of bcc primitive vectors. To help you here is a bit of code that will mark the points you have found with a red dot.

lattice[bcc] = {AbsolutePointSize[10], RGBColor[1, 0, 0], 
          Point[zero], Point[a + b], Point[a + b + c]};

You can redefine your function bccvector to include the points.

\(bccvector[vector_] := 
	
      Show[
		{Graphics3D[{unitCell[bcc], 
              lattice[bcc]}], 
							ListPlotVectorField3D[{{zero, 
                vector}}, 
			\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ VectorHeads\  -> \ True, 
            Boxed -> 
              False, 
							\ \ \ \ \ \ DisplayFunction -> 
              Identity]}, Boxed -> False, 
        ViewPoint -> {1.3, \(-2.4\), 
            1}, 
\ \ DisplayFunction -> $DisplayFunction]\)

Keep on adding in points to lattice[bcc] as you find them until all the lattice points are located.

In you write-up briefly describe the task, the code you used to a complete it and what it did, a list of the points of the unit cell expressed as sums of primitive vectors, and a 3D illustration of your final set of points with one of the displacement vectors used to determine the points.

2: The fcc lattice

Repeat for the fcc lattice. The usual choice of primitive vectors in this case is

zero = {0, 0, 0};
a2 = {1, 1, 0}/2;
b2 = {0, 1, 1}/2;
c2 = {1, 0, 1}/2;

Note that they've been given slightly different names to avoid interference between them and the ones we've already defined for the bcc lattice, and you will need to edit bccvector and lattice[bcc] to produce "fcc" equivalents.

In your write up describe how you edited the code, list the points of the unit cell expressed as sums of primitive vectors, and provide a 3D illustration of your final set of points together with one of the displacement vectors used to determine the points.

2. Bases and bonds

A true crystal is created by mapping a base onto a space lattice. That's what this section is about.

2.1 Preliminary code

We're going to be constructing a unit cell of gallium arsenide, which is based on the fcc lattice. So we need to have code for generating gallium and arsenic atoms and bonds. First we define colour and radius.

atomColor[Ga] = RGBColor[0.8, 0, 0];
atomColor[As] = RGBColor[0, 0.8, 0];
radius[Ga] = 0.075;
radius[As] = 0.1;

Then the atoms' shapes (as points or shaded spheres) and bonds (as lines). Much of this code will be mysterious at this stage. Don't worry about it, and unless you're heavily into computing you probably won't want to investigate it.

Needs["Graphics`Shapes`"]

atomPoint[{atom_, coords_}] := {atomColor[atom], 
        PointSize[radius[atom]], Point[coords]}

atomSphere[{atom_, coords_}] := {EdgeForm[], 
        SurfaceColor[atomColor[atom]], 
        TranslateShape[Sphere[radius[atom], 10, 10], coords]}

bondLine[{coords1_, coords2_}] := {Thickness[0.025], 
        RGBColor[0.8, 0.8, 0], Line[{coords1, coords2}]}

Exercises and Explorations 2

1: The atoms

The gallium arsenide basis consists of a gallium atom at the origin and an arsenic atom at the point ((1/4), (1/4), (1/4)). Building the GaAs crystal corresponds to placing a copy of the basis at every point of the space lattice. Let's define a function for placing the basis at a particular set of coordinates

TranslateBasis[
          coords_] := {{Ga, {0, 0, 0} + coords}, {As, {1/4, 1/4, 1/4} + 
              coords}};

Test the function to see how it works

TranslateBasis[{(1/2), (1/2), 0}]

and describe this in your report.

We now have to do this for all the fcc lattice points to create a large table defining the positions of every Ga and As atom. There's a natural way of doing this in Mathematica using the Map command, which we will use a number of times in this exercise. Here's an example, using just two of the points in the fcc space lattice

Map[TranslateBasis, {{0, 0, 0}, {(1/2), (1/2), 0}}]

In your report you should explain what Map does.

To place the basis on all of the lattice points you now need to use the coordinates you obtained in the previous section to complete the table below

unitCellCoords[fcc] = {zero, 
          a2 + b2 + c2, ... ..};

and then you can place the basis on all of the lattice points

unitCellBases = Map[TranslateBasis, unitCellCoords[fcc]]

For what we're going to need to do later, we need the atoms to be listed individually, not (as here) in pairs. We can undo the pairing using the Flatten command

unitCellAtoms = Flatten[unitCellBases, 1]

Let's convert what we've generated into a simple graphic and have a look at it. We use the Map command again to replace the Ga's and As's by their graphical representations.

im1 = Map[atomPoint, unitCellAtoms]

Show[Graphics3D[{unitCell[fcc], im1}], Boxed -> False, 
      ViewPoint -> {1.3, -2.4, 1}]

Well it's a sort of success. The atoms are all there in the unit cell, but many of the arsenic atoms we've generated lie outside the unit cell! The following code checks up what is inside the unit cell and then selects it for display

inside[{atom_, {x_, y_, z_}}] := 
      TrueQ[(0 ≤ x ≤ 1) && (0 ≤ 
              y ≤ 1) && (0 ≤ z ≤ 
              1)]

unitCellAtoms = Select[unitCellAtoms, inside]

im2 = Map[atomPoint, unitCellAtoms]

Show[Graphics3D[{unitCell[fcc], im2}], Boxed -> False, 
      ViewPoint -> {1.3, -2.4, 1}]

Briefly explain why simply placing a copy of the base at every point of the unit cell generates a figure that extends beyond the unit cell.

2: The bonds

Your task is now to add all the bonds to this picture. Here we define the start and finish position vectors of one of the bonds

bond1 = {{(3/4), (3/4), (1/4)}, {1, 1, 0}}

which we place in a list, which will eventually contain all the bond coordinates

bondCoords = {bond1}

Now we can turn this into a working graphic

Bonds = Map[bondLine, bondCoords]

and add it to our working picture of the unit cell

Show[Graphics3D[{im2, Bonds, unitCell[fcc]}], Boxed -> False, 
      ViewPoint -> {1.3, -2.4, 1}]

Now find the next bond, name it bond2 and add it to the bondCoords list and check it is OK. Keep on doing this until all the bonds have been drawn. Print this figure for your report.