- #1
JohnGano
- 6
- 0
Homework Statement
I'm trying to program the 2D Ising model with Java, but for some reason, I cannot get magnetization to come out right. The energy and magnetization appear to be acting right for increase and decrease in temperatures, but I don't see anything significant at a critical temperature when I set it to one. It seems to be just like any other temperature in terms of how it effects it.
Homework Equations
The change in magnetization if a spin is flipped would be
M2 = M1 - 2 * flippedspin
Right?
The Attempt at a Solution
Code:
/*
* ising.Ising2D.java
*/
package ising;
import java.util.*;
import java.io.*;
public class Ising2D
{
public static final int DEFAULT_LATTICE[][] = new int[5][5];
public static final double DEFAULT_INTERACTION_STRENGTH = 1.0;
public static final double DEFAULT_EXTERNAL_FIELD = 0.0;
public static final String OUTPUT_FILE = "C:/spins.txt";
PrintWriter outputStream = null;
Scanner reader = null;
Random random = new Random();
int spinLattice[][] = DEFAULT_LATTICE;
double interactionStrength = DEFAULT_INTERACTION_STRENGTH;
double externalField = DEFAULT_EXTERNAL_FIELD;
double temperature = 1.0;
double energy = 0.0;
double magnetization = 0.0;
double averageEnergy = 0.0;
double averageMagnetization = 0.0;
double totalAverageE = 0.0;
double totalAverageM = 0.0;
/**
* Creates a new instance of Ising2D that takes in
* the lattice rows, columns, interaction strength,
* external field value, temperature, and spin pattern.
* Then it runs through 5 000 flips 100 000 times to
* come up with a total average energy and magnetization
*
* @param rowsIn the rows to set spinLattice to
* @param columnsIn the colums to set spinLattice to
* @param interactionStrengthIn the interaction strength to use
* @param externalFieldIn the external field value to use
*/
Ising2D(int rowsIn, int columnsIn, double interactionStrengthIn,
double externalFieldIn, double temperatureIn, int spinPattern)
{
setLattice(rowsIn, columnsIn);
interactionStrength = interactionStrengthIn;
externalField = externalFieldIn;
temperature = temperatureIn;
for(int i = 0; i < 10000; i++)
{
switch (spinPattern)
{
case 1: setRandomSpins(); break;
case 2: usePreviousSpins(); break;
case 3: setCheckerSpins(); break;
case 4: setEqualSpins(); break;
}
System.out.println(magnetization / (20 * 20));
for(int j = 0; j < 5000; j++)
{
spinFlip();
}
averageEnergy = averageEnergy / (20 * 20) / (5000) / 2; // per spin
averageMagnetization = averageMagnetization / (20 * 20) / 5000;
totalAverageE += averageEnergy;
totalAverageM += averageMagnetization;
System.out.println(averageEnergy + " " + averageMagnetization);
}
totalAverageE /= 10000;
totalAverageM /= 10000;
System.out.println("Average E & Average M");
System.out.println(totalAverageE + " " + totalAverageM);
} /**
* Sets spinLattice to the specified amount of rows and columns
*/
public void setLattice(int rowsIn, int columnsIn)
{
spinLattice = new int[rowsIn][columnsIn];
}
/**
* Sums the nearest neighbors of the passed in location on the
* array spinLattice using periodic boundary conditions.
*
* @param rowIn the row to find nearest neighbors of
* @param columnIn the column to find nearest neighbors of
* @return the sum of nearest neighbor interactions
*/
public int sumNearestNeighbors(int rowIn, int columnIn)
{
int sum = 0;
int top = rowIn - 1;
int bottom = rowIn + 1;
int left = columnIn - 1;
int right = columnIn + 1;
if(rowIn == 0)
top = spinLattice.length - 1;
else if(rowIn == spinLattice.length - 1)
bottom = 0;
if(columnIn == 0)
left = spinLattice[0].length - 1;
else if(columnIn == spinLattice[0].length - 1)
right = 0;
sum = spinLattice[top][columnIn] + spinLattice[bottom][columnIn] +
spinLattice[rowIn][left] + spinLattice[rowIn][right];
return sum;
}
/**
* Sums the spin interactions with each other over the entire lattice
* then multiplies it by their interaction strength to get the spin
* energy sum.
*
* @return the sum of the spin energy
*/
public double sumSpinEnergy()
{
double spinEnergy = 0.0;
for(int i = 0; i < spinLattice.length; i++)
{
for(int j = 0; j < spinLattice[i].length; j++)
{
spinEnergy += spinLattice[i][j] * sumNearestNeighbors(i, j);
}
}
spinEnergy *= -interactionStrength;
return spinEnergy;
}
/**
* Sums the magnetization over the entire lattice.
*
* @return the sum of the magnetization
*/
public double sumMagnetization()
{
double sumOfMagnetization = 0.0;
for(int i = 0; i < spinLattice.length; i++)
{
for(int j = 0; j < spinLattice[i].length; j++)
{
sumOfMagnetization += spinLattice[i][j];
}
}
return sumOfMagnetization;
}
/**
* Generates a random spin of either 1 or -1
*
* @return a number of either 1 or -1
*/
public int generateRandomSpin()
{
return (int)Math.pow(-1, Math.abs(random.nextInt()) % 2);
}
/**
* Uses the Monte Carlo method to flip a spin based on the change
* of energy. If energy change < 0, flip the spin, if > 0, flip it
* with a certain probability.
*/
public void spinFlip()
{
int randomRow = random.nextInt(spinLattice.length);
int randomColumn = random.nextInt(spinLattice[0].length);
int trialSpin = -spinLattice[randomRow][randomColumn];
double deltaEnergy = 2 * (trialSpin * interactionStrength *
sumNearestNeighbors(randomRow, randomColumn)
+ externalField);
if(deltaEnergy < 0 || Math.exp(-deltaEnergy / temperature)
<= random.nextDouble())
{
spinLattice[randomRow][randomColumn] = trialSpin;
energy += deltaEnergy;
magnetization -= 2 * spinLattice[randomRow][randomColumn];
averageEnergy += energy;
averageMagnetization += magnetization;
}
}
/**
* Sets the spins in spinLattice to be random 1 or -1
*/
public void setRandomSpins()
{
try
{
outputStream = new PrintWriter(OUTPUT_FILE);
}
catch(FileNotFoundException e)
{
System.out.println("Could not open file: " + OUTPUT_FILE);
System.exit(0);
}
for(int i = 0; i < spinLattice.length; i++)
{
for(int j = 0; j < spinLattice[i].length; j++)
{
spinLattice[i][j] = 1;
spinLattice[i][j] *= generateRandomSpin();
outputStream.println(spinLattice[i][j]);
}
}
outputStream.close();
energy = sumSpinEnergy();
magnetization = sumMagnetization();
averageMagnetization = magnetization;
averageEnergy = energy;
}
/**
* Sets up a checkerboard pattern of spins in spinLattice
*/
public void setCheckerSpins()
{
for(int i = 0; i < spinLattice.length; i++)
{
for(int j = 0; j < spinLattice[i].length; j++)
{
if(i % 2 == 0)
{
if(j % 2 == 0)
spinLattice[i][j] = 1;
else
spinLattice[i][j] = -1;
}
else
{
if(j % 2 == 0)
spinLattice[i][j] = -1;
else
spinLattice[i][j] = 1;
}
}
}
energy = sumSpinEnergy() - sumMagnetization() * externalField;
magnetization = sumMagnetization();
averageMagnetization = magnetization;
averageEnergy = energy;
}
/**
* Sets spinLattice to use the previously recorded spins
*/
public void usePreviousSpins()
{
try
{
reader = new Scanner(new File(OUTPUT_FILE));
}
catch(FileNotFoundException e)
{
System.out.println("Could not open file: " + OUTPUT_FILE);
System.exit(0);
}
while(reader.hasNextLine())
{
for(int i = 0; i < spinLattice.length; i++)
{
for(int j = 0; j < spinLattice[i].length; j++)
{
spinLattice[i][j] = Integer.parseInt(reader.nextLine());
}
}
}
reader.close();
energy = sumSpinEnergy();
magnetization = sumMagnetization();
averageMagnetization = magnetization;
averageEnergy = energy;
}
/**
* Sets up all the spins in spinLattice to be the same, in this case, 1
*/
public void setEqualSpins()
{
for(int i = 0; i < spinLattice.length; i++)
{
for(int j = 0; j < spinLattice[i].length; j++)
{
spinLattice[i][j] = 1;
}
}
energy = sumSpinEnergy();
magnetization = sumMagnetization();
averageMagnetization = magnetization;
averageEnergy = energy;
}
}
If someone knows what I'm doing wrong, I'd really appreciate the help.
Last edited: