File indexing completed on 2025-08-05 08:15:40
0001 #include "Rossegger.h"
0002
0003 #include <TFile.h>
0004 #include <TMath.h>
0005 #include <TTree.h>
0006
0007 #pragma GCC diagnostic push
0008 #pragma GCC diagnostic ignored "-Wshadow"
0009 #include <boost/math/special_functions.hpp> //covers all the special functions.
0010 #pragma GCC diagnostic pop
0011
0012 #include <boost/format.hpp>
0013
0014 #include <algorithm> // for max
0015 #include <cmath>
0016 #include <cstdlib> // for exit, abs
0017 #include <fstream>
0018 #include <iostream>
0019 #include <sstream>
0020 #include <string>
0021
0022
0023 extern "C"
0024 {
0025 void dkia_(int *IFAC, double *X, double *A, double *DKI, double *DKID, int *IERRO);
0026 void dlia_(int *IFAC, double *X, double *A, double *DLI, double *DLID, int *IERRO);
0027 }
0028
0029
0030
0031 #define jn(order, x) boost::math::cyl_bessel_j(order, x)
0032
0033 #define yn(order, x) boost::math::cyl_neumann(order, x)
0034
0035 #define in(order, x) boost::math::cyl_bessel_i(order, x)
0036
0037 #define kn(order, x) boost::math::cyl_bessel_k(order, x)
0038 #define limu(im_order, x) Rossegger::Limu(im_order, x)
0039 #define kimu(im_order, x) Rossegger::Kimu(im_order, x)
0040
0041
0042
0043
0044
0045 Rossegger::Rossegger(double InnerRadius, double OuterRadius, double Rdo_Z, double precision)
0046 {
0047 a = InnerRadius;
0048 b = OuterRadius;
0049 L = Rdo_Z;
0050
0051 epsilon = precision;
0052
0053 verbosity = 0;
0054 pi = M_PI;
0055
0056 PrecalcFreeConstants();
0057
0058
0059 std::string zeroesfilename = boost::str(boost::format("rosseger_zeroes_eps%1.0E_a%2.2f_b%2.2f_L%2.2f.root") % epsilon % a % b % L);
0060 TFile *fileptr = TFile::Open(zeroesfilename.c_str(), "READ");
0061 if (!fileptr)
0062 {
0063 FindMunk(epsilon);
0064 FindBetamn(epsilon);
0065 SaveZeroes(zeroesfilename);
0066 }
0067 else
0068 {
0069 fileptr->Close();
0070 LoadZeroes(zeroesfilename);
0071 }
0072
0073 PrecalcDerivedConstants();
0074
0075 std::cout << "Rossegger object initialized as follows:" << std::endl;
0076 std::cout << " Inner Radius = " << a << " cm." << std::endl;
0077 std::cout << " Outer Radius = " << b << " cm." << std::endl;
0078 std::cout << " Half Length = " << L << " cm." << std::endl;
0079
0080 if (!CheckZeroes(0.01))
0081 {
0082 std::cout << "CheckZeroes(0.01) returned false, exiting" << std::endl;
0083 exit(1);
0084 }
0085 return;
0086 }
0087
0088 double Rossegger::FindNextZero(double xstart, double localepsilon, int order, double (Rossegger::*func)(int, double))
0089 {
0090 double previous = (this->*func)(order, xstart);
0091 double x = xstart + localepsilon;
0092 double value = previous;
0093
0094 while (!((value == 0) || (value < 0 && previous > 0) || (value > 0 && previous < 0)))
0095 {
0096
0097 value = (this->*func)(order, x);
0098 if (value == 0)
0099 {
0100 std::cout << "hit it exactly! Go buy a lottery ticket!" << std::endl;
0101 }
0102 if ((value == 0) || (value < 0 && previous > 0) || (value > 0 && previous < 0))
0103 {
0104
0105
0106
0107
0108 double slope = (value - previous) / localepsilon;
0109 double intercept = value - slope * x;
0110 double x0 = -intercept / slope;
0111 if (verbosity > 1)
0112 {
0113 std::cout << " " << x0 << "," << std::endl;
0114 }
0115 double n0 = (this->*func)(order, x - localepsilon);
0116 double n1 = (this->*func)(order, x + localepsilon);
0117 if ((n0 < 0 && n1 < 0) || (n0 > 0 && n1 > 0))
0118 {
0119 std::cout << "neighbors on both sides have the same sign. Check your function resolution!" << std::endl;
0120 }
0121
0122 return x0;
0123 }
0124 previous = value;
0125 x += localepsilon;
0126 }
0127 std::cout << "logic break!" << std::endl;
0128 exit(1);
0129 }
0130
0131 void Rossegger::FindBetamn(double localepsilon)
0132 {
0133 std::cout << "Now filling the Beta[m][n] Array..." << std::endl;
0134 if (verbosity > 5)
0135 {
0136 std::cout << "numberOfOrders= " << NumberOfOrders << std::endl;
0137 }
0138 for (int m = 0; m < NumberOfOrders; m++)
0139 {
0140 if (verbosity)
0141 {
0142 std::cout << "Filling Beta[" << m << "][n]..." << std::endl;
0143 }
0144
0145 double x = localepsilon;
0146 for (int n = 0; n < NumberOfOrders; n++)
0147 {
0148 x = FindNextZero(x, localepsilon, m, &Rossegger::Rmn_for_zeroes);
0149 Betamn[m][n] = x / b;
0150 x += localepsilon;
0151 }
0152 }
0153
0154
0155 for (int m = 0; m < NumberOfOrders; m++)
0156 {
0157 for (int n = 0; n < NumberOfOrders; n++)
0158 {
0159
0160
0161 N2mn[m][n] = 2 / (pi * pi * Betamn[m][n] * Betamn[m][n]);
0162
0163 double jna_over_jnb = jn(m, Betamn[m][n] * a) / jn(m, Betamn[m][n] * b);
0164 N2mn[m][n] *= (jna_over_jnb * jna_over_jnb - 1.0);
0165
0166 if (verbosity > 1)
0167 {
0168 std::cout << "m: " << m << " n: " << n << " N2[m][n]: " << N2mn[m][n];
0169 }
0170 double step = 0.01;
0171 if (verbosity > 1)
0172 {
0173 double integral = 0.0;
0174 for (double r = a; r < b; r += step)
0175 {
0176 double rmnval = Rmn(m, n, r);
0177
0178 integral += rmnval * rmnval * r * step;
0179 }
0180 std::cout << " Int: " << integral << std::endl;
0181 }
0182
0183 }
0184 }
0185
0186 std::cout << "Done." << std::endl;
0187 }
0188
0189 void Rossegger::FindMunk(double localepsilon)
0190 {
0191 std::cout << "Now filling the Mu[n][k] Array..." << std::endl;
0192 if (verbosity > 5)
0193 {
0194 std::cout << "numberOfOrders= " << NumberOfOrders << std::endl;
0195 }
0196
0197
0198
0199
0200
0201
0202
0203 for (int n = 0; n < NumberOfOrders; n++)
0204 {
0205 if (verbosity)
0206 {
0207 std::cout << "Filling Mu[" << n << "][k]..." << std::endl;
0208 }
0209 double x = localepsilon;
0210 for (int k = 0; k < NumberOfOrders; k++)
0211 {
0212 x = FindNextZero(x, localepsilon, n, &Rossegger::Rnk_for_zeroes);
0213 Munk[n][k] = x;
0214 x += localepsilon;
0215 if (verbosity > 0)
0216 {
0217 std::cout << boost::str(boost::format("Mu[%d][%d]=%E") % n % k % Munk[n][k]) << std::endl;
0218 std::cout << boost::str(boost::format("adjacent values are Rnk[mu-localepsilon]=%E\tRnk[mu+localepsilon]=%E") % (Rnk_for_zeroes(n, x - localepsilon)) % (Rnk_for_zeroes(n, x + localepsilon))) << std::endl;
0219 if (verbosity > 100)
0220 {
0221 std::cout << "values of argument to limu and kimu are " << ((n + 1) * pi / L * a)
0222 << " and " << ((n + 1) * pi / L * b) << std::endl;
0223 }
0224 }
0225 }
0226 }
0227
0228
0229 for (int n = 0; n < NumberOfOrders; n++)
0230 {
0231 for (int k = 0; k < NumberOfOrders; k++)
0232 {
0233
0234
0235
0236 double integral = 0.0;
0237 double step = 0.001;
0238
0239 for (double r = a; r < b; r += step)
0240 {
0241 double rnkval = Rnk_(n, k, r);
0242
0243 integral += rnkval * rnkval / r * step;
0244 }
0245 if (verbosity > 1)
0246 {
0247 std::cout << " Int: " << integral << std::endl;
0248 }
0249 N2nk[n][k] = integral;
0250 if (verbosity > 1)
0251 {
0252 std::cout << "n: " << n << " k: " << k << " N2nk[n][k]: " << N2nk[n][k];
0253 }
0254 }
0255 }
0256
0257 std::cout << "Done." << std::endl;
0258 return;
0259 }
0260
0261 bool Rossegger::CheckZeroes(double localepsilon)
0262 {
0263
0264 double result;
0265 for (int m = 0; m < NumberOfOrders; m++)
0266 {
0267 for (int n = 0; n < NumberOfOrders; n++)
0268 {
0269 result = Rmn_for_zeroes(m, Betamn[m][n] * b);
0270 if (abs(result) > localepsilon)
0271 {
0272 std::cout << boost::str(boost::format("(m=%d,n=%d) Jm(x)Ym(lx)-Jm(lx)Ym(x) = %f for x=b*%f") % m % n % result % Betamn[m][n]) << std::endl;
0273 return false;
0274 }
0275 }
0276 }
0277
0278
0279 for (int n = 0; n < NumberOfOrders; n++)
0280 {
0281 for (int k = 0; k < NumberOfOrders; k++)
0282 {
0283 result = Rnk_for_zeroes(n, Munk[n][k]);
0284 if (abs(result) > localepsilon * 100)
0285 {
0286 std::cout << boost::str(boost::format("(n=%d,k=%d) limu(npi*a/L)kimu(npi*b/L)-kimu(npi*a/L)kimu(npi*b/L) = %f (>eps*100) for mu=%f") % n % k % result % Munk[n][k]) << std::endl;
0287 return false;
0288 }
0289 }
0290 }
0291
0292 return true;
0293 }
0294
0295 void Rossegger::PrecalcFreeConstants()
0296 {
0297
0298 std::cout << "Precalcing " << (3 * NumberOfOrders + 5 * NumberOfOrders * NumberOfOrders)
0299 << "geometric constants" << std::endl;
0300 for (int n = 0; n < NumberOfOrders; n++)
0301 {
0302 BetaN[n] = (n + 1) * pi / L;
0303 BetaN_a[n] = BetaN[n] * a;
0304 BetaN_b[n] = BetaN[n] * b;
0305 for (int m = 0; m < NumberOfOrders; m++)
0306 {
0307 km_BetaN_a[m][n] = kn(m, BetaN_a[n]);
0308 im_BetaN_a[m][n] = in(m, BetaN_a[n]);
0309 km_BetaN_b[m][n] = kn(m, BetaN_b[n]);
0310 im_BetaN_b[m][n] = in(m, BetaN_b[n]);
0311 bessel_denominator[m][n] = TMath::BesselI(m, BetaN_a[n]) * TMath::BesselK(m, BetaN_b[n]) - TMath::BesselI(m, BetaN_b[n]) * TMath::BesselK(m, BetaN_a[n]);
0312 }
0313 }
0314 return;
0315 }
0316 void Rossegger::PrecalcDerivedConstants()
0317 {
0318
0319 std::cout << "Precalcing " << (6 * NumberOfOrders * NumberOfOrders)
0320 << " geometric constants" << std::endl;
0321
0322 for (int n = 0; n < NumberOfOrders; n++)
0323 {
0324 for (int m = 0; m < NumberOfOrders; m++)
0325 {
0326 ym_Betamn_a[m][n] = yn(m, Betamn[m][n] * a);
0327 jm_Betamn_a[m][n] = jn(m, Betamn[m][n] * a);
0328 sinh_Betamn_L[m][n] = sinh(Betamn[m][n] * L);
0329 }
0330 for (int k = 0; k < NumberOfOrders; k++)
0331 {
0332 liMunk_BetaN_a[n][k] = limu(Munk[n][k], BetaN_a[n]);
0333 kiMunk_BetaN_a[n][k] = kimu(Munk[n][k], BetaN_a[n]);
0334 sinh_pi_Munk[n][k] = sinh(pi * Munk[n][k]);
0335 }
0336 }
0337 return;
0338 }
0339
0340 double Rossegger::Limu(double mu, double x)
0341 {
0342
0343
0344
0345
0346
0347 int IFAC = 1;
0348 double A = mu;
0349 double DLI = 0;
0350 double DERR = 0;
0351 int IERRO = 0;
0352
0353 double X = x;
0354 dlia_(&IFAC, &X, &A, &DLI, &DERR, &IERRO);
0355 return DLI;
0356 }
0357 double Rossegger::Kimu(double mu, double x)
0358 {
0359 int IFAC = 1;
0360 double A = mu;
0361 double DKI = 0;
0362 double DERR = 0;
0363 int IERRO = 0;
0364
0365 double X = x;
0366 dkia_(&IFAC, &X, &A, &DKI, &DERR, &IERRO);
0367 return DKI;
0368 }
0369
0370 double Rossegger::Rmn_for_zeroes(int m, double x)
0371 {
0372 double lx = a * x / b;
0373
0374
0375 return jn(m, x) * yn(m, lx) - jn(m, lx) * yn(m, x);
0376 }
0377
0378 double Rossegger::Rmn(int m, int n, double r)
0379 {
0380 if (verbosity > 100)
0381 {
0382 std::cout << "Determine Rmn(" << m << "," << n << "," << r << ") = ";
0383 }
0384
0385
0386 int error = 0;
0387 if (m < 0 || m >= NumberOfOrders)
0388 {
0389 error = 1;
0390 }
0391 if (n < 0 || n >= NumberOfOrders)
0392 {
0393 error = 1;
0394 }
0395 if (r < a || r > b)
0396 {
0397 error = 1;
0398 }
0399 if (error)
0400 {
0401 std::cout << "Invalid arguments Rmn(" << m << "," << n << "," << r << ")" << std::endl;
0402 ;
0403 return 0;
0404 }
0405
0406
0407
0408
0409 double R = 0;
0410 R = ym_Betamn_a[m][n] * jn(m, Betamn[m][n] * r) - jm_Betamn_a[m][n] * yn(m, Betamn[m][n] * r);
0411
0412 if (verbosity > 100)
0413 {
0414 std::cout << R << std::endl;
0415 }
0416 return R;
0417 }
0418
0419 double Rossegger::Rmn_(int m, int n, double r)
0420 {
0421 if (verbosity > 100)
0422 {
0423 std::cout << "Determine Rmn(" << m << "," << n << "," << r << ") = ";
0424 }
0425
0426
0427 int error = 0;
0428 if (m < 0 || m >= NumberOfOrders)
0429 {
0430 error = 1;
0431 }
0432 if (n < 0 || n >= NumberOfOrders)
0433 {
0434 error = 1;
0435 }
0436 if (r < a || r > b)
0437 {
0438 error = 1;
0439 }
0440 if (error)
0441 {
0442 std::cout << "Invalid arguments Rmn(" << m << "," << n << "," << r << ")" << std::endl;
0443 ;
0444 return 0;
0445 }
0446
0447
0448
0449
0450 double R = 0;
0451 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);
0452
0453 if (verbosity > 100)
0454 {
0455 std::cout << R << std::endl;
0456 }
0457 return R;
0458 }
0459
0460 double Rossegger::Rmn1(int m, int n, double r)
0461 {
0462
0463 int error = 0;
0464 if (m < 0 || m >= NumberOfOrders)
0465 {
0466 error = 1;
0467 }
0468 if (n < 0 || n >= NumberOfOrders)
0469 {
0470 error = 1;
0471 }
0472 if (r < a || r > b)
0473 {
0474 error = 1;
0475 }
0476 if (error)
0477 {
0478 std::cout << "Invalid arguments Rmn1(" << m << "," << n << "," << r << ")" << std::endl;
0479 ;
0480 return 0;
0481 }
0482
0483
0484
0485
0486 double R = 0;
0487 R = km_BetaN_a[m][n] * in(m, BetaN[n] * r) - im_BetaN_a[m][n] * kn(m, BetaN[n] * r);
0488
0489 return R;
0490 }
0491
0492 double Rossegger::Rmn1_(int m, int n, double r)
0493 {
0494
0495 int error = 0;
0496 if (m < 0 || m >= NumberOfOrders)
0497 {
0498 error = 1;
0499 }
0500 if (n < 0 || n >= NumberOfOrders)
0501 {
0502 error = 1;
0503 }
0504 if (r < a || r > b)
0505 {
0506 error = 1;
0507 }
0508 if (error)
0509 {
0510 std::cout << "Invalid arguments Rmn1(" << m << "," << n << "," << r << ")" << std::endl;
0511 ;
0512 return 0;
0513 }
0514
0515
0516
0517
0518 double R = 0;
0519 double BetaN_ = (n + 1) * pi / L;
0520 R = kn(m, BetaN_ * a) * in(m, BetaN_ * r) - in(m, BetaN_ * a) * kn(m, BetaN_ * r);
0521
0522 return R;
0523 }
0524
0525 double Rossegger::Rmn2(int m, int n, double r)
0526 {
0527
0528 int error = 0;
0529 if (m < 0 || m >= NumberOfOrders)
0530 {
0531 error = 1;
0532 }
0533 if (n < 0 || n >= NumberOfOrders)
0534 {
0535 error = 1;
0536 }
0537 if (r < a || r > b)
0538 {
0539 error = 1;
0540 }
0541 if (error)
0542 {
0543 std::cout << "Invalid arguments Rmn2(" << m << "," << n << "," << r << ")" << std::endl;
0544 ;
0545 return 0;
0546 }
0547
0548
0549
0550
0551 double R = 0;
0552 R = km_BetaN_b[m][n] * in(m, BetaN[n] * r) - im_BetaN_b[m][n] * kn(m, BetaN[n] * r);
0553
0554 return R;
0555 }
0556
0557 double Rossegger::Rmn2_(int m, int n, double r)
0558 {
0559
0560 int error = 0;
0561 if (m < 0 || m >= NumberOfOrders)
0562 {
0563 error = 1;
0564 }
0565 if (n < 0 || n >= NumberOfOrders)
0566 {
0567 error = 1;
0568 }
0569 if (r < a || r > b)
0570 {
0571 error = 1;
0572 }
0573 if (error)
0574 {
0575 std::cout << "Invalid arguments Rmn2(" << m << "," << n << "," << r << ")" << std::endl;
0576 ;
0577 return 0;
0578 }
0579
0580
0581
0582
0583 double R = 0;
0584 double BetaN_ = (n + 1) * pi / L;
0585 R = kn(m, BetaN_ * b) * in(m, BetaN_ * r) - in(m, BetaN_ * b) * kn(m, BetaN_ * r);
0586
0587 return R;
0588 }
0589
0590 double Rossegger::RPrime(int m, int n, double ref, double r)
0591 {
0592
0593 int error = 0;
0594 if (m < 0 || m >= NumberOfOrders)
0595 {
0596 error = 1;
0597 }
0598 if (n < 0 || n >= NumberOfOrders)
0599 {
0600 error = 1;
0601 }
0602 if (ref < a || ref > b)
0603 {
0604 error = 1;
0605 }
0606 if (r < a || r > b)
0607 {
0608 error = 1;
0609 }
0610 if (error)
0611 {
0612 std::cout << "Invalid arguments RPrime(" << m << "," << n << "," << ref << "," << r << ")" << std::endl;
0613 ;
0614 return 0;
0615 }
0616
0617 double R = 0;
0618
0619
0620
0621
0622
0623
0624
0625 double BetaN_ = BetaN[n];
0626 double term1 = kn(m, BetaN_ * ref) * (in(m - 1, BetaN_ * r) + in(m + 1, BetaN_ * r));
0627 double term2 = in(m, BetaN_ * ref) * (kn(m - 1, BetaN_ * r) + kn(m + 1, BetaN_ * r));
0628 R = BetaN_ / 2.0 * (term1 + term2);
0629
0630 return R;
0631 }
0632
0633 double Rossegger::RPrime_(int m, int n, double ref, double r)
0634 {
0635
0636 int error = 0;
0637 if (m < 0 || m >= NumberOfOrders)
0638 {
0639 error = 1;
0640 }
0641 if (n < 0 || n >= NumberOfOrders)
0642 {
0643 error = 1;
0644 }
0645 if (ref < a || ref > b)
0646 {
0647 error = 1;
0648 }
0649 if (r < a || r > b)
0650 {
0651 error = 1;
0652 }
0653 if (error)
0654 {
0655 std::cout << "Invalid arguments RPrime(" << m << "," << n << "," << ref << "," << r << ")" << std::endl;
0656 ;
0657 return 0;
0658 }
0659
0660 double R = 0;
0661
0662
0663
0664
0665
0666
0667 double BetaN_ = (n + 1) * pi / L;
0668 double term1 = kn(m, BetaN_ * ref) * (in(m - 1, BetaN_ * r) + in(m + 1, BetaN_ * r));
0669 double term2 = in(m, BetaN_ * ref) * (kn(m - 1, BetaN_ * r) + kn(m + 1, BetaN_ * r));
0670 R = BetaN_ / 2.0 * (term1 + term2);
0671
0672 return R;
0673 }
0674
0675 double Rossegger::Rnk_for_zeroes(int n, double mu)
0676 {
0677
0678 if (verbosity > 10)
0679 {
0680 std::cout << "Rnk_for_zeroes called with n=" << n << ",mu=" << mu << std::endl;
0681 }
0682 double betana = BetaN_a[n];
0683 double betanb = BetaN_b[n];
0684
0685
0686
0687 return limu(mu, betana) * kimu(mu, betanb) - kimu(mu, betana) * limu(mu, betanb);
0688 }
0689
0690 double Rossegger::Rnk_for_zeroes_(int n, double mu)
0691 {
0692
0693 if (verbosity > 10)
0694 {
0695 std::cout << "Rnk_for_zeroes called with n=" << n << ",mu=" << mu << std::endl;
0696 }
0697 double BetaN_ = (n + 1) * pi / L;
0698 double betana = BetaN_ * a;
0699 double betanb = BetaN_ * b;
0700
0701
0702
0703 return limu(mu, betana) * kimu(mu, betanb) - kimu(mu, betana) * limu(mu, betanb);
0704 }
0705
0706 double Rossegger::Rnk(int n, int k, double r)
0707 {
0708
0709 int error = 0;
0710 if (n < 0 || n >= NumberOfOrders)
0711 {
0712 error = 1;
0713 }
0714 if (k < 0 || k >= NumberOfOrders)
0715 {
0716 error = 1;
0717 }
0718 if (r < a || r > b)
0719 {
0720 error = 1;
0721 }
0722 if (error)
0723 {
0724 std::cout << "Invalid arguments Rnk(" << n << "," << k << "," << r << ")" << std::endl;
0725 ;
0726 return 0;
0727 }
0728
0729
0730
0731 return liMunk_BetaN_a[n][k] * kimu(Munk[n][k], BetaN[n] * r) - kiMunk_BetaN_a[n][k] * limu(Munk[n][k], BetaN[n] * r);
0732 }
0733
0734 double Rossegger::Rnk_(int n, int k, double r)
0735 {
0736
0737 int error = 0;
0738 if (n < 0 || n >= NumberOfOrders)
0739 {
0740 error = 1;
0741 }
0742 if (k < 0 || k >= NumberOfOrders)
0743 {
0744 error = 1;
0745 }
0746 if (r < a || r > b)
0747 {
0748 error = 1;
0749 }
0750 if (error)
0751 {
0752 std::cout << "Invalid arguments Rnk(" << n << "," << k << "," << r << ")" << std::endl;
0753 ;
0754 return 0;
0755 }
0756 double BetaN_ = (n + 1) * pi / L;
0757
0758
0759
0760 return limu(Munk[n][k], BetaN_ * a) * kimu(Munk[n][k], BetaN_ * r) - kimu(Munk[n][k], BetaN_ * a) * limu(Munk[n][k], BetaN_ * r);
0761 }
0762
0763 double Rossegger::Ez(double r, double phi, double z, double r1, double phi1, double z1)
0764 {
0765
0766 int error = 0;
0767 if (r < a || r > b)
0768 {
0769 error = 1;
0770 }
0771 if (phi < 0 || phi > 2 * pi)
0772 {
0773 error = 1;
0774 }
0775 if (z < 0 || z > L)
0776 {
0777 error = 1;
0778 }
0779 if (r1 < a || r1 > b)
0780 {
0781 error = 1;
0782 }
0783 if (phi1 < 0 || phi1 > 2 * pi)
0784 {
0785 error = 1;
0786 }
0787 if (z1 < 0 || z1 > L)
0788 {
0789 error = 1;
0790 }
0791 if (error)
0792 {
0793 std::cout << "Invalid arguments Ez(";
0794 std::cout << r << ",";
0795 std::cout << phi << ",";
0796 std::cout << z << ",";
0797 std::cout << r1 << ",";
0798 std::cout << phi1 << ",";
0799 std::cout << z1;
0800 std::cout << ")" << std::endl;
0801 ;
0802 return 0;
0803 }
0804
0805 double G = 0;
0806 for (int m = 0; m < NumberOfOrders; m++)
0807 {
0808 if (verbosity > 10)
0809 {
0810 std::cout << std::endl
0811 << m;
0812 }
0813 for (int n = 0; n < NumberOfOrders; n++)
0814 {
0815 if (verbosity > 10)
0816 {
0817 std::cout << " " << n;
0818 }
0819 double term = 1;
0820 if (verbosity > 10)
0821 {
0822 std::cout << " " << term;
0823 }
0824 term *= (2 - ((m == 0) ? 1 : 0)) * cos(m * (phi - phi1));
0825 if (verbosity > 10)
0826 {
0827 std::cout << " " << term;
0828 }
0829 term *= Rmn(m, n, r) * Rmn(m, n, r1) / N2mn[m][n];
0830 if (verbosity > 10)
0831 {
0832 std::cout << " " << term;
0833 }
0834 if (z < z1)
0835 {
0836 term *= cosh(Betamn[m][n] * z) * sinh(Betamn[m][n] * (L - z1)) / sinh_Betamn_L[m][n];
0837 }
0838 else
0839 {
0840 term *= -cosh(Betamn[m][n] * (L - z)) * sinh(Betamn[m][n] * z1) / sinh_Betamn_L[m][n];
0841 }
0842 if (verbosity > 10)
0843 {
0844 std::cout << " " << term;
0845 }
0846 G += term;
0847 if (verbosity > 10)
0848 {
0849 std::cout << " " << term << " " << G << std::endl;
0850 }
0851 }
0852 }
0853
0854 G = G / (2.0 * pi);
0855 if (verbosity)
0856 {
0857 std::cout << "Ez = " << G << std::endl;
0858 }
0859
0860 return G;
0861 }
0862
0863 double Rossegger::Ez_(double r, double phi, double z, double r1, double phi1, double z1)
0864 {
0865
0866
0867 int error = 0;
0868 if (r < a || r > b)
0869 {
0870 error = 1;
0871 }
0872 if (phi < 0 || phi > 2 * pi)
0873 {
0874 error = 1;
0875 }
0876 if (z < 0 || z > L)
0877 {
0878 error = 1;
0879 }
0880 if (r1 < a || r1 > b)
0881 {
0882 error = 1;
0883 }
0884 if (phi1 < 0 || phi1 > 2 * pi)
0885 {
0886 error = 1;
0887 }
0888 if (z1 < 0 || z1 > L)
0889 {
0890 error = 1;
0891 }
0892 if (error)
0893 {
0894 std::cout << "Invalid arguments Ez(";
0895 std::cout << r << ",";
0896 std::cout << phi << ",";
0897 std::cout << z << ",";
0898 std::cout << r1 << ",";
0899 std::cout << phi1 << ",";
0900 std::cout << z1;
0901 std::cout << ")" << std::endl;
0902 ;
0903 return 0;
0904 }
0905
0906 double G = 0;
0907 for (int m = 0; m < NumberOfOrders; m++)
0908 {
0909 if (verbosity > 10)
0910 {
0911 std::cout << std::endl
0912 << m;
0913 }
0914 for (int n = 0; n < NumberOfOrders; n++)
0915 {
0916 if (verbosity > 10)
0917 {
0918 std::cout << " " << n;
0919 }
0920 double term = 1 / (2.0 * pi);
0921 if (verbosity > 10)
0922 {
0923 std::cout << " " << term;
0924 }
0925 term *= (2 - ((m == 0) ? 1 : 0)) * cos(m * (phi - phi1));
0926 if (verbosity > 10)
0927 {
0928 std::cout << " " << term;
0929 }
0930 term *= Rmn(m, n, r) * Rmn(m, n, r1) / N2mn[m][n];
0931 if (verbosity > 10)
0932 {
0933 std::cout << " " << term;
0934 }
0935 if (z < z1)
0936 {
0937 term *= cosh(Betamn[m][n] * z) * sinh(Betamn[m][n] * (L - z1)) / sinh(Betamn[m][n] * L);
0938 }
0939 else
0940 {
0941 term *= -cosh(Betamn[m][n] * (L - z)) * sinh(Betamn[m][n] * z1) / sinh(Betamn[m][n] * L);
0942 ;
0943 }
0944 if (verbosity > 10)
0945 {
0946 std::cout << " " << term;
0947 }
0948 G += term;
0949 if (verbosity > 10)
0950 {
0951 std::cout << " " << term << " " << G << std::endl;
0952 }
0953 }
0954 }
0955 if (verbosity)
0956 {
0957 std::cout << "Ez = " << G << std::endl;
0958 }
0959
0960 return G;
0961 }
0962
0963 double Rossegger::Er(double r, double phi, double z, double r1, double phi1, double z1)
0964 {
0965
0966
0967
0968
0969
0970
0971 int error = 0;
0972 if (r < a || r > b)
0973 {
0974 error = 1;
0975 }
0976 if (phi < 0 || phi > 2 * pi)
0977 {
0978 error = 1;
0979 }
0980 if (z < 0 || z > L)
0981 {
0982 error = 1;
0983 }
0984 if (r1 < a || r1 > b)
0985 {
0986 error = 1;
0987 }
0988 if (phi1 < 0 || phi1 > 2 * pi)
0989 {
0990 error = 1;
0991 }
0992 if (z1 < 0 || z1 > L)
0993 {
0994 error = 1;
0995 }
0996 if (error)
0997 {
0998 std::cout << "Invalid arguments Er(";
0999 std::cout << r << ",";
1000 std::cout << phi << ",";
1001 std::cout << z << ",";
1002 std::cout << r1 << ",";
1003 std::cout << phi1 << ",";
1004 std::cout << z1;
1005 std::cout << ")" << std::endl;
1006 ;
1007 return 0;
1008 }
1009
1010 double part = 0;
1011 double G = 0;
1012 for (int m = 0; m < NumberOfOrders; m++)
1013 {
1014 for (int n = 0; n < NumberOfOrders; n++)
1015 {
1016 double term = 1;
1017 part = (2 - ((m == 0) ? 1 : 0)) * cos(m * (phi - phi1));
1018 if (verbosity > 10)
1019 {
1020 std::cout << "(2 - ((m==0)?1:0))*cos(m*(phi-phi1)); = " << part << std::endl;
1021 }
1022 term *= part;
1023 part = sin(BetaN[n] * z) * sin(BetaN[n] * z1);
1024 if (verbosity > 10)
1025 {
1026 std::cout << "sin(BetaN[n]*z)*sin(BetaN[n]*z1); = " << part << std::endl;
1027 }
1028 term *= part;
1029
1030 if (r < r1)
1031 {
1032 term *= RPrime(m, n, a, r) * Rmn2(m, n, r1);
1033 }
1034 else
1035 {
1036 term *= Rmn1(m, n, r1) * RPrime(m, n, b, r);
1037 }
1038 term /= bessel_denominator[m][n];
1039 G += term;
1040 }
1041 }
1042
1043 G = G / (L * pi);
1044 if (verbosity)
1045 {
1046 std::cout << "Er = " << G << std::endl;
1047 }
1048
1049 return G;
1050 }
1051
1052 double Rossegger::Er_(double r, double phi, double z, double r1, double phi1, double z1)
1053 {
1054
1055
1056
1057
1058
1059 int error = 0;
1060 if (r < a || r > b)
1061 {
1062 error = 1;
1063 }
1064 if (phi < 0 || phi > 2 * pi)
1065 {
1066 error = 1;
1067 }
1068 if (z < 0 || z > L)
1069 {
1070 error = 1;
1071 }
1072 if (r1 < a || r1 > b)
1073 {
1074 error = 1;
1075 }
1076 if (phi1 < 0 || phi1 > 2 * pi)
1077 {
1078 error = 1;
1079 }
1080 if (z1 < 0 || z1 > L)
1081 {
1082 error = 1;
1083 }
1084 if (error)
1085 {
1086 std::cout << "Invalid arguments Er(";
1087 std::cout << r << ",";
1088 std::cout << phi << ",";
1089 std::cout << z << ",";
1090 std::cout << r1 << ",";
1091 std::cout << phi1 << ",";
1092 std::cout << z1;
1093 std::cout << ")" << std::endl;
1094 ;
1095 return 0;
1096 }
1097
1098 double G = 0;
1099 for (int m = 0; m < NumberOfOrders; m++)
1100 {
1101 for (int n = 0; n < NumberOfOrders; n++)
1102 {
1103 double term = 1 / (L * pi);
1104 term *= (2 - ((m == 0) ? 1 : 0)) * cos(m * (phi - phi1));
1105 double BetaN_ = (n + 1) * pi / L;
1106 term *= sin(BetaN_ * z) * sin(BetaN_ * z1);
1107 if (r < r1)
1108 {
1109 term *= RPrime_(m, n, a, r) * Rmn2_(m, n, r1);
1110 }
1111 else
1112 {
1113 term *= Rmn1_(m, n, r1) * RPrime_(m, n, b, r);
1114 }
1115
1116 term /= TMath::BesselI(m, BetaN_ * a) * TMath::BesselK(m, BetaN_ * b) - TMath::BesselI(m, BetaN_ * b) * TMath::BesselK(m, BetaN_ * a);
1117
1118 G += term;
1119 }
1120 }
1121
1122 if (verbosity)
1123 {
1124 std::cout << "Er = " << G << std::endl;
1125 }
1126
1127 return G;
1128 }
1129
1130 double Rossegger::Ephi(double r, double phi, double z, double r1, double phi1, double z1)
1131 {
1132
1133
1134
1135 int error = 0;
1136 if (r < a || r > b)
1137 {
1138 error = 1;
1139 }
1140 if (phi < 0 || phi > 2 * pi)
1141 {
1142 error = 1;
1143 }
1144 if (z < 0 || z > L)
1145 {
1146 error = 1;
1147 }
1148 if (r1 < a || r1 > b)
1149 {
1150 error = 1;
1151 }
1152 if (phi1 < 0 || phi1 > 2 * pi)
1153 {
1154 error = 1;
1155 }
1156 if (z1 < 0 || z1 > L)
1157 {
1158 error = 1;
1159 }
1160 if (error)
1161 {
1162 std::cout << "Invalid arguments Ephi(";
1163 std::cout << r << ",";
1164 std::cout << phi << ",";
1165 std::cout << z << ",";
1166 std::cout << r1 << ",";
1167 std::cout << phi1 << ",";
1168 std::cout << z1;
1169 std::cout << ")" << std::endl;
1170 ;
1171 return 0;
1172 }
1173
1174 double G = 0;
1175
1176 for (int k = 0; k < NumberOfOrders; k++)
1177 {
1178 for (int n = 0; n < NumberOfOrders; n++)
1179 {
1180 double term = 1;
1181 term *= sin(BetaN[n] * z) * sin(BetaN[n] * z1);
1182 term *= Rnk(n, k, r) * Rnk(n, k, r1) / N2nk[n][k];
1183
1184
1185 if (phi > phi1)
1186 {
1187 term *= -sinh(Munk[n][k] * (pi - (phi - phi1)));
1188 }
1189 else
1190 {
1191 term *= sinh(Munk[n][k] * (pi - (phi1 - phi)));
1192 }
1193 term *= 1 / sinh_pi_Munk[n][k];
1194 G += term;
1195 }
1196 }
1197
1198 G = G / (L * r);
1199 if (verbosity)
1200 {
1201 std::cout << "Ephi = " << G << std::endl;
1202 }
1203
1204 return G;
1205 }
1206
1207 double Rossegger::Ephi_(double r, double phi, double z, double r1, double phi1, double z1)
1208 {
1209
1210
1211 int error = 0;
1212 if (r < a || r > b)
1213 {
1214 error = 1;
1215 }
1216 if (phi < 0 || phi > 2 * pi)
1217 {
1218 error = 1;
1219 }
1220 if (z < 0 || z > L)
1221 {
1222 error = 1;
1223 }
1224 if (r1 < a || r1 > b)
1225 {
1226 error = 1;
1227 }
1228 if (phi1 < 0 || phi1 > 2 * pi)
1229 {
1230 error = 1;
1231 }
1232 if (z1 < 0 || z1 > L)
1233 {
1234 error = 1;
1235 }
1236 if (error)
1237 {
1238 std::cout << "Invalid arguments Ephi(";
1239 std::cout << r << ",";
1240 std::cout << phi << ",";
1241 std::cout << z << ",";
1242 std::cout << r1 << ",";
1243 std::cout << phi1 << ",";
1244 std::cout << z1;
1245 std::cout << ")" << std::endl;
1246 ;
1247 return 0;
1248 }
1249
1250 verbosity = 1;
1251 double G = 0;
1252
1253 for (int k = 0; k < NumberOfOrders; k++)
1254 {
1255 if (verbosity)
1256 {
1257 std::cout << "\nk=" << k;
1258 }
1259 for (int n = 0; n < NumberOfOrders; n++)
1260 {
1261 if (verbosity)
1262 {
1263 std::cout << " n=" << n;
1264 }
1265 double BetaN_ = (n + 1) * pi / L;
1266 double term = 1 / (L * r);
1267 if (verbosity)
1268 {
1269 std::cout << " 1/L=" << term;
1270 }
1271 term *= sin(BetaN_ * z) * sin(BetaN_ * z1);
1272 if (verbosity)
1273 {
1274 std::cout << " *sinsin=" << term;
1275 }
1276 term *= Rnk_(n, k, r) * Rnk_(n, k, r1);
1277 if (verbosity)
1278 {
1279 std::cout << " *rnkrnk=" << term;
1280 }
1281 term /= N2nk[n][k];
1282 if (verbosity)
1283 {
1284 std::cout << " */nnknnk=" << term;
1285 }
1286
1287
1288 if (phi > phi1)
1289 {
1290 term *= -sinh(Munk[n][k] * (pi - (phi - phi1)));
1291
1292
1293 }
1294 else
1295 {
1296 term *= sinh(Munk[n][k] * (pi - (phi1 - phi)));
1297
1298
1299 }
1300 if (verbosity)
1301 {
1302 std::cout << " *sinh(mu*pi-phi-phi)=" << term;
1303 }
1304 term *= 1 / (sinh(pi * Munk[n][k]));
1305
1306
1307 G += term;
1308 if (verbosity)
1309 {
1310 std::cout << " /sinh=" << term << " G=" << G << std::endl;
1311 }
1312 }
1313 }
1314 if (verbosity)
1315 {
1316 std::cout << "Ephi = " << G << std::endl;
1317 }
1318 verbosity = 0;
1319
1320 return G;
1321 }
1322
1323 void Rossegger::SaveZeroes(const std::string &destfile)
1324 {
1325 TFile *output = TFile::Open(destfile.c_str(), "RECREATE");
1326 output->cd();
1327
1328 TTree *tInfo = new TTree("info", "Mu[n][k] values");
1329 int ord = NumberOfOrders;
1330 tInfo->Branch("order", &ord);
1331 tInfo->Branch("epsilon", &epsilon);
1332 tInfo->Fill();
1333
1334 int n, k, m;
1335 double munk, betamn;
1336 double n2nk, n2mn;
1337 TTree *tmunk = new TTree("munk", "Mu[n][k] values");
1338 tmunk->Branch("n", &n);
1339 tmunk->Branch("k", &k);
1340 tmunk->Branch("munk", &munk);
1341 tmunk->Branch("n2nk", &n2nk);
1342 for (n = 0; n < ord; n++)
1343 {
1344 for (k = 0; k < ord; k++)
1345 {
1346 munk = Munk[n][k];
1347 n2nk = N2nk[n][k];
1348 tmunk->Fill();
1349 }
1350 }
1351
1352 TTree *tbetamn = new TTree("betamn", "Beta[m][n] values");
1353 tbetamn->Branch("m", &m);
1354 tbetamn->Branch("n", &n);
1355 tbetamn->Branch("betamn", &betamn);
1356 tbetamn->Branch("n2mn", &n2mn);
1357 for (m = 0; m < ord; m++)
1358 {
1359 for (n = 0; n < ord; n++)
1360 {
1361 betamn = Betamn[m][n];
1362 n2mn = N2mn[m][n];
1363 tbetamn->Fill();
1364 }
1365 }
1366
1367 tInfo->Write();
1368 tmunk->Write();
1369 tbetamn->Write();
1370
1371 output->Close();
1372 return;
1373 }
1374
1375 void Rossegger::LoadZeroes(const std::string &destfile)
1376 {
1377 TFile *f = TFile::Open(destfile.c_str(), "READ");
1378 std::cout << "reading rossegger zeroes from " << destfile << std::endl;
1379 TTree *tInfo = (TTree *) (f->Get("info"));
1380 int ord;
1381 tInfo->SetBranchAddress("order", &ord);
1382 tInfo->SetBranchAddress("epsilon", &epsilon);
1383 tInfo->GetEntry(0);
1384 std::cout << "order=" << ord << ",epsilon=" << epsilon << std::endl;
1385
1386 int n, k, m;
1387 double munk, betamn;
1388 double n2nk, n2mn;
1389 TTree *tmunk = (TTree *) (f->Get("munk"));
1390 tmunk->SetBranchAddress("n", &n);
1391 tmunk->SetBranchAddress("k", &k);
1392 tmunk->SetBranchAddress("munk", &munk);
1393 tmunk->SetBranchAddress("n2nk", &n2nk);
1394 for (int i = 0; i < tmunk->GetEntries(); i++)
1395 {
1396 tmunk->GetEntry(i);
1397 Munk[n][k] = munk;
1398 N2nk[n][k] = n2nk;
1399 }
1400
1401 TTree *tbetamn = (TTree *) (f->Get("betamn"));
1402 tbetamn->SetBranchAddress("m", &m);
1403 tbetamn->SetBranchAddress("n", &n);
1404 tbetamn->SetBranchAddress("betamn", &betamn);
1405 tbetamn->SetBranchAddress("n2mn", &n2mn);
1406 for (int i = 0; i < tbetamn->GetEntries(); i++)
1407 {
1408 tbetamn->GetEntry(i);
1409 Betamn[m][n] = betamn;
1410 N2mn[m][n] = n2mn;
1411 }
1412
1413 f->Close();
1414 return;
1415 }