Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:15:12

0001 #include "LaplaceSolution.h"
0002 
0003 #include <iostream>
0004 #include <math.h>
0005 #include "TMath.h"
0006 #include "TFile.h"
0007 #include <string>
0008 
0009 using namespace std;
0010 using namespace TMath;
0011 
0012 //  Here we create the interface to the fortran code we got off the web...
0013 extern"C"{
0014   void dkia_(int *IFAC, double *X, double *A, double *DKI, double *DKID, int *IERRO);
0015   void dlia_(int *IFAC, double *X, double *A, double *DLI, double *DLID, int *IERRO);
0016 }
0017 
0018 
0019 LaplaceSolution::LaplaceSolution(std::string filename) {
0020   TFile *file = new TFile(filename.data());
0021   fByFile = true;
0022 }
0023 
0024 LaplaceSolution::LaplaceSolution(double InnerRadius, double OuterRadius, double HalfLength)
0025 {
0026   a = InnerRadius;
0027   b = OuterRadius;
0028   L = HalfLength;
0029 
0030   cout << "LaplaceSolution object initialized as follows:" << endl;
0031   cout << "  Inner Radius = " << a << " cm." << endl;
0032   cout << "  Outer Radius = " << b << " cm." << endl;
0033   cout << "  Half  Length = " << L << " cm." << endl;
0034 
0035   verbosity = 0;
0036   pi = 2.0 * asin(1.0);
0037   cout << pi << endl;
0038 
0039   FindBetamn(0.0001);
0040   FindMunk(0.0001);
0041 
0042   fByFile = false;
0043   return ;
0044 }
0045 
0046 
0047 void LaplaceSolution::FindBetamn(double epsilon)
0048 {
0049   cout << "Now filling the Beta[m][n] Array..."<<endl;
0050   double l = a/b;
0051   for (int m=0; m<NumberOfOrders; m++)
0052     {
0053       if (verbosity) cout << endl << m;
0054       int n=0;  //  !!!  Off by one from Rossegger convention  !!!
0055       double x=epsilon;
0056       double previous = jn(m,x)*yn(m,l*x) - jn(m,l*x)*yn(m,x);
0057       while (n < NumberOfOrders)
0058     {
0059       //  Rossegger equation 5.12
0060       double value = jn(m,x)*yn(m,l*x) - jn(m,l*x)*yn(m,x);
0061       //if (verbosity) cout << " " << value;
0062       if (value == 0) cout << "FFFFFFUUUUUUUUUUU......" << endl;
0063       if ( (value == 0) || (value<0 && previous>0) || (value>0 && previous<0))
0064         {
0065           double slp = (value-previous)/epsilon;
0066           double cpt =  value - slp*x;
0067           double x0  = -cpt/slp;
0068 
0069           Betamn[m][n] = x0/b;
0070           if (verbosity) cout << " " << x0 << "," << Betamn[m][n];
0071           n++;
0072         }
0073       previous = value;
0074       x+=epsilon;
0075     }
0076     }
0077 
0078 
0079   //  Now fill in the N2mn array...
0080   for (int m=0; m<NumberOfOrders; m++)
0081     {
0082       for (int n=0; n<NumberOfOrders; n++)
0083     {
0084       //  Rossegger Equation 5.17
0085       //  N^2_mn = 2/(pi * beta)^2 [ {Jm(beta a)/Jm(beta b)}^2 - 1 ]
0086       N2mn[m][n]  = 2/(pi*pi*Betamn[m][n]*Betamn[m][n]);
0087       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);
0088       if (verbosity) cout << "m: " << m << " n: " << n << " N2[m][n]: " << N2mn[m][n];
0089       double integral=0.0;
0090       double step = 0.01;
0091       for (double r=a; r<b; r+=step)
0092         {
0093           integral += Rmn(m,n,r)*Rmn(m,n,r)*r*step;
0094         }
0095       if (verbosity) cout << " Int: " << integral << endl;
0096       //N2mn[m][n] = integral;
0097     }
0098     }
0099 
0100   cout << "Done." << endl;
0101 }
0102 
0103 
0104 void LaplaceSolution::FindMunk(double epsilon)
0105 {
0106   cout << "Now filling the Mu[n][k] Array..."<<endl;
0107   cout << "Done." << endl;
0108 }
0109 
0110 
0111 double LaplaceSolution::Rmn(int m, int n, double r)
0112 {
0113   if (verbosity) cout << "Determine Rmn("<<m<<","<<n<<","<<r<<") = ";
0114 
0115   //  Check input arguments for sanity...
0116   int error=0;
0117   if (m<0 || m>NumberOfOrders) error=1;
0118   if (n<0 || n>NumberOfOrders) error=1;
0119   if (r<a || r>b)              error=1;
0120   if (error)
0121     {
0122       cout << "Invalid arguments Rmn("<<m<<","<<n<<","<<r<<")" << endl;;
0123       return 0;
0124     }
0125 
0126   //  Calculate the function using C-libraries from math.h
0127   //  Rossegger Equation 5.11:
0128   //         Rmn(r) = Ym(Beta_mn a)*Jm(Beta_mn r) - Jm(Beta_mn a)*Ym(Beta_mn r)
0129   double R=0;
0130   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);
0131 
0132   if (verbosity) cout << R << endl;
0133   return R;
0134 }
0135 
0136 double LaplaceSolution::Rmn1(int m, int n, double r)
0137 {
0138  //  Check input arguments for sanity...
0139   int error=0;
0140   if (m<0 || m>NumberOfOrders) error=1;
0141   if (n<0 || n>NumberOfOrders) error=1;
0142   if (r<a || r>b)              error=1;
0143   if (error)
0144     {
0145       cout << "Invalid arguments Rmn1("<<m<<","<<n<<","<<r<<")" << endl;;
0146       return 0;
0147     }
0148 
0149   //  Calculate using the TMath functions from root.
0150   //  Rossegger Equation 5.32
0151   //         Rmn1(r) = Km(BetaN a)Im(BetaN r) - Im(BetaN a) Km(BetaN r)
0152   double R=0;
0153   double BetaN = (n+1)*pi/L;
0154   R = BesselK(m,BetaN*a)*BesselI(m,BetaN*r)-BesselI(m,BetaN*a)*BesselK(m,BetaN*r);
0155 
0156   return R;
0157 }
0158 
0159 double LaplaceSolution::Rmn2(int m, int n, double r)
0160 {
0161  //  Check input arguments for sanity...
0162   int error=0;
0163   if (m<0 || m>NumberOfOrders) error=1;
0164   if (n<0 || n>NumberOfOrders) error=1;
0165   if (r<a || r>b)              error=1;
0166   if (error)
0167     {
0168       cout << "Invalid arguments Rmn2("<<m<<","<<n<<","<<r<<")" << endl;;
0169       return 0;
0170     }
0171 
0172   //  Calculate using the TMath functions from root.
0173   //  Rossegger Equation 5.33
0174   //         Rmn2(r) = Km(BetaN b)Im(BetaN r) - Im(BetaN b) Km(BetaN r)
0175   double R=0;
0176   double BetaN = (n+1)*pi/L;
0177   R = BesselK(m,BetaN*b)*BesselI(m,BetaN*r)-BesselI(m,BetaN*b)*BesselK(m,BetaN*r);
0178 
0179   return R;
0180 }
0181 
0182 double LaplaceSolution::RPrime(int m, int n, double ref, double r)
0183 {
0184  //  Check input arguments for sanity...
0185   int error=0;
0186   if (m<0   || m>NumberOfOrders) error=1;
0187   if (n<0   || n>NumberOfOrders) error=1;
0188   if (ref<a || ref>b)            error=1;
0189   if (r<a   || r>b)              error=1;
0190   if (error)
0191     {
0192       cout << "Invalid arguments RPrime("<<m<<","<<n<<","<<ref<<","<<r<<")" << endl;;
0193       return 0;
0194     }
0195 
0196   double R=0;
0197   //  Calculate using the TMath functions from root.
0198   //  Rossegger Equation 5.65
0199   //         Rmn2(ref,r) = BetaN/2* [   Km(BetaN ref) {Im-1(BetaN r) + Im+1(BetaN r)}
0200   //                                  - Im(BetaN ref) {Km-1(BetaN r) + Km+1(BetaN r)}  ]
0201   //  NOTE:  K-m(z) = Km(z) and I-m(z) = Im(z)... 
0202   //
0203   //
0204   double BetaN = (n+1)*pi/L;
0205   double term1 = BesselK(m,BetaN*ref)*( BesselI(abs(m-1),BetaN*r) + BesselI(m+1,BetaN*r) );
0206   double term2 = BesselI(m,BetaN*ref)*( BesselK(abs(m-1),BetaN*r) + BesselK(m+1,BetaN*r) );
0207   R = BetaN/2.0*(term1 + term2);
0208 
0209   return R;
0210 }
0211 
0212 double LaplaceSolution::Rnk(int n, int k, double r)
0213 {
0214  //  Check input arguments for sanity...
0215   int error=0;
0216   if (n<0   || n>NumberOfOrders) error=1;
0217   if (k<0   || k>NumberOfOrders) error=1;
0218   if (r<a   || r>b)              error=1;
0219   if (error)
0220     {
0221       cout << "Invalid arguments Rnk("<<n<<","<<k<<","<<r<<")" << endl;;
0222       return 0;
0223     }
0224 
0225   //  Rossegger Equation 5.45
0226   //       Rnk(r) = Limu_nk (BetaN a) Kimu_nk (BetaN r) - Kimu_nk(BetaN a) Limu_nk (BetaN r)
0227   double BetaN = (n+1)*pi/L;
0228 
0229   int IFAC=1;
0230   double A=Munk[n][k];
0231   double DLI_1=0; 
0232   double DKI_1=0; 
0233   double DLI_2=0; 
0234   double DKI_2=0; 
0235   double DERR=0;
0236   int IERRO=0;
0237 
0238   double X=BetaN*a;
0239   dlia_( &IFAC, &X, &A, &DLI_1, &DERR, &IERRO);
0240 
0241   X=BetaN*r;
0242   dkia_( &IFAC, &X, &A, &DKI_1, &DERR, &IERRO);
0243 
0244   X=BetaN*a;
0245   dkia_( &IFAC, &X, &A, &DKI_2, &DERR, &IERRO);
0246 
0247   X=BetaN*r;
0248   dlia_( &IFAC, &X, &A, &DLI_2, &DERR, &IERRO);
0249 
0250   double R= DLI_1*DKI_1 - DKI_2*DLI_2;
0251 
0252   return R;
0253 
0254 }
0255 
0256 double LaplaceSolution::ByFileEZ(double r, double phi, double z, double r1, double phi1, double z1)
0257 {
0258   return -1;
0259 }
0260 
0261 double LaplaceSolution::ByFileER(double r, double phi, double z, double r1, double phi1, double z1)
0262 {
0263   return -1;
0264 }
0265 
0266 double LaplaceSolution::Ez(double r, double phi, double z, double r1, double phi1, double z1)
0267 {
0268   if(fByFile) return ByFileEZ(r,phi,z,r1,phi1,z1);
0269   //  Check input arguments for sanity...
0270   int error=0;
0271   if (r<a    || r>b)         error=1;
0272   if (phi<0  || phi>2*pi)    error=1;
0273   if (z<0    || z>L)         error=1;
0274   if (r1<a   || r1>b)        error=1;
0275   if (phi1<0 || phi1>2*pi)   error=1;
0276   if (z1<0   || z1>L)        error=1;
0277   if (error)
0278     {
0279       cout << "Invalid arguments Ez(";
0280       cout <<r<<",";
0281       cout <<phi<<",";
0282       cout <<z<<",";
0283       cout <<r1<<",";
0284       cout <<phi1<<",";
0285       cout <<z1;
0286       cout <<")" << endl;;
0287       return 0;
0288     }
0289 
0290   double G=0;
0291   for (int m=0; m<NumberOfOrders; m++)
0292     {
0293       if (verbosity) cout << endl << m;
0294       for (int n=0; n<NumberOfOrders; n++)
0295     {
0296       if (verbosity) cout << " " << n;
0297       double term = 1/(2.0*pi);
0298       if (verbosity) cout << " " << term; 
0299       term *= (2 - ((m==0)?1:0))*cos(m*(phi-phi1));
0300       if (verbosity) cout << " " << term; 
0301       term *= Rmn(m,n,r)*Rmn(m,n,r1)/N2mn[m][n];
0302       if (verbosity) cout << " " << term; 
0303       if (z<z1)
0304         {
0305           term *=  cosh(Betamn[m][n]*z)*sinh(Betamn[m][n]*(L-z1))/sinh(Betamn[m][n]*L);
0306         }
0307       else
0308         {
0309           term *= -cosh(Betamn[m][n]*(L-z))*sinh(Betamn[m][n]*z1)/sinh(Betamn[m][n]*L);;
0310         }
0311       if (verbosity) cout << " " << term; 
0312       G += term;
0313       if (verbosity) cout << " " << term << " " << G << endl;
0314     }
0315     }
0316   if (verbosity) cout << "Ez = " << G << endl;
0317 
0318   return G;
0319 }
0320 
0321 
0322 double LaplaceSolution::Er(double r, double phi, double z, double r1, double phi1, double z1)
0323 {
0324   if(fByFile) return ByFileER(r,phi,z,r1,phi1,z1);
0325   //  Check input arguments for sanity...
0326   int error=0;
0327   if (r<a    || r>b)         error=1;
0328   if (phi<0  || phi>2*pi)    error=1;
0329   if (z<0    || z>L)         error=1;
0330   if (r1<a   || r1>b)        error=1;
0331   if (phi1<0 || phi1>2*pi)   error=1;
0332   if (z1<0   || z1>L)        error=1;
0333   if (error)
0334     {
0335       cout << "Invalid arguments Er(";
0336       cout <<r<<",";
0337       cout <<phi<<",";
0338       cout <<z<<",";
0339       cout <<r1<<",";
0340       cout <<phi1<<",";
0341       cout <<z1;
0342       cout <<")" << endl;;
0343       return 0;
0344     }
0345 
0346   double G=0;
0347   for (int m=0; m<NumberOfOrders; m++)
0348     {
0349       for (int n=0; n<NumberOfOrders; n++)
0350     {
0351       double term = 1/(L*pi);
0352 
0353       term *= (2 - ((m==0)?1:0))*cos(m*(phi-phi1));
0354 
0355       double BetaN = (n+1)*pi/L;
0356       term *= sin(BetaN*z)*sin(BetaN*z1);
0357 
0358       if (r<r1)
0359         {
0360           term *= RPrime(m,n,a,r)*Rmn2(m,n,r1);
0361         }
0362       else
0363         {
0364           term *= Rmn1(m,n,r1)*RPrime(m,n,b,r);
0365         }
0366 
0367       term /= BesselI(m,BetaN*a)*BesselK(m,BetaN*b)-BesselI(m,BetaN*b)*BesselK(m,BetaN*a);
0368 
0369       G += term;
0370     }
0371     }
0372 
0373   if (verbosity) cout << "Er = " << G << endl;
0374 
0375   return G;
0376 }
0377 
0378 double LaplaceSolution::Ephi(double r, double phi, double z, double r1, double phi1, double z1)
0379 {
0380   //  Check input arguments for sanity...
0381   int error=0;
0382   if (r<a    || r>b)         error=1;
0383   if (phi<0  || phi>2*pi)    error=1;
0384   if (z<0    || z>L)         error=1;
0385   if (r1<a   || r1>b)        error=1;
0386   if (phi1<0 || phi1>2*pi)   error=1;
0387   if (z1<0   || z1>L)        error=1;
0388   if (error)
0389     {
0390       cout << "Invalid arguments Ephi(";
0391       cout <<r<<",";
0392       cout <<phi<<",";
0393       cout <<z<<",";
0394       cout <<r1<<",";
0395       cout <<phi1<<",";
0396       cout <<z1;
0397       cout <<")" << endl;;
0398       return 0;
0399     }
0400 
0401   double G=0;
0402   //cout << "Ephi = " << G << endl;
0403   return G;
0404 }
0405 
0406