import java.awt.*;
import java.applet.*;
import java.lang.Math;
/**
* An interactive demo of the Extended Simplified Theory
* plotting temperature, oxygen, and fuel mass fraction as
* well as the flame location. Input corresponds to Excel
* spreadsheet format.  Can be run either as a standalone 
* application or as an applet in the AppletViewer.
*
*    Written by: Jeff West
*     Rev. Date: March 14, 1996
* Dev. Platform: Win 95 using Jpad editor on 486DX2-66 8MB RAM
*
*  Send comments/suggestions to jwest@voyager3.sdsu.edu
* <a href="mailto:jwest@voyager3.sdsu.edu">"jwest@voyager3.sdsu.edu"</a>
*/
public class ExtSimpTheory extends Applet {
	EstControls controls;
	EstOutput   output;
    
	public void init() {
		setLayout(new BorderLayout());
		DataSheet data = new DataSheet();
		add("South", output = new EstOutput(data));
		EstCanvas c = new EstCanvas(data,output);
		add("Center", c);
		add("North", controls = new EstControls(c,data,output));

	}

	public void start() {
		controls.enable();
	}

	public void stop() {
		controls.disable();
	}

	public boolean handleEvent(Event e) {
		if (e.id == Event.WINDOW_DESTROY) {
			System.exit(0);
		}
		return false;
	}

	public static void main(String args[]) {
		Frame f = new Frame("ExtSimpTheory");
		ExtSimpTheory extSimpTheory = new ExtSimpTheory();

		extSimpTheory.init();
		extSimpTheory.start();

		f.add("Center", extSimpTheory);
		f.resize(300, 300);
		f.show();
	}
}
    

class EstCanvas extends Canvas {
	int		startAngle = 0;
	int		endAngle = 45;
	double      x;
	boolean	bNeedUpdate = false;
	Font	font;
	DataSheet   data;
	EstOutput   output;

	public EstCanvas( DataSheet data,EstOutput output) {
		this.data = data;
		this.output=output;
	}
	
