Lemma is an Electromagnetics API
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  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 05/18/2012
  9. **/
  10. #ifndef KERNELEM1DREFLBASE_INC
  11. #define KERNELEM1DREFLBASE_INC
  12. #include "KernelEM1DBase.h"
  13. #include "DipoleSource.h"
  14. #include "LayeredEarthEM.h"
  15. namespace Lemma {
  16. enum DIPOLE_LOCATION { INAIR, INGROUND };
  17. // forward declaration for friend
  18. template<EMMODE Mode, int Ikernel, DIPOLE_LOCATION Isource, DIPOLE_LOCATION Irecv>
  19. class KernelEM1DSpec;
  20. // ===================================================================
  21. // Class: KernelEM1DReflBase
  22. /**
  23. \ingroup FDEM1D
  24. \brief Abstract class defining EM1DRefl class.
  25. \details Derived classes are template specialized for optimal performance.
  26. */
  27. // ===================================================================
  28. class KernelEM1DReflBase : public LemmaObject {
  29. template<EMMODE Mode, int Ikernel, DIPOLE_LOCATION Isource, DIPOLE_LOCATION Irecv>
  30. friend class KernelEM1DSpec;
  31. friend class KernelEM1DManager;
  32. //friend class DipoleSource;
  33. public:
  34. // ==================== LIFECYCLE =======================
  35. // ==================== OPERATORS =======================
  36. // ==================== OPERATIONS =======================
  37. void Initialise( std::shared_ptr<LayeredEarthEM> EarthIn) {
  38. nlay = EarthIn->GetNumberOfLayers();
  39. zh = VectorXcr::Zero(nlay);
  40. yh = VectorXcr::Zero(nlay);
  41. u = VectorXcr::Zero(nlay);
  42. cf = VectorXcr::Zero(nlay); // nlay -1 (lay 0 empty)
  43. rtu = VectorXcr::Zero(nlay); // nlay -1 Interfaces only
  44. rtd = VectorXcr::Zero(nlay); // nlay -1 Interfaces only
  45. kk = VectorXcr::Zero(nlay);
  46. Zyu = VectorXcr::Zero(nlay);
  47. Zyd = VectorXcr::Zero(nlay);
  48. Zyi = VectorXcr::Zero(nlay);
  49. th = VectorXcr::Zero(nlay);
  50. // Don't attach Earth, because this is performance critical.
  51. // Everying is internal, it's OK relax Frankie
  52. //if (Earth != NULL) {
  53. // Earth->DetachFrom(this);
  54. // Earth = NULL;
  55. //}
  56. //EarthIn->AttachTo(this);
  57. Earth = EarthIn;
  58. LayerThickness.resize(nlay);
  59. for (int ilay=0; ilay<nlay; ++ilay) {
  60. LayerThickness(ilay) = Earth->GetLayerThickness(ilay);
  61. }
  62. LayerDepth.resize(nlay);
  63. for (int ilay=0; ilay<nlay; ++ilay) {
  64. LayerDepth(ilay) = Earth->GetLayerDepth(ilay);
  65. }
  66. }
  67. void SetUpSource( DipoleSource* Dipole, const int &ifreq ) {
  68. zh(0) = Complex(0, Dipole->GetAngularFrequency(ifreq)*MU0);
  69. yh(0) = Complex(0, Dipole->GetAngularFrequency(ifreq)*EPSILON0);
  70. kk(0) = -zh(0) * yh(0);
  71. Earth->EvaluateColeColeModel(Dipole->GetAngularFrequency(ifreq));
  72. for (int ilay=1; ilay<Earth->GetNumberOfLayers(); ++ilay) {
  73. zh(ilay) = zh(0) * Earth->GetLayerSusceptibility(ilay);
  74. yh(ilay) = Earth->GetLayerConductivity(ilay) +
  75. yh(0)*Earth->GetLayerPermitivity(ilay);
  76. kk(ilay) = -zh(ilay)*yh(ilay);
  77. }
  78. tx_z = Dipole->GetLocation(2);
  79. lays = 0;
  80. Real Depth(0);
  81. for (int ilay=1; ilay<nlay; ++ilay) {
  82. if (tx_z > Depth) {
  83. lays = ilay;
  84. }
  85. Depth += LayerThickness(ilay);
  86. }
  87. }
  88. void SetUpReceiver(const Real &rz) {
  89. rx_z = rz;
  90. Real Depth(0.);
  91. layr = 0;
  92. for (int ilay=1; ilay<Earth->GetNumberOfLayers(); ++ilay) {
  93. if (rx_z > Depth) {
  94. layr = ilay;
  95. }
  96. Depth += LayerThickness(ilay);
  97. }
  98. }
  99. // ==================== ACCESS =======================
  100. Complex GetYm() {
  101. return yh(layr);
  102. }
  103. Complex GetZm() {
  104. return zh(layr);
  105. }
  106. Complex GetZs() {
  107. return zh(lays);
  108. }
  109. Complex GetKs() {
  110. return kk(lays);
  111. }
  112. // ==================== INQUIRY =======================
  113. virtual std::string GetName() const {
  114. return CName;
  115. }
  116. protected:
  117. // ==================== LIFECYCLE =======================
  118. /// Default protected constructor.
  119. KernelEM1DReflBase ( const ctor_key& key ) : LemmaObject( key )
  120. {
  121. }
  122. /// Default protected constructor.
  123. ~KernelEM1DReflBase () {
  124. }
  125. // ==================== OPERATIONS =======================
  126. /** Computes reflection coefficients. Depending on the
  127. * specialisation, this will either be TM or TE mode.
  128. */
  129. virtual void ComputeReflectionCoeffs(const Real& lambda)=0;
  130. /** Precomputes expensive calculations that are reused by insances
  131. * of KernelEM1DSpec in the calculation of Related potentials.
  132. */
  133. virtual void PreComputePotentialTerms()=0;
  134. // ==================== DATA MEMBERS =========================
  135. /// Bessel order, only 0 or 1 supported
  136. int id; // Needs to be dim nRel, or separate
  137. /// Layer the source is in
  138. int lays;
  139. /// Layer the receiver is in
  140. int layr;
  141. /// Number of Layers
  142. int nlay;
  143. /// Number of Related kernels to be computed
  144. int nRelated;
  145. /// Used in related kernel precompute calls
  146. int relIud;
  147. /// Receiver z position
  148. Real rx_z;
  149. /// Transmitter z position
  150. Real tx_z;
  151. /// bessel arg squared
  152. Real rams;
  153. /** Related part of con term */
  154. Complex relCon;
  155. Complex relenukadz;
  156. Complex relexp_pbs1;
  157. Complex relexp_pbs2;
  158. Complex rel_a;
  159. /// TM or TE mode
  160. EMMODE mode;
  161. /// Pointer to layered earth
  162. std::shared_ptr<LayeredEarthEM> Earth = nullptr;
  163. Complex uk;
  164. Complex um;
  165. VectorXcr cf; // nlay
  166. VectorXcr u; // nlay
  167. VectorXcr yh; // nlay
  168. VectorXcr zh; // nlay
  169. VectorXcr kk; // nlay
  170. VectorXcr Zyu; //(nlay); //Zyu.setZero();
  171. VectorXcr Zyd; //(nlay); //Zyd.setZero();
  172. VectorXcr Zyi; //(nlay); //Zyi.setZero();
  173. VectorXcr th; //(nlay);
  174. VectorXr LayerThickness;
  175. VectorXr LayerDepth;
  176. /// Reflection/Transmission coeffients for upgoing waves in a
  177. /// layered earth model
  178. VectorXcr rtu;
  179. /// Reflection/Transmission coeffients for downgoing waves in
  180. /// a layered earth model
  181. VectorXcr rtd;
  182. private:
  183. static constexpr auto CName = "KernelEM1DReflBase";
  184. }; // ----- end of class KernelEM1DReflBase -----
  185. } // ----- end of Lemma name -----
  186. #endif // ----- #ifndef KERNELEM1DREFLBASE_INC -----