#include "AMISIC++/Tools/Matter_Overlap.H" #include "ATOOLS/Math/Histogram.H" #include "ATOOLS/Math/Random.H" #include "ATOOLS/Math/MathTools.H" #include "ATOOLS/Math/Gauss_Integrator.H" #include "ATOOLS/Org/Message.H" #include "ATOOLS/Org/Exception.H" using namespace AMISIC; using namespace ATOOLS; // All equations in this file refer to // Sjostrand-van der Zijl, PRD 36 (1987) 2019. Matter_Overlap::Matter_Overlap() : m_bstep(0.), m_bmax(0.), m_integral(0.), m_norm(1./M_PI) ///(4.*M_PI*M_PI)) {} Matter_Overlap::~Matter_Overlap() {} void Matter_Overlap::Initialize() { InitializeFormFactors(); CalculateIntegral(); } double Matter_Overlap::operator()(double b) { // Matter overlap in two forms available, but only Single_Gaussian fully // functional at the moment. switch (m_overlapform) { case overlap_form::Single_Gaussian: return m_norm * m_norm1 * exp(-b*b/m_radius12); case overlap_form::Double_Gaussian: default: double b2(b*b); return m_norm * (m_norm1 * exp(-b2/m_radius12) + m_norm2 * exp(-b2/m_radius22) + m_norm3 * exp(-b2/m_radius32)); } return 0.; } double Matter_Overlap::SelectB() const { // Algorithm: // 1. select a radius R according to matter content: // - for single Gaussian, there is no selection to be made // - for double Gaussian, one of the three radii is picked. // 2. Select b according to d^2b O(b) = d b^2 exp(-b^2/R^2). double b(0), radius; switch (m_overlapform) { case overlap_form::Single_Gaussian: radius = m_radius1; break; case overlap_form::Double_Gaussian: double rand = ran->Get(); if ((rand-=sqr(m_fraction1))<=0.) radius = m_radius1; else if ((rand-=sqr(1-m_fraction1))<=0.) radius = m_radius2; else radius = m_radius3; break; } do { b = sqrt(-log(Max(1.e-12,ran->Get())))*radius; } while (b>m_bmax); return b; } void Matter_Overlap::InitializeFormFactors() { // Matter overlap in two forms available, but only Single_Gaussian fully // functional at the moment. m_overlapform = mipars->GetOverlapForm(); switch (m_overlapform) { case overlap_form::Single_Gaussian: m_fraction1 = 1.; m_radius1 = (*mipars)("Matter_Radius1"); m_radius12 = sqr(m_radius1); m_norm1 = 1./m_radius12; m_bstep = m_radius1/100.; break; case overlap_form::Double_Gaussian: m_fraction1 = (*mipars)("Matter_Fraction1"); m_radius1 = (*mipars)("Matter_Radius1"); m_radius12 = sqr(m_radius1); m_radius2 = (*mipars)("Matter_Radius2"); m_radius22 = sqr(m_radius2); m_radius32 = (m_radius12+m_radius22)/2.; m_radius3 = sqrt(m_radius32); m_norm1 = sqr(m_fraction1)/m_radius12; m_norm2 = sqr(1.-m_fraction1)/m_radius22; m_norm3 = 2.*m_fraction1*(1.-m_fraction1)/m_radius32; m_bstep = Min(m_radius1,m_radius2)/100.; break; } } void Matter_Overlap::CalculateIntegral() { // Integral int d^2b O(b), numerator Eq.(32) MO_Integrand moint(this); Gauss_Integrator integrator(&moint); double bmin = 0., bstep = m_bstep, previous = 0., previous2 = 0., result = 0.; do { result += previous = integrator.Integrate(bmin,bmin+bstep,1.e-8,1); bmin += bstep; } while (dabs(previous/result)>1.e-10); m_bmax = bmin; m_integral = result; msg_Out()<