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

public class iciceikiboruisidegistirici
{liquid_CS boru_ici_sivi;   //(boru içi)
 liquid_CS boru_disi_sivi;  //(boru dışı)
 String akis;
 double eps;                // yüzey pürüzlülüğü
 double di;                 // boru iç çapı
 double dout;               // boru dış çapı
 double dh;                 // dış boru hidrolik çapı
 double D;                  // ısı değiştirici çapı
 double dP;                 // basınç düşümü
 double Uortalama;
 double eod; 
 double Tsoguk[];
 double Tsicak[];
 double x[];               // ısı değiştirici boy koordinatı
 double Q;
 double Lboru;             // boru boyu
 double dL;                // boru step boyu
 int nboru;                // boru step sayısı
 double KL;                // yerel basınç düşüş katsayısı
 double Aboru;             // boru yüzey alanı
 double debi_icteki;       // içteki akışkan debisi
 double debi_distaki;      // dıştaki akışkan debisi
 double Ric,Rdis; //Boru yüzeyi ısıl direnç katsayıları
 double kboru;//bakır boru kabul edildi
 double LMTD;
 double Qlmtd;
 public iciceikiboruisidegistirici(String ic_sivi,
 String dis_sivi,
 double ieps,
 double idi,
 double idout,
 double iD,
 double imsoguk,
 double imsicak,
 double Lborui,
 double dLi,
 double KLi)
 {boru_ici_sivi=new liquid_CS(ic_sivi);
  boru_disi_sivi=new liquid_CS(dis_sivi);
  akis="tanımsız";
  eps=ieps;
  Lboru=Lborui;
  Uortalama=0;
  dL=dLi;
  KL=KLi;
  nboru=(int)(Lboru/dL+0.0001)+1;
  Tsoguk=new double[nboru];
  Tsicak=new double[nboru];
  x=new double[nboru]; //sıcaklık koordinatı
  Q=0;
  di=idi;
  dout=idout;
  D=iD;
  dh=(D-dout);
  Ric=0.0002;
  Rdis=0.0002;
  kboru=54; //W/mK
  debi_icteki=imsoguk;
  debi_distaki=imsicak;
  }  
 // eps     : pipe equivalent roughness m
 //          -------------------------------------------
 //          value of equivalent roughness for some pipes:
 //          Pipe             equivalent rougness m
 //          -------------    ---------------------
 //          Riveted steel    0.9e-3 - 9e-3
 //          Concrete         0.3e-3 - 3e-3
 //          Wood stave       0.18e-3 - 0.9 e-3
 //          Cast iron        0.26e-3
 //          Galvanised iron  0.15e-3
 //          Commercial steel 0.045e-3
 //          wrought iron     0.045e-3
 //          drawn tubing     0.0015e-3
 //          Plastic,glass    0.0 (smooth)
 //          -------------------------------------------
 public double f(double Re)
 {
 //Goudar equation 
 double a=2/Math.log(10);
 double b=eod/3.7;
 double d=Math.log(10.0)/5.02*Re;
 double s=b*d+Math.log(d);
 double q=Math.pow(s,(s/(s+1)));
 double g=b*d+Math.log(d/q);
 double z=Math.log(q/g);
 double dLA=(g/(g+1))*z;
 double dCFA=dLA*(1+z/2.0/((g+1)*(g+1)+(z/3)*(2.0*g-1)));
 double f1=a*(Math.log(d/q)+dCFA);
 f1=1.0/(f1*f1);
 return f1;
 }
 
public double  velocity(double t)
{
// velocity of the pipe m/x
double x=0.0;
//double mboru=debi_icteki/n;
double ro=boru_ici_sivi.rd.rol(t+273.15);
double A=Math.PI*di*di/4.0;
return (double) debi_icteki/(ro*A);
}

public double  Re(double t)
{
// reynold's number boru içi
eod=eps/di;
double ro=boru_ici_sivi.rd.rol(t+273.15);
double vis=boru_ici_sivi.rd.viscosity_l(t+273.15);
double vv=velocity(t);
double res=(di*vv*ro/vis);
return res;
}

public double  hc(double t)
{
// convective heat transfer coefficient
double Rey=Re(t);
double Nu=0;
if(Rey<2300)
  { Nu=3.66; }
else
  {
  double fr  = f(Rey);
  double Prt = boru_ici_sivi.rd.Pr(t+273.15);
  // Gnielinski equation
  // Gnielinski, V, Int. Chem Eng., 16, 359,1976
  // Valid for 2000 < Re <5e5, 0.5 < Pr < 2000  
  Nu=(fr/2.0)*(Rey)*Prt/(1+8.7* Math.sqrt(fr/2.0)*(Prt-1.0));
  }
  double kt  =  boru_ici_sivi.rd.k_l(t+273.15);
  double ss=Nu*kt/di;
  //System.out.println("Re="+Rey+"h="+ss);
  return ss;
}
//boru dışı ısı transferi
public double Reout(double t)
{
//======= Reynold sayısı boru dışı ==========	
//x : % karışım miktarı
//t sıvı sıcaklığı	
//orta kesitteki boru alanı
eod=eps/dh;
double As= Math.PI*(D*D-dout*dout)/4;
double ro=boru_disi_sivi.rd.rol(t+273.15);
double vis=boru_disi_sivi.rd.viscosity_l(t+273.15);
double Gs=debi_distaki/As; //
double res=Gs*dh/vis;
return res;
}

public double hout(double t)
{
//t  sıvı sıcaklığı	
//===== Boru dışı taşınım ısı transferi katsayısı W/M^2 K ===========
//	    Tek boru
double Re=Reout(t);
double vis=boru_disi_sivi.rd.viscosity_l(t+273.15);
double k=boru_disi_sivi.rd.k_l(t+273.15);
double Pr=boru_disi_sivi.rd.Pr(t+273.15);
double f=f(Re);
double ho=k/((D*D-dout*dout)/dout)*(f/2.0)*(Re)*Pr/(1+8.7* Math.sqrt(f/2.0)*(Pr-1.0));
return ho;   
}

public double U0(double tic,double tdis)
{
double hi=hc(tic);    // boru içi ısı transferi
double ho=hout(tdis); // boru dışı ısı transferi
double Uboru=1.0/((dout/di)*(1.0/hi+Ric)+
dout/2/kboru*Math.log(dout/di)+Rdis+1/ho);
System.out.println("hi="+hi+"h0="+ho+"Uboru="+Uboru);
return Uboru;
}

public void hesapla_paralel(double tic, double tdis)
{
	Q=0;
	double dq=0;
	double dA=Math.PI*dout*dL;
	double roavg=0;
	double Vavg=0;
	akis="paralel";
	Aboru=nboru*dA;
	dP=0;
    double xx=0;
    Uortalama=0;
    double uu=0;
	for(int k=0;k<nboru;k++)
	{   uu=U0(tic,tdis);
		Uortalama+=uu;
		dq=uu*dA*(tdis-tic);
	    double Rey=Re(tic);
	    double f=f(Rey);
	    double ro=boru_ici_sivi.rd.rol(tic+273.15);
	    roavg+=ro;
	    double V=velocity(tic);
	    double dtic=0;
	    double dtdis=0;
	    Vavg+=V;
	    dP+=f*dL/dout*ro*V*V/2;
	    Q+=dq;
	    Tsoguk[k]=tic;
	    Tsicak[k]=tdis;
	    x[k]=xx;
	    dtic=dq/(debi_icteki*boru_ici_sivi.rd.Cpl(tic+273.15)*1.0e3);
        dtdis=dq/(debi_distaki*boru_disi_sivi.rd.Cpl(tdis+273.15)*1.0e3);
        tic+=dtic;
        tdis-=dtdis;
        xx+=dL;
    }
    roavg/=nboru;
    Vavg/=nboru;
    Uortalama/=nboru;
    dP+=KL*roavg*Vavg*Vavg/2.0;
}


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*1e-3,Uortalama);
 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 String toString()
{String s="Isı değiştirici \n";
s+="akış = "+akis+"\n";
s+="boru içi akışkan = "+boru_ici_sivi.rd.liquidName+"\n";
s+="boru dışı akışkan = "+boru_disi_sivi.rd.liquidName+"\n";
s+="boru içi yüzey pürüzlülüğü : "+eps+"\n";
s+="boru içi çapı : "+di+"\n";
s+="boru dışı çapı : "+dout+"\n";
s+="basınç düşümü : "+dP+"\n";
s+="ortalama ısı transfer katsayısı : "+Uortalama+"\n";
s+="Isı transferi : "+Q+"\n";
s+="Isı değiştirici alanı : "+Aboru+"\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;
}
  
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 double hesapla_ters1(double tic, double tdis1)
{
	Q=0;
	double dq=0;
	double dA=Math.PI*dout*dL;
	double roavg=0;
	double Vavg=0;
	akis="ters";
	Aboru=nboru*dA;
	dP=0;
    double xx=0;
    Uortalama=0;
    double uu=0;
	for(int k=0;k<nboru;k++)
	{   uu=U0(tic,tdis1);
		Uortalama+=uu;
		dq=uu*dA*(tdis1-tic);
	    double Rey=Re(tic);
	    double f=f(Rey);
	    double ro=boru_ici_sivi.rd.rol(tic+273.15);
	    roavg+=ro;
	    double V=velocity(tic);
	    double dtic=0;
	    double dtdis=0;
	    Vavg+=V;
	    dP+=f*dL/dout*ro*V*V/2;
	    Q+=dq;
	    Tsoguk[k]=tic;
	    Tsicak[k]=tdis1;
	    x[k]=xx;
	    dtic=dq/(debi_icteki*boru_ici_sivi.rd.Cpl(tic+273.15)*1.0e3);
        dtdis=dq/(debi_distaki*boru_disi_sivi.rd.Cpl(tdis1+273.15)*1.0e3);
        tic+=dtic;
        tdis1+=dtdis;
        xx+=dL;
    }
    roavg/=nboru;
    Vavg/=nboru;
    Uortalama/=nboru;
    dP+=KL*roavg*Vavg*Vavg/2.0;
    return  Tsicak[nboru-1];
}
public void hesapla_ters(double tic, double tdis)
{
//ters akışlı sistem
//tic  : soğuk sıvı giriş sıcaklığı	
//tdis : sıcak sıvı giriş sıcaklığı
double dT=(tdis-tic)/30;
double Tgir[]=new double[25];
double Tcik[]=new double[25];
akis="ters";
for(int i=0;i<25;i++)
{Tcik[i]=tdis-dT*i;
 Tgir[i]=hesapla_ters1(tic, Tcik[i]);
}
double e[]=EKK(Tgir,Tcik,7);
double tdis1=funcEKK(e,tdis);
double tdis2=hesapla_ters1(tic,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;
}
}