Public Member Functions | Private Member Functions | Private Attributes | List of all members
osc::EarthModel Class Reference

#include <EarthModel.h>

Public Member Functions

 EarthModel (const char *which, double tol)
 
double Ne (double r)
 
double Density (double r)
 
double ZoverA (double r)
 
void GetLayers (std::vector< double > &rlo, std::vector< double > &rhi, std::vector< double > &ne)
 
void LineProfile (double prodL, double cosQ, double rdet, std::list< double > &Ls, std::list< double > &Ns)
 

Private Member Functions

void InitPREM ()
 
void InitStacey ()
 
double DensityPREM (double r)
 
double DensityStacey (double r)
 
double AveNe (double r1, double r2, int nsample)
 
void MakeLayers (double tol)
 
int IntersectLineAndCircle (double x1, double y1, double x2, double y2, double r, double *xa, double *ya, double *xb, double *yb)
 

Private Attributes

int fModelID
 
double fRouterCore
 
double fRearth
 
std::vector< double > fRregion
 
std::vector< double > fRlo
 
std::vector< double > fRhi
 
std::vector< double > fNe
 

Detailed Description

Definition at line 13 of file EarthModel.h.

Constructor & Destructor Documentation

EarthModel::EarthModel ( const char *  which,
double  tol 
)

Definition at line 18 of file EarthModel.cxx.

19 {
20  if (std::string("PREM") ==which) this->InitPREM();
21  else if (std::string("STACEY")==which) this->InitStacey();
22  // else if (std::string("ModelX")==which) this->InitModelX();
23  else {
24  std::cerr << __FILE__ << ":" << __LINE__
25  << " Model '" << which << "' is not supported."
26  << " Currently only PREM is supported." << std::endl;
27  abort();
28  }
29  this->MakeLayers(tol);
30 }
std::string string
Definition: nybbler.cc:12
void MakeLayers(double tol)
Definition: EarthModel.cxx:278
QTextStream & endl(QTextStream &s)

Member Function Documentation

double EarthModel::AveNe ( double  r1,
double  r2,
int  nsample 
)
private

Definition at line 266 of file EarthModel.cxx.

267 {
268  double sum = 0.0;
269  double r;
270  for (int i=0; i<nsample; ++i) {
271  r = r1 + (r2-r1)*((float)i+0.5)/(float)nsample;
272  sum += this->Ne(r);
273  }
274  return sum/(float)nsample;
275 }
double Ne(double r)
Definition: EarthModel.cxx:33
double EarthModel::Density ( double  r)

Definition at line 39 of file EarthModel.cxx.

40 {
41  switch (fModelID) {
42  case kPREM: return this->DensityPREM(r);
43  case kSTACEY: return this->DensityStacey(r);
44  default: abort();
45  }
46  return 0.0;
47 }
double DensityStacey(double r)
Definition: EarthModel.cxx:105
double DensityPREM(double r)
Definition: EarthModel.cxx:69
static const int kPREM
Definition: EarthModel.cxx:15
static const int kSTACEY
Definition: EarthModel.cxx:16
double EarthModel::DensityPREM ( double  r)
private

Definition at line 69 of file EarthModel.cxx.

70 {
71  double x = r/fRearth;
72 
73  // The regions are checked in order from largest to smallest
74  if (r>1221.5&&r<=3480.0) return 12.5815+x*(-1.2638+x*(-3.6426+x*(-5.5281)));
75  if (r>3480.0&&r<=5701.0) return 7.9565+x*(-6.4761+x*(5.5283+x*(-3.0807)));
76  if (r<=1221.5) return 13.0885-8.8381*x*x;
77  if (r>5771.0&&r<=5971.0) return 11.2494-8.0298*x;
78  if (r>5971.0&&r<=6151.0) return 7.1089-3.8045*x;
79  if (r>6151.0&&r<=6291.0) return 2.6910+0.6924*x;
80  if (r>5701.0&&r<=5771.0) return 5.3197-1.4836*x;
81  if (r>6291.0&&r<=6346.6) return 2.6910+0.6924*x;
82  if (r>6346.6&&r<=6356.0) return 2.90;
83  if (r>6356.0&&r<=6368.0) return 2.60;
84  if (r>6368.0&&r<=6371.0) return 1.020;
85  return 0.0;
86 }
double fRearth
Definition: EarthModel.h:46
list x
Definition: train.py:276
double EarthModel::DensityStacey ( double  r)
private

Definition at line 105 of file EarthModel.cxx.

