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.

uttemsandbox.cpp 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. // ===========================================================================
  2. //
  3. // Filename: uttemsandbox.cpp
  4. //
  5. // Created: 09/29/2010 07:38:26 AM
  6. // Compiler: Tested with g++, icpc, and MSVC 2010
  7. //
  8. // Author: Trevor Irons (ti), M. Andy Kass
  9. //
  10. //
  11. // Organisation: Colorado School of Mines (CSM)
  12. // United States Geological Survey (USGS)
  13. // Broken Spoke Development, LLC
  14. //
  15. // Email: tirons@mines.edu, tirons@usgs.gov
  16. // mkass@numericalgeo.com
  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 09/29/2010
  36. @version 0.0
  37. **/
  38. #include "Lemma"
  39. using namespace Lemma;
  40. #ifdef LEMMAUSEVTK
  41. #include "matplot.h"
  42. using namespace matplot;
  43. #endif
  44. int main() {
  45. int nfreq = 6000; // Number of frequencies
  46. // Specify receiver times
  47. int ntimes = 30;
  48. VectorXr times(ntimes);
  49. times <<
  50. 36.0, 45.25, 57.0, 72.25, 92.0,
  51. 117.0, 148.0, 186.5, 234.0, 290.0,
  52. 352.5, 427.5, 525.0, 647.5, 802.5,
  53. 1002.5, 1257.5, 1582.5, 1997.5, 2525.0,
  54. 3197.5, 4055.0, 5147.5, 6542.5, 8322.5,
  55. 10592.0, 13490.0, 17187.0, 21902.0, 27915.0;
  56. times = times.array()*1.0e-6;
  57. //CALCULATE ABSCISSA
  58. //define bounds
  59. gaussianquadrature *lgqw = gaussianquadrature::New();
  60. Real lowb;
  61. Real upb;
  62. lowb = 1.0;
  63. upb = 6000000.0;
  64. lgqw->SetFreqs(nfreq,upb,lowb);
  65. lgqw->CalcAW();
  66. VectorXr xu(nfreq);
  67. xu=lgqw->GetAbscissae();
  68. DipoleSource* Trans=DipoleSource::New();
  69. Trans->SetType(MAGNETICDIPOLE);
  70. Trans->SetPolarisation(ZPOLARISATION);
  71. Trans->SetLocation(0.0,0.0,-1e-4);
  72. // Specify Transmitter
  73. //PolygonalWireAntenna* Trans = PolygonalWireAntenna::New();
  74. //Trans->SetNumberOfPoints(5);
  75. //Trans->SetPoint(0, Vector3r( 0, 0, -1e-3));
  76. //Trans->SetPoint(1, Vector3r( 100, 0, -1e-3));
  77. //Trans->SetPoint(2, Vector3r( 100, 100, -1e-3));
  78. //Trans->SetPoint(3, Vector3r( 0, 100, -1e-3));
  79. //Trans->SetPoint(4, Vector3r( 0, 0, -1e-3));
  80. Trans->SetNumberOfFrequencies(nfreq);
  81. VectorXr f(nfreq);
  82. for (int ifreq=0; ifreq<nfreq; ++ifreq) {
  83. // Trans->SetFrequency(ifreq, 1e-3 + dfreq*(Real)(ifreq));
  84. Trans->SetFrequency(ifreq,xu(ifreq));
  85. f(ifreq) = xu(ifreq);
  86. }
  87. //cout << Trans->GetFrequencies();
  88. //Trans->SetCurrent(1);
  89. //Trans->SetNumberOfTurns(1);
  90. // Earth properties, top layer is air layer 0 conductivity is fine
  91. LayeredEarthEM *Earth = LayeredEarthEM::New();
  92. Earth->SetNumberOfLayers(4);
  93. Earth->SetLayerConductivity( (VectorXcr(4) << 0.,1.e-6,1.e-2,1.e-6 ).finished() );
  94. Earth->SetLayerThickness( (VectorXr(2) << 50, 20).finished() );
  95. // Receivers, just 1 in the centre for now
  96. ReceiverPoints *Receivers = ReceiverPoints::New();
  97. Vector3r loc;
  98. Real ox = 50.;
  99. Real oy = 50.;
  100. Real depth = -1e-2;
  101. Receivers->SetNumberOfReceivers(1);
  102. loc << ox, oy, depth;
  103. Receivers->SetLocation(0, loc);
  104. // EmEarth
  105. EMEarth1D *EmEarth = EMEarth1D::New();
  106. //EmEarth->AttachWireAntenna(Trans);
  107. EmEarth->AttachDipoleSource(Trans);
  108. EmEarth->AttachLayeredEarthEM(Earth);
  109. EmEarth->AttachReceiverPoints(Receivers);
  110. EmEarth->SetFieldsToCalculate(H);
  111. // slower but may be more accurate, depending on frequencies
  112. EmEarth->SetHankelTransformMethod(CHAVE);
  113. //EmEarth->SetHankelTransformMethod(DIGITALFILTERING);
  114. // Do calculation
  115. //EmEarth->CalculateWireAntennaFields();
  116. //EmEarth->MakeCalc();
  117. EmEarth->MakeCalc3();
  118. // Grab Z component
  119. // A little painful, I'll try to clean up the API
  120. VectorXcr Hw(nfreq);
  121. VectorXr e(nfreq);
  122. Hw(0) = 0.; // DC component
  123. for (int ifreq=0; ifreq<nfreq; ++ifreq) {
  124. Hw(ifreq) = (Receivers->GetHfield(ifreq, 0))(2);
  125. e(ifreq) = ifreq;
  126. }
  127. VectorXr Ht(ntimes); // Time domain H field
  128. //Sine transform
  129. VectorXr func(nfreq);
  130. for (int ii=0;ii<ntimes;++ii) {
  131. func = (Hw.imag().array()*((f.array()*times(ii)).sin()));
  132. lgqw->SetFunc(func);
  133. lgqw->Integrate();
  134. Ht(ii)=lgqw->GetResult();
  135. }
  136. Ht = Ht.array()*(-2.0/PI);
  137. std::ofstream myfile1;
  138. myfile1.open("solution.txt");
  139. for (int ii=0;ii<ntimes;++ii) {
  140. myfile1 << times(ii) << " " << Ht(ii) << std::endl;
  141. }
  142. myfile1.close();
  143. std::ofstream myfile2;
  144. myfile2.open("freq_domain.txt");
  145. for (int ii=0;ii<nfreq;++ii) {
  146. myfile2 << f(ii) << " " << Hw(ii).real() << " " << Hw(ii).imag()
  147. << std::endl;
  148. }
  149. myfile2.close();
  150. //std::cout << Ht << std::endl;
  151. //std::cout << Hw.real() << std::endl;
  152. // Quick and dirty plot
  153. #ifdef LEMMAUSEVTK
  154. double colour1[3] = {0.0,0.0,1.0};
  155. double colour2[3] = {1.0,0.0,0.0};
  156. Plot2D_VTK p1("Hz", "Re(Hw)", 800, 600);
  157. p1.plot(f, Hw.real().eval(), colour1, ".-");
  158. p1.show();
  159. Plot2D_VTK p2("Hz", "Im(Hw)", 800, 600);
  160. p2.plot(f, Hw.imag().eval(), colour2, ".-");
  161. p2.show();
  162. Plot2D_VTK p3("Time (seconds)", "Ht", 800, 600);
  163. p3.plot(times, Ht, colour2, ".-");
  164. p3.show();
  165. //Plot2D_VTK p4("index", "frequency",800,600);
  166. //p4.plot(e,f,colour1,".-");
  167. //p4.show();
  168. #endif
  169. // Clean up
  170. Trans->Delete();
  171. Earth->Delete();
  172. Receivers->Delete();
  173. EmEarth->Delete();
  174. return EXIT_SUCCESS;
  175. }