	public void SetUpdate(boolean bstate) {
		bNeedUpdate=bstate;
		if(bNeedUpdate)
		{
			redraw();
		}
	}
	
    
	public void paint(Graphics g) {
		Rectangle r = bounds();
		Point ptold = new Point(0,0) , ptnew = new Point(0,0);
		Point ptold1 = new Point(0,0) , ptnew1 = new Point(0,0);
		double hlines,vlines; // pixels per unit of window
		double deltav,deltah,vlabel;
		double dreturn,dreturn1,valmax;
		double xmin,xmax,ymin,ymax;
		double lgas;  // in mm
		boolean bdrawn=false; // a boolean used to draw tickmarks
		int xzero,yzero;

		if(bNeedUpdate)
		{
			font=new Font("Helvetica",Font.BOLD,16);
			g.setFont(font);
			g.setColor(Color.blue);
			g.drawString( "Input has changed! You need to hit the Draw button.",
					 r.width/4, r.height/2 ); 
			return;
		}

		lgas=data.GetLgas();    
		xmin=data.GetXmin();
		xmax=data.GetXmax();
		ymin=data.GetYmin();
		ymax=data.GetYmax();
		xzero=(int)(-1.*xmin/(xmax-xmin)*(double)r.width);
		yzero=r.height-(int)(-1.*ymin/(ymax-ymin)*(double)r.height);
		hlines=(double)r.height/(ymax-ymin); //pixels/mm
		vlines=(double)r.width /(xmax-xmin);
		deltav=vlines/2.;
		deltah=hlines/2.;

		font=new Font("Helvetica",Font.BOLD,11);
		g.setFont(font);
		if(data.GetT())
		{
			g.setColor(Color.red);
			valmax=data.GetTfmax();
			dreturn1=dreturn=1.;
			for(double val=1;val<valmax;val+=data.GetPhi())
			{
				ptold1.x=ptold.x=xzero;
				ptold1.y=ptold.y=yzero;
				for (int i =xzero+1; i <= r.width; i+=10) {
					ptnew.x = i ;
					ptnew1.x = i ;
					x=(ptnew.x-(double)xzero)/vlines;// in mm
					x=x/lgas; // now in Lg
					dreturn=data.GetTHeight(x,val);// returning in Lg units
					if(dreturn > 0.)
					{
						dreturn=dreturn*lgas;// now in mm		
						ptnew.y=yzero - (int)(hlines*dreturn);
						if(ptold.y<0){ptold.y=ptnew.y;ptold.x=ptnew.x;}
						g.drawLine(ptold.x, ptold.y, ptnew.x,ptnew.y);
						ptold.x=ptnew.x;
						ptold.y=ptnew.y;
					} else{
						ptold.x=ptnew.x;
						ptold.y=-1;
					}
  
					dreturn1=data.GetTHeight(x,-1.*val);
					if(dreturn1 > 0.)
					{
						dreturn1=dreturn1*lgas;    			
						ptnew1.y=yzero - (int)(hlines*dreturn1);
						if(ptold1.y<0){ptold1.y=ptnew1.y;ptold1.x=ptnew1.x;}
						g.drawLine(ptold1.x, ptold1.y, ptnew1.x,ptnew1.y);
						ptold1.x=ptnew1.x;
						ptold1.y=ptnew1.y;
					} else{
						ptold1.x=ptnew1.x;
						ptold1.y=-1;
					}
  
				}
				g.setColor(Color.black);
				if(dreturn > 0.)
				{
					g.drawString( ""+val, r.width-20, ptnew.y ); 
				}
				if(dreturn1> 0.)
				{
					g.drawString( ""+val, r.width-20, ptnew1.y ); 
				}
				g.setColor(Color.red);
			}
			for(double val=1.2;val<4.0;val+=0.2)
			{
				ptold.x=xzero;
				ptold.y=yzero;
				for (int i = xzero+1; i <= r.width; i+=10) {
					ptnew.x = i ;
					x=(ptnew.x-(double)xzero)/vlines;
					x=x/lgas;
					ptnew.y=yzero + (int)(hlines*data.GetPhi3Height(x,val)*lgas);
					g.drawLine(ptold.x, ptold.y, ptnew.x,ptnew.y);
					ptold.x=ptnew.x;
					ptold.y=ptnew.y;
				}
				g.setColor(Color.black);
				g.drawString( ""+val, r.width-20, ptnew.y+10 ); 
				g.setColor(Color.red);
			}
		}
		if(data.GetYo())
		{
			g.setColor(Color.yellow);
			for(double val=0.;val<=1.0;val+=0.1)
			{
				ptold.x=xzero;
				ptold.y=yzero;
				bdrawn=false;
				for (int i = xzero+1; i <= r.width; i+=10) {
					ptnew.x = i ;
					x=(ptnew.x-(double)xzero)/vlines;
					x=x/lgas;
					dreturn=data.GetYoHeight(x,val);
					if(dreturn > 0.)
					{
						ptnew.y=yzero - (int)(hlines*dreturn*lgas);
						if(ptold.y<0){ptold.y=ptnew.y;}
						g.drawLine(ptold.x, ptold.y, ptnew.x,ptnew.y);
						if(!bdrawn&&(r.width-ptnew.x)<50){
							g.drawString(""+val,ptnew.x,ptnew.y-6);
							bdrawn=true;
						}
					}
					ptold.x=ptnew.x;
					ptold.y=ptnew.y;
				}
			}
		}
		if(data.GetYf())
		{
			g.setColor(Color.blue);
			for(double val=0.05;val<=1.5;val+=0.05)
			{
				ptold.x=xzero;
				ptold.y=yzero;
				bdrawn=false;
				for (int i = xzero+1; i <= r.width; i+=10) {
					ptnew.x = i ;
					x=(ptnew.x-(double)xzero)/vlines;
					x=x/lgas;
					dreturn=data.GetYfHeight(x,val);
					if(dreturn > 0.)
					{
						ptnew.y=yzero - (int)(hlines*dreturn*lgas);
						if(ptold.y<0.){ptold.y=ptnew.y;}
						g.drawLine(ptold.x, ptold.y, ptnew.x,ptnew.y);
						if(!bdrawn&&(r.width-ptnew.x)<90){
							g.drawString(""+val,ptnew.x,ptnew.y-6);
							bdrawn=true;
						}
						ptold.x=ptnew.x;
						ptold.y=ptnew.y;
					}
				}
			}
		}

		if(data.GetFlame())
		{
			g.setColor(Color.green);
			ptold.x=xzero;
			ptold.y=yzero;
			for (int i = xzero+1; i <= r.width; i+=10) {
				ptnew.x = i ;
				x=(ptnew.x-(double)xzero)/vlines;
				x=x/lgas;
				ptnew.y=yzero - (int)(hlines*data.GetFlameHeight(x)*lgas);
				g.drawLine(ptold.x, ptold.y, ptnew.x,ptnew.y);
				ptold.x=ptnew.x;
				ptold.y=ptnew.y;
			}
		}

		font=new Font("Helvetica",Font.BOLD,14);
		g.setFont(font);
		int sx = 10;
		int sy =(int)(0.1*(double)r.height);
		// draw the axes
		g.setColor(Color.black);
		g.drawLine(0, yzero, r.width, yzero);
		g.drawLine(xzero, 0, xzero, r.height);
		font=new Font("Helvetica",Font.BOLD,10);
		g.setFont(font);
		int iold=yzero;
		vlabel=0;
		bdrawn=true;
		for(int i=yzero;i<r.height;i++)
		{
			if((i-iold)>deltah){
				iold=i;
				vlabel-=deltah/hlines;
				if(bdrawn){
					g.drawLine(xzero-2, i, xzero+2, i);
					bdrawn=false;
				} else{
					g.drawLine(xzero-5, i, xzero+5, i);
					g.drawString( ""+vlabel, xzero-10, i ); 
					bdrawn=true;
				}
			}
		}
		iold=yzero;
		vlabel=0;
		bdrawn=true;
		for(int i=yzero;i>0;i--)
		{
			if((iold-i)>deltah){
				iold=i;
				vlabel+=deltah/hlines;
				if(bdrawn){
					g.drawLine(xzero-2, i, xzero+2, i);
					bdrawn=false;
				} else{
					g.drawLine(xzero-5, i, xzero+5, i);
					g.drawString( ""+vlabel, xzero-10, i ); 
					bdrawn=true;
				}
			}
		}
		g.drawString( "y, mm", xzero+10, 10 ); 
		vlabel=0;
		iold=xzero;
		bdrawn=true;
		for(int i=xzero;i>0;i--)
		{
			if((iold-i)>deltav){
				iold=i+1;
				vlabel-=deltav/vlines;
				if(bdrawn){
					g.drawLine(i,yzero-2,i, yzero+2);
					bdrawn=false;
				} else{
					g.drawLine(i,yzero-5,i, yzero+5);
					g.drawString( ""+vlabel, i,yzero+10 ); 
					bdrawn=true;
				}
			}
		}
		vlabel=0;
		iold=xzero;
		bdrawn=true;
		for(int i=xzero;i<r.width;i++)
		{
			if((i-iold)>deltav){
				iold=i+1;
				vlabel+=deltav/vlines;
				if(bdrawn){
					g.drawLine(i,yzero-2,i, yzero+2);
					bdrawn=false;
				} else{
					g.drawLine(i,yzero-5,i, yzero+5);
					g.drawString( ""+vlabel, i,yzero+10 ); 
					bdrawn=true;
				}
			}
		}
		g.drawString( "-x, mm", 10, yzero+20 ); 
	}