106 {
107  static double crustD[2] = { 0.0,
108  15.0};
109  static double upperMantleD[6] = { 15.0,
110  60.0,
111  100.0,
112  200.0,
113  300.0,
114  350.0};
115  static double middleMantleD[6] = {350.0,
116  400.0,
117  413.0,
118  500.0,
119  600.0,
120  650.0};
121  static double lowerMantleD[14] = {650.0,
122  800.0,
123  984.0,
124  1000.0,
125  1200.0,
126  1400.0,
127  1600.0,
128  1800.0,
129  2000.0,
130  2200.0,
131  2400.0,
132  2600.0,
133  2800.0,
134  2878.0};
135  static double outerCoreD[14] = { 2878.0,
136  3000.0,
137  3200.0,
138  3400.0,
139  3600.0,
140  3800.0,
141  4000.0,
142  4200.0,
143  4400.0,
144  4600.0,
145  4800.0,
146  4982.0,
147  5000.0,
148  5121.0};
149  static double innerCoreD[8] ={ 5121.0,
150  5200.0,
151  5400.0,
152  5600.0,
153  5800.0,
154  6000.0,
155  6200.0,
156  6371.0};
157  static double crustRho[2] = { 2.840,
158  2.840};
159  static double upperMantleRho[6] = { 3.313,
160  3.332,
161  3.348,
162  3.387,
163  3.424,
164  3.441};
165  static double middleMantleRho[6] = {3.700,
166  3.775,
167  3.795,
168  3.925,
169  4.075,
170  4.150};
171  static double lowerMantleRho[14] = {4.200,
172  4.380,
173  4.529,
174  4.538,
175  4.655,
176  4.768,
177  4.877,
178  4.983,
179  5.087,
180  5.188,
181  5.288,
182  5.387,
183  5.487,
184  5.527};
185  static double outerCoreRho[14] = { 9.927,
186  10.121,
187  10.421,
188  10.697,
189  10.948,
190  11.176,
191  11.383,
192  11.570,
193  11.737,
194  11.887,
195  12.017,
196  12.121,
197  12.130,
198  12.197};
199  static double innerCoreRho[7] = { 12.229,
200  12.301,
201  12.360,
202  12.405,
203  12.437,
204  12.455,
205  12.460};
206  // ============ END DENSITY TABLE ============
207 
208  if (r>fRearth) return 0.0;
209  double d = fRearth-r; // Table uses depth
210  register int i;
211 
212  if (d>=crustD[0] && d<crustD[1]) {
213  for (i=0; i<1; ++i) {
214  if (d>=crustD[i] && d<crustD[i+1]) {
215  return crustRho[i];
216  }
217  }
218  }
219  if (d>=upperMantleD[0] && d<upperMantleD[5]) {
220  for (i=0; i<5; ++i) {
221  if (d>=upperMantleD[i] && d<upperMantleD[i+1]) {
222  return upperMantleRho[i];
223  }
224  }
225  }
226  if (d>=middleMantleD[0] && d<middleMantleD[5]) {
227  for (i=0; i<5; ++i) {
228  if (d>=middleMantleD[i] && d<middleMantleD[i+1]) {
229  return middleMantleRho[i];
230  }
231  }
232  }
233  if (d>=lowerMantleD[0] && d<lowerMantleD[13]) {
234  for (i=0; i<13; ++i) {
235  if (d>=lowerMantleD[i] && d<lowerMantleD[i+1]) {
236  return lowerMantleRho[i];
237  }
238  }
239  }
240  if (d>=outerCoreD[0] && d<outerCoreD[13]) {
241  for (i=0; i<13; ++i) {
242  if (d>=outerCoreD[i] && d<outerCoreD[i+1]) {
243  return outerCoreRho[i];
244  }
245  }
246  }
247  if (d>=innerCoreD[0] && d<innerCoreD[7]) {
248  for (i=0; i<7; ++i) {
249  if (d>=innerCoreD[i] && d<innerCoreD[i+1]) {
250  return innerCoreRho[i];
251  }
252  }
253  }
254  return 0.0;
255 }
double fRearth
Definition: EarthModel.h:46
void EarthModel::GetLayers ( std::vector< double > &  rlo,
std::vector< double > &  rhi,
std::vector< double > &  ne 
)

Definition at line 324 of file EarthModel.cxx.

