import java.applet.*;
import java.awt.*;
import java.util.Date;

//******************************************
public class Fig051 extends Contour
//******************************************
{
	int mode_pcon=1;
	double Omega=1.6;
	int m=10,n=10,f_max=m;
	CheckboxGroup chkbox_group;
	Checkbox[] chkboxes;
//========================================== 
  public  Fig051()
//==========================================
  {
	  super(600,500,30.,-5.,-9.);
  }
//==========================================
	public void init()
//==========================================
	{

		chkbox_group = new CheckboxGroup();
		chkboxes = new Checkbox[2];
		chkboxes[0]=  new Checkbox("Turbo",chkbox_group,true);
		chkboxes[0].reshape(  350,30, 80, 15 );
		add(chkboxes[0]);
		chkboxes[1]=  new Checkbox("Normal with graphics",chkbox_group,false);
		chkboxes[1].reshape(  350,345, 80, 15 );
		add(chkboxes[1]);
	}
//==========================================
  public boolean handleEvent( Event event )
//==========================================
  {
	if(event.id == Event.ACTION_EVENT)
	{
		if(event.target==chkboxes[0])mode_pcon=1;
		else mode_pcon=0;
        repaint();
        return true;
	}

	return super.handleEvent( event );
  }
//==========================================
public void paint(Graphics g)
//==========================================
{
	double	T[][]		=new double[20][20],
			Buf[][]		=new double[20][20],
			x2dim[][]	=new double[20][20],
			y2dim[][]	=new double[20][20];
	char 	flg2dim[][]	=new char[20][20];
	double	setlvl[]=new double[21];
	int		stclr[]=new int[21],
			stlsy[]=new int[21];
	int		NLevel=15;

	int		xdim=n+1,
			ydim=n+1,
			vdim=f_max+1;

	double	r=1.e-4,error=1.0;
	double	North=0.,South=0.,West=0.,East=1.;

	int		i,j,Loop=0,Iteration;
	long	Start_time;

	double	R0=10.,r0=5.;

	g.drawString("Fig051", 10, 20);
	symbol(g,0.,-2.,"Laplace's Partial Differential Equation");
	g.drawString("Solution by SOR(Successive OverRelaxation)", 10, 40);

	g.drawString("Size x=" + m ,  10 , 50 );
	g.drawString("Size y=" + n , 150 , 50 );

	Date starttime= new Date();
	Start_time=starttime.getMinutes()*60+starttime.getSeconds();
	g.drawString("Omega="+String.valueOf(Omega), 10, 60);
	g.drawString("Conv. radius(abs)="+String.valueOf(r), 10, 70);

	number(g,-.2,n/2.,.5,West,90.,2);
	number(g,m+1.,n/2.,.5,East,90.,2);
	number(g,m/2.,n+.2,.5,North,0.,2);
	number(g,m/2.,-1.,.5,South,0.,2);

	for(i=0;i<=m;i++)
	{
		for(j=0;j<=n;j++)
		{
			x2dim[i][j]=(r0+r0*i/m)*Math.cos(90./n*j*Math.PI/180.);
			y2dim[i][j]=(r0+r0*i/m)*Math.sin(90./n*j*Math.PI/180.);
			flg2dim[i][j]='F';
		}
	}

	for(i=0;i<=NLevel;i++)
	{
		setlvl[i]=(double)i/(double)NLevel;
		stclr[i]=i*255/NLevel;
	}

	SetColorTable(stclr,NLevel);
	SetLevelTable(setlvl,NLevel);
	Indexdraw(g,-5.,-0.,-4.,9.);

// Boundary setting
	for(i=0;i<=m;i++)
	{
		T[i][0]=Buf[i][0]=South;
		T[i][n]=Buf[i][n]=North;
		x2dim[i][0]=r0+(R0-r0)/m*i;
		y2dim[i][0]=0.;
		x2dim[i][n]=0.;
		y2dim[i][n]=r0+(R0-r0)/m*i;
	}
	for(j=0;j<=n;j++)
	{
		T[0][j]=Buf[0][j]=West;
		T[m][j]=Buf[m][j]=East;
		x2dim[0][j]=r0*Math.cos(90./n*j*Math.PI/180.);
		y2dim[0][j]=r0*Math.sin(90./n*j*Math.PI/180.);
		if(j<=n/2)
		{
			x2dim[m][j]=R0;
			y2dim[m][j]=2.*R0/n*j;
		}
		else
		{
			x2dim[m][j]=2.*R0-2.*R0/n*j;
			y2dim[m][j]=R0;
		}
	}

	ContourSet(g,1,x2dim,y2dim, T, flg2dim, m,n);

// Iteration loop
	Loop=0;error=1.0;
	double Alpha;
	error=1.;
//	for(Loop=0;Loop<100;Loop++){
	while(error>r){		
		error=0.0;
		for(i=1;i<=m-1;i++)
		{
			for(j=1;j<=n-1;j++)
			{
				Alpha=Omega*(0.25*(x2dim[i-1][j]+x2dim[i][j-1]+
					x2dim[i+1][j]+x2dim[i][j+1])-x2dim[i][j]);
				error+=Math.abs(Alpha);
				x2dim[i][j]+=Alpha;
			}
		}
	}
//	}
	error=1.;
//	for(Loop=0;Loop<100;Loop++){
	while(error>r){		
		error=0.0;
		for(i=1;i<=m-1;i++)
		{
			for(j=1;j<=n-1;j++)
			{
				Alpha=Omega*(0.25*(y2dim[i-1][j]+y2dim[i][j-1]+
					y2dim[i+1][j]+y2dim[i][j+1])-y2dim[i][j]);
				error+=Math.abs(Alpha);
				y2dim[i][j]+=Alpha;
			}
		}
	}
//	}
	error=1.;
	while(error>r){		
		error=0.0;
		for(i=1;i<=m-1;i++)
		{
			for(j=1;j<=n-1;j++)
			{
				Buf[i][j]=T[i][j]+
					Omega*(0.25*(Buf[i-1][j]+Buf[i][j-1]+
					T[i+1][j]+T[i][j+1])-T[i][j]);
				error+=Math.abs(Buf[i][j]-T[i][j]);
			}
		}
		for(i=1;i<=m-1;i++)
		{
			for(j=1;j<=n-1;j++)
			{
				T[i][j]=Buf[i][j];
			}
		}
		Loop++;
		if(mode_pcon!=1)
		{
			ContourSet(g,-1,x2dim,y2dim, T, flg2dim	,m,n);
		}
	}

	Date endtime= new Date();
	long elapse=endtime.getMinutes()*60+endtime.getSeconds()-
		Start_time;
	double Etime=(double)elapse;

	g.drawString("Elapse time:  "+ 	Etime +"  sec", 10, 90);
	
	g.drawString("Converged at loop  " + Loop, 10, 100);

	ContourSet(g,1,x2dim,y2dim, T, flg2dim, m,n);
}
//==========================================
public void ContourSet(Graphics g,int mode,
			double[][] x,double[][] y,double[][] f,
			char[][] flg,
			int m,int n)
//==========================================
{
	g.setColor(Color.white);
	f_rect(g,0.,0.,(double)(m),(double)(n));
	g.setColor(Color.red);
	mshplt(g, 0,1,x,y,flg,m,n,0.,0.);
	contdraw(g,mode,x, y, f,flg,m,n);
}
//==========================================	
void SetColorTable(int[] stclr,int lvl)
//==========================================	
{
	NPattern=lvl;
	for(int i=0;i<=NPattern;i++)
	{
		ColorPattern[i]=new Color(
			stclr[i],
			127-stclr[i]/2,
			127-stclr[i]/2);
	}
}
//==========================================
}
