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.

lemma.h 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. /* This file is part of Lemma, a geophysical modelling and inversion API */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. /**
  6. @file
  7. @author Trevor Irons
  8. @date 06/19/2009 09:12:20 AM The Birth of Lemma!
  9. @version $Id: lemma.h 203 2015-01-09 21:19:04Z tirons $
  10. **/
  11. /** \mainpage Lemma is an ElectroMagnetics Modelling API
  12. \image html lemma.png
  13. \authors Trevor Irons and M. Andrew Kass and others
  14. Lemma is a recursive acronym that stands for <B>L</B>emma is an
  15. <B>E</B>lectro<B>M</B>agnetics <B>M</B>odelling <B>A</B>PI.
  16. Lemma is a cross-platform library delivering an expressive API that
  17. can be used to easily create versatile programs.
  18. We are building a powerful, flexible,
  19. expresive framework that allows for the straightforward creation of
  20. geophysical EM applications. Lemma is not itself a program, instead
  21. it is a collection of building blocks to make applications.
  22. We chose this name because:
  23. - In mathematics a Lemma is a proven proposition which is used as a
  24. stepping stone to a larger result rather than as a statement in-and-of
  25. itself.
  26. - In addition to the electromagnetic modelling, some other facilities are
  27. provided such as numerical optimization and inversion capabilities. These
  28. tools are also considered stepping stones to final products.
  29. We feel that this is a partucularily approprate name, as Lemma's
  30. API can be leveraged create powerful applications such as forward
  31. modelling and inverting frequency and time-domain
  32. surveys of arbitrary survey design, SNMR surveys, CSAMT and more.
  33. \section Motivation
  34. Why another Geophysical EM project? For starters, there
  35. aren't that many quality open source packages out there. Those that do
  36. exist are generally specialized to perform a single task and extending
  37. them is a major undertaking. Lemma's approach is much different, by
  38. providing a set of general tools users can easily assemble applications
  39. that suite their needs.
  40. While most geophysical EM modeling packages are concerned with forward
  41. modeling <B>DATA</B> between specific transmitters and receivers located
  42. on the surface of the earth; Lemma is fundamentally concerned with
  43. modelling <B>FIELDS</B> due to sources, the field values can be calculated
  44. everywhere within the domain. This allows for solving multiphysics EM
  45. problems. Tradional EM data may be forward modelled using the Lemma::Instrument
  46. classes.
  47. \section Capabilities Capabilities
  48. In the long term, we have many goals for this software project. Due to its
  49. design, Lemma can be built upon and extended easily. The initial aim is to
  50. provide flexible 1D and 3D EM modelling in the time and frequency domains.
  51. The project is still in beta, but we have made a lot of progress already.
  52. We will release our first non-beta release as soon as the following are
  53. supported.
  54. \subsection FDM Frequency-domain forward modelling
  55. Lemma was initially called EMMODFD: Electromagnetic Modelling in the Frequency
  56. Domain. As such this is the most mature area of Lemma.
  57. \par 1D
  58. Frequency domain solutions to electrical and magnetic dipoles can be computed
  59. quasi-analytically in 1D. Calculations can be made in or above the layered
  60. media, and complex electrical conductivity and magnetic susceptibility are
  61. supported according to the Cole-Cole model. Sources may be embdedded in the
  62. media or in the resisitive air layer. Lemma can also can compute fields due
  63. to arbitrarily shaped ungrounded wire loops, topography of the loops is also
  64. supported. Two separate approaches to solving the Hankel transform, one
  65. based on Anderson's digitial filtering technique, and another based on Gaussian
  66. quadrature.
  67. \par 3D
  68. A fast 3D solver that can modify the 1D results based
  69. on arbitrary electrical conductivity model is nearing completion.
  70. \par future work
  71. We are also planning on supporting grounded wires in the near future.
  72. \subsection TDM Time-domain forward modelling
  73. A 1D time-domain solution has been implemented that utilises both a
  74. dipole source as well as a wire loop. Currently, only one receiver is
  75. modelled at a time, but will be generalised. In addition, utilities
  76. to read in data files for modelling have been implemented.
  77. We would like to offer 3D time domain support, but this will not be
  78. provided before our first stable release.
  79. \subsection DataFormats Data Formats
  80. The EM community is plagued with myriad data formats. Often each equiptment
  81. manufacturer provides their own data format and interoperability is a
  82. constant struggle. We are working on a flexible data format based on the XML
  83. format that can be adapted to many types of data. The template for this
  84. format will be publically released and we hope it catches on in the community.
  85. At the least, it will provide a mechanism to compare datasets and datatypes
  86. within Lemma.
  87. \section Modules Modules
  88. Due to Lemma's design, it is easy to extend the platform. In some cases this
  89. extension results in adding functionality that is not directly related to
  90. ElectroMagnetics. The following modules utilise parts of Lemma to provide
  91. their functionality.
  92. \subsection Merlin Merlin.
  93. This module provides nuclear magnetic resonance functionality.
  94. \section Tutorials
  95. - \ref Tutorial - Basic intruduction to Lemma, including aquiring and
  96. compiling the code, class structure, and building your own
  97. applications.
  98. - \ref Extending Tutorial on how to extend Lemma.
  99. \section Development Development and design
  100. Ths package is primarily being developed by the Center for Gravity,
  101. Electrical, and Magnetic Studies (CGEM) at the Colorado School of Mines (CSM), the United
  102. States Geological Survey (USGS), and Broken Spoke Development, LLC. It draws on work by
  103. many others including Ki Ha Lee, and Walt Anderson. All new work and
  104. interfaces are written entirely in C++. Several small external projects are
  105. included, which are written in standard C, and FORTRAN 77. We adapt a
  106. modern, test driven, object oriented, C++ framework.
  107. \section Legalities
  108. \subsection Copyrights
  109. The following copyrights apply to the source.
  110. Most of the code was developed either by Trevor
  111. Copyright (C) 2008-2010 Trevor Irons <tirons@mines.edu> or
  112. M. Andrew Kass Copyright (C) 2010 <mkass@numericalgeo.com>.
  113. The 1D EM solver was derived (but updated heavily) from a fortran
  114. programme written by Ki Ha Lee in 1984. We have communicated with Ki Ha,
  115. and he assured us that this code is in the public domian.
  116. A Gaussian quadrature hankel transform originally written by Alan Chave was
  117. ported to C++. This code is in the public domain, and was published in Geophysics.
  118. A digital filtering approach to the Hankel transform written by Walt
  119. Anderson was also rewritten for Lemma. The origional fortran code is also in
  120. the public domain. Using this Hankel transform works
  121. arround the copyright issue mentioned above, but may not produce accurate
  122. results for high frequencies.
  123. Please note that Ki Ha Lee and Walt Anderson had no part in this work, and
  124. the above should not be interpreted as any sort of endorsement by those
  125. parties.
  126. \subsection License
  127. This Source Code Form is subject to the terms of the Mozilla Public
  128. License, v. 2.0. If a copy of the MPL was not distributed with this
  129. file, You can obtain one at http://mozilla.org/MPL/2.0/.
  130. \section Contributing Suggestions and contributions
  131. We welcome contributions and suggestions. Feel free to email the development
  132. team at info@lemmasoftware.org.
  133. Under the terms of the MPL, if you modify a Lemma file, you are obligated to
  134. share those contributions back with the community.
  135. \section Useful Useful links
  136. - Home page https://lemmasoftware.org
  137. - SVN repository https://svn.lemmasoftware.org
  138. - Broken Spoke Develpment http://numericalgeo.com
  139. - CGEM at the Coloroado School of Mines http://geophysics.mines.edu/cgem/
  140. **/
  141. #pragma once
  142. #ifndef __LEMMA_H
  143. #define __LEMMA_H
  144. // Include some basic stuff that will always be needed
  145. #include <iostream>
  146. #include <iomanip>
  147. #include <complex>
  148. #include <fstream>
  149. #include <string>
  150. #include <vector>
  151. #include <stdexcept>
  152. #include <sstream>
  153. #include <Eigen/Core>
  154. #include <cstddef>
  155. #include <Eigen/StdVector>
  156. #include <Eigen/Sparse>
  157. #include <unsupported/Eigen/FFT>
  158. //#include <unsupported/Eigen/SparseExtra>
  159. #include <Eigen/Geometry>
  160. /** \brief The only namespace used by Lemma
  161. *
  162. * \details The rational behind this namespace is that built-in
  163. * types should be used wherever possible, but not
  164. * not built-in names. This allows for code that is better
  165. * enacsulated and easier to modify. The typedefs and constants
  166. * specified here are defined so that
  167. * precision/inplimentation can easily be changed.
  168. * All floating precision types should be typedefed in this file
  169. * and should not be used natively within any code.
  170. * Lemma uses
  171. * the Eigen Matrix/Vector/Linear Algebra library.
  172. * <http://eigen.tuxfamily.org> and a lot of the namespece typedefs
  173. * are specifying Eigen types.
  174. */
  175. namespace Lemma {
  176. /// Real defines precision for the whole API, default is double
  177. #ifdef LEMMA_SINGLE_PRECISION
  178. typedef float Real;
  179. #else // ----- LEMMA_SINGLE_PRECISION -----
  180. typedef double Real;
  181. #endif // ----- not LEMMA_SINGLE_PRECISION -----
  182. /// Complex version of Real.
  183. typedef std::complex<Real> Complex;
  184. /// A 3 component Eigen vector of Reals
  185. typedef Eigen::Matrix<Real, 3, 1> Vector3r;
  186. /// A 3 X Dynamic Component Eigen matrix of Reals
  187. typedef Eigen::Matrix<Real, 3, Eigen::Dynamic> Vector3Xr;
  188. /// Variable length Eigen vector of Reals
  189. typedef Eigen::Matrix<Real, Eigen::Dynamic, 1> VectorXr;
  190. /// Variable length Eigen vector of integers (int)
  191. typedef Eigen::Matrix<int, Eigen::Dynamic, 1> VectorXi;
  192. /// Variable length Eigen vector of Complexes
  193. typedef Eigen::Matrix<Complex, Eigen::Dynamic, 1> VectorXcr;
  194. /// A 3 Component Eigen vector of Complexes
  195. typedef Eigen::Matrix<Complex, 3, 1> Vector3cr;
  196. /// A 3 X Dynamic Component Eigen matrix of Complexes
  197. typedef Eigen::Matrix<Complex, 3, Eigen::Dynamic> Vector3Xcr;
  198. /// Variable length Eigen Matrix of Reals
  199. typedef Eigen::Matrix<Real, Eigen::Dynamic, Eigen::Dynamic> MatrixXr;
  200. /// Variable length Eigen Matrix of ints
  201. typedef Eigen::Matrix<int, Eigen::Dynamic, Eigen::Dynamic> MatrixXi;
  202. /// Variable length Eigen vector of Complexes
  203. typedef Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic> MatrixXcr;
  204. ////////////////////////////////////////
  205. // Constants used across the programmes
  206. /// Restating the obvious, this is pi
  207. const Real PI = 4.0*atan(1.0);
  208. /// Permitivity of Free Space
  209. //const Real EPSILON0 = 8.854187817e-12;
  210. const Real EPSILON0 = 8.854187817e-12;
  211. /// Permeability of free space
  212. const Real MU0 = 4.*PI*1e-7;
  213. /// 1/4 of \f$ \pi\f$
  214. const Real QPI = .25/PI;
  215. /// Some functions will convert units from SI (standard) to Gauss
  216. /// This is because NMR calculations are much more natural in Gauss
  217. enum MAGUNITS {TESLA, NANOTESLA, GAUSS};
  218. /// Unit of temperature entered
  219. enum TEMPUNITS {CELCIUS, KELVIN};
  220. /// Unit of time entered
  221. enum TIMEUNITS {SEC, MILLISEC, MICROSEC, NANOSEC, PICOSEC};
  222. /// Unit of time entered
  223. enum FREQUENCYUNITS {HZ, KHZ, MHZ, GHZ};
  224. /// FEM coil relative orientations
  225. enum FEMCOILORIENTATION {COAXIAL, COPLANAR};
  226. /// General orientation relative to coordinate system
  227. enum ORIENTATION {X, Y, Z, NX, NY, NZ};
  228. /// Type of field
  229. enum FIELDTYPE {HFIELDREAL, HFIELDIMAG, EFIELDREAL, EFIELDIMAG};
  230. /// Compenent of vector field
  231. enum FIELDCOMPONENT {XCOMPONENT=0, YCOMPONENT=1, ZCOMPONENT=2};
  232. /// Spatial component of vector
  233. enum SPATIALCOORDINANT {XCOORD=0, YCOORD=1, ZCOORD=2};
  234. /** Evaluation method for Hankel integrals.
  235. * ANDERSON801 Walt Anderson's 801 point filter
  236. * CHAVE Alan Chave's gaussian quadrature integration method
  237. * FHTKEY201 Key's 201 point filter
  238. * FHTKEY201 Key's 101 point filter
  239. * FHTKEY51 Key's 51 point filter
  240. * QWEKEY Key's Gaussian quadrature integration method
  241. */
  242. enum HANKELTRANSFORMTYPE { ANDERSON801, CHAVE, FHTKEY201, FHTKEY101, FHTKEY51, QWEKEY };
  243. /** Enum is OK because these are the only physically possible sources.
  244. @param NOSOURCETYPE is default.
  245. @param ELECTRICDIPOLE is an electric dipole
  246. @param MAGNETICDIPOLE is a magnetic dipole
  247. */
  248. enum DipoleSourceType {NOSOURCETYPE, GROUNDEDELECTRICDIPOLE, UNGROUNDEDELECTRICDIPOLE, MAGNETICDIPOLE};
  249. /// Only three polarizations are supported. They may be summed to
  250. /// approximate others
  251. /// @param NOPOLARISATION is uninitialized, default value
  252. /// @param XPOLARISATION is a dipole oriented in the x direction
  253. /// @param YPOLARISATION is a dipole oriented in the y direction
  254. /// @param ZPOLARISATION is a dipole oriented in the z direction
  255. enum DipoleSourcePolarisation {NOPOLARISATION, XPOLARISATION,
  256. YPOLARISATION, ZPOLARISATION};
  257. /// The polarity may be either negative or positinve
  258. enum DipoleSourcePolarity {NEGATIVE, POSITIVE};
  259. /** The fields to make calculations on
  260. */
  261. enum FIELDCALCULATIONS {E, H, BOTH};
  262. }
  263. #endif // __Lemma_H