nmie.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. //**********************************************************************************//
  2. // Copyright (C) 2009-2015 Ovidio Pena <ovidio@bytesfall.com> //
  3. // Copyright (C) 2013-2015 Konstantin Ladutenko <kostyfisik@gmail.com> //
  4. // //
  5. // This file is part of scattnlay //
  6. // //
  7. // This program is free software: you can redistribute it and/or modify //
  8. // it under the terms of the GNU General Public License as published by //
  9. // the Free Software Foundation, either version 3 of the License, or //
  10. // (at your option) any later version. //
  11. // //
  12. // This program is distributed in the hope that it will be useful, //
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of //
  14. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
  15. // GNU General Public License for more details. //
  16. // //
  17. // The only additional remark is that we expect that all publications //
  18. // describing work using this software, or all commercial products //
  19. // using it, cite the following reference: //
  20. // [1] O. Pena and U. Pal, "Scattering of electromagnetic radiation by //
  21. // a multilayered sphere," Computer Physics Communications, //
  22. // vol. 180, Nov. 2009, pp. 2348-2354. //
  23. // //
  24. // You should have received a copy of the GNU General Public License //
  25. // along with this program. If not, see <http://www.gnu.org/licenses/>. //
  26. //**********************************************************************************//
  27. #define VERSION "0.3.1"
  28. #include <array>
  29. #include <complex>
  30. #include <cstdlib>
  31. #include <iostream>
  32. #include <vector>
  33. namespace nmie {
  34. int ScattCoeffs(const unsigned int L, const int pl, std::vector<double>& x, std::vector<std::complex<double> >& m, const int nmax, std::vector<std::complex<double> > &an, std::vector<std::complex<double> > &bn);
  35. int nMie(const unsigned int L, const int pl, std::vector<double>& x, std::vector<std::complex<double> >& m, const unsigned int nTheta, std::vector<double>& Theta, const int nmax, double *Qext, double *Qsca, double *Qabs, double *Qbk, double *Qpr, double *g, double *Albedo, std::vector<std::complex<double> >& S1, std::vector<std::complex<double> >& S2);
  36. int nMie(const unsigned int L, std::vector<double>& x, std::vector<std::complex<double> >& m, const unsigned int nTheta, std::vector<double>& Theta, double *Qext, double *Qsca, double *Qabs, double *Qbk, double *Qpr, double *g, double *Albedo, std::vector<std::complex<double> >& S1, std::vector<std::complex<double> >& S2);
  37. int nMie(const unsigned int L, const int pl, std::vector<double>& x, std::vector<std::complex<double> >& m, const unsigned int nTheta, std::vector<double>& Theta, double *Qext, double *Qsca, double *Qabs, double *Qbk, double *Qpr, double *g, double *Albedo, std::vector<std::complex<double> >& S1, std::vector<std::complex<double> >& S2);
  38. int nMie(const unsigned int L, std::vector<double>& x, std::vector<std::complex<double> >& m, const unsigned int nTheta, std::vector<double>& Theta, const int nmax, double *Qext, double *Qsca, double *Qabs, double *Qbk, double *Qpr, double *g, double *Albedo, std::vector<std::complex<double> >& S1, std::vector<std::complex<double> >& S2);
  39. int nField(const unsigned int L, const int pl, const std::vector<double>& x, const std::vector<std::complex<double> >& m, const int nmax, const unsigned int ncoord, const std::vector<double>& Xp, const std::vector<double>& Yp, const std::vector<double>& Zp, std::vector<std::vector<std::complex<double> > >& E, std::vector<std::vector<std::complex<double> > >& H);
  40. class MultiLayerMie {
  41. public:
  42. // Run calculation
  43. void RunMieCalculation();
  44. void RunFieldCalculation();
  45. // Return calculation results
  46. double GetQext();
  47. double GetQsca();
  48. double GetQabs();
  49. double GetQbk();
  50. double GetQpr();
  51. double GetAsymmetryFactor();
  52. double GetAlbedo();
  53. std::vector<std::complex<double> > GetS1();
  54. std::vector<std::complex<double> > GetS2();
  55. std::vector<std::complex<double> > GetAn(){return an_;};
  56. std::vector<std::complex<double> > GetBn(){return bn_;};
  57. // Problem definition
  58. // Add new layer
  59. void AddNewLayer(double layer_size, std::complex<double> layer_index);
  60. // Modify width of the layer
  61. void SetLayerSize(std::vector<double> layer_size, int layer_position = 0);
  62. // Modify refractive index of the layer
  63. void SetLayerIndex(std::vector< std::complex<double> > layer_index, int layer_position = 0);
  64. // Modify size of all layers
  65. void SetLayersSize(const std::vector<double>& layer_size);
  66. // Modify refractive index of all layers
  67. void SetLayersIndex(const std::vector< std::complex<double> >& index);
  68. // Modify scattering (theta) angles
  69. void SetAngles(const std::vector<double>& angles);
  70. // Modify coordinates for field calculation
  71. void SetFieldCoords(const std::vector< std::vector<double> >& coords);
  72. // Modify PEC layer
  73. void SetPECLayer(int layer_position = 0);
  74. // Set a fixed value for the maximun number of terms
  75. void SetMaxTerms(int nmax);
  76. // Get maximun number of terms
  77. int GetMaxTerms() {return nmax_;};
  78. // Clear layer information
  79. void ClearLayers();
  80. // Applied units requests
  81. double GetSizeParameter();
  82. double GetLayerWidth(int layer_position = 0);
  83. std::vector<double> GetLayersSize();
  84. std::vector<std::complex<double> > GetLayersIndex();
  85. std::vector<std::array<double, 3> > GetFieldCoords();
  86. std::vector<std::vector< std::complex<double> > > GetFieldE(){return E_;}; // {X[], Y[], Z[]}
  87. std::vector<std::vector< std::complex<double> > > GetFieldH(){return H_;};
  88. private:
  89. void calcNstop();
  90. void calcNmax(unsigned int first_layer);
  91. std::complex<double> calc_an(int n, double XL, std::complex<double> Ha, std::complex<double> mL,
  92. std::complex<double> PsiXL, std::complex<double> ZetaXL,
  93. std::complex<double> PsiXLM1, std::complex<double> ZetaXLM1);
  94. std::complex<double> calc_bn(int n, double XL, std::complex<double> Hb, std::complex<double> mL,
  95. std::complex<double> PsiXL, std::complex<double> ZetaXL,
  96. std::complex<double> PsiXLM1, std::complex<double> ZetaXLM1);
  97. void calc_an_bn_bulk(std::vector<std::complex<double> >& an,
  98. std::vector<std::complex<double> >& bn,
  99. double x, std::complex<double> m);
  100. std::complex<double> calc_S1(int n, std::complex<double> an, std::complex<double> bn,
  101. double Pi, double Tau);
  102. std::complex<double> calc_S2(int n, std::complex<double> an, std::complex<double> bn,
  103. double Pi, double Tau);
  104. void calcD1D3(std::complex<double> z,
  105. std::vector<std::complex<double> >& D1,
  106. std::vector<std::complex<double> >& D3);
  107. void calcPsiZeta(std::complex<double> x,
  108. std::vector<std::complex<double> >& Psi,
  109. std::vector<std::complex<double> >& Zeta);
  110. void sbesjh(std::complex<double> z,
  111. std::vector<std::complex<double> >& jn, std::vector<std::complex<double> >& jnp,
  112. std::vector<std::complex<double> >& h1n, std::vector<std::complex<double> >& h1np);
  113. void calcPiTau(const double& costheta,
  114. std::vector<double>& Pi, std::vector<double>& Tau);
  115. void calcSpherHarm(const double Rho, const double Phi, const double Theta,
  116. const std::complex<double>& zn, const std::complex<double>& dzn,
  117. const double& Pi, const double& Tau, const double& n,
  118. std::vector<std::complex<double> >& Mo1n, std::vector<std::complex<double> >& Me1n,
  119. std::vector<std::complex<double> >& No1n, std::vector<std::complex<double> >& Ne1n);
  120. void ExternalScattCoeffs();
  121. void InternalScattCoeffs();
  122. void fieldExt(const double Rho, const double Phi, const double Theta,
  123. std::vector<std::complex<double> >& E, std::vector<std::complex<double> >& H);
  124. void calcField(const double Rho, const double Phi, const double Theta,
  125. std::vector<std::complex<double> >& E, std::vector<std::complex<double> >& H);
  126. bool isIntCoeffsCalc_ = false;
  127. bool isExtCoeffsCalc_ = false;
  128. bool isMieCalculated_ = false;
  129. // Size parameter for all layers
  130. std::vector<double> size_param_;
  131. // Refractive index for all layers
  132. std::vector< std::complex<double> > refractive_index_;
  133. // Scattering angles for scattering pattern in radians
  134. std::vector<double> theta_;
  135. // Should be -1 if there is no PEC.
  136. int PEC_layer_position_ = -1;
  137. // with calcNmax(int first_layer);
  138. int nmax_ = -1;
  139. int nmax_preset_ = -1;
  140. // Scattering coefficients
  141. std::vector<std::complex<double> > an_, bn_;
  142. std::vector< std::vector<double> > coords_;
  143. // TODO: check if l index is reversed will lead to performance
  144. // boost, if $a^(L+1)_n$ stored in aln_[n][0], $a^(L)_n$ in
  145. // aln_[n][1] and so on...
  146. // at the moment order is forward!
  147. std::vector< std::vector<std::complex<double> > > aln_, bln_, cln_, dln_;
  148. /// Store result
  149. double Qsca_ = 0.0, Qext_ = 0.0, Qabs_ = 0.0, Qbk_ = 0.0, Qpr_ = 0.0, asymmetry_factor_ = 0.0, albedo_ = 0.0;
  150. std::vector<std::vector< std::complex<double> > > E_, H_; // {X[], Y[], Z[]}
  151. std::vector<std::complex<double> > S1_, S2_;
  152. //Used constants
  153. const double PI_=3.14159265358979323846;
  154. // light speed [m s-1]
  155. double const cc_ = 2.99792458e8;
  156. // assume non-magnetic (MU=MU0=const) [N A-2]
  157. double const mu_ = 4.0*PI_*1.0e-7;
  158. //Temporary variables
  159. std::vector<std::complex<double> > PsiZeta_;
  160. }; // end of class MultiLayerMie
  161. } // end of namespace nmie