/*
 * poissonapplet.java
 *
 * Created on 22. März 2008, 11:48
 */

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  poj
 */
public class poissonapplet extends javax.swing.JApplet
        implements ActionListener {

    DecimalFormat df, df1;
    Timer timer;
    Thread calculatorThread;
    Graphics2D gb;
    BufferedImage image;
    int NMAX = 100;
    int NSIZE = 100;
    double grid0 = 0.1;    /*Angstrom*/

    double grid;
    double DK = 80.0;
    double kappa = 0.0;
    double omega = 1.8;
    double radius = 0.25;
    double[][][] U;
    double[][][] eps;
    double[][][] qg;
    int[][][] inside;
    double[] maxdev;
    double[] uzer;
    double csum, vol, r, fac, su, se, smax, e000, e100, e010, e001, em100, e0m10, e00m1;
    int ipp, loop, i_m, j_m, k_m, i, j, k, l, m, n, imax, i1, jj1, k1;
    double x, y, z, dx, dy, dz, q, shielding, hscale;
    int initial = 0;

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

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


        timer = new Timer(10, this);
        timer.setInitialDelay(10);
        timer.start();


    }

    public void actionPerformed(ActionEvent e) {

        if ((loop > 1000)) {
            return;
        }

        iterate();
        //draw();
        timer.setInitialDelay(1);
        timer.setDelay(1);
        timer.restart();

    }

    /** 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();
        jLabel1 = new javax.swing.JLabel();
        jButton1 = new javax.swing.JButton();
        jSlider1 = new javax.swing.JSlider();
        jSlider2 = new javax.swing.JSlider();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jSlider3 = new javax.swing.JSlider();
        jLabel4 = new javax.swing.JLabel();
        jSlider4 = new javax.swing.JSlider();
        jComboBox1 = new javax.swing.JComboBox();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTextArea1 = new javax.swing.JTextArea();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();

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

        jLabel1.setText("NSIZE");

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

        jSlider1.setMaximum(800);
        jSlider1.setMinimum(10);
        jSlider1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                jSlider1MouseReleased(evt);
            }
        });
        jSlider1.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                jSlider1MouseDragged(evt);
            }
        });

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

        jLabel2.setText("jLabel2");

        jLabel3.setText("jLabel3");

        jSlider3.setMaximum(200);
        jSlider3.setMinimum(100);
        jSlider3.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                jSlider3MouseReleased(evt);
            }
        });
        jSlider3.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                jSlider3MouseDragged(evt);
            }
        });

        jLabel4.setText("jLabel3");

        jSlider4.setMajorTickSpacing(20);
        jSlider4.setMinimum(20);
        jSlider4.setMinorTickSpacing(10);
        jSlider4.setPaintLabels(true);
        jSlider4.setPaintTicks(true);
        jSlider4.setSnapToTicks(true);
        jSlider4.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                jSlider4MouseReleased(evt);
            }
        });
        jSlider4.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                jSlider4MouseDragged(evt);
            }
        });

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

        jTextArea1.setColumns(20);
        jTextArea1.setRows(5);
        jScrollPane1.setViewportView(jTextArea1);

        jLabel5.setText("jLabel5");

        jLabel6.setText("initial values:");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGap(21, 21, 21)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 261, Short.MAX_VALUE)
                            .addComponent(jLabel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addGroup(layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addGroup(layout.createSequentialGroup()
                                        .addGap(109, 109, 109)
                                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                            .addComponent(jButton1)
                                            .addComponent(jLabel2)))
                                    .addGroup(layout.createSequentialGroup()
                                        .addGap(110, 110, 110)
                                        .addComponent(jLabel3))
                                    .addGroup(layout.createSequentialGroup()
                                        .addGap(114, 114, 114)
                                        .addComponent(jLabel4))
                                    .addGroup(layout.createSequentialGroup()
                                        .addGap(54, 54, 54)
                                        .addComponent(jSlider4, javax.swing.GroupLayout.PREFERRED_SIZE, 159, javax.swing.GroupLayout.PREFERRED_SIZE))
                                    .addGroup(layout.createSequentialGroup()
                                        .addGap(62, 62, 62)
                                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                            .addComponent(jSlider2, javax.swing.GroupLayout.PREFERRED_SIZE, 159, javax.swing.GroupLayout.PREFERRED_SIZE)
                                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                                .addComponent(jSlider1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 159, Short.MAX_VALUE)
                                                .addComponent(jSlider3, javax.swing.GroupLayout.Alignment.TRAILING, 0, 0, Short.MAX_VALUE))
                                            .addGroup(layout.createSequentialGroup()
                                                .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 97, javax.swing.GroupLayout.PREFERRED_SIZE)
                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(118, 118, 118)
                        .addComponent(jLabel1)))
                .addContainerGap(308, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(21, 21, 21)
                .addComponent(jButton1)
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(27, 27, 27)
                        .addComponent(jLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(26, 26, 26)
                        .addComponent(jLabel3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jSlider2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(jLabel4)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jSlider3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(32, 32, 32)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel6))
                        .addGap(34, 34, 34)
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jSlider4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(50, 50, 50)
                        .addComponent(jLabel5)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 116, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed

        reset();
        loop = 0;// TODO add your handling code here:
    }//GEN-LAST:event_jButton1ActionPerformed

    private void jSlider1MouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jSlider1MouseDragged

        jLabel2.setText("DK=" + df.format(jSlider1.getValue() * 0.1));// TODO add your handling code here:
    }//GEN-LAST:event_jSlider1MouseDragged

    private void jSlider1MouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jSlider1MouseReleased
        DK = jSlider1.getValue() * 0.1;

        reset();
        loop = 0;  // TODO add your handling code here:
    }//GEN-LAST:event_jSlider1MouseReleased

    private void jSlider2MouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jSlider2MouseReleased
        kappa = jSlider2.getValue() * 0.1;
        reset();

        loop = 0;
    // TODO add your handling code here:
    }//GEN-LAST:event_jSlider2MouseReleased

    private void jSlider3MouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jSlider3MouseReleased

        omega = jSlider3.getValue() * 0.01;
        reset();
    // TODO add your handling code here:
    }//GEN-LAST:event_jSlider3MouseReleased

    private void jSlider2MouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jSlider2MouseDragged
        jLabel3.setText("kappa=" + df.format(jSlider2.getValue() * 0.1));
    // TODO add your handling code here:
    }//GEN-LAST:event_jSlider2MouseDragged

    private void jSlider3MouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jSlider3MouseDragged
        jLabel4.setText("omega=" + df.format(jSlider3.getValue() * 0.01)); // TODO add your handling code here:
    }//GEN-LAST:event_jSlider3MouseDragged

    private void jSlider4MouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jSlider4MouseReleased
        NSIZE = jSlider4.getValue();
        reset();
        loop = 0;
    // TODO add your handling code here:
    }//GEN-LAST:event_jSlider4MouseReleased

    private void jSlider4MouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jSlider4MouseDragged
    // TODO add your handling code here:
    }//GEN-LAST:event_jSlider4MouseDragged

    private void jComboBox1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jComboBox1ActionPerformed
        initial = jComboBox1.getSelectedIndex();  // TODO add your handling code here:
    }//GEN-LAST:event_jComboBox1ActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JComboBox jComboBox1;
    private javax.swing.JLabel jLabel1;
    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.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JSlider jSlider1;
    private javax.swing.JSlider jSlider2;
    private javax.swing.JSlider jSlider3;
    private javax.swing.JSlider jSlider4;
    private javax.swing.JTextArea jTextArea1;
    // End of variables declaration//GEN-END:variables
    void init_variables() {
        int i, j, k;
        U = new double[NMAX][NMAX][NMAX];
        eps = new double[NMAX][NMAX][NMAX];
        qg = new double[NMAX][NMAX][NMAX];
        inside = new int[NMAX][NMAX][NMAX];
        uzer = new double[NMAX];
        maxdev = new double[1000];
        image =
                new BufferedImage(550, 650, BufferedImage.TYPE_INT_RGB);
        gb = (Graphics2D) image.createGraphics();
        gb.setBackground(Color.white);
        gb.clearRect(0, 0, 550, 650);
        df = new DecimalFormat("##.00");
        jSlider2.setValue((int) (10 * kappa));
        jLabel3.setText("kappa=" + df.format(kappa));
        jSlider3.setValue((int) (omega * 100));
        jLabel4.setText("omega=" + df.format(omega));
        jSlider1.setValue((int) (10 * DK));
        jLabel2.setText("DK=" + df.format(DK));
        jSlider4.setValue(NSIZE);


    }

    void reset() {
        set_variables();
        sphere12();
        if (initial == 1) {
            estimate();
        } else {
            initialzero();
        }
        loop = 0;
        smax = 1;
    }

    void set_variables() {

        hscale = 500.0 / NSIZE;
        grid = grid0 * hscale * 0.1;
        jLabel1.setText("NSIZE , grid=" + df.format(grid));
        fac = 1.0E10 * 1.602176E-19 / (8.8542E-12 * grid);


        shielding = kappa * kappa * grid * grid;


        for (i = 0; i < NSIZE; i++) {
            for (j = 0; j < NSIZE; j++) {
                for (k = 0; k < NSIZE; k++) {
                    U[i][j][k] = 0;
                    eps[i][j][k] = DK;
                    inside[i][j][k] = 0;
                    qg[l][j][k] = 0.0;
                }
            }
            smax = 1;
        }

        for (i = 0; i < 1000; i++) {
            maxdev[i] = 1.0;
        }


    }
    
     void sphere12() {
        int imax2; double mind,maxd,dx,dy,dz,vol,dist,cellvol;
        int il,jl,kl,iv,nin,nout,nbound,nall,nreso,nsub;
        /* put one charged sphere  at the center */

        /* position of the center grid point */

        l = (int) (NSIZE / 2);
        j = (int) (NSIZE / 2);
        k = (int) (NSIZE / 2);

        cellvol=(4.0*Math.PI/3.0)*radius*radius*radius/(grid*grid*grid);
        
        nreso=21;

        //imax = (int) (radius / grid);
        //imax2 = (int) (radius * radius / (grid * grid));
        
        
        nin=0;
        nout=0;
        nbound=0;
        nall=0;

        for (i1 = 0; i1 < NSIZE; i1++) {
            for (jj1 = 0; jj1 < NSIZE; jj1++) {
                for (k1 = 0; k1 < NSIZE; k1++) {
                    
                    dx=(Math.abs(i1-l)+0.5)*grid;
                    dy=(Math.abs(jj1-j)+0.5)*grid;
                    dz=(Math.abs(k1-k)+0.5)*grid;
                    
                    maxd=Math.sqrt(dx*dx+dy*dy+dz*dz);
                    
                    
                    dx=(Math.abs(i1-l)-0.5)*grid;
                    dy=(Math.abs(jj1-j)-0.5)*grid;
                    dz=(Math.abs(k1-k)-0.5)*grid;
                    
                    mind=Math.sqrt(dx*dx+dy*dy+dz*dz);
                    
                    
                   
                    
                   
                     if(maxd<=radius){
                     // fully inside
                         // jTextArea1.append(""+i1+"  "+jj1+"  "+k1+"  "+mind+" "+maxd+"\n");
                            inside[i1][jj1][ k1] = 1;
                            eps[i1][jj1][k1] = 1.0;
                            qg[i1][jj1][ k1] = 1.0/cellvol;
                            nin++;
                        }
                     
                     if( (mind<=radius) && (maxd>radius)){
                      // partially inside      
                         iv=0;
                         // calculate occupied volume
                         for(il=0;il<nreso;il++)for(jl=0;jl<nreso;jl++)for(kl=0;kl<nreso;kl++)
                         {
                          nsub=(nreso-1)/2;
                          dx=(i1-l)*grid+(il-nsub)*grid/nreso;
                          dy=(jj1-j)*grid+(jl-nsub)*grid/nreso;
                          dz=(k1-k)*grid+(kl-nsub)*grid/nreso;
                          
                          dist=Math.sqrt(dx*dx+dy*dy+dz*dz);
                          if(dist<=radius) iv++;
                        
                         
                         }
                         vol=iv/(double)(nreso*nreso*nreso);//1331.0;
                         //jTextArea1.append(""+i1+"  "+jj1+"  "+k1+"  "+mind+" "+maxd+" "+vol+"\n");
                         
                            inside[i1][jj1][ k1] = 1;
                           // eps[i1][jj1][ k1] = vol+(1.0-vol)*DK;
                           eps[i1][jj1][ k1] =1./(vol+(1.-vol)/DK);
                           qg[i1][jj1][k1] = vol/cellvol;
                      
                           nbound++;
                         
                     }
                     
                      if(mind>radius){
                     // fully outside
                        
                            inside[i1][jj1][ k1] = 0;
                            eps[i1][jj1][ k1] = DK;
                            qg[i1][jj1][k1] = 0.0;
                            nout++;
                        }
                     nall++;
                    }
                }
            }
        
        jTextArea1.setText("");
        jTextArea1.append("radius of sphere:"+radius+"\n"+"cells:"+nall+"\n"+"inside: "+nin+"\n"
          +"boundary: "+nbound+"\n"+  "outside: "+nout+"\n");



        /* normalizecharge */

        csum = 0.0;
        for (i = 0; i < NSIZE; i++) {
            for (j = 0; j < NSIZE; j++) {
                for (k = 0; k < NSIZE; k++) {
                    csum = csum + qg[i][j][k];
                }
            }
        }
        jTextArea1.append("total charge "+csum+"\n");
        
        /*
        for (i = 0; i < NSIZE; i++) {
            for (j = 0; j < NSIZE; j++) {
                for (k = 0; k < NSIZE; k++) {
                    qg[i][j][k] = qg[i][j][k] / csum;
                }
            }
        }
         */

    }

    void sphere() {
        int imax2;
        /* put one charged sphere  at the center */



        l = (int) (NSIZE / 2);
        j = (int) (NSIZE / 2);
        k = (int) (NSIZE / 2);



        imax = (int) (radius / grid);
        imax2 = (int) (radius * radius / (grid * grid));

        for (i1 = -imax; i1 < imax + 1; i1++) {
            for (jj1 = -imax; jj1 < imax + 1; jj1++) {
                for (k1 = -imax; k1 < imax + 1; k1++) {
                    if ((i1 * i1 + jj1 * jj1 + k1 * k1) <= (imax2)) {

                        if (((l + i1) >= 0) && ((l + i1) < NSIZE) && ((j + jj1) >= 0) &&
                                ((j + 1) < NSIZE) && ((k + k1) >= 0) && ((k + k1) < NSIZE)) {
                            inside[l + i1][j + jj1][k + k1] = 1;
                            eps[l + i1][j + jj1][k + k1] = 1.0;
                            qg[l + i1][j + jj1][k + k1] = 1.0;
                        }
                    }
                }
            }
        }



        /* normalizecharge */

        csum = 0.0;
        for (i = 0; i < NSIZE; i++) {
            for (j = 0; j < NSIZE; j++) {
                for (k = 0; k < NSIZE; k++) {
                    csum = csum + qg[i][j][k];
                }
            }
        }
        for (i = 0; i < NSIZE; i++) {
            for (j = 0; j < NSIZE; j++) {
                for (k = 0; k < NSIZE; k++) {
                    qg[i][j][k] = qg[i][j][k] / csum;
                }
            }
        }


    }

    void initialzero() {
        for (i = 0; i < NSIZE; i++) {
            uzer[i] = 0;
            for (j = 0; j < NSIZE; j++) {
                for (k = 0; k < NSIZE; k++) {

                    U[i][j][k] = 0;
                }
            }
        }
    }

    void estimate() {
        double V0, erad;
        erad = radius;
        V0 = 7.2 * (DK * kappa * erad + DK + 2) / (DK * erad * (1 + kappa * erad));

        /* estimate solution  */

        for (i = 0; i < NSIZE; i++) {
            for (j = 0; j < NSIZE; j++) {
                for (k = 0; k < NSIZE; k++) {
                    x = grid * (i - NSIZE / 2);
                    y = grid * (j - NSIZE / 2);
                    z = grid * (k - NSIZE / 2);

                    r = Math.sqrt(x * x + y * y + z * z);

                    if (r < erad) {
                        U[i][j][k] = V0 - 7.2 * r * r / (erad * erad * erad);
                    } else {
                        U[i][j][k] = 14.4 * Math.exp(kappa * (erad - r)) / (DK * r * (1 + kappa * erad));
                    }
                }
            }
        }

        for (i = 0; i < NSIZE; i++) {
            uzer[i] = U[i][NSIZE / 2][NSIZE / 2];
        }
    }

    void iterate() {
        int iy0, iy1,ixzer,idx;
        double esum,s1,s2,s3,s4,s5,s6,em,e200,e020,e002;
        Graphics g = jPanel1.getGraphics();

        Graphics2D g2 = (Graphics2D) g;

        if (loop < 999) {
            smax = 0.0;

            for (i = 1; i < NSIZE - 1; i++) {
                for (j = 1; j < NSIZE - 1; j++) {
                    for (k = 1; k < NSIZE - 1; k++) {

                     
                        e000 = eps[i][j][k];
                        
 /*  first edition of the book
  * 
                        e100 = 0.5 * (eps[i + 1][j][k] + e000);
                        em100 = 0.5 * (eps[i - 1][j][k] + e000);
                        e010 = 0.5 * (eps[i][j + 1][k] + e000);
                        e0m10 = 0.5 * (eps[i][j - 1][k] + e000);
                        e001 = 0.5 * (eps[i][j][k + 1] + e000);
                        e00m1 = 0.5 * (eps[i][j][k - 1] + e000);

                        su = qg[i][j][k] * fac + (U[i + 1][j][k] * e100 + U[i][j + 1][k] * e010 + U[i][j][k + 1] * e001 + U[i - 1][j][k] * em100 + U[i][j - 1][k] * e0m10 + U[i][j][k - 1] * e00m1);

                        esum = e100 + e010 + e001 + em100 + e0m10 + e00m1;

                        if (inside[i][j][k] == 1) {
                            su = su / esum;
                        } else {
                            su = su / (esum + e000 * shielding);
                        }
*/       
                        su = qg[i][j][k] * fac;
                        e100 = 2 * (eps[i + 1][j][k] * eps[i][j][k]) / (eps[i + 1][j][k] + eps[i][j][k]);
                        s1 = U[i + 1][j][k] * e100;
                        e200 = 2 * (eps[i - 1][j][k] * eps[i][j][k]) / (eps[i - 1][j][k] + eps[i][j][k]);
                        s2 = U[i - 1][j][k] * e200;
                        e010 = 2 * (eps[i][j + 1][k] * eps[i][j][k]) / (eps[i][j + 1][k] + eps[i][j][k]);
                        s3 = U[i][j + 1][k] * e010;
                        e020 = 2 * (eps[i][j - 1][k] * eps[i][j][k]) / (eps[i][j - 1][k] + eps[i][j][k]);
                        s4 = U[i][j - 1][k] * e020;
                        e001 = 2 * (eps[i][j][k + 1] * eps[i][j][k]) / (eps[i][j][k + 1] + eps[i][j][k]);
                        s5 = U[i][j][k + 1] * e001;
                        e002 = 2 * (eps[i][j][k - 1] * eps[i][j][k]) / (eps[i][j][k - 1] + eps[i][j][k]);
                        s6 = U[i][j][k - 1] * e002;

                        em = e100 + e200 + e010 + e020 + e001 + e002;
	                su=(su+s1+s2+s3+s4+s5+s6)/em;

                        if (Math.abs(U[i][j][k] - su) > smax) {
                            i_m = i;
                            j_m = j;
                            k_m = k;
                            smax = Math.abs(U[i][j][k] - su);
                        }


                        U[i][j][k] = omega * su + (1.0 - omega) * U[i][j][k];

                    }
                }
            }

            maxdev[loop] = smax;
            
            
              csum=0.0;
    for(i=1;i<NSIZE-1;i++)  for(j=1;j<NSIZE-1;j++)  for(k=1;k<NSIZE-1;k++)
      csum=csum+U[i][j][k]*qg[i][j][k];


    jLabel5.setText("Energy: "+(csum*0.5));



            loop++;
            gb.setBackground(Color.white);
            gb.clearRect(0, 0, 550, 650);
            
            gb.setColor(Color.black);
            gb.drawString("x",400,330);
            gb.drawString("maximum potential change",10,330);
            gb.drawLine(0,300,400,300);
            
            
            
            for(i=0;i<=NSIZE/10;i++)
            {
            
            iy0= (int) (10*i*hscale);
            gb.drawLine(iy0,300,iy0,307);
            gb.drawString(""+(i*10),iy0-4,320);
            
            }
            
            for (i=0;i<NSIZE;i++)
            {
                iy0=(int) (i*hscale);
            gb.drawLine(iy0,300,iy0,304);
            
            }

            gb.setColor(Color.red);
            gb.drawString("red=potential",160,20);
            for (i = 1; i < NSIZE; i++) {
                iy0 = 300 - (int) (2 * U[i - 1][NSIZE / 2][NSIZE / 2]);
                iy1 = 300 - (int) (2 * U[i][NSIZE / 2][NSIZE / 2]);
                gb.drawLine((int) (hscale * i), iy0, (int) (hscale * (i + 1)), iy1);
            }

            gb.setColor(Color.blue);
            gb.drawString("blue=initial values",20,20);
            for (i = 1; i < NSIZE; i++) {
                iy0 = 300 - (int) (2 * uzer[i - 1]);
                iy1 = 300 - (int) (2 * uzer[i]);
                gb.drawLine((int) (hscale * i), iy0, (int) (hscale * (i + 1)), iy1);
            }

          
            
            gb.setColor(Color.green);
            
            for (i = 1; i < loop; i++) {
                if (maxdev[i] > 1.0E-15) {
                    gb.drawLine((int) (50 * Math.log(i)), (int) (350 - 5 * Math.log(maxdev[i - 1])),
                            (int) (50 * Math.log(i + 1)),
                            (int) (350 - 5 * Math.log(maxdev[i])));
                }
            }

            gb.setColor(Color.black);
            for (i = 1; i < 10; i++) {
                gb.drawLine((int) (50 * Math.log(10 * i)), 350, (int) (50 * Math.log(10 * i)), 500);
            }
            for (i = 1; i < 11; i++) {
                gb.drawLine((int) (50 * Math.log(100 * i)), 350, (int) (50 * Math.log(100 * i)), 500);
            }

            gb.drawLine(1, (int) (350 - 5 * Math.log(0.1)), 400, (int) (350 - 5 * Math.log(0.1)));
            gb.drawLine(1, (int) (350 - 5 * Math.log(0.001)), 400, (int) (350 - 5 * Math.log(0.001)));
            gb.drawLine(1, (int) (350 - 5 * Math.log(0.00001)), 400, (int) (350 - 5 * Math.log(0.00001)));
            gb.drawLine(1, (int) (350 - 5 * Math.log(0.0000001)), 400, (int) (350 - 5 * Math.log(0.0000001)));
            gb.drawLine(1, (int) (350 - 5 * Math.log(0.000000001)), 400, (int) (350 - 5 * Math.log(0.000000001)));
            gb.drawLine(1, (int) (350 - 5 * Math.log(0.00000000001)), 400, (int) (350 - 5 * Math.log(0.00000000001)));

            gb.drawString("10", (int) (50 * Math.log(10)) - 5, 510);
            gb.drawString("100", (int) (50 * Math.log(100)) - 5, 510);
            gb.drawString("1000", (int) (50 * Math.log(1000)) - 5, 510);
            gb.drawString("iterations", 200, 520);


            gb.drawString("10^-3", 420, (int) (350 - 5 * Math.log(0.001)));
            gb.drawString("10^-7", 420, (int) (350 - 5 * Math.log(0.0000001)));
            gb.drawString("10^-11", 420, (int) (350 - 5 * Math.log(0.00000000001)));

            g2.drawImage(image, 0, 0, null);
        }
    }

    //for (i = 0; i < NSIZE; i++) {
    //  fprintf(fp, " %f  %e \n", i * grid, U[i][NSIZE / 2][NSIZE / 2]);
    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);



        }
    }
}