327 {
328  rlo.resize(fRlo.size());
329  rhi.resize(fRlo.size());
330  ne. resize(fRlo.size());
331  for (unsigned int i=0; i<fRlo.size(); ++i) {
332  rlo[i] = fRlo[i];
333  rhi[i] = fRhi[i];
334  ne[i] = fNe[i];
335  }
336 }
std::vector< double > fNe
Definition: EarthModel.h:51
void resize(Vector< T > &vec1, Index n1, const V &val)
std::vector< double > fRlo
Definition: EarthModel.h:49
std::vector< double > fRhi
Definition: EarthModel.h:50
void EarthModel::InitPREM ( )
private

Definition at line 50 of file EarthModel.cxx.

51 {
52  fModelID = kPREM;
53  fRouterCore = 3480.0;
54  fRearth = 6371.0;
55 
56  fRregion.push_back(0.0);
57  fRregion.push_back(1221.5); // Inner core
58  fRregion.push_back(3480.0); // Outer core
59  fRregion.push_back(3630.0); // D''
60  fRregion.push_back(5701.0); // Lower mantle
61  fRregion.push_back(6151.0); // Transition zone
62  fRregion.push_back(6291.0); // Low velocity zone
63  fRregion.push_back(6346.6); // LID
64  fRregion.push_back(6368.0); // Crust
65  fRregion.push_back(6371.0); // Ocean
66 }
double fRearth
Definition: EarthModel.h:46
std::vector< double > fRregion
Definition: EarthModel.h:47
double fRouterCore
Definition: EarthModel.h:45
static const int kPREM
Definition: EarthModel.cxx:15
void EarthModel::InitStacey ( )
private

Definition at line 89 of file EarthModel.cxx.

90 {
91  fModelID = kSTACEY;
92  fRouterCore = 6371.0-2878.0;
93  fRearth = 6371.0;
94 
95  fRregion.push_back(0.0);
96  fRregion.push_back(6371.0-5121.0); // Inner core
97  fRregion.push_back(6371.0-2878.0); // Outer core
98  fRregion.push_back(6371.0-650.0); // Lower mantle
99  fRregion.push_back(6371.0-350.0); // Middle mantle
100  fRregion.push_back(6371.0-15.0); // Upper mantle
101  fRregion.push_back(6371.0); // Crust
102 }
double fRearth
Definition: EarthModel.h:46
std::vector< double > fRregion
Definition: EarthModel.h:47
double fRouterCore
Definition: EarthModel.h:45
static const int kSTACEY
Definition: EarthModel.cxx:16
int EarthModel::IntersectLineAndCircle ( double  x1,
double  y1,
double  x2,
double  y2,
double  r,
double *  xa,
double *  ya,
double *  xb,
double *  yb 
)
private

Definition at line 517 of file EarthModel.cxx.

522 {
523  double dx = x2-x1;
524  double dy = y2-y1;
525  double drsqr = dx*dx + dy*dy;
526  double D = x1*y2 - x2*y1;
527  double arg = r*r*drsqr - D*D;
528  if (arg<0.0) return 0;
529 
530  double sgndy = 1.0;
531  if (dy<0.0) sgndy = -1.0;
532 
533  *xa = ( D*dy - sgndy * dx * sqrt(arg) ) / drsqr;
534  *ya = (-D*dx - fabs(dy) * sqrt(arg) ) / drsqr;
535  *xb = ( D*dy + sgndy * dx * sqrt(arg) ) / drsqr;
536  *yb = (-D*dx + fabs(dy) * sqrt(arg) ) / drsqr;
537 
538  if (arg==0.0) return 1;
539  return 2;
540 }
#define D
Debug message.
Definition: tclscanner.cpp:775
void EarthModel::LineProfile ( double  prodL,
double  cosQ,
double  rdet,
std::list< double > &  Ls,
std::list< double > &  Ns 
)

Definition at line 339 of file EarthModel.cxx.