	public void redraw() {
		repaint();
	}
}

class EstControls extends Panel {
	TextField O2,P,Gravity,Vg,Tau,Tginf;
	TextField halfheight,Xdev,Chyd,Cbouy,Clift;
	Choice    Geometry;
	TextField TV,Tlam,Tmu,LamO2,LamN2,MuO2;
	TextField MuN2,Tprop,LamSolid,RhoSolid,Cgas,Csolid;
	TextField MWN2,S,Dhc,Dhv,Bg,Egas;
	TextField Phi,Xmin,Xmax,Ymin,Ymax;
	Checkbox  checkT,checkYo,checkYf,checkFlame;
	EstCanvas canvas;
	DataSheet data;
	EstOutput output;

	public EstControls(EstCanvas canvas, DataSheet data, EstOutput output) {
		this.canvas = canvas;
		this.data   = data;
		this.output = output;
		setLayout(new GridLayout(0,8));
		// first row
		add("Label",new Label("% Ox."));
		add("Label",new Label("P atm"));
		add("Label",new Label("Grav"));
		add("Label",new Label("Vg(cm/s)"));
		add("Label",new Label("Tau mm"));
		add("Label",new Label("Tg,inf K"));
		add("Label",new Label("h cm"));
		add("Label",new Label("xdev, mm"));
		add(O2 = new TextField(".5", 5)); 
		add(P = new TextField("1.0", 5)); 
		add(Gravity = new TextField("1.0", 5)); 
		add(Vg = new TextField("40", 5)); 
		add(Tau = new TextField("3.2", 5));
		add(Tginf = new TextField("298.", 5));
		add(halfheight = new TextField("2", 5)); 
		add(Xdev = new TextField("1.0", 5)); 
		// second row
		add("Label",new Label("Geometry"));
		add("Label",new Label("Chyd,EST"));
		add("Label",new Label("Cbuoy,EST"));
		add("Label",new Label("Clift,EST"));
		add("Label",new Label("Tv, K"));
		add("Label",new Label("Tlam, K"));
		add("Label",new Label("Trho, K"));
		add("Label",new Label("lamO2"));
		add(Geometry = new Choice());
		Geometry.addItem("FDC");
		Geometry.addItem("Devchan");
		Geometry.addItem("FP");
		Geometry.addItem("Buoyant");
		add(Chyd = new TextField("0.573", 5)); 
		add(Cbouy = new TextField("0.575", 5));
		add(Clift = new TextField("0.089.", 5));
		add(TV = new TextField("618.", 5)); 
		add(Tlam = new TextField("618.", 5)); 
		add(Tmu = new TextField("618.", 5)); 
		add(LamO2 = new TextField("0.054", 5)); 
		// 3
		add("Label",new Label("lamN2"));
		add("Label",new Label("muO2"));
		add("Label",new Label("muN2"));
		add("Label",new Label("T,prop, K"));
		add("Label",new Label("Lam_s"));
		add("Label",new Label("Rho_s"));
		add("Label",new Label("cg kJ/kgK"));
		add("Label",new Label("cs kJ/kgK"));

		add(LamN2 = new TextField("0.049", 5));
		add(MuO2 = new TextField("48.4", 5));
		add(MuN2 = new TextField("32.3", 5)); 
		add(Tprop = new TextField("700.", 5)); 
		add(LamSolid = new TextField("0.188", 5)); 
		add(RhoSolid = new TextField("1190.", 5)); 
		add(Cgas = new TextField("1.183", 5));
		add(Csolid = new TextField("1.465.", 5));
		// fourth row
		add("Label",new Label("MwN2"));
		add("Label",new Label("s"));
		add("Label",new Label("Dhc MJ/kg"));
		add("Label",new Label("Dhv MJ/kg"));
		add("Label",new Label("Bg m^3/kgs"));
		add("Label",new Label("Egas kJ/kmol"));
		add("Label",new Label("Draw Button"));
		add("Label",new Label("Contour Levels"));

		add(MWN2 = new TextField("28.0", 5)); 
		add(S = new TextField("1.92", 5)); 
		add(Dhc = new TextField("25.9", 5)); 
		add(Dhv = new TextField("0.941", 5)); 
		add(Bg = new TextField("8.93e7", 5));
		add(Egas = new TextField("88943.", 5));
		add(new Button("Draw"));
		add(Phi = new TextField("1.0", 5));
		// next
		add("Label",new Label("Xmin mm"));
		add("Label",new Label("Xmax mm"));
		add("Label",new Label("Ymin mm"));
		add("Label",new Label("Ymax mm"));
		add("Label",new Label("Temperature"));
		add("Label",new Label("Fuel"));
		add("Label",new Label("Oxygen"));
		add("Label",new Label("Flame"));

		add(Xmin = new TextField("-2", 5));
		add(Xmax = new TextField("10", 5));
		add(Ymin = new TextField("-3",5));
		add(Ymax = new TextField("8", 5));
		add(checkT = new Checkbox("T/Tinf"));
		checkT.setState(true);
		checkT.setBackground(Color.red);
		add(checkYf = new Checkbox("Yfuel"));
		checkYf.setBackground(Color.blue);
		add(checkYo = new Checkbox("Yoxygen"));
		checkYo.setBackground(Color.yellow);
		add(checkFlame = new Checkbox("y-flame"));
		checkFlame.setBackground(Color.green);



		// enable and disable by intial conditions
		Xdev.disable();
		GrabData();
	}

