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.

WireAntenna.cpp 8.0KB

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