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.

uthantenna.cpp 8.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. // ===========================================================================
  2. //
  3. // Filename: hantenna.cpp
  4. //
  5. // Created: 10/07/2010 08:57:04 AM
  6. // Modified: 14 Aug 2012
  7. // Compiler: Tested with g++, icpc, and MSVC 2010
  8. //
  9. // Author: Trevor Irons (ti)
  10. //
  11. // Copyright (C) 2011 Broken Spoke Development, LLC
  12. // Copyright (C) 2012 Trevor Irons
  13. //
  14. // Organisation: Colorado School of Mines (CSM)
  15. //
  16. // Email: tirons@mines.edu
  17. //
  18. // This program is free software: you can redistribute it and/or modify
  19. // it under the terms of the GNU General Public License as published by
  20. // the Free Software Foundation, either version 3 of the License, or
  21. // (at your option) any later version.
  22. //
  23. // This program is distributed in the hope that it will be useful,
  24. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26. // GNU General Public License for more details.
  27. //
  28. // You should have received a copy of the GNU General Public License
  29. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  30. //
  31. // ===========================================================================
  32. /**
  33. @file
  34. @author Trevor Irons
  35. @date 10/07/2010
  36. @version $Revision: 208 $
  37. $Id$
  38. **/
  39. #include "receiverpoints.h"
  40. #include "emearth1d.h"
  41. #include "PolygonalWireAntenna.h"
  42. #ifdef LEMMAUSEOMP
  43. #include "omp.h"
  44. #endif
  45. #include "timer.h"
  46. using namespace Lemma;
  47. std::vector<Real> readinpfile(const std::string& fname);
  48. std::vector<std::string> readinpfile2(const std::string& fname);
  49. int main(int argc, char** argv) {
  50. std::cout <<
  51. "\n"
  52. << "hantenna- $Date: 2015-01-26 10:11:24 -0700 (Mon, 26 Jan 2015) $ $Revision: 208 $\n\n"
  53. << "hantenna is a programme for computing the h field from polygonal wire\n"
  54. << "loop sources \n\n"
  55. << "hantenna was built using Lemma (Lemma is an Electromagnetics Modelling API)\n"
  56. << "Lemma is Free and Open Source Software (FOSS) and is released under\n"
  57. << "the MPL, it is covered by the following copyrights:\n"
  58. << "Copyright (C) 2009, 2010, 2011, 2012 Colorado School of Mines\n"
  59. << "Copyright (C) 2009, 2010, 2011, 2012 Trevor P. Irons\n"
  60. << "Copyright (C) 2011, 2012 M. Andy Kass\n\n"
  61. << "More information may be found at: https://lemmasoftware.org\n"
  62. << " info@lemmasoftware.org\n\n"
  63. << "=====================================================================\n"
  64. << "This programme is part of Lemma, a geophysical modelling and inversion API \n"
  65. << "This Source Code Form is subject to the terms of the Mozilla Public\n"
  66. << "License, v. 2.0. If a copy of the MPL was not distributed with this\n"
  67. << "file, You can obtain one at http://mozilla.org/MPL/2.0/. \n"
  68. << "=====================================================================\n\n\n";
  69. if (argc < 5) {
  70. std::cout << "usage: hantenna.exe trans.inp cond.inp points.inp config.inp \n";
  71. exit(0);
  72. }
  73. #ifdef LEMMAUSEOMP
  74. std::cout << "OpenMP is using " << omp_get_max_threads() << " threads" << std::endl;
  75. #endif
  76. std::vector<Real> Trans = readinpfile(std::string(argv[1]));
  77. std::vector<Real> CondMod = readinpfile(std::string(argv[2]));
  78. std::vector<Real> Points = readinpfile(std::string(argv[3]));
  79. std::vector<std::string> config = readinpfile2(std::string(argv[4]));
  80. //////////////////////////////////////
  81. // Define transmitter
  82. PolygonalWireAntenna* trans = PolygonalWireAntenna::New();
  83. trans->SetNumberOfPoints((int)(Trans[0]));
  84. int ip=1;
  85. for ( ; ip<=(int)(Trans[0])*2; ip+=2) {
  86. trans->SetPoint(ip/2, Vector3r (Trans[ip], Trans[ip+1], -1e-3));
  87. }
  88. trans->SetNumberOfFrequencies(1);
  89. trans->SetFrequency(0, Trans[ip]);
  90. trans->SetCurrent(Trans[ip+1]);
  91. trans->SetMinDipoleRatio(atof(config[1].c_str()));
  92. trans->SetMinDipoleMoment(atof(config[2].c_str()));
  93. trans->SetMaxDipoleMoment(atof(config[3].c_str()));
  94. // Receivers
  95. ReceiverPoints *receivers = ReceiverPoints::New();
  96. int nx = (int)Points[0];
  97. int ny = (int)Points[1];
  98. int nz = (int)Points[2];
  99. Real ox = Points[3];
  100. Real oy = Points[4];
  101. Real oz = Points[5];
  102. Vector3r loc;
  103. VectorXr dx(nx-1);
  104. VectorXr dy(ny-1);
  105. VectorXr dz(nz-1);
  106. ip = 6;
  107. int ir = 0;
  108. for ( ; ip <6+nx-1; ++ip) {
  109. dx[ir] = Points[ip];
  110. ++ir;
  111. }
  112. ir = 0;
  113. for ( ; ip <6+ny-1+nx-1; ++ip) {
  114. dy[ir] = Points[ip];
  115. ++ir;
  116. }
  117. ir = 0;
  118. for ( ; ip <6+nz-1+ny-1+nx-1; ++ip) {
  119. dz[ir] = Points[ip];
  120. ++ir;
  121. }
  122. receivers->SetNumberOfReceivers(nx*ny*nz);
  123. ir = 0;
  124. Real pz = oz;
  125. for (int iz=0; iz<nz; ++iz) {
  126. Real py = oy;
  127. for (int iy=0; iy<ny; ++iy) {
  128. Real px = ox;
  129. for (int ix=0; ix<nx; ++ix) {
  130. loc << px, py, pz;
  131. receivers->SetLocation(ir, loc);
  132. if (ix < nx-1) px += dx[ix];
  133. ++ ir;
  134. }
  135. if (iy<ny-1) py += dy[iy];
  136. }
  137. if (iz<nz-1) pz += dz[iz];
  138. }
  139. ////////////////////////////////////
  140. // Define model
  141. LayeredEarthEM *earth = LayeredEarthEM::New();
  142. VectorXcr sigma;
  143. VectorXr thick;
  144. earth->SetNumberOfLayers(CondMod[0]+1);
  145. sigma.resize(CondMod[0]+1); sigma(0) = 0; // airlayer
  146. thick.resize(CondMod[0]-1);
  147. int ilay=1;
  148. for ( ; ilay/2<CondMod[0]-1; ilay+=2) {
  149. sigma(ilay/2+1) = 1./CondMod[ilay];
  150. thick(ilay/2) = CondMod[ilay+1];
  151. }
  152. sigma(ilay/2+1) = 1./ CondMod[ilay];
  153. earth->SetLayerConductivity(sigma);
  154. if (thick.size() > 0) earth->SetLayerThickness(thick);
  155. EMEarth1D *EmEarth = EMEarth1D::New();
  156. EmEarth->AttachWireAntenna(trans);
  157. EmEarth->AttachLayeredEarthEM(earth);
  158. EmEarth->AttachReceiverPoints(receivers);
  159. EmEarth->SetFieldsToCalculate(H);
  160. EmEarth->SetHankelTransformMethod(string2Enum<HANKELTRANSFORMTYPE>(config[0]));
  161. EmEarth->SetHankelTransformMethod(FHTKEY201);
  162. // Keep track of time
  163. jsw_timer timer;
  164. timer.begin();
  165. clock_t launch = clock();
  166. EmEarth->CalculateWireAntennaFields(true); // true=status bar
  167. Real paTime = timer.end();
  168. std::cout << "\n\n===========================================\ncalc. real time: " << paTime/60. << "\t[m]\n";
  169. std::cout << "calc. user time: " << (clock()-launch)/CLOCKS_PER_SEC/60. << "\t[CPU m]"
  170. << std::endl;
  171. ////////////////////////////////////
  172. // Report
  173. std::fstream hrep("hfield.yaml", std::ios::out);
  174. std::fstream hreal("hfield.dat", std::ios::out);
  175. hrep << *EmEarth << std::endl;
  176. hrep.close();
  177. //hreal << *trans << std::endl;
  178. //hreal << *earth << std::endl;
  179. hreal << "// Right hand coordinate system, z is positive down\n";
  180. hreal << "// x[m]\ty[m]\tz[m]\tHx[A/m]\tHy[A/m]\tHz[A/m]\n";
  181. hreal.precision(8);
  182. int i=0;
  183. for (int iz=0; iz<nz; ++iz) {
  184. for (int iy=0; iy<ny; ++iy) {
  185. for (int ix=0; ix<nx; ++ix) {
  186. hreal << receivers->GetLocation(i).transpose() << "\t";
  187. hreal << receivers->GetHfield(0, i).transpose() << "\n";
  188. ++i;
  189. }
  190. }
  191. }
  192. hreal.close();
  193. // Clean up
  194. EmEarth->Delete();
  195. earth->Delete();
  196. receivers->Delete();
  197. trans->Delete();
  198. }
  199. std::vector<Real> readinpfile(const std::string& fname) {
  200. std::string buf;
  201. char dump[255];
  202. std::vector<Real> vals;
  203. std::fstream input(fname.c_str(), std::ios::in);
  204. if (input.fail()) {
  205. std::cerr << "Input file " << fname << " failed to open\n";
  206. exit(EXIT_FAILURE);
  207. }
  208. while (input >> buf) {
  209. if (buf.substr(0,2) == "//") {
  210. input.getline(dump, 255);
  211. } else {
  212. vals.push_back( atof(buf.c_str() ));
  213. }
  214. }
  215. return vals;
  216. }
  217. std::vector<std::string> readinpfile2(const std::string& fname) {
  218. std::string buf;
  219. char dump[255];
  220. std::vector<std::string> vals;
  221. std::fstream input(fname.c_str(), std::ios::in);
  222. if (input.fail()) {
  223. std::cerr << "Input file " << fname << " failed to open\n";
  224. exit(EXIT_FAILURE);
  225. }
  226. while (input >> buf) {
  227. if (buf.substr(0,2) == "//") {
  228. input.getline(dump, 255);
  229. } else {
  230. vals.push_back( std::string(buf.c_str() ));
  231. }
  232. }
  233. return vals;
  234. }