/*
 * NewJApplet.java
 *
 * Created on February 13, 2008, 6:36 PM
 */

import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
import java.awt.Graphics2D;
import java.awt.geom.*;
import java.text.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import java.awt.image.BufferedImage;
/**
 *
 * @author  root
 */
public class NewJApplet extends JApplet
        implements Runnable {
    DecimalFormat df,df1;
    Timer timer;
    Thread calculatorThread;
    
     Graphics2D gb;
     BufferedImage image;
    
  int N=       500;
  int MAXITER= 200;
  double J=1.0;
  int NSQ=40000;
  
int [] Lattice;  
double kT,magav,B;
int Npoints,magsum,done,number_samples;
char [] message;
char cc;


int i; 
int j; 
int iter; 
int Spin;
double DE;
double r;

double [] Analytical;


int count=0;
int loops=20000;

int ixo=0;
int iyo=0;


    /** Initializes the applet NewJApplet */
    public void init() {
        try {
            java.awt.EventQueue.invokeAndWait(new Runnable() {

                public void run() { int i;
                    initComponents();
                    
                }
            });
        } catch (Exception ex) {
            ex.printStackTrace();
        }

     
      
       
        df =new DecimalFormat("00.000E0"); 
        df1 =new DecimalFormat("0.000");
       
        Lattice=new int[N];
        
        Analytical = new double[200];
       
        //timer = new Timer(1, this);
        //timer.setInitialDelay(1);
        //timer.start(); 
        image =
        new BufferedImage(400, 400, BufferedImage.TYPE_INT_RGB);
        gb = (Graphics2D)image.createGraphics();
        gb.setBackground(Color.white);
        gb.clearRect(0,0,400,400);
        
        reset_all();
        
        calc_exact();
        //jPanel1.repaint();
    }
    
         public void run()
         { int i;
         
          while (Thread.currentThread() == calculatorThread) {
              
             Metropolis();
    
         }
         }
    
        public void start()
        {
            if (calculatorThread == null) {
            calculatorThread = new Thread(this);
            calculatorThread.start();
              }
        }
        
        
        public void stop() {
          calculatorThread = null;
}
        
        
       
        
        public void reset_all()
        {
        i=0;j=0;
        count=0;
        
        kT=2.0;
        B=1.0;
        kTlab.setText("kT="+df1.format(kT));
        kTslider.setValue((int)(Math.sqrt(kT)*100));
        Blab.setText("B="+df1.format(B));
        Bslider.setValue((int)(Math.sqrt(B)*100));
        
        RandomSpin();
        ClearAverage();
        }
        
        public void calc_exact()
        { double s;
        Analytical[0]=1;
        for(i=1;i<200;i++)
        {
        double x=i*0.05;
        s=Math.sinh(B/x);
        Analytical[i]=s/Math.sqrt(s*s+Math.exp(-4*J/x));
        
        
        }    
        
        
        }
        
    /** This method is called from within the init() method to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new myPanel();
        jPanel2 = new javax.swing.JPanel();
        kTslider = new javax.swing.JSlider();
        kTlab = new javax.swing.JLabel();
        Bslider = new javax.swing.JSlider();
        Blab = new javax.swing.JLabel();
        jButton3 = new javax.swing.JButton();
        jButton4 = new javax.swing.JButton();

        jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        jPanel1.setDoubleBuffered(false);
        jPanel1.setMaximumSize(new java.awt.Dimension(350, 550));
        jPanel1.setMinimumSize(new java.awt.Dimension(350, 550));
        jPanel1.setPreferredSize(new java.awt.Dimension(350, 550));

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 415, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 0, Short.MAX_VALUE)
        );

        jPanel2.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        jPanel2.setMaximumSize(new java.awt.Dimension(120, 550));
        jPanel2.setMinimumSize(new java.awt.Dimension(120, 550));
        jPanel2.setPreferredSize(new java.awt.Dimension(120, 550));

        kTslider.setMaximum(310);
        kTslider.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                kTsliderMouseDragged(evt);
            }
        });

        kTlab.setText("jLabel1");

        Bslider.setMaximum(200);
        Bslider.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                BsliderMouseDragged(evt);
            }
        });

        Blab.setText("jLabel1");

        jButton3.setText("all up");
        jButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton3ActionPerformed(evt);
            }
        });

        jButton4.setText("randomize");
        jButton4.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton4ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap(22, Short.MAX_VALUE)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                        .addComponent(kTlab)
                        .addGap(66, 66, 66))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                        .addComponent(Blab)
                        .addGap(64, 64, 64))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(Bslider, javax.swing.GroupLayout.PREFERRED_SIZE, 125, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(kTslider, javax.swing.GroupLayout.PREFERRED_SIZE, 125, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jButton3, javax.swing.GroupLayout.PREFERRED_SIZE, 125, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jButton4, javax.swing.GroupLayout.PREFERRED_SIZE, 125, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(25, 25, 25))))
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addGap(29, 29, 29)
                .addComponent(kTlab)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(kTslider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(42, 42, 42)
                .addComponent(Blab)
                .addGap(18, 18, 18)
                .addComponent(Bslider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(80, 80, 80)
                .addComponent(jButton3)
                .addGap(18, 18, 18)
                .addComponent(jButton4)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 417, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, 174, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(499, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, 399, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
                .addContainerGap(480, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void kTsliderMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_kTsliderMouseDragged
        
        kT=kTslider.getValue()*0.01;
        kT=kT*kT;
        kTlab.setText("kT="+df1.format(kT));
        //ClearAverage();
        //jPanel1.repaint();// TODO add your handling code here:
}//GEN-LAST:event_kTsliderMouseDragged

    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed
        stop();
        AllUp();// TODO add your handling code here:
        start();
    }//GEN-LAST:event_jButton3ActionPerformed

    private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton4ActionPerformed
        RandomSpin();// TODO add your handling code here:
    }//GEN-LAST:event_jButton4ActionPerformed

    private void BsliderMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_BsliderMouseDragged
        B=Bslider.getValue()*0.01;
        B=B*B;
        Blab.setText("B="+df1.format(B));
        calc_exact();// TODO add your handling code here:
}//GEN-LAST:event_BsliderMouseDragged

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel Blab;
    private javax.swing.JSlider Bslider;
    private javax.swing.JButton jButton3;
    private javax.swing.JButton jButton4;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JLabel kTlab;
    private javax.swing.JSlider kTslider;
    // End of variables declaration//GEN-END:variables
    
   
   
void AllUp ()
{
 int i,j;
 
 
  for (i = 0; i < N; i++)
    
     { Lattice[i] = 1;
       
    }
       

}



void RandomSpin ()
{ double r; int i,j;
  Graphics g=jPanel1.getGraphics();
 
  for (i=0;i<N;i++) 
    { r=Math.random();
    if (r<0.5) 
      {Lattice[i]=-1;}
    else {Lattice[i]=1;}
    
    }
}

double Energy (int i,  int Spin)
{
  int left, right, top, bottom;
  
  // periodic b.c.
  
  left = (i == 0 ? (N - 1) : (i - 1));
  right = (i == (N - 1) ? 0 : (i + 1));
 

  return - 2.0 * J * Spin * (Lattice[left] + Lattice[right])+2.0*B*Spin;
			    
}

void Metropolis()

  { Graphics g; int i,j,ix,iy;
    g=jPanel1.getGraphics();
    
     Graphics2D g2 = (Graphics2D)g;
       
          
       for(i=0;i<N;i++)
       { 
       
       
                     
 
   
      {
	Spin = Lattice[i] < 1 ? 1 : -1; 
	// calculate energy change
	DE = Energy (i,  Spin); 
	// if DE < 0 then flip spin  
	if (DE < 0) 
	  { Lattice[i] = Spin; 
             
            
            }
	else {
	  // use BoltzmaNn factor to decide
	  r = Math.random();
	  if (Math.exp(- DE/kT) > r)
          { Lattice[i] = Spin;
            
            }
            
	} /* else */
        
      
        
      } 

  }
    
  

  number_samples++;

  magsum=0;
  for (i=0;i<N;i++) magsum=magsum+Lattice[i];
    magav=magav+(double)magsum;
 

  

  

 

  if (number_samples>500)
  {
   gb.clearRect(0,40,400,250);
  gb.setColor(Color.red);
  ix=(int) (kT*40)+2; iy=245-(int) (200.0*Math.abs(magav)/(N*number_samples));
  gb.drawOval(ix-5, iy-5, 10,10); 
  ClearAverage();
     
          for(ix=1;ix<200;ix++)
          gb.drawLine(2*(ix-1),245-(int)(200*Analytical[ix-1]),2*ix,245-(int)(200*Analytical[ix]));
  gb.setColor(Color.black);
  gb.drawLine(0,245,400,245);
  gb.drawLine(0,0,0,245);
  
  for (i=1;i<10;i++)
  {
  ix=i*40+2;
  gb.drawLine(ix,245,ix,250);
  gb.drawString(""+i,ix-4,265);
  }
  
  for (i=1;i<6;i++)
  {
  iy=245-i*40;
  gb.drawLine(0,iy,5,iy);
  
  }
  
  gb.drawString("average magnetisation",20,20);
  gb.drawString("kT",350,280);
  
  g2.drawImage(image, 0, 0, null);
  }
  }

void ClearAverage()

{ magav=0.0; number_samples=0;}



    public

     class myPanel extends javax.swing.JPanel {

        int iy0, iy1,  ix0, ix1;
        double tscale;
        
     

        
      
        public void paint(Graphics g) {
        int ix,iy,ir,ix5,ix10,ix15,ix20,ix25,k,i,j;    
        double xp,yp;
        Graphics2D g2=(Graphics2D) g;
        int size=200;
        
        //if(count==0) {super.paintComponent(g);
         
         //}
            
          super.paintComponent(g);
        
       
          g2.drawImage(image, 0, 0, null);
          
         
          
        }
    }
}
     
     
     
