/*
 * 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.*;

/**
 *
 * @author  root
 */
public class NewJApplet extends javax.swing.JApplet
        implements ActionListener {
    DecimalFormat df,df1,df2;
    Timer timer;
    int loops = 25000;
    int loops_i = 100;
    int NMAX = 1000;
    int size=300;
    
    int POINTS = 5;
    int NHISTO = 300,NCORR=300;
    int meastype=0;
    
    double DISTANCE = 4.5;
    double TEMP_0 = 100.0;
    double mass = 12.5;
    double vdwe = 85.0E-23;
    double vdws = 2.95;
    double dvdwmin2 = 100.0;
    double TIMESTEP = 0.0005;
    double BOXSIZE = 50.0;
    double NEW_BOXSIZE = 50.0;
    double vscale=0.1;
    
    double[] xc, yc, zc, vx, vy, vz, xc0, yc0, zc0, vx0, vy0, vz0, xcold, ycold, zcold,
            dxc, dyc, dzc, dvx, dvy, dvz,ax0,ay0,az0,ax1,ay1,az1,axm1,aym1,azm1;
    double pressav, ktav, pvs, viri, virisum, virav,vv0;
    int i, j, k, iloop, il2, count1, countall, ia,collected,coll2;
    int[] histo;
    double [] corrf;
    double vdws6, vdws12, fox, foy, foz, ekin, epot, etot, temper, ttime, tsf,
            DEkin, epot_0, ekin_0, pressure, vmol, densty;
    int NATOMS;
    boolean equilibrate=true,showhisto=false,showdist=false,
            showvcor=false,showxsq=false;
    

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

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

        xc = new double[NMAX];
        yc = new double[NMAX];
        zc = new double[NMAX];

        xcold = new double[NMAX];
        ycold = new double[NMAX];
        zcold = new double[NMAX];

        xc0 = new double[NMAX];
        yc0 = new double[NMAX];
        zc0 = new double[NMAX];

        dxc = new double[NMAX];
        dyc = new double[NMAX];
        dzc = new double[NMAX];

        vx = new double[NMAX];
        vy = new double[NMAX];
        vz = new double[NMAX];

        vx0 = new double[NMAX];
        vy0 = new double[NMAX];
        vz0 = new double[NMAX];

        dvx = new double[NMAX];
        dvy = new double[NMAX];
        dvz = new double[NMAX];
        
        ax0=new double[NMAX];
        ay0=new double[NMAX];
        az0=new double[NMAX];
        
             
        ax1=new double[NMAX];
        ay1=new double[NMAX];
        az1=new double[NMAX];
        
             
        axm1=new double[NMAX];
        aym1=new double[NMAX];
        azm1=new double[NMAX];
        
        
        
        histo=new int[NHISTO];
        corrf=new double[NCORR];

        vdws6 = vdws * vdws * vdws * vdws * vdws * vdws;
        vdws12 = vdws6 * vdws6;
        tsf = TIMESTEP * 1.0E-14 / 1.66E-27;

   
       
        df =new DecimalFormat("00.000E0"); 
        df1 =new DecimalFormat("00.000");
        df2=new DecimalFormat("0.0");
       
        reset_all();
        jPanel1.repaint();
    }
        public void actionPerformed(ActionEvent e) {
           
           if(count1>=loops) {return;}
          jPanel1.repaint();
          timer.restart();
          
      }
        
        public void reset_all()
        {
        ttime = 0.0;
        
        DISTANCE=BOXSIZE/5.0;
        set_coord();
        set_velocities();
        set_accel();
        vmol=BOXSIZE/POINTS; vmol=1e-30*vmol*vmol*vmol;
        densty=mass*1.6E-27/vmol;
        
       

        reset_counters();
        
        timer = new Timer(1, this);
        timer.setInitialDelay(10);
        timer.start(); 
         equilbutton.setSelected(true); 
        
         jSlider1.setValue((int)(TEMP_0*0.25));
         jSlider2.setValue((int)(BOXSIZE*2.0));
         jLabel12.setText("T0=" + TEMP_0);
         jLabel13.setText("BOX="+BOXSIZE);
        
        
        }
        public void reset_counters()
        {
        epot_0 = 0;
        ekin_0 = 0;
        pressav = 0.0;
        ktav = 0.0;
        virav = 0.0;
        count1 = 0;
        countall = 0;
        collected=0;
        coll2=0;
        ttime=0.0;
        }
    
    /** 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();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        jLabel8 = new javax.swing.JLabel();
        jLabel9 = new javax.swing.JLabel();
        jLabel10 = new javax.swing.JLabel();
        jLabel11 = new javax.swing.JLabel();
        jLabel14 = new javax.swing.JLabel();
        jLabel15 = new javax.swing.JLabel();
        jPanel3 = new javax.swing.JPanel();
        equilbutton = new javax.swing.JToggleButton();
        jLabel12 = new javax.swing.JLabel();
        jSlider1 = new javax.swing.JSlider();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jSlider2 = new javax.swing.JSlider();
        jLabel13 = new javax.swing.JLabel();
        jComboBox1 = new javax.swing.JComboBox();

        jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        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, 367, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 548, 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));

        jLabel1.setText("jLabel1");

        jLabel2.setText("jLabel2");

        jLabel3.setText("jLabel3");

        jLabel4.setText("jLabel4");

        jLabel5.setText("jLabel5");

        jLabel6.setText("jLabel6");

        jLabel7.setText("jLabel7");

        jLabel8.setText("jLabel8");

        jLabel9.setText("jLabel8");

        jLabel10.setText("jLabel8");

        jLabel11.setText("Label11");

        jLabel14.setText("jLabel14");

        jLabel15.setText("jLabel15");

        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()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel1)
                    .addComponent(jLabel2)
                    .addComponent(jLabel7)
                    .addComponent(jLabel5)
                    .addComponent(jLabel4)
                    .addComponent(jLabel11)
                    .addComponent(jLabel10)
                    .addComponent(jLabel8)
                    .addComponent(jLabel3)
                    .addComponent(jLabel14)
                    .addComponent(jLabel15)
                    .addComponent(jLabel6)
                    .addComponent(jLabel9))
                .addContainerGap(106, Short.MAX_VALUE))
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addGap(23, 23, 23)
                .addComponent(jLabel1)
                .addGap(19, 19, 19)
                .addComponent(jLabel3)
                .addGap(18, 18, 18)
                .addComponent(jLabel8)
                .addGap(18, 18, 18)
                .addComponent(jLabel10)
                .addGap(18, 18, 18)
                .addComponent(jLabel11)
                .addGap(42, 42, 42)
                .addComponent(jLabel4)
                .addGap(18, 18, 18)
                .addComponent(jLabel5)
                .addGap(18, 18, 18)
                .addComponent(jLabel7)
                .addGap(18, 18, 18)
                .addComponent(jLabel2)
                .addGap(18, 18, 18)
                .addComponent(jLabel9)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 65, Short.MAX_VALUE)
                .addComponent(jLabel6)
                .addGap(40, 40, 40)
                .addComponent(jLabel14)
                .addGap(18, 18, 18)
                .addComponent(jLabel15)
                .addGap(20, 20, 20))
        );

        jPanel3.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        jPanel3.setMaximumSize(new java.awt.Dimension(32767, 550));
        jPanel3.setMinimumSize(new java.awt.Dimension(0, 550));

        equilbutton.setText("Thermostat");
        equilbutton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                equilbuttonActionPerformed(evt);
            }
        });

        jLabel12.setText("jLabel1");

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

        jButton1.setText("Reset av");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jButton2.setText("Restart");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        jSlider2.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                jSlider2MouseDragged(evt);
            }
        });

        jLabel13.setText("jLabel1");

        jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "nothing", "velocities", "distances", "vcorrel", "xsquare" }));
        jComboBox1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jComboBox1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(equilbutton))
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addGap(42, 42, 42)
                        .addComponent(jLabel12))
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 105, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jButton2))
                    .addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, 125, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jSlider2, javax.swing.GroupLayout.PREFERRED_SIZE, 125, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addGap(42, 42, 42)
                        .addComponent(jLabel13))
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jComboBox1, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addGap(24, 24, 24))
        );

        jPanel3Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {equilbutton, jButton1, jButton2});

        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(equilbutton)
                .addGap(18, 18, 18)
                .addComponent(jLabel12)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(44, 44, 44)
                .addComponent(jButton1)
                .addGap(43, 43, 43)
                .addComponent(jButton2)
                .addGap(32, 32, 32)
                .addComponent(jLabel13)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSlider2, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(37, 37, 37)
                .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(181, 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, 369, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, 173, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(385, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap(206, Short.MAX_VALUE))
        );

        layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {jPanel1, jPanel2, jPanel3});

    }// </editor-fold>//GEN-END:initComponents

    private void equilbuttonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_equilbuttonActionPerformed
      equilibrate = equilbutton.isSelected();  // TODO add your handling code here:
    }//GEN-LAST:event_equilbuttonActionPerformed

    private void jSlider1MouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jSlider1MouseDragged
        TEMP_0=jSlider1.getValue()*5.0;
        jLabel12.setText("T0="+TEMP_0);// TODO add your handling code here:
    }//GEN-LAST:event_jSlider1MouseDragged

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

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
        reset_all();
        jPanel1.repaint();// TODO add your handling code here:
    }//GEN-LAST:event_jButton2ActionPerformed

    private void jSlider2MouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jSlider2MouseDragged
        BOXSIZE=jSlider2.getValue()*0.5;
        jLabel13.setText("BOX="+BOXSIZE);// TODO add your handling code here:
    }//GEN-LAST:event_jSlider2MouseDragged

    private void jComboBox1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jComboBox1ActionPerformed
        meastype=jComboBox1.getSelectedIndex();
        showhisto=(meastype==1);
        showdist=(meastype==2);
        showvcor=(meastype==3);
        showxsq=(meastype==4);
        collected=0;
        coll2=0;// TODO add your handling code here:
    }//GEN-LAST:event_jComboBox1ActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JToggleButton equilbutton;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JComboBox jComboBox1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel13;
    private javax.swing.JLabel jLabel14;
    private javax.swing.JLabel jLabel15;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JSlider jSlider1;
    private javax.swing.JSlider jSlider2;
    // End of variables declaration//GEN-END:variables
    
    void vel_corr()
    { int i,index; double vv;
      
      if(collected==0)
      { for(i=0;i<NATOMS;i++)
        vx0[i]=vx[i];
        vy0[i]=vy[i];
        vz0[i]=vz[i];
      }
      
      {
       if(collected>=0 && collected<NCORR)
       {
       vv=0.0;
        for(i=0;i<NATOMS;i++)
        {
         vv=vv+vx[i]*vx0[i]+vy[i]*vy0[i]+vz[i]*vz0[i];
        
        }
        corrf[collected]+=vv;
        
       }
          
      }}
    void x_sq()
    { int i,index; double xsq,dx,dy,dz;
      if (collected==0) for(i=0;i<NATOMS;i++)
      { xc0[i]=xc[i];
        yc0[i]=yc[i];
        zc0[i]=zc[i];
      }
    if(collected>=0 && collected<NCORR)
    {
        for(i=0;i<NATOMS;i++)
        {
        dx=xc[i]-xc0[i];
        dy=yc[i]-yc0[i];
        dz=zc[i]-zc0[i];
        xsq=dx*dx+dy*dy+dz*dz;
        corrf[collected]+=xsq;
        }
    }
    }
    void vel_histo()
    { int i,index; double vabs;
     for(i=0;i<NATOMS;i++)
      
      {
        vabs=Math.sqrt(vx[i]*vx[i]+vy[i]*vy[i]+vz[i]*vz[i]);
        index=(int)(vabs/vscale);
        if ( index>=0 && index<NHISTO) histo[index]++;
      
      }
    
    
    }
    
    
    void dist_histo()
    { int i,j,index; double rij,dx,dy,dz;
    for(i=0;i<NATOMS;i++)
        for(j=i+1;j<NATOMS;j++)
            
        {dx=xc[i]-xc[j];
         dy=yc[i]-yc[j];
         dz=zc[i]-zc[j];
        
         rij=Math.sqrt(dx*dx+dy*dy+dz*dz);
         index=(int)(rij*20.0);
         if ( index>=0 && index<NHISTO) histo[index]++;
        }
            
    
    }
    
    int vdwforce(int i, int j) {
        double dx, dy, dz, d2, d6, d8, d14, fac6, fac12, facall;
        int notzero;
        dx = xc[i] - xc[j];
        dy = yc[i] - yc[j];
        dz = zc[i] - zc[j];

        d2 = dx * dx + dy * dy + dz * dz;
        if (d2 < 0.09) {
            d2 = 0.09;
        }

        if (d2 < dvdwmin2) {
            d6 = d2 * d2 * d2;
            d8 = d6 * d2;
            d14 = d6 * d6 * d2;
            fac12 = 1.0E10 * 48.0 * vdwe * (vdws12) / d14;
            fac6 = -24.0E10 * vdwe * (vdws6) / d8;
            facall = fac6 + fac12;




            fox = facall * dx;
            foy = facall * dy;
            foz = facall * dz;

            notzero = 1;


        } else {
            notzero = 0;
            fox = 0.0;
            foy = 0.0;
            foz = 0.0;
        }
        return notzero;
    }

    double vdwen(int i, int j) /* van der Vaals interaction between two atoms i and j */ {
        double dx, dy, dz, d2, d6, d12, fac6, fac12, facall;

        dx = xc[i] - xc[j];
        dy = yc[i] - yc[j];
        dz = zc[i] - zc[j];

        d2 = dx * dx + dy * dy + dz * dz;
        if (d2 < 0.09) {
            d2 = 0.09;
        }

        if (d2 < dvdwmin2) {
            d6 = d2 * d2 * d2;
            d12 = d6 * d6;
            fac12 = 4.0 * vdwe * (vdws12) / d12;
            fac6 = -4.0 * vdwe * (vdws6) / d6;
            facall = fac6 + fac12;
            return facall;

        } else {
            return 0.0;
        }
    }

    double vdwsum() {
        int i, j;
        double sum;

        sum = 0.0;
        for (i = 0; i < NATOMS - 1; i++) {
            for (j = i + 1; j < NATOMS; j++) {
                sum = sum + vdwen(i, j);
            }
        }
        return sum;
    }

    void set_coord() {
        int i, j, k;
        double xm, ym, zm;

        xm = 0;
        ym = 0;
        zm = 0;


        NATOMS = 0;

        for (i = 0; i < POINTS; i++) {
            for (j = 0; j < POINTS; j++) {
                for (k = 0; k < POINTS; k++) {
                    if (NATOMS < NMAX) {
                        xc[NATOMS] = i * DISTANCE;
                        yc[NATOMS] = j * DISTANCE;
                        zc[NATOMS] = k * DISTANCE;

                        xm = xm + xc[NATOMS];
                        ym = ym + yc[NATOMS];
                        zm = zm + zc[NATOMS];

                    } else {
                        this.stop();
                    }
                    NATOMS++;
                }
            }
        }

        xm = xm / NATOMS;
        ym = ym / NATOMS;
        zm = zm / NATOMS;

        for (i = 0; i < NATOMS; i++) {
            xc[i] = xc[i] - xm;
            yc[i] = yc[i] - ym;
            zc[i] = zc[i] - zm;
        }

    }

    double randgauss() {
        double x, r, phi, rho;

        r = Math.random();
        phi = 2.0 * Math.PI * r;

        r = Math.random();
        rho = Math.sqrt(-Math.log(1 - r));
        x = rho * Math.cos(phi) * Math.sqrt(2.0);

        return x;
    }

    void set_velocities() {
        int i;
        double vterm;

        vterm = Math.sqrt(TEMP_0 * 1.38 / (1.66 * mass));

        for (i = 0; i < NATOMS; i++) {
            vx[i] = vterm * randgauss();
            vy[i] = vterm * randgauss();
            vz[i] = vterm * randgauss();

            xcold[i] = xc[i] - vx[i] * TIMESTEP;
            ycold[i] = yc[i] - vy[i] * TIMESTEP;
            zcold[i] = zc[i] - vz[i] * TIMESTEP;

        }
        
    }
    void set_accel(){
         int i, j, notzero;

        double foxs, foys, fozs;

        
        
     for (i = 0; i < NATOMS; i++) {
            foxs = 0.0;
            foys = 0.0;
            fozs = 0.0;
            for (j = 0; j < NATOMS; j++) {
                if (i != j) {
                    notzero = vdwforce(i, j);
                    if (notzero == 1) {
                        foxs = foxs + fox;
                        foys = foys + foy;
                        fozs = fozs + foz;


                    }
                }
                
                
            }

            ax1[i] =ax0[i]=axm1[i]= foxs *tsf/ mass;
            ay1[i] =ay0[i]=aym1[i]= foys *tsf/ mass;
            az1[i] =az0[i]=azm1[i]= fozs *tsf/ mass;
        }
    }

    void beeman() {
        int i, j, notzero;

        double foxs, foys, fozs;

     
        /* (1) advance coordinates */

        for (i = 0; i < NATOMS; i++) {
            dxc[i] = vx[i] * TIMESTEP+(4*ax0[i]-axm1[i])*TIMESTEP/6;
            dyc[i] = vy[i] * TIMESTEP+(4*ay0[i]-aym1[i])*TIMESTEP/6;
            dzc[i] = vz[i] * TIMESTEP+(4*az0[i]-azm1[i])*TIMESTEP/6;

         

            xc[i] = xc[i] + dxc[i];
            yc[i] = yc[i] + dyc[i];
            zc[i] = zc[i] + dzc[i];

            xcold[i]=xc[i] ;
            ycold[i]=yc[i] ;
            zcold[i]=zc[i] ;

        }
        
        /* (2) calculate forces   */

        DEkin = 0;
        virisum = 0.0;

        for (i = 0; i < NATOMS; i++) {
            foxs = 0.0;
            foys = 0.0;
            fozs = 0.0;
            for (j = 0; j < NATOMS; j++) {
                if (i != j) {
                    notzero = vdwforce(i, j);
                    if (notzero == 1) {
                        foxs = foxs + fox;
                        foys = foys + foy;
                        fozs = fozs + foz;

                        viri = (xc[i] - xc[j]) * fox + (yc[i] - yc[j]) * foy + (zc[i] - zc[j]) * foz;

                        virisum += viri;

                    }
                }
                
                
            }

            ax1[i] = foxs *tsf/ mass;
            ay1[i] = foys *tsf/ mass;
            az1[i] = fozs *tsf/ mass;
        }
            virisum = virisum * 0.5E-10 / NATOMS;
          
            // advance velocities
          
            for (i = 0; i < NATOMS; i++) {
            dvx[i] = (2*ax1[i]+5*ax0[i]-axm1[i])/6;
            dvy[i] = (2*ay1[i]+5*ay0[i]-aym1[i])/6;
            dvz[i] = (2*az1[i]+5*az0[i]-azm1[i])/6;

         

            vx[i] = vx[i] + dvx[i];
            vy[i] = vy[i] + dvy[i];
            vz[i] = vz[i] + dvz[i];


        }
            
            
        //recycle accelerations    

        for (i = 0; i < NATOMS; i++) {

            axm1[i] = ax0[i];
            aym1[i] = ay0[i];
            azm1[i] = az0[i];
            ax0[i] = ax1[i];
            ay0[i] = ay1[i];
            az0[i] = az1[i];
        }


    }
        void verlet() {
        int i, j, notzero;

        double foxs, foys, fozs;

        /* (1) calculate forces   */

        DEkin = 0;
        virisum = 0.0;

        for (i = 0; i < NATOMS; i++) {
            foxs = 0.0;
            foys = 0.0;
            fozs = 0.0;
            for (j = 0; j < NATOMS; j++) {
                if (i != j) {
                    notzero = vdwforce(i, j);
                    if (notzero == 1) {
                        foxs = foxs + fox;
                        foys = foys + foy;
                        fozs = fozs + foz;

                        viri = (xc[i] - xc[j]) * fox + (yc[i] - yc[j]) * foy + (zc[i] - zc[j]) * foz;

                        virisum += viri;

                    }
                }
            }


        
            /* (2) velocity changes  */

            dvx[i] = foxs * tsf / mass;
            dvy[i] = foys * tsf / mass;
            dvz[i] = fozs * tsf / mass;
        }
        
        /* (3) advance coordinates */

        for (i = 0; i < NATOMS; i++) {
            dxc[i] = xc[i] - xcold[i] + dvx[i] * TIMESTEP;
            dyc[i] = yc[i] - ycold[i] + dvy[i] * TIMESTEP;
            dzc[i] = zc[i] - zcold[i] + dvz[i] * TIMESTEP;

            xcold[i] = xc[i];
            ycold[i] = yc[i];
            zcold[i] = zc[i];

            xc[i] = xc[i] + dxc[i];
            yc[i] = yc[i] + dyc[i];
            zc[i] = zc[i] + dzc[i];


            vx[i] = dxc[i] / TIMESTEP + 0.5 * dvx[i];
            vy[i] = dyc[i] / TIMESTEP + 0.5 * dvy[i];
            vz[i] = dzc[i] / TIMESTEP + 0.5 * dvz[i];

        }


        virisum = virisum * 0.5E-10 / NATOMS;


    }

    double ekinsum() {
        int i;
        double sum;
        sum = 0.0;
        for (i = 0; i < NATOMS; i++) {
            sum = sum + vx[i] * vx[i];
            sum = sum + vy[i] * vy[i];
            sum = sum + vz[i] * vz[i];
        }
        sum = sum * 0.5 * mass * 1.66E-23;
        return sum;
    }

    void rescale_velocities() {
        double T_now, Ekin_now, s_factor;
        int ia;

        Ekin_now = ekinsum();
        T_now = Ekin_now / (1.5 * 1.38E-23 * NATOMS);
        
        
        
        if((T_now<0.8*TEMP_0) || (T_now>1.2*TEMP_0))
        
        {s_factor = Math.sqrt(TEMP_0 / T_now);}
        
        else
        {s_factor=1.0+(TEMP_0/T_now -1.0)/20.0;}    
       
        for (ia = 0; ia < NATOMS; ia++) {



            vx[ia] = (xc[ia] - xcold[ia]) / TIMESTEP;
            vy[ia] = (yc[ia] - ycold[ia]) / TIMESTEP;
            vz[ia] = (zc[ia] - zcold[ia]) / TIMESTEP;



            vx[ia] = vx[ia] * s_factor;
            vy[ia] = vy[ia] * s_factor;
            vz[ia] = vz[ia] * s_factor;

            xcold[ia] = xc[ia] - vx[ia] * TIMESTEP;
            ycold[ia] = yc[ia] - vy[ia] * TIMESTEP;
            zcold[ia] = zc[ia] - vz[ia] * TIMESTEP;



        }
    }
     void rescale_velocitiesb() {
        double T_now, Ekin_now, s_factor;
        int ia;

        Ekin_now = ekinsum();
        T_now = Ekin_now / (1.5 * 1.38E-23 * NATOMS);
        
        
        
        if((T_now<0.8*TEMP_0) || (T_now>1.2*TEMP_0))
        
        {s_factor = Math.sqrt(TEMP_0 / T_now);}
        
        else
        {s_factor=1.0+(TEMP_0/T_now -1.0)/20.0;}    
       
        for (ia = 0; ia < NATOMS; ia++) {



        


            vx[ia] = vx[ia] * s_factor;
            vy[ia] = vy[ia] * s_factor;
            vz[ia] = vz[ia] * s_factor;

         



        }
    }

    void swapx(int i) {
        double stor;

        stor = xc[i];
        xc[i] = xcold[i];
        xcold[i] = stor;
        
        ax1[i]=-ax1[i];
        ax0[i]=-ax0[i];
        axm1[i]=-axm1[i];
        
    }

    void swapy(int i) {
        double stor;

        stor = yc[i];
        yc[i] = ycold[i];
        ycold[i] = stor;
        
        ay1[i]=-ay1[i];
        ay0[i]=-ay0[i];
        aym1[i]=-aym1[i];
        
    }

    void swapz(int i) {
        double stor;

        stor = zc[i];
        zc[i] = zcold[i];
        zcold[i] = stor;
        
        az1[i]=-az1[i];
        az0[i]=-az0[i];
        azm1[i]=-azm1[i];
        
    }

    double check_box() {
        int i;
        double impact;

        impact = 0.0;

        for (i = 0; i < NATOMS; i++) {

            if (xc[i] < -BOXSIZE / 2) {
                if (vx[i] < 0.0) {
                    vx[i] = Math.abs(vx[i]);
                    impact += Math.abs(vx[i]);
                    swapx(i);
                }
            }
            if (yc[i] < -BOXSIZE / 2) {
                if (vy[i] < 0.0) {
                    vy[i] = Math.abs(vy[i]);
                    impact += Math.abs(vy[i]);
                    swapy(i);
                }
            }
            if (zc[i] < -BOXSIZE / 2) {
                if (vz[i] < 0.0) {
                    vz[i] = Math.abs(vz[i]);
                    impact += Math.abs(vz[i]);
                    swapz(i);
                }
            }

            if (xc[i] > BOXSIZE / 2) {
                if (vx[i] > 0.0) {
                    vx[i] = -Math.abs(vx[i]);
                    impact += Math.abs(vx[i]);
                    swapx(i);
                }
            }
            if (yc[i] > BOXSIZE / 2) {
                if (vy[i] > 0.0) {
                    vy[i] = -Math.abs(vy[i]);
                    impact += Math.abs(vy[i]);
                    swapy(i);
                }
            }
            if (zc[i] > BOXSIZE / 2) {
                if (vz[i] > 0.0) {
                    vz[i] = -Math.abs(vz[i]);
                    impact += Math.abs(vz[i]);
                    swapz(i);
                }
            }
        }
        return impact / 3.0;

    /* factor 2 since momentum transfer = 2mv */
    /* factor 1/6 for average over 6 faces */

    }

    void simulate() {
        double impact;
    


         {
            impact = 0.0;
            count1++;


           

            for (il2 = 0; il2 < loops_i; il2++) {

                countall++;
                if (equilibrate) {
                rescale_velocitiesb();
                 }

                //verlet();
                

                impact += check_box();
                beeman();
               
                ttime = ttime + TIMESTEP;
         

            }
               epot = vdwsum();

              
                ekin = ekinsum();
               
                etot = ekin + epot;
                temper = ekin / (1.5 * 1.38E-23 * NATOMS);
                ktav = ktav + temper * 1.38E-23;
                virav = virav + virisum;


            pressure = 1E34 * (1.0 / loops_i) * impact * mass *
                       1.66E-27 / (TIMESTEP * BOXSIZE * BOXSIZE);

            pressav = pressav + pressure;


            pvs = 0.0;
            for (ia = 0; ia < NATOMS; ia++) {
                if (vx[ia] > 0) {
                    pvs = pvs + vx[ia] * vx[ia];
                }
            }
            pvs = pvs * 2.0 * mass * 1.6E-27 * 1E4 / NATOMS;



        /* kg /(psec**2 A) = 1E34  kg/(s**2 m) */


      

        }


    }


    public

     class myPanel extends javax.swing.JPanel {

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

        

        public void paintComponent(Graphics g) {
        int i,ix,iy,ir,ix5,ix10,ix15,ix20,ix25;    
        double xp,yp;
        Graphics2D g2=(Graphics2D) g;
        
        {super.paintComponent(g);
         
        g.clearRect(0,0,size,size); }
            
        
        if((showhisto||showdist) && collected==0)
        {
         for(i=0;i<NHISTO;i++) histo[i]=0;
        
        }
         if((showvcor) && coll2==0)
        {
         for(i=0;i<NCORR;i++) corrf[i]=0; coll2=1; corrf[0]=1.0;
        
        }
        
        if((showxsq) && coll2==0)
        {
         for(i=0;i<NCORR;i++) corrf[i]=0; coll2=1;
        
        }
        
        
        simulate();   
        
        if(showhisto)
        {
        vel_histo();
        collected++;
        
        }
        
        if(showdist)
        {
        dist_histo();
        collected++;
        }
        
        
        if(showvcor)
        {
        vel_corr();
        collected++;
        
        }
        if(showxsq)
        {
        x_sq();
        collected++;
        
        }
        
         for (i=0;i<NATOMS;i++)
         {
         xp= ((xc[i]+BOXSIZE/2)*size/BOXSIZE);
         yp= ((yc[i]+BOXSIZE/2)*size/BOXSIZE);
         ir=(int) ((zc[i]+BOXSIZE/2)*10/BOXSIZE)+1;
        
         g.setColor(Color.red);
         g2.fill(new Ellipse2D.Double(xp-ir/2,yp-ir/2,ir,ir));
         }
        
        
        
        if (showhisto)
        {
        g.setColor(Color.black);    
        g.drawLine(1,500,NHISTO,500);
        g.drawString("Angstrom/psec",150,530);
        for(i=1;i<8;i++){ix=i*40;g.drawString(""+(i*40*vscale),ix-5,520);g.drawLine(ix,500,ix,510);}
        xp = Math.sqrt(2*TEMP_0 * 1.38 / (1.66 * mass));
        ix=(int)(xp/vscale);
        g.setColor(Color.green);
        g.drawLine(ix,500,ix,300);
         g.setColor(Color.black);    
        for (i=0;i<NHISTO;i++)
            
        {
         g.drawRect(i,500-20*histo[i]/collected,1,20*histo[i]/collected);
        
        }
        
        if (collected>=200) collected=0;
        }
        
         
        if (showdist)
        {
        g.setColor(Color.black);    
        g.drawLine(1,500,NHISTO,500);
        g.drawString("Angstrom",150,530);
        for(i=1;i<15;i++){ix=i*20;g.drawString(""+i,ix-5,520);g.drawLine(ix,500,ix,510);}
            
        for (i=0;i<NHISTO;i++)
            
        {yp=0.2*BOXSIZE*histo[i]/(collected); iy0=(int)yp;
         g.drawRect(i,500-iy0,1,iy0);
        
        }
        
        if (collected>=200) collected=0;
        }
        
         if (showvcor)
        {
                   g.setColor(Color.blue); 
        for (i=1;i<collected;i++)
            
            
     
        {if((corrf[0]>0.0) && (i>0))
         g.drawLine(i-1,510-(int)(200*corrf[i-1]/corrf[0]),i,510-(int)(200*corrf[i]/corrf[0]));
         
        }
        g.setColor(Color.black);
        g.drawLine(1,510,NCORR,510);
        g.drawLine(1,310,NCORR,310);
        g.drawLine(1,510-(int)(200*Math.exp(-1.0)),NCORR,510-(int)(200*Math.exp(-1.0)));
        if (collected>=NCORR) {collected=0; coll2++;vv0=corrf[0];}
        
        if(coll2>1)
        {
        for (i=collected+1;i<NCORR;i++)
        {
        g.drawLine(i-1,510-(int)(200*corrf[i-1]/vv0),i,510-(int)(200*corrf[i]/vv0));
        
        }
        
        }
        
        
        tscale=TIMESTEP*loops_i;
        for(i=0;i<7;i++)
        {g.drawLine(1+i*50,510,1+i*50,310);
         
         g.drawString(""+df2.format(tscale*i*50),1+i*50,520);
        }
        g.drawString("psec",150,530);
        g.drawString("1.0", 320, 310);
        g.drawString("1/e", 320,510-(int)(200*Math.exp(-1.0)));
        }
        
        if (showxsq)
        {
        g.setColor(Color.blue); 
        
        for (i=1;i<collected;i++)
        g.drawLine(i-1,510-(int)(0.3*corrf[i-1]/(coll2*NATOMS)),i,510-(int)(0.3*corrf[i]/(coll2*NATOMS)));
         
        if(coll2>1)
        {
        for(i=collected+1;i<NCORR;i++)    
        g.drawLine(i-1,510-(int)(0.3*corrf[i-1]/((coll2-1)*NATOMS)),i,510-(int)(0.3*corrf[i]/((coll2-1)*NATOMS)));
        }
        g.drawOval(collected-1,510-(int)(0.3*corrf[collected-1]/(coll2*NATOMS)),3,3);
        
       
        g.setColor(Color.black);
        g.drawLine(1,510,NCORR,510);
        g.drawLine(1,310,NCORR,310);
        
        if (collected>=NCORR) {collected=0; coll2++;}
        
        tscale=TIMESTEP*loops_i;
        for(i=0;i<7;i++)
        {g.drawLine(1+i*50,510,1+i*50,310);
         
         g.drawString(""+df2.format(tscale*i*50),1+i*50,520);
        }
        g.drawString("psec",150,530);
        
        ix5=510-(int)(0.3*25);
        ix10=510-(int)(0.3*100);
        ix15=510-(int)(0.3*225);
        ix20=510-(int)(0.3*400);
        ix25=510-(int)(0.3*625);
        
        g.drawString("(5A)^2",305,ix5);
        g.drawString("(10A)^2",305,ix10);
        g.drawString("(15A)^2",305,ix15);
        g.drawString("(20A)^2",305,ix20);
        g.drawString("(25A)^2",305,ix25);
        
        g.drawLine(1,ix5,NCORR,ix5);
          g.drawLine(1,ix10,NCORR,ix10);
          g.drawLine(1,ix15,NCORR,ix15); 
          g.drawLine(1,ix20,NCORR,ix20); 
          g.drawLine(1,ix25,NCORR,ix25);
        
        }
        
        
        jLabel1.setText("T="+df1.format(temper));
        
        
        jLabel2.setText("Virial="+df.format(virav/(3*count1)));
        jLabel3.setText("p="+df.format(pressav/count1));
        jLabel4.setText("pV="+df.format(vmol*pressav/count1));
        jLabel5.setText("kT="+df.format(ktav/count1));
        jLabel6.setText("rho="+df1.format(densty));
        jLabel7.setText("pvs="+df.format(pvs));
        jLabel8.setText("ETOT="+df.format(etot));
        jLabel9.setText("TIME="+df1.format(ttime));
         jLabel10.setText("EKIN="+df.format(ekin));
         jLabel11.setText("EPOT="+df.format(epot));
        
          jLabel14.setText("count1="+collected);
          jLabel15.setText("count2="+coll2);
 
        
        }
    }
}
     
     
     