344 {
345  // A typical number density for the crust
346  static const double crustNe = 2.6*0.5;
347 
348  // Locations are relative to a cicular Earth centered at (0,0)
349  double rdet; // Radial location of detector (km)
350  double rnu; // Radial location of neutrino (km)
351  double Lnu; // Total flight distance of neutrino (km)
352  double x1; // Location of detector (km)
353  double y1; // Location of detector (km)
354  double x2; // Location of neutrino production (km)
355  double y2; // Location of neutrino production (km)
356 
357  rdet = fRearth+adet;
358  rnu = fRearth+anu;
359  Lnu = rdet*(sqrt(util::sqr(rnu/rdet)+cosQ*cosQ-1.0)-cosQ);
360 
361  x2 = 0.0;
362  y2 = rdet;
363  x1 = x2+sqrt(1.0-cosQ*cosQ)*Lnu;
364  y1 = y2+cosQ*Lnu;
365 
366  unsigned int i;
367  int n1, n2;
368  double L;
369  double xina, yina;
370  double xouta, youta;
371  double xinb, yinb;
372  double xoutb, youtb;
373  Ls.clear();
374  Ns.clear();
375 
376  //
377  // For down-going neutrinos, only consider matter in the top layer
378  //
379  if (cosQ>=0.0) {
380  if (adet>0.0) {
381  Ls.push_back(Lnu);
382  Ns.push_back(0.0);
383  }
384  else {
385  n1 = this->IntersectLineAndCircle(x1, y1, x2, y2, fRearth,
386  &xouta, &youta, &xoutb, &youtb);
387  L = util::pythag(x1-xoutb, y1-youtb);
388  Ls.push_back(L);
389  Ns.push_back(0.0);
390 
391  L = util::pythag(x2-xoutb, y2-youtb);
392  Ls.push_back(L);
393  Ns.push_back(crustNe); // Typical rock density
394  }
395  return;
396  }
397 
398  //
399  // For up-going neutrinos, find the intersections of the neutrino's
400  // path with all layers of the Earth model.
401  //
402  for (i=0; i<fRhi.size()-1; ++i) {
403  n1 = this->IntersectLineAndCircle(x1, y1, x2, y2, fRhi[i],
404  &xouta, &youta, &xoutb, &youtb);
405 
406  n2 = this->IntersectLineAndCircle(x1, y1, x2, y2, fRlo[i],
407  &xina, &yina, &xinb, &yinb);
408  //
409  // Create segments for each layer we intersect
410  //
411  if (n1==2 && n2<2) {
412  //
413  // Intersect outer radius, but not inner radius:
414  // Only one one segment to create.
415  //
416  L = util::pythag(xouta-xoutb, youta-youtb);
417 
418  Ls.push_back(L);
419  Ns.push_back(fNe[i]);
420  }
421  else if (n1==2 && n2==2) {
422  //
423  // Path intersects both inner and outer radii: Two sections to
424  // create, one on the way in, one on the way out.
425  //
426  L = util::pythag(xouta-xina, youta-yina);
427  Ls.push_front(L);
428  Ns.push_front(fNe[i]);
429 
430  L = util::pythag(xoutb-xinb, youtb-yinb);
431  Ls.push_back(L);
432  Ns.push_back(fNe[i]);
433  }
434  } // Loop on all but last layer
435 
436  //
437  // Handle the last layer specially
438  //
439  i = fRhi.size()-1;
440  n1 = this->IntersectLineAndCircle(x1, y1, x2, y2, fRhi[i],
441  &xouta, &youta, &xoutb, &youtb);
442  n2 = this->IntersectLineAndCircle(x1, y1, x2, y2, fRlo[i],
443  &xina, &yina, &xinb, &yinb);
444  if (n1==2 && n2<2) {
445  //
446  // Intersect outer radius, but not inner radius:
447  // One one segment to create
448  //
449  if (youtb>y2) {
450  //
451  // Don't over shoot the detector location
452  //
453  L = util::pythag(xouta-x2, youta-y2);
454  }
455  else {
456  L = util::pythag(xouta-xoutb, youta-youtb);
457  }
458  Ls.push_back(L);
459  Ns.push_back(fNe[i]);
460  }
461  else if (n1==2 && n2==2) {
462  //
463  // Path intersects both inner and outer radii: Two sections to
464  // create, one on the way in, one on the way out.
465  //
466  L = util::pythag(xouta-xina, youta-yina);
467  Ls.push_front(L);
468  Ns.push_front(fNe[i]);
469 
470  if (youtb>y2) {
471  //
472  // Don't over shoot the detector location
473  //
474  L = util::pythag(x2-xinb, y2-yinb);
475  }
476  else {
477  L = util::pythag(xoutb-xinb, youtb-yinb);
478  }
479  Ls.push_back(L);
480  Ns.push_back(fNe[i]);
481  }
482  //
483  // Add segment to get neutrino from production to Earth's surface
484  //
485  L = util::pythag(xouta-x1, youta-y1);
486  Ls.push_front(L);
487  Ns.push_front(0.0); // Density of air~=0
488 
489  //
490  // If required, add segment to get from sea level up to the
491  // detector's position
492  //
493  if (youtb<y2) {
494  L = util::pythag(xoutb-x2, youtb-y2);
495  Ls.push_back(L);
496  Ns.push_back(crustNe); // Density of of standard rock (mole/cm^3)
497  }
498 
499  //
500  // The following is a useful piece of debugging - check that we've
501  // accounted for all pieces of the neutrino flight distance
502  //
503  if (false) {
504  std::list<double>::iterator itr(Ls.begin());
505  std::list<double>::iterator itrEnd(Ls.end());
506  double ltot = 0.0;
507  for (; itr!=itrEnd; ++itr) {
508  ltot += (*itr);
509  }
510  std::cout << ltot << " " << Lnu << std::endl;
511  if (fabs(ltot-Lnu)>1e-6) abort();
512  }
513 }
intermediate_table::iterator iterator
std::vector< double > fNe
Definition: EarthModel.h:51
double fRearth
Definition: EarthModel.h:46
const double rdet
Definition: LBNENuWeight.cc:13
T sqr(T v)
int IntersectLineAndCircle(double x1, double y1, double x2, double y2, double r, double *xa, double *ya, double *xb, double *yb)
Definition: EarthModel.cxx:517
std::vector< double > fRlo
Definition: EarthModel.h:49
std::vector< double > fRhi
Definition: EarthModel.h:50
QTextStream & endl(QTextStream &s)
void EarthModel::MakeLayers ( double  tol)
private