	public boolean action(Event ev, Object arg) {
		if (ev.target == checkT) 
		{
			if(data.GetT()){data.SetT(false);} else{data.SetT(true);}
			canvas.redraw();
			return true;
		}
		if (ev.target == checkYf) 
		{
			if(data.GetYf()){data.SetYf(false);} else{data.SetYf(true);}
			canvas.redraw();
			return true;
		}
		if (ev.target == checkYo) 
		{
			if(data.GetYo()){data.SetYo(false);} else{data.SetYo(true);}
			canvas.redraw();
			return true;
		}
		if (ev.target == checkFlame) 
		{
			if(data.GetFlame()){data.SetFlame(false);} else{data.SetFlame(true);}
			canvas.redraw();
			return true;
		}
		if (ev.target instanceof Choice) 
		{
			String choice = (String)arg;
			Gravity.disable();
			if (choice.equals("FDC"))	{
				Xdev.disable();
				halfheight.enable();
				data.SetGeometry(0);
			} else if (choice.equals("Devchan"))	{
				Xdev.enable();
				halfheight.enable();
				data.SetGeometry(1);
				System.out.println("set devchan mode!");
			} else if (choice.equals("FP")){
				Xdev.enable();
				halfheight.disable();
				data.SetGeometry(2);
			} else if (choice.equals("Buoyant"))			{
				Xdev.disable();
				halfheight.disable();
				Gravity.enable();
				data.SetGeometry(3);
			}
			
			data.CalculateBetas();
			output.UpdateFields();
			canvas.SetUpdate(false);
			canvas.redraw();
			return true;
		} // choice if

		if (ev.target instanceof Button) 	{
			GrabData();
			data.CalculateBetas();
			output.UpdateFields();
			canvas.SetUpdate(false);
			canvas.redraw();

			return true;
		}

		if (ev.target instanceof TextField) 	{
			canvas.SetUpdate(true);
			return true;
		}
		
		
		return false;
	}
	public void GrabData()
	{
		// first row
		//    TextField O2,P,Gravity,Vg,Tau,Tginf;
		data.SetO2( Double.valueOf(O2.getText().trim()).doubleValue() );
		data.SetP( Double.valueOf(P.getText().trim()).doubleValue() );
		data.SetGravity( Double.valueOf(Gravity.getText().trim()).doubleValue() );
		data.SetVg( Double.valueOf(Vg.getText().trim()).doubleValue() );
		data.SetTau( Double.valueOf(Tau.getText().trim()).doubleValue() );
		data.SetTginf( Double.valueOf(Tginf.getText().trim()).doubleValue() );
		// second row
		//    TextField halfheight,Xdev,Chyd,Cbouy,Clift;
		//    Choice    Geometry;
		data.Sethalfheight( Double.valueOf(halfheight.getText().trim()).doubleValue() );
		data.SetXdev( Double.valueOf(Xdev.getText().trim()).doubleValue() );
		data.SetChyd( Double.valueOf(Chyd.getText().trim()).doubleValue() );
		data.SetCbouy( Double.valueOf(Cbouy.getText().trim()).doubleValue() );
		data.SetClift( Double.valueOf(Clift.getText().trim()).doubleValue() );
		// third row
		//    TextField TV,Tlam,Tmu,LamO2,LamN2,MuO2;
		data.SetTv( Double.valueOf(TV.getText().trim()).doubleValue() );
		data.SetTlam( Double.valueOf(Tlam.getText().trim()).doubleValue() );
		data.SetTrho( Double.valueOf(Tmu.getText().trim()).doubleValue() );
		data.SetLamO2( Double.valueOf(LamO2.getText().trim()).doubleValue() );
		data.SetLamN2( Double.valueOf(LamN2.getText().trim()).doubleValue() );
		data.SetMuO2( Double.valueOf(MuO2.getText().trim()).doubleValue() );
		// fourth row
		//    TextField MuN2,Tprop,LamSolid,RhoSolid,Cgas,Csolid;
		data.SetMuN2( Double.valueOf(MuN2.getText().trim()).doubleValue() );
		data.SetTprop( Double.valueOf(Tprop.getText().trim()).doubleValue() );
		data.SetLamSolid( Double.valueOf(LamSolid.getText().trim()).doubleValue() );
		data.SetRhoSolid( Double.valueOf(RhoSolid.getText().trim()).doubleValue() );
		data.SetCgas( Double.valueOf(Cgas.getText().trim()).doubleValue() );
		data.SetCsolid( Double.valueOf(Csolid.getText().trim()).doubleValue() );
		// fifth row
		//    TextField MWN2,S,Dhc,Dhv,Bg,Egas;
		data.SetMWN2( Double.valueOf(MWN2.getText().trim()).doubleValue() );
		data.SetS( Double.valueOf(S.getText().trim()).doubleValue() );
		data.SetDhc( Double.valueOf(Dhc.getText().trim()).doubleValue() );
		data.SetDhv( Double.valueOf(Dhv.getText().trim()).doubleValue() );
		data.SetBg( Double.valueOf(Bg.getText().trim()).doubleValue() );
		data.SetEgas( Double.valueOf(Egas.getText().trim()).doubleValue() );
		// sixth row
		data.SetPhi(Double.valueOf(Phi.getText().trim()).doubleValue() );
		data.SetXmin(Double.valueOf(Xmin.getText().trim()).doubleValue() );
		data.SetXmax(Double.valueOf(Xmax.getText().trim()).doubleValue() );
		data.SetYmin(Double.valueOf(Ymin.getText().trim()).doubleValue() );
		data.SetYmax(Double.valueOf(Ymax.getText().trim()).doubleValue() );

	}
	
}
	
