Пример #1
0
void SIAM::get_Ps()
{
    double** p1 = new double*[N];
    double** p2 = new double*[N];

    #pragma omp parallel for
    for (int i=0; i<N; i++)
    {
        p1[i] = new double[N];
        p2[i] = new double[N];
        for (int j=0; j<N; j++)
        {
            p1[i][j] = r->Am[j] * grid->interpl(r->Ap, r->omega[j] - r->omega[i]);
            p2[i][j] = r->Ap[j] * grid->interpl(r->Am, r->omega[j] - r->omega[i]);
        }

        //get Ps by integrating
        r->P1[i] = pi * TrapezIntegral(N, p1[i], r->omega);
        r->P2[i] = pi * TrapezIntegral(N, p2[i], r->omega);

        delete [] p1[i];
        delete [] p2[i];
    }

    delete [] p1;
    delete [] p2;
}
Пример #2
0
bool SIAM::Run(double mu, complex<double>* Delta, //input
               complex<double>* G_out, complex<double>* Sigma_out, double &n_out) //output
{  
  if (!Initialized) exit(1);
  Clipped = false;

  this->mu = mu;
  this->Delta = Delta;

  if ((mu==0)&&(epsilon==-U/2.0)) 
    SymmetricCase = true;
  else 
    SymmetricCase = false;  
  
  printf("    -------%s SIAM: mu=%.3f, U=%.3f, T=%.3f, epsilon=%.3f -------\n", (SymmetricCase) ? "Symmetric" : "",mu, U, T, epsilon);
  
 
  //----- initial guess ------// 
  n = 0.5;  
  mu0 = 0.0;  
  if ((!SymmetricCase)and(UseMPT_Bs))
     MPT_B = epsilon;
  else
     MPT_B = 0.0;

  complex<double>* V = new complex<double>[2];
  V[0] = mu0; 
  V[1] = MPT_B;
  //---------------------------//

  //------ SOLVE SIAM ---------//
  if (SymmetricCase) 
    //mu0 and n are known => there's no solving of system of equations
    SolveSiam(V);
  else 
    //use broyden to solve system of two equations
    UseBroyden<SIAM>(2, MAX_ITS, Accr, &SIAM::SolveSiam, this, V);
  
  delete [] V;
  //----------------------------//
  
  //output spectral weight if optioned
  if (CheckSpectralWeight)
  {
    printf("        Spectral weight G: %fe\n", -imag(TrapezIntegral(N,G,omega))/pi);
    printf("        Spectral weight G0: %fe\n", -imag(TrapezIntegral(N,G0,omega))/pi);
  }

  //-------- OUTPUT ---------//
  for (int i=0; i<N; i++)
  {
    G_out[i] = G[i];
    Sigma_out[i] = Sigma[i];
  }
  n_out = n;
  //-------------------------//

  return Clipped;
}
Пример #3
0
int main()
{

  int N=1000;
  GRID grid(N, 1.5, false);
  
  //GRID grid("params");
  //int N=grid.get_N();

  double* omega = new double[N];
  double* dos = new double[N];

  grid.assign_omega(omega);
  printf("-----grid ready\n");

  int Nx = 4000;
  int Ny = 4000;
  IBZ ibz(IBZtypes::TriangularLattice, Nx, Ny);
  printf("-----ibz ready\n");
  for(int n=0; n<N; n++)
  { for(int i=0; i<Nx; i++)
    for(int j=0; j<Ny; j++)
      ibz.summand[i][j] = 1.0/(omega[n]-ibz.epsilon[i][j]+ii*1e-3);
    printf("-----summand ready, n=%d \n",n);
    dos[n] = -(1.0/pi)*imag(ibz.sum());    
  }
  PrintFunc("triangular_dos",N,dos,omega);
  printf("Spectral weight: %.6f\n",TrapezIntegral(N, dos, omega));
  delete [] dos;  
  delete [] omega;
  return 0;
}
Пример #4
0
void SIAM::get_SOCSigma()
{
    double** s = new double*[N];
    #pragma omp parallel for
    for (int i=0; i<N; i++)
    {   //printf("tid: %d i: %d\n",omp_get_thread_num(),i);
        s[i] = new double[N];
        for (int j=0; j<N; j++)
        {   //printf("tid: %d j: %d\n",omp_get_thread_num());
            s[i][j] =   grid->interpl(r->Ap, r->omega[i] - r->omega[j]) * r->P2[j]
                        + grid->interpl(r->Am, r->omega[i] - r->omega[j]) * r->P1[j];
        }

        //integrate

        r->SOCSigma[i] = complex<double>(0.0, - U*U * TrapezIntegral(N, s[i], r->omega) );

        if (ClipOff( r->SOCSigma[i] )) Clipped = true ;
        delete [] s[i];
    }
    delete [] s;
    //int i;
    //cin >> i;
    if (Clipped) printf("    !!!Clipping SOCSigma!!!!\n");
    grid->KramarsKronig( r->SOCSigma );
}
Пример #5
0
double SIAM::get_n(complex<double> X[])
{
  double* g = new double[N];
  for (int i=0; i<N; i++)
    g[i]=-(1/pi)*imag(X[i])*fermi[i];
  double n = TrapezIntegral(N, g,omega);
  delete [] g;
  return n; 
}
Пример #6
0
void SIAM::get_Ps()
{
  for (int i=0; i<N; i++)
  { 
    //get integrand arrays
    double* p1 = new double[N];
    double* p2 = new double[N];
    for (int j=0; j<N; j++)
    {  
       p1[j] = Am[j]*grid->interpl(Ap, omega[j]-omega[i]);
       p2[j] = Ap[j]*grid->interpl(Am, omega[j]-omega[i]);
    }

    //get Ps by integrating                           
    P1[i] = pi*TrapezIntegral(N, p1, omega);
    P2[i] = pi*TrapezIntegral(N, p2, omega);
    delete [] p1;
    delete [] p2;
  }
}
Пример #7
0
double SIAM::get_MPT_B()
{
  if (!UseMPT_Bs) return 0.0;
  
  complex<double>* b = new complex<double>[N];
  for(int i=0; i<N; i++)
    b[i] = complex<double>(fermi[i]) * Delta[i] * G[i]
           * ( complex<double>(2.0 / U) * Sigma[i] - (double)1.0 );
  double mpt_b = epsilon - 1.0/(pi*n*(1.0-n)) * imag(TrapezIntegral(N, b,omega));
  delete [] b;
  return mpt_b;
}
Пример #8
0
double SIAM::get_MPT_B0()
{
  if (!UseMPT_Bs) return 0.0;
  
  complex<double>* b0 = new complex<double>[N]; //integrand function
  for(int i=0; i<N; i++)
    b0[i] = complex<double>(fermi[i]) * Delta[i] * G0[i];
  double mpt_b0 = epsilon - 1.0  * (2*n-1) * imag(TrapezIntegral(N, b0,omega))
                           / ( pi * n * (1-n) ) ;
  delete [] b0;
  return mpt_b0;
}
Пример #9
0
void SIAM::get_G_CHM()
{

    get_Sigma();

    if (UseLatticeSpecificG)
        #pragma omp parallel for
        for (int i=0; i<N; i++)
        {   complex<double> com = r->omega[i] + r->mu - r->Sigma[i];
            r->G[i] = LS_get_G(LatticeType, t, com);
        }
    else
    {

        complex<double>** g = new complex<double>*[N];
        #pragma omp parallel for
        for (int i=0; i<N; i++)
        {

            //treat integrand carefully
            double D = 0.0;
            complex<double> LogTerm = 0.0;
            if (abs(imag(r->Sigma[i]))<0.1)
            {
                D = grid->interpl(r->NIDOS, r->mu + r->omega[i] - real(r->Sigma[i]));
                LogTerm = complex<double>(D, 0.0) * log( (r->mu + r->omega[i] - r->Sigma[i] + r->omega[N-1])
                          /(r->mu + r->omega[i] - r->Sigma[i] - r->omega[N-1]) );
            }

            //create integrand array
            g[i] = new complex<double>[N];
            for (int j=0; j<N; j++)
                g[i][j] = complex<double>(r->NIDOS[j] - D, 0.0)
                          / ( r->mu + r->omega[i] - r->omega[j] - r->Sigma[i] );


            //integrate to get G
            r->G[i] = TrapezIntegral(N, g[i], r->omega) + LogTerm ;

            if (ClipOff(r->G[i])) Clipped = true;
            delete [] g[i];
        }

        delete [] g;

        if (Clipped) printf("    !!!!Clipping G!!!!\n");

    }
}
Пример #10
0
void SIAM::GetGfOnImagAxis(int M, complex<double> * G_out)
{ 
  complex<double>* g = new complex<double>[N];
  double* mf = new double[M];
  for(int m=0; m<M; m++)
  { 
    mf[m]=MatsFreq(m);
    for(int i=0; i<N; i++)
      g[i] = imag(G[i]) / complex<double>( -omega[i], mf[m] );
    
    G_out[m] = -1/(pi)*TrapezIntegral(N, g,omega);
  }
  delete [] g;
  delete [] mf;
}
Пример #11
0
void SIAM::get_G_CHM()
{
  get_Sigma();   
  
  for (int i=0; i<N; i++)
  {
      
    //treat integrand carefully
    double D = 0.0;
    complex<double> LogTerm = 0.0;
    if (abs(imag(Sigma[i]))<0.1) 
    {
      D = grid->interpl(Dos,mu + omega[i]-real(Sigma[i]));/*DOS(DOStype_CHM, t_CHM, mu + omega[i]-real(Sigma[i]));*/
      LogTerm = complex<double>(D, 0.0) * log( (mu + omega[i] - Sigma[i] + omega[N-1])
                                             /(mu + omega[i] - Sigma[i] - omega[N-1]) );
    }

    //create integrand array
    complex<double>* g = new complex<double>[N];
    for (int j=0; j<N; j++)
      g[j] = complex<double>(/*DOS( DOStype_CHM, t_CHM, omega[j] )*/Dos[j] - D, 0.0) 
                           / ( mu + omega[i] - omega[j] - Sigma[i] ); 
    
  

/*   //treat integrand less carefully
   complex<double>* g = new complex<double>[N];
   for (int j=0; j<N; j++)
      g[j] = complex<double>(DOS( DOStype_CHM, t_CHM, omega[j] )) 
                           / ( complex<double>(mu,eta) + omega[i] - omega[j] - Sigma[i] );
   
*/    
    //integrate to get G 
    G[i] = TrapezIntegral(N, g,omega) + LogTerm ; 

    if (ClipOff(G[i])) Clipped = true;
    delete [] g;    
  }
  if (Clipped) printf("    !!!!Clipping G!!!!\n");

}
Пример #12
0
void SIAM::get_SOCSigma()
{
  int i,j;

  for (i=0; i<N; i++)
  { 
    //get integrand array
    double* s = new double[N];
    for (j=0; j<N; j++)      
       s[j] =   grid->interpl(Ap,omega[i]-omega[j])*P2[j] 
              + grid->interpl(Am,omega[i]-omega[j])*P1[j];
                         
    //integrate
    SOCSigma[i] = complex<double>(0.0, - U*U * TrapezIntegral(N, s,omega) );    
     
    if (ClipOff(SOCSigma[i])) Clipped = true ;
    delete [] s;
  }
  if (Clipped) printf("    !!!Clipping SOCSigma!!!!\n");
  grid->KramarsKronig(SOCSigma);
}
Пример #13
0
bool SIAM::Run_CHM(double n, complex<double>* Delta, //input
                   complex<double>* G_out, complex<double>* Sigma_out, double &mu_out) //output
{  
  if (!Initialized) exit(1);
  Clipped = false;
  for (int i=0; i<N; i++) if (ClipOff(Delta[i])) Clipped = true;
  if (Clipped) printf("    !!! Clipping Delta !!!\n");

  this->n = n;
  this->Delta = Delta;
  //PrintFunc("DeltaSiam",N,Delta,omega);
  this->epsilon = 0;

  if (n==0.5) HalfFilling = true; 
  else HalfFilling = false;
  
  printf("    ------- SIAM for CHM: n=%.3f, U=%.3f, T=%.3f, epsilon=%.3f -------\n", n, U, T, epsilon);
  
  if (HalfFilling) 
  {
    mu = 0.5*U;
    mu0 = 0.0;
    MPT_B = 0.0;
    MPT_B0 = 0.0;
    SymmetricCase = true;
  }

  //------initial guess---------//
  complex<double>* V = new complex<double>[1];
  V[0] = mu0; //initial guess is always the last mu0. in first DMFT iteration it is 0
  //---------------------------//

  printf("     MPT: B = %fe, B0 = %fe\n", MPT_B, MPT_B0);  

  //----------------- CALCULATION ----------------------//
  if (HalfFilling)//and (SymmetricCase))
    get_G0();
  else
    UseBroyden<SIAM>(1, MAX_ITS, Accr, &SIAM::get_G0, this, V);  

  printf("    mu0 = %f\n", mu0);

  printf("Integral G0: %.6f\n",imag(TrapezIntegral(N,G0,omega)));

  get_As();
  get_Ps();
  get_SOCSigma();

  V[0] = mu;
  
  if (HalfFilling)//and (SymmetricCase))
  { if (IsBethe)
    { get_Sigma();
      get_G();  //get_G() !!!! samo proba
  //    printf("        Integral G = %.6f\n",imag(TrapezIntegral(N,G,omega)));
    }
    else
      get_G_CHM();
  }
  else
  { if (IsBethe)
      UseBroyden<SIAM>(1, MAX_ITS, Accr, &SIAM::get_G, this, V);  
    else
      UseBroyden<SIAM>(1, MAX_ITS, Accr, &SIAM::get_G_CHM, this, V);
  }
  MPT_B = get_MPT_B();
  MPT_B0 = get_MPT_B0();

  printf("    mu = %f\n", mu);

  delete [] V;
  //-----------------------------------------------------//

  //output spectral weight if optioned
  if (CheckSpectralWeight)
  {
    printf("        Spectral weight G: %fe\n", -imag(TrapezIntegral(N,G,omega))/pi);
    printf("        Spectral weight G0: %fe\n", -imag(TrapezIntegral(N,G0,omega))/pi);
  }

  //-------- OUTPUT ---------//
  for (int i=0; i<N; i++)
  {
    G_out[i] = G[i];
    Sigma_out[i] = Sigma[i];
  }
  mu_out = mu;
  //-------------------------//
//  printf("     PROVERA: n = %f, U = %f \n",n, U); 
  return Clipped;
}