Lemma is an Electromagnetics API
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

hankeltransformhankel2.h 8.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /* This file is part of Lemma, a geophysical modelling and inversion API */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. /**
  6. @file
  7. @author Trevor Irons
  8. @date 06/26/2009
  9. @version $Id: hankeltransformhankel2.h 201 2015-01-03 00:07:47Z tirons $
  10. **/
  11. #ifndef __HANKEL2_H
  12. #define __HANKEL2_H
  13. #include "hankeltransform.h"
  14. #include "kernelem1dbase.h"
  15. #include "kernelem1dspec.h"
  16. #include "CubicSplineInterpolator.h"
  17. namespace Lemma {
  18. // ==========================================================================
  19. // Class: Hankel2
  20. /** \brief Computes the Hankel transform of orders 0 and 1 using lagged
  21. and related convolutions.
  22. \details A rewrite of work by Anderson who wrote a FORTRAN program
  23. that he released while working at the USGS.
  24. The transform evaluates an integral of the form:
  25. \f[ \int_0^\infty K(\lambda) J_I (\lambda r) ~ d \lambda
  26. \f]
  27. Where \f$ K(\lambda) \f$ is some kernel function. The value
  28. \f$ J_I \f$ is the Bessel function of order
  29. \f$I, I \in \{0,1\} \f$
  30. The kernel function is unique for each source and is computed
  31. in the class CalculateKernel. The value \f$r\f$ is the radial
  32. distance away from the centre of the grid \f$ r=\sqrt{x^2 + y^2} \f$
  33. The Hankel transform is useful as it allows a double fourier
  34. transform to be written as a single integral:
  35. \f[ \mathop {\int \!\!\! \int}_{\!\!\!\!\!-\infty}^{\,\,\infty}
  36. F(k_x^2 + k_y^2)
  37. e^{\imath (k_x x + k_y y)} dk_x \, dk_y = 2 \pi
  38. \int_0^\infty K(\lambda) J_I (\lambda r) ~ d \lambda
  39. \f]
  40. This can only be done where there is radial symmetry. Hence
  41. its application to 1D solutions here.
  42. */
  43. // ==========================================================================
  44. class Hankel2 : public HankelTransform {
  45. friend std::ostream &operator<<(std::ostream &stream, const Hankel2 &ob);
  46. public:
  47. // ==================== LIFECYCLE ==============================
  48. /**
  49. * Returns pointer to new Hankel2. Location is
  50. * initialized to (0,0,0) type and polarization are
  51. * initialized to nonworking values that will throw
  52. * exceptions if used.
  53. */
  54. static Hankel2 *New();
  55. /**
  56. * @copybrief LemmaObject::Delete()
  57. * @copydetails LemmaObject::Delete()
  58. */
  59. void Delete();
  60. // ==================== OPERATORS ==============================
  61. // ==================== OPERATIONS ==============================
  62. /// Sets the number of convolutions
  63. void SetNumConv(const int &i);
  64. /// Computes the hankel transform with arguments
  65. /// @param rho [input] rho is the hankel transform argument
  66. /// @param ntol [input] ntol is
  67. /// @param tol [input] tol is
  68. void Compute(const Real &rho, const int& ntol, const Real &tol);
  69. /// Computes the related
  70. void ComputeRelated(const Real &rho, KernelEm1DBase* Kernel);
  71. /// Computes the related
  72. void ComputeRelated(const Real &rho, std::vector< KernelEm1DBase* > KernelVec);
  73. /// Computes the related
  74. void ComputeRelated(const Real &rho, KernelEM1DManager* Manager);
  75. /// Computes the related and lagged convolutions
  76. void ComputeLaggedRelated(const Real &rho, const int& nlag, KernelEM1DManager* Manager);
  77. // ==================== ACCESS ==============================
  78. /// Returns the answer
  79. Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic> GetAnswer();
  80. /// Returns the arguments for lagged convolutions
  81. VectorXr GetArg() {return Arg;};
  82. /// Returns the value of Abscissa stepping
  83. Real GetABSER( ) { return ABSER; };
  84. /// Sets the lagged kernel index so that the proper value is returned
  85. void SetLaggedArg(const Real& rho);
  86. // ==================== INQUIRY ==============================
  87. /// Calculates Hankel Transform using filtering.
  88. /// ikk: type of kernel depending on source and receiver couple
  89. /// imode: a switch for TE(0) and TM(1) mode
  90. /// itype: order of Bessel function
  91. /// rho is argument to integral
  92. /// wavef is the propogation constant of free space
  93. /// = omega * sqrt( EP*AMU ) amu = 4 pi e-7 ep = 8.85e-12
  94. Complex Zgauss(const int &ikk, const EMMODE &imode,
  95. const int &itype, const Real &rho,
  96. const Real &wavef, KernelEm1DBase *Kernel);
  97. protected:
  98. // ==================== LIFECYCLE ==============================
  99. /** A rewrite of Anderson's Pseudo-subroutine. */
  100. inline void StoreRetreive(const int &idx, const int &lag,
  101. Complex &Zsum, const int &irel, Complex &C, const Real& rho0) {
  102. int look = idx+lag;
  103. int iq = look/801;
  104. int ir = look%801;
  105. int iroll = iq*800;
  106. if(this->Key[ir] <= iroll) {
  107. this->Key[ir] = iroll + ir;
  108. ++this->NumFun;
  109. Manager->ComputeReflectionCoeffs(this->Lambda, idx, rho0);
  110. for (unsigned int ir2=0; ir2<this->kernelVec.size(); ++ir2) {
  111. this->Zwork(ir, ir2) = this->kernelVec[ir2]->RelBesselArg(this->Lambda);
  112. }
  113. }
  114. C = this->Zwork(ir, irel) * this->FilterWeights(this->BesselOrder, idx);
  115. Zsum += C;
  116. return;
  117. }
  118. /// Default protected constructor
  119. Hankel2(const std::string& name);
  120. /// Default protected destructor
  121. ~Hankel2();
  122. /**
  123. * @copybrief LemmaObject::Release()
  124. * @copydetails LemmaObject::Release()
  125. */
  126. void Release();
  127. // ==================== OPERATIONS ==============================
  128. void DeleteSplines();
  129. // ==================== DATA MEMBERS ==============================
  130. /// The hankel transform wavenumber embedded in the integral
  131. Real Lambda;
  132. /// Number of times a kernel was evaluated
  133. int NumFun;
  134. /// Number of lagged convolutions
  135. /// must be greater or equal to 1
  136. /// It is set automatically in the @see Compute function so
  137. /// that \f$ \rho \exp\left( -.1*(\mathtt{NumConv} -1) \right) \f$
  138. /// does not underflow the exponent range
  139. int NumConv;
  140. /// Number of related kernels
  141. int NumRel;
  142. /** Bessel transform order to use */
  143. int BesselOrder;
  144. /** Lag argument */
  145. int iLag;
  146. /* Should results be cached? Useful for repeated calculations of few receiver points */
  147. // turned out to have only marginal benefits in best case, and awful consequences in many
  148. //bool cacheResults;
  149. /** Related Kernel Manager */
  150. KernelEM1DManager* Manager;
  151. /// Used as base for filter abscissa generation
  152. static const Real ABSCISSA;
  153. /// Also used in abscissa generation \f$ ABSE = \exp{.1} \f$
  154. static const Real ABSE;
  155. /// Also used in abscissa generation \f$ ABSER = 1 / \exp{.1} \f$
  156. static const Real ABSER;
  157. /// Counter for calculated
  158. int icount;
  159. /// Kernel Calculator
  160. std::vector <KernelEm1DBase*> kernelVec;
  161. /// Spines for lagged convolutions (real part)
  162. std::vector <CubicSplineInterpolator*> splineVecReal;
  163. /// Spines for lagged convolutions (imaginary part)
  164. std::vector <CubicSplineInterpolator*> splineVecImag;
  165. /// Key used internally
  166. Eigen::Matrix<int, 801, 1> Key;
  167. //int Key[801];
  168. //Eigen::Matrix<int, Eigen::Dynamic, 1> Key;
  169. /// Filter weight coefficients. Set for either \f$J_0\f$ or \f$J_1\f$
  170. /// internally by protected function SetFilterWeights.
  171. /// Fixed sized will yield better performance. (not necessarily)
  172. //Eigen::Matrix<Real, 801, 1> FilterWeights;
  173. static const Eigen::Matrix<Real, 2, 801> FilterWeights;
  174. //static const Eigen::Matrix<Real, Eigen::Dynamic, Eigen::Dynamic> FilterWeights;
  175. /// Zwork from Anderson
  176. Eigen::Matrix<Complex, 801, Eigen::Dynamic> Zwork;
  177. //Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic> Zwork;
  178. /// Holds answer, dimensions are NumConv, and NumberRelated.
  179. Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic> Zans;
  180. /// Holds the arguments for lagged convolutions
  181. VectorXr Arg;
  182. }; // ----- end of class HankelTransform -----
  183. }
  184. #endif // __HANKEL2_h