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; }
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; }
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; }
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 ); }
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; }
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; } }
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; }
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; }
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"); } }
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; }
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"); }
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); }
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; }