import javax.swing.JOptionPane;
import java.util.Locale;

public class levha_isi_degistirici
{ liquid_CS soguk_sivi; //soğuk sıvı (boru içi)
  liquid_CS sicak_sivi; //sıcak sıvı (boru dışı)
  String akis;
  double b;      // kanal shevron yüksekliği
  double fi;     // shevron açısı
  double lambda; // levha şevron dalga genişliği
  double Lp;     // levha boyu 
  double Bp;     // levha genişliği
  double dP;     // basınç düşümü
  double t;      // metal et kalınlığı
  double Uortalama;
  double Tsoguk[];
  double Tsicak[];
  double x[];      // ısı değiştirici boy koordinatı
  double Q;        // ısı transferi
  double Qlmtd;    // ısı transferi LMTD metodu
  double LMTD;
  double di;       //hydraulic diameter
  double dL;       // sonlu fark step boyu
  int nboru;       // sonlu fark step sayısı
  int n;           // levha sayısı
  double msoguk;   // soğuk alışkan debisi
  double msicak;   // sicak akışkan debisi
  double Ric,Rdis; // Boru yüzeyi ısıl direnç katsayıları
  double klevha;   // levha ısıl iletkenlik katsayısı
  double Aboru; //  levha ısı değiştirici toplam alanı
  double dP_soguk_sivi; 
  double dP_sicak_sivi;
  double Uavg;
   
