Main Lemma Repository
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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  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 12/02/2009
  9. **/
  10. #ifndef __EMEARTH1D_H
  11. #define __EMEARTH1D_H
  12. // forward declare these due to include cycle
  13. //#include "LayeredEarthEM.h"
  14. //#include "DipoleSource.h"
  15. //#include "FieldPoints.h"
  16. //#include "WireAntenna.h"
  17. //#include "PolygonalWireAntenna.h"
  18. //#include "KernelEM1DManager.h"
  19. #include "KernelEM1DSpec.h"
  20. #include "HankelTransformFactory.h"
  21. #include "GQChave.h"
  22. #include "FHTAnderson801.h"
  23. #include "FHTKey201.h"
  24. #include "FHTKey101.h"
  25. #include "FHTKey51.h"
  26. #include "QWEKey.h"
  27. #include "CubicSplineInterpolator.h"
  28. #ifdef HAVE_BOOST_PROGRESS
  29. #include "boost/progress.hpp"
  30. #endif
  31. namespace Lemma {
  32. enum TXRXMODE { TX, RX, TXRX, NOMODE };
  33. class WireAntenna;
  34. class PolygonalWireAntenna;
  35. class FieldPoints;
  36. class DipoleSource;
  37. class LayeredEarthEM;
  38. // =======================================================================
  39. // Class: EmEarth1D
  40. /// \ingroup FDEM1D
  41. /// \brief Implimentation of 1D EM solution.
  42. /// \details We've done a lot of different things.
  43. // =======================================================================
  44. class EMEarth1D : public LemmaObject {
  45. friend std::ostream &operator<<(std::ostream &stream,
  46. const EMEarth1D &ob);
  47. public:
  48. //friend class KernelEm1D;
  49. // ==================== LIFECYCLE ===========================
  50. /** Default protected constructor. */
  51. explicit EMEarth1D ( const ctor_key& );
  52. /** Default protected constructor. */
  53. EMEarth1D ( const YAML::Node& node, const ctor_key& );
  54. /** Default protected constructor. */
  55. ~EMEarth1D ();
  56. /**
  57. * Returns pointer to new EMEarth1D. Location is
  58. * initialized to (0,0,0) type and polarization are
  59. * initialized to nonworking values that will throw
  60. * exceptions if used.
  61. */
  62. static std::shared_ptr<EMEarth1D> NewSP();
  63. /** stream debugging info to std::out
  64. */
  65. void Query();
  66. /** YAML Serializing method
  67. */
  68. YAML::Node Serialize() const;
  69. // TODO, add this
  70. //static EMEarth1D* DeSerialize(const YAML::Node& node);
  71. // ==================== OPERATORS ===========================
  72. // ==================== OPERATIONS ===========================
  73. /// Calculates the field(s) due to an ungrounded dipole source
  74. /// Calls FORTRAN library em1d (em1dnew.for)
  75. #ifdef KIHALEE_EM1D
  76. void MakeCalc();
  77. #endif
  78. /** C++ wrapper for em1dnew.for, serial */
  79. void MakeCalc3();
  80. /** Calculates the field(s) due to a wire antennae */
  81. void CalculateWireAntennaFields(bool progressbar=false);
  82. // ==================== ACCESS ===========================
  83. /** Attaches an antennae */
  84. void AttachWireAntenna( std::shared_ptr<WireAntenna> antennae );
  85. /** Attaches a dipole for calculation */
  86. void AttachDipoleSource( std::shared_ptr<DipoleSource> dipole );
  87. /** Attaches a layered earth model for calculation */
  88. void AttachLayeredEarthEM( std::shared_ptr<LayeredEarthEM> Earth );
  89. /** Attaches a set of receiver points for calculation */
  90. void AttachFieldPoints( std::shared_ptr<FieldPoints> Receivers );
  91. /** Sets the fields that are calcultated, E,H or BOTH */
  92. void SetFieldsToCalculate( const FIELDCALCULATIONS &calc );
  93. /** Sets the method to use to evaluate the Hankel integral,
  94. */
  95. void SetHankelTransformMethod( const HANKELTRANSFORMTYPE &type );
  96. /**
  97. * Accesor for field points
  98. */
  99. inline FieldPoints* GetFieldPoints() {
  100. return this->Receivers.get();
  101. }
  102. /**
  103. * Sets the Mode enum tag.
  104. */
  105. void SetTxRxMode( const TXRXMODE& ModeSet ) {
  106. this->Mode = ModeSet;
  107. }
  108. // ==================== INQUIRY ===========================
  109. /**
  110. * Returns the name of the underlying class, similiar to Python's type
  111. * @return string of class name
  112. */
  113. virtual std::string GetName() const;
  114. /**
  115. * Returns the Mode enum tag.
  116. */
  117. inline TXRXMODE GetTxRxMode() const {
  118. return Mode;
  119. }
  120. protected:
  121. // ==================== OPERATIONS ===========================
  122. /** Used internally, this is the innermost loop of the MakeCalc3,
  123. * and CalculateWireAntennaField routines.
  124. */
  125. void SolveSingleTxRxPair(const int &irec,
  126. HankelTransform* Hankel,
  127. const Real &wavef, const int &ifreq,
  128. DipoleSource* tDipole);
  129. // void SolveSingleTxRxPair(const int &irec,
  130. // std::shared_ptr<HankelTransform> Hankel,
  131. // const Real &wavef, const int &ifreq,
  132. // std::shared_ptr<DipoleSource> tDipole);
  133. /** Used internally, this is the innermost loop of the MakeCalc3,
  134. * and CalculateWireAntennaField routines.
  135. */
  136. void SolveLaggedTxRxPair(const int &irec, HankelTransform* Hankel,
  137. const Real &wavef, const int &ifreq,
  138. PolygonalWireAntenna* antenna);
  139. // ==================== DATA MEMBERS ===========================
  140. /** Computes field due to dipole */
  141. std::shared_ptr<DipoleSource> Dipole;
  142. /** Earth model (Cole-cole) */
  143. std::shared_ptr<LayeredEarthEM> Earth;
  144. /** Receiver points */
  145. std::shared_ptr<FieldPoints> Receivers;
  146. /** Wire antennae tx */
  147. std::shared_ptr<WireAntenna> Antenna;
  148. /** What fields are wanted */
  149. FIELDCALCULATIONS FieldsToCalculate;
  150. /** The type of Hankel transform to use, default to digital
  151. * filtering
  152. */
  153. HANKELTRANSFORMTYPE HankelType;
  154. /** Counter for number of caclulations made
  155. */
  156. int icalcinner;
  157. /** Counter for number of caclulations made
  158. */
  159. int icalc;
  160. /**
  161. * Convenience tag that can be used for marking whether these
  162. * fields are part of a transmit or receive array.
  163. */
  164. TXRXMODE Mode = NOMODE;
  165. /** ASCII string representation of the class name */
  166. static constexpr auto CName = "EMEarth1D";
  167. }; // ----- end of class EMEarth1D -----
  168. /////////////////////////////////////////
  169. // Exception classes
  170. /** If a Receivers Class is NULL valued, throw this.
  171. */
  172. class NullReceivers : public std::runtime_error {
  173. /** Thrown when Receivers pointer is NULL
  174. */
  175. public: NullReceivers();
  176. };
  177. /** If an Antenna is NULL valued, throw this error.
  178. */
  179. class NullAntenna : public std::runtime_error {
  180. /** Thrown when an antenna pointer is NULL
  181. */
  182. public: NullAntenna();
  183. };
  184. /** If an Instrument is NULL valued, throw this error.
  185. */
  186. class NullInstrument : public std::runtime_error {
  187. /** thrown when an instrument pointer is NULL.
  188. * @param[in] ptr is a pointer to the class throwing the exception.
  189. */
  190. public: NullInstrument(LemmaObject* ptr);
  191. };
  192. /** If a dipole source is specified, but a method calling a wire antenna is
  193. * called, throw this.
  194. */
  195. class DipoleSourceSpecifiedForWireAntennaCalc : public std::runtime_error {
  196. /** Thrown when a dipole source is specified when a wire antenna is
  197. * expected
  198. */
  199. public: DipoleSourceSpecifiedForWireAntennaCalc();
  200. };
  201. } // Namespace Lemma
  202. #endif // __EMEARTH1D_H