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 17KB

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