Browse Source

EMEarth1D compiles, not yet tested or profiled.

enhancement_3
Trevor Irons 7 years ago
parent
commit
7263dff1b4

Modules/FDEM1D/src/emdipearth1d.cpp → Modules/FDEM1D/examples/emdipearth1d.cpp View File


+ 1
- 1
Modules/FDEM1D/include/DipoleSource.h View File

@@ -99,7 +99,7 @@ namespace Lemma {
99 99
                     const int& irec, std::shared_ptr<LayeredEarthEM> Earth );
100 100
 
101 101
             /** Updates the receiver fields */
102
-            virtual void UpdateFields(const int& ifreq, std::shared_ptr<HankelTransform> Hankel, const Real& wavef);
102
+            virtual void UpdateFields(const int& ifreq, HankelTransform* Hankel, const Real& wavef);
103 103
 
104 104
             // ====================  ACCESS        ======================
105 105
 

Modules/FDEM1D/include/emearth1d.h → Modules/FDEM1D/include/EMEarth1D.h View File

@@ -8,14 +8,11 @@
8 8
   @file
9 9
   @author   Trevor Irons
10 10
   @date     12/02/2009
11
-  @version  $Id: emearth1d.h 266 2015-04-01 03:24:00Z tirons $
12 11
  **/
13 12
 
14 13
 #ifndef __EMEARTH1D_H
15 14
 #define __EMEARTH1D_H
16 15
 
17
-
18
-
19 16
 // forward declare these due to include cycle
20 17
 //#include "LayeredEarthEM.h"
21 18
 //#include "DipoleSource.h"
@@ -25,11 +22,11 @@
25 22
 //#include "KernelEM1DManager.h"
26 23
 
27 24
 #include "KernelEM1DSpec.h"
28
-#include "hankeltransformgaussianquadrature.h"
29
-#include "hankeltransformhankel2.h"
30
-#include "FHTKey.h"
31
-#include "FHTKey51.h"
25
+#include "GQChave.h"
26
+#include "FHTAnderson801.h"
27
+#include "FHTKey201.h"
32 28
 #include "FHTKey101.h"
29
+#include "FHTKey51.h"
33 30
 #include "QWEKey.h"
34 31
 #include "CubicSplineInterpolator.h"
35 32
 
