GENIEGenerator
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ARSampledNucleus.cxx
Go to the documentation of this file.
1 //____________________________________________________________________________
2 /*
3  Copyright (c) 2003-2024, 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
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
void SGNR(const double a, const double b, const unsigned int n, const unsigned int nsamp, double *x, unsigned int &np, double *w)
#define pDEBUG
Definition: Messenger.h:63