예제 #1
0
/*
   In:  tau (lattice parameter)
   Out: g2 -> g[0]
        g3 -> g[1]
*/
void compute_invariants(gsl_complex tau, gsl_complex *g)
{
  gsl_complex q, q14;
  gsl_complex t2,t3,t24,t34;
  gsl_complex g3_term1, g3_term2;
  gsl_complex g2, g3;

  q = gsl_complex_exp(gsl_complex_mul_imag(tau,M_PI));
  q14 = gsl_complex_exp(gsl_complex_mul_imag(tau,M_PI_4));

  t2=theta20(q,q14);
  t3=theta30(q);
  t24 = pow4(t2);
  t34 = pow4(t3);

  g2 = gsl_complex_mul_real(gsl_complex_sub(gsl_complex_add(gsl_complex_mul(t24,t24),gsl_complex_mul(t34,t34)),gsl_complex_mul(t24,t34)),_CONST_43PI4);

  g3_term1 = gsl_complex_add(gsl_complex_mul(t24,gsl_complex_mul(t24,t24)),gsl_complex_mul(t34,gsl_complex_mul(t34,t34)));
  
  g3_term2 = gsl_complex_mul(gsl_complex_add(t24,t34),gsl_complex_mul(t24,t34));

  g3 = gsl_complex_sub( gsl_complex_mul_real(g3_term1, _CONST_827PI6),
			gsl_complex_mul_real(g3_term2, _CONST_49PI6) );

  g[0] = g2;
  g[1] = g3;
}
예제 #2
0
void expm(gsl_matrix_complex * L, gsl_complex t, gsl_matrix * m)
     {
    int i,j,s;
	gsl_vector_complex *eval = gsl_vector_complex_alloc(4);
	gsl_matrix_complex *evec = gsl_matrix_complex_alloc(4, 4);
	gsl_eigen_nonsymmv_workspace * w = gsl_eigen_nonsymmv_alloc(4);
	gsl_matrix_complex *evalmat = gsl_matrix_complex_alloc(4, 4);
	gsl_matrix_complex *vd = gsl_matrix_complex_alloc(4, 4);
	gsl_complex one = gsl_complex_rect(1, 0);
	gsl_complex zero = gsl_complex_rect(0, 0);

	gsl_matrix_complex *K = gsl_matrix_complex_alloc(4, 4);
	gsl_permutation *p = gsl_permutation_alloc(4);
	gsl_vector_complex *x = gsl_vector_complex_alloc(4);

	gsl_vector_complex_view bp;
	gsl_complex z;

	gsl_eigen_nonsymmv(m, eval, evec, w);
	gsl_eigen_nonsymmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC);

	gsl_eigen_nonsymmv_free(w); // clear workspace

	for (i = 0; i < 4; i++)
	{
		gsl_complex eval_i = gsl_vector_complex_get(eval, i);
		gsl_complex expeval = gsl_complex_mul(eval_i,t);
		expeval = gsl_complex_exp(expeval);
		gsl_matrix_complex_set(evalmat, i, i, expeval);
	}

	gsl_vector_complex_free(eval); // clear vector for eigenvalues

	// v'L'=De'v'
	gsl_blas_zgemm(CblasTrans, CblasTrans, one, evalmat, evec, zero, vd);
	gsl_matrix_complex_transpose(evec);//transpose v

	gsl_matrix_complex_memcpy(K,evec);

	for (i = 0; i < 4; i++)
	{
		bp = gsl_matrix_complex_column(vd, i);
		gsl_linalg_complex_LU_decomp(evec, p, &s);
		gsl_linalg_complex_LU_solve(evec, p, &bp.vector, x);
			for (j = 0; j < 4; j++)
			{
				z = gsl_vector_complex_get(x, j);
				gsl_matrix_complex_set(L,i,j,z); //'through the looking glass' transpose
			}
		gsl_matrix_complex_memcpy(evec,K);
	}


	gsl_permutation_free(p);
	gsl_vector_complex_free(x);
	gsl_matrix_complex_free(vd);
	gsl_matrix_complex_free(evec);
	gsl_matrix_complex_free(evalmat);
	gsl_matrix_complex_free(K);
}
예제 #3
0
gsl_complex f_integrand(gsl_complex p, const Params *params)
{
    double r = params->r;

    return gsl_complex_mul(
            f_envelope(p, params),
            gsl_complex_exp(gsl_complex_mul_imag(p, r)));
}
예제 #4
0
파일: xrr.c 프로젝트: FHe/tdl
/******************************************************************************
* calc_I()
* Calculate the field intensity at an arbitrary point within layer 
* 
* Parameters
* ---------
*
* Returns
* -------
*
* Notes
* -----
* Note assume that 0 <= z <= d[j] (but we dont check that here)
* except for the base layer (j==0), in that case z <= 0
*
******************************************************************************/
double calc_I(int layer_idx, double z, ref_model *ref, angle_calc *ang_c, layer_calc *lay_c){
    double  I, k;
    gsl_complex Ai, Ar, Ei, Er, g, phase_i, phase_r;

    k = ref->k;

    GSL_REAL(Ai) = ang_c->Re_Ai[layer_idx];
    GSL_IMAG(Ai) = ang_c->Im_Ai[layer_idx];
    GSL_REAL(Ar) = ang_c->Re_Ar[layer_idx];
    GSL_IMAG(Ar) = ang_c->Im_Ar[layer_idx];
    GSL_REAL(g)  = ang_c->Re_g[layer_idx];
    GSL_IMAG(g)  = ang_c->Im_g[layer_idx];

    // calculate Ei at z within layer j
    // make sure z is neg for base layer
    if (layer_idx == 0){
        if (z > 0) z = -1.0*z;
    } else {
        if (z < 0) z = -1.0*z;
    }
    GSL_REAL(phase_i) = 0.0;
    GSL_IMAG(phase_i) = 1.0*k*z;
    phase_i = gsl_complex_exp( gsl_complex_mul(phase_i,g));
    Ei = gsl_complex_mul(Ai,phase_i);

    // calculate Er at z within layer j
    if (layer_idx > 0) {    
        GSL_REAL(phase_r) = 0.0;
        GSL_IMAG(phase_r) = -1.0*k*z;
        phase_r = gsl_complex_exp( gsl_complex_mul(phase_r,g));
        Er = gsl_complex_mul(Ar,phase_r);
    } else {
        GSL_REAL(phase_r) = 0.0;
        GSL_IMAG(phase_r) = 0.0;
        GSL_REAL(Er) = 0.0;
        GSL_IMAG(Er) = 0.0;
    }

    I = gsl_complex_abs2(gsl_complex_add(Ei,Er));
    return (I);
}
예제 #5
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;
}
예제 #6
0
 /** exponentioal of a complex number
 \ingroup complex
 \param[in] z Complex number
 \return \f$ e^z \f$*/
 complex exp(const complex& z)
 {
   return complex(gsl_complex_exp(z.as_gsl_type()));
 }