  public levha_isi_degistirici(String isoguk_sivi,
  String isicak_sivi,
  double bi, double fii,double lambdai, double Lpi,double Bpi,
  double imsoguk,
  double imsicak,
  double dLi,
  int ni,
  double klevhai,
  double ti)
 {soguk_sivi=new liquid_CS(isoguk_sivi);
  sicak_sivi=new liquid_CS(isicak_sivi);
  akis="tanımsız";
  b=bi;
  fi=fii;
  lambda=lambdai;
  Lp=Lpi;
  Bp=Bpi;
  Uortalama=0;
  dL=dLi;
  n=ni;
  nboru=(int)(Lp/dL+0.0001)+1;
  Tsoguk=new double[nboru];
  Tsicak=new double[nboru];
  x=new double[nboru]; //sıcaklık koordinatı
  Q=0;
  t=ti;
  Ric=0.00001;
  Rdis=0.00001;
  msoguk=imsoguk;
  msicak=imsicak;
  klevha=klevhai;
  double X=2.0*Math.PI*b/lambda;
  double F=1.0/6.0*(1+Math.sqrt(1+X*X)+4.0*Math.sqrt(1.0+X*X/2.0));
  di=2*b/F;
  }  

public double  hiz_soguk_sivi(double t)
{
double mlevha=msoguk/n;
double ro=soguk_sivi.rd.rol(t+273.15);
return (mlevha/ro/b/Bp);
}

public double  hiz_sicak_sivi(double t)
{
double mlevha=msicak/n;
double ro=sicak_sivi.rd.rol(t+273.15);
return (mlevha/ro/b/Bp);
}

public double  Re_soguk_sivi(double t)
{
double ro=soguk_sivi.rd.rol(t+273.15);
double vis=soguk_sivi.rd.viscosity_l(t+273.15);
double vv=hiz_soguk_sivi(t);

double res=(di*vv*ro/vis);
return res;
}
public double  Re_sicak_sivi(double t)
{
double ro=sicak_sivi.rd.rol(t+273.15);
double vis=sicak_sivi.rd.viscosity_l(t+273.15);
double vv=hiz_sicak_sivi(t);
double res=(di*vv*ro/vis);
return res;
}

public double f_soguk_sivi(double t)
{
double Re=Re_soguk_sivi(t);
double f0,f1;
double xx=1.0;
if(Re<2000) f0=20.0/Re;
else        {xx=1.56*Math.log(Re)-3.0;f0=1.0/(xx*xx);}
if(Re<2000) {f1=149.0/Re+0.9625;}
else        {f1=9.75/Math.pow(Re,0.289);}
xx=Math.cos(fi)/Math.sqrt(0.045*Math.tan(fi)+0.09*Math.sin(fi)+f0/Math.cos(fi))+
   (1-Math.cos(fi))/Math.sqrt(3.8*f1);
double f=1.0/(xx*xx);
return f;   
}

public double f_sicak_sivi(double t)
{
double Re=Re_sicak_sivi(t);
double f0,f1;
double xx=1.0;
if(Re<2000) f0=20.0/Re;
else        {xx=1.56*Math.log(Re)-3.0;f0=1.0/(xx*xx);}
if(Re<2000) {f1=149.0/Re+0.9625;}
else        {f1=9.75/Math.pow(Re,0.289);}
xx=Math.cos(fi)/Math.sqrt(0.045*Math.tan(fi)+0.09*Math.sin(fi)+f0/Math.cos(fi))+
   (1-Math.cos(fi))/Math.sqrt(3.8*f1);
double f=1.0/(xx*xx);
return f;   
}

public double  h_soguk_sivi(double t,double tw)
{
double Re=Re_soguk_sivi(t);
double Pr = soguk_sivi.rd.Pr(t+273.15);
double visw=sicak_sivi.rd.viscosity_l(tw+273.15);
double vis=sicak_sivi.rd.viscosity_l(t+273.15);
double kt  =  sicak_sivi.rd.k_l(t+273.15);
double f=f_soguk_sivi(t);
double Nu=0.205*Math.pow(Pr,(1.0/3.0))*Math.pow((visw/vis),(1.0/6.0))*Math.pow((f*Re*Re*Math.sin(2.0*fi)),0.374);
double ss=Nu*kt/di;
return ss;
}
public double  h_sicak_sivi(double t,double tw)
{
double Re=Re_sicak_sivi(t);
double Pr = sicak_sivi.rd.Pr(t+273.15);
double visw=sicak_sivi.rd.viscosity_l(tw+273.15);
double vis=sicak_sivi.rd.viscosity_l(t+273.15);
double kt  =  sicak_sivi.rd.k_l(t+273.15);
double f=f_sicak_sivi(t);
double Nu=0.205*Math.pow(Pr,(1.0/3.0))*Math.pow((visw/vis),(1.0/6.0))*Math.pow((f*Re*Re*Math.sin(2.0*fi)),0.374);
double ss=Nu*kt/di;
return ss;
}

public double  dP_soguk_sivi(double t)
{
double ro=soguk_sivi.rd.rol(t+273.15);
double V=hiz_soguk_sivi(t);
double f=f_sicak_sivi(t);
double dP=f*dL/di*ro*V*V/2.0;
return dP;
}

public double  dP_sicak_sivi(double t)
{
double ro=sicak_sivi.rd.rol(t+273.15);
double V=hiz_sicak_sivi(t);
double f=f_sicak_sivi(t);
double dP=f*dL/di*ro*V*V/2.0;
return dP;
}

public double U0(double tc,double th)
{
double tw=(tc+th)/2.0;
double hi=h_soguk_sivi(tc,tw);    // boru içi ısı transferi
double ho=h_sicak_sivi(th,tw); // boru dışı ısı transferi

double Uboru=1.0/(1.0/hi+Ric+t/klevha+Rdis+1/ho);
//System.out.println("tw="+tw+"hi="+hi+"h0="+ho+"U0="+Uboru);
return Uboru;
}

public void hesapla_paralel(double tc, double th)
{
	Q=0;
	double dq=0;
	double X=2.0*Math.PI*b/lambda;
    double F=1.0/6.0*(1+Math.sqrt(1+X*X)+4.0*Math.sqrt(1.0+X*X/2.0));
	double dA=Bp*dL*F;
	double roavg=0;
	double Vavg=0;
	akis="paralel";
	Aboru=nboru*dA;
	dP_soguk_sivi=0.0;
	dP_sicak_sivi=0.0;
    double xx=0;
    Uavg=0;
    double uu=0;
    double mlevha_soguk=msoguk/n;
    double mlevha_sicak=msoguk/n;
	for(int k=0;k<nboru;k++)
	{   uu=U0(tc,th);
		Uavg+=uu;
		dq=uu*dA*(th-tc);
	    dP_soguk_sivi+=dP_soguk_sivi(tc);
	    dP_sicak_sivi+=dP_sicak_sivi(th);
	  
	    Q+=dq;
	    Tsoguk[k]=tc;
	    Tsicak[k]=th;
	    x[k]=xx;
	    double dtc=dq/(mlevha_soguk*soguk_sivi.rd.Cpl(tc+273.15)*1.0e3);
        double dth=dq/(mlevha_sicak*sicak_sivi.rd.Cpl(th+273.15)*1.0e3);
        tc+=dtc;
        th-=dth;
        xx+=dL;
        System.out.println("k="+k+"u="+uu+"dq="+dq+"dtc="+dtc);
    }
    roavg/=nboru;
    Vavg/=nboru;
    Uavg/=nboru;
    double dT1=Tsicak[0]-Tsoguk[0];
    double dT2=Tsicak[nboru-1]-Tsoguk[nboru-1];
    Aboru=Bp*Lp*F*n;
    LMTD=(dT1-dT2)/Math.log(dT1/dT2);
    Qlmtd=Uavg*Aboru*LMTD;
}

public double  hesapla_ters1(double tc, double th1)
{
	Q=0;
	double dq=0;
	double X=2.0*Math.PI*b/lambda;
    double F=1.0/6.0*(1+Math.sqrt(1+X*X)+4.0*Math.sqrt(1.0+X*X/2.0));
	double dA=Bp*dL*F;
	double roavg=0;
	double Vavg=0;
	akis="ters";
	double Aboru=nboru*dA;
	dP_soguk_sivi=0.0;
	dP_sicak_sivi=0.0;
    double xx=0;
    Uavg=0;
    double uu=0;
    double mlevha_soguk=msoguk/n;
    double mlevha_sicak=msoguk/n;
    double dtc,dth;
	for(int k=0;k<nboru;k++)
	{   uu=U0(tc,th1);
		Uavg+=uu;
		dq=uu*dA*(th1-tc);
	    dP_soguk_sivi+=dP_soguk_sivi(tc);
	    dP_sicak_sivi+=dP_sicak_sivi(th1);
	    //System.out.println("dP="+dP+"f="+f+"dout="+dout+"ro="+ro);
	    Q+=dq;
	    Tsoguk[k]=tc;
	    Tsicak[k]=th1;
	    x[k]=xx;
	    dtc=dq/(mlevha_soguk*soguk_sivi.rd.Cpl(tc+273.15)*1.0e3);
        dth=dq/(mlevha_sicak*sicak_sivi.rd.Cpl(th1+273.15)*1.0e3);
        tc+=dtc;
        th1+=dth;
        xx+=dL;
    }
    roavg/=nboru;
    Vavg/=nboru;
    Uavg/=nboru;
    double dT1=Tsicak[0]-Tsoguk[0];
    double dT2=Tsicak[nboru-1]-Tsoguk[nboru-1];
    Aboru=Bp*Lp*F*n;
    LMTD=(dT1-dT2)/Math.log(dT1/dT2);
    Qlmtd=Uavg*Aboru*LMTD;
    return Tsicak[nboru-1];
}

public void hesapla_ters(double tc, double th)
{
//ters akışlı sistem
//tic  : soğuk sıvı giriş sıcaklığı	
//tdis : sıcak sıvı giriş sıcaklığı
double dT=(th-tc)/30.0;
double Tgir[]=new double[25];
double Tcik[]=new double[25];
akis="ters";
for(int i=0;i<25;i++)
{Tcik[i]=th-dT*i;
 Tgir[i]=hesapla_ters1(tc, Tcik[i]);
}
double e[]=EKK(Tgir,Tcik,7);
double tdis1=funcEKK(e,th);
//System.out.println("tdis1="+tdis1);
double tdis2=hesapla_ters1(tc,tdis1);
    double dT1=Tsicak[0]-Tsoguk[0];
    double dT2=Tsicak[nboru-1]-Tsoguk[nboru-1];
    LMTD=(dT1-dT2)/Math.log(dT1/dT2);
    Qlmtd=Uortalama*Aboru*LMTD;
}

public void plot()
{
 Plot pp=new Plot(x,Tsoguk);
 pp.addData(x,Tsicak);
 Locale us=new Locale("US");          
 String s1="Q = %4.1f kW A = %4.1f m^2 dP = %4.1f kPa U = %4.0f W/m^2K";
 String s4=String.format(us,s1,Q*1e-3,Aboru,dP_soguk_sivi*1e-3,Uavg);
 pp.setPlabel(s4);
 pp.setXlabel("x, m");
 pp.setYlabel("T sıcaklık , derece C");
 pp.plot();
}

//en kucuk kareler metodu	
  public static double[] pivotlugauss(double a[][],double b[])
  { //kısmi pivotlu gauss eleme yöntemi
  int n=b.length;	  
  double x[]=new double[n];
  double carpan=0;
  double toplam=0;
  double buyuk;
  double dummy=0;
  //gauss eleme
  int i,j,k,p,ii,jj;
  for(k=0;k<(n-1);k++)
  { //pivotlama
	p=k;
	buyuk=Math.abs(a[k][k]);
	for(ii=k+1;ii<n;ii++)
	{  dummy=Math.abs(a[ii][k]);
	   if(dummy > buyuk) {buyuk=dummy;p=ii;}
	}
	if(p!=k)
	{ for(jj=k;jj<n;jj++)
	  { dummy=a[p][jj];
	    a[p][jj]=a[k][jj];
	    a[k][jj]=dummy;
	  }
	  dummy=b[p];
	  b[p]=b[k];
	  b[k]=dummy;
	}
	//gauss elemeyi çözme  
    for(i=k+1;i<n;i++)
    {  carpan=a[i][k]/a[k][k];
       a[i][k]=0;
       for(j=k+1;j<n;j++)
       {   a[i][j]-=carpan*a[k][j]; }
           b[i]   =b[i]   -carpan*b[k];
	}
  }
  //geriye doğru yerine koyma
  x[n-1]=b[n-1]/a[n-1][n-1];
  for(i=n-2;i>=0;i--)
  {
    toplam=0;
    for(j=i+1;j<n;j++)
    {  toplam+=a[i][j]*x[j];}
    x[i]=(b[i]-toplam)/a[i][i];
  }
  return x;
}


  
public static double[] EKK(double xi[],double yi[],int n)
{
int l=xi.length;
int i,j,k;
int np1=n+1;
double A[][];
A=new double[np1][np1];
double B[];
B=new double[np1];
double X[];
X=new double[np1];
for(i=0;i<n+1;i++)
  {  for(j=0;j<n+1;j++)
     {if(i==0 && j==0) A[i][j]=l;
     else  for(k=0;k<l;k++) A[i][j] += Math.pow(xi[k],(i+j));
     }
     for(k=0;k<l;k++) { if(i==0)  B[i]+= yi[k];
                       else      B[i] += Math.pow(xi[k],i)*yi[k];}
  }
//System.out.println(Matrix.toString(A));
//System.out.println(Matrix.toStringT(B));  
X=pivotlugauss(A,B);
//X=B/A;
double max=0;
for(i=0;i<n+1;i++)
 if(Math.abs(X[i]) > max) max = Math.abs(X[i]);
for(i=0;i<n+1;i++)
 if((Math.abs(X[i]/max) > 0) && (Math.abs(X[i]/max) < 1.0e-100)) X[i]=0;
return X;
}

public static double funcEKK(double e[],double x)
{
// this function calculates the value of
// least square curve fitting function
int n=e.length;
double ff;
if(n!=0.0)
  { ff=e[n-1];
  for(int i=n-2;i>=0;i--)
   { ff=ff*x+e[i]; }
  }
else
  ff=0;
return ff;
}

public static double hata(double x[],double y[],double e[])
{
//calculates absolute square root error of a least square approach
double n=x.length;
 int k;
 double total=0;
 for(k=0;k<n;k++)
 {
 total+=(y[k]-funcEKK(e,x[k]))*(y[k]-funcEKK(e,x[k]));
 }
total=Math.sqrt(total);
return total;
}

public static double[][]  funcEKK(double xi[],double yi[],int polinomkatsayisi,int aradegersayisi)
{
//aradegersayisi:  x--o--o--x--o--o--x zincirinde x deneysel noktalar ise
// ara değer sayısı 2 dir
   int n=xi.length;
   int nn=(n-1)*(aradegersayisi+1)+1;
   double z[][]=new double[2][nn];
   double E[]=EKK(xi,yi,polinomkatsayisi);	
   System.out.println("katsayılar :\n"+Matrix.toStringT(E));
   double dx=0;
   int k=0;
   int i;
   for(i=0;i<(n-1);i++)
       {z[0][k]=xi[i];z[1][k]=funcEKK(E,z[0][k]);k++;
       for(int j=0;j<aradegersayisi;j++) 
       {dx=(xi[i+1]-xi[i])/((double)aradegersayisi+1.0);
       z[0][k]=z[0][k-1]+dx;z[1][k]=funcEKK(E,z[0][k]);k++;}
       }
       z[0][k]=xi[i];z[1][k]=funcEKK(E,z[0][k]);
   return z;
 } 
public String toString()
{String s="Isı değiştirici \n";
s+="soguk akışkan = "+soguk_sivi.rd.liquidName+"\n";
s+="sıcak akışkan = "+sicak_sivi.rd.liquidName+"\n";
s+="m_boru içi = "+msoguk+"kg/s \n ";
s+="m_boru dışı = "+msicak+"kg/s \n ";
s+="b kanal şevron yüksekliği : "+b+" m\n";
s+="lambda levha şevron dalga genişliği: "+lambda+" m\n";
s+="Lp levha boyu: "+Lp+" m\n";
s+="Bp levha genişliği: "+Bp+" m\n";
s+="t levha kalınlığı: "+t+" m\n";
s+="basınç düşümü soğuk sıvı : "+dP_soguk_sivi+" kPa\n";
s+="basınç düşümü sıcak sıvı : "+dP_sicak_sivi+" kPa\n";
s+="ısı transferi : "+Q+" W\n";
s+="LMTD logaritmik ortalama sıcaklık değişimi : "+LMTD+" K\n";
s+="Soğuk akışkan giriş-çıkış sıcaklıkları : "+"\n";
s+=Tsoguk[0]+"   "+Tsoguk[nboru-1]+"\n";
s+="Sıcak akışkan giriş-çıkış sıcaklıkları : "+"\n";
s+=Tsicak[0]+"   "+Tsicak[nboru-1]+"\n";
return s;
}
}