Jake Hansen
Contents
Bio
I started working for Dr. Hart in September of 2013. I am a Junior working towards a Physics Major and a Computer Science Minor. I can program in Java, C, C++ and Python. Although, I started writing an app lately with one of my friends and it made me realize how much Java I forgot during my mission. I served a full time Spanish speaking mission in Atlanta Georgia. While I was there I also got to learn some Vietnamese and have name tags in 3 different languages. I enjoy playing the piano, ice hockey, skiing, and playing ping pong.
Current Project
Super Alloy Hunt
The past few months I have been working with Mouli to find new super alloys. A super alloy is a metal that has extraordinary materials properties at high temperatures. They are commonly used in high temperature applications such as jet engines. We were inspired by a paper in 2006 about a cutting edge cobalt super alloy. For a few months we have been working on a method to predict whether or not metals will be stable at high temperature. As we stared exploring this idea we became familiar with aflow which lead us to expand our calculations to cover other systems of the same structure as the cobalt alloy I mentioned earlier. So far we have ran our calculations on a little over 1900 out of the 2220 unique systems that we selected to explore.
So what exactly are these calculations? Good question. The main thing that we are looking for is if a metal will be stable. This is mainly done by examining the enthalpy of formation. Generally if a material has a negative enthalpy of formation it will be stable. Conversely if if has a positive enthalpy of formation it will be unstable. Aflow enables us to calculate the enthalpies for various metals. Using all of the known enthalpies of each of the binary combinations we can draw convex hulls for the enthalpies of ternary alloys which look something like this.
Largely I have been involved in writing the code that calculates the likelihood of an alloy to be stable. Largely it is code that I have written from scratch, however we let qhull draw the convex hulls because of its versatility and speed.
Past Code
Binary Alloy on a Triangular Lattice
The media player is loading...

This is a video that I used to test the .mp4 extension that I added to the wiki. It shows a basic binary alloy on a triangular lattice. 
SUMMER 2014: Currently I am working on reproducing results found by David P. Landau of the University of Georgia that he published in his article (Phys. Rev. B 27, 5604). His work shows that for a binary alloy on a triangular lattice that there are two critical temperatures at which the system transitions. So far I have written code that builds lattices of any given size, as well as many of the generic functions like calculating neighboring site values. As of right now, although it appears that I can achieve ordered endstates, I have yet to see a double transition. At first my code showed that the specific heat was rather choppy when compared to that of a square binary alloy. I wondered if that is what was inhibiting my ability to see the two peaks that Landau recorded. So after some tinkering and upping the resolution, I found the two different peaks. At the moment however, the two peaks seem a bit smashed together, and the first peak almost doesn't show at R = 1. For this reason, I decided to up the resolution even further(10x, I'm now at 50000 MC steps per site which is 10x the upper limit that Landau proposed) and submit it as a job to the super computer to let it run over night. When the results came back it still looked like the right peak was overpowering the left peak, so I'll have to work some more at it to see if I can get both peaks to manifest. Meanwhile, I have been working on learning C++ and have been recoding my python code into c++ to reduce runtime. The goal is that the inner workings will all be written in C++ while all the bells and whistles are written in python. Some preliminary tests I ran showed that by using C++ to do all of the heavy lifting, I might be able to reduce the runtime by as much as a 2 orders of magnitude. Update: I have now finished the my c++ rendition of my triangular lattice code. It runs considerably faster, but I am still finding that unlike Landau, my R = 1 peak has a plateau and a peak instead of two distinct peaks. I do however see two distinct peaks at lower values such as R = 1/4 or R = 1/2. The most interesting thing is that I seem to get the same locations of the peaks that Landau shows, i.e. it feels like my peaks or plateaus are in the correct spots. I am not really sure what would be causing this.
The movie on the left shows an animated version of a binary alloy on a triangular lattice. Each spin in this configuration repels from it's nearest neighbors and attracts to its next nearest neighbors. Because of this we start to see a soccer ball pattern pretty quickly. You'll notice however that because the concentration is at 50% not all of the spins can can be in their ideal spot. That is why we begin to see an overall patter later in the movie. The program that builds the movies lets me see that at given configurations that the system behaves as it is supposed to.
These is my source code used to create the above animation. All three files are needed. Triangular_animate.py is the main file.
 File:Jake Triangular animate.py
 File:Jake TriangularLatticeFunctions.py
 File:Jake Triangular MvTime.py
