Lemma is an Electromagnetics API
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

BenchKiHa.h 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  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 = 11; //13
  64. int ny = 11; //13
  65. int nz = 11; //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. std::cout.precision(4);
  92. dipole->SetType(MAGNETICDIPOLE);
  93. dipole->SetPolarisation(ZPOLARISATION);
  94. // Put in a unit test that will be slow.
  95. std::cout << "MAGNETICDIPOLE Z polarisation" << std::endl;
  96. std::cout << "=====================================\n";
  97. std::cout << std::setw(18) << "Lemma/C++: ";
  98. std::cout.flush();
  99. timer.begin();
  100. EmEarth->MakeCalc3();
  101. Real lemmaTime = timer.end();
  102. std::cout << std::setw(14) << lemmaTime << std::setw(6) << " [s]" << std::endl;
  103. auto lc = receivers->GetEfield( 0 );
  104. #ifdef KIHALEE_EM1D
  105. receivers->ClearFields();
  106. std::cout << std::setw(18) << "KiHa/Fortran: ";
  107. std::cout.flush();
  108. timer.begin();
  109. EmEarth->MakeCalc();
  110. Real kihaTime = timer.end();
  111. std::cout << std::setw(14) << kihaTime << std::setw(6) << " [s]" << std::endl;
  112. auto fc = receivers->GetEfield( 0 ); //0,0);
  113. //std::cout.precision(16);
  114. std::cout << std::setw(18) << "Lemma norm: " << std::setw(14) << (lc).norm() << std::endl;
  115. std::cout << std::setw(18) << "KiHa norm: " << std::setw(14) << (fc).norm() << std::endl;
  116. std::cout << std::setw(18) << "Difference norm: " << std::setw(14) << (lc - fc).norm() << "\n";
  117. std::cout << std::setw(18) << "Speedup: " << std::setw(14) << kihaTime/lemmaTime << "\n" << std::endl;
  118. TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
  119. #endif
  120. }
  121. void test_Hx() {
  122. std::cout.precision(4);
  123. dipole->SetType(MAGNETICDIPOLE);
  124. dipole->SetPolarisation(XPOLARISATION);
  125. // Put in a unit test that will be slow.
  126. std::cout << "MAGNETICDIPOLE X polarisation" << std::endl;
  127. std::cout << "=====================================\n";
  128. std::cout << std::setw(18) << "Lemma/C++: ";
  129. std::cout.flush();
  130. timer.begin();
  131. EmEarth->MakeCalc3();
  132. Real lemmaTime = timer.end();
  133. std::cout << std::setw(14) << lemmaTime << std::setw(6) << " [s]" << std::endl;
  134. auto lc = receivers->GetEfield( 0 );
  135. #ifdef KIHALEE_EM1D
  136. receivers->ClearFields();
  137. std::cout << std::setw(18) << "KiHa/Fortran: ";
  138. timer.begin();
  139. EmEarth->MakeCalc();
  140. Real kihaTime = timer.end();
  141. std::cout << std::setw(14) << kihaTime << std::setw(6) << " [s]" << std::endl;
  142. auto fc = receivers->GetEfield( 0 ); //0,0);
  143. //std::cout.precision(16);
  144. std::cout << std::setw(18) << "Lemma norm: " << std::setw(14) << (lc).norm() << std::endl;
  145. std::cout << std::setw(18) << "KiHa norm: " << std::setw(14) << (fc).norm() << std::endl;
  146. std::cout << std::setw(18) << "Difference norm: " << std::setw(14) << (lc - fc).norm() << "\n";
  147. std::cout << std::setw(18) << "Speedup: " << std::setw(14) << kihaTime/lemmaTime << "\n" << std::endl;
  148. TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
  149. #endif
  150. }
  151. void test_Hy() {
  152. std::cout.precision(4);
  153. dipole->SetType(MAGNETICDIPOLE);
  154. dipole->SetPolarisation(YPOLARISATION);
  155. // Put in a unit test that will be slow.
  156. std::cout << "MAGNETICDIPOLE Y polarisation" << std::endl;
  157. std::cout << "=====================================\n";
  158. std::cout << std::setw(18) << "Lemma/C++: ";
  159. std::cout.flush();
  160. timer.begin();
  161. EmEarth->MakeCalc3();
  162. Real lemmaTime = timer.end();
  163. std::cout << std::setw(14) << lemmaTime << std::setw(6) << " [s]" << std::endl;
  164. auto lc = receivers->GetEfield( 0 );
  165. #ifdef KIHALEE_EM1D
  166. receivers->ClearFields();
  167. std::cout << std::setw(18) << "KiHa/Fortran: ";
  168. std::cout.flush();
  169. timer.begin();
  170. EmEarth->MakeCalc();
  171. Real kihaTime = timer.end();
  172. std::cout << std::setw(14) << kihaTime << std::setw(6) << " [s]" << std::endl;
  173. auto fc = receivers->GetEfield( 0 ); //0,0);
  174. //std::cout.precision(16);
  175. std::cout << std::setw(18) << "Lemma norm: " << std::setw(14) << (lc).norm() << std::endl;
  176. std::cout << std::setw(18) << "KiHa norm: " << std::setw(14) << (fc).norm() << std::endl;
  177. std::cout << std::setw(18) << "Difference norm: " << std::setw(14) << (lc - fc).norm() << "\n";
  178. std::cout << std::setw(18) << "Speedup: " << std::setw(14) << kihaTime/lemmaTime << "\n" << std::endl;
  179. TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
  180. #endif
  181. }
  182. void test_Ex() {
  183. std::cout.precision(4);
  184. dipole->SetType(GROUNDEDELECTRICDIPOLE);
  185. dipole->SetPolarisation(XPOLARISATION);
  186. // Put in a unit test that will be slow.
  187. std::cout << "GROUNDEDELECTRICDIPOLE X polarisation" << std::endl;
  188. std::cout << "=====================================\n";
  189. std::cout << std::setw(18) << "Lemma/C++: ";
  190. std::cout.flush();
  191. timer.begin();
  192. EmEarth->MakeCalc3();
  193. Real lemmaTime = timer.end();
  194. std::cout << std::setw(14) << lemmaTime << std::setw(6) << " [s]" << std::endl;
  195. auto lc = receivers->GetEfield( 0 );
  196. #ifdef KIHALEE_EM1D
  197. receivers->ClearFields();
  198. std::cout << std::setw(18) << "KiHa/Fortran: ";
  199. std::cout.flush();
  200. timer.begin();
  201. EmEarth->MakeCalc();
  202. Real kihaTime = timer.end();
  203. std::cout << std::setw(14) << kihaTime << std::setw(6) << " [s]" << std::endl;
  204. auto fc = receivers->GetEfield( 0 ); //0,0);
  205. //std::cout.precision(16);
  206. std::cout << std::setw(18) << "Lemma norm: " << std::setw(14) << (lc).norm() << std::endl;
  207. std::cout << std::setw(18) << "KiHa norm: " << std::setw(14) << (fc).norm() << std::endl;
  208. std::cout << std::setw(18) << "Difference norm: " << std::setw(14) << (lc - fc).norm() << "\n";
  209. std::cout << std::setw(18) << "Speedup: " << std::setw(14) << kihaTime/lemmaTime << "\n" << std::endl;
  210. TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
  211. #endif
  212. }
  213. void test_Ey() {
  214. std::cout.precision(4);
  215. dipole->SetType(GROUNDEDELECTRICDIPOLE);
  216. dipole->SetPolarisation(YPOLARISATION);
  217. // Put in a unit test that will be slow.
  218. std::cout << "GROUNDEDELECTRICDIPOLE Y polarisation" << std::endl;
  219. std::cout << "=====================================\n";
  220. std::cout << std::setw(18) << "Lemma/C++: ";
  221. std::cout.flush();
  222. timer.begin();
  223. EmEarth->MakeCalc3();
  224. Real lemmaTime = timer.end();
  225. std::cout << std::setw(14) << lemmaTime << std::setw(6) << " [s]" << std::endl;
  226. auto lc = receivers->GetEfield( 0 );
  227. #ifdef KIHALEE_EM1D
  228. receivers->ClearFields();
  229. std::cout << std::setw(18) << "KiHa/Fortran: ";
  230. std::cout.flush();
  231. timer.begin();
  232. EmEarth->MakeCalc();
  233. Real kihaTime = timer.end();
  234. std::cout << std::setw(14) << kihaTime << std::setw(6) << " [s]" << std::endl;
  235. auto fc = receivers->GetEfield( 0 ); //0,0);
  236. //std::cout.precision(16);
  237. std::cout << std::setw(18) << "Lemma norm: " << std::setw(14) << (lc).norm() << std::endl;
  238. std::cout << std::setw(18) << "KiHa norm: " << std::setw(14) << (fc).norm() << std::endl;
  239. std::cout << std::setw(18) << "Difference norm: " << std::setw(14) << (lc - fc).norm() << "\n";
  240. std::cout << std::setw(18) << "Speedup: " << std::setw(14) << kihaTime/lemmaTime << "\n" << std::endl;
  241. TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
  242. #endif
  243. }
  244. void test_Ez() {
  245. std::cout.precision(4);
  246. dipole->SetType(GROUNDEDELECTRICDIPOLE);
  247. dipole->SetPolarisation(ZPOLARISATION);
  248. // Put in a unit test that will be slow.
  249. std::cout << "GROUNDEDELECTRICDIPOLE Z polarisation" << std::endl;
  250. std::cout << "=====================================\n";
  251. std::cout << std::setw(18) << "Lemma/C++: ";
  252. std::cout.flush();
  253. timer.begin();
  254. EmEarth->MakeCalc3();
  255. Real lemmaTime = timer.end();
  256. std::cout << std::setw(14) << lemmaTime << std::setw(6) << " [s]" << std::endl;
  257. auto lc = receivers->GetEfield( 0 );
  258. #ifdef KIHALEE_EM1D
  259. receivers->ClearFields();
  260. std::cout << std::setw(18) << "KiHa/Fortran: ";
  261. std::cout.flush();
  262. timer.begin();
  263. EmEarth->MakeCalc();
  264. Real kihaTime = timer.end();
  265. std::cout << std::setw(14) << kihaTime << std::setw(6) << " [s]" << std::endl;
  266. auto fc = receivers->GetEfield( 0 ); //0,0);
  267. //std::cout.precision(16);
  268. std::cout << std::setw(18) << "Lemma norm: " << std::setw(14) << (lc).norm() << std::endl;
  269. std::cout << std::setw(18) << "KiHa norm: " << std::setw(14) << (fc).norm() << std::endl;
  270. std::cout << std::setw(18) << "Difference norm: " << std::setw(14) << (lc - fc).norm() << "\n";
  271. std::cout << std::setw(18) << "Speedup: " << std::setw(14) << kihaTime/lemmaTime << "\n" << std::endl;
  272. TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
  273. #endif
  274. }
  275. };