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.

DipoleSource.h 13KB

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