LCOV - code coverage report
Current view: top level - test - testMagneticField.cpp (source / functions) Coverage Total Hit
Test: coverage.info.cleaned Lines: 99.4 % 161 160
Test Date: 2026-06-18 09:49:19 Functions: 100.0 % 18 18

            Line data    Source code
       1              : #include <stdexcept>
       2              : 
       3              : #include "crpropa/magneticField/MagneticFieldGrid.h"
       4              : #include "crpropa/magneticField/CMZField.h"
       5              : #include "crpropa/magneticField/PolarizedSingleModeMagneticField.h"
       6              : #include "crpropa/magneticField/GalacticMagneticField.h"
       7              : #include "crpropa/magneticField/UF23Field.h"
       8              : #include "crpropa/Grid.h"
       9              : #include "crpropa/Units.h"
      10              : #include "crpropa/Common.h"
      11              : 
      12              : #include "gtest/gtest.h"
      13              : 
      14              : using namespace crpropa;
      15              : 
      16            1 : TEST(testUniformMagneticField, SimpleTest) {
      17              :         UniformMagneticField B(Vector3d(-1, 5, 3));
      18              :         Vector3d b = B.getField(Vector3d(1, 0, 0));
      19            1 :         EXPECT_DOUBLE_EQ(b.getX(), -1);
      20            1 :         EXPECT_DOUBLE_EQ(b.getY(), 5);
      21            1 :         EXPECT_DOUBLE_EQ(b.getZ(), 3);
      22            1 : }
      23              : 
      24            2 : TEST(testMagneticDipoleField, SimpleTest) {
      25              :         // Test magnetic dipole
      26              :         // mu0 / (4*M_PI) * m / r^3 (2*cos(theta)*e_r + sin(theta)*e_theta)
      27              :         MagneticDipoleField B(Vector3d(0,0,0), Vector3d(0,0,1), 1);
      28            1 :         Vector3d b1 = B.getField(Vector3d(0, 0, 1)); // theta = 0
      29            1 :         Vector3d b2 = B.getField(Vector3d(1, 0, 0)); // theta = 0
      30            1 :         EXPECT_NEAR(b1.getX(), 0, 1E-8);
      31            1 :         EXPECT_NEAR(b1.getY(), 0, 1E-8);
      32            1 :         EXPECT_NEAR(b1.getZ(), mu0 / (4*M_PI) * 2, 1E-8);
      33            1 :         EXPECT_NEAR(b2.getX(), 0, 1E-8);
      34            1 :         EXPECT_NEAR(b2.getY(), 0, 1E-8);
      35            1 :         EXPECT_NEAR(b2.getZ(), -1 * mu0 / (4*M_PI), 1E-8);
      36            1 : }
      37              : 
      38              : #ifdef CRPROPA_HAVE_MUPARSER
      39            1 : TEST(testRenormalizeMagneticField, simpleTest) {
      40            1 :         ref_ptr<UniformMagneticField> field = new UniformMagneticField(Vector3d(2*nG, 0, 0));
      41            2 :         RenormalizeMagneticField modField(field, "B^2-1*nG");
      42            1 :         Vector3d b = modField.getField(Vector3d(5, 5, 5));
      43            1 :         EXPECT_NEAR(b.getR(), 3*nG, 0.001);
      44            2 : }
      45              : #endif
      46              : 
      47            2 : TEST(testMagneticFieldList, SimpleTest) {
      48              :         // Test a list of three magnetic fields
      49              :         MagneticFieldList B;
      50            1 :         B.addField(new UniformMagneticField(Vector3d(1, 0, 0)));
      51            1 :         B.addField(new UniformMagneticField(Vector3d(0, 2, 0)));
      52            2 :         B.addField(new UniformMagneticField(Vector3d(0, 0, 3)));
      53            1 :         Vector3d b = B.getField(Vector3d(0.));
      54            1 :         EXPECT_DOUBLE_EQ(b.x, 1);
      55            1 :         EXPECT_DOUBLE_EQ(b.y, 2);
      56            1 :         EXPECT_DOUBLE_EQ(b.z, 3);
      57            1 : }
      58              : 
      59            1 : TEST(testMagneticFieldEvolution, SimpleTest) {
      60              :         // Test if this decorator scales the underlying field as (1+z)^m
      61            1 :         ref_ptr<UniformMagneticField> B = new UniformMagneticField(Vector3d(1,0,0));
      62              :         double z = 1.2;
      63              :         double m = 3;
      64            2 :         MagneticFieldEvolution Bz(B, m);
      65              : 
      66              :         // scaled field
      67            1 :         Vector3d b = Bz.getField(Vector3d(0,0,0), z);
      68            1 :         EXPECT_DOUBLE_EQ(b.x, pow(1+z, m));
      69              : 
      70              :         // unscaled field
      71            1 :         b = Bz.getField(Vector3d(0,0,0));
      72            1 :         EXPECT_DOUBLE_EQ(b.x, 1);
      73            1 : }
      74              : 
      75            1 : class EchoMagneticField: public MagneticField {
      76              : public:
      77            3 :         Vector3d getField(const Vector3d &position) const {
      78            3 :                 return position;
      79              :         }
      80              : };
      81              : 
      82            1 : TEST(testPeriodicMagneticField, Exceptions) {
      83            1 :         ref_ptr<EchoMagneticField> f = new EchoMagneticField();
      84              :         ref_ptr<PeriodicMagneticField> p = new PeriodicMagneticField(f,
      85            2 :                         Vector3d(10000, 10000, 10000), Vector3d(1000, 1000, 1000), true);
      86              : 
      87              :         // box 0, 0, 0
      88            1 :         Vector3d v = p->getField(Vector3d(1000, 2000, 3000));
      89            1 :         EXPECT_DOUBLE_EQ(0, v.x);
      90            1 :         EXPECT_DOUBLE_EQ(1000, v.y);
      91            1 :         EXPECT_DOUBLE_EQ(2000, v.z);
      92              : 
      93              :         // box 1, 2, 3
      94            1 :         v = p->getField(Vector3d(12000, 23000, 34000));
      95            1 :         EXPECT_DOUBLE_EQ(9000, v.x);
      96            1 :         EXPECT_DOUBLE_EQ(2000, v.y);
      97            1 :         EXPECT_DOUBLE_EQ(7000, v.z);
      98              : 
      99              :         // box -1, -2, -3
     100            1 :         v = p->getField(Vector3d(0, -10000, -20000));
     101            1 :         EXPECT_DOUBLE_EQ(1000, v.x);
     102            1 :         EXPECT_DOUBLE_EQ(9000, v.y);
     103            1 :         EXPECT_DOUBLE_EQ(1000, v.z);
     104              : 
     105            1 : }
     106              : 
     107            1 : TEST(testCMZMagneticField, SimpleTest) {
     108            1 :         ref_ptr<CMZField> field = new CMZField();
     109              : 
     110              :         // check use-Values
     111            1 :         EXPECT_FALSE(field->getUseMCField());
     112            1 :         EXPECT_TRUE(field->getUseICField());
     113            1 :         EXPECT_FALSE(field->getUseNTFField());
     114            1 :         EXPECT_FALSE(field->getUseRadioArc());
     115              : 
     116              :         // check set function
     117            1 :         field->setUseMCField(true);
     118            1 :         EXPECT_TRUE(field->getUseMCField());
     119            1 :         field->setUseICField(false);
     120            1 :         EXPECT_FALSE(field->getUseICField());
     121            1 :         field->setUseNTFField(true);
     122            1 :         EXPECT_TRUE(field->getUseNTFField());
     123            1 :         field->setUseRadioArc(true);
     124            1 :         EXPECT_TRUE(field->getUseRadioArc());
     125            1 : }
     126              : 
     127            1 : TEST(testCMZMagneticField, TestICComponent) {
     128            1 :         ref_ptr<CMZField> field = new CMZField();
     129              :         Vector3d pos(10*pc,15*pc,-5*pc);
     130              : 
     131              :         // check IC field at given position
     132            1 :         Vector3d bVec = field->getField(pos);
     133            1 :         EXPECT_NEAR(bVec.getR(), 10.501*muG, 1E-3*muG);
     134            1 :         EXPECT_NEAR(bVec.x, 0.225*muG, 1E-3*muG);
     135            1 :         EXPECT_NEAR(bVec.y, 0.524*muG, 1E-3*muG);
     136            1 :         EXPECT_NEAR(bVec.z, 10.486*muG, 1E-3*muG);
     137            1 : }
     138            1 : TEST(testCMZMagneticField, TestNTFField){
     139            1 :         ref_ptr<CMZField> field = new CMZField();
     140              :         Vector3d pos(10*pc,15*pc,-5*pc);
     141              : 
     142              :         // check NFTField at given position
     143            1 :         Vector3d bVec = field->getNTFField(pos);
     144            1 :         EXPECT_NEAR(bVec.getR(),1.692*muG, 1e-3*muG);
     145            1 :         EXPECT_NEAR(bVec.x, -0.584*muG, 1e-3*muG);
     146            1 :         EXPECT_NEAR(bVec.y, -1.185*muG, 1e-3*muG);
     147            1 :         EXPECT_NEAR(bVec.z, 1.057*muG, 1e-3*muG);
     148            1 : }
     149            1 : TEST(testCMZMagneticField, TestRaidoArcField){
     150            1 :         ref_ptr<CMZField> field = new CMZField();
     151              :         Vector3d pos(10*pc,15*pc,-5*pc);
     152              : 
     153              :         // check RadioArcField at given position
     154            1 :         Vector3d bVec = field->getRadioArcField(pos);
     155            1 :         EXPECT_NEAR(bVec.getR(), 31.616*muG, 1e-3*muG);
     156            1 :         EXPECT_NEAR(bVec.x, -4.671*muG, 1e-3*muG);
     157            1 :         EXPECT_NEAR(bVec.y, 5.465*muG, 1e-3*muG);
     158            1 :         EXPECT_NEAR(bVec.z, 30.788*muG, 1e-3*muG);
     159            1 : }
     160              : 
     161            1 : TEST(testCMZMagneticField, TestAzimutalComponent){
     162            1 :         ref_ptr<CMZField> field = new CMZField();
     163              :         Vector3d mid(12*pc, 9*pc, 20*pc);
     164              :         Vector3d pos(9*pc, 10*pc, 25*pc);
     165              : 
     166              :         // simple Test for inner part
     167            1 :         Vector3d bVec = field->BAz(pos, mid, 100, 0.2, 60*pc);
     168            1 :         EXPECT_NEAR(bVec.x, 3939.782, 1e-3);
     169            1 :         EXPECT_NEAR(bVec.y, 14347.304, 1e-3);
     170            1 :         EXPECT_DOUBLE_EQ(bVec.z, 0);
     171              : 
     172              :         // simple Test for outer part
     173            1 :         bVec = field->BAz(pos, mid, 100, 0.2, 10*pc);
     174            1 :         EXPECT_NEAR(bVec.x, -164.659, 1e-3);
     175            1 :         EXPECT_NEAR(bVec.y, -1317.270, 1e-3);
     176            1 :         EXPECT_DOUBLE_EQ(bVec.z, 0);
     177              : 
     178              :         // test for molecular Clouds
     179            1 :         bVec = field->getMCField(pos);
     180            1 :         EXPECT_NEAR(bVec.x, -8.339*muG, 1e-3*muG);
     181            1 :         EXPECT_NEAR(bVec.y, -0.850*muG, 1e-3*muG);
     182            1 :         EXPECT_DOUBLE_EQ(bVec.z, 0);
     183            1 : }
     184              : 
     185            1 : TEST(testToroidalHaloField, SimpleTest) {
     186            1 :         ref_ptr<ToroidalHaloField> field = new ToroidalHaloField();
     187            1 :         Vector3d b = field->getField(Vector3d(0.));
     188            1 :         EXPECT_DOUBLE_EQ(b.x, 0);
     189            1 :         EXPECT_DOUBLE_EQ(b.y, 0);
     190            1 :         EXPECT_DOUBLE_EQ(b.z, 0);
     191              : 
     192            1 :         b = field->getField(Vector3d(1,0,0));
     193            1 :         EXPECT_DOUBLE_EQ(b.x, 0.5);
     194            1 :         EXPECT_DOUBLE_EQ(b.y, 0);
     195            1 :         EXPECT_DOUBLE_EQ(b.z, 0);
     196            1 : }
     197              : 
     198            1 : TEST(testLogarithmicSpiralField, SimpleTest) {
     199            1 :         ref_ptr<LogarithmicSpiralField> field = new LogarithmicSpiralField();
     200            1 :         Vector3d b = field->getField(Vector3d(8.5, 0, 0)*kpc);
     201            1 :         EXPECT_NEAR(b.x, -1., 1E-2);
     202            1 :         EXPECT_NEAR(b.y, 0, 1E-10);
     203            1 :         EXPECT_NEAR(b.z, 0, 1E-10);
     204            1 : }
     205              : 
     206              : 
     207              : // UF23 reference values
     208              : std::vector<std::vector<Vector3d>>
     209            1 : getUF23ReferenceValues()
     210              : {
     211              :   using V = Vector3d;
     212              :   std::vector<std::vector<Vector3d>> retVal;
     213            2 :   retVal.push_back({
     214              :                     V{-1.46860417e+00, 1.64555489e+00, 8.35702311e-01},
     215              :                     V{0.00000000e+00, -4.22433497e-01, 1.83232985e-01},
     216              :                     V{-3.00239177e-01, -2.97045767e-01, 1.83232985e-01},
     217              :                     V{8.58382023e-04, 7.71891049e-03, 9.71705527e-01},
     218              :                     V{-1.17276875e+00, -2.33013590e-01, 4.10798494e-01},
     219              :                     V{2.63883569e-01, -8.79631081e-01, 5.54229961e-06},
     220              :                     V{-1.71971907e-02, -2.00291358e-02, 4.16024875e-02},
     221              :                     V{6.18960813e-01, -2.14437026e+00, 8.35702315e-01},
     222              :                     V{-1.50883911e+00, 2.63874909e+00, 1.16578928e-02}
     223              :     });
     224            2 :   retVal.push_back({
     225              :                     V{-1.39447625e+00, 1.57135437e+00, 8.65163870e-01},
     226              :                     V{0.00000000e+00, -4.44318027e-01, 1.54430718e-01},
     227              :                     V{-3.15695875e-01, -3.12652066e-01, 1.54430718e-01},
     228              :                     V{2.09678202e-03, 2.63832916e-03, 9.81077691e-01},
     229              :                     V{-1.08603376e+00, -1.86359136e-01, 3.91730436e-01},
     230              :                     V{2.11095801e-01, -7.04082667e-01, 8.86591950e-05},
     231              :                     V{-1.38087843e-02, -1.52011002e-02, 3.06842086e-02},
     232              :                     V{5.76543516e-01, -2.03544911e+00, 8.65163870e-01},
     233              :                     V{-3.77778745e-01, 6.89644787e-01, 5.85347897e-02},
     234              :     });
     235            2 :   retVal.push_back({
     236              :                     V{-1.04170166e+00, 1.93212739e+00, 2.95362499e+00},
     237              :                     V{0.00000000e+00, -5.87995638e-01, 4.66925506e-01},
     238              :                     V{-4.20802701e-01, -4.10291633e-01, 4.59557272e-01},
     239              :                     V{7.79982996e-03, 1.50482351e-02, 5.50337531e+00},
     240              :                     V{-1.34639246e+00, 6.80103301e-02, 8.60002649e-01},
     241              :                     V{1.37242004e-01, -8.67085225e-01, 1.25106474e-01},
     242              :                     V{-1.69325979e-02, -2.95454738e-02, 4.72616404e-02},
     243              :                     V{4.53873303e-01, -2.03292501e+00, 9.95205454e-01},
     244              :                     V{-1.30599234e+00, 2.25151057e+00, 2.56704152e-01},
     245              :     });
     246            2 :   retVal.push_back({
     247              :                     V{-1.45840221e+00, 1.64227817e+00, 8.41586777e-01},
     248              :                     V{0.00000000e+00, -6.98341816e-01, 1.84323895e-01},
     249              :                     V{-4.95342500e-01, -4.92154113e-01, 1.84323895e-01},
     250              :                     V{-5.27533653e-03, 1.48965596e-02, 9.86107885e-01},
     251              :                     V{-1.47472798e+00, -3.33905274e-01, 4.11265918e-01},
     252              :                     V{2.31202234e-01, -7.70722755e-01, 1.12129423e-05},
     253              :                     V{-1.54200071e-02, -2.22012150e-02, 4.22733003e-02},
     254              :                     V{5.92201401e-01, -2.10378256e+00, 8.41586782e-01},
     255              :                     V{4.05057122e-03, -9.76673905e-03, 8.24321504e-03},
     256              :     });
     257            2 :   retVal.push_back({
     258              :                     V{-1.50595160e+00, 1.67869437e+00, 8.29806168e-01},
     259              :                     V{0.00000000e+00, -2.27289811e-01, 1.86869632e-01},
     260              :                     V{-1.62291024e-01, -1.59076795e-01, 1.86869632e-01},
     261              :                     V{6.71536463e-04, 7.88990042e-03, 9.63291786e-01},
     262              :                     V{-9.35561196e-01, -1.55840707e-01, 4.13609050e-01},
     263              :                     V{2.68120686e-01, -8.93743434e-01, 3.48927149e-06},
     264              :                     V{-1.88291055e-02, -1.94245715e-02, 4.29970299e-02},
     265              :                     V{6.50804557e-01, -2.18817590e+00, 8.29806172e-01},
     266              :                     V{-1.58450595e+00, 2.77817014e+00, 1.10336683e-02},
     267              :     });
     268            2 :   retVal.push_back({
     269              :                     V{-1.33098823e+00, 1.49556466e+00, 6.88642986e-01},
     270              :                     V{0.00000000e+00, -4.99342453e-01, 1.16143813e-01},
     271              :                     V{-3.54225500e-01, -3.51947350e-01, 1.16143813e-01},
     272              :                     V{2.14352986e-03, 3.57971370e-03, 8.05219599e-01},
     273              :                     V{-1.15136627e+00, -2.48536546e-01, 2.95713475e-01},
     274              :                     V{1.18057505e-01, -3.98308301e-01, 9.11299352e-04},
     275              :                     V{-1.06899006e-02, -1.12335952e-02, 2.33358311e-02},
     276              :                     V{5.61264936e-01, -1.94601963e+00, 6.88642987e-01},
     277              :                     V{-1.18200258e+00, 2.01179003e+00, 8.02453884e-02},
     278              :     });
     279            2 :   retVal.push_back({
     280              :                     V{-3.65508814e-01, 4.74456797e-01, 5.76165841e-01},
     281              :                     V{0.00000000e+00, 0.00000000e+00, 6.36668108e-02},
     282              :                     V{-3.68784336e-03, -2.20689056e-03, 6.36668108e-02},
     283              :                     V{-5.03208784e-02, 5.09887480e-02, 6.27665021e-01},
     284              :                     V{-4.04821314e-01, -1.01426396e-02, 2.06022291e-01},
     285              :                     V{-2.34287239e-02, -9.72536117e-02, 2.80624948e-02},
     286              :                     V{-4.42698169e-03, -6.23429869e-03, 1.07555956e-02},
     287              :                     V{3.25022555e-01, -1.18950549e+00, 5.76163734e-01},
     288              :                     V{-8.65217092e-01, 1.85270104e+00, 3.73913202e-01},
     289              :     });
     290            2 :   retVal.push_back({
     291              :                     V{-1.92580231e+00, 2.17134243e+00, 1.13723929e+00},
     292              :                     V{0.00000000e+00, -4.73261099e-01, 2.65974345e-01},
     293              :                     V{-3.36780079e-01, -3.32368900e-01, 2.65974345e-01},
     294              :                     V{-5.24558924e-04, 1.51886238e-02, 1.33757258e+00},
     295              :                     V{-1.47213976e+00, -2.82203258e-01, 5.71920142e-01},
     296              :                     V{3.54206333e-01, -1.18108962e+00, 1.00077423e-04},
     297              :                     V{-2.67268842e-02, -2.88588605e-02, 6.38364561e-02},
     298              :                     V{7.90570955e-01, -2.84039611e+00, 1.13723931e+00},
     299              :                     V{-1.97316856e+00, 3.44153600e+00, 3.20266742e-02},
     300              :     });
     301            1 :   return retVal;
     302            0 : }
     303              : 
     304              : 
     305            1 : TEST(testUF23Field, SimpleTest) {
     306              :   const std::vector<UF23Field::ModelType> models =
     307              :     {
     308              :      UF23Field::base, UF23Field::neCL, UF23Field::expX, UF23Field::spur,
     309              :      UF23Field::cre10, UF23Field::synCG, UF23Field::twistX, UF23Field::nebCor
     310            1 :     };
     311              : 
     312              :   using V = Vector3d;
     313              :   const std::vector<Vector3d> testPositions =
     314              :     {
     315              :      V{1, 1, 1}, V{0, 0, -8}, V{0.1, -0.1, -8}, V{0.1, 0.1, 0.1}, V{-1, 3, 4},
     316              :      V{-10, -3, 2}, V{-10, -10, 20}, V{-4, -2, 1}, V{6, 5, -0.1}
     317            1 :     };
     318              : 
     319              :   const std::vector<std::vector<Vector3d>> referenceValues =
     320            1 :     getUF23ReferenceValues();
     321              : 
     322              :   const double precision = 1e-6;
     323              : 
     324            9 :   for (unsigned int i = 0; i < models.size(); ++i) {
     325              :     const auto& model = models[i];
     326            8 :     const UF23Field uf23Field(model);
     327           80 :     for (unsigned int j = 0; j < testPositions.size(); ++j) {
     328              :       const auto& position = testPositions[j];
     329           72 :       const auto val = uf23Field.getField(position*kpc);
     330              :       const auto& refVal = referenceValues[i][j] * microgauss;
     331           72 :       EXPECT_NEAR(val.x, refVal.x, precision);
     332           72 :       EXPECT_NEAR(val.y, refVal.y, precision);
     333           72 :       EXPECT_NEAR(val.z, refVal.z, precision);
     334              :     }
     335              :   }
     336            1 : }
     337              : 
     338            1 : TEST(testPolarizedSingleModeMagneticField, SimpleTest) {
     339            1 :         PolarizedSingleModeMagneticField B(2, 4, 0.5, Vector3d(1,1,1), Vector3d(0,1,0), Vector3d(1,0,0), "amplitude", "polarization", "elliptical");
     340            1 :         Vector3d b = B.getField(Vector3d(1,1,2));
     341            1 :         EXPECT_DOUBLE_EQ(b.x, 1);
     342            1 :         EXPECT_NEAR(b.y, 0, 1E-10);
     343            1 :         EXPECT_NEAR(b.z, 0, 1E-10);
     344            1 : }
     345              : 
     346            1 : int main(int argc, char **argv) {
     347            1 :         ::testing::InitGoogleTest(&argc, argv);
     348              :         return RUN_ALL_TESTS();
     349              : }
        

Generated by: LCOV version 2.0-1