Ising model in c++

11
// ComPhys File: Ising.cpp // 2-d Ising model simulation using Metropolis algorithm #include <iostream.h> #include <fstream.h> #include <stdlib.h> #include <math.h> #include <string.h> #include <iomanip.h> #include <time.h> #include "Utilities.h" #include "Vector.h" // globals -------------------------------------------------------------------- int Lx; // number of spins in x direction int Ly; Vector< Vector<int> > s; // spin values Vector<int> xNext; // to help implement periodic Vector<int> xPrevious; // boundary conditions Vector<int> yNext; Vector<int> yPrevious; double J; // coupling constant double T; // temperature double H; // magnetic field double mPerSpin; // updated after each pass double ePerSpin; double flipRatio; // for Metropolis algorithm double mSum; // accumulators for per spin quantities double mAbsSum; double eSum; double mSquaredSum; double eSquaredSum; double flipSum; double termsInSums; double mPerSpinAverage; // updated after specified passes double mAbsPerSpinAverage; double ePerSpinAverage; double chiPerSpinAverage; double cPerSpinAverage; double flipAverage; bool coldStart; // start with all spins up int t; // "time" = number of passes thro lattice int passes; // number of passes to accumulate data int passesToDiscard; // number of thermalization passes bool doTscan; // collect data as function of T double Tmin; double Tmax; double deltaT; bool writeFixed; // data file variables

Transcript of Ising model in c++

Page 1: Ising model in c++

7/27/2019 Ising model in c++

http://slidepdf.com/reader/full/ising-model-in-c 1/11

// ComPhys File: Ising.cpp// 2-d Ising model simulation using Metropolis algorithm

#include <iostream.h>#include <fstream.h>#include <stdlib.h>#include <math.h>#include <string.h>#include <iomanip.h>#include <time.h>

#include "Utilities.h"#include "Vector.h"

// globals --------------------------------------------------------------------

int Lx; // number of spins in x directionint Ly;Vector< Vector<int> > s; // spin values

Vector<int> xNext; // to help implement periodicVector<int> xPrevious; // boundary conditionsVector<int> yNext;Vector<int> yPrevious;

double J; // coupling constantdouble T; // temperaturedouble H; // magnetic field

double mPerSpin; // updated after each passdouble ePerSpin;double flipRatio; // for Metropolis algorithm

double mSum; // accumulators for per spin quantitiesdouble mAbsSum;double eSum;double mSquaredSum;

double eSquaredSum;double flipSum;double termsInSums;

double mPerSpinAverage; // updated after specified passesdouble mAbsPerSpinAverage;double ePerSpinAverage;double chiPerSpinAverage;double cPerSpinAverage;double flipAverage;

bool coldStart; // start with all spins up

int t; // "time" = number of passes thro latticeint passes; // number of passes to accumulate dataint passesToDiscard; // number of thermalization passes

bool doTscan; // collect data as function of Tdouble Tmin;double Tmax;double deltaT;

bool writeFixed; // data file variables

Page 2: Ising model in c++

7/27/2019 Ising model in c++

http://slidepdf.com/reader/full/ising-model-in-c 2/11

bool writeScan;char fixedFileName[30] = "fixed.data";char scanFileName[30] = "scan.data";ofstream fixedFile;ofstream scanFile;

// functions ------------------------------------------------------------------

void defaultParameters();void resizeLattice();void periodicBoundaryConditions();

void initializeSpins();bool updateSpin(int x, int y);void updateLattice();

void zeroAccumulators();void computeAverages();

void runTfixedSimulation();void runTscanSimulation();

void outputIdentifyingInformation(ostream& os);void outputTfixedData(ostream& os, bool header);

void outputTscanData(ostream& os, bool header);

void changeModelParameters();void changeTfixedParameters();void changeTscanParameters();

// function definitions -------------------------------------------------------

void defaultParameters() {

  Lx = 10;  Ly = 10;

  J = 1.0;  T = 1.5;  H = 0.0;

  coldStart = true;

  t = 0;  passes = 1000;  passesToDiscard = passes;

  doTscan = false;  Tmin = 1.0;  Tmax = 5.0;

  deltaT = 0.2;

  writeFixed = true;  writeScan = true;

}

void resizeLattice() {

  s.setDimension(Lx);

Page 3: Ising model in c++

7/27/2019 Ising model in c++

http://slidepdf.com/reader/full/ising-model-in-c 3/11

  for (int x = 0; x < Lx; ++x)  s[x].setDimension(Ly);

  periodicBoundaryConditions();

}