class  DataSheet {
	// derived parameters
	double beta1=0.278;
	double beta2=73.468;
	double beta3=2.073;
	double beta4=2.669;
	double beta5=5.595;
	double beta6=1201.348;
	//derived quantities
	double yox=1.,LamMix=0.054,AlphaGas=1e-6,Prno=1.,ReH=1.;
	double Chd=1.,Veq=0.1,Lgas=1.;
	double phi2flame,Gamlift,Tfest,Fest,Tfmax;
	double Eta,T,Vfestthk,Vfestthn;
	// in the spreadsheet
	double Kno=8.,Bno=8.,Tfadlin=10.,F=15.,Vf;
	double O2=0.5,P=1.,Gravity=1.0,Vg=0.4,Tau=0.0032,Tginf=298.;
	double halfheight=.02,Xdev=.001,Chyd=0.573,Cbouy=0.575,Clift=0.089;
	double Tv=618.,Tlam=618.,Trho=618.,LamO2=0.054,LamN2=0.049,MuO2=48.4;
	double MuN2=32.3,Tprop=700.,LamSolid=.188,RhoSolid=1190.,Cgas=1.183,Csolid=1.465;
	double MWN2=28.,S=1.92,Dhc=25.9,Dhv=0.941,Bg=8.928e7,Egas=88943.;
	// plotting variables
	double Phi=1.,Xmin=-10.,Xmax=10.,Ymin=-10.,Ymax=10.;
	boolean  bTemp=true,bYf=false,bYo=false,bFlame=false;
	// control variables
	int ngeometry=0;

