Lemma is an Electromagnetics API
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

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::LoadFile(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