void periodicBoundaryConditions() {

  int x, y; 

xNext.setDimension(Lx);  for (x = 0; x < Lx - 1; ++x)  xNext[x] = x + 1;  xNext[Lx - 1] = 0;

  xPrevious.setDimension(Lx);  xPrevious[0] = Lx - 1;  for (x = 1; x < Lx; ++x)  xPrevious[x] = x - 1; 

yNext.setDimension(Ly);  for (y = 0; y < Ly - 1; ++y)  yNext[y] = y + 1;

  yNext[Ly - 1] = 0;

  yPrevious.setDimension(Ly);  yPrevious[0] = Ly - 1;  for (y = 1; y < Ly; ++y)  yPrevious[y] = y - 1; }

void initializeSpins() {

  t = 0;

  for (int x = 0; x < Lx; ++x) {  for (int y = 0; y < Ly; ++y) {  if (coldStart) {  s[x][y] = 1;  } else {  if (drand48() < 0.5)  s[x][y] = 1;  else s[x][y] = -1;  }  }  }

}

bool updateSpin(int x, int y) {

  // Heat bath algorithm 

int sumOfNeighbors =  s[x][yNext[y]] + s[x][yPrevious[y]] +  s[xNext[x]][y] + s[xPrevious[x]][y] ; 

double E_flip = 2 * s[x][y] * (J * sumOfNeighbors + H);

Page 4: Ising model in c++

7/27/2019 Ising model in c++

http://slidepdf.com/reader/full/ising-model-in-c 4/11

  bool doFlip = false;

  if (E_flip < 0) {  doFlip = true;  } else {  double BoltzmannRatio = exp(-E_flip/T);  if (BoltzmannRatio > drand48())  doFlip = true;  }

  if (doFlip) {  s[x][y] = - s[x][y];  }

  return doFlip; }

void updateLattice() {

  int sum_si = 0;  int sum_si_sj = 0;  int flips = 0;

  for (int x = 0; x < Lx; ++x) {  for (int y = 0; y < Ly; ++y) {  if (updateSpin(x, y))  ++flips;  sum_si += s[x][y];  sum_si_sj += s[x][y] * (s[xNext[x]][y] + s[x][yNext[y]]);  }  } 

mPerSpin = sum_si / (double)(Lx * Ly);  ePerSpin = - (J * sum_si_sj + H * sum_si) / (double)(Lx * Ly);  flipRatio = flips / (double) (Lx * Ly);

  // accumulate data  mSum += mPerSpin;  mAbsSum += fabs(mPerSpin);  eSum += ePerSpin;  mSquaredSum += mPerSpin * mPerSpin;  eSquaredSum += ePerSpin * ePerSpin;  flipSum += flipRatio;  termsInSums += 1;

  ++t;

}

void zeroAccumulators() {

  mSum = 0;  mAbsSum = 0;  eSum = 0;  mSquaredSum = 0;  eSquaredSum = 0;  flipSum = 0;  termsInSums = 0;

Page 5: Ising model in c++

7/27/2019 Ising model in c++

http://slidepdf.com/reader/full/ising-model-in-c 5/11

}

void computeAverages() {

  mPerSpinAverage = mSum / termsInSums;  mAbsPerSpinAverage = mAbsSum / termsInSums;  ePerSpinAverage = eSum / termsInSums;  flipAverage = flipSum / termsInSums;

  chiPerSpinAverage =  (mSquaredSum / termsInSums  - mAbsPerSpinAverage * mAbsPerSpinAverage)  / T * Lx * Ly;

  cPerSpinAverage =  (eSquaredSum / termsInSums - ePerSpinAverage * ePerSpinAverage)  / T / T * Lx * Ly;

}

void runTfixedSimulation() {

  initializeSpins();

  zeroAccumulators(); if (writeFixed) {

  fixedFile.open(fixedFileName);  if (fixedFile.fail()) {  cerr << "Sorry, cannot open " << fixedFileName << endl;  writeFixed = false;  }  outputIdentifyingInformation(fixedFile);  }

  do {

  cout << " Time = " << t << endl  << " Doing " << passes << " passes through lattice " << flush; 

for (int pass = 0; pass < passes; ++pass) {

  updateLattice();  outputTfixedData(fixedFile, pass == 0); 

}

  cout << "done!" << endl;

  computeAverages();

  cout << " Magnetization per spin = " << mPerSpinAverage << endl  << " Energy per spin = " << ePerSpinAverage << endl  << " Specific heat per spin = " << cPerSpinAverage << endl  << " Susceptibility per spin = " << chiPerSpinAverage << endl  << " Spin flip average = " << flipAverage << endl;

  if (writeFixed) {  fixedFile << flush;  cout << " Data written to file " << fixedFileName << endl;

Page 6: Ising model in c++

7/27/2019 Ising model in c++

http://slidepdf.com/reader/full/ising-model-in-c 6/11

  }

  } while (getYesOrNo(" Continue simulation"));

  if (writeFixed)  fixedFile.close();

}

