Main Lemma Repository
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.

BenchKiHa.h 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  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 02/01/19 22:34:11
  11. * @version $Id$
  12. * @author Trevor Irons (ti)
  13. * @email Trevor.Irons@utah.edu
  14. * @copyright Copyright (c) 2019, University of Utah
  15. * @copyright Copyright (c) 2019, Lemma Software, LLC
  16. */
  17. #include <cxxtest/TestSuite.h>
  18. #include <FDEM1D>
  19. #include <random>
  20. #include "timer.h"
  21. #define EPSILON 1e-10
  22. using namespace Lemma;
  23. class MyAlgorithmTest : public CxxTest::TestSuite {
  24. // Put in your usual, quick unit tests here
  25. };
  26. class MyAlgorithmTestPerformance : public CxxTest::TestSuite {
  27. public:
  28. std::shared_ptr< DipoleSource > dipole;
  29. std::shared_ptr< LayeredEarthEM > earth;
  30. std::shared_ptr< FieldPoints > receivers;
  31. std::shared_ptr< EMEarth1D > EmEarth;
  32. jsw_timer timer;
  33. Real Delta;
  34. void setUp() {
  35. // Put in any code needed to set up your test,
  36. // but that should NOT be counted in the execution time.
  37. dipole = DipoleSource::NewSP();
  38. //dipole->SetType(GROUNDEDELECTRICDIPOLE);
  39. //dipole->SetPolarisation(XPOLARISATION);
  40. dipole->SetNumberOfFrequencies(1);
  41. dipole->SetMoment(1);
  42. dipole->SetFrequency(0, 4400.1000);
  43. //dipole->SetPhase(0);
  44. //dipole->SetLocation( (VectorXr(3) << 49, 49, -1e-4).finished() );
  45. dipole->SetLocation( 0, 0, -1e-1 );
  46. // Define model
  47. VectorXcr sigma(8);
  48. sigma << 0., 1e-2, .1, .01, .001, .1, .05, .2;
  49. VectorXr thick(6);
  50. thick << 10, 10, 10, 10, 10;
  51. earth = LayeredEarthEM::NewSP();
  52. earth->SetNumberOfLayers(8);
  53. earth->SetLayerConductivity(sigma);
  54. earth->SetLayerThickness(thick);
  55. receivers = FieldPoints::NewSP();
  56. Vector3r loc;
  57. Real ox = 250.;
  58. Real oy = 250.;
  59. Real oz = -250.;
  60. Real dx = 20;
  61. Real dy = 20;
  62. Real dz = 20;
  63. int nx = 5; //13
  64. int ny = 5; //13
  65. int nz = 5; //13
  66. Delta = nx*ny*nz*1e-9;
  67. receivers->SetNumberOfPoints(nx*ny*nz);
  68. int ir = 0;
  69. for (int ix=0; ix<nx; ++ix) {
  70. for (int iy=0; iy<ny; ++iy) {
  71. for (int iz=0; iz<nz; ++iz) {
  72. loc << ox+ix*dx, oy+iy*dy, oz+iz*dz;
  73. //std::cout << "Receiver location " << loc.transpose() << std::endl;
  74. receivers->SetLocation(ir, loc);
  75. //oz += dz;
  76. ++ ir;
  77. }
  78. }
  79. }
  80. EmEarth = EMEarth1D::NewSP();
  81. EmEarth->SetHankelTransformMethod(CHAVE);
  82. EmEarth->SetFieldsToCalculate(BOTH); // Fortran needs this
  83. EmEarth->AttachDipoleSource(dipole);
  84. EmEarth->AttachLayeredEarthEM(earth);
  85. EmEarth->AttachFieldPoints(receivers);
  86. }
  87. void tearDown() {
  88. // Clean-up code, also NOT counted in execution time.
  89. }
  90. void test_Hz() {
  91. dipole->SetType(MAGNETICDIPOLE);
  92. dipole->SetPolarisation(ZPOLARISATION);
  93. // Put in a unit test that will be slow.
  94. std::cout << "MAGNETICDIPOLE Z polarisation" << std::endl;
  95. std::cout << "=====================================\n";
  96. std::cout << "Lemma/C++: ";
  97. std::cout.flush();
  98. timer.begin();
  99. EmEarth->MakeCalc3();
  100. Real lemmaTime = timer.end();
  101. std::cout << lemmaTime << " [s]" << std::endl;
  102. auto lc = receivers->GetEfield( 0 );
  103. #ifdef KIHALEE_EM1D
  104. receivers->ClearFields();
  105. std::cout << "FORTRAN KiHa: ";
  106. std::cout.flush();
  107. timer.begin();
  108. EmEarth->MakeCalc();
  109. Real kihaTime = timer.end();
  110. std::cout << kihaTime << " [s]" << std::endl;
  111. auto fc = receivers->GetEfield( 0 ); //0,0);
  112. std::cout.precision(16);
  113. std::cout << "Lemma norm |" << (lc).norm() << "|" << std::endl;
  114. std::cout << "KiHa norm |" << (fc).norm() << "|" << std::endl;
  115. std::cout << "Difference norm |" << (lc - fc).norm() << "|\n";
  116. std::cout << "Speedup:" << kihaTime/lemmaTime << "\n" << std::endl;
  117. TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
  118. #endif
  119. }
  120. void test_Hx() {
  121. dipole->SetType(MAGNETICDIPOLE);
  122. dipole->SetPolarisation(XPOLARISATION);
  123. // Put in a unit test that will be slow.
  124. std::cout << "MAGNETICDIPOLE X polarisation" << std::endl;
  125. std::cout << "=====================================\n";
  126. std::cout << "Lemma/C++: ";
  127. std::cout.flush();
  128. timer.begin();
  129. EmEarth->MakeCalc3();
  130. Real lemmaTime = timer.end();
  131. std::cout << lemmaTime << " [s]" << std::endl;
  132. auto lc = receivers->GetEfield( 0 );
  133. #ifdef KIHALEE_EM1D
  134. receivers->ClearFields();
  135. std::cout << "FORTRAN KiHa: ";
  136. timer.begin();
  137. EmEarth->MakeCalc();
  138. Real kihaTime = timer.end();
  139. std::cout << kihaTime << " [s]" << std::endl;
  140. auto fc = receivers->GetEfield( 0 ); //0,0);
  141. std::cout.precision(16);
  142. std::cout << "Lemma norm |" << (lc).norm() << "|" << std::endl;
  143. std::cout << "KiHa norm |" << (fc).norm() << "|" << std::endl;
  144. std::cout << "Difference norm |" << (lc - fc).norm() << "|\n";
  145. std::cout << "Speedup:" << kihaTime/lemmaTime << "\n" << std::endl;
  146. TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
  147. #endif
  148. }
  149. void test_Hy() {
  150. dipole->SetType(MAGNETICDIPOLE);
  151. dipole->SetPolarisation(YPOLARISATION);
  152. // Put in a unit test that will be slow.
  153. std::cout << "MAGNETICDIPOLE Y polarisation" << std::endl;
  154. std::cout << "=====================================\n";
  155. std::cout << "Lemma/C++: ";
  156. std::cout.flush();
  157. timer.begin();
  158. EmEarth->MakeCalc3();
  159. Real lemmaTime = timer.end();
  160. std::cout << lemmaTime << " [s]" << std::endl;
  161. auto lc = receivers->GetEfield( 0 );
  162. #ifdef KIHALEE_EM1D
  163. receivers->ClearFields();
  164. std::cout << "FORTRAN KiHa: ";
  165. std::cout.flush();
  166. timer.begin();
  167. EmEarth->MakeCalc();
  168. Real kihaTime = timer.end();
  169. std::cout << kihaTime << " [s]" << std::endl;
  170. auto fc = receivers->GetEfield( 0 ); //0,0);
  171. std::cout.precision(16);
  172. std::cout << "Lemma norm |" << (lc).norm() << "|" << std::endl;
  173. std::cout << "KiHa norm |" << (fc).norm() << "|" << std::endl;
  174. std::cout << "Difference norm |" << (lc - fc).norm() << "|\n";
  175. std::cout << "Speedup:" << kihaTime/lemmaTime << "\n" << std::endl;
  176. TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
  177. #endif
  178. }
  179. void test_Ex() {
  180. dipole->SetType(GROUNDEDELECTRICDIPOLE);
  181. dipole->SetPolarisation(XPOLARISATION);
  182. // Put in a unit test that will be slow.
  183. std::cout << "GROUNDEDELECTRICDIPOLE X polarisation" << std::endl;
  184. std::cout << "=====================================\n";
  185. std::cout << "Lemma/C++: ";
  186. std::cout.flush();
  187. timer.begin();
  188. EmEarth->MakeCalc3();
  189. Real lemmaTime = timer.end();
  190. std::cout << lemmaTime << " [s]" << std::endl;
  191. auto lc = receivers->GetEfield( 0 );
  192. #ifdef KIHALEE_EM1D
  193. receivers->ClearFields();
  194. std::cout << "FORTRAN KiHa: ";
  195. std::cout.flush();
  196. timer.begin();
  197. EmEarth->MakeCalc();
  198. Real kihaTime = timer.end();
  199. std::cout << kihaTime << " [s]" << std::endl;
  200. auto fc = receivers->GetEfield( 0 ); //0,0);
  201. std::cout.precision(16);
  202. std::cout << "Lemma norm |" << (lc).norm() << "|" << std::endl;
  203. std::cout << "KiHa norm |" << (fc).norm() << "|" << std::endl;
  204. std::cout << "Difference norm |" << (lc - fc).norm() << "|\n";
  205. std::cout << "Speedup:" << kihaTime/lemmaTime << "\n" << std::endl;
  206. TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
  207. #endif
  208. }
  209. void test_Ey() {
  210. dipole->SetType(GROUNDEDELECTRICDIPOLE);
  211. dipole->SetPolarisation(YPOLARISATION);
  212. // Put in a unit test that will be slow.
  213. std::cout << "GROUNDEDELECTRICDIPOLE Y polarisation" << std::endl;
  214. std::cout << "=====================================\n";
  215. std::cout << "Lemma/C++: ";
  216. std::cout.flush();
  217. timer.begin();
  218. EmEarth->MakeCalc3();
  219. Real lemmaTime = timer.end();
  220. std::cout << lemmaTime << " [s]" << std::endl;
  221. auto lc = receivers->GetEfield( 0 );
  222. #ifdef KIHALEE_EM1D
  223. receivers->ClearFields();
  224. std::cout << "KiHa/FORTRAN: ";
  225. std::cout.flush();
  226. timer.begin();
  227. EmEarth->MakeCalc();
  228. Real kihaTime = timer.end();
  229. std::cout << kihaTime << " [s]" << std::endl;
  230. auto fc = receivers->GetEfield( 0 ); //0,0);
  231. std::cout << "Lemma time:" << lemmaTime << "\tKiHa time:" << kihaTime << std::endl;
  232. std::cout.precision(16);
  233. std::cout << "Lemma norm |" << (lc).norm() << "|" << std::endl;
  234. std::cout << "KiHa norm |" << (fc).norm() << "|" << std::endl;
  235. std::cout << "Difference norm |" << (lc - fc).norm() << "|\n";
  236. std::cout << "Speedup:" << kihaTime/lemmaTime << "\n" << std::endl;
  237. TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
  238. #endif
  239. }
  240. void test_Ez() {
  241. dipole->SetType(GROUNDEDELECTRICDIPOLE);
  242. dipole->SetPolarisation(ZPOLARISATION);
  243. // Put in a unit test that will be slow.
  244. std::cout << "GROUNDEDELECTRICDIPOLE Z polarisation" << std::endl;
  245. std::cout << "=====================================\n";
  246. std::cout << "Lemma/C++: ";
  247. std::cout.flush();
  248. timer.begin();
  249. EmEarth->MakeCalc3();
  250. Real lemmaTime = timer.end();
  251. std::cout << lemmaTime << " [s]" << std::endl;
  252. auto lc = receivers->GetEfield( 0 );
  253. #ifdef KIHALEE_EM1D
  254. receivers->ClearFields();
  255. std::cout << "KiHa/FORTRAN: ";
  256. std::cout.flush();
  257. timer.begin();
  258. EmEarth->MakeCalc();
  259. Real kihaTime = timer.end();
  260. std::cout << kihaTime << " [s]" << std::endl;
  261. auto fc = receivers->GetEfield( 0 ); //0,0);
  262. std::cout << "Lemma time:" << lemmaTime << "\tKiHa time:" << kihaTime << std::endl;
  263. std::cout.precision(16);
  264. std::cout << "Lemma norm |" << (lc).norm() << "|" << std::endl;
  265. std::cout << "KiHa norm |" << (fc).norm() << "|" << std::endl;
  266. std::cout << "Difference norm |" << (lc - fc).norm() << "|\n";
  267. std::cout << "Speedup:" << kihaTime/lemmaTime << "\n" << std::endl;
  268. TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
  269. #endif
  270. }
  271. };