Lemma is an Electromagnetics API
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

FieldPoints.cpp 16KB

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