//======================================================
// Thermodynamic Package in java
// Class Gas Properties of perfect gases
// Dr. Turhan Coban
// TUBITAK Ulusal Metroloji Enstitüs
// email : Turhan.Coban@ume.tubitak.gov.tr
//======================================================
// File Name   : Gas.java
// This file contains the Gas class
// this class sets basic properties of perfect gases
// required data is read from Gas.dat.
// =====================================================
// Description  : This file contains the gas class
//               class gas calculates thermophysical properties of
//               perfect gasses
//               following properties can be calculated
//               T()     : Temperature degree K
//               h(T)    : enthalpy  KJ/kmol
//               hf      : formation enthalpy KJ/kg
//               ht(T)   : total enthalpy KJ/kg (h+hf)
//               M       : molar mass kg/kmol
//               HT(T)   : total enthalpy KJ : M*ht(T)
//               P()     : presuure bar
//               s(T,P)  : entropy KJ/kmol K
//               Cp(T)   : specific heat at constant pressure KJ/kmol K
//               Cv(T)   : specific heat at constant volume KJ/kg K
//               gamma(T): adiabatic constant Cp/Cv
//               u(T)    : Internal energy KJ/kmol
//               c(T)    : speed of sound m/s
//               vis(T)  : viscosity      Ns/m^2
//               k(T)    : thermal conductivity KJ/kg K
// DATA FILE DEFINATION
// gas datas are written in the data file "Gas.dat"
// if gas data is not given in the data file, it can be curve fitted
// and added to the data file. Additional curve fitting programs supplied
// in Numerical Analysis package. Each data has the following form :
//------------------
// gasName
// n_equation M h0 hf sf
// xa[0] xb[0] xc[0] xd[0] tl[0] th[0]
// .........
// xa[n_equation-1] xb[n_equation-1]......th[n_equation-1]
// n_vis
// xvis[0]
// .........
// xvis[n_vis-1]
// n_k
// xk[0]
// .........
// xk[n_k-1]
//-------------------
// unit of the xa :  kcal/kmol
// note : if any curvefitting applied for a new gas temperature values
// in K nad enthalpy values in the unit of Kcal.kmol should be supply
// for the Cp curve fitting
//============================================================
//  VARIABLE IDENTIFICATION
// all the variables that type is not defined is a double variable
// PROTECTED VARIABLES :
// xa,xb,xc,xd ,tl,th : double pointers. This values used to calculate
// specific heat at constant pressure  from the following equation :
// Cp(T) = xa[i]+xb[i]*1e-3*T+xc[i]*1.0e5/T^2+xd[i]*1e-6*T^3
// where tl[i] <= T <= th[i]
// n_equation : number of equations (xa,xb,xc,xd,tl,th) for a gas
// xvis : real pointers to define viscosity according to formula :
// vis(T)=sum(xvis(i)*T^i) , for(i=0;i<n_vis;i++)
// n_vis : number of coefficients in polynomial viscosity curve fitting
// xk :real pointers to define thermal conductivity according to formula
// k(t)=sum(xk(i)*T^i) ,  for(i=0;i<n_k;i++)
// PUBLIC VARIABLES :
// gasName : name of the gas example : H2O   :variable class str
// (class str is defined at file cstr.h and str.cpp, written by Timotyhy A. Budd)
// M : mol number of the gas example mol number of H2O is 18.016 kg/kmol
// h0 : value of enthalpy at 298 K in the unit of KJ/kmol
// hf : formation enthalpy at 298 K in the unit of KJ/kmol
// sf : value of enthalpy at 298 K and 1 bar pressure
// N  : molar weight of the gas, kmol
// ierror : integer variable, error flag
//============================================================
import java.io.*;
import java.net.*;