예제 #7
0
void Spectrometer::countAmplitudes_bulk_B(Medium &Osrodek, QString DataName, QProgressBar *Progress, QTextBrowser *Browser, double kx, double ky, double w, int polarisation, double x_lenght, double y_lenght, double precision) {

    double a=Osrodek.itsBasis.getLatticeConstant();

    int RecVec=itsRecVectors;

    int dimension=3*(2*RecVec+1)*(2*RecVec+1);

    std::ofstream plik;
    DataName="results/amplitudes/"+ DataName + ".dat";
    QByteArray   bytes  = DataName.toAscii();
    const char * CDataName = bytes.data();
    plik.open(CDataName);

    //inicjalizacje wektorów i macierzy
    gsl_matrix *gamma=gsl_matrix_calloc(dimension, dimension);
    gsl_matrix *V=gsl_matrix_calloc(dimension, dimension);
    gsl_vector *S=gsl_vector_calloc(dimension);
    gsl_vector *work=gsl_vector_calloc(dimension);


    //gamma dla Podłoża
    /*
    S - numeruje transformaty tensora sprężystoœci i gestosci
    i - numeruje wiersze macierzy
    j - numeruje kolumny macierzy
    */
    for(int Nx=-RecVec, i=0, S=0; Nx<=RecVec; Nx++) {
        for(int Ny=-RecVec; Ny<=RecVec; Ny++, i=i+3) {
            for(int Nx_prim=-RecVec, j=0; Nx_prim<=RecVec; Nx_prim++) {
                for(int Ny_prim=-RecVec; Ny_prim<=RecVec; Ny_prim++, j=j+3, S++) {

                    double Elasticity[6][6];
                    itsRecBasisSubstance[S].getElasticity(Elasticity);
                    double Density=itsRecBasisSubstance[S].getDensity();
                    double gx=2*M_PI*Nx/a;
                    double gy=2*M_PI*Ny/a;
                    double gx_prim=2*M_PI*Nx_prim/a;
                    double gy_prim=2*M_PI*Ny_prim/a;

                    gsl_matrix_set(gamma, i, j, Elasticity[0][0]*(kx+gx)*(kx+gx_prim)+Elasticity[3][3]*(ky+gy)*(ky+gy_prim)-Density*w*w);
                    gsl_matrix_set(gamma, i+1, j, Elasticity[0][1]*(kx+gx_prim)*(ky+gy)+Elasticity[3][3]*(ky+gy_prim)*(kx+gx));
                    gsl_matrix_set(gamma, i, j+1, Elasticity[0][1]*(ky+gy_prim)*(kx+gx)+Elasticity[3][3]*(kx+gx_prim)*(ky+gy));
                    gsl_matrix_set(gamma, i+1, j+1, Elasticity[0][0]*(ky+gy_prim)*(ky+gy)+Elasticity[3][3]*(kx+gx_prim)*(kx+gx)-Density*w*w);
                    gsl_matrix_set(gamma, i+2, j+2, Elasticity[3][3]*(ky+gy_prim)*(ky+gy)+Elasticity[3][3]*(kx+gx_prim)*(kx+gx)-Density*w*w);

                }
            }
        }
    }

    //rozwiązanie układu równań
    gsl_linalg_SV_decomp(gamma, V, S, work);

    gsl_complex u;
    double Gx, Gy;

    if (polarisation==3) {

        gsl_complex ux, uy, uz;

        for(double x=0; x < x_lenght; x=x+precision) {
            for(double y=0; y < y_lenght; y=y+precision) {
                ux = gsl_complex_rect(0, 0);
                uy = gsl_complex_rect(0, 0);
                uz = gsl_complex_rect(0, 0);

                //pasek postepu
                int postep=int(100*x/x_lenght);
                Progress->setValue(postep);
                Progress->update();
                QApplication::processEvents();

                for (int Nx=-RecVec, i=0; Nx <= RecVec; Nx++) {
                    for (int Ny=-RecVec; Ny <= RecVec; Ny++, i=i+3) {

                        Gx=2*M_PI*Nx/a;
                        Gy=2*M_PI*Ny/a;

                        double Ax = gsl_matrix_get(V, i, dimension-1);
                        double Ay = gsl_matrix_get(V, i+1, dimension-1);
                        double Az = gsl_matrix_get(V, i+2, dimension-1);

                        gsl_complex expin1 = gsl_complex_rect(0, (kx+Gx)*x+(ky+Gy)*y);
                        gsl_complex exp1 = gsl_complex_exp(expin1);

                        gsl_complex multiply = gsl_complex_mul_real(exp1, Ax);
                        ux = gsl_complex_add(ux, multiply);

                        expin1 = gsl_complex_rect(0, (kx+Gx)*x+(ky+Gy)*y);
                        exp1 = gsl_complex_exp(expin1);

                        multiply = gsl_complex_mul_real(exp1, Ay);
                        uy = gsl_complex_add(uy, multiply);

                        expin1 = gsl_complex_rect(0, (kx+Gx)*x+(ky+Gy)*y);
                        exp1 = gsl_complex_exp(expin1);

                        multiply = gsl_complex_mul_real(exp1, Az);
                        uz = gsl_complex_add(uz, multiply);
                    }
                }

                double U = sqrt(gsl_complex_abs(ux)*gsl_complex_abs(ux)+gsl_complex_abs(uy)*gsl_complex_abs(uy)+gsl_complex_abs(uz)*gsl_complex_abs(uz));

                //zapisanie wartości do pliku
                QString nazwa = Osrodek.itsBasis.getFillingSubstance().getName();
                if(nazwa=="Air")
                {
                    double rad=Osrodek.itsBasis.getRadius();
                    if(sqrt(x*x+y*y) > rad && sqrt((a-x)*(a-x)+y*y) > rad && sqrt((a-x)*(a-x)+(a-y)*(a-y)) > rad && sqrt((a-y)*(a-y)+x*x) > rad)
                    {
                        plik << x << "\t" << y << "\t" << U << "\n";
                    }
                } else {
                    plik << x << "\t" << y << "\t" << U << "\n";
                }

            }



            plik << "\n";
        }

    } else if (polarisation==4) {

            gsl_complex uxx, uxy, uxz, uyx, uyy, uyz, uzx, uzy, uzz;
            double Uxx, Uxy, Uxz, Uyx, Uyy, Uyz, Uzx, Uzy, Uzz;

            for(double x=0; x < x_lenght; x=x+precision) {
                for(double y=0; y < y_lenght; y=y+precision) {

                    uxx = gsl_complex_rect(0, 0);
                    uxy = gsl_complex_rect(0, 0);
                    uxz = gsl_complex_rect(0, 0);
                    uyx = gsl_complex_rect(0, 0);
                    uyy = gsl_complex_rect(0, 0);
                    uyz = gsl_complex_rect(0, 0);
                    uzx = gsl_complex_rect(0, 0);
                    uzy = gsl_complex_rect(0, 0);
                    uzz = gsl_complex_rect(0, 0);

                    double rad=Osrodek.itsBasis.getRadius();
                    double Ela[6][6];
                    if(sqrt(x*x+y*y) > rad && sqrt((a-x)*(a-x)+y*y) > rad && sqrt((a-x)*(a-x)+(a-y)*(a-y)) > rad && sqrt((a-y)*(a-y)+x*x) > rad)
                    {
                        Osrodek.itsBasis.getSubstance().getElasticity(Ela);
                    } else {
                        Osrodek.itsBasis.getFillingSubstance().getElasticity(Ela);
                    }

                    //pasek postepu
                    int postep=int(100*x/x_lenght);
                    Progress->setValue(postep);
                    Progress->update();
                    QApplication::processEvents();

                    for (int Nx=-RecVec, i=0; Nx <= RecVec; Nx++) {
                        for (int Ny=-RecVec; Ny <= RecVec; Ny++, i=i+3) {

                            Gx=2*M_PI*Nx/a;
                            Gy=2*M_PI*Ny/a;

                            double Ax = gsl_matrix_get(V, i, dimension-1);
                            double Ay = gsl_matrix_get(V, i+1, dimension-1);
                            double Az = gsl_matrix_get(V, i+2, dimension-1);

                            gsl_complex expin1 = gsl_complex_rect(0, (kx+Gx)*x+(ky+Gy)*y);
                            gsl_complex exp1 = gsl_complex_exp(expin1);

                            gsl_complex multiply = gsl_complex_mul_real(exp1, Ax);

                            //uxx
                            gsl_complex multidiff = gsl_complex_mul(multiply, gsl_complex_mul_real(gsl_complex_rect(0,1), kx+Gx));
                            uxx = gsl_complex_add(uxx, multidiff);

                            //uxy
                            multidiff = gsl_complex_mul(multiply, gsl_complex_mul_real(gsl_complex_rect(0,1), ky+Gy));
                            uxy = gsl_complex_add(uxy, multidiff);


                            expin1 = gsl_complex_rect(0, (kx+Gx)*x+(ky+Gy)*y);
                            exp1 = gsl_complex_exp(expin1);

                            //uy
                            multiply = gsl_complex_mul_real(exp1, Ay);

                            //uyx
                            multidiff = gsl_complex_mul(multiply, gsl_complex_mul_real(gsl_complex_rect(0,1), kx+Gx));
                            uyx = gsl_complex_add(uyx, multidiff);

                            //uyy
                            multidiff = gsl_complex_mul(multiply, gsl_complex_mul_real(gsl_complex_rect(0,1), ky+Gy));
                            uyy = gsl_complex_add(uyy, multidiff);

                            expin1 = gsl_complex_rect(0, (kx+Gx)*x+(ky+Gy)*y);
                            exp1 = gsl_complex_exp(expin1);

                            multiply = gsl_complex_mul_real(exp1, Az);

                            //uzx
                            multidiff = gsl_complex_mul(multiply, gsl_complex_mul_real(gsl_complex_rect(0,1), kx+Gx));
                            uzx = gsl_complex_add(uzx, multidiff);

                            //uzy
                            multidiff = gsl_complex_mul(multiply, gsl_complex_mul_real(gsl_complex_rect(0,1), ky+Gy));
                            uzy = gsl_complex_add(uzy, multidiff);
                        }
                    }

                    Uxx=gsl_complex_abs(uxx);
                    Uxy=gsl_complex_abs(uxy);
                    Uxz=gsl_complex_abs(uxz);
                    Uyx=gsl_complex_abs(uyx);
                    Uyy=gsl_complex_abs(uyy);
                    Uyz=gsl_complex_abs(uyz);
                    Uzx=gsl_complex_abs(uzx);
                    Uzy=gsl_complex_abs(uzy);
                    Uzz=gsl_complex_abs(uzz);

                    double U = Ela[0][0]*(Uxx*Uxx+Uyy*Uyy+Uzz*Uzz)+2*Ela[0][1]*(Uxx*Uyy+Uxx*Uzz+Uyy*Uzz)+0.25*Ela[3][3]*((Uyz+Uzy)*(Uyz+Uzy)+(Uxz+Uzx)*(Uxz+Uzx)+(Uxy+Uyx)*(Uxy+Uyx));

                    //zapisanie wartości do pliku
                    QString nazwa = Osrodek.itsBasis.getFillingSubstance().getName();
                    if(nazwa=="Air")
                    {
                        double rad=Osrodek.itsBasis.getRadius();
                        if(sqrt(x*x+y*y) > rad && sqrt((a-x)*(a-x)+y*y) > rad && sqrt((a-x)*(a-x)+(a-y)*(a-y)) > rad && sqrt((a-y)*(a-y)+x*x) > rad)
                        {
                            plik << x << "\t" << y << "\t" << U << "\n";
                        }
                    } else {
                        plik << x << "\t" << y << "\t" << U << "\n";
                    }

                }



                plik << "\n";
            }


    } else {

        for(double x=0; x < x_lenght; x=x+precision) {
            for(double y=0; y < y_lenght; y=y+precision) {
                u = gsl_complex_rect(0, 0);

                //pasek postepu
                int postep=int(100*x/x_lenght);
                Progress->setValue(postep);
                Progress->update();
                QApplication::processEvents();

                for (int Nx=-RecVec, i=0; Nx <= RecVec; Nx++) {
                    for (int Ny=-RecVec; Ny <= RecVec; Ny++, i=i+3) {

                        Gx=2*M_PI*Nx/a;
                        Gy=2*M_PI*Ny/a;

                        double A = gsl_matrix_get(V, i+polarisation, dimension-1);

                        gsl_complex expin1 = gsl_complex_rect(0, (kx+Gx)*x+(ky+Gy)*y);
                        gsl_complex exp1 = gsl_complex_exp(expin1);

                        gsl_complex multiply = gsl_complex_mul_real(exp1, A);
                        u = gsl_complex_add(u, multiply);
                    }
                }

                double U = gsl_complex_abs(u);

                //zapisanie wartości do pliku
                plik << x << "\t" << y << "\t" << U << "\n";

            }



            plik << "\n";
        }

    }


    plik.close();
    gsl_matrix_free(gamma);
    gsl_matrix_free(V);
    gsl_vector_free(S);
    gsl_vector_free(work);
}
예제 #8
0
파일: my_gsl.cpp 프로젝트: mar80nik/Tracker
ComplexGSL exp( ComplexGSL& c )		{ return ComplexGSL(gsl_complex_exp(c.z)); }
예제 #9
0
gsl_complex integrate_line_segment(Params *params,
                                   gsl_complex p0,
                                   gsl_complex p1)
{
    gsl_complex k = gsl_complex_sub(p1, p0);

    const double r = params->r;
    const double a = 0.0; // parameter interval start
    const double b = 1.0; // parameter interval end
    const double L = b - a; // length of parameter interval
    const size_t table_size = 1000;

    // calculate frequency of oscillatory part
    double omega = GSL_REAL(k) * r;

    gsl_integration_workspace *ws = gsl_integration_workspace_alloc(table_size);

    // prepare sine/cosine tables for integration
    gsl_integration_qawo_table *table_cos = gsl_integration_qawo_table_alloc(omega, L, GSL_INTEG_COSINE, table_size);
    gsl_integration_qawo_table *table_sin = gsl_integration_qawo_table_alloc(omega, L, GSL_INTEG_SINE, table_size);

    LineSegmentParams lsp;
    lsp.p0 = p0;
    lsp.k = k;
    lsp.damping = params->r * GSL_IMAG(k);
    lsp.params = params;

    //fprintf(stderr, "p0 = %g %g, p1 = %g %g, k = %g %g, r = %g, omega = %g, damping = %g\n",
    //        GSL_REAL(p0), GSL_IMAG(p0), GSL_REAL(p1), GSL_IMAG(p1),
    //        GSL_REAL(k), GSL_IMAG(k), r, omega, lsp.damping);

    gsl_function F;
    F.function = &line_segment_integrand_wrapper;
    F.params = &lsp;

    double result_real_cos, abserr_real_cos;
    double result_real_sin, abserr_real_sin;
    double result_imag_cos, abserr_imag_cos;
    double result_imag_sin, abserr_imag_sin;

    double epsabs = 1e-9;
    double epsrel = 1e-9;

    lsp.part = REAL;
    gsl_integration_qawo(&F, a, epsabs, epsrel, table_size, ws, table_cos, &result_real_cos, &abserr_real_cos);
    gsl_integration_qawo(&F, a, epsabs, epsrel, table_size, ws, table_sin, &result_real_sin, &abserr_real_sin);

    lsp.part = IMAG;
    gsl_integration_qawo(&F, a, epsabs, epsrel, table_size, ws, table_cos, &result_imag_cos, &abserr_imag_cos);
    gsl_integration_qawo(&F, a, epsabs, epsrel, table_size, ws, table_sin, &result_imag_sin, &abserr_imag_sin);

    //fprintf(stderr, "    cos: %g (+- %g) %g (+- %g)  sin: %g (+- %g) %g (+- %g)\n",
    //        result_real_cos, abserr_real_cos, result_imag_cos, abserr_imag_cos,
    //        result_real_sin, abserr_real_sin, result_imag_sin, abserr_imag_sin);

    gsl_complex cos_part = gsl_complex_rect(result_real_cos, result_imag_cos);
    gsl_complex sin_part = gsl_complex_rect(-result_imag_sin, result_real_sin);
    gsl_complex sum = gsl_complex_add(cos_part, sin_part);
    gsl_complex result = gsl_complex_mul(
            k,
            gsl_complex_mul(sum, gsl_complex_exp(gsl_complex_mul_imag(p0, params->r))));

    gsl_integration_qawo_table_free(table_sin);
    gsl_integration_qawo_table_free(table_cos);

    gsl_integration_workspace_free(ws);

    return result;
}
예제 #10
0
void AbsArg(param_ param, abs_info_ *abs_info, gsl_complex *W, double *absW,
            double *argW, gsl_complex *complex_rot) {

    /*
     * In this function, we calculate the abs and arg
     * values for every point on the lattice. We also
     * find the total and max values for the abs across
     * the entire lattice.
     */

    int i, j, tmp_int;
    gsl_complex complex_I;
    double *max_array, tmp;
    int max_num_threads;

    int L=param.L;

    GSL_SET_COMPLEX(&complex_I,0.,1.);

    tmp = 0.;
    tmp_int = 0;
    (*abs_info).max=0.;

    #pragma omp parallel
    {

        /*
         * The optimization here creates an array once in the
         * main thread, of length equal to the total number
         * of threads, and then updates local maxima along
         * the individual threads, storing them in the newly
         * created array. At the end, the local maxima are
         * compared.
         */

        #pragma omp master
        {
            max_num_threads = omp_get_num_threads();
            max_array = (double *)calloc(max_num_threads,sizeof(double));
        }

        int num;
        num=omp_get_thread_num();

        #pragma omp barrier //this barrier ensures the array
        //is visible to all threads

        #pragma omp for reduction(+:tmp)

        for(i=0; i<L*L; i++) {
            absW[i]=gsl_complex_abs(W[i]);
            tmp += absW[i];
            if(absW[i] > max_array[num])
                max_array[num]=absW[i];

            argW[i] = gsl_complex_arg(W[i]);

            complex_rot[i] = gsl_complex_exp(gsl_complex_mul_real(\
                                             complex_I,(-0.5)*argW[i]));
        }

        #pragma omp barrier

        #pragma omp master
        {
            for(i=0; i<max_num_threads; i++)
                if(max_array[i] > (*abs_info).max)
                    (*abs_info).max = max_array[i];

            free(max_array);
        }

    } //end parallel construct

    (*abs_info).total = tmp;

    /*
     * Here, we find the total number of
     * points considered active according to
     * param.p_thresh.
     */

    for(j=0; j<param.pr_range; j++) {
        tmp_int = 0;

        #pragma omp parallel for reduction(+:tmp_int)

        for(i=0; i<L*L; i++)
            if(absW[i] >= param.pr_thresh[j]*(*abs_info).max)
                tmp_int++;

        (*abs_info).int_total[j] = tmp_int;
    }

}
예제 #11
0
파일: xrr.c 프로젝트: 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);
}
예제 #12
0
파일: xrr.c 프로젝트: 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);
}