	// class constructor
	public DataSheet(){CalculateBetas();}
	// control
	public void SetGeometry(int n) { ngeometry=n;}
	public boolean GetT() { return bTemp;}
	public void SetT(boolean b) { bTemp=b;}
	public boolean GetYf() { return bYf;}
	public void SetYf(boolean b) { bYf=b;}
	public boolean GetYo() { return bYo;}
	public void SetYo(boolean b) { bYo=b;}
	public boolean GetFlame() { return bFlame;}
	public void SetFlame(boolean b) { bFlame=b;}



	// Methods for data access
	public double GetBeta1() { return beta1;}
	public double GetBeta2() { return beta2;}
	public double GetBeta3() { return beta3;}
	public double GetBeta4() { return beta4;}
	public double GetBeta5() { return beta5;}
	public double GetBeta6() { return beta6;}
	public double GetK() { return Kno;}
	public double GetB() { return Bno;}
	public double GetF() { return F;}
	public double GetTv() { return Tv;}
	public double GetTginf() { return Tginf;}
	public double GetGamlift() { return Gamlift;}
	public double GetTfest() { return Tfest;}
	public double GetTfmax() { return Tfmax;}
	public double GetFest() { return Fest;}
	public double GetLgas() { return Lgas*1000.;}// returns in mm
	public double GetEta() { return Eta;}
	public double GetTndim() { return T;}
	public double GetTaucrit() { return 1000.*Tau/T;}


	// first row
	//    double O2=0.5,P=1.,Gravity=0.,Vg=1.,Tau=3.2,Tginf=298.;
	public void SetO2(double d) {O2=d;}
	public void SetP(double d) { P=d;}
	public void SetGravity(double d) {Gravity=d;}
	public void SetVg(double d) { Vg=d/100.;}
	public void SetTau(double d) { Tau=d/1000.;}
	public void SetTginf(double d) {Tginf=d;}
	// second row
	//    double halfheight=.02,Xdev=.01,Chyd=0.573,Cbouy=0.574,Clift=0.089;
	public void Sethalfheight(double d) {halfheight=d/100.;}
	public void SetXdev(double d) { Xdev=d/1000.;}
	public void SetChyd(double d) {Chyd=d;}
	public void SetCbouy(double d) { Cbouy=d;}
	public void SetClift(double d) { Clift=d;}
	// third row
	//  double Tv=618.,Tlam=298.,Tmu=298.,LamO2=0.054,LamN2=0.035,MuO2=48.4;
	public void SetTv(double d) {Tv=d;}
	public void SetTlam(double d) { Tlam=d;}
	public void SetTrho(double d) {Trho=d;}
	public void SetLamO2(double d) {LamO2=d;}
	public void SetLamN2(double d) { LamN2=d;}
	public void SetMuO2(double d) {MuO2=d;}
	// fourth row
	//    double MuN2=32.3,Tprop=700.,LamSolid=.188,RhoSolid=1190.,Cgas=1.183,Csolid=1.465;
	public void SetMuN2(double d) {MuN2=d;}
	public void SetTprop(double d) { Tprop=d;}
	public void SetLamSolid(double d) {LamSolid=d;}
	public void SetRhoSolid(double d) {RhoSolid=d;}
	public void SetCgas(double d) { Cgas=d;}
	public void SetCsolid(double d) {Csolid=d;}
	// fifth row
	//    double MWN2=28.,S=1.92,Dhc=25.9,Dhv=.941,Bg=8.928e7,Egas=88900.;
	public void SetMWN2(double d) {MWN2=d;}
	public void SetS(double d) { S=d;}
	public void SetDhc(double d) {Dhc=d;}
	public void SetDhv(double d) {Dhv=d;}
	public void SetBg(double d) { Bg=d;}
	public void SetEgas(double d) {Egas=d;}

	void CalculateBetas()
	{
		double mwmix,rhogas,mumix;

		mwmix=O2*32.+(1.-O2)*(MWN2);
		yox=32.*O2/mwmix;
		LamMix=O2*LamO2+(1.-O2)*LamN2;
		LamMix=LamMix*Math.sqrt(Tlam/Tprop);
		rhogas=P*101.325/8.314*mwmix/Trho;
		AlphaGas=LamMix/rhogas/(Cgas*1e3);
		mumix=1e-6*(O2*MuO2+(1.-O2)*MuN2);
		mumix=mumix*Math.sqrt(Tlam/Tprop);
		Prno=mumix*Cgas*1e3/LamMix;
		beta1=yox/S;
		beta2=Dhc*1e6/(Cgas*1e3)/Tginf;
		beta3=Tv/Tginf;
		beta4=Dhv*1e6/(Cgas*1e3)/Tginf;
		beta5=LamSolid/LamMix;
		beta6=RhoSolid/rhogas*Csolid/Cgas;
		Bno=(beta1*beta2+1.-beta3)/beta4;
		Kno=beta2/beta4*Math.log(1.+Bno)/Bno;
		phi2flame=beta1*beta2/beta4;
		Tfadlin=1.+beta1*( beta2-beta4*Bno/Math.log(1.+Bno) );
		F=(Tfadlin-beta3)/(beta3-1.);
		Gamlift=1.+Clift*Math.log(1.+Bno)/beta1;
		Tfest=1.+beta1*beta2*(1.-Gamlift/Kno);
		Tfmax=beta3/Gamlift+(1.+beta1*beta2)*(1.-1./Gamlift);
		Fest=(Tfest-beta3)/(beta3-1.);
		GetVeq();// make sure Veq is set
		Lgas=AlphaGas/Veq; // in m
		GetVfEstThick();
		GetVfStThin();
		Eta=Vfestthn/Vfestthk;
		if(Eta<1.){Eta=1.;}
		T=Tau*RhoSolid*Csolid*1e3*Fest*Fest*Veq/Chd/(Math.PI/4.)/F/LamMix/beta5/beta6;
	}