class Gas
{
boolean mole=false; //switch for mole/mass basis
boolean SI=true;   //switch for SI/EN units
URL gn;
double xa[],xb[],xc[],xd[],tl[],th[];
int n_equation;
int n_vis;
int n_k;
double xvis[];
double xk[];
int natom;
String gasName;
Atom atomList[];
double M;  // molar mass of atom kg/kmol
double h0; // enthalpy at T=298 K
double s0; // enthrophy at 298 K
double hf; // enthalpy of formation
double sf; // entropy of formation    kJ/kmol K
double gf; // gibbs free energy of formation 
double N;  // moles of gas kmol
int ierror;
BufferedReader fin;
File gasDir;
// definations of class functions
// constructors
//===================================================================
public Gas()
{
//empty constructor
int i;
gasName="******************************";
natom=1;
atomList=new Atom[natom];
M=0;
N=1.0;
h0=0;
s0=0;
hf=0;
sf=0;
gf=0;
n_equation=6;
n_vis=10;
n_k=10;
xa=new double[6];
xb=new double[6];
xc=new double[6];
xd=new double[6];
tl=new double[6];
th=new double[6];
xvis=new double[10];
xk=new double[10];
for(i=0;i<n_equation;i++)
{xa[i]=0.0;xb[i]=0.0;xc[i]=0.0;xd[i]=0.0;tl[i]=293.0;th[i]=293.0;}
for(i=0;i<n_vis;i++)
{xvis[i]=0.0;}
for(i=0;i<n_k;i++)
{xk[i]=0.0;}
}
//===================================================================

public Gas(String gName,double Nnew) throws IOException
{
int i;
String aName;
double aN;
ierror=1;
N=Nnew;
String tempGasName="";

    try{
       File ff=new File("Gas.txt");
       fin=new BufferedReader(new FileReader(ff));
       } catch(IOException e)
       {
       System.err.println("Error Opening File Gas.dat\n"+e.toString());
       System.exit(1);
       }
try{
while(fin!=null)
{
tempGasName=Text.readString(fin);
if (tempGasName.equals(gName)) {ierror=0;break;}
}
  } catch(EOFException e_eof)
     {
     System.out.println("error required gas "+tempGasName+" is not found");
     fin.close();return;
     }
gasName=gName;
natom=Text.readInt(fin);
atomList=new Atom[natom];
M=0;
for(i=0;i<natom;i++)
 {
 aName=Text.readString(fin);
 aN=Text.readDouble(fin);
 atomList[i]=new Atom(aName,aN);
 M+=atomList[i].mass;
 }
n_equation=Text.readInt(fin);
h0=Text.readDouble(fin);
s0=Text.readDouble(fin);
hf=Text.readDouble(fin);
sf=Text.readDouble(fin);
gf=hf-298.0*sf;
xa=new double[n_equation];
xb=new double[n_equation];
xc=new double[n_equation];
xd=new double[n_equation];
tl=new double[n_equation];
th=new double[n_equation];

for(i=0;i<n_equation;i++)
  {
    xa[i]=Text.readDouble(fin);
    xb[i]=Text.readDouble(fin);
    xc[i]=Text.readDouble(fin);
    xd[i]=Text.readDouble(fin);
    tl[i]=Text.readDouble(fin);
    th[i]=Text.readDouble(fin);
  }
n_vis=Text.readInt(fin);
xvis=new double[n_vis];
for(i=0;i<n_vis;i++)
  {
  xvis[i]=Text.readDouble(fin);
  }
n_k=Text.readInt(fin);
xk=new double[n_k];
for(i=0;i<n_k;i++)
  {
  xk[i]=Text.readDouble(fin);
  }
}

public Gas(String gName) throws IOException
{
double Nnew=1;
int i;
String aName;
double aN;
ierror=1;
N=Nnew;
String tempGasName="";
    try{
       File ff=new File("Gas.txt");
       fin=new BufferedReader(new FileReader(ff));
       } catch(IOException e)
       {
       System.err.println("Error Opening File Gas.dat\n"+e.toString());
       System.exit(1);
       }

try{
while(fin!=null)
{
tempGasName=Text.readString(fin);
if (tempGasName.equals(gName)) {ierror=0;break;}
}
  } catch(EOFException e_eof)
     {
     System.out.println("error required gas "+tempGasName+" is not found");
     fin.close();return;
     }
gasName=gName;
//fin>>natom;
natom=Text.readInt(fin);
atomList=new Atom[natom];
M=0;
for(i=0;i<natom;i++)
 {
 //fin>>aName>>aN;
 aName=Text.readString(fin);
 aN=Text.readDouble(fin);
 atomList[i]=new Atom(aName,aN);
 M+=atomList[i].mass;
 }
//fin>>n_equation>>h0>>hf>>sf;
n_equation=Text.readInt(fin);
h0=Text.readDouble(fin);
s0=Text.readDouble(fin);
hf=Text.readDouble(fin);
sf=Text.readDouble(fin);
gf=hf-298.0*sf;
xa=new double[n_equation];
xb=new double[n_equation];
xc=new double[n_equation];
xd=new double[n_equation];
tl=new double[n_equation];
th=new double[n_equation];

for(i=0;i<n_equation;i++)
  {
    xa[i]=Text.readDouble(fin);
    xb[i]=Text.readDouble(fin);
    xc[i]=Text.readDouble(fin);
    xd[i]=Text.readDouble(fin);
    tl[i]=Text.readDouble(fin);
    th[i]=Text.readDouble(fin);
  }
n_vis=Text.readInt(fin);
xvis=new double[n_vis];
for(i=0;i<n_vis;i++)
  {
  xvis[i]=Text.readDouble(fin);
  }
n_k=Text.readInt(fin);
xk=new double[n_k];
for(i=0;i<n_k;i++)
  {
  xk[i]=Text.readDouble(fin);
  }
}

public String readGasNames() throws IOException
{
    String temp1="";
    int natom;
    String temp=new String("");
    String pgasName;
    String aName;
    double aN;
    double ppercent;
    int n_equation;
    double h0,hf,sf;
    double xai,xbi,xci,xdi,tli,thi;
    int n_vis,n_k;
    double xvisi,xki;
    int i;
    try{
        File ff=new File("Gas.txt");
        fin=new BufferedReader(new FileReader(ff));
               try {
                   while(fin!=null)
	                 {
                     temp1=temp1+Text.readString(fin)+ " ";
                     natom=Text.readInt(fin);
                     for(i=0;i<natom;i++)
                       {
                       aName=Text.readString(fin);
                       aN=Text.readDouble(fin);
                       }
                     n_equation=Text.readInt(fin);
                     h0=Text.readDouble(fin);
                     s0=Text.readDouble(fin);
                     hf=Text.readDouble(fin);
                     sf=Text.readDouble(fin);
                     gf=hf-298.0*sf;
                     for(i=0;i<n_equation;i++)
                       {
                       xai=Text.readDouble(fin);
                       xbi=Text.readDouble(fin);
                       xci=Text.readDouble(fin);
                       xdi=Text.readDouble(fin);
                       tli=Text.readDouble(fin);
                       thi=Text.readDouble(fin);
                       }
                     n_vis=Text.readInt(fin);
                     for(i=0;i<n_vis;i++)
                       {
                       xvisi=Text.readDouble(fin);
                       }
                     n_k=Text.readInt(fin);
                     for(i=0;i<n_k;i++)
                       {
                       xki=Text.readDouble(fin);
                       }
                     } //end of while
                   }  catch(EOFException e_eof)  {fin.close();}
       }
       catch(FileNotFoundException fnfe) {System.out.println("File Gmix.txt not found");}
    return temp1;
}

// ==============================================================

public Gas(Gas g) throws IOException
{
int i;
gasName=g.gasName;
natom=g.natom;
atomList=new Atom[natom];
for(i=0;i<natom;i++)
{
atomList[i]=g.atomList[i];
}
M=g.M;
N=g.N;
h0=g.h0;
hf=g.hf;
sf=g.sf;
gf=hf-298.0*sf;
n_equation=g.n_equation;
n_vis=g.n_vis;
n_k=g.n_k;
xa=new double[n_equation];
xb=new double[n_equation];
xc=new double[n_equation];
xd=new double[n_equation];
tl=new double[n_equation];
th=new double[n_equation];
xvis=new double[n_vis];
xk=new double[n_k];
for(i=0;i<n_equation;i++)
{xa[i]=g.xa[i];xb[i]=g.xb[i];xc[i]=g.xc[i];xd[i]=g.xd[i];tl[i]=g.tl[i];th[i]=g.th[i];}
for(i=0;i<n_vis;i++)
{xvis[i]=g.xvis[i];}
for(i=0;i<n_k;i++)
{xk[i]=g.xk[i];}

}

//===================================================================

//change/assign new molar mass
// see also * operator for the similar function
public void changeN(double Nnew)
{
N=Nnew;
}
//===================================================================
public String toString()
{
//return the chemical symbol of the gas
String s="";
for(int i=0;i<natom;i++)
  s=s+atomList[i].toString();
return s;
}
//===================================================================

public double vis(double T)
{
// SI Ns/m^2
// EN lbm/(ft.s)
if(!SI) T/=1.8;
// dynamic viscosity of the gas
double visg=0;
if(n_vis!=0.0)
{
  visg=xvis[n_vis-1];
  for(int i=n_vis-2;i>=0;i--)
   { visg=visg*T+xvis[i]; }
  visg*=1.0e-7;
}
else
  visg=0;
if(!SI) visg/=1.488;
return visg;
}
//===================================================================

public double k(double T)
{
// thermal conductivity of the gas
if(!SI) T/=1.8;
double kg;
if(n_k!=0.0)
{
  int nk=n_k-1;
  kg=xk[nk];
  for(int i=n_k-2;i>=0;i--)
   { kg+=kg*T+xk[i]; }
	kg*=1.0e-3;
}
else
  kg=0;
if(!SI) kg/=1.731;
return kg;
}
//===================================================================

