static void make_filter(T *result_b, T *result_a, const complex4c *alpha, const complex4c *beta, int K, T sigma) { const double denom = sigma * M_SQRT2PI; complex4c b[DERICHE_MAX_K], a[DERICHE_MAX_K + 1]; int k, j; b[0] = alpha[0]; /* Initialize b/a = alpha[0] / (1 + beta[0] z^-1) */ a[0] = make_complex(1, 0); a[1] = beta[0]; for (k = 1; k < K; ++k) { /* Add kth term, b/a += alpha[k] / (1 + beta[k] z^-1) */ b[k] = c_mul(beta[k], b[k-1]); for (j = k - 1; j > 0; --j) b[j] = c_add(b[j], c_mul(beta[k], b[j - 1])); for (j = 0; j <= k; ++j) b[j] = c_add(b[j], c_mul(alpha[k], a[j])); a[k + 1] = c_mul(beta[k], a[k]); for (j = k; j > 0; --j) a[j] = c_add(a[j], c_mul(beta[k], a[j - 1])); } for (k = 0; k < K; ++k) { result_b[k] = (T)(b[k].real / denom); result_a[k + 1] = (T)a[k + 1].real; } return; }
/** * \brief Expand pole product * \param c resulting filter coefficients * \param poles pole locations * \param K number of poles * \ingroup vyv_gaussian * * This routine expands the product to obtain the filter coefficients: * \f[ \prod_{k=0}^{K-1}\frac{\mathrm{poles}[k]-1}{\mathrm{poles}[k]-z^{-1}} = \frac{c[0]}{1+\sum_{k=1}^K c[k] z^{-k}}. \f] */ static void expand_pole_product(double *c, const complex4c *poles, int K) { complex4c denom[VYV_MAX_K + 1]; int k, j; assert(K <= VYV_MAX_K); denom[0] = poles[0]; denom[1] = make_complex(-1, 0); for (k = 1; k < K; ++k) { denom[k + 1] = c_neg(denom[k]); for (j = k; j > 0; --j) denom[j] = c_sub(c_mul(denom[j], poles[k]), denom[j - 1]); denom[0] = c_mul(denom[0], poles[k]); } for (k = 1; k <= K; ++k) c[k] = c_div(denom[k], denom[0]).real; for (c[0] = 1, k = 1; k <= K; ++k) c[0] += c[k]; return; }
struct c_complex Lentz_Dn(struct c_complex z,long n) /*:10*/ #line 126 "./mie.w" { struct c_complex alpha_j1,alpha_j2,zinv,aj; struct c_complex alpha,result,ratio,runratio; /*12:*/ #line 156 "./mie.w" zinv= c_sdiv(2.0,z); alpha= c_smul(n+0.5,zinv); aj= c_smul(-n-1.5,zinv); alpha_j1= c_add(aj,c_inv(alpha)); alpha_j2= aj; ratio= c_div(alpha_j1,alpha_j2); runratio= c_mul(alpha,ratio); /*:12*/ #line 131 "./mie.w" do /*13:*/ #line 179 "./mie.w" { aj.re= zinv.re-aj.re; aj.im= zinv.im-aj.im; alpha_j1= c_add(c_inv(alpha_j1),aj); alpha_j2= c_add(c_inv(alpha_j2),aj); ratio= c_div(alpha_j1,alpha_j2); zinv.re*= -1; zinv.im*= -1; runratio= c_mul(ratio,runratio); } /*:13*/ #line 134 "./mie.w" while(fabs(c_abs(ratio)-1.0)> 1e-12); result= c_add(c_sdiv((double)-n,z),runratio); return result; }
/** * \brief Derivative of variance with respect to q * \param poles0 unscaled pole locations * \param q rescaling parameter * \param K number of poles * \return derivative of variance with respect to q * \ingroup vyv_gaussian * * This function is used by compute_q() in solving for q. */ static double dq_variance(const complex4c *poles0, int K, double q) { complex4c sum = { 0, 0 }; int k; for (k = 0; k < K; ++k) { complex4c z = c_real_pow(poles0[k], 1 / q), w = z, denom = z; w.real += 1; denom.real -= 1; /* Compute sum += z log(z) (z + 1) / (z - 1)^3 */ sum = c_add(sum, c_div(c_mul(c_mul(z, c_log(z)), w), c_real_pow(denom, 3))); } return (2 / q) * sum.real; }
/** * \brief Compute the variance of the impulse response * \param poles0 unscaled pole locations * \param q rescaling parameter * \param K number of poles * \return variance achieved by poles = poles0^(1/q) * \ingroup vyv_gaussian */ static double variance(const complex4c *poles0, int K, double q) { complex4c sum = { 0, 0 }; int k; for (k = 0; k < K; ++k) { complex4c z = c_real_pow(poles0[k], 1 / q), denom = z; denom.real -= 1; /* Compute sum += z / (z - 1)^2. */ sum = c_add(sum, c_div(z, c_mul(denom, denom))); } return 2 * sum.real; }
//傅里叶变化 void fft(int N,complex f[]) { complex t,wn;//中间变量 int i,j,k,m,n,l,r,M; int la,lb,lc; /*----计算分解的级数M=log2(N)----*/ for(i=N,M=1;(i=i/2)!=1;M++); /*----按照倒位序重新排列原信号----*/ for(i=1,j=N/2;i<=N-2;i++) { if(i<j) { t=f[j]; f[j]=f[i]; f[i]=t; } k=N/2; while(k<=j) { j=j-k; k=k/2; } j=j+k; } /*----FFT算法----*/ for(m=1;m<=M;m++) { la=pow(2,m); //la=2^m代表第m级每个分组所含节点数 lb=la/2; //lb代表第m级每个分组所含碟形单元数 //同时它也表示每个碟形单元上下节点之间的距离 /*----碟形运算----*/ for(l=1;l<=lb;l++) { r=(l-1)*pow(2,M-m); for(n=l-1;n<N-1;n=n+la) //遍历每个分组,分组总数为N/la { lc=n+lb; //n,lc分别代表一个碟形单元的上、下节点编号 Wn_i(N,r,&wn,1);//wn=Wnr c_mul(f[lc],wn,&t);//t = f[lc] * wn复数运算 c_sub(f[n],t,&(f[lc]));//f[lc] = f[n] - f[lc] * Wnr c_plus(f[n],t,&(f[n]));//f[n] = f[n] + f[lc] * Wnr } } } }
void schurFactorization(long n, complex **A, complex **T, complex **U) { /* Schur factorization: A = U*T*U', T = upper triangular, U = unitary */ long i,j,iter,maxIter; double tol, diff1,diff2; complex T11, T12, T21, T22; complex sigma1, sigma2, sigma; complex z, z1, z2; complex **P, **Q, **R; /* Allocate auxiliary matrices */ P = (complex **)Mem(MEM_ALLOC,n, sizeof(complex *)); Q = (complex **)Mem(MEM_ALLOC,n, sizeof(complex *)); R = (complex **)Mem(MEM_ALLOC,n, sizeof(complex *)); for (i=0; i<n; i++){ P[i] = (complex *)Mem(MEM_ALLOC,n, sizeof(complex)); Q[i] = (complex *)Mem(MEM_ALLOC,n, sizeof(complex)); R[i] = (complex *)Mem(MEM_ALLOC,n, sizeof(complex)); } /* ------------------------------------------------------------*/ /* Parameters for iteration */ maxIter = 500; tol = 1E-30; /* ------------------------------------------------------------*/ /* Init U = eye(n) (identity matrix) */ for (i=0; i<n; i++){ U[i][i].re = 1.0; U[i][i].im = 0.0; } /* ------------------------------------------------------------*/ /* Reduce A to Hessenberg form */ hessFactorization(n,A,P,T); /* ------------------------------------------------------------*/ /* Compute Schur factorization of Hessenberg matrix T */ for (j=n-1; j>0; j--){ /* Main loop */ for (iter=0; iter<maxIter; iter++){ /* Iteration loop */ sigma.re = T[j][j].re; sigma.im = T[j][j].im; /* -- Use Wilkinson shift -- */ /* submatrix considered in the shift */ T11 = T[j-1][j-1]; T12 = T[j-1][j]; T21 = T[j][j-1]; T22 = T[j][j]; /* Compute eigenvalues of submatrix */ z.re = 0.0; z.im = 0.0; z2.re = 0.0; z2.im = 0.0; /* z = T11*T11 + T22*T22 - 2*T11*T22 + 4*T12*T21 */ z1 = c_mul(T11,T11); z = c_add(z ,z1); z2 = c_add(z2,z1); z1 = c_mul(T22,T22); z = c_add(z ,z1); z2 = c_add(z2,z1); z1 = c_mul(T11,T22); z1.re = -2.0 * z1.re; z1.im = -2.0 * z1.im; z = c_add(z,z1); z1 = c_mul(T12,T21); z1.re = 4.0 * z1.re; z1.im = 4.0 * z1.im; z = c_add(z,z1); /* Square root*/ z = c_sqrt(z); /* Eigenvalues */ sigma1 = c_add(z2,z); sigma2 = c_sub(z2,z); /* printf("sigma1 = %e %e\n", sigma1.re, sigma1.im); */ /* printf("sigma2 = %e %e\n", sigma2.re, sigma2.im); */ /* Select eigenvalue for shift*/ diff1 = c_norm( c_sub(T[j][j], sigma1) ); diff2 = c_norm( c_sub(T[j][j], sigma2) ); if (diff1 < diff2){ sigma.re = sigma1.re; sigma.im = sigma1.im; }else{ sigma.re = sigma2.re; sigma.im = sigma2.im; } /* --- QR step with Wilkinson shift --- */ /* Shift: T(1:j,1:j) = T(1:j,1:j) - sigma * eye(j) */ for (i=0; i<j+1; i++){ CheckValue(FUNCTION_NAME, "T[i][i].re","", T[i][i].re, -INFTY, INFTY); CheckValue(FUNCTION_NAME, "T[i][i].im","", T[i][i].im, -INFTY, INFTY); T[i][i].re = T[i][i].re - sigma.re; T[i][i].im = T[i][i].im - sigma.im; } /* Compute QR factorization of shifted Hessenberg matrix */ for (i=0; i<n; i++){ memset(Q[i], 0, n*sizeof(complex)); memset(R[i], 0, n*sizeof(complex)); } QRfactorization(n,T,Q,R); /* T = T_new = R * Q */ for (i=0; i<n; i++){ memset(T[i], 0, n*sizeof(complex)); } matProduct(n, n, n, R, Q, T); /* T(1:j,1:j) = T(1:j,1:j) + sigma * eye(j) */ for (i=0; i<j+1; i++){ T[i][i].re = T[i][i].re + sigma.re; T[i][i].im = T[i][i].im + sigma.im; } /* R = U_new = U * Q */ for (i=0; i<n; i++){ memset(R[i], 0, n*sizeof(complex)); } matProduct(n,n,n,U,Q,R); /* U = R */ for (i=0; i<n; i++){ memcpy(U[i],R[i], n*sizeof(complex)); } /* Check convergence */ if (c_norm( T[j][j-1] ) <= tol * (c_norm(T[j-1][j-1]) + c_norm(T[j][j]))){ T[j][j-1].re = 0.0; T[j][j-1].im = 0.0; break; } } /* end of iter loop */ } /* end of main loop */ /* -------------------------------------------------------------*/ /* U = P*U */ for (i=0; i<n; i++){ memset(U[i], 0, n*sizeof(complex)); } matProduct(n,n,n,P,R,U); /* -------------------------------------------------------------*/ /* Free auxiliary variables */ for (i=0; i<n; i++){ Mem(MEM_FREE,P[i]); Mem(MEM_FREE,Q[i]); Mem(MEM_FREE,R[i]); } Mem(MEM_FREE,P); Mem(MEM_FREE,Q); Mem(MEM_FREE,R); /* Return */ return; }
void QRfactorization(long n, complex **A, complex **Q, complex **R) { /* QR factorization based on Householder transformations */ long i,j,k,m; double nrm; complex z,z1,z2; complex *vj; /* Init. Q = eye(n) (identity matrix) */ for (i=0; i<n; i++){ Q[i][i].re = 1.0; Q[i][i].im = 0.0; } /* Init. R = A */ for(j=0; j<n; j++){ for (i=0; i<n; i++){ R[i][j].re = A[i][j].re; R[i][j].im = A[i][j].im; CheckValue(FUNCTION_NAME, "A[i][j].re","", A[i][j].re, -INFTY, INFTY); CheckValue(FUNCTION_NAME, "A[i][j].im","", A[i][j].im, -INFTY, INFTY); } } /* Allocate auxiliary variables*/ vj = (complex *)Mem(MEM_ALLOC, n, sizeof(complex)); /* printf("begin calc, n = %d\n", n); */ /* ------------------------------------------------------------*/ for (j=0; j<n; j++){ /* Main loop */ /* R(j:end, j) */ for (i=j; i<n; i++){ vj[i-j].re = R[i][j].re; vj[i-j].im = R[i][j].im; } nrm = vectorNorm(n-j, vj); /* v(1) = v(1) + sign(R(j,j)) * norm(v) */ vj[0].re = vj[0].re + R[j][j].re / c_norm(R[j][j]) * nrm; vj[0].im = vj[0].im + R[j][j].im / c_norm(R[j][j]) * nrm; /* Update norm */ nrm = vectorNorm(n-j, vj); /* v = v./norm(v) */ for (i=0; i<n-j; i++){ vj[i].re = vj[i].re / nrm; vj[i].im = vj[i].im / nrm; } /* Update */ /* R(j:end, :) = R(j:end,:) - 2 * vj * vj' * R(j:end,:), : */ /* Q(:,j:end) = Q(:,j:end) - 2 * Q(:,j:end) * vj * vj^T */ for (k=0; k<n; k++){ /* (v * v' * A)_ik = v_i SUM_m Conj(v_m) A_mk */ z.re = 0.0; z.im = 0.0; for (m=j; m<n; m++){ z1 = c_con(vj[m-j]); z1 = c_mul(z1, R[m][k]); z = c_add(z,z1); } for (i=j; i<n; i++){ z2 = c_mul(vj[i-j],z); /* Update R(i,k) */ R[i][k].re = R[i][k].re - 2.0 * z2.re; R[i][k].im = R[i][k].im - 2.0 * z2.im; CheckValue(FUNCTION_NAME, "R[i][k].re","", R[i][k].re, -INFTY, INFTY); CheckValue(FUNCTION_NAME, "R[i][k].im","", R[i][k].im, -INFTY, INFTY); } /* (A * v * v^')_ki = v_i * SUM_m Conj(v_m) A_km */ z.re = 0.0; z.im = 0.0; for (m=j; m<n; m++){ z1 = vj[m-j]; z1 = c_mul(z1, Q[k][m]); z = c_add(z,z1); } for (i=j; i<n; i++){ z1 = c_con(vj[i-j]); z2 = c_mul(z1,z); /* Update Q(k,i)*/ Q[k][i].re = Q[k][i].re - 2.0 * z2.re; Q[k][i].im = Q[k][i].im - 2.0 * z2.im; CheckValue(FUNCTION_NAME, "Q[k][i].re","", Q[k][i].re, -INFTY, INFTY); CheckValue(FUNCTION_NAME, "Q[k][i].im","", Q[k][i].im, -INFTY, INFTY); } } } /* End of main loop (j) */ /* -------------------------------------------------------------*/ /* Free auxiliary variables */ Mem(MEM_FREE, vj); return; }
int main() { struct compoundData cdtest; int i; XRayInit(); //if something goes wrong, the test will end with EXIT_FAILURE //SetHardExit(1); std::printf("Example of C++ program using xraylib\n"); std::printf("Ca K-alpha Fluorescence Line Energy: %f\n", LineEnergy(20,KA_LINE)); std::printf("Fe partial photoionization cs of L3 at 6.0 keV: %f\n",CS_Photo_Partial(26,L3_SHELL,6.0)); std::printf("Zr L1 edge energy: %f\n",EdgeEnergy(40,L1_SHELL)); std::printf("Pb Lalpha XRF production cs at 20.0 keV (jump approx): %f\n",CS_FluorLine(82,LA_LINE,20.0)); std::printf("Pb Lalpha XRF production cs at 20.0 keV (Kissel): %f\n",CS_FluorLine_Kissel(82,LA_LINE,20.0)); std::printf("Bi M1N2 radiative rate: %f\n",RadRate(83,M1N2_LINE)); std::printf("U M3O3 Fluorescence Line Energy: %f\n",LineEnergy(92,M3O3_LINE)); //parser test for Ca(HCO3)2 (calcium bicarbonate) if (CompoundParser("Ca(HCO3)2",&cdtest) == 0) return 1; std::printf("Ca(HCO3)2 contains %i atoms and %i elements\n",cdtest.nAtomsAll,cdtest.nElements); for (i = 0 ; i < cdtest.nElements ; i++) std::printf("Element %i: %lf %%\n",cdtest.Elements[i],cdtest.massFractions[i]*100.0); FREE_COMPOUND_DATA(cdtest) //parser test for SiO2 (quartz) if (CompoundParser("SiO2",&cdtest) == 0) return 1; std::printf("SiO2 contains %i atoms and %i elements\n",cdtest.nAtomsAll,cdtest.nElements); for (i = 0 ; i < cdtest.nElements ; i++) std::printf("Element %i: %lf %%\n",cdtest.Elements[i],cdtest.massFractions[i]*100.0); FREE_COMPOUND_DATA(cdtest) std::printf("Ca(HCO3)2 Rayleigh cs at 10.0 keV: %f\n",CS_Rayl_CP("Ca(HCO3)2",10.0f) ); std::printf("CS2 Refractive Index at 10.0 keV : %f - %f i\n",Refractive_Index_Re("CS2",10.0f,1.261f),Refractive_Index_Im("CS2",10.0f,1.261f)); std::printf("C16H14O3 Refractive Index at 1 keV : %f - %f i\n",Refractive_Index_Re("C16H14O3",1.0f,1.2f),Refractive_Index_Im("C16H14O3",1.0f,1.2f)); std::printf("SiO2 Refractive Index at 5 keV : %f - %f i\n",Refractive_Index_Re("SiO2",5.0f,2.65f),Refractive_Index_Im("SiO2",5.0f,2.65f)); std::printf("Compton profile for Fe at pz = 1.1 : %f\n",ComptonProfile(26,1.1f)); std::printf("M5 Compton profile for Fe at pz = 1.1 : %f\n",ComptonProfile_Partial(26,M5_SHELL,1.1f)); std::printf("K atomic level width for Fe: %f\n", AtomicLevelWidth(26,K_SHELL)); std::printf("M1->M5 Coster-Kronig transition probability for Au : %f\n",CosKronTransProb(79,FM15_TRANS)); std::printf("L1->L3 Coster-Kronig transition probability for Fe : %f\n",CosKronTransProb(26,FL13_TRANS)); std::printf("Au Ma1 XRF production cs at 10.0 keV (Kissel): %f\n", CS_FluorLine_Kissel(79,MA1_LINE,10.0f)); std::printf("Au Mb XRF production cs at 10.0 keV (Kissel): %f\n", CS_FluorLine_Kissel(79,MB_LINE,10.0f)); std::printf("Au Mg XRF production cs at 10.0 keV (Kissel): %f\n", CS_FluorLine_Kissel(79,MG_LINE,10.0f)); std::printf("Bi L2-M5M5 Auger non-radiative rate: %f\n",AugerRate(86,L2_M5M5_AUGER)); std::printf("Pb Malpha XRF production cs at 20.0 keV with cascade effect: %f\n",CS_FluorLine_Kissel(82,MA1_LINE,20.0)); std::printf("Pb Malpha XRF production cs at 20.0 keV with radiative cascade effect: %f\n",CS_FluorLine_Kissel_Radiative_Cascade(82,MA1_LINE,20.0)); std::printf("Pb Malpha XRF production cs at 20.0 keV with non-radiative cascade effect: %f\n",CS_FluorLine_Kissel_Nonradiative_Cascade(82,MA1_LINE,20.0)); std::printf("Pb Malpha XRF production cs at 20.0 keV without cascade effect: %f\n",CS_FluorLine_Kissel_no_Cascade(82,MA1_LINE,20.0)); /* Si Crystal structure */ Crystal_Struct* cryst = Crystal_GetCrystal("Si", NULL); if (cryst == NULL) return 1; std::printf ("Si unit cell dimensions are %f %f %f\n", cryst->a, cryst->b, cryst->c); std::printf ("Si unit cell angles are %f %f %f\n", cryst->alpha, cryst->beta, cryst->gamma); std::printf ("Si unit cell volume is %f\n", cryst->volume); std::printf ("Si atoms at:\n"); std::printf (" Z fraction X Y Z\n"); Crystal_Atom* atom; for (i = 0; i < cryst->n_atom; i++) { atom = &cryst->atom[i]; std::printf (" %3i %f %f %f %f\n", atom->Zatom, atom->fraction, atom->x, atom->y, atom->z); } /* Si diffraction parameters */ std::printf ("\nSi111 at 8 KeV. Incidence at the Bragg angle:\n"); float energy = 8; float debye_temp_factor = 1.0; float rel_angle = 1.0; float bragg = Bragg_angle (cryst, energy, 1, 1, 1); std::printf (" Bragg angle: Rad: %f Deg: %f\n", bragg, bragg*180/PI); float q = Q_scattering_amplitude (cryst, energy, 1, 1, 1, rel_angle); std::printf (" Q Scattering amplitude: %f\n", q); float f0, fp, fpp; Atomic_Factors (14, energy, q, debye_temp_factor, &f0, &fp, &fpp); std::printf (" Atomic factors (Z = 14) f0, fp, fpp: %f, %f, i*%f\n", f0, fp, fpp); Complex FH, F0; FH = Crystal_F_H_StructureFactor (cryst, energy, 1, 1, 1, debye_temp_factor, rel_angle); std::printf (" FH(1,1,1) structure factor: (%f, %f)\n", FH.re, FH.im); F0 = Crystal_F_H_StructureFactor (cryst, energy, 0, 0, 0, debye_temp_factor, rel_angle); std::printf (" F0=FH(0,0,0) structure factor: (%f, %f)\n", F0.re, F0.im); /* Diamond diffraction parameters */ cryst = Crystal_GetCrystal("Diamond", NULL); std::printf ("\nDiamond 111 at 8 KeV. Incidence at the Bragg angle:\n"); bragg = Bragg_angle (cryst, energy, 1, 1, 1); std::printf (" Bragg angle: Rad: %f Deg: %f\n", bragg, bragg*180/PI); q = Q_scattering_amplitude (cryst, energy, 1, 1, 1, rel_angle); std::printf (" Q Scattering amplitude: %f\n", q); Atomic_Factors (6, energy, q, debye_temp_factor, &f0, &fp, &fpp); std::printf (" Atomic factors (Z = 6) f0, fp, fpp: %f, %f, i*%f\n", f0, fp, fpp); FH = Crystal_F_H_StructureFactor (cryst, energy, 1, 1, 1, debye_temp_factor, rel_angle); std::printf (" FH(1,1,1) structure factor: (%f, %f)\n", FH.re, FH.im); F0 = Crystal_F_H_StructureFactor (cryst, energy, 0, 0, 0, debye_temp_factor, rel_angle); std::printf (" F0=FH(0,0,0) structure factor: (%f, %f)\n", F0.re, F0.im); Complex FHbar = Crystal_F_H_StructureFactor (cryst, energy, -1, -1, -1, debye_temp_factor, rel_angle); float dw = 1e10 * 2 * (R_E / cryst->volume) * (KEV2ANGST * KEV2ANGST/ (energy * energy)) * sqrt(c_abs(c_mul(FH, FHbar))) / PI / sin(2*bragg); std::printf (" Darwin width: %f micro-radians\n", 1e6*dw); /* Alpha Quartz diffraction parameters */ cryst = Crystal_GetCrystal("AlphaQuartz", NULL); std::printf ("\nAlpha Quartz 020 at 8 KeV. Incidence at the Bragg angle:\n"); bragg = Bragg_angle (cryst, energy, 0, 2, 0); std::printf (" Bragg angle: Rad: %f Deg: %f\n", bragg, bragg*180/PI); q = Q_scattering_amplitude (cryst, energy, 0, 2, 0, rel_angle); std::printf (" Q Scattering amplitude: %f\n", q); Atomic_Factors (8, energy, q, debye_temp_factor, &f0, &fp, &fpp); std::printf (" Atomic factors (Z = 8) f0, fp, fpp: %f, %f, i*%f\n", f0, fp, fpp); FH = Crystal_F_H_StructureFactor (cryst, energy, 0, 2, 0, debye_temp_factor, rel_angle); std::printf (" FH(0,2,0) structure factor: (%f, %f)\n", FH.re, FH.im); F0 = Crystal_F_H_StructureFactor (cryst, energy, 0, 0, 0, debye_temp_factor, rel_angle); std::printf (" F0=FH(0,0,0) structure factor: (%f, %f)\n", F0.re, F0.im); /* Muscovite diffraction parameters */ cryst = Crystal_GetCrystal("Muscovite", NULL); std::printf ("\nMuscovite 331 at 8 KeV. Incidence at the Bragg angle:\n"); bragg = Bragg_angle (cryst, energy, 3, 3, 1); std::printf (" Bragg angle: Rad: %f Deg: %f\n", bragg, bragg*180/PI); q = Q_scattering_amplitude (cryst, energy, 3, 3, 1, rel_angle); std::printf (" Q Scattering amplitude: %f\n", q); Atomic_Factors (19, energy, q, debye_temp_factor, &f0, &fp, &fpp); std::printf (" Atomic factors (Z = 19) f0, fp, fpp: %f, %f, i*%f\n", f0, fp, fpp); FH = Crystal_F_H_StructureFactor (cryst, energy, 3, 3, 1, debye_temp_factor, rel_angle); std::printf (" FH(3,3,1) structure factor: (%f, %f)\n", FH.re, FH.im); F0 = Crystal_F_H_StructureFactor (cryst, energy, 0, 0, 0, debye_temp_factor, rel_angle); std::printf (" F0=FH(0,0,0) structure factor: (%f, %f)\n", F0.re, F0.im); std::printf ("\n--------------------------- END OF XRLEXAMPLE6 -------------------------------\n"); return 0; }
void simulation_solve(simulation_t *simulation) { int m,s; int i,j,k, i_max, x; m = simulation->n_vars; int n = m+1; s = simulation_context_get_n_samples(simulation->nodelist->netlist->sc); for ( k = 0 ; k < m ; ++k ) { //pivot is col k //find a line with the maximum k i_max = simulation_max(simulation, k,m); if ( cell_is_zero(simulation, &simulation->cells[i_max][k]) ) { fprintf(stderr,"singular matrix, zero found @ row %d col %d (mean = %.1f)\n", i_max, k, (double)cell_mean(simulation,&simulation->cells[i_max][k])); simulation_dump(simulation); assert(0); } assert(i_max >= k); if ( i_max != k ) { cell_t *tmp; tmp = simulation->cells[k]; simulation->cells[k] = simulation->cells[i_max]; simulation->cells[i_max] = tmp; } for ( i = k + 1 ; i < m ; i ++ ) { if ( simulation->cells[i][k].state == CELL_ZERO ) { //fprintf(stderr,"continue\n"); continue; } assert( i != k); #ifdef USE_OMP #pragma omp parallel for #endif for ( j = n - 1 ; j > k ; --j ) { // Fij = Fij - Fkj * Fik/Fkk assert( j != k ); cell_t *line_i = simulation->cells[i]; cell_t *line_k = simulation->cells[k]; line_i[j].state = CELL_SET; for ( x = 0 ; x < s ; ++x ) { //assert( line_k[k].state != CELL_ZERO && !cell_is_zero(simulation,&line_k[k])); line_i[j].values[x] = c_let( c_sub(line_i[j].values[x], c_mul(line_k[j].values[x], c_div( line_i[k].values[x], line_k[k].values[x] )))); /* line_i[j].values[x] = line_i[j].values[x] - line_k[j].values[x] * ( line_i[k].values[x] / line_k[k].values[x] ); */ /* assert( i != k ); line_i[j].values[x] = line_i[j].values[x] * line_k[k].values[x] - line_k[j].values[x] * line_i[k].values[x]; */ } } simulation->cells[i][k].state = CELL_ZERO; #ifdef USE_OMP #pragma omp parallel for #endif for ( x = 0 ; x < s ; ++x ) { simulation->cells[i][k].values[x]=0.L; } } } //simulation_dump(simulation); //backward elimination //simulation_dump(simulation); if (1) for ( k = m - 1 ; k >= 0 ; --k ) { //set pivot to 1 // Lk = Lk / Fk,k #ifdef USE_OMP #pragma omp parallel for #endif for ( j = k+1 ; j < n ; ++j ) { assert( j != k ); simulation->cells[k][j].state = CELL_SET; for ( x = 0 ; x < s ; ++x ) { //assert( simulation->cells[k][k].state != CELL_ZERO && !cell_is_zero(simulation, &simulation->cells[k][k])); simulation->cells[k][j].values[x] = c_let( c_div(simulation->cells[k][j].values[x], simulation->cells[k][k].values[x] )); /* simulation->cells[k][j].values[x] = simulation->cells[k][j].values[x] / simulation->cells[k][k].values[x]; */ } } simulation->cells[k][k].state = CELL_POSITIVE_UNITY; #ifdef USE_OMP #pragma omp parallel for #endif for ( x = 0 ; x < s ; ++x ) { simulation->cells[k][k].values[x] = 1.L + I * 0.L; } } //zeroes pivot col for ( k = m - 1 ; k >= 0 ; --k ) // vertical pivot Fk,k { assert( simulation->cells[k][k].state == CELL_POSITIVE_UNITY ); // Li = Li - Lk * Fik #ifdef USE_OMP #pragma omp parallel for #endif for ( i = 0 ; i < k ; ++i) // vertical { assert( i != k ); for ( j = k + 1 ; j < m ; ++ j ) assert( simulation->cells[i][j].state == CELL_ZERO ); // => Fir = Fir - Fik x Fkr // => Fi,k = 0 int result_col = n - 1; simulation->cells[i][result_col].state = CELL_SET; for ( x = 0 ; x < s ; ++x ) { simulation->cells[i][result_col].values[x] = c_let( c_sub(simulation->cells[i][result_col].values[x], c_mul(simulation->cells[i][k].values[x], simulation->cells[k][result_col].values[x]))); /* simulation->cells[i][j].values[x] = simulation->cells[i][j].values[x] - simulation->cells[i][k].values[x] * simulation->cells[k][j].values[x]; */ } simulation->cells[i][k].state = CELL_ZERO; for ( x = 0 ; x < s ; ++x ) { simulation->cells[i][k].values[x] = 0.L; } } } //sanity check assert( m == simulation->n_vars ); assert( n == simulation->n_vars+1 ); for ( i = 0 ; i < m ; ++ i ) for ( j = 0 ; j < m ; ++ j ) if ( i==j ) assert(simulation->cells[i][j].state == CELL_POSITIVE_UNITY ); else assert(simulation->cells[i][j].state == CELL_ZERO ); }
void LUdecomposition(long n, complex **A, complex *b, complex *x) { long i,j,k,*p; complex akk, bk, z, sum; complex *Ak; /* Allocate auxiliary variables */ p = (long *)Mem(MEM_ALLOC, n, sizeof(long)); /* Gaussian elimination with partial pivoting */ for (k=0; k<n-1; k++){ /* columns of A */ /* --- Pivoting --- */ akk.re = 0.0; akk.im = 0.0; j = k; for (i=k; i<n; i++){ if ( c_norm(A[i][k]) > c_norm(akk)){ akk = A[i][k]; CheckValue(FUNCTION_NAME, "A[i][k].re","", A[i][k].re, -INFTY, INFTY); CheckValue(FUNCTION_NAME, "A[i][k].im","", A[i][k].im, -INFTY, INFTY); j = i; } } if (j != k){ /* swap rows j and k*/ Ak = A[k]; A[k] = A[j]; /* swap pointers*/ A[j] = Ak; bk = b[k]; b[k] = b[j]; b[j] = bk; } p[k] = j; /* Keep list of permutations */ /* Sanity check */ if (akk.re != A[k][k].re && akk.im != A[k][k].im){ Die(FUNCTION_NAME, "Something went wrong with pivoting?"); return; } if (akk.re == 0.0 && akk.im == 0.0){ Die(FUNCTION_NAME, "Matrix singular?"); return; } /* Store L part */ for (i=k+1;i<n; i++){ A[i][k] = c_div(A[i][k],A[k][k]); CheckValue(FUNCTION_NAME, "A[i][k].re","", A[i][k].re, -INFTY, INFTY); CheckValue(FUNCTION_NAME, "A[i][k].im","", A[i][k].im, -INFTY, INFTY); } /* Update */ for (i=k+1; i<n; i++){ /* update b */ z = c_mul(A[i][k], b[k]); b[i] = c_sub(b[i], z); CheckValue(FUNCTION_NAME, "b[i].re","", b[i].re, -INFTY, INFTY); CheckValue(FUNCTION_NAME, "b[i].im","", b[i].im, -INFTY, INFTY); for (j=k+1; j<n; j++){ /* Update U part of A */ z = c_mul( A[i][k], A[k][j]); A[i][j] = c_sub(A[i][j],z); CheckValue(FUNCTION_NAME, "A[i][j].re","", A[i][j].re, -INFTY, INFTY); CheckValue(FUNCTION_NAME, "A[i][j].im","", A[i][j].im, -INFTY, INFTY); } } } /* Solve x */ x[n-1] = c_div(b[n-1],A[n-1][n-1]); for (i=n-2; i>=0; i--){ sum.re = 0.0; sum.im = 0.0; for (j=i+1; j<n; j++){ z = c_mul(A[i][j], x[j]); sum = c_add(sum, z); } z = c_sub(b[i], sum); x[i] = c_div(z, A[i][i]); } Mem(MEM_FREE, p); /* Return */ return; }
int main() { struct compoundData *cdtest; int i; XRayInit(); SetErrorMessages(0); //if something goes wrong, the test will end with EXIT_FAILURE //SetHardExit(1); std::printf("Example of C++ program using xraylib\n"); std::printf("Density of pure Al: %f g/cm3\n", ElementDensity(13)); std::printf("Ca K-alpha Fluorescence Line Energy: %f\n", LineEnergy(20,KA_LINE)); std::printf("Fe partial photoionization cs of L3 at 6.0 keV: %f\n",CS_Photo_Partial(26,L3_SHELL,6.0)); std::printf("Zr L1 edge energy: %f\n",EdgeEnergy(40,L1_SHELL)); std::printf("Pb Lalpha XRF production cs at 20.0 keV (jump approx): %f\n",CS_FluorLine(82,LA_LINE,20.0)); std::printf("Pb Lalpha XRF production cs at 20.0 keV (Kissel): %f\n",CS_FluorLine_Kissel(82,LA_LINE,20.0)); std::printf("Bi M1N2 radiative rate: %f\n",RadRate(83,M1N2_LINE)); std::printf("U M3O3 Fluorescence Line Energy: %f\n",LineEnergy(92,M3O3_LINE)); //parser test for Ca(HCO3)2 (calcium bicarbonate) if ((cdtest = CompoundParser("Ca(HCO3)2")) == NULL) return 1; std::printf("Ca(HCO3)2 contains %g atoms, %i elements and has a molar mass of %g g/mol\n", cdtest->nAtomsAll, cdtest->nElements, cdtest->molarMass); for (i = 0 ; i < cdtest->nElements ; i++) std::printf("Element %i: %f %% and %g atoms\n", cdtest->Elements[i], cdtest->massFractions[i]*100.0, cdtest->nAtoms[i]); FreeCompoundData(cdtest); //parser test for SiO2 (quartz) if ((cdtest = CompoundParser("SiO2")) == NULL) return 1; std::printf("SiO2 contains %g atoms, %i elements and has a molar mass of %g g/mol\n", cdtest->nAtomsAll, cdtest->nElements, cdtest->molarMass); for (i = 0 ; i < cdtest->nElements ; i++) std::printf("Element %i: %f %% and %g atoms\n", cdtest->Elements[i], cdtest->massFractions[i]*100.0, cdtest->nAtoms[i]); FreeCompoundData(cdtest); std::printf("Ca(HCO3)2 Rayleigh cs at 10.0 keV: %f\n",CS_Rayl_CP("Ca(HCO3)2",10.0f) ); std::printf("CS2 Refractive Index at 10.0 keV : %f - %f i\n",Refractive_Index_Re("CS2",10.0f,1.261f),Refractive_Index_Im("CS2",10.0f,1.261f)); std::printf("C16H14O3 Refractive Index at 1 keV : %f - %f i\n",Refractive_Index_Re("C16H14O3",1.0f,1.2f),Refractive_Index_Im("C16H14O3",1.0f,1.2f)); std::printf("SiO2 Refractive Index at 5 keV : %f - %f i\n",Refractive_Index_Re("SiO2",5.0f,2.65f),Refractive_Index_Im("SiO2",5.0f,2.65f)); std::printf("Compton profile for Fe at pz = 1.1 : %f\n",ComptonProfile(26,1.1f)); std::printf("M5 Compton profile for Fe at pz = 1.1 : %f\n",ComptonProfile_Partial(26,M5_SHELL,1.1f)); std::printf("K atomic level width for Fe: %f\n", AtomicLevelWidth(26,K_SHELL)); std::printf("M1->M5 Coster-Kronig transition probability for Au : %f\n",CosKronTransProb(79,FM15_TRANS)); std::printf("L1->L3 Coster-Kronig transition probability for Fe : %f\n",CosKronTransProb(26,FL13_TRANS)); std::printf("Au Ma1 XRF production cs at 10.0 keV (Kissel): %f\n", CS_FluorLine_Kissel(79,MA1_LINE,10.0f)); std::printf("Au Mb XRF production cs at 10.0 keV (Kissel): %f\n", CS_FluorLine_Kissel(79,MB_LINE,10.0f)); std::printf("Au Mg XRF production cs at 10.0 keV (Kissel): %f\n", CS_FluorLine_Kissel(79,MG_LINE,10.0f)); std::printf("Bi L2-M5M5 Auger non-radiative rate: %f\n",AugerRate(86,L2_M5M5_AUGER)); std::printf("Bi L3 Auger yield: %f\n", AugerYield(86, L3_SHELL)); std::printf("Sr anomalous scattering factor Fi at 10.0 keV: %f\n", Fi(38, 10.0)); std::printf("Sr anomalous scattering factor Fii at 10.0 keV: %f\n", Fii(38, 10.0)); char *symbol = AtomicNumberToSymbol(26); std::printf("Symbol of element 26 is: %s\n",symbol); xrlFree(symbol); std::printf("Number of element Fe is: %i\n",SymbolToAtomicNumber("Fe")); std::printf("Pb Malpha XRF production cs at 20.0 keV with cascade effect: %f\n",CS_FluorLine_Kissel(82,MA1_LINE,20.0)); std::printf("Pb Malpha XRF production cs at 20.0 keV with radiative cascade effect: %f\n",CS_FluorLine_Kissel_Radiative_Cascade(82,MA1_LINE,20.0)); std::printf("Pb Malpha XRF production cs at 20.0 keV with non-radiative cascade effect: %f\n",CS_FluorLine_Kissel_Nonradiative_Cascade(82,MA1_LINE,20.0)); std::printf("Pb Malpha XRF production cs at 20.0 keV without cascade effect: %f\n",CS_FluorLine_Kissel_no_Cascade(82,MA1_LINE,20.0)); std::printf("Al mass energy-absorption cs at 20.0 keV: %f\n", CS_Energy(13, 20.0)); std::printf("Pb mass energy-absorption cs at 40.0 keV: %f\n", CS_Energy(82, 40.0)); std::printf("CdTe mass energy-absorption cs at 40.0 keV: %f\n", CS_Energy_CP("CdTe", 40.0)); /* Si Crystal structure */ Crystal_Struct* cryst = Crystal_GetCrystal("Si", NULL); if (cryst == NULL) return 1; std::printf ("Si unit cell dimensions are %f %f %f\n", cryst->a, cryst->b, cryst->c); std::printf ("Si unit cell angles are %f %f %f\n", cryst->alpha, cryst->beta, cryst->gamma); std::printf ("Si unit cell volume is %f\n", cryst->volume); std::printf ("Si atoms at:\n"); std::printf (" Z fraction X Y Z\n"); Crystal_Atom* atom; for (i = 0; i < cryst->n_atom; i++) { atom = &cryst->atom[i]; std::printf (" %3i %f %f %f %f\n", atom->Zatom, atom->fraction, atom->x, atom->y, atom->z); } /* Si diffraction parameters */ std::printf ("\nSi111 at 8 KeV. Incidence at the Bragg angle:\n"); double energy = 8; double debye_temp_factor = 1.0; double rel_angle = 1.0; double bragg = Bragg_angle (cryst, energy, 1, 1, 1); std::printf (" Bragg angle: Rad: %f Deg: %f\n", bragg, bragg*180/PI); double q = Q_scattering_amplitude (cryst, energy, 1, 1, 1, rel_angle); std::printf (" Q Scattering amplitude: %f\n", q); double f0, fp, fpp; Atomic_Factors (14, energy, q, debye_temp_factor, &f0, &fp, &fpp); std::printf (" Atomic factors (Z = 14) f0, fp, fpp: %f, %f, i*%f\n", f0, fp, fpp); xrlComplex FH, F0; FH = Crystal_F_H_StructureFactor (cryst, energy, 1, 1, 1, debye_temp_factor, rel_angle); std::printf (" FH(1,1,1) structure factor: (%f, %f)\n", FH.re, FH.im); F0 = Crystal_F_H_StructureFactor (cryst, energy, 0, 0, 0, debye_temp_factor, rel_angle); std::printf (" F0=FH(0,0,0) structure factor: (%f, %f)\n", F0.re, F0.im); /* Diamond diffraction parameters */ cryst = Crystal_GetCrystal("Diamond", NULL); std::printf ("\nDiamond 111 at 8 KeV. Incidence at the Bragg angle:\n"); bragg = Bragg_angle (cryst, energy, 1, 1, 1); std::printf (" Bragg angle: Rad: %f Deg: %f\n", bragg, bragg*180/PI); q = Q_scattering_amplitude (cryst, energy, 1, 1, 1, rel_angle); std::printf (" Q Scattering amplitude: %f\n", q); Atomic_Factors (6, energy, q, debye_temp_factor, &f0, &fp, &fpp); std::printf (" Atomic factors (Z = 6) f0, fp, fpp: %f, %f, i*%f\n", f0, fp, fpp); FH = Crystal_F_H_StructureFactor (cryst, energy, 1, 1, 1, debye_temp_factor, rel_angle); std::printf (" FH(1,1,1) structure factor: (%f, %f)\n", FH.re, FH.im); F0 = Crystal_F_H_StructureFactor (cryst, energy, 0, 0, 0, debye_temp_factor, rel_angle); std::printf (" F0=FH(0,0,0) structure factor: (%f, %f)\n", F0.re, F0.im); xrlComplex FHbar = Crystal_F_H_StructureFactor (cryst, energy, -1, -1, -1, debye_temp_factor, rel_angle); double dw = 1e10 * 2 * (R_E / cryst->volume) * (KEV2ANGST * KEV2ANGST/ (energy * energy)) * std::sqrt(c_abs(c_mul(FH, FHbar))) / PI / std::sin(2*bragg); std::printf (" Darwin width: %f micro-radians\n", 1e6*dw); /* Alpha Quartz diffraction parameters */ cryst = Crystal_GetCrystal("AlphaQuartz", NULL); std::printf ("\nAlpha Quartz 020 at 8 KeV. Incidence at the Bragg angle:\n"); bragg = Bragg_angle (cryst, energy, 0, 2, 0); std::printf (" Bragg angle: Rad: %f Deg: %f\n", bragg, bragg*180/PI); q = Q_scattering_amplitude (cryst, energy, 0, 2, 0, rel_angle); std::printf (" Q Scattering amplitude: %f\n", q); Atomic_Factors (8, energy, q, debye_temp_factor, &f0, &fp, &fpp); std::printf (" Atomic factors (Z = 8) f0, fp, fpp: %f, %f, i*%f\n", f0, fp, fpp); FH = Crystal_F_H_StructureFactor (cryst, energy, 0, 2, 0, debye_temp_factor, rel_angle); std::printf (" FH(0,2,0) structure factor: (%f, %f)\n", FH.re, FH.im); F0 = Crystal_F_H_StructureFactor (cryst, energy, 0, 0, 0, debye_temp_factor, rel_angle); std::printf (" F0=FH(0,0,0) structure factor: (%f, %f)\n", F0.re, F0.im); /* Muscovite diffraction parameters */ cryst = Crystal_GetCrystal("Muscovite", NULL); std::printf ("\nMuscovite 331 at 8 KeV. Incidence at the Bragg angle:\n"); bragg = Bragg_angle (cryst, energy, 3, 3, 1); std::printf (" Bragg angle: Rad: %f Deg: %f\n", bragg, bragg*180/PI); q = Q_scattering_amplitude (cryst, energy, 3, 3, 1, rel_angle); std::printf (" Q Scattering amplitude: %f\n", q); Atomic_Factors (19, energy, q, debye_temp_factor, &f0, &fp, &fpp); std::printf (" Atomic factors (Z = 19) f0, fp, fpp: %f, %f, i*%f\n", f0, fp, fpp); FH = Crystal_F_H_StructureFactor (cryst, energy, 3, 3, 1, debye_temp_factor, rel_angle); std::printf (" FH(3,3,1) structure factor: (%f, %f)\n", FH.re, FH.im); F0 = Crystal_F_H_StructureFactor (cryst, energy, 0, 0, 0, debye_temp_factor, rel_angle); std::printf (" F0=FH(0,0,0) structure factor: (%f, %f)\n", F0.re, F0.im); char **crystals; crystals = Crystal_GetCrystalsList(NULL, NULL); std::printf ("List of available crystals:\n"); for (i = 0 ; crystals[i] != NULL ; i++) { std::printf (" Crystal %i: %s\n", i, crystals[i]); xrlFree(crystals[i]); } xrlFree(crystals); std::printf ("\n"); /* compoundDataNIST tests */ struct compoundDataNIST *cdn; cdn = GetCompoundDataNISTByName("Uranium Monocarbide"); std::printf ("Uranium Monocarbide\n"); std::printf (" Name: %s\n", cdn->name); std::printf (" Density: %lf g/cm3\n", cdn->density); for (i = 0 ; i < cdn->nElements ; i++) { std::printf(" Element %i: %lf %%\n",cdn->Elements[i],cdn->massFractions[i]*100.0); } FreeCompoundDataNIST(cdn); cdn = NULL; cdn = GetCompoundDataNISTByIndex(NIST_COMPOUND_BRAIN_ICRP); std::printf ("NIST_COMPOUND_BRAIN_ICRP\n"); std::printf (" Name: %s\n", cdn->name); std::printf (" Density: %lf g/cm3\n", cdn->density); for (i = 0 ; i < cdn->nElements ; i++) { std::printf(" Element %i: %lf %%\n",cdn->Elements[i],cdn->massFractions[i]*100.0); } FreeCompoundDataNIST(cdn); cdn = NULL; char **nistCompounds = GetCompoundDataNISTList(NULL); std::printf ("List of available NIST compounds:\n"); for (i = 0 ; nistCompounds[i] != NULL ; i++) { std::printf (" Compound %i: %s\n", i, nistCompounds[i]); xrlFree(nistCompounds[i]); } xrlFree(nistCompounds); std::printf ("\n"); /* radioNuclideData tests */ struct radioNuclideData *rnd; rnd = GetRadioNuclideDataByName("109Cd"); std::printf ("109Cd\n"); std::printf (" Name: %s\n", rnd->name); std::printf (" Z: %i\n", rnd->Z); std::printf (" A: %i\n", rnd->A); std::printf (" N: %i\n", rnd->N); std::printf (" Z_xray: %i\n", rnd->Z_xray); std::printf (" X-rays:\n"); for (i = 0 ; i < rnd->nXrays ; i++) std::printf (" %f keV -> %f\n", LineEnergy(rnd->Z_xray, rnd->XrayLines[i]), rnd->XrayIntensities[i]); std::printf (" Gamma rays:\n"); for (i = 0 ; i < rnd->nGammas ; i++) std::printf (" %f keV -> %f\n", rnd->GammaEnergies[i], rnd->GammaIntensities[i]); FreeRadioNuclideData(rnd); rnd = GetRadioNuclideDataByIndex(RADIO_NUCLIDE_125I); std::printf ("RADIO_NUCLIDE_125I\n"); std::printf (" Name: %s\n", rnd->name); std::printf (" Z: %i\n", rnd->Z); std::printf (" A: %i\n", rnd->A); std::printf (" N: %i\n", rnd->N); std::printf (" Z_xray: %i\n", rnd->Z_xray); std::printf (" X-rays:\n"); for (i = 0 ; i < rnd->nXrays ; i++) std::printf (" %f keV -> %f\n", LineEnergy(rnd->Z_xray, rnd->XrayLines[i]), rnd->XrayIntensities[i]); std::printf (" Gamma rays:\n"); for (i = 0 ; i < rnd->nGammas ; i++) std::printf (" %f keV -> %f\n", rnd->GammaEnergies[i], rnd->GammaIntensities[i]); FreeRadioNuclideData(rnd); char **radioNuclides; radioNuclides = GetRadioNuclideDataList(NULL); std::printf ("List of available radionuclides:\n"); for (i = 0 ; radioNuclides[i] != NULL ; i++) { std::printf (" Radionuclide %i: %s\n", i, radioNuclides[i]); xrlFree(radioNuclides[i]); } xrlFree(radioNuclides); std::printf ("\n--------------------------- END OF XRLEXAMPLE6 -------------------------------\n"); return 0; }
void Mie(double x,struct c_complex m,double*mu,long nangles,struct c_complex*s1, struct c_complex*s2,double*qext,double*qsca,double*qback,double*g) /*:34*/ #line 519 "./mie.w" { /*36:*/ #line 546 "./mie.w" struct c_complex*D; struct c_complex z1,an,bn,bnm1,anm1,qbcalc; double*pi0,*pi1,*tau; struct c_complex xi,xi0,xi1; double psi,psi0,psi1; double alpha,beta,factor; long n,k,nstop,sign; *qext= -1; *qsca= -1; *qback= -1; *g= -1; /*:36*/ #line 522 "./mie.w" /*37:*/ #line 559 "./mie.w" if(m.im> 0.0){ mie_error("This program requires m.im>=0",1); return; } if(x<=0.0){ mie_error("This program requires positive sphere sizes",2); return; } if(nangles<0){ mie_error("This program requires non-negative angle sizes",3); return; } if(nangles<0){ mie_error("This program requires non-negative angle sizes",4); return; } if((nangles> 0)&&(s1==NULL)){ mie_error("Space must be allocated for s1 if nangles!=0",5); return; } if((nangles> 0)&&(s2==NULL)){ mie_error("Space must be allocated for s2if nangles!=0",6); return; } if(x> 20000){ mie_error("Program not validated for spheres with x>20000",7); return; } /*:37*/ #line 524 "./mie.w" /*38:*/ #line 589 "./mie.w" if((m.re==0)&&(x<0.1)){ small_conducting_Mie(x,m,mu,nangles,s1,s2,qext,qsca,qback,g); return; } if((m.re> 0.0)&&(c_abs(m)*x<0.1)){ small_Mie(x,m,mu,nangles,s1,s2,qext,qsca,qback,g); return; } /*:38*/ #line 525 "./mie.w" /*40:*/ #line 616 "./mie.w" nstop= floor(x+4.05*pow(x,0.33333)+2.0); /*:40*/ #line 527 "./mie.w" /*39:*/ #line 600 "./mie.w" if(nangles> 0){ set_carray(s1,nangles,c_set(0.0,0.0)); set_carray(s2,nangles,c_set(0.0,0.0)); pi0= new_darray(nangles); pi1= new_darray(nangles); tau= new_darray(nangles); set_darray(pi0,nangles,0.0); set_darray(tau,nangles,0.0); set_darray(pi1,nangles,1.0); } /*:39*/ #line 529 "./mie.w" if(m.re> 0) /*41:*/ #line 634 "./mie.w" { struct c_complex z; z= c_smul(x,m); D= new_carray(nstop+1); if(D==NULL){ mie_error("Cannot allocate log array",8); return; } if(fabs(m.im*x)<((13.78*m.re-10.8)*m.re+3.9)) Dn_up(z,nstop,D); else Dn_down(z,nstop,D); } /*:41*/ #line 531 "./mie.w" /*42:*/ #line 671 "./mie.w" psi0= sin(x); psi1= psi0/x-cos(x); xi0= c_set(psi0,cos(x)); xi1= c_set(psi1,cos(x)/x+sin(x)); *qsca= 0.0; *g= 0.0; *qext= 0.0; sign= 1; qbcalc= c_set(0.0,0.0); anm1= c_set(0.0,0.0); bnm1= c_set(0.0,0.0); /*:42*/ #line 533 "./mie.w" for(n= 1;n<=nstop;n++){ /*43:*/ #line 696 "./mie.w" if(m.re==0.0){ an= c_sdiv(n*psi1/x-psi0,c_sub(c_smul(n/x,xi1),xi0)); bn= c_sdiv(psi1,xi1); }else if(m.im==0.0){ z1.re= D[n].re/m.re+n/x; an= c_sdiv(z1.re*psi1-psi0,c_sub(c_smul(z1.re,xi1),xi0)); z1.re= D[n].re*m.re+n/x; bn= c_sdiv(z1.re*psi1-psi0,c_sub(c_smul(z1.re,xi1),xi0)); }else{ z1= c_div(D[n],m); z1.re+= n/x; an= c_div(c_set(z1.re*psi1-psi0,z1.im*psi1),c_sub(c_mul(z1,xi1),xi0)); z1= c_mul(D[n],m); z1.re+= n/x; bn= c_div(c_set(z1.re*psi1-psi0,z1.im*psi1),c_sub(c_mul(z1,xi1),xi0)); } /*:43*/ #line 536 "./mie.w" /*44:*/ #line 734 "./mie.w" for(k= 0;k<nangles;k++){ factor= (2.0*n+1.0)/(n+1.0)/n; tau[k]= n*mu[k]*pi1[k]-(n+1)*pi0[k]; alpha= factor*pi1[k]; beta= factor*tau[k]; s1[k].re+= alpha*an.re+beta*bn.re; s1[k].im+= alpha*an.im+beta*bn.im; s2[k].re+= alpha*bn.re+beta*an.re; s2[k].im+= alpha*bn.im+beta*an.im; } for(k= 0;k<nangles;k++){ factor= pi1[k]; pi1[k]= ((2.0*n+1.0)*mu[k]*pi1[k]-(n+1.0)*pi0[k])/n; pi0[k]= factor; } /*:44*/ #line 537 "./mie.w" /*45:*/ #line 780 "./mie.w" factor= 2.0*n+1.0; *g+= (n-1.0/n)*(anm1.re*an.re+anm1.im*an.im+bnm1.re*bn.re+bnm1.im*bn.im); *g+= factor/n/(n+1.0)*(an.re*bn.re+an.im*bn.im); *qsca+= factor*(c_norm(an)+c_norm(bn)); *qext+= factor*(an.re+bn.re); sign*= -1; qbcalc.re+= sign*factor*(an.re-bn.re); qbcalc.im+= sign*factor*(an.im-bn.im); /*:45*/ #line 538 "./mie.w" /*46:*/ #line 804 "./mie.w" factor= (2.0*n+1.0)/x; xi= c_sub(c_smul(factor,xi1),xi0); xi0= xi1; xi1= xi; psi= factor*psi1-psi0; psi0= psi1; psi1= xi1.re; anm1= an; bnm1= bn; /*:46*/ #line 539 "./mie.w" } /*47:*/ #line 817 "./mie.w" *qsca*= 2/(x*x); *qext*= 2/(x*x); *g*= 4/(*qsca)/(x*x); *qback= c_norm(qbcalc)/(x*x); /*:47*/ #line 542 "./mie.w" /*48:*/ #line 823 "./mie.w" if(m.re> 0)free_carray(D); if(nangles> 0){ free_darray(pi0); free_darray(pi1); free_darray(tau); } /*:48*/ #line 543 "./mie.w" }
void small_Mie(double x,struct c_complex m,double*mu, long nangles,struct c_complex*s1, struct c_complex*s2,double*qext,double*qsca, double*qback,double*g) /*:22*/ #line 285 "./mie.w" { struct c_complex ahat1,ahat2,bhat1; struct c_complex z0,m2,m4; double x2,x3,x4; if((s1==NULL)||(s2==NULL))nangles= 0; m2= c_sqr(m); m4= c_sqr(m2); x2= x*x; x3= x2*x; x4= x2*x2; z0.re= -m2.im; z0.im= m2.re-1; /*24:*/ #line 319 "./mie.w" {struct c_complex z1,z2,z3,z4,D; z1= c_smul(2.0/3.0,z0); z2.re= 1.0-0.1*x2+(4.0*m2.re+5.0)*x4/1400.0; z2.im= 4.0*x4*m2.im/1400.0; z3= c_mul(z1,z2); z4= c_smul(x3*(1.0-0.1*x2),z1); D.re= 2.0+m2.re+(1-0.7*m2.re)*x2-(8.0*m4.re-385.0*m2.re+350.0)/1400.0*x4+z4.re; D.im= m2.im+(-0.7*m2.im)*x2-(8.0*m4.im-385.0*m2.im)/1400.0*x4+z4.im; ahat1= c_div(z3,D); } /*:24*/ #line 302 "./mie.w" /*25:*/ #line 339 "./mie.w" { struct c_complex z2,z6,z7; z2= c_smul(x2/45.0,z0); z6.re= 1.0+(2.0*m2.re-5.0)*x2/70.0; z6.im= m2.im*x2/35.0; z7.re= 1.0-(2.0*m2.re-5.0)*x2/30.0; z7.im= -m2.im*x2/15.0; bhat1= c_mul(z2,c_div(z6,z7)); } /*:25*/ #line 303 "./mie.w" /*26:*/ #line 354 "./mie.w" {struct c_complex z3,z8; z3= c_smul((1.0-x2/14.0)*x2/15.0,z0); z8.re= 2.0*m2.re+3.0-(m2.re/7.0-0.5)*x2; z8.im= 2.0*m2.im-m2.im/7.0*x2; ahat2= c_div(z3,z8); } /*:26*/ #line 304 "./mie.w" /*28:*/ #line 396 "./mie.w" {struct c_complex ss1; double T; T= c_norm(ahat1)+c_norm(bhat1)+(5.0/3.0)*c_norm(ahat2); *qsca= 6.0*x4*T; *qext= 6.0*x*(ahat1.re+bhat1.re+(5.0/3.0)*ahat2.re); *g= (ahat1.re*(ahat2.re+bhat1.re)+ahat1.im*(ahat2.im+bhat1.im))/T; ss1.re= 1.5*x2*(ahat1.re-bhat1.re-(5.0/3.0)*ahat2.re); ss1.im= 1.5*x2*(ahat1.im-bhat1.im-(5.0/3.0)*ahat2.im); *qback= 4*c_norm(ss1); } /*:28*/ #line 305 "./mie.w" /*29:*/ #line 418 "./mie.w" { double muj,angle; long j; x3*= 1.5; ahat1.re*= x3; ahat1.im*= x3; bhat1.re*= x3; bhat1.im*= x3; ahat2.re*= x3*(5.0/3.0); ahat2.im*= x3*(5.0/3.0); for(j= 0;j<nangles;j++){ muj= mu[j]; angle= 2.0*muj*muj-1.0; s1[j].re= ahat1.re+(bhat1.re+ahat2.re)*muj; s1[j].im= ahat1.im+(bhat1.im+ahat2.im)*muj; s2[j].re= bhat1.re+ahat1.re*muj+ahat2.re*angle; s2[j].im= bhat1.im+ahat1.im*muj+ahat2.im*angle; } } /*:29*/ #line 306 "./mie.w" }
complex c_pow(complex x, complex y) /* 累乗 $x^y$ */ { return c_exp(c_mul(y, c_log(x))); }