nmie.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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. using namespace std;
  34. namespace nmie {
  35. int ScattCoeffs(const unsigned int L, const int pl, vector<double>& x, vector<complex<double> >& m, const int nmax, vector<complex<double> >& an, vector<complex<double> >& bn);
  36. int nMie(const unsigned int L, const int pl, vector<double>& x, vector<complex<double> >& m, const unsigned int nTheta, vector<double>& Theta, const int nmax, double *Qext, double *Qsca, double *Qabs, double *Qbk, double *Qpr, double *g, double *Albedo, vector<complex<double> >& S1, vector<complex<double> >& S2);
  37. int nMie(const unsigned int L, vector<double>& x, vector<complex<double> >& m, const unsigned int nTheta, vector<double>& Theta, double *Qext, double *Qsca, double *Qabs, double *Qbk, double *Qpr, double *g, double *Albedo, vector<complex<double> >& S1, vector<complex<double> >& S2);
  38. int nMie(const unsigned int L, const int pl, vector<double>& x, vector<complex<double> >& m, const unsigned int nTheta, vector<double>& Theta, double *Qext, double *Qsca, double *Qabs, double *Qbk, double *Qpr, double *g, double *Albedo, vector<complex<double> >& S1, vector<complex<double> >& S2);
  39. int nMie(const unsigned int L, vector<double>& x, vector<complex<double> >& m, const unsigned int nTheta, vector<double>& Theta, const int nmax, double *Qext, double *Qsca, double *Qabs, double *Qbk, double *Qpr, double *g, double *Albedo, vector<complex<double> >& S1, vector<complex<double> >& S2);
  40. int nField(const unsigned int L, const int pl, const vector<double>& x, const vector<complex<double> >& m, const int nmax, const unsigned int ncoord, const vector<double>& Xp, const vector<double>& Yp, const vector<double>& Zp, vector<vector<complex<double> > >& E, vector<vector<complex<double> > >& H);
  41. class MultiLayerMie {
  42. public:
  43. // Run calculation
  44. void RunMieCalculation();
  45. void RunFieldCalculation();
  46. void calcScattCoeffs();
  47. // Return calculation results
  48. double GetQext();
  49. double GetQsca();
  50. double GetQabs();
  51. double GetQbk();
  52. double GetQpr();
  53. double GetAsymmetryFactor();
  54. double GetAlbedo();
  55. vector<complex<double> > GetS1();
  56. vector<complex<double> > GetS2();
  57. vector<complex<double> > GetAn(){return an_;};
  58. vector<complex<double> > GetBn(){return bn_;};
  59. // Problem definition
  60. // Add new layer
  61. void AddNewLayer(double layer_size, complex<double> layer_index);
  62. // Modify width of the layer
  63. void SetLayerSize(vector<double> layer_size, int layer_position = 0);
  64. // Modify refractive index of the layer
  65. void SetLayerIndex(vector< complex<double> > layer_index, int layer_position = 0);
  66. // Modify size of all layers
  67. void SetAllLayersSize(const vector<double>& layer_size);
  68. // Modify refractive index of all layers
  69. void SetAllLayersIndex(const vector< complex<double> >& index);
  70. // Modify scattering (theta) angles
  71. void SetAngles(const vector<double>& angles);
  72. // Modify coordinates for field calculation
  73. void SetFieldCoords(const vector< vector<double> >& coords);
  74. // Modify PEC layer
  75. void SetPECLayer(int layer_position = 0);
  76. // Set a fixed value for the maximun number of terms
  77. void SetMaxTerms(int nmax);
  78. // Get maximun number of terms
  79. int GetMaxTerms() {return nmax_;};
  80. // Clear layer information
  81. void ClearLayers();
  82. // Applied units requests
  83. double GetSizeParameter();
  84. double GetLayerWidth(int layer_position = 0);
  85. vector<double> GetLayersSize();
  86. vector<complex<double> > GetLayersIndex();
  87. vector<array<double, 3> > GetFieldCoords();
  88. vector<vector< complex<double> > > GetFieldE(){return E_;}; // {X[], Y[], Z[]}
  89. vector<vector< complex<double> > > GetFieldH(){return H_;};
  90. private:
  91. void calcNstop();
  92. void calcNmax(unsigned int first_layer);
  93. complex<double> calc_an(int n, double XL, complex<double> Ha, complex<double> mL,
  94. complex<double> PsiXL, complex<double> ZetaXL,
  95. complex<double> PsiXLM1, complex<double> ZetaXLM1);
  96. complex<double> calc_bn(int n, double XL, complex<double> Hb, complex<double> mL,
  97. complex<double> PsiXL, complex<double> ZetaXL,
  98. complex<double> PsiXLM1, complex<double> ZetaXLM1);
  99. complex<double> calc_S1(int n, complex<double> an, complex<double> bn,
  100. double Pi, double Tau);
  101. complex<double> calc_S2(int n, complex<double> an, complex<double> bn,
  102. double Pi, double Tau);
  103. void calcD1D3(complex<double> z,
  104. vector<complex<double> >& D1,
  105. vector<complex<double> >& D3);
  106. void calcPsiZeta(complex<double> x,
  107. vector<complex<double> >& Psi,
  108. vector<complex<double> >& Zeta);
  109. void calcPiTau(const double& costheta,
  110. vector<double>& Pi, vector<double>& Tau);
  111. void calcSpherHarm(const complex<double> Rho, const double Theta, const double Phi,
  112. const complex<double>& rn, const complex<double>& Dn,
  113. const double& Pi, const double& Tau, const double& n,
  114. vector<complex<double> >& Mo1n, vector<complex<double> >& Me1n,
  115. vector<complex<double> >& No1n, vector<complex<double> >& Ne1n);
  116. void calcExpanCoeffs();
  117. void calcField(const double Rho, const double Theta, const double Phi,
  118. vector<complex<double> >& E, vector<complex<double> >& H);
  119. bool isExpCoeffsCalc_ = false;
  120. bool isScaCoeffsCalc_ = false;
  121. bool isMieCalculated_ = false;
  122. // Size parameter for all layers
  123. vector<double> size_param_;
  124. // Refractive index for all layers
  125. vector< complex<double> > refractive_index_;
  126. // Scattering angles for scattering pattern in radians
  127. vector<double> theta_;
  128. // Should be -1 if there is no PEC.
  129. int PEC_layer_position_ = -1;
  130. // with calcNmax(int first_layer);
  131. int nmax_ = -1;
  132. int nmax_preset_ = -1;
  133. // Scattering coefficients
  134. vector<complex<double> > an_, bn_;
  135. vector< vector<double> > coords_;
  136. // TODO: check if l index is reversed will lead to performance
  137. // boost, if $a^(L+1)_n$ stored in aln_[n][0], $a^(L)_n$ in
  138. // aln_[n][1] and so on...
  139. // at the moment order is forward!
  140. vector< vector<complex<double> > > aln_, bln_, cln_, dln_;
  141. /// Store result
  142. double Qsca_ = 0.0, Qext_ = 0.0, Qabs_ = 0.0, Qbk_ = 0.0, Qpr_ = 0.0, asymmetry_factor_ = 0.0, albedo_ = 0.0;
  143. vector<vector< complex<double> > > E_, H_; // {X[], Y[], Z[]}
  144. vector<complex<double> > S1_, S2_;
  145. //Used constants
  146. const double PI_=3.14159265358979323846;
  147. // light speed [m s-1]
  148. double const cc_ = 2.99792458e8;
  149. // assume non-magnetic (MU=MU0=const) [N A-2]
  150. double const mu_ = 4.0*PI_*1.0e-7;
  151. //Temporary variables
  152. vector<complex<double> > PsiZeta_;
  153. }; // end of class MultiLayerMie
  154. } // end of namespace nmie