   public double h(double T)
   {
   if(!SI) T/=1.8;
   //  enthalpy KJ/kmol
   //integration of function dh=Cp(T)*dT
   double hh = h0;
     for(int i=0;i<n_equation;i++)
     {
	     if(((T>th[i]) && (i== (n_equation-1) ) )
		|| ((T<tl[i]) && (i== 0 ) ) )
             {
	     hh+=   xa[i]*(T- tl[i])
	          + xb[i]*1.0e-3/2.0*(T*T-tl[i]*tl[i])
		  - xc[i]*1e5*(1/T-1/tl[i])
		  + xd[i]*1e-6*(T*T*T-tl[i]*tl[i]*tl[i])/3.0;
      }
             else if((T<= th[i]) && (T> tl[i]))
				 {
	     hh+=   xa[i]*(T- tl[i])
	          + xb[i]*1.0e-3/2.0*(T*T-tl[i]*tl[i])
		  - xc[i]*1e5*(1/T-1/tl[i])
		  + xd[i]*1e-6*(T*T*T-tl[i]*tl[i]*tl[i])/3.0;
             }
             else if(T>th[i])
				 {
	     hh+=   xa[i]*(th[i]- tl[i])
	          + xb[i]*1.0e-3/2.0*(th[i]*th[i] - tl[i]*tl[i])
		  - xc[i]*1e5*(1/th[i]-1/tl[i])
		  + xd[i]*1e-6*(th[i]*th[i]*th[i]-tl[i]*tl[i]*tl[i])/3.0;
             }
	  }
   if(!SI) hh*=0.42992;
   if(!mole) hh/=M;
   return hh;
   }
//===================================================================

