superdirectivity.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #ifndef _SUPERDIRECTIVITY_H
  2. #define _SUPERDIRECTIVITY_H
  3. #include <complex>
  4. #include <vector>
  5. #include <iostream>
  6. #include "sph_bessel.h"
  7. #define _USE_MATH_DEFINES
  8. #include <cmath>
  9. Real get_directivity_sphml_dZx_epsRe(std::vector<Real> &param, void *cls);
  10. Real get_directivity_sphml_dZx_epsRe_parallel(std::vector<Real> &param, void *cls);
  11. const int _degree = 15;
  12. class sphere_ml {
  13. public:
  14. sphere_ml() {
  15. deg_max = _degree;
  16. ampl_in = new Complex [4*deg_max];
  17. ampl_out = new Complex [4*deg_max];
  18. rt = new Complex [8*deg_max];
  19. rtml_in = new Complex [8*deg_max];
  20. rtml_out = new Complex [8*deg_max];
  21. pi1 = new Real [deg_max];
  22. tau0 = new Real [deg_max];
  23. tau1 = new Real [deg_max];
  24. theta = phi = Real(0);
  25. set_directivity_angles(theta, phi);
  26. }
  27. sphere_ml(int deg_max_) {
  28. deg_max = deg_max_;
  29. ampl_in = new Complex [4*deg_max];
  30. ampl_out = new Complex [4*deg_max];
  31. rt = new Complex [8*deg_max];
  32. rtml_in = new Complex [8*deg_max];
  33. rtml_out = new Complex [8*deg_max];
  34. pi1 = new Real [deg_max];
  35. tau0 = new Real [deg_max];
  36. tau1 = new Real [deg_max];
  37. theta = phi = Real(0);
  38. set_directivity_angles(theta, phi);
  39. }
  40. sphere_ml(const sphere_ml &sphml) {
  41. delete [] ampl_in; delete [] ampl_out;
  42. delete [] rt; delete [] rtml_in; delete [] rtml_out;
  43. delete [] pi1; delete [] tau0; delete [] tau1;
  44. deg_max = sphml.deg_max;
  45. ampl_in = new Complex [4*deg_max];
  46. ampl_out = new Complex [4*deg_max];
  47. rt = new Complex [8*deg_max];
  48. rtml_in = new Complex [8*deg_max];
  49. rtml_out = new Complex [8*deg_max];
  50. pi1 = new Real [deg_max];
  51. tau0 = new Real [deg_max];
  52. tau1 = new Real [deg_max];
  53. theta = sphml.theta; phi = sphml.phi;
  54. set_directivity_angles(theta, phi);
  55. }
  56. ~sphere_ml() {
  57. delete [] ampl_in; delete [] ampl_out;
  58. delete [] rt; delete [] rtml_in; delete [] rtml_out;
  59. delete [] pi1; delete [] tau0; delete [] tau1;
  60. }
  61. int get_degree() const {return deg_max;}
  62. // pre-define direction in which the directivity should be evaluated (0,0 by default)
  63. void set_directivity_angles(Real theta, Real phi);
  64. // return directivity for an electric dipole placed at -kzd on axis Z
  65. // in the presence of a spherical multilayer: kR - vector of radii of
  66. // spherical interfaces; eps - vector of permittivities (should be one element larger than kR)
  67. Real get_directivity_edipole_x(Real kzd, const std::vector<Real> &kR, const std::vector<Complex> &eps);
  68. // return the amplitudes of the emitted waves, which were calculated at the last directivity evaluation
  69. std::vector<Complex> get_last_ampl() const;
  70. // calculate the radiation pattern
  71. std::vector<Complex> ampl_far(Real th_rad, Real ph_rad);
  72. private:
  73. int deg_max; // maximum degree of spherical hamonics
  74. Real theta, phi; // directivity angles
  75. Real *pi1, *tau0, *tau1; // angular function arrays
  76. Complex *ampl_in, *ampl_out; // amplitude arrays
  77. Complex *rt, *rtml_in, *rtml_out; // s-matrix coefficient arrays
  78. // electric dipole is located at (-kz) and has amplitude 1 along x:
  79. void get_edipole_amp_x(Complex kz, Complex *ampl, bool in);
  80. // elextric dipole is located at (-kz) and has amplitude 1 along z:
  81. void get_edipole_amp_z(Complex kz, Complex *ampl, bool in);
  82. // elextric dipole is located at (-kz) and has amplitude 1 directed at angle th relative to z:
  83. void get_edipole_amp_xz(Complex kz, Complex *ampl, Real th, bool in);
  84. // reflection and transmission coefficients at spherical interface
  85. void sphere_sm(Real kr, Complex eps_in, Complex eps_out, Complex *res);
  86. // T-matrix of a spherical interface
  87. void sphere_tm(Real kr, Complex eps_in, Complex eps_out, Complex *res);
  88. // composition of S-matrices
  89. void compose_sm(Complex *in, Complex *out, Complex *res);
  90. // composition of T-matrices
  91. void compose_tm(Complex *in, Complex *out, Complex *res);
  92. // directivity of a dipole located at axiz Z
  93. Real directivity_dipole_z(Complex *ampl) const;
  94. };
  95. //#################################################################################
  96. // class for parallel calculation:
  97. class sphere_ml_parallel {
  98. public:
  99. sphere_ml_parallel() {
  100. deg_max = _degree;
  101. pi1 = new Real [_degree];
  102. tau0 = new Real [_degree];
  103. tau1 = new Real [_degree];
  104. theta = phi = Real(0);
  105. set_directivity_angles(theta, phi);
  106. }
  107. int get_degree() const {return deg_max;}
  108. // pre-define direction in which the directivity should be evaluated (0,0 by default)
  109. void set_directivity_angles(Real theta, Real phi);
  110. // return directivity for an electric dipole placed at -kzd on axis Z
  111. // in the presence of a spherical multilayer: kR - vector of radii of
  112. // spherical interfaces; eps - vector of permittivities (should be one element larger than kR)
  113. Real get_directivity_edipole_x(Real kzd, const std::vector<Real> &kR, const std::vector<Complex> &eps);
  114. private:
  115. int deg_max; // maximum degree of spherical hamonics
  116. Real theta, phi; // directivity angles
  117. Real *pi1, *tau0, *tau1; // angular function arrays
  118. // electric dipole is located at (-kz) and has amplitude 1 along x:
  119. void get_edipole_amp_x(Complex kz, Complex *ampl, bool in);
  120. // elextric dipole is located at (-kz) and has amplitude 1 along z:
  121. // reflection and transmission coefficients at spherical interface
  122. void sphere_sm(Real kr, Complex eps_in, Complex eps_out, Complex *res);
  123. // composition of S-matrices
  124. void compose_sm(Complex *in, Complex *out, Complex *res);
  125. // directivity of a dipole located at axiz Z
  126. Real directivity_dipole_z(Complex *ampl) const;
  127. };
  128. #endif // _SUPERDIRECTIVITY_H