Definition at line 278 of file EarthModel.cxx.

279 {
280  unsigned int nsample = 20;
281  for (unsigned int i=0; i<fRregion.size()-1; ++i) {
282  // Add layers within each region until all layers are within
283  // tolerance
284  double rRegionLo = fRregion[i];
285  double rRegionHi = fRregion[i+1];
286  double r1 = rRegionLo;
287  double r2 = rRegionHi;
288  double r;
289  double ne;
290  while (1) {
291  double ave = this->AveNe(r1, r2, nsample);
292  bool isok = true;
293  for (unsigned int j=0; j<nsample; ++j) {
294  r = r1+(r2-r1)*((float)j+0.5)/(float)nsample;
295  ne = this->Ne(r);
296  if (fabs(ne-ave)/ne>tol) { isok = false; break; }
297  }
298  if (isok) {
299  // Layer is within tolerance - accept it
300  fRlo.push_back(r1);
301  fRhi.push_back(r2);
302  fNe. push_back(ave);
303  if (r2>=rRegionHi) {
304  // Finished subdividing this region
305  break;
306  }
307  else {
308  // Ready next iteration of subdivision
309  r1 = r2;
310  r2 = rRegionHi;
311  }
312  } // if (isok) ...
313  else {
314  // Layer is not within tolerance - reduce its size
315  r2 -= 1.0; // Step back some distance (km) and try again
316  if (r2<=r1) r2 = r1+0.5;
317  }
318  } // making layers within region
319  } // loop on regions
320 }
std::vector< double > fNe
Definition: EarthModel.h:51
std::vector< double > fRregion
Definition: EarthModel.h:47
double Ne(double r)
Definition: EarthModel.cxx:33
double AveNe(double r1, double r2, int nsample)
Definition: EarthModel.cxx:266
std::vector< double > fRlo
Definition: EarthModel.h:49
std::vector< double > fRhi
Definition: EarthModel.h:50
if(!yymsg) yymsg
double EarthModel::Ne ( double  r)

Definition at line 33 of file EarthModel.cxx.

34 {
35  return this->ZoverA(r)*this->Density(r);
36 }
double ZoverA(double r)
Definition: EarthModel.cxx:258
double Density(double r)
Definition: EarthModel.cxx:39
double EarthModel::ZoverA ( double  r)

Definition at line 258 of file EarthModel.cxx.

259 {
260  if (r<fRouterCore) return 0.468;
261  return 0.497;
262 }
double fRouterCore
Definition: EarthModel.h:45

Member Data Documentation

int osc::EarthModel::fModelID
private

Definition at line 44 of file EarthModel.h.

std::vector<double> osc::EarthModel::fNe
private

Definition at line 51 of file EarthModel.h.

double osc::EarthModel::fRearth
private

Definition at line 46 of file EarthModel.h.

std::vector<double> osc::EarthModel::fRhi
private

Definition at line 50 of file EarthModel.h.

std::vector<double> osc::EarthModel::fRlo
private

Definition at line 49 of file EarthModel.h.

double osc::EarthModel::fRouterCore
private

Definition at line 45 of file EarthModel.h.

std::vector<double> osc::EarthModel::fRregion
private

Definition at line 47 of file EarthModel.h.


The documentation for this class was generated from the following files: