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.

FieldPoints.cpp 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  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. @version $Id: receiverpoints.cpp 203 2015-01-09 21:19:04Z tirons $
  10. **/
  11. #include "FieldPoints.h"
  12. namespace Lemma {
  13. // ==================== FRIENDS ======================
  14. std::ostream &operator << (std::ostream &stream, const FieldPoints &ob) {
  15. stream << ob.Serialize() << "\n---\n"; // End of doc ---
  16. return stream;
  17. }
  18. // ==================== LIFECYCLE ===================================
  19. FieldPoints::FieldPoints( const ctor_key& ) : LemmaObject( ),
  20. NumberOfPoints(0), NumberOfBinsE(0), NumberOfBinsH(0) {
  21. }
  22. //--------------------------------------------------------------------------------------
  23. // Class: FieldPoints
  24. // Method: FieldPoints
  25. // Description: constructor (protected)
  26. //--------------------------------------------------------------------------------------
  27. FieldPoints::FieldPoints (const YAML::Node& node, const ctor_key&) : LemmaObject(node) {
  28. //DeSerialize
  29. NumberOfPoints = node["NumberOfPoints"].as<int>();
  30. NumberOfBinsE = node["NumberOfBinsE"].as<int>();
  31. NumberOfBinsH = node["NumberOfBinsH"].as<int>();
  32. Mask = node["Mask"].as<VectorXi>();
  33. Locations = node["Locations"].as<Vector3Xr>();
  34. } // ----- end of method FieldPoints::FieldPoints (constructor) -----
  35. FieldPoints::~FieldPoints() {
  36. }
  37. std::shared_ptr<FieldPoints> FieldPoints::NewSP() {
  38. return std::make_shared<FieldPoints> ( ctor_key() );
  39. }
  40. //--------------------------------------------------------------------------------------
  41. // Class: FieldPoints
  42. // Method: Serialize
  43. //--------------------------------------------------------------------------------------
  44. YAML::Node FieldPoints::Serialize ( ) const {
  45. YAML::Node node = LemmaObject::Serialize();
  46. node.SetTag( GetName() );
  47. // update here
  48. node["NumberOfPoints"] = NumberOfPoints;
  49. node["NumberOfBinsE"] = NumberOfBinsE;
  50. node["NumberOfBinsH"] = NumberOfBinsH;
  51. node["Mask"] = Mask;
  52. node["Locations"] = Locations;// Can be huge
  53. //std::cout << "Locations.data" << Locations.data()[0] << std::endl;
  54. return node;
  55. } // ----- end of method FieldPoints::Serialize -----
  56. //--------------------------------------------------------------------------------------
  57. // Class: FieldPoints
  58. // Method: DeSerialize
  59. //--------------------------------------------------------------------------------------
  60. std::shared_ptr<FieldPoints> FieldPoints::DeSerialize ( const YAML::Node& node ) {
  61. if (node.Tag() != "FieldPoints") {
  62. throw DeSerializeTypeMismatch( "FieldPoints", node.Tag());
  63. }
  64. return std::make_shared<FieldPoints> ( node, ctor_key() );
  65. } // ----- end of method FieldPoints::DeSerialize -----
  66. // ==================== ACCESS ===================================
  67. void FieldPoints::SetNumberOfPoints(const int &nrec) {
  68. if (nrec > 0)
  69. this->NumberOfPoints = nrec;
  70. else
  71. throw std::runtime_error("NUMBER RECEIVERS LESS THAN 1");
  72. this->Locations.resize(Eigen::NoChange, nrec);
  73. Locations.setZero();
  74. this->Mask.resize(nrec);
  75. Mask.setZero();
  76. ResizeEField();
  77. ResizeHField();
  78. }
  79. void FieldPoints::ResizeEField() {
  80. Efield.clear();
  81. for (int i=0; i<NumberOfBinsE; ++i) {
  82. Eigen::Matrix<Complex, 3, Eigen::Dynamic> tempe;
  83. this->Efield.push_back(tempe);
  84. this->Efield[i].resize(Eigen::NoChange, NumberOfPoints);
  85. this->Efield[i].setZero();
  86. }
  87. }
  88. void FieldPoints::ResizeHField() {
  89. Hfield.clear();
  90. for (int i=0; i<NumberOfBinsH; ++i) {
  91. Eigen::Matrix<Complex, 3, Eigen::Dynamic> temph;
  92. this->Hfield.push_back(temph);
  93. this->Hfield[i].resize(Eigen::NoChange, NumberOfPoints);
  94. this->Hfield[i].setZero();
  95. }
  96. }
  97. void FieldPoints::SetNumberOfBinsE(const int& nbins) {
  98. NumberOfBinsE = nbins;
  99. ResizeEField();
  100. }
  101. void FieldPoints::SetNumberOfBinsH(const int& nbins) {
  102. NumberOfBinsH = nbins;
  103. ResizeHField();
  104. }
  105. void FieldPoints::SetLocation(const int&nrec,const Vector3r& loc) {
  106. this->Locations.col(nrec) = loc;
  107. }
  108. void FieldPoints::SetLocation(const int&nrec,const Real& xp,
  109. const Real& yp, const Real& zp) {
  110. this->Locations.col(nrec) << xp, yp, zp;
  111. }
  112. void FieldPoints::SetEfield(const int& nbin,
  113. const int& loc, const Complex &ex,
  114. const Complex &ey, const Complex &ez) {
  115. this->Efield[nbin].col(loc) << ex, ey, ez;
  116. }
  117. void FieldPoints::AppendEfield(const int&nbin, const int& loc,
  118. const Complex &ex,
  119. const Complex &ey, const Complex &ez) {
  120. #ifdef LEMMAUSEOMP
  121. #pragma omp critical
  122. #endif
  123. this->Efield[nbin].col(loc) += Vector3cr(ex, ey, ez); //temp;
  124. }
  125. void FieldPoints::SetHfield(const int &nbin, const int& loc,
  126. const Complex &hx, const Complex &hy,
  127. const Complex &hz) {
  128. this->Hfield[nbin].col(loc) << hx, hy, hz;
  129. }
  130. void FieldPoints::AppendHfield(const int &nbin, const int& loc,
  131. const Complex &hx, const Complex &hy,
  132. const Complex &hz) {
  133. // #ifdef LEMMAUSEOMP
  134. // #pragma omp atomic
  135. // std::real(this->Hfield[nbin].col(loc)[0]) += std::real(hx);
  136. // #pragma omp atomic
  137. // std::imag(this->Hfield[nbin].col(loc)[0]) += std::imag(hx);
  138. // #pragma omp atomic
  139. // std::real(this->Hfield[nbin].col(loc)[1]) += std::real(hy);
  140. // #pragma omp atomic
  141. // std::imag(this->Hfield[nbin].col(loc)[1]) += std::imag(hy);
  142. // #pragma omp atomic
  143. // std::real(this->Hfield[nbin].col(loc)[2]) += std::real(hz);
  144. // #pragma omp atomic
  145. // std::imag(this->Hfield[nbin].col(loc)[2]) += std::imag(hz);
  146. // #else
  147. //(critical sections are slow)
  148. #ifdef LEMMAUSEOMP
  149. #pragma omp critical
  150. #endif
  151. this->Hfield[nbin].col(loc) += Vector3cr(hx,hy,hz);
  152. //#endif
  153. }
  154. // ==================== INQUIRY ===================================
  155. Vector3Xr FieldPoints::GetLocations() {
  156. return this->Locations;
  157. }
  158. MatrixXr FieldPoints::GetLocationsMat() {
  159. return MatrixXr(this->Locations);
  160. }
  161. Vector3r FieldPoints::GetLocation(const int &nrec) {
  162. return this->Locations.col(nrec);
  163. }
  164. Real FieldPoints::GetLocationX(const int &nrec) {
  165. return this->Locations.col(nrec)[0];
  166. }
  167. Real FieldPoints::GetLocationY(const int &nrec) {
  168. return this->Locations.col(nrec)[1];
  169. }
  170. Real FieldPoints::GetLocationZ(const int &nrec) {
  171. return this->Locations.col(nrec)[2];
  172. }
  173. Vector3cr FieldPoints::GetEfield(const int &nfreq, const int&nrec) {
  174. return this->Efield[nfreq].col(nrec);
  175. }
  176. Vector3cr FieldPoints::GetHfield(const int &nfreq, const int&nrec) {
  177. return this->Hfield[nfreq].col(nrec);
  178. }
  179. std::vector<Vector3Xcr> FieldPoints::GetHfield( ) {
  180. return this->Hfield;
  181. }
  182. std::vector<Vector3Xcr> FieldPoints::GetEfield( ) {
  183. return this->Efield;
  184. }
  185. Vector3Xcr FieldPoints::GetEfield (const int &nfreq) {
  186. return this->Efield[nfreq];
  187. }
  188. MatrixXcr FieldPoints::GetEfieldMat (const int &nfreq) {
  189. return MatrixXcr(this->Efield[nfreq]);
  190. }
  191. MatrixXcr FieldPoints::GetHfieldMat (const int &nfreq) {
  192. return MatrixXcr(this->Hfield[nfreq]);
  193. }
  194. Vector3Xcr FieldPoints::GetHfield (const int &nfreq) {
  195. return this->Hfield[nfreq];
  196. }
  197. void FieldPoints::MaskPoint(const int& imask) {
  198. Mask(imask) = true;
  199. }
  200. void FieldPoints::UnMaskPoint(const int& imask) {
  201. Mask(imask) = false;
  202. }
  203. void FieldPoints::UnMaskAllPoints() {
  204. Mask.setZero();
  205. }
  206. int FieldPoints::GetMask(const int& i) {
  207. return Mask(i);
  208. }
  209. int FieldPoints::GetNumberOfPoints() {
  210. return this->NumberOfPoints;
  211. }
  212. void FieldPoints::ClearFields() {
  213. for (int i=0; i<NumberOfBinsE; ++i) {
  214. this->Efield[i].setZero();
  215. }
  216. for (int i=0; i<NumberOfBinsH; ++i) {
  217. this->Hfield[i].setZero();
  218. }
  219. }
  220. #ifdef LEMMAUSEVTK
  221. vtkActor* FieldPoints::GetVtkGlyphActor(const FIELDTYPE &ftype,
  222. const Real &clip, const Real &scale,
  223. const int &nfreq) {
  224. vtkArrowSource *vArrow;
  225. vtkGlyph3D *vGlyph;
  226. vtkActor *vActor;
  227. vtkPolyDataMapper *vPolyMapper;
  228. vtkPoints *vPoints;
  229. vtkDoubleArray *vVects;
  230. vtkPolyData *vPointSet;
  231. vActor = vtkActor::New();
  232. vGlyph = vtkGlyph3D::New();
  233. vArrow = vtkArrowSource::New();
  234. vPolyMapper = vtkPolyDataMapper::New();
  235. vPoints = vtkPoints::New();
  236. vPointSet = vtkPolyData::New();
  237. vVects = vtkDoubleArray::New();
  238. vVects->SetNumberOfComponents(3);
  239. // Make PointData
  240. for (int ic=0; ic<NumberOfPoints; ++ic) {
  241. Vector3r loc = this->GetLocation(ic);
  242. vPoints->InsertPoint(ic, loc[0], loc[1],
  243. loc[2]);
  244. Vector3r temp;
  245. temp.setZero();
  246. switch (ftype) {
  247. case HFIELDREAL:
  248. temp = scale*(GetHfield(nfreq,ic).real());
  249. break;
  250. case HFIELDIMAG:
  251. temp = scale*(GetHfield(nfreq,ic).imag());
  252. break;
  253. case EFIELDREAL:
  254. temp = scale*(GetEfield(nfreq, ic).real());
  255. break;
  256. case EFIELDIMAG:
  257. temp = scale*(GetEfield(nfreq, ic).imag());
  258. break;
  259. }
  260. if (temp.norm() > clip) {
  261. temp /= temp.norm(); // norm
  262. temp *= clip; // clip dimension
  263. }
  264. vVects->InsertTuple3(ic, temp(0), temp(1),
  265. temp(2));
  266. }
  267. vPointSet->SetPoints(vPoints);
  268. vPointSet->GetPointData()->SetVectors(vVects);
  269. vGlyph->ScalingOn();
  270. vGlyph->SetScaleModeToScaleByVector();
  271. vGlyph->SetSourceConnection(vArrow->GetOutputPort());
  272. vGlyph->SetVectorMode(true);
  273. vGlyph->SetVectorModeToUseVector();
  274. vGlyph->OrientOn();
  275. vGlyph->SetInputData(vPointSet);
  276. vPolyMapper->SetInputConnection(vGlyph->GetOutputPort());
  277. vActor->SetMapper(vPolyMapper);
  278. if (vArrow != NULL) {
  279. vArrow->Delete();
  280. vArrow = NULL;
  281. }
  282. //if (vActor != NULL) {
  283. // vActor->Delete();
  284. // vActor = NULL;
  285. //}
  286. if (vPolyMapper != NULL) {
  287. vPolyMapper->Delete();
  288. vPolyMapper = NULL;
  289. }
  290. if (vVects != NULL) {
  291. vVects->Delete();
  292. vVects = NULL;
  293. }
  294. if (vPointSet != NULL) {
  295. vPointSet->Delete();
  296. vPointSet = NULL;
  297. }
  298. if (vPoints != NULL) {
  299. vPoints->Delete();
  300. vPoints = NULL;
  301. }
  302. if (vGlyph != NULL) {
  303. vGlyph->Delete();
  304. vGlyph = NULL;
  305. }
  306. return vActor;
  307. }
  308. vtkDataObject* FieldPoints::GetVtkDataObject(const FIELDTYPE &ftype,
  309. const int& nbin,
  310. const int& start, const int& end,
  311. const FIELDCOMPONENT& fcomp,
  312. const SPATIALCOORDINANT &scord) {
  313. if (start < 0) throw 77;
  314. if (end > NumberOfPoints) throw 78;
  315. if (start > end) throw 79;
  316. int ifc(-1);
  317. switch (fcomp) {
  318. case XCOMPONENT:
  319. ifc = 0;
  320. break;
  321. case YCOMPONENT:
  322. ifc = 1;
  323. break;
  324. case ZCOMPONENT:
  325. ifc = 2;
  326. break;
  327. }
  328. int isc(-1);
  329. switch (scord) {
  330. case XCOORD:
  331. isc = 0;
  332. break;
  333. case YCOORD:
  334. isc = 1;
  335. break;
  336. case ZCOORD:
  337. isc = 2;
  338. break;
  339. }
  340. vtkDoubleArray *_data = vtkDoubleArray::New();
  341. _data->SetNumberOfComponents(1);
  342. vtkDoubleArray *_pos = vtkDoubleArray::New();
  343. _pos->SetNumberOfComponents(1);
  344. int id=0;
  345. for (int irec=start; irec<end; ++irec) {
  346. switch (ftype) {
  347. case HFIELDREAL:
  348. _data->InsertTuple1(id, std::real(Hfield[nbin](ifc, irec)));
  349. break;
  350. case HFIELDIMAG:
  351. _data->InsertTuple1(id, std::imag(Hfield[nbin](ifc, irec)));
  352. break;
  353. case EFIELDREAL:
  354. _data->InsertTuple1(id, std::real(Efield[nbin](ifc, irec)));
  355. break;
  356. case EFIELDIMAG:
  357. _data->InsertTuple1(id, std::imag(Efield[nbin](ifc, irec)));
  358. break;
  359. }
  360. _pos->InsertTuple1(id, Locations(isc, irec));
  361. ++id;
  362. }
  363. vtkFieldData *_fieldData = vtkFieldData::New();
  364. _fieldData->AllocateArrays(2);
  365. _fieldData->AddArray(_data);
  366. _fieldData->AddArray(_pos);
  367. vtkDataObject *_dataObject = vtkDataObject::New();
  368. _dataObject->SetFieldData(_fieldData);
  369. _data->Delete();
  370. _pos->Delete();
  371. _fieldData->Delete();
  372. return _dataObject;
  373. }
  374. vtkDataObject* FieldPoints::GetVtkDataObjectFreq(const FIELDTYPE &ftype,
  375. const int& nrec,
  376. const int& fstart, const int& fend,
  377. const FIELDCOMPONENT& fcomp,
  378. const VectorXr& Freqs) {
  379. if (fstart < 0) throw 77;
  380. //if (fend > NumberOfFrequencies) throw 78;
  381. if (fstart > fend) throw 79;
  382. int ifc(-1);
  383. switch (fcomp) {
  384. case XCOMPONENT:
  385. ifc = 0;
  386. break;
  387. case YCOMPONENT:
  388. ifc = 1;
  389. break;
  390. case ZCOMPONENT:
  391. ifc = 2;
  392. break;
  393. }
  394. vtkDoubleArray *_data = vtkDoubleArray::New();
  395. _data->SetNumberOfComponents(1);
  396. vtkDoubleArray *_pos = vtkDoubleArray::New();
  397. _pos->SetNumberOfComponents(1);
  398. int id=0;
  399. //std::cout.precision(12);
  400. for (int ifreq=fstart; ifreq<fend; ++ifreq) {
  401. switch (ftype) {
  402. case HFIELDREAL:
  403. _data->InsertTuple1(id, std::real(Hfield[ifreq](ifc, nrec)));
  404. //std::cout << Hfield[ifreq](ifc, nrec) << std::endl;
  405. break;
  406. case HFIELDIMAG:
  407. _data->InsertTuple1(id, std::imag(Hfield[ifreq](ifc, nrec)));
  408. break;
  409. case EFIELDREAL:
  410. _data->InsertTuple1(id, std::real(Efield[ifreq](ifc, nrec)));
  411. break;
  412. case EFIELDIMAG:
  413. _data->InsertTuple1(id, std::imag(Efield[ifreq](ifc, nrec)));
  414. break;
  415. }
  416. _pos->InsertTuple1(id, Freqs[ifreq]);
  417. ++id;
  418. }
  419. vtkFieldData *_fieldData = vtkFieldData::New();
  420. _fieldData->AllocateArrays(2);
  421. _fieldData->AddArray(_data);
  422. _fieldData->AddArray(_pos);
  423. vtkDataObject *_dataObject = vtkDataObject::New();
  424. _dataObject->SetFieldData(_fieldData);
  425. _data->Delete();
  426. _pos->Delete();
  427. _fieldData->Delete();
  428. return _dataObject;
  429. }
  430. #endif
  431. }