Lemma is an Electromagnetics API
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

BenchKiHa.h 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  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 = 13;
  64. int ny = 13;
  65. int nz = 13;
  66. Delta = nx*ny*nz*1e-10;
  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 << "C++\n";
  96. timer.begin();
  97. EmEarth->MakeCalc3();
  98. Real lemmaTime = timer.end();
  99. auto lc = receivers->GetEfield( 0 );
  100. #ifdef KIHALEE_EM1D
  101. receivers->ClearFields();
  102. std::cout << "\nFORTRAN KiHa\n";
  103. timer.begin();
  104. EmEarth->MakeCalc();
  105. Real kihaTime = timer.end();
  106. auto fc = receivers->GetEfield( 0 ); //0,0);
  107. std::cout << "Lemma time:" << lemmaTime << "\tKiHa time:" << kihaTime << std::endl;
  108. std::cout.precision(16);
  109. std::cout << "Lemma norm |" << (lc).norm() << "|" << std::endl;
  110. std::cout << "KiHa norm |" << (fc).norm() << "|" << std::endl;
  111. std::cout << "Difference norm |" << (lc - fc).norm() << "|" << std::endl;
  112. TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
  113. #endif
  114. }
  115. void test_Hx() {
  116. dipole->SetType(MAGNETICDIPOLE);
  117. dipole->SetPolarisation(XPOLARISATION);
  118. // Put in a unit test that will be slow.
  119. std::cout << "C++\n";
  120. std::cout << "MAGNETICDIPOLE X polarisation" << std::endl;
  121. timer.begin();
  122. EmEarth->MakeCalc3();
  123. Real lemmaTime = timer.end();
  124. auto lc = receivers->GetEfield( 0 );
  125. #ifdef KIHALEE_EM1D
  126. receivers->ClearFields();
  127. std::cout << "\nFORTRAN KiHa\n";
  128. timer.begin();
  129. EmEarth->MakeCalc();
  130. Real kihaTime = timer.end();
  131. auto fc = receivers->GetEfield( 0 ); //0,0);
  132. std::cout << "Lemma time:" << lemmaTime << "\tKiHa time:" << kihaTime << std::endl;
  133. std::cout.precision(16);
  134. std::cout << "Lemma norm |" << (lc).norm() << "|" << std::endl;
  135. std::cout << "KiHa norm |" << (fc).norm() << "|" << std::endl;
  136. std::cout << "Difference norm |" << (lc - fc).norm() << "|" << std::endl;
  137. TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
  138. #endif
  139. }
  140. void test_Hy() {
  141. dipole->SetType(MAGNETICDIPOLE);
  142. dipole->SetPolarisation(YPOLARISATION);
  143. // Put in a unit test that will be slow.
  144. std::cout << "C++\n";
  145. std::cout << "MAGNETICDIPOLE Y polarisation" << std::endl;
  146. timer.begin();
  147. EmEarth->MakeCalc3();
  148. Real lemmaTime = timer.end();
  149. auto lc = receivers->GetEfield( 0 );
  150. #ifdef KIHALEE_EM1D
  151. receivers->ClearFields();
  152. std::cout << "\nFORTRAN KiHa\n";
  153. timer.begin();
  154. EmEarth->MakeCalc();
  155. Real kihaTime = timer.end();
  156. auto fc = receivers->GetEfield( 0 ); //0,0);
  157. std::cout << "Lemma time:" << lemmaTime << "\tKiHa time:" << kihaTime << std::endl;
  158. std::cout.precision(16);
  159. std::cout << "Lemma norm |" << (lc).norm() << "|" << std::endl;
  160. std::cout << "KiHa norm |" << (fc).norm() << "|" << std::endl;
  161. std::cout << "Difference norm |" << (lc - fc).norm() << "|" << std::endl;
  162. TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
  163. #endif
  164. }
  165. void test_Ex() {
  166. dipole->SetType(GROUNDEDELECTRICDIPOLE);
  167. dipole->SetPolarisation(XPOLARISATION);
  168. // Put in a unit test that will be slow.
  169. std::cout << "C++\n";
  170. std::cout << "GROUNDEDELECTRICDIPOLE X polarisation" << std::endl;
  171. timer.begin();
  172. EmEarth->MakeCalc3();
  173. Real lemmaTime = timer.end();
  174. auto lc = receivers->GetEfield( 0 );
  175. #ifdef KIHALEE_EM1D
  176. receivers->ClearFields();
  177. std::cout << "\nFORTRAN KiHa\n";
  178. timer.begin();
  179. EmEarth->MakeCalc();
  180. Real kihaTime = timer.end();
  181. auto fc = receivers->GetEfield( 0 ); //0,0);
  182. std::cout << "Lemma time:" << lemmaTime << "\tKiHa time:" << kihaTime << std::endl;
  183. std::cout.precision(16);
  184. std::cout << "Lemma norm |" << (lc).norm() << "|" << std::endl;
  185. std::cout << "KiHa norm |" << (fc).norm() << "|" << std::endl;
  186. std::cout << "Difference norm |" << (lc - fc).norm() << "|" << std::endl;
  187. TS_ASSERT_DELTA((lc-fc).norm(), 0.0, Delta);
  188. #endif
  189. }
  190. };