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.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  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. #ifdef HAVE_YAMLCPP
  14. std::ostream &operator << (std::ostream &stream, const WireAntenna &ob) {
  15. stream << ob.Serialize() << "\n---\n"; // End of doc --- as a direct stream should encapulste thingy
  16. return stream;
  17. }
  18. #else
  19. std::ostream &operator<<(std::ostream &stream,
  20. const WireAntenna &ob) {
  21. stream << *(LemmaObject*)(&ob);
  22. stream << "Current: " << ob.Current << " [A]\n";
  23. stream << "Frequencies: " << ob.Freqs.transpose() << " [Hz]\n";
  24. stream << "Number of points " << ob.NumberOfPoints << "\n";
  25. stream << "Number of turns " << ob.NumberOfTurns << "\n";
  26. if (ob.NumberOfPoints) {
  27. stream << "Points:\n" << ob.Points.transpose() << "\n";
  28. //stream << "Dipoles used to approximate " << ob.Dipoles.size() << "\n";
  29. }
  30. return stream;
  31. }
  32. #endif
  33. // ==================== LIFECYCLE =======================
  34. WireAntenna::WireAntenna(const std::string &name) :
  35. LemmaObject(name),
  36. NumberOfPoints(0), Current(1), NumberOfTurns(1) {
  37. }
  38. #ifdef HAVE_YAMLCPP
  39. WireAntenna::WireAntenna(const YAML::Node &node) :
  40. LemmaObject(node) {
  41. Points = node["Points"].as<Vector3Xr>();
  42. Freqs = node["Freqs"].as<VectorXr>();
  43. NumberOfPoints = node["NumberOfPoints"].as<int>();
  44. NumberOfTurns = node["NumberOfTurns"].as<int>();
  45. Current = node["Current"].as<Real>();
  46. }
  47. #endif
  48. WireAntenna::~WireAntenna() {
  49. for (unsigned int id=0; id<Dipoles.size(); ++id) {
  50. Dipoles[id]->Delete();
  51. }
  52. Dipoles.clear();
  53. if (this->NumberOfReferences != 0) {
  54. throw DeleteObjectWithReferences(this);
  55. }
  56. }
  57. WireAntenna* WireAntenna::New() {
  58. WireAntenna* Obj = new WireAntenna("WireAntenna");
  59. Obj->AttachTo(Obj);
  60. return Obj;
  61. }
  62. WireAntenna* WireAntenna::Clone() {
  63. WireAntenna* copy = WireAntenna::New();
  64. //copy->AttachTo(copy); // NO! Attached above!
  65. copy->NumberOfPoints = this->NumberOfPoints;
  66. copy->Freqs = this->Freqs;
  67. copy->Current = this->Current;
  68. copy->NumberOfTurns = this->NumberOfTurns;
  69. copy->Points = this->Points;
  70. //copy->Dipoles = this->Dipoles; // no, disaster
  71. return copy;
  72. }
  73. void WireAntenna::Delete() {
  74. this->DetachFrom(this);
  75. }
  76. void WireAntenna::Release() {
  77. delete this;
  78. }
  79. // ==================== ACCESS =======================
  80. void WireAntenna::SetNumberOfTurns(const int &nturns) {
  81. this->NumberOfTurns = nturns;
  82. }
  83. int WireAntenna::GetNumberOfTurns( ) {
  84. return this->NumberOfTurns;
  85. }
  86. void WireAntenna::SetNumberOfPoints(const int &np) {
  87. Points.resize( Eigen::NoChange, np);
  88. NumberOfPoints = np;
  89. }
  90. void WireAntenna::SetNumberOfFrequencies(const int &nfreq){
  91. Freqs.resize(nfreq);
  92. Freqs.setZero();
  93. }
  94. void WireAntenna::SetFrequency(const int& ifreq, const Real & freq) {
  95. assert(ifreq < Freqs.size());
  96. this->Freqs[ifreq] = freq;
  97. }
  98. Real WireAntenna::GetFrequency(const int& ifreq) {
  99. return this->Freqs[ifreq];
  100. }
  101. int WireAntenna::GetNumberOfFrequencies() {
  102. return Freqs.size();
  103. }
  104. Vector3Xr WireAntenna::GetPoints() {
  105. return Points;
  106. }
  107. MatrixXr WireAntenna::GetPointsMat() {
  108. return MatrixXr(Points.transpose());
  109. }
  110. void WireAntenna::SetCurrent(const Real &amps) {
  111. this->Current = amps;
  112. }
  113. Real WireAntenna::GetCurrent( ) {
  114. return this->Current;
  115. }
  116. void WireAntenna::SetPoint(const int &p, const Vector3r& pos) {
  117. if (p >= 0 && p<NumberOfPoints ) {
  118. Points.col(p) = pos;
  119. } else {
  120. throw 7;
  121. }
  122. }
  123. void WireAntenna::SetPoint(const int &p, const Real& x, const Real& y, const Real& z) {
  124. if (p >= 0 && p<NumberOfPoints ) {
  125. Points.col(p) = Vector3r(x,y,z);
  126. } else {
  127. throw 7;
  128. }
  129. }
  130. void WireAntenna::ApproximateWithElectricDipoles(const Real &deltai) {
  131. // Get rid of any dipoles
  132. for (unsigned int id=0; id<Dipoles.size(); ++id) {
  133. Dipoles[id]->Delete();
  134. }
  135. Dipoles.clear();
  136. Real Dist(0);
  137. Vector3r r;
  138. Vector3r p;
  139. for (int ip=0; ip<NumberOfPoints-1; ++ip) {
  140. Dist = (Points.col(ip+1) - Points.col(ip)).norm();
  141. r = (Points.col(ip+1) - Points.col(ip))/Dist;
  142. int nd = (int)(Dist/deltai);
  143. Real add = (Dist - (Real)(nd)*deltai) / (Real)(nd);
  144. Real delta = deltai + add;
  145. Real scale = (Real)(NumberOfTurns)*Current;
  146. p = Points.col(ip) + .5*delta*r;
  147. for (Real id=0.; id<Dist-delta/2; id+=delta) {
  148. // X dipoles
  149. if (std::abs(r[0]) > 1e-6) {
  150. DipoleSource *tx = DipoleSource::New();
  151. tx->SetLocation(p);
  152. tx->SetType(GROUNDEDELECTRICDIPOLE);
  153. tx->SetPolarisation(XPOLARISATION);
  154. tx->SetFrequencies(Freqs);
  155. tx->SetMoment(scale*delta*r[0]);
  156. Dipoles.push_back(tx);
  157. }
  158. // Y dipoles
  159. if (std::abs(r[1]) > 1e-6) {
  160. DipoleSource *ty = DipoleSource::New();
  161. ty->SetLocation(p);
  162. ty->SetType(GROUNDEDELECTRICDIPOLE);
  163. ty->SetPolarisation(YPOLARISATION);
  164. ty->SetFrequencies(Freqs);
  165. ty->SetMoment(scale*delta*r[1]);
  166. Dipoles.push_back(ty);
  167. }
  168. // Z dipoles
  169. if (std::abs(r[2]) > 1e-6) {
  170. DipoleSource *tz = DipoleSource::New();
  171. tz->SetLocation(p);
  172. tz->SetType(GROUNDEDELECTRICDIPOLE);
  173. tz->SetPolarisation(ZPOLARISATION);
  174. tz->SetFrequencies(Freqs);
  175. tz->SetMoment(scale*delta*r[2]);
  176. Dipoles.push_back(tz);
  177. }
  178. p += delta*r;
  179. }
  180. }
  181. }
  182. // ==================== INQUIRY =======================
  183. int WireAntenna::GetNumberOfDipoles() {
  184. return Dipoles.size();
  185. }
  186. DipoleSource* WireAntenna::GetDipoleSource(const int &dip) {
  187. return this->Dipoles[dip];
  188. }
  189. #ifdef LEMMAUSEVTK
  190. vtkActor* WireAntenna::GetVtkActor(const int &idip) {
  191. return Dipoles[idip]->GetVtkActor();
  192. }
  193. #endif
  194. #ifdef HAVE_YAMLCPP
  195. //--------------------------------------------------------------------------------------
  196. // Class: WireAntenna
  197. // Method: Serialize
  198. //--------------------------------------------------------------------------------------
  199. YAML::Node WireAntenna::Serialize ( ) const {
  200. YAML::Node node = LemmaObject::Serialize();
  201. node.SetTag( this->Name );
  202. node["NumberOfPoints"] = NumberOfPoints;
  203. node["NumberOfTurns"] = NumberOfTurns;
  204. node["Current"] = Current;
  205. node["Points"] = Points;
  206. node["Freqs"] = Freqs;
  207. return node;
  208. } // ----- end of method WireAntenna::Serialize -----
  209. //--------------------------------------------------------------------------------------
  210. // Class: WireAntenna
  211. // Method: DeSerialize
  212. //--------------------------------------------------------------------------------------
  213. WireAntenna* WireAntenna::DeSerialize ( const YAML::Node& node ) {
  214. WireAntenna* Object = new WireAntenna(node);
  215. Object->AttachTo(Object);
  216. DESERIALIZECHECK( node, Object )
  217. return Object ;
  218. } // ----- end of method WireAntenna::DeSerialize -----
  219. #endif
  220. //--------------------------------------------------------------------------------------
  221. // Class: WireAntenna
  222. // Method: IsPlanar
  223. //--------------------------------------------------------------------------------------
  224. bool WireAntenna::IsHorizontallyPlanar ( ) {
  225. //for (int ip=0; ip<NumberOfPoints; ++ip) {
  226. // std::cout << Points(2,ip) << std::endl;
  227. //}
  228. if ( std::abs(Points.row(2).sum() - (NumberOfPoints*Points(2,0))) < 1e-5 ) {
  229. return true ;
  230. } else {
  231. return false;
  232. }
  233. } // ----- end of method WireAntenna::IsPlanar -----
  234. }