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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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/16/2009
  9. @version $Id: wireantenna.cpp 199 2014-12-29 19:25:20Z tirons $
  10. **/
  11. #include "WireAntenna.h"
  12. namespace Lemma {
  13. std::ostream &operator << (std::ostream &stream, const WireAntenna &ob) {
  14. stream << ob.Serialize() << "\n";
  15. return stream;
  16. }
  17. // ==================== LIFECYCLE =======================
  18. WireAntenna::WireAntenna( const ctor_key& key ) : LemmaObject( key ),
  19. NumberOfPoints(0), Current(1), NumberOfTurns(1) {
  20. }
  21. WireAntenna::WireAntenna( const YAML::Node& node, const ctor_key& key ) : LemmaObject( node, key ) {
  22. Points = node["Points"].as<Vector3Xr>();
  23. Freqs = node["Freqs"].as<VectorXr>();
  24. NumberOfPoints = node["NumberOfPoints"].as<int>();
  25. NumberOfTurns = node["NumberOfTurns"].as<int>();
  26. Current = node["Current"].as<Real>();
  27. }
  28. WireAntenna::~WireAntenna() {
  29. }
  30. std::shared_ptr<WireAntenna> WireAntenna::NewSP() {
  31. return std::make_shared<WireAntenna>( ctor_key() );
  32. }
  33. std::shared_ptr<WireAntenna> WireAntenna::Clone() const {
  34. auto copy = WireAntenna::NewSP();
  35. copy->NumberOfPoints = this->NumberOfPoints;
  36. copy->Freqs = this->Freqs;
  37. copy->Current = this->Current;
  38. copy->NumberOfTurns = this->NumberOfTurns;
  39. copy->Points = this->Points;
  40. //copy->Dipoles = this->Dipoles; // no, disaster
  41. return copy;
  42. }
  43. //--------------------------------------------------------------------------------------
  44. // Class: WireAntenna
  45. // Method: Serialize
  46. //--------------------------------------------------------------------------------------
  47. YAML::Node WireAntenna::Serialize ( ) const {
  48. YAML::Node node = LemmaObject::Serialize();
  49. node.SetTag( GetName() );
  50. node["NumberOfPoints"] = NumberOfPoints;
  51. node["NumberOfTurns"] = NumberOfTurns;
  52. node["Current"] = Current;
  53. node["Points"] = Points;
  54. node["Freqs"] = Freqs;
  55. return node;
  56. } // ----- end of method WireAntenna::Serialize -----
  57. //--------------------------------------------------------------------------------------
  58. // Class: WireAntenna
  59. // Method: DeSerialize
  60. //--------------------------------------------------------------------------------------
  61. std::shared_ptr<WireAntenna> WireAntenna::DeSerialize ( const YAML::Node& node ) {
  62. if (node.Tag() != "WireAntenna") {
  63. throw DeSerializeTypeMismatch( "WireAntenna", node.Tag());
  64. }
  65. return std::make_shared<WireAntenna> ( node, ctor_key() );
  66. } // ----- end of method WireAntenna::DeSerialize -----
  67. //--------------------------------------------------------------------------------------
  68. // Class: WireAntenna
  69. // Method: GetName
  70. // Description: Class identifier
  71. //--------------------------------------------------------------------------------------
  72. inline std::string WireAntenna::GetName ( ) const {
  73. return CName;
  74. } // ----- end of method WireAntenna::GetName -----
  75. // ==================== ACCESS =======================
  76. void WireAntenna::SetNumberOfTurns(const int &nturns) {
  77. this->NumberOfTurns = nturns;
  78. }
  79. int WireAntenna::GetNumberOfTurns( ) {
  80. return this->NumberOfTurns;
  81. }
  82. void WireAntenna::SetNumberOfPoints(const int &np) {
  83. Points.resize( Eigen::NoChange, np);
  84. NumberOfPoints = np;
  85. }
  86. void WireAntenna::SetNumberOfFrequencies(const int &nfreq){
  87. Freqs.resize(nfreq);
  88. Freqs.setZero();
  89. }
  90. void WireAntenna::SetFrequency(const int& ifreq, const Real & freq) {
  91. assert(ifreq < Freqs.size());
  92. this->Freqs[ifreq] = freq;
  93. }
  94. Real WireAntenna::GetFrequency(const int& ifreq) {
  95. return this->Freqs[ifreq];
  96. }
  97. int WireAntenna::GetNumberOfFrequencies() {
  98. return Freqs.size();
  99. }
  100. Vector3Xr WireAntenna::GetPoints() {
  101. return Points;
  102. }
  103. MatrixXr WireAntenna::GetPointsMat() {
  104. return MatrixXr(Points.transpose());
  105. }
  106. void WireAntenna::SetCurrent(const Real &amps) {
  107. this->Current = amps;
  108. }
  109. Real WireAntenna::GetCurrent( ) {
  110. return this->Current;
  111. }
  112. void WireAntenna::SetPoint(const int &p, const Vector3r& pos) {
  113. if (p >= 0 && p<NumberOfPoints ) {
  114. Points.col(p) = pos;
  115. } else {
  116. throw 7;
  117. }
  118. }
  119. void WireAntenna::SetPoint(const int &p, const Real& x, const Real& y, const Real& z) {
  120. if (p >= 0 && p<NumberOfPoints ) {
  121. Points.col(p) = Vector3r(x,y,z);
  122. } else {
  123. throw 7;
  124. }
  125. }
  126. void WireAntenna::ApproximateWithElectricDipoles(const Real &deltai) {
  127. // Get rid of any dipoles
  128. Dipoles.clear();
  129. Real Dist(0);
  130. Vector3r r;
  131. Vector3r p;
  132. for (int ip=0; ip<NumberOfPoints-1; ++ip) {
  133. Dist = (Points.col(ip+1) - Points.col(ip)).norm();
  134. r = (Points.col(ip+1) - Points.col(ip))/Dist;
  135. int nd = (int)(Dist/deltai);
  136. Real add = (Dist - (Real)(nd)*deltai) / (Real)(nd);
  137. Real delta = deltai + add;
  138. Real scale = (Real)(NumberOfTurns)*Current;
  139. p = Points.col(ip) + .5*delta*r;
  140. for (Real id=0.; id<Dist-delta/2; id+=delta) {
  141. // X dipoles
  142. if (std::abs(r[0]) > 1e-6) {
  143. auto tx = DipoleSource::NewSP();
  144. tx->SetLocation(p);
  145. tx->SetType(GROUNDEDELECTRICDIPOLE);
  146. tx->SetPolarisation(XPOLARISATION);
  147. tx->SetFrequencies(Freqs);
  148. tx->SetMoment(scale*delta*r[0]);
  149. Dipoles.push_back(tx);
  150. }
  151. // Y dipoles
  152. if (std::abs(r[1]) > 1e-6) {
  153. auto ty = DipoleSource::NewSP();
  154. ty->SetLocation(p);
  155. ty->SetType(GROUNDEDELECTRICDIPOLE);
  156. ty->SetPolarisation(YPOLARISATION);
  157. ty->SetFrequencies(Freqs);
  158. ty->SetMoment(scale*delta*r[1]);
  159. Dipoles.push_back(ty);
  160. }
  161. // Z dipoles
  162. if (std::abs(r[2]) > 1e-6) {
  163. auto tz = DipoleSource::NewSP();
  164. tz->SetLocation(p);
  165. tz->SetType(GROUNDEDELECTRICDIPOLE);
  166. tz->SetPolarisation(ZPOLARISATION);
  167. tz->SetFrequencies(Freqs);
  168. tz->SetMoment(scale*delta*r[2]);
  169. Dipoles.push_back(tz);
  170. }
  171. p += delta*r;
  172. }
  173. }
  174. }
  175. // ==================== INQUIRY =======================
  176. int WireAntenna::GetNumberOfDipoles() {
  177. return Dipoles.size();
  178. }
  179. std::shared_ptr<DipoleSource> WireAntenna::GetDipoleSource(const int &dip) {
  180. return this->Dipoles[dip];
  181. }
  182. #ifdef LEMMAUSEVTK
  183. vtkActor* WireAntenna::GetVtkActor(const int &idip) {
  184. return Dipoles[idip]->GetVtkActor();
  185. }
  186. #endif
  187. //--------------------------------------------------------------------------------------
  188. // Class: WireAntenna
  189. // Method: IsPlanar
  190. //--------------------------------------------------------------------------------------
  191. bool WireAntenna::IsHorizontallyPlanar ( ) {
  192. //for (int ip=0; ip<NumberOfPoints; ++ip) {
  193. // std::cout << Points(2,ip) << std::endl;
  194. //}
  195. if ( std::abs(Points.row(2).sum() - (NumberOfPoints*Points(2,0))) < 1e-5 ) {
  196. return true ;
  197. } else {
  198. return false;
  199. }
  200. } // ----- end of method WireAntenna::IsPlanar -----
  201. }