void runTscanSimulation() {

  initializeSpins();  T = Tmin;

  if (writeScan) {  scanFile.open(scanFileName);  if (scanFile.fail()) {  cerr << "Sorry, cannot open " << scanFileName << endl;  writeScan = false;  }  outputIdentifyingInformation(scanFile);  }

  cout << " Doing a temperature scan - this may take awhile ... " << endl;

  for (T = Tmin; T <= Tmax + 0.001; T += deltaT) {

  int pass;  for (pass = 0; pass < passesToDiscard; ++pass)  updateLattice();

  zeroAccumulators();

  for (pass = 0; pass < passes; ++pass) {  updateLattice();  }

  computeAverages();

  outputTscanData(cout, T == Tmin);  cout << flush;  if (writeScan) {  outputTscanData(scanFile, T == Tmin);  scanFile << flush;  }

  }

  if (writeScan) {  scanFile.close();

  cout << " Data written to file " << scanFileName << endl;  }

}

void outputIdentifyingInformation(ostream& os) {

  char comment = (os == cout) ? ' ' : '#'; // gnuplot comment start  time_t currentTime = time(NULL);  os << comment << "2-d Ising Model Simulation\t" << ctime(&currentTime)

Page 7: Ising model in c++

7/27/2019 Ising model in c++

http://slidepdf.com/reader/full/ising-model-in-c 7/11

  << comment << "Lx = " << Lx << ", Ly = " << Ly<< ", J = " << J << ", T = " << T << ", H = " << H

  << (coldStart ? ", Cold Start" : ", Hot Start")  << ", passes = " << passes << endl;

}

void outputTfixedData(ostream& os, bool header) {

  if (header) {  char comment = (os == cout) ? ' ' : '#';  os << comment << "Time M / Spin E / Spin\n"  << comment << "---- -------- --------\n";  }

  os.setf(ios::left, ios::adjustfield);  os << ' '  << setw(8) << t << " "  << setw(12) << mPerSpin << " "  << setw(12) << ePerSpin << '\n';

}

void outputTscanData(ostream& os, bool header) {

  if (header) {  char comment = (os == cout) ? ' ' : '#';  os << comment << "T |M| / Spin E / Spin Chi / Spin C / Spin  Flip Prob\n"  << comment << "- ---------- -------- ---------- --------  ---------\n";  }

  os.setf(ios::left, ios::adjustfield);  os << ' '  << setw(6) << T << " "  << setw(12) << mAbsPerSpinAverage << " "

  << setw(12) << ePerSpinAverage << " "  << setw(12) << chiPerSpinAverage << " "  << setw(12) << cPerSpinAverage << " "  << flipAverage  << '\n';

}

main() {

  defaultParameters();  resizeLattice();  initializeSpins();

  bool done = false;  while (!done) {  cout << "\n 2-DIMENSIONAL ISING MODEL SIMULATION"  << "\n ------------------------------------"  << "\n [1] Change Model Parameters"  << "\n [2] Type of Simulation: "  << (doTscan ? "T Scan" : "Fixed T") << " (select to change)"  << "\n [3] Change Simulation Parameters"  << "\n [4] Quit Program"

Page 8: Ising model in c++

7/27/2019 Ising model in c++

http://slidepdf.com/reader/full/ising-model-in-c 8/11

  << "\n\n Enter choice 1..4"  << " or hit RETURN to run simulation: " << flush;  int choice = 0;  getInput(choice);  switch (choice) {  case 0:  if (doTscan) {  runTscanSimulation();  } else {  runTfixedSimulation();  }

break;  case 1:  changeModelParameters();  break;  case 2:  doTscan = doTscan ? false : true;  break;  case 3:  if (doTscan)  changeTscanParameters();  else  changeTfixedParameters();  break;

  case 4:  done = true;  break;  default:  break;  }  }

  exit(0);}