3D Chaos Game
Source Code: JakeChaosGame3D.py
This simple code produces a 3D version of the Sierpinski triangle using a Monte Carlo method. It is very similar to the 2D version except it adds a 4th point that it can randomly pick from. It is a good example of a simple python script. You might notice that unlike other programming languages python does not use braces or semicolons. But rather uses whitespace for organization. It also does not require that you declare the types of your variables.
Created on Dec 20, 2013
@author: Jacob Hansen
import random as r
import matplotlib.pyplot as plt
import copy
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
def newPoint(Fixed_Point, Current_Point):
"""Decide where the new point will be located. Returns a List [x,y,z]"""
new_point = [0,0,0]
new_point[0] = Fixed_Point[0] if Fixed_Point[0] < Current_Point[0] else Current_Point[0]
new_point[1] = Fixed_Point[1] if Fixed_Point[1] < Current_Point[1] else Current_Point[1]
new_point[2] = Fixed_Point[2] if Fixed_Point[2] < Current_Point[2] else Current_Point[2]
new_point[0] += np.abs(Fixed_Point[0]  Current_Point[0])/2
new_point[1] += np.abs(Fixed_Point[1]  Current_Point[1])/2
new_point[2] += np.abs(Fixed_Point[2]  Current_Point[2])/2
return new_point
fig = plt.figure() # configure 3D plot
ax = fig.gca(projection='3d')
"""Initialize starting parameters."""
size = 20000
point0 = [0.0,0.0,0.0]
point1 = [size,0.0,0.0]
point2 = [size/2,0.0,size]
point3 = [size/2,size,size/2]
decide = 0
xList = [point0[0],point1[0],point2[0],point3[0]]
yList = [point0[1],point1[1],point2[1],point3[1]]
zList = [point0[2],point1[2],point2[2],point3[2]]
old = [r.randint(0,size),r.randint(0,size),r.randint(0,size)]
original = old
"""Build new points."""
for i in range(10000):
decide = r.choice([point0,point1,point2,point3])
new = newPoint(decide,old)
xList.append(new[0])
yList.append(new[1])
zList.append(new[2])
old = copy.deepcopy(new)
"""Plot data."""
ax.axes.xaxis.set_ticklabels([])
ax.axes.yaxis.set_ticklabels([])
ax.axes.zaxis.set_ticklabels([])
plt.title("3D veiw of X, Y and Z")
ax.scatter(xList,yList,zList,s=1,lw=0)
plt.show()
Ising Model
Below is the code that I wrote as I studied chapter 8 of Giordano and the Monte Carlo method. One of the things that really interested me while studying Ch 8. was something that Giordano said about random versus sequential steps as you iterated through your grid. In all reality it probably isn't super interesting. In his book Giordano states that sequential steps through the lattice are sufficient but that random steps also work. As I was helping Will with his code one day we were trying to debug an interesting error that he had, after we fixed it I noticed that Will's results differed slightly from my own. Will had written his code to sequentially step through the lattice as Giordano had suggested, where I had written mine to step randomly. The difference wasn't huge but it was enough to make me wonder why they were different and if one was better than the other. Giordano uses sequential iteration in his book, suggesting that it is the preferential method, but upon closer observation there are some major flaws with stepping sequentially through the lattice. One of the biggest problems is that sequential iterations don't give each spin the same chance to flip. The Graph on the left was created using sequential iterations while the graph on the right was created using random iterations. Both graphs show the tail end of a lattice after it has found its happiest state. In this case the lattice is full of spins that are oriented in the +1 direction, or up direction. We can see that there is some fluctuation, but that in general it will stay around 1.
As we look closely at these two graphs we notice an interesting difference that happens to be the root of our problem. You'll notice that in the sequential graph when a spin becomes unaligned, it quickly becomes realigned. In fact almost never after a lattice has reached its end state will a spin remain unaligned for more than one iteration. Now on the other hand, if we step randomly, you'll notice that spins might stick around for an iteration or two before flipping back. This is because every spin is not examined every iteration. This might lead us to believe that the random iteration is the method that is not allowing equal chances to flip. However, this is not the case. Although some spins might not be examined during each iteration while stepping randomly, if we step sequentially all spins are considered but do not have an equal(fair) chance to flip. Each spin is heavily influenced by what its neighbor before it did. Because of this influence if the spins were considered sequentially, we could end up with a chain of dominoes of a sort. This can be easily seen if we use sequential iteration on a checkerboard grid. Essentially what happens is that each spin decides that it needs to flip which leaves us with the opposite of what we started with, then as we iterate through again we are back to what we started with, and thus we are stuck in this metastable state. If we examined the same checkerboard lattice random steps instead we would see that the lattice will tend to polarize the spins to point in the same direction.
IsingFunctions
Source Code: JakeIsingFunctions.py
IsingFunctions.py is a module that contains vital functions for the rest of my Ising programs. You will need this module to be able to run any of my other Ising modules. You can download the source code from the link above.
Animated Ising Model with Graph of Magnetization
Source Code: Jake_M_animate2.py
By far the most tricky piece of code that I've written in python to date. However, it was a blast writing it. If you want to try it out I would suggest playing with the temperature around the critical point of 2.27 as well as the size. The other interesting parameter to play with is the fpf(flips per frame). This allows you to change the resolution of the animations. For example setting it to 1 means that only 1 spin will change each time the animation updates. It can be set to create mp4 movies of definite length or you can just watch it run for forever. Below is a link to a cool video that I made with this code. Note that the M graph isn't accurate as I disabled it as I compiled this video.
Alloy Version of the Ising Model
We also played with a binary alloy version of the Ising Model. Derek and Spencer have done quite a bit more on this than I have. But I also animated it. So if you want more info check with Derek and Spencer. Either way here are the files to animate it with.
Source Code: Jake_AlloyAnimate.py
Necessary Files: Jake_AlloyFunctions.py