nmie.hpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. #ifndef SRC_NMIE_HPP_
  2. #define SRC_NMIE_HPP_
  3. //******************************************************************************
  4. // Copyright (C) 2009-2022 Ovidio Pena <ovidio@bytesfall.com>
  5. // Copyright (C) 2013-2022 Konstantin Ladutenko <kostyfisik@gmail.com>
  6. //
  7. // This file is part of scattnlay
  8. //
  9. // This program is free software: you can redistribute it and/or modify
  10. // it under the terms of the GNU General Public License as published by
  11. // the Free Software Foundation, either version 3 of the License, or
  12. // (at your option) any later version.
  13. //
  14. // This program is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. // GNU General Public License for more details.
  18. //
  19. // The only additional remark is that we expect that all publications
  20. // describing work using this software, or all commercial products
  21. // using it, cite at least one of the following references:
  22. // [1] O. Pena and U. Pal, "Scattering of electromagnetic radiation by
  23. // a multilayered sphere," Computer Physics Communications,
  24. // vol. 180, Nov. 2009, pp. 2348-2354.
  25. // [2] K. Ladutenko, U. Pal, A. Rivera, and O. Pena-Rodriguez, "Mie
  26. // calculation of electromagnetic near-field for a multilayered
  27. // sphere," Computer Physics Communications, vol. 214, May 2017,
  28. // pp. 225-230.
  29. //
  30. // You should have received a copy of the GNU General Public License
  31. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  32. //******************************************************************************
  33. #define VERSION "2.2" // Compare with Makefile and setup.py
  34. #include <array>
  35. #include <complex>
  36. #include <cstdlib>
  37. #include <iostream>
  38. #include <vector>
  39. #include "nmie-precision.hpp"
  40. //#ifdef MULTI_PRECISION
  41. //#include <boost/math/constants/constants.hpp>
  42. //#endif
  43. namespace nmie {
  44. //******************************************************************************
  45. int ScattCoeffs(const unsigned int L,
  46. const int pl,
  47. const std::vector<double>& x,
  48. const std::vector<std::complex<double>>& m,
  49. const int nmax,
  50. std::vector<std::complex<double>>& an,
  51. std::vector<std::complex<double>>& bn);
  52. int ExpanCoeffs(const unsigned int L,
  53. const int pl,
  54. const std::vector<double>& x,
  55. const std::vector<std::complex<double>>& m,
  56. const int nmax,
  57. std::vector<std::vector<std::complex<double>>>& an,
  58. std::vector<std::vector<std::complex<double>>>& bn,
  59. std::vector<std::vector<std::complex<double>>>& cn,
  60. std::vector<std::vector<std::complex<double>>>& dn);
  61. //******************************************************************************
  62. // helper functions
  63. //******************************************************************************
  64. template <typename FloatType>
  65. double eval_delta(const unsigned int steps,
  66. const double from_value,
  67. const double to_value);
  68. template <class T>
  69. inline T pow2(const T value) {
  70. return value * value;
  71. }
  72. template <class T>
  73. inline T cabs(const std::complex<T> value) {
  74. return sqrt_t(pow2(value.real()) + pow2(value.imag()));
  75. }
  76. template <class T>
  77. inline T vabs(const std::vector<std::complex<T>> value) {
  78. return nmm::sqrt(pow2(value[0].real()) + pow2(value[1].real()) +
  79. pow2(value[2].real()) + pow2(value[0].imag()) +
  80. pow2(value[1].imag()) + pow2(value[2].imag()));
  81. }
  82. template <typename FloatType>
  83. int newround(FloatType x) {
  84. return x >= 0 ? static_cast<int>(x + 0.5) : static_cast<int>(x - 0.5);
  85. // return x >= 0 ? (x + 0.5).convert_to<int>():(x - 0.5).convert_to<int>();
  86. }
  87. template <typename T>
  88. inline std::complex<T> my_exp(const std::complex<T>& x) {
  89. using std::exp; // use ADL
  90. T const& r = exp(x.real());
  91. return std::polar(r, x.imag());
  92. }
  93. //******************************************************************************
  94. // pl, nmax, mode_n, mode_type
  95. int nMie(const unsigned int L,
  96. const int pl,
  97. std::vector<double>& x,
  98. std::vector<std::complex<double>>& m,
  99. const unsigned int nTheta,
  100. std::vector<double>& Theta,
  101. const int nmax,
  102. double* Qext,
  103. double* Qsca,
  104. double* Qabs,
  105. double* Qbk,
  106. double* Qpr,
  107. double* g,
  108. double* Albedo,
  109. std::vector<std::complex<double>>& S1,
  110. std::vector<std::complex<double>>& S2,
  111. int mode_n,
  112. int mode_type);
  113. //******************************************************************************
  114. // pl and nmax
  115. int nMie(const unsigned int L,
  116. const int pl,
  117. std::vector<double>& x,
  118. std::vector<std::complex<double>>& m,
  119. const unsigned int nTheta,
  120. std::vector<double>& Theta,
  121. const int nmax,
  122. double* Qext,
  123. double* Qsca,
  124. double* Qabs,
  125. double* Qbk,
  126. double* Qpr,
  127. double* g,
  128. double* Albedo,
  129. std::vector<std::complex<double>>& S1,
  130. std::vector<std::complex<double>>& S2);
  131. //******************************************************************************
  132. // no pl and nmax
  133. int nMie(const unsigned int L,
  134. std::vector<double>& x,
  135. std::vector<std::complex<double>>& m,
  136. const unsigned int nTheta,
  137. std::vector<double>& Theta,
  138. double* Qext,
  139. double* Qsca,
  140. double* Qabs,
  141. double* Qbk,
  142. double* Qpr,
  143. double* g,
  144. double* Albedo,
  145. std::vector<std::complex<double>>& S1,
  146. std::vector<std::complex<double>>& S2);
  147. //******************************************************************************
  148. // pl
  149. int nMie(const unsigned int L,
  150. const int pl,
  151. std::vector<double>& x,
  152. std::vector<std::complex<double>>& m,
  153. const unsigned int nTheta,
  154. std::vector<double>& Theta,
  155. double* Qext,
  156. double* Qsca,
  157. double* Qabs,
  158. double* Qbk,
  159. double* Qpr,
  160. double* g,
  161. double* Albedo,
  162. std::vector<std::complex<double>>& S1,
  163. std::vector<std::complex<double>>& S2);
  164. //******************************************************************************
  165. // nmax
  166. int nMie(const unsigned int L,
  167. std::vector<double>& x,
  168. std::vector<std::complex<double>>& m,
  169. const unsigned int nTheta,
  170. std::vector<double>& Theta,
  171. const int nmax,
  172. double* Qext,
  173. double* Qsca,
  174. double* Qabs,
  175. double* Qbk,
  176. double* Qpr,
  177. double* g,
  178. double* Albedo,
  179. std::vector<std::complex<double>>& S1,
  180. std::vector<std::complex<double>>& S2);
  181. //******************************************************************************
  182. int nField(const unsigned int L,
  183. const int pl,
  184. const std::vector<double>& x,
  185. const std::vector<std::complex<double>>& m,
  186. const int nmax,
  187. const int mode_n,
  188. const int mode_type,
  189. const unsigned int ncoord,
  190. const std::vector<double>& Xp,
  191. const std::vector<double>& Yp,
  192. const std::vector<double>& Zp,
  193. std::vector<std::vector<std::complex<double>>>& E,
  194. std::vector<std::vector<std::complex<double>>>& H);
  195. //******************************************************************************
  196. // constants for per mode evaluation
  197. //******************************************************************************
  198. enum Modes { kAll = -1, kElectric = 0, kMagnetic = 1 };
  199. enum Planes { kEk = 0, kHk = 1, kEH = 2 };
  200. //******************************************************************************
  201. const FloatType PI_ =
  202. 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609433057270365759591953092186117381932611793105118548074462379962749567351885752724891227938183011949129833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901224953430146549585371050792279689258923542019956112129021960864034418159813629774771309960518707211349999998372978049951059731732816096318595024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303598253490428755468731159562863882353787593751957781857780532171226806613001927876611195909216420198938095257201065485863278865936153381827968230301952035301852968995773622599413891249721775283479131515574857242454150695950829533116861727855889075098381754637464939319255060400927701671139009848824012858361603563707660104710181942955596198946767837449448255379774726847104047534646208046684259069491293313677028989152104752162056966024058038150193511253382430035587640247496473263914199272604269922796782354781636009341721641219924586315030286182974555706749838505494588586926995690927210797509302955321165344987202755960236480665499119881834797753566369807426542527862551818417574672890977772793800081647060016145249192173217214772350141441973568548161361157352552133475741849468438523323907394143334547762416862518983569485562099219222184272550254256887671790494601653466804988627232791786085784383827967976681454100953883786360950680064225125205117392984896084128488626945604241965285022210661186306744278622039194945047123713786960956364371917287467764657573962413890865832645995813390478027590099465764078951269468398352595709825822620522489407726719478268482601476990902640136394437455305068203496252451749399651431429809190659250937221696461515709858387410597885959772975498930161753928468138268683868942774155991855925245953959431049972524680845987273644695848653836736222626099124608051243884390451244136549762780797715691435997700129616089441694868555848406353422072225828488648158456028506016842739452267467678895252138522549954666727823986456596116354886230577456498035593634568174324112515076069479451096596094025228879710893145669136867228748940560101503308;
  203. // light speed [m/s]
  204. const double cc_ = 2.99792458e8;
  205. // assume non-magnetic (MU=MU0=const) [N/A^2]
  206. const FloatType mu_ = 4.0 * PI_ * 1.0e-7;
  207. //******************************************************************************
  208. //******************************************************************************
  209. template <typename FloatType = double>
  210. class MultiLayerMie {
  211. public:
  212. #ifdef MULTI_PRECISION
  213. const FloatType convergence_threshold_ = std::pow(10, -MULTI_PRECISION / 2);
  214. // const FloatType convergence_threshold_ = 1e-50;
  215. // const FloatType nearfield_convergence_threshold_ = std::pow(10,
  216. // -MULTI_PRECISION/2);
  217. // For near-field evaluation we use Le Ru cutoff which is valid only for
  218. // double precision, so convergence threshold is the same
  219. const FloatType nearfield_convergence_threshold_ = 1e-14;
  220. #else
  221. const double convergence_threshold_ = 1e-25;
  222. const double nearfield_convergence_threshold_ = 1e-14;
  223. #endif
  224. void RunMieCalculation();
  225. void RunFieldCalculation(bool isMarkUnconverged = true);
  226. void RunFieldCalculationPolar(
  227. const int outer_arc_points = 1,
  228. const int radius_points = 1,
  229. const double from_Rho = 0,
  230. const double to_Rho = static_cast<double>(1.),
  231. const double from_Theta = 0,
  232. const double to_Theta = static_cast<double>(3.14159265358979323),
  233. const double from_Phi = 0,
  234. const double to_Phi = static_cast<double>(3.14159265358979323),
  235. const bool isMarkUnconverged = true,
  236. int nmax_in = -1);
  237. void RunFieldCalculationCartesian(const int first_side_points = 2,
  238. const int second_side_points = 2,
  239. const double relative_side_length = 2,
  240. const int plane_selected = Planes::kEk,
  241. const double at_x = 0,
  242. const double at_y = 0,
  243. const double at_z = 0,
  244. const bool isMarkUnconverged = true,
  245. const int nmax_in = -1);
  246. void calcScattCoeffs();
  247. void calcExpanCoeffs();
  248. //****************************************************************************
  249. // Return calculation results
  250. //****************************************************************************
  251. template <typename outputType = FloatType>
  252. outputType GetQext();
  253. template <typename outputType = FloatType>
  254. outputType GetQsca();
  255. template <typename outputType = FloatType>
  256. outputType GetQabs();
  257. template <typename outputType = FloatType>
  258. outputType GetQbk();
  259. template <typename outputType = FloatType>
  260. outputType GetQpr();
  261. template <typename outputType = FloatType>
  262. outputType GetAsymmetryFactor();
  263. template <typename outputType = FloatType>
  264. outputType GetAlbedo();
  265. std::vector<std::complex<FloatType>> GetS1();
  266. std::vector<std::complex<FloatType>> GetS2();
  267. std::vector<std::complex<FloatType>> GetAn() {
  268. return an_;
  269. };
  270. std::vector<std::complex<FloatType>> GetBn() {
  271. return bn_;
  272. };
  273. std::vector<std::vector<std::complex<FloatType>>> GetLayerAn() {
  274. return aln_;
  275. };
  276. std::vector<std::vector<std::complex<FloatType>>> GetLayerBn() {
  277. return bln_;
  278. };
  279. std::vector<std::vector<std::complex<FloatType>>> GetLayerCn() {
  280. return cln_;
  281. };
  282. std::vector<std::vector<std::complex<FloatType>>> GetLayerDn() {
  283. return dln_;
  284. };
  285. //****************************************************************************
  286. // Problem definition
  287. // Modify size of all layers
  288. //****************************************************************************
  289. void SetLayersSize(const std::vector<FloatType>& layer_size);
  290. // Modify refractive index of all layers
  291. void SetLayersIndex(const std::vector<std::complex<FloatType>>& index);
  292. template <typename evalType = FloatType>
  293. void GetIndexAtRadius(const evalType Rho,
  294. std::complex<evalType>& ml,
  295. unsigned int& l);
  296. template <typename evalType = FloatType>
  297. void GetIndexAtRadius(const evalType Rho, std::complex<evalType>& ml);
  298. // Modify scattering (theta) angles
  299. void SetAngles(const std::vector<FloatType>& angles);
  300. // Modify coordinates for field calculation
  301. void SetFieldCoords(const std::vector<std::vector<FloatType>>& coords);
  302. // Modify index of PEC layer
  303. void SetPECLayer(int layer_position = 0);
  304. // Modify the mode taking into account for evaluation of output variables
  305. void SetModeNmaxAndType(int mode_n, int mode_type) {
  306. mode_n_ = mode_n;
  307. mode_type_ = mode_type;
  308. };
  309. // Set a fixed value for the maximum number of terms
  310. void SetMaxTerms(int nmax);
  311. // Get maximum number of terms
  312. int GetMaxTerms() {
  313. return nmax_;
  314. };
  315. bool isMieCalculated() {
  316. return isMieCalculated_;
  317. };
  318. // Clear layer information
  319. void ClearLayers();
  320. void MarkUncalculated();
  321. // Read parameters
  322. // Get total size parameter of particle
  323. FloatType GetSizeParameter();
  324. // Returns size of all layers
  325. std::vector<FloatType> GetLayersSize() {
  326. return size_param_;
  327. };
  328. // Returns refractive index of all layers
  329. std::vector<std::complex<FloatType>> GetLayersIndex() {
  330. return refractive_index_;
  331. };
  332. // Returns scattering (theta) angles
  333. std::vector<FloatType> GetAngles() {
  334. return theta_;
  335. };
  336. // Returns coordinates used for field calculation
  337. std::vector<std::vector<FloatType>> GetFieldCoords() {
  338. return coords_;
  339. };
  340. // Returns index of PEC layer
  341. int GetPECLayer() {
  342. return PEC_layer_position_;
  343. };
  344. std::vector<std::vector<std::complex<FloatType>>> GetFieldE() {
  345. return E_;
  346. }; // {X[], Y[], Z[]}
  347. std::vector<std::vector<std::complex<FloatType>>> GetFieldH() {
  348. return H_;
  349. };
  350. std::vector<FloatType> GetFieldEabs() {
  351. return Eabs_;
  352. }; // {X[], Y[], Z[]}
  353. std::vector<FloatType> GetFieldHabs() {
  354. return Habs_;
  355. };
  356. bool GetFieldConvergence();
  357. // Get fields in spherical coordinates.
  358. std::vector<std::vector<std::complex<FloatType>>> GetFieldEs() {
  359. return Es_;
  360. }; // {rho[], theta[], phi[]}
  361. std::vector<std::vector<std::complex<FloatType>>> GetFieldHs() {
  362. return Hs_;
  363. };
  364. protected:
  365. // Size parameter for all layers
  366. std::vector<FloatType> size_param_;
  367. // Refractive index for all layers
  368. std::vector<std::complex<FloatType>> refractive_index_;
  369. // Scattering coefficients
  370. std::vector<std::complex<FloatType>> an_, bn_;
  371. std::vector<std::vector<std::complex<FloatType>>> aln_, bln_, cln_, dln_;
  372. // Points for field evaluation
  373. std::vector<std::vector<FloatType>> coords_;
  374. std::vector<std::vector<FloatType>> coords_polar_;
  375. private:
  376. unsigned int calcNstop(FloatType xL = -1);
  377. unsigned int calcNmax(FloatType xL = -1);
  378. std::complex<FloatType> calc_an(int n,
  379. FloatType XL,
  380. std::complex<FloatType> Ha,
  381. std::complex<FloatType> mL,
  382. std::complex<FloatType> PsiXL,
  383. std::complex<FloatType> ZetaXL,
  384. std::complex<FloatType> PsiXLM1,
  385. std::complex<FloatType> ZetaXLM1);
  386. std::complex<FloatType> calc_bn(int n,
  387. FloatType XL,
  388. std::complex<FloatType> Hb,
  389. std::complex<FloatType> mL,
  390. std::complex<FloatType> PsiXL,
  391. std::complex<FloatType> ZetaXL,
  392. std::complex<FloatType> PsiXLM1,
  393. std::complex<FloatType> ZetaXLM1);
  394. std::complex<FloatType> calc_S1(int n,
  395. std::complex<FloatType> an,
  396. std::complex<FloatType> bn,
  397. FloatType Pi,
  398. FloatType Tau);
  399. std::complex<FloatType> calc_S2(int n,
  400. std::complex<FloatType> an,
  401. std::complex<FloatType> bn,
  402. FloatType Pi,
  403. FloatType Tau);
  404. void calcD1D3(std::complex<FloatType> z,
  405. std::vector<std::complex<FloatType>>& D1,
  406. std::vector<std::complex<FloatType>>& D3);
  407. void calcPsiZeta(std::complex<FloatType> x,
  408. std::vector<std::complex<FloatType>>& Psi,
  409. std::vector<std::complex<FloatType>>& Zeta);
  410. void calcPiTau(const FloatType& costheta,
  411. std::vector<FloatType>& Pi,
  412. std::vector<FloatType>& Tau);
  413. template <typename evalType = FloatType>
  414. void calcSpherHarm(const std::complex<evalType> Rho,
  415. const evalType Theta,
  416. const evalType Phi,
  417. const std::complex<evalType>& rn,
  418. const std::complex<evalType>& Dn,
  419. const evalType& Pi,
  420. const evalType& Tau,
  421. const evalType& n,
  422. std::vector<std::complex<evalType>>& Mo1n,
  423. std::vector<std::complex<evalType>>& Me1n,
  424. std::vector<std::complex<evalType>>& No1n,
  425. std::vector<std::complex<evalType>>& Ne1n);
  426. template <typename evalType = FloatType>
  427. void calcFieldByComponents(const evalType Rho,
  428. const evalType Theta,
  429. const evalType Phi,
  430. const std::vector<std::complex<evalType>>& Psi,
  431. const std::vector<std::complex<evalType>>& D1n,
  432. const std::vector<std::complex<evalType>>& Zeta,
  433. const std::vector<std::complex<evalType>>& D3n,
  434. const std::vector<evalType>& Pi,
  435. const std::vector<evalType>& Tau,
  436. std::vector<std::complex<evalType>>& E,
  437. std::vector<std::complex<evalType>>& H,
  438. std::vector<bool>& isConvergedE,
  439. std::vector<bool>& isConvergedH,
  440. bool isMarkUnconverged);
  441. bool isExpCoeffsCalc_ = false;
  442. bool isScaCoeffsCalc_ = false;
  443. bool isMieCalculated_ = false;
  444. std::vector<bool> isConvergedE_ = {false, false, false};
  445. std::vector<bool> isConvergedH_ = {false, false, false};
  446. // Scattering angles for scattering pattern in radians
  447. std::vector<FloatType> theta_;
  448. // Should be -1 if there is no PEC.
  449. int PEC_layer_position_ = -1;
  450. int mode_n_ = Modes::kAll;
  451. int mode_type_ = Modes::kAll;
  452. // with calcNmax(int first_layer);
  453. int nmax_ = -1;
  454. int nmax_preset_ = -1;
  455. int available_maximal_nmax_ = -1;
  456. // Store result
  457. FloatType Qsca_ = 0.0, Qext_ = 0.0, Qabs_ = 0.0, Qbk_ = 0.0, Qpr_ = 0.0,
  458. asymmetry_factor_ = 0.0, albedo_ = 0.0;
  459. // {X[], Y[], Z[]}
  460. std::vector<std::vector<std::complex<FloatType>>> E_, H_;
  461. std::vector<std::vector<std::complex<FloatType>>> Es_, Hs_;
  462. std::vector<FloatType> Eabs_, Habs_;
  463. std::vector<std::complex<FloatType>> S1_, S2_;
  464. void calcMieSeriesNeededToConverge(const FloatType Rho, int nmax_in = -1);
  465. void calcPiTauAllTheta(const double from_Theta,
  466. const double to_Theta,
  467. std::vector<std::vector<FloatType>>& Pi,
  468. std::vector<std::vector<FloatType>>& Tau);
  469. void calcRadialOnlyDependantFunctions(
  470. const double from_Rho,
  471. const double to_Rho,
  472. std::vector<std::vector<std::complex<FloatType>>>& Psi,
  473. std::vector<std::vector<std::complex<FloatType>>>& D1n,
  474. std::vector<std::vector<std::complex<FloatType>>>& Zeta,
  475. std::vector<std::vector<std::complex<FloatType>>>& D3n,
  476. int nmax_in = -1);
  477. void convertFieldsFromSphericalToCartesian();
  478. void UpdateConvergenceStatus(std::vector<bool> isConvergedE,
  479. std::vector<bool> isConvergedH);
  480. }; // end of class MultiLayerMie
  481. //******************************************************************************
  482. //******************************************************************************
  483. template <typename FloatType = double>
  484. class MesoMie {
  485. public:
  486. std::vector<std::complex<FloatType>> an_, bn_;
  487. FloatType x_;
  488. std::complex<FloatType> m_;
  489. std::vector<std::complex<FloatType>> GetAn() { return an_; };
  490. std::vector<std::complex<FloatType>> GetBn() { return bn_; };
  491. FloatType Qsca_ = 0.0, Qext_ = 0.0;
  492. template <typename outputType = FloatType>
  493. outputType GetQsca() {
  494. return static_cast<outputType>(Qsca_);
  495. }
  496. template <typename outputType = FloatType>
  497. outputType GetQext() {
  498. return static_cast<outputType>(Qext_);
  499. }
  500. void calc_ab(FloatType R,
  501. FloatType xd,
  502. std::complex<FloatType> xm,
  503. std::complex<FloatType> eps_d,
  504. std::complex<FloatType> eps_m,
  505. std::complex<FloatType> d_parallel,
  506. std::complex<FloatType> d_perp);
  507. void calc_Q();
  508. // template <typename outputType = FloatType>
  509. // outputType GetQext();
  510. // template <typename outputType = FloatType>
  511. // outputType GetQsca();
  512. }; // end of class MesoMie
  513. } // end of namespace nmie
  514. #endif // SRC_NMIE_HPP_