class fgibbs extends f_xj
{	double[][] A;	
	gibbsSpecies[] gs;
	double[] n0;
	double[] n00;
	double[] n;
	double[] del_lnnm;
	double[] del_nm;
	double[] lnnm;
	double nt;
	double lnnt;
	double del_lnnt;
	int NG;//Gas species number
	int l;//element number
	double[][] d_coeff;
	double[] d_const;
	double[] b0;
	double[] b;
	double[] mu;
	double[] mutemp;
	double P;
	double T;
	double T0;
	double[] Te;
	double lambda;	
	double lambda1;
	double lambda2;
	double etemp=0;
	double Tref=298.15;
	double G=0;
	double Gnew=0;
	double diff=0;
	double SIZE=25.328436;//18.420681;
	double ntahminilk;
	int it_max=100;
	int it_max0=100;
	int o2=-1;
	int n2=-1;
	double x1[];
	double x2[];
			public fgibbs(String igs[],double[] in0,double iTe[],double iT,double iP){
			     Te=new double[iTe.length];
			     for(int i=0;i<iTe.length;i++)			     
			     Te[i]=iTe[i];
			     setgibbs(igs,in0,iT,iP);			
		}
		public void setgibbs(String igs[],double[] in0,double iT,double iP){
			gs=new gibbsSpecies[igs.length];		
			for(int i=0;i<igs.length;i++){
				gs[i]=new gibbsSpecies(igs[i],"gas");
			}
	    	int nn=igs.length;
			int nat=110;
			double B[][]=new double[nat][nn];
			int nk=0;		
			for(int i=0;i<nn;i++){
				for(nk=0;nk<gs[i].atomList.length;nk++){
					B[gs[i].atomList[nk].number-1][i]=gs[i].atomList[nk].N;
					}
				}
			int natcount=0;
			boolean zeroflag[]=new boolean[110];
			for(int j=0;j<nat;j++)
			{zeroflag[j]=false;for(int i=0;i<nn;i++){if(B[j][i]!=0){zeroflag[j]=true;}};if(zeroflag[j]) natcount++;}
			A=new double[natcount][nn];		
			int k=0;
			for(int j=0;j<nat;j++)
			{if(zeroflag[j]){A[k]=B[j];k++;}}
			n0=in0;
			n00=new double[n0.length];
			for(int i=0;i<n0.length;i++) n00[i]=in0[i];
			P=iP;
			T=iT;
			T0=iT;	
			mu=new double[gs.length];
			mutemp=new double[gs.length];	
			l=A.length;
			NG=A[0].length;			
			lambda=1;
			del_lnnm=new double[NG];
			del_nm=new double[NG];
			lnnm=new double[NG];					
			d_coeff=new double[l+1][l+1];
			d_const=new double[l+1];
			b=new double[l];
			nt=getnt(n0);
			ntahminilk=nt/n0.length;
			n=new double[n0.length];
			for(int i=0;i<n0.length;i++){
				n[i]=ntahminilk;
			}
			nt=getnt(n);					
			b0=new double[l];
			for(int ii=0;ii<b0.length;ii++){
				for(int ij=0;ij<NG;ij++){
					double carpim=A[ii][ij]*n0[ij];	
					b0[ii]+=carpim;		
				}						
			}  	
			calMu(n0);
}


		public double getnt(double[] jn){
			double nt_inner=0;
			for(int i=0;i<jn.length;i++) {nt_inner+=jn[i];}
			return nt_inner;		
	 	}
	 	public void setN0(double[] in0){
			//n00=new double[n0.length][1];
		    for(int i=0;i<n0.length;i++) n0[i]=in0[i];
		}
		public void setN0Default(){
			//n00=new double[n0.length][1];
		    for(int i=0;i<n0.length;i++) n0[i]=n00[i];
		    b0=getb(n00);
		}
		public void setT(double iTeq){
			T=iTeq;
			calMu(n0);			
		}
		public void setTDefault(){
			T=T0;	
		} 
		public void setNmax(int iit_max){
			it_max=iit_max;			
		} 
		public void setNmaxDefault(){
			it_max=it_max0;	
		}
	 	public void calMu(double[] in){
			for(int i=0;i<mu.length;i++){
				double inT=getnt(in);
				mu[i]=gs[i].mu(T,P,in[i],inT);
			}	
		}
		public double[] getb(double[] in){
			double inner_b[]=new double[A.length];
			for(int ii=0;ii<inner_b.length;ii++){
				inner_b[ii]=0;
				for(int ij=0;ij<NG;ij++){  				
					inner_b[ii]+=A[ii][ij]*in[ij];			
				}
			}
			return inner_b;
		}	
	 	public double getG(double[] in)
	 	{
		 	calMu(in);
		 	double munt=0;
			for(int j=0;j<mu.length;j++) mu[j]*=in[j];
		 	for(int i=0;i<mu.length;i++) munt+=mu[i];
			return munt;		
	 	}


	
public double func(double x[]) 
{
//çözümü istenen fonksiyon	
double ff=0;
double G;
double x1[]=new double[NG];
double x2[]=new double[l];
for(int i=0;i<NG;i++) {x1[i]=x[i];//System.out.println("x1["+i+"] = "+x1[i]);
}     //n_i
for(int i=NG;i<(NG+l);i++) {x2[i-NG]=x[i];//System.out.println("x1["+i+"] = "+x1[i]);
} //lambda_k
ff+=getG(x1);
double temp;
double temp1=0;
			double cc=1.0;
			for(int ii=0;ii<b0.length;ii++)
			{
				for(int ij=0;ij<NG;ij++){
					cc=A[ii][ij]*x1[ij];	
					b0[ii]+=cc;		
				}						
			} 
for(int k=0;k<l;k++)
{
temp=0;
for(int i=0;i<NG;i++)
{temp+=A[k][i]*x1[i];}
temp1+=x2[k]*(b0[k]-temp);
}
ff+=temp1;
String s="G="+ff+"  ";
for(int i=0;i<x.length;i++) {s+=x[i]+" ";}
System.out.println(s); 
return -ff; 
}
}