   public double ht( double t)
   {
   double hf1=hf;
   double Tref=298.0;
   if(!SI) {Tref=536.67;hf1=hf*0.42992;}
   double ht= h(t)-h(Tref)+hf1;
   if(!mole) ht/=M;
   return ht;
   }

   public double s0t( double t)
   {
   double sf1=sf;
   double Tref=298.0;
   if(!SI) {Tref=536.67;sf1*=0.238846;}
   double st=s(t)-s(Tref)+sf;
   if(!mole) st/=M;
   return st;
   }

   public double st( double t,double p)
   {
   double sf1=sf;
   double Tref=298.0,Pref=1.0;
   if(!SI) {Tref=536.67;sf1*=0.238846;Pref=14.503684;;}
   double sst= s(t,p)-s(Tref,Pref)+sf1;
   if(!mole) sst/=M;
   return sst;
   }

//===================================================================

   public double H(double t)
   {
   return h(t)*N;
   }
//===================================================================

   public double HT(double t)
   {
   return ht(t)*N;
   }
//===================================================================

   public double u(double T)
   {
   // internal energy KJ/kmol
   // Integration of function du = Cv(T)*dT
   double ht=h(T);
   double R=8.3145;
   if(!SI) {R=1.986;}
   double at= R*T;
   if(!mole) at/=M;
   return ht-at;
   }
//===================================================================

   public double v(double T,double P)
   {
   // specific volume of the gas m^3/kmol
   if(!SI) {T/=1.8;P/=14.503684;}
   double vt= 8314.5*T/(P*1e5);
   if(!mole) vt/=M;
   if(!SI) vt*=16.016949;
   return vt;
   }

   public double v(double T)
   {
   if(!SI) {T/=1.8;}
   double P=1.0;
   // specific volume of the gas m^3/kmol
   double vt=8314.5*T/(P*1e5);
   if(!mole) vt/=M;
   if(!SI) vt*=16.016949;
   return vt;
   }

//===================================================================
   public double c(double t)
   {
   double g=gamma(t);
   if(!SI) t/=1.8;
   // speed of sound m/s
   double ct=Math.sqrt(8314.5/M*t*g);
   if(!SI) ct/=0.3048;
   return ct;
   }
//===================================================================

