Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
LaplaceSolution.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file LaplaceSolution.cxx
1 #include "LaplaceSolution.h"
2 
3 #include <iostream>
4 #include <math.h>
5 #include "TMath.h"
6 #include "TFile.h"
7 #include <string>
8 
9 using namespace std;
10 using namespace TMath;
11 
12 // Here we create the interface to the fortran code we got off the web...
13 extern"C"{
14  void dkia_(int *IFAC, double *X, double *A, double *DKI, double *DKID, int *IERRO);
15  void dlia_(int *IFAC, double *X, double *A, double *DLI, double *DLID, int *IERRO);
16 }
17 
18 
20  TFile *file = new TFile(filename.data());
21  fByFile = true;
22 }
23 
24 LaplaceSolution::LaplaceSolution(double InnerRadius, double OuterRadius, double HalfLength)
25 {
26  a = InnerRadius;
27  b = OuterRadius;
28  L = HalfLength;
29 
30  cout << "LaplaceSolution object initialized as follows:" << endl;
31  cout << " Inner Radius = " << a << " cm." << endl;
32  cout << " Outer Radius = " << b << " cm." << endl;
33  cout << " Half Length = " << L << " cm." << endl;
34 
35  verbosity = 0;
36  pi = 2.0 * asin(1.0);
37  cout << pi << endl;
38 
39  FindBetamn(0.0001);
40  FindMunk(0.0001);
41 
42  fByFile = false;
43  return ;
44 }
45 
46 
47 void LaplaceSolution::FindBetamn(double epsilon)
48 {
49  cout << "Now filling the Beta[m][n] Array..."<<endl;
50  double l = a/b;
51  for (int m=0; m<NumberOfOrders; m++)
52  {
53  if (verbosity) cout << endl << m;
54  int n=0; // !!! Off by one from Rossegger convention !!!
55  double x=epsilon;
56  double previous = jn(m,x)*yn(m,l*x) - jn(m,l*x)*yn(m,x);
57  while (n < NumberOfOrders)
58  {
59  // Rossegger equation 5.12
60  double value = jn(m,x)*yn(m,l*x) - jn(m,l*x)*yn(m,x);
61  //if (verbosity) cout << " " << value;
62  if (value == 0) cout << "FFFFFFUUUUUUUUUUU......" << endl;
63  if ( (value == 0) || (value<0 && previous>0) || (value>0 && previous<0))
64  {
65  double slp = (value-previous)/epsilon;
66  double cpt = value - slp*x;
67  double x0 = -cpt/slp;
68 
69  Betamn[m][n] = x0/b;
70  if (verbosity) cout << " " << x0 << "," << Betamn[m][n];
71  n++;
72  }
73  previous = value;
74  x+=epsilon;
75  }
76  }
77 
78 
79  // Now fill in the N2mn array...
80  for (int m=0; m<NumberOfOrders; m++)
81  {
82  for (int n=0; n<NumberOfOrders; n++)
83  {
84  // Rossegger Equation 5.17
85  // N^2_mn = 2/(pi * beta)^2 [ {Jm(beta a)/Jm(beta b)}^2 - 1 ]
86  N2mn[m][n] = 2/(pi*pi*Betamn[m][n]*Betamn[m][n]);
87  N2mn[m][n] *= (jn(m,Betamn[m][n]*a)*jn(m,Betamn[m][n]*a)/jn(m,Betamn[m][n]*b)/jn(m,Betamn[m][n]*b) - 1.0);
88  if (verbosity) cout << "m: " << m << " n: " << n << " N2[m][n]: " << N2mn[m][n];
89  double integral=0.0;
90  double step = 0.01;
91  for (double r=a; r<b; r+=step)
92  {
93  integral += Rmn(m,n,r)*Rmn(m,n,r)*r*step;
94  }
95  if (verbosity) cout << " Int: " << integral << endl;
96  //N2mn[m][n] = integral;
97  }
98  }
99 
100  cout << "Done." << endl;
101 }
102 
103 
104 void LaplaceSolution::FindMunk(double epsilon)
105 {
106  cout << "Now filling the Mu[n][k] Array..."<<endl;
107  cout << "Done." << endl;
108 }
109 
110 
111 double LaplaceSolution::Rmn(int m, int n, double r)
112 {
113  if (verbosity) cout << "Determine Rmn("<<m<<","<<n<<","<<r<<") = ";
114 
115  // Check input arguments for sanity...
116  int error=0;
117  if (m<0 || m>NumberOfOrders) error=1;
118  if (n<0 || n>NumberOfOrders) error=1;
119  if (r<a || r>b) error=1;
120  if (error)
121  {
122  cout << "Invalid arguments Rmn("<<m<<","<<n<<","<<r<<")" << endl;;
123  return 0;
124  }
125 
126  // Calculate the function using C-libraries from math.h
127  // Rossegger Equation 5.11:
128  // Rmn(r) = Ym(Beta_mn a)*Jm(Beta_mn r) - Jm(Beta_mn a)*Ym(Beta_mn r)
129  double R=0;
130  R = yn(m,Betamn[m][n]*a)*jn(m,Betamn[m][n]*r) - jn(m,Betamn[m][n]*a)*yn(m,Betamn[m][n]*r);
131 
132  if (verbosity) cout << R << endl;
133  return R;
134 }
135 
136 double LaplaceSolution::Rmn1(int m, int n, double r)
137 {
138  // Check input arguments for sanity...
139  int error=0;
140  if (m<0 || m>NumberOfOrders) error=1;
141  if (n<0 || n>NumberOfOrders) error=1;
142  if (r<a || r>b) error=1;
143  if (error)
144  {
145  cout << "Invalid arguments Rmn1("<<m<<","<<n<<","<<r<<")" << endl;;
146  return 0;
147  }
148 
149  // Calculate using the TMath functions from root.
150  // Rossegger Equation 5.32
151  // Rmn1(r) = Km(BetaN a)Im(BetaN r) - Im(BetaN a) Km(BetaN r)
152  double R=0;
153  double BetaN = (n+1)*pi/L;
154  R = BesselK(m,BetaN*a)*BesselI(m,BetaN*r)-BesselI(m,BetaN*a)*BesselK(m,BetaN*r);
155 
156  return R;
157 }
158 
159 double LaplaceSolution::Rmn2(int m, int n, double r)
160 {
161  // Check input arguments for sanity...
162  int error=0;
163  if (m<0 || m>NumberOfOrders) error=1;
164  if (n<0 || n>NumberOfOrders) error=1;
165  if (r<a || r>b) error=1;
166  if (error)
167  {
168  cout << "Invalid arguments Rmn2("<<m<<","<<n<<","<<r<<")" << endl;;
169  return 0;
170  }
171 
172  // Calculate using the TMath functions from root.
173  // Rossegger Equation 5.33
174  // Rmn2(r) = Km(BetaN b)Im(BetaN r) - Im(BetaN b) Km(BetaN r)
175  double R=0;
176  double BetaN = (n+1)*pi/L;
177  R = BesselK(m,BetaN*b)*BesselI(m,BetaN*r)-BesselI(m,BetaN*b)*BesselK(m,BetaN*r);
178 
179  return R;
180 }
181 
182 double LaplaceSolution::RPrime(int m, int n, double ref, double r)
183 {
184  // Check input arguments for sanity...
185  int error=0;
186  if (m<0 || m>NumberOfOrders) error=1;
187  if (n<0 || n>NumberOfOrders) error=1;
188  if (ref<a || ref>b) error=1;
189  if (r<a || r>b) error=1;
190  if (error)
191  {
192  cout << "Invalid arguments RPrime("<<m<<","<<n<<","<<ref<<","<<r<<")" << endl;;
193  return 0;
194  }
195 
196  double R=0;
197  // Calculate using the TMath functions from root.
198  // Rossegger Equation 5.65
199  // Rmn2(ref,r) = BetaN/2* [ Km(BetaN ref) {Im-1(BetaN r) + Im+1(BetaN r)}
200  // - Im(BetaN ref) {Km-1(BetaN r) + Km+1(BetaN r)} ]
201  // NOTE: K-m(z) = Km(z) and I-m(z) = Im(z)...
202  //
203  //
204  double BetaN = (n+1)*pi/L;
205  double term1 = BesselK(m,BetaN*ref)*( BesselI(abs(m-1),BetaN*r) + BesselI(m+1,BetaN*r) );
206  double term2 = BesselI(m,BetaN*ref)*( BesselK(abs(m-1),BetaN*r) + BesselK(m+1,BetaN*r) );
207  R = BetaN/2.0*(term1 + term2);
208 
209  return R;
210 }
211 
212 double LaplaceSolution::Rnk(int n, int k, double r)
213 {
214  // Check input arguments for sanity...
215  int error=0;
216  if (n<0 || n>NumberOfOrders) error=1;
217  if (k<0 || k>NumberOfOrders) error=1;
218  if (r<a || r>b) error=1;
219  if (error)
220  {
221  cout << "Invalid arguments Rnk("<<n<<","<<k<<","<<r<<")" << endl;;
222  return 0;
223  }
224 
225  // Rossegger Equation 5.45
226  // Rnk(r) = Limu_nk (BetaN a) Kimu_nk (BetaN r) - Kimu_nk(BetaN a) Limu_nk (BetaN r)
227  double BetaN = (n+1)*pi/L;
228 
229  int IFAC=1;
230  double A=Munk[n][k];
231  double DLI_1=0;
232  double DKI_1=0;
233  double DLI_2=0;
234  double DKI_2=0;
235  double DERR=0;
236  int IERRO=0;
237 
238  double X=BetaN*a;
239  dlia_( &IFAC, &X, &A, &DLI_1, &DERR, &IERRO);
240 
241  X=BetaN*r;
242  dkia_( &IFAC, &X, &A, &DKI_1, &DERR, &IERRO);
243 
244  X=BetaN*a;
245  dkia_( &IFAC, &X, &A, &DKI_2, &DERR, &IERRO);
246 
247  X=BetaN*r;
248  dlia_( &IFAC, &X, &A, &DLI_2, &DERR, &IERRO);
249 
250  double R= DLI_1*DKI_1 - DKI_2*DLI_2;
251 
252  return R;
253 
254 }
255 
256 double LaplaceSolution::ByFileEZ(double r, double phi, double z, double r1, double phi1, double z1)
257 {
258  return -1;
259 }
260 
261 double LaplaceSolution::ByFileER(double r, double phi, double z, double r1, double phi1, double z1)
262 {
263  return -1;
264 }
265 
266 double LaplaceSolution::Ez(double r, double phi, double z, double r1, double phi1, double z1)
267 {
268  if(fByFile) return ByFileEZ(r,phi,z,r1,phi1,z1);
269  // Check input arguments for sanity...
270  int error=0;
271  if (r<a || r>b) error=1;
272  if (phi<0 || phi>2*pi) error=1;
273  if (z<0 || z>L) error=1;
274  if (r1<a || r1>b) error=1;
275  if (phi1<0 || phi1>2*pi) error=1;
276  if (z1<0 || z1>L) error=1;
277  if (error)
278  {
279  cout << "Invalid arguments Ez(";
280  cout <<r<<",";
281  cout <<phi<<",";
282  cout <<z<<",";
283  cout <<r1<<",";
284  cout <<phi1<<",";
285  cout <<z1;
286  cout <<")" << endl;;
287  return 0;
288  }
289 
290  double G=0;
291  for (int m=0; m<NumberOfOrders; m++)
292  {
293  if (verbosity) cout << endl << m;
294  for (int n=0; n<NumberOfOrders; n++)
295  {
296  if (verbosity) cout << " " << n;
297  double term = 1/(2.0*pi);
298  if (verbosity) cout << " " << term;
299  term *= (2 - ((m==0)?1:0))*cos(m*(phi-phi1));
300  if (verbosity) cout << " " << term;
301  term *= Rmn(m,n,r)*Rmn(m,n,r1)/N2mn[m][n];
302  if (verbosity) cout << " " << term;
303  if (z<z1)
304  {
305  term *= cosh(Betamn[m][n]*z)*sinh(Betamn[m][n]*(L-z1))/sinh(Betamn[m][n]*L);
306  }
307  else
308  {
309  term *= -cosh(Betamn[m][n]*(L-z))*sinh(Betamn[m][n]*z1)/sinh(Betamn[m][n]*L);;
310  }
311  if (verbosity) cout << " " << term;
312  G += term;
313  if (verbosity) cout << " " << term << " " << G << endl;
314  }
315  }
316  if (verbosity) cout << "Ez = " << G << endl;
317 
318  return G;
319 }
320 
321 
322 double LaplaceSolution::Er(double r, double phi, double z, double r1, double phi1, double z1)
323 {
324  if(fByFile) return ByFileER(r,phi,z,r1,phi1,z1);
325  // Check input arguments for sanity...
326  int error=0;
327  if (r<a || r>b) error=1;
328  if (phi<0 || phi>2*pi) error=1;
329  if (z<0 || z>L) error=1;
330  if (r1<a || r1>b) error=1;
331  if (phi1<0 || phi1>2*pi) error=1;
332  if (z1<0 || z1>L) error=1;
333  if (error)
334  {
335  cout << "Invalid arguments Er(";
336  cout <<r<<",";
337  cout <<phi<<",";
338  cout <<z<<",";
339  cout <<r1<<",";
340  cout <<phi1<<",";
341  cout <<z1;
342  cout <<")" << endl;;
343  return 0;
344  }
345 
346  double G=0;
347  for (int m=0; m<NumberOfOrders; m++)
348  {
349  for (int n=0; n<NumberOfOrders; n++)
350  {
351  double term = 1/(L*pi);
352 
353  term *= (2 - ((m==0)?1:0))*cos(m*(phi-phi1));
354 
355  double BetaN = (n+1)*pi/L;
356  term *= sin(BetaN*z)*sin(BetaN*z1);
357 
358  if (r<r1)
359  {
360  term *= RPrime(m,n,a,r)*Rmn2(m,n,r1);
361  }
362  else
363  {
364  term *= Rmn1(m,n,r1)*RPrime(m,n,b,r);
365  }
366 
367  term /= BesselI(m,BetaN*a)*BesselK(m,BetaN*b)-BesselI(m,BetaN*b)*BesselK(m,BetaN*a);
368 
369  G += term;
370  }
371  }
372 
373  if (verbosity) cout << "Er = " << G << endl;
374 
375  return G;
376 }
377 
378 double LaplaceSolution::Ephi(double r, double phi, double z, double r1, double phi1, double z1)
379 {
380  // Check input arguments for sanity...
381  int error=0;
382  if (r<a || r>b) error=1;
383  if (phi<0 || phi>2*pi) error=1;
384  if (z<0 || z>L) error=1;
385  if (r1<a || r1>b) error=1;
386  if (phi1<0 || phi1>2*pi) error=1;
387  if (z1<0 || z1>L) error=1;
388  if (error)
389  {
390  cout << "Invalid arguments Ephi(";
391  cout <<r<<",";
392  cout <<phi<<",";
393  cout <<z<<",";
394  cout <<r1<<",";
395  cout <<phi1<<",";
396  cout <<z1;
397  cout <<")" << endl;;
398  return 0;
399  }
400 
401  double G=0;
402  //cout << "Ephi = " << G << endl;
403  return G;
404 }
405 
406