	public double GetVfdeRisThick() {
		//CalculateBetas();
		Vf=F*F/beta5/beta6*Vg;
		return Vf*1000.;
	}
	public double GetVfdeRisThin() {
		//CalculateBetas();
		Vf=Math.PI/4.*LamMix*F/RhoSolid/(Csolid*1e3)/Tau;
		return Vf*100.;
	}
	public double GetVfStThin() {
		double alpha,l;
		alpha=beta1/Math.log(1+Bno);
		l=1.365*Math.exp(-7.463*alpha);
		Chd=1.0+1.324*l-0.684*l*l;
		Vfestthn=Chd*Math.PI/4.*LamMix*F/RhoSolid/(Csolid*1e3)/Tau;
		return Vfestthn*100.;
	}
	public double GetVfEstThick()	{
		Vfestthk=Fest*Fest/beta5/beta6*Veq;
		return Vfestthk*1000.;
	}

	public double GetVeq()	{
		double x;
		switch(ngeometry)
		{
			case 0: //Fully Developed Channel Flow
			Veq=Vg*Chyd*Math.sqrt(15.*AlphaGas/2./halfheight/Vg);
			break;

			case 1: // Developing Channel Flow
			double xfdev,xdev;
			ReH=2.*halfheight*Vg/AlphaGas/Prno;
			xfdev=0.01*ReH*2.*halfheight;
			xdev=Math.min(xfdev,Xdev); // xdev is the dev. length
			//xdev=xfdev;
			x=AlphaGas/Vg/Prno/xdev;
			Veq=Vg*Chyd*Math.pow(x,0.25);
			break;

			case 2:  // Flat Plate
			x=AlphaGas/Vg/Prno/Xdev;
			Veq=Vg*Chyd*Math.pow(x,0.25);
			break;

			case 3:  // Buoyant Flow
			x=AlphaGas*Gravity*9.80665*(Tv-Tginf)/Tginf;
			Veq=Cbouy*Math.pow(x,0.333333);     
			break;
		}
		return Veq;
	}


	public double Erfc(double d)
	{ // Numerical Recipes page 176
		double t,z,ans;

		if(d>2.2){return 0.;}
		z=d;
		t=1.0/(1.+0.5*z);
		ans=t*Math.exp(-1*z*z-1.26551223+t*(1.00002368+t*(0.37409196+t*(0.09678418+
		t*(-0.18628806+t*(0.27886807+t*(-1.13520398+t*(1.48851587+
		t*(-0.82215223+t*(0.17087277))))))))));
		return ans;
	}

	public double GetTHeight(double x,double value)	{
		double y,phi,phi1,phi2,T,denom;
		double temp0,temp1,temp2;
		double Tnew=-1,Told=-1;
		boolean  bsecond=false;
		
		if(value<0.) { bsecond=true;value*=-1.;}
		denom=2.*Math.sqrt(x);
		temp0=beta1*beta2+1.;
		temp1=phi2flame*Gamlift;
		temp2=-1.*Bno;
		for(y=0.;y<20. ;y+=0.1)
		{
			phi=Erfc(y/denom);
			if(phi<0.01){return -1.;}
			// this is the diemsionless phi
			phi1=phi*temp2;    
			phi2=phi*temp1;               
			if(phi2>=phi2flame)	{// under or on flame
				T=phi1*beta4+temp0;           
			} else{// over flame
				T=1.+beta4*(phi1+phi2);
			}
			if(Told<value){
				if(T>value){  		
					if(bsecond){
						bsecond=false;
					} else{
						return y;
					}
				}
			}else if (Told>value)	{
				if(T<value){
					if(bsecond){
						bsecond=false;
					} else{
						return y;
					}
				}
			}
			Told=T;
		}	
		return -1.;
	}
	public double GetYoHeight(double x,double value)
	{
		double y,phi,phi2,yo,temp,denom;
		if(value>=yox){return -1;}
		denom=2.*Math.sqrt(x);
		temp=phi2flame*Gamlift;
		for(y=0.;y<100.;y+=0.1)
		{
			phi=Erfc(y/denom);
			phi2=phi*temp;
			if(phi2<phi2flame){// yo can be calculated
				yo=(-1*phi2/phi2flame+1.)*yox;  		
				if(yo>=value){ return y;}
			}
		}
		return -1;
	}