   public double si(double T, double P)
   {
   // entropy KJ/kmol K
   // integration of function
   // ds = Cp(T) * dt/T - R dP/P
   // 0 point at 298 K
   // si=s(t,P)-s0(298)
   if(!SI) {T/=1.8;P/=14.503684;}
   double sot=s0;
   if(!mole) sot/=M;
   if(!SI) sot*=0.2388444444;
   return s(T,P)-sot;
   }

   public double s(double T, double P)
   {
   //entropy KJ/kmol K
   //integration of function
   // ds = Cp(T) * dt/T - R dP/P
   // 0 point at 0 K (so is added up at 298 K)
   if(!SI) {T/=1.8;P/=14.503684;}
   double ss=s0;
   for(int i=0;i<n_equation;i++)
		{
           if( ( T > th[i]  && i==n_equation - 1 )
	     ||( T < tl[i]  && i==0              ))
		       {
	       ss+=xa[i]*Math.log(T/tl[i])
	       + xb[i]*1.0E-3*(T-tl[i])
	       - xc[i]*1e5/2.0*(1.0/(T*T) - 1.0/(tl[i]*tl[i]))
	       + xd[i]*1e-6/2.0*(T*T-tl[i]*tl[i]);
               }
	   else if((T <= th[i]) && (T > tl[i]))
	       {
	       ss+=xa[i]*Math.log(T/tl[i])
	       + xb[i]*1.0E-3*(T-tl[i])
	       - xc[i]*1e5/2.0*(1.0/(T*T) - 1.0/(tl[i]*tl[i]))
               + xd[i]*1e-6/2.0*(T*T-tl[i]*tl[i]);
					}
	   else if( T > th[i] )
	       {
	       ss+=xa[i]*Math.log(th[i]/tl[i])
	       + xb[i]*1.0E-3*(th[i]-tl[i])
	       - xc[i]*1e5/2.0*(1.0/(th[i]*th[i]) - 1.0/(tl[i]*tl[i]))
	       + xd[i]*1e-6/2.0*(th[i]*th[i] - tl[i]*tl[i]);
					}
	   }
   double sst= (ss-8.3145*Math.log(P));
   if(!mole) sst/=M;
   if(!SI) sst*=0.238846;
   return sst;
   }

   public double S(double T, double P)
   {
   return s(T,P)*N;
   }

   public double Si(double T, double P)
   {
   return si(T,P)*N;
   }

   public double s(double T)
   {
   //entropy KJ/kmol K
   //integration of function
   // ds = Cp(T) * dt/T - R dP/P
   double P=1;
   if(!SI) {T/=1.8;}
   double ss=s0;
   for(int i=0;i<n_equation;i++)
		{
           if( ( T > th[i]  && i==n_equation - 1 )
	     ||( T < tl[i]  && i==0              ))
		       {
	       ss+=xa[i]*Math.log(T/tl[i])
	       + xb[i]*1.0E-3*(T-tl[i])
	       - xc[i]*1e5/2.0*(1.0/(T*T) - 1.0/(tl[i]*tl[i]))
	       + xd[i]*1e-6/2.0*(T*T-tl[i]*tl[i]);
               }
	   else if((T <= th[i]) && (T > tl[i]))
	       {
	       ss+=xa[i]*Math.log(T/tl[i])
	       + xb[i]*1.0E-3*(T-tl[i])
	       - xc[i]*1e5/2.0*(1.0/(T*T) - 1.0/(tl[i]*tl[i]))
               + xd[i]*1e-6/2.0*(T*T-tl[i]*tl[i]);
					}
	   else if( T > th[i] )
	       {
	       ss+=xa[i]*Math.log(th[i]/tl[i])
	       + xb[i]*1.0E-3*(th[i]-tl[i])
	       - xc[i]*1e5/2.0*(1.0/(th[i]*th[i]) - 1.0/(tl[i]*tl[i]))
	       + xd[i]*1e-6/2.0*(th[i]*th[i] - tl[i]*tl[i]);
					}
	   }
   if(!mole) ss/=M;
   if(!SI) ss*=0.238846;
   return ss;
   }

