LCOV - code coverage report
Current view: top level - src - GridTools.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 67 245 27.3 %
Date: 2024-04-29 14:43:01 Functions: 7 19 36.8 %

          Line data    Source code
       1             : #include "crpropa/GridTools.h"
       2             : #include "crpropa/magneticField/MagneticField.h"
       3             : 
       4             : #include <fstream>
       5             : #include <sstream>
       6             : 
       7             : namespace crpropa {
       8             : 
       9           0 : void scaleGrid(ref_ptr<Grid1f> grid, double a) {
      10           0 :         for (int ix = 0; ix < grid->getNx(); ix++)
      11           0 :                 for (int iy = 0; iy < grid->getNy(); iy++)
      12           0 :                         for (int iz = 0; iz < grid->getNz(); iz++)
      13           0 :                                 grid->get(ix, iy, iz) *= a;
      14           0 : }
      15             : 
      16          11 : void scaleGrid(ref_ptr<Grid3f> grid, double a) {
      17         654 :         for (int ix = 0; ix < grid->getNx(); ix++)
      18       41612 :                 for (int iy = 0; iy < grid->getNy(); iy++)
      19     2662436 :                         for (int iz = 0; iz < grid->getNz(); iz++)
      20     2621467 :                                 grid->get(ix, iy, iz) *= a;
      21          11 : }
      22             : 
      23           1 : Vector3f meanFieldVector(ref_ptr<Grid3f> grid) {
      24             :         size_t Nx = grid->getNx();
      25             :         size_t Ny = grid->getNy();
      26             :         size_t Nz = grid->getNz();
      27             :         Vector3f mean(0.);
      28          65 :         for (int ix = 0; ix < Nx; ix++)
      29        4160 :                 for (int iy = 0; iy < Ny; iy++)
      30      266240 :                         for (int iz = 0; iz < Nz; iz++)
      31             :                                 mean += grid->get(ix, iy, iz);
      32           1 :         return mean / Nx / Ny / Nz;
      33             : }
      34             : 
      35           0 : double meanFieldStrength(ref_ptr<Grid3f> grid) {
      36             :         size_t Nx = grid->getNx();
      37             :         size_t Ny = grid->getNy();
      38             :         size_t Nz = grid->getNz();
      39             :         double mean = 0;
      40           0 :         for (int ix = 0; ix < Nx; ix++)
      41           0 :                 for (int iy = 0; iy < Ny; iy++)
      42           0 :                         for (int iz = 0; iz < Nz; iz++)
      43           0 :                                 mean += grid->get(ix, iy, iz).getR();
      44           0 :         return mean / Nx / Ny / Nz;
      45             : }
      46             : 
      47           0 : double meanFieldStrength(ref_ptr<Grid1f> grid) {
      48             :         size_t Nx = grid->getNx();
      49             :         size_t Ny = grid->getNy();
      50             :         size_t Nz = grid->getNz();
      51             :         double mean = 0;
      52           0 :         for (int ix = 0; ix < Nx; ix++)
      53           0 :                 for (int iy = 0; iy < Ny; iy++)
      54           0 :                         for (int iz = 0; iz < Nz; iz++)
      55           0 :                                 mean += grid->get(ix, iy, iz);
      56           0 :         return mean / Nx / Ny / Nz;
      57             : }
      58             : 
      59          11 : double rmsFieldStrength(ref_ptr<Grid3f> grid) {
      60             :         size_t Nx = grid->getNx();
      61             :         size_t Ny = grid->getNy();
      62             :         size_t Nz = grid->getNz();
      63             :         double sumV2 = 0;
      64         715 :         for (int ix = 0; ix < Nx; ix++)
      65       45760 :                 for (int iy = 0; iy < Ny; iy++)
      66     2928640 :                         for (int iz = 0; iz < Nz; iz++)
      67     2883584 :                                 sumV2 += grid->get(ix, iy, iz).getR2();
      68          11 :         return std::sqrt(sumV2 / Nx / Ny / Nz);
      69             : }
      70             : 
      71           0 : double rmsFieldStrength(ref_ptr<Grid1f> grid) {
      72             :         size_t Nx = grid->getNx();
      73             :         size_t Ny = grid->getNy();
      74             :         size_t Nz = grid->getNz();
      75             :         double sumV2 = 0;
      76           0 :         for (int ix = 0; ix < Nx; ix++)
      77           0 :                 for (int iy = 0; iy < Ny; iy++)
      78           0 :                         for (int iz = 0; iz < Nz; iz++)
      79           0 :                                 sumV2 += pow(grid->get(ix, iy, iz), 2);
      80           0 :         return std::sqrt(sumV2 / Nx / Ny / Nz);
      81             : }
      82             : 
      83           0 : std::array<float, 3> rmsFieldStrengthPerAxis(ref_ptr<Grid3f> grid) {
      84             :     size_t Nx = grid->getNx();
      85             :     size_t Ny = grid->getNy();
      86             :     size_t Nz = grid->getNz();
      87             :     float sumV2_x = 0;
      88             :     float sumV2_y = 0;
      89             :     float sumV2_z = 0;
      90           0 :     for (int ix = 0; ix < Nx; ix++)
      91           0 :         for (int iy = 0; iy < Ny; iy++)
      92           0 :             for (int iz = 0; iz < Nz; iz++) {
      93           0 :                 sumV2_x += pow(grid->get(ix, iy, iz).x, 2);
      94           0 :                 sumV2_y += pow(grid->get(ix, iy, iz).y, 2);
      95           0 :                 sumV2_z += pow(grid->get(ix, iy, iz).z, 2);
      96             :             }
      97             :     return {
      98           0 :         std::sqrt(sumV2_x / Nx / Ny / Nz),
      99           0 :         std::sqrt(sumV2_y / Nx / Ny / Nz),
     100           0 :         std::sqrt(sumV2_z / Nx / Ny / Nz)
     101           0 :     };
     102             : }
     103             : 
     104           0 : void fromMagneticField(ref_ptr<Grid3f> grid, ref_ptr<MagneticField> field) {
     105             :         Vector3d origin = grid->getOrigin();
     106             :         Vector3d spacing = grid->getSpacing();
     107             :         size_t Nx = grid->getNx();
     108             :         size_t Ny = grid->getNy();
     109             :         size_t Nz = grid->getNz();
     110           0 :         for (size_t ix = 0; ix < Nx; ix++)
     111           0 :                 for (size_t iy = 0; iy < Ny; iy++)
     112           0 :                         for (size_t iz = 0; iz < Nz; iz++) {
     113           0 :                                 Vector3d pos = Vector3d(double(ix) + 0.5, double(iy) + 0.5, double(iz) + 0.5) * spacing + origin;
     114           0 :                                 Vector3d B = field->getField(pos);
     115             :                                 grid->get(ix, iy, iz) = B;
     116             :         }
     117           0 : }
     118             : 
     119           0 : void fromMagneticFieldStrength(ref_ptr<Grid1f> grid, ref_ptr<MagneticField> field) {
     120             :         Vector3d origin = grid->getOrigin();
     121             :         Vector3d spacing = grid->getSpacing();
     122             :         size_t Nx = grid->getNx();
     123             :         size_t Ny = grid->getNy();
     124             :         size_t Nz = grid->getNz();
     125           0 :         for (size_t ix = 0; ix < Nx; ix++)
     126           0 :                 for (size_t iy = 0; iy < Ny; iy++)
     127           0 :                         for (size_t iz = 0; iz < Nz; iz++) {
     128           0 :                                 Vector3d pos = Vector3d(double(ix) + 0.5, double(iy) + 0.5, double(iz) + 0.5) * spacing + origin;
     129           0 :                                 double s = field->getField(pos).getR();
     130           0 :                                 grid->get(ix, iy, iz) = s;
     131             :         }
     132           0 : }
     133             : 
     134           1 : void loadGrid(ref_ptr<Grid3f> grid, std::string filename, double c) {
     135           1 :         std::ifstream fin(filename.c_str(), std::ios::binary);
     136           1 :         if (!fin) {
     137           0 :                 std::stringstream ss;
     138           0 :                 ss << "load Grid3f: " << filename << " not found";
     139           0 :                 throw std::runtime_error(ss.str());
     140           0 :         }
     141             : 
     142             :         // get length of file and compare to size of grid
     143           1 :         fin.seekg(0, fin.end);
     144           1 :         size_t length = fin.tellg() / sizeof(float);
     145           1 :         fin.seekg (0, fin.beg);
     146             : 
     147             :         size_t nx = grid->getNx();
     148             :         size_t ny = grid->getNy();
     149             :         size_t nz = grid->getNz();
     150             : 
     151           1 :         if (length != (3 * nx * ny * nz))
     152           0 :                 throw std::runtime_error("loadGrid: file and grid size do not match");
     153             : 
     154           4 :         for (int ix = 0; ix < grid->getNx(); ix++) {
     155          12 :                 for (int iy = 0; iy < grid->getNy(); iy++) {
     156          36 :                         for (int iz = 0; iz < grid->getNz(); iz++) {
     157             :                                 Vector3f &b = grid->get(ix, iy, iz);
     158          27 :                                 fin.read((char*) &(b.x), sizeof(float));
     159          27 :                                 fin.read((char*) &(b.y), sizeof(float));
     160          27 :                                 fin.read((char*) &(b.z), sizeof(float));
     161          27 :                                 b *= c;
     162             :                         }
     163             :                 }
     164             :         }
     165           1 :         fin.close();
     166           1 : }
     167             : 
     168           0 : void loadGrid(ref_ptr<Grid1f> grid, std::string filename, double c) {
     169           0 :         std::ifstream fin(filename.c_str(), std::ios::binary);
     170           0 :         if (!fin) {
     171           0 :                 std::stringstream ss;
     172           0 :                 ss << "load Grid1f: " << filename << " not found";
     173           0 :                 throw std::runtime_error(ss.str());
     174           0 :         }
     175             : 
     176             :         // get length of file and compare to size of grid
     177           0 :         fin.seekg(0, fin.end);
     178           0 :         size_t length = fin.tellg() / sizeof(float);
     179           0 :         fin.seekg (0, fin.beg);
     180             : 
     181             :         size_t nx = grid->getNx();
     182             :         size_t ny = grid->getNy();
     183             :         size_t nz = grid->getNz();
     184             : 
     185           0 :         if (length != (nx * ny * nz))
     186           0 :                 throw std::runtime_error("loadGrid: file and grid size do not match");
     187             : 
     188           0 :         for (int ix = 0; ix < nx; ix++) {
     189           0 :                 for (int iy = 0; iy < ny; iy++) {
     190           0 :                         for (int iz = 0; iz < nz; iz++) {
     191             :                                 float &b = grid->get(ix, iy, iz);
     192           0 :                                 fin.read((char*) &b, sizeof(float));
     193           0 :                                 b *= c;
     194             :                         }
     195             :                 }
     196             :         }
     197           0 :         fin.close();
     198           0 : }
     199             : 
     200           1 : void dumpGrid(ref_ptr<Grid3f> grid, std::string filename, double c) {
     201           1 :         std::ofstream fout(filename.c_str(), std::ios::binary);
     202           1 :         if (!fout) {
     203           0 :                 std::stringstream ss;
     204           0 :                 ss << "dump Grid3f: " << filename << " not found";
     205           0 :                 throw std::runtime_error(ss.str());
     206           0 :         }
     207           4 :         for (int ix = 0; ix < grid->getNx(); ix++) {
     208          12 :                 for (int iy = 0; iy < grid->getNy(); iy++) {
     209          36 :                         for (int iz = 0; iz < grid->getNz(); iz++) {
     210          27 :                                 Vector3f b = grid->get(ix, iy, iz) * c;
     211          27 :                                 fout.write((char*) &(b.x), sizeof(float));
     212          27 :                                 fout.write((char*) &(b.y), sizeof(float));
     213          27 :                                 fout.write((char*) &(b.z), sizeof(float));
     214             :                         }
     215             :                 }
     216             :         }
     217           1 :         fout.close();
     218           1 : }
     219             : 
     220           0 : void dumpGrid(ref_ptr<Grid1f> grid, std::string filename, double c) {
     221           0 :         std::ofstream fout(filename.c_str(), std::ios::binary);
     222           0 :         if (!fout) {
     223           0 :                 std::stringstream ss;
     224           0 :                 ss << "dump Grid1f: " << filename << " not found";
     225           0 :                 throw std::runtime_error(ss.str());
     226           0 :         }
     227           0 :         for (int ix = 0; ix < grid->getNx(); ix++) {
     228           0 :                 for (int iy = 0; iy < grid->getNy(); iy++) {
     229           0 :                         for (int iz = 0; iz < grid->getNz(); iz++) {
     230           0 :                                 float b = grid->get(ix, iy, iz) * c;
     231           0 :                                 fout.write((char*) &b, sizeof(float));
     232             :                         }
     233             :                 }
     234             :         }
     235           0 :         fout.close();
     236           0 : }
     237             : 
     238           1 : void loadGridFromTxt(ref_ptr<Grid3f> grid, std::string filename, double c) {
     239           1 :         std::ifstream fin(filename.c_str());
     240           1 :         if (!fin) {
     241           0 :                 std::stringstream ss;
     242           0 :                 ss << "load Grid3f: " << filename << " not found";
     243           0 :                 throw std::runtime_error(ss.str());
     244           0 :         }
     245             :         // skip header lines
     246           1 :         while (fin.peek() == '#')
     247           0 :                 fin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
     248             : 
     249           4 :         for (int ix = 0; ix < grid->getNx(); ix++) {
     250          12 :                 for (int iy = 0; iy < grid->getNy(); iy++) {
     251          36 :                         for (int iz = 0; iz < grid->getNz(); iz++) {
     252             :                                 Vector3f &b = grid->get(ix, iy, iz);
     253          27 :                                 fin >> b.x >> b.y >> b.z;
     254          27 :                                 b *= c;
     255          27 :                                 if (fin.eof())
     256           0 :                                         throw std::runtime_error("load Grid3f: file too short");
     257             :                         }
     258             :                 }
     259             :         }
     260           1 :         fin.close();
     261           1 : }
     262             : 
     263           0 : void loadGridFromTxt(ref_ptr<Grid1f> grid, std::string filename, double c) {
     264           0 :         std::ifstream fin(filename.c_str());
     265           0 :         if (!fin) {
     266           0 :                 std::stringstream ss;
     267           0 :                 ss << "load Grid1f: " << filename << " not found";
     268           0 :                 throw std::runtime_error(ss.str());
     269           0 :         }
     270             :         // skip header lines
     271           0 :         while (fin.peek() == '#')
     272           0 :                 fin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
     273             : 
     274           0 :         for (int ix = 0; ix < grid->getNx(); ix++) {
     275           0 :                 for (int iy = 0; iy < grid->getNy(); iy++) {
     276           0 :                         for (int iz = 0; iz < grid->getNz(); iz++) {
     277             :                                 float &b = grid->get(ix, iy, iz);
     278             :                                 fin >> b;
     279           0 :                                 b *= c;
     280           0 :                                 if (fin.eof())
     281           0 :                                         throw std::runtime_error("load Grid1f: file too short");
     282             :                         }
     283             :                 }
     284             :         }
     285           0 :         fin.close();
     286           0 : }
     287             : 
     288           1 : void dumpGridToTxt(ref_ptr<Grid3f> grid, std::string filename, double c) {
     289           1 :         std::ofstream fout(filename.c_str());
     290           1 :         if (!fout) {
     291           0 :                 std::stringstream ss;
     292           0 :                 ss << "dump Grid3f: " << filename << " not found";
     293           0 :                 throw std::runtime_error(ss.str());
     294           0 :         }
     295           4 :         for (int ix = 0; ix < grid->getNx(); ix++) {
     296          12 :                 for (int iy = 0; iy < grid->getNy(); iy++) {
     297          36 :                         for (int iz = 0; iz < grid->getNz(); iz++) {
     298          27 :                                 Vector3f b = grid->get(ix, iy, iz) * c;
     299          27 :                                 fout << b << "\n";
     300             :                         }
     301             :                 }
     302             :         }
     303           1 :         fout.close();
     304           1 : }
     305             : 
     306           0 : void dumpGridToTxt(ref_ptr<Grid1f> grid, std::string filename, double c) {
     307           0 :         std::ofstream fout(filename.c_str());
     308           0 :         if (!fout) {
     309           0 :                 std::stringstream ss;
     310           0 :                 ss << "dump Grid1f: " << filename << " not found";
     311           0 :                 throw std::runtime_error(ss.str());
     312           0 :         }
     313           0 :         for (int ix = 0; ix < grid->getNx(); ix++) {
     314           0 :                 for (int iy = 0; iy < grid->getNy(); iy++) {
     315           0 :                         for (int iz = 0; iz < grid->getNz(); iz++) {
     316           0 :                                 float b = grid->get(ix, iy, iz) * c;
     317           0 :                                 fout << b << "\n";
     318             :                         }
     319             :                 }
     320             :         }
     321           0 :         fout.close();
     322           0 : }
     323             : 
     324             : #ifdef CRPROPA_HAVE_FFTW3F
     325             : 
     326           0 : std::vector<std::pair<int, float>> gridPowerSpectrum(ref_ptr<Grid3f> grid) {
     327             : 
     328           0 :   double rms = rmsFieldStrength(grid);
     329             :   size_t n = grid->getNx(); // size of array
     330             : 
     331             :   // arrays to hold the complex vector components of the B(k)-field
     332             :   fftwf_complex *Bkx, *Bky, *Bkz;
     333           0 :   Bkx = (fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex) * n * n * n);
     334           0 :   Bky = (fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex) * n * n * n);
     335           0 :   Bkz = (fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex) * n * n * n);
     336             : 
     337             :   fftwf_complex *Bx = (fftwf_complex *)Bkx;
     338             :   fftwf_complex *By = (fftwf_complex *)Bky;
     339             :   fftwf_complex *Bz = (fftwf_complex *)Bkz;
     340             : 
     341             :   // save to temp
     342             :   int i;
     343           0 :   for (size_t ix = 0; ix < n; ix++) {
     344           0 :     for (size_t iy = 0; iy < n; iy++) {
     345           0 :       for (size_t iz = 0; iz < n; iz++) {
     346           0 :         i = ix * n * n + iy * n + iz;
     347             :         Vector3<float> &b = grid->get(ix, iy, iz);
     348           0 :         Bx[i][0] = b.x / rms;
     349           0 :         By[i][0] = b.y / rms;
     350           0 :         Bz[i][0] = b.z / rms;
     351             :       }
     352             :     }
     353             :   }
     354             : 
     355             :   // in-place, real to complex, inverse Fourier transformation on each component
     356             :   // note that the last elements of B(x) are unused now
     357             :   fftwf_plan plan_x =
     358           0 :       fftwf_plan_dft_3d(n, n, n, Bx, Bkx, FFTW_FORWARD, FFTW_ESTIMATE);
     359           0 :   fftwf_execute(plan_x);
     360           0 :   fftwf_destroy_plan(plan_x);
     361             : 
     362             :   fftwf_plan plan_y =
     363           0 :       fftwf_plan_dft_3d(n, n, n, By, Bky, FFTW_FORWARD, FFTW_ESTIMATE);
     364           0 :   fftwf_execute(plan_y);
     365           0 :   fftwf_destroy_plan(plan_y);
     366             : 
     367             :   fftwf_plan plan_z =
     368           0 :       fftwf_plan_dft_3d(n, n, n, Bz, Bkz, FFTW_FORWARD, FFTW_ESTIMATE);
     369           0 :   fftwf_execute(plan_z);
     370           0 :   fftwf_destroy_plan(plan_z);
     371             : 
     372             :   float power;
     373             :   std::map<size_t, std::pair<float, int>> spectrum;
     374             :   int k;
     375             : 
     376           0 :   for (size_t ix = 0; ix < n; ix++) {
     377           0 :     for (size_t iy = 0; iy < n; iy++) {
     378           0 :       for (size_t iz = 0; iz < n; iz++) {
     379           0 :         i = ix * n * n + iy * n + iz;
     380           0 :         k = static_cast<int>(
     381           0 :             std::floor(std::sqrt(ix * ix + iy * iy + iz * iz)));
     382           0 :         if (k > n / 2. || k == 0)
     383           0 :           continue;
     384           0 :         power = ((Bkx[i][0] * Bkx[i][0] + Bkx[i][1] * Bkx[i][1]) +
     385           0 :                  (Bky[i][0] * Bky[i][0] + Bky[i][1] * Bky[i][1]) +
     386           0 :                  (Bkz[i][0] * Bkz[i][0] + Bkz[i][1] * Bkz[i][1]));
     387           0 :         if (spectrum.find(k) == spectrum.end()) {
     388           0 :           spectrum[k].first = power;
     389           0 :           spectrum[k].second = 1;
     390             :         } else {
     391           0 :           spectrum[k].first += power;
     392           0 :           spectrum[k].second += 1;
     393             :         }
     394             :       }
     395             :     }
     396             :   }
     397             : 
     398           0 :   fftwf_free(Bkx);
     399           0 :   fftwf_free(Bky);
     400           0 :   fftwf_free(Bkz);
     401             : 
     402             :   std::vector<std::pair<int, float>> points;
     403           0 :   for (std::map<size_t, std::pair<float, int>>::iterator it = spectrum.begin();
     404           0 :        it != spectrum.end(); ++it) {
     405           0 :     points.push_back(
     406           0 :         std::make_pair(it->first, (it->second).first / (it->second).second));
     407             :   }
     408             : 
     409           0 :   return points;
     410             : }
     411             : 
     412             : #endif // CRPROPA_HAVE_FFTW3F
     413             : 
     414             : 
     415             : } // namespace crpropa

Generated by: LCOV version 1.14