void SIAM::get_fermi() { #pragma omp parallel for for (int i=0; i<N; i++) { //printf("tid: %d i: %d\n",omp_get_thread_num(),i); r->fermi[i] = get_fermi(i); } }
void SIAM::InitImpurity(double U, double T, double epsilon) { //printf("SIAM Initialize: epsilon = %f",epsilon); this->epsilon = epsilon; this->U = U; this->T = T; for (int i=0; i<N; i++) fermi[i] = get_fermi(i); }
void SIAM::PrepareArrays() { fermi = new double[N]; G0 = new complex<double>[N]; Ap = new double[N]; Am = new double[N]; P1 = new double[N]; P2 = new double[N]; SOCSigma = new complex<double>[N]; Sigma = new complex<double>[N]; G = new complex<double>[N]; for (int i=0; i<N; i++) fermi[i] = get_fermi(i); Initialized = true; }
bool SIAM::Run_CHM(Result* r) //output { this->r = r; N = r->grid->get_N(); grid = r->grid; get_fermi(); Clipped = false; epsilon = 0; if (r->n==0.5) HalfFilling = true; else HalfFilling = false; printf(" ------- SIAM for CHM: n=%.3f, U=%.3f, T=%.3f, epsilon=%.3f -------\n", r->n, U, T, epsilon); if (HalfFilling) { r->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); get_As(); get_Ps(); get_SOCSigma(); V[0] = r->mu; if (HalfFilling)//and (SymmetricCase)) { if (isBethe) { get_Sigma(); get_G(); } 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", r->mu); delete [] V; //-----------------------------------------------------// //output spectral weight if optioned if (CheckSpectralWeight) { printf(" n0: %.6f\n", get_n(r->G0)); printf(" n: %.6f\n", get_n(r->G)); } // fill in DOS #pragma omp parallel for for (int i=0; i<N; i++) r->DOS[i] = - imag(r->G[i]) / pi; r->mu0 = mu0; return false; }
bool SIAM::Run(Result* r) //output { this->r = r; N = r->grid->get_N(); grid = r->grid; get_fermi(); Clipped = false; if ((r->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" : "Asymmetric", r->mu, U, T, epsilon); //----- initial guess ------// r->n = 0.5; mu0 = r->mu0; 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 ---------// double mu0inits [] = {0.0, 1.0, -1.0, -0.8, 2.0, 1.5, -1.5, 2.5, -2.5, -2.0, 0.05, 0.8, 0.1, -0.1, 0.3, -0.3, 0.5, -0.5, -0.05, 0.4, -0.4, 0.6, -0.6, 2.3, -2.3, 2.8, -2.8, 1.8, -1.8 }; if (SymmetricCase) //mu0 and n are known => there's no solving of system of equations SolveSiam(V); else { int c = 0; while ( UseBroyden<SIAM>(2, MAX_ITS, Accr, &SIAM::SolveSiam, this, V) != 1 ) { c++; if ( c > sizeof(mu0inits)/sizeof(double) - 1 ) { printf("\n\n\n\n==== ERROR ====: SIAM Failed to converge!!!\n\n\n\n"); return true; } V[0] = mu0inits[c]; V[1] = MPT_B; printf("==================== ====================== ========== TRYING new mu0 int!!! c = %d, mu0init = %f\n\n\n",c, mu0inits[c]); }; //use broyden to solve system of two equations } delete [] V; //----------------------------// //output spectral weight if optioned if (CheckSpectralWeight) { printf(" Spectral weight G: %fe\n", -imag(TrapezIntegralMP(N, r->G, r->omega))/pi); printf(" Spectral weight G0: %fe\n", -imag(TrapezIntegralMP(N, r->G0, r->omega))/pi); } r->mu0 = mu0; return Clipped; }