@@ -64,7 +61,7 @@ namespace Lemma {
64 61
             // ====================  LIFECYCLE     ===========================
65 62
 
66 63
             /** Default protected constructor. */
67
-            EMEarth1D ( const ctor_key& );
64
+            explicit EMEarth1D ( const ctor_key& );
68 65
 
69 66
             /** Default protected constructor. */
70 67
 			EMEarth1D ( const YAML::Node& node, const ctor_key& );
@@ -109,7 +106,7 @@ namespace Lemma {
109 106
             // ====================  ACCESS        ===========================
110 107
 
111 108
             /** Attaches an antennae */
112
-            void AttachWireAntenna(WireAntenna *antennae);
109
+            void AttachWireAntenna( std::shared_ptr<WireAntenna> antennae);
113 110
 
114 111
             /** Attaches a dipole for calculation */
115 112
             void AttachDipoleSource( std::shared_ptr<DipoleSource> dipole);
@@ -137,19 +134,16 @@ namespace Lemma {
137 134
              *  and CalculateWireAntennaField routines.
138 135
              */
139 136
             void SolveSingleTxRxPair(const int &irec,
140
-                    std::shared_ptr<HankelTransform> Hankel,
137
+                    HankelTransform* Hankel,
141 138
                     const Real &wavef, const int &ifreq,
142
-                    std::shared_ptr<DipoleSource> tDipole);
139
+                    DipoleSource* tDipole);
143 140
 
144 141
             /** Used internally, this is the innermost loop of the MakeCalc3,
145 142
              *  and CalculateWireAntennaField routines.
146 143
              */
147
-            void SolveLaggedTxRxPair(const int &irec, std::shared_ptr<Hankel2> Hankel,
144
+            void SolveLaggedTxRxPair(const int &irec, FHTAnderson801* Hankel,
148 145
                     const Real &wavef, const int &ifreq,
149
-                    std::shared_ptr<PolygonalWireAntenna> antenna);
150
-
151
-            /** Removes all connections */
152
-            void DetachAll();
146
+                    PolygonalWireAntenna* antenna);
153 147
 
154 148
             // ====================  DATA MEMBERS  ===========================
155 149
 

+ 5
- 1
Modules/FDEM1D/include/PolygonalWireAntenna.h View File

@@ -51,7 +51,11 @@ namespace Lemma {
51 51
 
52 52
             /// Makes a deep copy of this antenna with all connections except
53 53
             /// the dipole approximation.
54
-            std::shared_ptr<WireAntenna> Clone();
54
+            virtual std::shared_ptr<WireAntenna> Clone() const ;
55
+
56
+            /// Makes a deep copy of this antenna with all connections except
57
+            /// the dipole approximation.
58
+            virtual std::shared_ptr<PolygonalWireAntenna> ClonePA() const ;
55 59
 
56 60
             /**
57 61
              *  Uses YAML to serialize this object.

+ 39
- 34
Modules/FDEM1D/include/QWEKey.h View File

@@ -12,20 +12,18 @@
12 12
  * @date      02/12/2014 10:20:18 AM
13 13
  * @version   $Id$
14 14
  * @author    Trevor Irons (ti)
15
- * @email     Trevor.Irons@xri-geo.com
16
- * @copyright Copyright (c) 2014, XRI Geophysics, LLC
15
+ * @email     Trevor.Irons@lemmasoftware.org
17 16
  * @copyright Copyright (c) 2014, Trevor Irons
18 17
  */
19 18
 
20 19
 #ifndef  QWEKEY_INC
21 20
 #define  QWEKEY_INC
22 21
 
23
-#include	"hankeltransform.h"
24
-#include    <Eigen/Eigenvalues>
25
-#ifdef HAVEBOOSTSPECIALFUNCTIONS
22
+#include "HankelTransform.h"
23
+
24
+#include <Eigen/Eigenvalues>
26 25
 #include "boost/math/special_functions.hpp"
27 26
 #include "boost/math/special_functions/bessel.hpp"
28
-#endif
29 27
 
30 28
 namespace Lemma {
31 29
 
@@ -47,24 +45,37 @@ namespace Lemma {
47 45
      */
48 46
     class QWEKey : public HankelTransform {
49 47
 
50
-        friend std::ostream &operator<<(std::ostream &stream,
51
-                const QWEKey &ob);
48
+        friend std::ostream &operator<<(std::ostream &stream, const QWEKey &ob);
49
+
50
+        struct ctor_key {};
52 51
 
53 52
         public:
54 53
 
55 54
         // ====================  LIFECYCLE     =======================
56 55
 
56
+        /** Default locked constructor, use NewSP */
57
+        QWEKey ( const ctor_key& );
58
+
59
+        /** DeSerializing locked constructor, use DeSerialize */
60
+        QWEKey ( const YAML::Node& node, const ctor_key& );
61
+
62
+        /** Default destructor */
63
+        ~QWEKey ();
64
+
57 65
         /**
58
-         * @copybrief LemmaObject::New()
59
-         * @copydetails LemmaObject::New()
66
+         *  Factory method for generating objects.
67
+         *   @return std::shared_ptr< QWEKey >
68
+         */
69
+        static std::shared_ptr<QWEKey> NewSP();
70
+
71
+        /** YAML Serializing method
60 72
          */
61
-        static QWEKey* New();
73
+        YAML::Node Serialize() const;
62 74
 
63 75
         /**
64
-         *  @copybrief   LemmaObject::Delete()
65
-         *  @copydetails LemmaObject::Delete()
76
+         *   Constructs an object from a YAML::Node.
66 77
          */
67
-        void Delete();
78
+        static std::shared_ptr< QWEKey > DeSerialize(const YAML::Node& node);
68 79
 
69 80
         // ====================  OPERATORS     =======================
70 81
 
@@ -72,39 +83,31 @@ namespace Lemma {
72 83
 
73 84
         // ====================  OPERATIONS    =======================
74 85
 
75
-
76 86
         Complex Zgauss(const int &ikk, const EMMODE &imode,
77 87
                             const int &itype, const Real &rho,
78
-                            const Real &wavef, KernelEm1DBase *Kernel);
88
+                            const Real &wavef, KernelEM1DBase* Kernel);
79 89
 
80 90
         /// Computes related kernels, if applicable, otherwise this is
81 91
         /// just a dummy function.
82
-        void ComputeRelated(const Real& rho, KernelEm1DBase* Kernel);
92
+        void ComputeRelated(const Real& rho, std::shared_ptr<KernelEM1DBase> Kernel);
83 93
 
84
-        void ComputeRelated(const Real& rho, std::vector< KernelEm1DBase* > KernelVec);
94
+        void ComputeRelated(const Real& rho, std::vector< std::shared_ptr<KernelEM1DBase> > KernelVec);
85 95
 
86
-        void ComputeRelated(const Real& rho, KernelEM1DManager* KernelManager);
96
+        void ComputeRelated(const Real& rho, std::shared_ptr<KernelEM1DManager> KernelManager);
87 97
 
88 98
         // ====================  ACCESS        =======================
89 99
 
90 100
         // ====================  INQUIRY       =======================
91 101
 
102
+        /** Returns the name of the underlying class, similiar to Python's type */
103
+        virtual inline std::string GetName() const {
104
+            return CName;
105
+        }
106
+
92 107
         protected:
93 108
 
94 109
         // ====================  LIFECYCLE     =======================
95 110
 
96
-        /** Default protected constructor, use New */
97
-        QWEKey (const std::string& name);
98
-
99
-        /** Default protected destructor, use Delete */
100
-        ~QWEKey ();
101
-
102
-        /**
103
-         *  @copybrief   LemmaObject::Release()
104
-         *  @copydetails LemmaObject::Release()
105
-         */
106
-        void Release();
107
-
108 111
         /** Calculates Gauss quadrature weights of order N on the interval -1,1
109 112
             Algorithm from p 129 in:
110 113
             Trefethen, L. N., 2000, Spectral methods in MATLAB: Society for
@@ -185,12 +188,14 @@ namespace Lemma {
185 188
         Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic > Zans;
186 189
 
187 190
         /** Manager for related kernels to evaluate */
188
-        KernelEM1DManager* KernelManager;
191
+        std::shared_ptr<KernelEM1DManager>  KernelManager;
189 192
 
190
-    }; // -----  end of class  QWEKey  -----
193
+        /** ASCII string representation of the class name */
194
+        static constexpr auto CName = "QWEKey";
191 195
 
196
+    }; // -----  end of class  QWEKey  -----
192 197
 
193
-}		// -----  end of Lemma  name  -----
198
+} // -----  end of Lemma  name  -----
194 199
 
195 200
 #endif   // ----- #ifndef QWEKEY_INC  -----
196 201
 

+ 1
- 1
Modules/FDEM1D/include/WireAntenna.h View File

@@ -58,7 +58,7 @@ namespace Lemma {
58 58
             /**
59 59
              * Provides deep copy
60 60
              */
61
-            virtual std::shared_ptr<WireAntenna> Clone();
61
+            virtual std::shared_ptr<WireAntenna> Clone() const ;
62 62
 
63 63
             /**
64 64
              *  Uses YAML to serialize this object.

+ 2
- 1
Modules/FDEM1D/src/CMakeLists.txt View File

@@ -19,8 +19,9 @@ set (FDEM1DSOURCE
19 19
 	${CMAKE_CURRENT_SOURCE_DIR}/FHTKey101.cpp
20 20
 	${CMAKE_CURRENT_SOURCE_DIR}/FHTKey51.cpp
21 21
 	${CMAKE_CURRENT_SOURCE_DIR}/GQChave.cpp
22
-	#${CMAKE_CURRENT_SOURCE_DIR}/QWEKey.cpp
22
+	${CMAKE_CURRENT_SOURCE_DIR}/QWEKey.cpp
23 23
 	
24
+	${CMAKE_CURRENT_SOURCE_DIR}/EMEarth1D.cpp
24 25
 
25 26
 	#${CMAKE_CURRENT_SOURCE_DIR}/AEMSurvey.cpp
26 27
 	#${CMAKE_CURRENT_SOURCE_DIR}/AEMSurveyReader.cpp

+ 1
- 1
Modules/FDEM1D/src/DipoleSource.cpp View File

@@ -739,7 +739,7 @@ namespace Lemma {
739 739
 
740 740
     }
741 741
 
742
-    void DipoleSource::UpdateFields( const int& ifreq, std::shared_ptr<HankelTransform> Hankel, const Real& wavef) {
742
+    void DipoleSource::UpdateFields( const int& ifreq, HankelTransform* Hankel, const Real& wavef) {
743 743
 
744 744
         Vector3r Pol = Phat;
745 745
 

+ 16
- 1
Modules/FDEM1D/src/PolygonalWireAntenna.cpp View File

@@ -65,7 +65,7 @@ namespace Lemma {
65 65
         return std::make_shared<PolygonalWireAntenna>( ctor_key() );
66 66
 	}
67 67
 
68
-	std::shared_ptr<WireAntenna> PolygonalWireAntenna::Clone() {
68
+	std::shared_ptr<WireAntenna> PolygonalWireAntenna::Clone() const {
69 69
 		auto copy = PolygonalWireAntenna::NewSP();
70 70
         copy->minDipoleRatio = this->minDipoleRatio;
71 71
 		copy->minDipoleMoment = this->minDipoleMoment;
@@ -79,6 +79,21 @@ namespace Lemma {
79 79
 		return copy;
80 80
 	}
81 81
 
82
+    std::shared_ptr<PolygonalWireAntenna> PolygonalWireAntenna::ClonePA() const {
83
+		auto copy = PolygonalWireAntenna::NewSP();
84
+        copy->minDipoleRatio = this->minDipoleRatio;
85
+		copy->minDipoleMoment = this->minDipoleMoment;
86
+		copy->maxDipoleMoment = this->maxDipoleMoment;
87
+		copy->NumberOfPoints = this->NumberOfPoints;
88
+		copy->Freqs = this->Freqs;
89
+		copy->Current = this->Current;
90
+		copy->NumberOfTurns = this->NumberOfTurns;
91
+		copy->Points = this->Points;
92
+		//copy->Dipoles = this->Dipoles; // no, disaster
93
+		return copy;
94
+	}
95
+
96
+
82 97
     void PolygonalWireAntenna::SetMinDipoleRatio (const Real& ratio) {
83 98
         minDipoleRatio = ratio;
84 99
     }

+ 39
- 39
Modules/FDEM1D/src/QWEKey.cpp View File

@@ -19,25 +19,19 @@
19 19
 /**
20 20
  * @file
21 21
  * @date      02/12/2014 10:28:15 AM
22
- * @version   $Id$
23 22
  * @author    Trevor Irons (ti)
24
- * @email     Trevor.Irons@xri-geo.com
25
- * @copyright Copyright (c) 2014, XRI Geophysics, LLC
23
+ * @email     Trevor.Irons@lemmasoftware.org
26 24
  * @copyright Copyright (c) 2014, Trevor Irons
27 25
  */
28 26
 
29 27
 #include "QWEKey.h"
30 28
 
31
-//#include <Eigen/Eigenvalues>
32
-
33 29
 namespace Lemma {
34 30
 
35 31
     // ====================  FRIEND METHODS  =====================
36 32
 
37 33
     std::ostream &operator<<(std::ostream &stream, const QWEKey &ob) {
38
-
39
-        stream << *(HankelTransform*)(&ob);
40
-
34
+        stream << ob.Serialize()  << "\n---\n"; // End of doc ---
41 35
         return stream;
42 36
     }
43 37
 
@@ -49,22 +43,28 @@ namespace Lemma {
49 43
     // Description:  constructor (protected)
50 44
     //--------------------------------------------------------------------------------------
51 45
     //
52
-    QWEKey::QWEKey (const std::string& name) : HankelTransform(name), RelTol(1e-12), AbsTol(1e-32), nQuad(61), nDelay(1),
46
+    QWEKey::QWEKey (const ctor_key& ) : HankelTransform( ), RelTol(1e-12), AbsTol(1e-32), nQuad(61), nDelay(1),
53 47
     //QWEKey::QWEKey (const std::string& name) : HankelTransform(name), RelTol(1e-38), AbsTol(1e-48), nQuad(39), nDelay(5),
54 48
         nIntervalsMax(40) {
55 49
         BesselWeights( J0 ); // TODO experiment with zero weight (J0, J1) options, should be static one time method
56 50
     }  // -----  end of method QWEKey::QWEKey  (constructor)  -----
57 51
 
52
+    //--------------------------------------------------------------------------------------
53
+    //       Class:  QWEKey
54
+    //      Method:  QWEKey
55
+    // Description:  constructor (locked)
56
+    //--------------------------------------------------------------------------------------
57
+    QWEKey::QWEKey( const YAML::Node& node, const ctor_key& ) : HankelTransform(node) {
58
+
59
+    }
58 60
 
59 61
     //--------------------------------------------------------------------------------------
60 62
     //       Class:  QWEKey
61 63
     //      Method:  New()
62 64
     // Description:  public constructor
63 65
     //--------------------------------------------------------------------------------------
64
-    QWEKey* QWEKey::New() {
65
-        QWEKey*  Obj = new QWEKey("QWEKey");
66
-        Obj->AttachTo(Obj);
67
-        return Obj;
66
+    std::shared_ptr<QWEKey> QWEKey::NewSP() {
67
+        return std::make_shared<QWEKey>( ctor_key() );
68 68
     }
69 69
 
70 70
     //--------------------------------------------------------------------------------------
@@ -78,20 +78,26 @@ namespace Lemma {
78 78
 
79 79
     //--------------------------------------------------------------------------------------
80 80
     //       Class:  QWEKey
81
-    //      Method:  Delete
82
-    // Description:  public destructor
81
+    //      Method:  DeSerialize
82
+    // Description:  Factory method, converts YAML node into object
83 83
     //--------------------------------------------------------------------------------------
84
-    void QWEKey::Delete() {
85
-        this->DetachFrom(this);
84
+    std::shared_ptr<QWEKey> QWEKey::DeSerialize( const YAML::Node& node ) {
85
+        if (node.Tag() != "QWEKey") {
86
+            throw  DeSerializeTypeMismatch( "QWEKey", node.Tag());
87
+        }
88
+        return std::make_shared<QWEKey> ( node, ctor_key() );
86 89
     }
87 90
 
88 91
     //--------------------------------------------------------------------------------------
89 92
     //       Class:  QWEKey
90
-    //      Method:  Release
91
-    // Description:  destructor (protected)
93
+    //      Method:  Serialize
94
+    // Description:  Converts object into Serialized version
92 95
     //--------------------------------------------------------------------------------------
93
-    void QWEKey::Release() {
94
-        delete this;
96
+    YAML::Node QWEKey::Serialize() const {
97
+        YAML::Node node = HankelTransform::Serialize();
98
+        node.SetTag( GetName() );
99
+        //node["LayerConductivity"] = LayerConductivity;
100
+        return node;
95 101
     }
96 102
 
97 103
     //--------------------------------------------------------------------------------------
@@ -100,7 +106,7 @@ namespace Lemma {
100 106
     //--------------------------------------------------------------------------------------
101 107
     Complex QWEKey::Zgauss ( const int &ikk, const EMMODE &imode,
102 108
                             const int &itype, const Real &rho,
103
-                            const Real &wavef, KernelEm1DBase *Kernel ) {
109
+                            const Real &wavef, KernelEM1DBase *Kernel ) {
104 110
         return Textrap(Kernel->GetManagerIndex(), Tn(Kernel->GetManagerIndex())) ;
105 111
     }		// -----  end of method QWEKey::Zgauss  -----
106 112
 
@@ -108,7 +114,7 @@ namespace Lemma {
108 114
     //       Class:  QWEKey
109 115
     //      Method:  ComputeRelated
110 116
     //--------------------------------------------------------------------------------------
111
-    void QWEKey::ComputeRelated ( const Real& rho, KernelEm1DBase* Kernel ) {
117
+    void QWEKey::ComputeRelated ( const Real& rho, std::shared_ptr<KernelEM1DBase> Kernel ) {
112 118
         return ;
113 119
     }		// -----  end of method QWEKey::ComputeRelated  -----
114 120
 
@@ -116,7 +122,7 @@ namespace Lemma {
116 122
     //       Class:  QWEKey
117 123
     //      Method:  ComputeRelated
118 124
     //--------------------------------------------------------------------------------------
119
-    void QWEKey::ComputeRelated ( const Real& rho, std::vector< KernelEm1DBase* > KernelVec ) {
125
+    void QWEKey::ComputeRelated ( const Real& rho, std::vector< std::shared_ptr<KernelEM1DBase> > KernelVec ) {
120 126
         return ;
121 127
     }		// -----  end of method QWEKey::ComputeRelated  -----
122 128
 
@@ -124,7 +130,7 @@ namespace Lemma {
124 130
     //       Class:  QWEKey
125 131
     //      Method:  ComputeRelated
126 132
     //--------------------------------------------------------------------------------------
127
-    void QWEKey::ComputeRelated ( const Real& rho, KernelEM1DManager* KernelManagerIn ) {
133
+    void QWEKey::ComputeRelated ( const Real& rho, std::shared_ptr<KernelEM1DManager> KernelManagerIn ) {
128 134
         KernelManager = KernelManagerIn;  // OK becauase this is internal and we know what we are doing
129 135
 
130 136
         Lambda = Bx.array()/rho;
@@ -140,16 +146,14 @@ namespace Lemma {
140 146
     //      Method:  GaussQuadWeights
141 147
     //--------------------------------------------------------------------------------------
142 148
     void QWEKey::GaussQuadWeights(const int& N) {
143
-        std::cerr<<"QWEKey needs work to remove Boost, etc." << std::endl;
144
-        // Below works with older Eigen, need to find problem
145
-//         VectorXr Nv = VectorXr::LinSpaced(N-1, 1, N-1);
146
-//         VectorXr beta  = 0.5 / (1.-(2.*Nv.array()).pow(-2)).sqrt();
147
-//         MatrixXr T = MatrixXr::Zero(N,N);
148
-//         //std::cerr << "Eigen ERROR BELOW, QWEKey.cpp  QWEKey::GaussQuadWeights, COMMENTED OUT ";
149
-//         T.bottomLeftCorner(N-1, N-1) = beta.asDiagonal();
150
-//         Eigen::SelfAdjointEigenSolver<MatrixXr> eig( T.selfadjointView< Eigen::Lower >() ); // PROBLEM LINE
151
-//             GaussAbscissa = eig.eigenvalues();
152
-//             GaussWeights = 2.*eig.eigenvectors().row(0).array().pow(2);
149
+        VectorXr Nv = VectorXr::LinSpaced(N-1, 1, N-1);
150
+        VectorXr beta  = 0.5 / (1.-(2.*Nv.array()).pow(-2)).sqrt();
151
+        MatrixXr T = MatrixXr::Zero(N,N);
152
+        //std::cerr << "Eigen ERROR BELOW, QWEKey.cpp  QWEKey::GaussQuadWeights, COMMENTED OUT ";
153
+        T.bottomLeftCorner(N-1, N-1) = beta.asDiagonal();
154
+        Eigen::SelfAdjointEigenSolver<MatrixXr> eig( T.selfadjointView< Eigen::Lower >() );
155
+            GaussAbscissa = eig.eigenvalues();
156
+            GaussWeights = 2.*eig.eigenvectors().row(0).array().pow(2);
153 157
     }
154 158
 
155 159
     //--------------------------------------------------------------------------------------
@@ -157,7 +161,6 @@ namespace Lemma {
157 161
     //      Method:  BesselWeights
158 162
     //--------------------------------------------------------------------------------------
159 163
     void QWEKey::BesselWeights ( const sZeroType& sType ) {
160
-    #ifdef HAVEBOOSTSPECIALFUNCTIONS
161 164
         GaussQuadWeights(nQuad); // TODO should this be moved out of initializer?
162 165
         std::vector<Real> bz;
163 166
         xInt = VectorXr(nIntervalsMax+1);
@@ -194,9 +197,6 @@ namespace Lemma {
194 197
             if (iw == GaussWeights.size()) iw = 0;
195 198
         }
196 199
         return ;
197
-    # else
198
-        std::cerr  << "QWEKey requires Boost functionalility that is missing\n";
199
-    #endif
200 200
     }		// -----  end of method QWEKey::BesselWeights  -----
201 201
 
202 202
 

+ 1
- 1
Modules/FDEM1D/src/WireAntenna.cpp View File

@@ -41,7 +41,7 @@ namespace Lemma {
41 41
         return std::make_shared<WireAntenna>( ctor_key() );
42 42
     }
43 43
 
44
-    std::shared_ptr<WireAntenna> WireAntenna::Clone() {
44
+    std::shared_ptr<WireAntenna> WireAntenna::Clone() const {
45 45
         auto copy = WireAntenna::NewSP();
46 46
 
47 47
 		copy->NumberOfPoints = this->NumberOfPoints;

+ 0
- 972
Modules/FDEM1D/src/emearth1d.cpp View File

@@ -1,972 +0,0 @@
1
-/* This file is part of Lemma, a geophysical modelling and inversion API */
2
-
3
-/* This Source Code Form is subject to the terms of the Mozilla Public
4
- * License, v. 2.0. If a copy of the MPL was not distributed with this
5
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
-
7
-/**
8
-  @file
9
-  @author   Trevor Irons
10
-  @date     12/02/2009
11
-  @version  $Id: emearth1d.cpp 270 2015-08-24 15:45:41Z tirons $
12
- **/
13
-
14
-#include "emearth1d.h"
15
-
16
-#ifdef LEMMAUSEOMP
17
-#include "omp.h"
18
-#endif
19
-
20
-namespace Lemma {
21
-
22
-#ifdef HAVE_YAMLCPP
23
-    std::ostream &operator << (std::ostream &stream, const EMEarth1D &ob) {
24
-        stream << ob.Serialize()  << "\n---\n"; // End of doc --- as a direct stream should encapulste thingy
25
-        return stream;
26
-    }
27
-#else
28
-	std::ostream &operator<<(std::ostream &stream, const
29
-		EMEarth1D &ob) {
30
-
31
-		stream << *(LemmaObject*)(&ob);
32
-		stream << "Dipole source address: " << ob.Dipole << std::endl;
33
-		stream << "Wire antenna address: " << ob.Antenna << std::endl;
34
-		stream << *ob.Earth << std::endl;
35
-		stream << *ob.Receivers;
36
-		return stream;
37
-	}
38
-#endif
39
-
40
-#ifdef KIHALEE_EM1D
41
-    // Wrapper function for Fortran subroutine Em1D bi kihand
42
-    // Returns E or H fields (SLOW)
43
-    extern "C" { void em1dcall_(int &itype,   // source
44
-                            int     &ipol,    // source
45
-                            int     &nlay,    // Earth
46
-                            int     &nfreq,   // source
47
-                            int     &nfield,  // Calculator
48
-                            int     &nres,    // Receivers
49
-                            int     &jtype,   // N/A
50
-                            int     &jgamma,  // Controller
51
-                            double  &acc,     // Controller
52
-                            double  *dep,     // Earth
53
-                            std::complex<double> *sig,     // Earth
54
-                            double  *susl,    // Earth
55
-                            double  *sush,    // Earth
56
-                            double  *sustau,  // Earth
57
-                            double  *susalp,  // Earth
58
-                            double  *eprl,    // Earth
59
-                            double  *eprh,    // Earth
60
-                            double  *eprtau,  // Earth
61
-                            double  *epralp,  // Earth
62
-                            double  &finit,   // N/A
63
-                            double  &flimit,  // N/A
64
-                            double  &dlimit,  // N/A
65
-                            double  &lfinc,   // N/A
66
-                            double  &tx,      // Source
67
-                            double  &ty,      // Source
68
-                            double  &tz,      // Source
69
-                            double  *rxx,     // Receivers
70
-                            double  *rxy,     // Receivers
71
-                            double  *rxz,     // Receivers
72
-                            std::complex<double> *ex,      // Receivers
73
-                            std::complex<double> *ey,      //    |
74
-                            std::complex<double> *ez,      //    |
75
-                            std::complex<double> *hx,      //    |
76
-                            std::complex<double> *hy,      //    V
77
-                            std::complex<double> *hz );    //   ___
78
-    }
79
-#endif
80
-
81
-    // ====================  LIFECYCLE     ===================================
82
-
83
-    // TODO init large arrays here.
84
-    EMEarth1D::EMEarth1D(const std::string& name) : LemmaObject(name),
85
-            Dipole(nullptr), Earth(nullptr), Receivers(nullptr), Antenna(nullptr),
86
-            FieldsToCalculate(BOTH), HankelType(ANDERSON801), icalcinner(0), icalc(0)
87
-        //#ifdef HAVEBOOSTPROGRESS
88
-        //    , disp(0)
89
-        //#endif
90
-        {
91
-    }
92
-
93
-    EMEarth1D::~EMEarth1D() {
94
-        if (this->NumberOfReferences > 0)
95
-            throw DeleteObjectWithReferences( this );
96
-        DetachAll();
97
-    }
98
-
99
-    EMEarth1D* EMEarth1D::New() {
100
-        EMEarth1D * Obj = new EMEarth1D("EmEarth1D");
101
-        Obj->AttachTo(Obj);
102
-        return Obj;
103
-    }
104
-
105
-    void EMEarth1D::Delete() {
106
-        this->DetachFrom(this);
107
-    }
108
-
109
-    void EMEarth1D::Release() {
110
-        DetachAll();
111
-        delete this;
112
-    }
113
-
114
-    #ifdef HAVE_YAMLCPP
115
-    YAML::Node EMEarth1D::Serialize() const {
116
-        YAML::Node node = LemmaObject::Serialize();
117
-
118
-        node["FieldsToCalculate"] = enum2String(FieldsToCalculate);
119
-        node["HankelType"] = enum2String(HankelType);
120
-
121
-        //if (Dipole != NULL) node["Dipole"] = Dipole->Serialize();
122
-        if (Earth != NULL)     node["Earth"] = Earth->Serialize();
123
-        //if (Receivers != NULL) node["Receivers"] = Receivers->Serialize(); Can be huge?
124
-        if (Antenna != NULL)   node["Antenna"] = Antenna->Serialize();
125
-
126
-        node.SetTag( this->Name );
127
-
128
-        return node;
129
-    }
130
-    #endif
131
-
132
-    // ====================  ACCESS        ===================================
133
-    void EMEarth1D::AttachDipoleSource(DipoleSource *dipoleptr) {
134
-        if (this->Dipole != NULL) {
135
-            this->Dipole->DetachFrom(this);
136
-        }
137
-        dipoleptr->AttachTo(this);
138
-        this->Dipole = dipoleptr;
139
-    }
140
-
141
-    void EMEarth1D::AttachLayeredEarthEM(LayeredEarthEM *earthptr) {
142
-        if (this->Earth != NULL)
143
-            this->Earth->DetachFrom(this);
144
-        earthptr->AttachTo(this);
145
-        this->Earth = earthptr;
146
-    }
147
-
148
-    void EMEarth1D::AttachReceiverPoints(ReceiverPoints *recptr) {
149
-        if (this->Receivers != NULL) {
150
-            this->Receivers->DetachFrom(this);
151
-        }
152
-
153
-        recptr->AttachTo(this);
154
-        this->Receivers = recptr;
155
-
156
-        if (Receivers == NULL) {
157
-            std::cout << "NULL Receivers in emearth1d.cpp " << std::endl;
158
-            return;
159
-        }
160
-
161
-        if (Dipole != NULL) {
162
-            switch (FieldsToCalculate) {
163
-                case E:
164
-                    Receivers->SetNumberOfBinsE(Dipole->GetNumberOfFrequencies());
165
-                    break;
166
-                case H:
167
-                    Receivers->SetNumberOfBinsH(Dipole->GetNumberOfFrequencies());
168
-                    break;
169
-                case BOTH:
170
-                    Receivers->SetNumberOfBinsE(Dipole->GetNumberOfFrequencies());
171
-                    Receivers->SetNumberOfBinsH(Dipole->GetNumberOfFrequencies());
172
-                    break;
173
-            }
174
-        } else if (Antenna != NULL) {
175
-            switch (FieldsToCalculate) {
176
-                case E:
177
-                    Receivers->SetNumberOfBinsE(Antenna->GetNumberOfFrequencies());
178
-                    break;
179
-                case H:
180
-                    Receivers->SetNumberOfBinsH(Antenna->GetNumberOfFrequencies());
181
-                    break;
182
-                case BOTH:
183
-                    Receivers->SetNumberOfBinsE(Antenna->GetNumberOfFrequencies());
184
-                    Receivers->SetNumberOfBinsH(Antenna->GetNumberOfFrequencies());
185
-                    break;
186
-            }
187
-
188
-        }
189
-
190
-    }
191
-
192
-    void EMEarth1D::AttachWireAntenna(WireAntenna *antennae) {
193
-        if (this->Antenna != NULL) {
194
-            this->Antenna->DetachFrom(this);
195
-        }
196
-        antennae->AttachTo(this);
197
-        this->Antenna = antennae;
198
-    }
199
-
200
-    void EMEarth1D::SetFieldsToCalculate(const FIELDCALCULATIONS &calc) {
201
-        FieldsToCalculate = calc;
202
-    }
203
-
204
-    void EMEarth1D::SetHankelTransformMethod( const HANKELTRANSFORMTYPE &type) {
205
-        HankelType = type;
206
-    }
207
-
208
-    void EMEarth1D::Query() {
209
-        std::cout << "EmEarth1D::Query()" << std::endl;
210
-
211
-        std::cout << "Dipole " << Dipole;
212
-        if (Dipole) std::cout << *Dipole << std::endl;
213
-
214
-        std::cout << "Earth " << Earth;
215
-        if (Earth) std::cout << *Earth << std::endl;
216
-
217
-        std::cout << "Receivers " << Earth;
218
-        if (Earth) std::cout << *Receivers << std::endl;
219
-
220
-        std::cout << "Antenna " << Earth;
221
-        if (Antenna) std::cout << *Antenna << std::endl;
222
-
223
-        std::cout << "icalc " << icalc << std::endl;
224
-
225
-        std::cout << "icalcinner " << icalcinner << std::endl;
226
-    }
227
-
228
-    // ====================  OPERATIONS    ===================================
229
-    void EMEarth1D::DetachAll() {
230
-
231
-        if (this->Dipole != NULL){
232
-            this->Dipole->DetachFrom(this);
233
-        }
234
-        Dipole = NULL;
235
-
236
-        if (this->Receivers != NULL){
237
-            this->Receivers->DetachFrom(this);
238
-        }
239
-        Receivers = NULL;
240
-
241
-        if (this->Earth != NULL){
242
-            this->Earth->DetachFrom(this);
243
-        }
244
-        Earth = NULL;
245
-
246
-        if (this->Antenna != NULL){
247
-            this->Antenna->DetachFrom(this);
248
-        }
249
-        Antenna = NULL;
250
-    }
251
-
252
-    void EMEarth1D::CalculateWireAntennaFields(bool progressbar) {
253
-
254
-        #ifdef HAVEBOOSTPROGRESS
255
-        boost::progress_display *disp;
256
-        #endif
257
-
258
-        if (Earth == NULL) {
259
-            throw NullEarth();
260
-        }
261
-        if (Receivers == NULL) {
262
-            throw NullReceivers();
263
-        }
264
-        if (Antenna == NULL) {
265
-            throw NullAntenna();
266
-        }
267
-        if (Dipole != NULL) {
268
-            throw DipoleSourceSpecifiedForWireAntennaCalc();
269
-        }
270
-
271
-        Receivers->ClearFields();
272
-
273
-        // Check to make sure Receivers are set up for all calculations
274
-        switch(FieldsToCalculate) {
275
-            case E:
276
-                if (Receivers->NumberOfBinsE != Antenna->GetNumberOfFrequencies())
277
-                    Receivers->SetNumberOfBinsE(Antenna->GetNumberOfFrequencies());
278
-                break;
279
-            case H:
280
-                if (Receivers->NumberOfBinsH != Antenna->GetNumberOfFrequencies())
281
-                    Receivers->SetNumberOfBinsH(Antenna->GetNumberOfFrequencies());
282
-                break;
283
-            case BOTH:
284
-                if (Receivers->NumberOfBinsH != Antenna->GetNumberOfFrequencies())
285
-                    Receivers->SetNumberOfBinsH(Antenna->GetNumberOfFrequencies());
286
-                if (Receivers->NumberOfBinsE != Antenna->GetNumberOfFrequencies())
287
-                    Receivers->SetNumberOfBinsE(Antenna->GetNumberOfFrequencies());
288
-                break;
289
-        }
290
-
291
-        if (Antenna->GetName() == std::string("PolygonalWireAntenna") || Antenna->GetName() == std::string("TEMTransmitter") ) {
292
-
293
-            icalc += 1;
294
-
295
-            // Check to see if they are all on a plane? If so we can do this fast
296
-            /* TODO FIX THIS ISSUES */
297
-            if (Antenna->IsHorizontallyPlanar() && HankelType == ANDERSON801) {
298
-                //std::cout << "Lag baby lag" << std::endl;
299
-                for (int ifreq=0; ifreq<Antenna->GetNumberOfFrequencies();++ifreq) {
300
-                    //std::cout << "Num Recs" <<  Receivers->GetNumberOfReceivers() << std::endl;
301
-                    Real wavef = 2.*PI* Antenna->GetFrequency(ifreq);
302
-                    #ifdef LEMMAUSEOMP
303
-                    #pragma omp parallel
304
-                    {
305
-                    #endif
306
-                    Hankel2* Hankel = Hankel2::New();
307
-                    #ifdef LEMMAUSEOMP
308
-                    #pragma omp for schedule(static, 1)
309
-                    #endif
310
-                    for (int irec=0; irec<Receivers->GetNumberOfReceivers(); ++irec) {
311
-                    //for (int irec=0; irec<2; ++irec) { // TODO FIXME BELO
312
-                        PolygonalWireAntenna *AntCopy = static_cast<PolygonalWireAntenna*>(this->Antenna)->Clone();
313
-                        SolveLaggedTxRxPair(irec, Hankel, wavef, ifreq, AntCopy);
314
-                        AntCopy->Delete();
315
-                        //exit(0);
316
-                    }
317
-                    //Receivers->ClearFields(); // FIXME DEBUG TODO
318
-                    Hankel->Delete();
319
-                    #ifdef LEMMAUSEOMP
320
-                    }
321
-                    #endif
322
-                }
323
-            } else
324
-            if (Receivers->GetNumberOfReceivers() > Antenna->GetNumberOfFrequencies()) {
325
-
326
-                //std::cout << "freq parallel #1" << std::endl;
327
-                //** Progress display bar for long calculations */
328
-                #ifdef HAVEBOOSTPROGRESS
329
-                if (progressbar) {
330
-                    disp = new boost::progress_display( Receivers->GetNumberOfReceivers()*Antenna->GetNumberOfFrequencies() );
331
-                }
332
-                #endif
333
-
334
-                // parallelise across receivers
335
-                #ifdef LEMMAUSEOMP
336
-                #pragma omp parallel
337
-                #endif
338
-                { // OpenMP Parallel Block
339
-                    // Since these antennas change we need a local copy for each
340
-                    // thread.
341
-                    PolygonalWireAntenna *AntCopy =
342
-                            static_cast<PolygonalWireAntenna*>(this->Antenna)->Clone();
343
-
344
-                    HankelTransform* Hankel;
345
-                    switch (HankelType) {
346
-                        case ANDERSON801:
347
-                            Hankel = Hankel2::New();
348
-                            break;
349
-                        case CHAVE:
350
-                            Hankel = HankelTransformGaussianQuadrature::New();
351
-                            break;
352
-                        case FHTKEY201:
353
-                            Hankel = FHTKey::New();
354
-                            break;
355
-                        case FHTKEY101:
356
-                            Hankel = FHTKey101::New();
357
-                            break;
358
-                        case FHTKEY51:
359
-                            Hankel = FHTKey51::New();
360
-                            break;
361
-                        case QWEKEY:
362
-                            Hankel = QWEKey::New();
363
-                            break;
364
-                        default:
365
-                            std::cerr << "Hankel transform cannot be created\n";
366
-                            exit(EXIT_FAILURE);
367
-                    }
368
-
369
-                    //for (int irec=tid; irec<Receivers->GetNumberOfReceivers(); irec+=nthreads) {
370
-                    #ifdef LEMMAUSEOMP
371
-                    #pragma omp for schedule(static, 1) //nowait
372
-                    #endif
373
-                    for (int irec=0; irec<Receivers->GetNumberOfReceivers(); ++irec) {
374
-                        if (!Receivers->GetMask(irec)) {
375
-                            AntCopy->ApproximateWithElectricDipoles(Receivers->GetLocation(irec));
376
-                            for (int idip=0; idip<AntCopy->GetNumberOfDipoles(); ++idip) {
377
-                                DipoleSource* tDipole = AntCopy->GetDipoleSource(idip);
378
-                                //#ifdef LEMMAUSEOMP
379
-                                //#pragma omp for schedule(static, 1)
380
-                                //#endif
381
-                                for (int ifreq=0; ifreq<tDipole->GetNumberOfFrequencies();
382
-                                        ++ifreq) {
383
-                                    // Propogation constant in free space
384
-                                    Real wavef   = tDipole->GetAngularFrequency(ifreq) *
385
-                                          std::sqrt(MU0*EPSILON0);
386
-                                    SolveSingleTxRxPair(irec, Hankel, wavef, ifreq, tDipole);
387
-                                } // freq loop
388
-                            } // dipole loop
389
-                        } // mask
390
-                        //std::cout << "Normal Path\n";
391
-                        //std::cout << Receivers->GetHfield(0, irec) << std::endl;
392
-                        //if (irec == 1) exit(0);
393
-                        #ifdef HAVEBOOSTPROGRESS
394
-                        if (progressbar) ++(*disp);
395
-                        #endif
396
-                    } // receiver loop
397
-                    Hankel->Delete();
398
-                    AntCopy->Delete();
399
-                } // OMP_PARALLEL BLOCK
400
-            } else if (Antenna->GetNumberOfFrequencies() > 8) {
401
-                // parallel across frequencies
402
-                //std::cout << "freq parallel #2" << std::endl;
403
-                for (int irec=0; irec<Receivers->GetNumberOfReceivers(); ++irec) {
404
-                    if (!Receivers->GetMask(irec)) {
405
-                        static_cast<PolygonalWireAntenna*>(Antenna)->
406
-                            ApproximateWithElectricDipoles(Receivers->GetLocation(irec));
407
-                        #ifdef LEMMAUSEOMP
408
-                        #pragma omp parallel
409
-                        #endif
410
-                        { // OpenMP Parallel Block
411
-
412
-                            HankelTransform* Hankel;
413
-                            switch (HankelType) {
414
-                                case ANDERSON801:
415
-                                    Hankel = Hankel2::New();
416
-                                    break;
417
-                                case CHAVE:
418
-                                    Hankel = HankelTransformGaussianQuadrature::New();
419
-                                    break;
420
-                                case FHTKEY201:
421
-                                    Hankel = FHTKey::New();
422
-                                    break;
423
-                                case FHTKEY101:
424
-                                    Hankel = FHTKey101::New();
425
-                                    break;
426
-                                case FHTKEY51:
427
-                                    Hankel = FHTKey51::New();
428
-                                    break;
429
-                                case QWEKEY:
430
-                                    Hankel = QWEKey::New();
431
-                                    break;
432
-                                default:
433
-                                    std::cerr << "Hankel transform cannot be created\n";
434
-                                    exit(EXIT_FAILURE);
435
-                            }
436
-                            #ifdef LEMMAUSEOMP
437
-                            #pragma omp for schedule(static, 1)
438
-                            #endif
439
-                            for (int ifreq=0; ifreq<Antenna->GetNumberOfFrequencies(); ++ifreq) {
440
-                                for (int idip=0; idip<Antenna->GetNumberOfDipoles(); ++idip) {
441
-                                    DipoleSource* tDipole = Antenna->GetDipoleSource(idip);
442
-                                    // Propogation constant in free space
443
-                                    Real wavef   = tDipole->GetAngularFrequency(ifreq) *
444
-                                          std::sqrt(MU0*EPSILON0);
445
-                                    SolveSingleTxRxPair(irec, Hankel, wavef,
446
-                                                    ifreq, tDipole);
447
-                                } // dipole loop
448
-                            } // frequency loop
449
-                            Hankel->Delete();
450
-                        } // OMP_PARALLEL BLOCK
451
-                    } // mask loop
452
-                    #ifdef HAVEBOOSTPROGRESS
453
-                    //if (Receivers->GetNumberOfReceivers() > 100) {
454
-                    //    ++ disp;
455
-                    //}
456
-                    #endif
457
-                } // receiver loop
458
-                //std::cout << "End freq parallel " << std::endl;
459
-            } // Frequency Parallel
460
-              else {
461
-                //std::cout << "parallel across #3 " << std::endl;
462
-                for (int irec=0; irec<Receivers->GetNumberOfReceivers(); ++irec) {
463
-                    if (!Receivers->GetMask(irec)) {
464
-
465
-                        static_cast<PolygonalWireAntenna*>(Antenna)->
466
-                            ApproximateWithElectricDipoles(Receivers->GetLocation(irec));
467
-//                         std::cout << "Not Masked " << std::endl;
468
-//                         std::cout << "n Freqs " << Antenna->GetNumberOfFrequencies() << std::endl;
469
-//                         std::cout << "n Dipoles " << Antenna->GetNumberOfDipoles() << std::endl;
470
-//                         if ( !Antenna->GetNumberOfDipoles() ) {
471
-//                             std::cout << "NO DIPOLES!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
472
-// //                            std::cout << "rec location " << Receivers->GetLocation(irec) << std::endl;
473
-// //                        }
474
-
475
-                        #ifdef LEMMAUSEOMP
476
-                        #pragma omp parallel
477
-                        #endif
478
-                        { // OpenMP Parallel Block
479
-                            HankelTransform* Hankel;
480
-                            switch (HankelType) {
481
-                                case ANDERSON801:
482
-                                    Hankel = Hankel2::New();
483
-                                    break;
484
-                                case CHAVE:
485
-                                    Hankel = HankelTransformGaussianQuadrature::New();
486
-                                    break;
487
-                                case FHTKEY201:
488
-                                    Hankel = FHTKey::New();
489
-                                    break;
490
-                                case FHTKEY101:
491
-                                    Hankel = FHTKey101::New();
492
-                                    break;
493
-                                case FHTKEY51:
494
-                                    Hankel = FHTKey51::New();
495
-                                    break;
496
-                                case QWEKEY:
497
-                                    Hankel = QWEKey::New();
498
-                                    break;
499
-                                default:
500
-                                    std::cerr << "Hankel transform cannot be created\n";
501
-                                    exit(EXIT_FAILURE);
502
-                            }
503
-                            for (int ifreq=0; ifreq<Antenna->GetNumberOfFrequencies(); ++ifreq) {
504
-                                #ifdef LEMMAUSEOMP
505
-                                #pragma omp for schedule(static, 1)
506
-                                #endif
507
-                                for (int idip=0; idip<Antenna->GetNumberOfDipoles(); ++idip) {
508
-                                    //#pragma omp critical
509
-                                    //{
510
-                                    //cout << "idip=" << idip << "\tthread num=" << omp_get_thread_num() << '\n';
511
-                                    //}
512
-                                    DipoleSource* tDipole = Antenna->GetDipoleSource(idip);
513
-                                    // Propogation constant in free space
514
-                                    Real wavef   = tDipole->GetAngularFrequency(ifreq) *
515
-                                          std::sqrt(MU0*EPSILON0);
516
-                                    SolveSingleTxRxPair(irec, Hankel, wavef, ifreq, tDipole);
517
-                                } // dipole loop
518
-                            } // frequency loop
519
-                            Hankel->Delete();
520
-                        } // OMP_PARALLEL BLOCK
521
-                    } // mask loop
522
-                    #ifdef HAVEBOOSTPROGRESS
523
-                    //if (Receivers->GetNumberOfReceivers() > 100) {
524
-                    //    ++ disp;
525
-                    //}
526
-                    #endif
527
-                } // receiver loop
528
-           } // Polygonal parallel logic
529
-        } else {
530
-             std::cerr << "Lemma with WireAntenna class is currently broken"
531
-                  << " fix or use PolygonalWireAntenna\n" << std::endl;
532
-             exit(EXIT_FAILURE);
533
-            // TODO, getting wrong answer, curiously worKernel->GetKs() with MakeCalc, maybe
534
-            // a threading issue, use SolveSingleTxRxPair maype instead of call
535
-            // to MakeCalc3? !!!
536
-            for (int idip=0; idip<Antenna->GetNumberOfDipoles(); ++idip) {
537
-                this->Dipole = Antenna->GetDipoleSource(idip);
538
-                MakeCalc3();
539
-                //++disp;
540
-            }
541
-            this->Dipole = NULL;
542
-        }
543
-
544
-        #ifdef HAVEBOOSTPROGRESS
545
-        if (progressbar) {
546
-            delete disp;
547
-        }
548
-        #endif
549
-    }
550
-
551
-    #ifdef KIHALEE_EM1D
552
-    void EMEarth1D::MakeCalc() {
553
-
554
-        int itype;       // 1 = elec, 2 = mag
555
-        switch (this->Dipole->GetDipoleSourceType()) {
556
-            case (GROUNDEDELECTRICDIPOLE) :
557
-                itype = 1;
558
-                break;
559
-            case (MAGNETICDIPOLE) :
560
-                itype = 2;
561
-                break;
562
-            case (UNGROUNDEDELECTRICDIPOLE) :
563
-                std::cerr << "Fortran routine cannot calculate ungrounded"
564
-                             "electric dipole\n";
565
-            default:
566
-                throw NonValidDipoleType();
567
-        }
568
-
569
-        int ipol ;
570
-        Vector3r Pol = this->Dipole->GetPolarisation();
571
-        if (std::abs(Pol[0]-1) < 1e-5) {
572
-            ipol = 1;
573
-        } else if (std::abs(Pol[1]-1) < 1e-5) {
574
-            ipol = 2;
575
-        } else if (std::abs(Pol[2]-1) < 1e-5) {
576
-            ipol = 3;
577
-        } else {
578
-            std::cerr << "Fortran routine cannot calculate arbitrary "
579
-                             "dipole polarisation, set to x, y, or z\n";
580
-        }
581
-
582
-        int nlay   =  Earth->GetNumberOfNonAirLayers();
583
-
584
-        if (nlay > MAXLAYERS) {
585
-            std::cerr << "FORTRAN CODE CAN ONLY HANDLE " << MAXLAYERS
586
-                      << " LAYERS\n";
587
-            throw  EarthModelWithMoreThanMaxLayers();
588
-        }
589
-
590
-        int nfreq  = 1;     // number of freqs
591
-
592
-        int nfield;     // field output 1 = elec, 2 = mag, 3 = both
593
-        switch (FieldsToCalculate) {
594
-            case E:
595
-                nfield = 1;
596
-                break;
597
-            case H:
598
-                nfield = 2;
599
-                break;
600
-            case BOTH:
601
-                nfield = 3;
602
-                break;
603
-            default:
604
-                throw 7;
605
-        }
606
-
607
-        int nres   = Receivers->GetNumberOfReceivers();
608
-        int jtype  = 3;     // form ouf output,
609
-                            // 1 = horizontal,
610
-                            // 2 = down hole,
611
-                            // 3 = freq sounding
612
-                            // 4 = down hole logging
613
-
614
-        int jgamma = 0;     // Units 0 = MKS (H->A/m and E->V/m)
615
-                            //       1 = h->Gammas   E->V/m
616
-
617
-        double acc = 0.;    // Tolerance
618
-
619
-        // TODO, fix FORTRAN calls so these arrays can be nlay long, not
620
-        // MAXLAYERS.
621
-
622
-        // Model Parameters
623
-        double *dep    = new double[MAXLAYERS];
624
-        dep[0] = 0.;          // We always say air starts at 0
625
-        for (int ilay=1; ilay<Earth->GetNumberOfLayers(); ++ilay) {
626
-            dep[ilay] = dep[ilay-1] + Earth->GetLayerThickness(ilay);
627
-            //std::cout << "Depth " << dep[ilay] << std::endl;
628
-        }
629
-
630
-        std::complex<double> *sig = new std::complex<double> [MAXLAYERS];
631
-        for (int ilay=1; ilay<=nlay; ++ilay) {
632
-            sig[ilay-1] = (std::complex<double>)(Earth->GetLayerConductivity(ilay));
633
-        }
634
-
635
-        // TODO, pass these into Fortran call, and return Cole-Cole model
636
-        // parameters. Right now this does nothing
637
-        //std::complex<double> *sus   = new std::complex<double>[MAXLAYERS];
638
-        //std::complex<double> *epr   = new std::complex<double>[MAXLAYERS];
639
-
640
-        // Cole-Cole model stuff
641
-        double *susl   = new double[MAXLAYERS];
642
-        for (int ilay=1; ilay<=nlay; ++ilay) {
643
-            susl[ilay-1] = Earth->GetLayerLowFreqSusceptibility(ilay);
644
-        }
645
-
646
-        double *sush   = new double[MAXLAYERS];
647
-        for (int ilay=1; ilay<=nlay; ++ilay) {
648
-            sush[ilay-1] = Earth->GetLayerHighFreqSusceptibility(ilay);
649
-        }
650
-
651
-        double *sustau = new double[MAXLAYERS];
652
-        for (int ilay=1; ilay<=nlay; ++ilay) {
653
-            sustau[ilay-1] = Earth->GetLayerTauSusceptibility(ilay);
654
-        }
655
-
656
-        double *susalp = new double[MAXLAYERS];
657
-        for (int ilay=1; ilay<=nlay; ++ilay) {
658
-            susalp[ilay-1] = Earth->GetLayerBreathSusceptibility(ilay);
659
-        }
660
-
661
-        double *eprl   = new double[MAXLAYERS];
662
-        for (int ilay=1; ilay<=nlay; ++ilay) {
663
-            eprl[ilay-1] = Earth->GetLayerLowFreqPermitivity(ilay);
664
-        }
665
-
666
-        double *eprh   = new double[MAXLAYERS];
667
-        for (int ilay=1; ilay<=nlay; ++ilay) {
668
-            eprh[ilay-1] = Earth->GetLayerHighFreqPermitivity(ilay);
669
-        }
670
-
671
-        double *eprtau = new double[MAXLAYERS];
672
-        for (int ilay=1; ilay<=nlay; ++ilay) {
673
-            eprtau[ilay-1] = Earth->GetLayerTauPermitivity(ilay);
674
-        }
675
-
676
-        double *epralp = new double[MAXLAYERS];
677
-        for (int ilay=1; ilay<=nlay; ++ilay) {
678
-            epralp[ilay-1] = Earth->GetLayerBreathPermitivity(ilay);
679
-        }
680
-
681
-        // Freq stuff
682
-        double finit  = Dipole->GetFrequency(0); //(1000);   // Starting freq
683
-        double flimit = Dipole->GetFrequency(0); //(1000);   // max freq
684
-        double dlimit = Dipole->GetFrequency(0); //(1000);   // difusion limit
685
-        double lfinc(1);       // no. freq per decade
686
-
687
-        // tx location jtype != 4
688
-        double txx = Dipole->GetLocation(0); // (0.);
689
-        double txy = Dipole->GetLocation(1); // (0.);
690
-        double txz = Dipole->GetLocation(2); // (0.);
691
-
692
-        // rx position
693
-        // TODO, fix Fortran program to not waste this memory
694
-        // maybe
695
-        const int MAXREC = 15;
696
-        double *rxx = new double [MAXREC];
697
-        double *rxy = new double [MAXREC];
698
-        double *rxz = new double [MAXREC];
699
-
700
-        std::complex<double> *ex = new std::complex<double>[MAXREC];
701
-        std::complex<double> *ey = new std::complex<double>[MAXREC];
702
-        std::complex<double> *ez = new std::complex<double>[MAXREC];
703
-
704
-        std::complex<double> *hx = new std::complex<double>[MAXREC];
705
-        std::complex<double> *hy = new std::complex<double>[MAXREC];
706
-        std::complex<double> *hz = new std::complex<double>[MAXREC];
707
-
708
-        int nres2 = MAXREC;
709
-        int ii=0;
710
-
711
-        for (ii=0; ii<nres-MAXREC; ii+=MAXREC) {
712
-
713
-            for (int ir=0; ir<MAXREC; ++ir) {
714
-                //Vector3r pos = Receivers->GetLocation(ii+ir);
715
-                rxx[ir] = Receivers->GetLocation(ii+ir)[0];
716
-                rxy[ir] = Receivers->GetLocation(ii+ir)[1];
717
-                rxz[ir] = Receivers->GetLocation(ii+ir)[2];
718
-            }
719
-
720
-            em1dcall_(itype, ipol, nlay, nfreq, nfield, nres2, jtype,
721
-                  jgamma, acc, dep, sig, susl, sush, sustau, susalp,
722
-                  eprl, eprh, eprtau, epralp, finit, flimit, dlimit,
723
-                  lfinc, txx, txy, txz, rxx, rxy, rxz, ex, ey, ez,
724
-                  hx, hy, hz);
725
-
726
-            // Scale By Moment
727
-            for (int ir=0; ir<MAXREC; ++ir) {
728
-
729
-                ex[ir] *= Dipole->GetMoment();
730
-                ey[ir] *= Dipole->GetMoment();
731
-                ez[ir] *= Dipole->GetMoment();
732
-
733
-                hx[ir] *= Dipole->GetMoment();
734
-                hy[ir] *= Dipole->GetMoment();
735
-                hz[ir] *= Dipole->GetMoment();
736
-
737
-                // Append values instead of setting them
738
-                this->Receivers->AppendEfield(0, ii+ir, (Complex)(ex[ir]),
739
-                                                        (Complex)(ey[ir]),
740
-                                                        (Complex)(ez[ir]) );
741
-                this->Receivers->AppendHfield(0, ii+ir, (Complex)(hx[ir]),
742
-                                                        (Complex)(hy[ir]),
743
-                                                        (Complex)(hz[ir]) );
744
-            }
745
-        }
746
-
747
-        //ii += MAXREC;
748
-        nres2 = 0;
749
-        // Perform last positions
750
-        for (int ir=0; ir<nres-ii; ++ir) {
751
-            rxx[ir] = Receivers->GetLocation(ii+ir)[0];
752
-            rxy[ir] = Receivers->GetLocation(ii+ir)[1];
753
-            rxz[ir] = Receivers->GetLocation(ii+ir)[2];
754
-            ++nres2;
755
-        }
756
-
757
-        em1dcall_(itype, ipol, nlay, nfreq, nfield, nres2, jtype,
758
-              jgamma, acc, dep, sig, susl, sush, sustau, susalp,
759
-              eprl, eprh, eprtau, epralp, finit, flimit, dlimit,
760
-              lfinc, txx, txy, txz, rxx, rxy, rxz, ex, ey, ez,
761
-              hx, hy, hz);
762
-
763
-        // Scale By Moment
764
-        for (int ir=0; ir<nres-ii; ++ir) {
765
-
766
-            ex[ir] *= Dipole->GetMoment();
767
-            ey[ir] *= Dipole->GetMoment();
768
-            ez[ir] *= Dipole->GetMoment();
769
-
770
-            hx[ir] *= Dipole->GetMoment();
771
-            hy[ir] *= Dipole->GetMoment();
772
-            hz[ir] *= Dipole->GetMoment();
773
-
774
-            // Append values instead of setting them
775
-            this->Receivers->AppendEfield(0, ii+ir, (Complex)(ex[ir]),
776
-                                                    (Complex)(ey[ir]),
777
-                                                    (Complex)(ez[ir]) );
778
-            this->Receivers->AppendHfield(0, ii+ir, (Complex)(hx[ir]),
779
-                                                    (Complex)(hy[ir]),
780
-                                                    (Complex)(hz[ir]) );
781
-
782
-        }
783
-
784
-        delete [] sig;
785
-        delete [] dep;
786
-
787
-        //delete [] sus;
788
-        //delete [] epr;
789
-
790
-        delete [] susl;
791
-        delete [] sush;
792
-        delete [] susalp;
793
-        delete [] sustau;
794
-
795
-        delete [] eprl;
796
-        delete [] eprh;
797
-        delete [] epralp;
798
-        delete [] eprtau;
799
-
800
-        delete [] rxx;
801
-        delete [] rxy;
802
-        delete [] rxz;
803
-
804
-        delete [] ex;
805
-        delete [] ey;
806
-        delete [] ez;
807
-
808
-        delete [] hx;
809
-        delete [] hy;
810
-        delete [] hz;
811
-
812
-    }
813
-#endif
814
-
815
-
816
-    void EMEarth1D::SolveSingleTxRxPair (const int &irec,
817
-                   HankelTransform *Hankel, const Real &wavef, const int &ifreq,
818
-                   DipoleSource *tDipole) {
819
-        ++icalcinner;
820
-
821
-        Real rho = (Receivers->GetLocation(irec).head<2>() - tDipole->GetLocation().head<2>()).norm();
822
-
823
-        tDipole->SetKernels(ifreq, FieldsToCalculate, Receivers, irec, Earth);
824
-        Hankel->ComputeRelated( rho, tDipole->GetKernelManager() );
825
-        tDipole->UpdateFields( ifreq,  Hankel, wavef );
826
-    }
827
-
828
-    void EMEarth1D::SolveLaggedTxRxPair(const int &irec, Hankel2* Hankel,
829
-                    const Real &wavef, const int &ifreq, PolygonalWireAntenna* antenna) {
830
-
831
-        antenna->ApproximateWithElectricDipoles(Receivers->GetLocation(irec));
832
-
833
-        // Determine the min and max arguments
834
-        Real rhomin = 1e9;
835
-        Real rhomax = 1e-9;
836
-        for (int idip=0; idip<antenna->GetNumberOfDipoles(); ++idip) {
837
-            DipoleSource* tDipole = antenna->GetDipoleSource(idip);
838
-            Real rho = (Receivers->GetLocation(irec).head<2>() - tDipole->GetLocation().head<2>()).norm();
839
-            rhomin = std::min(rhomin, rho);
840
-            rhomax = std::max(rhomax, rho);
841
-        }
842
-        //std::cout << "rhomin\t" << rhomin << "\trhomax" << rhomax << std::endl;
843
-
844
-        // Determine number of lagged convolutions to do
845
-        // TODO, can Hankel2 adjust the lagg spacing safely?
846
-        int nlag = 1; // We need an extra for some reason for stability
847
-        Real lrho ( 1.01* rhomax );
848
-        while ( lrho > rhomin ) {
849
-            nlag += 1;
850
-            lrho *= Hankel->GetABSER();
851
-        }
852
-
853
-        //int nlag = rhomin
854
-        DipoleSource* tDipole = antenna->GetDipoleSource(0);
855
-        tDipole->SetKernels(ifreq, FieldsToCalculate, Receivers, irec, Earth);
856
-
857
-        // Instead we should pass the antenna into this so that Hankel hass all the rho arguments...
858
-        Hankel->ComputeLaggedRelated( 1.01* rhomax, nlag, tDipole->GetKernelManager() );
859
-
860
-        //std::cout << Hankel->GetAnswer() << std::endl;
861
-        //std::cout << Hankel->GetArg() << std::endl;
862
-
863
-
864
-        // Sort the dipoles by rho
865
-
866
-        for (int idip=0; idip<antenna->GetNumberOfDipoles(); ++idip) {
867
-        //for (int idip=0; idip<1; ++idip) {
868
-            DipoleSource* tDipole = antenna->GetDipoleSource(idip);
869
-            tDipole->SetKernels(ifreq, FieldsToCalculate, Receivers, irec, Earth);
870
-            // Pass Hankel2 a message here so it knows which one to return in Zgauss!
871
-            Real rho = (Receivers->GetLocation(irec).head<2>() - tDipole->GetLocation().head<2>()).norm();
872
-            //std::cout << " in Lagged " <<  rho << "\t" << rhomin << "\t" << rhomax << std::endl;
873
-            Hankel->SetLaggedArg( rho );
874
-            //std::cout << "out Lagged" << std::endl;
875
-            tDipole->UpdateFields( ifreq,  Hankel, wavef );
876
-        }
877
-        //std::cout << "Spline\n";
878
-        //std::cout << Receivers->GetHfield(0, irec) << std::endl;
879
-    }
880
-
881
-    //////////////////////////////////////////////////////////
882
-    // Thread safe OO Reimplimentation of KiHand's
883
-    // EM1DNEW.for programme
884
-    void EMEarth1D::MakeCalc3() {
885
-
886
-        if ( Dipole == NULL ) throw NullDipoleSource();
887
-
888
-        if (Earth == NULL) throw NullEarth();
889
-
890
-        if (Receivers == NULL) throw NullReceivers();
891
-
892
-        #ifdef LEMMAUSEOMP
893
-        #pragma omp parallel
894
-        #endif
895
-        { // OpenMP Parallel Block
896
-
897
-            #ifdef LEMMAUSEOMP
898
-            int tid = omp_get_thread_num();
899
-            int nthreads = omp_get_num_threads();
900
-            #else
901
-            int tid=0;
902
-            int nthreads=1;
903
-            #endif
904
-
905
-            DipoleSource* tDipole = Dipole->Clone();
906
-
907
-            HankelTransform* Hankel;
908
-            switch (HankelType) {
909
-                case ANDERSON801:
910
-                    Hankel = Hankel2::New();
911
-                    break;
912
-                case CHAVE:
913
-                    Hankel = HankelTransformGaussianQuadrature::New();
914
-                    break;
915
-                case FHTKEY201:
916
-                    Hankel = FHTKey::New();
917
-                    break;
918
-                case FHTKEY101:
919
-                    Hankel = FHTKey101::New();
920
-                    break;
921
-                case FHTKEY51:
922
-                    Hankel = FHTKey51::New();
923
-                    break;
924
-                case QWEKEY:
925
-                    Hankel = QWEKey::New();
926
-                    break;
927
-                default:
928
-                    std::cerr << "Hankel transform cannot be created\n";
929
-                    exit(EXIT_FAILURE);
930
-            }
931
-
932
-            if ( tDipole->GetNumberOfFrequencies() < Receivers->GetNumberOfReceivers() ) {
933
-                for (int ifreq=0; ifreq<tDipole->GetNumberOfFrequencies(); ++ifreq) {
934
-                    // Propogation constant in free space being input to Hankel
935
-                    Real wavef   = tDipole->GetAngularFrequency(ifreq) * std::sqrt(MU0*EPSILON0);
936
-                    for (int irec=tid; irec<Receivers->GetNumberOfReceivers(); irec+=nthreads) {
937
-                        SolveSingleTxRxPair(irec, Hankel, wavef, ifreq, tDipole);
938
-                    }
939
-                }
940
-            } else {
941
-                for (int irec=0; irec<Receivers->GetNumberOfReceivers(); ++irec) {
942
-                    for (int ifreq=tid; ifreq<tDipole->GetNumberOfFrequencies(); ifreq+=nthreads) {
943
-                        // Propogation constant in free space being input to Hankel
944
-                        Real wavef   = tDipole->GetAngularFrequency(ifreq) * std::sqrt(MU0*EPSILON0);
945
-                        SolveSingleTxRxPair(irec, Hankel, wavef, ifreq, tDipole);
946
-                    }
947
-                }
948
-            }
949
-
950
-            tDipole->Delete();
951
-            Hankel->Delete();
952
-
953
-        } // OpenMP Parallel Block
954
-    }
955
-
956
-    NullReceivers::NullReceivers() :
957
-        runtime_error("NULL RECEIVERS") {}
958
-
959
-    NullAntenna::NullAntenna() :
960
-        runtime_error("NULL ANTENNA") {}
961
-
962
-    NullInstrument::NullInstrument(LemmaObject* ptr) :
963
-        runtime_error("NULL INSTRUMENT") {
964
-        std::cout << "Thrown by instance of "
965
-                  << ptr->GetName() << std::endl;
966
-    }
967
-
968
-    DipoleSourceSpecifiedForWireAntennaCalc::
969
-        DipoleSourceSpecifiedForWireAntennaCalc() :
970
-        runtime_error("DIPOLE SOURCE SPECIFIED FOR WIRE ANTENNA CALC"){}
971
-
972
-} // end of Lemma Namespace

+ 1
- 1
vim/c.vim View File

@@ -17,7 +17,7 @@ syn keyword nspace Lemma YAML Eigen
17 17
 
18 18
 " Lemma types
19 19
 highlight leType ctermfg=Yellow guifg=Yellow
20
-syn keyword leType HankelTransform FHTAnderson801 FHTKey201 FHTKey101 FHTKey51 KernelEM1D KernelEM1DSpec KernelEM1DBase KernelEM1DManager DipoleSource EarthModel LayeredEarth LayeredEarthEM TEMSurvey TEMSurveyLine TEMSurveyLineRecord TEMInductiveReceiver WireAntenna PolygonalWireAntenna TEMTransmitter TEMReceiver Instrument InstrumentTem LemmaObject FieldPoints DCIPElectrode TEMSurveyData TEMSurveyLineData TEMSurveyLineRecordData  ASCIIParser CubicSplineInterpolator RectilinearGrid GridReader RectilinearGridReader RectilinearGridVTKExporter Filter WindowFilter DEMParticle DEMGrain Data DataReader 
20
+syn keyword leType HankelTransform FHTAnderson801 FHTKey201 FHTKey101 FHTKey51 GQChave QWEKey KernelEM1D KernelEM1DSpec KernelEM1DBase KernelEM1DManager DipoleSource EarthModel LayeredEarth LayeredEarthEM TEMSurvey TEMSurveyLine TEMSurveyLineRecord TEMInductiveReceiver WireAntenna PolygonalWireAntenna TEMTransmitter TEMReceiver Instrument InstrumentTem LemmaObject FieldPoints DCIPElectrode TEMSurveyData TEMSurveyLineData TEMSurveyLineRecordData  ASCIIParser CubicSplineInterpolator RectilinearGrid GridReader RectilinearGridReader RectilinearGridVTKExporter Filter WindowFilter DEMParticle DEMGrain Data DataReader 
21 21
 
22 22
 " Deprecated Lemma Types
23 23
 highlight dleType ctermfg=Blue guifg=Blue 

Loading…
Cancel
Save