public class FonctionsEDP{
    
 public static void main(String[] args) {

     D2op F = new L2functions(); //Question: Est-ce que c'est plus utile de construire une fonction ou un opérateur différentiel?

     double x,dx=0.01;
     int n=1;

     int N = 100;
     double[] s = new double[N+1];//contient les coefficients de la méthode d'intégration
     double[] f = new double[N+1];//contient les valeurs de la fonction, dont on cherche à calculer l'intégrale
     double[] c = new double[N+1];//coefficients du développement de la fonction que l'on cherche sur la base
                                  //des fonctions propres
     
     Intégrateurs.trapezes(s,N);//On vient d'attribuer les valeurs au vecteur s

     //Tester que la définition des fonctions est cohérente
     /*
     for(n=0;n<=N;n++){
	 x = n*dx;
	 System.out.println(x+" "+F.ConditionInitiale(x));
     }
     */
     
     for(n=0;n<=N;n++){
	 x=n*dx;
	 f[n]=F.ConditionInitiale(x);//Le vecteur des valeurs de la condition initiale
     }

     //Tester la méthode des trapèzees sur des fonctions connues
     /*
     double somme=0.0;
     for(n=0;n<=N;n++){
	 somme = somme + s[n]*f[n];
     }
     somme = somme*dx; //Multiplier par le pas!
     
     //     System.out.println("Intégrale de sqrt(2)*sin(pi*x) entre 0 et 1= "+somme); //OK!
     */

     //Tester l'orthogonalité des fonctions propres
     int k=1, l; double somme;
	  /*
	  for(n=0;n<=N;n++){
	 x = n*dx;
	 f[n] = F.Dfonctionspropres(k,x)*F.Dfonctionspropres(l,x);
     }

      somme=0.0;
     for(n=0;n<=N;n++){
	 somme = somme + s[n]*f[n];
     }
     somme = somme*dx; //Multiplier par le pas!
     
     System.out.println("Intégrale de sqrt(2)*sin(pi*x) entre 0 et 1= "+somme); //OK!
     */

     //Calculer les coefficients du développement de la condtion initiale dans la base des fonctions propres:
     //Pour Robin il y a la contribution de la valeur propre négative!
     double cstar; double gamma = 0.1;

     for(n=0;n<=N;n++){
	 x = n*dx;
	 f[n] = F.Rfpropren(gamma,x)*F.ConditionInitiale(x);
     }

     somme = 0.0;
     for(n=0;n<=N;n++){
	 somme = somme + s[n]*f[n];
     }
     cstar= somme*dx; 
     
     for(k=0;k<=N;k++){

	 for(n=0;n<=N;n++){
	     x=n*dx;
	     //	     	     f[n]=F.Dfonctionspropres(k,x)*F.ConditionInitiale(x);//Dirichlet
	     //	       f[n]=F.Nfonctionspropres(k,x)*F.ConditionInitiale(x); //Neumann
	     f[n] = F.Rfonctionspropres(k,gamma,x)*F.ConditionInitiale(x);//Robin: la série des valeurs propres positives
	 }

	 somme = 0.0;

	 for(n=0;n<=N;n++){
	     somme = somme + s[n]*f[n];
	 }
	 
	 c[k]=somme*dx;
     }

     //Tester!
     
     /*
     for(n=0;n<=N;n++){
	 x =n*dx;
	 somme=cstar*F.Rfpropren(gamma,x);
	 for(k=0;k<=N;k++){
	     somme = somme + c[k]*F.Rfonctionspropres(k,gamma,x);
	 }
	 System.out.println(x+" "+somme+" "+F.ConditionInitiale(x));
     }
     */

     double somme1, Jbord0, Jbord1, dJbord;
     
     //Calcul de l'évolution dans le temps
     double t,dt=0.005;
     int j;

     
     for(j=0;j<=8*N;j=j+10){
	 t = j*dt;
	 //	 	 for(n=0;n<=N;n++){
	 //	     x = n*dx;
	 x=0.0;
	     //on calcule J(0,t) avec conditions aux limites Dirichlet ou Neumann
	     //-------------------------------------------------------------------------
	 somme = cstar*F.dRfpropren(gamma,x);//Pour les conditions aux limites Robin; Contriburion pour dphi/du
	 somme1 = 0.0;//si l'on choisit les paramètres pour que le fond ne dépende pas du temps 
	     for(k=0;k<=N;k++){
		 //		 somme = somme + c[k]*Math.cos(F.valeurspropres(k)*t)*F.Dfonctionspropres(k,x);//Dirichlet
		 //somme = somme + c[k]*Math.cos( Math.sqrt(F.valeurspropres(k))*t)*F.Nfonctionspropres(k,x);//Neumann
		 somme = somme + c[k]*Math.cos( Math.sqrt(F.valeurspropres(k))*t)*F.dRfonctionspropres(k,gamma,x);// contribution à dphi/du de la série infinie des valeurs propres positives
		 somme1 = somme1 + c[k]*(-Math.sqrt( F.valeurspropres(k) )*Math.sin( Math.sqrt(F.valeurspropres(k))*t)  )*F.Rfonctionspropres(k,gamma,x);// contribution à dphi/dtau
	     }
	     Jbord0 = somme*somme1;

	     	 x=1.0;
	     //on calcule J(1,t) avec conditions aux limites Dirichlet ou Neumann
	     //-------------------------------------------------------------------------
		 somme =cstar*F.dRfpropren(gamma,x); somme1 = 0.0;//Pour les conditions aux limites Robin ici doit apparaître la contribution de la valeur propre négative isolée
	     for(k=0;k<=N;k++){
		 //	 		 somme = somme + c[k]*Math.cos(F.valeurspropres(k)*t)*F.Dfonctionspropres(k,x);//Dirichlet
		 //		 somme = somme + c[k]*Math.cos( Math.sqrt(F.valeurspropres(k))*t)*F.Nfonctionspropres(k,x);//Neumann
		 somme = somme + c[k]*Math.cos( Math.sqrt(F.valeurspropres(k))*t)*F.dRfonctionspropres(k,gamma, x);// contribution à dphi/du
		 somme1 = somme1 + c[k]*(-Math.sqrt( F.valeurspropres(k) )*Math.sin( Math.sqrt(F.valeurspropres(k))*t)  )*F.Rfonctionspropres(k,gamma,x);// contribution à dphi/dtau
	     }
	     	     Jbord1 = somme*somme1;
	     	     dJbord = Jbord0-Jbord1;

	     //--------------------------------------------------------------------------
	     //	     System.out.println(t+" "+x+" "+somme*somme1);//Le courant dans le domaine
	     //  	 }
	     System.out.println(t+" "+Jbord0+" "+Jbord1+" "+dJbord);
     }

     
     
     /*     for(n=0;n<s.length;n++){
	 System.out.println(n+" "+s[n]);
     }
     
     */
     /* 
     for(x=0;x<=1.0;x = x+dx){
	 //	 System.out.println(x+" "+f.Dfonctionspropres(n,x));
	 //	 	 System.out.println(x+" "+f.ConditionInitiale(x));
     }
     */

 }

}
