/// Fourier transform of NFW profile for satellites double cosmology::uskofm(double k, double m, double z, double csbycdm) { double mvir,rvir, cvir, r200, c200; modelNFWhalo(m,z,mvir,rvir,cvir,r200,c200); c200=c200*csbycdm; double rs=r200/c200; double fac=log(1.+c200) - c200/(1.+c200); double ci1,ci2; double si1,si2; double arg1=k*rs; double arg2=(1.+c200)*k*rs; double arg3=c200*k*rs; ci1=gsl_sf_Ci(arg1); ci2=gsl_sf_Ci(arg2); si1=gsl_sf_Si(arg1); si2=gsl_sf_Si(arg2); double res1=sin(arg1)*(si2-si1); res1-=sin(arg3)/arg2; res1+=cos(arg1)*(ci2-ci1); return res1/fac; }
// FFT of NFW profile from White '01 double rho_NFW_fft(double k, double M_vir, double z, int mode, cosmo_info **cosmo){ double c_vir; double R_vir; double r_s; double z_k; double g_c; double rho_o; double x1; double x2; double Ci1; double Ci2; double Si1; double Si2; double r_val; set_NFW_params(M_vir,z,mode,cosmo,&c_vir,&R_vir); r_s =R_vir/c_vir; z_k =k*r_s; g_c =1./(log(1.+c_vir)-c_vir/(1.+c_vir)); rho_o=M_vir*g_c/(FOUR_PI*r_s*r_s*r_s); x1 =1.+c_vir; x2 =c_vir*z_k; Ci1=gsl_sf_Ci((1.+c_vir)*z_k); Si1=gsl_sf_Si((1.+c_vir)*z_k); Ci2=gsl_sf_Ci( z_k); Si2=gsl_sf_Si( z_k); r_val=(FOUR_PI*rho_o*r_s*r_s*r_s/M_vir)*(cos(z_k)*(Ci1-Ci2)+ sin(z_k)*(Si1-Si2)- sin(c_vir*z_k)/(z_k*(1.+c_vir))); return(r_val); }
scalar sasfit_ff_pearl_necklace(scalar q, sasfit_param * param) { scalar qR,ql,qA,Psi,L,Mr,mr,ms,beta,Sr,Sp,Sm,sinqA_qA,sinql2_ql2,A; SASFIT_ASSERT_PTR(param); // assert pointer param is valid SASFIT_CHECK_COND1((q < 0.0), param, "q(%lg) < 0",q); SASFIT_CHECK_COND1((R < 0.0), param, "R(%lg) < 0",R); // modify condition to your needs SASFIT_CHECK_COND1((L < 0.0), param, "L(%lg) < 0",L); // modify condition to your needs SASFIT_CHECK_COND1((NU < 0.0), param, "nu(%lg) < 0",NU); // modify condition to your needs SASFIT_CHECK_COND1((B < 0.0), param, "b(%lg) < 0",B); // modify condition to your needs SASFIT_CHECK_COND1((NP < 0.0), param, "Np(%lg) < 0",NP); // modify condition to your needs // insert your code here A=l+2.*R; qR = q*R; ql = q*l; qA = q*A; mr=l/B; // number of monomers in rod-like segment ms=4.0*M_PI*gsl_pow_3(R)/(3.*NU); Mr=NP-1.0; if (qR==0.0) { Psi = 1; } else { Psi=3.*(sin(qR)-qR*cos(qR))/gsl_pow_3(qR); } if (ql == 0.0) { L=1.0; sinql2_ql2= 1.0; } else { L=gsl_sf_Si(ql)/(ql); sinql2_ql2 = sin(ql/2.0)*2/ql; } if (qA == 0.0) { sinqA_qA=1.; } else { sinqA_qA=sin(qA)/(qA); } if (q==0) { beta = 1.0; } else if (A==2*R) { if (R==0) { beta = 1; } else { beta = sin(q*R)/(q*R); } } else { beta=(gsl_sf_Si(q*(A-R))-gsl_sf_Si(qR))/(ql); } Sp=2*pow(ms,2)*pow(Psi,2)*((NP/(1-sinqA_qA))-(NP/2)-((1-pow(fabs(sinqA_qA),NP))/pow(1-sinqA_qA,2))*sinqA_qA); Sr=pow(mr,2)*(Mr*(2*L-pow(sinql2_ql2,2))+(2*Mr*pow(beta,2)/(1-sinqA_qA))- 2*pow(beta,2)*(1-pow(fabs(sinqA_qA),Mr))/pow(1-sinqA_qA,2)); Sm=mr*beta*ms*Psi*4*(((NP-1)/(1-sinqA_qA))-((1-pow(fabs(sinqA_qA),NP-1))/pow(1-sinqA_qA,2))*sinqA_qA); return (Sp+Sr+Sm)/pow(Mr*mr+NP*ms,2); }
scalar sasfit_ff_very_long_cyl_w_gauss_chains(scalar q, sasfit_param * param) { scalar Pp, Pcs, Fc, w, Scc, Ssc, J1x_x; scalar R, Rg, d, Nagg, H, r_core, r_chains; SASFIT_ASSERT_PTR(param); sasfit_get_param(param, 7, &R, &Rg, &d, &Nagg, &H, &r_core, &r_chains); SASFIT_CHECK_COND1((H <= 0.0), param, "H(%lg) < 0", H); if (q == 0.0) return Pp = 1.0; Pp =(2.0*gsl_sf_Si(q*H)/(q*H)-pow(sin(q*H*0.5)/(q*H*0.5),2.0)); w = sasfit_rwbrush_w(q, Rg); Fc = sasfit_gauss_fc(q, Rg); Scc = w*w*pow(gsl_sf_bessel_J0(q*(R+d*Rg)),2.); if (q*R == 0) { J1x_x = 0.5; } else { J1x_x = gsl_sf_bessel_J1(q*R)/(q*R); } Ssc = w*2.*J1x_x*gsl_sf_bessel_J0(q*(R+d*Rg)); Pcs = pow(r_core*2.*J1x_x,2.) + Nagg*(Nagg-1.)*pow(r_chains,2.0)*Scc*((Nagg < 1) ? 0 : 1) + 2.*Nagg*r_chains*r_core*Ssc; // sasfit_out("Cyl_Fc:%lf \n",pow(r_chains,2.0)*Nagg*Fc); return Pp*Pcs + pow(r_chains,2.0)*Nagg*Fc; }
/* * form factor of a spherical Cylinder with radius R, height L and scattering * length density eta */ scalar sasfit_ff_long_cyl(scalar q, sasfit_param * param) { scalar mu, sigma, pi_mu, G1, G2, I_sp, Sum, V, omega; scalar R, L, eta; SASFIT_ASSERT_PTR(param); sasfit_get_param(param, 4, &R, &L, EMPTY, &eta); SASFIT_CHECK_COND1((q < 0.0), param, "q(%lg) < 0",q); SASFIT_CHECK_COND1((R < 0.0), param, "R(%lg) < 0",R); SASFIT_CHECK_COND1((L < 0.0), param, "L(%lg) < 0",L); if (R == 0.0) return 0.0; if (L == 0.0) return 0.0; mu = L*q; sigma = 2.0*R*q; V = M_PI*R*R*L; if (R==0 || L==0) return 0; if (q==0) return V*V*eta*eta; pi_mu = gsl_sf_Si(mu)+cos(mu)/mu+sin(mu)/mu/mu; G1 = 2.0/(0.5*sigma) * gsl_sf_bessel_J1(0.5*sigma); G2 = 8.0/sigma/sigma * gsl_sf_bessel_Jn(2,sigma); // I_sp = 3.0 * (sin(sigma*0.5)-0.5*sigma*cos(0.5*sigma)) / pow(sigma/2.0,3); // I_sp = I_sp*I_sp; omega = 8/gsl_pow_2(sigma)*(3*gsl_sf_bessel_Jn(2,sigma)+gsl_sf_bessel_J0(sigma)-1); // Sum = 2.0/mu * (pi_mu*G1*G1 - 1.0/mu*(2.0*G2-I_sp) - sin(mu)/mu/mu); Sum = 2.0/mu * (pi_mu*G1*G1 - omega/mu - sin(mu)/mu/mu); return eta*eta *V*V* Sum; }
/* Int_0^mu dy cos(a*y) log(abs(b*y)) = (1/a) * (log(|b*mu|)*sin(a*mu) - Si(a*mu) ) */ double FC_FUNC(intcoslog, INTCOSLOG)(double *mu, double *a, double *b) { if(fabs(*a)>0.0){ return (1.0/(*a)) * (log((*b)*(*mu))*sin((*a)*(*mu)) - gsl_sf_Si((*a)*(*mu)) ); }else{ return (*mu)*(log((*mu)*(*b)) - 1.0); } }
scalar sasfit_ff_Rod_Exp_Profile(scalar q, sasfit_param * param) { scalar Psh, Fsh, Fsh1, Fsh2, Fc, Pc, Vc, V, S, Nagg, b_c, b_sh, Pcs, Pp, Plocal; scalar eta_out_in; scalar Rc, n_agg, Vsh, rho_c, rho_sh, rho_solv, xsolv_core, t, alpha, H; sasfit_param subParam; SASFIT_ASSERT_PTR(param); sasfit_get_param(param, 10, EMPTY, EMPTY, &Vsh, &rho_c, &rho_sh, &rho_solv, EMPTY, &t, &alpha, &H); switch( param->kernelSelector ) { case ROD_EXP: Rc = param->p[0]; n_agg = param->p[1]; xsolv_core = param->p[6]; eta_out_in = 0.0; if (Rc == 0.0) return 0.0; V = M_PI *Rc*Rc * H; S = 2. * M_PI *Rc*H; Nagg = n_agg*S; if (Nagg == 0.0) return 0; Vc = V * (1.-xsolv_core) / Nagg; break; case ROD_EXP_RC: Rc = param->p[0]; Vc = param->p[1]; eta_out_in = param->p[6]; xsolv_core = 0.0; if (Rc == 0.0) return 0.0; SASFIT_CHECK_COND1((Vc <= 0.0), param, "Vcore(%lg) <= 0", Vc); V = M_PI *Rc*Rc * H; S = 2. * M_PI *Rc*H; Nagg = V * (1.-xsolv_core)/ Vc; break; case ROD_EXP_NAGG: n_agg = param->p[0]; Vc = param->p[1]; eta_out_in = param->p[6]; xsolv_core = 0.0; SASFIT_CHECK_COND1((n_agg < 0.0), param, "n_agg(%lg) < 0", n_agg); if ( n_agg==0.0 ) return 0.0; // wrong equation Rc = sqrt(n_agg*Vc/(1.-xsolv_core)/M_PI); // Solve[{Vc/(1 - xsolv)*nagg*2*Pi*Rc*H == Pi*Rc^2*H}, {Rc}] // here the total volume of the rod is given by V == Vc/(1 - xsolv)*nagg*2*Pi*Rc*H == Pi*Rc^2*H // {{Rc -> 0}, {Rc -> -((2 nagg Vc)/(-1 + xsolv))}} Rc = 2.0*n_agg*Vc/(1.0-xsolv_core); S = 2. * M_PI *Rc*H; Nagg = n_agg*H; if (Nagg == 0.0) return 0; break; default: SASFIT_ERR_UNKNOWN_KERNEL(param, "kernel"); break; } Fc = sasfit_rod_fc(q, Rc); Pc = Fc * Fc; b_c = Vc * (rho_c - rho_solv); b_sh = Vsh * (rho_sh - rho_solv); if (b_sh==0.0) { Fsh = Psh = 0.0; } else { //Fsh = ROD_Exp_ave(interp,q,Rc,eta_out_in,t,alpha,error); sasfit_init_param( &subParam ); subParam.p[0] = Rc; subParam.p[1] = eta_out_in; subParam.p[2] = t; subParam.p[3] = alpha; subParam.p[MAXPAR-1] = q; Fsh1 = sasfit_integrate(Rc, Rc+t, sasfit_Rod_Exp_ave_core, &subParam); subParam.p[MAXPAR-1] = 0.0; Fsh2 = sasfit_integrate(Rc, Rc+t, sasfit_Rod_Exp_ave_core, &subParam); SASFIT_CHECK_SUB_ERR(param, subParam); Fsh = Fsh1/Fsh2; Psh = Fsh*Fsh; } Pcs = Nagg*Nagg * b_c*b_c * Pc + Nagg*(Nagg-1.0) * b_sh * b_sh * Psh * ((Nagg < 1) ? 0 : 1) + // Nagg*Nagg * b_sh * b_sh * Psh + 2.0*Nagg*Nagg * b_c * b_sh * Fc * Fsh; Pp =(2.0*gsl_sf_Si(q*H)/(q*H)-pow(sin(q*H*0.5)/(q*H*0.5),2.0)); Plocal =(2.0*gsl_sf_Si(q*t)/(q*t)-pow(sin(q*t*0.5)/(q*t*0.5),2.0)); return Pp*Pcs + Nagg*b_sh*b_sh*Plocal; }
double FC_FUNC_(oct_sine_integral, OCT_SINE_INTEGRAL) (const double *x) { return gsl_sf_Si(*x); }
/// The fourier transform of the NFW profile on a grid of k*rs and c /// krsmin=10^-6 and krsmax=10.0^8.0 /// log(cmin)=0.0 and logcmax=2.5 void cosmology::ukinit() { double krsdiff=(krsmax-krsmin)/(Nuk-1.); double cdiff=(cmax-cmin)/(Nuk-1.); for(int i=0;i<Nuk;i++) { uk_krs[i]=krsmin+i*krsdiff; uk_c [i]=cmin +i*cdiff; } /// Bilinear interpolation is not defined in GSL. So code this up yourself //std::cout<<"# Start check here"<<std::endl; for(int i=0;i<Nuk;i++) { double con=pow(10.,uk_c[i]); double fac=log(1.+con) - con/(1.+con); bool extrap=false; double x_extrap,y_extrap; for(int j=0;j<Nuk;j++) { double krs=pow(10.,uk_krs[j]); // Do the cisi calculation only when u(k)>10^-6 // A log-linear interpolation for values below if(!extrap) { double arg1=krs; double arg2=(1.0+con)*krs; double arg3=con*krs; double ci1,ci2; double si1,si2; ci1=gsl_sf_Ci(arg1); ci2=gsl_sf_Ci(arg2); si1=gsl_sf_Si(arg1); si2=gsl_sf_Si(arg2); double res1=sin(arg1)*(si2-si1); res1-=sin(arg3)/arg2; res1+=cos(arg1)*(ci2-ci1); if(res1/fac<=0.0){ std::cout<<"Some serious trouble here "<<res1<<" "<<fac<<" "<<krs<<" "<<con<<std::endl; exit(0); } ukrsc[i][j]=log10(res1/fac); //std::cout<<std::scientific; //std::cout<<krs<<" "<<con<<" "<<res1/fac<<" "<<std::endl; if (ukrsc[i][j] < -6.0) { extrap=true; x_extrap=uk_krs[j]; y_extrap=ukrsc[i][j]; } }else{ ukrsc[i][j]=y_extrap-1.99*(uk_krs[j]-x_extrap); //std::cout<<std::scientific; //std::cout<<krs<<" "<<con<<" "<<pow(10.,ukrsc[i][j])<<" "<<std::endl; } } //std::cout<<std::endl; } //exit(0); uk_c_acc=gsl_interp_accel_alloc(); uk_krs_acc=gsl_interp_accel_alloc(); bool_inituk=true; }