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.

DCSurvey.cpp 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. /* This file is part of Lemma, a geophysical modelling and inversion API.
  2. * More information is available at http://lemmasoftware.org
  3. */
  4. /* This Source Code Form is subject to the terms of the Mozilla Public
  5. * License, v. 2.0. If a copy of the MPL was not distributed with this
  6. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  7. */
  8. /**
  9. * @file
  10. * @date 10/08/2014 01:52:04 PM
  11. * @version $Id$
  12. * @author Trevor Irons (ti)
  13. * @email Trevor.Irons@xri-geo.com
  14. * @copyright Copyright (c) 2014, XRI Geophysics, LLC
  15. * @copyright Copyright (c) 2014, Trevor Irons
  16. */
  17. #include "DCSurvey.h"
  18. namespace Lemma {
  19. // ==================== FRIEND METHODS =====================
  20. #ifdef HAVE_YAMLCPP
  21. std::ostream &operator << (std::ostream &stream, const DCSurvey &ob) {
  22. stream << ob.Serialize() << "\n---\n"; // End of doc --- a direct stream should encapsulate object
  23. return stream;
  24. }
  25. #else
  26. std::ostream &operator<<(std::ostream &stream, const DCSurvey &ob) {
  27. stream << *(LemmaObject*)(&ob);
  28. return stream;
  29. }
  30. #endif
  31. // ==================== LIFECYCLE =======================
  32. //--------------------------------------------------------------------------------------
  33. // Class: DCSurvey
  34. // Method: DCSurvey
  35. // Description: constructor (protected)
  36. //--------------------------------------------------------------------------------------
  37. DCSurvey::DCSurvey (const std::string& name) : LemmaObject(name) {
  38. } // ----- end of method DCSurvey::DCSurvey (constructor) -----
  39. //--------------------------------------------------------------------------------------
  40. // Class: DCSurvey
  41. // Method: DCSurvey
  42. // Description: DeSerializing constructor (protected)
  43. //--------------------------------------------------------------------------------------
  44. #ifdef HAVE_YAMLCPP
  45. DCSurvey::DCSurvey (const YAML::Node& node) : LemmaObject(node) {
  46. if (node.Tag() != "DCSurvey") {
  47. throw std::runtime_error("DCSurvey->DeSerialize cannot deserialize non-DCSurvey");
  48. }
  49. std::map<YAML::Node, int> eMap;
  50. for(YAML::const_iterator it=node["Electrodes"].begin(); it!=node["Electrodes"].end(); ++it) {
  51. std::string e = it->first.as<std::string>();
  52. Electrodes.push_back( DCIPElectrode::DeSerialize( node["Electrodes"][e] ) );
  53. Electrodes[Electrodes.size()-1]->AttachTo(this);
  54. eMap[ node["Electrodes"][Electrodes.size()-1] ] = Electrodes.size() -1 ;
  55. OrderedElectrodeLabels.push_back(e);
  56. ElectrodeLabelMap[e] = std::pair<DCIPElectrode*, int>(Electrodes[Electrodes.size()-1], Electrodes.size()-1);
  57. }
  58. //std::cout << "J-0\n" << node["Injections"]["J-0"] << std::endl;
  59. int ij = 0 ;
  60. for(YAML::const_iterator it=node["Injections"].begin(); it!=node["Injections"].end(); ++it) {
  61. //std::cout << "it->first" << it->first << std::endl;
  62. A_Electrodes.push_back( ElectrodeLabelMap[ it->second["A"]["Label"].as<std::string>() ].second );
  63. B_Electrodes.push_back( ElectrodeLabelMap[ it->second["B"]["Label"].as<std::string>() ].second );
  64. J_Electrodes.push_back( it->second["J"].as<Real>() );
  65. //std::string Jstr = it->first.as<std::string>(); // J-1
  66. M_Electrodes.push_back( std::vector<int>() );
  67. N_Electrodes.push_back( std::vector<int>() );
  68. for (int ii=0; ii<it->second["Measurements"]["Number"].as<int>(); ++ii) {
  69. std::string Mstr = std::string("V-") + to_string(ii);
  70. //std::cout << "measurements" << it->second["Measurements"][Mstr]["M"]["Label"] << std::endl;
  71. M_Electrodes[ij].push_back( ElectrodeLabelMap[ it->second["Measurements"][Mstr]["M"]["Label"].as<std::string>() ].second );
  72. N_Electrodes[ij].push_back( ElectrodeLabelMap[ it->second["Measurements"][Mstr]["N"]["Label"].as<std::string>() ].second );
  73. }
  74. ++ ij;
  75. }
  76. } // ----- end of method DCSurvey::DCSurvey (constructor) -----
  77. #endif
  78. //--------------------------------------------------------------------------------------
  79. // Class: DCSurvey
  80. // Method: New()
  81. // Description: public constructor
  82. //--------------------------------------------------------------------------------------
  83. DCSurvey* DCSurvey::New() {
  84. DCSurvey* Obj = new DCSurvey("DCSurvey");
  85. Obj->AttachTo(Obj);
  86. return Obj;
  87. }
  88. //--------------------------------------------------------------------------------------
  89. // Class: DCSurvey
  90. // Method: ~DCSurvey
  91. // Description: destructor (protected)
  92. //--------------------------------------------------------------------------------------
  93. DCSurvey::~DCSurvey () {
  94. } // ----- end of method DCSurvey::~DCSurvey (destructor) -----
  95. //--------------------------------------------------------------------------------------
  96. // Class: DCSurvey
  97. // Method: Delete
  98. // Description: public destructor
  99. //--------------------------------------------------------------------------------------
  100. void DCSurvey::Delete() {
  101. this->DetachFrom(this);
  102. }
  103. //--------------------------------------------------------------------------------------
  104. // Class: DCSurvey
  105. // Method: Release
  106. // Description: destructor (protected)
  107. //--------------------------------------------------------------------------------------
  108. void DCSurvey::Release() {
  109. this->PullElectrodes();
  110. delete this;
  111. }
  112. #ifdef HAVE_YAMLCPP
  113. //--------------------------------------------------------------------------------------
  114. // Class: DCSurvey
  115. // Method: Serialize
  116. //--------------------------------------------------------------------------------------
  117. YAML::Node DCSurvey::Serialize ( ) const {
  118. YAML::Node node = LemmaObject::Serialize();
  119. node.SetTag( this->Name );
  120. node["NumberOfElectrodes"] = Electrodes.size();
  121. // All the electrodes
  122. for (std::map<std::string, std::pair<DCIPElectrode*, int> >::const_iterator it = ElectrodeLabelMap.begin();
  123. it != ElectrodeLabelMap.end(); ++it) {
  124. node["Electrodes"][ it->first ] = it->second.first->Serialize();
  125. }
  126. // Injections and Measurements
  127. for (unsigned int ic=0; ic<A_Electrodes.size(); ++ic) {
  128. std::string strLab = std::string("J-") + to_string(ic);
  129. node["Injections"][strLab]["A"] = node["Electrodes"][ OrderedElectrodeLabels[ A_Electrodes[ic] ] ];
  130. node["Injections"][strLab]["B"] = node["Electrodes"][ OrderedElectrodeLabels[ B_Electrodes[ic] ] ];
  131. node["Injections"][strLab]["J"] = J_Electrodes[ic];
  132. node["Injections"][strLab]["Measurements"]["Number"] = M_Electrodes[ic].size();
  133. for (unsigned int iv=0; iv<M_Electrodes[ic].size(); ++iv) {
  134. node["Injections"][strLab]["Measurements"][std::string("V-") + to_string(iv)]["M"] =
  135. node["Electrodes"][ OrderedElectrodeLabels[M_Electrodes[ic][iv]] ];
  136. node["Injections"][strLab]["Measurements"][std::string("V-") + to_string(iv)]["N"] =
  137. node["Electrodes"][ OrderedElectrodeLabels[N_Electrodes[ic][iv]] ];
  138. }
  139. }
  140. return node;
  141. } // ----- end of method DCSurvey::Serialize -----
  142. //--------------------------------------------------------------------------------------
  143. // Class: DCSurvey
  144. // Method: DeSerialize
  145. //--------------------------------------------------------------------------------------
  146. DCSurvey* DCSurvey::DeSerialize ( const YAML::Node& node ) {
  147. DCSurvey* Object = new DCSurvey(node);
  148. Object->AttachTo(Object);
  149. DESERIALIZECHECK( node, Object )
  150. return Object ;
  151. } // ----- end of method DCSurvey::DeSerialize -----
  152. #endif
  153. //--------------------------------------------------------------------------------------
  154. // Class: DCSurvey
  155. // Method: PoundElectrode
  156. //--------------------------------------------------------------------------------------
  157. int DCSurvey::PoundElectrode ( DCIPElectrode* Electrode, const std::string& tag, const int&nodeID ) {
  158. Electrodes.push_back(Electrode);
  159. if (tag != "NULL") {
  160. OrderedElectrodeLabels.push_back(tag);
  161. //ElectrodeTagMap[tag] = Electrode;
  162. ElectrodeLabelMap[tag] = std::pair<DCIPElectrode*, int> (Electrode, Electrodes.size()-1);
  163. Electrode->SetLabel(tag);
  164. } else {
  165. OrderedElectrodeLabels.push_back( std::string("E") + to_string(Electrodes.size()-1) );
  166. //ElectrodeTagMap[std::string("E") + to_string(Electrodes.size()-1)] = Electrode;
  167. ElectrodeLabelMap[std::string("E") + to_string(Electrodes.size()-1)] =
  168. std::pair<DCIPElectrode*, int>(Electrode, Electrodes.size()-1);
  169. Electrode->SetLabel( std::string("E") + to_string(Electrodes.size()-1) );
  170. }
  171. Electrode->AttachTo(this);
  172. return static_cast<int>( Electrodes.size() ) ;
  173. } // ----- end of method DCSurvey::PoundElectrode -----
  174. //--------------------------------------------------------------------------------------
  175. // Class: DCSurvey
  176. // Method: PoundElectrode
  177. //--------------------------------------------------------------------------------------
  178. DCIPElectrode* DCSurvey::PoundElectrode ( const Vector3r& loc, const std::string& tag, const int& nodeID ) {
  179. DCIPElectrode* Electrode = DCIPElectrode::New();
  180. Electrode->SetLocation( loc );
  181. Electrodes.push_back(Electrode);
  182. if (tag != "NULL") {
  183. OrderedElectrodeLabels.push_back(tag);
  184. ElectrodeLabelMap[tag] = std::pair<DCIPElectrode*, int> (Electrode, Electrodes.size()-1);
  185. Electrode->SetLabel(tag);
  186. } else {
  187. OrderedElectrodeLabels.push_back( std::string("E") + to_string(Electrodes.size()-1) );
  188. ElectrodeLabelMap[std::string("E") + to_string(Electrodes.size()-1)] =
  189. std::pair<DCIPElectrode*, int>(Electrode, Electrodes.size()-1);
  190. Electrode->SetLabel( std::string("E") + to_string(Electrodes.size()-1) );
  191. }
  192. Electrode->AttachTo(this);
  193. return Electrode;
  194. } // ----- end of method DCSurvey::PoundElectrode -----
  195. //--------------------------------------------------------------------------------------
  196. // Class: DCSurvey
  197. // Method: PoundElectrode
  198. //--------------------------------------------------------------------------------------
  199. #ifdef LEMMAUSEVTK
  200. DCIPElectrode* DCSurvey::PoundElectrode( const int& nodeID, vtkDataSet* Mesh, const std::string& tag ) {
  201. DCIPElectrode* Electrode = DCIPElectrode::New();
  202. double* loc = Mesh->GetPoint(nodeID);
  203. Electrode->SetLocation( Vector3r(loc[0], loc[1], loc[2]) );
  204. Electrodes.push_back(Electrode);
  205. if (tag != "NULL") {
  206. OrderedElectrodeLabels.push_back(tag);
  207. ElectrodeLabelMap[tag] = std::pair<DCIPElectrode*, int> (Electrode, Electrodes.size()-1);
  208. Electrode->SetLabel(tag);
  209. } else {
  210. OrderedElectrodeLabels.push_back( std::string("E") + to_string(Electrodes.size()-1) );
  211. ElectrodeLabelMap[std::string("E") + to_string(Electrodes.size()-1)] =
  212. std::pair<DCIPElectrode*, int>(Electrode, Electrodes.size()-1);
  213. Electrode->SetLabel( std::string("E") + to_string(Electrodes.size()-1) );
  214. }
  215. Electrode->AttachTo(this);
  216. return Electrode;
  217. } // ----- end of method DCSurvey::PoundElectrode -----
  218. #endif
  219. //--------------------------------------------------------------------------------------
  220. // Class: DCSurvey
  221. // Method: PullElectrodes
  222. //--------------------------------------------------------------------------------------
  223. void DCSurvey::PullElectrodes ( ) {
  224. for (std::vector<DCIPElectrode*>::iterator it = Electrodes.begin() ; it != Electrodes.end(); ++it) {
  225. (*it)->DetachFrom(this);
  226. }
  227. Electrodes.clear();
  228. OrderedElectrodeLabels.clear();
  229. ElectrodeLabelMap.clear();
  230. A_Electrodes.clear();
  231. B_Electrodes.clear();
  232. M_Electrodes.clear();
  233. N_Electrodes.clear();
  234. return ;
  235. } // ----- end of method DCSurvey::PullElectrodes -----
  236. //--------------------------------------------------------------------------------------
  237. // Class: DCSurvey
  238. // Method: AddInjection
  239. //--------------------------------------------------------------------------------------
  240. int DCSurvey::AddInjection ( DCIPElectrode* A, DCIPElectrode* B, const Real& J ) {
  241. bool fA = false;
  242. bool fB = false;
  243. for (unsigned int i=0; i<Electrodes.size(); ++i) {
  244. if (Electrodes[i] == A) {
  245. A_Electrodes.push_back(i);
  246. M_Electrodes.push_back( std::vector<int>() );
  247. N_Electrodes.push_back( std::vector<int>() );
  248. fA = true;
  249. }
  250. if (Electrodes[i] == B) {
  251. B_Electrodes.push_back(i);
  252. fB = true;
  253. }
  254. if (fA == true && fB == true) break;
  255. }
  256. if (!fA) {
  257. throw std::runtime_error( "Injection point A not found" );
  258. }
  259. if (!fB) {
  260. throw std::runtime_error( "Injection point B not found" );
  261. }
  262. J_Electrodes.push_back(J);
  263. return A_Electrodes.size()-1; // we want index
  264. } // ----- end of method DCSurvey::AddInjection -----
  265. //--------------------------------------------------------------------------------------
  266. // Class: DCSurvey
  267. // Method: AddMeasurement
  268. //--------------------------------------------------------------------------------------
  269. void DCSurvey::AddMeasurement ( const int& iJ, DCIPElectrode* M, DCIPElectrode* N ) {
  270. bool fM = false;
  271. bool fN = false;
  272. for (unsigned int i=0; i<Electrodes.size(); ++i) {
  273. if (Electrodes[i] == M) {
  274. M_Electrodes[iJ].push_back(i);
  275. fM = true;
  276. }
  277. if (Electrodes[i] == N) {
  278. N_Electrodes[iJ].push_back(i);
  279. fN = true;
  280. }
  281. if (fM == true && fN == true) break;
  282. }
  283. if (!fM) {
  284. throw std::runtime_error( "Injection point M not found" );
  285. }
  286. if (!fN) {
  287. throw std::runtime_error( "Injection point N not found" );
  288. }
  289. return ;
  290. } // ----- end of method DCSurvey::AddMeasurement -----
  291. //--------------------------------------------------------------------------------------
  292. // Class: DCSurvey
  293. // Method: AddMeasurement
  294. //--------------------------------------------------------------------------------------
  295. void DCSurvey::AddMeasurement ( const int& iJ, const std::string& M, const std::string& N ) {
  296. std::pair<DCIPElectrode*, int> Mp = ElectrodeLabelMap[M];
  297. std::pair<DCIPElectrode*, int> Np = ElectrodeLabelMap[N];
  298. if (Mp.first == NULL) {
  299. throw std::runtime_error( "Injection point M not found" );
  300. }
  301. if (Np.first == NULL) {
  302. throw std::runtime_error( "Injection point N not found" );
  303. }
  304. M_Electrodes[iJ].push_back( Mp.second );
  305. N_Electrodes[iJ].push_back( Np.second );
  306. return ;
  307. } // ----- end of method DCSurvey::AddMeasurement -----
  308. //--------------------------------------------------------------------------------------
  309. // Class: DCSurvey
  310. // Method: GetA
  311. //--------------------------------------------------------------------------------------
  312. void DCSurvey::GetA (const int& iA, int& iB, Real& J ) {
  313. iB = Electrodes[A_Electrodes[iA]]->GetNodeID();
  314. J = J_Electrodes[iA];
  315. return ;
  316. } // ----- end of method DCSurvey::GetA -----
  317. //--------------------------------------------------------------------------------------
  318. // Class: DCSurvey
  319. // Method: GetB
  320. //--------------------------------------------------------------------------------------
  321. void DCSurvey::GetB (const int& iA, int& iB, Real& J ) {
  322. iB = Electrodes[B_Electrodes[iA]]->GetNodeID();
  323. J = -J_Electrodes[iA];
  324. return ;
  325. } // ----- end of method DCSurvey::GetA -----
  326. } // ----- end of Lemma name -----