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 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. }