/* psi(z) for large |z| in the right half-plane; [Abramowitz + Stegun, 6.3.18] */ static gsl_complex psi_complex_asymp(gsl_complex z) { /* coefficients in the asymptotic expansion for large z; * let w = z^(-2) and write the expression in the form * * ln(z) - 1/(2z) - 1/12 w (1 + c1 w + c2 w + c3 w + ... ) */ static const double c1 = -0.1; static const double c2 = 1.0/21.0; static const double c3 = -0.05; gsl_complex zi = gsl_complex_inverse(z); gsl_complex w = gsl_complex_mul(zi, zi); gsl_complex cs; /* Horner method evaluation of term in parentheses */ gsl_complex sum; sum = gsl_complex_mul_real(w, c3/c2); sum = gsl_complex_add_real(sum, 1.0); sum = gsl_complex_mul_real(sum, c2/c1); sum = gsl_complex_mul(sum, w); sum = gsl_complex_add_real(sum, 1.0); sum = gsl_complex_mul_real(sum, c1); sum = gsl_complex_mul(sum, w); sum = gsl_complex_add_real(sum, 1.0); /* correction added to log(z) */ cs = gsl_complex_mul(sum, w); cs = gsl_complex_mul_real(cs, -1.0/12.0); cs = gsl_complex_add(cs, gsl_complex_mul_real(zi, -0.5)); return gsl_complex_add(gsl_complex_log(z), cs); }
/* psi(z) for complex z in the right half-plane */ static int psi_complex_rhp( gsl_complex z, gsl_sf_result * result_re, gsl_sf_result * result_im ) { int n_recurse = 0; int i; gsl_complex a; if(GSL_REAL(z) == 0.0 && GSL_IMAG(z) == 0.0) { result_re->val = 0.0; result_im->val = 0.0; result_re->err = 0.0; result_im->err = 0.0; return GSL_EDOM; } /* compute the number of recurrences to apply */ if(GSL_REAL(z) < 20.0 && fabs(GSL_IMAG(z)) < 20.0) { const double sp = sqrt(20.0 + GSL_IMAG(z)); const double sn = sqrt(20.0 - GSL_IMAG(z)); const double rhs = sp*sn - GSL_REAL(z); if(rhs > 0.0) n_recurse = ceil(rhs); } /* compute asymptotic at the large value z + n_recurse */ a = psi_complex_asymp(gsl_complex_add_real(z, n_recurse)); result_re->err = 2.0 * GSL_DBL_EPSILON * fabs(GSL_REAL(a)); result_im->err = 2.0 * GSL_DBL_EPSILON * fabs(GSL_IMAG(a)); /* descend recursively, if necessary */ for(i = n_recurse; i >= 1; --i) { gsl_complex zn = gsl_complex_add_real(z, i - 1.0); gsl_complex zn_inverse = gsl_complex_inverse(zn); a = gsl_complex_sub(a, zn_inverse); /* accumulate the error, to catch cancellations */ result_re->err += 2.0 * GSL_DBL_EPSILON * fabs(GSL_REAL(zn_inverse)); result_im->err += 2.0 * GSL_DBL_EPSILON * fabs(GSL_IMAG(zn_inverse)); } result_re->val = GSL_REAL(a); result_im->val = GSL_IMAG(a); result_re->err += 2.0 * GSL_DBL_EPSILON * fabs(result_re->val); result_im->err += 2.0 * GSL_DBL_EPSILON * fabs(result_im->val); return GSL_SUCCESS; }
gsl_complex f_envelope(gsl_complex p, const Params *params) { double m = params->m; gsl_complex env = gsl_complex_div( p, gsl_complex_sqrt(gsl_complex_add_real(gsl_complex_mul(p,p), m*m))); if (params->smear) { gsl_complex sp = gsl_complex_mul_real(p, params->sigma); env = gsl_complex_mul(env, gsl_complex_exp(gsl_complex_negative(gsl_complex_mul(sp, sp)))); } return env; }
/* Assuming z is in the (1,tau) parallelogram, return the point closest to the origin among all translates of z by the lattice. */ gsl_complex near_origin(gsl_complex z, gsl_complex tau) { gsl_complex znew; znew = gsl_complex_sub_real(z,1.0); if (gsl_complex_abs(z) > gsl_complex_abs(znew)) z = znew; znew = gsl_complex_sub(z,tau); if (gsl_complex_abs(z) > gsl_complex_abs(znew)) z = znew; znew = gsl_complex_sub(z,gsl_complex_add_real(tau,1.0)); if (gsl_complex_abs(z) > gsl_complex_abs(znew)) z = znew; return z; }
complex& complex::operator+=(const double& a) { _complex = gsl_complex_add_real(_complex,a); return *this; }
complex complex::operator+(const double& a) const { gsl_complex rl = gsl_complex_add_real(_complex,a); return complex(rl); }
/****************************************************************************** * calc_A() * This function calcs the A's for a given theta. * * Parameters * --------- * * Returns * ------- * * Notes * ----- * This function assumes that the X[j] and g[j] values have already * been calculated (see calc_X()) * * Note: X[j] = Ar[j]/Ai[j] * And we can derive: * * Ai[j] = phase*Ai[j+1]*t[j+1] / ( 1 + phase^2 * X[j] * r[j+1]) * Ar[j] = Ai[j]*X[j] * * where Ar[j] and Ai[j] are the field amplitudes within layer j at * the j/j-1 interface. * * For the top layer Ai[nlayer-1] = 1. ie everything is referenced to * unit intensity (Io=|Ai|^2) within the top layer. Therefore Ar[0] = X[0]. * * Given the known values for the top layer we can procede to calculate each Ai and Ar * value starting at the top. * * For the base layer X[0] = 0, ie Ar[0] = 0 * * The values of r[j+1] and t[j+1] are the reflection and transmission coefficients * for the j+1/j interface, respectively, and calculated from: * * r[j+1] = (g[j+1]-g[j])/(g[j+1]+g[j]) * t[j+1] = 2*g[j+1]/(g[j+1] + g[j]) = 1 + r[j+1] * * This function also includes an interfacial roughness term mult into * the reflection coefficient for the j+1/j interface: * * r[j+1] = r[j+1]*exp(-1.0(q*sig[j+1])^2) * * Note we include roughness in the t calc using the below: * t[j+1] = 1 + r[j+1]*exp(-1.0(q*sig[j+1])^2) * * Therefore as r-> 0, t-> 1. This is only done if calc_params[10] > 0. * Otherwise t is calc explicitley from the g's * * The phase term accounts for the phase shift and attentuation of the field * traversing the j layer (ie from the j+1/j interface to the j/j-1 interface), * ie the Ai[j] and Ar[j] are the field amplitudes at the j/j-1 interface: * * phase = exp( -i*k*d[j] * g[j]) * * Note if j == 0 then the phase for layer j is 0.0, and X[0] = 0 * ie in the infinitley thick base layer we assumer the is no reflected * field (Ar[0] = 0.0) and we are calculating the the field amplitude at the * top of layer 0 rather than the bottom of layer 0. * * * Note: double check how doing the phase calc below, is that the best way?? * e.g. could we use: * phase = gsl_complex_exp( gsl_complex_mul_real(g1,-1.0*k*d[j])); * instead of * phase = gsl_complex_exp( gsl_complex_mul(phase,g1)); * * ******************************************************************************/ int calc_A(double theta, ref_model *ref, angle_calc *ang_c, layer_calc *lay_c){ int i, j, idx; double cos_sqr_thet, k, q, dw; double *d, *sig; gsl_complex g1, g2, num, den, r, t, Ai_2, Ar_2, Ai_1, Ar_1, X1, phase, phase_sqr; //gsl_complex n1, n2; // convenience vars cos_sqr_thet = square(cos(theta*M_PI/180.)); k = ref->k; q = 2.0*k*sin((theta*M_PI/180.)); d = ref->d; sig = ref->sigma; // start at top idx = ref->nlayer - 1; // get g for upper layer, ie air/vaccum slab // ie del ~ bet ~ 0. // n = 1 - del -i*bet ~ 1 // g2 = sqrt( n^2 - cos(theta)^2 ) //GSL_REAL(n2) = 1.0 - lay_c->del[idx]; //GSL_IMAG(n2) = -1.0*lay_c->bet[idx]; //g2 = gsl_complex_sqrt( gsl_complex_sub_real(gsl_complex_mul(n2, n2), cos_sqr_thet) ); GSL_SET_COMPLEX(&g2,ang_c->Re_g[idx],ang_c->Im_g[idx]); // for the top (j=nlayer-1) layer, Ai =1.0 // therefore Ar = Ai*X = X // store these in A arrays ang_c->Re_Ai[idx] = GSL_REAL(Ai_2) = 1.0; ang_c->Im_Ai[idx] = GSL_IMAG(Ai_2) = 0.0; ang_c->Re_Ar[idx] = GSL_REAL(Ar_2) = ang_c->Re_X[idx]; ang_c->Im_Ar[idx] = GSL_IMAG(Ar_2) = ang_c->Im_X[idx]; // loop over all layers, start at top - 1 // ie loop from j = nlayer-2 --> j = 0 // note j is lower layer in the r and t calcs // therefore we are considering the j+1/j interface // i is the interface number, ie which interface // are the r's and t's calc for i = idx - 1; for ( j = idx - 1; j > -1 ; j--){ // calc g and phase for lower layer // n = 1 - del -i*bet // g1 = sqrt( n^2 - cos(theta)^2 ) //GSL_REAL(n1) = 1.0 - xpar->del[j]; //GSL_IMAG(n1) = -1.0 * xpar->bet[j]; //g1 = gsl_complex_sqrt( gsl_complex_sub_real(gsl_complex_mul(n1, n1), cos_sqr_thet) ); GSL_SET_COMPLEX(&g1,ang_c->Re_g[j],ang_c->Im_g[j]); //calc phase and attenuation // phase = exp( -i*k*d[j] * g1) // phase_sqr = (phase)^2 if (j == 0){ GSL_REAL(phase) = 1.0; GSL_IMAG(phase) = 0.0; GSL_REAL(phase_sqr) = 1.0; GSL_IMAG(phase_sqr) = 0.0; } else { GSL_REAL(phase) = 0.0; GSL_IMAG(phase) = -1.0*k*d[j]; phase = gsl_complex_exp( gsl_complex_mul(phase,g1)); GSL_REAL(phase_sqr) = 0.0; GSL_IMAG(phase_sqr) = -2.0*k*d[j]; phase_sqr = gsl_complex_exp( gsl_complex_mul(phase_sqr,g1)); } // calc r for upper layer // r = (g2-g1)/(g2+g1) GSL_SET_COMPLEX(&num,0.0,0.0); GSL_SET_COMPLEX(&den,0.0,0.0); num = gsl_complex_sub(g2,g1); den = gsl_complex_add(g2,g1); r = gsl_complex_div(num,den); // include simple dw type roughness // r = r*exp(-1.0(q*sig)^2) if (ref->sigma[j+1] > 0.0){ //dw = exp(-1.0*square(q*ref->sigma[j+1])); dw = exp(-1.0*square(q*ref->sigma[i])); r = gsl_complex_mul_real(r,dw); } // calc t for upper layer // t = 2*g2/(g2 + g1) if (ref->calc_params[10] == 0.0){ GSL_SET_COMPLEX(&num,0.0,0.0); num = gsl_complex_mul_real(g2, 2.0); t = gsl_complex_div(num,den); } else { // note as as r->0, t->1 // ie t = 1+r, so we could just calc t from r? t = gsl_complex_add_real(r,1.0); } // calc Ai_1 and Ar_1 // these are field mag in the lower slab (layer j) // at the bottom of the slab, relative to Ai in the top layer (j=nlayer-1) // Ai_1 = phase*Ai_2*t / ( 1 + phase^2 * X1 * r) // Ar_1 = Ai_1*X1 GSL_REAL(X1) = ang_c->Re_X[j]; GSL_IMAG(X1) = ang_c->Im_X[j]; GSL_SET_COMPLEX(&num,0.0,0.0); GSL_SET_COMPLEX(&den,0.0,0.0); num = gsl_complex_mul(t,gsl_complex_mul(Ai_2,phase)); den = gsl_complex_add_real(gsl_complex_mul(phase_sqr,gsl_complex_mul(X1,r)),1.0); Ai_1 = gsl_complex_div(num,den); if (fabs(GSL_REAL(Ai_1)) < 1.0e-12){ GSL_REAL(Ai_1) = 0.0; } if (fabs(GSL_IMAG(Ai_1)) < 1.0e-12){ GSL_IMAG(Ai_1) = 0.0; } Ar_1 = gsl_complex_mul(Ai_1,X1); //store results ang_c->Re_Ai[j] = GSL_REAL(Ai_1); ang_c->Im_Ai[j] = GSL_IMAG(Ai_1); ang_c->Re_Ar[j] = GSL_REAL(Ar_1); ang_c->Im_Ar[j] = GSL_IMAG(Ar_1); // this is the field intensity at the bottom of layer j // except for layer j = 0, this is the intensity at the top // of the base layer (bc of how phase is calc above) // use bottom layer as top for next time through GSL_REAL(Ai_2) = GSL_REAL(Ai_1); GSL_IMAG(Ai_2) = GSL_IMAG(Ai_1); GSL_REAL(Ar_2) = GSL_REAL(Ar_1); GSL_IMAG(Ar_2) = GSL_IMAG(Ar_1); // do the same for g's GSL_REAL(g2) = GSL_REAL(g1); GSL_IMAG(g2) = GSL_IMAG(g1); // increment interface number i--; } return (SUCCESS); }
/****************************************************************************** * calc_X() * This function calcs the X's and g's for a given theta. * * Parameters * --------- * * Returns * ------- * * Notes * ----- * This function computes * X[j] = Ar[j]/Ai[j] * where Ar[j] and Ai[j] are the field amplitdues within layer j at * the j/j-1 interface. For the base layer X[0] = 0, * ie there is no reflected field in the substrate. While * X[nlayers-1] is the field intensity at the top of the multilayer, * therefore |X[nlayers-1]|^2 = R * * The X's are calculated using the optical recursion formlua, starting at the bottom * where X[0] = 0 and calc X[1], and proceding to calc of X[nlayer-1]: * * X[j] = ( r[j] + X[j-1]*phase) / (1 + r[j]*X[j-1]*phase) * * The r[j] values are the reflection coefficients for the j/j-1 interface, * and calculated from: * * r[j] = (g[j]-g[j-1])/(g[j]+g[j-1]) * * This function also includes an interfacial roughness term mult into * the reflection coefficient for the j/j-1 interface: * * r[j] = r[j]*exp(-1.0(q*sig[j])^2) * * The phase term accounts for the phase shift and attentuation of the field * traversing the j-1 layer (ie from the j-1/j-2 interface to the j/j-1 interface) * * phase = exp( -i* 2*k*d[j-1] * g[j-1]) * * Note if j == 1 then the phase for layer j-1 is 0.0, * ie infinitley thick base layer * * Note: g[j] = sqrt( n[j]^2 - cos(theta)^2 ) * where n[j] is the layers index of refraction: n[j] = 1-del[j]-i*bet[j] * Hence, each layer has a unique g value. We assume here * that the del[j] and bet[j] have already been calculated * (see calc_del_bet(), this should be called before this function). * * * Note: double check how doing the phase calc below, is that the best way?? * e.g. could we use: * phase = gsl_complex_exp( gsl_complex_mul_real(g1,-1.0*k*d[j])); * instead of * phase = gsl_complex_exp( gsl_complex_mul(phase,g1)); * * Note we should move the g and r calc to a new function, possibly calc the * t values as well and store these so we dont have to recalc in calc_A() (???) * ******************************************************************************/ int calc_X(double theta, ref_model *ref, angle_calc *ang_c, layer_calc *lay_c){ int i, j; double cos_sqr_thet, k, q, dw; double *d, *sig; gsl_complex g1, g2, num, den, r, X2, X1, n1, n2, phase; // convenience vars cos_sqr_thet = square(cos(theta*M_PI/180.)); k = ref->k; q = 2.0*k*sin((theta*M_PI/180.)); d = ref->d; sig = ref->sigma; // start at bottom // ie interface 0 ang_c->Re_X[0] = GSL_REAL(X1) = 0.0; ang_c->Im_X[0] = GSL_IMAG(X1) = 0.0; // calc g for base layer (g[0]) // n = 1 - del -i*bet // g = sqrt( n^2 - cos(theta)^2 ) GSL_REAL(n1) = 1.0 - lay_c->del[0]; GSL_IMAG(n1) = -1.0*lay_c->bet[0]; g1 = gsl_complex_sqrt( gsl_complex_sub_real(gsl_complex_mul(n1, n1), cos_sqr_thet) ); // store g for base layer ang_c->Re_g[0] = GSL_REAL(g1); ang_c->Im_g[0] = GSL_IMAG(g1); // loop over all layers // note j is upper layer and i is the interface number // the loop starts considering the first interface (i=0) // which is the interface between the base layer (j=0) // and the first layer (j=1) ie the 1/0 interface // note there are nlayer-1 interfaces... i = 0; for ( j = 1; j < ref->nlayer; j++){ // calc g for upper layer // n = 1 - del -i*bet // g2 = sqrt( n^2 - cos(theta)^2 ) GSL_REAL(n2) = 1.0 - lay_c->del[j]; GSL_IMAG(n2) = -1.0 * lay_c->bet[j]; g2 = gsl_complex_sqrt( gsl_complex_sub_real(gsl_complex_mul(n2, n2), cos_sqr_thet) ); // store g for layer j ang_c->Re_g[j] = GSL_REAL(g2); ang_c->Im_g[j] = GSL_IMAG(g2); // calculate r for the j/j-1 interface // r_j = (g2-g1)/(g2+g1) //GSL_SET_COMPLEX(&num,0.0,0.0); //GSL_SET_COMPLEX(&den,0.0,0.0); //GSL_SET_COMPLEX(&r,0.0,0.0); num = gsl_complex_sub(g2,g1); den = gsl_complex_add(g2,g1); r = gsl_complex_div(num,den); // calc r including roughness // simple dw roughness model // r = r*exp(-1.0(q*sig)^2) // sigma[i] if (ref->sigma[j] > 0.0){ //dw = exp(-1.0*square(q*ref->sigma[j])); dw = exp(-1.0*square(q*ref->sigma[i])); r = gsl_complex_mul_real(r,dw); } //calc phase shift and attentuation for //field traversing the j-1 layer //phase = exp( -i* 2*k*d[j-1] * g1) // if j == 1 then the phase for layer j-1 // is 0.0, ie infinitley thick base layer if (j == 1){ GSL_REAL(phase) = 0.0; GSL_IMAG(phase) = 0.0; } else { // check here GSL_REAL(phase) = 0.0; GSL_IMAG(phase) = -2.0*k*d[j-1]; phase = gsl_complex_exp( gsl_complex_mul(phase,g1)); } // calc Xj // X2 = ( r + X1*phase) / (1 + r*X1*phase) //GSL_SET_COMPLEX(&num,0.0,0.0); //GSL_SET_COMPLEX(&den,0.0,0.0); num = gsl_complex_add(r,gsl_complex_mul(X1,phase)); den = gsl_complex_add_real(gsl_complex_mul(r,gsl_complex_mul(X1,phase)), 1.0); X2 = gsl_complex_div(num,den); if (fabs(GSL_REAL(X2)) < 1e-10){ GSL_REAL(X2) = 0.0; } if (fabs(GSL_IMAG(X2)) < 1e-10){ GSL_IMAG(X2) = 0.0; } // store values of Xj ang_c->Re_X[j] = GSL_REAL(X2); ang_c->Im_X[j] = GSL_IMAG(X2); // use top layer as bottom for next time through GSL_REAL(X1) = GSL_REAL(X2); GSL_IMAG(X1) = GSL_IMAG(X2); // do the same for g's GSL_REAL(g1) = GSL_REAL(g2); GSL_IMAG(g1) = GSL_IMAG(g2); //increment the interface number i++; } return (SUCCESS); }
int main(int argc, char *argv[]){ int i,j,k, c, N; int dflag=0, eflag=0, gflag=0, vflag=0, hflag=0; float w; /* frec */ //char *lvalue=NULL; double **M, // XYZ coordinates dos, lambda=0; while((c = getopt (argc, argv, "degvhl:")) != -1){ switch (c){ case 'd': dflag = 1; break; case 'e': eflag = 1; break; case 'g': gflag = 1; break; case 'v': vflag = 1; break; case 'h': hflag = 1; break; case 'l': lambda = atof(optarg); break; } } scanf("%d",&N); M = (double **) malloc (N*sizeof(double *)); // coordinate matrix // read coordinates (XYZ format file) for (int i=0; i<N; i++){ char null[5]; // discard element double *tmp = (double *) malloc (3 * sizeof(double)); // 3 coordinates scanf("%s%lf%lf%lf", null, &tmp[0], &tmp[1], &tmp[2]); M[i] = tmp; // printf("- %.2f %.2f\n",M[i][0], M[i][1]); // DEBUG } /* M: coordinate matrix, N: number of atoms, l: spin-orbit parameter (set to 0 to tight-binding)*/ gsl_matrix_complex * Hso = hamiltonian(M, N, lambda); /* print hamiltonial */ if (hflag){ printComMat(Hso,N*SPIN*ORB); return 0; } /* eigenvalues */ gsl_matrix_complex * evec = gsl_matrix_complex_alloc(N*SPIN*ORB, N*SPIN*ORB); gsl_vector * eval = gsl_vector_alloc(N*SPIN*ORB); gsl_eigen_hermv_workspace * ws = gsl_eigen_hermv_alloc(N*SPIN*ORB); gsl_matrix_complex * A = Hso; // gsl_eigen_hermv() destroys Hso matrix, use a copy instead gsl_eigen_hermv (A, eval, evec, ws); gsl_eigen_hermv_sort (eval, evec, GSL_EIGEN_SORT_VAL_ASC); gsl_eigen_hermv_free(ws); if (eflag){ for (int i=0; i<N*SPIN*ORB; i++) printf("%d %.4g \n", i, gsl_vector_get(eval,i)); return 0; } if (vflag){ printComMat(evec, N*SPIN*ORB); return 0; } /* calculate DoS * __ __ * \ \ Hij Hji * DOS(E) = -imag /_ /_ ---------------- * i j E - En + i*eta * * where H is the hamiltonian, and n is the state. * NOTE: i and j 0-indexed list. i*eta */ double eval_min = gsl_vector_min (eval), /* lower bound */ eval_max = gsl_vector_max (eval); /* upper bound */ if (dflag) for (w = eval_min; w < eval_max; w += 1e-3){ dos = 0; #pragma omp parallel num_threads(4) { int tid = omp_get_thread_num(); #pragma omp for private(i,k) reduction (+:dos) for (i=0; i<N*SPIN*ORB; i++) for (k=0; k<N*SPIN*ORB; k++){ gsl_complex h = gsl_matrix_complex_get (Hso, i, k); double l = gsl_vector_get (eval ,k); gsl_complex z = gsl_complex_rect(0,5e-3); /* parte imaginaria */ gsl_complex num = gsl_complex_mul(h,gsl_complex_conjugate(h)); /* numerador */ gsl_complex den = gsl_complex_add_real(z, w-l); /* denominador */ gsl_complex g = gsl_complex_div(num,den); dos += GSL_IMAG(g); } if (dflag && tid==0) printf("%.3g %g \n", w, -dos/PI); } } /* Green's function * * <i|n> <n|j> * Gij(E) = ---------------- * E - En + i*eta * * where i and j are atoms, and n is the state. * NOTE: i and j 0-indexed list. */ int list[]={0,1,2,5,6,7}; /* atoms to get conductance */ int NL = (int) sizeof(list)/sizeof(list[0]); gsl_matrix_complex * G = gsl_matrix_complex_alloc(NL*SPIN*ORB, NL*SPIN*ORB); // Green if (gflag) for (double E = eval_min; E < eval_max; E += 1e-3){ // energy gsl_matrix_complex_set_all(G, GSL_COMPLEX_ZERO); // init for (int n=0; n<N*SPIN*ORB; n++) // states for (i=0; i<NL; i++) // atoms for (j=0; j<NL; j++) // atoms for (int k0=0; k0<SPIN*ORB; k0++){ // orbitals for (int k1=0; k1<SPIN*ORB; k1++){ // orbitals gsl_complex in = gsl_matrix_complex_get (evec, n, list[i]*SPIN*ORB+k0); gsl_complex nj = gsl_matrix_complex_get (evec, n, list[j]*SPIN*ORB+k1); double En = gsl_vector_get (eval ,n); gsl_complex eta = gsl_complex_rect(0,5e-3); /* delta */ gsl_complex num = gsl_complex_mul(in, gsl_complex_conjugate(nj)); /* num */ gsl_complex den = gsl_complex_add_real(eta, E - En); /* den */ gsl_complex Gij = gsl_complex_div(num,den); gsl_complex tmp = gsl_matrix_complex_get(G, i*SPIN*ORB+k0, j*SPIN*ORB+k1); gsl_complex sum = gsl_complex_add(tmp, Gij); gsl_matrix_complex_set(G, i*SPIN*ORB+k0, j*SPIN*ORB+k1, sum); } } dos = 0 ; for(int i=0; i<NL*SPIN*ORB; i++) dos += GSL_IMAG( gsl_matrix_complex_get(G, i, i) ); printf("%.3g %g\n", E, -dos/PI); // printComMat(G, NL*SPIN*ORB); } gsl_matrix_complex_free(G); gsl_vector_free(eval); gsl_matrix_complex_free(evec); return 0; }