Example #1
0
File: psi.c Project: gaow/kbac
/* 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);
}
Example #2
0
/* 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;
}
Example #3
0
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;
}
Example #4
0
/* 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;
}
Example #5
0
 complex& complex::operator+=(const double& a)
 {
   _complex = gsl_complex_add_real(_complex,a);
   return *this;
 }
Example #6
0
 complex complex::operator+(const double& a) const
 {
   gsl_complex rl = gsl_complex_add_real(_complex,a);
   return complex(rl);
 }
Example #7
0
File: xrr.c Project: FHe/tdl
/******************************************************************************
* 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);
}
Example #8
0
File: xrr.c Project: FHe/tdl
/******************************************************************************
* 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);
}
Example #9
0
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;
}