<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://chemwiki.ch.ic.ac.uk/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ly2412</id>
	<title>ChemWiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://chemwiki.ch.ic.ac.uk/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ly2412"/>
	<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/wiki/Special:Contributions/Ly2412"/>
	<updated>2026-05-17T00:12:18Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=486913</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=486913"/>
		<updated>2015-02-13T14:27:35Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Determining the heat capacity */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000 because they need to be parallel to each other to minimise their energies.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE: The energy in the graph above should be in the unit of J(J is the constant related to the strength of interactions between two neighboring spins), the magnetisation should be in the unit of ћ and the temperature should be in the unit of J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;. These units should be them same in the rest of this report unless stated otherwise.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. &lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations vs. temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the accuracy of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations vs. temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&#039;&#039;&#039;NOTE: The heat capacity in the graph above has the unit of K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt; and it has the same unit in the rest of this report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice is plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice(between 2.0 and 2.5 K), as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully. If the order of the polynomial was increased even higher, an error message would pop up to alert about the possible poor quality of the polynomial fitting.&lt;br /&gt;
&lt;br /&gt;
[[File: LY_fit10PN3232r.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt;(J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;) || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_line.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.281 J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.269 J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;.&amp;lt;ref name=&amp;quot;2DIL&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1. The lack of data points on the right hand side of the graph due to the nature of the x-axis which is 1/L  and L must be integers. Therefore, only three points are possible to be located on the right half of the graph with x coordinates, 0.25, 0.33 and 0.5. &lt;br /&gt;
&lt;br /&gt;
2. The qualities of the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values for small lattices such as 2X2 and 4x4 are poor. There are only 4 spins in the 2x2 lattice, which means the possible values of the energy and the magnetisation of the system are very limited. Therefore the variance of the energy of this system can very significantly from one simulation to another, especially in the region near the Curie temperature, which means &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; can vary from one simulation to another.&lt;br /&gt;
&lt;br /&gt;
3. The order of the polynomial and the exact peak region that we chose to fit the polynomial onto can greatly influence the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values obtained. &lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding.In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Actually, just by ignoring the data from 2x2 and 4x4 lattices, and fitting a straight line to the rest of the points, a much better result is obtained, as shown in &#039;&#039;&#039;Figure 11&#039;&#039;&#039;. In &#039;&#039;&#039;Figure 11&#039;&#039;&#039;, the y-intercept is exactly 2.269 J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;. However, the quality of this analysis is highly questionable due to the fact that only 4 points are used. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_line_2.png|thumb|center|500px|&#039;&#039;&#039;Figure 11. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;2DIL&amp;quot;&amp;gt;H.A. Kramers and G.H. Wannier, Phys. Rev. 60, 252 (1941).&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=486911</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=486911"/>
		<updated>2015-02-13T14:25:14Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Introduction to Monte Carlo simulation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000 because they need to be parallel to each other to minimise their energies.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE: The energy in the graph above should be in the unit of J(J is the constant related to the strength of interactions between two neighboring spins), the magnetisation should be in the unit of ћ and the temperature should be in the unit of J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;. These units should be them same in the rest of this report unless stated otherwise.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. &lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations vs. temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the accuracy of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations vs. temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice is plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice(between 2.0 and 2.5 K), as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully. If the order of the polynomial was increased even higher, an error message would pop up to alert about the possible poor quality of the polynomial fitting.&lt;br /&gt;
&lt;br /&gt;
[[File: LY_fit10PN3232r.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt;(J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;) || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_line.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.281 J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.269 J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;.&amp;lt;ref name=&amp;quot;2DIL&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1. The lack of data points on the right hand side of the graph due to the nature of the x-axis which is 1/L  and L must be integers. Therefore, only three points are possible to be located on the right half of the graph with x coordinates, 0.25, 0.33 and 0.5. &lt;br /&gt;
&lt;br /&gt;
2. The qualities of the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values for small lattices such as 2X2 and 4x4 are poor. There are only 4 spins in the 2x2 lattice, which means the possible values of the energy and the magnetisation of the system are very limited. Therefore the variance of the energy of this system can very significantly from one simulation to another, especially in the region near the Curie temperature, which means &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; can vary from one simulation to another.&lt;br /&gt;
&lt;br /&gt;
3. The order of the polynomial and the exact peak region that we chose to fit the polynomial onto can greatly influence the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values obtained. &lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding.In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Actually, just by ignoring the data from 2x2 and 4x4 lattices, and fitting a straight line to the rest of the points, a much better result is obtained, as shown in &#039;&#039;&#039;Figure 11&#039;&#039;&#039;. In &#039;&#039;&#039;Figure 11&#039;&#039;&#039;, the y-intercept is exactly 2.269 J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;. However, the quality of this analysis is highly questionable due to the fact that only 4 points are used. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_line_2.png|thumb|center|500px|&#039;&#039;&#039;Figure 11. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;2DIL&amp;quot;&amp;gt;H.A. Kramers and G.H. Wannier, Phys. Rev. 60, 252 (1941).&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=486910</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=486910"/>
		<updated>2015-02-13T14:12:25Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* The effect of temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000 because they need to be parallel to each other to minimise their energies.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. &lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations vs. temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the accuracy of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations vs. temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice is plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice(between 2.0 and 2.5 K), as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully. If the order of the polynomial was increased even higher, an error message would pop up to alert about the possible poor quality of the polynomial fitting.&lt;br /&gt;
&lt;br /&gt;
[[File: LY_fit10PN3232r.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt;(J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;) || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_line.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.281 J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.269 J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;.&amp;lt;ref name=&amp;quot;2DIL&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1. The lack of data points on the right hand side of the graph due to the nature of the x-axis which is 1/L  and L must be integers. Therefore, only three points are possible to be located on the right half of the graph with x coordinates, 0.25, 0.33 and 0.5. &lt;br /&gt;
&lt;br /&gt;
2. The qualities of the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values for small lattices such as 2X2 and 4x4 are poor. There are only 4 spins in the 2x2 lattice, which means the possible values of the energy and the magnetisation of the system are very limited. Therefore the variance of the energy of this system can very significantly from one simulation to another, especially in the region near the Curie temperature, which means &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; can vary from one simulation to another.&lt;br /&gt;
&lt;br /&gt;
3. The order of the polynomial and the exact peak region that we chose to fit the polynomial onto can greatly influence the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values obtained. &lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding.In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Actually, just by ignoring the data from 2x2 and 4x4 lattices, and fitting a straight line to the rest of the points, a much better result is obtained, as shown in &#039;&#039;&#039;Figure 11&#039;&#039;&#039;. In &#039;&#039;&#039;Figure 11&#039;&#039;&#039;, the y-intercept is exactly 2.269 J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;. However, the quality of this analysis is highly questionable due to the fact that only 4 points are used. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_line_2.png|thumb|center|500px|&#039;&#039;&#039;Figure 11. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;2DIL&amp;quot;&amp;gt;H.A. Kramers and G.H. Wannier, Phys. Rev. 60, 252 (1941).&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=486908</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=486908"/>
		<updated>2015-02-13T14:11:32Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000 because they need to be parallel to each other to minimise their energies.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(K)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. &lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations vs. temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the accuracy of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations vs. temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice is plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice(between 2.0 and 2.5 K), as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully. If the order of the polynomial was increased even higher, an error message would pop up to alert about the possible poor quality of the polynomial fitting.&lt;br /&gt;
&lt;br /&gt;
[[File: LY_fit10PN3232r.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt;(J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;) || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_line.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.281 J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.269 J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;.&amp;lt;ref name=&amp;quot;2DIL&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1. The lack of data points on the right hand side of the graph due to the nature of the x-axis which is 1/L  and L must be integers. Therefore, only three points are possible to be located on the right half of the graph with x coordinates, 0.25, 0.33 and 0.5. &lt;br /&gt;
&lt;br /&gt;
2. The qualities of the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values for small lattices such as 2X2 and 4x4 are poor. There are only 4 spins in the 2x2 lattice, which means the possible values of the energy and the magnetisation of the system are very limited. Therefore the variance of the energy of this system can very significantly from one simulation to another, especially in the region near the Curie temperature, which means &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; can vary from one simulation to another.&lt;br /&gt;
&lt;br /&gt;
3. The order of the polynomial and the exact peak region that we chose to fit the polynomial onto can greatly influence the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values obtained. &lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding.In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Actually, just by ignoring the data from 2x2 and 4x4 lattices, and fitting a straight line to the rest of the points, a much better result is obtained, as shown in &#039;&#039;&#039;Figure 11&#039;&#039;&#039;. In &#039;&#039;&#039;Figure 11&#039;&#039;&#039;, the y-intercept is exactly 2.269 J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;. However, the quality of this analysis is highly questionable due to the fact that only 4 points are used. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_line_2.png|thumb|center|500px|&#039;&#039;&#039;Figure 11. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;2DIL&amp;quot;&amp;gt;H.A. Kramers and G.H. Wannier, Phys. Rev. 60, 252 (1941).&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=486907</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=486907"/>
		<updated>2015-02-13T14:10:23Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000 because they need to be parallel to each other to minimise their energies.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(K)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. &lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations vs. temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the accuracy of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations vs. temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice is plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice(between 2.0 and 2.5 K), as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully. If the order of the polynomial was increased even higher, an error message would pop up to alert about the possible poor quality of the polynomial fitting.&lt;br /&gt;
&lt;br /&gt;
[[File: LY_fit10PN3232r.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_line.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.281 J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.269 J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;.&amp;lt;ref name=&amp;quot;2DIL&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1. The lack of data points on the right hand side of the graph due to the nature of the x-axis which is 1/L  and L must be integers. Therefore, only three points are possible to be located on the right half of the graph with x coordinates, 0.25, 0.33 and 0.5. &lt;br /&gt;
&lt;br /&gt;
2. The qualities of the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values for small lattices such as 2X2 and 4x4 are poor. There are only 4 spins in the 2x2 lattice, which means the possible values of the energy and the magnetisation of the system are very limited. Therefore the variance of the energy of this system can very significantly from one simulation to another, especially in the region near the Curie temperature, which means &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; can vary from one simulation to another.&lt;br /&gt;
&lt;br /&gt;
3. The order of the polynomial and the exact peak region that we chose to fit the polynomial onto can greatly influence the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values obtained. &lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding.In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Actually, just by ignoring the data from 2x2 and 4x4 lattices, and fitting a straight line to the rest of the points, a much better result is obtained, as shown in &#039;&#039;&#039;Figure 11&#039;&#039;&#039;. In &#039;&#039;&#039;Figure 11&#039;&#039;&#039;, the y-intercept is exactly 2.269 J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;. However, the quality of this analysis is highly questionable due to the fact that only 4 points are used. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_line_2.png|thumb|center|500px|&#039;&#039;&#039;Figure 11. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;2DIL&amp;quot;&amp;gt;H.A. Kramers and G.H. Wannier, Phys. Rev. 60, 252 (1941).&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=486906</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=486906"/>
		<updated>2015-02-13T14:09:10Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000 because they need to be parallel to each other to minimise their energies.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(K)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. &lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations vs. temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the accuracy of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations vs. temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice is plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice(between 2.0 and 2.5 K), as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully. If the order of the polynomial was increased even higher, an error message would pop up to alert about the possible poor quality of the polynomial fitting.&lt;br /&gt;
&lt;br /&gt;
[[File: LY_fit10PN3232r.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_line.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.281 J/K&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt;, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.269 K.&amp;lt;ref name=&amp;quot;2DIL&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1. The lack of data points on the right hand side of the graph due to the nature of the x-axis which is 1/L  and L must be integers. Therefore, only three points are possible to be located on the right half of the graph with x coordinates, 0.25, 0.33 and 0.5. &lt;br /&gt;
&lt;br /&gt;
2. The qualities of the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values for small lattices such as 2X2 and 4x4 are poor. There are only 4 spins in the 2x2 lattice, which means the possible values of the energy and the magnetisation of the system are very limited. Therefore the variance of the energy of this system can very significantly from one simulation to another, especially in the region near the Curie temperature, which means &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; can vary from one simulation to another.&lt;br /&gt;
&lt;br /&gt;
3. The order of the polynomial and the exact peak region that we chose to fit the polynomial onto can greatly influence the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values obtained. &lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding.In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Actually, just by ignoring the data from 2x2 and 4x4 lattices, and fitting a straight line to the rest of the points, a much better result is obtained, as shown in &#039;&#039;&#039;Figure 11&#039;&#039;&#039;. In &#039;&#039;&#039;Figure 11&#039;&#039;&#039;, the y-intercept is exactly 2.269 K. However, the quality of this analysis is highly questionable due to the fact that only 4 points are used. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_line_2.png|thumb|center|500px|&#039;&#039;&#039;Figure 11. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;2DIL&amp;quot;&amp;gt;H.A. Kramers and G.H. Wannier, Phys. Rev. 60, 252 (1941).&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=486903</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=486903"/>
		<updated>2015-02-13T14:02:34Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000 because they need to be parallel to each other to minimise their energies.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(K)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. &lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations vs. temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the accuracy of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations vs. temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice is plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice(between 2.0 and 2.5 K), as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully. If the order of the polynomial was increased even higher, an error message would pop up to alert about the possible poor quality of the polynomial fitting.&lt;br /&gt;
&lt;br /&gt;
[[File: LY_fit10PN3232r.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_line.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.281 K, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.269 K.&amp;lt;ref name=&amp;quot;2DIL&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1. The lack of data points on the right hand side of the graph due to the nature of the x-axis which is 1/L  and L must be integers. Therefore, only three points are possible to be located on the right half of the graph with x coordinates, 0.25, 0.33 and 0.5. &lt;br /&gt;
&lt;br /&gt;
2. The qualities of the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values for small lattices such as 2X2 and 4x4 are poor. There are only 4 spins in the 2x2 lattice, which means the possible values of the energy and the magnetisation of the system are very limited. Therefore the variance of the energy of this system can very significantly from one simulation to another, especially in the region near the Curie temperature, which means &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; can vary from one simulation to another.&lt;br /&gt;
&lt;br /&gt;
3. The order of the polynomial and the exact peak region that we chose to fit the polynomial onto can greatly influence the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values obtained. &lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding.In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Actually, just by ignoring the data from 2x2 and 4x4 lattices, and fitting a straight line to the rest of the points, a much better result is obtained, as shown in &#039;&#039;&#039;Figure 11&#039;&#039;&#039;. In &#039;&#039;&#039;Figure 11&#039;&#039;&#039;, the y-intercept is exactly 2.269 K. However, the quality of this analysis is highly questionable due to the fact that only 4 points are used. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_line_2.png|thumb|center|500px|&#039;&#039;&#039;Figure 11. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;2DIL&amp;quot;&amp;gt;H.A. Kramers and G.H. Wannier, Phys. Rev. 60, 252 (1941).&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=486900</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=486900"/>
		<updated>2015-02-13T14:00:00Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* The effect of system size */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000 because they need to be parallel to each other to minimise their energies.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(K)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. &lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations vs. temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the accuracy of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations vs. temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice(between 2.0 and 2.5 K), as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully. If the order of the polynomial was increased even higher, an error message would pop up to alert about the possible poor quality of the polynomial fitting.&lt;br /&gt;
&lt;br /&gt;
[[File: LY_fit10PN3232r.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_line.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.281 K, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.269 K.&amp;lt;ref name=&amp;quot;2DIL&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1. The lack of data points on the right hand side of the graph due to the nature of the x-axis which is 1/L  and L must be integers. Therefore, only three points are possible to be located on the right half of the graph with x coordinates, 0.25, 0.33 and 0.5. &lt;br /&gt;
&lt;br /&gt;
2. The qualities of the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values for small lattices such as 2X2 and 4x4 are poor. There are only 4 spins in the 2x2 lattice, which means the possible values of the energy and the magnetisation of the system are very limited. Therefore the variance of the energy of this system can very significantly from one simulation to another, especially in the region near the Curie temperature, which means &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; can vary from one simulation to another.&lt;br /&gt;
&lt;br /&gt;
3. The order of the polynomial and the exact peak region that we chose to fit the polynomial onto can greatly influence the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values obtained. &lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding.In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Actually, just by ignoring the data from 2x2 and 4x4 lattices, and fitting a straight line to the rest of the points, a much better result is obtained, as shown in &#039;&#039;&#039;Figure 11&#039;&#039;&#039;. In &#039;&#039;&#039;Figure 11&#039;&#039;&#039;, the y-intercept is exactly 2.269 K. However, the quality of this analysis is highly questionable due to the fact that only 4 points are used. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_line_2.png|thumb|center|500px|&#039;&#039;&#039;Figure 11. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;2DIL&amp;quot;&amp;gt;H.A. Kramers and G.H. Wannier, Phys. Rev. 60, 252 (1941).&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=486895</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=486895"/>
		<updated>2015-02-13T13:53:50Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Introduction to the Ising model */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000 because they need to be parallel to each other to minimise their energies.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(K)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. &lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice(between 2.0 and 2.5 K), as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully. If the order of the polynomial was increased even higher, an error message would pop up to alert about the possible poor quality of the polynomial fitting.&lt;br /&gt;
&lt;br /&gt;
[[File: LY_fit10PN3232r.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_line.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.281 K, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.269 K.&amp;lt;ref name=&amp;quot;2DIL&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1. The lack of data points on the right hand side of the graph due to the nature of the x-axis which is 1/L  and L must be integers. Therefore, only three points are possible to be located on the right half of the graph with x coordinates, 0.25, 0.33 and 0.5. &lt;br /&gt;
&lt;br /&gt;
2. The qualities of the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values for small lattices such as 2X2 and 4x4 are poor. There are only 4 spins in the 2x2 lattice, which means the possible values of the energy and the magnetisation of the system are very limited. Therefore the variance of the energy of this system can very significantly from one simulation to another, especially in the region near the Curie temperature, which means &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; can vary from one simulation to another.&lt;br /&gt;
&lt;br /&gt;
3. The order of the polynomial and the exact peak region that we chose to fit the polynomial onto can greatly influence the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values obtained. &lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding.In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Actually, just by ignoring the data from 2x2 and 4x4 lattices, and fitting a straight line to the rest of the points, a much better result is obtained, as shown in &#039;&#039;&#039;Figure 11&#039;&#039;&#039;. In &#039;&#039;&#039;Figure 11&#039;&#039;&#039;, the y-intercept is exactly 2.269 K. However, the quality of this analysis is highly questionable due to the fact that only 4 points are used. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_line_2.png|thumb|center|500px|&#039;&#039;&#039;Figure 11. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;2DIL&amp;quot;&amp;gt;H.A. Kramers and G.H. Wannier, Phys. Rev. 60, 252 (1941).&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485461</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485461"/>
		<updated>2015-02-11T21:22:09Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* The effect of temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(K)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. &lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice(between 2.0 and 2.5 K), as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully. If the order of the polynomial was increased even higher, an error message would pop up to alert about the possible poor quality of the polynomial fitting.&lt;br /&gt;
&lt;br /&gt;
[[File: LY_fit10PN3232r.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_line.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.281 K, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.269 K.&amp;lt;ref name=&amp;quot;2DIL&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1. The lack of data points on the right hand side of the graph due to the nature of the x-axis which is 1/L  and L must be integers. Therefore, only three points are possible to be located on the right half of the graph with x coordinates, 0.25, 0.33 and 0.5. &lt;br /&gt;
&lt;br /&gt;
2. The qualities of the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values for small lattices such as 2X2 and 4x4 are poor. There are only 4 spins in the 2x2 lattice, which means the possible values of the energy and the magnetisation of the system are very limited. Therefore the variance of the energy of this system can very significantly from one simulation to another, especially in the region near the Curie temperature, which means &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; can vary from one simulation to another.&lt;br /&gt;
&lt;br /&gt;
3. The order of the polynomial and the exact peak region that we chose to fit the polynomial onto can greatly influence the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values obtained. &lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding.In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Actually, just by ignoring the data from 2x2 and 4x4 lattices, and fitting a straight line to the rest of the points, a much better result is obtained, as shown in &#039;&#039;&#039;Figure 11&#039;&#039;&#039;. In &#039;&#039;&#039;Figure 11&#039;&#039;&#039;, the y-intercept is exactly 2.269 K. However, the quality of this analysis is highly questionable due to the fact that only 4 points are used. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_line_2.png|thumb|center|500px|&#039;&#039;&#039;Figure 11. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;2DIL&amp;quot;&amp;gt;H.A. Kramers and G.H. Wannier, Phys. Rev. 60, 252 (1941).&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485457</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485457"/>
		<updated>2015-02-11T21:19:58Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(K)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice(between 2.0 and 2.5 K), as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully. If the order of the polynomial was increased even higher, an error message would pop up to alert about the possible poor quality of the polynomial fitting.&lt;br /&gt;
&lt;br /&gt;
[[File: LY_fit10PN3232r.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_line.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.281 K, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.269 K.&amp;lt;ref name=&amp;quot;2DIL&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1. The lack of data points on the right hand side of the graph due to the nature of the x-axis which is 1/L  and L must be integers. Therefore, only three points are possible to be located on the right half of the graph with x coordinates, 0.25, 0.33 and 0.5. &lt;br /&gt;
&lt;br /&gt;
2. The qualities of the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values for small lattices such as 2X2 and 4x4 are poor. There are only 4 spins in the 2x2 lattice, which means the possible values of the energy and the magnetisation of the system are very limited. Therefore the variance of the energy of this system can very significantly from one simulation to another, especially in the region near the Curie temperature, which means &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; can vary from one simulation to another.&lt;br /&gt;
&lt;br /&gt;
3. The order of the polynomial and the exact peak region that we chose to fit the polynomial onto can greatly influence the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; values obtained. &lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding.In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Actually, just by ignoring the data from 2x2 and 4x4 lattices, and fitting a straight line to the rest of the points, a much better result is obtained, as shown in &#039;&#039;&#039;Figure 11&#039;&#039;&#039;. In &#039;&#039;&#039;Figure 11&#039;&#039;&#039;, the y-intercept is exactly 2.269 K. However, the quality of this analysis is highly questionable due to the fact that only 4 points are used. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_line_2.png|thumb|center|500px|&#039;&#039;&#039;Figure 11. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;2DIL&amp;quot;&amp;gt;H.A. Kramers and G.H. Wannier, Phys. Rev. 60, 252 (1941).&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485445</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485445"/>
		<updated>2015-02-11T21:04:23Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(K)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice(between 2.0 and 2.5 K), as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully. If the order of the polynomial was increased even higher, an error message would pop up to alert about the possible poor quality of the polynomial fitting.&lt;br /&gt;
&lt;br /&gt;
[[File: LY_fit10PN3232r.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_line.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.281 K, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.269 K.&amp;lt;ref name=&amp;quot;2DIL&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1. The lack of data points on the upper right corner of the graph due to the nature of the x-axis which is 1/L  and L must be integers. Therefore, only 0.5, 0.33, 0.25 &lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
&lt;br /&gt;
3.&lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding.In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Actually, just by ignoring the data from 2x2 and 4x4 lattices, and fitting a straight line to the rest of the points, a much better result is obtained, as shown in &#039;&#039;&#039;Figure 11&#039;&#039;&#039;. In &#039;&#039;&#039;Figure 11&#039;&#039;&#039;, the y-intercept is exactly 2.269 K. However, the quality of this analysis is highly questionable due to the fact that only 4 points are used. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_line_2.png|thumb|center|500px|&#039;&#039;&#039;Figure 11. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;2DIL&amp;quot;&amp;gt;H.A. Kramers and G.H. Wannier, Phys. Rev. 60, 252 (1941).&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485444</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485444"/>
		<updated>2015-02-11T21:00:49Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(K)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice(between 2.0 and 2.5 K), as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully. If the order of the polynomial was increased even higher, an error message would pop up to alert about the possible poor quality of the polynomial fitting.&lt;br /&gt;
&lt;br /&gt;
[[File: LY_fit10PN3232r.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_line.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.281 K, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.269 K.&amp;lt;ref name=&amp;quot;2DIL&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
&lt;br /&gt;
3.&lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding.In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Actually, just by ignoring the data from 2x2 and 4x4 lattices, and fitting a straight line to the rest of the points, a much better result is obtained, as shown in &#039;&#039;&#039;Figure 11&#039;&#039;&#039;. In &#039;&#039;&#039;Figure 11&#039;&#039;&#039;, the y-intercept is exactly 2.269 K. However, the quality of this analysis is highly questionable due to the fact that only 4 points are used. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_line_2.png|thumb|center|500px|&#039;&#039;&#039;Figure 11. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;2DIL&amp;quot;&amp;gt;H.A. Kramers and G.H. Wannier, Phys. Rev. 60, 252 (1941).&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485441</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485441"/>
		<updated>2015-02-11T20:58:27Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(K)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice(between 2.0 and 2.5 K), as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully. If the order of the polynomial was increased even higher, an error message would pop up to alert about the possible poor quality of the polynomial fitting.&lt;br /&gt;
&lt;br /&gt;
[[File: LY_fit10PN3232r.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_line.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.281 K, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.269 K.&amp;lt;ref name=&amp;quot;2DIL&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
&lt;br /&gt;
3.&lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding.In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Actually, just by ignoring the data from 2x2 and 4x4 lattices, and fitting a straight line to the rest of the points, a much better result is obtained, as shown in &#039;&#039;&#039;Figure 11&#039;&#039;&#039;. In &#039;&#039;&#039;Figure 11&#039;&#039;&#039;, the y-intercept is exactly 2.269 K. However, the quality of this analysis is highly questionable due to the fact that only 4 points are used. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_line_2.png|thumb|center|500px|&#039;&#039;&#039;Figure 11. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;2DIL&amp;quot;&amp;gt;J.D. Gale, &#039;&#039;JCS Faraday Trans.&#039;&#039;, &#039;&#039;&#039;93&#039;&#039;&#039;, 629 (1997).&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485440</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485440"/>
		<updated>2015-02-11T20:57:34Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(K)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice(between 2.0 and 2.5 K), as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully. If the order of the polynomial was increased even higher, an error message would pop up to alert about the possible poor quality of the polynomial fitting.&lt;br /&gt;
&lt;br /&gt;
[[File: LY_fit10PN3232r.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_line.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.281 K, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.269 K.&amp;lt;ref name=&amp;quot;2DIL&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
&lt;br /&gt;
3.&lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding.In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Actually, just by ignoring the data from 2x2 and 4x4 lattices, and fitting a straight line to the rest of the points, a much better result is obtained, as shown in &#039;&#039;&#039;Figure 11&#039;&#039;&#039;. In &#039;&#039;&#039;Figure 11&#039;&#039;&#039;, the y-intercept is exactly 2.269 K. However, the quality of this analysis is highly questionable due to the fact that only 4 points are used. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_line_2.png|thumb|center|500px|&#039;&#039;&#039;Figure 11. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485438</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485438"/>
		<updated>2015-02-11T20:51:25Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(K)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice(between 2.0 and 2.5 K), as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully. If the order of the polynomial was increased even higher, an error message would pop up to alert about the possible poor quality of the polynomial fitting.&lt;br /&gt;
&lt;br /&gt;
[[File: LY_fit10PN3232r.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_line.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.281 K, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.269 K.&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
&lt;br /&gt;
3.&lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding.In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Actually, just by ignoring the data from 2x2 and 4x4 lattices, and fitting a straight line to the rest of the points, a much better result is obtained, as shown in &#039;&#039;&#039;Figure 11&#039;&#039;&#039;. In &#039;&#039;&#039;Figure 11&#039;&#039;&#039;, the y-intercept is exactly 2.269 K. However, the quality of this analysis is highly questionable due to the fact that only 4 points are used. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_line_2.png|thumb|center|500px|&#039;&#039;&#039;Figure 11. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485404</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485404"/>
		<updated>2015-02-11T19:57:43Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(K)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice(between 2.0 and 2.5 K), as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully. If the order of the polynomial was increased even higher, an error message would pop up to alert about the possible poor quality of the polynomial fitting.&lt;br /&gt;
&lt;br /&gt;
[[File: LY_fit10PN3232r.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_line.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.281 K, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.269 K.&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
&lt;br /&gt;
3.&lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding. Actually, just by ignoring the data from 2x2 and 4x4 lattices, and fitting a straight line to the rest of the points, a much better result is obtained, as shown in &#039;&#039;&#039;Figure 11&#039;&#039;&#039;. In &#039;&#039;&#039;Figure 11&#039;&#039;&#039;, the y-intercept is exactly 2.269 K. However, the quality of this analysis is highly questionable due to the fact that only 4 points are used. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_line_2.png|thumb|center|500px|&#039;&#039;&#039;Figure 11. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485403</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485403"/>
		<updated>2015-02-11T19:57:11Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(K)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice(between 2.0 and 2.5 K), as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully. If the order of the polynomial was increased even higher, an error message would pop up to alert about the possible poor quality of the polynomial fitting.&lt;br /&gt;
&lt;br /&gt;
[[File: LY_fit10PN3232r.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_line.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.281 K, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.269 K.&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
&lt;br /&gt;
3.&lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding. Actually, just by ignoring the data from 2x2 and 4x4 lattices, and fitting a straight line to the rest of the points, a much better result is obtained, as shown in &#039;&#039;&#039;Figure 11&#039;&#039;&#039;. In &#039;&#039;&#039;Figure 11&#039;&#039;&#039;, the y-intercept is 2.269 K. However, the quality of this analysis is highly questionable due to the fact that only 4 points are used. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_line_2.png|thumb|center|500px|&#039;&#039;&#039;Figure 11. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=File:LY_line_2.png&amp;diff=485402</id>
		<title>File:LY line 2.png</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=File:LY_line_2.png&amp;diff=485402"/>
		<updated>2015-02-11T19:56:45Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485397</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485397"/>
		<updated>2015-02-11T19:47:33Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(K)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice(between 2.0 and 2.5 K), as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully. If the order of the polynomial was increased even higher, an error message would pop up to alert about the possible poor quality of the polynomial fitting.&lt;br /&gt;
&lt;br /&gt;
[[File: LY_fit10PN3232r.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_line.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.73, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.69.&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
&lt;br /&gt;
3.&lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding. &lt;br /&gt;
&lt;br /&gt;
In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=File:LY_line.png&amp;diff=485396</id>
		<title>File:LY line.png</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=File:LY_line.png&amp;diff=485396"/>
		<updated>2015-02-11T19:47:05Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485395</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485395"/>
		<updated>2015-02-11T19:45:22Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(K)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice(between 2.0 and 2.5 K), as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully. If the order of the polynomial was increased even higher, an error message would pop up to alert about the possible poor quality of the polynomial fitting.&lt;br /&gt;
&lt;br /&gt;
[[File: LY_fit10PN3232r.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.73, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.69.&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
&lt;br /&gt;
3.&lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding. &lt;br /&gt;
&lt;br /&gt;
In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485392</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485392"/>
		<updated>2015-02-11T19:40:58Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(K)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice(between 2.0 and 2.5 K), as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully.&lt;br /&gt;
&lt;br /&gt;
[[File: LY_fit10PN3232r.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.73, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.69.&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
&lt;br /&gt;
3.&lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding. &lt;br /&gt;
&lt;br /&gt;
In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=File:LY_fit10PN3232r.png&amp;diff=485390</id>
		<title>File:LY fit10PN3232r.png</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=File:LY_fit10PN3232r.png&amp;diff=485390"/>
		<updated>2015-02-11T19:40:27Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485388</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485388"/>
		<updated>2015-02-11T19:37:20Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(K)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately. &lt;br /&gt;
[[File:LY_fit10PN3232.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice, as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.73, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.69.&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
&lt;br /&gt;
3.&lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding. &lt;br /&gt;
&lt;br /&gt;
In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=File:LY_fit10PN3232.png&amp;diff=485387</id>
		<title>File:LY fit10PN3232.png</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=File:LY_fit10PN3232.png&amp;diff=485387"/>
		<updated>2015-02-11T19:36:56Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485385</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485385"/>
		<updated>2015-02-11T19:32:38Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* The effect of temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5!! 1.0&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_0_5K.png|400px]] || [[File:LY_88_1K.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;Temperature(K)&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;1.5&#039;&#039;&#039;&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;&#039;&#039;&#039;2.0&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_1_5K.png|400px]] || [[File:LY_88_2K.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately.&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice, as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.73, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.69.&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
&lt;br /&gt;
3.&lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding. &lt;br /&gt;
&lt;br /&gt;
In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=File:LY_88_0_5K.png&amp;diff=485383</id>
		<title>File:LY 88 0 5K.png</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=File:LY_88_0_5K.png&amp;diff=485383"/>
		<updated>2015-02-11T19:32:20Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485377</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485377"/>
		<updated>2015-02-11T19:28:23Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* The effect of temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 1.0!! 1.5!! &lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_1K.png|300px]] || [[File:LY_88_1_5K.png|300px]] &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;Temperature(K)&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;2.0&amp;lt;/center&amp;gt; || &amp;lt;center&amp;gt;2.5&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot ||[[File:LY_88_2K.png|300px]] || [[File:LY_88_2K.png|300px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately.&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice, as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.73, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.69.&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
&lt;br /&gt;
3.&lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding. &lt;br /&gt;
&lt;br /&gt;
In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485376</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485376"/>
		<updated>2015-02-11T19:23:39Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* The effect of temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 1.0 !! 1.5 !! 2.0 &lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY_88_1K.png|300px]] || [[File:LY_88_1_5K.png|300px]] ||  [[File:LY_88_2K.png|300px]]&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately.&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice, as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.73, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.69.&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
&lt;br /&gt;
3.&lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding. &lt;br /&gt;
&lt;br /&gt;
In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=File:LY_88_2K.png&amp;diff=485375</id>
		<title>File:LY 88 2K.png</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=File:LY_88_2K.png&amp;diff=485375"/>
		<updated>2015-02-11T19:23:23Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=File:LY_88_1_5K.png&amp;diff=485374</id>
		<title>File:LY 88 1 5K.png</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=File:LY_88_1_5K.png&amp;diff=485374"/>
		<updated>2015-02-11T19:22:43Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=File:LY_88_1K.png&amp;diff=485373</id>
		<title>File:LY 88 1K.png</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=File:LY_88_1K.png&amp;diff=485373"/>
		<updated>2015-02-11T19:22:16Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485335</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485335"/>
		<updated>2015-02-11T18:07:40Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5 !! 1.5 !! 2.0 !! 2.5&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY IL MC 2000 original.png|300px]] || [[File:LY IL MC 2000 accelerated final.png|300px]]  ||  ||&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately.&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice, as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.73, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.69.&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
&lt;br /&gt;
1.&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
&lt;br /&gt;
3.&lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding. &lt;br /&gt;
&lt;br /&gt;
In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485334</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485334"/>
		<updated>2015-02-11T18:07:13Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5 !! 1.5 !! 2.0 !! 2.5&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY IL MC 2000 original.png|300px]] || [[File:LY IL MC 2000 accelerated final.png|300px]]  ||  ||&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately.&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice, as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; was then plotted against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; to find &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;, as shown in &#039;&#039;&#039;Figure 10&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
The straight line in &#039;&#039;&#039;Figure 10&#039;&#039;&#039; was obtained by fitting a first order polynomial to the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; vs. &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; data. The y-intercept of this line is 2.73, which is slightly higher than the theoretical Curie Temperature for the infinite 2D Ising lattice, 2.69.&lt;br /&gt;
&lt;br /&gt;
The reasons behind the difference between the value obtained via this computational exercise and the theoretical value may be threefold.&lt;br /&gt;
1.&lt;br /&gt;
2.&lt;br /&gt;
3.&lt;br /&gt;
&lt;br /&gt;
One way of improving the accuracy of the Curie temperature found using this method may be neglecting the data for 2x2 and 4x4 lattices, and including more larger lattices such as 128x128 and 256x256. The drawback of simulating a even larger Ising lattice is obvious as it is very computationally demanding. &lt;br /&gt;
&lt;br /&gt;
In fact, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using the 64x64 lattice is closer to the theoretical value than the one obtained from linear fit. Therefore, the &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; found using a 256x256 lattice could probably be approximated as &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; already, because the constant A would have been scaled down by 256 times and thus cause very little influence to the &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485323</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485323"/>
		<updated>2015-02-11T17:42:42Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5 !! 1.5 !! 2.0 !! 2.5&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY IL MC 2000 original.png|300px]] || [[File:LY IL MC 2000 accelerated final.png|300px]]  ||  ||&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately.&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polynomial to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice, as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked in &#039;&#039;&#039;Figure 9&#039;&#039;&#039; and from this graph, &amp;lt;math&amp;gt;T_{C, 32}&amp;lt;/math&amp;gt; can be extracted successfully.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polynomial to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By doing the polynomial fitting described earlier to all the lattice sizes, &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes were obtained and summarised in &#039;&#039;&#039;Table 5&#039;&#039;&#039; below.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 5. &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; for all the lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32!!64x64&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; || 2.52830831 || 2.45439439||2.34848849 ||2.30837838 || 2.29540541 ||2.27378378&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; against &amp;lt;math&amp;gt;1/L&amp;lt;/math&amp;gt; curve&#039;&#039;&#039;]]&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485308</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485308"/>
		<updated>2015-02-11T17:29:34Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5 !! 1.5 !! 2.0 !! 2.5&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY IL MC 2000 original.png|300px]] || [[File:LY IL MC 2000 accelerated final.png|300px]]  ||  ||&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve is more continuous as it contains more points. i.e. The C++ curve has a better resolution in the peak region. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 10th order polynomial was fitted to the C++ heat capacity curve for the 32x32 lattice, shown in &#039;&#039;&#039;Figure 8&#039;&#039;&#039;. However, this is still not a good fit, as it cannot capture the peak region accurately.&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 8. Fitting 10th order polymer to the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
An 8th order polynomial was then fitted to the peak region of the C++ curve for the 32x32 lattice, as shown in &#039;&#039;&#039;Figure 9&#039;&#039;&#039;. The area around the Curie temperature is successfully mimicked &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 9. Fitting 8th order polymer to the peak region of the heat capacity curve obtained from C++ data  with lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 10. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485297</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485297"/>
		<updated>2015-02-11T17:18:28Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5 !! 1.5 !! 2.0 !! 2.5&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY IL MC 2000 original.png|300px]] || [[File:LY IL MC 2000 accelerated final.png|300px]]  ||  ||&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. The two curves coincide with each other in both the low and high temperature regions. However, in the central peak region, the C++ curve &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485296</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485296"/>
		<updated>2015-02-11T17:15:54Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5 !! 1.5 !! 2.0 !! 2.5&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY IL MC 2000 original.png|300px]] || [[File:LY IL MC 2000 accelerated final.png|300px]]  ||  ||&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485216</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485216"/>
		<updated>2015-02-11T15:21:37Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5 !! 1.5 !! 2.0 !! 2.5&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY IL MC 2000 original.png|300px]] || [[File:LY IL MC 2000 accelerated final.png|300px]]  ||  ||&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485215</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485215"/>
		<updated>2015-02-11T15:21:17Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5 !! 1.5 !! 2.0 !! 2.5&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY IL MC 2000 original.png|300px]] || [[File:LY IL MC 2000 accelerated final.png|300px]]  ||  ||&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice size were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_3232compare.png|thumb|center|500px|&#039;&#039;&#039;Figure 7. Comparisons between heat capacity calculated from C++ and Python data for the lattice size of 32x32&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=File:LY_3232compare.png&amp;diff=485214</id>
		<title>File:LY 3232compare.png</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=File:LY_3232compare.png&amp;diff=485214"/>
		<updated>2015-02-11T15:20:47Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485212</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485212"/>
		<updated>2015-02-11T15:18:13Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* The effect of system size */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5 !! 1.5 !! 2.0 !! 2.5&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY IL MC 2000 original.png|300px]] || [[File:LY IL MC 2000 accelerated final.png|300px]]  ||  ||&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; The temperature ranges in all the above calculations are all from 0.2 to 5.0 with the same step size 0.1.&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice size were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485211</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485211"/>
		<updated>2015-02-11T15:16:17Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Locating the Curie temperature */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5 !! 1.5 !! 2.0 !! 2.5&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY IL MC 2000 original.png|300px]] || [[File:LY IL MC 2000 accelerated final.png|300px]]  ||  ||&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The heat capacity versus temperature curves calculated using data generated by Phthon and C++ for the 32x32 lattice size were plotted in &#039;&#039;&#039;Figure 7&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485196</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485196"/>
		<updated>2015-02-11T15:09:22Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Determining the heat capacity */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5 !! 1.5 !! 2.0 !! 2.5&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY IL MC 2000 original.png|300px]] || [[File:LY IL MC 2000 accelerated final.png|300px]]  ||  ||&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;Figure 6&#039;&#039;&#039;, as lattice size increases, the temperature as which maximum heat capacity occurs shifts to the left gradually. This is expected  due to the finite size effect, which is very common in the simulations of systems bearing long ranged interactions. The trend in &#039;&#039;&#039;Figure 6&#039;&#039;&#039; is actually in good agreement with the relationship &amp;lt;math&amp;gt;T_{C, L} = \frac{A}{L} + T_{C,\infty}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;T_{C, L}&amp;lt;/math&amp;gt; is the Curie temperature of an &amp;lt;math&amp;gt;L\times L&amp;lt;/math&amp;gt;lattice, &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt; is the Curie temperature of an infinite lattice, and &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is a constant.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485173</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485173"/>
		<updated>2015-02-11T14:55:40Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Determining the heat capacity */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5 !! 1.5 !! 2.0 !! 2.5&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY IL MC 2000 original.png|300px]] || [[File:LY IL MC 2000 accelerated final.png|300px]]  ||  ||&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LY_heatcapacityallin1.png|thumb|center|500px|&#039;&#039;&#039;Figure 6. Heat capacity versus temperature curves for all the lattice sizes&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=File:LY_heatcapacityallin1.png&amp;diff=485172</id>
		<title>File:LY heatcapacityallin1.png</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=File:LY_heatcapacityallin1.png&amp;diff=485172"/>
		<updated>2015-02-11T14:55:23Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485170</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485170"/>
		<updated>2015-02-11T14:52:04Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Determining the heat capacity */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5 !! 1.5 !! 2.0 !! 2.5&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY IL MC 2000 original.png|300px]] || [[File:LY IL MC 2000 accelerated final.png|300px]]  ||  ||&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485169</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485169"/>
		<updated>2015-02-11T14:51:45Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* Determining the heat capacity */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5 !! 1.5 !! 2.0 !! 2.5&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY IL MC 2000 original.png|300px]] || [[File:LY IL MC 2000 accelerated final.png|300px]]  ||  ||&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Since the heat capacity is defined as &amp;lt;math&amp;gt;C = \frac{\partial E}{\partial T} = \frac{\mathrm{Var}[E]}{k_B T^2}&amp;lt;/math&amp;gt;, by extracting the &amp;lt;math&amp;gt;\left\langle E^2\right\rangle&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\left\langle E\right\rangle&amp;lt;/math&amp;gt; data from the &#039;&#039;.dat&#039;&#039;&#039; files generated previously, heat capacity versus temperature curves for each lattice size were computed and plotted in &#039;&#039;&#039;Figure 6&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
	<entry>
		<id>https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485168</id>
		<title>Rep:Mod:PYTHONLY2412</title>
		<link rel="alternate" type="text/html" href="https://chemwiki.ch.ic.ac.uk/index.php?title=Rep:Mod:PYTHONLY2412&amp;diff=485168"/>
		<updated>2015-02-11T14:45:19Z</updated>

		<summary type="html">&lt;p&gt;Ly2412: /* The effect of system size */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction to the Ising model==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Show that the lowest possible energy for the Ising model is &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; is the number of dimensions and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the total number of spins. What is the multiplicity of this state? Calculate its entropy.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a spin in a system of dimension &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, there are &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; interactions associated with it due to its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; number of neighbouring spins. To minimise the energy of these interactions, this spin and its &amp;lt;math&amp;gt;2D&amp;lt;/math&amp;gt; neighbours must have the same sign, i.e. all up or all down. Therefore the minimum energy of these interactions associated with this one spin is &amp;lt;math&amp;gt;E\ =-0.5\times2DJ = -DJ&amp;lt;/math&amp;gt;. If the system has total number of spins of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, then the overall lowest energy must be &amp;lt;math&amp;gt;E\ =\ -DNJ&amp;lt;/math&amp;gt;. The multiplicity of such a system should be 2 since the whole system can either have all of its spins up or down. The entropy of such a system is therefore &amp;lt;math&amp;gt;S\ =\ K_b\ln 2=9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Imagine that the system is in the lowest energy configuration. To move to a different state, one of the spins must spontaneously change direction (&amp;quot;flip&amp;quot;). What is the change in energy if this happens (&amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt;)? How much entropy does the system gain by doing so?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of &amp;lt;math&amp;gt;D=3,\ N=1000&amp;lt;/math&amp;gt; in its lowest energy configuration, the energy of this configuration is &amp;lt;math&amp;gt;E\ =-3000J&amp;lt;/math&amp;gt; and the entropy of this system is &amp;lt;math&amp;gt;S\ =9.57\times 10^{-24}  JK^{-1} &amp;lt;/math&amp;gt;. If one of the spins change its direction, there are 6 unique interaction energies changes from -1 to +1 and the overall energy changes to &amp;lt;math&amp;gt;E\ =-2988J&amp;lt;/math&amp;gt;. In this excited state, the entropy is &amp;lt;math&amp;gt;S\ =\ K_b\ln 2000=1.05\times 10^{-22}  JK^{-1} &amp;lt;/math&amp;gt; because there are 2000 ways of arranging this system. Therefore the change in energy of this process is &amp;lt;math&amp;gt;\Delta E\ =12J&amp;lt;/math&amp;gt; and the change in entropy is &amp;lt;math&amp;gt;\Delta S\ =9.54\times 10^{-23}  JK^{-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Calculate the magnetisation of the 1D and 2D lattices in figure 1. What magnetisation would you expect to observe for an Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The magnetisations of the 1D and 2D lattices in figure 1 are both +1. For a Ising lattice with &amp;lt;math&amp;gt;D = 3,\ N=1000&amp;lt;/math&amp;gt; at absolute zero, its magnetisation can be either +1000 or -1000.&lt;br /&gt;
&lt;br /&gt;
==Calculating the energy and magnetisation==&lt;br /&gt;
In this section, two functions from the IsingLattice.py file, energy() and magnetisation(), were completed to calculate the energy and magnetisation of any 2D Ising lattice and a screenshot of these codes is shown below in &#039;&#039;&#039;Figure 1&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
[[File:LY IL code.png|thumb|center|500px|&#039;&#039;&#039;Figure 1. The original code for energy() and magnetisation() functions&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The validity of these two functions were checked using a given ILcheck.py file and the output is given below in &#039;&#039;&#039;Figure 2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:LY_ILcheck.png|thumb|center|400px|&#039;&#039;&#039;Figure 2. The output from the ILcheck.py file&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==Introduction to Monte Carlo simulation==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: How many configurations are available to a system with 100 spins? To evaluate these expressions, we have to calculate the energy and magnetisation for each of these configurations, then perform the sum. Let&#039;s be very, very, generous, and say that we can analyse &amp;lt;math&amp;gt;1\times 10^9&amp;lt;/math&amp;gt; configurations per second with our computer. How long will it take to evaluate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For a system of 100 spins, since each spin can be either up or down, the total number of configurations is therefore &amp;lt;math&amp;gt;W\ =2^{100}=1.27\times 10^{30}&amp;lt;/math&amp;gt; and it will take about &amp;lt;math&amp;gt;4.02\times 10^{13}&amp;lt;/math&amp;gt; years to calculate a single value of &amp;lt;math&amp;gt;\left\langle M\right\rangle_T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: If &amp;lt;math&amp;gt;T &amp;lt; T_C&amp;lt;/math&amp;gt;, do you expect a spontaneous magnetisation (i.e. do you expect &amp;lt;math&amp;gt;\left\langle M\right\rangle \neq 0&amp;lt;/math&amp;gt;)? When the state of the simulation appears to stop changing (when you have reached an equilibrium state), use the controls to export the output to PNG and attach this to your report. You should also include the output from your statistics() function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A montecarlostep(T) function and a statistics() function were written in this section to perform a single step Monte Carlo simulation and calculate average properties of the system, respectively. The output from ILanim.py file is shown below in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_ILanim_out.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_ILanim_out_2.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 350&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 3. The output from ILanim.py and statistics()&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Accelerating the code==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;current&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: Use the script ILtimetrial.py to record how long your &#039;&#039;new&#039;&#039; version of IsingLattice.py takes to perform 2000 Monte Carlo steps. This will vary, depending on what else the computer happens to be doing, so perform repeats and report the error in your average!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this section, the energy() and statistics() functions were modified using numpy.sum(), numpy.roll() and numpy.multiply() functions. After the modification, the calculation time has been shortened significantly in performing 2000 Monte Carlo steps. The comparison is shown below in &#039;&#039;&#039;Table 1&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 1. The effect of accelerating codes on computational time &lt;br /&gt;
!  !! before acceleration !! after acceleration&lt;br /&gt;
|-&lt;br /&gt;
| screen shot || [[File:LY IL MC 2000 original.png|400px]] || [[File:LY IL MC 2000 accelerated final.png|400px]] &lt;br /&gt;
|-&lt;br /&gt;
| average (s)|| 21.6 || 0.283&lt;br /&gt;
|-&lt;br /&gt;
| standard error (s)|| 0.162 || 0.00140&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The effect of temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: The script ILfinalframe.py runs for a given number of cycles at a given temperature, then plots a depiction of the &#039;&#039;final&#039;&#039; lattice state as well as graphs of the energy and magnetisation as a function of cycle number. This is much quicker than animating every frame! Experiment with different temperature and lattice sizes. How many cycles are typically needed for the system to go from its random starting position to the equilibrium state? Modify your statistics() and montecarlostep() functions so that the first N cycles of the simulation are ignored when calculating the averages. You should state in your report what period you chose to ignore, and include graphs from ILfinalframe.py to illustrate your motivation in choosing this figure.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From the top picture in &#039;&#039;&#039;Figure 3&#039;&#039;&#039;, we can see that the first few hundreds step of the Monte Carlo calculation are relaxation steps. Therefore, these steps should be excluded during the calculation of average properties of the system. Some outputs from the ILfinalframe.py file for the 8x8 lattice at different temperatures are shown below in &#039;&#039;&#039;Table 2&#039;&#039;&#039;. From this table, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of this lattice size. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 2. The effect of temperature on the total number of relaxation steps of the 8x8 lattice&lt;br /&gt;
! Temperature(K) !! 0.5 !! 1.5 !! 2.0 !! 2.5&lt;br /&gt;
|-&lt;br /&gt;
| Output Screenshot || [[File:LY IL MC 2000 original.png|300px]] || [[File:LY IL MC 2000 accelerated final.png|300px]]  ||  ||&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Use ILtemperaturerange.py to plot the average energy and magnetisation for each temperature, &#039;&#039;with error bars&#039;&#039;, for an &amp;lt;math&amp;gt;8\times 8&amp;lt;/math&amp;gt; lattice. Use your initution and results from the script ILfinalframe.py to estimate how many cycles each simulation should be. The temperature range 0.25 to 5.0 is sufficient. Use as many temperature points as you feel necessary to illustrate the trend, but do not use a temperature spacing larger than 0.5. T NumPy function savetxt() stores your array of output data on disk &amp;amp;mdash; you will need it later. Save the file as &#039;&#039;8x8.dat&#039;&#039; so that you know which lattice size it came from.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Table 2&#039;&#039;&#039;, it is clear that the first 2000 steps should be excluded and a total run-time of 50000 should be appropriate in the calculation of average proprieties of the 8x8  lattice. The output from the IL.temperaturerange.py file of a 8x8 lattice is shown below in &#039;&#039;&#039;Figure 4&#039;&#039;&#039;. The temperature range is from 0.2 to 5.0 and step-size is 0.1. Errors bars of average energies and magnetisations at each temperature point are shown as well. In fact these error bars are too small to be seen clearly. However, this does not mean that the calculations are accurate enough......&lt;br /&gt;
[[File:LY_88.png|thumb|center|500px|&#039;&#039;&#039;Figure 4. The output from the ILtemperature.py file for 8x8 lattice&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
==The effect of system size==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Repeat the final task of the previous section for the following lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32. Make sure that you name each datafile that your produce after the corresponding lattice size! Write a Python script to make a plot showing the energy &#039;&#039;per spin&#039;&#039; versus temperature for each of your lattice sizes. Hint: the NumPy loadtxt function is the reverse of the savetxt function, and can be used to read your previously saved files into the script. Repeat this for the magnetisation. As before, use the plot controls to save your a PNG image of your plot and attach this to the report. How big a lattice do you think is big enough to capture the long range fluctuations?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The number of relaxation and equilibration steps needed to calculate reliable average properties depend strongly on the system size. Therefore, several ILfinalframe.py calculations were performed for different lattice sizes to determine the number of relaxation steps and total run-time required. The results are summarised in &#039;&#039;&#039;Table 3&#039;&#039;&#039; below and these values are used when ILtemperaturerange.py calculations were performed for lattice sizes: 2x2, 4x4, 8x8, 16x16, 32x32.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 3. The relaxation and equilibration steps for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4!!8x8!!16x16!!32x32&lt;br /&gt;
|-&lt;br /&gt;
| number of relaxation steps || 500 || 1000||2000 ||20000 || 75000 &lt;br /&gt;
|-&lt;br /&gt;
| total run time||20000  ||30000 || 50000||150000 ||300000 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The ILtemperaturerange.py script was then used to calculate average energies and magnetisations of the following lattice sizes: 2x2, 4x4, 16x16, 32x32 and results are shown in &#039;&#039;&#039;Table 4&#039;&#039;&#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin: 1em auto 1em auto;&amp;quot;&lt;br /&gt;
|+ Table 4. The output of ILtemperaturerange.py for different lattice sizes&lt;br /&gt;
! lattice size !! 2x2 !! 4x4&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_22.png|400px]] || [[File:LY_44.png|400px]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;center&amp;gt;&#039;&#039;&#039;lattice size&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;16x16&#039;&#039;&#039;&amp;lt;/center&amp;gt; ||&amp;lt;center&amp;gt; &#039;&#039;&#039;32x32&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| output || [[File:LY_1616.png|400px]] || [[File:LY_3232.png|400px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The energies and magnetisations per spin  versus temperature graphs for each lattice size were then plotted together for comparisons, as shown in &#039;&#039;&#039;Figure 5&#039;&#039;&#039;.&lt;br /&gt;
{{multiple image&lt;br /&gt;
| image1 = LY_energyallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| image2 = LY_magallin1.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| direction = vertical&lt;br /&gt;
| align = center&lt;br /&gt;
| width = 450&lt;br /&gt;
| footer = &#039;&#039;&#039;Figure 5. The energies and magnetisations vs. temperature graphs for different lattice sizes shown in one figure&#039;&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
From &#039;&#039;&#039;Figure 5&#039;&#039;&#039;, it is clear to see that by increasing the lattice size from 2x2 to 4x4 and from 4x4 to 8x8, both energies and magnetisations per temperature curves change in shapes significantly. In other words, by increasing the lattice size from 2x2 to 8x8, the quality of the calculations has been greatly improved and more details of the behaviors of both energies and magnetisations per temperature curves  have been revealed. However, by changing the lattice size from 8x8 to 16x16 and 32x32, both plots in &#039;&#039;&#039;Figure 5&#039;&#039;&#039; do not change in general features, where as the computational time increases significantly. Therefore, the 8x8 lattice can be seen as the minimum lattice size required to capture the long range fluctuations.&lt;br /&gt;
&lt;br /&gt;
==Determining the heat capacity==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK&amp;lt;/big&amp;gt;: Write a Python script to make a plot showing the heat capacity versus temperature for each of your lattice sizes from the previous section. You may need to do some research to recall the connection between the variance of a variable, &amp;lt;math&amp;gt;\mathrm{Var}[X]&amp;lt;/math&amp;gt;, the mean of its square &amp;lt;math&amp;gt;\left\langle X^2\right\rangle&amp;lt;/math&amp;gt;, and its squared mean &amp;lt;math&amp;gt;\left\langle X\right\rangle^2&amp;lt;/math&amp;gt;. You may find that the data around the peak is very noisy &amp;amp;mdash; this is normal, and is a result of being in the critical region. As before, use the plot controls to save your a PNG image of your plot and attach this to the report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Locating the Curie temperature==&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK1&amp;lt;/big&amp;gt;: A C++ program has been used to run some much longer simulations than would be possible on the college computers in Python. You can view its source code [https://github.com/niallj/ducking-avenger/tree/master/Ising here] if you are interested. Each file contains six columns: &amp;lt;math&amp;gt;T, E, E^2, M, M^2, C&amp;lt;/math&amp;gt; (the final five quantities are per spin), and you can read them with the NumPy loadtxt function as before. For each lattice size, plot the C++ data against your data. For &#039;&#039;one&#039;&#039; lattice size, save a PNG of this comparison and add it to your report &amp;amp;mdash; add a legend to the graph to label which is which. To do this, you will need to pass the label=&amp;quot;...&amp;quot; keyword to the plot function, then call the legend() function of the axis object (documentation [http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.legend here]).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK2&amp;lt;/big&amp;gt;: write a script to read the data from a particular file, and plot C vs T, as well as a fitted polynomial. Try changing the degree of the polynomial to improve the fit &amp;amp;mdash; in general, it might be difficult to get a good fit! Attach a PNG of an example fit to your report.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK3&amp;lt;/big&amp;gt;: Modify your script from the previous section. You should still plot the whole temperature range, but fit the polynomial only to the peak of the heat capacity! You should find it easier to get a good fit when restricted to this region.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;big&amp;gt;TASK4&amp;lt;/big&amp;gt;: find the temperature at which the maximum in C occurs for each datafile that you were given. Make a text file containing two colums: the lattice side length (2,4,8, etc.), and the temperature at which C is a maximum. This is your estimate of &amp;lt;math&amp;gt;T_C&amp;lt;/math&amp;gt; for that side length. Make a plot that uses the scaling relation given above to determine &amp;lt;math&amp;gt;T_{C,\infty}&amp;lt;/math&amp;gt;. By doing a little research online, you should be able to find the theoretical exact Curie temperature for the infinite 2D Ising lattice. How does your value compare to this? Are you surprised by how good/bad the agreement is? Attach a PNG of this final graph to your report, and discuss briefly what you think the major sources of error are in your estimate.&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Ly2412</name></author>
	</entry>
</feed>