	public double GetYfHeight(double x,double value)
	{
		double y,phi,phi2,yf,yfmax,denom,temp;
		yfmax=beta1*(Gamlift-1.);
		if(value>yfmax){return -1;}
		denom=2.*Math.sqrt(x);
		temp=phi2flame*Gamlift;
		for(y=0.;y<100.;y+=0.1)
		{
			phi=Erfc(y/denom);
			phi2=phi*temp;
			if(phi2>phi2flame){// yf can be calculated
				yf=beta4*phi2/beta2-beta1;
				if(yf<=value){ return y;}
			}
		}
		return -1;
	}

	public double GetFlameHeight(double x)
	{
		double y,phi,phi2,denom,temp;
		denom=2.*Math.sqrt(x);
		temp=phi2flame*Gamlift;
		for(y=0.;y<100.;y+=0.05)
		{
			phi=Erfc(y/denom);
			phi2=phi*temp;
			if(phi2<=phi2flame){ return y;}
		}
		return y;
	}

	public double GetPhiHeight(double x,double value)
	{
		double y,phi;
		for(y=0.;y<100.;y+=0.025)
		{
			phi=Erfc(y/(2.*Math.sqrt(x)));
			if(phi<=value){ return y;}
		}
		return y;
	}
	public double GetPhi3Height(double x,double value)
	{
		double y,phi,Ts,denom,phi3w;
           
		denom=2.*Math.sqrt(x)*beta5/Fest;
		phi3w=(beta3-1.)/beta4;
		for(y=0.;y<100.;y+=0.1)
		{
			phi=Erfc(y/denom);
			Ts=phi*phi3w*beta4+1.;
			if(Ts<=value){ return y;}
			if(Ts<=1.01){ return -1.;}
		}
		return -1.;
	}

	public void SetPhi(double d) {	Phi=d;	}
	public double GetPhi() {	return Phi;	}
	public void SetXmin(double d) {	Xmin=d;	}
	public double GetXmin() {	return Xmin;	}
	public void SetXmax(double d) {	Xmax=d;	}
	public double GetXmax() {	return Xmax;	}
	public void SetYmin(double d) {	Ymin=d;	}
	public double GetYmin() {	return Ymin;	}
	public void SetYmax(double d) {	Ymax=d;	}
	public double GetYmax() {	return Ymax;	}
	
}
class EstOutput extends Panel {

	DataSheet data;
  	Label l1,l2,l3,l4,l5,l6;	
	Label l7,l8,l9;

        
	public EstOutput(DataSheet data)
	{
		this.data=data;
		setLayout(new GridLayout(0,6));
		add("Label",new Label("Vf,EST mm/s"));
		add("Label",new Label("Vg,eqv mm/s"));
		add("Label",new Label("Lg,diff mm"));
		add("Label",new Label("Eta"));
		add("Label",new Label("T"));
		add("Label",new Label("Tf,max(K)"));


		add("Label",l1 = new Label("NC"));
		add("Label",l2 = new Label("NC"));
		add("Label",l3 = new Label("NC"));
		add("Label",l4 = new Label("NC"));
		add("Label",l5 = new Label("NC"));
		add("Label",l6 = new Label("NC"));
		
		add("Label",new Label("Tcrit, mm"));
		add("Label",new Label("Vf,EST,thk mm/s"));
		add("Label",new Label("Vf,EST,thn mm/s"));
		add("Label",new Label("not used"));
		add("Label",new Label("not used"));
		add("Label",new Label("not used"));

		add("Label",l7 = new Label("NC"));
		add("Label",l8 = new Label("NC"));
		add("Label",l9 = new Label("NC"));
//		add("Label",l4 = new Label("NC"));
//		add("Label",l5 = new Label("NC"));
//		add("Label",l6 = new Label("NC"));


	}
	public void UpdateFields()
	{
		double x;
		double T;
		
//		x=data.GetVfEstThick();
//		l1.setText(""+x );
		x=data.GetVeq();
		l2.setText(""+x*1000. );
		x=data.GetLgas();
		l3.setText(""+x );
		x=data.GetEta();
		l4.setText(""+x );
		T=data.GetTndim();
		l5.setText(""+T );
		x=data.GetTfmax()*data.GetTginf();
		l6.setText(""+x );
		// second row
		x=data.GetTaucrit();
		l7.setText(""+x );
		x=data.GetVfEstThick();
		l8.setText(""+x );
		x=data.GetVfStThin();
		l9.setText(""+x*10. );

		if(T>1.)
		{
			x=data.GetVfEstThick();
			l1.setText(""+x );
		}else{
			x=data.GetVfStThin();
			l1.setText(""+x*10. );
		}
		
	}
}