   public double si(double T)
   {
   return s(T)*N;
   }

//===================================================================

public double s0(double T)
{
  return s(T);
}

public double pr(double T)
{
double Tref, Rref;
  if(!SI) {Tref=491.67;Rref=1.986;}
  else {Tref=273.15;Rref=8.3145;}
  if(!mole) Rref/=M;
  return Math.exp((s(T)-s(Tref))/Rref);
}

public double vr(double T)
{
  double Rref;
  if(!SI) {Rref=1.986;}
  else {Rref=8.3145;}
  return (Rref/M)*T/pr(T)*10;
}

//===================================================================
public double g(double T,double P)
{
  return h(T)-T*s(T,P);
}

public double gt(double T,double P)
{
  return h(T)+hf-T*st(T,P);
}

public double gt(double T)
{
  double Pref;
  if(!SI) {Pref=14.503684;}
  else {Pref=1.0;}
  return h(T)+hf-T*st(T,Pref);
}

public double g(double T)
{
  double Pref;
  if(!SI) {Pref=14.503684;}
  else {Pref=1.0;}
  return h(T)-T*s(T,Pref);
}

public double G(double T,double P)
{
 return g(T,P)*N;
}

public double G(double T)
{
 return g(T)*N;
}

public double GT(double T)
{
 return gt(T)*N;
}

public double GT(double T,double P)
{
 return gt(T,P)*N;
}


//===================================================================
public double g0(double T)
{
  return h(T)-T*s0(T);
}
//===================================================================
public double Cp(double T)
{
   //specific heat at constant pressure KJ/kmol K
   if(!SI) {T/=1.8;}
   double cp=0.0;
   for (int i=0;i<n_equation;i++)
     {
        if( ( T > th[i]  && i==n_equation - 1 )
		  ||( T < tl[i]  && i==0              ))
		{
        cp=xa[i]+xb[i]*1.0e-3*T+xc[i]*1.0e5/T/T+xd[i]*1.0e-6*T*T;
	break;
	}
	else if((T <= th[i]) && (T >= tl[i]) )
	{
	cp=xa[i]+xb[i]*1.0e-3*T+xc[i]*1.0e5/T/T+xd[i]*1.0e-6*T*T;
		  break;
	}
}
if(!mole) cp/=M;
if(!SI) cp*=0.2388444444;
return cp;
}

//===================================================================
public double Cv(double T)
{
//specific heat at constant volume KJ/kmol K
double Rref;
if(!SI) {Rref=1.986;}
else {Rref=8.3145;}
if(!mole) Rref/=M;
double cv;
cv=Cp(T) - Rref;
return cv;
}
//===================================================================
public double gamma(double T)
{
//adiabatic constant
return Cp(T)/Cv(T);
}
//===================================================================
public double T( char name,double y0,double p)
{
// name can have values h : for enthalpy
//                      u : for internal energy
//                      s : for entropy
//                      v : specific volume
// yo : the value of the variable given by variable name
double t;
if(!SI) {t=540;}
else {t=300;}
if(name=='v') {
  double R;
  if(!SI) {R=1545/144;}  //R
  else    {R=8.3145e3/1e5;} //K
  if(!mole) R/=M;
  t= p*y0/R;
              }
  else
  {
  double dt=0;
  int nmax=400;
  double tolerance=1.0e-8;
  for(int i=0;i<nmax;i++)
    {
// apply newtons method for finding roots of equation
    if     (name=='h') dt=-( h(t)   - y0 ) /Cp(t);
    else if(name=='u') dt=-( u(t)   - y0 ) /Cv(t);
    else if(name=='s') dt=-( s(t,p) - y0 ) /(Cp(t)/t);
    else { System.out.println("wrong name defined please try h,u,s ot v");}
	 t+=dt;
//   if error range is less than tolerance, exit
    if(Math.abs(dt)<tolerance) break;
    }
  }
return t;
}

public double T( char name,double y0)
{
// name can have values h : for enthalpy
//                      u : for internal energy
//                      s : for entropy
//                      v : specific volume
// yo : the value of the variable given by variable name
double t,p=1.0;
  double R;
  if(!SI) {R=1545/144;p=14.503684;t=540;}  //R
  else    {R=8.3145e3/1e5;p=1.0;t=300;} //K
  if(!mole) {R/=M;}
if(name=='v') { t= p*y0/R; }
else
  {
  double dt=0;
  int nmax=400;
  double tolerance=1.0e-8;
  for(int i=0;i<nmax;i++)
    {
// apply newtons method for finding roots of equation
    if     (name=='h') dt=-( h(t)   - y0 ) /Cp(t);
    else if(name=='u') dt=-( u(t)   - y0 ) /Cv(t);
    else if(name=='s') dt=-( s(t,p) - y0 ) /(Cp(t)/t);
    else { System.out.println("wrong name defined please try h,u,s ot v");}
	 t+=dt;
//   if error range is less than tolerance, exit
    if(Math.abs(dt)<tolerance) break;
    }
  }
return t;
}

//===================================================================
public double P( char name,double y0,double t1)
{
// name can have values v : for specific volume
//                      s : for entropy
// note : for a perfect gas enthalpy and internal energy
// is not function of pressure
// yo : the value of the variable given by variable name
  double R,R1;
  if(!SI) {R=1545;R1=1.986;}  //R
  else    {R=8.3145e3/1e5;R1=8.3145;} //K
  if(!mole) {R/=M;R1/=M;}

if(name=='v')       return R*t1/y0;
else if (name=='s') return Math.exp((s(t1,1.0)-y0)/R1);
else { System.out.println("wrong name defined please try s or v"); return 1.0;}
}
//===================================================================
public double Prandtl(double t)
{
// Prandtl number
double cp;
if(mole) {cp=Cp(t)/M;}
else {cp=Cp(t);}
double pr=0;
if(SI) pr=cp*vis(t)/k(t)*1e3;
else pr=cp*vis(t)/k(t)*3600;
return pr;
}
//===================================================================
public void assign(Gas g1) throws IOException
{
// assign operator (assigning a new gas to the gas variable)
int i;
ierror=1;
gasName=g1.gasName;
N=g1.N;
n_equation=g1.n_equation;
n_k=g1.n_k;
n_vis=g1.n_vis;
M=g1.M;
h0=g1.h0;
hf=g1.hf;
sf=g1.sf;
natom=g1.natom;
atomList=new Atom[natom];
M=0;
for(i=0;i<natom;i++)
 {
 atomList[i]=new Atom(g1.atomList[i].name,g1.atomList[i].N);
 }
xa=new double[n_equation];
xb=new double[n_equation];
xc=new double[n_equation];
xd=new double[n_equation];
tl=new double[n_equation];
th=new double[n_equation];
xvis=new double[n_vis];
xk=new double[n_k];
for(i=0;i<n_equation;i++)
  { xa[i]=g1.xa[i];
    xb[i]=g1.xb[i];
    xc[i]=g1.xc[i];
    xd[i]=g1.xd[i];
    tl[i]=g1.tl[i];
    th[i]=g1.th[i];
  }
for(i=0;i<n_vis;i++)
  { xvis[i]=g1.xvis[i];}
for(i=0;i<n_k;i++)
  {xk[i]=g1.xk[i];}
}

//===================================================================
public Gas multiply(double Nnew, Gas g1) throws IOException
{
Gas g2=new Gas(g1);
g2.N*=Nnew;
return g2;
}

public boolean equals(Gas g)
{
if(gasName.equals(g.gasName))
    return true;
else
    return false;
}

public boolean base(String s)
{
if(s.equals("mole")) {mole=true;}
else                 {mole=false;}
return mole;
}

public boolean unit(String s)
{
if(s.equals("SI")) {SI=true;}
else               {SI=false;}
return SI;
}

public double[] property(double t, double p)
{
double pp[]=new double[20];
pp[0]=p;
pp[1]=t;
pp[2]=v(t,p);
pp[3]=1.0/pp[2];
pp[4]=h(t);
pp[5]=u(t);
pp[6]=s(t,p);
pp[7]=g(t,p);
pp[8]=ht(t);
pp[9]=gt(t,p);
pp[10]=Cp(t);
pp[11]=Cv(t);
pp[12]=gamma(t);
pp[13]=c(t);
pp[14]=vis(t);
pp[15]=k(t);
pp[16]=M;
pp[17]=Prandtl(t);
pp[18]=pr(t);
pp[19]=vr(t);
return pp;
}

public String[][] toString1(double v1, double v2)
{
  String s1[][]=new String[20][3];
   s1[0][0]="P, pressure                  ";
   s1[1][0]="T, temperature               ";
   s1[2][0]="v, specific volume           ";
   s1[3][0]="   density                   ";
   s1[4][0]="h, enthalpy                  ";
   s1[5][0]="u, internal energy           ";
   s1[6][0]="s, entropy                   ";
   s1[7][0]="g, qibbs free energy         ";
   s1[8][0]="ht,chemical entropy          ";
   s1[9][0]="gt,chemical gibbs f.e.       ";
   s1[10][0]="Cp, specific heat at const P ";
   s1[11][0]="Cv, specific heat at const v";
   s1[12][0]="Cp/Cv, adiabatic constant   ";
   s1[13][0]="c, speed of sound           ";
   s1[14][0]="viscosity                   ";
   s1[15][0]="thermal conductivity        ";
   s1[16][0]="M, molecular weight         ";
   s1[17][0]="Prandtl number              ";
   s1[18][0]="Pr, reduced pressure        ";
   s1[19][0]="vr, reduced volume          ";

   if(SI && !mole)
   {
   s1[0][2]=" bars          ";
   s1[1][2]=" deg K         ";
   s1[2][2]=" m^3/kg        ";
   s1[3][2]=" kg/m^3        ";
   s1[4][2]=" KJ/kg         ";
   s1[5][2]=" KJ/kg         ";
   s1[6][2]=" KJ/kg K       ";
   s1[7][2]=" KJ/kg         ";
   s1[8][2]=" KJ/kg         ";
   s1[9][2]=" KJ/kg         ";
   s1[10][2]=" KJ/kg K        ";
   s1[11][2]=" KJ/kg K       ";
   s1[12][2]="               ";
   s1[13][2]=" m/s           ";
   s1[14][2]=" Ns/m^2        ";
   s1[15][2]=" W/m K         ";
   s1[16][2]=" kg/kmol       ";
   s1[17][2]="               ";
   s1[18][2]="               ";
   s1[19][2]="               ";
   }
   else if(SI && mole)
   {
   s1[0][2]=" bars          ";
   s1[1][2]=" deg K         ";
   s1[2][2]=" m^3/kmole     ";
   s1[3][2]=" kmole/m^3     ";
   s1[4][2]=" KJ/kmole      ";
   s1[5][2]=" KJ/kmole      ";
   s1[6][2]=" KJ/kmole K    ";
   s1[7][2]=" KJ/kmole      ";
   s1[8][2]=" KJ/kmole      ";
   s1[9][2]=" KJ/kmole      ";
   s1[10][2]=" KJ/kmole K    ";
   s1[11][2]=" KJ/kmole K   ";
   s1[12][2]="               ";
   s1[13][2]=" m/s           ";
   s1[14][2]=" Ns/m^2        ";
   s1[15][2]=" W/m K         ";
   s1[16][2]=" kg/kmol       ";
   s1[17][2]="               ";
   s1[18][2]="               ";
   s1[19][2]="               ";
   }
   else if(!SI && mole)
   {
   s1[0][2]=" lbf/in^2, psia  ";
   s1[1][2]=" deg R           ";
   s1[2][2]=" ft^3/lbmole     ";
   s1[3][2]=" lbmole/ft^3     ";
   s1[4][2]=" BTU/lbmole      ";
   s1[5][2]=" BTU/lbmole      ";
   s1[6][2]=" BTU/lbmole K    ";
   s1[7][2]=" BTU/lbmole      ";
   s1[8][2]=" BTU/lbmole      ";
   s1[9][2]=" BTU/lbmole      ";
   s1[10][2]=" BTU/lbmole K   ";
   s1[11][2]=" BTU/lbmole K   ";
   s1[12][2]="                ";
   s1[13][2]=" ft/s           ";
   s1[14][2]=" lbm/(ft.s)     ";
   s1[15][2]=" BTU/(hr ft R)  ";
   s1[16][2]=" lbm/lbmole     ";
   s1[17][2]="                ";
   s1[18][2]="                ";
   s1[19][2]="                ";
   }
   else if(!SI && !mole)
   {
   s1[0][2]=" lbf/in^2, psia  ";
   s1[1][2]=" deg R           ";
   s1[2][2]=" ft^3/lbm     ";
   s1[3][2]=" ft^3/lbm     ";
   s1[4][2]=" BTU/lbm      ";
   s1[5][2]=" BTU/lbm      ";
   s1[6][2]=" BTU/lbm K    ";
   s1[7][2]=" BTU/lbm      ";
   s1[8][2]=" BTU/lbm      ";
   s1[9][2]=" BTU/lbm      ";
   s1[10][2]=" BTU/lbm K    ";
   s1[11][2]=" BTU/lbm K   ";
   s1[12][2]="                ";
   s1[13][2]=" ft/s           ";
   s1[14][2]=" lbm/(ft.s)     ";
   s1[15][2]=" BTU/(hr ft R)  ";
   s1[16][2]=" lbm/lbmole     ";
   s1[17][2]="                ";
   s1[18][2]="                ";
   s1[19][2]="                ";
   }
   double pp[]=property(v1,v2);
   for(int i=0;i<20;i++)
   {s1[i][1]=""+pp[i];}
return s1;
}
//=================================================================
}

//=================================================================

