Main Lemma Repository
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  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 __FHTANDERSON801_H
  12. #define __FHTANDERSON801_H
  13. #include "KernelEM1DBase.h"
  14. #include "KernelEM1DSpec.h"
  15. #include "CubicSplineInterpolator.h"
  16. #include "HankelTransform.h"
  17. namespace Lemma {
  18. // ==========================================================================
  19. // Class: FHTAnderson801
  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. Anderson, W. L., 1989, A hybrid fast hankel transform algorithm for
  25. electromagnetic modeling: Geophysics, 54, 263-266.
  26. This function does not provide the Hybrid functionality however, merely the
  27. digital filter implimentation.
  28. The transform evaluates an integral of the form:
  29. \f[ \int_0^\infty K(\lambda) J_I (\lambda r) ~ d \lambda
  30. \f]
  31. Where \f$ K(\lambda) \f$ is some kernel function. The value
  32. \f$ J_I \f$ is the Bessel function of order
  33. \f$I, I \in \{0,1\} \f$
  34. The kernel function is unique for each source and is computed
  35. in the class CalculateKernel. The value \f$r\f$ is the radial
  36. distance away from the centre of the grid \f$ r=\sqrt{x^2 + y^2} \f$
  37. The Hankel transform is useful as it allows a double fourier
  38. transform to be written as a single integral:
  39. \f[ \mathop {\int \!\!\! \int}_{\!\!\!\!\!-\infty}^{\,\,\infty}
  40. F(k_x^2 + k_y^2)
  41. e^{\imath (k_x x + k_y y)} dk_x \, dk_y = 2 \pi
  42. \int_0^\infty K(\lambda) J_I (\lambda r) ~ d \lambda
  43. \f]
  44. This can only be done where there is radial symmetry. Hence
  45. its application to 1D solutions here.
  46. \note In previous versions of Lemma, this class was called HankelTransformHankel2,
  47. which more closely follows Anderson's procedural routine names, but was non-descriptive
  48. regarding where the algorithm is derived from.
  49. */
  50. // ==========================================================================
  51. class FHTAnderson801 : public HankelTransform {
  52. friend std::ostream &operator<<(std::ostream &stream, const FHTAnderson801 &ob);
  53. public:
  54. // ==================== LIFECYCLE ==============================
  55. /**
  56. * Returns shared_ptr to new FHTAnderson801.
  57. */
  58. static std::shared_ptr<FHTAnderson801> NewSP();
  59. /**
  60. * Returns unique_ptr to new FHTAnderson801.
  61. */
  62. static std::unique_ptr<FHTAnderson801> NewUP();
  63. /// Default locked constructor
  64. FHTAnderson801( const ctor_key& );
  65. /** Locked deserializing constructor. */
  66. FHTAnderson801 ( const YAML::Node& node, const ctor_key& );
  67. /// Default destructor
  68. ~FHTAnderson801();
  69. /**
  70. * YAML Serializing method
  71. */
  72. YAML::Node Serialize() const;
  73. /**
  74. * Constructs an object from a YAML::Node.
  75. */
  76. static std::shared_ptr< FHTAnderson801 > DeSerialize(const YAML::Node& node);
  77. // ==================== OPERATORS ==============================
  78. // ==================== OPERATIONS ==============================
  79. /// Sets the number of convolutions
  80. void SetNumConv(const int &i);
  81. /// Computes the hankel transform with arguments
  82. /// @param rho [input] rho is the hankel transform argument
  83. /// @param ntol [input] ntol is
  84. /// @param tol [input] tol is
  85. void Compute(const Real &rho, const int& ntol, const Real &tol);
  86. /// Computes the related
  87. void ComputeRelated(const Real &rho, std::shared_ptr<KernelEM1DBase> Kernel);
  88. /// Computes the related
  89. void ComputeRelated(const Real &rho, std::vector< std::shared_ptr<KernelEM1DBase> > KernelVec);
  90. /// Computes the related
  91. void ComputeRelated(const Real &rho, std::shared_ptr<KernelEM1DManager> Manager);
  92. /// Computes the related and lagged convolutions
  93. void ComputeLaggedRelated(const Real &rho, const int& nlag, std::shared_ptr<KernelEM1DManager> Manager);
  94. // ==================== ACCESS ==============================
  95. /// Returns the answer
  96. Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic> GetAnswer();
  97. /// Returns the arguments for lagged convolutions
  98. VectorXr GetArg() {return Arg;};
  99. /// Returns the value of Abscissa stepping
  100. Real GetABSER( ) { return ABSER; };
  101. /// Sets the lagged kernel index so that the proper value is returned
  102. void SetLaggedArg(const Real& rho);
  103. // ==================== INQUIRY ==============================
  104. /// Calculates Hankel Transform using filtering.
  105. /// ikk: type of kernel depending on source and receiver couple
  106. /// imode: a switch for TE(0) and TM(1) mode
  107. /// itype: order of Bessel function
  108. /// rho is argument to integral
  109. /// wavef is the propogation constant of free space
  110. /// = omega * sqrt( EP*AMU ) amu = 4 pi e-7 ep = 8.85e-12
  111. Complex Zgauss(const int &ikk, const EMMODE &imode,
  112. const int &itype, const Real &rho,
  113. const Real &wavef, KernelEM1DBase* Kernel);
  114. /** Returns the name of the underlying class, similiar to Python's type */
  115. virtual inline std::string GetName() const;
  116. protected:
  117. private:
  118. // ==================== LIFECYCLE ==============================
  119. /** A rewrite of Anderson's "Pseudo-subroutine" computed GOTO madness. */
  120. inline void StoreRetreive(const int &idx, const int &lag,
  121. Complex &Zsum, const int &irel, Complex &C, const Real& rho0) {
  122. int look = idx+lag;
  123. int iq = look/801;
  124. int ir = look%801;
  125. int iroll = iq*800;
  126. if(this->Key[ir] <= iroll) {
  127. this->Key[ir] = iroll + ir;
  128. ++this->NumFun;
  129. Manager->ComputeReflectionCoeffs(this->Lambda, idx, rho0);
  130. for (unsigned int ir2=0; ir2<this->kernelVec.size(); ++ir2) {
  131. this->Zwork(ir, ir2) = this->kernelVec[ir2]->RelBesselArg(this->Lambda);
  132. }
  133. }
  134. C = this->Zwork(ir, irel) * this->FilterWeights(this->BesselOrder, idx);
  135. Zsum += C;
  136. return;
  137. }
  138. // ==================== OPERATIONS ==============================
  139. void DeleteSplines();
  140. // ==================== DATA MEMBERS ==============================
  141. /// The hankel transform wavenumber embedded in the integral
  142. Real Lambda;
  143. /// Number of times a kernel was evaluated
  144. int NumFun;
  145. /// Number of lagged convolutions
  146. /// must be greater or equal to 1
  147. /// It is set automatically in the @see Compute function so
  148. /// that \f$ \rho \exp\left( -.1*(\mathtt{NumConv} -1) \right) \f$
  149. /// does not underflow the exponent range
  150. int NumConv;
  151. /// Number of related kernels
  152. int NumRel;
  153. /** Bessel transform order to use */
  154. int BesselOrder;
  155. /** Lag argument */
  156. int iLag;
  157. /* Should results be cached? Useful for repeated calculations of few receiver points */
  158. // turned out to have only marginal benefits in best case, and awful consequences in many
  159. //bool cacheResults;
  160. /** Related Kernel Manager */
  161. std::shared_ptr<KernelEM1DManager> Manager;
  162. /// Used as base for filter abscissa generation
  163. static const Real ABSCISSA;
  164. /// Also used in abscissa generation \f$ ABSE = \exp{.1} \f$
  165. static const Real ABSE;
  166. /// Also used in abscissa generation \f$ ABSER = 1 / \exp{.1} \f$
  167. static const Real ABSER;
  168. /// Counter for calculated
  169. int icount;
  170. /// Kernel Calculator
  171. std::vector < std::shared_ptr<KernelEM1DBase> > kernelVec;
  172. /// Spines for lagged convolutions (real part)
  173. std::vector <std::shared_ptr<CubicSplineInterpolator> > splineVecReal;
  174. /// Spines for lagged convolutions (imaginary part)
  175. std::vector < std::shared_ptr<CubicSplineInterpolator> > splineVecImag;
  176. /// Key used internally
  177. Eigen::Matrix<int, 801, 1> Key;
  178. //int Key[801];
  179. //Eigen::Matrix<int, Eigen::Dynamic, 1> Key;
  180. /// Filter weight coefficients. Set for either \f$J_0\f$ or \f$J_1\f$
  181. /// internally by protected function SetFilterWeights.
  182. /// Fixed sized will yield better performance. (not necessarily)
  183. //Eigen::Matrix<Real, 801, 1> FilterWeights;
  184. static const Eigen::Matrix<Real, 2, 801> FilterWeights;
  185. //static const Eigen::Matrix<Real, Eigen::Dynamic, Eigen::Dynamic> FilterWeights;
  186. /// Zwork from Anderson
  187. Eigen::Matrix<Complex, 801, Eigen::Dynamic> Zwork;
  188. //Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic> Zwork;
  189. /// Holds answer, dimensions are NumConv, and NumberRelated.
  190. Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic> Zans;
  191. /// Holds the arguments for lagged convolutions
  192. VectorXr Arg;
  193. /** ASCII string representation of the class name */
  194. static constexpr auto CName = "FHTAnderson801";
  195. }; // ----- end of class FHTAnderson801 -----
  196. }
  197. #endif // __FHTAnderson801_h