void changeModelParameters() {

  bool done = false;  while (!done) {  cout << "\n MODEL PARAMETER MENU Value"  << "\n -------------------- -----"  << "\n [1] No. Spins in x direction Lx = " << Lx  << "\n [2] No. Spins in y direction Ly = " << Ly  << "\n [3] Temperature T = " << T  << "\n [4] Magnetic Field H = " << H  << "\n [5] Initial Configuration = "  << (coldStart ? "Cold Start" : "Hot Start")  << "\n\n Enter choice 1..5"  << " or hit RETURN for main menu: " << flush;  int choice = 0;

  getInput(choice);  int iValue;  double dValue;  switch (choice) {  case 0:  done = true;  break;  case 1:  cout << " Enter new Lx: " << flush;  getInput(iValue);

Page 9: Ising model in c++

7/27/2019 Ising model in c++

http://slidepdf.com/reader/full/ising-model-in-c 9/11

  if (iValue != Lx && iValue > 0) {  Lx = iValue;  resizeLattice();  }  break;  case 2:  cout << " Enter new Ly: " << flush;  getInput(iValue);  if (iValue != Ly && iValue > 0) {  Ly = iValue;  resizeLattice();  }  break;  case 3:  cout << " Enter new T: " << flush;  getInput(T);  break;  case 4:  cout << " Enter new H: " << flush;  getInput(H);  break;  case 5:  coldStart = coldStart ? false : true;  break;

  default:  break;  }  }

}

void changeTfixedParameters() {

  bool done = false;  while (!done) {  cout << "\n FIXED T PARAMETER MENU Value"  << "\n ---------------------- -----"

  << "\n [1] Temperature T = " << T  << "\n [2] Magnetic Field H = " << H  << "\n [3] Initial Configuration = "  << (coldStart ? "Cold Start" : "Hot Start")  << "\n [4] Output data to file? = "  << (writeFixed ? "YES" : "NO")  << "\n [5] Data file name = "  << (writeFixed ? fixedFileName : "")  << "\n [6] Number of passes = " << passes  << "\n\n Enter choice 1..6"  << " or hit RETURN for main menu: " << flush;  int choice = 0;  getInput(choice);

  switch (choice) {  case 0:  done = true;  break;  case 1:  cout << " Enter new T: " << flush;  getInput(T);  break;  case 2:  cout << " Enter new H: " << flush;

Page 10: Ising model in c++

7/27/2019 Ising model in c++

http://slidepdf.com/reader/full/ising-model-in-c 10/11

  getInput(H);  break;  case 3:  coldStart = coldStart ? false : true;  break;  case 4:  writeFixed = writeFixed ? false : true;  break;  case 5:  cout << " Enter new data file name: " << flush;  getInput(fixedFileName);  break;  case 6:  cout << " Enter new number of passes: " << flush;  getInput(passes);  default:  break;  }  }

}

void changeTscanParameters() {

  bool done = false;  while (!done) {  cout << "\n T SCAN PARAMETER MENU Value"  << "\n --------------------- -----"  << "\n [1] Minimum temperature T_min = " << Tmin  << "\n [2] Maximum temperature T_max = " << Tmax  << "\n [3] Temperature step size delta_T = " << deltaT  << "\n [4] Thermalization passes discard = " << passesToDiscard  << "\n [5] Passes to retain = " << passes  << "\n [6] Output data to file? = "  << (writeScan ? "YES" : "NO")  << "\n [7] Data file name = "  << (writeScan ? scanFileName : "")

  << "\n\n Enter choice 1..7"  << " or hit RETURN for main menu: " << flush;  int choice = 0;  getInput(choice);  switch (choice) {  case 0:  done = true;  break;  case 1:  cout << " Enter new T_min: " << flush;  getInput(Tmin);  break;  case 2:

  cout << " Enter new T_max: " << flush;  getInput(Tmax);  break;  case 3:  cout << " Enter new delta_T: " << flush;  getInput(deltaT);  break;  case 4:  cout << " Enter new thermalization passes to discard: " << flush;  getInput(passesToDiscard);

Page 11: Ising model in c++

7/27/2019 Ising model in c++

http://slidepdf.com/reader/full/ising-model-in-c 11/11

  break;  case 5:  cout << " Enter new number of passes: " << flush;  getInput(passes);  break;  case 6:  writeScan = writeScan ? false : true;  break;  case 7:  cout << " Enter new data file name: " << flush;  getInput(scanFileName);  break;  default:  break;  }  }

}