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.

DipoleSource.h 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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. @version $Id: dipolesource.h 203 2015-01-09 21:19:04Z tirons $
  10. **/
  11. #ifndef __DIPOLESOURCE_H
  12. #define __DIPOLESOURCE_H
  13. #include "LemmaObject.h"
  14. #include "LayeredEarthEM.h"
  15. #ifdef LEMMAUSEVTK
  16. #include "vtkActor.h"
  17. #include "vtkLineSource.h"
  18. #include "vtkSphereSource.h"
  19. #include "vtkPolyDataMapper.h"
  20. #include "vtkTubeFilter.h"
  21. #include "vtkRegularPolygonSource.h"
  22. #include "vtkProperty.h"
  23. #endif
  24. namespace Lemma {
  25. // Forward declarations
  26. class KernelEM1DManager;
  27. class FieldPoints;
  28. class HankelTransform;
  29. // ==========================================================================
  30. // Class: DipoleSource
  31. /// \brief Dipole sources form the backbone of Lemma.
  32. /// \details More complex sources are constructed from a superposition of
  33. /// dipoles.
  34. // ==========================================================================
  35. class DipoleSource : public std::enable_shared_from_this<DipoleSource>, LemmaObject {
  36. // ==================== FRIENDS ======================
  37. friend std::ostream &operator<<(std::ostream &stream, const DipoleSource &ob);
  38. public:
  39. // ==================== LIFECYCLE ======================
  40. /** Default locked constructor. */
  41. explicit DipoleSource ( const ctor_key& );
  42. /** Locked deserializing constructor */
  43. DipoleSource ( const YAML::Node& node, const ctor_key& );
  44. /** Default locked constructor. */
  45. ~DipoleSource ();
  46. /**
  47. * Returns shared_ptr to new DipoleSource. Location is
  48. * initialized to (0,0,0) type and polarization are
  49. * initialized to nonworking values that will throw
  50. * exceptions if used.
  51. */
  52. static std::shared_ptr< DipoleSource > NewSP();
  53. /**
  54. * YAML Serializing method
  55. */
  56. YAML::Node Serialize() const;
  57. /**
  58. * Constructs an object from a YAML::Node.
  59. */
  60. static std::shared_ptr< DipoleSource > DeSerialize(const YAML::Node& node);
  61. /** Returns a deep copy of the dipole. Used to make thread safe methods. Does not
  62. copy attachments.
  63. */
  64. std::shared_ptr< DipoleSource > Clone();
  65. // ==================== OPERATORS ======================
  66. // ==================== OPERATIONS ======================
  67. /** Determines if kernels have been loaded already, and if so if they can be reused
  68. */
  69. void SetKernels(const int& ifreq, const FIELDCALCULATIONS& Fields, std::shared_ptr<FieldPoints> Receivers, const int& irec,
  70. std::shared_ptr<LayeredEarthEM> Earth );
  71. /** resets the kernels if they cannot be reused */
  72. virtual void ReSetKernels(const int& ifreq, const FIELDCALCULATIONS& Fields, std::shared_ptr<FieldPoints> Receivers,
  73. const int& irec, std::shared_ptr<LayeredEarthEM> Earth );
  74. /** Updates the receiver fields */
  75. virtual void UpdateFields(const int& ifreq, HankelTransform* Hankel, const Real& wavef);
  76. // ==================== ACCESS ======================
  77. /** Sets the position.
  78. * @param [in] posin
  79. */
  80. void SetLocation(const Vector3r &posin);
  81. /** Sets the location using three Real coordinate arguments.
  82. * @param[in] xp is the x coordinate of the dipole
  83. * @param[in] yp is the y coordinate of the dipole
  84. * @param[in] zp is the z coordinate of the dipole
  85. */
  86. void SetLocation(const Real &xp, const Real &yp, const Real &zp);
  87. /** Sets the dipole direction (polarisation). This method
  88. * replaced SetPolarisation(DipoleSourcePolarisation) and allows for general dipole
  89. * directionality.
  90. * @param[in] dir is the direction of the dipole. This will be normalised.
  91. */
  92. void SetPolarisation(const Vector3r &dir);
  93. /** Sets the polarisation of the dipole. Conveneince method that calls
  94. * SetPolarisation(const Vector3r &dir), constructing the normalized Vector | <x, y, z> |
  95. */
  96. void SetPolarisation(const Real& x, const Real& y, const Real& z );
  97. /// Sets the dipole polarisation
  98. /// @param[in] pol is the enumerated polarisation
  99. void SetPolarisation(const DipoleSourcePolarisation &pol);
  100. /// Sets the dipole source type
  101. /// @param[in] stype is one of the enerated values taking either
  102. /// ELECTRICDIPOLE or MAGNETICDIPOLE
  103. void SetType(const DipoleSourceType &stype);
  104. /// Sets the dipole moment
  105. void SetMoment(const Real &moment);
  106. /// Sets the dipole phse
  107. void SetPhase(const Real &phase);
  108. /// Sets the polarity
  109. void SetPolarity(const DipoleSourcePolarity& pol);
  110. /// Sets number of frequencies
  111. void SetNumberOfFrequencies(const int &nfreq);
  112. /// Sets a specific frequency.
  113. /// @param[in] ifreq is the frequency bin number
  114. /// @param[in] freq is the frequency to set, in Hz
  115. void SetFrequency(const int &ifreq, const Real &freq);
  116. /// Sets the frequencies of the dipole.
  117. /// @param[in] freqs is a vector of the frequencies. Also sets
  118. /// number of frequencies
  119. void SetFrequencies(const VectorXr& freqs);
  120. // ==================== INQUIRY ======================
  121. /** Accessor to polarisation vector.
  122. @return returns the unit polarisation vector.
  123. */
  124. Vector3r GetPolarisation();
  125. /// Returns Vector3r position of the dipole
  126. Vector3r GetLocation();
  127. /// Returns a specific coordinate of the dipole
  128. /// @param coordinate 0=x, 1=y, 2=z
  129. Real GetLocation(const int &coordinate);
  130. /// Returns enumerated of DipoleSourceType
  131. DipoleSourceType GetDipoleSourceType();
  132. /// Returns the dipole type
  133. DipoleSourceType GetType();
  134. /// Returns pointer to KernelEM1DManager
  135. std::shared_ptr<KernelEM1DManager> GetKernelManager();
  136. // Returns enumerated DipoleSourcePolarization
  137. //DipoleSourcePolarisation GetDipoleSourcePolarisation();
  138. /// Returns the dipole moment
  139. Real GetMoment();
  140. /// Returns the angular frequency of the dipole
  141. Real GetAngularFrequency(const int &ifreq);
  142. /// Returns the frequency of the dipole (Hz)
  143. Real GetFrequency(const int &ifreq);
  144. /// Returns the frequency of the dipole (Hz)
  145. VectorXr GetFrequencies( );
  146. /// Returns the phase offset of the dipole
  147. Real GetPhase();
  148. /// Returns the number of frequencies
  149. int GetNumberOfFrequencies();
  150. #ifdef LEMMAUSEVTK
  151. /// Returns an actor that can be placed into a vtk scene easily
  152. /// Note that this function throws a pointer, it is the receivers
  153. /// job to manage this memory!
  154. vtkActor* GetVtkActor();
  155. #endif
  156. /** Returns the name of the underlying class, similiar to Python's type */
  157. virtual std::string GetName() const ;
  158. private:
  159. // ==================== DATA MEMBERS ======================
  160. /// Defines the type of source (magnetic or electric)
  161. DipoleSourceType Type;
  162. // Polarization of the dipole, (x, y or z)
  163. //DipoleSourcePolarisation Polarisation;
  164. // Dipole polarity
  165. //DipoleSourcePolarity Polarity;
  166. /// Which receiver index should Kernels be configured for
  167. int irec;
  168. int lays;
  169. int layr;
  170. /// Phase offset of the dipole, referenced from 0
  171. Real Phase;
  172. /// Dipole Moment
  173. Real Moment;
  174. Real xxp;
  175. Real yyp;
  176. Real rho;
  177. Real sp;
  178. Real cp;
  179. Real scp;
  180. Real sps;
  181. Real cps;
  182. Real c2p;
  183. Real kernelFreq;
  184. FIELDCALCULATIONS FieldsToCalculate = BOTH;
  185. VectorXcr f;
  186. VectorXi ik;
  187. /// Central location of the dipole
  188. Vector3r Location;
  189. /// Unit vector defining directionality of the dipole
  190. Vector3r Phat;
  191. /// Freqencies of the source, in Hz
  192. VectorXr Freqs;
  193. /// Storage of the EM1D kernels used by this dipole
  194. std::shared_ptr<KernelEM1DManager> KernelManager;
  195. /// Receiver points, keep track if these have changed
  196. std::shared_ptr<FieldPoints> Receivers;
  197. /// Layered Earth used by Kernels
  198. std::shared_ptr<LayeredEarthEM> Earth;
  199. /** ASCII string representation of the class name */
  200. static constexpr auto CName = "DipoleSource";
  201. }; // ----- end of class DipoleSource -----
  202. /** If no dipole source has been specified, throw this error.
  203. */
  204. class NullDipoleSource : public std::runtime_error {
  205. public:
  206. /** Thrown when a DipoleSource pointer is NULL
  207. */
  208. NullDipoleSource ( );
  209. };
  210. /** Error class for assignment of a dipole source that did not connect properly.
  211. */
  212. class NonValidDipoleTypeAssignment : public std::runtime_error {
  213. public:
  214. NonValidDipoleTypeAssignment( );
  215. };
  216. /** Error class for a non-valid dipole type. Generally thrown if this was not
  217. * set properly.
  218. */
  219. class NonValidDipoleType : public std::runtime_error {
  220. public:
  221. /** Throws error. This is a deprecated function. Call the method with
  222. * the pointer address instead.
  223. */
  224. NonValidDipoleType( );
  225. /** Throws error with information on the class throwing the error.
  226. */
  227. NonValidDipoleType( LemmaObject *ptr );
  228. };
  229. /** Error class for non valid dipole polarisation
  230. */
  231. class NonValidDipolePolarisation : public std::runtime_error {
  232. public:
  233. NonValidDipolePolarisation( );
  234. };
  235. /** Error class for non valid dipole polarity
  236. */
  237. class NonValidDipolePolarity : public std::runtime_error {
  238. public:
  239. NonValidDipolePolarity( );
  240. };
  241. /** Error class for non valid dipole polarisation
  242. */
  243. class NonValidDipolePolarisationAssignment : public std::runtime_error {
  244. public:
  245. NonValidDipolePolarisationAssignment( );
  246. };
  247. /** Error class for non valid location coordinate.
  248. */
  249. class NonValidLocationCoordinate : public std::runtime_error {
  250. public:
  251. NonValidLocationCoordinate( );
  252. };
  253. }
  254. #endif // __DIPOLESOURCE_H