#include "SHRiMPS/Eikonals/Form_Factors.H" #include "SHRiMPS/Tools/MinBias_Parameters.H" #include "SHRiMPS/Tools/Special_Functions.H" #include "ATOOLS/Math/Gauss_Integrator.H" #include "ATOOLS/Math/Random.H" #include "ATOOLS/Math/Histogram.H" #include "ATOOLS/Org/Message.H" #include "ATOOLS/Org/MyStrStream.H" using namespace SHRIMPS; using namespace ATOOLS; Special_Functions SHRIMPS::SF; double Form_Factor::Norm_Argument::operator()(double q) { return 2.*M_PI*q*(*p_ff)(q); } double Form_Factor::FT_Argument::operator()(double q) { return 2.*M_PI*q*SF.Jn(0,q*m_b)*(*p_ff)(q); } Form_Factor::Form_Factor(const FormFactor_Parameters & params) : m_ftarg(this), m_number(params.number), m_form(params.form), m_prefactor(params.norm), m_beta(sqrt(params.beta02)), m_Lambda2(params.Lambda2), m_kappa(params.kappa), m_xi(params.xi), m_bmax(params.bmax), m_bsteps(16), m_deltab(m_bmax/double(m_bsteps)), m_accu(10.*params.accu), m_ffmin(1.e-8), m_ffmax(0.), m_ftnorm(4.*M_PI*M_PI) { } void Form_Factor::Initialise() { m_norm = NormAnalytical(); m_ftarg = FT_Argument(this); FillFourierTransformGrid(); } void Form_Factor::FillFourierTransformGrid() { msg_Tracking()< 12) { msg_Error()<0. && dabs(value/m_ffmax)m_ffmax) m_ffmax = value; m_values.push_back(value); b += m_deltab; } } bool Form_Factor::GridGood() { for (size_t i=1;i1.e-6 && dabs(fit)/m_ffmax>1.e-6 && dabs(fit/exact-1.)>m_accu/5.) { msg_Tracking()<<" - does not meet accuracy goal yet " <<"("<<(dabs(fit/exact-1.)>0.01)<<") " <<"in "< delta_b = "<<(m_deltab/2.)<<".\n"; return false; } } msg_Tracking()<<" - did meet accuracy goal.\n"; return true; } double Form_Factor::CalculateFourierTransform(const double & b) { double ft(0.), diff(1.), qmin(0.), qmax(10.); m_ftarg.SetB(b); Gauss_Integrator gauss(&m_ftarg); while (dabs(diff)>1.e-8) { diff = gauss.Integrate(qmin,qmax,sqr(m_accu)); ft += diff; qmin = qmax; qmax *= 2.; } if (ftm_bmax) return 0.; size_t bbin(size_t(absB/m_deltab)); if (bbin=1 && bbinm_values.front()) return 0.; if (valGet(); qt2 = -pref*log(1.-ATOOLS::ran->Get()*(1.-exp(-qt2max/pref))); } while (qt2Get(); //Original form factor //exp(-xi* ...)/(1+q^2/Lambda^2)^2 qt2 = (pref*qt2max*random)/(qt2max*(1.-random)+pref); } while (qt2Get()); break; default: break; } return qt2; } double Form_Factor::NormAnalytical() { double norm(m_beta*m_beta*M_PI*m_Lambda2/m_ftnorm); switch (m_form) { case ff_form::Gauss: break; case ff_form::dipole: norm *= (1.-exp(m_xi)*m_xi*SF.IncompleteGamma(0,m_xi)); break; default: norm = 0.; break; } return norm; } double Form_Factor::AnalyticalFourierTransform(const double & b) { double kernel(0.), pref(m_beta*m_beta*m_Lambda2*M_PI/m_ftnorm), help(0.); switch (m_form) { case ff_form::Gauss: kernel = exp(-b*b*m_Lambda2/(4.*(1.+m_kappa))); break; case ff_form::dipole: if (b<=1.e-8) kernel = 1.; else { help = sqrt((1.+m_kappa)/m_Lambda2); kernel = b/help * SF.Kn(1,b/help); } break; default: break; } return pref * kernel; } double Form_Factor::Norm() { Norm_Argument normarg(this); double norm(0.), diff(0.), rel(1.), qmin(0.), qmax(1.); Gauss_Integrator gauss(&normarg); while (rel>m_accu) { diff = gauss.Integrate(qmin,qmax,m_accu,1); norm += diff; rel = dabs(diff/norm); qmin = qmax; qmax *= 2.; } return norm/m_ftnorm; } void Form_Factor::Test(const std::string & dirname) { TestSpecialFunctions(dirname); WriteOutFF_Q(dirname); WriteOutFF_B(dirname); TestNormAndSpecificBs(dirname); TestQ2Selection(dirname); } void Form_Factor::TestSpecialFunctions(const std::string & dirname) { std::ofstream was1,was2; std::string filename1 = dirname+std::string("/LnGamma.dat"); was1.open(filename1.c_str()); std::string filename2 = dirname+std::string("/IncompleteGamma.dat"); was2.open(filename2.c_str()); for (int t=1;t<51;t++) { was1< params; params.push_back(m_prefactor); params.push_back(m_Lambda2); params.push_back(m_beta); params.push_back(m_kappa); params.push_back(m_xi); params.push_back(m_bmax); params.push_back(m_accu); diporig.Initialise(params); dipGauss.Initialise(params); params[4] = 1.e-6; dipana.Initialise(params); params[4] = 0.5; diphalf.Initialise(params); params[3] = -m_kappa; params[4] = m_xi; dipmin.Initialise(params); params[3] = 0.; dipzero.Initialise(params); double q(0.); std::string filename = dirname+ std::string("Form_Factor_In_Qspace.")+tag+std::string(".dat"); std::ofstream was; was.open(filename.c_str()); was<<"# Form factor in Q space: \n"; for (int qstep=0;qstep<10000;qstep++) { q = qstep*1./1000.; was<<" "<0 analytic xi=0.5 Gauss analytic \n"; double b(0.), val1, val2, val2a, val2b, val3, val3a; while (b<=8.) { val1 = diporig.FourierTransform(b); val2 = dipana.FourierTransform(b); val2a = dipana.AnalyticalFourierTransform(b); val2b = diphalf.FourierTransform(b); val3 = dipGauss.FourierTransform(b); val3a = dipGauss.AnalyticalFourierTransform(b); was<<" "<-kappa\n"; b = 0.; while (b<=8.) { val1 = diporig.FourierTransform(b); val2 = dipzero.FourierTransform(b); val3 = dipmin.FourierTransform(b); was<<" "<