LCOV - code coverage report
Current view: top level - src/magneticField - PT11Field.cpp (source / functions) Coverage Total Hit
Test: coverage.info.cleaned Lines: 0.0 % 63 0
Test Date: 2026-06-18 09:49:19 Functions: 0.0 % 9 0

            Line data    Source code
       1              : #include "crpropa/magneticField/PT11Field.h"
       2              : #include "crpropa/Units.h"
       3              : 
       4              : #include <algorithm>
       5              : 
       6              : namespace crpropa {
       7              : 
       8            0 : PT11Field::PT11Field() : useASS(true), useBSS(false), useHalo(true) {
       9              :         // disk parameters
      10            0 :         d = - 0.6 * kpc;
      11            0 :         R_sun = 8.5 * kpc;
      12            0 :         R_c = 5.0 * kpc;
      13            0 :         z0_D = 1.0 * kpc;
      14            0 :         B0_D = 2.0 * muG;
      15              : 
      16              :         // halo parameters
      17            0 :         z0_H = 1.3 * kpc;
      18            0 :         R0_H = 8.0 * kpc;
      19            0 :         B0_Hn = 4.0 * muG;
      20            0 :         B0_Hs = 4.0 * muG;
      21            0 :         z11_H = 0.25 * kpc;
      22            0 :         z12_H = 0.4 * kpc;
      23              : 
      24              :         // set ASS specific parameters
      25            0 :         setUseASS(true);
      26            0 : }
      27              : 
      28            0 : void PT11Field::SetParams() {
      29            0 :         cos_pitch = cos(pitch);
      30            0 :         sin_pitch = sin(pitch);
      31            0 :         PHI = cos_pitch / sin_pitch * log1p(d / R_sun) - M_PI / 2;
      32            0 :         cos_PHI = cos(PHI);
      33            0 : }
      34              : 
      35            0 : void PT11Field::setUseASS(bool use) {
      36            0 :         useASS = use;
      37            0 :         if (not(use))
      38              :                 return;
      39              : 
      40            0 :         if (useBSS) {
      41              :                 std::cout << "PT11Field: Disk field changed to ASS" << std::endl;
      42            0 :                 useBSS = false;
      43              :         }
      44              : 
      45            0 :         pitch = -5.0 * M_PI / 180;
      46            0 :         B0_Hs = 2.0 * muG;
      47            0 :         SetParams();
      48              : }
      49              : 
      50            0 : void PT11Field::setUseBSS(bool use) {
      51            0 :         useBSS = use;
      52            0 :         if (not(use))
      53              :                 return;
      54              : 
      55            0 :         if (useASS) {
      56              :                 std::cout << "PT11Field: Disk field changed to BSS" << std::endl;
      57            0 :                 useASS = false;
      58              :         }
      59              : 
      60            0 :         pitch = -6.0 * M_PI / 180;
      61            0 :         B0_Hs = 4.0 * muG;
      62            0 :         SetParams();
      63              : }
      64              : 
      65            0 : void PT11Field::setUseHalo(bool use) {
      66            0 :         useHalo = use;
      67            0 : }
      68              : 
      69            0 : bool PT11Field::isUsingASS() {
      70            0 :         return useASS;
      71              : }
      72              : 
      73            0 : bool PT11Field::isUsingBSS() {
      74            0 :         return useBSS;
      75              : }
      76              : 
      77            0 : bool PT11Field::isUsingHalo() {
      78            0 :         return useHalo;
      79              : }
      80              : 
      81            0 : Vector3d PT11Field::getField(const Vector3d& pos) const {
      82            0 :         double r = sqrt(pos.x * pos.x + pos.y * pos.y);  // in-plane radius
      83              : 
      84              :         Vector3d b(0.);
      85              : 
      86              :         // disk field
      87            0 :         if ((useASS) or (useBSS)) {
      88              :                 // PT11 paper has B_theta = B * cos(p) but this seems because they define azimuth clockwise, while we have anticlockwise.
      89              :                 // see Tinyakov 2002 APh 18,165: "local field points to l=90+p" so p=-5 deg gives l=85 and hence clockwise from above.
      90              :                 // so to get local B clockwise in our system, need minus (like Sun etal).
      91              :                 // Ps base their system on Han and Qiao 1994 A&A 288,759 which has a diagram with azimuth clockwise, hence confirmed.
      92              : 
      93              :                 // PT11 paper define Earth position at (+8.5, 0, 0) kpc; but usual convention is (-8.5, 0, 0)
      94              :                 // thus we have to rotate our position by 180 degree in azimuth
      95            0 :                 double theta = M_PI - pos.getPhi();  // azimuth angle theta: PT11 paper uses opposite convention for azimuth
      96              :                 // the following is equivalent to sin(pi - phi) and cos(pi - phi) which is computationally slower
      97            0 :                 double cos_theta = - pos.x / r;
      98            0 :                 double sin_theta = pos.y / r;
      99              : 
     100              :                 // After some geometry calculations (on whiteboard) one finds:
     101              :                 // Bx = +cos(theta) * B_r - sin(theta) * B_{theta}
     102              :                 // By = -sin(theta) * B_r - cos(theta) * B_{theta}
     103              :                 // Use from paper: B_theta = B * cos(pitch)     and B_r = B * sin(pitch)
     104            0 :                 b.x = sin_pitch * cos_theta - cos_pitch * sin_theta;
     105            0 :                 b.y = - sin_pitch * sin_theta - cos_pitch * cos_theta;
     106              :                 b *= -1;        // flip magnetic field direction, as B_{theta} and B_{phi} refering to 180 degree rotated field
     107              : 
     108            0 :                 double bMag = cos(theta - cos_pitch / sin_pitch * log(r / R_sun) + PHI);
     109            0 :                 if (useASS)
     110            0 :                         bMag = fabs(bMag);
     111            0 :                 bMag *= B0_D * R_sun / std::max(r, R_c) / cos_PHI * exp(-fabs(pos.z) / z0_D);
     112              :                 b *= bMag;
     113              :         }
     114              : 
     115              :         // halo field
     116            0 :         if (useHalo) {
     117            0 :                 double bMag = (pos.z > 0 ? B0_Hn : - B0_Hs);
     118            0 :                 double z1 = (fabs(pos.z) < z0_H ? z11_H : z12_H);
     119            0 :                 bMag *= r / R0_H * exp(1 - r / R0_H) / (1 + pow((fabs(pos.z) - z0_H) / z1, 2.));
     120              :                 // equation (8) in paper: theta uses now the conventional azimuth definition in contrast to equation (3)
     121              :                 // cos(phi) = pos.x / r (phi going counter-clockwise)
     122              :                 // sin(phi) = pos.y / r
     123              :                 // unitvector of phi in polar coordinates: (-sin(phi), cos(phi), 0)
     124            0 :                 b += bMag * Vector3d(-pos.y / r, pos.x / r, 0);
     125              :         }
     126              : 
     127            0 :         return b;
     128              : }
     129              : 
     130              : } // namespace crpropa
        

Generated by: LCOV version 2.0-1