ARSampledNucleus.cxx
Go to the documentation of this file.
1 //____________________________________________________________________________
2 /*
3  Copyright (c) 2003-2020, The GENIE Collaboration
4  For the full text of the license visit http://copyright.genie-mc.org
5 
6  Daniel Scully ( d.i.scully \at warwick.ac.uk)
7  University of Warwick
8 */
9 //____________________________________________________________________________
10 
11 #include "ARSampledNucleus.h"
14 
15 #include <string>
16 #include <iostream>
17 #include <cstdlib>
18 #include <sstream>
19 #include <fstream>
20 #include <istream>
21 #include <complex>
22 
23 #include <TSystem.h>
24 #include <TF1.h>
25 #include <TMath.h>
26 #include <Math/GaussLegendreIntegrator.h>
27 
31 
32 //
33 // Equation/Table numbers refer to:
34 // J. Nieves and E. Oset
35 // A Theoretical approach to pionic atoms and the problem of anomalies
36 // Nuclear Physics A 554 (1993) 509-553
37 //
38 
39 using namespace genie::constants;
40 
41 namespace genie {
42 namespace alvarezruso {
43 
44 double ARSampledNucleus::mean_radius_squared = 0.69; // fm (CA)
45 
46 ARSampledNucleus::ARSampledNucleus(unsigned int ZNumber, unsigned int ANumber, unsigned int fSampling_):
47  fZ(ZNumber),
48  fA(ANumber),
49  fSampling(fSampling_)
50 {
52 
53  fDensities = NULL;
54  fDensitiesOfCentres = NULL;
55  fRadii = NULL;
56  fSample_points_1 = NULL;
57  fSample_points_2 = NULL;
58  fSample_weights_1 = NULL;
59  fSample_weights_2 = NULL;
60 
61  if(fA>20) { // fermi gas
62  if (fA == 27) { fNucRadius = 3.07; fDiffuseness = 0.52; } // aluminum
63  else if (fA == 28) { fNucRadius = 3.07; fDiffuseness = 0.54; } // silicon
64  else if (fA == 40) { fNucRadius = 3.53; fDiffuseness = 0.54; } // argon
65  else if (fA == 56) { fNucRadius = 4.10; fDiffuseness = 0.56; } // iron
66  else if (fA == 208) { fNucRadius = 6.62; fDiffuseness = 0.55; } // lead
67  else {
68  fNucRadius = pow(fA,0.35); fDiffuseness = 0.54;
69  } //others
70  fUseHarmonicOscillator = false;
71  }
72  else {
73  if (fA == 7) { fNucRadius = 1.77 ; fDiffuseness = 0.327;} // lithium
74  else if (fA == 12) { fNucRadius = 1.692 ; fDiffuseness = 1.083;} // carbon
75  else if (fA == 14) { fNucRadius = 1.76 ; fDiffuseness = 1.23; } // nitrogen
76  else if (fA == 16) { fNucRadius = 1.83 ; fDiffuseness = 1.54; } // oxygen
77  else if (fA <= 4 ) { fNucRadius = 1.344 ; fDiffuseness = 0.00; } // helium
78  else {
79  fNucRadius=1.75; fDiffuseness=-0.4+.12*fA;
80  } //others- fDiffuseness=0.08 if A=4
81 
83  }
84 
86 
87  // Calculate number densities (density of 'centres'):
88  double diff2 = fDiffuseness*fDiffuseness;
90  fRadiusCentres = TMath::Sqrt( (fNucRadiusSq) - (mean_radius_squared / 1.5) );
91  double x = (fDiffuseness * fNucRadiusSq) / ((1 + (1.5*fDiffuseness)) * (fRadiusCentres*fRadiusCentres));
92  fDiffusenessCentres = 2.*x / (2. - 3.*x ) ;
93  }
94  else { //fermi liquid
95  double numerator = 5.0 * mean_radius_squared * fNucRadius;
96  double denominator = (15.0 * (fNucRadiusSq)) + (7.0 * kPi2 * fDiffuseness*fDiffuseness);
97  fRadiusCentres = fNucRadius + (numerator / denominator);
98 
99  numerator = (fNucRadiusSq*fNucRadius) + (kPi2 * diff2 * fRadiusCentres) - (fRadiusCentres*fRadiusCentres*fRadiusCentres);
100  denominator = kPi2 * fRadiusCentres;
101 
102  fDiffusenessCentres = sqrt( numerator / denominator );
103  }
104 
105  this->Fill();
106 }
107 
109 {
110  for(unsigned int i = 0; i != fNDensities; ++i)
111  {
112  if (fDensities && fDensities [i]) delete[] fDensities[i];
114  if (fRadii && fRadii [i]) delete[] fRadii [i];
115  }
116 
117  if (fDensities ) delete[] fDensities;
119  if (fRadii ) delete[] fRadii ;
120  if (fSample_points_1 ) delete[] fSample_points_1;
121  if (fSample_points_2 ) delete[] fSample_points_2;
122  if (fSample_weights_1 ) delete[] fSample_weights_1;
123  if (fSample_weights_2 ) delete[] fSample_weights_2;
124 }
126 {
127 
128  fR_max = 3.0 * TMath::Power(this->A(), (1.0/3.0));
129 
130 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
131  LOG("AR_PiWFunction_Table", pDEBUG)<< "N:: fR_max = " << fR_max
132  << "N:: z = " << fZ
133  << "N:: a = " << fA
134 #endif
135 
136  this->FillSamplePoints();
137  this->FillDensities();
138 }
139 
140 double ARSampledNucleus::Density(const int i, const int j) const
141 {
142  return fDensities[i][j];
143 }
144 
145 double ARSampledNucleus::DensityOfCentres(const int i, const int j) const
146 {
147  return fDensitiesOfCentres[i][j];
148 }
149 
150 double ARSampledNucleus::Radius(const int i, const int j) const
151 {
152  return fRadii[i][j];
153 }
154 
156 {
157  if (fSample_points_1) delete[] fSample_points_1;
158  if (fSample_points_2) delete[] fSample_points_2;
159  if (fSample_weights_1) delete[] fSample_weights_1;
160  if (fSample_weights_2) delete[] fSample_weights_2;
161 
162  fSample_points_1 = new double[fNDensities];
163  fSample_points_2 = new double[fNDensities];
164 
165  fSample_weights_1 = new double[fNDensities];
166  fSample_weights_2 = new double[fNDensities];
167  unsigned int decoy;
168 
171 
172 }
173 
175 {
176  double r;
177 
178  for(unsigned int i = 0; i != fNDensities; ++i)
179  {
180  if (fDensities && fDensities [i]) delete[] fDensities [i];
182  if (fRadii && fRadii [i]) delete[] fRadii [i];
183  }
184  if (fDensities ) delete[] fDensities;
186  if (fRadii ) delete[] fRadii ;
187 
188  fDensities = new double*[fNDensities];
189  fDensitiesOfCentres = new double*[fNDensities];
190  fRadii = new double*[fNDensities];
191 
192  for(unsigned int i = 0; i != fNDensities; ++i)
193  {
194  fDensities [i] = new double[fNDensities];
195  fDensitiesOfCentres[i] = new double[fNDensities];
196  fRadii [i] = new double[fNDensities];
197 
198  for(unsigned int j = 0; j != fNDensities; ++j)
199  {
200  r = TMath::Sqrt( fSample_points_1[i]*fSample_points_1[i] + fSample_points_2[j]*fSample_points_2[j] );
201  fRadii[i][j] = r;
202  fDensities [i][j]=this->CalcMatterDensity(r);
203  fDensitiesOfCentres[i][j]=this->CalcNumberDensity(r);
204  }
205  }
206 }
207 
208 unsigned int ARSampledNucleus::GetSampling (void) const
209 {
210  return fSampling;
211 }
212 unsigned int ARSampledNucleus::GetNDensities(void) const
213 {
214  return fNDensities;
215 }
216 
217 double ARSampledNucleus::CalcDensity(double r, double nuc_rad, double nuc_diff) const
218 {
219  double dens_rel;
221  dens_rel = (1.0 + nuc_diff*r*r/(nuc_rad*nuc_rad)) * exp(-r*r/(nuc_rad*nuc_rad));
222  }
223  else { //fermi liquid
224  dens_rel = 1.0 / (1.0 + exp((r - nuc_rad)/nuc_diff));
225  }
226 
227  //~ double dens_0 = utils::nuclear::Density(nuc_rad, fA);
228  double dens_0 = Density0(fA,nuc_rad,nuc_diff);
229 
230  return dens_0 * dens_rel;
231 }
232 
234  unsigned int number, // A
235  double radius, // R
236  double diffuseness // a
237  ) const
238 {
239  double result = 0.0;
241  {
242  double u = fR_max/radius;
243  double dterm = (3*diffuseness+2);
244  double term1 = TMath::Sqrt(TMath::Pi())*dterm*TMath::Power(radius,3)*TMath::Exp(u*u)*TMath::Erf(u);
245  double term2 = 2*fR_max*(dterm*radius*radius+2*diffuseness*radius*radius);
246  result = (0.5)*TMath::Pi()*TMath::Exp(-u*u)*(term1 - term2);
247  }
248  else
249  {
250  //Probably faster to do this via the integral for the moment as ROOT doesn't have a builtin
251  //PolyLog function
252  TF1* f = this->Density0Function();
253  f->SetParameter(0, diffuseness);
254  f->SetParameter(1, radius);
255  result = f->Integral(0.0,fR_max);
256  delete f;
257  }
258 
259  return ( number / result );
260 }
261 
263 {
264  return (new TF1("density0function", Density0FunctionFermiLiquid, 0.0, fR_max, 2));
265 }
266 
267 Double_t ARSampledNucleus::Density0FunctionFermiLiquid(Double_t* r_, Double_t* parameters)
268 {
269  double r = (*r_);
270  double diffuseness = parameters[0];
271  double radius = parameters[1];
272 
273  double dens = 1.0 / (1.0 + exp((r - radius)/diffuseness));
274 
275  return 4.0*TMath::Pi()*r*r*dens;
276 }
277 
279 {
280  return this->CalcDensity(r,fNucRadius,fDiffuseness);
281 }
282 
284 {
286 }
287 
288 } //namespace alvarezruso
289 } //namespace genie
double Density(const int i, const int j) const
Basic constants.
THE MAIN GENIE PROJECT NAMESPACE
Definition: AlgCmp.h:25
static QCString result
constexpr T pow(T x)
Definition: pow.h:72
double Radius(const int i, const int j) const
double CalcMatterDensity(double r) const
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:96
static Double_t Density0FunctionFermiLiquid(Double_t *r, Double_t *parameters)
double Density0(unsigned int number, double diffuseness, double radius) const
double CalcDensity(double radius, double nuc_rad, double nuc_diff) const
unsigned int GetNDensities(void) const
unsigned int GetSampling(void) const
double CalcNumberDensity(double r) const
double DensityOfCentres(const int i, const int j) const
list x
Definition: train.py:276
void SGNR(const double a, const double b, const unsigned int n, const unsigned int nsamp, double *x, unsigned int &np, double *w)
static const double kPi2
Definition: Constants.h:38
#define pDEBUG
Definition: Messenger.h:63