Browse Source

Added new modules, but build does not yet support them.

enhancement_3
Trevor Irons 7 years ago
parent
commit
adee55f7a6
100 changed files with 25103 additions and 0 deletions
  1. 0
    0
      Modules/DCIP/CMakeLists.txt
  2. 116
    0
      Modules/DCIP/examples/DCIPElectrode.cpp
  3. 127
    0
      Modules/DCIP/include/DCIPElectrode.h
  4. 240
    0
      Modules/DCIP/include/DCSurvey.h
  5. 165
    0
      Modules/DCIP/src/DCIPElectrode.cpp
  6. 377
    0
      Modules/DCIP/src/DCSurvey.cpp
  7. 0
    0
      Modules/FDEM1D/CMakeLists.txt
  8. 112
    0
      Modules/FDEM1D/include/FHTKey.h
  9. 112
    0
      Modules/FDEM1D/include/FHTKey101.h
  10. 112
    0
      Modules/FDEM1D/include/FHTKey51.h
  11. 87
    0
      Modules/FDEM1D/include/GroundedElectricDipole.h
  12. 105
    0
      Modules/FDEM1D/include/LayeredEarthEMReader.h
  13. 88
    0
      Modules/FDEM1D/include/MagneticDipole.h
  14. 169
    0
      Modules/FDEM1D/include/PolygonalWireAntenna.h
  15. 197
    0
      Modules/FDEM1D/include/QWEKey.h
  16. 88
    0
      Modules/FDEM1D/include/UngroundedElectricDipole.h
  17. 249
    0
      Modules/FDEM1D/include/WireAntenna.h
  18. 232
    0
      Modules/FDEM1D/include/emearth1d.h
  19. 139
    0
      Modules/FDEM1D/include/gaussianquadrature.h
  20. 90
    0
      Modules/FDEM1D/include/hankeltransform.h
  21. 349
    0
      Modules/FDEM1D/include/hankeltransformgaussianquadrature.h
  22. 246
    0
      Modules/FDEM1D/include/hankeltransformhankel2.h
  23. 144
    0
      Modules/FDEM1D/include/instrumentfem.h
  24. 92
    0
      Modules/FDEM1D/include/integrationkernel.h
  25. 118
    0
      Modules/FDEM1D/include/inversesolver.h
  26. 85
    0
      Modules/FDEM1D/include/kernel.h
  27. 111
    0
      Modules/FDEM1D/include/kernelem1dbase.h
  28. 217
    0
      Modules/FDEM1D/include/kernelem1dmanager.h
  29. 253
    0
      Modules/FDEM1D/include/kernelem1dreflbase.h
  30. 373
    0
      Modules/FDEM1D/include/kernelem1dreflspec.h
  31. 1485
    0
      Modules/FDEM1D/include/kernelem1dspec.h
  32. 314
    0
      Modules/FDEM1D/include/layeredearthem.h
  33. 68
    0
      Modules/FDEM1D/include/modelreaderfem1d.h
  34. 358
    0
      Modules/FDEM1D/include/octreegrid.h
  35. 169
    0
      Modules/FDEM1D/include/receivercubes.h
  36. 281
    0
      Modules/FDEM1D/include/receiverpoints.h
  37. 97
    0
      Modules/FDEM1D/include/sintransintegrationkernel.h
  38. 359
    0
      Modules/FDEM1D/src/FHTKey.cpp
  39. 259
    0
      Modules/FDEM1D/src/FHTKey101.cpp
  40. 209
    0
      Modules/FDEM1D/src/FHTKey51.cpp
  41. 85
    0
      Modules/FDEM1D/src/GroundedElectricDipole.cpp
  42. 124
    0
      Modules/FDEM1D/src/LayeredEarthEMReader.cpp
  43. 82
    0
      Modules/FDEM1D/src/MagneticDipole.cpp
  44. 349
    0
      Modules/FDEM1D/src/PolygonalWireAntenna.cpp
  45. 332
    0
      Modules/FDEM1D/src/QWEKey.cpp
  46. 84
    0
      Modules/FDEM1D/src/UngroundedElectricDipole.cpp
  47. 293
    0
      Modules/FDEM1D/src/WireAntenna.cpp
  48. 345
    0
      Modules/FDEM1D/src/dipolefreqsweep.cpp
  49. 231
    0
      Modules/FDEM1D/src/edipole.cpp
  50. 141
    0
      Modules/FDEM1D/src/emdipearth1d.cpp
  51. 972
    0
      Modules/FDEM1D/src/emearth1d.cpp
  52. 199
    0
      Modules/FDEM1D/src/femforward.cpp
  53. 138
    0
      Modules/FDEM1D/src/gaussianquadrature.cpp
  54. 39
    0
      Modules/FDEM1D/src/hankeltransform.cpp
  55. 1134
    0
      Modules/FDEM1D/src/hankeltransformgaussianquadrature.cpp
  56. 1118
    0
      Modules/FDEM1D/src/hankeltransformhankel2.cpp
  57. 174
    0
      Modules/FDEM1D/src/instrumentfem.cpp
  58. 27
    0
      Modules/FDEM1D/src/integrationkernel.cpp
  59. 78
    0
      Modules/FDEM1D/src/inversesolver.cpp
  60. 29
    0
      Modules/FDEM1D/src/kernel.cpp
  61. 128
    0
      Modules/FDEM1D/src/kernelem1dmanager.cpp
  62. 241
    0
      Modules/FDEM1D/src/kernelem1dreflspec.cpp
  63. 2652
    0
      Modules/FDEM1D/src/kernelem1dspec.cpp
  64. 361
    0
      Modules/FDEM1D/src/layeredearthem.cpp
  65. 48
    0
      Modules/FDEM1D/src/modelreaderfem1d.cpp
  66. 1473
    0
      Modules/FDEM1D/src/octreegrid.cpp
  67. 115
    0
      Modules/FDEM1D/src/receivercubes.cpp
  68. 563
    0
      Modules/FDEM1D/src/receiverpoints.cpp
  69. 103
    0
      Modules/FDEM1D/src/sintransintegrationkernel.cpp
  70. 0
    0
      Modules/Optimization/CMakeLists.txt
  71. 111
    0
      Modules/Optimization/include/quasinewtonbfgs.h
  72. 85
    0
      Modules/Optimization/src/quasinewtonbfgs.cpp
  73. 0
    0
      Modules/TEM1D/CMakeLists.txt
  74. 44
    0
      Modules/TEM1D/examples/datatem.cpp
  75. 106
    0
      Modules/TEM1D/include/TEMInductiveReceiver.h
  76. 184
    0
      Modules/TEM1D/include/TEMReceiver.h
  77. 137
    0
      Modules/TEM1D/include/TEMSurvey.h
  78. 161
    0
      Modules/TEM1D/include/TEMSurveyData.h
  79. 117
    0
      Modules/TEM1D/include/TEMSurveyLine.h
  80. 146
    0
      Modules/TEM1D/include/TEMSurveyLineData.h
  81. 140
    0
      Modules/TEM1D/include/TEMSurveyLineRecord.h
  82. 141
    0
      Modules/TEM1D/include/TEMSurveyLineRecordData.h
  83. 125
    0
      Modules/TEM1D/include/TEMTransmitter.h
  84. 213
    0
      Modules/TEM1D/include/instrumenttem.h
  85. 146
    0
      Modules/TEM1D/include/inversesolvertem1d.h
  86. 83
    0
      Modules/TEM1D/include/modelreadertem1d.h
  87. 116
    0
      Modules/TEM1D/include/modelreadertem1dubc.h
  88. 103
    0
      Modules/TEM1D/include/temintegrationkernel.h
  89. 127
    0
      Modules/TEM1D/src/TEMInductiveReceiver.cpp
  90. 333
    0
      Modules/TEM1D/src/TEMReceiver.cpp
  91. 202
    0
      Modules/TEM1D/src/TEMSurvey.cpp
  92. 244
    0
      Modules/TEM1D/src/TEMSurveyData.cpp
  93. 162
    0
      Modules/TEM1D/src/TEMSurveyLine.cpp
  94. 230
    0
      Modules/TEM1D/src/TEMSurveyLineData.cpp
  95. 254
    0
      Modules/TEM1D/src/TEMSurveyLineRecord.cpp
  96. 248
    0
      Modules/TEM1D/src/TEMSurveyLineRecordData.cpp
  97. 227
    0
      Modules/TEM1D/src/TEMTransmitter.cpp
  98. 449
    0
      Modules/TEM1D/src/instrumenttem.cpp
  99. 419
    0
      Modules/TEM1D/src/inversesolvertem1d.cpp
  100. 0
    0
      Modules/TEM1D/src/modelreadertem1d.cpp

+ 0
- 0
Modules/DCIP/CMakeLists.txt View File


+ 116
- 0
Modules/DCIP/examples/DCIPElectrode.cpp View File

@@ -0,0 +1,116 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      11/10/2014 12:31:01 PM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#include "DCIPElectrode.h"
21
+#include "DCSurvey.h"
22
+
23
+using namespace Lemma;
24
+
25
+int main() {
26
+
27
+
28
+    //DCIPElectrode* Electrode1 = DCIPElectrode::New();
29
+    DCIPElectrode* Electrode2 = DCIPElectrode::New();
30
+    DCIPElectrode* Electrode3 = DCIPElectrode::New();
31
+    DCIPElectrode* Electrode4 = DCIPElectrode::New();
32
+    DCIPElectrode* Electrode5 = DCIPElectrode::New();
33
+    DCIPElectrode* Electrode6 = DCIPElectrode::New();
34
+    DCIPElectrode* Electrode7 = DCIPElectrode::New();
35
+    DCIPElectrode* Electrode8 = DCIPElectrode::New();
36
+    DCIPElectrode* Electrode9 = DCIPElectrode::New();
37
+
38
+        //Electrode1->SetLocation( Vector3r( 23.23, 18.1, -45 )  );
39
+        Electrode2->SetLocation( Vector3r( 13.23, 18.1, -25 ) );
40
+        Electrode3->SetLocation( Vector3r( 13.23, 18.1, -25 ) );
41
+        Electrode4->SetLocation( Vector3r( 13.23, 18.1, -25 ) );
42
+        Electrode4->SetLocation( Vector3r( 13.23, 18.1, -25 ) );
43
+        Electrode5->SetLocation( Vector3r( 13.23, 18.1, -25 ) );
44
+        Electrode6->SetLocation( Vector3r( 13.23, 18.1, -25 ) );
45
+        Electrode7->SetLocation( Vector3r( 13.23, 18.1, -25 ) );
46
+        Electrode8->SetLocation( Vector3r( 13.23, 18.1, -25 ) );
47
+        Electrode9->SetLocation( Vector3r( 13.23, 18.1, -25 ) );
48
+
49
+//:        std::cout << *Electrode1 << std::endl;
50
+//     std::ofstream ofstr("DCIPElectrode.yaml");
51
+//         ofstr << *Electrode1;
52
+//         ofstr.close();
53
+
54
+    /*
55
+    //std::ifstream ifstr("DCIPElectrode.yaml");
56
+    std::ifstream ifstr("test.yaml");
57
+    YAML::Node node = YAML::Load(ifstr);
58
+    DCIPElectrode* Ex = DCIPElectrode::DeSerialize(node);
59
+    std::cout << *Ex << std::endl;
60
+    */
61
+    //exit(1);
62
+
63
+    //std::cout << *Electrode << std::endl;
64
+    //std::cout << *Electrode2 << std::endl;
65
+
66
+    // Set up a Survey
67
+    DCSurvey* Survey = DCSurvey::New();
68
+        // Instead we should just put location in, and then survey acts as factory?
69
+        DCIPElectrode* Electrode1 = Survey->PoundElectrode( Vector3r( 13.23, 18.1, -25 ), "L0-E0" );
70
+        Survey->PoundElectrode( Electrode2 , "L0-E1" );
71
+        Survey->PoundElectrode( Electrode3 , "L0-E2" );
72
+        Survey->PoundElectrode( Electrode4 , "L0-E3" );
73
+        Survey->PoundElectrode( Electrode5 , "L0-E4" );
74
+        Survey->PoundElectrode( Electrode6 , "L0-E5" );
75
+        Survey->PoundElectrode( Electrode7 , "L0-E6" );
76
+        Survey->PoundElectrode( Electrode8 , "L0-E7" );
77
+        Survey->PoundElectrode( Electrode9 , "L0-E8" );
78
+
79
+        int J0 = Survey->AddInjection( Electrode1, Electrode2, 1.0 );
80
+            Survey->AddMeasurement(J0, Electrode3, Electrode4 );
81
+            Survey->AddMeasurement(J0, Electrode5, Electrode6 );
82
+            Survey->AddMeasurement(J0, Electrode6, Electrode7 );
83
+            Survey->AddMeasurement(J0, "L0-E7", "L0-E8" );
84
+
85
+        int J1 = Survey->AddInjection( Electrode2, Electrode3, 1.0 );
86
+            Survey->AddMeasurement(J1, Electrode3, Electrode4 );
87
+            Survey->AddMeasurement(J1, Electrode5, Electrode6 );
88
+            Survey->AddMeasurement(J1, Electrode6, Electrode7 );
89
+
90
+        int J2 = Survey->AddInjection( Electrode3, Electrode4, 1.0 );
91
+            Survey->AddMeasurement(J2, Electrode3, Electrode4 );
92
+            Survey->AddMeasurement(J2, Electrode5, Electrode6 );
93
+            Survey->AddMeasurement(J2, Electrode6, Electrode7 );
94
+
95
+        //Survey->AddMeasurement(L1, L2)
96
+        std::cout << *Survey << std::endl;
97
+
98
+        std::ofstream outstr("DC.yaml");
99
+            outstr << *Survey << std::endl;
100
+            outstr.close();
101
+
102
+        Survey->Delete();
103
+
104
+        //TODO recheck DeSerialize make sure we are filling in all the Tag vectors
105
+
106
+        std::ifstream ifstr2("DC.yaml");
107
+        YAML::Node node2 = YAML::Load(ifstr2);
108
+        DCSurvey* Survey2 = DCSurvey::DeSerialize(node2);
109
+
110
+        std::cout << "==============================================================\n";
111
+        std::cout << *Survey2 << std::endl;
112
+
113
+    return(EXIT_SUCCESS);
114
+
115
+}
116
+

+ 127
- 0
Modules/DCIP/include/DCIPElectrode.h View File

@@ -0,0 +1,127 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      11/10/2014 10:53:34 AM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+
21
+#ifndef  DCIPELECTRODE_INC
22
+#define  DCIPELECTRODE_INC
23
+
24
+#include "LemmaObject.h"
25
+
26
+namespace Lemma {
27
+
28
+    /**
29
+      \brief
30
+      \details
31
+     */
32
+    class DCIPElectrode : public LemmaObject {
33
+
34
+        friend std::ostream &operator<<(std::ostream &stream,
35
+                const DCIPElectrode &ob);
36
+
37
+        public:
38
+
39
+        // ====================  LIFECYCLE     =======================
40
+
41
+        /**
42
+         * @copybrief LemmaObject::New()
43
+         * @copydetails LemmaObject::New()
44
+         */
45
+        static DCIPElectrode* New();
46
+
47
+        /**
48
+         *  @copybrief   LemmaObject::Delete()
49
+         *  @copydetails LemmaObject::Delete()
50
+         */
51
+        void Delete();
52
+
53
+        // ====================  OPERATORS     =======================
54
+
55
+        // ====================  OPERATIONS    =======================
56
+
57
+        // ====================  ACCESS        =======================
58
+
59
+        /** Sets the physical location of the electrode
60
+         *  @param[in] loc is the location
61
+         */
62
+        void SetLocation(const Vector3r& loc);
63
+
64
+        /** Sets the tag (label) for the electrode
65
+         */
66
+        void SetLabel(const std::string& tag);
67
+
68
+        /** Sets the tag (label) for the electrode
69
+         */
70
+        std::string GetLabel( );
71
+
72
+        int GetNodeID() {return Node_ID;}
73
+        // ====================  INQUIRY       =======================
74
+
75
+#ifdef HAVE_YAMLCPP
76
+        /**
77
+         *  Uses YAML to serialize this object.
78
+         *  @return a YAML::Node
79
+         */
80
+        YAML::Node Serialize() const;
81
+
82
+        /**
83
+         *   Constructs an object from a YAML::Node.
84
+         */
85
+        static DCIPElectrode* DeSerialize(const YAML::Node& node);
86
+#endif
87
+
88
+        protected:
89
+
90
+        // ====================  LIFECYCLE     =======================
91
+
92
+        /** Default protected constructor, use New */
93
+        DCIPElectrode (const std::string& name);
94
+
95
+#ifdef HAVE_YAMLCPP
96
+        /** Protected DeDerializing constructor, use factory DeSerialize  method*/
97
+        DCIPElectrode (const YAML::Node& node);
98
+#endif
99
+
100
+        /** Default protected destructor, use Delete */
101
+        ~DCIPElectrode ();
102
+
103
+        /**
104
+         *  @copybrief   LemmaObject::Release()
105
+         *  @copydetails LemmaObject::Release()
106
+         */
107
+        void Release();
108
+
109
+        private:
110
+
111
+        // ====================  DATA MEMBERS  =========================
112
+
113
+        /** The location of the electrode */
114
+        Vector3r Location;
115
+
116
+        /** Local Node_ID on a mesh */
117
+        int Node_ID;
118
+
119
+        /** String label for the electrode */
120
+        std::string Label;
121
+
122
+    }; // -----  end of class  DCIPElectrode  -----
123
+
124
+}		// -----  end of Lemma  name  -----
125
+
126
+#endif   // ----- #ifndef DCIPELECTRODE_INC  -----
127
+

+ 240
- 0
Modules/DCIP/include/DCSurvey.h View File

@@ -0,0 +1,240 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      10/08/2014 01:51:50 PM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#ifndef  DCSURVEY
21
+#define  DCSURVEY
22
+
23
+#include "LemmaObject.h"
24
+#include "DCIPElectrode.h"
25
+
26
+#ifdef HAVE_YAMLCPP
27
+#include "yaml-cpp/yaml.h"
28
+#endif
29
+
30
+#ifdef LEMMAUSEVTK
31
+#include <vtkDataSet.h>
32
+#endif
33
+
34
+namespace Lemma {
35
+
36
+    #define EINFINITY -9999
37
+
38
+    /**
39
+      \brief   Describes a DC survey.
40
+      \details This class aims to encapulate any type of DC survey.
41
+     */
42
+    class DCSurvey : public LemmaObject {
43
+
44
+        friend std::ostream &operator<<(std::ostream &stream,
45
+                const DCSurvey &ob);
46
+
47
+        public:
48
+
49
+        // ====================  LIFECYCLE     =======================
50
+
51
+        /**
52
+         * @copybrief LemmaObject::New()
53
+         * @copydetails LemmaObject::New()
54
+         */
55
+        static DCSurvey* New();
56
+
57
+        /**
58
+         *  @copybrief   LemmaObject::Delete()
59
+         *  @copydetails LemmaObject::Delete()
60
+         */
61
+        void Delete();
62
+
63
+        // ====================  OPERATORS     =======================
64
+
65
+        // ====================  OPERATIONS    =======================
66
+
67
+        /**
68
+         *   Adds new electrode to the survey.
69
+         *   @param[in] Electrode `Pounds' a new Electrode into place.
70
+         *   @return integer index to this electrode.
71
+         *   @note Single electrodes cannot be pulled once they are pounded. The reason for this is that
72
+         *         every index then would become invalid. Furthurmore these are stored in a std::vector and
73
+         *         removing arbitrary items is inefficient.
74
+         *   @see PullElectrodes
75
+         *   @param[in] label is an optional tag for electrode.
76
+         *   @param[in] nodeID is the optional node ID on a mesh
77
+         */
78
+        int PoundElectrode( DCIPElectrode* Electrode, const std::string& label = "NULL", const int& nodeID=-1 );
79
+
80
+        /** Alternative Factory method of setting electrodes. IN this manner all memoy management
81
+         *  is handled by DCSurvey.
82
+         *  @note there is no logic preventing one from pounding coincident electrodes. Don't do it.
83
+         *  @note Single electrodes cannot be pulled once they are pounded. The reason for this is that
84
+         *         every index then would become invalid. Furthurmore these are stored in a std::vector and
85
+         *         removing arbitrary items is inefficient.
86
+         *  @see PullElectrodes
87
+         *  @param[in] loc is the location of the electrode.
88
+         *  @param[in] label is an optional label for electrode.
89
+         *  @param[in] nodeID is the optional node ID on a mesh
90
+         */
91
+        DCIPElectrode* PoundElectrode( const Vector3r& loc, const std::string& label = "NULL", const int& nodeID=-1  );
92
+
93
+#ifdef LEMMAUSEVTK
94
+        DCIPElectrode* PoundElectrode( const int& nodeID, vtkDataSet* Mesh, const std::string& label = "NULL" );
95
+#endif
96
+
97
+        /**
98
+         *  Pulls all electrodes and removes connections.
99
+         */
100
+        void PullElectrodes();
101
+
102
+        /**
103
+         *   Adds an injection point.
104
+         *   @param[in] A is the positive current electrode
105
+         *   @param[in] B is the negative current electrode
106
+         *   @param[in] J is the current intensity
107
+         *   @see AddInjection(const int& iA, const int& iB, const Real& J)
108
+         *   @see AddInjection(const int& iA, const Real& J)
109
+         *   @see AddInjection(DCIPElectrode* A, const Real& J)
110
+         */
111
+        int AddInjection( DCIPElectrode* A, DCIPElectrode* B, const Real& J);
112
+
113
+        /**
114
+         *   Adds an injection point.
115
+         *   @param[in] A is the positive current electrode.
116
+         *   @param[in] J is the current intensity.
117
+         *   B,  the negative current electrode is taken to be infinity
118
+         *   @see AddInjection(const int& iA, const int& iB, const Real& J)
119
+         *   @see AddInjection(const int& iA, const Real& J)
120
+         *   @see AddInjection(DCIPElectrode* A, DCIPElectrode* B, const Real& J)
121
+         */
122
+        int AddInjection( DCIPElectrode* A, const Real& J );
123
+
124
+        /**
125
+         *   Adds an injection point.
126
+         *   @param[in] A is the positive current electrode index
127
+         *   @param[in] B is the negative current electrode index
128
+         *   @param[in] J is the current intensity
129
+         *   @see AddInjection(DCIPElectrode* A, DCIPElectrode* B, const Real& J)
130
+         *   @see AddInjection(DCIPElectrode* A, const Real& J)
131
+         *   @see AddInjection(const int& iA, const Real& J)
132
+         */
133
+        int AddInjection( const int& iA, const int& iB, const Real& J );
134
+
135
+        /**
136
+         *   Adds an injection point with the negative electrode at infinity.
137
+         *   @param[in] A is the positive current electrode index
138
+         *   @param[in] J is the current intensity
139
+         *   @see AddInjection(DCIPElectrode* A, DCIPElectrode* B, const Real& J)
140
+         *   @see AddInjection(DCIPElectrode* A, const Real& J)
141
+         *   @see AddInjection(const int& iA, const int& iB, const Real& J)
142
+         */
143
+        int AddInjection( const int& iA, const Real& J );
144
+
145
+        /** Adds a potential measurement via the electrode pair comparison \f$ M - N \f$.
146
+         *   @param[in] M is a pointer to the `positive' electrode
147
+         *   @param[in] N is a pointer to the `negative' electrode
148
+         *   @param[in] iJ is the current injection index to associate with this measurement
149
+         */
150
+        void AddMeasurement( const int& iJ, DCIPElectrode* M, DCIPElectrode* N );
151
+
152
+        /** Adds a potential measurement via the electrode pair comparison \f$ M - N \f$.
153
+         *   @param[in] M is the `positive' electrode string label name
154
+         *   @param[in] N is the `negative' electrode string label name
155
+         *   @param[in] iJ is the current injection index to associate with this measurement
156
+         *   @see AddMeasurement( const int& iJ, DCIPElectrode* M, DCIPElectrode* N )
157
+         */
158
+        void AddMeasurement( const int& ij, const std::string& M, const std::string& N);
159
+
160
+        /**
161
+         *  Used to probe for the index and current of an injection
162
+         *  @param[in] ij is the current injection indes
163
+         *  @param[out] ii is the node index
164
+         *  @param[out] jj is the current
165
+         */
166
+        void GetA( const int& ij, int& ii, Real& jj );
167
+
168
+        /**
169
+         *  Used to probe for the index and current of an injection
170
+         *  @param[in] ij is the current injection indes
171
+         *  @param[out] ii is the node index
172
+         *  @param[out] jj is the current
173
+         */
174
+        void GetB( const int& ij, int& ii, Real& jj );
175
+
176
+
177
+        // ====================  ACCESS        =======================
178
+
179
+        // ====================  INQUIRY       =======================
180
+
181
+        #ifdef HAVE_YAMLCPP
182
+        YAML::Node Serialize() const;
183
+        static DCSurvey* DeSerialize(const YAML::Node& node);
184
+        #endif
185
+
186
+        protected:
187
+
188
+        // ====================  LIFECYCLE     =======================
189
+
190
+        /** Default protected constructor, use New */
191
+        DCSurvey (const std::string& name);
192
+
193
+        #ifdef HAVE_YAMLCPP
194
+        /** Default protected constructor, use New */
195
+        DCSurvey (const YAML::Node& node);
196
+        #endif
197
+
198
+        /** Default protected destructor, use Delete */
199
+        ~DCSurvey ();
200
+
201
+        /**
202
+         *  @copybrief   LemmaObject::Release()
203
+         *  @copydetails LemmaObject::Release()
204
+         */
205
+        void Release();
206
+
207
+        private:
208
+
209
+        // ====================  DATA MEMBERS  =========================
210
+
211
+        /** The electrodes */
212
+        std::vector<DCIPElectrode*>                Electrodes;
213
+
214
+        /** Tags for the electrodes, lines etc. Ordered with Electrodes std::vector */
215
+        std::vector<std::string>                   OrderedElectrodeLabels;
216
+
217
+        /** Map of tags for the electrodes, lines etc. */
218
+        std::map<std::string, std::pair<DCIPElectrode*, int> >      ElectrodeLabelMap;
219
+
220
+        /** The A Injection electrodes */
221
+        std::vector<int>     A_Electrodes;
222
+
223
+        /** The A Injection electrodes */
224
+        std::vector<int>     B_Electrodes;
225
+
226
+        /** The A Injection electrodes */
227
+        std::vector<Real>    J_Electrodes;
228
+
229
+        /** First Potential electrodes */
230
+        std::vector< std::vector<int> > M_Electrodes;
231
+
232
+        /** Second Potential electrodes */
233
+        std::vector< std::vector<int> > N_Electrodes;
234
+
235
+    }; // -----  end of class  DCSurvey  -----
236
+
237
+
238
+}		// -----  end of Lemma  name  -----
239
+
240
+#endif   // ----- #ifndef DCSURVEY  -----

+ 165
- 0
Modules/DCIP/src/DCIPElectrode.cpp View File

@@ -0,0 +1,165 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      11/10/2014 10:53:53 AM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#include "DCIPElectrode.h"
21
+
22
+namespace Lemma {
23
+
24
+
25
+
26
+    // ====================  FRIEND METHODS  =====================
27
+#ifdef HAVE_YAMLCPP
28
+    std::ostream &operator << (std::ostream &stream, const DCIPElectrode &ob) {
29
+        stream << ob.Serialize()  << "\n---\n"; // End of doc --- as a direct stream should encapulate thingy
30
+        return stream;
31
+    }
32
+#else
33
+    std::ostream &operator<<(std::ostream &stream, const DCIPElectrode& ob) {
34
+        stream << *(LemmaObject*)(&ob);
35
+        return stream;
36
+    }
37
+#endif
38
+
39
+    // ====================  LIFECYCLE     =======================
40
+
41
+    //--------------------------------------------------------------------------------------
42
+    //       Class:  DCIPElectrode
43
+    //      Method:  DCIPElectrode
44
+    // Description:  constructor (protected)
45
+    //--------------------------------------------------------------------------------------
46
+    DCIPElectrode::DCIPElectrode (const std::string& name) : LemmaObject(name), Node_ID(-1), Label(std::string("None")) {
47
+
48
+    }  // -----  end of method DCIPElectrode::DCIPElectrode  (constructor)  -----
49
+
50
+#ifdef HAVE_YAMLCPP
51
+    //--------------------------------------------------------------------------------------
52
+    //       Class:  DCIPElectrode
53
+    //      Method:  DCIPElectrode
54
+    // Description:  DeSerializing constructor (protected)
55
+    //--------------------------------------------------------------------------------------
56
+    DCIPElectrode::DCIPElectrode (const YAML::Node& node) : LemmaObject(node) {
57
+        if (node.Tag() != this->Name) {
58
+            throw std::runtime_error("In DCIPElectrode(node), node is of wrong type");
59
+        }
60
+        this->Location = node["Location"].as<Vector3r>();
61
+        this->Node_ID = node["Node_ID"].as<int>();
62
+        this->Label = node["Label"].as<std::string>();
63
+    }  // -----  end of method DCIPElectrode::DCIPElectrode  (constructor)  -----
64
+#endif
65
+
66
+    //--------------------------------------------------------------------------------------
67
+    //       Class:  DCIPElectrode
68
+    //      Method:  New()
69
+    // Description:  public constructor
70
+    //--------------------------------------------------------------------------------------
71
+    DCIPElectrode* DCIPElectrode::New() {
72
+        DCIPElectrode*  Obj = new DCIPElectrode("DCIPElectrode");
73
+        Obj->AttachTo(Obj);
74
+        return Obj;
75
+    }
76
+
77
+    //--------------------------------------------------------------------------------------
78
+    //       Class:  DCIPElectrode
79
+    //      Method:  ~DCIPElectrode
80
+    // Description:  destructor (protected)
81
+    //--------------------------------------------------------------------------------------
82
+    DCIPElectrode::~DCIPElectrode () {
83
+
84
+    }  // -----  end of method DCIPElectrode::~DCIPElectrode  (destructor)  -----
85
+
86
+    //--------------------------------------------------------------------------------------
87
+    //       Class:  DCIPElectrode
88
+    //      Method:  Delete
89
+    // Description:  public destructor
90
+    //--------------------------------------------------------------------------------------
91
+    void DCIPElectrode::Delete() {
92
+        this->DetachFrom(this);
93
+    }
94
+
95
+    //--------------------------------------------------------------------------------------
96
+    //       Class:  DCIPElectrode
97
+    //      Method:  Release
98
+    // Description:  destructor (protected)
99
+    //--------------------------------------------------------------------------------------
100
+    void DCIPElectrode::Release() {
101
+        delete this;
102
+    }
103
+
104
+
105
+#ifdef HAVE_YAMLCPP
106
+    //--------------------------------------------------------------------------------------
107
+    //       Class:  DCIPElectrode
108
+    //      Method:  Serialize
109
+    //--------------------------------------------------------------------------------------
110
+    YAML::Node  DCIPElectrode::Serialize (  ) const {
111
+        YAML::Node node = LemmaObject::Serialize();
112
+        node.SetTag( this->Name );
113
+        // FILL IN CLASS SPECIFICS HERE
114
+        node["Location"] = Location;
115
+        node["Node_ID"] = Node_ID;
116
+        node["Label"] = Label;
117
+        return node;
118
+    }		// -----  end of method DCIPElectrode::Serialize  -----
119
+
120
+
121
+    //--------------------------------------------------------------------------------------
122
+    //       Class:  DCIPElectrode
123
+    //      Method:  DeSerialize
124
+    //--------------------------------------------------------------------------------------
125
+    DCIPElectrode* DCIPElectrode::DeSerialize ( const YAML::Node& node  ) {
126
+        DCIPElectrode* Object = new DCIPElectrode(node);
127
+        Object->AttachTo(Object);
128
+        DESERIALIZECHECK( node, Object )
129
+        return Object ;
130
+    }		// -----  end of method DCIPElectrode::DeSerialize  -----
131
+#endif
132
+
133
+
134
+    //--------------------------------------------------------------------------------------
135
+    //       Class:  DCIPElectrode
136
+    //      Method:  SetLocation
137
+    //--------------------------------------------------------------------------------------
138
+    void DCIPElectrode::SetLocation ( const Vector3r& loc ) {
139
+        Location = loc;
140
+        return ;
141
+    }		// -----  end of method DCIPElectrode::SetLocation  -----
142
+
143
+
144
+
145
+    //--------------------------------------------------------------------------------------
146
+    //       Class:  DCIPElectrode
147
+    //      Method:  SetTag
148
+    //--------------------------------------------------------------------------------------
149
+    void DCIPElectrode::SetLabel ( const std::string& inLabel  ) {
150
+        Label = inLabel;
151
+        return ;
152
+    }		// -----  end of method DCIPElectrode::SetTag  -----
153
+
154
+
155
+    //--------------------------------------------------------------------------------------
156
+    //       Class:  DCIPElectrode
157
+    //      Method:  get_Label
158
+    //--------------------------------------------------------------------------------------
159
+    std::string DCIPElectrode::GetLabel (  ) {
160
+        return Label;
161
+    }		// -----  end of method DCIPElectrode::get_Label  -----
162
+
163
+
164
+}		// -----  end of Lemma  name  -----
165
+

+ 377
- 0
Modules/DCIP/src/DCSurvey.cpp View File

@@ -0,0 +1,377 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      10/08/2014 01:52:04 PM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#include	"DCSurvey.h"
21
+
22
+namespace Lemma {
23
+
24
+
25
+    // ====================  FRIEND METHODS  =====================
26
+
27
+    #ifdef HAVE_YAMLCPP
28
+    std::ostream &operator << (std::ostream &stream, const DCSurvey &ob) {
29
+        stream << ob.Serialize()  << "\n---\n"; // End of doc --- a direct stream should encapsulate object
30
+        return stream;
31
+    }
32
+    #else
33
+    std::ostream &operator<<(std::ostream &stream, const DCSurvey &ob) {
34
+        stream << *(LemmaObject*)(&ob);
35
+        return stream;
36
+    }
37
+    #endif
38
+
39
+    // ====================  LIFECYCLE     =======================
40
+
41
+    //--------------------------------------------------------------------------------------
42
+    //       Class:  DCSurvey
43
+    //      Method:  DCSurvey
44
+    // Description:  constructor (protected)
45
+    //--------------------------------------------------------------------------------------
46
+    DCSurvey::DCSurvey (const std::string& name) : LemmaObject(name) {
47
+
48
+    }  // -----  end of method DCSurvey::DCSurvey  (constructor)  -----
49
+
50
+    //--------------------------------------------------------------------------------------
51
+    //       Class:  DCSurvey
52
+    //      Method:  DCSurvey
53
+    // Description:  DeSerializing constructor (protected)
54
+    //--------------------------------------------------------------------------------------
55
+    #ifdef HAVE_YAMLCPP
56
+    DCSurvey::DCSurvey (const YAML::Node& node) : LemmaObject(node) {
57
+
58
+        if (node.Tag() != "DCSurvey") {
59
+            throw std::runtime_error("DCSurvey->DeSerialize cannot deserialize non-DCSurvey");
60
+        }
61
+
62
+        std::map<YAML::Node, int>  eMap;
63
+        for(YAML::const_iterator it=node["Electrodes"].begin(); it!=node["Electrodes"].end(); ++it) {
64
+            std::string e = it->first.as<std::string>();
65
+            Electrodes.push_back( DCIPElectrode::DeSerialize( node["Electrodes"][e] ) );
66
+            Electrodes[Electrodes.size()-1]->AttachTo(this);
67
+            eMap[ node["Electrodes"][Electrodes.size()-1] ] = Electrodes.size() -1 ;
68
+            OrderedElectrodeLabels.push_back(e);
69
+            ElectrodeLabelMap[e] = std::pair<DCIPElectrode*, int>(Electrodes[Electrodes.size()-1], Electrodes.size()-1);
70
+        }
71
+
72
+        //std::cout << "J-0\n" << node["Injections"]["J-0"] << std::endl;
73
+        int ij = 0 ;
74
+        for(YAML::const_iterator it=node["Injections"].begin(); it!=node["Injections"].end(); ++it) {
75
+
76
+            //std::cout << "it->first" << it->first << std::endl;
77
+
78
+            A_Electrodes.push_back( ElectrodeLabelMap[ it->second["A"]["Label"].as<std::string>() ].second );
79
+            B_Electrodes.push_back( ElectrodeLabelMap[ it->second["B"]["Label"].as<std::string>() ].second );
80
+            J_Electrodes.push_back( it->second["J"].as<Real>() );
81
+            //std::string Jstr = it->first.as<std::string>(); // J-1
82
+
83
+            M_Electrodes.push_back( std::vector<int>() );
84
+            N_Electrodes.push_back( std::vector<int>() );
85
+
86
+            for (int ii=0; ii<it->second["Measurements"]["Number"].as<int>(); ++ii) {
87
+                std::string Mstr = std::string("V-") + to_string(ii);
88
+                //std::cout << "measurements" << it->second["Measurements"][Mstr]["M"]["Label"] << std::endl;
89
+                M_Electrodes[ij].push_back( ElectrodeLabelMap[ it->second["Measurements"][Mstr]["M"]["Label"].as<std::string>() ].second );
90
+                N_Electrodes[ij].push_back( ElectrodeLabelMap[ it->second["Measurements"][Mstr]["N"]["Label"].as<std::string>() ].second );
91
+            }
92
+            ++ ij;
93
+        }
94
+
95
+    }  // -----  end of method DCSurvey::DCSurvey  (constructor)  -----
96
+    #endif
97
+
98
+    //--------------------------------------------------------------------------------------
99
+    //       Class:  DCSurvey
100
+    //      Method:  New()
101
+    // Description:  public constructor
102
+    //--------------------------------------------------------------------------------------
103
+    DCSurvey* DCSurvey::New() {
104
+        DCSurvey*  Obj = new DCSurvey("DCSurvey");
105
+        Obj->AttachTo(Obj);
106
+        return Obj;
107
+    }
108
+
109
+    //--------------------------------------------------------------------------------------
110
+    //       Class:  DCSurvey
111
+    //      Method:  ~DCSurvey
112
+    // Description:  destructor (protected)
113
+    //--------------------------------------------------------------------------------------
114
+    DCSurvey::~DCSurvey () {
115
+
116
+    }  // -----  end of method DCSurvey::~DCSurvey  (destructor)  -----
117
+
118
+    //--------------------------------------------------------------------------------------
119
+    //       Class:  DCSurvey
120
+    //      Method:  Delete
121
+    // Description:  public destructor
122
+    //--------------------------------------------------------------------------------------
123
+    void DCSurvey::Delete() {
124
+        this->DetachFrom(this);
125
+    }
126
+
127
+    //--------------------------------------------------------------------------------------
128
+    //       Class:  DCSurvey
129
+    //      Method:  Release
130
+    // Description:  destructor (protected)
131
+    //--------------------------------------------------------------------------------------
132
+    void DCSurvey::Release() {
133
+        this->PullElectrodes();
134
+        delete this;
135
+    }
136
+
137
+    #ifdef HAVE_YAMLCPP
138
+    //--------------------------------------------------------------------------------------
139
+    //       Class:  DCSurvey
140
+    //      Method:  Serialize
141
+    //--------------------------------------------------------------------------------------
142
+    YAML::Node  DCSurvey::Serialize (  ) const {
143
+        YAML::Node node = LemmaObject::Serialize();
144
+        node.SetTag( this->Name );
145
+        node["NumberOfElectrodes"] = Electrodes.size();
146
+
147
+        // All the electrodes
148
+        for (std::map<std::string, std::pair<DCIPElectrode*, int> >::const_iterator it  = ElectrodeLabelMap.begin();
149
+                                                                                    it != ElectrodeLabelMap.end(); ++it) {
150
+            node["Electrodes"][ it->first ] = it->second.first->Serialize();
151
+        }
152
+
153
+        // Injections and Measurements
154
+        for (unsigned int ic=0; ic<A_Electrodes.size(); ++ic) {
155
+            std::string strLab = std::string("J-") + to_string(ic);
156
+            node["Injections"][strLab]["A"] = node["Electrodes"][ OrderedElectrodeLabels[ A_Electrodes[ic] ] ];
157
+            node["Injections"][strLab]["B"] = node["Electrodes"][ OrderedElectrodeLabels[ B_Electrodes[ic] ] ];
158
+            node["Injections"][strLab]["J"] = J_Electrodes[ic];
159
+            node["Injections"][strLab]["Measurements"]["Number"] = M_Electrodes[ic].size();
160
+            for (unsigned int iv=0; iv<M_Electrodes[ic].size(); ++iv) {
161
+                node["Injections"][strLab]["Measurements"][std::string("V-") + to_string(iv)]["M"] =
162
+                    node["Electrodes"][ OrderedElectrodeLabels[M_Electrodes[ic][iv]] ];
163
+                node["Injections"][strLab]["Measurements"][std::string("V-") + to_string(iv)]["N"] =
164
+                    node["Electrodes"][ OrderedElectrodeLabels[N_Electrodes[ic][iv]] ];
165
+            }
166
+        }
167
+
168
+        return node;
169
+    }		// -----  end of method DCSurvey::Serialize  -----
170
+
171
+
172
+    //--------------------------------------------------------------------------------------
173
+    //       Class:  DCSurvey
174
+    //      Method:  DeSerialize
175
+    //--------------------------------------------------------------------------------------
176
+    DCSurvey* DCSurvey::DeSerialize ( const YAML::Node& node  ) {
177
+        DCSurvey* Object = new DCSurvey(node);
178
+        Object->AttachTo(Object);
179
+        DESERIALIZECHECK( node, Object )
180
+        return Object ;
181
+    }		// -----  end of method DCSurvey::DeSerialize  -----
182
+    #endif
183
+
184
+    //--------------------------------------------------------------------------------------
185
+    //       Class:  DCSurvey
186
+    //      Method:  PoundElectrode
187
+    //--------------------------------------------------------------------------------------
188
+    int DCSurvey::PoundElectrode ( DCIPElectrode* Electrode, const std::string& tag, const int&nodeID ) {
189
+        Electrodes.push_back(Electrode);
190
+        if (tag != "NULL") {
191
+            OrderedElectrodeLabels.push_back(tag);
192
+            //ElectrodeTagMap[tag] = Electrode;
193
+            ElectrodeLabelMap[tag] = std::pair<DCIPElectrode*, int> (Electrode, Electrodes.size()-1);
194
+            Electrode->SetLabel(tag);
195
+        } else {
196
+            OrderedElectrodeLabels.push_back( std::string("E") + to_string(Electrodes.size()-1) );
197
+            //ElectrodeTagMap[std::string("E") + to_string(Electrodes.size()-1)] = Electrode;
198
+            ElectrodeLabelMap[std::string("E") + to_string(Electrodes.size()-1)] =
199
+                std::pair<DCIPElectrode*, int>(Electrode, Electrodes.size()-1);
200
+            Electrode->SetLabel( std::string("E") + to_string(Electrodes.size()-1) );
201
+        }
202
+        Electrode->AttachTo(this);
203
+        return  static_cast<int>( Electrodes.size() ) ;
204
+    }		// -----  end of method DCSurvey::PoundElectrode  -----
205
+
206
+    //--------------------------------------------------------------------------------------
207
+    //       Class:  DCSurvey
208
+    //      Method:  PoundElectrode
209
+    //--------------------------------------------------------------------------------------
210
+    DCIPElectrode* DCSurvey::PoundElectrode ( const Vector3r& loc, const std::string& tag, const int& nodeID ) {
211
+        DCIPElectrode* Electrode = DCIPElectrode::New();
212
+            Electrode->SetLocation( loc );
213
+        Electrodes.push_back(Electrode);
214
+        if (tag != "NULL") {
215
+            OrderedElectrodeLabels.push_back(tag);
216
+            ElectrodeLabelMap[tag] = std::pair<DCIPElectrode*, int> (Electrode, Electrodes.size()-1);
217
+            Electrode->SetLabel(tag);
218
+        } else {
219
+            OrderedElectrodeLabels.push_back( std::string("E") + to_string(Electrodes.size()-1) );
220
+            ElectrodeLabelMap[std::string("E") + to_string(Electrodes.size()-1)] =
221
+                std::pair<DCIPElectrode*, int>(Electrode, Electrodes.size()-1);
222
+            Electrode->SetLabel( std::string("E") + to_string(Electrodes.size()-1) );
223
+        }
224
+        Electrode->AttachTo(this);
225
+        return  Electrode;
226
+    }		// -----  end of method DCSurvey::PoundElectrode  -----
227
+
228
+    //--------------------------------------------------------------------------------------
229
+    //       Class:  DCSurvey
230
+    //      Method:  PoundElectrode
231
+    //--------------------------------------------------------------------------------------
232
+#ifdef LEMMAUSEVTK
233
+    DCIPElectrode* DCSurvey::PoundElectrode( const int& nodeID, vtkDataSet* Mesh, const std::string& tag ) {
234
+        DCIPElectrode* Electrode = DCIPElectrode::New();
235
+        double* loc = Mesh->GetPoint(nodeID);
236
+        Electrode->SetLocation( Vector3r(loc[0], loc[1], loc[2]) );
237
+        Electrodes.push_back(Electrode);
238
+        if (tag != "NULL") {
239
+            OrderedElectrodeLabels.push_back(tag);
240
+            ElectrodeLabelMap[tag] = std::pair<DCIPElectrode*, int> (Electrode, Electrodes.size()-1);
241
+            Electrode->SetLabel(tag);
242
+        } else {
243
+            OrderedElectrodeLabels.push_back( std::string("E") + to_string(Electrodes.size()-1) );
244
+            ElectrodeLabelMap[std::string("E") + to_string(Electrodes.size()-1)] =
245
+                std::pair<DCIPElectrode*, int>(Electrode, Electrodes.size()-1);
246
+            Electrode->SetLabel( std::string("E") + to_string(Electrodes.size()-1) );
247
+        }
248
+        Electrode->AttachTo(this);
249
+        return Electrode;
250
+    }		// -----  end of method DCSurvey::PoundElectrode  -----
251
+#endif
252
+
253
+    //--------------------------------------------------------------------------------------
254
+    //       Class:  DCSurvey
255
+    //      Method:  PullElectrodes
256
+    //--------------------------------------------------------------------------------------
257
+    void DCSurvey::PullElectrodes (  ) {
258
+        for (std::vector<DCIPElectrode*>::iterator it = Electrodes.begin() ; it != Electrodes.end(); ++it) {
259
+            (*it)->DetachFrom(this);
260
+        }
261
+        Electrodes.clear();
262
+        OrderedElectrodeLabels.clear();
263
+        ElectrodeLabelMap.clear();
264
+        A_Electrodes.clear();
265
+        B_Electrodes.clear();
266
+        M_Electrodes.clear();
267
+        N_Electrodes.clear();
268
+
269
+        return ;
270
+    }		// -----  end of method DCSurvey::PullElectrodes  -----
271
+
272
+
273
+    //--------------------------------------------------------------------------------------
274
+    //       Class:  DCSurvey
275
+    //      Method:  AddInjection
276
+    //--------------------------------------------------------------------------------------
277
+    int DCSurvey::AddInjection ( DCIPElectrode* A, DCIPElectrode* B, const Real& J ) {
278
+        bool fA = false;
279
+        bool fB = false;
280
+        for (unsigned int i=0; i<Electrodes.size(); ++i) {
281
+            if (Electrodes[i] == A) {
282
+                A_Electrodes.push_back(i);
283
+                M_Electrodes.push_back( std::vector<int>() );
284
+                N_Electrodes.push_back( std::vector<int>() );
285
+                fA = true;
286
+            }
287
+            if (Electrodes[i] == B) {
288
+                B_Electrodes.push_back(i);
289
+                fB = true;
290
+            }
291
+            if (fA == true && fB == true) break;
292
+        }
293
+        if (!fA) {
294
+            throw std::runtime_error( "Injection point A not found" );
295
+        }
296
+        if (!fB) {
297
+            throw std::runtime_error( "Injection point B not found" );
298
+        }
299
+        J_Electrodes.push_back(J);
300
+        return A_Electrodes.size()-1; // we want index
301
+    }		// -----  end of method DCSurvey::AddInjection  -----
302
+
303
+
304
+    //--------------------------------------------------------------------------------------
305
+    //       Class:  DCSurvey
306
+    //      Method:  AddMeasurement
307
+    //--------------------------------------------------------------------------------------
308
+    void DCSurvey::AddMeasurement ( const int& iJ, DCIPElectrode* M, DCIPElectrode* N  ) {
309
+        bool fM = false;
310
+        bool fN = false;
311
+        for (unsigned int i=0; i<Electrodes.size(); ++i) {
312
+            if (Electrodes[i] == M) {
313
+                M_Electrodes[iJ].push_back(i);
314
+                fM = true;
315
+            }
316
+            if (Electrodes[i] == N) {
317
+                N_Electrodes[iJ].push_back(i);
318
+                fN = true;
319
+            }
320
+            if (fM == true && fN == true) break;
321
+        }
322
+        if (!fM) {
323
+            throw std::runtime_error( "Injection point M not found" );
324
+        }
325
+        if (!fN) {
326
+            throw std::runtime_error( "Injection point N not found" );
327
+        }
328
+        return ;
329
+    }		// -----  end of method DCSurvey::AddMeasurement  -----
330
+
331
+    //--------------------------------------------------------------------------------------
332
+    //       Class:  DCSurvey
333
+    //      Method:  AddMeasurement
334
+    //--------------------------------------------------------------------------------------
335
+
336
+    void DCSurvey::AddMeasurement ( const int& iJ, const std::string& M, const std::string& N ) {
337
+
338
+        std::pair<DCIPElectrode*, int> Mp = ElectrodeLabelMap[M];
339
+        std::pair<DCIPElectrode*, int> Np = ElectrodeLabelMap[N];
340
+
341
+        if (Mp.first == NULL) {
342
+            throw std::runtime_error( "Injection point M not found" );
343
+        }
344
+        if (Np.first == NULL) {
345
+            throw std::runtime_error( "Injection point N not found" );
346
+        }
347
+
348
+        M_Electrodes[iJ].push_back( Mp.second );
349
+        N_Electrodes[iJ].push_back( Np.second );
350
+
351
+        return ;
352
+    }		// -----  end of method DCSurvey::AddMeasurement  -----
353
+
354
+
355
+    //--------------------------------------------------------------------------------------
356
+    //       Class:  DCSurvey
357
+    //      Method:  GetA
358
+    //--------------------------------------------------------------------------------------
359
+    void DCSurvey::GetA (const int& iA, int& iB, Real& J ) {
360
+        iB = Electrodes[A_Electrodes[iA]]->GetNodeID();
361
+        J = J_Electrodes[iA];
362
+        return ;
363
+    }		// -----  end of method DCSurvey::GetA  -----
364
+
365
+    //--------------------------------------------------------------------------------------
366
+    //       Class:  DCSurvey
367
+    //      Method:  GetB
368
+    //--------------------------------------------------------------------------------------
369
+    void DCSurvey::GetB (const int& iA, int& iB, Real& J ) {
370
+        iB = Electrodes[B_Electrodes[iA]]->GetNodeID();
371
+        J = -J_Electrodes[iA];
372
+        return ;
373
+    }		// -----  end of method DCSurvey::GetA  -----
374
+
375
+
376
+}		// -----  end of Lemma  name  -----
377
+

+ 0
- 0
Modules/FDEM1D/CMakeLists.txt View File


+ 112
- 0
Modules/FDEM1D/include/FHTKey.h View File

@@ -0,0 +1,112 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      02/11/2014 03:33:08 PM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+
21
+#ifndef  FHTKEY_INC
22
+#define  FHTKEY_INC
23
+
24
+#include "hankeltransform.h"
25
+
26
+namespace Lemma {
27
+
28
+    /**
29
+      \brief   Impliments the fast Hankel transform as outlines by Key 2011
30
+      \details This filter uses 61, 121, or 201 filter points and supports both lagged and related
31
+                kernel arguments. This algorithm is a port of code carrying the following copyright and
32
+                restriction:
33
+                %------------------------------------------------------------------%
34
+                % Copyright (c) 2012 by the Society of Exploration Geophysicists.  %
35
+                % For more information, go to http://software.seg.org/2012/0003 .  %
36
+                % You must read and accept usage terms at:                         %
37
+                % http://software.seg.org/disclaimer.txt before use.               %
38
+                %------------------------------------------------------------------%
39
+     */
40
+    class FHTKey : public HankelTransform {
41
+
42
+        friend std::ostream &operator<<(std::ostream &stream,
43
+                const FHTKey &ob);
44
+
45
+        public:
46
+
47
+        // ====================  LIFECYCLE     =======================
48
+
49
+        /**
50
+         * @copybrief LemmaObject::New()
51
+         * @copydetails LemmaObject::New()
52
+         */
53
+        static FHTKey* New();
54
+
55
+        /**
56
+         *  @copybrief   LemmaObject::Delete()
57
+         *  @copydetails LemmaObject::Delete()
58
+         */
59
+        void Delete();
60
+
61
+        // ====================  OPERATORS     =======================
62
+
63
+        // ====================  OPERATIONS    =======================
64
+
65
+        Complex Zgauss(const int &ikk, const EMMODE &imode,
66
+                            const int &itype, const Real &rho,
67
+                            const Real &wavef, KernelEm1DBase *Kernel);
68
+
69
+        /// Computes related kernels, if applicable, otherwise this is
70
+        /// just a dummy function.
71
+        void ComputeRelated(const Real& rho, KernelEm1DBase* Kernel);
72
+
73
+        void ComputeRelated(const Real& rho, std::vector< KernelEm1DBase* > KernelVec);
74
+
75
+        void ComputeRelated(const Real& rho, KernelEM1DManager* KernelManager);
76
+
77
+        // ====================  ACCESS        =======================
78
+
79
+        // ====================  INQUIRY       =======================
80
+
81
+        protected:
82
+
83
+        // ====================  LIFECYCLE     =======================
84
+
85
+        /** Default protected constructor, use New */
86
+        FHTKey (const std::string& name);
87
+
88
+        /** Default protected destructor, use Delete */
89
+        ~FHTKey ();
90
+
91
+        /**
92
+         *  @copybrief   LemmaObject::Release()
93
+         *  @copydetails LemmaObject::Release()
94
+         */
95
+        void Release();
96
+
97
+        private:
98
+
99
+        // ====================  DATA MEMBERS  =========================
100
+
101
+        // Shared Filter Weights
102
+		static const Eigen::Matrix<Real, 201, 3>  WT201;
103
+
104
+        /// Holds answer, dimensions are NumConv, and NumberRelated.
105
+        Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic> Zans;
106
+
107
+    }; // -----  end of class  FHTKey  -----
108
+
109
+}		// -----  end of Lemma  name  -----
110
+
111
+#endif   // ----- #ifndef FHTKEY_INC  -----
112
+

+ 112
- 0
Modules/FDEM1D/include/FHTKey101.h View File

@@ -0,0 +1,112 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      02/11/2014 03:33:08 PM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+
21
+#ifndef  FHTKEY101_INC
22
+#define  FHTKEY101_INC
23
+
24
+#include "hankeltransform.h"
25
+
26
+namespace Lemma {
27
+
28
+    /**
29
+      \brief   Impliments the fast Hankel transform as outlines by Key 2011
30
+      \details This filter uses 51, 101, or 201 filter points and supports both lagged and related
31
+                kernel arguments. This algorithm is a port of code carrying the following copyright and
32
+                restriction:
33
+                %------------------------------------------------------------------%
34
+                % Copyright (c) 2012 by the Society of Exploration Geophysicists.  %
35
+                % For more information, go to http://software.seg.org/2012/0003 .  %
36
+                % You must read and accept usage terms at:                         %
37
+                % http://software.seg.org/disclaimer.txt before use.               %
38
+                %------------------------------------------------------------------%
39
+     */
40
+    class FHTKey101 : public HankelTransform {
41
+
42
+        friend std::ostream &operator<<(std::ostream &stream,
43
+                const FHTKey101 &ob);
44
+
45
+        public:
46
+
47
+        // ====================  LIFECYCLE     =======================
48
+
49
+        /**
50
+         * @copybrief LemmaObject::New()
51
+         * @copydetails LemmaObject::New()
52
+         */
53
+        static FHTKey101* New();
54
+
55
+        /**
56
+         *  @copybrief   LemmaObject::Delete()
57
+         *  @copydetails LemmaObject::Delete()
58
+         */
59
+        void Delete();
60
+
61
+        // ====================  OPERATORS     =======================
62
+
63
+        // ====================  OPERATIONS    =======================
64
+
65
+        Complex Zgauss(const int &ikk, const EMMODE &imode,
66
+                            const int &itype, const Real &rho,
67
+                            const Real &wavef, KernelEm1DBase *Kernel);
68
+
69
+        /// Computes related kernels, if applicable, otherwise this is
70
+        /// just a dummy function.
71
+        void ComputeRelated(const Real& rho, KernelEm1DBase* Kernel);
72
+
73
+        void ComputeRelated(const Real& rho, std::vector< KernelEm1DBase* > KernelVec);
74
+
75
+        void ComputeRelated(const Real& rho, KernelEM1DManager* KernelManager);
76
+
77
+        // ====================  ACCESS        =======================
78
+
79
+        // ====================  INQUIRY       =======================
80
+
81
+        protected:
82
+
83
+        // ====================  LIFECYCLE     =======================
84
+
85
+        /** Default protected constructor, use New */
86
+        FHTKey101 (const std::string& name);
87
+
88
+        /** Default protected destructor, use Delete */
89
+        ~FHTKey101 ();
90
+
91
+        /**
92
+         *  @copybrief   LemmaObject::Release()
93
+         *  @copydetails LemmaObject::Release()
94
+         */
95
+        void Release();
96
+
97
+        private:
98
+
99
+        // ====================  DATA MEMBERS  =========================
100
+
101
+        // Shared Filter Weights
102
+		static const Eigen::Matrix<Real, 101, 3>  WT101;
103
+
104
+        /// Holds answer, dimensions are NumConv, and NumberRelated.
105
+        Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic> Zans;
106
+
107
+    }; // -----  end of class  FHTKey101  -----
108
+
109
+}		// -----  end of Lemma  name  -----
110
+
111
+#endif   // ----- #ifndef FHTKEY101_INC  -----
112
+

+ 112
- 0
Modules/FDEM1D/include/FHTKey51.h View File

@@ -0,0 +1,112 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      02/11/2014 03:33:08 PM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+
21
+#ifndef  FHTKEY51_INC
22
+#define  FHTKEY51_INC
23
+
24
+#include "hankeltransform.h"
25
+
26
+namespace Lemma {
27
+
28
+    /**
29
+      \brief   Impliments the fast Hankel transform as outlines by Key 2011
30
+      \details This filter uses 51, 101, or 201 filter points and supports both lagged and related
31
+                kernel arguments. This algorithm is a port of code carrying the following copyright and
32
+                restriction:
33
+                %------------------------------------------------------------------%
34
+                % Copyright (c) 2012 by the Society of Exploration Geophysicists.  %
35
+                % For more information, go to http://software.seg.org/2012/0003 .  %
36
+                % You must read and accept usage terms at:                         %
37
+                % http://software.seg.org/disclaimer.txt before use.               %
38
+                %------------------------------------------------------------------%
39
+     */
40
+    class FHTKey51 : public HankelTransform {
41
+
42
+        friend std::ostream &operator<<(std::ostream &stream,
43
+                const FHTKey51 &ob);
44
+
45
+        public:
46
+
47
+        // ====================  LIFECYCLE     =======================
48
+
49
+        /**
50
+         * @copybrief LemmaObject::New()
51
+         * @copydetails LemmaObject::New()
52
+         */
53
+        static FHTKey51* New();
54
+
55
+        /**
56
+         *  @copybrief   LemmaObject::Delete()
57
+         *  @copydetails LemmaObject::Delete()
58
+         */
59
+        void Delete();
60
+
61
+        // ====================  OPERATORS     =======================
62
+
63
+        // ====================  OPERATIONS    =======================
64
+
65
+        Complex Zgauss(const int &ikk, const EMMODE &imode,
66
+                            const int &itype, const Real &rho,
67
+                            const Real &wavef, KernelEm1DBase *Kernel);
68
+
69
+        /// Computes related kernels, if applicable, otherwise this is
70
+        /// just a dummy function.
71
+        void ComputeRelated(const Real& rho, KernelEm1DBase* Kernel);
72
+
73
+        void ComputeRelated(const Real& rho, std::vector< KernelEm1DBase* > KernelVec);
74
+
75
+        void ComputeRelated(const Real& rho, KernelEM1DManager* KernelManager);
76
+
77
+        // ====================  ACCESS        =======================
78
+
79
+        // ====================  INQUIRY       =======================
80
+
81
+        protected:
82
+
83
+        // ====================  LIFECYCLE     =======================
84
+
85
+        /** Default protected constructor, use New */
86
+        FHTKey51 (const std::string& name);
87
+
88
+        /** Default protected destructor, use Delete */
89
+        ~FHTKey51 ();
90
+
91
+        /**
92
+         *  @copybrief   LemmaObject::Release()
93
+         *  @copydetails LemmaObject::Release()
94
+         */
95
+        void Release();
96
+
97
+        private:
98
+
99
+        // ====================  DATA MEMBERS  =========================
100
+
101
+        // Shared Filter Weights
102
+		static const Eigen::Matrix<Real, 51, 3>  WT51;
103
+
104
+        /// Holds answer, dimensions are NumConv, and NumberRelated.
105
+        Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic> Zans;
106
+
107
+    }; // -----  end of class  FHTKey51  -----
108
+
109
+}		// -----  end of Lemma  name  -----
110
+
111
+#endif   // ----- #ifndef FHTKEY51_INC  -----
112
+

+ 87
- 0
Modules/FDEM1D/include/GroundedElectricDipole.h View File

@@ -0,0 +1,87 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      01/29/2014 06:59:39 AM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+
21
+#ifndef  GROUNDEDELECTRICDIPOLE_INC
22
+#define  GROUNDEDELECTRICDIPOLE_INC
23
+
24
+#include "dipolesource.h"
25
+
26
+namespace Lemma {
27
+
28
+    /**
29
+      \brief   Grounded electric dipole
30
+      \details Used to model an idealised grounded electrid dipole of arbitrary
31
+               polarisation.
32
+     */
33
+    class GroundedElectricDipole : public DipoleSource {
34
+
35
+        friend std::ostream &operator<<(std::ostream &stream,
36
+                const GroundedElectricDipole &ob);
37
+
38
+        public:
39
+
40
+        // ====================  LIFECYCLE     =======================
41
+
42
+        /**
43
+         * @copybrief LemmaObject::New()
44
+         * @copydetails LemmaObject::New()
45
+         */
46
+        static GroundedElectricDipole* New();
47
+
48
+        /**
49
+         *  @copybrief   LemmaObject::Delete()
50
+         *  @copydetails LemmaObject::Delete()
51
+         */
52
+        void Delete();
53
+
54
+        // ====================  OPERATORS     =======================
55
+
56
+        // ====================  OPERATIONS    =======================
57
+
58
+        // ====================  ACCESS        =======================
59
+
60
+        // ====================  INQUIRY       =======================
61
+
62
+        protected:
63
+
64
+        // ====================  LIFECYCLE     =======================
65
+
66
+        /** Default protected constructor, use New */
67
+        GroundedElectricDipole (const std::string& name);
68
+
69
+        /** Default protected destructor, use Delete */
70
+        ~GroundedElectricDipole ();
71
+
72
+        /**
73
+         *  @copybrief   LemmaObject::Release()
74
+         *  @copydetails LemmaObject::Release()
75
+         */
76
+        void Release();
77
+
78
+        private:
79
+
80
+        // ====================  DATA MEMBERS  =========================
81
+
82
+    }; // -----  end of class  GroundedElectricDipole  -----
83
+
84
+}		// -----  end of Lemma  name  -----
85
+
86
+#endif   // ----- #ifndef GROUNDEDELECTRICDIPOLE_INC  -----
87
+

+ 105
- 0
Modules/FDEM1D/include/LayeredEarthEMReader.h View File

@@ -0,0 +1,105 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      09/27/2013 01:44:36 PM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2013, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2013, Trevor Irons
18
+ */
19
+
20
+#ifndef  LAYEREDEARTHEMREADER_INC
21
+#define  LAYEREDEARTHEMREADER_INC
22
+
23
+#include "LemmaObject.h"
24
+#include "ASCIIParser.h"
25
+#include "layeredearthem.h"
26
+
27
+namespace Lemma {
28
+
29
+    /**
30
+      \brief
31
+      \details
32
+     */
33
+    class LayeredEarthEMReader : public LemmaObject {
34
+
35
+        friend std::ostream &operator<<(std::ostream &stream,
36
+                const LayeredEarthEMReader &ob);
37
+
38
+        public:
39
+
40
+        // ====================  LIFECYCLE     =======================
41
+
42
+        /**
43
+         * @copybrief LemmaObject::New()
44
+         * @copydetails LemmaObject::New()
45
+         */
46
+        static LayeredEarthEMReader* New();
47
+
48
+        /**
49
+         *  @copybrief   LemmaObject::Delete()
50
+         *  @copydetails LemmaObject::Delete()
51
+         */
52
+        void Delete();
53
+
54
+        // ====================  OPERATORS     =======================
55
+
56
+        // ====================  OPERATIONS    =======================
57
+
58
+        /** Reads ASCII input file. The format is as follows
59
+@code
60
+4           // Number of NON-AIR layers
61
+200   10    // resistivity, thickness layer 1 [Ohm-m] [m]
62
+20    10    // resistivity, thickness layer 2 [Ohm-m] [m]
63
+1120  10    // resistivity, thickness layer 3 [Ohm-m] [m]
64
+200         // resistivity of bottom layer [Ohm-m]
65
+@endcode
66
+         * @param[in] name is the filename
67
+         */
68
+        void ReadASCIIInputFile( const std::string& name );
69
+
70
+        // ====================  ACCESS        =======================
71
+
72
+        /** @return the pointer address of the LayeredEarthEM
73
+         */
74
+        LayeredEarthEM* GetLayeredEarth();
75
+
76
+        // ====================  INQUIRY       =======================
77
+
78
+        protected:
79
+
80
+        // ====================  LIFECYCLE     =======================
81
+
82
+        /** Default protected constructor, use New */
83
+        LayeredEarthEMReader (const std::string& name);
84
+
85
+        /** Default protected destructor, use Delete */
86
+        ~LayeredEarthEMReader ();
87
+
88
+        /**
89
+         *  @copybrief   LemmaObject::Release()
90
+         *  @copydetails LemmaObject::Release()
91
+         */
92
+        void Release();
93
+
94
+        private:
95
+
96
+        // ====================  DATA MEMBERS  =========================
97
+
98
+        LayeredEarthEM*         LayEarth;
99
+
100
+    }; // -----  end of class  LayeredEarthEMReader  -----
101
+
102
+
103
+}		// -----  end of Lemma  name  -----
104
+
105
+#endif   // ----- #ifndef LAYEREDEARTHEMREADER_INC  -----

+ 88
- 0
Modules/FDEM1D/include/MagneticDipole.h View File

@@ -0,0 +1,88 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      09/25/2013 08:20:14 AM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2013, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2013, Trevor Irons
18
+ */
19
+
20
+#ifndef  MAGNETICDIPOLE_INC
21
+#define  MAGNETICDIPOLE_INC
22
+
23
+#include "dipolesource.h"
24
+
25
+namespace Lemma {
26
+
27
+/**
28
+  @class
29
+  \brief   Magnetic Dipole
30
+  \details Used to model an idealised magnetic dipole of arbitrary
31
+           polarisation.
32
+ */
33
+class MagneticDipole : public DipoleSource {
34
+
35
+    friend std::ostream &operator<<(std::ostream &stream,
36
+            const MagneticDipole &ob);
37
+
38
+    public:
39
+
40
+    // ====================  LIFECYCLE     =======================
41
+
42
+    /**
43
+     * @copybrief LemmaObject::New()
44
+     * @copydetails LemmaObject::New()
45
+     */
46
+    static MagneticDipole* New();
47
+
48
+    /**
49
+     *  @copybrief   LemmaObject::Delete()
50
+     *  @copydetails LemmaObject::Delete()
51
+     */
52
+    void Delete();
53
+
54
+    // ====================  OPERATORS     =======================
55
+
56
+    // ====================  OPERATIONS    =======================
57
+
58
+    // ====================  ACCESS        =======================
59
+
60
+    // ====================  INQUIRY       =======================
61
+
62
+    protected:
63
+
64
+    // ====================  LIFECYCLE     =======================
65
+
66
+    /** Default protected constructor, use New */
67
+    MagneticDipole (const std::string& name);
68
+
69
+    /** Default protected destructor, use Delete */
70
+    ~MagneticDipole ();
71
+
72
+    /**
73
+     *  @copybrief   LemmaObject::Release()
74
+     *  @copydetails LemmaObject::Release()
75
+     */
76
+    void Release();
77
+
78
+    private:
79
+
80
+    // ====================  DATA MEMBERS  =========================
81
+
82
+    KernelEM1DManager*          Kernels;
83
+
84
+}; // -----  end of class  MagneticDipole  -----
85
+
86
+} // namespace Lemma
87
+
88
+#endif   // ----- #ifndef MAGNETICDIPOLE_INC  -----

+ 169
- 0
Modules/FDEM1D/include/PolygonalWireAntenna.h View File

@@ -0,0 +1,169 @@
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     05/18/2010
11
+  @version  $Id: PolygonalWireAntenna.h 211 2015-02-27 05:43:26Z tirons $
12
+ **/
13
+
14
+#include "WireAntenna.h"
15
+
16
+#ifndef  POLYGONALWIREANTENNA_INC
17
+#define  POLYGONALWIREANTENNA_INC
18
+
19
+namespace Lemma {
20
+
21
+    // ===================================================================
22
+    //        Class:  PolygonalWireAntenna
23
+    /// \brief   Class representing polygonal wire antennae.
24
+    /// \details For EM calculations, dipoles representing this loop are
25
+    ///    created dynamically, depending on receiver location.
26
+    /// @todo enforce minimum dipole moment.
27
+    // ===================================================================
28
+    class PolygonalWireAntenna : public WireAntenna {
29
+
30
+        friend std::ostream &operator<<(std::ostream &stream,
31
+                const PolygonalWireAntenna &ob);
32
+
33
+        public:
34
+
35
+            // ====================  LIFECYCLE     =======================
36
+
37
+            /**
38
+             * Declares all memory and returns a new instance.
39
+             */
40
+            static PolygonalWireAntenna* New();
41
+
42
+            /**
43
+             * @copybrief LemmaObject::Delete()
44
+             * @copydetails LemmaObject::Delete()
45
+             */
46
+            void Delete();
47
+
48
+            /// Makes a deep copy of this antenna with all connections except
49
+            /// the dipole approximation.
50
+            PolygonalWireAntenna* Clone();
51
+
52
+            // ====================  OPERATORS     =======================
53
+
54
+            // ====================  OPERATIONS    =======================
55
+
56
+            /// Approximates with ungrounded electrical dipoles, such that
57
+            /// minDipoleRatio is satisfied.
58
+            virtual void ApproximateWithElectricDipoles(const Vector3r &rp);
59
+
60
+            /** Sets the minimum ratio for dipole moments to be used to
61
+             * approximate the loop. A smaller ratio yields a more accurate
62
+             * result, but is more expensive. Default is (1/5).
63
+             */
64
+            void SetMinDipoleRatio(const Real& ratio);
65
+
66
+            /** Sets the minimum moment for dipole moments to be used to
67
+             * approximate the loop.
68
+             */
69
+            void SetMinDipoleMoment(const Real& m);
70
+
71
+            /** Sets the minimum moment for dipole moments to be used to
72
+             * approximate the loop.
73
+             */
74
+            void SetMaxDipoleMoment(const Real& m);
75
+
76
+            // ====================  ACCESS        =======================
77
+
78
+            // ====================  INQUIRY       =======================
79
+
80
+            #ifdef HAVE_YAMLCPP
81
+            /**
82
+             *  Uses YAML to serialize this object.
83
+             *  @return a YAML::Node
84
+             */
85
+            YAML::Node Serialize() const;
86
+
87
+            /**
88
+             *   Constructs an object from a YAML::Node.
89
+             */
90
+            static PolygonalWireAntenna* DeSerialize(const YAML::Node& node);
91
+            #endif
92
+
93
+        protected:
94
+
95
+            // ====================  LIFECYCLE     =======================
96
+
97
+            /// Default protected constructor.
98
+            PolygonalWireAntenna (const std::string& name);
99
+
100
+#ifdef HAVE_YAMLCPP
101
+            /// Default protected constructor.
102
+            PolygonalWireAntenna (const YAML::Node& node);
103
+#endif
104
+
105
+            /// Default protected constructor.
106
+            ~PolygonalWireAntenna ();
107
+
108
+            /**
109
+             * @copybrief LemmaObject::Release()
110
+             * @copydetails LemmaObject::Release()
111
+             */
112
+            void Release();
113
+
114
+            // ====================  DATA MEMBERS  =======================
115
+
116
+            /// minimum ratio of dipole moment to distance to receiver point
117
+            Real minDipoleRatio;
118
+
119
+            /// Maximum dipole moment allowed
120
+            Real minDipoleMoment;
121
+
122
+            /// Maximum dipole moment allowed
123
+            Real maxDipoleMoment;
124
+
125
+            /// appends
126
+            void PushXYZDipoles(const Vector3r &step, const Vector3r &cp,
127
+                            const Vector3r &dir,
128
+                            std::vector<DipoleSource*> &Dipoles) ;
129
+
130
+            /// corrects for overstep
131
+            void CorrectOverstepXYZDipoles(const Vector3r &step,
132
+                            const Vector3r &cp,
133
+                            const Vector3r &dir,
134
+                            std::vector<DipoleSource*> &Dipoles );
135
+
136
+            // ====================  OPERATIONS    =======================
137
+
138
+
139
+            /// Returns the nearest point on a line segment to another point.
140
+            /// if the point is not on the line-segment, return the
141
+            /// nearest end-point
142
+            /// @param[in] p0, p1 define the line segement
143
+            /// @param[in] rp is a point in space. The function returns the
144
+            /// closest point on the line to this point.
145
+            /// @return The point (Lemma::Vector3r) on the line defined by p0,
146
+            /// and p1, closest to rp
147
+            Vector3r ClosestPointOnLine(const Vector3r &p0, const Vector3r &p1,
148
+                            const Vector3r &rp);
149
+
150
+            /// Interpolates dipoles along line segment defined by p0 and p1.
151
+            void InterpolateLineSegment(const Vector3r &p0, const Vector3r &p1,
152
+                            const Vector3r &rp);
153
+
154
+
155
+            /// List of the dipoles
156
+            //std::vector<DipoleSource*>           Dipoles;
157
+
158
+            /// Points that define this loop
159
+            //Vector3Xr                            Points;
160
+
161
+        private:
162
+
163
+            Vector3r                               rRepeat;
164
+
165
+    }; // -----  end of class  PolygonalWireAntenna  -----
166
+
167
+}       // -----  end of Lemma  name  -----
168
+
169
+#endif   // ----- #ifndef POLYGONALWIREANTENNA_INC  -----

+ 197
- 0
Modules/FDEM1D/include/QWEKey.h View File

@@ -0,0 +1,197 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      02/12/2014 10:20:18 AM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#ifndef  QWEKEY_INC
21
+#define  QWEKEY_INC
22
+
23
+#include	"hankeltransform.h"
24
+#include    <Eigen/Eigenvalues>
25
+#ifdef HAVEBOOSTSPECIALFUNCTIONS
26
+#include "boost/math/special_functions.hpp"
27
+#include "boost/math/special_functions/bessel.hpp"
28
+#endif
29
+
30
+namespace Lemma {
31
+
32
+    /** breakpoint to use in division of domain, based on zeros of bessel function or
33
+        regular nPi spacing.
34
+     */
35
+    enum sZeroType{J0, J1, NPI};
36
+
37
+    /**
38
+      \brief  Port of Key's quadrature with extrapolation Hankel transform algorithm.
39
+      \details Details of the algorithm can be found in Key2011. This code is a port
40
+               of the published algorithm, which contains the following notice:
41
+        %------------------------------------------------------------------%
42
+        % Copyright (c) 2012 by the Society of Exploration Geophysicists.  %
43
+        % For more information, go to http://software.seg.org/2012/0003 .  %
44
+        % You must read and accept usage terms at:                         %
45
+        % http://software.seg.org/disclaimer.txt before use.               %
46
+        %------------------------------------------------------------------%
47
+     */
48
+    class QWEKey : public HankelTransform {
49
+
50
+        friend std::ostream &operator<<(std::ostream &stream,
51
+                const QWEKey &ob);
52
+
53
+        public:
54
+
55
+        // ====================  LIFECYCLE     =======================
56
+
57
+        /**
58
+         * @copybrief LemmaObject::New()
59
+         * @copydetails LemmaObject::New()
60
+         */
61
+        static QWEKey* New();
62
+
63
+        /**
64
+         *  @copybrief   LemmaObject::Delete()
65
+         *  @copydetails LemmaObject::Delete()
66
+         */
67
+        void Delete();
68
+
69
+        // ====================  OPERATORS     =======================
70
+
71
+        void TestPrivate(const int& N);
72
+
73
+        // ====================  OPERATIONS    =======================
74
+
75
+
76
+        Complex Zgauss(const int &ikk, const EMMODE &imode,
77
+                            const int &itype, const Real &rho,
78
+                            const Real &wavef, KernelEm1DBase *Kernel);
79
+
80
+        /// Computes related kernels, if applicable, otherwise this is
81
+        /// just a dummy function.
82
+        void ComputeRelated(const Real& rho, KernelEm1DBase* Kernel);
83
+
84
+        void ComputeRelated(const Real& rho, std::vector< KernelEm1DBase* > KernelVec);
85
+
86
+        void ComputeRelated(const Real& rho, KernelEM1DManager* KernelManager);
87
+
88
+        // ====================  ACCESS        =======================
89
+
90
+        // ====================  INQUIRY       =======================
91
+
92
+        protected:
93
+
94
+        // ====================  LIFECYCLE     =======================
95
+
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
+        /** Calculates Gauss quadrature weights of order N on the interval -1,1
109
+            Algorithm from p 129 in:
110
+            Trefethen, L. N., 2000, Spectral methods in MATLAB: Society for
111
+            Industrial and Applied Mathematics (SIAM), volume 10 of Software,
112
+            Environments, and Tools.
113
+        */
114
+        void GaussQuadWeights(const int& N);
115
+
116
+        /** Returns the quadrature intervals and Bessel function weights used for the
117
+            QWE method.
118
+
119
+         */
120
+        void BesselWeights( const sZeroType& sType);
121
+
122
+        /**  Computes an infinite integral using the partial sum of quadrature terms
123
+             accelerated by sequence extrapolation using the Shanks transformation
124
+             implemented with Wynn's epsilon algorithm.
125
+         */
126
+        void QWE(const Real& rho);
127
+
128
+        /** Calls the underlying kernel functions evaluated as necessary
129
+         */
130
+        void getEyKernel(const int& i, const int& idx, const Real& rho);
131
+
132
+        private:
133
+
134
+        // ====================  DATA MEMBERS  =========================
135
+
136
+        /** Relative tolerance, default is 1e-6 */
137
+        Real    RelTol;
138
+
139
+        /** Absolute tolerance, default is 1e-24 */
140
+        Real    AbsTol;
141
+
142
+        /** Quadrature order, higher is more accurate but more expensive. Eefault is 9 */
143
+        int     nQuad;
144
+
145
+        /** in QWE partial integrals before Shanks recurive algorithm. Defaults to 1  */
146
+        int nDelay;
147
+
148
+        /** Maximum number of intervals to integrate over . Defaults to 40  */
149
+        int nIntervalsMax;
150
+
151
+        /** Weighing of gaussian quadrature points */
152
+        VectorXr GaussWeights;
153
+
154
+        /** Abscissa locations of quadrature points */
155
+        VectorXr GaussAbscissa;
156
+
157
+        /** Breakpoints for dividing up the global integral */
158
+        VectorXr xInt;
159
+
160
+        /** All quadrature points between all breakpoints */
161
+        VectorXr Bx;
162
+
163
+        /** J0 weights */
164
+        VectorXr BJ0;
165
+
166
+        /** J1 weights */
167
+        VectorXr BJ1;
168
+
169
+        /** array of lambda arguments */
170
+        VectorXr Lambda;
171
+
172
+        /** array of lambda arguments */
173
+        VectorXr Intervals;
174
+
175
+        MatrixXcr TS;
176
+        VectorXi  Tn;
177
+        MatrixXcr Textrap;
178
+        MatrixXr  TrelErr;
179
+        MatrixXr  TabsErr;
180
+
181
+        /** Container to hold bessel arguments */
182
+        Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic > Zwork;
183
+
184
+        /** Container to hold bessel arguments */
185
+        Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic > Zans;
186
+
187
+        /** Manager for related kernels to evaluate */
188
+        KernelEM1DManager* KernelManager;
189
+
190
+    }; // -----  end of class  QWEKey  -----
191
+
192
+
193
+}		// -----  end of Lemma  name  -----
194
+
195
+#endif   // ----- #ifndef QWEKEY_INC  -----
196
+
197
+

+ 88
- 0
Modules/FDEM1D/include/UngroundedElectricDipole.h View File

@@ -0,0 +1,88 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      01/29/2014 08:52:43 AM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+
21
+#ifndef  UNGROUNDEDELECTRICDIPOLE_INC
22
+#define  UNGROUNDEDELECTRICDIPOLE_INC
23
+
24
+#include "dipolesource.h"
25
+
26
+namespace Lemma {
27
+
28
+    /**
29
+      \brief  Ungrounded electric dipole
30
+      \details Used to model an idealised ungrounded electric dipole. Used primarily in integrating
31
+                around current sources.
32
+     */
33
+    class UngroundedElectricDipole : public DipoleSource {
34
+
35
+        friend std::ostream &operator<<(std::ostream &stream,
36
+                const UngroundedElectricDipole &ob);
37
+
38
+        public:
39
+
40
+        // ====================  LIFECYCLE     =======================
41
+
42
+        /**
43
+         * @copybrief LemmaObject::New()
44
+         * @copydetails LemmaObject::New()
45
+         */
46
+        static UngroundedElectricDipole* New();
47
+
48
+        /**
49
+         *  @copybrief   LemmaObject::Delete()
50
+         *  @copydetails LemmaObject::Delete()
51
+         */
52
+        void Delete();
53
+
54
+        // ====================  OPERATORS     =======================
55
+
56
+        // ====================  OPERATIONS    =======================
57
+
58
+        // ====================  ACCESS        =======================
59
+
60
+        // ====================  INQUIRY       =======================
61
+
62
+        protected:
63
+
64
+        // ====================  LIFECYCLE     =======================
65
+
66
+        /** Default protected constructor, use New */
67
+        UngroundedElectricDipole (const std::string& name);
68
+
69
+        /** Default protected destructor, use Delete */
70
+        ~UngroundedElectricDipole ();
71
+
72
+        /**
73
+         *  @copybrief   LemmaObject::Release()
74
+         *  @copydetails LemmaObject::Release()
75
+         */
76
+        void Release();
77
+
78
+        private:
79
+
80
+        // ====================  DATA MEMBERS  =========================
81
+
82
+    }; // -----  end of class  UngroundedElectricDipole  -----
83
+
84
+
85
+}		// -----  end of Lemma  name  -----
86
+
87
+#endif   // ----- #ifndef UNGROUNDEDELECTRICDIPOLE_INC  -----
88
+

+ 249
- 0
Modules/FDEM1D/include/WireAntenna.h View File

@@ -0,0 +1,249 @@
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/16/2009
11
+  @version  $Id: WireAntenna.h 201 2015-01-03 00:07:47Z tirons $
12
+ **/
13
+
14
+#ifndef __WIREANTENNA_H
15
+#define __WIREANTENNA_H
16
+
17
+#include "LemmaObject.h"
18
+#include "dipolesource.h"
19
+
20
+#ifdef LEMMAUSEVTK
21
+#include "vtkActor.h"
22
+#endif
23
+
24
+namespace Lemma {
25
+
26
+
27
+    // ===================================================================
28
+    /**      Class:  WireAntenna
29
+      * \brief   Class representing a wire antennae.
30
+      * \details This is an abstract class.
31
+	  */
32
+    // ===================================================================
33
+    class WireAntenna : public LemmaObject {
34
+
35
+        friend std::ostream &operator<<(std::ostream &stream,
36
+            const WireAntenna &ob);
37
+
38
+        public:
39
+
40
+            // ====================  LIFECYCLE     =======================
41
+
42
+            /**
43
+             * Initialises antenna to contain no points, with no current
44
+             * and no frequency. NumberOfTurns set to 1
45
+             */
46
+            static WireAntenna* New();
47
+
48
+            /**
49
+             * Provides deep copy
50
+             */
51
+            virtual WireAntenna* Clone();
52
+
53
+            /**
54
+             * @copybrief LemmaObject::Delete()
55
+             * @copydetails LemmaObject::Delete()
56
+             */
57
+            void Delete();
58
+
59
+            // ====================  OPERATORS     =======================
60
+
61
+            // ====================  OPERATIONS    =======================
62
+
63
+            /**
64
+              * Approximates with evenly spaced electric dipoles around loop
65
+              * @param[in] delta is the spacing between moments
66
+			  */
67
+            virtual void ApproximateWithElectricDipoles(const Real &delta);
68
+
69
+            // ====================  ACCESS        =======================
70
+
71
+			/**
72
+              * Sets the number of turns in the loop, default is 1
73
+              * @param[in] nturns is the number of turns of the loop.
74
+			  */
75
+            void SetNumberOfTurns(const int &nturns);
76
+
77
+            /**
78
+              * Sets the number of points in the loop
79
+			  */
80
+            void SetNumberOfPoints(const int &np);
81
+
82
+			/**
83
+              * Sets a corner point of the loop. Counting starts at 0. It
84
+              * is not required to have the loop be closed right now, but
85
+              * its a good idea.
86
+			  */
87
+            void SetPoint(const int &p, const Vector3r &pos);
88
+
89
+            /**
90
+              * Sets a corner point of the loop. Counting starts at 0. It
91
+              * is not required to have the loop be closed right now, but
92
+              * its a good idea.
93
+			  */
94
+            void SetPoint(const int &p, const Real&x, const Real& y, const Real& z);
95
+
96
+            /** Sets the frequency of the current in the loop, default is 0
97
+			  * @param[in] ifreq is the frequency number to set
98
+              * @param[in] freq is the frequency (Hz) of the current
99
+			  */
100
+            void SetFrequency(const int& ifreq, const Real &freq);
101
+			/**
102
+              * Sets the number of frequencies.
103
+              * @param[in] nfreq is the number of frequencies that will be
104
+              * computed.
105
+			  */
106
+            void SetNumberOfFrequencies(const int& nfreq);
107
+
108
+			/**
109
+              * Sets the current in the loop, default is 0
110
+              * @param[in] amp is the current in the loop, in Amperes
111
+			  */
112
+            void SetCurrent(const Real &amp);
113
+
114
+            // ====================  INQUIRY       =======================
115
+
116
+            #ifdef HAVE_YAMLCPP
117
+            /**
118
+             *  Uses YAML to serialize this object.
119
+             *  @return a YAML::Node
120
+             */
121
+            YAML::Node Serialize() const;
122
+
123
+            /**
124
+             *   Constructs an object from a YAML::Node.
125
+             */
126
+            static WireAntenna* DeSerialize(const YAML::Node& node);
127
+            #endif
128
+
129
+			/**
130
+              * Returns the number of turns
131
+              * @return the number of turns of the loop.
132
+			  */
133
+            int GetNumberOfTurns( );
134
+
135
+            /**
136
+             * Returns all of the points
137
+             */
138
+            Vector3Xr GetPoints();
139
+
140
+            /**
141
+             * Returns all of the points in a general matrix, useful for python wrapper
142
+             */
143
+            MatrixXr GetPointsMat();
144
+
145
+			/**
146
+              * Returns the frequency in the loop.
147
+              * @return is the frequency in the loop in Hz
148
+			  */
149
+            Real GetFrequency(const int& ifreq);
150
+
151
+
152
+			/**
153
+              * Returns the current in the loop.
154
+              * @return is the Current
155
+			  */
156
+            Real GetCurrent( );
157
+
158
+
159
+			/**
160
+              * Returns pointer to a dipole source
161
+			  */
162
+            DipoleSource* GetDipoleSource(const int &dip);
163
+
164
+			/**
165
+              * returns number of dipoles used to approximate this
166
+              * loop
167
+			  */
168
+            int GetNumberOfDipoles();
169
+
170
+			/**
171
+              * @return the number of frequencies of this wire loop.
172
+			  */
173
+            int GetNumberOfFrequencies();
174
+
175
+            #ifdef LEMMAUSEVTK
176
+            /** Returns an actor that can be placed into a vtk scene easily
177
+              * Note that this function throws a pointer, it is the
178
+              * receivers job to manage this memory!
179
+			  */
180
+            vtkActor* GetVtkActor(const int &idip);
181
+            #endif
182
+
183
+            /** Returns true or false if loop is horizontally planar
184
+             */
185
+            bool IsHorizontallyPlanar();
186
+
187
+        protected:
188
+
189
+            // ====================  LIFECYCLE     =======================
190
+
191
+			/**
192
+              * Default protected constructor.
193
+			  */
194
+            WireAntenna (const std::string &name);
195
+
196
+#ifdef HAVE_YAMLCPP
197
+        /** Protected DeDerializing constructor, use factory DeSerialize  method*/
198
+            WireAntenna (const YAML::Node& node);
199
+#endif
200
+
201
+			/**
202
+              * Default protected destructor.
203
+			  */
204
+            ~WireAntenna ();
205
+
206
+            /**
207
+             * @copybrief LemmaObject::Release()
208
+             * @copydetails LemmaObject::Release()
209
+             */
210
+            void Release();
211
+
212
+            // ====================  DATA MEMBERS  =======================
213
+
214
+			/**
215
+              * Number of points that define the loop
216
+			  */
217
+            int NumberOfPoints;
218
+
219
+			/**
220
+              * Current in antennae (Amps)
221
+			  */
222
+            Real Current;
223
+
224
+			/**
225
+              * Number of turns
226
+			  */
227
+            int NumberOfTurns;
228
+
229
+			/**
230
+              * List of the dipoles
231
+			  */
232
+            std::vector<DipoleSource*>           Dipoles;
233
+
234
+			/**
235
+              * Points that define this loop
236
+			  */
237
+            Vector3Xr                            Points;
238
+
239
+			/**
240
+              * Frequencies of the loop.
241
+			  */
242
+            VectorXr                             Freqs;
243
+
244
+        private:
245
+
246
+    }; // -----  end of class  WireAntenna  -----
247
+
248
+}
249
+#endif // __WIREANTENNA_H

+ 232
- 0
Modules/FDEM1D/include/emearth1d.h View File

@@ -0,0 +1,232 @@
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.h 266 2015-04-01 03:24:00Z tirons $
12
+ **/
13
+
14
+#ifndef __EMEARTH1D_H
15
+#define __EMEARTH1D_H
16
+
17
+#include "dipolesource.h"
18
+#include "layeredearthem.h"
19
+#include "receiverpoints.h"
20
+#include "WireAntenna.h"
21
+#include "PolygonalWireAntenna.h"
22
+#include "kernelem1dspec.h"
23
+#include "kernelem1dmanager.h"
24
+#include "hankeltransformgaussianquadrature.h"
25
+#include "hankeltransformhankel2.h"
26
+#include "FHTKey.h"
27
+#include "FHTKey51.h"
28
+#include "FHTKey101.h"
29
+#include "QWEKey.h"
30
+#include "CubicSplineInterpolator.h"
31
+
32
+#ifdef HAVEBOOSTPROGRESS
33
+#include "boost/progress.hpp"
34
+#endif
35
+
36
+namespace Lemma {
37
+
38
+    // =======================================================================
39
+    //        Class:  EmEarth1D
40
+    /// \brief  Implimentation of 1D EM solution.
41
+    /// \details  We've done a lot of different things.
42
+    // =======================================================================
43
+    class EMEarth1D : public LemmaObject {
44
+
45
+		friend std::ostream &operator<<(std::ostream &stream,
46
+			const EMEarth1D &ob);
47
+
48
+        public:
49
+
50
+            //friend class KernelEm1D;
51
+
52
+            // ====================  LIFECYCLE     ===========================
53
+
54
+            /**
55
+             *  Returns pointer to new EMEarth1D. Location is
56
+             *  initialized to (0,0,0) type and polarization are
57
+             *  initialized  to nonworking values that will throw
58
+             *  exceptions if used.
59
+             */
60
+            static EMEarth1D* New();
61
+
62
+            /**
63
+             * @copybrief LemmaObject::Delete()
64
+             * @copydetails LemmaObject::Delete()
65
+             */
66
+            void Delete();
67
+
68
+            /** stream debugging info to std::out
69
+             */
70
+            void Query();
71
+
72
+            #ifdef HAVE_YAMLCPP
73
+            /** YAML Serializing method
74
+             */
75
+            YAML::Node Serialize() const;
76
+
77
+            //static EMEarth1D* DeSerialize(const YAML::Node& node);
78
+            #endif
79
+
80
+            // ====================  OPERATORS     ===========================
81
+
82
+            // ====================  OPERATIONS    ===========================
83
+
84
+            /// Calculates the field(s) due to an ungrounded dipole source
85
+            /// Calls FORTRAN library em1d (em1dnew.for)
86
+#ifdef COMPILE_FORTRAN
87
+            void MakeCalc();
88
+#endif
89
+
90
+            /** C++ wrapper for em1dnew.for, serial */
91
+            void MakeCalc3();
92
+
93
+            /** Calculates the field(s) due to a wire antennae */
94
+            void CalculateWireAntennaFields(bool progressbar=false);
95
+
96
+            // ====================  ACCESS        ===========================
97
+
98
+            /** Attaches an antennae */
99
+            void AttachWireAntenna(WireAntenna *antennae);
100
+
101
+            /** Attaches a dipole for calculation */
102
+            void AttachDipoleSource(DipoleSource *dipole);
103
+
104
+            /** Attaches a layered earth model for calculation */
105
+            void AttachLayeredEarthEM(LayeredEarthEM *Earth);
106
+
107
+            /** Attaches a set of receiver points for calculation */
108
+            void AttachReceiverPoints(ReceiverPoints *Receivers);
109
+
110
+            /** Sets the fields that are calcultated, E,H or BOTH */
111
+            void SetFieldsToCalculate(const FIELDCALCULATIONS &calc);
112
+
113
+            /** Sets the method to use to evaluate the Hankel integral,
114
+             */
115
+            void SetHankelTransformMethod(const HANKELTRANSFORMTYPE &type);
116
+
117
+            // ====================  INQUIRY       ===========================
118
+
119
+        protected:
120
+
121
+            // ====================  LIFECYCLE     ===========================
122
+
123
+            /** Default protected constructor. */
124
+            EMEarth1D (const std::string& name);
125
+
126
+            #ifdef HAVE_YAMLCPP
127
+            /** Default protected constructor. */
128
+			EMEarth1D (const YAML::Node& node);
129
+            #endif
130
+
131
+            /** Default protected constructor. */
132
+            ~EMEarth1D ();
133
+
134
+            /**
135
+             * @copybrief LemmaObject::Release()
136
+             * @copydetails LemmaObject::Release()
137
+             */
138
+            void Release();
139
+
140
+            // ====================  OPERATIONS    ===========================
141
+
142
+            /** Used internally, this is the innermost loop of the MakeCalc3,
143
+             *  and CalculateWireAntennaField routines.
144
+             */
145
+            void SolveSingleTxRxPair(const int &irec,
146
+                    HankelTransform *Hankel,
147
+                    const Real &wavef, const int &ifreq,
148
+                    DipoleSource *tDipole);
149
+
150
+            /** Used internally, this is the innermost loop of the MakeCalc3,
151
+             *  and CalculateWireAntennaField routines.
152
+             */
153
+            void SolveLaggedTxRxPair(const int &irec, Hankel2* Hankel,
154
+                    const Real &wavef, const int &ifreq,
155
+                    PolygonalWireAntenna* antenna);
156
+
157
+            /** Removes all connections */
158
+            void DetachAll();
159
+
160
+            // ====================  DATA MEMBERS  ===========================
161
+
162
+            /** Computes field due to dipole */
163
+            DipoleSource*        Dipole;
164
+
165
+            /** Earth model (Cole-cole) */
166
+            LayeredEarthEM*      Earth;
167
+
168
+            /** Receiver points */
169
+            ReceiverPoints*      Receivers;
170
+
171
+            /** Wire antennae tx */
172
+            WireAntenna*         Antenna;
173
+
174
+            /** What fields are wanted */
175
+            FIELDCALCULATIONS    FieldsToCalculate;
176
+
177
+            /** The type of Hankel transform to use, default to digital
178
+             *  filtering
179
+             */
180
+            HANKELTRANSFORMTYPE  HankelType;
181
+
182
+            /** Counter for number of caclulations made
183
+             */
184
+            int icalcinner;
185
+
186
+            /** Counter for number of caclulations made
187
+             */
188
+            int icalc;
189
+
190
+    }; // -----  end of class  EMEarth1D  -----
191
+
192
+    /////////////////////////////////////////
193
+    // Exception classes
194
+
195
+    /** If a Receivers Class is NULL valued, throw this.
196
+     */
197
+    class NullReceivers : public std::runtime_error {
198
+            /** Thrown when Receivers pointer is NULL
199
+             */
200
+            public: NullReceivers();
201
+    };
202
+
203
+    /** If an Antenna is NULL valued, throw this error.
204
+     */
205
+    class NullAntenna : public std::runtime_error {
206
+            /** Thrown when an antenna pointer is NULL
207
+             */
208
+            public: NullAntenna();
209
+    };
210
+
211
+    /** If an Instrument is NULL valued, throw this error.
212
+     */
213
+    class NullInstrument : public std::runtime_error {
214
+            /** thrown when an instrument pointer is NULL.
215
+             *  @param[in] ptr is a pointer to the class throwing the exception.
216
+             */
217
+            public: NullInstrument(LemmaObject* ptr);
218
+    };
219
+
220
+    /** If a dipole source is specified, but a method calling a wire antenna is
221
+     * called, throw this.
222
+     */
223
+    class DipoleSourceSpecifiedForWireAntennaCalc : public std::runtime_error {
224
+            /** Thrown when a dipole source is specified when a wire antenna is
225
+             * expected
226
+             */
227
+            public: DipoleSourceSpecifiedForWireAntennaCalc();
228
+    };
229
+
230
+} // Namespace Lemma
231
+
232
+#endif // __EMEARTH1D_H

+ 139
- 0
Modules/FDEM1D/include/gaussianquadrature.h View File

@@ -0,0 +1,139 @@
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     10/07/2010
11
+  @version  $Id: gaussianquadrature.h 193 2014-11-10 23:51:41Z tirons $
12
+ **/
13
+
14
+#ifndef __gaussianquadrature_h
15
+#define __gaussianquadrature_h
16
+
17
+#include "LemmaObject.h"
18
+
19
+namespace Lemma {
20
+
21
+
22
+	// ===================================================================
23
+	//        Class:  gaussianquadrature
24
+	/// \brief Numerical integration via Legendre-Gauss Quadrature.
25
+	/// \details Returns integration result, weights, and abscissae.  This
26
+	/// script computes the Legendre-Gauss nodes and weights on an interval
27
+	/// [a,b] with truncation order N.  This class is heavily derived from
28
+	/// lgwt.m by Greg von Winckel (2/25/2004).
29
+	// ===================================================================
30
+	class gaussianquadrature {
31
+
32
+		public:
33
+
34
+			friend std::ostream &operator<<(std::ostream &stream,
35
+						const gaussianquadrature &ob);
36
+
37
+			// ====================  LIFECYCLE     =======================
38
+
39
+			static gaussianquadrature* New();
40
+
41
+			void Delete();
42
+
43
+			// ====================  OPERATORS     =======================
44
+
45
+			// ====================  OPERATIONS    =======================
46
+			/// Perform Gaussian Quadrature Integration
47
+			void Integrate();
48
+
49
+			/// Calculate abscissae and weights
50
+			void CalcAW();
51
+
52
+			// ====================  ACCESS        =======================
53
+			/// Set number of points and limits
54
+			void SetFreqs(const int& nfreq, const Real& a, const Real& b);
55
+
56
+			/// Eigen Vector of function values to be integrated over
57
+			void SetFunc(const VectorXr& fx);
58
+
59
+			// ====================  INQUIRY       =======================
60
+			/// Returns Eigen Vector of Abscissae
61
+			VectorXr GetAbscissae();
62
+
63
+			/// Returns Eigen Vector of Weights
64
+			VectorXr GetWeights();
65
+
66
+			/// Returns integration result
67
+			Real GetResult();
68
+
69
+
70
+		protected:
71
+
72
+			// ====================  LIFECYCLE     =======================
73
+
74
+			/// Default protected constructor.
75
+			gaussianquadrature ();
76
+
77
+			/// Default protected constructor.
78
+			~gaussianquadrature ();
79
+
80
+
81
+
82
+			// ====================  DATA MEMBERS  =========================
83
+			/// Interval
84
+			Real dx;
85
+
86
+			/// Machine precision
87
+			Real machineeps;
88
+
89
+			/// Bookkeeping variable
90
+			int N;
91
+
92
+			/// Bookkeeping variable
93
+			int N1;
94
+
95
+			/// Bookkeeping variable
96
+			int N2;
97
+
98
+			/// Lower bound
99
+			Real a;
100
+
101
+			/// Upper bound
102
+			Real b;
103
+
104
+			/// Placeholder vector
105
+			VectorXr ytemp;
106
+
107
+			/// Abscissae
108
+			VectorXr xu;
109
+
110
+			/// Intermediate Abscissae vector
111
+			VectorXr y;
112
+
113
+			/// Intermediate Abscissae vector
114
+			VectorXr y0;
115
+
116
+			/// Legendre-Gauss Vandermonde Matrix
117
+			MatrixXr L;
118
+
119
+			/// Derivative of LGVM
120
+			VectorXr Lp;
121
+
122
+			/// Intermediate Matrix
123
+			VectorXr Ltemp;
124
+
125
+			/// Weights Vector
126
+			VectorXr wgq;
127
+
128
+			///Function to integrate
129
+			VectorXr funcx;
130
+
131
+			/// Integration result
132
+			Real intres;
133
+
134
+		private:
135
+
136
+	}; // -----  end of class  gaussianquadrature  -----
137
+} // end of namespace Lemma
138
+#endif // __gaussianquadrature_h
139
+

+ 90
- 0
Modules/FDEM1D/include/hankeltransform.h View File

@@ -0,0 +1,90 @@
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     01/28/2010
11
+  @version  $Id: hankeltransform.h 270 2015-08-24 15:45:41Z tirons $
12
+ **/
13
+
14
+#ifndef __hankeltransform_h
15
+#define __hankeltransform_h
16
+
17
+#include "LemmaObject.h"
18
+#include "kernelem1dbase.h"
19
+#include "kernelem1dspec.h"
20
+#include "kernelem1dmanager.h"
21
+
22
+namespace Lemma {
23
+
24
+        // ===================================================================
25
+        //        Class:  HankelTransform
26
+        /// \brief  Pure abstract class for hankel transforms
27
+        /// \details
28
+        // ===================================================================
29
+        class HankelTransform : public LemmaObject {
30
+
31
+            public:
32
+
33
+                /// Prints out basic info about the class
34
+                friend std::ostream &operator<<(std::ostream &stream,
35
+                        const HankelTransform &ob);
36
+
37
+                // ====================  LIFECYCLE     =======================
38
+
39
+                //static HankelTransform* New();
40
+
41
+                //void Delete();
42
+
43
+                // ====================  OPERATORS     =======================
44
+
45
+                // ====================  OPERATIONS    =======================
46
+
47
+                /// @todo this is actually a deprecated function. Only Chave
48
+                ///   uses this.
49
+                /// Performs numerical integration using Gaussian quadrature
50
+                /// ikk:   type of kernel depending on source and receiver couple
51
+                /// imode: a switch for TE(0) and TM(1) mode
52
+                /// itype: order of Bessel function
53
+                /// rho is argument to integral
54
+                /// wavef is the propogation constant of free space
55
+                /// = omega * sqrt( EP*AMU )  amu = 4 pi e-7  ep = 8.85e-12
56
+                virtual Complex Zgauss(const int &ikk, const EMMODE &imode,
57
+                            const int &itype, const Real &rho,
58
+                            const Real &wavef, KernelEm1DBase *Kernel)=0;
59
+
60
+                /// Computes related kernels, if applicable, otherwise this is
61
+                /// just a dummy function.
62
+                virtual void ComputeRelated(const Real& rho, KernelEm1DBase* Kernel);
63
+
64
+                virtual void ComputeRelated(const Real& rho, std::vector< KernelEm1DBase* > KernelVec);
65
+
66
+                virtual void ComputeRelated(const Real& rho, KernelEM1DManager* KernelManager);
67
+
68
+                // ====================  ACCESS        =======================
69
+
70
+                // ====================  INQUIRY       =======================
71
+
72
+                // ====================  DATA MEMBERS  =======================
73
+
74
+            protected:
75
+
76
+                // ====================  LIFECYCLE     =======================
77
+
78
+                /// Default protected constructor.
79
+                HankelTransform (const std::string &name);
80
+
81
+                /// Default protected constructor.
82
+                ~HankelTransform ();
83
+
84
+            private:
85
+
86
+    }; // -----  end of class  HankelTransform  -----
87
+
88
+}
89
+
90
+#endif // __hankeltransform_h

+ 349
- 0
Modules/FDEM1D/include/hankeltransformgaussianquadrature.h View File

@@ -0,0 +1,349 @@
1
+/* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
+
5
+/**
6
+  @file
7
+  @author   Trevor Irons
8
+  @date     01/02/2010
9
+  @version  $Id: hankeltransformgaussianquadrature.h 199 2014-12-29 19:25:20Z tirons $
10
+ **/
11
+
12
+#ifndef  _HANKELTRANSFORMGAUSSIANQUADRATURE_h_INC
13
+#define  _HANKELTRANSFORMGAUSSIANQUADRATURE_h_INC
14
+
15
+#include "hankeltransform.h"
16
+#include "kernelem1dbase.h"
17
+
18
+#ifdef HAVEBOOSTCYLBESSEL
19
+#include "boost/math/special_functions.hpp"
20
+#endif
21
+
22
+namespace Lemma {
23
+
24
+
25
+	// =======================================================================
26
+	//        Class:  HankelTransformGaussianQuadrature
27
+	/// \brief  Calculates hankel transform using gaussian quadrature.
28
+	/// \details  Accurate but slow, this is a port of Alan Chave's public domain
29
+    /// fortran code
30
+	// =======================================================================
31
+	class HankelTransformGaussianQuadrature : public HankelTransform {
32
+
33
+		friend std::ostream &operator<<(std::ostream &stream,
34
+				const HankelTransformGaussianQuadrature &ob);
35
+
36
+		public:
37
+
38
+			// ====================  LIFECYCLE     ===========================
39
+
40
+            /**
41
+             *  Returns pointer to new HankelTransformGaussianQuadrature.
42
+             *  Location is
43
+             *  initialized to (0,0,0) type and polarization are
44
+             *  initialized  to nonworking values that will throw
45
+             *  exceptions if used.
46
+             */
47
+			static HankelTransformGaussianQuadrature* New();
48
+
49
+            /**
50
+             * @copybrief LemmaObject::Delete()
51
+             * @copydetails LemmaObject::Delete()
52
+             */
53
+            void Delete();
54
+
55
+			// ====================  OPERATORS     ===========================
56
+
57
+			// ====================  OPERATIONS    ===========================
58
+
59
+			/// Performs numerical integration using Gaussian quadrature
60
+			/// ikk:   type of kernel depending on source and receiver couple
61
+			/// imode: a switch for TE(0) and TM(1) mode
62
+			/// itype: order of Bessel function
63
+			/// rho is argument to integral
64
+			/// wavef is the propogation constant of free space
65
+			/// = omega * sqrt( EP*AMU )  amu = 4 pi e-7  ep = 8.85e-12
66
+            //template <EMMODE T>
67
+			Complex Zgauss(const int &ikk, const EMMODE &imode,
68
+							const int &itype, const Real &rho,
69
+							const Real &wavef, KernelEm1DBase *Kernel);
70
+
71
+			// ====================  ACCESS        ============================
72
+
73
+			// ====================  INQUIRY       ============================
74
+
75
+			// ====================  DATA MEMBERS  ============================
76
+
77
+		protected:
78
+
79
+			// ====================  LIFECYCLE     ============================
80
+
81
+			/// Default protected constructor.
82
+			HankelTransformGaussianQuadrature (const std::string &name);
83
+
84
+            /// Default protected constructor.
85
+			~HankelTransformGaussianQuadrature ();
86
+
87
+            /**
88
+             * @copybrief LemmaObject::Release()
89
+             * @copydetails LemmaObject::Release()
90
+             */
91
+            void Release();
92
+
93
+			// ====================  OPERATIONS    ============================
94
+
95
+			/// Modified by Yoonho Song to branch cut, June, 1996
96
+			/// Separate Gaussian quarature integral by two interval
97
+			/// first:  integal from 0 to wavenumber of free space
98
+			/// second: integral from wavenunmber of free space to infinity
99
+			///         for large arguments, it uses continued fraction also
100
+			/// It is recommended to use nl = 1 to 6, nu =7
101
+			/// PERFORMS AUTOMATIC CALCULATION OF BESSEL TRANSFORM TO SPECIFIED
102
+			/// RELATIVportisheadE AND ABSOLUTE ERROR
103
+			///
104
+			/// ARGUMENT LIST:
105
+			///
106
+			/// BESR,BESI-REAL AND IMAGINARY PARTS RETURNED BY BESAUX
107
+			/// iorder-ORDER OF THE BESSEL FUNCTION
108
+			/// NL-LOWER LIMIT FOR GAUSS ORDER TO START COMPUTATION
109
+			/// NU-UPPER LIMIT FOR GAUSS ORDER
110
+			/// NU,NL=1,...7 SELECTS 3,7,15,31,63,127,AND 255 POINT GAUSS
111
+			/// QUADRATURE BETWEEN THE ZERO CROSSINGS OF THE BESSEL FUNCTION
112
+			/// R-ARGUMENT OF THE BESSEL FUNCTION
113
+			/// RERR,AERR-RELATIVE AND ABSOLUTE ERROR FOR TERMINATION
114
+			/// BESAUX TERMINATES WHEN INCREASING THE GAUSS ORDER DOES NOT
115
+			/// CHANGE THE RESULT BY MORE THAN RERR OR WHEN THE ABSOLUTE ERROR
116
+			/// IS LESS THAN AERR OR WHEN A GAUSS ORDER OF NU IS REACHED.
117
+			/// NPCS-NUMBER OF PIECES INTO WHICH EACH PARTIAL INTEGRAND
118
+			/// IS DIVIDED,
119
+			/// ORDINARILY SET TO ONE. FOR VERY SMALL VALUES OF R WHERE
120
+			/// THE KERNEL FUNCTION IS APPRECIABLE ONLY OVER THE FIRST FEW
121
+			/// LOOPS OF THE BESSEL FUNCTION, NPCS MAY BE INCREASED TO ACHIEVE
122
+			/// REASONABLE ACCURACY.
123
+			/// NEW  IF NEW=1, THE INTEGRANDS ARE COMPUTED AND SAVED AT EACH
124
+			/// GAUSS
125
+			/// ORDER. IF NEW=2, PREVIOUSLY COMPUTED INTEGRANDS ARE USED. NOTE
126
+			/// THAT ORDER,R, AND NPCS MUST NOT BE CHANGED WHEN SETTING NEW=2.
127
+			/// IERR-ERROR PARAMETER
128
+			/// IERR=0--NORMAL RETURN
129
+			/// IERR=1--RESULT NOT ACCURATE TO RERR DUE TO TOO LOW A GAUSS
130
+			///  ORDER OR CONVERGENCE NOT ACHIEVED IN BESTRX
131
+            //template <EMMODE T>
132
+			void Besautn(Real &besr, Real &besi, const int &iorder,
133
+							const int &nl, const int &nu, const Real &rho,
134
+							const Real &rerr, const Real &aerr,
135
+							const int &npcs, int &inew, const Real &aorb,
136
+							KernelEm1DBase *Kernel);
137
+
138
+			/// COMPUTES BESSEL TRANSFORM OF SPECIFIED ORDER DEFINED AS
139
+			/// INTEGRAL(FUNCT(X)*J-SUB-ORDER(X*R)*DX) FROM X=0 TO INFINITY
140
+			/// COMPUTATION IS ACHIEVED BY INTEGRATION BETWEEN THE ASYMPTOTIC
141
+			/// ZERO CROSSINGS OF THE BESSEL FUNCTION USING GAUSS QUADRATURE.
142
+			/// THE RESULTING SERIES OF PARTIAL INTEGRANDS IS SUMMED BY
143
+			/// CALCULATING THE PADE APPROXIMANTS TO SPEED UP CONVERGENCE.
144
+			/// ARGUMENT LIST:
145
+			/// BESR,BESI  REAL AND IMAGINARY PARTS RETURNED BY BESTRN
146
+			/// iorder  ORDER OF THE BESSEL FUNCTIONC  NG  NUMBER OF GAUSS
147
+			/// POINTS TO USE IN THE QUADRATURE ROUTINE.
148
+			/// NG=1 THROUGH 7 SELECTS 3,7,15,31,63,126,AND 255 TERMS.
149
+			///   R     ARGUMENT OF THE BESSEL FUNCTION
150
+			///   RERR,AERR  SPECIFIED RELATIVE AND ABSOLUTE ERROR FOR THE
151
+			///           CALCULATION.  THE INTEGRATION
152
+			///  TERMINATES WHEN AN ADDITIONAL TERM DOES NOT CHANGE THE
153
+			///  RESULT BY MORE THAN RERR*RESULT+AERR
154
+			///  NPCS  NUMBER OF PIECES INTO WHICH EACH PARTIAL I
155
+			///        NTEGRAND IS DIVIDED,
156
+			///        ORDINARILY SET TO ONE. FOR VERY SMALL VALUES OF RANGE
157
+			///        WHERE THE KERNEL FUNCTION IS APPRECIABLE ONLY OVER THE
158
+			///        FIRST FEW LOOPS OF THE BESSEL FUNCTION, NPCS MAY BE
159
+			///        INCREASED TO ACHIEVE REASONABLE ACCURACY. NOTE THAT
160
+			///        NPCS AFFECTS ONLY THE PADE
161
+			///        SUM PORTION OF THE INTEGRATION, OVER X(NSUM) TO INFINITY.
162
+			/// XSUM  VECTOR OF VALUES OF THE KERNEL ARGUMENT OF FUNCT FOR WHICH
163
+			/// EXPLICIT CALCULATION OF THE INTEGRAL IS DESIRED, SO THAT THE
164
+			/// INTEGRAL OVER 0 TO XSUM(NSUM) IS ADDED TO THE INTEGRAL OVER
165
+			/// XSUM(NSUM) TO INFINITY WITH THE PADE METHOD INVOKED ONLY FOR
166
+			/// THE LATTER. THIS ALLOWS THE PADE SUMMATION METHOD TO BE
167
+			/// OVERRIDDEN AND SOME TYPES OF SINGULARITIES TO BE HANDLED.
168
+			/// NSUM  NUMBER OF VALUES IN XSUM, MAY BE ZERO.
169
+			/// NEW   DETERMINES METHOD OF KERNEL CALCULATION
170
+			/// NEW=0 MEANS  CALCULATE BUT DO NOT SAVE INTEGRANDS
171
+			/// NEW=1 MEANS CALCULATE KERNEL BY CALLING FUNCT-SAVE KERNEL
172
+			///       TIMES BESSEL FUNCTION
173
+			/// NEW=2 MEANS USE SAVED KERNELS TIMES BESSEL FUNCTIONS IN
174
+			///       COMMON /BESINT/. NOTE THAT ORDER,R,NPCS,XSUM, AND
175
+			///       NSUM MAY NOT BE CHANGED WHEN SETTING NEW=2.
176
+			/// IERR  ERROR PARAMETER
177
+			///       0 NORMAL RETURN-INTEGRAL CONVERGED
178
+			///       1 MEANS NO CONVERGENCE AFTER NSTOP TERMS IN THE PADE SUM
179
+			///
180
+			/// SUBROUTINES REQUIRED:
181
+			/// BESQUD,PADECF,CF,ZEROJ,DOT,JBESS
182
+			///  A.CHAVE IGPP/UCSD
183
+			/// NTERM IS MAXIMUM NUMBER OF BESSEL FUNCTION LOOPS STORED IF
184
+			/// NEW.NE.0
185
+			/// NSTOP IS MAXIMUM Number of Pade terms
186
+            //template <EMMODE T>
187
+ 			void Bestrn( Real &BESR, Real &BESI, const int &iorder,
188
+ 					const int &NG, const Real &R,
189
+ 					const Real &RERR, const Real &AERR, const int &npcs,
190
+ 					VectorXi &XSUM, int &NSUM, int &NEW,
191
+ 					int &IERR, int &NCNTRL, const Real &AORB,
192
+					KernelEm1DBase *Kernel);
193
+
194
+			/// CALCULATES THE INTEGRAL OF F(X)*J-SUB-N(X*R) OVER THE
195
+			/// INTERVAL A TO B AT A SPECIFIED GAUSS ORDER THE RESULT IS
196
+			/// OBTAINED USING A SEQUENCE OF 1, 3, 7, 15, 31, 63, 127, AND 255
197
+			/// POINT INTERLACING GAUSS FORMULAE SO THAT NO INTEGRAND
198
+			/// EVALUATIONS ARE WASTED. THE KERNEL FUNCTIONS MAY BE
199
+			/// SAVED SO THAT BESSEL TRANSFORMS OF SIMILAR KERNELS ARE COMPUTED
200
+			/// WITHOUT NEW EVALUATION OF THE KERNEL.  DETAILS ON THE FORMULAE
201
+			/// ARE GIVEN IN 'THE OPTIMUM ADDITION OF POINTS TO QUADRATURE
202
+			/// FORMULAE' BY T.N.L. PATTERSON, MATHS.COMP. 22,847-856 (1968).
203
+			/// GAUSS WEIGHTS TAKEN FROM COMM. A.C.M. 16,694-699 (1973)
204
+			/// ARGUMENT LIST:
205
+			/// A      LOWER LIMIT OF INTEGRATION
206
+			/// B      UPPER LIMIT OF INTEGRATION
207
+			/// BESR,BESI RETURNED INTEGRAL VALUE REAL AND IMAGINARY PARTS
208
+			/// NG NUMBER OF POINTS IN THE GAUSS FORMULA.  NG=1,...7
209
+			///        SELECTS 3,7,15,31,63,127,AND 255 POINT QUADRATURE.
210
+			///  NEW SELECTS METHOD OF KERNEL EVALUATION
211
+			///    NEW=0 CALCULATES KERNELS BY CALLING F - NOTHING SAVED
212
+			///    NEW=1 CALCULATES KERNELS BY CALLING F AND SAVES KERNEL TIMES
213
+			///           BESSEL FUNCTION IN COMMON /BESINT/
214
+			///    NEW=2 USES SAVED KERNEL TIMES BESSEL FUNCTIONS IN
215
+			///           COMMON /BESINT/
216
+			/// iorder ORDER OF THE BESSEL FUNCTION
217
+			/// R    ARGUMENT OF THE BESSEL FUNCTION
218
+			/// F     F(X) IS THE EXTERNAL INTEGRAND SUBROUTINE
219
+			/// A.CHAVE IGPP/UCSDC
220
+			/// MAXIMUM NUMBER OF BESSEL FUNCTION LOOPS THAT CAN BE SAVED
221
+            //template <EMMODE T>
222
+			void Besqud(const Real &A, const Real &B, Real &BESR, Real &BESI,
223
+							const int &NG, const int &NEW, const int &iorder,
224
+							const Real &R, KernelEm1DBase *Kernel);
225
+
226
+			/// COMPUTES SUM(S(I)),I=1,...N BY COMPUTATION OF PADE APPROXIMANT
227
+			/// USING CONTINUED FRACTION EXPANSION.  FUNCTION IS DESIGNED TO BE
228
+			/// CALLED SEQUENTIALLY AS N IS INCREMENTED FROM 1 TO ITS FINAL
229
+			/// VALUE.  THE NTH CONTINUED FRACTION COEFFICIENT IS CALCULATED AND
230
+			/// STORED AND THE NTH CONVERGENT RETURNED.  IT IS UP TO THE USER TO
231
+			/// STOP THE CALCULATION WHEN THE DESIRED ACCURACY IS ACHIEVED.
232
+			/// ALGORITHM FROM HANGGI ET AL., Z.NATURFORSCH. 33A,402-417 (1977)
233
+			/// IN THEIR NOTATION, VECTORS CFCOR,CFCOI ARE LOWER CASE D,
234
+			/// VECTORS DR, DI ARE UPPER CASE D, VECTORS XR,XI ARE X, AND
235
+			/// VECTORS SR,SI ARE S
236
+			/// A.CHAVE IGPP/UCSD
237
+			void Padecf(Real &SUMR, Real &SUMI, const int &N);
238
+
239
+			/// EVALUATES A COMPLEX CONTINUED FRACTION BY RECURSIVE DIVISION
240
+			/// STARTING AT THE BOTTOM, AS USED BY PADECF
241
+			/// RESR,RESI ARE REAL AND IMAGINARY PARTS RETURNED
242
+			/// CFCOR,CFCOI ARE REAL AND IMAGINARY VECTORS OF CONTINUED FRACTION
243
+			/// COEFFICIENTS
244
+			void CF(        Real& RESR, Real &RESI,
245
+							Eigen::Matrix<Real, 100, 1> &CFCOR,
246
+							Eigen::Matrix<Real, 100, 1> &CFCOI,
247
+							const int &N);
248
+
249
+
250
+			/// COMPUTES ZERO OF BESSEL FUNCTION OF THE FIRST KIND FROM
251
+			/// MCMAHON'S ASYMPTOTIC EXPANSION
252
+			/// NZERO-NUMBER OF THE ZERO
253
+			/// iorder-ORDER OF THE BESSEL FUNCTION (0 OR 1)
254
+			Real ZeroJ(const int &ZERO, const int &IORDER);
255
+
256
+			/// COMPUTES BESSEL FUNCTION OF ORDER "ORDER" AND ARGUMENT X BY
257
+			/// CALLING NBS ROUTINES J0X AND J1X (REAL*8 BUT APPROXIMATELY
258
+			/// REAL*4 ACCURACY).
259
+			/// FOR MORE ACCURACY JBESS COULD BE CHANGED TO CALL, FOR EXAMPLE,
260
+			/// THE IMSL ROUTINES MMBSJ0,MMBSJ1 << SEE C// BELOW >>
261
+			Real Jbess(const Real &X, const int &IORDER);
262
+
263
+			/// COMPUTES DOT PRODUCT OF TWO D.P. VECTORS WITH NONUNIT
264
+			/// INCREMENTING ALLOWED. REPLACEMENT FOR BLAS SUBROUTINE SDOT.
265
+			/// Currently does no checking, kind of stupid.
266
+			/// The fortran version will wrap around if (inc*N) > X1.size()
267
+			/// but not in a nice way.
268
+			Real _dot(const int&N,
269
+				const Eigen::Matrix<Real, Eigen::Dynamic, Eigen::Dynamic> &X1,
270
+							const int &INC1,
271
+				const Eigen::Matrix<Real, Eigen::Dynamic, Eigen::Dynamic> &X2,
272
+				const int &INC2);
273
+
274
+			// ====================  DATA MEMBERS  ============================
275
+
276
+            static const Real PI2;
277
+			static const Real X01P;
278
+			static const Real XMAX;
279
+			static const Real XSMALL;
280
+			static const Real J0_X01;
281
+			static const Real J0_X02;
282
+			static const Real J0_X11;
283
+			static const Real J0_X12;
284
+			static const Real FUDGE;
285
+			static const Real FUDGEX;
286
+			static const Real TWOPI1;
287
+			static const Real TWOPI2;
288
+			static const Real RTPI2;
289
+			static const Real XMIN;
290
+			static const Real J1_X01;
291
+			static const Real J1_X02;
292
+			static const Real J1_X11;
293
+			static const Real J1_X12;
294
+
295
+			/// Highest gauss order used, Was NG
296
+			int HighestGaussOrder;
297
+
298
+			/// Total number of partial integrals on last call, was NI
299
+			int NumberPartialIntegrals;
300
+
301
+			/// Total number of function calls, was NF
302
+			int NumberFunctionEvals;
303
+
304
+			int          np;
305
+			int          nps;
306
+
307
+            /////////////////////////////////////////////////////////////
308
+			// Eigen members
309
+
310
+            // Shared constant values
311
+			static const VectorXr  WT;
312
+			static const VectorXr  WA;
313
+
314
+			Eigen::Matrix<int,  100, 1>    Nk;
315
+			//Eigen::Matrix<Real, 255, 100>  karg;
316
+			//Eigen::Matrix<Real, 510, 100>  kern;
317
+			Eigen::Matrix<Real, Eigen::Dynamic, Eigen::Dynamic>  karg;
318
+			Eigen::Matrix<Real, Eigen::Dynamic, Eigen::Dynamic>  kern;
319
+
320
+			// Was Besval COMMON block
321
+			Eigen::Matrix<Real, 100, 1> Xr;
322
+			Eigen::Matrix<Real, 100, 1> Xi;
323
+			Eigen::Matrix<Real, 100, 1> Dr;
324
+			Eigen::Matrix<Real, 100, 1> Di;
325
+			Eigen::Matrix<Real, 100, 1> Sr;
326
+			Eigen::Matrix<Real, 100, 1> Si;
327
+			Eigen::Matrix<Real, 100, 1> Cfcor;
328
+			Eigen::Matrix<Real, 100, 1> Cfcoi;
329
+
330
+		private:
331
+
332
+	}; // -----  end of class  HankelTransformGaussianQuadrature  -----
333
+
334
+    //////////////////////////////////////////////////////////////
335
+    // Exception Classes
336
+
337
+    /** If the lower integration limit is greater than the upper limit, throw this
338
+     * error.
339
+     */
340
+    class LowerGaussLimitGreaterThanUpperGaussLimit :
341
+        public std::runtime_error {
342
+        /** Thrown when the LowerGaussLimit is greater than the upper limit.
343
+         */
344
+        public: LowerGaussLimitGreaterThanUpperGaussLimit();
345
+    };
346
+
347
+}	   // -----  end of Lemma  name  -----
348
+
349
+#endif   // ----- #ifndef _HANKELTRANSFORMGAUSSIANQUADRATURE_h_INC  -----

+ 246
- 0
Modules/FDEM1D/include/hankeltransformhankel2.h View File

@@ -0,0 +1,246 @@
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     06/26/2009
11
+  @version  $Id: hankeltransformhankel2.h 201 2015-01-03 00:07:47Z tirons $
12
+ **/
13
+
14
+#ifndef __HANKEL2_H
15
+#define __HANKEL2_H
16
+
17
+#include "hankeltransform.h"
18
+#include "kernelem1dbase.h"
19
+#include "kernelem1dspec.h"
20
+#include "CubicSplineInterpolator.h"
21
+
22
+namespace Lemma {
23
+
24
+// ==========================================================================
25
+//        Class:  Hankel2
26
+/** \brief   Computes the Hankel transform of orders 0 and 1 using lagged
27
+             and related convolutions.
28
+    \details A rewrite of work by Anderson who wrote a FORTRAN program
29
+             that he released while working at the USGS.
30
+             The  transform evaluates an integral of the form:
31
+             \f[ \int_0^\infty K(\lambda) J_I (\lambda r) ~ d \lambda
32
+             \f]
33
+             Where \f$ K(\lambda) \f$ is some kernel function. The value
34
+             \f$ J_I \f$ is the Bessel function of order
35
+             \f$I, I \in \{0,1\} \f$
36
+             The kernel function is unique for each source and is computed
37
+             in the class CalculateKernel. The value \f$r\f$ is the radial
38
+             distance away from the centre of the grid \f$ r=\sqrt{x^2 + y^2} \f$
39
+             The Hankel transform is useful as it allows a double fourier
40
+             transform to be written as a single integral:
41
+             \f[ \mathop {\int \!\!\! \int}_{\!\!\!\!\!-\infty}^{\,\,\infty}
42
+             F(k_x^2 + k_y^2)
43
+                 e^{\imath (k_x x + k_y y)} dk_x \, dk_y = 2 \pi
44
+                 \int_0^\infty K(\lambda) J_I (\lambda r) ~ d \lambda
45
+             \f]
46
+             This can only be done where there is radial symmetry. Hence
47
+             its application to 1D solutions here.
48
+ */
49
+// ==========================================================================
50
+
51
+class Hankel2 : public HankelTransform {
52
+
53
+    friend std::ostream &operator<<(std::ostream &stream, const Hankel2 &ob);
54
+
55
+    public:
56
+
57
+        // ====================  LIFECYCLE     ==============================
58
+        /**
59
+         *  Returns pointer to new Hankel2. Location is
60
+         *  initialized to (0,0,0) type and polarization are
61
+         *  initialized  to nonworking values that will throw
62
+         *  exceptions if used.
63
+         */
64
+        static Hankel2 *New();
65
+
66
+        /**
67
+         * @copybrief LemmaObject::Delete()
68
+         * @copydetails LemmaObject::Delete()
69
+         */
70
+        void Delete();
71
+
72
+        // ====================  OPERATORS     ==============================
73
+
74
+        // ====================  OPERATIONS    ==============================
75
+
76
+        /// Sets the number of convolutions
77
+        void SetNumConv(const int &i);
78
+
79
+        /// Computes the hankel transform with arguments
80
+        /// @param rho [input] rho is the hankel transform argument
81
+        /// @param ntol [input] ntol is
82
+        /// @param tol [input] tol is
83
+        void Compute(const Real &rho, const int& ntol, const Real &tol);
84
+
85
+        /// Computes the related
86
+        void ComputeRelated(const Real &rho, KernelEm1DBase* Kernel);
87
+
88
+        /// Computes the related
89
+        void ComputeRelated(const Real &rho,  std::vector< KernelEm1DBase* > KernelVec);
90
+
91
+        /// Computes the related
92
+        void ComputeRelated(const Real &rho,  KernelEM1DManager* Manager);
93
+
94
+        /// Computes the related and lagged convolutions
95
+        void ComputeLaggedRelated(const Real &rho, const int& nlag,  KernelEM1DManager* Manager);
96
+
97
+        // ====================  ACCESS        ==============================
98
+
99
+        /// Returns the answer
100
+        Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic>  GetAnswer();
101
+
102
+        /// Returns the arguments for lagged convolutions
103
+        VectorXr GetArg() {return Arg;};
104
+
105
+        /// Returns the value of Abscissa stepping
106
+        Real GetABSER( ) { return ABSER; };
107
+
108
+        /// Sets the lagged kernel index so that the proper value is returned
109
+        void SetLaggedArg(const Real& rho);
110
+
111
+
112
+        // ====================  INQUIRY       ==============================
113
+
114
+        /// Calculates Hankel Transform using filtering.
115
+        /// ikk:   type of kernel depending on source and receiver couple
116
+        /// imode: a switch for TE(0) and TM(1) mode
117
+        /// itype: order of Bessel function
118
+        /// rho is argument to integral
119
+        /// wavef is the propogation constant of free space
120
+        /// = omega * sqrt( EP*AMU )  amu = 4 pi e-7  ep = 8.85e-12
121
+        Complex Zgauss(const int &ikk, const EMMODE &imode,
122
+                        const int &itype, const Real &rho,
123
+                        const Real &wavef, KernelEm1DBase *Kernel);
124
+
125
+    protected:
126
+
127
+        // ====================  LIFECYCLE     ==============================
128
+
129
+        /** A rewrite of Anderson's Pseudo-subroutine. */
130
+        inline void StoreRetreive(const int &idx, const int &lag,
131
+                        Complex &Zsum, const int &irel, Complex &C, const Real& rho0) {
132
+
133
+            int look = idx+lag;
134
+    		int	iq = look/801;
135
+    		int	ir = look%801;
136
+    		int iroll = iq*800;
137
+
138
+    		if(this->Key[ir] <= iroll) {
139
+			    this->Key[ir] = iroll + ir;
140
+ 	    		++this->NumFun;
141
+                Manager->ComputeReflectionCoeffs(this->Lambda, idx, rho0);
142
+ 			    for (unsigned int ir2=0; ir2<this->kernelVec.size(); ++ir2) {
143
+ 			        this->Zwork(ir, ir2) = this->kernelVec[ir2]->RelBesselArg(this->Lambda);
144
+ 			    }
145
+		    }
146
+
147
+		    C = this->Zwork(ir, irel) * this->FilterWeights(this->BesselOrder, idx);
148
+		    Zsum += C;
149
+		    return;
150
+	    }
151
+
152
+        /// Default protected constructor
153
+        Hankel2(const std::string& name);
154
+
155
+        /// Default protected destructor
156
+        ~Hankel2();
157
+
158
+        /**
159
+         * @copybrief LemmaObject::Release()
160
+         * @copydetails LemmaObject::Release()
161
+         */
162
+        void Release();
163
+
164
+        // ====================  OPERATIONS    ==============================
165
+
166
+        void DeleteSplines();
167
+
168
+        // ====================  DATA MEMBERS  ==============================
169
+
170
+        /// The hankel transform wavenumber embedded in the integral
171
+        Real Lambda;
172
+
173
+        /// Number of times a kernel was evaluated
174
+        int NumFun;
175
+
176
+        /// Number of lagged convolutions
177
+        /// must be greater or equal to 1
178
+        /// It is set automatically in the @see Compute function so
179
+        /// that  \f$ \rho \exp\left( -.1*(\mathtt{NumConv} -1) \right) \f$
180
+        /// does not underflow the exponent range
181
+        int NumConv;
182
+
183
+        /// Number of related kernels
184
+        int NumRel;
185
+
186
+        /** Bessel transform order to use */
187
+        int BesselOrder;
188
+
189
+        /** Lag argument */
190
+        int iLag;
191
+
192
+        /* Should results be cached? Useful for repeated calculations of few receiver points */
193
+        // turned out to have only marginal benefits in best case, and awful consequences in many
194
+        //bool cacheResults;
195
+
196
+        /** Related Kernel Manager */
197
+        KernelEM1DManager*          Manager;
198
+
199
+        /// Used as base for filter abscissa generation
200
+        static const Real ABSCISSA;
201
+
202
+        /// Also used in abscissa generation \f$ ABSE = \exp{.1} \f$
203
+        static const Real ABSE;
204
+
205
+        /// Also used in abscissa generation \f$ ABSER = 1 / \exp{.1} \f$
206
+        static const Real ABSER;
207
+
208
+        /// Counter for calculated
209
+        int icount;
210
+
211
+        /// Kernel Calculator
212
+        std::vector <KernelEm1DBase*> kernelVec;
213
+
214
+        /// Spines for lagged convolutions (real part)
215
+        std::vector <CubicSplineInterpolator*> splineVecReal;
216
+
217
+        /// Spines for lagged convolutions (imaginary part)
218
+        std::vector <CubicSplineInterpolator*> splineVecImag;
219
+
220
+        /// Key used internally
221
+        Eigen::Matrix<int, 801, 1> Key;
222
+        //int  Key[801];
223
+        //Eigen::Matrix<int, Eigen::Dynamic, 1> Key;
224
+
225
+        /// Filter weight coefficients. Set for either \f$J_0\f$ or \f$J_1\f$
226
+        /// internally by protected function SetFilterWeights.
227
+        /// Fixed sized will yield better performance. (not necessarily)
228
+        //Eigen::Matrix<Real, 801, 1> FilterWeights;
229
+        static const Eigen::Matrix<Real, 2, 801> FilterWeights;
230
+        //static const Eigen::Matrix<Real, Eigen::Dynamic, Eigen::Dynamic> FilterWeights;
231
+
232
+        /// Zwork from Anderson
233
+        Eigen::Matrix<Complex, 801, Eigen::Dynamic> Zwork;
234
+        //Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic> Zwork;
235
+
236
+        /// Holds answer, dimensions are NumConv, and NumberRelated.
237
+        Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic> Zans;
238
+
239
+        /// Holds the arguments for lagged convolutions
240
+        VectorXr Arg;
241
+
242
+}; // -----  end of class  HankelTransform  -----
243
+
244
+}
245
+
246
+#endif // __HANKEL2_h

+ 144
- 0
Modules/FDEM1D/include/instrumentfem.h View File

@@ -0,0 +1,144 @@
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   M. Andy Kass
10
+  @date     01/14/2013
11
+  @version  $Id$
12
+ **/
13
+
14
+#ifndef __INSTRUMENTFEM_H
15
+#define __INSTRUMENTFEM_H
16
+
17
+#include "instrument.h"
18
+#include "emearth1d.h"
19
+#include "WireAntenna.h"
20
+#include "PolygonalWireAntenna.h"
21
+#include "receiverpoints.h"
22
+#include "dipolesource.h"
23
+#include "layeredearthem.h"
24
+#include "datafem.h"
25
+
26
+namespace Lemma {
27
+
28
+// ===================================================================
29
+//        Class:  InstrumentFem
30
+/// \brief
31
+/// \details
32
+// ===================================================================
33
+	class InstrumentFem : public Instrument {
34
+		friend std::ostream &operator<<(std::ostream &stream,
35
+			const InstrumentFem &ob);
36
+
37
+
38
+	public:
39
+
40
+	// ====================  LIFECYCLE     =======================
41
+
42
+		static InstrumentFem* New();
43
+
44
+		void Delete();
45
+
46
+	// ====================  OPERATORS     =======================
47
+
48
+	// ====================  OPERATIONS    =======================
49
+
50
+		/// Make the forward model calculation
51
+		void MakeCalculation();
52
+
53
+		/// Forward model from a vector of inputs
54
+		void ForwardModelProfile();
55
+
56
+	// ====================  ACCESS        =======================
57
+	//
58
+		/// Set layered earth model
59
+		void EMEarthModel(LayeredEarthEM* Earth);
60
+
61
+		/// Set dipole source
62
+		void SetDipoleSource(DipoleSource* dipolesource);
63
+
64
+		/// Set Field Points
65
+		void SetReceiverPoints(ReceiverPoints* receiver);
66
+
67
+		/// Copy parameters from data object
68
+		void AlignWithData(DataFEM* inpdata);
69
+
70
+		/// Set a data object for output
71
+		void SetOutputData(DataFEM* outputdata);
72
+
73
+
74
+
75
+	// ====================  INQUIRY       =======================
76
+
77
+
78
+	protected:
79
+
80
+	// ====================  LIFECYCLE     =======================
81
+
82
+		/// Default protected constructor.
83
+		InstrumentFem (const std::string &name);
84
+
85
+		/// Default protected constructor.
86
+		~InstrumentFem ();
87
+
88
+		void Release();
89
+
90
+	// ====================  DATA MEMBERS  =========================
91
+
92
+	LayeredEarthEM* EarthModel;
93
+
94
+	DipoleSource* Dipole;
95
+
96
+	ReceiverPoints* Receiver;
97
+
98
+	DataFEM* InputData;
99
+
100
+	DataFEM* OutputData;
101
+
102
+	/// Vector of dipole sources - may be superceded by boost
103
+	std::vector<DipoleSource*> Transmitters;
104
+
105
+	/// Vector of receivers - may be superceded by boost
106
+	/// not necessary--one set of receivers for all dipoles,
107
+	/// except the number of frequencies is built into the receiver
108
+	std::vector<ReceiverPoints*> Receivers;
109
+
110
+	/// Vector of Earth Models - may be superceded by boost
111
+	//std::vector<LayeredEarthEM*> EarthModels;
112
+
113
+	/// Number of frequencies
114
+	int nFreq;
115
+
116
+	/// Number of observation locations
117
+	int nObs;
118
+
119
+	/// Array of frequencies
120
+	VectorXr freq;
121
+
122
+	/// Position vector, with z as height above the ground surface (pos)
123
+	Vector3Xr xyz;
124
+
125
+	/// Array of Tx orientations (x,y,z) for each freq
126
+	Eigen::Matrix<ORIENTATION,Eigen::Dynamic,1> TxOrientation;
127
+
128
+	/// Array of Rx orientations (x,y,z) for each freq
129
+	Eigen::Matrix<ORIENTATION,Eigen::Dynamic,1> RxOrientation;
130
+
131
+	/// Transmitter moments, one for each frequency
132
+	VectorXr TxMom;
133
+
134
+	/// Tx/Rx Separation in local, right hand system with x aligned with flight
135
+	Vector3Xr TxRxSep;
136
+
137
+	/// Scale factor as described in EM1DFM manual
138
+	VectorXr ScaleFac;
139
+
140
+	private:
141
+
142
+}; // -----  end of class  InstrumentFem  -----
143
+} // end of namespace Lemma
144
+#endif

+ 92
- 0
Modules/FDEM1D/include/integrationkernel.h View File

@@ -0,0 +1,92 @@
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     02/07/2011
11
+  @version  $Id: integrationkernel.h 193 2014-11-10 23:51:41Z tirons $
12
+ **/
13
+
14
+#ifndef  INTEGRATIONKERNEL_INC
15
+#define  INTEGRATIONKERNEL_INC
16
+
17
+#include "LemmaObject.h"
18
+
19
+namespace Lemma {
20
+
21
+    // ===================================================================
22
+    //  Class:  IntegrationKernel
23
+    /**
24
+      @class
25
+      \brief    Abstract class that computes arguments for numerical
26
+                integrators.
27
+      \details  Needs to provide Argument function, as well as be able to
28
+                set necessary integration parameters.
29
+     */
30
+    // ===================================================================
31
+    template <typename T>
32
+    class IntegrationKernel : public LemmaObject {
33
+
34
+        public:
35
+
36
+            // ====================  LIFECYCLE     =======================
37
+
38
+
39
+            // ====================  OPERATORS     =======================
40
+
41
+            // ====================  OPERATIONS    =======================
42
+
43
+            /** Returns the argument of a function at a given argument. Also
44
+             *  capable or returning related function values.
45
+             */
46
+            //template <typename T>
47
+            virtual T Argument(const Real& x, const int& iRelated)=0;
48
+
49
+            // ====================  ACCESS        =======================
50
+
51
+            // ====================  INQUIRY       =======================
52
+
53
+            virtual int GetNumRel()=0;
54
+
55
+        protected:
56
+
57
+            // ====================  LIFECYCLE     =======================
58
+
59
+            /// Default protected constructor.
60
+            IntegrationKernel (const std::string& name);
61
+
62
+            /// Default protected constructor.
63
+            ~IntegrationKernel ();
64
+
65
+            // ====================  DATA MEMBERS  =========================
66
+
67
+        private:
68
+
69
+    }; // -----  end of class  IntegrationKernel  -----
70
+
71
+    template <typename T>
72
+    IntegrationKernel<T>::IntegrationKernel(const std::string& name) :
73
+        LemmaObject(name) {
74
+    }
75
+
76
+    template<typename T>
77
+    IntegrationKernel<T>::~IntegrationKernel( ) {
78
+    }
79
+
80
+//     template <typename T>
81
+//     T IntegrationKernel<T>::Argument(const Real& x, const int& iRelated) {
82
+//         return 11.;
83
+//     }
84
+//
85
+//     template <typename T>
86
+//     int IntegrationKernel<T>::GetNumRel( ) {
87
+//         return 0;
88
+//     }
89
+
90
+}		// -----  end of Lemma  name  -----
91
+
92
+#endif   // ----- #ifndef INTEGRATIONKERNEL_INC  -----

+ 118
- 0
Modules/FDEM1D/include/inversesolver.h View File

@@ -0,0 +1,118 @@
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     07/14/2010
11
+  @version  $Id: inversesolver.h 193 2014-11-10 23:51:41Z tirons $
12
+ **/
13
+
14
+#ifndef  INVERSESOLVER_H_INC
15
+#define  INVERSESOLVER_H_INC
16
+
17
+#include "LemmaObject.h"
18
+#include "data.h"
19
+#include "instrument.h"
20
+#include "octreegrid.h"
21
+
22
+namespace Lemma {
23
+
24
+
25
+    // ===================================================================
26
+    //  Class:  InverseSolver
27
+    /**
28
+      @class  InverseSolver
29
+      \brief   Abstract class for inverse problem solver.
30
+      \details General solution of inverse problems.
31
+     */
32
+    // ===================================================================
33
+    class InverseSolver : public LemmaObject {
34
+
35
+        friend  std::ostream &operator<<(std::ostream &stream,
36
+                const InverseSolver &ob);
37
+
38
+        friend class OctreeGrid;
39
+
40
+        public:
41
+
42
+            // ====================  LIFECYCLE     =======================
43
+
44
+            // ====================  OPERATORS     =======================
45
+
46
+            // ====================  OPERATIONS    =======================
47
+
48
+            // ====================  ACCESS        =======================
49
+
50
+            /** @brief Sets the obsered data, any instance of Data.
51
+             *  @details This may either be field data, or forward modelled
52
+             *  data.
53
+             *  @param[in] ObsData a pointer to the observed data class.
54
+             */
55
+            void SetObservedData(Data* ObsData);
56
+
57
+            /** @brief Sets the instument that is used to create the data.
58
+             *  @details This is used for all forward modelling.
59
+             *  @param[in] inst is a pointer to the instrument class.
60
+             */
61
+            void SetInstrument(Instrument* inst);
62
+
63
+            /** @brief Returns the predicted data.
64
+             *  @return a pointer to the predicted data.
65
+             */
66
+            Data* GetPredictedData();
67
+
68
+            // ====================  INQUIRY       =======================
69
+
70
+            /** Returns the number of iterations it took to converge to a
71
+             *  solution.
72
+             */
73
+            virtual int NumberOfIterations()=0;
74
+
75
+            /** Returns true if the inversion converged successfully.
76
+             */
77
+            virtual bool Success()=0;
78
+
79
+            /** Returns a vector of \f$ \phi_M \f$
80
+             */
81
+            virtual VectorXr GetPhiMVector()=0;
82
+
83
+            /** Returns a vector of \f$ \phi_D \f$
84
+             */
85
+            virtual VectorXr GetPhiDVector()=0;
86
+
87
+        protected:
88
+
89
+            // ====================  OPERATIONS    =======================
90
+
91
+            /// Used as a callback function from iterating mesh.
92
+            virtual void FillInG(const Vector3r& pos, const Vector3r& step)=0;
93
+
94
+            // ====================  LIFECYCLE     =======================
95
+
96
+            /// Default protected constructor.
97
+            InverseSolver (const std::string &name);
98
+
99
+            /// Default protected constructor.
100
+            ~InverseSolver ();
101
+
102
+            // ====================  DATA MEMBERS  =========================
103
+
104
+            /// The Observed Data
105
+            Data* ObservedData;
106
+
107
+            /// The Predicted Data
108
+            Data* PredictedData;
109
+
110
+            /// Instrument that makes the data
111
+            Instrument*            ModelInstrument;
112
+
113
+        private:
114
+
115
+    }; // -----  end of class  InverseSolver  -----
116
+}		// -----  end of Lemma  name  -----
117
+
118
+#endif   // ----- #ifndef INVERSESOLVER_H_INC  -----

+ 85
- 0
Modules/FDEM1D/include/kernel.h View File

@@ -0,0 +1,85 @@
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     01/29/2010
11
+  @version  $Id: kernel.h 193 2014-11-10 23:51:41Z tirons $
12
+ **/
13
+
14
+#ifndef __kernel_h
15
+#define __kernel_h
16
+
17
+#ifdef LEMMAUSEVTK
18
+#include "vtkImplicitFunction.h"
19
+#endif
20
+
21
+#include "LemmaObject.h"
22
+#include "receivercubes.h"
23
+
24
+namespace Lemma {
25
+
26
+        // ==================================================================
27
+        //        Class:  Kernel
28
+        /// \brief Pure abstract class for some kind of kernel function.
29
+        /// \details Provides a consistent interface to kernel functions.
30
+        // ==================================================================
31
+        class Kernel : public LemmaObject {
32
+
33
+            /// Prints out basic info about the class
34
+            friend std::ostream &operator<<(std::ostream &stream,
35
+                        const Kernel &ob);
36
+
37
+            public:
38
+
39
+                // ====================  LIFECYCLE     ======================
40
+
41
+                //static Kernel* New();
42
+
43
+                virtual void Delete()=0;
44
+
45
+                // ====================  OPERATORS     ======================
46
+
47
+                // ====================  OPERATIONS    ======================
48
+
49
+                // ====================  ACCESS        ======================
50
+
51
+                // ====================  INQUIRY       ======================
52
+
53
+                virtual VectorXcr ComputeSensitivity()=0;
54
+
55
+                #ifdef LEMMAUSEVTK
56
+                virtual VectorXcr ComputeSensitivity(vtkImplicitFunction* Impl)=0;
57
+                #endif
58
+
59
+                /** computes sensitivity for same value */
60
+                virtual VectorXcr ComputeSensitivity(const Real& fval)=0;
61
+
62
+                /** Computes sensitivity for array of values */
63
+                virtual VectorXcr ComputeSensitivity(const VectorXr& fval)=0;
64
+
65
+                virtual void SetFieldCubes(ReceiverCubes* pts)=0;
66
+
67
+                // ====================  DATA MEMBERS  ======================
68
+
69
+            protected:
70
+
71
+                // ====================  LIFECYCLE     ======================
72
+
73
+                /// Default protected constructor.
74
+                Kernel (const std::string& name);
75
+
76
+                /// Default protected constructor.
77
+                ~Kernel ();
78
+
79
+        private:
80
+
81
+    }; // -----  end of class  Kernel  -----
82
+
83
+}
84
+
85
+#endif // __kernel_h

+ 111
- 0
Modules/FDEM1D/include/kernelem1dbase.h View File

@@ -0,0 +1,111 @@
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
+
10
+  @author   Trevor Irons
11
+  @date     05/18/2012
12
+  @version  $Id: kernelem1dbase.h 193 2014-11-10 23:51:41Z tirons $
13
+ **/
14
+
15
+#ifndef  KERNELEM1DBASE_INC
16
+#define  KERNELEM1DBASE_INC
17
+
18
+#include "LemmaObject.h"
19
+
20
+namespace Lemma {
21
+
22
+    // Transverse electric or magnetic mode
23
+    enum EMMODE {TM, TE, NONE};
24
+
25
+    // ===================================================================
26
+    //  Class:  KernelEm1DBase
27
+    /**
28
+      @class
29
+      \brief   Pure virtual base class of KernelEm1D
30
+      \details Defines interface for HankelTransform classes
31
+     */
32
+    // ===================================================================
33
+    class KernelEm1DBase : public LemmaObject {
34
+
35
+        friend class KernelEM1DManager;
36
+
37
+        public:
38
+
39
+            // ====================  LIFECYCLE     =======================
40
+
41
+            // ====================  OPERATORS     =======================
42
+
43
+            // ====================  OPERATIONS    =======================
44
+
45
+            /** Returns the Complex bessel argument to be evaluated for a given
46
+			 * lambda value
47
+             */
48
+            virtual Complex BesselArg(const Real& lambda)=0;
49
+
50
+            /** Returns the complex bessel argument. Same as above, but does not
51
+             *  call reflection coefficient calculation in KernelEM1DReflBase.
52
+             *  @param[in] lambda is the hankel wave value.
53
+             */
54
+            virtual Complex RelBesselArg(const Real& lambda)=0;
55
+
56
+            // ====================  ACCESS        =======================
57
+            virtual void SetIk(const int& ik)=0;
58
+
59
+            virtual void SetMode(const EMMODE& mode)=0;
60
+
61
+            int GetManagerIndex() {
62
+                return this->managerIdx;
63
+            }
64
+
65
+            // ====================  INQUIRY       =======================
66
+            virtual int GetNumRel()=0;
67
+
68
+            virtual int GetBesselOrder()=0;
69
+
70
+            virtual Complex GetZm()=0;
71
+
72
+            virtual Complex GetYm()=0;
73
+
74
+            virtual Complex GetZs()=0;
75
+
76
+            virtual Complex GetKs()=0;
77
+
78
+        protected:
79
+
80
+            // ====================  LIFECYCLE     =======================
81
+
82
+            /// Default protected constructor.
83
+            KernelEm1DBase (const std::string& name) : LemmaObject(name)
84
+            {
85
+            }
86
+
87
+            /// Default protected constructor.
88
+            ~KernelEm1DBase () {
89
+                if (this->NumberOfReferences > 0)
90
+                    throw DeleteObjectWithReferences( this );
91
+            }
92
+
93
+            void Release() {
94
+                delete this;
95
+            }
96
+
97
+            // ====================  OPERATIONS    =======================
98
+
99
+
100
+            // ====================  DATA MEMBERS  =========================
101
+
102
+            /** Where does this kernel live on the vector managed by the manager */
103
+            int  managerIdx;
104
+
105
+        private:
106
+
107
+    }; // -----  end of class  KernelEm1DBase  -----
108
+
109
+} // namespace Lemma
110
+
111
+#endif   // ----- #ifndef KERNELEM1DBASE_INC  -----

+ 217
- 0
Modules/FDEM1D/include/kernelem1dmanager.h View File

@@ -0,0 +1,217 @@
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     06/26/2012
11
+  @version   0.0
12
+ **/
13
+
14
+#ifndef  KERNELEM1DMANAGER_INC
15
+#define  KERNELEM1DMANAGER_INC
16
+
17
+//#include "dipolesource.h"
18
+//#include "kernelem1dreflbase.h"
19
+#include "kernelem1dbase.h"
20
+#include "kernelem1dspec.h"
21
+
22
+namespace Lemma {
23
+
24
+    class DipoleSource;
25
+    class KernelEM1DReflBase;
26
+
27
+    // ===================================================================
28
+    //  Class:  KernelEM1DManager
29
+    /**
30
+      @class
31
+      \brief
32
+      \details
33
+     */
34
+    // ===================================================================
35
+    class KernelEM1DManager : public LemmaObject {
36
+
37
+        public:
38
+
39
+            friend std::ostream &operator<<(std::ostream &stream,
40
+                        const KernelEM1DManager &ob);
41
+
42
+            // ====================  LIFECYCLE     =======================
43
+
44
+            /** Returns a pointer to a new object of type KernelEM1DManager.
45
+             * It allocates all necessary memory.
46
+             */
47
+            static KernelEM1DManager* New();
48
+
49
+            /** Deletes this object. Delete also disconnects any
50
+             * attachments to this object.
51
+             */
52
+            void Delete();
53
+
54
+            // ====================  OPERATORS     =======================
55
+
56
+            // ====================  OPERATIONS    =======================
57
+
58
+            template<EMMODE Mode, int Ikernel, DIPOLE_LOCATION Isource, DIPOLE_LOCATION Irecv>
59
+            int AddKernel( );
60
+            /*
61
+            {
62
+
63
+                KernelEm1DSpec<Mode, Ikernel, Isource, Irecv>* NewKern =
64
+                    KernelEm1DSpec<Mode, Ikernel, Isource, Irecv>::New();
65
+                KernelVec.push_back( NewKern );
66
+                NewKern->managerIdx = KernelVec.size()-1;
67
+                switch (Mode) {
68
+                    case TE:
69
+                        if (TEReflBase == NULL) {
70
+                            TEReflBase = KernelEM1DReflSpec<TE, Isource, Irecv>::New();
71
+                            TEReflBase->Initialise(Earth);
72
+                            TEReflBase->SetUpSource(Dipole, ifreq);
73
+                            TEReflBase->SetUpReceiver( rx_z );
74
+                        }
75
+                        NewKern->SetReflBase(TEReflBase);
76
+                        break;
77
+                    case TM:
78
+                        if (TMReflBase == NULL) {
79
+                            TMReflBase = KernelEM1DReflSpec<TM, Isource, Irecv>::New();
80
+                            TMReflBase->Initialise(Earth);
81
+                            TMReflBase->SetUpSource(Dipole, ifreq);
82
+                            TMReflBase->SetUpReceiver( rx_z );
83
+                        }
84
+                        NewKern->SetReflBase(TMReflBase);
85
+                        break;
86
+                }
87
+                return static_cast<int>(KernelVec.size()-1);
88
+            }
89
+            */
90
+
91
+            void ResetSource(const int& ifreq);
92
+
93
+            /** For use in related Kernel calculations. This function calles
94
+             * ComputeReflectionCoeffs on TEReflBase and TMReflBase, if they
95
+             * exist. After this has been called, KernelEM1DBase::RelBesselArg() may be safely
96
+             * called. This method stores solutions of the same idx. rho0 is the intial lambda argument
97
+             */
98
+            void ComputeReflectionCoeffs(const Real& lambda, const int& idx, const Real& rho0);
99
+
100
+            /** Clears the vector of kernels */
101
+            void ClearVec() {
102
+                for (unsigned int ik=0; ik<this->KernelVec.size(); ++ik) {
103
+                    this->KernelVec[ik]->Delete();
104
+                }
105
+                KernelVec.clear();
106
+            }
107
+
108
+            // ====================  ACCESS        =======================
109
+
110
+            /** Sets the LayeredEarthEM class that will be used by the kernels.
111
+             */
112
+            void SetEarth( LayeredEarthEM*   Earth);
113
+
114
+            /** Sets the source of the kernels */
115
+            void SetDipoleSource( DipoleSource*   Dipole, const int& ifreq, const Real& rx_zin);
116
+
117
+            /** Returns pointer to specified kernel indice. Indices are assigned in the same
118
+                order as they are created by AddKernel.
119
+             */
120
+            KernelEm1DBase*    GetKernel(const unsigned int& ik);
121
+
122
+            /** Returns pointer to connected dipole.
123
+             */
124
+            DipoleSource*    GetDipole( );
125
+
126
+            inline std::vector<KernelEm1DBase*>  GetSTLVector() {
127
+                return KernelVec;
128
+            }
129
+
130
+            // ====================  INQUIRY       =======================
131
+
132
+        protected:
133
+
134
+            // ====================  LIFECYCLE     =======================
135
+
136
+            /** Default protected constructor. */
137
+            KernelEM1DManager (const std::string& name);
138
+
139
+            /** Default protected constructor. */
140
+            ~KernelEM1DManager ();
141
+
142
+            /**
143
+             * @copybrief LemmaObject::Release()
144
+             * @copydetails LemmaObject::Release()
145
+             */
146
+            void Release();
147
+
148
+            // ====================  DATA MEMBERS  =========================
149
+
150
+            /** List of KernelEm1D instances */
151
+            std::vector<KernelEm1DBase*>           KernelVec;
152
+
153
+            /** Reflection base used for TE mode */
154
+            KernelEM1DReflBase*                    TEReflBase;
155
+
156
+            /** Reflection base used for TM mode */
157
+            KernelEM1DReflBase*                    TMReflBase;
158
+
159
+            /** EmEarth Class */
160
+            LayeredEarthEM*                        Earth;
161
+
162
+            /** EM dipole souce */
163
+            DipoleSource*                          Dipole;
164
+
165
+            /** Frequency index for the sources */
166
+            int                                    ifreq;
167
+
168
+            /** Receiver height */
169
+            Real                                   rx_z;
170
+
171
+        private:
172
+
173
+    }; // -----  end of class  KernelEM1DManager  -----
174
+
175
+    // template methods
176
+    template<EMMODE Mode, int Ikernel, DIPOLE_LOCATION Isource, DIPOLE_LOCATION Irecv>
177
+    int KernelEM1DManager::AddKernel( ) {
178
+
179
+        KernelEm1DSpec<Mode, Ikernel, Isource, Irecv>* NewKern =
180
+                    KernelEm1DSpec<Mode, Ikernel, Isource, Irecv>::New();
181
+        KernelVec.push_back( NewKern );
182
+        NewKern->managerIdx = KernelVec.size()-1;
183
+        switch (Mode) {
184
+            case TE:
185
+                if (TEReflBase == NULL) {
186
+                    TEReflBase = KernelEM1DReflSpec<TE, Isource, Irecv>::New();
187
+                    TEReflBase->Initialise(Earth);
188
+                    TEReflBase->SetUpSource(Dipole, ifreq);
189
+                    TEReflBase->SetUpReceiver( rx_z );
190
+                }
191
+                NewKern->SetReflBase(TEReflBase);
192
+                break;
193
+            case TM:
194
+                if (TMReflBase == NULL) {
195
+                    TMReflBase = KernelEM1DReflSpec<TM, Isource, Irecv>::New();
196
+                    TMReflBase->Initialise(Earth);
197
+                    TMReflBase->SetUpSource(Dipole, ifreq);
198
+                    TMReflBase->SetUpReceiver( rx_z );
199
+                }
200
+                NewKern->SetReflBase(TMReflBase);
201
+                break;
202
+        }
203
+        return static_cast<int>(KernelVec.size()-1);
204
+     }
205
+
206
+
207
+//     /** Clears the vector of kernels */
208
+//     void ClearVec() {
209
+//         for (unsigned int ik=0; ik<this->KernelVec.size(); ++ik) {
210
+//             this->KernelVec[ik]->Delete();
211
+//         }
212
+//         KernelVec.clear();
213
+//     }
214
+
215
+}		// -----  end of Lemma  name  -----
216
+
217
+#endif   // ----- #ifndef KERNELEM1DMANAGER_INC  -----

+ 253
- 0
Modules/FDEM1D/include/kernelem1dreflbase.h View File

@@ -0,0 +1,253 @@
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     05/18/2012
11
+  @version  $Id: kernelem1dreflbase.h 193 2014-11-10 23:51:41Z tirons $
12
+ **/
13
+
14
+#ifndef  KERNELEM1DREFLBASE_INC
15
+#define  KERNELEM1DREFLBASE_INC
16
+
17
+#include "dipolesource.h"
18
+#include "kernelem1dbase.h"
19
+#include "layeredearthem.h"
20
+//#include "kernelem1dspec.h"
21
+
22
+namespace Lemma {
23
+
24
+    //class DipoleSource;
25
+
26
+    enum DIPOLE_LOCATION { INAIR, INGROUND };
27
+
28
+    // forward declaration for friend
29
+    template<EMMODE Mode, int Ikernel, DIPOLE_LOCATION Isource, DIPOLE_LOCATION Irecv>
30
+    class KernelEm1DSpec;
31
+
32
+
33
+    // ===================================================================
34
+    //  Class:  KernelEM1DReflBase
35
+    /**
36
+      @class
37
+      \brief   Abstract class defining EM1DRefl class.
38
+      \details Derived classes are template specialized for optimal performance.
39
+     */
40
+    // ===================================================================
41
+    class KernelEM1DReflBase : public LemmaObject {
42
+
43
+        template<EMMODE Mode, int Ikernel, DIPOLE_LOCATION Isource, DIPOLE_LOCATION Irecv>
44
+        friend class KernelEm1DSpec;
45
+        friend class KernelEM1DManager;
46
+
47
+        public:
48
+
49
+            // ====================  LIFECYCLE     =======================
50
+
51
+            // ====================  OPERATORS     =======================
52
+
53
+            // ====================  OPERATIONS    =======================
54
+
55
+            void Initialise(LayeredEarthEM* EarthIn) {
56
+
57
+                nlay = EarthIn->GetNumberOfLayers();
58
+                zh = VectorXcr::Zero(nlay);
59
+                yh = VectorXcr::Zero(nlay);
60
+                u = VectorXcr::Zero(nlay);
61
+                cf = VectorXcr::Zero(nlay);    // nlay -1 (lay 0 empty)
62
+                rtu = VectorXcr::Zero(nlay);   // nlay -1 Interfaces only
63
+                rtd = VectorXcr::Zero(nlay);   // nlay -1 Interfaces only
64
+                kk = VectorXcr::Zero(nlay);
65
+                Zyu = VectorXcr::Zero(nlay);
66
+                Zyd = VectorXcr::Zero(nlay);
67
+                Zyi = VectorXcr::Zero(nlay);
68
+                th = VectorXcr::Zero(nlay);
69
+
70
+                // Don't attach Earth, because this is performance critical.
71
+                // Everying is internal, it's OK relax Frankie
72
+                //if (Earth != NULL) {
73
+                //    Earth->DetachFrom(this);
74
+                //    Earth = NULL;
75
+                //}
76
+                //EarthIn->AttachTo(this);
77
+                Earth = EarthIn;
78
+
79
+                LayerThickness.resize(nlay);
80
+                for (int ilay=0; ilay<nlay; ++ilay) {
81
+                    LayerThickness(ilay) =  Earth->GetLayerThickness(ilay);
82
+                }
83
+
84
+                LayerDepth.resize(nlay);
85
+                for (int ilay=0; ilay<nlay; ++ilay) {
86
+                    LayerDepth(ilay) =  Earth->GetLayerDepth(ilay);
87
+                }
88
+
89
+            }
90
+
91
+            void SetUpSource(DipoleSource *Dipole, const int &ifreq) {
92
+
93
+                zh(0) = Complex(0, Dipole->GetAngularFrequency(ifreq)*MU0);
94
+                yh(0) = Complex(0, Dipole->GetAngularFrequency(ifreq)*EPSILON0);
95
+                kk(0) = -zh(0) * yh(0);
96
+
97
+                Earth->EvaluateColeColeModel(Dipole->GetAngularFrequency(ifreq));
98
+
99
+                for (int ilay=1; ilay<Earth->GetNumberOfLayers(); ++ilay) {
100
+                    zh(ilay) = zh(0) * Earth->GetLayerSusceptibility(ilay);
101
+                    yh(ilay) = Earth->GetLayerConductivity(ilay) +
102
+                            yh(0)*Earth->GetLayerPermitivity(ilay);
103
+                    kk(ilay)   = -zh(ilay)*yh(ilay);
104
+                }
105
+
106
+                tx_z = Dipole->GetLocation(2);
107
+                lays = 0;
108
+                Real Depth(0);
109
+                for (int ilay=1; ilay<nlay; ++ilay) {
110
+                    if (tx_z > Depth) {
111
+                        lays = ilay;
112
+                    }
113
+                    Depth += LayerThickness(ilay);
114
+                }
115
+            }
116
+
117
+            void SetUpReceiver(const Real &rz) {
118
+                rx_z = rz;
119
+                Real Depth(0.);
120
+                layr = 0;
121
+                for (int ilay=1; ilay<Earth->GetNumberOfLayers(); ++ilay) {
122
+                    if (rx_z > Depth) {
123
+                        layr = ilay;
124
+                    }
125
+                    Depth += LayerThickness(ilay);
126
+                }
127
+            }
128
+
129
+            // ====================  ACCESS        =======================
130
+            Complex GetYm() {
131
+                return yh(layr);
132
+            }
133
+
134
+            Complex GetZm() {
135
+                return zh(layr);
136
+            }
137
+
138
+            Complex GetZs() {
139
+                return zh(lays);
140
+            }
141
+
142
+            Complex GetKs() {
143
+                return kk(lays);
144
+            }
145
+
146
+            // ====================  INQUIRY       =======================
147
+
148
+        protected:
149
+
150
+            // ====================  LIFECYCLE     =======================
151
+
152
+            /// Default protected constructor.
153
+            KernelEM1DReflBase (const std::string& name) : LemmaObject(name)
154
+            {
155
+            }
156
+
157
+            /// Default protected constructor.
158
+            ~KernelEM1DReflBase () {
159
+                if (this->NumberOfReferences > 0)
160
+                    throw DeleteObjectWithReferences( this );
161
+            }
162
+
163
+            void Release() {
164
+                delete this;
165
+            }
166
+
167
+            // ====================  OPERATIONS    =======================
168
+
169
+            /** Computes reflection coefficients. Depending on the
170
+             * specialisation, this will either be TM or TE mode.
171
+             */
172
+            virtual void ComputeReflectionCoeffs(const Real& lambda)=0;
173
+
174
+            /** Precomputes expensive calculations that are reused by insances
175
+             * of KernelEM1DSpec in the calculation of Related potentials.
176
+             */
177
+            virtual void PreComputePotentialTerms()=0;
178
+
179
+            // ====================  DATA MEMBERS  =========================
180
+
181
+			/// Bessel order, only 0 or 1 supported
182
+			int id; // Needs to be dim nRel, or separate
183
+
184
+            /// Layer the source is in
185
+			int lays;
186
+
187
+			/// Layer the receiver is in
188
+			int layr;
189
+
190
+			/// Number of Layers
191
+			int nlay;
192
+
193
+            /// Number of Related kernels to be computed
194
+            int nRelated;
195
+
196
+            /// Used in related kernel precompute calls
197
+            int relIud;
198
+
199
+			/// Receiver z position
200
+			Real rx_z;
201
+
202
+			/// Transmitter z position
203
+			Real tx_z;
204
+
205
+            /// bessel arg squared
206
+            Real rams;
207
+
208
+            /** Related part of con term */
209
+            Complex  relCon;
210
+
211
+            Complex  relenukadz;
212
+
213
+            Complex  relexp_pbs1;
214
+
215
+            Complex  relexp_pbs2;
216
+
217
+            Complex  rel_a;
218
+
219
+			/// TM or TE mode
220
+			EMMODE mode;
221
+
222
+            /// Pointer to layered earth
223
+            LayeredEarthEM *Earth;
224
+
225
+			Complex       uk;
226
+			Complex       um;
227
+			VectorXcr     cf;  // nlay
228
+			VectorXcr      u;  // nlay
229
+			VectorXcr     yh;  // nlay
230
+			VectorXcr     zh;  // nlay
231
+			VectorXcr     kk;  // nlay
232
+			VectorXcr    Zyu;  //(nlay); //Zyu.setZero();
233
+			VectorXcr    Zyd;  //(nlay); //Zyd.setZero();
234
+			VectorXcr    Zyi;  //(nlay); //Zyi.setZero();
235
+			VectorXcr     th;  //(nlay);
236
+			VectorXr     LayerThickness;
237
+			VectorXr     LayerDepth;
238
+
239
+			/// Reflection/Transmission coeffients for upgoing waves in a
240
+			/// layered earth model
241
+			VectorXcr    rtu;
242
+
243
+			/// Reflection/Transmission coeffients for downgoing waves in
244
+			/// a layered earth model
245
+			VectorXcr    rtd;
246
+
247
+        private:
248
+
249
+    }; // -----  end of class  KernelEM1DReflBase  -----
250
+
251
+}		// -----  end of Lemma  name  -----
252
+
253
+#endif   // ----- #ifndef KERNELEM1DREFLBASE_INC  -----

+ 373
- 0
Modules/FDEM1D/include/kernelem1dreflspec.h View File

@@ -0,0 +1,373 @@
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     05/18/2012
11
+  @version  $Id: kernelem1dreflspec.h 123 2014-02-05 23:47:20Z tirons $
12
+ **/
13
+
14
+#ifndef  KERNELEM1DREFLSPEC_INC
15
+#define  KERNELEM1DREFLSPEC_INC
16
+
17
+#include "dipolesource.h"
18
+#include "kernelem1dreflbase.h"
19
+#include "layeredearthem.h"
20
+
21
+// #include<unordered_map> // for caching results
22
+
23
+namespace Lemma {
24
+
25
+    // forward declare
26
+    //struct cache;
27
+    // Simple container to hold reflection results
28
+    struct  cache {
29
+        Real                       rho0;
30
+        Real                       lambda[805];
31
+        Real                       rams[805];
32
+        Complex                    uk[805];
33
+        Complex                    um[805];
34
+        Real                       zh0i[805];
35
+        VectorXcr                  Rtd[805];
36
+        VectorXcr                  Rtu[805];
37
+        VectorXcr                  u[805];
38
+        VectorXcr                  cf[805];
39
+        VectorXcr                  kk[805];
40
+        const Real                 epsilon;
41
+        //bool                       nc;
42
+        cache( ) : epsilon (std::numeric_limits<Real>::epsilon() ) { // TODO reset to precision of Real
43
+            //Rtd = VectorXcr::Zero(805);
44
+            //Rtu = VectorXcr::Zero(805);
45
+        }
46
+    };
47
+
48
+    // forward declaration for friend
49
+    template<EMMODE Mode, int Ikernel, DIPOLE_LOCATION Isource, DIPOLE_LOCATION Irecv>
50
+    class KernelEm1DSpec;
51
+
52
+    // ===================================================================
53
+    //  Class:  KernelEM1DReflSpec
54
+    /**
55
+      @class
56
+      \brief   Specialized version of KernelEM1DReflBase
57
+      \details Through use of template specialisations, this KernelEm1D
58
+               class delivers much better performance.
59
+     */
60
+    // ===================================================================
61
+    template<EMMODE Mode, DIPOLE_LOCATION Isource, DIPOLE_LOCATION Irecv>
62
+    class KernelEM1DReflSpec : public KernelEM1DReflBase {
63
+
64
+        public:
65
+
66
+            template<EMMODE Mode2, int Ikernel2, DIPOLE_LOCATION Isource2, DIPOLE_LOCATION Irecv2>
67
+            friend class KernelEm1DSpec;
68
+            friend class KernelEM1DManager;
69
+
70
+            // ====================  LIFECYCLE     =======================
71
+
72
+            static KernelEM1DReflSpec* New() {
73
+                KernelEM1DReflSpec<Mode, Isource, Irecv>*  Obj =
74
+                    new KernelEM1DReflSpec<Mode, Isource, Irecv>("KernelEM1DReflSpec<>");
75
+                Obj->AttachTo(Obj);
76
+                return Obj;
77
+            }
78
+
79
+            void Delete() {
80
+                this->DetachFrom(this);
81
+            }
82
+
83
+            // ====================  OPERATORS     =======================
84
+
85
+            // ====================  OPERATIONS    =======================
86
+
87
+            // ====================  ACCESS        =======================
88
+
89
+            // ====================  INQUIRY       =======================
90
+
91
+        protected:
92
+
93
+            // ====================  LIFECYCLE     =======================
94
+
95
+            /// Default protected constructor.
96
+            KernelEM1DReflSpec (const std::string& name) : KernelEM1DReflBase(name)
97
+            {
98
+            }
99
+
100
+            /// Default protected constructor.
101
+            ~KernelEM1DReflSpec () {
102
+                if (this->NumberOfReferences > 0)
103
+                    throw DeleteObjectWithReferences( this );
104
+            }
105
+
106
+            void Release() {
107
+                delete this;
108
+            }
109
+
110
+            // ====================  OPERATIONS    =======================
111
+
112
+            /** Computes reflection coefficients. Depending on the
113
+             * specialisation, this will either be TM or TE mode.
114
+             */
115
+            void ComputeReflectionCoeffs(const Real &lambda);
116
+
117
+            /* Computes reflection coefficients. Depending on the
118
+             * specialisation, this will either be TM or TE mode. This method
119
+             * stores previous results in a struct. For a given index, and
120
+             * lambda, the result will be the same. Turned out to be of limited utility.
121
+             */
122
+            //void ComputeReflectionCoeffs(const Real &lambda, const int& idx);
123
+
124
+            /** Precomputes expensive calculations that are reused by insances
125
+             * of KernelEM1DSpec in the calculation of Related potentials. This
126
+             * method is specialised based on template parameters
127
+             */
128
+            void PreComputePotentialTerms();
129
+
130
+            /*
131
+             * Sets the cache in CACHE to use. Somewhat expensive, avoid calling in tight loops
132
+             */
133
+            //void SetTCache(const Real& rho0);
134
+
135
+            // ====================  DATA MEMBERS  =========================
136
+
137
+        private:
138
+
139
+            //** Storage container for reused results */
140
+            //static std::unordered_map<Real, cache> CACHE;
141
+
142
+            //** Currenly used cache */
143
+            //cache* tcache;
144
+            //#pragma omp threadprivate(tcache)
145
+
146
+    }; // -----  end of class  KernelEM1DReflSpec  -----
147
+
148
+    //template<EMMODE Mode, DIPOLE_LOCATION Isource, DIPOLE_LOCATION Irecv>
149
+    //std::unordered_map<Real, cache> KernelEM1DReflSpec<Mode, Isource, Irecv>::CACHE;
150
+
151
+    //template<EMMODE Mode, DIPOLE_LOCATION Isource, DIPOLE_LOCATION Irecv>
152
+    //cache*  KernelEM1DReflSpec<Mode, Isource, Irecv>::tcache;
153
+
154
+    ///////////////////////////////////////////////
155
+    // Declarations of specialisations
156
+
157
+    template<>
158
+    void KernelEM1DReflSpec<TM, INAIR, INAIR>::ComputeReflectionCoeffs(const Real& lambda);
159
+
160
+    template<>
161
+    void KernelEM1DReflSpec<TE, INAIR, INAIR>::ComputeReflectionCoeffs(const Real& lambda);
162
+
163
+    template<>
164
+    void KernelEM1DReflSpec<TM, INAIR, INGROUND>::ComputeReflectionCoeffs(const Real& lambda);
165
+
166
+    template<>
167
+    void KernelEM1DReflSpec<TE, INAIR, INGROUND>::ComputeReflectionCoeffs(const Real& lambda);
168
+
169
+    template<>
170
+    void KernelEM1DReflSpec<TM, INAIR, INAIR>::PreComputePotentialTerms( );
171
+
172
+    template<>
173
+    void KernelEM1DReflSpec<TE, INAIR, INAIR>::PreComputePotentialTerms( );
174
+
175
+    template<>
176
+    void KernelEM1DReflSpec<TM, INAIR, INGROUND>::PreComputePotentialTerms( );
177
+
178
+    template<>
179
+    void KernelEM1DReflSpec<TE, INAIR, INGROUND>::PreComputePotentialTerms( );
180
+
181
+    ///////////////////////////////////////////////
182
+    // Default mode definitions
183
+
184
+/*
185
+    template<EMMODE Mode, DIPOLE_LOCATION Isource, DIPOLE_LOCATION Irecv>
186
+    void KernelEM1DReflSpec<Mode, Isource, Irecv>::SetTCache(const Real& rho0) {
187
+       #ifdef LEMMAUSEOMP
188
+        #pragma omp critical
189
+        #endif
190
+        {
191
+        this->tcache = &this->CACHE[rho0];
192
+        }
193
+    }
194
+*/
195
+
196
+/*
197
+    template<EMMODE Mode, DIPOLE_LOCATION Isource, DIPOLE_LOCATION Irecv>
198
+    void KernelEM1DReflSpec<Mode, Isource, Irecv>::ComputeReflectionCoeffs(const Real& lambda, const int& idx) {
199
+
200
+        if ( (std::abs(this->tcache->lambda[idx]-lambda) <= this->tcache->epsilon) &&
201
+            this->tcache->u[idx].size() > 0  && std::abs(this->kk(0) - this->tcache->kk[idx](0)) <= this->tcache->epsilon ) {
202
+            //std::cout << "USING CACHED RESULTS !!!!!!" << std::endl;
203
+            // load all the values we need
204
+            this->u   = this->tcache->u[idx];
205
+            this->rams = this->tcache->rams[idx];
206
+            this->cf = this->tcache->cf[idx];
207
+            //this->kk = this->tcache->kk[idx];
208
+            this->uk = this->tcache->uk[idx];
209
+            this->um = this->tcache->um[idx];
210
+            this->rtd = this->tcache->Rtd[idx];
211
+            this->rtu = this->tcache->Rtu[idx];
212
+
213
+        } else { // else do the work
214
+        }
215
+
216
+        ComputeReflectionCoeffs(lambda);
217
+
218
+        //#pragma omp critical
219
+        //{
220
+        //std::cout << idx << "\t" << lambda << "\t" << rtd.transpose() << std::endl;
221
+        //}
222
+        // store the results
223
+        this->tcache->u[idx]      = this->u;
224
+        this->tcache->cf[idx]     = this->cf;
225
+        this->tcache->kk[idx]     = this->kk;
226
+        this->tcache->uk[idx]     = this->uk;
227
+        this->tcache->um[idx]     = this->um;
228
+        this->tcache->Rtd[idx]    = this->rtd;
229
+        this->tcache->Rtu[idx]    = this->rtu;
230
+        this->tcache->zh0i[idx]    = std::imag(this->zh[0]);
231
+        this->tcache->lambda[idx] = lambda;
232
+        this->tcache->rams[idx]   = rams;
233
+
234
+        }
235
+
236
+        return;
237
+    }
238
+*/
239
+
240
+    template<EMMODE Mode, DIPOLE_LOCATION Isource, DIPOLE_LOCATION Irecv>
241
+    void KernelEM1DReflSpec<Mode, Isource, Irecv>::ComputeReflectionCoeffs(const Real& lambda) {
242
+        static bool called = false;
243
+        if (!called) {
244
+            std::cout << "unspecialised Reflection function KernelEM1DReflSpec<"
245
+                      << Mode << ", " << Isource << ", "
246
+                      << Irecv << " >::ComputeReflectionCoeffs( const Real& lambda ) --> SLOW PERFORMANCE EXPECTED\n";
247
+            called = true;
248
+        }
249
+
250
+        rams = lambda*lambda;
251
+        //////////////////////////////////////////
252
+        // Compute TEM stuff
253
+
254
+        // This call to sqrt takes ~ 15% of execution time
255
+        u  = (rams-kk.array()).sqrt();
256
+        uk = u(lays);
257
+        um = u(layr);
258
+
259
+        switch (Mode) {
260
+
261
+            // TM mode
262
+            case (TM):
263
+                Zyu(1) = -u(0)/yh(0);
264
+                Zyi    =  u.array() / yh.array();
265
+                break;
266
+
267
+            // TE mode
268
+            case (TE):
269
+                Zyu(1) = -u(0)/zh(0);
270
+                Zyi    =  u.array() / zh.array();
271
+                break;
272
+
273
+            default:
274
+                throw 11; //IllegalMode(this);
275
+        }
276
+
277
+        Zyd.tail<1>() = Zyi.tail<1>();
278
+
279
+        for (int ilay=1; ilay<nlay-1; ++ilay) {
280
+            cf(ilay) =
281
+                std::exp(-(Real)(2.)*u(ilay)*LayerThickness(ilay));
282
+            th(ilay) = ((Real)(1.)-cf(ilay)) / ((Real)(1.)+cf(ilay));
283
+        }
284
+
285
+        // Can't use blocks, b/c recursive
286
+        for (int N=1; N<lays; ++N){
287
+            Zyu(N+1)=Zyi(N)*(Zyu(N)-Zyi(N)*th(N)) /
288
+                            (Zyi(N)-Zyu(N)*th(N)) ;
289
+        }
290
+
291
+        int ne = nlay-2;
292
+        for (int N=ne; N >=lays+1; --N) {
293
+            Zyd(N) = Zyi(N)*(Zyd(N+1)+Zyi(N)*th(N)) /
294
+                            (Zyi(N)+Zyd(N+1)*th(N)) ;
295
+        }
296
+
297
+        rtd(nlay-1) = 0;
298
+
299
+        if (layr < lays) {
300
+            // Receiver above source layer
301
+            int ls = layr;
302
+            if (ls == 0) {
303
+                ls = layr+1;
304
+            }
305
+            for (int N=ls; N<=lays; ++N) {
306
+                rtu(N)= (Zyi(N)+Zyu(N)) /
307
+                        (Zyi(N)-Zyu(N)) ;
308
+            }
309
+            if (lays < nlay-1) {
310
+                rtd(lays) = (Zyi(lays)-Zyd(lays+1)) /
311
+                            (Zyi(lays)+Zyd(lays+1)) ;
312
+            }
313
+        } else {
314
+            // RECEIVER IN OR BELOW THE SOURCE LAYER
315
+            if (lays == layr) {  // Rx In source Layer
316
+                if (layr == 0) {
317
+                    rtd(0) = (Zyu(1)+Zyd(1)) /
318
+                             (Zyu(1)-Zyd(1)) ;
319
+                } else if (layr == nlay-1) {
320
+                    rtu(nlay-1) = (Zyi(nlay-1)+Zyu(nlay-1)) /
321
+                                  (Zyi(nlay-1)-Zyu(nlay-1)) ;
322
+                } else {
323
+                    rtu(layr) = (Zyi(layr)+Zyu(layr)) /
324
+                                (Zyi(layr)-Zyu(layr)) ;
325
+                    rtd(layr) = (Zyi(layr)-Zyd(layr+1)) /
326
+                                (Zyi(layr)+Zyd(layr+1)) ;
327
+                }
328
+            } else { // receiver below source layer
329
+                if (lays == 0) {
330
+                    rtd(0) = (Zyu(1)+Zyd(1)) /
331
+                             (Zyu(1)-Zyd(1)) ;
332
+                } else {
333
+                    rtu(lays) = (Zyi(lays)+Zyu(lays)) /
334
+                                (Zyi(lays)-Zyu(lays)) ;
335
+                }
336
+                int le = layr;
337
+                if (le == nlay-1) --le;
338
+                int ls = lays;
339
+                if (lays == 0   ) ++ls;
340
+
341
+                // TODO use blocks to vectorize maybe?
342
+                // This works but gives same to slightly worse
343
+                // performance as loop.
344
+//                 int nn = le-ls+1;
345
+//                 rtd.segment(ls, nn) =
346
+//                      (Zyi.segment(ls  , nn).array() -
347
+//                       Zyd.segment(ls+1, nn).array()).array() /
348
+//                      (Zyi.segment(ls  , nn).array() +
349
+//                       Zyd.segment(ls+1, nn).array()).array() ;
350
+                for (int N=ls; N<=le; ++N) {
351
+                    rtd(N) = (Zyi(N)-Zyd(N+1)) /
352
+                             (Zyi(N)+Zyd(N+1)) ;
353
+                }
354
+            }
355
+        } // End in or below source layer
356
+        return;
357
+    }
358
+
359
+    template<EMMODE Mode, DIPOLE_LOCATION Isource, DIPOLE_LOCATION Irecv>
360
+    void KernelEM1DReflSpec<Mode, Isource, Irecv>::PreComputePotentialTerms( ) {
361
+        static bool called = false;
362
+        if (!called) {
363
+            std::cerr << "unspecialised function KernelEM1DReflSpec<"
364
+                      << Mode << ", " << Isource << ", "
365
+                      << Irecv << " >::PreComputePotentialTerms\n";
366
+            called = true;
367
+        }
368
+    }
369
+
370
+
371
+}		// -----  end of Lemma  name  -----
372
+
373
+#endif   // ----- #ifndef KERNELEM1DREFLSPEC_INC  -----

+ 1485
- 0
Modules/FDEM1D/include/kernelem1dspec.h
File diff suppressed because it is too large
View File


+ 314
- 0
Modules/FDEM1D/include/layeredearthem.h View File

@@ -0,0 +1,314 @@
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     06/24/2009
11
+  @version   0.0
12
+ **/
13
+
14
+#ifndef __LAYEREDEARTHEM_H
15
+#define __LAYEREDEARTHEM_H
16
+
17
+#include "layeredearth.h"
18
+#include <iomanip>
19
+
20
+namespace Lemma {
21
+
22
+    // =======================================================================
23
+    //        Class:  LayeredEarthEM
24
+    /// \brief  1D layered earth. Attributes include all aspects of
25
+    /// Cole-Cole model.
26
+    /// \details   Primarily used for EM calculations.
27
+    // =======================================================================
28
+    class LayeredEarthEM : public LayeredEarth {
29
+
30
+        public:
31
+
32
+            // ====================    FRIENDS     ===========================
33
+
34
+            /** Recursively streams information about this class */
35
+            friend std::ostream &operator<<(std::ostream &stream,
36
+                        const LayeredEarthEM &ob);
37
+
38
+            // ====================  LIFECYCLE     ===========================
39
+
40
+            /**
41
+             *  Public constructor. Creates a new instance of the class and
42
+             *  assigns a reference to the thrown pointer.
43
+             */
44
+            static LayeredEarthEM* New();
45
+
46
+            /**
47
+             * @copybrief LemmaObject::Delete()
48
+             * @copydetails LemmaObject::Delete()
49
+             */
50
+            void Delete();
51
+
52
+            #ifdef HAVE_YAMLCPP
53
+            /** YAML Serializing method
54
+             */
55
+            YAML::Node Serialize() const;
56
+
57
+
58
+            //static LayeredEarthEM* DeSerialize(const YAML::Node& node);
59
+            #endif
60
+
61
+            /** @return a deep copy
62
+             */
63
+			LayeredEarthEM* Clone();
64
+
65
+            // ====================  OPERATORS     ===========================
66
+
67
+            // ====================  OPERATIONS    ===========================
68
+
69
+            /** Evaluates the cole-cole model for suceptability and
70
+             * permeability.
71
+             * @param[in] omega is the frequency in Hz
72
+             */
73
+            void EvaluateColeColeModel(const Real& omega);
74
+
75
+            // ====================  ACCESS        ===========================
76
+
77
+            /** Sets the number of layers and resizes all model parameters to
78
+             *  be the correct size, finally initialises all values to free
79
+             *  space.
80
+             *  @param[in] nlay is the number of layers
81
+             */
82
+            virtual void SetNumberOfLayers(const int& nlay);
83
+
84
+            /** Sets Complex Conductivity of the layers
85
+             *  @param[in] sigma is a vector of the conducivity of the layers
86
+             */
87
+            void SetLayerConductivity(const VectorXcr &sigma);
88
+
89
+            /** Sets Complex Conductivity of a single layer
90
+             *  @param[in] sigma is  the conducivity of the layer
91
+             *  @param[in] ilay is  the layer index
92
+             */
93
+            void SetLayerConductivity(const int& ilay, const Complex &sigma);
94
+
95
+            /* Sets Complex resitivity of the layers
96
+             *  @param[in] ohm is a vector of the resistivity of the layers
97
+                Singularity at 0 resistivity in air. Need to reformaulat things a bit
98
+             */
99
+            //void SetLayerResistivity(const VectorXcr &ohm);
100
+
101
+            /** Sets the thickness of the layers
102
+             *  @param[in] thick is a vector of the thicknesses of the layers.
103
+             *  Must be two less than the total number of Layers as the top and
104
+             *  bottom layers are assumed infinite.
105
+             */
106
+            void SetLayerThickness(const VectorXr &thick);
107
+
108
+            /** Sets the High frequency susceptibility
109
+             */
110
+            void SetLayerHighFreqSusceptibility(const VectorXr& sushi);
111
+
112
+            /** Sets the Low frequency susceptibility
113
+             */
114
+            void SetLayerLowFreqSusceptibility(const VectorXr& sushi);
115
+
116
+            /** Sets the Layer breath susceptibility
117
+             */
118
+            void SetLayerBreathSusceptibility(const VectorXr& susbr);
119
+
120
+            /** Sets the Layer tau susceptibility
121
+             */
122
+            void SetLayerTauSusceptibility(const VectorXr& susta);
123
+
124
+            /** Sets the High frequency permitivity
125
+             */
126
+            void SetLayerHighFreqPermitivity(const VectorXr& sushi);
127
+
128
+            /** Sets the Low frequency permitivity
129
+             */
130
+            void SetLayerLowFreqPermitivity(const VectorXr& sushi);
131
+
132
+            /** Sets the Layer breath permitivity
133
+             */
134
+            void SetLayerBreathPermitivity(const VectorXr& oerbr);
135
+
136
+            /** Sets the Layer breath permitivity
137
+             */
138
+            void SetLayerTauPermitivity(const VectorXr& oerbr);
139
+
140
+            // ====================  INQUIRY       ===========================
141
+
142
+            /** Returns the thickness of a layer
143
+                @return a VectorXcr of the layer conductivities.
144
+             */
145
+            VectorXcr GetLayerConductivity( );
146
+
147
+            /** Returns the conductivity of a layer
148
+             *  @param[in] ilay is the layer indice of interest
149
+             *  @return the complex valued conductivity of the layer of
150
+             *  interest.
151
+             */
152
+            Complex GetLayerConductivity(const int &ilay);
153
+
154
+            /** Returns the susceptibility of a layer
155
+             *  @param[in] ilay is the layer indice of interest.
156
+             *  @return a Complex value of the electrical susceptibility of the
157
+             *  probes layer.
158
+             */
159
+            Complex GetLayerSusceptibility(const int &ilay);
160
+
161
+            /** Returns the Susceptibility of Cole-Cole model
162
+             *  @return a VectorXcr of the suceptibilities of the model.
163
+             */
164
+            VectorXcr GetLayerSusceptibility( );
165
+
166
+            /** Returns the low freq susceptibility of a layer
167
+             */
168
+            Real GetLayerLowFreqSusceptibility(const int &ilay);
169
+
170
+            /** Returns the low freq susceptibility of a layer
171
+             */
172
+            VectorXr GetLayerLowFreqSusceptibility( );
173
+
174
+            /** Returns the low freq susceptibility of a layer
175
+             */
176
+            Real GetLayerHighFreqSusceptibility(const int &ilay);
177
+
178
+            /** Returns the low freq susceptibility of a layer
179
+             */
180
+            VectorXr GetLayerHighFreqSusceptibility( );
181
+
182
+            /** Returns the low freq susceptibility of a layer
183
+             */
184
+            Real GetLayerTauSusceptibility(const int &ilay);
185
+
186
+            /** Returns the low freq susceptibility of a layer
187
+             */
188
+            VectorXr GetLayerTauSusceptibility( );
189
+
190
+            /** Returns the low freq susceptibility of a layer
191
+             */
192
+            Real GetLayerBreathSusceptibility(const int &ilay);
193
+
194
+            /** Returns the low freq susceptibility of a layer
195
+             */
196
+            VectorXr GetLayerBreathSusceptibility( );
197
+
198
+            /** Returns the Relative Permitivity of the cole cole model
199
+             */
200
+            VectorXcr GetLayerPermitivity( );
201
+
202
+            /** Returns the conductivity of a layer
203
+             *  @param[in] ilay is the layer indice of interest.
204
+             *  @return a Complex value of the electrical permitivity of the
205
+             *  probed layer.
206
+             */
207
+            Complex GetLayerPermitivity(const int &ilay);
208
+
209
+            /** Low Freq permivitity
210
+             */
211
+            VectorXr  GetLayerLowFreqPermitivity( );
212
+
213
+            /** Returns the low freq susceptibility of a layer
214
+             */
215
+            Real GetLayerLowFreqPermitivity(const int &ilay);
216
+
217
+            /** Returns the low freq susceptibility of a layer
218
+             */
219
+            Real GetLayerHighFreqPermitivity(const int &ilay);
220
+
221
+            /** Returns the low freq susceptibility of a layer
222
+             */
223
+            VectorXr GetLayerHighFreqPermitivity( );
224
+
225
+            /** Returns the low freq susceptibility of a layer
226
+             */
227
+            Real GetLayerTauPermitivity(const int &ilay);
228
+
229
+            /** Returns the low freq susceptibility of a layer
230
+             */
231
+            VectorXr GetLayerTauPermitivity( );
232
+
233
+            /** Returns the low freq susceptibility of a layer
234
+             */
235
+            Real GetLayerBreathPermitivity(const int &ilay);
236
+
237
+            /** Returns the low freq susceptibility of a layer
238
+             */
239
+            VectorXr GetLayerBreathPermitivity( );
240
+
241
+        protected:
242
+
243
+            // ====================  LIFECYCLE     ===========================
244
+
245
+            /** Default protected constructor. */
246
+            LayeredEarthEM (const std::string &name);
247
+
248
+            #ifdef HAVE_YAMLCPP
249
+            /** Default protected constructor. */
250
+			LayeredEarthEM (const YAML::Node& node);
251
+            #endif
252
+
253
+            /** Default protected constructor. */
254
+            ~LayeredEarthEM ();
255
+
256
+            /**
257
+             * @copybrief LemmaObject::Release()
258
+             * @copydetails LemmaObject::Release()
259
+             */
260
+            void Release();
261
+
262
+            // ====================  DATA MEMBERS  ===========================
263
+
264
+            /** Vector of layer Conductivity */
265
+            VectorXcr         LayerConductivity;
266
+
267
+            /** Vector of layer Susceptibility (chi)
268
+             *  This is calculated using the Cole-Cole model
269
+             *  \f[ sus(i) = sush(i)
270
+             *   + \frac{(susl(i)-sush(i))}  {(1+(jw * sustau(i))^{susalp(i)})} \f]
271
+             */
272
+            VectorXcr         LayerSusceptibility;
273
+
274
+            /** Vector of low frequency susceptibility, for use in Cole-Cole
275
+              model */
276
+            VectorXr          LayerLowFreqSusceptibility;
277
+
278
+            /** Vector of high frequency susceptibility, for use in Cole-Cole
279
+             model */
280
+            VectorXr          LayerHighFreqSusceptibility;
281
+
282
+            /** Vector of relaxation time constants, for use in Cole-Cole model
283
+             */
284
+            VectorXr          LayerTauSusceptibility;
285
+
286
+            /** Vector relaxation breath, for use in Cole-Cole model
287
+             */
288
+            VectorXr          LayerBreathSusceptibility;
289
+
290
+            /** Vector of Layer Permitivity (epsilon)
291
+             *  Calculated using the Cole-Cole model
292
+             *  \f[ epr(i) = eprh(i)
293
+             *     + \frac{ (eprl(i)-eprh(i))}  { (1+(jw*eprtau(i))^{epralp(i)})} \f]
294
+             */
295
+            VectorXcr         LayerPermitivity;
296
+
297
+            /** Low frequency permitivity for each layer */
298
+            VectorXr          LayerLowFreqPermitivity;
299
+
300
+            /** High frequency permitivity for each layer */
301
+            VectorXr          LayerHighFreqPermitivity;
302
+
303
+            /** Decay time constant for each layer */
304
+            VectorXr          LayerTauPermitivity;
305
+
306
+            /** Relaxation breath for each layer */
307
+            VectorXr          LayerBreathPermitivity;
308
+
309
+    }; // -----  end of class  LayeredEarthEM  -----
310
+
311
+
312
+} // namespace Lemma
313
+
314
+#endif // __LAYEREDEARTHEM_H

+ 68
- 0
Modules/FDEM1D/include/modelreaderfem1d.h View File

@@ -0,0 +1,68 @@
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   M. Andy Kass
10
+  @date     01/03/2013
11
+  @version  $Id$
12
+ **/
13
+
14
+#ifndef __MODELREADERFEM1D_H
15
+#define __MODELREADERFEM1D_H
16
+
17
+#include "modelreader.h"
18
+
19
+namespace Lemma {
20
+
21
+
22
+// ===================================================================
23
+//        Class:  ModelReaderFem1D
24
+/// \brief
25
+/// \details
26
+// ===================================================================
27
+	class ModelReaderFem1D : public ModelReader {
28
+
29
+		friend std::ostream &operator<<(std::ostream &stream,
30
+			const ModelReaderFem1D &ob);
31
+
32
+	public:
33
+
34
+	// ====================  LIFECYCLE     =======================
35
+
36
+	static ModelReaderFem1D* New();
37
+
38
+	void Delete();
39
+
40
+	// ====================  OPERATORS     =======================
41
+
42
+	// ====================  OPERATIONS    =======================
43
+
44
+	// ====================  ACCESS        =======================
45
+
46
+	// ====================  INQUIRY       =======================
47
+
48
+
49
+
50
+	protected:
51
+
52
+	// ====================  LIFECYCLE     =======================
53
+
54
+	/// Default protected constructor.
55
+	ModelReaderFem1D (const std::string &name);
56
+
57
+	/// Default protected constructor.
58
+	~ModelReaderFem1D ();
59
+
60
+	void Release();
61
+
62
+	// ====================  DATA MEMBERS  =========================
63
+
64
+	private:
65
+
66
+}; // -----  end of class  ModelReaderFem1D  -----
67
+} // end of namespace Lemma
68
+#endif // __MODELREADERFEM1D_H

+ 358
- 0
Modules/FDEM1D/include/octreegrid.h View File

@@ -0,0 +1,358 @@
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     03/19/2010
11
+  @version  $Id: octreegrid.h 193 2014-11-10 23:51:41Z tirons $
12
+ **/
13
+
14
+#ifndef  OCTREEGRID_INC
15
+#define  OCTREEGRID_INC
16
+
17
+// This class depends on VTK!
18
+
19
+#ifdef  LEMMAUSEVTK
20
+#include "grid.h"
21
+#include "vtkHyperOctree.h"        // In Filtering
22
+#include "vtkHyperOctreeCursor.h"
23
+#include "vtkHyperOctreeSampleFunction.h"
24
+#include "vtkImplicitFunction.h"
25
+#include "vtkCell.h"
26
+#include "vtkGenericCell.h"
27
+
28
+#ifdef  LEMMA_SINGLE_PRECISION
29
+#include "vtkFloatArray.h"
30
+#else      // -----  not LEMMA_SINGLE_PRECISION  -----
31
+#include "vtkDoubleArray.h"
32
+#endif     // -----  not LEMMA_SINGLE_PRECISION  -----
33
+
34
+#include "kernel.h"
35
+#include "receiverpoints.h"
36
+#include "receivercubes.h"
37
+#include "layeredearth.h"
38
+//#include "layeredearthnmr.h"
39
+#include "inversesolver.h"
40
+
41
+//#include "FastDelegate.h"
42
+//#include "FastDelegateBind.h"
43
+
44
+namespace Lemma {
45
+
46
+    // forward declaration
47
+    class InverseSolver ;
48
+
49
+    // ===================================================================
50
+    //        Class:  OctreeGrid
51
+    /** An Octree class, builds off VtkHyperOctree so this class can
52
+        only be used when compiled with VTK libs.
53
+        An Octree is a heirarchial 3D mesh with rectangular cells containing
54
+        either 0 or 8 children.
55
+     */
56
+    // ===================================================================
57
+    class OctreeGrid : public Grid {
58
+
59
+        friend class InverseSolver;
60
+        //friend class SNMRInversion1D;        // From Merlin Module
61
+
62
+        friend std::ostream &operator<<(std::ostream &stream,
63
+                const OctreeGrid &ob);
64
+
65
+        public:
66
+
67
+            // ====================  LIFECYCLE     =======================
68
+
69
+            /**
70
+             * new grid octreee
71
+             */
72
+            static OctreeGrid* New();
73
+
74
+            /**
75
+             * @copybrief LemmaObject::Delete()
76
+             * @copydetails LemmaObject::Delete()
77
+             */
78
+            void Delete();
79
+
80
+            // ====================  OPERATORS     =======================
81
+
82
+
83
+            // ====================  ACCESS        =======================
84
+
85
+            /** Sets the kernel function to be used to make the mesh.
86
+             *  @param[in] kern is a kernel that is used to generate a mesh.
87
+             */
88
+            void SetKernel(Kernel* kern);
89
+
90
+            /// Sets a 1D model associated with this kernel.
91
+            /// @param[in] model1d is a pointer to a LayeredEarth model that
92
+            /// will be used to pre-subdivide leaves that overlap several
93
+            /// layers.
94
+            void SetLayeredEarth(LayeredEarth* model1d);
95
+
96
+            /** Sets the size of the mesh
97
+                @param[in] size is the size of the mesh. The mesh must start at
98
+                [0,0,0] and goes to [sizex, sizey, sizez].
99
+             */
100
+            void SetSize(const Vector3r& size);
101
+
102
+            /** Sets the origin of the mesh
103
+                @param[in] origin is the origin of the mesh.
104
+             */
105
+            void SetOrigin(const Vector3r& origin);
106
+
107
+            /** Sets the minimum depth to model. This must be greater than 0.
108
+                @param[in] depth is the new minimum depth.
109
+             */
110
+            void SetMinimumDepth(const Real& depth);
111
+
112
+            /** Fills in the leaf data with the kernel sensitivity
113
+             */
114
+            void FillMeshWithKernel();
115
+
116
+            /** Fills in the leaf data with the kernel sensitivity
117
+             */
118
+            void FillMeshWithKernel(vtkImplicitFunction* Impl);
119
+
120
+            /** Sets the size of the mesh
121
+             */
122
+            void SetSize(const Real &x, const Real &y, const Real &z);
123
+
124
+            /** Generates mesh to specified tolerance.
125
+             *  @param[in] tol is the kernel tolerance.
126
+             */
127
+            void GenerateMesh(const Real &tol);
128
+
129
+
130
+            /** Generates a mesh to specified tolerance, but initially splits
131
+             *  based on implicit function.
132
+             *  @param[in] tol is the kernel tolerance.
133
+             *  @param[in] Impl is the implicit dataset used for initial
134
+             *  subdivision
135
+             *  @param[in] impltol is the tolerance for the initial model based
136
+             *  subdividing.
137
+             */
138
+            void GenerateMesh(const Real& tol, vtkImplicitFunction* Impl,
139
+                              const Real& impltol);
140
+
141
+            /** Generates an Octree mesh using a pre-sampled input Octree Dataset.
142
+                Speeds up repeated kernel calculations when the underlying model in
143
+                the above ImplicitFunction needs to be called often or is complex.
144
+             */
145
+            void GenerateMesh(const Real& tol, vtkImplicitFunction* Impl,
146
+                    vtkHyperOctreeSampleFunction* OctSamp);
147
+
148
+            /** Evaluates the kernel on the mesh. In some cases this is the same thing
149
+                as generate mesh, but if more that one calculation are needed on a
150
+                mesh you can use this method. It interfaces with the kernels by
151
+                calling
152
+             */
153
+            Complex EvaluateKernelOnMesh();
154
+
155
+            /** Returns a receiver cube class that represents the same Geometry as the
156
+                HyperOctree. This is useful as it can be passed directly to em1dearth,
157
+                and currently, an Octree cannot. But this requires storage of all the
158
+                cell volumes and locations. In the future, you should be able to pass
159
+                around this class just like a ReceiverCubes.
160
+             */
161
+            void ReceiverCubeRepresentation();
162
+
163
+            /** Returns the receiver cube class. */
164
+            ReceiverCubes* GetReceiverCubes();
165
+
166
+            /** returns the kernel sum from generation */
167
+            Complex GetKernelSum();
168
+
169
+            /** Accessor to underlying vtkClass.
170
+             *  @return a vtkHyperOctree that can be used for visualization.
171
+             */
172
+            vtkHyperOctree* GetVtkHyperOctree( );
173
+
174
+            /** Traverse the data structure and call a function at each leaf
175
+             */
176
+            void TraverseAndCall(InverseSolver* Inverse);
177
+
178
+            /** Traverse the data structure and call a function at each leaf
179
+             */
180
+            void TraverseAndCall( vtkImplicitFunction* Impl );
181
+
182
+            /**
183
+             */
184
+            void TraverseLeaves(vtkImplicitFunction* Impl);
185
+
186
+            /**
187
+             */
188
+            void FollowExistingTree(vtkHyperOctree* Leader, vtkHyperOctreeCursor* LeaderCursor,
189
+                    vtkImplicitFunction* Impl);
190
+
191
+            // ====================  OPERATIONS    =======================
192
+
193
+            /** Binds any derived member function of a derived class of
194
+                LayeredEarth to SampleScalarFromLayeredEarthFD. This function is then
195
+                used to sample the Octree mesh for that parameter. The member function
196
+                needs to be of the type GetLayerXXX(const int Layer& lay).
197
+                @param[in] earth is a pointer to a derived class of LayeredEarth
198
+                @param[in] fcnptr is a function pointer to a member function. It
199
+                should be called like &LayeredEarthNMR::GetLayerPorosity
200
+                @param[in] name is a std::string identifier.
201
+             */
202
+            template <class Derived>
203
+            void SampleScalarFromLayeredEarth(LayeredEarth* earth,
204
+                    Real (Derived::*fcnptr)(const int& id), const std::string &name) {
205
+                std::cerr << "In octreegrid.h SampleScalrFromLayeredEarth FastDelegate method was "
206
+                         << "removed, need to fix with move semantics or function pointer." << std::endl;
207
+                exit(3);
208
+                //TODO fix SampleScalar below, as call to SampleScalarFromLayeredEarthFD is
209
+                //     removed there.
210
+/*
211
+                SampleScalarFromLayeredEarthFD.bind(static_cast<Derived*>(earth), fcnptr);
212
+                GetLayerInt.bind(earth, &LayeredEarth::GetLayerAtThisDepth);
213
+                // TODO, don't use KernelArray, instead create new Array, and set it
214
+                // in there. Then delete?
215
+                this->KernelArray->SetName(name.c_str());
216
+                this->KernelArray->SetNumberOfTuples(Octree->GetNumberOfLeaves());
217
+                SampleScalar();
218
+                this->Octree->GetLeafData()->SetScalars( KernelArray );
219
+                this->Octree->GetLeafData()->AddArray( KernelArray );
220
+*/
221
+            }
222
+
223
+            /** Sends cursor to root
224
+             */
225
+            void CursorToRoot();
226
+
227
+            // ====================  INQUIRY       =======================
228
+
229
+        protected:
230
+
231
+            // ====================  LIFECYCLE     =======================
232
+
233
+            /** Default protected constructor. */
234
+            OctreeGrid (const std::string &name);
235
+
236
+            /** Default protected constructor. */
237
+            ~OctreeGrid ();
238
+
239
+            /**
240
+             * @copybrief LemmaObject::Release()
241
+             * @copydetails LemmaObject::Release()
242
+             */
243
+            void Release();
244
+
245
+            // ====================  OPERATIONS    =======================
246
+
247
+            /** Used internally. The leaf data is saved and then set as the vtk leaf
248
+             *  data.
249
+             */
250
+            void SetLeafDataFromGridCreation();
251
+
252
+            /** Return position of leaf, returns centre location
253
+             */
254
+            void GetPosition( Real* p );
255
+
256
+            /* Used to fill leaf data with a scalar value from a layered earth
257
+             *  model
258
+             */
259
+            //fastdelegate::FastDelegate1< const int&, Real > SampleScalarFromLayeredEarthFD;
260
+
261
+            /* Used to get the Layer of delagated model.
262
+             */
263
+            //fastdelegate::FastDelegate1< const Real&, int >  GetLayerInt;
264
+
265
+            /** Recursively determines the mesh to use
266
+             */
267
+            void EvaluateKids( );
268
+
269
+            /** Recursively determines the mesh to use
270
+                @param[in] kval is the current leaf kernel value
271
+                           which may be reused in analysis.
272
+             */
273
+            void EvaluateKids( Complex kval );
274
+
275
+            /** Same as above, but uses an implict function.
276
+             */
277
+            void EvaluateKids (vtkImplicitFunction* Impl);
278
+
279
+            /** Same as above, but lets function value be passed directly
280
+             */
281
+            void EvaluateKids (const Real& fval, vtkImplicitFunction* Impl);
282
+
283
+            /** Same as above but is passed a static fval to reuse. Useful when underlying model is smooth
284
+             */
285
+            void EvaluateKidsStatic(const Real& fval);
286
+
287
+            /** Same as above, but lets function value be passed directly
288
+             */
289
+            void SampleFunction(vtkImplicitFunction* Impl);
290
+
291
+            /** Recursively determines the mesh to use
292
+             */
293
+            void FillGrid( );
294
+
295
+            /** Recursively determines the mesh to use
296
+             */
297
+            void FillGrid(vtkImplicitFunction* Impl);
298
+
299
+            /** Used internally to build a receiver cube representation
300
+             */
301
+            void AssembleReceiverCubes( );
302
+
303
+            /** Samples a scalar from a LayeredEarth object. Used internally and calls
304
+             *  SampleScalarFromLayeredEarthFD, which can be set using
305
+             *  SampleScalarFromLayeredEarth.
306
+             */
307
+            void SampleScalar();
308
+
309
+
310
+
311
+            // Returns ReceiverPoints for the Octree.
312
+            //void ComputeFieldOnOctree( WireAntenna* loop );
313
+
314
+            // ====================  DATA MEMBERS  =========================
315
+
316
+        private:
317
+
318
+            Vector3r                Size;
319
+            Vector3r                Origin;
320
+            Vector3r                step;
321
+            Vector3r                cpos;
322
+
323
+            int                     level;
324
+            int                     maxlevel;
325
+            int                     index;
326
+            int                     counter;
327
+
328
+            Real                    cvol;
329
+            Real                    tvol;
330
+            Real                    tol;
331
+            Complex                 KernelSum;
332
+
333
+            Eigen::Matrix<Real, 8, 3> Posadd;
334
+
335
+            std::vector<Real>       leafdata;
336
+            std::vector<vtkIdType>  leafids;
337
+
338
+            Kernel                 *SenseKernel;
339
+            ReceiverCubes          *Cubes;
340
+            LayeredEarth           *Model1D;
341
+
342
+            vtkHyperOctree               *Octree;
343
+            vtkHyperOctreeCursor         *Cursor;
344
+            vtkHyperOctreeSampleFunction *OctSamp;
345
+
346
+            #ifdef  LEMMA_SINGLE_PRECISION
347
+            vtkFloatArray          *KernelArray;
348
+            #else      // -----  not LEMMA_SINGLE_PRECISION  -----
349
+            vtkDoubleArray         *KernelArray;
350
+            #endif     // -----  not LEMMA_SINGLE_PRECISION  -----
351
+            vtkDataArray           *SampleArray;
352
+
353
+    }; // -----  end of class  OctreeGrid  -----
354
+
355
+}       // -----  end of Lemma  name  -----
356
+
357
+#endif     // -----  not LEMMAUSEVTK  -----
358
+#endif   // ----- #ifndef OCTREEGRID_INC  -----

+ 169
- 0
Modules/FDEM1D/include/receivercubes.h View File

@@ -0,0 +1,169 @@
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     06/17/2010
11
+  @version  $Id: receivercubes.h 193 2014-11-10 23:51:41Z tirons $
12
+ **/
13
+
14
+#ifndef  RECEIVERCUBES_INC
15
+#define  RECEIVERCUBES_INC
16
+
17
+#include "receiverpoints.h"
18
+
19
+namespace Lemma {
20
+
21
+
22
+    // ===================================================================
23
+    //        Class:  ReceiverCubes
24
+    /** This class builds on Reciver points, but supports a cube around
25
+     * each point. It is a direct descendent and may be used wherever
26
+     * ReceiverPoints is used
27
+     */
28
+    // ===================================================================
29
+    class ReceiverCubes : public ReceiverPoints {
30
+
31
+        friend std::ostream &operator<<(std::ostream &stream,
32
+                const ReceiverCubes &ob);
33
+
34
+        friend class EmDipEarth1D;
35
+
36
+        public:
37
+
38
+            // ====================  LIFECYCLE     =======================
39
+
40
+            /**
41
+             *  Returns pointer to new DipoleSource. Location is
42
+             *  initialized to (0,0,0) type and polarization are
43
+             *  initialized  to nonworking values that will throw
44
+             *  exceptions if used.
45
+             */
46
+            static ReceiverCubes* New();
47
+
48
+            /**
49
+             * @copybrief LemmaObject::Delete()
50
+             * @copydetails LemmaObject::Delete()
51
+             */
52
+            void Delete();
53
+
54
+            // ====================  OPERATORS     =======================
55
+
56
+            // ====================  OPERATIONS    =======================
57
+
58
+            /** Sets the number of reciver cubes.
59
+             *  This method also resizes all the dynamic vectors in the class
60
+             *  to support this size.
61
+             *  @param[in] nrec is the number of cubes in the class.
62
+             */
63
+            void SetNumberOfReceivers(const int &nrec);
64
+
65
+            /** Sets the length of the x dimension of a single cube.
66
+             * @param[in] i is the cube number.
67
+             * @param[in] lx is the length of this cube, in this dimension.
68
+             */
69
+            void SetLengthX(const int &i, const Real &lx);
70
+
71
+            /** Sets the length of the y dimension of a single cube.
72
+             * @param[in] i is the cube number.
73
+             * @param[in] ly is the length of this cube, in this dimension.
74
+             */
75
+            void SetLengthY(const int &i, const Real &ly);
76
+
77
+            /** Sets the length of the z dimension of a single cube.
78
+             * @param[in] i is the cube number.
79
+             * @param[in] lz is the length of this cube, in this dimension.
80
+             */
81
+            void SetLengthZ(const int &i, const Real &lz);
82
+
83
+            /** Sets the lengths of all three dimensions of a single cube.
84
+             * @param[in] i is the cube number.
85
+             * @param[in] lx is the length of this cube, in this dimension.
86
+             * @param[in] ly is the length of this cube, in this dimension.
87
+             * @param[in] lz is the length of this cube, in this dimension.
88
+             */
89
+            void SetLength(const int &i, const Real& lx, const Real& ly,
90
+                            const Real &lz);
91
+
92
+            /** Sets the length of the x dimension of a single cube.
93
+             * @param[in] i is the cube number.
94
+             * @param[in] V is a vector of lenths.
95
+             */
96
+            void SetLength(const int &i, const Vector3r &V);
97
+
98
+
99
+            /** Gets the x dimension of cube i
100
+              * @param[in] i is the cube in quesion
101
+              * @return The legth of the x dimension of cube i
102
+              */
103
+            Real GetLengthX(const int &i);
104
+
105
+            /** Gets the y dimension of cube i
106
+              * @param[in] i is the cube in quesion
107
+              * @return The length of the y dimension of cube i
108
+              */
109
+            Real GetLengthY(const int &i);
110
+
111
+            /** Gets the z dimension of cube i
112
+              * @param[in] i is the cube in quesion
113
+              * @return The length of the z dimension of cube i
114
+              */
115
+            Real GetLengthZ(const int &i);
116
+
117
+            /** Gets the z dimension of cube i
118
+              * @param[in] i is the cube in quesion
119
+              * @return A vector of the lengths of the cube
120
+              */
121
+            Vector3r GetLength(const int& i);
122
+
123
+            /** Returns the volume of a cube
124
+              * @param[in] i is the cube of interest
125
+              * @return is the volume
126
+              */
127
+            Real GetVolume(const int&i);
128
+
129
+            /** Returns the volume of all the receiver cubes.
130
+              */
131
+            Real GetVolumeSum();
132
+
133
+            // ====================  ACCESS        =======================
134
+
135
+            // ====================  INQUIRY       =======================
136
+
137
+            // Returns the volume of a cube.
138
+            //Real GetCubeVolume(const int&i);
139
+            //VectorXr GetCubeVolumes();
140
+
141
+        protected:
142
+
143
+            // ====================  LIFECYCLE     =======================
144
+
145
+            /// Default protected constructor.
146
+            ReceiverCubes (const std::string &name);
147
+
148
+            /// Default protected constructor.
149
+            ~ReceiverCubes ();
150
+
151
+            /**
152
+             * @copybrief LemmaObject::Release()
153
+             * @copydetails LemmaObject::Release()
154
+             */
155
+            void Release();
156
+
157
+            // ====================  DATA MEMBERS  =========================
158
+
159
+            /// Dimension of each cube stored here, first indice is x, second y, and
160
+            /// third z
161
+            Vector3Xr Lengths;
162
+
163
+        private:
164
+
165
+    }; // -----  end of class  ReceiverCubes  -----
166
+
167
+}       // -----  end of Lemma  name  -----
168
+
169
+#endif   // ----- #ifndef RECEIVERCUBES_INC  -----

+ 281
- 0
Modules/FDEM1D/include/receiverpoints.h View File

@@ -0,0 +1,281 @@
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: receiverpoints.h 199 2014-12-29 19:25:20Z tirons $
12
+ **/
13
+
14
+#ifndef __RECEIVERPOINTS_H
15
+#define __RECEIVERPOINTS_H
16
+
17
+#ifdef LEMMAUSEVTK
18
+#include "vtkPointData.h"
19
+#include "vtkFieldData.h"
20
+#include "vtkGlyph3D.h"
21
+#include "vtkArrowSource.h"
22
+#include "vtkActor.h"
23
+#include "vtkPolyDataMapper.h"
24
+#include "vtkPoints.h"
25
+#include "vtkPolyData.h"
26
+#include "vtkDoubleArray.h"
27
+#include "vtkDataObject.h"
28
+#endif
29
+
30
+#include "LemmaObject.h"
31
+#include "dipolesource.h"
32
+
33
+#ifdef HAVE_YAMLCPP
34
+#include "yaml-cpp/yaml.h"
35
+#endif
36
+
37
+namespace Lemma {
38
+
39
+    // =======================================================================
40
+    //        Class:  ReceiverPoints
41
+    /// \brief  Points in the subsurface to make EM calculations,
42
+    ///  more general than the grids.
43
+    // =======================================================================
44
+    class ReceiverPoints : public LemmaObject {
45
+
46
+        public:
47
+
48
+            // ====================    FRIENDS     ===========================
49
+
50
+            /** Stream operator printing out information about this class.
51
+             */
52
+            friend std::ostream &operator<<(std::ostream &stream,
53
+                        const ReceiverPoints &ob);
54
+
55
+            friend class EMEarth1D;
56
+            friend class DipoleSource;
57
+
58
+            // ====================  LIFECYCLE     ===========================
59
+
60
+            /**
61
+             *  Returns pointer to new DipoleSource. Location is
62
+             *  initialized to (0,0,0) type and polarization are
63
+             *  initialized  to nonworking values that will throw
64
+             *  exceptions if used.
65
+             */
66
+            static ReceiverPoints* New();
67
+
68
+
69
+            /**
70
+             * @copybrief LemmaObject::Delete()
71
+             * @copydetails LemmaObject::Delete()
72
+             */
73
+            void Delete();
74
+
75
+            // ====================  OPERATORS     ===========================
76
+
77
+            // ====================  OPERATIONS    ===========================
78
+
79
+            // ====================  ACCESS        ===========================
80
+
81
+            /// Sets the number of receivers
82
+            virtual void SetNumberOfReceivers(const int &nrec);
83
+
84
+            /// Returns the location of a single receiver as an Eigen Vector
85
+            void SetLocation(const int& nrec, const Vector3r& loc);
86
+
87
+            /// Returns the location of a single receiver as an Eigen Vector
88
+            void SetLocation(const int& nrec, const Real& xp, const Real& yp,
89
+                            const Real& zp);
90
+
91
+            // ====================  INQUIRY       ===========================
92
+
93
+            /// Returns the number of receiverpoints.
94
+            int GetNumberOfReceivers();
95
+
96
+            /// Returns all the receiver locations as a 3 X matrix
97
+            Vector3Xr GetLocations();
98
+
99
+            /// Returns all the receiver locations as a general matrix, useful for python wrapper
100
+            MatrixXr GetLocationsMat();
101
+
102
+            /// Returns the E field for all locations
103
+            /// nfreq is the freqency desired
104
+            Vector3Xcr GetEfield(const int &nfreq);
105
+
106
+            /// Returns the E field for all locations
107
+            /// nfreq is the freqency desired, cast to general dynamic matrix, for python interoperability
108
+            MatrixXcr GetEfieldMat(const int &nfreq);
109
+
110
+            /// Returns the H field for all locations
111
+            /// nfreq is the freqency desired, cast to general dynamic matrix, for python interoperability
112
+            MatrixXcr GetHfieldMat(const int &nfreq);
113
+
114
+            /// Returns the H field for all locations
115
+            /// nfreq is the freqency desired
116
+            Vector3Xcr GetHfield(const int &nfreq);
117
+
118
+            /// Returns all of the computed H fields. Every frequency
119
+            std::vector<Vector3Xcr> GetHfield( );
120
+
121
+            /// Returns all of the computed E fields. Every frequency
122
+            std::vector<Vector3Xcr> GetEfield( );
123
+
124
+            /// Returns the E field of a single receiver as an Eigen Vector
125
+            /// nfreq is the freqency desired
126
+            Vector3cr GetEfield(const int &nfreq, const int& loc);
127
+
128
+            /// Returns the H field of a single receiver as an Eigen Vector
129
+            /// nfreq is the freqency desired
130
+            Vector3cr GetHfield(const int &nfreq, const int& loc);
131
+
132
+            /// Returns the B field of a single receiver as an Eigen Vector
133
+            /// nfreq is the freqency desired
134
+            Vector3cr GetBfield(const int &nfreq, const int& loc);
135
+
136
+            #ifdef LEMMAUSEVTK
137
+            /// Returns vtk Glyph actor that can be placed into scenes
138
+            vtkActor* GetVtkGlyphActor(const FIELDTYPE &ftype,
139
+                const Real& clip, const Real &scale,
140
+                const int &nfreq);
141
+
142
+            /// Returns a vtk Data Object that can easily be plotted
143
+            vtkDataObject * GetVtkDataObject(const FIELDTYPE &ftype,
144
+                const int& nbin,
145
+                const int& start, const int& end,
146
+                const FIELDCOMPONENT& fcomp,
147
+                const SPATIALCOORDINANT& scord);
148
+
149
+            /// Returns a vtk Data Object that can easily be plotted
150
+            vtkDataObject * GetVtkDataObjectFreq(const FIELDTYPE &ftype,
151
+                const int& nrec,
152
+                const int& fstart, const int& fend,
153
+                const FIELDCOMPONENT& fcomp,
154
+                const VectorXr& Freqs);
155
+            #endif
156
+
157
+            /// Returns the location of a single receiver as an Eigen Vector
158
+            Vector3r GetLocation(const int& loc);
159
+
160
+            /// Returns the x component of the location
161
+            Real GetLocationX(const int& loc);
162
+
163
+            /// Returns the y component of the location
164
+            Real GetLocationY(const int& loc);
165
+
166
+            /// Returns the z component of the location
167
+            Real GetLocationZ(const int& loc);
168
+
169
+            /// Resets fields
170
+            void ClearFields();
171
+
172
+            /// Sets the mask variable to true for this point.
173
+            void MaskPoint(const int& i);
174
+
175
+            /// Turns the mask off for this point.
176
+            void UnMaskPoint(const int& i);
177
+
178
+            /// Removes making on all points
179
+            void UnMaskAllPoints();
180
+
181
+            /// Returns the mask for this point
182
+            int GetMask(const int& i);
183
+
184
+            #ifdef HAVE_YAMLCPP
185
+        	/**
186
+             *  Uses YAML to serialize this object.
187
+             *  @return a YAML::Node
188
+             */
189
+            YAML::Node Serialize() const;
190
+
191
+            /**
192
+             *   Constructs an object from a YAML::Node.
193
+             */
194
+            static ReceiverPoints* DeSerialize(const YAML::Node& node);
195
+            #endif
196
+
197
+        protected:
198
+
199
+            // ====================  LIFECYCLE     ===========================
200
+
201
+            /// Default protected constructor.
202
+            ReceiverPoints (const std::string& name);
203
+
204
+            #ifdef HAVE_YAMLCPP
205
+            /// Default protected constructor.
206
+            ReceiverPoints (const YAML::Node& node);
207
+            #endif
208
+
209
+            /// Default protected constructor.
210
+            ~ReceiverPoints ();
211
+
212
+            /**
213
+             * @copybrief LemmaObject::Release()
214
+             * @copydetails LemmaObject::Release()
215
+             */
216
+            void Release();
217
+
218
+            // ====================  OPERATIONS    ===========================
219
+
220
+            /// Sets the number of H bins. These bins are often frequencies.
221
+            void SetNumberOfBinsH(const int& nbins);
222
+
223
+            /// Sets the number of E bins. These bins are often frequencies.
224
+            void SetNumberOfBinsE(const int& nbins);
225
+
226
+            /** Internal function that resizes the EField data structure */
227
+            void ResizeEField();
228
+
229
+            /** Internal function that resizes the HField data structure */
230
+            void ResizeHField();
231
+
232
+            /// Sets the value of the E field
233
+            void SetEfield(const int &nfreq, const int& loc,
234
+                const Complex &ex, const Complex &ey, const Complex &ez);
235
+
236
+            /// Sets the value of the H field
237
+            void SetHfield(const int &nfreq, const int& loc,
238
+                const Complex &hx, const Complex &hy, const Complex &hz);
239
+
240
+            /// Appends the value of the E field. This method is not
241
+            /// thread safe.
242
+            void AppendEfield(const int&nfreq, const int& loc,
243
+                const Complex &ex, const Complex &ey, const Complex &ez);
244
+
245
+            /// Appends the value of the H field. This method is not
246
+            /// thread safe.
247
+            void AppendHfield(const int &nfreq, const int& loc,
248
+                const Complex &hx, const Complex &hy, const Complex &hz);
249
+
250
+            // ====================  DATA MEMBERS  ===========================
251
+
252
+            /// Number of receivers
253
+            int                         NumberOfReceivers;
254
+
255
+            /// Number of fields
256
+            int                         NumberOfBinsE;
257
+
258
+            /// Number of fields
259
+            int                         NumberOfBinsH;
260
+
261
+            /// Used to mask this point so no computation is made at
262
+            /// this point.
263
+            VectorXi                    Mask;
264
+
265
+            /// Locations of receivers
266
+            Vector3Xr                   Locations;
267
+
268
+        private:
269
+
270
+            // NOTE, these are not serialized in output!
271
+
272
+            /// Electric field at receiver locations
273
+            std::vector<Vector3Xcr>     Efield;
274
+
275
+            /// H field at receiver locations
276
+            std::vector<Vector3Xcr>     Hfield;
277
+
278
+    }; // -----  end of class  ReceiverPoints  -----
279
+}
280
+
281
+#endif // __RECEIVERPOINTS

+ 97
- 0
Modules/FDEM1D/include/sintransintegrationkernel.h View File

@@ -0,0 +1,97 @@
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     02/08/2011
11
+  @version  $Id: sintransintegrationkernel.h 87 2013-09-05 22:44:05Z tirons $
12
+ **/
13
+
14
+#ifndef  SINTRANSINTEGRATIONKERNEL_INC
15
+#define  SINTRANSINTEGRATIONKERNEL_INC
16
+
17
+#include "integrationkernel.h"
18
+
19
+namespace Lemma {
20
+
21
+    // ===================================================================
22
+    //  Class:  SinTransIntegrationKernel
23
+    /**
24
+      @class
25
+      \brief    Integration kernel for testing sinine transform.
26
+      \details  Evaluates sinine at the argument, using lagged convolution.
27
+                all of these kernels have exact solutions.
28
+     */
29
+    // ===================================================================
30
+    class SinTransIntegrationKernel : public IntegrationKernel<Real> {
31
+
32
+        public:
33
+
34
+            // ====================  LIFECYCLE     =======================
35
+
36
+            /** Returns a pointer to a new object of type SinTransIntegrationKernel.
37
+             * It allocates all necessary memory.
38
+             */
39
+            static SinTransIntegrationKernel* New();
40
+
41
+            /** Deletes this object. Delete also disconnects any
42
+             * attachments to this object.
43
+             */
44
+            void Delete();
45
+
46
+            // ====================  OPERATORS     =======================
47
+
48
+            Real Argument(const Real&x, const int& iRelated);
49
+
50
+            int GetNumRel();
51
+
52
+            /// Sets the value 'A' used in test cases
53
+            void SetA(const Real& A);
54
+
55
+            /** Sets the integral to evaluate (1, 2, 3)
56
+             */
57
+            void SetIntegral(const int& i);
58
+
59
+            /** Returns the analytical answer at A and B */
60
+            Real GetAnalytical(const Real& B);
61
+            // ====================  OPERATIONS    =======================
62
+
63
+            // ====================  ACCESS        =======================
64
+
65
+            // ====================  INQUIRY       =======================
66
+
67
+        protected:
68
+
69
+            // ====================  LIFECYCLE     =======================
70
+
71
+            /** Deletes this object. Delete also disconnects any
72
+             * attachments to this object.
73
+             */
74
+            void Release();
75
+
76
+            /// Default protected constructor.
77
+            SinTransIntegrationKernel (const std::string& name);
78
+
79
+            /// Default protected constructor.
80
+            ~SinTransIntegrationKernel ();
81
+
82
+            // ====================  DATA MEMBERS  =========================
83
+
84
+            /** Value used in test cases  */
85
+            Real A;
86
+
87
+            /** Test integral to evaluate */
88
+            int Integral;
89
+
90
+        private:
91
+
92
+    }; // -----  end of class  SinTransIntegrationKernel  -----
93
+
94
+
95
+}		// -----  end of Lemma  name  -----
96
+
97
+#endif   // ----- #ifndef SINTRANSINTEGRATIONKERNEL_INC  -----

+ 359
- 0
Modules/FDEM1D/src/FHTKey.cpp View File

@@ -0,0 +1,359 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      02/11/2014 03:42:53 PM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#include "FHTKey.h"
21
+
22
+namespace Lemma {
23
+
24
+    // ====================  FRIEND METHODS  =====================
25
+
26
+    std::ostream &operator<<(std::ostream &stream, const FHTKey &ob) {
27
+
28
+        stream << *(HankelTransform*)(&ob);
29
+
30
+        return stream;
31
+    }
32
+
33
+
34
+    // ====================  STATIC CONST MEMBERS     ============
35
+
36
+    const Eigen::Matrix<Real, 201, 3>  FHTKey::WT201 =
37
+        ( Eigen::Matrix<Real, 201, 3>()   <<
38
+        // Base                   J0                      J1
39
+          4.1185887075357082e-06, 1.5020099209519960e-03, 4.7827871332506182e-10
40
+        , 4.6623077830484039e-06,-1.0381698214761684e-02,-2.9784175503440788e-09
41
+        , 5.2778064058937756e-06, 3.6840860097595164e-02, 9.7723832770897220e-09
42
+        , 5.9745606155328603e-06,-8.9903380392274704e-02,-2.2382340996085809e-08
43
+        , 6.7632974390298035e-06, 1.7082286536833860e-01, 4.0446774329470848e-08
44
+        , 7.6561600412698171e-06,-2.7115749656836280e-01,-6.1734815854553919e-08
45
+        , 8.6668946776271221e-06, 3.7649328091859574e-01, 8.3293912185608189e-08
46
+        , 9.8110623273521872e-06,-4.7220778569122657e-01,-1.0249453502284080e-07
47
+        , 1.1106278265924788e-05, 5.4778211089647089e-01, 1.1780779749909977e-07
48
+        , 1.2572483264760042e-05,-5.9823516853035097e-01,-1.2870061460834850e-07
49
+        , 1.4232250593579901e-05, 6.2345791612185331e-01, 1.3559243438349901e-07
50
+        , 1.6111133551969887e-05,-6.2650436648257724e-01,-1.3921010821521872e-07
51
+        , 1.8238058880617237e-05, 6.1197225351173345e-01, 1.4065745722769670e-07
52
+        , 2.0645772109076137e-05,-5.8470173866140451e-01,-1.4074881908375281e-07
53
+        , 2.3371341696506312e-05, 5.4911055789616858e-01, 1.4051720878600928e-07
54
+        , 2.6456729726989950e-05,-5.0878861684860843e-01,-1.4040746687777830e-07
55
+        , 2.9949437945688260e-05, 4.6652106345430200e-01, 1.4127886061686993e-07
56
+        , 3.3903239082024059e-05,-4.2426478870289325e-01,-1.4315595655055356e-07
57
+        , 3.8379004719130766e-05, 3.8339538911933357e-01, 1.4689283208027915e-07
58
+        , 4.3445642455208216e-05,-3.4472344791723936e-01,-1.5210916706348747e-07
59
+        , 4.9181156785051293e-05, 3.0876891466890510e-01, 1.5989801550138741e-07
60
+        , 5.5673850034776868e-05,-2.7570439368364807e-01,-1.6940918407911260e-07
61
+        , 6.3023681838995322e-05, 2.4562331000974616e-01, 1.8227089415749844e-07
62
+        , 7.1343808090545215e-05,-2.1839207265400126e-01,-1.9695856878603369e-07
63
+        , 8.0762323056016586e-05, 1.9393194321380827e-01, 2.1603952427106760e-07
64
+        , 9.1424231478173270e-05,-1.7198162962644575e-01,-2.3691320619292838e-07
65
+        , 1.0349368102719458e-04, 1.5242270280410272e-01, 2.6369843208466607e-07
66
+        , 1.1715648947091054e-04,-1.3494945901825492e-01,-2.9202021404039016e-07
67
+        , 1.3262300547161834e-04, 1.1946763189654602e-01, 3.2852445086324662e-07
68
+        , 1.5013134705348249e-04,-1.0565870880444576e-01,-3.6589094553627693e-07
69
+        , 1.6995106759902750e-04, 9.3482355548033913e-02, 4.1487501036863030e-07
70
+        , 1.9238730581535294e-04,-8.2612525279836244e-02,-4.6327136995173986e-07
71
+        , 2.1778548356175115e-04, 7.3077763526174969e-02, 5.2852697369750518e-07
72
+        , 2.4653662386513240e-04,-6.4536481281701225e-02,-5.9034983719954077e-07
73
+        , 2.7908337099788406e-04, 5.7096310621587334e-02, 6.7710211611560898e-07
74
+        , 3.1592680530155527e-04,-5.0384859605213800e-02,-7.5512942807901028e-07
75
+        , 3.5763415767542709e-04, 4.4599557396733047e-02, 8.7062473466409799e-07
76
+        , 4.0484754250000483e-04,-3.9316995063444334e-02,-9.6788530918130449e-07
77
+        , 4.5829384344501882e-04, 3.4838544754296139e-02, 1.1222658353725904e-06
78
+        , 5.1879590436097246e-04,-3.0664946477420088e-02,-1.2417228058919743e-06
79
+        , 5.8728519754599128e-04, 2.7221072240291456e-02, 1.4493467036899140e-06
80
+        , 6.6481616442494776e-04,-2.3901586108434601e-02,-1.5932456559208080e-06
81
+        , 7.5258244942583781e-04, 2.1281566646364738e-02, 1.8747045814274419e-06
82
+        , 8.5193527698548301e-04,-1.8612484595521447e-02,-2.0433320340041385e-06
83
+        , 9.6440425461164468e-04, 1.6655386303461400e-02, 2.4285695351967146e-06
84
+        , 1.0917209222795108e-03,-1.4472420076504743e-02,-2.6179926456520528e-06
85
+        , 1.2358454107222641e-03, 1.3057747649606617e-02, 3.1511729661391781e-06
86
+        , 1.3989966190390965e-03,-1.1226286001060300e-02,-3.3492412032881268e-06
87
+        , 1.5836863762264436e-03, 1.0266818557930830e-02, 4.0964186613549959e-06
88
+        , 1.7927581125735061e-03,-8.6738022421653585e-03,-4.2758275751239154e-06
89
+        , 2.0294306362957340e-03, 8.1103368670848164e-03, 5.3371197552207799e-06
90
+        , 2.2973476893787268e-03,-6.6573628142085938e-03,-5.4435423773626499e-06
91
+        , 2.6006340455800008e-03, 6.4551189810889585e-03, 6.9725766921672099e-06
92
+        , 2.9439590142573526e-03,-5.0524015117839084e-03,-6.9045562968161745e-06
93
+        , 3.3326083277104117e-03, 5.1989014270506263e-03, 9.1397025436977438e-06
94
+        , 3.7725655187922052e-03,-3.7597430078747883e-03,-8.7148373033635960e-06
95
+        , 4.2706040416570154e-03, 4.2640545165292636e-03, 1.2029590806160379e-05
96
+        , 4.8343915539089625e-03,-2.6994965688974474e-03,-1.0927976968519436e-05
97
+        , 5.4726079656493079e-03, 3.5928000560587229e-03, 1.5912526719455299e-05
98
+        , 6.1950790728715292e-03,-1.8061291289989019e-03,-1.3582559661331659e-05
99
+        , 7.0129278325854246e-03, 3.1436470898586703e-03, 2.1176226828087565e-05
100
+        , 7.9387456086585442e-03,-1.0244200001620755e-03,-1.6678205993448338e-05
101
+        , 8.9867860248264830e-03, 2.8888297674091743e-03, 2.8384979250408712e-05
102
+        , 1.0173184409377162e-02,-3.0605070741955765e-04,-2.0132088397797457e-05
103
+        , 1.1516206210016314e-02, 2.8125907445050334e-03, 3.8372045311188108e-05
104
+        , 1.3036528203437736e-02, 3.9337862066047565e-04,-2.3702184335455945e-05
105
+        , 1.4757556829019875e-02, 2.9102041487017727e-03, 5.2385308850007940e-05
106
+        , 1.6705788547622769e-02, 1.1170884769911178e-03,-2.6854373943701261e-05
107
+        , 1.8911217773465227e-02, 3.1876763415953362e-03, 7.2318581557902158e-05
108
+        , 2.1407798659484324e-02, 1.9097806429850762e-03,-2.8535361884516687e-05
109
+        , 2.4233967845691123e-02, 3.6621020321465411e-03, 1.0108123118106823e-04
110
+        , 2.7433236218606032e-02, 2.8203783587849949e-03,-2.6788477540644352e-05
111
+        , 3.1054858792331431e-02, 4.3626885599390430e-03, 1.4319185407094621e-04
112
+        , 3.5154593024557458e-02, 3.9050024915686802e-03,-1.8108424211338017e-05
113
+        , 3.9795557242315927e-02, 5.3324923486866077e-03, 2.0573561552327273e-04
114
+        , 4.5049202393557801e-02, 5.2303399394270488e-03, 3.6361648565843316e-06
115
+        , 5.0996412085361466e-02, 6.6309348458396984e-03, 2.9991264692859609e-04
116
+        , 5.7728747844643331e-02, 6.8775540687037451e-03, 4.8993332079278846e-05
117
+        , 6.5349858773045680e-02, 8.3371689988226087e-03, 4.4354733854670903e-04
118
+        , 7.3977077298642363e-02, 8.9468564745410102e-03, 1.3589101811995494e-04
119
+        , 8.3743225592195963e-02, 1.0554326601376745e-02, 6.6515823521273764e-04
120
+        , 9.4798660459030126e-02, 1.1562765604509096e-02, 2.9451991608624389e-04
121
+        , 1.0731358818908403e-01, 1.3414536265660639e-02, 1.0105553806271136e-03
122
+        , 1.2148068500391276e-01, 1.4879837399735491e-02, 5.7533964792254050e-04
123
+        , 1.3751806344428075e-01, 1.7084241336519569e-02, 1.5535077418254303e-03
124
+        , 1.5567263036799733e-01, 1.9088092654441269e-02, 1.0621193133794828e-03
125
+        , 1.7622388825676111e-01, 2.1768513715084332e-02, 2.4128970258747457e-03
126
+        , 1.9948823835583873e-01, 2.4416120601223806e-02, 1.8929698186109245e-03
127
+        , 2.2582385189647586e-01, 2.7711234465350204e-02, 3.7800177772191607e-03
128
+        , 2.5563618439697788e-01, 3.1127164234404547e-02, 3.2937343278959356e-03
129
+        , 2.8938421793905067e-01, 3.5184140220277452e-02, 5.9612179800391544e-03
130
+        , 3.2758752752368947e-01, 3.9497913113638941e-02, 5.6295935320552241e-03
131
+        , 3.7083428029819565e-01, 4.4449762157204989e-02, 9.4422526803168080e-03
132
+        , 4.1979029080811425e-01, 4.9758433269983887e-02, 9.4810228247137925e-03
133
+        , 4.7520927168614446e-01, 5.5667457114992429e-02, 1.4979159139973408e-02
134
+        , 5.3794443759467447e-01, 6.1949790434151823e-02, 1.5745093424331037e-02
135
+        , 6.0896164107289685e-01, 6.8682064905571841e-02, 2.3708966370000140e-02
136
+        , 6.8935424252422239e-01, 7.5616743950118387e-02, 2.5740590762136872e-02
137
+        , 7.8035994327803426e-01, 8.2584983563572259e-02, 3.7232782843117498e-02
138
+        , 8.8337984088275090e-01, 8.9193635262987042e-02, 4.1225008900614292e-02
139
+        , 1.0000000000000000e+00, 9.4874686942005279e-02, 5.7507103212277359e-02
140
+        , 1.1320158709991752e+00, 9.8891681869094042e-02, 6.4044642846235691e-02
141
+        , 1.2814599321940212e+00, 1.0004294654495730e-01, 8.6091796551857253e-02
142
+        , 1.4506329812931589e+00, 9.7016844329802857e-02, 9.4717139804457451e-02
143
+        , 1.6421395578187052e+00, 8.7789596149914384e-02, 1.2172497389177185e-01
144
+        , 1.8589280418463421e+00, 7.0509767592855419e-02, 1.2853597000398900e-01
145
+        , 2.1043360464154781e+00, 4.2778853484849347e-02, 1.5450777327408322e-01
146
+        , 2.3821418024579781e+00, 3.5584532926218175e-03, 1.4755964090969320e-01
147
+        , 2.6966223273530128e+00,-4.7210453264879347e-02, 1.5621399202016978e-01
148
+        , 3.0526192726543444e+00,-1.0489787743225988e-01, 1.1147620703185755e-01
149
+        , 3.4556134647626755e+00,-1.6020950407348281e-01, 7.7489831356083380e-02
150
+        , 3.9118092861497971e+00,-1.9459781573132096e-01,-2.7628266850147711e-02
151
+        , 4.4282301962435247e+00,-1.8490774599542381e-01,-1.0198730178317840e-01
152
+        , 5.0128268625854631e+00,-1.0754165020025190e-01,-2.2039889971111640e-01
153
+        , 5.6745995670177445e+00, 3.6037727487476613e-02,-2.1185762869925318e-01
154
+        , 6.4237367714291338e+00, 1.9759013047489976e-01,-1.6052415083152241e-01
155
+        , 7.2717719763787807e+00, 2.6132313321851336e-01, 9.1649025798681089e-02
156
+        , 8.2317612875478190e+00, 1.1713996822458939e-01, 2.3792823877700942e-01
157
+        , 9.3184844237807365e+00,-1.8758779281301441e-01, 2.6075777853738125e-01
158
+        , 1.0548672261378394e+01,-3.0238114997462151e-01,-1.5662188259001042e-01
159
+        , 1.1941264417849103e+01, 4.8163135684567732e-02,-2.8932081756330175e-01
160
+        , 1.3517700840802913e+01, 3.6399529664885466e-01, 1.3148519116247689e-02
161
+        , 1.5302251891207787e+01,-1.4910233461562913e-01, 4.2691302759079564e-01
162
+        , 1.7322392002874359e+01,-2.6373490348543854e-01,-4.0005050006489040e-01
163
+        , 1.9609222670922968e+01, 4.0362661807718703e-01, 1.1513789407450359e-01
164
+        , 2.2197951281441636e+01,-3.1409794650104578e-01, 9.3748244358717620e-02
165
+        , 2.5128433154258410e+01, 1.8179369405131079e-01,-1.6037231301955096e-01
166
+        , 2.8445785143962375e+01,-9.0738718042631769e-02, 1.5071857939129532e-01
167
+        , 3.2201080245997971e+01, 4.2946487545160242e-02,-1.2120369075996129e-01
168
+        , 3.6452133901787732e+01,-2.0586135807067835e-02, 9.4110656079982341e-02
169
+        , 4.1264394108610787e+01, 1.0392667161913182e-02,-7.3742238434584328e-02
170
+        , 4.6711949038112273e+01,-5.6117848068723023e-03, 5.9038567576124905e-02
171
+        , 5.2878667676447755e+01, 3.2402025511569896e-03,-4.8288117528475852e-02
172
+        , 5.9859491047029913e+01,-1.9858724388273777e-03, 4.0197054299576880e-02
173
+        , 6.7761893895170928e+01, 1.2807317326135252e-03,-3.3919787720641081e-02
174
+        , 7.6707539338295589e+01,-8.6253791756068252e-04, 2.8918247156763971e-02
175
+        , 8.6834151956244213e+01, 6.0296590782143555e-04,-2.4845271759013743e-02
176
+        , 9.8297638159222487e+01,-4.3548936996943465e-04, 2.1470449751150148e-02
177
+        , 1.1127448647797397e+02, 3.2375891570874245e-04,-1.8635828020057092e-02
178
+        , 1.2596448473034971e+02,-2.4698212240059978e-04, 1.6229579362363859e-02
179
+        , 1.4259379589698909e+02, 1.9279062274925971e-04,-1.4170085406786529e-02
180
+        , 1.6141844006140866e+02,-1.5357911509105972e-04, 1.2396084121011890e-02
181
+        , 1.8272823602144376e+02, 1.2453787849367440e-04,-1.0860414401084047e-02
182
+        , 2.0685126325595743e+02,-1.0255126402954421e-04, 9.5259444245356633e-03
183
+        , 2.3415891294197226e+02, 8.5558482209476271e-05,-8.3628577447233381e-03
184
+        , 2.6507160578622688e+02,-7.2170928476334345e-05, 7.3468029551253195e-03
185
+        , 3.0006526470124555e+02, 6.1436863283080017e-05,-6.4576043210966359e-03
186
+        , 3.3967864197737873e+02,-5.2693349406473615e-05, 5.6783439955994880e-03
187
+        , 3.8452161375783919e+02, 4.5471255142623729e-05,-4.9946949167265437e-03
188
+        , 4.3528456951608860e+02,-3.9433284158653591e-05, 4.3944258108608806e-03
189
+        , 4.9274904109325632e+02, 3.4332971164795619e-05,-3.8670264019660858e-03
190
+        , 5.5779973493719069e+02,-2.9987212220165472e-05, 3.4034180355556670e-03
191
+        , 6.3143815278803334e+02, 2.6257657435614391e-05,-2.9957260668529964e-03
192
+        , 7.1479801051045558e+02,-2.3037978256349448e-05, 2.6370977166248776e-03
193
+        , 8.0916269245647072e+02, 2.0245071331016652e-05,-2.3215540117372982e-03
194
+        , 9.1598501008114988e+02,-1.7812925644382519e-05, 2.0438677474690805e-03
195
+        , 1.0369095690092008e+03, 1.5688305607849465e-05,-1.7994616759226389e-03
196
+        , 1.1737980889093292e+03,-1.3827679492110470e-05, 1.5843226896713463e-03
197
+        , 1.3287580659938624e+03, 1.2195005442258958e-05,-1.3949288614414647e-03
198
+        , 1.5041752194232211e+03,-1.0760110818279243e-05, 1.2281869708886250e-03
199
+        , 1.7027502211507524e+03, 9.4974857670959145e-06,-1.0813786997088304e-03
200
+        , 1.9275402746900081e+03,-8.3853711343938338e-06, 9.5211407460757294e-04
201
+        , 2.1820061829391980e+03, 7.4050612540713192e-06,-8.3829103020448140e-04
202
+        , 2.4700656297055034e+03,-6.5403682860228500e-06, 7.3806018220987763e-04
203
+        , 2.7961534952362003e+03, 5.7772102413267325e-06,-6.4979406671247244e-04
204
+        , 3.1652901343571971e+03,-5.1032933218796731e-06, 5.7206022901230412e-04
205
+        , 3.5831586684094545e+03, 4.5078641320869195e-06,-5.0359764543483573e-04
206
+        , 4.0561924809477755e+03,-3.9815111951817114e-06, 4.4329604122300101e-04
207
+        , 4.5916742642604040e+03, 3.5159993210292339e-06,-3.9017773206623073e-04
208
+        , 5.1978481416012310e+03,-3.1041249680128287e-06, 3.4338166974098888e-04
209
+        , 5.8840465913361650e+03, 2.7395854235553632e-06,-3.0214941633163506e-04
210
+        , 6.6608341270911405e+03,-2.4168587823583312e-06, 2.6581280850704716e-04
211
+        , 7.5401699459601114e+03, 2.1310948134441218e-06,-2.3378310479588391e-04
212
+        , 8.5355920488578286e+03,-1.8780185742021288e-06, 2.0554143583887405e-04
213
+        , 9.6624256676814348e+03, 1.6538488252707735e-06,-1.8063040107732216e-04
214
+        , 1.0938019208165191e+04,-1.4552318768651144e-06, 1.5864667598176302e-04
215
+        , 1.2382011340936813e+04, 1.2791890865306748e-06,-1.3923451235168759e-04
216
+        , 1.4016633352832258e+04,-1.1230741959148155e-06, 1.2208003098625932e-04
217
+        , 1.5867051413382505e+04, 9.8453630538596172e-07,-1.0690622166177854e-04
218
+        , 1.7961754025908867e+04,-8.6148574493190796e-07, 9.3468580362568137e-05
219
+        , 2.0332990628312182e+04, 7.5206242699701732e-07,-8.1551328581234316e-05
220
+        , 2.3017268096126892e+04,-6.5460810334682633e-07, 7.0964174631531072e-05
221
+        , 2.6055912791858576e+04, 5.6764451596029765e-07,-6.1539592468666665e-05
222
+        , 2.9495706813754354e+04,-4.8985884555184997e-07, 5.3130609116145443e-05
223
+        , 3.3389608239508460e+04, 4.2009674106879252e-07,-4.5609105983126460e-05
224
+        , 3.7797566453568354e+04,-3.5736212641225517e-07, 3.8864648584181207e-05
225
+        , 4.2787445110585410e+04, 3.0082215969939671e-07,-3.2803856352344075e-05
226
+        , 4.8436066944688770e+04,-2.4981510481639669e-07, 2.7350296775876261e-05
227
+        , 5.4830396510166145e+04, 2.0385823466866512e-07,-2.2444816150805301e-05
228
+        , 6.2068879062685897e+04,-1.6265189071584773e-07, 1.8046076281584239e-05
229
+        , 7.0262956194088882e+04, 1.2607416700611311e-07,-1.4130826937491561e-05
230
+        , 7.9538781555028458e+04,-9.4158417913450858e-08, 1.0693106849359383e-05
231
+        , 9.0039163080228551e+04, 6.7043911217063425e-08,-7.7412053314530284e-06
232
+        , 1.0192576161830177e+05,-4.4891090827293947e-08, 5.2910576443698300e-06
233
+        , 1.1538157981559623e+05, 2.7761325666544702e-08,-3.3552268362550323e-06
234
+        , 1.3061377957221285e+05,-1.5480404355710375e-08, 1.9282956206367452e-06
235
+        , 1.4785687144693290e+05, 7.5327300141098751e-09,-9.7253712572058755e-07
236
+        , 1.6737632511421290e+05,-3.0524770418657847e-09, 4.1100807632959352e-07
237
+        , 1.8947265645880660e+05, 9.5877856096830783e-10,-1.3553176263207053e-07
238
+        , 2.1448605423174356e+05,-2.0575286298055636e-10, 3.0748587523233524e-08
239
+        , 2.4280161749832361e+05, 2.2414416956474645e-11,-3.5668195345476294e-09 ).finished();
240
+
241
+    // ====================  LIFECYCLE     =======================
242
+
243
+    //--------------------------------------------------------------------------------------
244
+    //       Class:  FHTKey
245
+    //      Method:  FHTKey
246
+    // Description:  constructor (protected)
247
+    //--------------------------------------------------------------------------------------
248
+    FHTKey::FHTKey (const std::string& name) : HankelTransform(name) {
249
+
250
+    }  // -----  end of method FHTKey::FHTKey  (constructor)  -----
251
+
252
+
253
+    //--------------------------------------------------------------------------------------
254
+    //       Class:  FHTKey
255
+    //      Method:  New()
256
+    // Description:  public constructor
257
+    //--------------------------------------------------------------------------------------
258
+    FHTKey* FHTKey::New() {
259
+        FHTKey*  Obj = new FHTKey("FHTKey");
260
+        Obj->AttachTo(Obj);
261
+        return Obj;
262
+    }
263
+
264
+    //--------------------------------------------------------------------------------------
265
+    //       Class:  FHTKey
266
+    //      Method:  ~FHTKey
267
+    // Description:  destructor (protected)
268
+    //--------------------------------------------------------------------------------------
269
+    FHTKey::~FHTKey () {
270
+
271
+    }  // -----  end of method FHTKey::~FHTKey  (destructor)  -----
272
+
273
+    //--------------------------------------------------------------------------------------
274
+    //       Class:  FHTKey
275
+    //      Method:  Delete
276
+    // Description:  public destructor
277
+    //--------------------------------------------------------------------------------------
278
+    void FHTKey::Delete() {
279
+        this->DetachFrom(this);
280
+    }
281
+
282
+    //--------------------------------------------------------------------------------------
283
+    //       Class:  FHTKey
284
+    //      Method:  Release
285
+    // Description:  destructor (protected)
286
+    //--------------------------------------------------------------------------------------
287
+    void FHTKey::Release() {
288
+        delete this;
289
+    }
290
+
291
+
292
+    //--------------------------------------------------------------------------------------
293
+    //       Class:  FHTKey
294
+    //      Method:  Zgauss
295
+    //--------------------------------------------------------------------------------------
296
+    Complex FHTKey::Zgauss ( const int &ikk, const EMMODE &imode,
297
+                            const int &itype, const Real &rho,
298
+                            const Real &wavef, KernelEm1DBase *Kernel ) {
299
+ 		return Zans(0, Kernel->GetManagerIndex());
300
+    }		// -----  end of method FHTKey::ComputeRelated  -----
301
+
302
+
303
+    //--------------------------------------------------------------------------------------
304
+    //       Class:  FHTKey
305
+    //      Method:  ComputeRelated
306
+    //--------------------------------------------------------------------------------------
307
+    void FHTKey::ComputeRelated ( const Real& rho, KernelEm1DBase* Kernel ) {
308
+        return ;
309
+    }		// -----  end of method FHTKey::ComputeRelated  -----
310
+
311
+    //--------------------------------------------------------------------------------------
312
+    //       Class:  FHTKey
313
+    //      Method:  ComputeRelated
314
+    //--------------------------------------------------------------------------------------
315
+    void FHTKey::ComputeRelated ( const Real& rho, std::vector< KernelEm1DBase* > KernelVec ) {
316
+        return ;
317
+    }		// -----  end of method FHTKey::ComputeRelated  -----
318
+
319
+    //--------------------------------------------------------------------------------------
320
+    //       Class:  FHTKey
321
+    //      Method:  ComputeRelated
322
+    //--------------------------------------------------------------------------------------
323
+    void FHTKey::ComputeRelated ( const Real& rho, KernelEM1DManager* KernelManager ) {
324
+
325
+        //kernelVec = KernelManager->GetSTLVector();
326
+        int nrel = (int)(KernelManager->GetSTLVector().size());
327
+        Eigen::Matrix<Complex, 201, Eigen::Dynamic > Zwork;
328
+        // TODO, if we want to allow lagged, then 1 below should be nlag
329
+        Zans= Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic>::Zero(1, nrel);
330
+        Zwork.resize(201, nrel);
331
+        VectorXr lambda = WT201.col(0).array()/rho;
332
+        int NumFun = 0;
333
+        int idx = 0;
334
+
335
+        // Get Kernel values
336
+        for (int ir=0; ir<lambda.size(); ++ir) {
337
+            // irelated loop
338
+            ++NumFun;
339
+            KernelManager->ComputeReflectionCoeffs(lambda(ir), idx, rho);
340
+            for (int ir2=0; ir2<nrel; ++ir2) {
341
+                // Zwork* needed due to sign convention of filter weights
342
+ 			    Zwork(ir, ir2) = std::conj(KernelManager->GetSTLVector()[ir2]->RelBesselArg(lambda(ir)));
343
+            }
344
+
345
+        }
346
+
347
+        // We diverge slightly from Key here, each kernel is evaluated seperately, whereby instead
348
+        // they prefer to sum them. The reason is that all those terms have been removed from the kernels
349
+        // in the interests of making them as generic and reusable as possible. This approach requires slightly
350
+        // more multiplies, but the same number of kernel evaluations, which is the expensive part.
351
+        // Inner product and scale
352
+        for (int ir2=0; ir2<nrel; ++ir2) {
353
+            Zans(0, ir2) = Zwork.col(ir2).dot(WT201.col(KernelManager->GetSTLVector()[ir2]->GetBesselOrder() + 1))/rho;
354
+        }
355
+
356
+        return ;
357
+    }		// -----  end of method FHTKey::ComputeRelated  -----
358
+
359
+}		// -----  end of Lemma  name  -----

+ 259
- 0
Modules/FDEM1D/src/FHTKey101.cpp View File

@@ -0,0 +1,259 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      02/11/2014 03:42:53 PM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#include "FHTKey101.h"
21
+
22
+namespace Lemma {
23
+
24
+    // ====================  FRIEND METHODS  =====================
25
+
26
+    std::ostream &operator<<(std::ostream &stream, const FHTKey101 &ob) {
27
+
28
+        stream << *(HankelTransform*)(&ob);
29
+
30
+        return stream;
31
+    }
32
+
33
+
34
+    // ====================  STATIC CONST MEMBERS     ============
35
+
36
+    const Eigen::Matrix<Real, 101, 3>  FHTKey101::WT101 =
37
+        ( Eigen::Matrix<Real, 101, 3>()   <<
38
+       // Base                   J0                      J1
39
+       5.5308437014783363e-04,   5.1818808036862153e-02,   4.1746363961646286e-06,
40
+       6.4259236035555788e-04,  -2.9258492652779172e-01,  -2.5993370843637242e-05,
41
+       7.4658580837667996e-04,   8.7289913080159265e-01,   9.2506838353721647e-05,
42
+       8.6740895730700251e-04,  -1.8525183961240297e+00,  -2.4318740269846489e-04,
43
+       1.0077854290485113e-03,   3.2096055660873608e+00,   5.2276050788732404e-04,
44
+       1.1708796207911744e-03,  -4.9248158048315069e+00,  -9.5803859755432658e-04,
45
+       1.3603680375478939e-03,   7.0219167445719828e+00,   1.5308357107396591e-03,
46
+       1.5805221687362171e-03,  -9.4781099645811544e+00,  -2.1584605764249656e-03,
47
+       1.8363047770289071e-03,   1.2098564895534539e+01,   2.7161344302423967e-03,
48
+       2.1334817700377098e-03,  -1.4476661837664896e+01,  -3.0845361397036195e-03,
49
+       2.4787521766663585e-03,   1.6146079632847474e+01,   3.2133980102756368e-03,
50
+       2.8798991580882430e-03,  -1.6810370923047440e+01,  -3.1305779240645847e-03,
51
+       3.3459654574712720e-03,   1.6506202923977266e+01,   2.9239120736637542e-03,
52
+       3.8874572434761303e-03,  -1.5534747212675301e+01,  -2.6680602560576316e-03,
53
+       4.5165809426126703e-03,   1.4267433361428399e+01,   2.4131379039476304e-03,
54
+       5.2475183991813838e-03,  -1.2939053370802849e+01,  -2.1549566068119440e-03,
55
+       6.0967465655156379e-03,   1.1628520257389562e+01,   1.9058200916563901e-03,
56
+       7.0834089290521185e-03,  -1.0325503688577493e+01,  -1.6533122444456158e-03,
57
+       8.2297470490200302e-03,   9.0574401975545840e+00,   1.4391633836110848e-03,
58
+       9.5616019305435132e-03,  -7.8759096646654951e+00,  -1.2363666069459527e-03,
59
+       1.1108996538242306e-02,   6.8446506699312666e+00,   1.0907227256323094e-03,
60
+       1.2906812580479873e-02,  -5.9542991234257840e+00,  -9.2712769282234358e-04,
61
+       1.4995576820477703e-02,   5.1830565431894602e+00,   8.2888526218099687e-04,
62
+       1.7422374639493515e-02,  -4.4805481279340267e+00,  -6.7675613963809832e-04,
63
+       2.0241911445804391e-02,   3.8608298760715378e+00,   6.3558641899842260e-04,
64
+       2.3517745856009110e-02,  -3.3125736597743227e+00,  -4.8591507683128695e-04,
65
+       2.7323722447292573e-02,   2.8648088091590589e+00,   5.1892328126100203e-04,
66
+       3.1745636378067953e-02,  -2.4710577422247479e+00,  -3.3190335155472070e-04,
67
+       3.6883167401240015e-02,   2.1450315408533416e+00,   4.6189809360776176e-04,
68
+       4.2852126867040180e-02,  -1.8334353019592327e+00,  -1.8326476919948130e-04,
69
+       4.9787068367863944e-02,   1.5850020809005190e+00,   4.7669939315323097e-04,
70
+       5.7844320874838456e-02,  -1.3468969891769780e+00,  -1.7380345519175726e-05,
71
+       6.7205512739749784e-02,   1.1802299801807625e+00,   5.9009214750893949e-04,
72
+       7.8081666001153169e-02,  -9.9988174688478793e-01,   2.1645139320505843e-04,
73
+       9.0717953289412512e-02,   8.8503813256539254e-01,   8.5203135609860704e-04,
74
+       1.0539922456186433e-01,  -7.3165077099639619e-01,   5.9560990889710838e-04,
75
+       1.2245642825298191e-01,   6.5909386165012596e-01,   1.3651107378683781e-03,
76
+       1.4227407158651359e-01,  -5.3038429622108840e-01,   1.2606987195022564e-03,
77
+       1.6529888822158656e-01,   5.0119791866928076e-01,   2.3131990435032663e-03,
78
+       1.9204990862075413e-01,  -3.8269840749371159e-01,   2.4572002938857678e-03,
79
+       2.2313016014842982e-01,   3.8622329595139565e-01,   4.0408430887840449e-03,
80
+       2.5924026064589156e-01,  -2.6413330193320073e-01,   4.6278078809669602e-03,
81
+       3.0119421191220208e-01,   3.0353632730294311e-01,   7.1437051276295131e-03,
82
+       3.4993774911115533e-01,  -1.7255655176111537e-01,   8.5723466849983495e-03,
83
+       4.0656965974059917e-01,   2.5119774955173280e-01,   1.2684763573137947e-02,
84
+       4.7236655274101469e-01,  -9.8536724013140092e-02,   1.5643387012124067e-02,
85
+       5.4881163609402650e-01,   2.1755876398162183e-01,   2.2480928663078600e-02,
86
+       6.3762815162177333e-01,  -3.4268716744688760e-02,   2.8124131719595692e-02,
87
+       7.4081822068171788e-01,   1.9925218957836366e-01,   3.9373999883133115e-02,
88
+       8.6070797642505781e-01,   1.8319735495994052e-02,   4.9445586323210833e-02,
89
+       1.0000000000000000e+00,   1.8963099219918259e-01,   6.7326587032714463e-02,
90
+       1.1618342427282831e+00,   5.7228135568732394e-02,   8.3541701874077570e-02,
91
+       1.3498588075760032e+00,   1.7266316834158107e-01,   1.0961776964853986e-01,
92
+       1.5683121854901687e+00,   6.8141322181604499e-02,   1.3118216481048459e-01,
93
+       1.8221188003905089e+00,   1.2468074033081850e-01,   1.6144181878027153e-01,
94
+       2.1170000166126748e+00,   2.1678852838804014e-02,   1.7704476632134886e-01,
95
+       2.4596031111569494e+00,   1.1114005126278175e-02,   1.9032654055463888e-01,
96
+       2.8576511180631639e+00,  -1.0424806190544497e-01,   1.6333927603825021e-01,
97
+       3.3201169227365472e+00,  -1.6473681128667569e-01,   1.1034442879456068e-01,
98
+       3.8574255306969740e+00,  -2.3603153458714107e-01,  -1.1282682226217962e-02,
99
+       4.4816890703380645e+00,  -2.2093965064386309e-01,  -1.4579378661401318e-01,
100
+       5.2069798271798486e+00,  -7.5633542915308175e-02,  -2.7560051939484942e-01,
101
+       6.0496474644129448e+00,   1.3358180223826097e-01,  -2.3333751023296440e-01,
102
+       7.0286875805892928e+00,   3.3949946683489907e-01,  -5.9615109981928909e-03,
103
+       8.1661699125676499e+00,   1.2815187347111337e-01,   3.2380356528743487e-01,
104
+       9.4877358363585262e+00,  -2.2988301163130145e-01,   2.1970582679149839e-01,
105
+       1.1023176380641601e+01,  -3.3425750283830036e-01,  -2.8302631898505476e-01,
106
+       1.2807103782663029e+01,   4.4350537603751145e-01,  -2.2706962776315812e-01,
107
+       1.4879731724872830e+01,  -8.8943820418669634e-02,   4.7351258711649669e-01,
108
+       1.7287781840567639e+01,  -1.8646079800862164e-01,  -3.5417866045339608e-01,
109
+       2.0085536923187668e+01,   2.4494657419883456e-01,   1.6582378621661517e-01,
110
+       2.3336064580942711e+01,  -2.0169045144304532e-01,  -5.1221107687420810e-02,
111
+       2.7112638920657883e+01,   1.4661206655803793e-01,   3.5484710794282063e-03,
112
+       3.1500392308747923e+01,  -1.0564640256629308e-01,   1.1614894738175324e-02,
113
+       3.6598234443677974e+01,   7.8487036158411266e-02,  -1.4776256489774963e-02,
114
+       4.2521082000062783e+01,  -6.0533748554794195e-02,   1.4194293010344678e-02,
115
+       4.9402449105530167e+01,   4.8243702864613026e-02,  -1.2609914713728791e-02,
116
+       5.7397457045446188e+01,  -3.9347085461672239e-02,   1.0854082569077052e-02,
117
+       6.6686331040925154e+01,   3.2489421068688185e-02,  -9.2082270347668624e-03,
118
+       7.7478462925260828e+01,  -2.6982535264609676e-02,   7.7880648968821110e-03,
119
+       9.0017131300521811e+01,   2.2530196869950080e-02,  -6.6089268276601255e-03,
120
+       1.0458498557711414e+02,  -1.8947601435977172e-02,   5.6159700146012417e-03,
121
+       1.2151041751873485e+02,   1.6017457455233256e-02,  -4.7432063636330263e-03,
122
+       1.4117496392147686e+02,  -1.3519422964231352e-02,   3.9609893136500528e-03,
123
+       1.6402190729990167e+02,   1.1318328695851308e-02,  -3.2753768787828126e-03,
124
+       1.9056626845862999e+02,  -9.3839154851987506e-03,   2.6945716306237466e-03,
125
+       2.2140641620418697e+02,   7.7256174599644543e-03,  -2.2042319512562145e-03,
126
+       2.5723755590577474e+02,  -6.3199190181430056e-03,   1.7733135127602079e-03,
127
+       2.9886740096706029e+02,   5.0986473606509210e-03,  -1.3773733375919272e-03,
128
+       3.4723438047873447e+02,  -3.9929354358609528e-03,   1.0137885881408651e-03,
129
+       4.0342879349273511e+02,   2.9783618569305080e-03,  -6.9751488719640639e-04,
130
+       4.6871738678241655e+02,  -2.0802747552777045e-03,   4.4545125438205673e-04,
131
+       5.4457191012592898e+02,   1.3429398653973710e-03,  -2.6373575275283686e-04,
132
+       6.3270229281225352e+02,  -7.9345560431147465e-04,   1.4519595835116970e-04,
133
+       7.3509518924197266e+02,   4.2530878973518046e-04,  -7.4640168948626184e-05,
134
+       8.5405876252615155e+02,  -2.0457624610548748e-04,   3.5826939350044606e-05,
135
+       9.9227471560502534e+02,   8.6750842046621606e-05,  -1.5854604622793124e-05,
136
+       1.1528587427833875e+03,  -3.1406113278782205e-05,   6.2412989356183992e-06,
137
+       1.3394307643944169e+03,   9.1385289919391839e-06,  -2.0349222128793154e-06,
138
+       1.5561965278371533e+03,  -1.8949818224609619e-06,   4.8072849734177625e-07,
139
+       1.8080424144560632e+03,   2.0794387557779629e-07,  -6.0462736574031818e-08).finished();
140
+
141
+    // ====================  LIFECYCLE     =======================
142
+
143
+    //--------------------------------------------------------------------------------------
144
+    //       Class:  FHTKey101
145
+    //      Method:  FHTKey101
146
+    // Description:  constructor (protected)
147
+    //--------------------------------------------------------------------------------------
148
+    FHTKey101::FHTKey101 (const std::string& name) : HankelTransform(name) {
149
+
150
+    }  // -----  end of method FHTKey101::FHTKey101  (constructor)  -----
151
+
152
+
153
+    //--------------------------------------------------------------------------------------
154
+    //       Class:  FHTKey101
155
+    //      Method:  New()
156
+    // Description:  public constructor
157
+    //--------------------------------------------------------------------------------------
158
+    FHTKey101* FHTKey101::New() {
159
+        FHTKey101*  Obj = new FHTKey101("FHTKey101");
160
+        Obj->AttachTo(Obj);
161
+        return Obj;
162
+    }
163
+
164
+    //--------------------------------------------------------------------------------------
165
+    //       Class:  FHTKey101
166
+    //      Method:  ~FHTKey101
167
+    // Description:  destructor (protected)
168
+    //--------------------------------------------------------------------------------------
169
+    FHTKey101::~FHTKey101 () {
170
+
171
+    }  // -----  end of method FHTKey101::~FHTKey101  (destructor)  -----
172
+
173
+    //--------------------------------------------------------------------------------------
174
+    //       Class:  FHTKey101
175
+    //      Method:  Delete
176
+    // Description:  public destructor
177
+    //--------------------------------------------------------------------------------------
178
+    void FHTKey101::Delete() {
179
+        this->DetachFrom(this);
180
+    }
181
+
182
+    //--------------------------------------------------------------------------------------
183
+    //       Class:  FHTKey101
184
+    //      Method:  Release
185
+    // Description:  destructor (protected)
186
+    //--------------------------------------------------------------------------------------
187
+    void FHTKey101::Release() {
188
+        delete this;
189
+    }
190
+
191
+
192
+    //--------------------------------------------------------------------------------------
193
+    //       Class:  FHTKey101
194
+    //      Method:  Zgauss
195
+    //--------------------------------------------------------------------------------------
196
+    Complex FHTKey101::Zgauss ( const int &ikk, const EMMODE &imode,
197
+                            const int &itype, const Real &rho,
198
+                            const Real &wavef, KernelEm1DBase *Kernel ) {
199
+ 		return Zans(0, Kernel->GetManagerIndex());
200
+    }		// -----  end of method FHTKey101::ComputeRelated  -----
201
+
202
+
203
+    //--------------------------------------------------------------------------------------
204
+    //       Class:  FHTKey101
205
+    //      Method:  ComputeRelated
206
+    //--------------------------------------------------------------------------------------
207
+    void FHTKey101::ComputeRelated ( const Real& rho, KernelEm1DBase* Kernel ) {
208
+        return ;
209
+    }		// -----  end of method FHTKey101::ComputeRelated  -----
210
+
211
+    //--------------------------------------------------------------------------------------
212
+    //       Class:  FHTKey101
213
+    //      Method:  ComputeRelated
214
+    //--------------------------------------------------------------------------------------
215
+    void FHTKey101::ComputeRelated ( const Real& rho, std::vector< KernelEm1DBase* > KernelVec ) {
216
+        return ;
217
+    }		// -----  end of method FHTKey101::ComputeRelated  -----
218
+
219
+    //--------------------------------------------------------------------------------------
220
+    //       Class:  FHTKey101
221
+    //      Method:  ComputeRelated
222
+    //--------------------------------------------------------------------------------------
223
+    void FHTKey101::ComputeRelated ( const Real& rho, KernelEM1DManager* KernelManager ) {
224
+
225
+        //kernelVec = KernelManager->GetSTLVector();
226
+        int nrel = (int)(KernelManager->GetSTLVector().size());
227
+        Eigen::Matrix<Complex, 101, Eigen::Dynamic > Zwork;
228
+        // TODO, if we want to allow lagged, then 1 below should be nlag
229
+        Zans= Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic>::Zero(1, nrel);
230
+        Zwork.resize(101, nrel);
231
+        VectorXr lambda = WT101.col(0).array()/rho;
232
+        int NumFun = 0;
233
+        int idx = 0;
234
+
235
+        // Get Kernel values
236
+        for (int ir=0; ir<lambda.size(); ++ir) {
237
+            // irelated loop
238
+            ++NumFun;
239
+            KernelManager->ComputeReflectionCoeffs(lambda(ir), idx, rho);
240
+            for (int ir2=0; ir2<nrel; ++ir2) {
241
+                // Zwork* needed due to sign convention of filter weights
242
+ 			    Zwork(ir, ir2) = std::conj(KernelManager->GetSTLVector()[ir2]->RelBesselArg(lambda(ir)));
243
+            }
244
+
245
+        }
246
+
247
+        // We diverge slightly from Key here, each kernel is evaluated seperately, whereby instead
248
+        // they prefer to sum them. The reason is that all those terms have been removed from the kernels
249
+        // in the interests of making them as generic and reusable as possible. This approach requires slightly
250
+        // more multiplies, but the same number of kernel evaluations, which is the expensive part.
251
+        // Inner product and scale
252
+        for (int ir2=0; ir2<nrel; ++ir2) {
253
+            Zans(0, ir2) = Zwork.col(ir2).dot(WT101.col(KernelManager->GetSTLVector()[ir2]->GetBesselOrder() + 1))/rho;
254
+        }
255
+
256
+        return ;
257
+    }		// -----  end of method FHTKey101::ComputeRelated  -----
258
+
259
+}		// -----  end of Lemma  name  -----

+ 209
- 0
Modules/FDEM1D/src/FHTKey51.cpp View File

@@ -0,0 +1,209 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      02/11/2014 03:42:53 PM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#include "FHTKey51.h"
21
+
22
+namespace Lemma {
23
+
24
+    // ====================  FRIEND METHODS  =====================
25
+
26
+    std::ostream &operator<<(std::ostream &stream, const FHTKey51 &ob) {
27
+
28
+        stream << *(HankelTransform*)(&ob);
29
+
30
+        return stream;
31
+    }
32
+
33
+
34
+    // ====================  STATIC CONST MEMBERS     ============
35
+
36
+    const Eigen::Matrix<Real, 51, 3>  FHTKey51::WT51 =
37
+        ( Eigen::Matrix<Real, 51, 3>()   <<
38
+        // Base                   J0                      J1
39
+           4.9915939069102170e-03,   6.5314496156480717e-02,   3.8409924166118657e-05,
40
+           6.1703482511978082e-03,  -2.2265895125268051e-01,  -9.4382633059055269e-05,
41
+           7.6274629409160176e-03,   4.2794928430042073e-01,   1.6377612356675232e-04,
42
+           9.4286721829279947e-03,  -5.8890658905204007e-01,  -1.7853487610334151e-04,
43
+           1.1655233178024955e-02,   6.7897324897038758e-01,   1.9759569268356316e-04,
44
+           1.4407591843112350e-02,  -6.8296549495756353e-01,  -1.2796247718553291e-04,
45
+           1.7809914185937643e-02,   6.4702210424566342e-01,   1.3163370416771999e-04,
46
+           2.2015687754376449e-02,  -5.6843090153083187e-01,   1.7066927559149181e-05,
47
+           2.7214645856121149e-02,   4.9960500362966542e-01,   4.1368007808198310e-05,
48
+           3.3641326918204623e-02,  -4.0923517268678855e-01,   2.3582259002758631e-04,
49
+           4.1585655121173182e-02,   3.5487831784012780e-01,  -1.9929745662753875e-05,
50
+           5.1406019627642255e-02,  -2.7408257835871558e-01,   5.8196110748926486e-04,
51
+           6.3545442443014022e-02,   2.4668368971888163e-01,   1.1164151202379049e-05,
52
+           7.8551564282309541e-02,  -1.7348161774657314e-01,   1.2053942009238238e-03,
53
+           9.7101350057185065e-02,   1.7509173908347012e-01,   2.8328713800714110e-04,
54
+           1.2003162851145673e-01,  -1.0007796678766585e-01,   2.4375075610646724e-03,
55
+           1.4837684372696586e-01,   1.3297302593795621e-01,   1.1709289200267103e-03,
56
+           1.8341572156771246e-01,  -4.3822390117083297e-02,   5.0080095645252103e-03,
57
+           2.2672895630607542e-01,   1.1415804492335258e-01,   3.5856849047131551e-03,
58
+           2.8027051982381157e-01,   4.2584271963990363e-03,   1.0536604059335859e-02,
59
+           3.4645581033005746e-01,   1.1496183925974515e-01,   9.6674718436839564e-03,
60
+           4.2827061721265969e-01,   5.1313336759457658e-02,   2.2583365267100426e-02,
61
+           5.2940581770869455e-01,   1.3312389010285514e-01,   2.4201911801947001e-02,
62
+           6.5442388190885858e-01,   1.0111673764393908e-01,   4.8602551164692191e-02,
63
+           8.0896469756649991e-01,   1.6331446488042209e-01,   5.6856974938076565e-02,
64
+           1.0000000000000000e+00,   1.4704406144951229e-01,   1.0202078096072606e-01,
65
+           1.2361478850785035e+00,   1.8341391219815678e-01,   1.2202639829343022e-01,
66
+           1.5280615937840571e+00,   1.5073655145087875e-01,   1.9561985197118459e-01,
67
+           1.8889101074258496e+00,   1.2356364992866918e-01,   2.1570853920674185e-01,
68
+           2.3349722343978727e+00,   1.1529465836107913e-02,   2.8552388758852060e-01,
69
+           2.8863709892679585e+00,  -1.2852626053530605e-01,   2.0559964796530625e-01,
70
+           3.5679813939355345e+00,  -2.9874216118407571e-01,   1.1666011451374350e-01,
71
+           4.4105526541128617e+00,  -3.1330553036684633e-01,  -2.3636714743601936e-01,
72
+           5.4520953354089947e+00,  -3.2332453606385231e-02,  -3.4036030266164258e-01,
73
+           6.7395961181122024e+00,   4.2056051544727674e-01,  -1.9475364255836261e-01,
74
+           8.3311374876876929e+00,   1.3883637369942961e-01,   5.7608115965662166e-01,
75
+           1.0298517985703377e+01,  -5.0223684329542873e-01,  -2.1471464584834585e-01,
76
+           1.2730491227470161e+01,   3.7996073748731690e-01,  -1.2611070492338947e-01,
77
+           1.5736769806847677e+01,  -1.7984404170109178e-01,   2.0019703515125831e-01,
78
+           1.9452974714702009e+01,   7.0557286965350657e-02,  -1.6147664664730754e-01,
79
+           2.4046753552064487e+01,  -2.7522277139686569e-02,   1.1398023016900673e-01,
80
+           2.9725343546388515e+01,   1.1909130661901874e-02,  -7.9924455203352035e-02,
81
+           3.6744920558100112e+01,  -5.8977428045126450e-03,   5.7024556382799692e-02,
82
+           4.5422155835273074e+01,   3.2648420034561555e-03,  -4.1006636508593382e-02,
83
+           5.6148501871478999e+01,  -1.9304039780209286e-03,   2.9192063091319696e-02,
84
+           6.9407851838755207e+01,   1.1594138315987755e-03,  -2.0089573135329029e-02,
85
+           8.5798369258319340e+01,  -6.7050941490060716e-04,   1.2965400526524978e-02,
86
+           1.0605947270185592e+02,   3.5089803807606258e-04,  -7.5154910983038946e-03,
87
+           1.3110519287294045e+02,  -1.5287051174029577e-04,   3.6269079130258285e-03,
88
+           1.6206540689269471e+02,   4.8238483411813232e-05,  -1.2668720233377250e-03,
89
+           2.0033680997479166e+02,  -8.0433917146487977e-06,   2.3403502580547994e-04).finished();
90
+
91
+    // ====================  LIFECYCLE     =======================
92
+
93
+    //--------------------------------------------------------------------------------------
94
+    //       Class:  FHTKey51
95
+    //      Method:  FHTKey51
96
+    // Description:  constructor (protected)
97
+    //--------------------------------------------------------------------------------------
98
+    FHTKey51::FHTKey51 (const std::string& name) : HankelTransform(name) {
99
+
100
+    }  // -----  end of method FHTKey51::FHTKey51  (constructor)  -----
101
+
102
+
103
+    //--------------------------------------------------------------------------------------
104
+    //       Class:  FHTKey51
105
+    //      Method:  New()
106
+    // Description:  public constructor
107
+    //--------------------------------------------------------------------------------------
108
+    FHTKey51* FHTKey51::New() {
109
+        FHTKey51*  Obj = new FHTKey51("FHTKey51");
110
+        Obj->AttachTo(Obj);
111
+        return Obj;
112
+    }
113
+
114
+    //--------------------------------------------------------------------------------------
115
+    //       Class:  FHTKey51
116
+    //      Method:  ~FHTKey51
117
+    // Description:  destructor (protected)
118
+    //--------------------------------------------------------------------------------------
119
+    FHTKey51::~FHTKey51 () {
120
+
121
+    }  // -----  end of method FHTKey51::~FHTKey51  (destructor)  -----
122
+
123
+    //--------------------------------------------------------------------------------------
124
+    //       Class:  FHTKey51
125
+    //      Method:  Delete
126
+    // Description:  public destructor
127
+    //--------------------------------------------------------------------------------------
128
+    void FHTKey51::Delete() {
129
+        this->DetachFrom(this);
130
+    }
131
+
132
+    //--------------------------------------------------------------------------------------
133
+    //       Class:  FHTKey51
134
+    //      Method:  Release
135
+    // Description:  destructor (protected)
136
+    //--------------------------------------------------------------------------------------
137
+    void FHTKey51::Release() {
138
+        delete this;
139
+    }
140
+
141
+
142
+    //--------------------------------------------------------------------------------------
143
+    //       Class:  FHTKey51
144
+    //      Method:  Zgauss
145
+    //--------------------------------------------------------------------------------------
146
+    Complex FHTKey51::Zgauss ( const int &ikk, const EMMODE &imode,
147
+                            const int &itype, const Real &rho,
148
+                            const Real &wavef, KernelEm1DBase *Kernel ) {
149
+ 		return Zans(0, Kernel->GetManagerIndex());
150
+    }		// -----  end of method FHTKey51::ComputeRelated  -----
151
+
152
+
153
+    //--------------------------------------------------------------------------------------
154
+    //       Class:  FHTKey51
155
+    //      Method:  ComputeRelated
156
+    //--------------------------------------------------------------------------------------
157
+    void FHTKey51::ComputeRelated ( const Real& rho, KernelEm1DBase* Kernel ) {
158
+        return ;
159
+    }		// -----  end of method FHTKey51::ComputeRelated  -----
160
+
161
+    //--------------------------------------------------------------------------------------
162
+    //       Class:  FHTKey51
163
+    //      Method:  ComputeRelated
164
+    //--------------------------------------------------------------------------------------
165
+    void FHTKey51::ComputeRelated ( const Real& rho, std::vector< KernelEm1DBase* > KernelVec ) {
166
+        return ;
167
+    }		// -----  end of method FHTKey51::ComputeRelated  -----
168
+
169
+    //--------------------------------------------------------------------------------------
170
+    //       Class:  FHTKey51
171
+    //      Method:  ComputeRelated
172
+    //--------------------------------------------------------------------------------------
173
+    void FHTKey51::ComputeRelated ( const Real& rho, KernelEM1DManager* KernelManager ) {
174
+
175
+        //kernelVec = KernelManager->GetSTLVector();
176
+        int nrel = (int)(KernelManager->GetSTLVector().size());
177
+        Eigen::Matrix<Complex, 51, Eigen::Dynamic > Zwork;
178
+        // TODO, if we want to allow lagged, then 1 below should be nlag
179
+        Zans= Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic>::Zero(1, nrel);
180
+        Zwork.resize(51, nrel);
181
+        VectorXr lambda = WT51.col(0).array()/rho;
182
+        int NumFun = 0;
183
+        int idx = 0;
184
+
185
+        // Get Kernel values
186
+        for (int ir=0; ir<lambda.size(); ++ir) {
187
+            // irelated loop
188
+            ++NumFun;
189
+            KernelManager->ComputeReflectionCoeffs(lambda(ir), idx, rho);
190
+            for (int ir2=0; ir2<nrel; ++ir2) {
191
+                // Zwork* needed due to sign convention of filter weights
192
+ 			    Zwork(ir, ir2) = std::conj(KernelManager->GetSTLVector()[ir2]->RelBesselArg(lambda(ir)));
193
+            }
194
+
195
+        }
196
+
197
+        // We diverge slightly from Key here, each kernel is evaluated seperately, whereby instead
198
+        // they prefer to sum them. The reason is that all those terms have been removed from the kernels
199
+        // in the interests of making them as generic and reusable as possible. This approach requires slightly
200
+        // more multiplies, but the same number of kernel evaluations, which is the expensive part.
201
+        // Inner product and scale
202
+        for (int ir2=0; ir2<nrel; ++ir2) {
203
+            Zans(0, ir2) = Zwork.col(ir2).dot(WT51.col(KernelManager->GetSTLVector()[ir2]->GetBesselOrder() + 1))/rho;
204
+        }
205
+
206
+        return ;
207
+    }		// -----  end of method FHTKey51::ComputeRelated  -----
208
+
209
+}		// -----  end of Lemma  name  -----

+ 85
- 0
Modules/FDEM1D/src/GroundedElectricDipole.cpp View File

@@ -0,0 +1,85 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      01/29/2014 07:05:13 AM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#include "GroundedElectricDipole.h"
21
+
22
+
23
+namespace Lemma {
24
+
25
+    // ====================  FRIEND METHODS  =====================
26
+
27
+    std::ostream &operator<<(std::ostream &stream, const GroundedElectricDipole &ob) {
28
+
29
+        stream << *(DipoleSource*)(&ob);
30
+
31
+        return stream;
32
+    }
33
+
34
+    // ====================  LIFECYCLE     =======================
35
+
36
+    //--------------------------------------------------------------------------------------
37
+    //       Class:  GroundedElectricDipole
38
+    //      Method:  GroundedElectricDipole
39
+    // Description:  constructor (protected)
40
+    //--------------------------------------------------------------------------------------
41
+    GroundedElectricDipole::GroundedElectricDipole (const std::string& name) : DipoleSource(name) {
42
+
43
+    }  // -----  end of method GroundedElectricDipole::GroundedElectricDipole  (constructor)  -----
44
+
45
+
46
+    //--------------------------------------------------------------------------------------
47
+    //       Class:  GroundedElectricDipole
48
+    //      Method:  New()
49
+    // Description:  public constructor
50
+    //--------------------------------------------------------------------------------------
51
+    GroundedElectricDipole* GroundedElectricDipole::New() {
52
+        GroundedElectricDipole*  Obj = new GroundedElectricDipole("GroundedElectricDipole");
53
+        Obj->AttachTo(Obj);
54
+        return Obj;
55
+    }
56
+
57
+    //--------------------------------------------------------------------------------------
58
+    //       Class:  GroundedElectricDipole
59
+    //      Method:  ~GroundedElectricDipole
60
+    // Description:  destructor (protected)
61
+    //--------------------------------------------------------------------------------------
62
+    GroundedElectricDipole::~GroundedElectricDipole () {
63
+
64
+    }  // -----  end of method GroundedElectricDipole::~GroundedElectricDipole  (destructor)  -----
65
+
66
+    //--------------------------------------------------------------------------------------
67
+    //       Class:  GroundedElectricDipole
68
+    //      Method:  Delete
69
+    // Description:  public destructor
70
+    //--------------------------------------------------------------------------------------
71
+    void GroundedElectricDipole::Delete() {
72
+        this->DetachFrom(this);
73
+    }
74
+
75
+    //--------------------------------------------------------------------------------------
76
+    //       Class:  GroundedElectricDipole
77
+    //      Method:  Release
78
+    // Description:  destructor (protected)
79
+    //--------------------------------------------------------------------------------------
80
+    void GroundedElectricDipole::Release() {
81
+        delete this;
82
+    }
83
+
84
+}		// -----  end of Lemma  name  -----
85
+

+ 124
- 0
Modules/FDEM1D/src/LayeredEarthEMReader.cpp View File

@@ -0,0 +1,124 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      09/27/2013 01:44:46 PM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2013, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2013, Trevor Irons
18
+ */
19
+
20
+#include "LayeredEarthEMReader.h"
21
+
22
+namespace Lemma {
23
+
24
+    // ====================  FRIEND METHODS  =====================
25
+
26
+    std::ostream &operator<<(std::ostream &stream, const LayeredEarthEMReader &ob) {
27
+
28
+        stream << *(LemmaObject*)(&ob);
29
+
30
+        return stream;
31
+    }
32
+
33
+    // ====================  LIFECYCLE     =======================
34
+
35
+    //--------------------------------------------------------------------------------------
36
+    //       Class:  LayeredEarthEMReader
37
+    //      Method:  LayeredEarthEMReader
38
+    // Description:  constructor (protected)
39
+    //--------------------------------------------------------------------------------------
40
+    LayeredEarthEMReader::LayeredEarthEMReader (const std::string& name) : LemmaObject(name),
41
+        LayEarth(NULL) {
42
+
43
+    }  // -----  end of method LayeredEarthEMReader::LayeredEarthEMReader  (constructor)  -----
44
+
45
+
46
+    //--------------------------------------------------------------------------------------
47
+    //       Class:  LayeredEarthEMReader
48
+    //      Method:  New()
49
+    // Description:  public constructor
50
+    //--------------------------------------------------------------------------------------
51
+    LayeredEarthEMReader* LayeredEarthEMReader::New() {
52
+        LayeredEarthEMReader*  Obj = new LayeredEarthEMReader("LayeredEarthEMReader");
53
+        Obj->AttachTo(Obj);
54
+        return Obj;
55
+    }
56
+
57
+    //--------------------------------------------------------------------------------------
58
+    //       Class:  LayeredEarthEMReader
59
+    //      Method:  ~LayeredEarthEMReader
60
+    // Description:  destructor (protected)
61
+    //--------------------------------------------------------------------------------------
62
+    LayeredEarthEMReader::~LayeredEarthEMReader () {
63
+        if (LayEarth) LayEarth->Delete();
64
+    }  // -----  end of method LayeredEarthEMReader::~LayeredEarthEMReader  (destructor)  -----
65
+
66
+    //--------------------------------------------------------------------------------------
67
+    //       Class:  LayeredEarthEMReader
68
+    //      Method:  Delete
69
+    // Description:  public destructor
70
+    //--------------------------------------------------------------------------------------
71
+    void LayeredEarthEMReader::Delete() {
72
+        this->DetachFrom(this);
73
+    }
74
+
75
+    //--------------------------------------------------------------------------------------
76
+    //       Class:  LayeredEarthEMReader
77
+    //      Method:  Release
78
+    // Description:  destructor (protected)
79
+    //--------------------------------------------------------------------------------------
80
+    void LayeredEarthEMReader::Release() {
81
+        delete this;
82
+    }
83
+
84
+
85
+    //--------------------------------------------------------------------------------------
86
+    //       Class:  LayeredEarthEMReader
87
+    //      Method:  GetLayeredEarth
88
+    //--------------------------------------------------------------------------------------
89
+    LayeredEarthEM* LayeredEarthEMReader::GetLayeredEarth (  ) {
90
+        return LayEarth;
91
+    }		// -----  end of method LayeredEarthEMReader::GetLayeredEarth  -----
92
+
93
+
94
+    //--------------------------------------------------------------------------------------
95
+    //       Class:  LayeredEarthEMReader
96
+    //      Method:  ReadASCIIInputFile
97
+    //--------------------------------------------------------------------------------------
98
+    void LayeredEarthEMReader::ReadASCIIInputFile ( const std::string& name ) {
99
+        if (LayEarth) LayEarth->Delete();
100
+        ASCIIParser* Parser = ASCIIParser::New();
101
+        LayEarth = LayeredEarthEM::New();
102
+
103
+        Parser->SetCommentString("//");
104
+        Parser->Open(name);
105
+
106
+        int nlay = Parser->ReadInts( 1 )[0]; // non-air layers
107
+            LayEarth->SetNumberOfLayers(nlay+1);
108
+
109
+        VectorXcr sigma = VectorXcr::Zero(nlay+1);
110
+        VectorXr  thick(nlay-1);
111
+        for (int ilay=1; ilay<nlay; ++ilay) {
112
+            std::vector<Real> rval = Parser->ReadReals(2);
113
+            sigma(ilay) =  1./rval[0];
114
+            thick(ilay-1) =  rval[1]; //CondMod[ilay+1];
115
+        }
116
+        sigma(nlay) = 1./Parser->ReadReals(1)[0];
117
+        LayEarth->SetLayerConductivity(sigma);
118
+        if (thick.size() > 0) LayEarth->SetLayerThickness(thick);
119
+        Parser->Delete();
120
+        return ;
121
+    }		// -----  end of method LayeredEarthEMReader::ReadASCIIInputFile  -----
122
+
123
+
124
+}		// -----  end of Lemma  name  -----

+ 82
- 0
Modules/FDEM1D/src/MagneticDipole.cpp View File

@@ -0,0 +1,82 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      09/25/2013 08:20:14 AM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2013, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2013, Trevor Irons
18
+ */
19
+
20
+#include "MagneticDipole.h"
21
+
22
+namespace Lemma {
23
+
24
+    // ====================  FRIEND METHODS  =====================
25
+
26
+    std::ostream &operator<<(std::ostream &stream, const MagneticDipole &ob) {
27
+
28
+        stream << *(DipoleSource*)(&ob);
29
+
30
+        return stream;
31
+    }
32
+    // ====================  LIFECYCLE     =======================
33
+
34
+    //--------------------------------------------------------------------------------------
35
+    //       Class:  MagneticDipole
36
+    //      Method:  MagneticDipole
37
+    // Description:  constructor (protected)
38
+    //--------------------------------------------------------------------------------------
39
+    MagneticDipole::MagneticDipole (const std::string& name) : DipoleSource(name) {
40
+
41
+    }  // -----  end of method MagneticDipole::MagneticDipole  (constructor)  -----
42
+
43
+
44
+    //--------------------------------------------------------------------------------------
45
+    //       Class:  MagneticDipole
46
+    //      Method:  New()
47
+    // Description:  public constructor
48
+    //--------------------------------------------------------------------------------------
49
+    MagneticDipole* MagneticDipole::New() {
50
+        MagneticDipole*  Obj = new MagneticDipole("MagneticDipole");
51
+        Obj->AttachTo(Obj);
52
+        return Obj;
53
+    }
54
+
55
+    //--------------------------------------------------------------------------------------
56
+    //       Class:  MagneticDipole
57
+    //      Method:  ~MagneticDipole
58
+    // Description:  destructor (protected)
59
+    //--------------------------------------------------------------------------------------
60
+    MagneticDipole::~MagneticDipole () {
61
+
62
+    }  // -----  end of method MagneticDipole::~MagneticDipole  (destructor)  -----
63
+
64
+    //--------------------------------------------------------------------------------------
65
+    //       Class:  MagneticDipole
66
+    //      Method:  Delete
67
+    // Description:  public destructor
68
+    //--------------------------------------------------------------------------------------
69
+    void MagneticDipole::Delete() {
70
+        this->DetachFrom(this);
71
+    }
72
+
73
+    //--------------------------------------------------------------------------------------
74
+    //       Class:  MagneticDipole
75
+    //      Method:  Release
76
+    // Description:  destructor (protected)
77
+    //--------------------------------------------------------------------------------------
78
+    void MagneticDipole::Release() {
79
+        delete this;
80
+    }
81
+
82
+} // namespace Lemma

+ 349
- 0
Modules/FDEM1D/src/PolygonalWireAntenna.cpp View File

@@ -0,0 +1,349 @@
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     05/18/2010
11
+  @version  $Id: PolygonalWireAntenna.cpp 211 2015-02-27 05:43:26Z tirons $
12
+ **/
13
+
14
+#include "PolygonalWireAntenna.h"
15
+
16
+namespace Lemma {
17
+
18
+#ifdef HAVE_YAMLCPP
19
+    std::ostream &operator << (std::ostream &stream, const PolygonalWireAntenna &ob) {
20
+        stream << ob.Serialize()  << "\n---\n"; // End of doc --- as a direct stream should encapulste thingy
21
+        return stream;
22
+    }
23
+#else
24
+	std::ostream &operator<<(std::ostream &stream,
25
+				const PolygonalWireAntenna &ob) {
26
+
27
+		stream << *(WireAntenna*)(&ob);
28
+		//stream << "Current: " << ob.Current << " [A]\n";
29
+		//stream << "Frequencies: " << ob.Freqs.transpose() << " [Hz]\n";
30
+		//stream << "Number of points " << ob.NumberOfPoints << "\n";
31
+		//stream << "Points:\n" << ob.Points.transpose() << "\n";
32
+		//stream << "Dipoles used to approximate " << ob.Dipoles.size();
33
+		return stream;
34
+	}
35
+#endif
36
+	// ====================  LIFECYCLE     =======================
37
+
38
+	PolygonalWireAntenna::PolygonalWireAntenna(const std::string& name)
39
+		: WireAntenna(name), minDipoleRatio(.15),
40
+   		minDipoleMoment(1e-6), maxDipoleMoment(1e1), rRepeat(1e10,1e10,1e10) {
41
+		Points.setZero();
42
+        //rRepeat.setOnes();
43
+	}
44
+
45
+#ifdef HAVE_YAMLCPP
46
+    PolygonalWireAntenna::PolygonalWireAntenna(const YAML::Node& node)
47
+		: WireAntenna(node) {
48
+// minDipoleRatio(.15),
49
+// minDipoleMoment(1e-4),
50
+// maxDipoleMoment(1e-0)
51
+        minDipoleRatio   = node["minDipoleRatio"].as<Real>();
52
+        maxDipoleMoment  = node["maxDipoleMoment"].as<Real>();
53
+        minDipoleMoment  = node["minDipoleMoment"].as<Real>();
54
+	}
55
+#endif
56
+
57
+	PolygonalWireAntenna::~PolygonalWireAntenna() {
58
+        if (this->NumberOfReferences != 0)
59
+            throw DeleteObjectWithReferences( this );
60
+		// Taken care of in parent
61
+        //for (unsigned int id=0; id<Dipoles.size(); ++id) {
62
+		//	Dipoles[id]->Delete();
63
+		//}
64
+		//Dipoles.clear();
65
+	}
66
+
67
+	PolygonalWireAntenna* PolygonalWireAntenna::New() {
68
+		PolygonalWireAntenna* Obj = new
69
+            PolygonalWireAntenna("PolygonalWireAntenna");
70
+        Obj->AttachTo(Obj);
71
+        return Obj;
72
+	}
73
+
74
+	PolygonalWireAntenna* PolygonalWireAntenna::Clone() {
75
+		PolygonalWireAntenna* copy = PolygonalWireAntenna::New();
76
+		//copy->AttachTo(copy); // NO! Attached above!
77
+        copy->minDipoleRatio = this->minDipoleRatio;
78
+		copy->minDipoleMoment = this->minDipoleMoment;
79
+		copy->maxDipoleMoment = this->maxDipoleMoment;
80
+		copy->NumberOfPoints = this->NumberOfPoints;
81
+		copy->Freqs = this->Freqs;
82
+		copy->Current = this->Current;
83
+		copy->NumberOfTurns = this->NumberOfTurns;
84
+		copy->Points = this->Points;
85
+		//copy->Dipoles = this->Dipoles; // no, disaster
86
+		return copy;
87
+	}
88
+
89
+	void PolygonalWireAntenna::Delete() {
90
+		this->DetachFrom(this);
91
+	}
92
+
93
+    void PolygonalWireAntenna::Release() {
94
+		delete this;
95
+	}
96
+
97
+    void PolygonalWireAntenna::SetMinDipoleRatio (const Real& ratio) {
98
+        minDipoleRatio = ratio;
99
+    }
100
+
101
+    void PolygonalWireAntenna::SetMinDipoleMoment (const Real& m) {
102
+        minDipoleMoment = m;
103
+    }
104
+
105
+    void PolygonalWireAntenna::SetMaxDipoleMoment (const Real& m) {
106
+        maxDipoleMoment = m;
107
+    }
108
+
109
+	// ====================  OPERATIONS    =======================
110
+
111
+	void PolygonalWireAntenna::ApproximateWithElectricDipoles(const Vector3r &rp) {
112
+        // Only resplit if necessary. Save a few cycles if repeated
113
+        if ( (rRepeat-rp).norm() > 1e-16 ) {
114
+		    for (unsigned int id=0; id<Dipoles.size(); ++id) {
115
+			    Dipoles[id]->Delete();
116
+		    }
117
+		    Dipoles.clear();
118
+
119
+		    // loop over all segments
120
+		    for (int iseg=0; iseg<NumberOfPoints-1; ++iseg) {
121
+			    InterpolateLineSegment(Points.col(iseg), Points.col(iseg+1), rp);
122
+		    }
123
+            rRepeat = rp;
124
+
125
+        } else {
126
+            for (unsigned int id=0; id<Dipoles.size(); ++id) {
127
+                Dipoles[id]->SetFrequencies(Freqs);
128
+            }
129
+        }
130
+	}
131
+
132
+	Vector3r PolygonalWireAntenna::ClosestPointOnLine(const Vector3r &p1,
133
+					const Vector3r &p2, const Vector3r &tp) {
134
+
135
+		Vector3r v1 = p2 - p1;
136
+		Vector3r v2 = p1 - tp;
137
+		Vector3r v3 = p1 - p2;
138
+		Vector3r v4 = p2 - tp;
139
+
140
+		Real dot1 = v2.dot(v1);
141
+		Real dot2 = v1.dot(v1);
142
+		Real dot3 = v4.dot(v3);
143
+		Real dot4 = v3.dot(v3);
144
+		Real t1 = -1.*dot1/dot2;
145
+		Real t2 = -1.*dot3/dot4;
146
+
147
+		Vector3r pos =  p1+v1*t1 ;
148
+
149
+		// check if on line
150
+		//	else give back the closest end point
151
+		if ( t1>=0 && t2>=0. ) {
152
+			return pos;
153
+		} else if (t1<0) {
154
+			return p1;
155
+		} else {
156
+			return p2;
157
+		}
158
+	}
159
+
160
+	void PolygonalWireAntenna::PushXYZDipoles(const Vector3r &step,
161
+				    const Vector3r &cp, const Vector3r &dir,
162
+					std::vector<DipoleSource*> &xDipoles) {
163
+
164
+		Real scale = (Real)(NumberOfTurns)*Current;
165
+
166
+        DipoleSource *tx = DipoleSource::New();
167
+		    tx->SetLocation(cp);
168
+		    tx->SetType(UNGROUNDEDELECTRICDIPOLE);
169
+			tx->SetPolarisation(dir);
170
+			tx->SetFrequencies(Freqs);
171
+			tx->SetMoment(scale*step.norm());
172
+			xDipoles.push_back(tx);
173
+	}
174
+
175
+	void PolygonalWireAntenna::CorrectOverstepXYZDipoles(const Vector3r &step,
176
+				    const Vector3r &cp,	const Vector3r &dir,
177
+					std::vector<DipoleSource*> &xDipoles ) {
178
+
179
+		Real scale = (Real)(NumberOfTurns)*Current;
180
+
181
+		// X oriented dipoles
182
+		if (step.norm() > minDipoleMoment) {
183
+			xDipoles[xDipoles.size()-1]->SetLocation(cp);
184
+			xDipoles[xDipoles.size()-1]->SetMoment(scale*step.norm());
185
+		}
186
+	}
187
+
188
+	void PolygonalWireAntenna::InterpolateLineSegment(const Vector3r &p1,
189
+					const Vector3r &p2, const Vector3r & tp) {
190
+
191
+
192
+		Vector3r phat = (p1-p2).array() / (p1-p2).norm();
193
+		Vector3r c    = this->ClosestPointOnLine(p1, p2, tp);
194
+		Real dtp = (tp-c).norm();    // distance to point at c
195
+		Real dc1 = (p1-c).norm();    // distance to c from p1
196
+		Real dc2 = (p2-c).norm();    // distance to c from p1
197
+
198
+        // unit vector
199
+		Vector3r cdir = (p2-p1).array() / (p2-p1).norm();
200
+
201
+		///////////////////
202
+		// dipoles for this segment
203
+		std::vector<DipoleSource*>           xDipoles;
204
+
205
+		// go towards p1
206
+		if ( ((c-p1).array().abs() > minDipoleMoment).any() ) {
207
+
208
+			// cp = current pos, lp = last pos
209
+			Vector3r cp = c + phat*(dtp*minDipoleRatio)*.5;
210
+			Vector3r lp = c;
211
+ 			Real dist = (cp-p1).norm();
212
+ 			Real dist_old = dist+1.;
213
+
214
+			// check that we didn't run past the end, or that we aren't starting at
215
+			// the end, or that initial step runs over!
216
+			Vector3r dir = (p1-cp).array() / (p1-cp).norm();   // direction of movement
217
+			Vector3r step = phat*(dtp*minDipoleRatio);
218
+ 			Vector3r stepold = Vector3r::Zero();
219
+
220
+			// (dir-phat) just shows if we are stepping towards or away  from p1
221
+			while (dist < dist_old && (dir-phat).norm() < 1e-8) {
222
+
223
+				PushXYZDipoles(step, cp, cdir, xDipoles);
224
+
225
+				// Make 1/2 of previous step, 1/2 of this step, store this step
226
+				stepold  = step;
227
+				step     = phat*( (cp-tp).norm()*minDipoleRatio );
228
+			    while ( (step.array().abs() > maxDipoleMoment).any() ) {
229
+				    step *= .5;
230
+			    }
231
+				lp       = cp;
232
+				cp      += .5*stepold + .5*step;
233
+				dist     = (cp-p1).norm();
234
+				dir      = (p1-cp).array() / (p1-cp).norm();
235
+			}
236
+
237
+			// cp now points to end last of dipole moments
238
+			cp -= .5*step;
239
+
240
+			// Fix last dipole position, so that entire wire is represented,
241
+			// and no more
242
+			Real distLastSeg = (c - cp).norm();
243
+
244
+			if (distLastSeg + minDipoleMoment < dc1) {
245
+				// case 1: understep, add dipole
246
+				step  = (p1-cp).array();
247
+				cp   += .5*step;
248
+				PushXYZDipoles(step, cp, cdir, xDipoles);
249
+			} else if (distLastSeg > dc1 + minDipoleMoment) {
250
+				// case 2: overstep, reposition dipole and size
251
+				step  = (p1 - (lp-.5*stepold));
252
+				cp =  (lp-.5*stepold) + (.5*step);
253
+				CorrectOverstepXYZDipoles(step, cp, cdir, xDipoles);
254
+			}
255
+			// else case 0: nearly 'perfect' fit do nothing
256
+		}
257
+
258
+		// go towards p2
259
+		if ( ( (c-p2).array().abs() > minDipoleMoment).any() ) {
260
+
261
+ 			// cp = current pos, lp = last pos
262
+ 			Vector3r step = -phat*(dtp*minDipoleRatio);
263
+			while ( (step.array().abs() > maxDipoleMoment).any() ) {
264
+				step *= .5;
265
+			}
266
+
267
+ 			Vector3r cp = c + step*.5;
268
+ 			Vector3r lp = c;
269
+  			Real dist = (p2-cp).norm();
270
+  			Real dist_old = dist+1e3;
271
+
272
+			// check that we didn't run past the end, or that we aren't starting at
273
+			// the end, or that initial step runs over!
274
+			Vector3r dir = (p2-cp).array() / (p2-cp).norm();   // direction of movement
275
+
276
+ 			Vector3r stepold = Vector3r::Zero();
277
+
278
+ 			// (dir-phat) just shows if we are stepping towards or away  from p1
279
+ 			while (dist < dist_old && (dir+phat).norm() < 1e-8) {
280
+
281
+ 				PushXYZDipoles(step, cp, cdir, xDipoles);
282
+
283
+				// Make 1/2 of previous step, 1/2 of this step, store this step
284
+				stepold  = step;
285
+				step     = -phat*( (cp-tp).norm()*minDipoleRatio );
286
+			    while ( (step.array().abs() > maxDipoleMoment).any() ) {
287
+				    step *= .5;
288
+			    }
289
+				lp       = cp;
290
+				cp      += .5*stepold + .5*step;
291
+				dist     = (cp-p2).norm();
292
+				dir      = (p2-cp).array() / (p2-cp).norm();
293
+			}
294
+
295
+			// cp now points to end last of dipole moments
296
+			cp -= .5*step;
297
+
298
+			// Fix last dipole position, so that entire wire is represented,
299
+			// and no more
300
+			Real distLastSeg = (c - cp).norm();
301
+			if (distLastSeg + minDipoleMoment < dc2) {
302
+				// case 1: understep, add dipole
303
+				step  = (p2-cp).array();
304
+				cp   += .5*step;
305
+				PushXYZDipoles(step, cp, cdir, xDipoles);
306
+
307
+			} else if (distLastSeg > dc2 + minDipoleMoment) {
308
+
309
+				// case 2: overstep, reposition dipole and size
310
+				step  = (p2 - (lp-.5*stepold));
311
+				cp =  (lp-.5*stepold) + (.5*step);
312
+				CorrectOverstepXYZDipoles(step, cp, cdir, xDipoles);
313
+
314
+			}
315
+			// else case 0: nearly 'perfect' fit do nothing
316
+		}
317
+		Dipoles.insert(Dipoles.end(), xDipoles.begin(), xDipoles.end());
318
+	}
319
+
320
+    #ifdef HAVE_YAMLCPP
321
+
322
+    //--------------------------------------------------------------------------------------
323
+    //       Class:  PolygonalWireAntenna
324
+    //      Method:  Serialize
325
+    //--------------------------------------------------------------------------------------
326
+    YAML::Node PolygonalWireAntenna::Serialize (  ) const {
327
+        YAML::Node node = WireAntenna::Serialize();
328
+        node.SetTag( this->Name );
329
+        node["minDipoleRatio"]  = minDipoleRatio;
330
+        node["maxDipoleMoment"] = maxDipoleMoment;
331
+        node["minDipoleMoment"] = minDipoleMoment;
332
+        return node;
333
+    }		// -----  end of method PolygonalWireAntenna::Serialize  -----
334
+
335
+
336
+    //--------------------------------------------------------------------------------------
337
+    //       Class:  WireAntenna
338
+    //      Method:  DeSerialize
339
+    //--------------------------------------------------------------------------------------
340
+    PolygonalWireAntenna* PolygonalWireAntenna::DeSerialize ( const YAML::Node& node ) {
341
+        PolygonalWireAntenna* Object = new PolygonalWireAntenna(node);
342
+        Object->AttachTo(Object);
343
+        DESERIALIZECHECK( node, Object )
344
+        return Object ;
345
+    }		// -----  end of method WireAntenna::DeSerialize  -----
346
+
347
+    #endif
348
+
349
+}

+ 332
- 0
Modules/FDEM1D/src/QWEKey.cpp View File

@@ -0,0 +1,332 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/*      Original code is port of algorithm published by Key2011
11
+        %------------------------------------------------------------------%
12
+        % Copyright (c) 2012 by the Society of Exploration Geophysicists.  %
13
+        % For more information, go to http://software.seg.org/2012/0003 .  %
14
+        % You must read and accept usage terms at:                         %
15
+        % http://software.seg.org/disclaimer.txt before use.               %
16
+        %------------------------------------------------------------------%
17
+*/
18
+
19
+/**
20
+ * @file
21
+ * @date      02/12/2014 10:28:15 AM
22
+ * @version   $Id$
23
+ * @author    Trevor Irons (ti)
24
+ * @email     Trevor.Irons@xri-geo.com
25
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
26
+ * @copyright Copyright (c) 2014, Trevor Irons
27
+ */
28
+
29
+#include "QWEKey.h"
30
+
31
+//#include <Eigen/Eigenvalues>
32
+
33
+namespace Lemma {
34
+
35
+    // ====================  FRIEND METHODS  =====================
36
+
37
+    std::ostream &operator<<(std::ostream &stream, const QWEKey &ob) {
38
+
39
+        stream << *(HankelTransform*)(&ob);
40
+
41
+        return stream;
42
+    }
43
+
44
+    // ====================  LIFECYCLE     =======================
45
+
46
+    //--------------------------------------------------------------------------------------
47
+    //       Class:  QWEKey
48
+    //      Method:  QWEKey
49
+    // Description:  constructor (protected)
50
+    //--------------------------------------------------------------------------------------
51
+    //
52
+    QWEKey::QWEKey (const std::string& name) : HankelTransform(name), RelTol(1e-12), AbsTol(1e-32), nQuad(61), nDelay(1),
53
+    //QWEKey::QWEKey (const std::string& name) : HankelTransform(name), RelTol(1e-38), AbsTol(1e-48), nQuad(39), nDelay(5),
54
+        nIntervalsMax(40) {
55
+        BesselWeights( J0 ); // TODO experiment with zero weight (J0, J1) options, should be static one time method
56
+    }  // -----  end of method QWEKey::QWEKey  (constructor)  -----
57
+
58
+
59
+    //--------------------------------------------------------------------------------------
60
+    //       Class:  QWEKey
61
+    //      Method:  New()
62
+    // Description:  public constructor
63
+    //--------------------------------------------------------------------------------------
64
+    QWEKey* QWEKey::New() {
65
+        QWEKey*  Obj = new QWEKey("QWEKey");
66
+        Obj->AttachTo(Obj);
67
+        return Obj;
68
+    }
69
+
70
+    //--------------------------------------------------------------------------------------
71
+    //       Class:  QWEKey
72
+    //      Method:  ~QWEKey
73
+    // Description:  destructor (protected)
74
+    //--------------------------------------------------------------------------------------
75
+    QWEKey::~QWEKey () {
76
+
77
+    }  // -----  end of method QWEKey::~QWEKey  (destructor)  -----
78
+
79
+    //--------------------------------------------------------------------------------------
80
+    //       Class:  QWEKey
81
+    //      Method:  Delete
82
+    // Description:  public destructor
83
+    //--------------------------------------------------------------------------------------
84
+    void QWEKey::Delete() {
85
+        this->DetachFrom(this);
86
+    }
87
+
88
+    //--------------------------------------------------------------------------------------
89
+    //       Class:  QWEKey
90
+    //      Method:  Release
91
+    // Description:  destructor (protected)
92
+    //--------------------------------------------------------------------------------------
93
+    void QWEKey::Release() {
94
+        delete this;
95
+    }
96
+
97
+    //--------------------------------------------------------------------------------------
98
+    //       Class:  QWEKey
99
+    //      Method:  Zgauss
100
+    //--------------------------------------------------------------------------------------
101
+    Complex QWEKey::Zgauss ( const int &ikk, const EMMODE &imode,
102
+                            const int &itype, const Real &rho,
103
+                            const Real &wavef, KernelEm1DBase *Kernel ) {
104
+        return Textrap(Kernel->GetManagerIndex(), Tn(Kernel->GetManagerIndex())) ;
105
+    }		// -----  end of method QWEKey::Zgauss  -----
106
+
107
+    //--------------------------------------------------------------------------------------
108
+    //       Class:  QWEKey
109
+    //      Method:  ComputeRelated
110
+    //--------------------------------------------------------------------------------------
111
+    void QWEKey::ComputeRelated ( const Real& rho, KernelEm1DBase* Kernel ) {
112
+        return ;
113
+    }		// -----  end of method QWEKey::ComputeRelated  -----
114
+
115
+    //--------------------------------------------------------------------------------------
116
+    //       Class:  QWEKey
117
+    //      Method:  ComputeRelated
118
+    //--------------------------------------------------------------------------------------
119
+    void QWEKey::ComputeRelated ( const Real& rho, std::vector< KernelEm1DBase* > KernelVec ) {
120
+        return ;
121
+    }		// -----  end of method QWEKey::ComputeRelated  -----
122
+
123
+    //--------------------------------------------------------------------------------------
124
+    //       Class:  QWEKey
125
+    //      Method:  ComputeRelated
126
+    //--------------------------------------------------------------------------------------
127
+    void QWEKey::ComputeRelated ( const Real& rho, KernelEM1DManager* KernelManagerIn ) {
128
+        KernelManager = KernelManagerIn;  // OK becauase this is internal and we know what we are doing
129
+
130
+        Lambda = Bx.array()/rho;
131
+        Intervals = xInt.array()/rho;
132
+        int nrel = (int)(KernelManager->GetSTLVector().size());
133
+        Zans = Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic>::Zero(1, nrel);
134
+        QWE(rho);
135
+        return ;
136
+    }		// -----  end of method QWEKey::ComputeRelated  -----
137
+
138
+    //--------------------------------------------------------------------------------------
139
+    //       Class:  QWEKey
140
+    //      Method:  GaussQuadWeights
141
+    //--------------------------------------------------------------------------------------
142
+    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);
153
+    }
154
+
155
+    //--------------------------------------------------------------------------------------
156
+    //       Class:  QWEKey
157
+    //      Method:  BesselWeights
158
+    //--------------------------------------------------------------------------------------
159
+    void QWEKey::BesselWeights ( const sZeroType& sType ) {
160
+    #ifdef HAVEBOOSTSPECIALFUNCTIONS
161
+        GaussQuadWeights(nQuad); // TODO should this be moved out of initializer?
162
+        std::vector<Real> bz;
163
+        xInt = VectorXr(nIntervalsMax+1);
164
+        xInt(0) = 1e-20;
165
+        switch (sType) {
166
+            case J0:
167
+                boost::math::cyl_bessel_j_zero(0.0, 1, nIntervalsMax, std::back_inserter(bz));
168
+                xInt.tail(nIntervalsMax) = VectorXr::Map(&bz[0], nIntervalsMax);
169
+                break;
170
+            case J1:
171
+                boost::math::cyl_bessel_j_zero(1.0, 1, nIntervalsMax, std::back_inserter(bz));
172
+                xInt.tail(nIntervalsMax) = VectorXr::Map(&bz[0], nIntervalsMax);
173
+                break;
174
+            case NPI:
175
+                xInt << 1e-20, VectorXr::LinSpaced(nIntervalsMax, 1, nIntervalsMax).array() * PI;
176
+                break;
177
+        }
178
+        VectorXr dx = ( xInt.tail(nIntervalsMax) - xInt.head(nIntervalsMax) ).array() / 2.;
179
+        //  x = GaussAbscissa
180
+        //        dx in every row        GaussWeights+1 rows, cols = n
181
+        //     dx[0] dx[1] ... dx[N]       Gw[0]  Gw[0]  ... ndX
182
+        //     dx[0] dx[1] ... dx[N]       Gw[1]
183
+        MatrixXr Bxm = (dx.transpose().replicate(GaussAbscissa.size(), 1)).eval().array() *
184
+                 ((GaussAbscissa.replicate(1, dx.size()).array() + 1.));
185
+        Bxm.array() += xInt.head(Bxm.cols()).transpose().replicate( Bxm.rows(), 1 ).array();
186
+        Bx =  VectorXr::Map( &Bxm(0,0), Bxm.size() );
187
+        BJ0 = VectorXr(Bx.size());
188
+        BJ1 = VectorXr(Bx.size());
189
+        int iw = 0;
190
+        for (int ii=0; ii<Bx.size(); ++ii) {
191
+            BJ0(ii) = boost::math::cyl_bessel_j(0, Bx(ii)) * GaussWeights(iw);
192
+            BJ1(ii) = boost::math::cyl_bessel_j(1, Bx(ii)) * GaussWeights(iw);
193
+            ++iw;
194
+            if (iw == GaussWeights.size()) iw = 0;
195
+        }
196
+        return ;
197
+    # else
198
+        std::cerr  << "QWEKey requires Boost functionalility that is missing\n";
199
+    #endif
200
+    }		// -----  end of method QWEKey::BesselWeights  -----
201
+
202
+
203
+    //--------------------------------------------------------------------------------------
204
+    //       Class:  QWEKey
205
+    //      Method:  QWE
206
+    //--------------------------------------------------------------------------------------
207
+    void QWEKey::QWE ( const Real& rho ) {
208
+
209
+        // TODO, is -1 needed here?
210
+        int nTerms = nIntervalsMax - nDelay;// - 1;
211
+        int nrel = (int)(KernelManager->GetSTLVector().size());
212
+
213
+        // TODO GREMLINS LIVE IN HERE
214
+        MatrixXcr prev = Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic>::Zero(1, nrel);
215
+        for (int i=0; i<nDelay; ++i) {
216
+            getEyKernel(i, 0, rho);
217
+            prev += Zans;
218
+        }
219
+
220
+        // Some of these are complex
221
+        TS      = MatrixXcr::Zero(nrel, nTerms);
222
+        Tn      = VectorXi::Zero(nrel);
223
+        Textrap = MatrixXcr::Zero(nrel, nTerms);
224
+        TrelErr = MatrixXr::Zero(nrel, nTerms);
225
+        TabsErr = MatrixXr::Zero(nrel, nTerms);
226
+        VectorXi Converged = VectorXi::Zero(nrel);
227
+
228
+        // is nTerms right, 1 array shifting
229
+        for (int i=nDelay; i<nTerms; ++i) {
230
+
231
+            int n = i-nDelay;
232
+            getEyKernel(i, 0, rho);
233
+
234
+            for (int j=0; j<nrel; ++j) {
235
+
236
+                if (!Converged(j)) { //continue;
237
+
238
+                    Tn(j) = n;                            // order of the expansion
239
+                    TS(j,n+1) = TS(j, n) + Zans(0, j);    // working array for transformation
240
+
241
+                    /* Compute the Shanks transform using the Epsilon algorithm:
242
+                        Structured after Weniger (1989, p26) */
243
+                    /* TI - some kind ob bug here, shanks extrapolation doesn't buy much for TEM at least */
244
+                    Complex aux2(0);
245
+                    for (int k=n+1; k>0; --k) {
246
+                        Complex aux1 = aux2;
247
+                        aux2 = TS(j,k-1);
248
+                        Complex ddff = TS(j,k) - aux2;
249
+                        if (std::abs(ddff) < std::numeric_limits<Real>::min() ) {
250
+                            TS(j,k-1) = std::numeric_limits<Real>::max() ;
251
+                        } else {
252
+                            TS(j,k-1) = aux1 + 1./ddff;
253
+                        }
254
+
255
+                    }
256
+
257
+                    // The extrapolated result plus the prev integration term:
258
+                    Textrap(j,n) = TS(j, (n-1)%2)+prev(0, j);
259
+                    //Textrap(j,n) = TS(j, n%2 + 1)+prev(0, j);
260
+
261
+                    // Step 3: Analyze for convergence:
262
+                    if (n > 1) {
263
+                        TabsErr(j,n) = std::abs( Textrap(j, n) - Textrap(j, n-1));
264
+                        TrelErr(j,n) = TabsErr(j, n) / std::abs(Textrap(j, n)) ;
265
+                        Converged(j) = TrelErr(j,n) < RelTol + AbsTol/std::abs(Textrap(j,n));
266
+                    }
267
+                }
268
+            }
269
+            if ( Converged.all() == 1 ) break;
270
+        }
271
+
272
+        // Trim up results
273
+        // Clean up the T structure arrays? We can't really do this
274
+        // because they are fixed size, maybe see how they are used and
275
+        // init to zero. If they are only summed we are OK.
276
+        /*
277
+        for (int j = 0; j<nrel; ++j) {:nKernels
278
+            n = Tn(j);
279
+            T(j).extrap = T(j).extrap(1:n);
280
+            T(j).relErr = T(j).relErr(1:n);
281
+            T(j).absErr = T(j).absErr(1:n);
282
+        }
283
+        */
284
+        return ;
285
+    }		// -----  end of method QWEKey::QWE  -----
286
+
287
+
288
+    //--------------------------------------------------------------------------------------
289
+    //       Class:  QWEKey
290
+    //      Method:  getEyKernel
291
+    //--------------------------------------------------------------------------------------
292
+    void QWEKey::getEyKernel ( const int& i, const int& idx, const Real& rho ) {
293
+        int bidx = i*nQuad;
294
+        int nrel = (int)(KernelManager->GetSTLVector().size());
295
+        Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic > Zwork =
296
+            Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic>::Zero(nQuad, nrel);
297
+        for (int ik=0; ik<nQuad; ++ik) {
298
+            KernelManager->ComputeReflectionCoeffs( Lambda(bidx+ik), idx, rho );
299
+            for (int ir2=0; ir2<nrel; ++ir2) {
300
+                // Zwork* needed due to sign convention (e^-jwt) of FT in filter weights
301
+ 			    Zwork(ik, ir2) =    std::conj(KernelManager->GetSTLVector()[ir2]->RelBesselArg(Lambda(bidx+ik)));
302
+ 			}
303
+        }
304
+
305
+        Real bma  = (Intervals(i+1)-Intervals(i))/2;
306
+        for (int ir2=0; ir2<nrel; ++ir2) {
307
+            if (KernelManager->GetSTLVector()[ir2]->GetBesselOrder() == 0) {
308
+                Zans(0, ir2) = bma * Zwork.col(ir2).dot( BJ0.segment(bidx, nQuad) ); // / rho;
309
+            } else {
310
+                Zans(0, ir2) = bma * Zwork.col(ir2).dot( BJ1.segment(bidx, nQuad) ); // / rho;
311
+            }
312
+        }
313
+        // fcount += nQuad
314
+        return ;
315
+    }		// -----  end of method QWEKey::getEyKernel  -----
316
+
317
+    void QWEKey::TestPrivate(const int& N) {
318
+
319
+        //GaussQuadWeights(N);
320
+        //std::cout << "abscissa\n" << GaussAbscissa << std::endl;
321
+        //std::cout << "weights\n" << GaussWeights << std::endl;
322
+        BesselWeights( J1 );
323
+        //BesselZeros(0, N);
324
+        std::cout << std::scientific;
325
+        std::cout << "BJ0" << BJ0 << std::endl;
326
+        std::cout << "BJ1" << BJ1 << std::endl;
327
+        //std::cout << "Bess Zero\n" << xInt << std::endl;
328
+
329
+    }
330
+
331
+}		// -----  end of Lemma  name  -----
332
+

+ 84
- 0
Modules/FDEM1D/src/UngroundedElectricDipole.cpp View File

@@ -0,0 +1,84 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      01/29/2014 08:55:18 AM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#include "UngroundedElectricDipole.h"
21
+
22
+namespace Lemma {
23
+
24
+    // ====================  FRIEND METHODS  =====================
25
+
26
+    std::ostream &operator<<(std::ostream &stream, const UngroundedElectricDipole &ob) {
27
+
28
+        stream << *(DipoleSource*)(&ob);
29
+
30
+        return stream;
31
+    }
32
+
33
+    // ====================  LIFECYCLE     =======================
34
+
35
+    //--------------------------------------------------------------------------------------
36
+    //       Class:  UngroundedElectricDipole
37
+    //      Method:  UngroundedElectricDipole
38
+    // Description:  constructor (protected)
39
+    //--------------------------------------------------------------------------------------
40
+    UngroundedElectricDipole::UngroundedElectricDipole (const std::string& name) : DipoleSource(name) {
41
+
42
+    }  // -----  end of method UngroundedElectricDipole::UngroundedElectricDipole  (constructor)  -----
43
+
44
+
45
+    //--------------------------------------------------------------------------------------
46
+    //       Class:  UngroundedElectricDipole
47
+    //      Method:  New()
48
+    // Description:  public constructor
49
+    //--------------------------------------------------------------------------------------
50
+    UngroundedElectricDipole* UngroundedElectricDipole::New() {
51
+        UngroundedElectricDipole*  Obj = new UngroundedElectricDipole("UngroundedElectricDipole");
52
+        Obj->AttachTo(Obj);
53
+        return Obj;
54
+    }
55
+
56
+    //--------------------------------------------------------------------------------------
57
+    //       Class:  UngroundedElectricDipole
58
+    //      Method:  ~UngroundedElectricDipole
59
+    // Description:  destructor (protected)
60
+    //--------------------------------------------------------------------------------------
61
+    UngroundedElectricDipole::~UngroundedElectricDipole () {
62
+
63
+    }  // -----  end of method UngroundedElectricDipole::~UngroundedElectricDipole  (destructor)  -----
64
+
65
+    //--------------------------------------------------------------------------------------
66
+    //       Class:  UngroundedElectricDipole
67
+    //      Method:  Delete
68
+    // Description:  public destructor
69
+    //--------------------------------------------------------------------------------------
70
+    void UngroundedElectricDipole::Delete() {
71
+        this->DetachFrom(this);
72
+    }
73
+
74
+    //--------------------------------------------------------------------------------------
75
+    //       Class:  UngroundedElectricDipole
76
+    //      Method:  Release
77
+    // Description:  destructor (protected)
78
+    //--------------------------------------------------------------------------------------
79
+    void UngroundedElectricDipole::Release() {
80
+        delete this;
81
+    }
82
+
83
+}		// -----  end of Lemma  name  -----
84
+

+ 293
- 0
Modules/FDEM1D/src/WireAntenna.cpp View File

@@ -0,0 +1,293 @@
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/16/2009
11
+  @version  $Id: wireantenna.cpp 199 2014-12-29 19:25:20Z tirons $
12
+ **/
13
+
14
+#include "WireAntenna.h"
15
+
16
+namespace Lemma {
17
+
18
+    #ifdef HAVE_YAMLCPP
19
+    std::ostream &operator << (std::ostream &stream, const WireAntenna &ob) {
20
+        stream << ob.Serialize()  << "\n---\n"; // End of doc --- as a direct stream should encapulste thingy
21
+        return stream;
22
+    }
23
+    #else
24
+    std::ostream &operator<<(std::ostream &stream,
25
+                const WireAntenna &ob) {
26
+
27
+        stream << *(LemmaObject*)(&ob);
28
+        stream << "Current: " << ob.Current << " [A]\n";
29
+        stream << "Frequencies: " << ob.Freqs.transpose() << " [Hz]\n";
30
+        stream << "Number of points " << ob.NumberOfPoints << "\n";
31
+        stream << "Number of turns " << ob.NumberOfTurns << "\n";
32
+
33
+        if (ob.NumberOfPoints) {
34
+            stream << "Points:\n" << ob.Points.transpose() << "\n";
35
+            //stream << "Dipoles used to approximate " << ob.Dipoles.size() << "\n";
36
+        }
37
+        return stream;
38
+    }
39
+    #endif
40
+    // ====================  LIFECYCLE     =======================
41
+
42
+    WireAntenna::WireAntenna(const std::string &name) :
43
+        LemmaObject(name),
44
+        NumberOfPoints(0), Current(1), NumberOfTurns(1) {
45
+    }
46
+
47
+#ifdef HAVE_YAMLCPP
48
+    WireAntenna::WireAntenna(const YAML::Node &node) :
49
+        LemmaObject(node) {
50
+        Points =  node["Points"].as<Vector3Xr>();
51
+        Freqs = node["Freqs"].as<VectorXr>();
52
+        NumberOfPoints = node["NumberOfPoints"].as<int>();
53
+        NumberOfTurns = node["NumberOfTurns"].as<int>();
54
+        Current = node["Current"].as<Real>();
55
+    }
56
+#endif
57
+
58
+    WireAntenna::~WireAntenna() {
59
+        for (unsigned int id=0; id<Dipoles.size(); ++id) {
60
+            Dipoles[id]->Delete();
61
+        }
62
+        Dipoles.clear();
63
+        if (this->NumberOfReferences != 0) {
64
+            throw DeleteObjectWithReferences(this);
65
+        }
66
+    }
67
+
68
+    WireAntenna* WireAntenna::New() {
69
+        WireAntenna* Obj = new WireAntenna("WireAntenna");
70
+        Obj->AttachTo(Obj);
71
+        return Obj;
72
+    }
73
+
74
+    WireAntenna* WireAntenna::Clone() {
75
+        WireAntenna* copy = WireAntenna::New();
76
+		//copy->AttachTo(copy); // NO! Attached above!
77
+		copy->NumberOfPoints = this->NumberOfPoints;
78
+		copy->Freqs = this->Freqs;
79
+		copy->Current = this->Current;
80
+		copy->NumberOfTurns = this->NumberOfTurns;
81
+		copy->Points = this->Points;
82
+		//copy->Dipoles = this->Dipoles; // no, disaster
83
+		return copy;
84
+    }
85
+
86
+    void WireAntenna::Delete() {
87
+        this->DetachFrom(this);
88
+    }
89
+
90
+    void WireAntenna::Release() {
91
+        delete this;
92
+    }
93
+
94
+
95
+    // ====================  ACCESS        =======================
96
+
97
+    void WireAntenna::SetNumberOfTurns(const int &nturns) {
98
+        this->NumberOfTurns = nturns;
99
+    }
100
+
101
+    int WireAntenna::GetNumberOfTurns( ) {
102
+        return this->NumberOfTurns;
103
+    }
104
+
105
+    void WireAntenna::SetNumberOfPoints(const int &np) {
106
+        Points.resize( Eigen::NoChange, np);
107
+        NumberOfPoints = np;
108
+    }
109
+
110
+    void WireAntenna::SetNumberOfFrequencies(const int &nfreq){
111
+        Freqs.resize(nfreq);
112
+        Freqs.setZero();
113
+    }
114
+
115
+    void WireAntenna::SetFrequency(const int& ifreq, const Real & freq) {
116
+        assert(ifreq < Freqs.size());
117
+        this->Freqs[ifreq] = freq;
118
+    }
119
+
120
+    Real WireAntenna::GetFrequency(const int& ifreq) {
121
+        return this->Freqs[ifreq];
122
+    }
123
+
124
+    int WireAntenna::GetNumberOfFrequencies() {
125
+        return Freqs.size();
126
+    }
127
+
128
+    Vector3Xr WireAntenna::GetPoints() {
129
+        return Points;
130
+    }
131
+
132
+    MatrixXr WireAntenna::GetPointsMat() {
133
+        return MatrixXr(Points.transpose());
134
+    }
135
+
136
+    void WireAntenna::SetCurrent(const Real &amps) {
137
+        this->Current = amps;
138
+    }
139
+
140
+    Real WireAntenna::GetCurrent( ) {
141
+        return this->Current;
142
+    }
143
+
144
+    void WireAntenna::SetPoint(const int &p, const Vector3r& pos) {
145
+
146
+        if (p >= 0 && p<NumberOfPoints )    {
147
+            Points.col(p) = pos;
148
+        } else {
149
+            throw  7;
150
+        }
151
+
152
+    }
153
+
154
+    void WireAntenna::SetPoint(const int &p, const Real& x, const Real& y, const Real& z) {
155
+
156
+        if (p >= 0 && p<NumberOfPoints )    {
157
+            Points.col(p) = Vector3r(x,y,z);
158
+        } else {
159
+            throw  7;
160
+        }
161
+
162
+    }
163
+
164
+
165
+    void WireAntenna::ApproximateWithElectricDipoles(const Real &deltai) {
166
+
167
+        // Get rid of any dipoles
168
+        for (unsigned int id=0; id<Dipoles.size(); ++id) {
169
+            Dipoles[id]->Delete();
170
+        }
171
+        Dipoles.clear();
172
+
173
+        Real Dist(0);
174
+        Vector3r r;
175
+        Vector3r p;
176
+
177
+        for (int ip=0; ip<NumberOfPoints-1; ++ip) {
178
+
179
+            Dist = (Points.col(ip+1) - Points.col(ip)).norm();
180
+            r = (Points.col(ip+1) - Points.col(ip))/Dist;
181
+
182
+            int nd = (int)(Dist/deltai);
183
+            Real add = (Dist - (Real)(nd)*deltai) / (Real)(nd);
184
+            Real delta = deltai + add;
185
+            Real scale = (Real)(NumberOfTurns)*Current;
186
+
187
+            p = Points.col(ip) + .5*delta*r;
188
+
189
+            for (Real id=0.; id<Dist-delta/2; id+=delta) {
190
+
191
+                // X dipoles
192
+                if (std::abs(r[0]) > 1e-6) {
193
+                    DipoleSource *tx = DipoleSource::New();
194
+                    tx->SetLocation(p);
195
+                    tx->SetType(GROUNDEDELECTRICDIPOLE);
196
+                    tx->SetPolarisation(XPOLARISATION);
197
+                    tx->SetFrequencies(Freqs);
198
+                    tx->SetMoment(scale*delta*r[0]);
199
+                    Dipoles.push_back(tx);
200
+                }
201
+
202
+                // Y dipoles
203
+                if (std::abs(r[1]) > 1e-6) {
204
+                    DipoleSource *ty = DipoleSource::New();
205
+                    ty->SetLocation(p);
206
+                    ty->SetType(GROUNDEDELECTRICDIPOLE);
207
+                    ty->SetPolarisation(YPOLARISATION);
208
+                    ty->SetFrequencies(Freqs);
209
+                    ty->SetMoment(scale*delta*r[1]);
210
+                    Dipoles.push_back(ty);
211
+                }
212
+
213
+                // Z dipoles
214
+                if (std::abs(r[2]) > 1e-6) {
215
+                    DipoleSource *tz = DipoleSource::New();
216
+                    tz->SetLocation(p);
217
+                    tz->SetType(GROUNDEDELECTRICDIPOLE);
218
+                    tz->SetPolarisation(ZPOLARISATION);
219
+                    tz->SetFrequencies(Freqs);
220
+                    tz->SetMoment(scale*delta*r[2]);
221
+                    Dipoles.push_back(tz);
222
+                }
223
+
224
+                p += delta*r;
225
+
226
+            }
227
+        }
228
+    }
229
+
230
+    // ====================  INQUIRY       =======================
231
+
232
+    int WireAntenna::GetNumberOfDipoles() {
233
+        return Dipoles.size();
234
+    }
235
+
236
+    DipoleSource* WireAntenna::GetDipoleSource(const int &dip) {
237
+        return this->Dipoles[dip];
238
+    }
239
+
240
+    #ifdef LEMMAUSEVTK
241
+    vtkActor* WireAntenna::GetVtkActor(const int &idip) {
242
+        return Dipoles[idip]->GetVtkActor();
243
+    }
244
+    #endif
245
+
246
+    #ifdef HAVE_YAMLCPP
247
+    //--------------------------------------------------------------------------------------
248
+    //       Class:  WireAntenna
249
+    //      Method:  Serialize
250
+    //--------------------------------------------------------------------------------------
251
+    YAML::Node WireAntenna::Serialize (  ) const {
252
+        YAML::Node node = LemmaObject::Serialize();
253
+        node.SetTag( this->Name );
254
+        node["NumberOfPoints"] = NumberOfPoints;
255
+        node["NumberOfTurns"] = NumberOfTurns;
256
+        node["Current"] = Current;
257
+        node["Points"] = Points;
258
+        node["Freqs"] = Freqs;
259
+        return node;
260
+    }		// -----  end of method WireAntenna::Serialize  -----
261
+
262
+
263
+    //--------------------------------------------------------------------------------------
264
+    //       Class:  WireAntenna
265
+    //      Method:  DeSerialize
266
+    //--------------------------------------------------------------------------------------
267
+    WireAntenna* WireAntenna::DeSerialize ( const YAML::Node& node ) {
268
+        WireAntenna* Object = new WireAntenna(node);
269
+        Object->AttachTo(Object);
270
+        DESERIALIZECHECK( node, Object )
271
+        return Object ;
272
+    }		// -----  end of method WireAntenna::DeSerialize  -----
273
+
274
+    #endif
275
+
276
+
277
+    //--------------------------------------------------------------------------------------
278
+    //       Class:  WireAntenna
279
+    //      Method:  IsPlanar
280
+    //--------------------------------------------------------------------------------------
281
+    bool WireAntenna::IsHorizontallyPlanar (  ) {
282
+        //for (int ip=0; ip<NumberOfPoints; ++ip) {
283
+        //   std::cout << Points(2,ip) << std::endl;
284
+        //}
285
+        if ( std::abs(Points.row(2).sum() - (NumberOfPoints*Points(2,0))) < 1e-5 ) {
286
+            return true ;
287
+        } else {
288
+            return false;
289
+        }
290
+    }		// -----  end of method WireAntenna::IsPlanar  -----
291
+
292
+
293
+}

+ 345
- 0
Modules/FDEM1D/src/dipolefreqsweep.cpp View File

@@ -0,0 +1,345 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      01/29/2014 09:53:49 PM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#include <iostream>
21
+#include <fstream>
22
+#include "dipolesource.h"
23
+#include "layeredearthem.h"
24
+#include "receiverpoints.h"
25
+#include "emearth1d.h"
26
+
27
+#ifdef LEMMAUSEOMP
28
+#include "omp.h"
29
+#endif
30
+
31
+// For testing purposes disable VTK and run scale.sh
32
+//#undef LEMMAUSEVTK
33
+//#undef KIHALEE_EM1D
34
+
35
+#ifdef LEMMAUSEVTK
36
+#include "vtkRenderer.h"
37
+#include "vtkRenderWindow.h"
38
+#include "vtkRenderWindowInteractor.h"
39
+#include "vtkDoubleArray.h"
40
+#include "vtkXYPlotActor.h"
41
+#include "vtkXYPlotWidget.h"
42
+#include "vtkProperty2D.h"
43
+#endif
44
+
45
+#include "timer.h"
46
+
47
+using namespace Lemma;
48
+
49
+int main() {
50
+
51
+    // Do calculation
52
+    jsw_timer timer;
53
+
54
+    DipoleSource *dipole = DipoleSource::New();
55
+    dipole->SetType(MAGNETICDIPOLE);
56
+        dipole->SetPolarisation(0., 0.0,  1.0);
57
+        //dipole->SetPolarisation(XPOLARISATION);
58
+        //dipole->SetPolarisation(YPOLARISATION);
59
+        //dipole->SetPolarisation(ZPOLARISATION);
60
+
61
+        //dipole->SetMoment(1);
62
+        //dipole->SetLocation(1,1,-.0100328);
63
+        dipole->SetLocation(0., 0., -0.001);
64
+        //dipole->SetLocation(-2.5,1.25,0);
65
+        int iif=10000;
66
+        dipole->SetNumberOfFrequencies(iif);
67
+        Real w0 = 10;
68
+        for (int iw=0; iw<iif; ++iw) {
69
+            dipole->SetFrequency(iw, w0);
70
+            w0 += 1523.;
71
+        }
72
+
73
+    VectorXcr sigma(8);
74
+    sigma << 0., 3e-4, 5e-4, 1e-2, .5, 5e-6, .03, .04;
75
+    VectorXr  thick(6);
76
+        thick << 10 , 10 , 10 , 10 , 10 , 10;
77
+
78
+    LayeredEarthEM *earth = LayeredEarthEM::New();
79
+        earth->SetNumberOfLayers(8);
80
+        earth->SetLayerConductivity(sigma);
81
+        earth->SetLayerThickness(thick);
82
+
83
+    ReceiverPoints *receivers = ReceiverPoints::New();
84
+        Vector3r loc;
85
+        receivers->SetNumberOfReceivers(1);
86
+        loc << 150, 175, -.01;
87
+        receivers->SetLocation(0, loc);
88
+
89
+    // EmEarth
90
+    EMEarth1D  *EmEarth = EMEarth1D::New();
91
+        EmEarth->AttachDipoleSource(dipole);
92
+        EmEarth->AttachLayeredEarthEM(earth);
93
+        EmEarth->AttachReceiverPoints(receivers);
94
+        //EmEarth->SetFieldsToCalculate(BOTH);
95
+        EmEarth->SetFieldsToCalculate(H);
96
+
97
+        //EmEarth->SetHankelTransformMethod(GAUSSIANQUADRATURE);
98
+        //EmEarth->SetHankelTransformMethod(DIGITALFILTERING);
99
+        //EmEarth->SetHankelTransformMethod(FHTKEY201);
100
+        EmEarth->SetHankelTransformMethod(QWEKEY);
101
+
102
+    timer.begin();
103
+    EmEarth->MakeCalc3();
104
+    //std::cout << "H\n" << receivers->GetHfield(0)
105
+    //          << "End of H" << std::endl;
106
+    Real  lemmaTime = timer.end();
107
+    //std::cout << receivers->GetHfield() << std::endl;
108
+    std::cout << lemmaTime << "\t";
109
+
110
+    #ifdef LEMMAUSEVTK
111
+    vtkDataObject *_dataObjectxr = receivers->GetVtkDataObjectFreq(HFIELDREAL, 0,
112
+                    0, iif, XCOMPONENT, dipole->GetFrequencies());
113
+
114
+    vtkDataObject *_dataObjectxi = receivers->GetVtkDataObjectFreq(HFIELDIMAG, 0,
115
+                    0, iif, XCOMPONENT, dipole->GetFrequencies());
116
+
117
+    vtkDataObject *_dataObjectyr= receivers->GetVtkDataObjectFreq(HFIELDREAL, 0,
118
+                    0, iif, YCOMPONENT, dipole->GetFrequencies());
119
+
120
+    vtkDataObject *_dataObjectyi = receivers->GetVtkDataObjectFreq(HFIELDIMAG, 0,
121
+                    0, iif, YCOMPONENT, dipole->GetFrequencies());
122
+
123
+    vtkDataObject *_dataObjectzr = receivers->GetVtkDataObjectFreq(HFIELDREAL, 0,
124
+                    0, iif, ZCOMPONENT, dipole->GetFrequencies());
125
+
126
+    vtkDataObject *_dataObjectzi = receivers->GetVtkDataObjectFreq(HFIELDIMAG, 0,
127
+                    0, iif, ZCOMPONENT, dipole->GetFrequencies());
128
+    #endif
129
+
130
+
131
+//     //dipole->SetPolarisation(XPOLARISATION);
132
+//     //std::cout << "Fortran Calc" << std::endl;
133
+//     #ifdef KIHALEE_EM1D
134
+//     timer.begin();
135
+//     EmEarth->MakeCalc();
136
+//     Real fortranTime = timer.end();
137
+//     std::cout << fortranTime << "\t";
138
+//     std::cout << fortranTime/lemmaTime << std::endl;
139
+//     #endif
140
+
141
+//     #ifdef LEMMAUSEVTK
142
+//     vtkDataObject *_fdataObjectxr = receivers->GetVtkDataObjectFreq(HFIELDREAL, 0,
143
+//                     0, receivers->GetNumberOfReceivers(), XCOMPONENT, dipole->GetFrequencies());
144
+//
145
+//     vtkDataObject *_fdataObjectxi = receivers->GetVtkDataObjectFreq(HFIELDIMAG, 0,
146
+//                     0, receivers->GetNumberOfReceivers(), XCOMPONENT, dipole->GetFrequencies());
147
+//
148
+//     vtkDataObject *_fdataObjectyr = receivers->GetVtkDataObjectFreq(HFIELDREAL, 0,
149
+//                     0, receivers->GetNumberOfReceivers(), YCOMPONENT, dipole->GetFrequencies());
150
+//
151
+//     vtkDataObject *_fdataObjectyi = receivers->GetVtkDataObjectFreq(HFIELDIMAG, 0,
152
+//                     0, receivers->GetNumberOfReceivers(), YCOMPONENT, dipole->GetFrequencies());
153
+//
154
+//     vtkDataObject *_fdataObjectzr = receivers->GetVtkDataObjectFreq(HFIELDREAL, 0,
155
+//                     0, receivers->GetNumberOfReceivers(), ZCOMPONENT, dipole->GetFrequencies());
156
+//
157
+//     vtkDataObject *_fdataObjectzi = receivers->GetVtkDataObjectFreq(HFIELDIMAG, 0,
158
+//                     0, receivers->GetNumberOfReceivers(), ZCOMPONENT, dipole->GetFrequencies());
159
+//     #endif
160
+
161
+
162
+    #ifdef LEMMAUSEVTK
163
+    vtkRenderer *_ren = vtkRenderer::New();
164
+    vtkRenderWindow *_renwin = vtkRenderWindow::New();
165
+    _renwin->AddRenderer(_ren);
166
+
167
+    ///////////////////////////////////////////////
168
+    // X Component Plot
169
+    vtkXYPlotActor *_xplot = vtkXYPlotActor::New();
170
+    //vtkXYPlotWidget *_wplot = vtkXYPlotWidget::New();
171
+        // Add the datasets
172
+        _xplot->AddDataObjectInput( _dataObjectxr);
173
+        _xplot->AddDataObjectInput( _dataObjectxi);
174
+        //_xplot->AddDataObjectInput(_fdataObjectxr);
175
+        //_xplot->AddDataObjectInput(_fdataObjectxi);
176
+        _xplot->SetTitle("X field");
177
+        _xplot->SetXTitle("Depth");
178
+        _xplot->SetYTitle("E Field");
179
+        _xplot->SetXValuesToValue();
180
+        //_plot->SetXValuesToIndex();
181
+
182
+        // set which parts of the data object are to be used for which axis
183
+        _xplot->SetDataObjectXComponent(0,1);
184
+        _xplot->SetDataObjectYComponent(0,0);
185
+        _xplot->SetDataObjectXComponent(1,1);
186
+        _xplot->SetDataObjectYComponent(1,0);
187
+        _xplot->SetDataObjectXComponent(2,1);
188
+        _xplot->SetDataObjectYComponent(2,0);
189
+        _xplot->SetDataObjectXComponent(3,1);
190
+        _xplot->SetDataObjectYComponent(3,0);
191
+        _xplot->SetNumberOfXLabels(3);
192
+        _xplot->SetPlotColor(0,1,1,1);
193
+        _xplot->SetPlotColor(1,1,1,1);
194
+        _xplot->SetPlotColor(2,1,0,0);
195
+        _xplot->SetPlotColor(3,1,0,0);
196
+        _xplot->GetProperty()->SetLineWidth(2);
197
+        _xplot->GetProperty()->SetPointSize(4);
198
+
199
+        //  _plot->SetPlotPoints(0,0);
200
+        //  _plot->SetPlotPoints(1,0);
201
+        //  _plot->SetPlotPoints(2,0);
202
+        //  _plot->SetPlotPoints(3,0);
203
+
204
+        //  _plot->SetPlotLines(0,0);
205
+        //  _plot->SetPlotLines(1,0);
206
+        //  _plot->SetPlotLines(2,0);
207
+        //  _plot->SetPlotLines(3,0);
208
+
209
+        _xplot->PlotCurvePointsOff();
210
+        _xplot->PlotCurveLinesOff();
211
+        _xplot->GetPositionCoordinate()->SetValue(0.0, 0.67, 0);
212
+        _xplot->GetPosition2Coordinate()->SetValue(1.0, 0.33, 0);
213
+        //_plot->SetReverseYAxis(1); // Just flips axis, not data!
214
+
215
+    ///////////////////////////////////////////////
216
+    // Y Component Plot
217
+    vtkXYPlotActor *_yplot = vtkXYPlotActor::New();
218
+    //vtkXYPlotWidget *_wplot = vtkXYPlotWidget::New();
219
+        // Add the datasets
220
+        _yplot->AddDataObjectInput( _dataObjectyr);
221
+        _yplot->AddDataObjectInput( _dataObjectyi);
222
+        //_yplot->AddDataObjectInput(_fdataObjectyr);
223
+        //_yplot->AddDataObjectInput(_fdataObjectyi);
224
+        _yplot->SetTitle("Y field");
225
+        _yplot->SetXTitle("Depth");
226
+        _yplot->SetYTitle("E Field");
227
+        _yplot->SetXValuesToValue();
228
+        //_yplot->SetXValuesToIndex();
229
+
230
+        // set which parts of the data object are to be used for which axis
231
+        _yplot->SetDataObjectXComponent(0,1);
232
+        _yplot->SetDataObjectYComponent(0,0);
233
+        _yplot->SetDataObjectXComponent(1,1);
234
+        _yplot->SetDataObjectYComponent(1,0);
235
+        _yplot->SetDataObjectXComponent(2,1);
236
+        _yplot->SetDataObjectYComponent(2,0);
237
+        _yplot->SetDataObjectXComponent(3,1);
238
+        _yplot->SetDataObjectYComponent(3,0);
239
+        _yplot->SetNumberOfXLabels(3);
240
+        _yplot->SetPlotColor(0,1,1,1);
241
+        _yplot->SetPlotColor(1,1,1,1);
242
+        _yplot->SetPlotColor(2,1,0,0);
243
+        _yplot->SetPlotColor(3,1,0,0);
244
+        _yplot->GetProperty()->SetLineWidth(2);
245
+        _yplot->GetProperty()->SetPointSize(4);
246
+        _yplot->GetPositionCoordinate()->SetValue(0.00, 0.33, 0);
247
+        _yplot->GetPosition2Coordinate()->SetValue(1.0, 0.33, 0);
248
+
249
+        //  _plot->SetPlotPoints(0,0);
250
+        //  _plot->SetPlotPoints(1,0);
251
+        //  _plot->SetPlotPoints(2,0);
252
+        //  _plot->SetPlotPoints(3,0);
253
+
254
+        //  _plot->SetPlotLines(0,0);
255
+        //  _plot->SetPlotLines(1,0);
256
+        //  _plot->SetPlotLines(2,0);
257
+        //  _plot->SetPlotLines(3,0);
258
+
259
+        _yplot->PlotCurvePointsOff();
260
+        _yplot->PlotCurveLinesOff();
261
+        //_plot->SetReverseYAxis(1)
262
+
263
+    ///////////////////////////////////////////////
264
+    // Z Component Plot
265
+    vtkXYPlotActor *_zplot = vtkXYPlotActor::New();
266
+    //vtkXYPlotWidget *_wplot = vtkXYPlotWidget::New();
267
+        // Add the datasets
268
+        _zplot->AddDataObjectInput( _dataObjectzr);
269
+        _zplot->AddDataObjectInput( _dataObjectzi);
270
+        //_zplot->AddDataObjectInput(_fdataObjectzr);
271
+        //_zplot->AddDataObjectInput(_fdataObjectzi);
272
+        _zplot->SetTitle("Z field");
273
+        _zplot->SetXTitle("Depth");
274
+        _zplot->SetYTitle("E Field");
275
+        _zplot->SetXValuesToValue();
276
+        //_plot->SetXValuesToIndex();
277
+
278
+        // set which parts of the data object are to be used for which axis
279
+        _zplot->SetDataObjectXComponent(0,1);
280
+        _zplot->SetDataObjectYComponent(0,0);
281
+        _zplot->SetDataObjectXComponent(1,1);
282
+        _zplot->SetDataObjectYComponent(1,0);
283
+        _zplot->SetDataObjectXComponent(2,1);
284
+        _zplot->SetDataObjectYComponent(2,0);
285
+        _zplot->SetDataObjectXComponent(3,1);
286
+        _zplot->SetDataObjectYComponent(3,0);
287
+        _zplot->SetNumberOfXLabels(3);
288
+        _zplot->SetPlotColor(0,1,1,1);
289
+        _zplot->SetPlotColor(1,1,1,1);
290
+        _zplot->SetPlotColor(2,1,0,0);
291
+        _zplot->SetPlotColor(3,1,0,0);
292
+        _zplot->GetProperty()->SetLineWidth(2);
293
+        _zplot->GetProperty()->SetPointSize(4);
294
+        _zplot->GetPositionCoordinate()->SetValue(0.0, 0.0, 0);
295
+        _zplot->GetPosition2Coordinate()->SetValue(1.0, 0.33, 0);
296
+        //  _plot->SetPlotPoints(0,0);
297
+        //  _plot->SetPlotPoints(1,0);
298
+        //  _plot->SetPlotPoints(2,0);
299
+        //  _plot->SetPlotPoints(3,0);
300
+
301
+        //  _plot->SetPlotLines(0,0);
302
+        //  _plot->SetPlotLines(1,0);
303
+        //  _plot->SetPlotLines(2,0);
304
+        //  _plot->SetPlotLines(3,0);
305
+
306
+        _zplot->PlotCurvePointsOff();
307
+        _zplot->PlotCurveLinesOff();
308
+        //_plot->SetReverseYAxis(1)
309
+
310
+    _ren->AddActor2D(_xplot);
311
+    _ren->AddActor2D(_yplot);
312
+    _ren->AddActor2D(_zplot);
313
+
314
+    vtkRenderWindowInteractor *_iren = vtkRenderWindowInteractor::New();
315
+    _iren->SetRenderWindow(_renwin);
316
+    _iren->Initialize();
317
+    _renwin->Render();
318
+
319
+    //_wplot->SetXYPlotActor(_plot);
320
+    //_wplot->SetInteractor(_iren);
321
+    //_wplot->EnabledOn();
322
+
323
+    _iren->Start();
324
+
325
+    // TODO clean up you dirty whore
326
+//  _iren->Delete();
327
+//  _plot->Delete();
328
+//  _dataObject->Delete();
329
+//  _fieldData->Delete();
330
+//  _renwin->Delete();
331
+//  _ren->Delete();
332
+//  _xdatareal->Delete();
333
+//  _ydata->Delete();
334
+//  _depth->Delete();
335
+    #endif
336
+
337
+    EmEarth->Delete();
338
+    receivers->Delete();
339
+    earth->Delete();
340
+    dipole->Delete();
341
+
342
+    return 0;
343
+
344
+
345
+}

+ 231
- 0
Modules/FDEM1D/src/edipole.cpp View File

@@ -0,0 +1,231 @@
1
+// ===========================================================================
2
+//
3
+//       Filename:  utsnmrinversion1d.cpp
4
+//
5
+//        Created:  10/07/2010 08:57:04 AM
6
+//       Compiler:  Tested with g++, icpc, and MSVC 2010
7
+//
8
+//         Author:  Trevor Irons (ti)
9
+//
10
+//   Organisation:  Colorado School of Mines (CSM)
11
+//                  United States Geological Survey (USGS)
12
+//
13
+//          Email:  tirons@mines.edu, tirons@usgs.gov
14
+//
15
+//  This program is free software: you can redistribute it and/or modify
16
+//  it under the terms of the GNU General Public License as published by
17
+//  the Free Software Foundation, either version 3 of the License, or
18
+//  (at your option) any later version.
19
+//
20
+//  This program is distributed in the hope that it will be useful,
21
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
+//  GNU General Public License for more details.
24
+//
25
+//  You should have received a copy of the GNU General Public License
26
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
27
+//
28
+// ===========================================================================
29
+
30
+/**
31
+  @file
32
+  @author   Trevor Irons
33
+  @date     10/07/2010
34
+  @version   0.0
35
+ **/
36
+
37
+#include "receiverpoints.h"
38
+#include "emearth1d.h"
39
+#include "dipolesource.h"
40
+
41
+using namespace Lemma;
42
+
43
+std::vector<Real>  readinpfile(const std::string& fname);
44
+
45
+int main(int argc, char** argv) {
46
+
47
+    std::cout <<
48
+    "\n"
49
+    << "ediple.exe Copyright (C) 2011 Broken Spoke Development, LLC\n\n"
50
+    << "This program is free software: you can redistribute it and/or modify\n"
51
+    << "it under the terms of the GNU General Public License as published by\n"
52
+    << "the Free Software Foundation, either version 3 of the License, or\n"
53
+    << "(at your option) any later version.\n\n"
54
+
55
+    << "This program is distributed in the hope that it will be useful,\n"
56
+    << "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
57
+    << "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
58
+    << "GNU General Public License for more details.\n\n"
59
+
60
+    << "You should have received a copy of the GNU General Public License\n"
61
+    << "along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\n";
62
+
63
+    if (argc < 4) {
64
+        std::cout << "usage: edipole.exe  dipole.inp cond.inp points.inp \n";
65
+        exit(0);
66
+    }
67
+
68
+    std::vector<Real> Trans   = readinpfile(std::string(argv[1]));
69
+    std::vector<Real> CondMod = readinpfile(std::string(argv[2]));
70
+    std::vector<Real> Points  = readinpfile(std::string(argv[3]));
71
+
72
+    //////////////////////////////////////
73
+    // Define dipole source
74
+    DipoleSource* dipole = DipoleSource::New();
75
+        switch ( (int)(Trans[0]) ) {
76
+            case 0:
77
+                dipole->SetType(MAGNETICDIPOLE);
78
+                break;
79
+            case 1:
80
+                dipole->SetType(GROUNDEDELECTRICDIPOLE);
81
+                break;
82
+            default:
83
+                std::cerr << "Undefined dipole type, must be:\n"
84
+                     << "\t0 -> Magnetic\n"
85
+                     << "\t1 -> Grounded Electric\n";
86
+                exit(EXIT_FAILURE);
87
+        }
88
+
89
+        switch ( (int)(Trans[1]) ) {
90
+            case 0:
91
+                dipole->SetPolarisation(XPOLARISATION);
92
+                break;
93
+            case 1:
94
+                dipole->SetPolarisation(YPOLARISATION);
95
+                break;
96
+            case 2:
97
+                dipole->SetPolarisation(ZPOLARISATION);
98
+                break;
99
+            default:
100
+                std::cerr << "Undefined orientation, must be:\n"
101
+                          << "\t0 -> x\n"
102
+                          << "\t1 -> y\n"
103
+                          << "\t2 -> z\n";
104
+                exit(EXIT_FAILURE);
105
+        }
106
+        dipole->SetNumberOfFrequencies(1);
107
+        dipole->SetFrequency(0, Trans[2]);
108
+        dipole->SetLocation(Trans[3], Trans[4], Trans[5]);
109
+        dipole->SetMoment(Trans[6]);
110
+
111
+	// Receivers
112
+ 	ReceiverPoints *receivers = ReceiverPoints::New();
113
+        int nx = (int)Points[0];
114
+        int ny = (int)Points[1];
115
+        int nz = (int)Points[2];
116
+        Real ox = Points[3];
117
+        Real oy = Points[4];
118
+        Real oz = Points[5];
119
+     	Vector3r loc;
120
+        VectorXr dx(nx-1); // TODO map the dx, dy, dz vectors
121
+        VectorXr dy(ny-1);
122
+        VectorXr dz(nz-1);
123
+        int ip = 6;
124
+        int ir = 0;
125
+        for ( ; ip <6+nx-1; ++ip) {
126
+            dx[ir] = Points[ip];
127
+            ++ir;
128
+        }
129
+        ir = 0;
130
+        for ( ; ip <6+ny-1+nx-1; ++ip) {
131
+            dy[ir] = Points[ip];
132
+            ++ir;
133
+        }
134
+        ir = 0;
135
+        for ( ; ip <6+nz-1+ny-1+nx-1; ++ip) {
136
+            dz[ir] = Points[ip];
137
+            ++ir;
138
+        }
139
+ 		receivers->SetNumberOfReceivers(nx*ny*nz);
140
+ 		ir = 0;
141
+        Real pz  = oz;
142
+ 		for (int iz=0; iz<nz; ++iz) {
143
+ 		    Real py    =  oy;
144
+ 		    for (int iy=0; iy<ny; ++iy) {
145
+ 		        Real px    =  ox;
146
+ 		        for (int ix=0; ix<nx; ++ix) {
147
+ 			        loc << px, py, pz;
148
+ 			        receivers->SetLocation(ir, loc);
149
+ 			        if (ix < nx-1) px += dx[ix];
150
+ 			        ++ ir;
151
+     	        }
152
+                if (iy<ny-1) py += dy[iy];
153
+            }
154
+            if (iz<nz-1) pz += dz[iz];
155
+        }
156
+
157
+    ////////////////////////////////////
158
+    // Define model
159
+    LayeredEarthEM *earth = LayeredEarthEM::New();
160
+    VectorXcr sigma;
161
+    VectorXr  thick;
162
+ 	earth->SetNumberOfLayers(CondMod[0]+1);
163
+ 	sigma.resize(CondMod[0]+1); sigma(0) = 0; // airlayer
164
+    thick.resize(CondMod[0]-1);
165
+    int ilay=1;
166
+    for ( ; ilay/2<CondMod[0]-1; ilay+=2) {
167
+        sigma(ilay/2+1) =  1./CondMod[ilay];
168
+        thick(ilay/2) =  CondMod[ilay+1];
169
+    }
170
+    sigma(ilay/2+1) = 1./ CondMod[ilay];
171
+	earth->SetLayerConductivity(sigma);
172
+    if (thick.size() > 0) earth->SetLayerThickness(thick);
173
+
174
+	EMEarth1D  *EmEarth = EMEarth1D::New();
175
+		EmEarth->AttachDipoleSource(dipole);
176
+		EmEarth->AttachLayeredEarthEM(earth);
177
+		EmEarth->AttachReceiverPoints(receivers);
178
+		EmEarth->SetFieldsToCalculate(E);
179
+        EmEarth->MakeCalc3();
180
+
181
+    ////////////////////////////////////
182
+    // Report
183
+ 	std::fstream hreal("efield.dat", std::ios::out);
184
+    hreal << *dipole << std::endl;
185
+    hreal << *earth << std::endl;
186
+    hreal << "Right hand coordinate system, z is positive down\n\n";
187
+    hreal << "x[m]\ty[m]\tz[m]\tRe(Ex) [V/m]\t Im(Ex) [V/m]\tRe(Ey) [V/m]\tIm(Ey) [V/m]\tRe(Ez) [V/m] Im(Ez) [V/m]\n";
188
+    hreal << "\\\\ ====================================================================================================\n";
189
+    hreal.precision(8);
190
+    int i=0;
191
+	for (int iz=0; iz<nz; ++iz) {
192
+	for (int iy=0; iy<ny; ++iy) {
193
+	for (int ix=0; ix<nx; ++ix) {
194
+        hreal << receivers->GetLocation(i).transpose() << "\t";
195
+ 		hreal << std::real(receivers->GetEfield(0, i).transpose()[0]) << "\t";
196
+ 		hreal << std::imag(receivers->GetEfield(0, i).transpose()[0]) << "\t";
197
+ 		hreal << std::real(receivers->GetEfield(0, i).transpose()[1]) << "\t";
198
+ 		hreal << std::imag(receivers->GetEfield(0, i).transpose()[1]) << "\t";
199
+ 		hreal << std::real(receivers->GetEfield(0, i).transpose()[2]) << "\t";
200
+ 		hreal << std::imag(receivers->GetEfield(0, i).transpose()[2]) << "\n";
201
+        ++i;
202
+    }
203
+    }
204
+    }
205
+    hreal.close();
206
+
207
+    // Clean up
208
+    EmEarth->Delete();
209
+    earth->Delete();
210
+    receivers->Delete();
211
+    dipole->Delete();
212
+}
213
+
214
+std::vector<Real>  readinpfile(const std::string& fname) {
215
+    std::string buf;
216
+    char dump[255];
217
+    std::vector<Real> vals;
218
+    std::fstream input(fname.c_str(), std::ios::in);
219
+    if (input.fail()) {
220
+        std::cerr << "Input file " << fname << " failed to open\n";
221
+        exit(EXIT_FAILURE);
222
+    }
223
+    while (input >> buf) {
224
+        if (buf.substr(0,2) == "//") {
225
+            input.getline(dump, 255);
226
+        } else {
227
+            vals.push_back( atof(buf.c_str() ));
228
+        }
229
+    }
230
+    return vals;
231
+}

+ 141
- 0
Modules/FDEM1D/src/emdipearth1d.cpp View File

@@ -0,0 +1,141 @@
1
+// ===========================================================================
2
+//
3
+//       Filename:  utemdipearth1d.cpp
4
+//
5
+//    Description:
6
+//
7
+//        Version:  0.0
8
+//        Created:  01/06/2010 04:27:56 PM
9
+//       Revision:  none
10
+//       Compiler:  g++ (c++)
11
+//
12
+//         Author:  Trevor Irons (ti)
13
+//
14
+//   Organisation:  Colorado School of Mines (CSM)
15
+//                  United States Geological Survey (USGS)
16
+//
17
+//          Email:  tirons@mines.edu, tirons@usgs.gov
18
+//
19
+//  This program is free software: you can redistribute it and/or modify
20
+//  it under the terms of the GNU General Public License as published by
21
+//  the Free Software Foundation, either version 3 of the License, or
22
+//  (at your option) any later version.
23
+//
24
+//  This program is distributed in the hope that it will be useful,
25
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
26
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27
+//  GNU General Public License for more details.
28
+//
29
+//  You should have received a copy of the GNU General Public License
30
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
31
+//
32
+// ===========================================================================
33
+#include "emearth1d.h"
34
+#include "dipolesource.h"
35
+#include "layeredearthem.h"
36
+#include "receiverpoints.h"
37
+
38
+using namespace Lemma;
39
+
40
+int main() {
41
+
42
+	// Test with a single dipole
43
+	DipoleSource *dipole = DipoleSource::New();
44
+		dipole->SetType(GROUNDEDELECTRICDIPOLE);
45
+		dipole->SetPolarisation(XPOLARISATION);
46
+		dipole->SetNumberOfFrequencies(1);
47
+		dipole->SetMoment(1);
48
+		dipole->SetFrequency(0, 4400.1000);
49
+		//dipole->SetPhase(0);
50
+		//dipole->SetLocation( (VectorXr(3) << 49, 49, -1e-4).finished() );
51
+		dipole->SetLocation( 49, 49, -1e-4  );
52
+
53
+
54
+	// Define model
55
+	VectorXcr sigma(2);
56
+		sigma << 0., 1e-3;//, .1;//, .01, .001;
57
+	VectorXr  thick(1);
58
+		thick << 10;//, 10, 10;
59
+
60
+	LayeredEarthEM *earth = LayeredEarthEM::New();
61
+        earth->SetNumberOfLayers(2);
62
+		earth->SetLayerConductivity(sigma);
63
+		//earth->SetLayerThickness(thick);
64
+
65
+	// Receivers
66
+	ReceiverPoints *receivers = ReceiverPoints::New();
67
+		Vector3r loc;
68
+		//Real ox = -5.1456;
69
+		//Real oy =  2.2350;
70
+		Real ox =    50.;
71
+		Real oy =    20.;
72
+		Real depth = 18.10;
73
+		Real dz = 2.6;
74
+		int  nz = 1;
75
+
76
+		receivers->SetNumberOfReceivers(nz);
77
+		int ir = 0;
78
+		for (int iz=0; iz<nz; ++iz) {
79
+			loc << ox, oy, depth;
80
+			receivers->SetLocation(ir, loc);
81
+			depth += dz;
82
+			++ ir;
83
+		}
84
+	//receivers->SetLocation(1, ox, oy, depth);
85
+
86
+	EMEarth1D *EmEarth = EMEarth1D::New();
87
+        //EmEarth->SetHankelTransformMethod(DIGITALFILTERING);
88
+        EmEarth->SetFieldsToCalculate(BOTH); // Fortran needs this
89
+		EmEarth->AttachDipoleSource(dipole);
90
+		EmEarth->AttachLayeredEarthEM(earth);
91
+		EmEarth->AttachReceiverPoints(receivers);
92
+
93
+        //dipole->SetType(ELECTRICDIPOLE);
94
+//         receivers->SetNumberOfReceivers(1);
95
+//         //for
96
+// 	    receivers->SetLocation(0, ox, oy, depth);
97
+
98
+
99
+	std::cout << "C++\n";
100
+	EmEarth->MakeCalc3();
101
+	std::cout << receivers->GetEfield(0,0) << std::endl;
102
+	//std::cout << receivers->GetEfield(0) << std::endl;
103
+	//std::cout << receivers->GetHfield(1) << std::endl;
104
+	//std::cout << receivers->GetEfield(1) << std::endl;
105
+	receivers->ClearFields();
106
+
107
+    // swap tx rx posigion
108
+    receivers->SetLocation(0, dipole->GetLocation());
109
+    dipole->SetLocation(loc);
110
+	EmEarth->MakeCalc3();
111
+	std::cout << receivers->GetEfield(0,0) << std::endl;
112
+
113
+	receivers->ClearFields();
114
+ #ifdef KIHALEE_EM1D
115
+// 	//std::cout << "\nFORTRAN\n";
116
+ 	EmEarth->MakeCalc();
117
+// 	std::cout << receivers->GetHfield(0,0) << std::endl;
118
+ 	std::cout << receivers->GetEfield(0,0) << std::endl;
119
+ #endif
120
+
121
+    dipole->Delete();
122
+    EmEarth->Delete();
123
+    receivers->Delete();
124
+    earth->Delete();
125
+
126
+// 	try {
127
+//
128
+// 	}
129
+//
130
+// 	// Catch exceptions
131
+// 	catch (NullEarth) {
132
+// 			std::cout << "Earth model not set dummy\n";
133
+// 	}
134
+//
135
+// 	catch (NullReceivers) {
136
+// 			std::cout << "Receivers not set dummy\n";
137
+// 	}
138
+
139
+	//EmEarth->TestBess();
140
+
141
+}

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

@@ -0,0 +1,972 @@
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

+ 199
- 0
Modules/FDEM1D/src/femforward.cpp View File

@@ -0,0 +1,199 @@
1
+// ===========================================================================
2
+// 
3
+//       Filename:  utfemforward.cpp
4
+// 
5
+//    Description:  
6
+// 
7
+//        Version:  0.0
8
+//        Created:  01/15/2013 12:11:34 PM
9
+//       Revision:  none
10
+//       Compiler:  Tested with g++ 
11
+// 
12
+//         Author:  M. Andy Kass (MAK)
13
+//
14
+//   Organisation:  Broken Spoke Development, LLC
15
+//                  
16
+//
17
+//          Email:  mkass@numericalgeo.com
18
+// 
19
+//  This program is free software: you can redistribute it and/or modify
20
+//  it under the terms of the GNU General Public License as published by
21
+//  the Free Software Foundation, either version 3 of the License, or
22
+//  (at your option) any later version.
23
+//
24
+//  This program is distributed in the hope that it will be useful,
25
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
26
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27
+//  GNU General Public License for more details.
28
+//
29
+//  You should have received a copy of the GNU General Public License
30
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
31
+//
32
+// ===========================================================================
33
+
34
+#include <time.h>
35
+#include "Lemma"
36
+#include "banner.h"
37
+
38
+using namespace Lemma;
39
+
40
+#ifdef LEMMAUSEVTK
41
+#include "matplot.h"
42
+using namespace matplot;
43
+#endif
44
+
45
+int main() {
46
+
47
+	clock_t launch = clock();
48
+
49
+	// Banner display
50
+	std::string name;
51
+	std::string version;
52
+	std::string usage;
53
+	name = "FEM Forward Modeller - 1D ";
54
+	version = "1.0alpha";
55
+	usage = "utfemforward [inputfile]";
56
+	banner(name,version,usage);
57
+
58
+	time_t curr = time(0);
59
+	std::cout << std::endl << "  Start time: " << ctime(&curr) << std::endl;
60
+
61
+	// Define some objects
62
+	DipoleSource* Trans = DipoleSource::New();
63
+	ReceiverPoints* Receivers = ReceiverPoints::New();
64
+	LayeredEarthEM* Earth = LayeredEarthEM::New();
65
+
66
+
67
+
68
+	// SINGLE SOUNDING
69
+
70
+	// Create new data object to receive forward model
71
+	DataFEM* modelledData = DataFEM::New();
72
+
73
+	// Create instrument object
74
+	InstrumentFem* theinstrument = InstrumentFem::New();	
75
+
76
+	// Set up EMEarthModel
77
+	Earth->SetNumberOfLayers(5);
78
+	Earth->SetLayerConductivity((VectorXcr(5) << 0.,1.e-4,1.e-2,
79
+		1.e-4,1.e-6).finished());
80
+	Earth->SetLayerThickness((VectorXr(3) << 20.,5.,50.).finished());
81
+	
82
+	// Set up transmitter
83
+	Real momtemp;
84
+	momtemp = 1;
85
+	Real freq;
86
+	freq = 391;
87
+	Trans->SetType(MAGNETICDIPOLE);
88
+	Trans->SetLocation(0,0,-1.e-3);
89
+	Trans->SetPolarisation(ZPOLARISATION);
90
+	// as a test
91
+	Trans->SetNumberOfFrequencies(1);
92
+	Trans->SetFrequency(0,freq);
93
+	Trans->SetMoment(momtemp);
94
+
95
+	// Set up receivers
96
+	Vector3r loc1;
97
+	Vector3r loc2;
98
+	Receivers->SetNumberOfReceivers(1);
99
+	loc1 << 9,0,-1.e-3;
100
+	Receivers->SetLocation(0,loc1);
101
+
102
+
103
+	// Attach to instrument
104
+	theinstrument->SetReceiverPoints(Receivers);
105
+	theinstrument->SetDipoleSource(Trans);
106
+	theinstrument->EMEarthModel(Earth);
107
+	theinstrument->SetOutputData(modelledData);
108
+
109
+	// Calculate
110
+	theinstrument->MakeCalculation();
111
+
112
+	// See what comes back...
113
+	std::cout << Receivers->GetHfield(0,0)(2) << std::endl;
114
+	
115
+	// Need to convert H field to ppm
116
+
117
+
118
+	theinstrument->Delete();
119
+	modelledData->Delete();
120
+
121
+	// MULTIPLE SOUNDING MODEL USING READ-IN DATA
122
+
123
+
124
+	InstrumentFem* theinstrument2 = InstrumentFem::New();
125
+	DataFEM* modelledData2 = DataFEM::New();
126
+
127
+	// Using the UBC data reader to read in the survey params
128
+	// this will be used for the multiple sounding testing
129
+	std::string datfile;
130
+	datfile = "126.obs";
131
+
132
+	DataReaderFemUBC* Reader = DataReaderFemUBC::New();
133
+	DataFEM* inpdata = DataFEM::New();
134
+	Reader->SetDataFEM(inpdata);
135
+	try {
136
+		Reader->ReadData(datfile,1);
137
+	} catch(std::exception& e) {
138
+		exit(EXIT_FAILURE);
139
+	}
140
+	std::cout << *inpdata << std::endl;
141
+	theinstrument2->SetOutputData(modelledData2);
142
+	theinstrument2->AlignWithData(inpdata);
143
+	// Now, how do I want to pass it an earth model for each sounding?
144
+	//
145
+	inpdata->Delete();
146
+
147
+
148
+
149
+
150
+	// Need to loop over transmitters
151
+	// The relative positions of the transmitter and receiver is fixed
152
+	// For testing, do some kind of random realisation of Earth model?
153
+//	int nObs;
154
+//	int nFreqs;
155
+//	nObs = inpdata->GetnObs();
156
+//	nFreqs = inpdata->GetnFreq();
157
+
158
+//	Trans->SetType(MAGNETICDIPOLE);
159
+//	Trans->SetLocation(0,0,-1e-3);
160
+
161
+//	Vector3r loc;
162
+//	Receivers->SetNumberOfReceivers(1);
163
+//	loc << 0,0,-1e-3;
164
+//	Receivers->SetLocation(0,loc);
165
+
166
+//	Earth->SetNumberOfLayers(5); //Including the two halfspaces
167
+//	Earth->SetLayerConductivity((VectorXcr(5) << 0.,1.e-4,1.e-2,
168
+//		1.e-4,1.e-6).finished());
169
+//	Earth->SetLayerThickness((VectorXr(3) << 20.,5.,50.).finished());
170
+
171
+//	for (int ii=0;ii<nObs;ii++) {
172
+//		for (int jj=0;jj<nFreqs;jj++) {
173
+//			Trans->SetMoment(inpdata->GetTxMom().coeff(jj));
174
+//			
175
+//		}
176
+//	}
177
+	
178
+	//This is a bunch of testing stuff
179
+	//theinstrument->AlignWithData(inpdata);
180
+	//theinstrument->MakeCalculation();
181
+	//inpdata->Delete();
182
+	//theinstrument->MakeCalculation();
183
+
184
+
185
+	theinstrument2->Delete();
186
+	Reader->Delete();
187
+	Earth->Delete();
188
+	Receivers->Delete();
189
+	Trans->Delete();
190
+
191
+	// Timey-wimey stuff
192
+	Real time;
193
+	clock_t done = clock();
194
+	time = (done-launch)/CLOCKS_PER_SEC;
195
+	std::cout << "  Execution time: " << time << " [CPU] seconds."
196
+		<< std::endl;
197
+
198
+	return EXIT_SUCCESS;
199
+}

+ 138
- 0
Modules/FDEM1D/src/gaussianquadrature.cpp View File

@@ -0,0 +1,138 @@
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   M. Andy Kass
10
+  @date     10/07/2010
11
+  @version  $Id: gaussianquadrature.cpp 87 2013-09-05 22:44:05Z tirons $
12
+ **/
13
+
14
+#include "gaussianquadrature.h"
15
+
16
+namespace Lemma {
17
+
18
+//	std::ostream &operator<<(std::ostream &stream,
19
+//				const gaussianquadrature &ob) {
20
+//
21
+//	}
22
+
23
+	////////////////////////////////////////////////
24
+	gaussianquadrature::gaussianquadrature() {
25
+	}
26
+	gaussianquadrature::~gaussianquadrature() {
27
+	}
28
+	gaussianquadrature* gaussianquadrature::New() {
29
+		return new gaussianquadrature;
30
+	}
31
+	void gaussianquadrature::Delete() {
32
+		delete this;
33
+	}
34
+
35
+	////////////////////////////////////////////////
36
+	void gaussianquadrature::Integrate() {
37
+
38
+		this->intres=(this->funcx.array()*this->wgq.array()).sum();
39
+
40
+	}
41
+
42
+	////////////////////////////////////////////////
43
+	void gaussianquadrature::CalcAW() {
44
+
45
+		while ((this->y-this->y0).array().abs().maxCoeff()>
46
+				this->machineeps) {
47
+			this->L.col(0).setOnes();
48
+			this->Ltemp.col(0).setZero();
49
+			this->L.col(1)=this->y;
50
+			this->Ltemp.col(1).setOnes();
51
+
52
+			for (int kk=2;kk<this->N2;++kk) {
53
+				this->ytemp=this->L.col(kk-1).array()*this->y.array();
54
+				this->ytemp=this->ytemp.array()*(2.0*Real(kk)-1.0);
55
+				this->L.col(kk)=this->ytemp.array()-((Real(kk)-1.0)*
56
+					this->L.col(kk-2).array());
57
+				this->L.col(kk)=this->L.col(kk).array()/Real(kk);
58
+			}
59
+			this->ytemp=this->y.array()*this->L.col(this->N1).array();
60
+			this->Lp=this->L.col(this->N1-1)-this->ytemp;
61
+			this->Lp=this->Lp.array()/(1.0-(this->y.array()*this->y.array()));
62
+			this->Lp=this->Lp.array()*this->N2;
63
+			this->y0=this->y;
64
+			this->ytemp=this->L.col(this->N1);
65
+			this->y=this->y0.array()-(this->ytemp.array()/this->Lp.array());
66
+		}
67
+
68
+		for (int ii=0;ii<this->N1;++ii) {
69
+			this->xu(ii)=((this->b-this->a)*((this->y(ii)+1.0)/2.0))+this->a;
70
+			this->wgq(ii)=((this->b-this->a)/((1.0-(this->y(ii)*this->y(ii)))*
71
+				(this->Lp(ii)*this->Lp(ii))))*((Real(this->N2)/Real(this->N1))*
72
+				(Real(this->N2)/Real(this->N1)));
73
+		}
74
+	}
75
+
76
+	////////////////////////////////////////////////
77
+	void gaussianquadrature::SetFreqs(const int& nfreq,
78
+			const Real& a, const Real& b) {
79
+		this->N = nfreq-1;
80
+		this->N1 = nfreq;
81
+		this->N2 = nfreq+1;
82
+		// \TODO Use pointers here instead
83
+		this->a = a;
84
+		this->b = b;
85
+
86
+		//Debugging only
87
+		//std::cout << N << "   " << a << "   " << b << std::endl;
88
+
89
+		this->dx = (2.0)/Real(nfreq);
90
+		this->machineeps = std::numeric_limits<Real>::epsilon();
91
+
92
+		this->ytemp.resize(this->N1);
93
+		this->xu.resize(this->N1);
94
+		this->y.resize(this->N1);
95
+		this->y0.resize(this->N1);
96
+		this->Lp.resize(this->N1);
97
+		this->wgq.resize(this->N1);
98
+		// \TODO Instead of copying the variable, use pointers
99
+		this->funcx.resize(nfreq);
100
+
101
+		this->L.resize(this->N1,this->N2);
102
+		this->Ltemp.resize(this->N1,this->N2);
103
+
104
+		for (int ii=0;ii<this->N1;++ii) {
105
+			this->xu(ii)=(dx*Real(ii))-1.0;
106
+			this->y(ii)=std::cos((2.0*Real(ii)+1.0)*PI/(2.0*
107
+				Real(this->N)+2.0))+(0.27/(Real(this->N1)))*
108
+				std::sin(PI*xu(ii)*Real(this->N)/(Real(this->N2)));
109
+			this->y0(ii)=2.0;
110
+			this->ytemp(ii)=0.0;
111
+		}
112
+	}
113
+
114
+	////////////////////////////////////////////////
115
+	void gaussianquadrature::SetFunc(const VectorXr& fx) {
116
+		this->funcx = fx;
117
+	}
118
+
119
+	////////////////////////////////////////////////
120
+	VectorXr gaussianquadrature::GetAbscissae() {
121
+
122
+		return this->xu;
123
+	}
124
+
125
+	////////////////////////////////////////////////
126
+	VectorXr gaussianquadrature::GetWeights() {
127
+
128
+		return this->wgq;
129
+	}
130
+
131
+	////////////////////////////////////////////////
132
+	Real gaussianquadrature::GetResult() {
133
+
134
+		return intres;
135
+	}
136
+
137
+} //end of namespace Lemma
138
+

+ 39
- 0
Modules/FDEM1D/src/hankeltransform.cpp View File

@@ -0,0 +1,39 @@
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     01/02/2010
11
+  @version  $Id: hankeltransform.cpp 193 2014-11-10 23:51:41Z tirons $
12
+ **/
13
+
14
+#include "hankeltransform.h"
15
+
16
+namespace Lemma {
17
+
18
+	std::ostream &operator<<(std::ostream &stream,
19
+			const HankelTransform &ob) {
20
+		stream << *(LemmaObject*)(&ob);
21
+		return stream;
22
+	}
23
+
24
+	HankelTransform::HankelTransform(const std::string &name) :
25
+	   LemmaObject(name)	{
26
+	}
27
+
28
+	HankelTransform::~HankelTransform() {
29
+	}
30
+
31
+    void HankelTransform::ComputeRelated(const Real& rho, KernelEm1DBase *Kernel) {
32
+    }
33
+
34
+    void HankelTransform::ComputeRelated(const Real& rho, std::vector< KernelEm1DBase* > KernelVec) {
35
+    }
36
+
37
+    void HankelTransform::ComputeRelated(const Real& rho, KernelEM1DManager*  KernelManager) {
38
+    }
39
+}

+ 1134
- 0
Modules/FDEM1D/src/hankeltransformgaussianquadrature.cpp
File diff suppressed because it is too large
View File


+ 1118
- 0
Modules/FDEM1D/src/hankeltransformhankel2.cpp
File diff suppressed because it is too large
View File


+ 174
- 0
Modules/FDEM1D/src/instrumentfem.cpp View File

@@ -0,0 +1,174 @@
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   M. Andy Kass
10
+  @date     01/14/2013
11
+  @version  $Id$
12
+ **/
13
+
14
+#include "instrumentfem.h"
15
+
16
+namespace Lemma {
17
+
18
+	std::ostream &operator<<(std::ostream &stream,
19
+		const InstrumentFem &ob) {
20
+		stream << *(LemmaObject*)(&ob);
21
+		return stream;
22
+	}
23
+
24
+	InstrumentFem::InstrumentFem(const std::string &name) : Instrument (name),
25
+		EarthModel(NULL), Dipole(NULL), Receiver(NULL), InputData(NULL),
26
+	    OutputData(NULL)	{
27
+		}
28
+
29
+	InstrumentFem::~InstrumentFem() {
30
+		if (NumberOfReferences !=0) {
31
+			throw DeleteObjectWithReferences(this);
32
+		}
33
+	}
34
+
35
+	InstrumentFem* InstrumentFem::New() {
36
+		InstrumentFem* Obj = new InstrumentFem("InstrumentFem");
37
+		Obj->AttachTo(Obj);
38
+		return Obj;
39
+	}
40
+
41
+	void InstrumentFem::Delete() {
42
+		this->DetachFrom(this);
43
+	}
44
+
45
+	void InstrumentFem::Release() {
46
+		delete this;
47
+	}
48
+
49
+	void InstrumentFem::MakeCalculation() {
50
+
51
+		EMEarth1D *EMEarthLocal=EMEarth1D::New();
52
+		EMEarthLocal->AttachLayeredEarthEM(this->EarthModel);
53
+		EMEarthLocal->AttachDipoleSource(this->Dipole);
54
+		EMEarthLocal->SetFieldsToCalculate(H);
55
+		//EMEarthLocal->SetHankelTransformMethod(DIGITALFILTERING);
56
+		EMEarthLocal->SetHankelTransformMethod(CHAVE);
57
+		EMEarthLocal->AttachReceiverPoints(this->Receiver);
58
+		EMEarthLocal->MakeCalc3();
59
+		//EMEarthLocal->MakeCalc();
60
+
61
+		EMEarthLocal->Delete();
62
+
63
+		// GetHfield(freq_idx, loc_idx)(comp)
64
+
65
+	}
66
+
67
+	void InstrumentFem::ForwardModelProfile() {
68
+
69
+
70
+	}
71
+
72
+	void InstrumentFem::EMEarthModel(LayeredEarthEM* Earth) {
73
+		if (this->EarthModel != NULL) {
74
+			this->EarthModel->DetachFrom(this);
75
+		}
76
+		Earth->AttachTo(this);
77
+		this->EarthModel = Earth;
78
+	}
79
+
80
+	void InstrumentFem::SetDipoleSource(DipoleSource* dipolesource) {
81
+		if (this->Dipole != NULL) {
82
+			this->Dipole->DetachFrom(this);
83
+		}
84
+		dipolesource->AttachTo(this);
85
+		this->Dipole = dipolesource;
86
+	}
87
+
88
+	void InstrumentFem::SetReceiverPoints(ReceiverPoints* receiver) {
89
+		if (this->Receiver != NULL) {
90
+			this->Receiver->DetachFrom(this);
91
+		}
92
+		receiver->AttachTo(this);
93
+		this->Receiver = receiver;
94
+	}
95
+
96
+	void InstrumentFem::AlignWithData(DataFEM* inpdata) {
97
+		this->nFreq = inpdata->GetnFreq();
98
+		this->nObs = inpdata->GetnObs();
99
+		this->freq = inpdata->GetFreqs();
100
+		this->xyz = inpdata->GetXYZ();
101
+		this->TxOrientation = inpdata->GetTxOrien();
102
+		this->RxOrientation = inpdata->GetRxOrien();
103
+		this->TxMom = inpdata->GetTxMom();
104
+		this->TxRxSep = inpdata->GetTxRxSep();
105
+		this->ScaleFac = inpdata->GetScaleFac();
106
+
107
+		// Check into boost for the use of pointer arrays
108
+		// array of nFreq DipoleSource objects
109
+			//first get rid of existing dipoles
110
+		for (unsigned int id=0;id<this->Transmitters.size();++id) {
111
+			this->Transmitters[id]->Delete();
112
+		}
113
+		this->Transmitters.clear();
114
+		//this->Transmitters.resize(this->nFreq);
115
+
116
+		for (unsigned int id=0;id<this->Receivers.size();++id) {
117
+			this->Receivers[id]->Delete();
118
+		}
119
+		this->Receivers.clear();
120
+
121
+
122
+		for (int ii=0;ii<this->nFreq;ii++) {
123
+			/*
124
+			this->Transmitters.push_back(DipoleSource::New());
125
+			std::cout << &(this->Transmitters[ii]) << std::endl;
126
+			*/
127
+			DipoleSource *tt = DipoleSource::New();
128
+			ReceiverPoints *tr = ReceiverPoints::New();
129
+			Real ftemp;
130
+			Real momtemp;
131
+			ftemp = this->freq(ii);
132
+			momtemp = this->TxMom(ii);
133
+			tt->SetType(MAGNETICDIPOLE);
134
+			tt->SetLocation(0,0,-1.e-3);
135
+			// This is really hoopty but will do for now
136
+			if (this->TxOrientation(ii) == X) {
137
+				tt->SetPolarisation(XPOLARISATION);
138
+			}
139
+			else if (this->TxOrientation(ii) == Y) {
140
+				tt->SetPolarisation(YPOLARISATION);
141
+			}
142
+			else if (this->TxOrientation(ii) == Z) {
143
+				tt->SetPolarisation(ZPOLARISATION);
144
+			}
145
+			else {
146
+				std::cout << "DANGER! DANGER! UNHELPFUL ERROR"
147
+					 << std::endl;
148
+				tt->SetPolarisation(ZPOLARISATION);
149
+			}
150
+			tt->SetNumberOfFrequencies(1);
151
+			tt->SetFrequency(0,ftemp);
152
+			tt->SetMoment(momtemp);
153
+			this->Transmitters.push_back(tt);
154
+			tr->SetNumberOfReceivers(1);
155
+			tr->SetLocation(0,this->TxRxSep.block(0,ii,3,1));
156
+			this->Receivers.push_back(tr);
157
+		}
158
+
159
+		// Now populate the attached output data object?
160
+		// Or, should I do this later after the computation?
161
+
162
+	}
163
+
164
+	void InstrumentFem::SetOutputData(DataFEM* outputdata) {
165
+		if (this->OutputData != NULL) {
166
+			this->OutputData->DetachFrom(this);
167
+		}
168
+		outputdata->AttachTo(this);
169
+		this->OutputData = outputdata;
170
+	}
171
+
172
+
173
+
174
+}// end of namespace lemma

+ 27
- 0
Modules/FDEM1D/src/integrationkernel.cpp View File

@@ -0,0 +1,27 @@
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     02/07/2011
11
+  @version  $Id: integrationkernel.cpp 193 2014-11-10 23:51:41Z tirons $
12
+ **/
13
+
14
+#include "integrationkernel.h"
15
+
16
+namespace Lemma {
17
+
18
+    template <typename T>
19
+    IntegrationKernel<T>::IntegrationKernel(const std::string& name) :
20
+        LemmaObject(name) {
21
+    }
22
+
23
+    template<typename T>
24
+    IntegrationKernel<T>::~IntegrationKernel( ) {
25
+    }
26
+
27
+}		// -----  end of Lemma  name  -----

+ 78
- 0
Modules/FDEM1D/src/inversesolver.cpp View File

@@ -0,0 +1,78 @@
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     07/14/2010
11
+  @version  $Id: inversesolver.cpp 193 2014-11-10 23:51:41Z tirons $
12
+ **/
13
+
14
+#include "inversesolver.h"
15
+
16
+namespace Lemma {
17
+
18
+    std::ostream &operator<<(std::ostream &stream,
19
+                const InverseSolver &ob) {
20
+        stream << *(LemmaObject*)(&ob);
21
+        return stream;
22
+    }
23
+
24
+    // ====================  LIFECYCLE     =======================
25
+
26
+    InverseSolver::InverseSolver(const std::string &name) :
27
+        LemmaObject(name), ObservedData(NULL),
28
+        PredictedData(NULL), ModelInstrument(NULL) {
29
+    }
30
+
31
+    InverseSolver::~InverseSolver() {
32
+
33
+        if (NumberOfReferences != 0) throw DeleteObjectWithReferences(this);
34
+
35
+        if (ObservedData != NULL)    ObservedData->DetachFrom(this);
36
+
37
+        if (PredictedData != NULL) {
38
+            PredictedData->Delete();
39
+        }
40
+
41
+        if (ModelInstrument != NULL)       ModelInstrument->DetachFrom(this);
42
+    }
43
+
44
+    // ====================  ACCESS        =======================
45
+
46
+    void InverseSolver::SetObservedData(Data* ObsData) {
47
+
48
+        if (ObservedData != NULL) {
49
+            ObservedData->DetachFrom(this);
50
+            ObservedData = NULL;
51
+        }
52
+
53
+        if (PredictedData != NULL) {
54
+            PredictedData->Delete();
55
+            PredictedData = NULL;
56
+        }
57
+
58
+        ObsData->AttachTo(this);
59
+        this->ObservedData = ObsData;
60
+
61
+        // Obs and predicted data need to be aligned.
62
+        PredictedData = ObservedData->Clone();
63
+        //PredictedData->AttachTo(this);
64
+    }
65
+
66
+    void InverseSolver::SetInstrument(Instrument* inst) {
67
+        if (ModelInstrument != NULL) {
68
+            ModelInstrument->DetachFrom(this);
69
+        }
70
+        inst->AttachTo(this);
71
+        this->ModelInstrument = inst;
72
+    }
73
+
74
+    Data* InverseSolver::GetPredictedData() {
75
+        return PredictedData; //->ThrowPointer();
76
+    }
77
+
78
+}		// -----  end of Lemma  name  -----

+ 29
- 0
Modules/FDEM1D/src/kernel.cpp View File

@@ -0,0 +1,29 @@
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     01/29/2010
11
+  @version  $Id: kernel.cpp 193 2014-11-10 23:51:41Z tirons $
12
+ **/
13
+
14
+#include "kernel.h"
15
+namespace Lemma {
16
+
17
+	std::ostream &operator<<(std::ostream &stream,
18
+				const Kernel &ob) {
19
+		stream << *(LemmaObject*)(&ob);
20
+		return stream;
21
+	}
22
+
23
+	Kernel::Kernel(const std::string& name) :
24
+			LemmaObject(name) {
25
+	}
26
+
27
+	Kernel::~Kernel() {
28
+	}
29
+}

+ 128
- 0
Modules/FDEM1D/src/kernelem1dmanager.cpp View File

@@ -0,0 +1,128 @@
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     06/26/2012
11
+  @version  $Id: kernelem1dmanager.cpp 193 2014-11-10 23:51:41Z tirons $
12
+ **/
13
+
14
+#include "kernelem1dmanager.h"
15
+
16
+
17
+namespace Lemma {
18
+
19
+    std::ostream &operator<<(std::ostream &stream,
20
+                const KernelEM1DManager &ob) {
21
+        stream << *(LemmaObject*)(&ob);
22
+        return stream;
23
+    }
24
+
25
+
26
+    // ====================  LIFECYCLE     =======================
27
+
28
+    KernelEM1DManager::KernelEM1DManager(const std::string& name) :
29
+                    LemmaObject(name), TEReflBase(NULL), TMReflBase(NULL), Earth(NULL), Dipole(NULL) {
30
+    }
31
+
32
+    KernelEM1DManager::~KernelEM1DManager() {
33
+
34
+        if (this->NumberOfReferences != 0)
35
+            throw DeleteObjectWithReferences(this);
36
+
37
+//         if (Earth != NULL) {
38
+//             Earth->DetachFrom(this);
39
+//         }
40
+//
41
+//         if (Dipole != NULL) {
42
+//             Dipole->DetachFrom(this);
43
+//         }
44
+
45
+        for (unsigned int ik=0; ik<KernelVec.size(); ++ik) {
46
+            KernelVec[ik]->Delete();
47
+        }
48
+
49
+        if (TEReflBase != NULL) TEReflBase->Delete();
50
+        if (TMReflBase != NULL) TMReflBase->Delete();
51
+
52
+    }
53
+
54
+    KernelEM1DManager* KernelEM1DManager::New() {
55
+        KernelEM1DManager* Obj = new KernelEM1DManager("KernelEM1DManager");
56
+        Obj->AttachTo(Obj);
57
+        return Obj;
58
+    }
59
+
60
+    void KernelEM1DManager::Delete() {
61
+        this->DetachFrom(this);
62
+    }
63
+
64
+    void KernelEM1DManager::Release() {
65
+        delete this;
66
+    }
67
+
68
+    // ====================  ACCESS        =======================
69
+
70
+    // A race condition can develop with these. It's OK to not attach, since this is an internal class, and
71
+    // we know what is going on.
72
+    void KernelEM1DManager::SetEarth(LayeredEarthEM* Earthin) {
73
+        //if (Earth != NULL) {
74
+        //    Earth->DetachFrom(this);
75
+        //}
76
+        //Earthin->AttachTo(this);
77
+        Earth = Earthin;
78
+    }
79
+
80
+    void KernelEM1DManager::SetDipoleSource(DipoleSource* DipoleIn, const int& ifreqin,
81
+            const Real& rx_zin) {
82
+        //if (Dipole != NULL) {
83
+        //    Dipole->DetachFrom(this);
84
+        //}
85
+        //DipoleIn->AttachTo(this);
86
+        Dipole = DipoleIn;
87
+
88
+        ifreq = ifreqin;
89
+        rx_z = rx_zin;
90
+    }
91
+
92
+    KernelEm1DBase* KernelEM1DManager::GetKernel(const unsigned int& ik) {
93
+        return KernelVec[ik];
94
+    }
95
+
96
+    DipoleSource* KernelEM1DManager::GetDipole( ) {
97
+        return Dipole;
98
+    }
99
+
100
+    // ====================  OPERATIONS    =======================
101
+
102
+    void KernelEM1DManager::ComputeReflectionCoeffs(const Real& lambda, const int& idx, const Real& rho0) {
103
+
104
+        if (TEReflBase != NULL) {
105
+            TEReflBase->ComputeReflectionCoeffs(lambda);
106
+            TEReflBase->PreComputePotentialTerms( );
107
+        }
108
+
109
+        if (TMReflBase != NULL) {
110
+            TMReflBase->ComputeReflectionCoeffs(lambda);
111
+            TMReflBase->PreComputePotentialTerms( );
112
+        }
113
+
114
+    }
115
+
116
+    void KernelEM1DManager::ResetSource(const int& ifreq) {
117
+
118
+        if (TEReflBase != NULL) {
119
+            TEReflBase->SetUpSource(Dipole, ifreq);
120
+        }
121
+
122
+        if (TMReflBase != NULL) {
123
+            TMReflBase->SetUpSource(Dipole, ifreq);
124
+
125
+        }
126
+    }
127
+
128
+}		// -----  end of Lemma  name  -----

+ 241
- 0
Modules/FDEM1D/src/kernelem1dreflspec.cpp View File

@@ -0,0 +1,241 @@
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     05/18/2012
11
+  @version  $Id: kernelem1dreflspec.cpp 169 2014-09-06 22:16:12Z tirons $
12
+ **/
13
+
14
+#include "kernelem1dreflspec.h"
15
+
16
+namespace Lemma {
17
+
18
+    template<>
19
+    void KernelEM1DReflSpec<TM, INAIR, INAIR>::ComputeReflectionCoeffs(const Real& lambda) {
20
+
21
+        rams = lambda*lambda;
22
+        u = (rams-kk.array()).sqrt(); // CRITICAL
23
+        uk = u(0);
24
+        um = u(0);
25
+
26
+        Zyu(1) = -u(0)/yh(0);
27
+        Zyi    =  u.array() / yh.array();
28
+
29
+        Zyd.tail<1>() = Zyi.tail<1>();
30
+
31
+        // Vectorise, performance is not really any better
32
+        cf.segment(1,nlay-2) = (-2.*u.segment(1, nlay-2).array() * LayerThickness.segment(1, nlay-2).array()).exp();
33
+        th.segment(1,nlay-2) = (1.-cf.segment(1, nlay-2).array()) / (1.+cf.segment(1, nlay-2).array());
34
+
35
+        /*
36
+        for (int ilay=1; ilay<nlay-1; ++ilay) {
37
+            cf(ilay) = std::exp(-(Real)(2.)*u(ilay)*LayerThickness(ilay));
38
+            th(ilay) = ((Real)(1.)-cf(ilay)) / ((Real)(1.)+cf(ilay));
39
+        }
40
+        */
41
+
42
+        // recursive, can't vectorize
43
+        for (int N=nlay-2; N >= 1; --N) {
44
+            Zyd(N) = Zyi(N)*(Zyd(N+1)+Zyi(N)*th(N)) / (Zyi(N)+Zyd(N+1)*th(N)) ;
45
+        }
46
+
47
+        //rtd(nlay-1) = 0;
48
+        rtd(0) = (Zyu(1)+Zyd(1)) / (Zyu(1)-Zyd(1)) ;
49
+
50
+        return;
51
+    }
52
+
53
+    template<>
54
+    void KernelEM1DReflSpec<TE, INAIR, INAIR>::ComputeReflectionCoeffs(const Real& lambda) {
55
+
56
+        rams = lambda*lambda;
57
+        u = (rams-kk.array()).sqrt(); // CRITICAL
58
+        uk = u(0);
59
+        um = u(0);
60
+
61
+        Zyu(1) = -u(0)/zh(0);
62
+        Zyi    =  u.array() / zh.array();
63
+
64
+        Zyd.tail<1>() = Zyi.tail<1>();
65
+
66
+        // Vectorise
67
+        cf.segment(1,nlay-2) = (-2.*u.segment(1, nlay-2).array() * LayerThickness.segment(1, nlay-2).array()).exp();
68
+        th.segment(1,nlay-2) = (1.-cf.segment(1, nlay-2).array()) / (1.+cf.segment(1, nlay-2).array());
69
+
70
+        /*
71
+        for (int ilay=1; ilay<nlay-1; ++ilay) {
72
+            cf(ilay) = std::exp(-(Real)(2.)*u(ilay)*LayerThickness(ilay));
73
+            th(ilay) = ((Real)(1.)-cf(ilay)) / ((Real)(1.)+cf(ilay));
74
+        }
75
+        */
76
+
77
+        // recursive, can't vectorize
78
+        for (int N=nlay-2; N >=1; --N) {
79
+            Zyd(N) = Zyi(N)*(Zyd(N+1)+Zyi(N)*th(N)) / (Zyi(N)+Zyd(N+1)*th(N)) ;
80
+        }
81
+
82
+        //rtd(nlay-1) = 0;
83
+        rtd(0) = (Zyu(1)+Zyd(1)) / (Zyu(1)-Zyd(1)) ;
84
+
85
+        return;
86
+    }
87
+
88
+    template<>
89
+    void KernelEM1DReflSpec<TM, INAIR, INGROUND>::ComputeReflectionCoeffs(const Real& lambda) {
90
+
91
+        rams = lambda*lambda;
92
+        u = (rams-kk.array()).sqrt();
93
+        uk = u(0);
94
+        um = u(layr);
95
+
96
+        Zyu(1) = -u(0)/yh(0);
97
+        Zyi    =  u.array() / yh.array();
98
+
99
+        Zyd.tail<1>() = Zyi.tail<1>();
100
+
101
+        for (int ilay=1; ilay<nlay-1; ++ilay) {
102
+            cf(ilay) = std::exp(-(Real)(2.)*u(ilay)*LayerThickness(ilay));
103
+            th(ilay) = ((Real)(1.)-cf(ilay)) / ((Real)(1.)+cf(ilay));
104
+        }
105
+
106
+        // Can't use blocks, b/c recursive
107
+        for (int N=1; N<lays; ++N){
108
+            Zyu(N+1)=Zyi(N)*(Zyu(N)-Zyi(N)*th(N)) /
109
+                            (Zyi(N)-Zyu(N)*th(N)) ;
110
+        }
111
+
112
+        int ne = nlay-2;
113
+        for (int N=ne; N >=lays+1; --N) {
114
+            Zyd(N) = Zyi(N)*(Zyd(N+1)+Zyi(N)*th(N)) /
115
+                            (Zyi(N)+Zyd(N+1)*th(N)) ;
116
+        }
117
+
118
+        rtd(nlay-1) = 0;
119
+        rtd(0) = (Zyu(1)+Zyd(1)) / (Zyu(1)-Zyd(1)) ;
120
+
121
+        int le = layr;
122
+        if (le == nlay-1) --le;
123
+        for (int N=1; N<=le; ++N) {
124
+            rtd(N) = (Zyi(N)-Zyd(N+1)) / (Zyi(N)+Zyd(N+1)) ;
125
+        }
126
+        return;
127
+    }
128
+
129
+    template<>
130
+    void KernelEM1DReflSpec<TE, INAIR, INGROUND>::ComputeReflectionCoeffs(const Real& lambda) {
131
+
132
+        rams = lambda*lambda;
133
+        u = (rams-kk.array()).sqrt();
134
+        uk = u(0);
135
+        um = u(layr);
136
+
137
+        Zyu(1) = -u(0)/zh(0);
138
+        Zyi    =  u.array() / zh.array();
139
+
140
+        Zyd.tail<1>() = Zyi.tail<1>();
141
+
142
+        for (int ilay=1; ilay<nlay-1; ++ilay) {
143
+            cf(ilay) = std::exp(-(Real)(2.)*u(ilay)*LayerThickness(ilay));
144
+            th(ilay) = ((Real)(1.)-cf(ilay)) / ((Real)(1.)+cf(ilay));
145
+        }
146
+
147
+        // Can't use blocks, b/c recursive
148
+        for (int N=1; N<lays; ++N){
149
+            Zyu(N+1)=Zyi(N)*(Zyu(N)-Zyi(N)*th(N)) /
150
+                            (Zyi(N)-Zyu(N)*th(N)) ;
151
+        }
152
+
153
+        int ne = nlay-2;
154
+        for (int N=ne; N >=lays+1; --N) {
155
+            Zyd(N) = Zyi(N)*(Zyd(N+1)+Zyi(N)*th(N)) /
156
+                            (Zyi(N)+Zyd(N+1)*th(N)) ;
157
+        }
158
+
159
+        rtd(nlay-1) = 0;
160
+        rtd(0) = (Zyu(1)+Zyd(1)) / (Zyu(1)-Zyd(1)) ;
161
+
162
+        int le = layr;
163
+        if (le == nlay-1) --le;
164
+        for (int N=1; N<=le; ++N) {
165
+            rtd(N) = (Zyi(N)-Zyd(N+1)) / (Zyi(N)+Zyd(N+1)) ;
166
+        }
167
+        return;
168
+    }
169
+
170
+    template<>
171
+    void KernelEM1DReflSpec<TM, INAIR, INAIR>::PreComputePotentialTerms( ) {
172
+        relIud = 0;
173
+        if (rx_z<= tx_z) relIud=1;
174
+        relCon = rtd(0)*std::exp(u(0)*(rx_z+tx_z));
175
+        Real adz = std::abs(rx_z - tx_z);
176
+        relenukadz = std::exp(-uk*adz); // Singular source term
177
+    }
178
+
179
+    template<>
180
+    void KernelEM1DReflSpec<TE, INAIR, INAIR>::PreComputePotentialTerms( ) {
181
+        relIud = 0;
182
+        if (rx_z<= tx_z) relIud=1;
183
+        relCon = rtd(0)*std::exp(u(0)*(rx_z+tx_z));
184
+        Real adz = std::abs(rx_z - tx_z);
185
+        relenukadz = std::exp(-uk*adz); // Singular source term
186
+    }
187
+
188
+    template<>
189
+    void KernelEM1DReflSpec<TM, INAIR, INGROUND>::PreComputePotentialTerms( ) {
190
+        Complex dd =  ((Real)(1.)+rtd(1)*cf(1));
191
+        rel_a = ((Real)(1.) + rtd(0)) / dd;
192
+        if (layr >= 2) {
193
+            for (int n=2; n<=layr; ++n) {
194
+                rel_a *= ((Real)(1.)+rtd(n-1));
195
+                if (n < nlay-1) {
196
+                    rel_a /= ((Real)(1.)+rtd(n)*cf(n));
197
+                }
198
+            }
199
+        }
200
+        Complex p(0,0);
201
+        for (int n=1; n<=layr; ++n) {
202
+            Complex ut = u(0);
203
+            if (n>1) {
204
+                ut = u(n-1);
205
+            }
206
+            p += (u(n)-ut) * LayerDepth(n-1);
207
+        }
208
+        relexp_pbs1 = std::exp(uk*tx_z-um*rx_z+ p);
209
+
210
+        if (layr < Earth->GetNumberOfLayers()-1) {
211
+            relexp_pbs2 = std::exp(uk*tx_z-um*((Real)(2.)*LayerDepth(layr)-rx_z)+p);
212
+        }
213
+    }
214
+
215
+    template<>
216
+    void KernelEM1DReflSpec<TE, INAIR, INGROUND>::PreComputePotentialTerms( ) {
217
+        Complex dd =  ((Real)(1.)+rtd(1)*cf(1));
218
+        rel_a = ((Real)(1.) + rtd(0)) / dd;
219
+        if (layr >= 2) {
220
+            for (int n=2; n<=layr; ++n) {
221
+                rel_a *= ((Real)(1.)+rtd(n-1));
222
+                if (n < nlay-1) {
223
+                    rel_a /= ((Real)(1.)+rtd(n)*cf(n));
224
+                }
225
+            }
226
+        }
227
+        Complex p(0,0);
228
+        for (int n=1; n<=layr; ++n) {
229
+            Complex ut = u(0);
230
+            if (n>1) {
231
+                ut = u(n-1);
232
+            }
233
+            p += (u(n)-ut) * LayerDepth(n-1);
234
+        }
235
+        relexp_pbs1 = std::exp(uk*tx_z-um*rx_z+ p);
236
+        if (layr < Earth->GetNumberOfLayers()-1) {
237
+            relexp_pbs2 = std::exp(uk*tx_z-um*((Real)(2.)*LayerDepth(layr)-rx_z)+p);
238
+        }
239
+    }
240
+
241
+}		// -----  end of Lemma  name  -----

+ 2652
- 0
Modules/FDEM1D/src/kernelem1dspec.cpp
File diff suppressed because it is too large
View File


+ 361
- 0
Modules/FDEM1D/src/layeredearthem.cpp View File

@@ -0,0 +1,361 @@
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     06/24/2009
11
+  @version  $Id: layeredearthem.cpp 216 2015-03-09 02:26:49Z tirons $
12
+ **/
13
+
14
+#include "layeredearthem.h"
15
+
16
+namespace Lemma {
17
+
18
+#ifdef HAVE_YAMLCPP
19
+    std::ostream &operator << (std::ostream &stream, const LayeredEarthEM &ob) {
20
+        stream << ob.Serialize()  << "\n---\n"; // End of doc --- as a direct stream should encapulste thingy
21
+        return stream;
22
+    }
23
+#else
24
+    std::ostream &operator<<(std::ostream &stream,
25
+                const LayeredEarthEM &ob) {
26
+        stream << *(LayeredEarth*)(&ob);
27
+        //stream << "Class Name : "<< ob.Name  << "\n";
28
+        stream << std::setw(15) << "LayerNumber"         << "\t"
29
+               << std::setw(15) << "Thickness"           << "\t"
30
+               << std::setw(15) << "BottomInterface"     << "\t"
31
+               << std::setw(15) << "Conductivity"        << "\t"
32
+               << std::setw(15) << "Susceptibility"      << "\t"
33
+               << std::setw(15) << "Permitivity"         << "\n";
34
+        stream << std::setw(15) << " "                   << "\t"
35
+               << std::setw(15) << "[m]"                 << "\t"
36
+               << std::setw(15) << "[m]"                 << "\t"
37
+               << std::setw(15) << "[Sm^-1]"             << "\t"
38
+               << std::setw(15) << "[]"                  << "\t"
39
+               << std::setw(15) << "[F/m]"               << "\n";
40
+        for (int i=0; i< ob.NumberOfLayers; ++i) {
41
+            stream << std::setw(15) <<  i << "\t"
42
+                   << std::setw(15) << ((LayeredEarth*)(&ob))->GetLayerThickness(i) << "\t"
43
+                   << std::setw(15) << ((LayeredEarth*)(&ob))->GetLayerDepth(i) << "\t"
44
+                   << std::setw(15) << ob.LayerConductivity(i)     << "\t"
45
+                   << std::setw(15) << ob.LayerSusceptibility(i)   << "\t"
46
+                   << std::setw(15) << ob.LayerPermitivity(i)      << "\n";
47
+        }
48
+
49
+        return stream;
50
+    }
51
+#endif
52
+
53
+    // ====================  LIFECYCLE     ===================================
54
+
55
+    LayeredEarthEM::LayeredEarthEM(const std::string &name) :
56
+        LayeredEarth(name) {
57
+    }
58
+
59
+    LayeredEarthEM::~LayeredEarthEM() {
60
+        if (NumberOfReferences != 0) {
61
+            throw DeleteObjectWithReferences(this);
62
+        }
63
+    }
64
+
65
+    LayeredEarthEM* LayeredEarthEM::New() {
66
+        LayeredEarthEM* Obj = new LayeredEarthEM("LayeredEarthEM");
67
+        Obj->AttachTo(Obj);
68
+        return Obj;
69
+    }
70
+
71
+    void LayeredEarthEM::Delete() {
72
+        this->DetachFrom(this);
73
+    }
74
+
75
+    void LayeredEarthEM::Release() {
76
+        delete this;
77
+    }
78
+
79
+    #ifdef HAVE_YAMLCPP
80
+    YAML::Node LayeredEarthEM::Serialize() const {
81
+        YAML::Node node = LayeredEarth::Serialize();
82
+        node.SetTag( this->Name );
83
+        node["LayerConductivity"] = LayerConductivity;
84
+        node["LayerSusceptibility"] = LayerSusceptibility;
85
+        node["LayerLowFreqSusceptibility"] = LayerLowFreqSusceptibility;
86
+        node["LayerHighFreqSusceptibility"] = LayerHighFreqSusceptibility;
87
+        node["LayerTauSusceptibility"] = LayerTauSusceptibility;
88
+        node["LayerBreathSusceptibility"] = LayerBreathSusceptibility;
89
+        node["LayerPermitivity"] = LayerPermitivity;
90
+        node["LayerLowFreqPermitivity"] = LayerLowFreqPermitivity;
91
+        node["LayerHighFreqPermitivity"] = LayerHighFreqPermitivity;
92
+        node["LayerTauPermitivity"] = LayerTauPermitivity;
93
+        node["LayerBreathPermitivity"] = LayerBreathPermitivity;
94
+        return node;
95
+    }
96
+    #endif
97
+
98
+    // ====================  OPERATIONS    ===================================
99
+    void LayeredEarthEM::EvaluateColeColeModel(const Real& omega) {
100
+
101
+        for (int ilay=0; ilay<NumberOfLayers; ++ilay) {
102
+            if ( LayerTauSusceptibility(ilay) > 1e-10) {
103
+                LayerSusceptibility(ilay) = LayerHighFreqSusceptibility(ilay) + (LayerLowFreqSusceptibility(ilay) -
104
+                     LayerHighFreqSusceptibility(ilay)) /
105
+                    ((Real)(1.) + std::pow(Complex(0, omega*
106
+                                    LayerTauSusceptibility(ilay)),
107
+                             LayerBreathSusceptibility(ilay)));
108
+            } else {
109
+                LayerSusceptibility(ilay) = LayerLowFreqSusceptibility(ilay);
110
+            }
111
+
112
+            if ( LayerTauPermitivity(ilay) > 1e-10) {
113
+                LayerPermitivity(ilay) = LayerHighFreqPermitivity(ilay) +
114
+                    (LayerLowFreqPermitivity(ilay) -
115
+                     LayerHighFreqPermitivity(ilay)) /
116
+                    ((Real)(1.) + std::pow(Complex(0,
117
+                                    omega*LayerTauPermitivity(ilay)),
118
+                            LayerBreathPermitivity(ilay)));
119
+            } else {
120
+                LayerPermitivity(ilay) = LayerLowFreqPermitivity(ilay);
121
+            }
122
+        }
123
+    }
124
+
125
+	LayeredEarthEM* LayeredEarthEM::Clone() {
126
+		LayeredEarthEM* copy = LayeredEarthEM::New();
127
+
128
+		copy->LayerConductivity = this->LayerConductivity;
129
+		copy->LayerSusceptibility = this->LayerSusceptibility;
130
+		copy->LayerLowFreqSusceptibility = this->LayerLowFreqSusceptibility;
131
+		copy->LayerHighFreqSusceptibility = this->LayerHighFreqSusceptibility;
132
+		copy->LayerTauSusceptibility = this->LayerTauSusceptibility;
133
+		copy->LayerBreathSusceptibility = this->LayerBreathSusceptibility;
134
+		copy->LayerPermitivity = this->LayerPermitivity;
135
+		copy->LayerLowFreqPermitivity = this->LayerLowFreqPermitivity;
136
+		copy->LayerHighFreqPermitivity = this->LayerHighFreqPermitivity;
137
+		copy->LayerTauPermitivity = this->LayerTauPermitivity;
138
+		copy->LayerBreathPermitivity = this->LayerBreathPermitivity;
139
+		copy->NumberOfLayers = this->NumberOfLayers;
140
+		copy->NumberOfInterfaces = this->NumberOfInterfaces;
141
+		copy->LayerThickness = this->LayerThickness;
142
+
143
+		return copy;
144
+
145
+	}
146
+
147
+    // ====================  ACCESS        ==================================
148
+
149
+    void LayeredEarthEM::SetLayerConductivity(const VectorXcr &sig) {
150
+        if (sig.size() != this->NumberOfLayers )
151
+            throw EarthModelParametersDoNotMatchNumberOfLayers( );
152
+        LayerConductivity = sig;
153
+    }
154
+
155
+    void LayeredEarthEM::SetLayerConductivity(const int& ilay, const Complex &sig) {
156
+        if (ilay > this->NumberOfLayers || ilay < 1 )
157
+            throw EarthModelParametersDoNotMatchNumberOfLayers( );
158
+        LayerConductivity[ilay] = sig;
159
+    }
160
+
161
+/*
162
+    void LayeredEarthEM::SetLayerResistivity(const VectorXcr &rhos) {
163
+        if (rhos.size() != this->NumberOfLayers )
164
+            throw EarthModelParametersDoNotMatchNumberOfLayers( );
165
+        LayerConductivity = 1./rhos.array();
166
+    }
167
+*/
168
+
169
+    void LayeredEarthEM::SetLayerHighFreqSusceptibility(const VectorXr &sus) {
170
+        if (sus.size() != this->NumberOfLayers )
171
+            throw EarthModelParametersDoNotMatchNumberOfLayers( );
172
+        LayerHighFreqSusceptibility = sus;
173
+    }
174
+
175
+    void LayeredEarthEM::SetLayerLowFreqSusceptibility(const VectorXr &sus) {
176
+        if (sus.size() != this->NumberOfLayers )
177
+            throw EarthModelParametersDoNotMatchNumberOfLayers( );
178
+        LayerLowFreqSusceptibility = sus;
179
+    }
180
+
181
+    void LayeredEarthEM::SetLayerBreathSusceptibility(const VectorXr &sus) {
182
+        if (sus.size() != this->NumberOfLayers )
183
+            throw EarthModelParametersDoNotMatchNumberOfLayers( );
184
+        LayerBreathSusceptibility = sus;
185
+    }
186
+
187
+    void LayeredEarthEM::SetLayerTauSusceptibility(const VectorXr &sus) {
188
+        if (sus.size() != this->NumberOfLayers )
189
+            throw EarthModelParametersDoNotMatchNumberOfLayers( );
190
+        LayerTauSusceptibility = sus;
191
+    }
192
+
193
+    void LayeredEarthEM::SetLayerHighFreqPermitivity(const VectorXr &per) {
194
+        if (per.size() != this->NumberOfLayers )
195
+            throw EarthModelParametersDoNotMatchNumberOfLayers( );
196
+        LayerHighFreqPermitivity = per;
197
+    }
198
+
199
+    void LayeredEarthEM::SetLayerLowFreqPermitivity(const VectorXr &per) {
200
+        if (per.size() != this->NumberOfLayers )
201
+            throw EarthModelParametersDoNotMatchNumberOfLayers( );
202
+        LayerLowFreqPermitivity = per;
203
+    }
204
+
205
+    void LayeredEarthEM::SetLayerBreathPermitivity(const VectorXr &per) {
206
+        if (per.size() != this->NumberOfLayers )
207
+            throw EarthModelParametersDoNotMatchNumberOfLayers( );
208
+        LayerBreathPermitivity = per;
209
+    }
210
+
211
+    void LayeredEarthEM::SetLayerTauPermitivity(const VectorXr &per) {
212
+        if (per.size() != this->NumberOfLayers )
213
+            throw EarthModelParametersDoNotMatchNumberOfLayers( );
214
+        LayerTauPermitivity = per;
215
+    }
216
+
217
+    void LayeredEarthEM::SetLayerThickness(const VectorXr &thick) {
218
+        if (thick.size() != this->NumberOfLayers - 2)
219
+            throw EarthModelParametersDoNotMatchNumberOfLayers( );
220
+        LayerThickness = thick;
221
+    }
222
+
223
+    void LayeredEarthEM::SetNumberOfLayers(const int&nlay) {
224
+
225
+        // Check for validity
226
+        if (nlay < 2) {
227
+            throw EarthModelWithLessThanTwoLayers();
228
+        }
229
+        //else if (nlay > MAXLAYERS)
230
+        //    throw EarthModelWithMoreThanMaxLayers();
231
+
232
+        // Otherwise
233
+        this->NumberOfLayers = nlay;
234
+
235
+
236
+        // Resize all layers
237
+
238
+        //////////////////////////////////
239
+        // Thicknesses set to zero
240
+        LayerThickness = VectorXr::Zero(NumberOfLayers);
241
+
242
+
243
+        ///////////////////////////////////
244
+        // Conducitivy set to zero
245
+        LayerConductivity = VectorXcr::Zero(NumberOfLayers);
246
+
247
+
248
+        ////////////////////////////////////
249
+        // Susceptibility set to One (free space)
250
+        LayerSusceptibility = VectorXcr::Ones(NumberOfLayers);
251
+
252
+        // workaround for Valgrind on AMD which compains about assignment to 1 of VectorXr
253
+        LayerLowFreqSusceptibility = LayerSusceptibility.real();  // 1
254
+        LayerHighFreqSusceptibility = LayerSusceptibility.real(); // 1
255
+        LayerTauSusceptibility = LayerSusceptibility.imag();      // 0
256
+        LayerBreathSusceptibility = LayerSusceptibility.imag();   // 0
257
+
258
+        //////////////////////////////////////
259
+        // Permitivity set to 1 (free space)
260
+        //this->LayerPermitivity.resize(NumberOfLayers);
261
+        //this->LayerPermitivity.setOnes();
262
+        LayerPermitivity = VectorXcr::Ones(NumberOfLayers);
263
+
264
+        // workaround for Valgrind on AMD which compains about assignment to 1 of VectorXr
265
+        LayerLowFreqPermitivity = LayerPermitivity.real();      // 1
266
+        LayerHighFreqPermitivity = LayerPermitivity.real();     // 1
267
+        LayerTauPermitivity = LayerPermitivity.imag();          // 0
268
+        LayerBreathPermitivity = LayerPermitivity.imag();       // 0
269
+
270
+    }
271
+
272
+    // ====================  INQUIRY       ===================================
273
+
274
+    VectorXcr LayeredEarthEM::GetLayerConductivity() {
275
+        return this->LayerConductivity;
276
+    }
277
+
278
+    Complex LayeredEarthEM::GetLayerConductivity(const int &ilay) {
279
+        return this->LayerConductivity(ilay);
280
+    }
281
+
282
+    Complex LayeredEarthEM::GetLayerSusceptibility(const int &ilay) {
283
+        return this->LayerSusceptibility(ilay);
284
+    }
285
+
286
+    VectorXcr LayeredEarthEM::GetLayerSusceptibility( ) {
287
+        return this->LayerSusceptibility;
288
+    }
289
+
290
+    Complex LayeredEarthEM::GetLayerPermitivity(const int &ilay) {
291
+        return this->LayerPermitivity(ilay);
292
+    }
293
+
294
+    VectorXcr LayeredEarthEM::GetLayerPermitivity( ) {
295
+        return this->LayerPermitivity;
296
+    }
297
+
298
+    Real LayeredEarthEM::GetLayerLowFreqSusceptibility(const int &ilay) {
299
+        return this->LayerLowFreqSusceptibility(ilay);
300
+    }
301
+
302
+    VectorXr LayeredEarthEM::GetLayerLowFreqSusceptibility( ) {
303
+        return this->LayerLowFreqSusceptibility;
304
+    }
305
+
306
+    Real LayeredEarthEM::GetLayerHighFreqSusceptibility(const int &ilay) {
307
+        return this->LayerHighFreqSusceptibility(ilay);
308
+    }
309
+
310
+    VectorXr LayeredEarthEM::GetLayerHighFreqSusceptibility( ) {
311
+        return this->LayerHighFreqSusceptibility;
312
+    }
313
+
314
+    Real LayeredEarthEM::GetLayerTauSusceptibility(const int &ilay) {
315
+        return this->LayerTauSusceptibility(ilay);
316
+    }
317
+
318
+    VectorXr LayeredEarthEM::GetLayerTauSusceptibility( ) {
319
+        return this->LayerTauSusceptibility;
320
+    }
321
+
322
+    Real LayeredEarthEM::GetLayerBreathSusceptibility(const int &ilay) {
323
+        return this->LayerBreathSusceptibility(ilay);
324
+    }
325
+
326
+    VectorXr LayeredEarthEM::GetLayerBreathSusceptibility( ) {
327
+        return this->LayerBreathSusceptibility;
328
+    }
329
+
330
+    Real LayeredEarthEM::GetLayerLowFreqPermitivity(const int &ilay) {
331
+        return this->LayerLowFreqPermitivity(ilay);
332
+    }
333
+
334
+    VectorXr LayeredEarthEM::GetLayerLowFreqPermitivity( ) {
335
+        return this->LayerLowFreqPermitivity;
336
+    }
337
+
338
+    Real LayeredEarthEM::GetLayerHighFreqPermitivity(const int &ilay) {
339
+        return this->LayerHighFreqPermitivity(ilay);
340
+    }
341
+
342
+    VectorXr LayeredEarthEM::GetLayerHighFreqPermitivity( ) {
343
+        return this->LayerHighFreqPermitivity;
344
+    }
345
+
346
+    Real LayeredEarthEM::GetLayerTauPermitivity(const int &ilay) {
347
+        return this->LayerTauPermitivity(ilay);
348
+    }
349
+
350
+    VectorXr LayeredEarthEM::GetLayerTauPermitivity( ) {
351
+        return this->LayerTauPermitivity;
352
+    }
353
+
354
+    Real LayeredEarthEM::GetLayerBreathPermitivity(const int &ilay) {
355
+        return this->LayerBreathPermitivity(ilay);
356
+    }
357
+
358
+    VectorXr LayeredEarthEM::GetLayerBreathPermitivity( ) {
359
+        return this->LayerBreathPermitivity;
360
+    }
361
+}

+ 48
- 0
Modules/FDEM1D/src/modelreaderfem1d.cpp View File

@@ -0,0 +1,48 @@
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     01/23/2013
11
+  @version  $Id$
12
+ **/
13
+
14
+#include "modelreaderfem1d.h"
15
+
16
+namespace Lemma {
17
+
18
+	std::ostream &operator<<(std::ostream &stream,
19
+		const ModelReaderFem1D &ob) {
20
+		stream << *(ModelReaderFem1D*)(&ob);
21
+		return stream;
22
+	}
23
+
24
+	ModelReaderFem1D::ModelReaderFem1D(const std::string &name) :
25
+		ModelReader(name) {
26
+	}
27
+
28
+	ModelReaderFem1D::~ModelReaderFem1D() {
29
+		if (NumberOfReferences != 0) {
30
+			throw DeleteObjectWithReferences(this);
31
+		}
32
+	}
33
+
34
+	ModelReaderFem1D* ModelReaderFem1D::New() {
35
+		ModelReaderFem1D* Obj = new ModelReaderFem1D("ModelReaderFem1D");
36
+		Obj->AttachTo(Obj);
37
+		return Obj;
38
+	}
39
+
40
+	void ModelReaderFem1D::Delete() {
41
+		this->DetachFrom(this);
42
+	}
43
+
44
+	void ModelReaderFem1D::Release() {
45
+		delete this;
46
+	}
47
+
48
+} // end of namespace Lemma

+ 1473
- 0
Modules/FDEM1D/src/octreegrid.cpp
File diff suppressed because it is too large
View File


+ 115
- 0
Modules/FDEM1D/src/receivercubes.cpp View File

@@ -0,0 +1,115 @@
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     06/17/2010
11
+  @version  $Id: receivercubes.cpp 87 2013-09-05 22:44:05Z tirons $
12
+ **/
13
+
14
+#include "receivercubes.h"
15
+
16
+namespace Lemma{
17
+
18
+	// ====================    FRIENDS     ======================
19
+	std::ostream &operator<<(std::ostream &stream,
20
+				const ReceiverCubes &ob) {
21
+		stream << *(ReceiverPoints*)(&ob);
22
+  		return stream;
23
+	}
24
+
25
+	// ====================  LIFECYCLE     ===================================
26
+
27
+	ReceiverCubes * ReceiverCubes::New() {
28
+		ReceiverCubes* Obj = new ReceiverCubes("ReceiverCubes");
29
+        Obj->AttachTo(Obj);
30
+        return Obj;
31
+	}
32
+
33
+	void ReceiverCubes::Delete() {
34
+		this->DetachFrom(this);
35
+	}
36
+
37
+    void ReceiverCubes::Release() {
38
+		delete this;
39
+	}
40
+
41
+	ReceiverCubes::ReceiverCubes(const std::string &name) :
42
+			ReceiverPoints(name) {
43
+	}
44
+
45
+	ReceiverCubes::~ReceiverCubes() {
46
+        if (this->NumberOfReferences != 0)
47
+            throw DeleteObjectWithReferences( this );
48
+    }
49
+
50
+	// ====================  OPERATIONS    =======================
51
+
52
+	void ReceiverCubes::SetNumberOfReceivers(const int &nrec){
53
+
54
+        ReceiverPoints::SetNumberOfReceivers(nrec);
55
+
56
+		this->Locations.resize(Eigen::NoChange, nrec);
57
+		this->Locations.setZero();
58
+
59
+		this->Lengths.resize(Eigen::NoChange, nrec);
60
+		this->Lengths.setZero();
61
+
62
+	}
63
+
64
+	void ReceiverCubes::SetLengthX(const int &ir, const  Real& lx) {
65
+		this->Lengths.col(ir)[0] = lx;
66
+	}
67
+
68
+	void ReceiverCubes::SetLengthY(const int &ir, const  Real& ly) {
69
+		this->Lengths.col(ir)[1] = ly;
70
+	}
71
+
72
+	void ReceiverCubes::SetLengthZ(const int &ir, const  Real& lz) {
73
+		this->Lengths.col(ir)[2] = lz;
74
+	}
75
+
76
+	void ReceiverCubes::SetLength(const int &ir, const  Vector3r& l) {
77
+		this->Lengths.col(ir) = l;
78
+	}
79
+
80
+	void ReceiverCubes::SetLength(const int &ir,const  Real& lx,
81
+					const Real& ly, const Real& lz) {
82
+		this->Lengths.col(ir) << lx, ly, lz;
83
+	}
84
+
85
+	Real ReceiverCubes::GetLengthX(const int &ir) {
86
+		return this->Lengths.col(ir)[0];
87
+	}
88
+
89
+	Real ReceiverCubes::GetLengthY(const int &ir) {
90
+		return this->Lengths.col(ir)[1];
91
+	}
92
+
93
+	Real ReceiverCubes::GetLengthZ(const int &ir) {
94
+		return this->Lengths.col(ir)[2];
95
+	}
96
+
97
+	Vector3r ReceiverCubes::GetLength(const int& ir) {
98
+		return this->Lengths.col(ir);
99
+	}
100
+
101
+	Real ReceiverCubes::GetVolume(const int& ir) {
102
+		return this->Lengths.col(ir)[0] *
103
+			   this->Lengths.col(ir)[1] *
104
+		       this->Lengths.col(ir)[2] ;
105
+	}
106
+
107
+	Real ReceiverCubes::GetVolumeSum() {
108
+		Real Vol = 0.;
109
+		for (int i=0; i<NumberOfReceivers; ++i) {
110
+			Vol += GetVolume(i);
111
+		}
112
+		return Vol;
113
+	}
114
+
115
+}		// -----  end of Lemma  name  -----

+ 563
- 0
Modules/FDEM1D/src/receiverpoints.cpp View File

@@ -0,0 +1,563 @@
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: receiverpoints.cpp 203 2015-01-09 21:19:04Z tirons $
12
+ **/
13
+
14
+#include "receiverpoints.h"
15
+
16
+namespace Lemma {
17
+
18
+    // ====================    FRIENDS     ======================
19
+
20
+#ifdef HAVE_YAMLCPP
21
+    std::ostream &operator << (std::ostream &stream, const ReceiverPoints &ob) {
22
+        stream << ob.Serialize()  << "\n---\n"; // End of doc --- as a direct stream should encapulste thingy
23
+        return stream;
24
+    }
25
+#else
26
+    std::ostream &operator<<(std::ostream &stream,
27
+                const ReceiverPoints &ob) {
28
+
29
+        stream << *(LemmaObject*)(&ob);
30
+        stream << "Number of Receivers "<< ob.NumberOfReceivers  << "\n";
31
+        return stream;
32
+    }
33
+#endif
34
+
35
+    // ====================  LIFECYCLE     ===================================
36
+
37
+    ReceiverPoints::ReceiverPoints(const std::string& name) :
38
+        LemmaObject(name),
39
+        NumberOfReceivers(0), NumberOfBinsE(0), NumberOfBinsH(0) {
40
+    }
41
+
42
+#ifdef HAVE_YAMLCPP
43
+    //--------------------------------------------------------------------------------------
44
+    //       Class:  ReceiverPoints
45
+    //      Method:  ReceiverPoints
46
+    // Description:  constructor (protected)
47
+    //--------------------------------------------------------------------------------------
48
+    ReceiverPoints::ReceiverPoints (const YAML::Node& node) : LemmaObject(node) {
49
+
50
+        //DeSerialize
51
+        NumberOfReceivers = node["NumberOfReceivers"].as<int>();
52
+        NumberOfBinsE = node["NumberOfBinsE"].as<int>();
53
+        NumberOfBinsH = node["NumberOfBinsH"].as<int>();
54
+        Mask = node["Mask"].as<VectorXi>();
55
+        Locations = node["Locations"].as<Vector3Xr>();
56
+
57
+    }  // -----  end of method ReceiverPoints::ReceiverPoints  (constructor)  -----
58
+#endif
59
+
60
+    ReceiverPoints::~ReceiverPoints() {
61
+        if (this->NumberOfReferences != 0)
62
+            throw DeleteObjectWithReferences( this );
63
+    }
64
+
65
+    ReceiverPoints* ReceiverPoints::New() {
66
+        ReceiverPoints* Obj = new ReceiverPoints("ReceiverPoints");
67
+        Obj->AttachTo(Obj);
68
+        return Obj;
69
+    }
70
+
71
+    void ReceiverPoints::Delete() {
72
+        this->DetachFrom(this);
73
+    }
74
+
75
+    void ReceiverPoints::Release() {
76
+        delete this;
77
+    }
78
+
79
+    // ====================  ACCESS        ===================================
80
+
81
+    void ReceiverPoints::SetNumberOfReceivers(const int &nrec) {
82
+
83
+        if (nrec > 0)
84
+            this->NumberOfReceivers = nrec;
85
+        else
86
+            throw std::runtime_error("NUMBER RECEIVERS LESS THAN 1");
87
+
88
+        this->Locations.resize(Eigen::NoChange, nrec);
89
+        Locations.setZero();
90
+
91
+        this->Mask.resize(nrec);
92
+        Mask.setZero();
93
+
94
+        ResizeEField();
95
+        ResizeHField();
96
+    }
97
+
98
+    void ReceiverPoints::ResizeEField() {
99
+        Efield.clear();
100
+        for (int i=0; i<NumberOfBinsE; ++i) {
101
+            Eigen::Matrix<Complex, 3, Eigen::Dynamic> tempe;
102
+            this->Efield.push_back(tempe);
103
+            this->Efield[i].resize(Eigen::NoChange, NumberOfReceivers);
104
+            this->Efield[i].setZero();
105
+        }
106
+    }
107
+
108
+    void ReceiverPoints::ResizeHField() {
109
+        Hfield.clear();
110
+        for (int i=0; i<NumberOfBinsH; ++i) {
111
+            Eigen::Matrix<Complex, 3, Eigen::Dynamic> temph;
112
+            this->Hfield.push_back(temph);
113
+            this->Hfield[i].resize(Eigen::NoChange, NumberOfReceivers);
114
+            this->Hfield[i].setZero();
115
+        }
116
+    }
117
+
118
+    void ReceiverPoints::SetNumberOfBinsE(const int& nbins) {
119
+        NumberOfBinsE = nbins;
120
+        ResizeEField();
121
+    }
122
+
123
+    void ReceiverPoints::SetNumberOfBinsH(const int& nbins) {
124
+        NumberOfBinsH = nbins;
125
+        ResizeHField();
126
+    }
127
+
128
+    void ReceiverPoints::SetLocation(const int&nrec,const  Vector3r& loc) {
129
+        this->Locations.col(nrec) = loc;
130
+    }
131
+
132
+    void ReceiverPoints::SetLocation(const int&nrec,const  Real& xp,
133
+                    const Real& yp, const Real& zp) {
134
+        this->Locations.col(nrec) << xp, yp, zp;
135
+    }
136
+
137
+    void ReceiverPoints::SetEfield(const int& nbin,
138
+                    const int& loc, const Complex &ex,
139
+                    const Complex &ey, const Complex &ez) {
140
+        this->Efield[nbin].col(loc) << ex, ey, ez;
141
+    }
142
+
143
+    void ReceiverPoints::AppendEfield(const int&nbin, const int& loc,
144
+                    const Complex &ex,
145
+                    const Complex &ey, const Complex &ez) {
146
+        #ifdef LEMMAUSEOMP
147
+        #pragma omp critical
148
+        #endif
149
+        this->Efield[nbin].col(loc) += Vector3cr(ex, ey, ez); //temp;
150
+    }
151
+
152
+    void ReceiverPoints::SetHfield(const int &nbin, const int& loc,
153
+                    const Complex &hx, const Complex &hy,
154
+                    const Complex &hz) {
155
+        this->Hfield[nbin].col(loc) << hx, hy, hz;
156
+    }
157
+
158
+    void ReceiverPoints::AppendHfield(const int &nbin, const int& loc,
159
+                    const Complex &hx, const Complex &hy,
160
+                    const Complex &hz) {
161
+//      #ifdef LEMMAUSEOMP
162
+//      #pragma omp atomic
163
+//      std::real(this->Hfield[nbin].col(loc)[0]) += std::real(hx);
164
+//      #pragma omp atomic
165
+//      std::imag(this->Hfield[nbin].col(loc)[0]) += std::imag(hx);
166
+//      #pragma omp atomic
167
+//      std::real(this->Hfield[nbin].col(loc)[1]) += std::real(hy);
168
+//      #pragma omp atomic
169
+//      std::imag(this->Hfield[nbin].col(loc)[1]) += std::imag(hy);
170
+//      #pragma omp atomic
171
+//      std::real(this->Hfield[nbin].col(loc)[2]) += std::real(hz);
172
+//      #pragma omp atomic
173
+//      std::imag(this->Hfield[nbin].col(loc)[2]) += std::imag(hz);
174
+//          #else
175
+        //(critical sections are slow)
176
+        #ifdef LEMMAUSEOMP
177
+        #pragma omp critical
178
+        #endif
179
+        this->Hfield[nbin].col(loc) += Vector3cr(hx,hy,hz);
180
+        //#endif
181
+    }
182
+
183
+
184
+    // ====================  INQUIRY       ===================================
185
+    Vector3Xr ReceiverPoints::GetLocations() {
186
+        return this->Locations;
187
+    }
188
+
189
+    MatrixXr ReceiverPoints::GetLocationsMat() {
190
+        return MatrixXr(this->Locations);
191
+    }
192
+
193
+    Vector3r ReceiverPoints::GetLocation(const int &nrec) {
194
+        return this->Locations.col(nrec);
195
+    }
196
+
197
+    Real ReceiverPoints::GetLocationX(const int &nrec) {
198
+        return this->Locations.col(nrec)[0];
199
+    }
200
+
201
+    Real ReceiverPoints::GetLocationY(const int &nrec) {
202
+        return this->Locations.col(nrec)[1];
203
+    }
204
+
205
+    Real ReceiverPoints::GetLocationZ(const int &nrec) {
206
+        return this->Locations.col(nrec)[2];
207
+    }
208
+
209
+    Vector3cr ReceiverPoints::GetEfield(const int &nfreq, const int&nrec) {
210
+        return this->Efield[nfreq].col(nrec);
211
+    }
212
+
213
+    Vector3cr ReceiverPoints::GetHfield(const int &nfreq, const int&nrec) {
214
+        return this->Hfield[nfreq].col(nrec);
215
+    }
216
+
217
+    std::vector<Vector3Xcr> ReceiverPoints::GetHfield( ) {
218
+        return this->Hfield;
219
+    }
220
+
221
+    std::vector<Vector3Xcr> ReceiverPoints::GetEfield( ) {
222
+        return this->Efield;
223
+    }
224
+
225
+    Vector3Xcr ReceiverPoints::GetEfield (const int &nfreq) {
226
+        return this->Efield[nfreq];
227
+    }
228
+
229
+    MatrixXcr ReceiverPoints::GetEfieldMat (const int &nfreq) {
230
+        return MatrixXcr(this->Efield[nfreq]);
231
+    }
232
+
233
+    MatrixXcr ReceiverPoints::GetHfieldMat (const int &nfreq) {
234
+        return MatrixXcr(this->Hfield[nfreq]);
235
+    }
236
+
237
+    Vector3Xcr ReceiverPoints::GetHfield (const int &nfreq) {
238
+        return this->Hfield[nfreq];
239
+    }
240
+
241
+    void ReceiverPoints::MaskPoint(const int& imask) {
242
+        Mask(imask) = true;
243
+    }
244
+
245
+    void ReceiverPoints::UnMaskPoint(const int& imask) {
246
+        Mask(imask) = false;
247
+    }
248
+
249
+    void ReceiverPoints::UnMaskAllPoints() {
250
+        Mask.setZero();
251
+    }
252
+
253
+    int ReceiverPoints::GetMask(const int& i) {
254
+        return Mask(i);
255
+    }
256
+
257
+    int ReceiverPoints::GetNumberOfReceivers() {
258
+        return this->NumberOfReceivers;
259
+    }
260
+
261
+    void ReceiverPoints::ClearFields() {
262
+        for (int i=0; i<NumberOfBinsE; ++i) {
263
+            this->Efield[i].setZero();
264
+        }
265
+        for (int i=0; i<NumberOfBinsH; ++i) {
266
+            this->Hfield[i].setZero();
267
+        }
268
+    }
269
+
270
+
271
+#ifdef HAVE_YAMLCPP
272
+    //--------------------------------------------------------------------------------------
273
+    //       Class:  ReceiverPoints
274
+    //      Method:  Serialize
275
+    //--------------------------------------------------------------------------------------
276
+    YAML::Node  ReceiverPoints::Serialize (  ) const {
277
+        YAML::Node node = LemmaObject::Serialize(); //static_cast<const LemmaObject*>(this)->Serialize();
278
+        node.SetTag( this->Name ); // Set Tag after doing parents
279
+
280
+        // update here
281
+        node["NumberOfReceivers"] = NumberOfReceivers;
282
+        node["NumberOfBinsE"] = NumberOfBinsE;
283
+        node["NumberOfBinsH"] = NumberOfBinsH;
284
+        //node["Mask"] = Mask;
285
+        //std::cout << "Locations.data" << Locations.data()[0] << std::endl;
286
+        // node["Locations"] = Locations.data(); // HUGE
287
+        return node;
288
+    }		// -----  end of method ReceiverPoints::Serialize  -----
289
+
290
+
291
+    //--------------------------------------------------------------------------------------
292
+    //       Class:  ReceiverPoints
293
+    //      Method:  DeSerialize
294
+    //--------------------------------------------------------------------------------------
295
+    ReceiverPoints* ReceiverPoints::DeSerialize ( const YAML::Node& node  ) {
296
+        ReceiverPoints* Object = new ReceiverPoints(node);
297
+        Object->AttachTo(Object);
298
+        DESERIALIZECHECK( node, Object )
299
+        return Object ;
300
+    }		// -----  end of method ReceiverPoints::DeSerialize  -----
301
+#endif
302
+
303
+
304
+    #ifdef LEMMAUSEVTK
305
+    vtkActor* ReceiverPoints::GetVtkGlyphActor(const FIELDTYPE &ftype,
306
+                    const Real &clip, const Real &scale,
307
+                    const int &nfreq) {
308
+
309
+        vtkArrowSource        *vArrow;
310
+        vtkGlyph3D            *vGlyph;
311
+        vtkActor              *vActor;
312
+        vtkPolyDataMapper     *vPolyMapper;
313
+        vtkPoints             *vPoints;
314
+        vtkDoubleArray        *vVects;
315
+        vtkPolyData           *vPointSet;
316
+
317
+        vActor = vtkActor::New();
318
+        vGlyph = vtkGlyph3D::New();
319
+        vArrow = vtkArrowSource::New();
320
+        vPolyMapper = vtkPolyDataMapper::New();
321
+        vPoints = vtkPoints::New();
322
+        vPointSet = vtkPolyData::New();
323
+        vVects = vtkDoubleArray::New();
324
+
325
+        vVects->SetNumberOfComponents(3);
326
+
327
+        // Make PointData
328
+        for (int ic=0; ic<NumberOfReceivers; ++ic) {
329
+
330
+            Vector3r loc = this->GetLocation(ic);
331
+
332
+            vPoints->InsertPoint(ic, loc[0], loc[1],
333
+                            loc[2]);
334
+            Vector3r temp;
335
+            temp.setZero();
336
+
337
+            switch (ftype) {
338
+                case HFIELDREAL:
339
+                    temp = scale*(GetHfield(nfreq,ic).real());
340
+                    break;
341
+                case HFIELDIMAG:
342
+                    temp = scale*(GetHfield(nfreq,ic).imag());
343
+                    break;
344
+                case EFIELDREAL:
345
+                    temp = scale*(GetEfield(nfreq, ic).real());
346
+                    break;
347
+                case EFIELDIMAG:
348
+                    temp = scale*(GetEfield(nfreq, ic).imag());
349
+                    break;
350
+            }
351
+            if (temp.norm() > clip) {
352
+                temp /= temp.norm(); // norm
353
+                temp *= clip;        // clip dimension
354
+            }
355
+
356
+            vVects->InsertTuple3(ic, temp(0), temp(1),
357
+                            temp(2));
358
+        }
359
+
360
+        vPointSet->SetPoints(vPoints);
361
+        vPointSet->GetPointData()->SetVectors(vVects);
362
+        vGlyph->ScalingOn();
363
+        vGlyph->SetScaleModeToScaleByVector();
364
+        vGlyph->SetSourceConnection(vArrow->GetOutputPort());
365
+        vGlyph->SetVectorMode(true);
366
+        vGlyph->SetVectorModeToUseVector();
367
+        vGlyph->OrientOn();
368
+        vGlyph->SetInputData(vPointSet);
369
+        vPolyMapper->SetInputConnection(vGlyph->GetOutputPort());
370
+        vActor->SetMapper(vPolyMapper);
371
+
372
+        if (vArrow != NULL) {
373
+            vArrow->Delete();
374
+            vArrow = NULL;
375
+        }
376
+        //if (vActor != NULL) {
377
+        //  vActor->Delete();
378
+        //  vActor = NULL;
379
+        //}
380
+        if (vPolyMapper != NULL) {
381
+            vPolyMapper->Delete();
382
+            vPolyMapper = NULL;
383
+        }
384
+        if (vVects != NULL) {
385
+            vVects->Delete();
386
+            vVects = NULL;
387
+        }
388
+        if (vPointSet != NULL) {
389
+            vPointSet->Delete();
390
+            vPointSet = NULL;
391
+        }
392
+        if (vPoints != NULL) {
393
+            vPoints->Delete();
394
+            vPoints = NULL;
395
+        }
396
+        if (vGlyph != NULL) {
397
+            vGlyph->Delete();
398
+            vGlyph = NULL;
399
+        }
400
+
401
+        return vActor;
402
+    }
403
+
404
+    vtkDataObject* ReceiverPoints::GetVtkDataObject(const FIELDTYPE &ftype,
405
+                    const int& nbin,
406
+                    const int& start, const int& end,
407
+                    const FIELDCOMPONENT& fcomp,
408
+                    const SPATIALCOORDINANT &scord) {
409
+
410
+        if (start < 0) throw 77;
411
+        if (end > NumberOfReceivers) throw 78;
412
+        if (start > end) throw 79;
413
+
414
+        int ifc(-1);
415
+        switch (fcomp) {
416
+            case XCOMPONENT:
417
+                ifc = 0;
418
+                break;
419
+            case YCOMPONENT:
420
+                ifc = 1;
421
+                break;
422
+            case ZCOMPONENT:
423
+                ifc = 2;
424
+                break;
425
+        }
426
+
427
+        int isc(-1);
428
+        switch (scord) {
429
+            case XCOORD:
430
+                isc = 0;
431
+                break;
432
+
433
+            case YCOORD:
434
+                isc = 1;
435
+                break;
436
+
437
+            case ZCOORD:
438
+                isc = 2;
439
+                break;
440
+        }
441
+
442
+        vtkDoubleArray *_data = vtkDoubleArray::New();
443
+            _data->SetNumberOfComponents(1);
444
+
445
+        vtkDoubleArray *_pos = vtkDoubleArray::New();
446
+            _pos->SetNumberOfComponents(1);
447
+
448
+        int id=0;
449
+        for (int irec=start; irec<end; ++irec) {
450
+
451
+            switch (ftype) {
452
+
453
+                case HFIELDREAL:
454
+                    _data->InsertTuple1(id, std::real(Hfield[nbin](ifc, irec)));
455
+                    break;
456
+
457
+                case HFIELDIMAG:
458
+                    _data->InsertTuple1(id, std::imag(Hfield[nbin](ifc, irec)));
459
+                    break;
460
+
461
+                case EFIELDREAL:
462
+                    _data->InsertTuple1(id, std::real(Efield[nbin](ifc, irec)));
463
+                    break;
464
+
465
+                case EFIELDIMAG:
466
+                    _data->InsertTuple1(id, std::imag(Efield[nbin](ifc, irec)));
467
+                    break;
468
+            }
469
+
470
+            _pos->InsertTuple1(id, Locations(isc, irec));
471
+            ++id;
472
+
473
+        }
474
+
475
+        vtkFieldData *_fieldData = vtkFieldData::New();
476
+            _fieldData->AllocateArrays(2);
477
+            _fieldData->AddArray(_data);
478
+            _fieldData->AddArray(_pos);
479
+
480
+        vtkDataObject *_dataObject = vtkDataObject::New();
481
+            _dataObject->SetFieldData(_fieldData);
482
+
483
+        _data->Delete();
484
+        _pos->Delete();
485
+        _fieldData->Delete();
486
+
487
+        return _dataObject;
488
+    }
489
+
490
+    vtkDataObject* ReceiverPoints::GetVtkDataObjectFreq(const FIELDTYPE &ftype,
491
+                    const int& nrec,
492
+                    const int& fstart, const int& fend,
493
+                    const FIELDCOMPONENT& fcomp,
494
+                    const VectorXr& Freqs) {
495
+
496
+        if (fstart < 0) throw 77;
497
+        //if (fend > NumberOfFrequencies) throw 78;
498
+        if (fstart > fend) throw 79;
499
+
500
+        int ifc(-1);
501
+        switch (fcomp) {
502
+            case XCOMPONENT:
503
+                ifc = 0;
504
+                break;
505
+            case YCOMPONENT:
506
+                ifc = 1;
507
+                break;
508
+            case ZCOMPONENT:
509
+                ifc = 2;
510
+                break;
511
+        }
512
+
513
+        vtkDoubleArray *_data = vtkDoubleArray::New();
514
+            _data->SetNumberOfComponents(1);
515
+
516
+        vtkDoubleArray *_pos = vtkDoubleArray::New();
517
+            _pos->SetNumberOfComponents(1);
518
+
519
+        int id=0;
520
+        //std::cout.precision(12);
521
+        for (int ifreq=fstart; ifreq<fend; ++ifreq) {
522
+
523
+            switch (ftype) {
524
+
525
+                case HFIELDREAL:
526
+                    _data->InsertTuple1(id, std::real(Hfield[ifreq](ifc, nrec)));
527
+                    //std::cout <<  Hfield[ifreq](ifc, nrec) << std::endl;
528
+                    break;
529
+
530
+                case HFIELDIMAG:
531
+                    _data->InsertTuple1(id, std::imag(Hfield[ifreq](ifc, nrec)));
532
+                    break;
533
+
534
+                case EFIELDREAL:
535
+                    _data->InsertTuple1(id, std::real(Efield[ifreq](ifc, nrec)));
536
+                    break;
537
+
538
+                case EFIELDIMAG:
539
+                    _data->InsertTuple1(id, std::imag(Efield[ifreq](ifc, nrec)));
540
+                    break;
541
+            }
542
+
543
+            _pos->InsertTuple1(id, Freqs[ifreq]);
544
+            ++id;
545
+
546
+        }
547
+
548
+        vtkFieldData *_fieldData = vtkFieldData::New();
549
+            _fieldData->AllocateArrays(2);
550
+            _fieldData->AddArray(_data);
551
+            _fieldData->AddArray(_pos);
552
+
553
+        vtkDataObject *_dataObject = vtkDataObject::New();
554
+            _dataObject->SetFieldData(_fieldData);
555
+
556
+        _data->Delete();
557
+        _pos->Delete();
558
+        _fieldData->Delete();
559
+
560
+        return _dataObject;
561
+    }
562
+    #endif
563
+}

+ 103
- 0
Modules/FDEM1D/src/sintransintegrationkernel.cpp View File

@@ -0,0 +1,103 @@
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     02/08/2011
11
+  @version  $Id: sintransintegrationkernel.cpp 87 2013-09-05 22:44:05Z tirons $
12
+ **/
13
+
14
+#include "sintransintegrationkernel.h"
15
+
16
+namespace Lemma {
17
+
18
+    // ====================  FRIENDS       =======================
19
+
20
+//     std::ostream &operator<<(std::ostream &stream,
21
+// 			const DigitalFilterSinTrans &ob) {
22
+// 		stream << *(DigitalFilterIntegrator<Real>*)(&ob);
23
+// 		return stream;
24
+// 	}
25
+
26
+    // ====================  LIFECYCLE     =======================
27
+
28
+    SinTransIntegrationKernel::
29
+        SinTransIntegrationKernel(const std::string& name) :
30
+        IntegrationKernel<Real>(name) {
31
+    }
32
+
33
+    SinTransIntegrationKernel::~SinTransIntegrationKernel() {}
34
+
35
+
36
+    SinTransIntegrationKernel* SinTransIntegrationKernel::New() {
37
+        SinTransIntegrationKernel* Obj =
38
+            new SinTransIntegrationKernel("SinTransIntegrationKernel");
39
+        Obj->AttachTo(Obj);
40
+        return Obj;
41
+    }
42
+
43
+    void SinTransIntegrationKernel::Delete() {
44
+        this->DetachFrom(this);
45
+    }
46
+
47
+    void SinTransIntegrationKernel::Release() {
48
+        delete this;
49
+    }
50
+
51
+    // ====================  OPERATIONS    =======================
52
+
53
+    void SinTransIntegrationKernel::SetA(const Real& Ain) {
54
+        A = Ain;
55
+    }
56
+
57
+    void SinTransIntegrationKernel::SetIntegral(const int& i) {
58
+        Integral = i;
59
+    }
60
+
61
+    Real SinTransIntegrationKernel::GetAnalytical (const Real& B) {
62
+        Real SQPI = std::sqrt(PI);
63
+        switch (Integral) {
64
+            case 1:
65
+                return SQPI*B*std::exp(-B*B/(4.*A*A))/(4.*A*A*A);
66
+                break;
67
+            case 2:
68
+                return (PI/2.)*std::exp(-A*B);
69
+                break;
70
+            case 3:
71
+                return B/(A*A+B*B);
72
+                break;
73
+            default:
74
+                std::cerr << "Test integral is not allowed\n";
75
+                exit(EXIT_FAILURE);
76
+        }
77
+    }
78
+
79
+    Real SinTransIntegrationKernel::Argument(const Real&x, const int& iRelated) {
80
+
81
+//     1      DEXP(-A*A*G*G)    SQPI*DEXP(-B*B/(4.*A*A))/(2.*A), WHERE
82
+//                               SQPI="SQUARE ROOT OF PI"
83
+//     2      1/(A*A+G*G)       (PI/2)*DEXP(-A*B)/A
84
+//     3      DEXP(-A*G)        A/(A*A+B*B)
85
+
86
+        switch (Integral) {
87
+            case 1:
88
+                return x*std::exp( -A*A*x*x );
89
+            case 2:
90
+                return x/(A*A+x*x);
91
+            case 3:
92
+                return std::exp(-A*x);
93
+            default:
94
+                std::cerr << "Test integral is not allowed\n";
95
+                exit(EXIT_FAILURE);
96
+        }
97
+    }
98
+
99
+    int SinTransIntegrationKernel::GetNumRel( ) {
100
+        return 1;
101
+    }
102
+
103
+}		// -----  end of Lemma  name  -----

+ 0
- 0
Modules/Optimization/CMakeLists.txt View File


+ 111
- 0
Modules/Optimization/include/quasinewtonbfgs.h View File

@@ -0,0 +1,111 @@
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     08/09/2010
11
+  @version  $Id: quasinewtonbfgs.h 193 2014-11-10 23:51:41Z tirons $
12
+ **/
13
+
14
+#ifndef  QUASINEWTONBFGS_INC
15
+#define  QUASINEWTONBFGS_INC
16
+
17
+#include "inversesolver.h"
18
+
19
+namespace Lemma {
20
+
21
+
22
+    // ===================================================================
23
+    //  Class:  QuasiNewtonBFGS
24
+    /**
25
+      @class  QuasiNewtonBFGS
26
+      \brief  Implimentation of a quasi-newton BFGS solver applied to
27
+              inverse problems.
28
+      \details Based of the algorithm described in Nocedal and Wright book.
29
+     */
30
+    // ===================================================================
31
+    class QuasiNewtonBFGS : public InverseSolver {
32
+
33
+        friend  std::ostream &operator<<(std::ostream &stream,
34
+                const QuasiNewtonBFGS &ob);
35
+
36
+        public:
37
+
38
+            // ====================  LIFECYCLE     =======================
39
+
40
+            /** Returns a pointer to a new object of type QuasiNewtonBFGS.
41
+             * It allocates all necessary memory.
42
+             */
43
+            static QuasiNewtonBFGS* New();
44
+
45
+            /**
46
+             * @copybrief LemmaObject::Delete()
47
+             * @copydetails LemmaObject::Delete()
48
+             */
49
+            void Delete();
50
+
51
+            // ====================  OPERATORS     =======================
52
+
53
+            // ====================  OPERATIONS    =======================
54
+
55
+            // ====================  ACCESS        =======================
56
+
57
+            // ====================  INQUIRY       =======================
58
+
59
+            /** @copybrief InverseSolver::NumberOfIterations()
60
+             *  @copydetails InverseSolver::NumberOfIterations()
61
+             */
62
+            int NumberOfIterations();
63
+
64
+            /** @copybrief InverseSolver::Success()
65
+             *  @copydetails InverseSolver::Success()
66
+             */
67
+            bool Success();
68
+
69
+            /** @copybrief InverseSolver::GetPhiMVector()
70
+             *  @copydetails InverseSolver::GetPhiMVector()
71
+             */
72
+            VectorXr GetPhiMVector();
73
+
74
+            /** @copybrief InverseSolver::GetPhiDVector()
75
+             *  @copydetails InverseSolver::GetPhiDVector()
76
+             */
77
+            VectorXr GetPhiDVector();
78
+
79
+            /// TODO remove this, test
80
+            void PrintNorm();
81
+
82
+        protected:
83
+
84
+            // ====================  LIFECYCLE     =======================
85
+
86
+            /// Default protected constructor.
87
+            QuasiNewtonBFGS (const std::string& cname);
88
+
89
+            /// Default protected constructor.
90
+            ~QuasiNewtonBFGS ();
91
+
92
+            /**
93
+             * @copybrief LemmaObject::Release()
94
+             * @copydetails LemmaObject::Release()
95
+             */
96
+            void Release();
97
+
98
+            // ====================  OPERATIONS    =======================
99
+
100
+            /// Just a filler
101
+            void FillInG(const Vector3r& pos, const Vector3r& step);
102
+
103
+            // ====================  DATA MEMBERS  =========================
104
+
105
+        private:
106
+
107
+    }; // -----  end of class  QuasiNewtonBFGS  -----
108
+
109
+}		// -----  end of Lemma  name  -----
110
+
111
+#endif   // ----- #ifndef QUASINEWTONBFGS_INC  -----

+ 85
- 0
Modules/Optimization/src/quasinewtonbfgs.cpp View File

@@ -0,0 +1,85 @@
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     08/09/2010
11
+  @version  $Id: quasinewtonbfgs.cpp 87 2013-09-05 22:44:05Z tirons $
12
+ **/
13
+
14
+#include "quasinewtonbfgs.h"
15
+
16
+
17
+namespace Lemma {
18
+
19
+    // ====================  STREAMS       =======================
20
+
21
+    std::ostream &operator<<(std::ostream &stream,
22
+            const QuasiNewtonBFGS &ob) {
23
+        stream << *(InverseSolver*)(&ob);
24
+        return stream;
25
+    }
26
+
27
+
28
+    // ====================  LIFECYCLE     =======================
29
+
30
+    QuasiNewtonBFGS* QuasiNewtonBFGS::New() {
31
+        QuasiNewtonBFGS* Object = new QuasiNewtonBFGS("QuasiNewtonBFGS");
32
+        Object->AttachTo(Object);
33
+        return Object;
34
+    }
35
+
36
+    QuasiNewtonBFGS::QuasiNewtonBFGS(const std::string &name) :
37
+        InverseSolver(name) {
38
+    }
39
+
40
+    void QuasiNewtonBFGS::Delete() {
41
+        this->DetachFrom(this);
42
+    }
43
+
44
+    void QuasiNewtonBFGS::Release() {
45
+        delete this;
46
+    }
47
+
48
+    QuasiNewtonBFGS::~QuasiNewtonBFGS() {
49
+        if (this->NumberOfReferences != 0)
50
+            throw DeleteObjectWithReferences( this );
51
+    }
52
+
53
+    // ====================  INQUIRY       =======================
54
+
55
+    int QuasiNewtonBFGS::NumberOfIterations() {
56
+        return 0;
57
+    }
58
+
59
+    bool QuasiNewtonBFGS::Success () {
60
+        return false;
61
+    }
62
+
63
+    void QuasiNewtonBFGS::PrintNorm() {
64
+        std::cout << "Norm " << std::endl;
65
+        PredictedData->Zero();
66
+        std::cout << ObservedData->Norm(PredictedData) << std::endl;
67
+    }
68
+
69
+    VectorXr QuasiNewtonBFGS::GetPhiMVector() {
70
+        VectorXr NewVec(2);
71
+        return NewVec;
72
+    }
73
+
74
+    VectorXr QuasiNewtonBFGS::GetPhiDVector() {
75
+        VectorXr NewVec(2);
76
+        return NewVec;
77
+    }
78
+
79
+    void QuasiNewtonBFGS::FillInG(const Vector3r& pos, const Vector3r& step) {
80
+
81
+    }
82
+
83
+    // ====================  ACCESS        =======================
84
+
85
+}		// -----  end of Lemma  name  -----

+ 0
- 0
Modules/TEM1D/CMakeLists.txt View File


+ 44
- 0
Modules/TEM1D/examples/datatem.cpp View File

@@ -0,0 +1,44 @@
1
+// ===========================================================================
2
+//
3
+//       Filename:
4
+//
5
+//    Description:
6
+//
7
+//        Version:  0.0
8
+//        Created:  03/02/2010 02:10:53 PM
9
+//       Revision:  none
10
+//       Compiler:  Tested with g++, icpc, and MSVC 2000
11
+//
12
+//         Author:  Trevor Irons (ti)
13
+//
14
+//   Organisation:  Colorado School of Mines (CSM)
15
+//                  United States Geological Survey (USGS)
16
+//
17
+//          Email:  tirons@mines.edu, tirons@usgs.gov
18
+//
19
+//  This program is free software: you can redistribute it and/or modify
20
+//  it under the terms of the GNU General Public License as published by
21
+//  the Free Software Foundation, either version 3 of the License, or
22
+//  (at your option) any later version.
23
+//
24
+//  This program is distributed in the hope that it will be useful,
25
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
26
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27
+//  GNU General Public License for more details.
28
+//
29
+//  You should have received a copy of the GNU General Public License
30
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
31
+//
32
+// ===========================================================================
33
+
34
+#include "Lemma"
35
+using namespace Lemma;
36
+
37
+int main() {
38
+
39
+	DataTEM * tdata = DataTEM::New();
40
+	std::cout << *tdata << std::endl;
41
+	tdata->Zero();
42
+	tdata->Delete();
43
+
44
+}

+ 106
- 0
Modules/TEM1D/include/TEMInductiveReceiver.h View File

@@ -0,0 +1,106 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      10/08/2014 03:17:52 PM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+
21
+#ifndef  TEMINDUCTIVERECEIVER_INC
22
+#define  TEMINDUCTIVERECEIVER_INC
23
+
24
+#include "TEMReceiver.h"
25
+
26
+namespace Lemma {
27
+
28
+    /**
29
+      \brief   Derived class of TEMReceiver.
30
+      \details An inductive receiver, measures dB/dt
31
+     */
32
+    class TEMInductiveReceiver : public TEMReceiver {
33
+
34
+        friend std::ostream &operator<<(std::ostream &stream,
35
+                const TEMInductiveReceiver &ob);
36
+
37
+        public:
38
+
39
+        // ====================  LIFECYCLE     =======================
40
+
41
+        /**
42
+         * @copybrief LemmaObject::New()
43
+         * @copydetails LemmaObject::New()
44
+         */
45
+        static TEMInductiveReceiver* New();
46
+
47
+        /**
48
+         *  @copybrief   LemmaObject::Delete()
49
+         *  @copydetails LemmaObject::Delete()
50
+         */
51
+        void Delete();
52
+
53
+        // ====================  OPERATORS     =======================
54
+
55
+        // ====================  OPERATIONS    =======================
56
+
57
+        // ====================  ACCESS        =======================
58
+
59
+        // ====================  INQUIRY       =======================
60
+
61
+#ifdef HAVE_YAMLCPP
62
+        /**
63
+         *  Uses YAML to serialize this object.
64
+         *  @return a YAML::Node
65
+         */
66
+        YAML::Node Serialize() const;
67
+
68
+        /**
69
+         *   Constructs an object from a YAML::Node.
70
+         */
71
+        static TEMInductiveReceiver* DeSerialize(const YAML::Node& node);
72
+#endif
73
+
74
+        protected:
75
+
76
+        // ====================  LIFECYCLE     =======================
77
+
78
+        /** Default protected constructor, use New */
79
+        TEMInductiveReceiver (const std::string& name);
80
+
81
+#ifdef HAVE_YAMLCPP
82
+        /** Default protected constructor, use New */
83
+        TEMInductiveReceiver (const YAML::Node& node);
84
+#endif
85
+
86
+        /** Default protected destructor, use Delete */
87
+        ~TEMInductiveReceiver ();
88
+
89
+        /**
90
+         *  @copybrief   LemmaObject::Release()
91
+         *  @copydetails LemmaObject::Release()
92
+         */
93
+        void Release();
94
+
95
+        private:
96
+
97
+        // ====================  DATA MEMBERS  =========================
98
+
99
+    }; // -----  end of class  TEMInductiveReceiver  -----
100
+
101
+
102
+}		// -----  end of Lemma  name  -----
103
+
104
+#endif   // ----- #ifndef TEMINDUCTIVERECEIVER_INC  -----
105
+
106
+

+ 184
- 0
Modules/TEM1D/include/TEMReceiver.h View File

@@ -0,0 +1,184 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      10/08/2014 02:36:47 PM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#ifndef  TEMRECEIVER_INC
21
+#define  TEMRECEIVER_INC
22
+
23
+#include "receiverpoints.h"
24
+
25
+//#include <boost/random.hpp>
26
+//#include <boost/random/normal_distribution.hpp>
27
+#include <random>
28
+
29
+namespace Lemma {
30
+
31
+#ifdef HAVE_YAMLCPP
32
+#include "yaml-cpp/yaml.h"
33
+#endif
34
+
35
+
36
+/**
37
+  \brief
38
+  \details
39
+ */
40
+class TEMReceiver : public ReceiverPoints {
41
+
42
+    friend std::ostream &operator<<(std::ostream &stream,
43
+            const TEMReceiver &ob);
44
+
45
+    public:
46
+
47
+    // ====================  LIFECYCLE     =======================
48
+
49
+    /**
50
+     * @copybrief LemmaObject::New()
51
+     * @copydetails LemmaObject::New()
52
+     */
53
+    static TEMReceiver* New();
54
+
55
+    /**
56
+     *   @return a deep copy of this
57
+     */
58
+    TEMReceiver* Clone();
59
+
60
+    /**
61
+     *  @copybrief   LemmaObject::Delete()
62
+     *  @copydetails LemmaObject::Delete()
63
+     */
64
+    void Delete();
65
+
66
+    // ====================  OPERATORS     =======================
67
+
68
+    // ====================  OPERATIONS    =======================
69
+
70
+    /**
71
+     * Uses the standard deviations provided to provide an instance
72
+     * of the expected noise. A realisation of the noise.
73
+     */
74
+    VectorXr SampleNoise();
75
+
76
+    // ====================  ACCESS        =======================
77
+
78
+    /**
79
+     *    Sets the gate integration windows
80
+     */
81
+    void SetWindows(const VectorXr& centres, const VectorXr& widths, const TIMEUNITS& Units);
82
+
83
+    /**
84
+     *   Sets the moment of the receiver. Defaults to 1 for normalized response.
85
+     */
86
+    void SetMoment( const Real&  moment);
87
+
88
+    /**
89
+     *  Sets std deviation values for noise channels.
90
+     *  @param[in] noise must be of the same length as the number of windows.
91
+     */
92
+    void SetNoiseSTD( const VectorXr& noise );
93
+
94
+    /**
95
+     *  Gets std deviation values for noise channels.
96
+     *  @return noise std dev.
97
+     */
98
+    VectorXr GetNoiseSTD(  );
99
+
100
+    /**
101
+     *  @param[in] refTime sets the reference time, defaults to 0
102
+     */
103
+    void SetReferenceTime( const Real& refTime, const TIMEUNITS& units );
104
+
105
+    /**
106
+     *  What field component to return
107
+     */
108
+    void SetComponent ( const FIELDCOMPONENT& COMP );
109
+
110
+    /**
111
+     *   @param[in] loc is the location of the dipole receiver
112
+     */
113
+    void SetRxLocation ( const Vector3r& loc );
114
+
115
+    // ====================  INQUIRY       =======================
116
+
117
+     #ifdef HAVE_YAMLCPP
118
+	/**
119
+     *  Uses YAML to serialize this object.
120
+     *  @return a YAML::Node
121
+     */
122
+    YAML::Node Serialize() const;
123
+
124
+    /**
125
+     *   Constructs an object from a YAML::Node.
126
+     */
127
+    static TEMReceiver* DeSerialize(const YAML::Node& node);
128
+     #endif
129
+
130
+    /**
131
+     * @return centre point of gates in sec
132
+     */
133
+    VectorXr GetWindowCentres();
134
+
135
+    /**
136
+     * @return width of gates in sec
137
+     */
138
+    VectorXr GetWindowWidths();
139
+
140
+    /**
141
+     *  @return the reference time
142
+     */
143
+    Real    GetReferenceTime();
144
+    protected:
145
+
146
+    // ====================  LIFECYCLE     =======================
147
+
148
+    /** Default protected constructor, use New */
149
+    TEMReceiver (const std::string& name);
150
+
151
+     #ifdef HAVE_YAMLCPP
152
+    /** Default protected de-serializing constructor, use factory DeSerialize */
153
+    TEMReceiver (const YAML::Node& node);
154
+    #endif
155
+
156
+    /** Default protected destructor, use Delete */
157
+    ~TEMReceiver ();
158
+
159
+    /**
160
+     *  @copybrief   LemmaObject::Release()
161
+     *  @copydetails LemmaObject::Release()
162
+     */
163
+    void Release();
164
+
165
+    private:
166
+
167
+    // ====================  DATA MEMBERS  =========================
168
+
169
+    Real            moment;
170
+    Real            referenceTime;
171
+    Vector3r        nHat;
172
+    FIELDCOMPONENT  component;
173
+
174
+    VectorXr        windowCentres;
175
+    VectorXr        windowWidths;
176
+    VectorXr        noiseSTD;
177
+    //Vector3r        location;
178
+
179
+}; // -----  end of class  TEMReceiver  -----
180
+
181
+}		// -----  end of Lemma  name  -----
182
+
183
+#endif   // ----- #ifndef TEMRECEIVER_INC  -----
184
+

+ 137
- 0
Modules/TEM1D/include/TEMSurvey.h View File

@@ -0,0 +1,137 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      10/08/2014 01:51:50 PM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#ifndef  TEMSURVEY_INC
21
+#define  TEMSURVEY_INC
22
+
23
+#include "LemmaObject.h"
24
+#include "TEMSurveyLine.h"
25
+#include "TEMSurveyData.h"
26
+
27
+#include "layeredearthem.h"
28
+
29
+#ifdef HAVE_YAMLCPP
30
+#include "yaml-cpp/yaml.h"
31
+#endif
32
+
33
+namespace Lemma {
34
+
35
+
36
+    /**
37
+      \brief   Describes a TEM survey.
38
+      \details This class aims to encapulate any type of TEM survey.
39
+     */
40
+    class TEMSurvey : public LemmaObject {
41
+
42
+        friend std::ostream &operator<<(std::ostream &stream,
43
+                const TEMSurvey &ob);
44
+
45
+        public:
46
+
47
+        // ====================  LIFECYCLE     =======================
48
+
49
+        /**
50
+         * @copybrief LemmaObject::New()
51
+         * @copydetails LemmaObject::New()
52
+         */
53
+        static TEMSurvey* New();
54
+
55
+        /**
56
+         *  @copybrief   LemmaObject::Delete()
57
+         *  @copydetails LemmaObject::Delete()
58
+         */
59
+        void Delete();
60
+
61
+        // ====================  OPERATORS     =======================
62
+
63
+        /**  @param[in] idx the index to return
64
+         *   @return the SurveyLine with index idx
65
+         */
66
+        TEMSurveyLine* operator( ) ( const int& idx ) const ;
67
+
68
+        /**  @param[in] iline the line index to return
69
+         *   @param[in] irec the line index to return
70
+         *   @return the SurveyLine with index iline, irec
71
+         */
72
+        TEMSurveyLineRecord* operator( ) ( const int& iline, const int& irec ) const;
73
+
74
+        // ====================  OPERATIONS    =======================
75
+
76
+        /**
77
+         *  @param[in] nlines sets the number of lines (TEMSurveyLine) in the survey. A line is any kind of
78
+         *             related set of measurements. In Airborne EM, this is a flight line, but
79
+         *             the idea extends to ground based profile lines.
80
+         */
81
+        void SetNumberOfLines( const int& nlines );
82
+
83
+        /**
84
+         *  Most basic form of forward modelling. Uses input model for ALL TEMSurveyLines and
85
+         *  TEMSurveyLineRecords (atomic). Most useful in the
86
+         *  case that there is only 1 line and 1 record. But even in that case it can be called directly from
87
+         *  the record. This method will likely be replaced  soon.
88
+         */
89
+        TEMSurveyData* ForwardModel(LayeredEarthEM* model, bool additiveNoise=false);
90
+
91
+        // ====================  ACCESS        =======================
92
+
93
+        /**
94
+         *   @return pointer to requested TEMSurveyLine
95
+         */
96
+        TEMSurveyLine*  GetLine(const unsigned int& iline);
97
+
98
+        // ====================  INQUIRY       =======================
99
+
100
+        #ifdef HAVE_YAMLCPP
101
+        YAML::Node Serialize() const;
102
+        static TEMSurvey* DeSerialize(const YAML::Node& node);
103
+        #endif
104
+
105
+        protected:
106
+
107
+        // ====================  LIFECYCLE     =======================
108
+
109
+        /** Default protected constructor, use New */
110
+        TEMSurvey (const std::string& name);
111
+
112
+        #ifdef HAVE_YAMLCPP
113
+        /** Default protected constructor, use New */
114
+        TEMSurvey (const YAML::Node& node);
115
+        #endif
116
+
117
+        /** Default protected destructor, use Delete */
118
+        ~TEMSurvey ();
119
+
120
+        /**
121
+         *  @copybrief   LemmaObject::Release()
122
+         *  @copydetails LemmaObject::Release()
123
+         */
124
+        void Release();
125
+
126
+        private:
127
+
128
+        // ====================  DATA MEMBERS  =========================
129
+
130
+        std::vector<TEMSurveyLine*>     Lines;
131
+
132
+    }; // -----  end of class  TEMSurvey  -----
133
+
134
+
135
+}		// -----  end of Lemma  name  -----
136
+
137
+#endif   // ----- #ifndef TEMSURVEY_INC  -----

+ 161
- 0
Modules/TEM1D/include/TEMSurveyData.h View File

@@ -0,0 +1,161 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      03/03/2015 09:54:25
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2015, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2015, Trevor Irons
18
+ */
19
+
20
+#ifndef  TEMSURVEYDATA_INC
21
+#define  TEMSURVEYDATA_INC
22
+
23
+#include "LemmaObject.h"
24
+#include "TEMSurveyLineData.h"
25
+
26
+namespace Lemma {
27
+
28
+    /**
29
+      \brief    Holds data from a TEMSurvey.
30
+      \details  Any form of TEMSurvey may be represented here. The
31
+                majority of the specification can be found in the associated
32
+                TEMSurvey. The TEMSurveyData object is intended to be lightweight.
33
+     */
34
+    class TEMSurveyData : public LemmaObject {
35
+
36
+        friend std::ostream &operator<<(std::ostream &stream,
37
+                const TEMSurveyData &ob);
38
+
39
+        friend class TEMSurvey;
40
+
41
+        public:
42
+
43
+        // ====================  LIFECYCLE     =======================
44
+
45
+        /**
46
+         * @copybrief LemmaObject::New()
47
+         * @copydetails LemmaObject::New()
48
+         */
49
+        static TEMSurveyData* New();
50
+
51
+        /**
52
+         *  @return a deep copy of this, this is acomplished through Serialize
53
+         *          and DeSerialize methods.
54
+         */
55
+        TEMSurveyData* Clone();
56
+
57
+        /**
58
+         *  @copybrief   LemmaObject::Delete()
59
+         *  @copydetails LemmaObject::Delete()
60
+         */
61
+        void Delete();
62
+
63
+        // ====================  OPERATORS     =======================
64
+
65
+        /** Surveys can be added or subtracted from each other, throws a
66
+         *  pointer that will need to be managed (Deleted)
67
+         */
68
+        TEMSurveyData* operator+(const TEMSurveyData& Survey);
69
+
70
+        /** Surveys can be added or subtracted from each other, throws a
71
+         *  pointer that will need to be managed (Deleted).
72
+         */
73
+        TEMSurveyData* operator-(const TEMSurveyData& Survey);
74
+
75
+        /** Surveys can be added or subtracted from each other
76
+         */
77
+        void operator+=(const TEMSurveyData& Survey);
78
+
79
+        /** Surveys can be added or subtracted from each other
80
+         */
81
+        void operator-=(const TEMSurveyData& Survey);
82
+
83
+
84
+        /**  @param[in] idx the index to return
85
+         *   @return the SurveyLine with index idx
86
+         */
87
+        TEMSurveyLineData* operator( ) ( const int& idx ) const;
88
+
89
+        /**  @param[in] iline the line index to return
90
+         *   @param[in] irec the line index to return
91
+         *   @return the SurveyLine with index iline, irec
92
+         */
93
+        TEMSurveyLineRecordData* operator( ) ( const int& iline, const int& irec ) const;
94
+
95
+
96
+        // ====================  OPERATIONS    =======================
97
+
98
+        /** Sets the number of lines
99
+         */
100
+        void SetNumberOfLines( const int& nlines );
101
+
102
+        // ====================  ACCESS        =======================
103
+
104
+        /** @return the number of lines in the data
105
+         */
106
+        int GetNumberOfLines() const;
107
+
108
+        /**
109
+         *   @return pointer to line
110
+         */
111
+        TEMSurveyLineData* GetLine(const int& iline) const;
112
+
113
+        // ====================  INQUIRY       =======================
114
+
115
+#ifdef HAVE_YAMLCPP
116
+        /**
117
+         *  Uses YAML to serialize this object.
118
+         *  @return a YAML::Node
119
+         */
120
+        YAML::Node Serialize() const;
121
+
122
+        /**
123
+         *   Constructs an object from a YAML::Node.
124
+         */
125
+        static TEMSurveyData* DeSerialize(const YAML::Node& node);
126
+#endif
127
+
128
+        protected:
129
+
130
+        // ====================  LIFECYCLE     =======================
131
+
132
+        /** Default protected constructor, use New */
133
+        TEMSurveyData (const std::string& name);
134
+
135
+#ifdef HAVE_YAMLCPP
136
+        /** Protected DeDerializing constructor, use factory DeSerialize  method*/
137
+        TEMSurveyData (const YAML::Node& node);
138
+#endif
139
+
140
+        /** Default protected destructor, use Delete */
141
+        ~TEMSurveyData ();
142
+
143
+        /**
144
+         *  @copybrief   LemmaObject::Release()
145
+         *  @copydetails LemmaObject::Release()
146
+         */
147
+        void Release();
148
+
149
+        private:
150
+
151
+        // ====================  DATA MEMBERS  =========================
152
+
153
+        std::vector<TEMSurveyLineData*>  LineData;
154
+
155
+    }; // -----  end of class  TEMSurveyData  -----
156
+
157
+
158
+
159
+}		// -----  end of Lemma  name  -----
160
+
161
+#endif   // ----- #ifndef TEMSURVEYDATA_INC  -----

+ 117
- 0
Modules/TEM1D/include/TEMSurveyLine.h View File

@@ -0,0 +1,117 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      10/10/2014 11:14:39 AM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#ifndef  TEMSURVEYLINE_INC
21
+#define  TEMSURVEYLINE_INC
22
+
23
+#include "LemmaObject.h"
24
+#include "TEMSurveyLineRecord.h"
25
+#include "TEMSurveyLineData.h"
26
+
27
+namespace Lemma {
28
+
29
+    /**
30
+      \brief    Represents a TEM survey line.
31
+      \details  This class is managed by TEMSurvey. You cannot create a TEMSurvey line directly
32
+                this should be done through a TEMSurvey.
33
+                @todo neeed to impliment a BaseClass besides LemmaObject without pure virtual Delete.
34
+     */
35
+    class TEMSurveyLine : public LemmaObject {
36
+
37
+        friend std::ostream &operator<<(std::ostream &stream,
38
+                const TEMSurveyLine &ob);
39
+
40
+        friend class TEMSurvey;
41
+
42
+        public:
43
+
44
+        // ====================  LIFECYCLE     =======================
45
+
46
+
47
+
48
+        // ====================  OPERATORS     =======================
49
+
50
+        // ====================  OPERATIONS    =======================
51
+
52
+        // ====================  ACCESS        =======================
53
+
54
+        /**
55
+            @return returns pointer to a specific record along the line
56
+         */
57
+        TEMSurveyLineRecord*  GetRecord(const unsigned int& irec);
58
+
59
+        /**
60
+            @param[in] nrec is the number of records along the line
61
+         */
62
+        void SetNumberOfRecords( const int& nrec );
63
+
64
+        // ====================  INQUIRY       =======================
65
+
66
+#ifdef HAVE_YAMLCPP
67
+        /**
68
+         *  Uses YAML to serialize this object.
69
+         *  @return a YAML::Node
70
+         */
71
+        YAML::Node Serialize() const;
72
+
73
+        /**
74
+         *   Constructs an object from a YAML::Node.
75
+         */
76
+        static TEMSurveyLine* DeSerialize(const YAML::Node& node);
77
+#endif
78
+
79
+        protected:
80
+
81
+        TEMSurveyLineData* ForwardModel(LayeredEarthEM* model, bool additiveNoise = false);
82
+
83
+        // ====================  LIFECYCLE     =======================
84
+
85
+        /** Default protected constructor, use New */
86
+        TEMSurveyLine (const std::string& name);
87
+
88
+#ifdef HAVE_YAMLCPP
89
+        /** Protected DeDerializing constructor, use factory DeSerialize  method*/
90
+        TEMSurveyLine (const YAML::Node& node);
91
+#endif
92
+
93
+        /** Default protected destructor, use Delete */
94
+        ~TEMSurveyLine ();
95
+
96
+        /**
97
+         *  @copybrief   LemmaObject::Release()
98
+         *  @copydetails LemmaObject::Release()
99
+         */
100
+        void Release();
101
+
102
+        private:
103
+
104
+        /**
105
+         *   Delete should not be called...
106
+         */
107
+        void Delete();
108
+
109
+        // ====================  DATA MEMBERS  =========================
110
+
111
+        std::vector<TEMSurveyLineRecord*>     Records;
112
+
113
+    }; // -----  end of class  TEMSurveyLine  -----
114
+
115
+}		// -----  end of Lemma  name  -----
116
+
117
+#endif   // ----- #ifndef TEMSURVEYLINE_INC  -----

+ 146
- 0
Modules/TEM1D/include/TEMSurveyLineData.h View File

@@ -0,0 +1,146 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      03/03/2015 10:16:47
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2015, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2015, Trevor Irons
18
+ */
19
+
20
+#ifndef  TEMSURVEYLINEDATA_INC
21
+#define  TEMSURVEYLINEDATA_INC
22
+
23
+#include "LemmaObject.h"
24
+#include "TEMSurveyLineRecordData.h"
25
+
26
+namespace Lemma {
27
+
28
+/**
29
+  \brief   Holds Data for a TEM survey line
30
+  \details An entire flight line worth of data is stored here.
31
+ */
32
+class TEMSurveyLineData : public LemmaObject {
33
+
34
+    friend std::ostream &operator<<(std::ostream &stream,
35
+            const TEMSurveyLineData &ob);
36
+
37
+    //friend class TEMSurveyData;
38
+    friend class TEMSurveyLine;
39
+
40
+    public:
41
+
42
+    // ====================  LIFECYCLE     =======================
43
+
44
+    /**
45
+     * @copybrief LemmaObject::New()
46
+     * @copydetails LemmaObject::New()
47
+     */
48
+    static TEMSurveyLineData* New();
49
+
50
+    /**
51
+     *  @return a deep copy of this, this is acomplished through Serialize
52
+     *          and DeSerialize methods.
53
+     */
54
+    TEMSurveyLineData* Clone();
55
+
56
+    /**
57
+     *  @copybrief   LemmaObject::Delete()
58
+     *  @copydetails LemmaObject::Delete()
59
+     */
60
+    void Delete();
61
+
62
+    // ====================  OPERATORS     =======================
63
+
64
+    /** Survey lines can be added or subtracted from each other
65
+     */
66
+    TEMSurveyLineData* operator+(const TEMSurveyLineData& Survey);
67
+
68
+    /** Survey lines can be added or subtracted from each other
69
+     */
70
+    TEMSurveyLineData* operator-(const TEMSurveyLineData& Survey);
71
+
72
+    /** Survey lines can be added or subtracted from each other
73
+     */
74
+    void operator+=(const TEMSurveyLineData& Survey);
75
+
76
+    /** Survey lines can be added or subtracted from each other
77
+     */
78
+    void operator-=(const TEMSurveyLineData& Survey);
79
+
80
+    /**  @param[in] ir the index to return
81
+     *   @return the SurveyLineRecord with index ir
82
+     */
83
+    TEMSurveyLineRecordData* operator( ) ( const int& ir ) const ;
84
+
85
+    // ====================  OPERATIONS    =======================
86
+
87
+    // ====================  ACCESS        =======================
88
+
89
+    /**
90
+     *    @return pointer to specified record
91
+     */
92
+    TEMSurveyLineRecordData*  GetRecord(const int& ir) const ;
93
+
94
+    /**
95
+     * @return the number of records
96
+     */
97
+    int GetNumberOfRecords() const;
98
+
99
+    // ====================  INQUIRY       =======================
100
+
101
+#ifdef HAVE_YAMLCPP
102
+    /**
103
+     *  Uses YAML to serialize this object.
104
+     *  @return a YAML::Node
105
+     */
106
+    YAML::Node Serialize() const;
107
+
108
+    /**
109
+     *   Constructs an object from a YAML::Node.
110
+     */
111
+    static TEMSurveyLineData* DeSerialize(const YAML::Node& node);
112
+#endif
113
+
114
+    protected:
115
+
116
+    // ====================  LIFECYCLE     =======================
117
+
118
+    /** Default protected constructor, use New */
119
+    TEMSurveyLineData (const std::string& name);
120
+
121
+#ifdef HAVE_YAMLCPP
122
+    /** Protected DeDerializing constructor, use factory DeSerialize  method*/
123
+    TEMSurveyLineData (const YAML::Node& node);
124
+#endif
125
+
126
+    /** Default protected destructor, use Delete */
127
+    ~TEMSurveyLineData ();
128
+
129
+    /**
130
+     *  @copybrief   LemmaObject::Release()
131
+     *  @copydetails LemmaObject::Release()
132
+     */
133
+    void Release();
134
+
135
+    private:
136
+
137
+    // ====================  DATA MEMBERS  =========================
138
+
139
+    std::vector<TEMSurveyLineRecordData*>   RecordData;
140
+
141
+}; // -----  end of class  TEMSurveyLineData  -----
142
+
143
+}		// -----  end of Lemma  name  -----
144
+
145
+#endif   // ----- #ifndef TEMSURVEYLINEDATA_INC  -----
146
+

+ 140
- 0
Modules/TEM1D/include/TEMSurveyLineRecord.h View File

@@ -0,0 +1,140 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      10/10/2014 12:15:03 PM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#ifndef  TEMSURVEYLINERECORD_INC
21
+#define  TEMSURVEYLINERECORD_INC
22
+
23
+#include "LemmaObject.h"
24
+#include "TEMReceiver.h"
25
+#include "TEMTransmitter.h"
26
+#include "TEMSurveyLineRecordData.h"
27
+#include "instrumenttem.h"
28
+
29
+namespace Lemma {
30
+
31
+    /**
32
+      \brief    Class holding everything necessary to create a TEM record.
33
+      \details  A TEM record represents the nexus of a transmitter with
34
+                receiver(s) and pulse moment(s). Therefore a record can contain
35
+                multiple sounding curves.
36
+     */
37
+    class TEMSurveyLineRecord : public LemmaObject {
38
+
39
+        friend std::ostream &operator<<(std::ostream &stream,
40
+                const TEMSurveyLineRecord &ob);
41
+
42
+        friend class TEMSurveyLine;
43
+
44
+        public:
45
+
46
+        // ====================  LIFECYCLE     =======================
47
+
48
+        // ====================  OPERATORS     =======================
49
+
50
+        // ====================  OPERATIONS    =======================
51
+
52
+        /**
53
+         *  Perfoms forward modelling given model.
54
+         *  @param[in] model is the earth model responsible for the response
55
+         *  @param[in] additiveNoise is whether or not to add noise to the response, defaults to false
56
+         *  @return the modelled data.
57
+         */
58
+        TEMSurveyLineRecordData* ForwardModel(LayeredEarthEM* model, bool additiveNoise=false);
59
+
60
+        /**
61
+         *  @param[in] nseq is the number of pulse sequences
62
+         */
63
+        void SetNumberOfPulseSequences( const int& nseq );
64
+
65
+        /**
66
+         *  @return the number of pulse sequences
67
+         */
68
+        int GetNumberOfPulseSequences();
69
+
70
+        /**
71
+         *  Sets the PulseSequence and Receiver pair used to model a *SINGLE* response curve.
72
+         *  @param[in] Seq is the Pulse Sequence
73
+         *  @param[in] Rx is the receiver for that pulse sequence
74
+         */
75
+        void SetTransmitterReceiverPair( const int& ii, TEMTransmitter* Seq, TEMReceiver* Rx );
76
+
77
+        // ====================  ACCESS        =======================
78
+
79
+        /**
80
+         *  @return a pointer to the specified receiver
81
+         */
82
+        TEMReceiver*   GetReceiver(const int& irec);
83
+
84
+        // ====================  INQUIRY       =======================
85
+
86
+#ifdef HAVE_YAMLCPP
87
+        /**
88
+         *  Uses YAML to serialize this object.
89
+         *  @return a YAML::Node
90
+         */
91
+        YAML::Node Serialize() const;
92
+
93
+        /**
94
+         *   Constructs an object from a YAML::Node.
95
+         */
96
+        static TEMSurveyLineRecord* DeSerialize(const YAML::Node& node);
97
+#endif
98
+
99
+        protected:
100
+
101
+
102
+
103
+        // ====================  LIFECYCLE     =======================
104
+
105
+        /** Default protected constructor, use New */
106
+        TEMSurveyLineRecord (const std::string& name);
107
+
108
+#ifdef HAVE_YAMLCPP
109
+        /** Protected DeDerializing constructor, use factory DeSerialize  method*/
110
+        TEMSurveyLineRecord (const YAML::Node& node);
111
+#endif
112
+
113
+        /** Default protected destructor, use Delete */
114
+        ~TEMSurveyLineRecord ();
115
+
116
+        /**
117
+         *  @copybrief   LemmaObject::Release()
118
+         *  @copydetails LemmaObject::Release()
119
+         */
120
+        void Release();
121
+
122
+        private:
123
+
124
+        /**
125
+         *   Delete is private, this class is managed through TEMSurvey
126
+         */
127
+        void Delete();
128
+
129
+        // ====================  DATA MEMBERS  =========================
130
+
131
+        int     numberOfPulseSequences;
132
+
133
+        std::vector<TEMTransmitter*>    Transmitters;
134
+        std::vector<TEMReceiver*>       Receivers;
135
+
136
+    }; // -----  end of class  TEMSurveyLineRecord  -----
137
+
138
+}		// -----  end of Lemma  name  -----
139
+
140
+#endif   // ----- #ifndef TEMSURVEYLINERECORD_INC  -----

+ 141
- 0
Modules/TEM1D/include/TEMSurveyLineRecordData.h View File

@@ -0,0 +1,141 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      03/03/2015 10:29:01
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2015, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2015, Trevor Irons
18
+ */
19
+#ifndef  TEMSURVEYLINERECORDDATA_INC
20
+#define  TEMSURVEYLINERECORDDATA_INC
21
+
22
+#include "LemmaObject.h"
23
+
24
+namespace Lemma {
25
+
26
+    /**
27
+      \brief
28
+      \details
29
+     */
30
+    class TEMSurveyLineRecordData : public LemmaObject {
31
+
32
+        friend std::ostream &operator<<(std::ostream &stream,
33
+                const TEMSurveyLineRecordData &ob);
34
+
35
+        friend class TEMSurveyLineRecord;
36
+
37
+        public:
38
+
39
+        // ====================  LIFECYCLE     =======================
40
+
41
+        /**
42
+         * @copybrief LemmaObject::New()
43
+         * @copydetails LemmaObject::New()
44
+         */
45
+        static TEMSurveyLineRecordData* New();
46
+
47
+
48
+        /** Provides deep copy
49
+         */
50
+        TEMSurveyLineRecordData* Clone();
51
+
52
+        /**
53
+         *  @copybrief   LemmaObject::Delete()
54
+         *  @copydetails LemmaObject::Delete()
55
+         */
56
+        void Delete();
57
+
58
+        // ====================  OPERATORS     =======================
59
+
60
+        /**
61
+         * Records can be added
62
+         */
63
+        TEMSurveyLineRecordData* operator + (const TEMSurveyLineRecordData&);
64
+
65
+        /**
66
+         * Records can be subtracted
67
+         */
68
+        TEMSurveyLineRecordData* operator - (const TEMSurveyLineRecordData&);
69
+
70
+        /**
71
+         * Records can be added in place
72
+         */
73
+        void operator += (const TEMSurveyLineRecordData&);
74
+
75
+        /**
76
+         * Records can be subtracted in place
77
+         */
78
+        void operator -= (const TEMSurveyLineRecordData&);
79
+
80
+        // ====================  OPERATIONS    =======================
81
+
82
+        // ====================  ACCESS        =======================
83
+
84
+        /** @return a VectorXr of the merged data (all moments)
85
+         * @todo TODO this is actually a copy? is this intended?
86
+         */
87
+        VectorXr GetCombinedData();
88
+
89
+        /** @return a VectorXr of the combined gate centres alligned with
90
+         *          GetCombinedData();
91
+         */
92
+        VectorXr GetCombinedGateCentres();
93
+        // ====================  INQUIRY       =======================
94
+
95
+#ifdef HAVE_YAMLCPP
96
+        /**
97
+         *  Uses YAML to serialize this object.
98
+         *  @return a YAML::Node
99
+         */
100
+        YAML::Node Serialize() const;
101
+
102
+        /**
103
+         *   Constructs an object from a YAML::Node.
104
+         */
105
+        static TEMSurveyLineRecordData* DeSerialize(const YAML::Node& node);
106
+#endif
107
+
108
+        protected:
109
+
110
+        // ====================  LIFECYCLE     =======================
111
+
112
+        /** Default protected constructor, use New */
113
+        TEMSurveyLineRecordData (const std::string& name);
114
+
115
+#ifdef HAVE_YAMLCPP
116
+        /** Protected DeDerializing constructor, use factory DeSerialize  method*/
117
+        TEMSurveyLineRecordData (const YAML::Node& node);
118
+#endif
119
+
120
+        /** Default protected destructor, use Delete */
121
+        ~TEMSurveyLineRecordData ();
122
+
123
+        /**
124
+         *  @copybrief   LemmaObject::Release()
125
+         *  @copydetails LemmaObject::Release()
126
+         */
127
+        void Release();
128
+
129
+        private:
130
+
131
+        // ====================  DATA MEMBERS  =========================
132
+
133
+        std::vector<VectorXr>           DataSeries;
134
+
135
+        std::vector<VectorXr>           GateCentres;
136
+
137
+    }; // -----  end of class  TEMSurveyLineRecordData  -----
138
+
139
+}		// -----  end of Lemma  name  -----
140
+
141
+#endif   // ----- #ifndef TEMSURVEYLINERECORDDATA_INC  -----

+ 125
- 0
Modules/TEM1D/include/TEMTransmitter.h View File

@@ -0,0 +1,125 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      09/29/2014 11:43:17 AM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#ifndef  TEMTRANSMITTER_INC
21
+#define  TEMTRANSMITTER_INC
22
+
23
+#include "PolygonalWireAntenna.h"
24
+
25
+#ifdef HAVE_YAMLCPP
26
+#include "yaml-cpp/yaml.h"
27
+#endif
28
+
29
+namespace Lemma {
30
+
31
+/**
32
+  \brief   Describes a TEM pulse sequence
33
+  \details Flexible class desribing a pulse sequence used by
34
+           a TEM instruement. Can be used by Airborne or Ground
35
+           instruments.
36
+ */
37
+class TEMTransmitter : public PolygonalWireAntenna {
38
+
39
+    friend std::ostream &operator<<(std::ostream &stream, const TEMTransmitter &ob);
40
+
41
+    public:
42
+
43
+    // ====================  LIFECYCLE     =======================
44
+
45
+    /**
46
+     * @copybrief LemmaObject::New()
47
+     * @copydetails LemmaObject::New()
48
+     */
49
+    static TEMTransmitter* New();
50
+
51
+    /**
52
+     *  Performs a deep copy of this and returns pointer
53
+     */
54
+    TEMTransmitter* Clone();
55
+
56
+    /**
57
+     *  @copybrief   LemmaObject::Delete()
58
+     *  @copydetails LemmaObject::Delete()
59
+     */
60
+    void Delete();
61
+
62
+    // ====================  OPERATORS     =======================
63
+
64
+    // ====================  OPERATIONS    =======================
65
+
66
+    // ====================  ACCESS        =======================
67
+
68
+    /** Sets the repetition frequency
69
+     */
70
+    void SetRepFrequency(const Real& fr, const FREQUENCYUNITS& units);
71
+
72
+    void SetWaveform( const VectorXr& times, const VectorXr& amps, const TIMEUNITS& units );
73
+
74
+    /**
75
+     *  @return the waveform times in seconds
76
+     */
77
+    VectorXr GetWfmTimes();
78
+
79
+    /** @return the waveform current in amps
80
+     */
81
+    VectorXr GetWfmAmps();
82
+
83
+    // ====================  INQUIRY       =======================
84
+
85
+#ifdef HAVE_YAMLCPP
86
+    YAML::Node Serialize() const;
87
+    static TEMTransmitter* DeSerialize(const YAML::Node& node);
88
+#endif
89
+
90
+    protected:
91
+
92
+    // ====================  LIFECYCLE     =======================
93
+
94
+    /** Default protected constructor, use New */
95
+    TEMTransmitter (const std::string& name);
96
+
97
+#ifdef HAVE_YAMLCPP
98
+    /** Default protected constructor, use New */
99
+    TEMTransmitter (const YAML::Node& node);
100
+#endif
101
+
102
+    /** Default protected destructor, use Delete */
103
+    ~TEMTransmitter ();
104
+
105
+    /**
106
+     *  @copybrief   LemmaObject::Release()
107
+     *  @copydetails LemmaObject::Release()
108
+     */
109
+    void Release();
110
+
111
+    private:
112
+
113
+    // ====================  DATA MEMBERS  =========================
114
+
115
+    Real                    repFreq;
116
+    FREQUENCYUNITS          repFreqUnits;
117
+    VectorXr                wfmTimes;
118
+    VectorXr                wfmAmps;
119
+
120
+}; // -----  end of class  TEMTransmitter  -----
121
+
122
+} // namespace Lemma
123
+
124
+#endif   // ----- #ifndef TEMTRANSMITTER_INC  -----
125
+

+ 213
- 0
Modules/TEM1D/include/instrumenttem.h View File

@@ -0,0 +1,213 @@
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   M. Andy Kass
10
+  @date     02/10/2011
11
+  @version  $Id: instrumenttem.h 201 2015-01-03 00:07:47Z tirons $
12
+ **/
13
+
14
+#ifndef __INSTRUMENTTEM_H
15
+#define __INSTRUMENTTEM_H
16
+
17
+#include "instrument.h"
18
+#include "emearth1d.h"
19
+#include "WireAntenna.h"
20
+#include "PolygonalWireAntenna.h"
21
+#include "receiverpoints.h"
22
+#include "dipolesource.h"
23
+#include "layeredearthem.h"
24
+#include "digitalfiltercostrans.h"
25
+#include "digitalfiltersintrans.h"
26
+#include "temintegrationkernel.h"
27
+#include "CubicSplineInterpolator.h"
28
+
29
+namespace Lemma {
30
+
31
+enum ReceiverType { INDUCTIVE, MAGNETOMETER, ELECTRIC };
32
+
33
+// ===================================================================
34
+//        Class:  InstrumentTem
35
+/// \brief  TEM Instrument Class
36
+/// \details Provides utility to forward model TEM data in Lemma.
37
+// ===================================================================
38
+class InstrumentTem : public Instrument {
39
+
40
+	friend std::ostream &operator<<(std::ostream &stream,
41
+		const InstrumentTem &ob);
42
+
43
+	public:
44
+
45
+	// ====================  LIFECYCLE     =======================
46
+
47
+		static InstrumentTem* New();
48
+
49
+		void Delete();
50
+
51
+	// ====================  OPERATORS     =======================
52
+
53
+	// ====================  OPERATIONS    =======================
54
+
55
+		/// Perform the forward model calculation
56
+		void MakeDirectCalculation( const HANKELTRANSFORMTYPE& hType );
57
+
58
+        /** Perform the forward model calculation, use lagged convolutions to
59
+         *  speed up the calculations
60
+         */
61
+		void MakeLaggedCalculation( const HANKELTRANSFORMTYPE& hType );
62
+
63
+	// ====================  ACCESS        =======================
64
+
65
+		/** Sets pulse parameters as a linearly segmented graph, so
66
+         *  for example a triangle wave needs three points in Amps and
67
+         *  times, a trapazoidal needs for. The pulse is assumed (defaults) to be
68
+         *  bipolar, only the positive polarity should be specified.
69
+         *  @param[in] Amp is the waveform current in Amps
70
+         *  @param[in] times are the abscissa values of the waveform
71
+         *  @param[in] bipolar specifies whether or not the pulse is bipolar
72
+         */
73
+		void SetPulse( const VectorXr& Amp, const VectorXr& times, bool bipolar=true );
74
+
75
+		/// Sets layered earth model
76
+		void EMEarthModel(LayeredEarthEM* Earth);
77
+
78
+		/// Sets transmitter parameters
79
+		void SetTransmitLoop(WireAntenna *antennae);
80
+
81
+		/// Sets dipole source parameters
82
+		void SetDipoleSource(DipoleSource* dipolesource);
83
+
84
+		/// Sets receiver points and parameters
85
+		void SetReceiver(ReceiverPoints* Receivers);
86
+
87
+        /** Sets the type of receiver/measurement
88
+         */
89
+        void SetReceiverType( const ReceiverType& rtype  );
90
+
91
+		/// Return calculated data
92
+		MatrixXr GetMeasurements();
93
+
94
+		/**
95
+            Set time gates, assumes gates widths are delta (instantaneous)
96
+            @param[in] times gate centres units are in seconds
97
+         */
98
+
99
+		void SetTimes(const VectorXr &times);
100
+
101
+        /** Sets time gates centres and widths, both in seconds. The window is assumed to be
102
+         *  a simple boxcar. Simpson's rule is used to integrate the response
103
+         * @param[in] times gate centres units are in seconds
104
+         * @param[in] widths gate widths units are in seconds
105
+         */
106
+        void SetTimeGates(const VectorXr &centres, const VectorXr& widths);
107
+
108
+		/// Get number of times
109
+		int GetNumberOfTimes();
110
+
111
+        /** Sets reference time for time gate to pulse time offset.
112
+         */
113
+        void SetReferenceTime(const Real& RefTime);
114
+
115
+		/// Attach EMEarth1D
116
+		//void AttachEMEarth1D(EMEarth1D *EMEarth);
117
+
118
+	// ====================  INQUIRY       =======================
119
+
120
+
121
+
122
+	protected:
123
+
124
+	// ====================  LIFECYCLE     =======================
125
+
126
+		/// Default protected constructor.
127
+		InstrumentTem (const std::string &name);
128
+
129
+		/// Default protected constructor.
130
+		~InstrumentTem ();
131
+
132
+		void Release();
133
+
134
+    // ====================  OPERATIONS    =======================
135
+
136
+        /**
137
+         *  Converts impulse B response (step db/dt) into inductive db/dt
138
+         *  response for general waveform.
139
+         */
140
+        void FoldAndConvolve( CubicSplineInterpolator* Spline );
141
+
142
+        /** Convolves the transmitter waveform(s), takes the impulse response
143
+            and uses simpson's rule to evaluate the integral.
144
+            @param[in] Spline is the Cubic Spline object representing the solution.
145
+            @param[in] t is the evaluation time.
146
+         */
147
+        Real ConvolveWaveform( CubicSplineInterpolator* Spline, const Real& t );
148
+
149
+        /** Subtracts previous waveform(s) from current impulse response, and re-splines.
150
+         */
151
+        void SubtractPrevious( CubicSplineInterpolator* Spline );
152
+
153
+
154
+	// ====================  DATA MEMBERS  =========================
155
+
156
+		//EMEarth1D* EmEarth;
157
+
158
+		WireAntenna* Antenna;
159
+
160
+		ReceiverPoints* Receiver;
161
+
162
+		LayeredEarthEM* EarthMod;
163
+
164
+		DipoleSource* Dipole;
165
+
166
+        bool     bipolarWaveform;
167
+
168
+        /** Number of previous pules to model */
169
+        int      NPreviousPulse;
170
+
171
+        /** Reference time (relative to pulse abscissa) for time gates */
172
+        Real     RefTime;
173
+
174
+        /** Pulse period, if bimodal 1/2 repitition period */
175
+        Real     PulseT;
176
+
177
+        /** Transmitter repitition frequency */
178
+        Real     TxFreq;
179
+
180
+        /** Receiver type */
181
+        ReceiverType  RType;
182
+
183
+        MatrixXr ModelledData;
184
+
185
+        /** Centre of time gate */
186
+		VectorXr TimeGates;
187
+
188
+        /** Width of time gates */
189
+        VectorXr GateWidths;
190
+
191
+        /** Pulse waveform */
192
+        VectorXr Waveform;
193
+
194
+        /** Current Amplitude of pulse */
195
+        VectorXr  TxAmp;
196
+
197
+        /** Current -delta of pulse */
198
+        VectorXr  TxDelta;
199
+
200
+        /** Current derivative of pulse */
201
+        VectorXr  TxDiff;
202
+
203
+        /** times associated with TxAmp segments */
204
+        VectorXr  TxAbs;
205
+
206
+	private:
207
+
208
+}; // -----  end of class  InstrumentTem  -----
209
+
210
+} // End of namespace Lemma
211
+
212
+#endif // __TEMINSTRUMENT_H
213
+

+ 146
- 0
Modules/TEM1D/include/inversesolvertem1d.h View File

@@ -0,0 +1,146 @@
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   M. Andy Kass
10
+  @date     03/23/2011
11
+  @version  $Id: inversesolvertem1d.h 201 2015-01-03 00:07:47Z tirons $
12
+ **/
13
+
14
+#ifndef _INVERSESOLVERTEM1D__H
15
+#define _INVERSESOLVERTEM1D__H
16
+
17
+#include "inversesolver.h"
18
+#include "layeredearthem.h"
19
+#include "WireAntenna.h"
20
+#include "dipolesource.h"
21
+#include "receiverpoints.h"
22
+#include "instrumenttem.h"
23
+#include "cg.h"
24
+
25
+namespace Lemma {
26
+	// ===================================================================
27
+	//        Class:  InverseSolverTEM1D
28
+	/// \brief  Inversion for 1D TEM data
29
+	/// \details
30
+	// ===================================================================
31
+	class InverseSolverTEM1D : public InverseSolver {
32
+
33
+		friend std::ostream &operator<<(std::ostream &stream,
34
+			const InverseSolverTEM1D &ob);
35
+
36
+		public:
37
+
38
+		// ====================  LIFECYCLE     =======================
39
+
40
+		static InverseSolverTEM1D* New();
41
+
42
+		void Delete();
43
+
44
+		// ====================  OPERATORS     =======================
45
+
46
+		// ====================  OPERATIONS    =======================
47
+
48
+		/// Perform the inverse calculation
49
+		void Calculate();
50
+
51
+		// ====================  ACCESS        =======================
52
+
53
+		/// Attach starting model
54
+		void AttachStartMod(LayeredEarthEM* inpstartmod);
55
+
56
+		/// Attach recovered model
57
+		void AttachRecMod(LayeredEarthEM* inprecmod);
58
+
59
+		/// Attach wire antenna source
60
+		void AttachWireAntenna(WireAntenna* inpwireantenna);
61
+
62
+		/// Attach dipole source
63
+		void AttachDipoleSource(DipoleSource* inpdipsource);
64
+
65
+		/// Attach receiver points
66
+		void AttachReceiver(ReceiverPoints* inpreceiver);
67
+
68
+		/// Set the time gates
69
+		void SetTimes(VectorXr &inptimes);
70
+
71
+		/// Show forward modelled data
72
+		void ShowSoln();
73
+
74
+		/// Write recovered model to file
75
+		void WriteSoln(const std::string &filename);
76
+
77
+		/// Set free parameter indices: layer, conductivity
78
+		void SetFreeParams(const VectorXi &layers, const VectorXi &cond);
79
+
80
+		/// Attach measured data for misfit comparison
81
+		void AttachMeasuredData(const MatrixXr &data);
82
+
83
+		// ====================  INQUIRY       =======================
84
+		/// Report number of iterations
85
+		int NumberOfIterations();
86
+
87
+		/// Report success/failure
88
+		bool Success();
89
+
90
+		/// Return phi m vector
91
+		VectorXr GetPhiMVector();
92
+
93
+		/// Return phi d vector
94
+		VectorXr GetPhiDVector();
95
+
96
+
97
+		protected:
98
+
99
+		/// Some crap trevor uses
100
+		void FillInG(const Vector3r& pos, const Vector3r& step);
101
+
102
+		/// Calculate Jacobian
103
+		MatrixXr CalcJac(LayeredEarthEM* m0);
104
+
105
+		// ====================  LIFECYCLE     =======================
106
+
107
+		/// Default protected constructor.
108
+		InverseSolverTEM1D (const std::string &name);
109
+
110
+		/// Default protected constructor.
111
+		~InverseSolverTEM1D ();
112
+
113
+        void Release();
114
+
115
+		// ====================  DATA MEMBERS  =========================
116
+
117
+		WireAntenna* Antenna;
118
+
119
+		DipoleSource* Dipole;
120
+
121
+		ReceiverPoints* Receiver;
122
+
123
+		LayeredEarthEM* StartingMod;
124
+
125
+		LayeredEarthEM* RecoveredMod;
126
+
127
+		InstrumentTem *InstrumentFor;
128
+
129
+		MatrixXr MeasuredData;
130
+
131
+		VectorXr Times;
132
+
133
+		/// Vector of indices for which layer conductivities are solved for
134
+		VectorXi SCondIndex;
135
+
136
+		/// Vecor of indices for which layer thicknesses are solved for
137
+		VectorXi SThickIndex;
138
+
139
+		/// Temporary vector for returning linearised step
140
+		VectorXr RecModStep;
141
+
142
+		private:
143
+
144
+}; // -----  end of class  InverseSolverTEM1D  -----
145
+} // End of namespace Lemma
146
+#endif // _INVERSESOLVERTEM1D__H

+ 83
- 0
Modules/TEM1D/include/modelreadertem1d.h View File

@@ -0,0 +1,83 @@
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   M. Andy Kass
10
+  @date     02/19/2011
11
+  @version  $Id: modelreadertem1d.h 87 2013-09-05 22:44:05Z tirons $
12
+ **/
13
+
14
+#ifndef __MODELREADERTEM1D_H
15
+#define __MODELREADERTEM1D_H
16
+
17
+#include "modelreader.h"
18
+
19
+namespace Lemma {
20
+
21
+// ===================================================================
22
+//        Class:  ModelReaderTem1D
23
+/// \brief Model reader class for forward modelling 1D TEM data
24
+/// \details This is a mostly abstract class.
25
+// ===================================================================
26
+class ModelReaderTem1D : public ModelReader {
27
+
28
+	friend std::ostream &operator<<(std::ostream &stream,
29
+		const ModelReaderTem1D &ob);
30
+
31
+	public:
32
+
33
+		// ====================  LIFECYCLE     =======================
34
+
35
+		static ModelReaderTem1D* New();
36
+
37
+		void Delete();
38
+
39
+		// ====================  OPERATORS     =======================
40
+
41
+		// ====================  OPERATIONS    =======================
42
+
43
+		//void ReadParameters(/* Pass file name */);
44
+
45
+		// ====================  ACCESS        =======================
46
+
47
+		// ====================  INQUIRY       =======================
48
+
49
+
50
+	protected:
51
+
52
+		// ====================  LIFECYCLE     =======================
53
+
54
+		/// Default protected constructor.
55
+		ModelReaderTem1D (const std::string &name);
56
+
57
+		/// Default protected constructor.
58
+		~ModelReaderTem1D ();
59
+
60
+		void Release();
61
+
62
+		/// Read in the Earth Model file and attach
63
+		//void ReadModel();
64
+
65
+		/// Read in the instrument parameters and attach
66
+		//void ReadInstrument();
67
+
68
+		/// Read in the waveform file (future)
69
+		//void ReadWaveform();
70
+
71
+		// ====================  DATA MEMBERS  =========================
72
+
73
+		//std::string modelfile;
74
+
75
+		//std::string instrumentfile;
76
+
77
+		//std::string waveformfile;
78
+
79
+	private:
80
+
81
+}; // -----  end of class  ModelReaderTem1D  -----
82
+} // end of namespace lemma
83
+#endif // __MODELREADERTEM1D_H

+ 116
- 0
Modules/TEM1D/include/modelreadertem1dubc.h View File

@@ -0,0 +1,116 @@
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   M. Andy Kass
10
+  @date     02/19/2011
11
+  @version  $Id: modelreadertem1dubc.h 87 2013-09-05 22:44:05Z tirons $
12
+ **/
13
+
14
+#ifndef __MODELREADERTEM1DUBC_H
15
+#define __MODELREADERTEM1DUBC_H
16
+
17
+#include "modelreadertem1d.h"
18
+
19
+namespace Lemma {
20
+
21
+// ===================================================================
22
+//        Class:  ModelReaderTem1DUBC
23
+/// \brief Model reader class for forward modelling 1D TEM data
24
+/// \details Reads UBC 1D TEM forward model format
25
+// ===================================================================
26
+class ModelReaderTem1DUBC : public ModelReaderTem1D {
27
+
28
+	friend std::ostream &operator<<(std::ostream &stream,
29
+		const ModelReaderTem1DUBC &ob);
30
+
31
+	public:
32
+
33
+		// ====================  LIFECYCLE     =======================
34
+
35
+		static ModelReaderTem1DUBC* New();
36
+
37
+		void Delete();
38
+
39
+		// ====================  OPERATORS     =======================
40
+
41
+		// ====================  OPERATIONS    =======================
42
+
43
+		void ReadParameters(const std::string &params);
44
+
45
+		// ====================  ACCESS        =======================
46
+
47
+		/// Attaches a LayeredEarthEM object
48
+		void SetEMEarth1D(LayeredEarthEM* earth);
49
+
50
+		/// Attaches a WireAntenna object
51
+		void SetTransmitter(WireAntenna *antennae);
52
+
53
+		/// Attaches a ReceiverPoints object
54
+		void SetReceiver(ReceiverPoints* receiver);
55
+
56
+		VectorXr GetTimes();
57
+
58
+		// ====================  INQUIRY       =======================
59
+
60
+
61
+	protected:
62
+
63
+		// ====================  LIFECYCLE     =======================
64
+
65
+		/// Default protected constructor.
66
+		ModelReaderTem1DUBC (const std::string &name);
67
+
68
+		/// Default protected constructor.
69
+		~ModelReaderTem1DUBC ();
70
+
71
+		void Release();
72
+
73
+		/// Read in the Earth Model file and attach
74
+		void ReadModel();
75
+
76
+		/// Read in the instrument parameters and attach
77
+		void ReadInstrument();
78
+
79
+		/// Read in the waveform file (future)
80
+		void ReadWaveform();
81
+
82
+		// ====================  DATA MEMBERS  =========================
83
+
84
+		std::string modelfile;
85
+
86
+		std::string instrumentfile;
87
+
88
+		std::string waveformfile;
89
+
90
+		WireAntenna* Trans;
91
+
92
+		ReceiverPoints* Receivers;
93
+
94
+		LayeredEarthEM* EarthMod;
95
+
96
+		/// Simulated noise flag
97
+		bool addednoise;
98
+
99
+		/// Simulated noise percentage
100
+		Real noisepercent;
101
+
102
+		/// Baseline threshold percentage
103
+		Real noisethresh;
104
+
105
+		/// Seed for random number generator
106
+		Real noiseseed;
107
+
108
+		VectorXr receivermoment;
109
+
110
+		VectorXr modtimes;
111
+
112
+	private:
113
+
114
+}; // -----  end of class  ModelReaderTem1DUBC  -----
115
+} // end of namespace lemma
116
+#endif // __MODELREADERTEM1DUBC_H

+ 103
- 0
Modules/TEM1D/include/temintegrationkernel.h View File

@@ -0,0 +1,103 @@
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   M. Andy Kass
10
+  @date     02/10/2011
11
+  @version  $Id: temintegrationkernel.h 190 2014-10-16 23:02:09Z tirons $
12
+ **/
13
+
14
+#ifndef __TEMINTEGRATIONKERNEL_H
15
+#define __TEMINTEGRATIONKERNEL_H
16
+
17
+#include "integrationkernel.h"
18
+#include "emearth1d.h"
19
+
20
+namespace Lemma {
21
+
22
+
23
+// ===================================================================
24
+//        Class:  TemIntegrationKernel
25
+/// \brief  Integration kernel for calculation of TEM data
26
+/// \details Calculates the integration kernel for the sine transform
27
+// ===================================================================
28
+
29
+class TemIntegrationKernel : public IntegrationKernel<Real>{
30
+
31
+	//friend std::ostream &operator<<(std::ostream &stream,
32
+	//	const TemIntegrationKernel &ob);
33
+
34
+	public:
35
+
36
+	// ====================  LIFECYCLE     =======================
37
+
38
+		static TemIntegrationKernel* New();
39
+
40
+		void Delete();
41
+
42
+	// ====================  OPERATORS     =======================
43
+
44
+	// ====================  OPERATIONS    =======================
45
+
46
+	// ====================  ACCESS        =======================
47
+
48
+		/// Calculates the integration argument.  Passed a frequency.
49
+		Real Argument(const Real&x, const int& iRelated);
50
+
51
+		int GetNumRel();
52
+
53
+		/// Attach EMEarth1D object to TemIntegrationKernel
54
+		void SetEMEarth1D(EMEarth1D* earth);
55
+
56
+		/// Attach Transmitter object
57
+		void SetTransmitter(WireAntenna *antennae);
58
+
59
+		/// Attach Dipole object
60
+		void SetDipole(DipoleSource* dipolesource);
61
+
62
+		/// Attach Receiver object
63
+		void SetReceiver(ReceiverPoints *receiver);
64
+
65
+        /**
66
+         *   @param[in] comp is the component to integrate
67
+         */
68
+        void SetComponent(const FIELDCOMPONENT& comp);
69
+	// ====================  INQUIRY       =======================
70
+
71
+
72
+
73
+	protected:
74
+
75
+	// ====================  LIFECYCLE     =======================
76
+
77
+		/// Default protected constructor.
78
+		TemIntegrationKernel (const std::string& name);
79
+
80
+		/// Default protected constructor.
81
+		~TemIntegrationKernel ();
82
+
83
+		void Release();
84
+
85
+	// ====================  DATA MEMBERS  =========================
86
+
87
+        FIELDCOMPONENT  component;
88
+
89
+		EMEarth1D* EmEarthInt;
90
+
91
+		WireAntenna* Trans;
92
+
93
+		DipoleSource* DipoleS;
94
+
95
+		ReceiverPoints* Receivers;
96
+
97
+	private:
98
+
99
+}; // -----  end of class  TemIntegrationKernel  -----
100
+
101
+} // End of namespace Lemma
102
+
103
+#endif // __TEMINTEGRATIONKERNEL_H

+ 127
- 0
Modules/TEM1D/src/TEMInductiveReceiver.cpp View File

@@ -0,0 +1,127 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      10/08/2014 03:19:58 PM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#include "TEMInductiveReceiver.h"
21
+
22
+namespace Lemma {
23
+
24
+
25
+
26
+    // ====================  FRIEND METHODS  =====================
27
+#ifdef HAVE_YAMLCPP
28
+    std::ostream &operator << (std::ostream &stream, const TEMInductiveReceiver &ob) {
29
+        stream << ob.Serialize()  << "\n---\n"; // End of doc --- as a direct stream should encapulste thingy
30
+        return stream;
31
+    }
32
+#else
33
+    std::ostream &operator<<(std::ostream &stream, const TEMInductiveReceiver& ob) {
34
+        stream << *(TEMReceiver*)(&ob);
35
+        return stream;
36
+    }
37
+#endif
38
+
39
+    // ====================  LIFECYCLE     =======================
40
+
41
+    //--------------------------------------------------------------------------------------
42
+    //       Class:  TEMInductiveReceiver
43
+    //      Method:  TEMInductiveReceiver
44
+    // Description:  constructor (protected)
45
+    //--------------------------------------------------------------------------------------
46
+    TEMInductiveReceiver::TEMInductiveReceiver (const std::string& name) : TEMReceiver(name) {
47
+
48
+    }  // -----  end of method TEMInductiveReceiver::TEMInductiveReceiver  (constructor)  -----
49
+
50
+#ifdef HAVE_YAMLCPP
51
+    //--------------------------------------------------------------------------------------
52
+    //       Class:  TEMInductiveReceiver
53
+    //      Method:  TEMInductiveReceiver
54
+    // Description:  constructor (protected)
55
+    //--------------------------------------------------------------------------------------
56
+    TEMInductiveReceiver::TEMInductiveReceiver (const YAML::Node& node) : TEMReceiver(node) {
57
+
58
+    }  // -----  end of method TEMInductiveReceiver::TEMInductiveReceiver  (constructor)  -----
59
+#endif
60
+
61
+    //--------------------------------------------------------------------------------------
62
+    //       Class:  TEMInductiveReceiver
63
+    //      Method:  New()
64
+    // Description:  public constructor
65
+    //--------------------------------------------------------------------------------------
66
+    TEMInductiveReceiver* TEMInductiveReceiver::New() {
67
+        TEMInductiveReceiver*  Obj = new TEMInductiveReceiver("TEMInductiveReceiver");
68
+        Obj->AttachTo(Obj);
69
+        return Obj;
70
+    }
71
+
72
+    //--------------------------------------------------------------------------------------
73
+    //       Class:  TEMInductiveReceiver
74
+    //      Method:  ~TEMInductiveReceiver
75
+    // Description:  destructor (protected)
76
+    //--------------------------------------------------------------------------------------
77
+    TEMInductiveReceiver::~TEMInductiveReceiver () {
78
+
79
+    }  // -----  end of method TEMInductiveReceiver::~TEMInductiveReceiver  (destructor)  -----
80
+
81
+    //--------------------------------------------------------------------------------------
82
+    //       Class:  TEMInductiveReceiver
83
+    //      Method:  Delete
84
+    // Description:  public destructor
85
+    //--------------------------------------------------------------------------------------
86
+    void TEMInductiveReceiver::Delete() {
87
+        this->DetachFrom(this);
88
+    }
89
+
90
+    //--------------------------------------------------------------------------------------
91
+    //       Class:  TEMInductiveReceiver
92
+    //      Method:  Release
93
+    // Description:  destructor (protected)
94
+    //--------------------------------------------------------------------------------------
95
+    void TEMInductiveReceiver::Release() {
96
+        delete this;
97
+    }
98
+
99
+
100
+#ifdef HAVE_YAMLCPP
101
+    //--------------------------------------------------------------------------------------
102
+    //       Class:  TEMInductiveReceiver
103
+    //      Method:  Serialize
104
+    //--------------------------------------------------------------------------------------
105
+    YAML::Node  TEMInductiveReceiver::Serialize (  ) const {
106
+        YAML::Node node;
107
+        node = TEMReceiver::Serialize();
108
+        node.SetTag( this->Name ); // Set Tag after doing parents
109
+        return node;
110
+    }		// -----  end of method TEMInductiveReceiver::Serialize  -----
111
+
112
+
113
+    //--------------------------------------------------------------------------------------
114
+    //       Class:  TEMInductiveReceiver
115
+    //      Method:  DeSerialize
116
+    //--------------------------------------------------------------------------------------
117
+    TEMInductiveReceiver* TEMInductiveReceiver::DeSerialize ( const YAML::Node& node  ) {
118
+        TEMInductiveReceiver* Object = new TEMInductiveReceiver(node);
119
+        Object->AttachTo(Object);
120
+        DESERIALIZECHECK( node, Object )
121
+        return Object ;
122
+    }		// -----  end of method TEMInductiveReceiver::DeSerialize  -----
123
+#endif
124
+
125
+
126
+}		// -----  end of Lemma  name  -----
127
+

+ 333
- 0
Modules/TEM1D/src/TEMReceiver.cpp View File

@@ -0,0 +1,333 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      10/08/2014 03:04:56 PM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#include "TEMReceiver.h"
21
+
22
+namespace Lemma {
23
+
24
+
25
+    // ====================  FRIEND METHODS  =====================
26
+#ifdef HAVE_YAMLCPP
27
+    std::ostream &operator << (std::ostream &stream, const TEMReceiver &ob) {
28
+        stream << ob.Serialize()  << "\n---\n"; // End of doc --- as a direct stream should encapulste thingy
29
+        return stream;
30
+    }
31
+#else
32
+    std::ostream &operator<<(std::ostream &stream, const TEMReceiver& ob) {
33
+        stream << *(ReceiverPoints*)(&ob);
34
+        return stream;
35
+    }
36
+#endif
37
+
38
+    // ====================  LIFECYCLE     =======================
39
+
40
+    //--------------------------------------------------------------------------------------
41
+    //       Class:  TEMReceiver
42
+    //      Method:  TEMReceiver
43
+    // Description:  constructor (protected)
44
+    //--------------------------------------------------------------------------------------
45
+    TEMReceiver::TEMReceiver (const std::string& name) : ReceiverPoints(name), moment(1), referenceTime(0) {
46
+
47
+    }  // -----  end of method TEMReceiver::TEMReceiver  (constructor)  -----
48
+
49
+#ifdef HAVE_YAMLCPP
50
+    //--------------------------------------------------------------------------------------
51
+    //       Class:  TEMReceiver
52
+    //      Method:  TEMReceiver
53
+    // Description:  constructor (protected)
54
+    //--------------------------------------------------------------------------------------
55
+    TEMReceiver::TEMReceiver (const YAML::Node& node) : ReceiverPoints(node) {
56
+
57
+        moment = node["moment"].as<Real>();
58
+        referenceTime = node["referenceTime"].as<Real>();
59
+        component = string2Enum<FIELDCOMPONENT>( node["component"].as<std::string>() );
60
+
61
+        windowCentres = node["windowCentres"].as<VectorXr>();
62
+        windowWidths  = node["windowWidths"].as<VectorXr>();
63
+        noiseSTD      = node["noiseSTD"].as<VectorXr>();
64
+        //location = node["location"].as<Vector3r>();
65
+    }  // -----  end of method TEMReceiver::TEMReceiver  (constructor)  -----
66
+#endif
67
+
68
+    //--------------------------------------------------------------------------------------
69
+    //       Class:  TEMReceiver
70
+    //      Method:  New()
71
+    // Description:  public constructor
72
+    //--------------------------------------------------------------------------------------
73
+    TEMReceiver* TEMReceiver::New() {
74
+        TEMReceiver*  Obj = new TEMReceiver("TEMReceiver");
75
+        Obj->AttachTo(Obj);
76
+        return Obj;
77
+    }
78
+
79
+
80
+    //--------------------------------------------------------------------------------------
81
+    //       Class:  TEMReceiver
82
+    //      Method:  Clone
83
+    //--------------------------------------------------------------------------------------
84
+    TEMReceiver* TEMReceiver::Clone() {
85
+        TEMReceiver* Copy = TEMReceiver::New();
86
+            Copy->SetNumberOfReceivers( this->NumberOfReceivers );
87
+            Copy->Mask = this->Mask;
88
+            Copy->Locations = this->Locations;
89
+            // TEM stuff
90
+            Copy->moment = this->moment;
91
+            Copy->referenceTime = this->referenceTime;
92
+            Copy->nHat = this->nHat;
93
+            Copy->component = this->component;
94
+            Copy->windowCentres = this->windowCentres;
95
+            Copy->windowWidths = this->windowWidths;
96
+            Copy->noiseSTD = this->noiseSTD;
97
+        return Copy;
98
+    }		// -----  end of method TEMReceiver::Clone  -----
99
+
100
+    //--------------------------------------------------------------------------------------
101
+    //       Class:  TEMReceiver
102
+    //      Method:  ~TEMReceiver
103
+    // Description:  destructor (protected)
104
+    //--------------------------------------------------------------------------------------
105
+    TEMReceiver::~TEMReceiver () {
106
+
107
+    }  // -----  end of method TEMReceiver::~TEMReceiver  (destructor)  -----
108
+
109
+    //--------------------------------------------------------------------------------------
110
+    //       Class:  TEMReceiver
111
+    //      Method:  Delete
112
+    // Description:  public destructor
113
+    //--------------------------------------------------------------------------------------
114
+    void TEMReceiver::Delete() {
115
+        this->DetachFrom(this);
116
+    }
117
+
118
+    //--------------------------------------------------------------------------------------
119
+    //       Class:  TEMReceiver
120
+    //      Method:  Release
121
+    // Description:  destructor (protected)
122
+    //--------------------------------------------------------------------------------------
123
+    void TEMReceiver::Release() {
124
+        delete this;
125
+    }
126
+
127
+
128
+    //--------------------------------------------------------------------------------------
129
+    //       Class:  TEMReceiver
130
+    //      Method:  SetWindows
131
+    //--------------------------------------------------------------------------------------
132
+    void TEMReceiver::SetWindows ( const VectorXr& centres, const VectorXr& widths, const TIMEUNITS& Units ) {
133
+
134
+        Real sc(0);
135
+        switch (Units) {
136
+            case SEC:
137
+                sc = 1;
138
+                break;
139
+            case MILLISEC:
140
+                sc = 1e-3;
141
+                break;
142
+            case MICROSEC:
143
+                sc = 1e-6;
144
+                break;
145
+            case NANOSEC:
146
+                sc = 1e-9;
147
+                break;
148
+            case PICOSEC:
149
+                sc = 1e-12;
150
+                break;
151
+        };
152
+        windowCentres = sc*centres;
153
+        windowWidths = sc*widths;
154
+        noiseSTD = VectorXr::Zero(windowCentres.size());
155
+        return ;
156
+    }		// -----  end of method TEMReceiver::SetWindows  -----
157
+
158
+
159
+    //--------------------------------------------------------------------------------------
160
+    //       Class:  TEMReceiver
161
+    //      Method:  SetNoiseSTD
162
+    //--------------------------------------------------------------------------------------
163
+    void TEMReceiver::SetNoiseSTD ( const VectorXr& noiseIn ) {
164
+        if ( noiseIn.size() == windowCentres.size() ) {
165
+            noiseSTD = noiseIn;
166
+        } else {
167
+            throw std::runtime_error("TEMReceiver::SetNoiseSTD not aligned");
168
+        }
169
+        return ;
170
+
171
+    }		// -----  end of method TEMReceiver::SetNoiseSTD  -----
172
+
173
+
174
+    //--------------------------------------------------------------------------------------
175
+    //       Class:  TEMReceiver
176
+    //      Method:  GetNoiseSTD
177
+    //--------------------------------------------------------------------------------------
178
+    VectorXr TEMReceiver::GetNoiseSTD (  ) {
179
+        return noiseSTD ;
180
+    }		// -----  end of method TEMReceiver::GetNoiseSTD  -----
181
+
182
+
183
+    //--------------------------------------------------------------------------------------
184
+    //       Class:  TEMReceiver
185
+    //      Method:  SampleNoise
186
+    //--------------------------------------------------------------------------------------
187
+    VectorXr TEMReceiver::SampleNoise (  ) {
188
+        
189
+	/* we have C++-11 now! No Boost! 
190
+        boost::mt19937 rng(time(0));
191
+        boost::normal_distribution<> nd(0.0, 1.0);
192
+        boost::variate_generator<boost::mt19937&, boost::normal_distribution<> > var_nor(rng, nd);
193
+	*/
194
+
195
+        std::random_device rd;
196
+        std::mt19937 gen(rd()); 
197
+        std::normal_distribution<> d(0.0, 1.00);
198
+
199
+        VectorXr noise = VectorXr::Zero( windowCentres.size() );
200
+        for (int ii=0; ii<windowCentres.size(); ++ii) {
201
+            //noise(ii) = var_nor(); // old boost way
202
+            noise(ii) = d(gen);
203
+        }
204
+        return noise.array() * noiseSTD.array();
205
+    }		// -----  end of method TEMReceiver::SampleNoise  -----
206
+
207
+
208
+    //--------------------------------------------------------------------------------------
209
+    //       Class:  TEMReceiver
210
+    //      Method:  SetReferenceTime
211
+    //--------------------------------------------------------------------------------------
212
+    void TEMReceiver::SetReferenceTime ( const Real& refTime, const TIMEUNITS& units ) {
213
+        Real sc(0);
214
+        switch (units) {
215
+            case SEC:
216
+                sc = 1;
217
+                break;
218
+            case MILLISEC:
219
+                sc = 1e-3;
220
+                break;
221
+            case MICROSEC:
222
+                sc = 1e-6;
223
+                break;
224
+            case NANOSEC:
225
+                sc = 1e-9;
226
+                break;
227
+            case PICOSEC:
228
+                sc = 1e-12;
229
+                break;
230
+        };
231
+        referenceTime = sc*refTime;
232
+
233
+        return ;
234
+    }		// -----  end of method TEMReceiver::SetReferenceTime  -----
235
+
236
+
237
+
238
+    //--------------------------------------------------------------------------------------
239
+    //       Class:  TEMReceiver
240
+    //      Method:  SetMoment
241
+    //--------------------------------------------------------------------------------------
242
+    void TEMReceiver::SetMoment ( const Real& mom ) {
243
+        moment = mom;
244
+        return ;
245
+    }		// -----  end of method TEMReceiver::SetMoment  -----
246
+
247
+
248
+
249
+    //--------------------------------------------------------------------------------------
250
+    //       Class:  TEMReceiver
251
+    //      Method:  SetLocation
252
+    //--------------------------------------------------------------------------------------
253
+    void TEMReceiver::SetRxLocation ( const Vector3r& loc ) {
254
+        this->SetNumberOfReceivers(1); // Valgrind doesn't like??
255
+        this->SetLocation(0, loc);
256
+        //location = loc;
257
+        return ;
258
+    }		// -----  end of method TEMReceiver::SetLocation  -----
259
+
260
+
261
+    //--------------------------------------------------------------------------------------
262
+    //       Class:  TEMReceiver
263
+    //      Method:  SetComponent
264
+    //--------------------------------------------------------------------------------------
265
+    void TEMReceiver::SetComponent ( const FIELDCOMPONENT& comp  ) {
266
+        component = comp;
267
+        return ;
268
+    }		// -----  end of method TEMReceiver::SetComponent  -----
269
+
270
+
271
+    //--------------------------------------------------------------------------------------
272
+    //       Class:  TEMReceiver
273
+    //      Method:  get_WindowWidths
274
+    //--------------------------------------------------------------------------------------
275
+    VectorXr TEMReceiver::GetWindowWidths (  ) {
276
+        return windowWidths;
277
+    }		// -----  end of method TEMReceiver::get_WindowWidths  -----
278
+
279
+
280
+    //--------------------------------------------------------------------------------------
281
+    //       Class:  TEMReceiver
282
+    //      Method:  get_WindowCentres
283
+    //--------------------------------------------------------------------------------------
284
+    VectorXr TEMReceiver::GetWindowCentres (  ) {
285
+        return windowCentres;
286
+    }		// -----  end of method TEMReceiver::get_WindowCentres  -----
287
+
288
+
289
+
290
+    //--------------------------------------------------------------------------------------
291
+    //       Class:  TEMReceiver
292
+    //      Method:  GetReferenceTime
293
+    //--------------------------------------------------------------------------------------
294
+    Real TEMReceiver::GetReferenceTime (  ) {
295
+        return referenceTime;
296
+    }		// -----  end of method TEMReceiver::GetReferenceTime  -----
297
+
298
+
299
+#ifdef HAVE_YAMLCPP
300
+    //--------------------------------------------------------------------------------------
301
+    //       Class:  TEMReceiver
302
+    //      Method:  Serialize
303
+    //--------------------------------------------------------------------------------------
304
+    YAML::Node  TEMReceiver::Serialize (  ) const {
305
+        YAML::Node node = ReceiverPoints::Serialize();
306
+        node.SetTag( this->Name );
307
+        node["moment"] = moment;
308
+        node["referenceTime"] = referenceTime;
309
+        node["component"] = enum2String(component);
310
+
311
+        node["windowCentres"] = windowCentres;
312
+        node["windowWidths"] = windowWidths;
313
+        node["noiseSTD"] = noiseSTD;
314
+        //node["location"] = location;
315
+        return node;
316
+    }		// -----  end of method TEMReceiver::Serialize  -----
317
+
318
+
319
+    //--------------------------------------------------------------------------------------
320
+    //       Class:  TEMReceiver
321
+    //      Method:  DeSerialize
322
+    //--------------------------------------------------------------------------------------
323
+    TEMReceiver* TEMReceiver::DeSerialize ( const YAML::Node& node  ) {
324
+        TEMReceiver* Object = new TEMReceiver(node);
325
+        Object->AttachTo(Object);
326
+        DESERIALIZECHECK( node, Object )
327
+        return Object ;
328
+
329
+    }		// -----  end of method TEMReceiver::DeSerialize  -----
330
+#endif
331
+
332
+}		// -----  end of Lemma  name  -----
333
+

+ 202
- 0
Modules/TEM1D/src/TEMSurvey.cpp View File

@@ -0,0 +1,202 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      10/08/2014 01:52:04 PM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#include	"TEMSurvey.h"
21
+
22
+namespace Lemma {
23
+
24
+
25
+    // ====================  FRIEND METHODS  =====================
26
+
27
+    #ifdef HAVE_YAMLCPP
28
+    std::ostream &operator << (std::ostream &stream, const TEMSurvey &ob) {
29
+        stream << ob.Serialize()  << "\n---\n"; // End of doc --- a direct stream should encapulste object
30
+        return stream;
31
+    }
32
+    #else
33
+    std::ostream &operator<<(std::ostream &stream, const TEMSurvey &ob) {
34
+        stream << *(LemmaObject*)(&ob);
35
+        return stream;
36
+    }
37
+    #endif
38
+
39
+    // ====================  LIFECYCLE     =======================
40
+
41
+    //--------------------------------------------------------------------------------------
42
+    //       Class:  TEMSurvey
43
+    //      Method:  TEMSurvey
44
+    // Description:  constructor (protected)
45
+    //--------------------------------------------------------------------------------------
46
+    TEMSurvey::TEMSurvey (const std::string& name) : LemmaObject(name) {
47
+
48
+    }  // -----  end of method TEMSurvey::TEMSurvey  (constructor)  -----
49
+
50
+    //--------------------------------------------------------------------------------------
51
+    //       Class:  TEMSurvey
52
+    //      Method:  TEMSurvey
53
+    // Description:  DeSerializing constructor (protected)
54
+    //--------------------------------------------------------------------------------------
55
+    #ifdef HAVE_YAMLCPP
56
+    TEMSurvey::TEMSurvey (const YAML::Node& node) : LemmaObject(node) {
57
+
58
+        Lines.resize( node["numberOfLines"].as<int>( ) );
59
+
60
+    }  // -----  end of method TEMSurvey::TEMSurvey  (constructor)  -----
61
+    #endif
62
+
63
+    //--------------------------------------------------------------------------------------
64
+    //       Class:  TEMSurvey
65
+    //      Method:  New()
66
+    // Description:  public constructor
67
+    //--------------------------------------------------------------------------------------
68
+    TEMSurvey* TEMSurvey::New() {
69
+        TEMSurvey*  Obj = new TEMSurvey("TEMSurvey");
70
+        Obj->AttachTo(Obj);
71
+        return Obj;
72
+    }
73
+
74
+    //--------------------------------------------------------------------------------------
75
+    //       Class:  TEMSurvey
76
+    //      Method:  ~TEMSurvey
77
+    // Description:  destructor (protected)
78
+    //--------------------------------------------------------------------------------------
79
+    TEMSurvey::~TEMSurvey () {
80
+
81
+    }  // -----  end of method TEMSurvey::~TEMSurvey  (destructor)  -----
82
+
83
+    //--------------------------------------------------------------------------------------
84
+    //       Class:  TEMSurvey
85
+    //      Method:  Delete
86
+    // Description:  public destructor
87
+    //--------------------------------------------------------------------------------------
88
+    void TEMSurvey::Delete() {
89
+        this->DetachFrom(this);
90
+    }
91
+
92
+    //--------------------------------------------------------------------------------------
93
+    //       Class:  TEMSurvey
94
+    //      Method:  Release
95
+    // Description:  destructor (protected)
96
+    //--------------------------------------------------------------------------------------
97
+    void TEMSurvey::Release() {
98
+        for (std::vector<TEMSurveyLine*>::iterator it = Lines.begin() ; it != Lines.end(); ++it) {
99
+            (*it)->DetachFrom(this);
100
+        }
101
+        delete this;
102
+    }
103
+
104
+    #ifdef HAVE_YAMLCPP
105
+    //--------------------------------------------------------------------------------------
106
+    //       Class:  TEMSurvey
107
+    //      Method:  Serialize
108
+    //--------------------------------------------------------------------------------------
109
+    YAML::Node  TEMSurvey::Serialize (  ) const {
110
+        YAML::Node node;
111
+        node.SetTag( this->Name );
112
+        node["numberOfLines"] = Lines.size();
113
+        for (unsigned int it = 0; it< Lines.size();  ++it) {
114
+            node[std::string("line_") +  to_string(it)] = Lines[it]->Serialize();
115
+        }
116
+        return node;
117
+    }		// -----  end of method TEMSurvey::Serialize  -----
118
+
119
+
120
+    //--------------------------------------------------------------------------------------
121
+    //       Class:  TEMSurvey
122
+    //      Method:  DeSerialize
123
+    //--------------------------------------------------------------------------------------
124
+    TEMSurvey* TEMSurvey::DeSerialize ( const YAML::Node& node  ) {
125
+        TEMSurvey* Object = new TEMSurvey(node);
126
+        Object->AttachTo(Object);
127
+        DESERIALIZECHECK( node, Object )
128
+        return Object ;
129
+    }		// -----  end of method TEMSurvey::DeSerialize  -----
130
+    #endif
131
+
132
+
133
+
134
+        // ====================  OPERATORS    =======================
135
+
136
+    TEMSurveyLine* TEMSurvey::operator( ) ( const int& idx ) const {
137
+        return this->Lines[ idx ];
138
+    }
139
+
140
+    TEMSurveyLineRecord* TEMSurvey::operator( ) ( const int& iline, const int& irec ) const {
141
+        return Lines[ iline ]->GetRecord( irec );
142
+    }
143
+
144
+    //--------------------------------------------------------------------------------------
145
+    //       Class:  TEMSurvey
146
+    //      Method:  SetNumberOfLines
147
+    //--------------------------------------------------------------------------------------
148
+    void TEMSurvey::SetNumberOfLines ( const int& nlines  ) {
149
+
150
+        // clean up any old lines
151
+        for (std::vector<TEMSurveyLine*>::iterator it = Lines.begin() ; it != Lines.end(); ++it) {
152
+            (*it)->DetachFrom(this);
153
+        }
154
+        Lines.clear();
155
+
156
+        // Allocate these lines
157
+        Lines.reserve(nlines);
158
+        for (int il=0; il<nlines; ++il) {
159
+            Lines.push_back( new TEMSurveyLine("TEMSurveyLine") );
160
+            Lines[il]->AttachTo(this);
161
+        }
162
+
163
+        return ;
164
+    }		// -----  end of method TEMSurvey::SetNumberOfLines  -----
165
+
166
+
167
+    //--------------------------------------------------------------------------------------
168
+    //       Class:  TEMSurvey
169
+    //      Method:  GetLine
170
+    //--------------------------------------------------------------------------------------
171
+    TEMSurveyLine* TEMSurvey::GetLine ( const unsigned int&  iline ) {
172
+        return Lines[iline];
173
+    }		// -----  end of method TEMSurvey::GetLine  -----
174
+
175
+
176
+
177
+    //--------------------------------------------------------------------------------------
178
+    //       Class:  TEMSurvey
179
+    //      Method:  ForwardModel
180
+    //--------------------------------------------------------------------------------------
181
+    TEMSurveyData* TEMSurvey::ForwardModel ( LayeredEarthEM* model, bool additiveNoise ) {
182
+
183
+        TEMSurveyData* ForwardData = TEMSurveyData::New();
184
+            //ForwardData->SetNumberOfLines(Lines.size());
185
+
186
+        for (std::vector<TEMSurveyLine*>::iterator it = Lines.begin() ; it != Lines.end(); ++it) {
187
+
188
+            TEMSurveyLineData* LineData = ((*it)->ForwardModel( model, additiveNoise ) );
189
+            LineData->AttachTo(ForwardData);
190
+            ForwardData->LineData.push_back( LineData );
191
+        }
192
+
193
+        //for (int it=0; it<Lines.size(); ++it) {
194
+        //    Lines[it]->ForwardModel( model );
195
+        //}
196
+
197
+        return  ForwardData;
198
+    }		// -----  end of method TEMSurvey::ForwardModel  -----
199
+
200
+
201
+}		// -----  end of Lemma  name  -----
202
+

+ 244
- 0
Modules/TEM1D/src/TEMSurveyData.cpp View File

@@ -0,0 +1,244 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      03/03/2015 10:00:22
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2015, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2015, Trevor Irons
18
+ */
19
+
20
+#include "TEMSurveyData.h"
21
+
22
+namespace Lemma {
23
+
24
+// ====================  FRIEND METHODS  =====================
25
+#ifdef HAVE_YAMLCPP
26
+std::ostream &operator << (std::ostream &stream, const TEMSurveyData &ob) {
27
+    stream << ob.Serialize()  << "\n---\n"; // End of doc --- as a direct stream should encapulste thingy
28
+    return stream;
29
+}
30
+#else
31
+std::ostream &operator<<(std::ostream &stream, const TEMSurveyData& ob) {
32
+    stream << *(LemmaObject*)(&ob);
33
+    return stream;
34
+}
35
+#endif
36
+
37
+// =================== OPERATORS ===============================
38
+
39
+TEMSurveyData* TEMSurveyData::operator + (const TEMSurveyData& d) {
40
+    TEMSurveyData* clone = Clone();
41
+    *clone += d;
42
+    return clone;
43
+}
44
+
45
+void TEMSurveyData::operator += (const TEMSurveyData& rhs) {
46
+
47
+    if ( this->GetNumberOfLines() != rhs.GetNumberOfLines() ) {
48
+        throw std::runtime_error( "Line mismatch in TEMSurveyData +=" );
49
+    }
50
+
51
+    for (int iline=0; iline<this->GetNumberOfLines(); ++iline ) {
52
+        *(*this)(iline) += *rhs(iline);
53
+        //*LineData[iline] += *rhs(iline);
54
+        //*LineData[iline] += *rhs.GetLine(iline);
55
+    }
56
+}
57
+
58
+void TEMSurveyData::operator -= (const TEMSurveyData& rhs) {
59
+
60
+    if ( this->GetNumberOfLines() != rhs.GetNumberOfLines() ) {
61
+        throw std::runtime_error( "Line mismatch in TEMSurveyData +=" );
62
+    }
63
+
64
+    for (int iline=0; iline<this->GetNumberOfLines(); ++iline ) {
65
+        *(*this)(iline) -= *rhs(iline);
66
+        //*LineData[iline] -= *rhs(iline);
67
+        //*LineData[iline] -= *rhs.GetLine(iline);
68
+    }
69
+
70
+}
71
+
72
+TEMSurveyData* TEMSurveyData::operator - (const TEMSurveyData& d) {
73
+    TEMSurveyData* clone = Clone();
74
+    *clone -= d;
75
+    return clone;
76
+}
77
+
78
+TEMSurveyLineData* TEMSurveyData::operator( ) ( const int& idx ) const {
79
+    return LineData[ idx ];
80
+}
81
+
82
+TEMSurveyLineRecordData* TEMSurveyData::operator( ) ( const int& iline, const int& irec ) const {
83
+    return LineData[ iline ]->GetRecord( irec );
84
+}
85
+
86
+// ====================  LIFECYCLE     =======================
87
+
88
+//--------------------------------------------------------------------------------------
89
+//       Class:  TEMSurveyData
90
+//      Method:  TEMSurveyData
91
+// Description:  constructor (protected)
92
+//--------------------------------------------------------------------------------------
93
+TEMSurveyData::TEMSurveyData (const std::string& name) : LemmaObject(name) {
94
+
95
+}  // -----  end of method TEMSurveyData::TEMSurveyData  (constructor)  -----
96
+
97
+#ifdef HAVE_YAMLCPP
98
+//--------------------------------------------------------------------------------------
99
+//       Class:  TEMSurveyData
100
+//      Method:  TEMSurveyData
101
+// Description:  DeSerializing constructor (protected)
102
+//--------------------------------------------------------------------------------------
103
+TEMSurveyData::TEMSurveyData (const YAML::Node& node) : LemmaObject(node) {
104
+
105
+    //SetNumberOfLines( node["numberOfLines"].as<int>( ) );
106
+
107
+    for (int ii=0; ii< node["numberOfLines"].as<int>( ); ++ii) {
108
+        //LineData.push_back( new TEMSurveyLineData("TEMSurveyLineData") );
109
+        LineData.push_back( TEMSurveyLineData::DeSerialize( node[ std::string("line_")  + to_string(ii)] ) );
110
+        LineData[ii]->AttachTo(this);
111
+    }
112
+
113
+
114
+}  // -----  end of method TEMSurveyData::TEMSurveyData  (constructor)  -----
115
+#endif
116
+
117
+//--------------------------------------------------------------------------------------
118
+//       Class:  TEMSurveyData
119
+//      Method:  New()
120
+// Description:  public constructor
121
+//--------------------------------------------------------------------------------------
122
+TEMSurveyData* TEMSurveyData::New() {
123
+    TEMSurveyData*  Obj = new TEMSurveyData("TEMSurveyData");
124
+    Obj->AttachTo(Obj);
125
+    return Obj;
126
+}
127
+
128
+
129
+//--------------------------------------------------------------------------------------
130
+//       Class:  TEMSurveyData
131
+//      Method:  Clone
132
+//--------------------------------------------------------------------------------------
133
+TEMSurveyData* TEMSurveyData::Clone (  ) {
134
+    return TEMSurveyData::DeSerialize( this->Serialize() ) ;
135
+}		// -----  end of method TEMSurveyData::Clone  -----
136
+
137
+//--------------------------------------------------------------------------------------
138
+//       Class:  TEMSurveyData
139
+//      Method:  ~TEMSurveyData
140
+// Description:  destructor (protected)
141
+//--------------------------------------------------------------------------------------
142
+TEMSurveyData::~TEMSurveyData () {
143
+
144
+}  // -----  end of method TEMSurveyData::~TEMSurveyData  (destructor)  -----
145
+
146
+//--------------------------------------------------------------------------------------
147
+//       Class:  TEMSurveyData
148
+//      Method:  Delete
149
+// Description:  public destructor
150
+//--------------------------------------------------------------------------------------
151
+void TEMSurveyData::Delete() {
152
+    this->DetachFrom(this);
153
+}
154
+
155
+//--------------------------------------------------------------------------------------
156
+//       Class:  TEMSurveyData
157
+//      Method:  Release
158
+// Description:  destructor (protected)
159
+//--------------------------------------------------------------------------------------
160
+void TEMSurveyData::Release() {
161
+
162
+    // clean up any old lines
163
+    for (std::vector<TEMSurveyLineData*>::iterator it = LineData.begin() ; it != LineData.end(); ++it) {
164
+        (*it)->DetachFrom(this);
165
+        (*it)->Delete();
166
+    }
167
+
168
+    delete this;
169
+}
170
+
171
+//--------------------------------------------------------------------------------------
172
+//       Class:  TEMSurveyData
173
+//      Method:  SetNumberOfLines
174
+//--------------------------------------------------------------------------------------
175
+void TEMSurveyData::SetNumberOfLines ( const int& nlines ) {
176
+
177
+        // clean up any old lines
178
+        for (std::vector<TEMSurveyLineData*>::iterator it = LineData.begin() ; it != LineData.end(); ++it) {
179
+            (*it)->DetachFrom(this);
180
+        }
181
+        LineData.clear();
182
+
183
+        // Allocate these lines
184
+        LineData.reserve(nlines);
185
+        for (int il=0; il<nlines; ++il) {
186
+            LineData.push_back( TEMSurveyLineData::New() );
187
+            LineData[il]->AttachTo(this);
188
+        }
189
+
190
+    return ;
191
+}		// -----  end of method TEMSurveyData::SetNumberOfLines  -----
192
+
193
+
194
+//--------------------------------------------------------------------------------------
195
+//       Class:  TEMSurveyData
196
+//      Method:  GetLine
197
+//--------------------------------------------------------------------------------------
198
+TEMSurveyLineData* TEMSurveyData::GetLine ( const int& iline) const {
199
+    return LineData[iline] ;
200
+}		// -----  end of method TEMSurveyData::GetLine  -----
201
+
202
+
203
+//--------------------------------------------------------------------------------------
204
+//       Class:  TEMSurveyData
205
+//      Method:  GetNumberOfLines
206
+//--------------------------------------------------------------------------------------
207
+int TEMSurveyData::GetNumberOfLines (  ) const {
208
+    return  LineData.size() ;
209
+}		// -----  end of method TEMSurveyData::GetNumberOfLines  -----
210
+
211
+
212
+
213
+#ifdef HAVE_YAMLCPP
214
+//--------------------------------------------------------------------------------------
215
+//       Class:  TEMSurveyData
216
+//      Method:  Serialize
217
+//--------------------------------------------------------------------------------------
218
+YAML::Node  TEMSurveyData::Serialize (  ) const {
219
+    YAML::Node node = LemmaObject::Serialize();;
220
+    node.SetTag( this->Name );
221
+    node["numberOfLines"] = LineData.size();
222
+
223
+    for (unsigned int it = 0; it<LineData.size();  ++it) {
224
+        node[std::string("line_") +  to_string(it)] = LineData[it]->Serialize();
225
+    }
226
+
227
+    return node;
228
+}		// -----  end of method TEMSurveyData::Serialize  -----
229
+
230
+
231
+//--------------------------------------------------------------------------------------
232
+//       Class:  TEMSurveyData
233
+//      Method:  DeSerialize
234
+//--------------------------------------------------------------------------------------
235
+TEMSurveyData* TEMSurveyData::DeSerialize ( const YAML::Node& node  ) {
236
+    TEMSurveyData* Object = new TEMSurveyData(node);
237
+    Object->AttachTo(Object);
238
+    DESERIALIZECHECK( node, Object )
239
+    return Object ;
240
+}		// -----  end of method TEMSurveyData::DeSerialize  -----
241
+#endif
242
+
243
+}		// -----  end of Lemma  name  -----
244
+

+ 162
- 0
Modules/TEM1D/src/TEMSurveyLine.cpp View File

@@ -0,0 +1,162 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      10/10/2014 11:19:38 AM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#include "TEMSurveyLine.h"
21
+
22
+namespace Lemma {
23
+
24
+    // ====================  FRIEND METHODS  =====================
25
+#ifdef HAVE_YAMLCPP
26
+    std::ostream &operator << (std::ostream &stream, const TEMSurveyLine &ob) {
27
+        stream << ob.Serialize()  << "\n---\n"; // End of doc --- as a direct stream should encapulste thingy
28
+        return stream;
29
+    }
30
+#else
31
+    std::ostream &operator<<(std::ostream &stream, const TEMSurveyLine& ob) {
32
+        stream << *(LemmaObject*)(&ob);
33
+        return stream;
34
+    }
35
+#endif
36
+
37
+    // ====================  LIFECYCLE     =======================
38
+
39
+    //--------------------------------------------------------------------------------------
40
+    //       Class:  TEMSurveyLine
41
+    //      Method:  TEMSurveyLine
42
+    // Description:  constructor (protected)
43
+    //--------------------------------------------------------------------------------------
44
+    TEMSurveyLine::TEMSurveyLine (const std::string& name) : LemmaObject(name) {
45
+
46
+    }  // -----  end of method TEMSurveyLine::TEMSurveyLine  (constructor)  -----
47
+
48
+#ifdef HAVE_YAMLCPP
49
+    //--------------------------------------------------------------------------------------
50
+    //       Class:  TEMSurveyLine
51
+    //      Method:  TEMSurveyLine
52
+    // Description:  DeSerializing constructor (protected)
53
+    //--------------------------------------------------------------------------------------
54
+    TEMSurveyLine::TEMSurveyLine (const YAML::Node& node) : LemmaObject(node) {
55
+
56
+    }  // -----  end of method TEMSurveyLine::TEMSurveyLine  (constructor)  -----
57
+#endif
58
+
59
+    //--------------------------------------------------------------------------------------
60
+    //       Class:  TEMSurveyLine
61
+    //      Method:  ~TEMSurveyLine
62
+    // Description:  destructor (protected)
63
+    //--------------------------------------------------------------------------------------
64
+    TEMSurveyLine::~TEMSurveyLine () {
65
+
66
+    }  // -----  end of method TEMSurveyLine::~TEMSurveyLine  (destructor)  -----
67
+
68
+    //--------------------------------------------------------------------------------------
69
+    //       Class:  TEMSurveyLine
70
+    //      Method:  Delete
71
+    // Description:  public destructor
72
+    //--------------------------------------------------------------------------------------
73
+    void TEMSurveyLine::Delete() {
74
+        // THIS is a private member, this class must be used through a TEMSurvey
75
+        this->DetachFrom(this);
76
+    }
77
+
78
+    //--------------------------------------------------------------------------------------
79
+    //       Class:  TEMSurveyLine
80
+    //      Method:  Release
81
+    // Description:  destructor (protected)
82
+    //--------------------------------------------------------------------------------------
83
+    void TEMSurveyLine::Release() {
84
+        for (std::vector<TEMSurveyLineRecord*>::iterator it = Records.begin() ; it != Records.end(); ++it) {
85
+            (*it)->DetachFrom(this);
86
+        }
87
+        delete this;
88
+    }
89
+
90
+
91
+#ifdef HAVE_YAMLCPP
92
+    //--------------------------------------------------------------------------------------
93
+    //       Class:  TEMSurveyLine
94
+    //      Method:  Serialize
95
+    //--------------------------------------------------------------------------------------
96
+    YAML::Node  TEMSurveyLine::Serialize (  ) const {
97
+        YAML::Node node;
98
+        node.SetTag( this->Name );
99
+        node["numberOfRecords"] = Records.size();
100
+        for (unsigned int it = 0; it< Records.size();  ++it) {
101
+            node[std::string("record_") +  to_string(it)] = Records[it]->Serialize();
102
+        }
103
+        return node;
104
+    }		// -----  end of method TEMSurveyLine::Serialize  -----
105
+
106
+
107
+    //--------------------------------------------------------------------------------------
108
+    //       Class:  TEMSurveyLine
109
+    //      Method:  DeSerialize
110
+    //--------------------------------------------------------------------------------------
111
+    TEMSurveyLine* TEMSurveyLine::DeSerialize ( const YAML::Node& node  ) {
112
+        TEMSurveyLine* Object = new TEMSurveyLine(node);
113
+        Object->AttachTo(Object);
114
+        DESERIALIZECHECK( node, Object )
115
+            return Object ;
116
+    }		// -----  end of method TEMSurveyLine::DeSerialize  -----
117
+#endif
118
+
119
+    TEMSurveyLineRecord* TEMSurveyLine::GetRecord( const unsigned int& irec )  {
120
+        return Records[irec];
121
+    }
122
+
123
+
124
+    //--------------------------------------------------------------------------------------
125
+    //       Class:  TEMSurveyLine
126
+    //      Method:  SetNumberOfRecords
127
+    //--------------------------------------------------------------------------------------
128
+    void TEMSurveyLine::SetNumberOfRecords ( const int& nrec  ) {
129
+
130
+        // clean up any old records
131
+        for (std::vector<TEMSurveyLineRecord*>::iterator it = Records.begin() ; it != Records.end(); ++it) {
132
+            (*it)->DetachFrom(this);
133
+        }
134
+        Records.clear();
135
+
136
+        // Allocate these lines
137
+        Records.reserve(nrec);
138
+        for (int ir=0; ir<nrec; ++ir) {
139
+            Records.push_back( new TEMSurveyLineRecord("TEMSurveyLineRecord") );
140
+            Records[ir]->AttachTo(this);
141
+        }
142
+
143
+        return ;
144
+    }		// -----  end of method TEMSurveyLine::SetNumberOfRecords  -----
145
+
146
+
147
+    //--------------------------------------------------------------------------------------
148
+    //       Class:  TEMSurveyLine
149
+    //      Method:  ForwardModel
150
+    //--------------------------------------------------------------------------------------
151
+    TEMSurveyLineData* TEMSurveyLine::ForwardModel ( LayeredEarthEM* Model, bool additiveNoise ) {
152
+        TEMSurveyLineData* Data = TEMSurveyLineData::New();
153
+        for (std::vector<TEMSurveyLineRecord*>::iterator it = Records.begin() ; it != Records.end(); ++it) {
154
+            TEMSurveyLineRecordData* RecData = (*it)->ForwardModel(Model, additiveNoise) ;
155
+            RecData->AttachTo(Data);
156
+            Data->RecordData.push_back( RecData );
157
+        }
158
+        return Data;
159
+    }		// -----  end of method TEMSurveyLine::ForwardModel  -----
160
+
161
+
162
+}		// -----  end of Lemma  name  -----

+ 230
- 0
Modules/TEM1D/src/TEMSurveyLineData.cpp View File

@@ -0,0 +1,230 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      03/03/2015 10:23:22
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2015, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2015, Trevor Irons
18
+ */
19
+
20
+#include "TEMSurveyLineData.h"
21
+
22
+namespace Lemma {
23
+
24
+    // ====================  FRIEND METHODS  =====================
25
+#ifdef HAVE_YAMLCPP
26
+    std::ostream &operator << (std::ostream &stream, const TEMSurveyLineData &ob) {
27
+        stream << ob.Serialize()  << "\n---\n"; // End of doc --- as a direct stream should encapulste thingy
28
+        return stream;
29
+    }
30
+#else
31
+    std::ostream &operator<<(std::ostream &stream, const TEMSurveyLineData& ob) {
32
+        stream << *(LemmaObject*)(&ob);
33
+        return stream;
34
+    }
35
+#endif
36
+
37
+    // ====================  LIFECYCLE     =======================
38
+
39
+    //--------------------------------------------------------------------------------------
40
+    //       Class:  TEMSurveyLineData
41
+    //      Method:  TEMSurveyLineData
42
+    // Description:  constructor (protected)
43
+    //--------------------------------------------------------------------------------------
44
+    TEMSurveyLineData::TEMSurveyLineData (const std::string& name) : LemmaObject(name) {
45
+
46
+    }  // -----  end of method TEMSurveyLineData::TEMSurveyLineData  (constructor)  -----
47
+
48
+#ifdef HAVE_YAMLCPP
49
+    //--------------------------------------------------------------------------------------
50
+    //       Class:  TEMSurveyLineData
51
+    //      Method:  TEMSurveyLineData
52
+    // Description:  DeSerializing constructor (protected)
53
+    //--------------------------------------------------------------------------------------
54
+    TEMSurveyLineData::TEMSurveyLineData (const YAML::Node& node) : LemmaObject(node) {
55
+        for (int ii=0; ii< node["numberOfRecords"].as<int>( ); ++ii) {
56
+            RecordData.push_back( TEMSurveyLineRecordData::DeSerialize( node[ std::string("record_")  + to_string(ii)] ) );
57
+            RecordData[ii]->AttachTo(this);
58
+        }
59
+    }  // -----  end of method TEMSurveyLineData::TEMSurveyLineData  (constructor)  -----
60
+#endif
61
+
62
+    //--------------------------------------------------------------------------------------
63
+    //       Class:  TEMSurveyLineData
64
+    //      Method:  New()
65
+    // Description:  public constructor
66
+    //--------------------------------------------------------------------------------------
67
+    TEMSurveyLineData* TEMSurveyLineData::New() {
68
+        TEMSurveyLineData*  Obj = new TEMSurveyLineData("TEMSurveyLineData");
69
+        Obj->AttachTo(Obj);
70
+        return Obj;
71
+    }
72
+
73
+    //--------------------------------------------------------------------------------------
74
+    //       Class:  TEMSurveyLineRecordData
75
+    //      Method:  Clone
76
+    //--------------------------------------------------------------------------------------
77
+    TEMSurveyLineData* TEMSurveyLineData::Clone (  ) {
78
+        return TEMSurveyLineData::DeSerialize( this->Serialize() )  ;
79
+    }		// -----  end of method TEMSurveyLineRecordData::Clone  -----
80
+
81
+    //--------------------------------------------------------------------------------------
82
+    //       Class:  TEMSurveyLineData
83
+    //      Method:  ~TEMSurveyLineData
84
+    // Description:  destructor (protected)
85
+    //--------------------------------------------------------------------------------------
86
+    TEMSurveyLineData::~TEMSurveyLineData () {
87
+
88
+    }  // -----  end of method TEMSurveyLineData::~TEMSurveyLineData  (destructor)  -----
89
+
90
+    //--------------------------------------------------------------------------------------
91
+    //       Class:  TEMSurveyLineData
92
+    //      Method:  Delete
93
+    // Description:  public destructor
94
+    //--------------------------------------------------------------------------------------
95
+    void TEMSurveyLineData::Delete() {
96
+        this->DetachFrom(this);
97
+    }
98
+
99
+    //--------------------------------------------------------------------------------------
100
+    //       Class:  TEMSurveyLineData
101
+    //      Method:  Release
102
+    // Description:  destructor (protected)
103
+    //--------------------------------------------------------------------------------------
104
+    void TEMSurveyLineData::Release() {
105
+        for (std::vector<TEMSurveyLineRecordData*>::iterator it = RecordData.begin() ; it != RecordData.end(); ++it) {
106
+            (*it)->DetachFrom(this);
107
+            (*it)->Delete();
108
+        }
109
+        delete this;
110
+    }
111
+
112
+    // =================== OPERATORS ===============================
113
+
114
+    TEMSurveyLineRecordData* TEMSurveyLineData::operator( ) ( const int& idx ) const {
115
+        return RecordData[ idx ];
116
+    }
117
+
118
+
119
+    //--------------------------------------------------------------------------------------
120
+    //       Class:  TEMSurveyLineData
121
+    //      Method:  operator +=
122
+    //--------------------------------------------------------------------------------------
123
+    void TEMSurveyLineData::operator += ( const TEMSurveyLineData& rhs) {
124
+
125
+        if ( this->GetNumberOfRecords() != rhs.GetNumberOfRecords() ) {
126
+            throw std::runtime_error( "Record mismatch in TEMSurveyLineData +=" );
127
+        }
128
+
129
+        for (int irec=0; irec<this->GetNumberOfRecords(); ++irec ) {
130
+            *(*this)(irec) += *rhs(irec);
131
+            //*LineData[irec] += *rhs(irec);
132
+            //*LineData[irec] += *rhs.GetLine(irec);
133
+        }
134
+
135
+        return ;
136
+    }		// -----  end of method TEMSurveyLineData::+=  -----
137
+
138
+
139
+    //--------------------------------------------------------------------------------------
140
+    //       Class:  TEMSurveyLineData
141
+    //      Method:  operator +
142
+    //--------------------------------------------------------------------------------------
143
+    TEMSurveyLineData* TEMSurveyLineData::operator + ( const TEMSurveyLineData& rhs) {
144
+        TEMSurveyLineData* clone = Clone();
145
+        *clone += rhs;
146
+        return clone;
147
+    }		// -----  end of method TEMSurveyLineData::operator +  -----
148
+
149
+
150
+    //--------------------------------------------------------------------------------------
151
+    //       Class:  TEMSurveyLineData
152
+    //      Method:  operator -=
153
+    //--------------------------------------------------------------------------------------
154
+    void TEMSurveyLineData::operator -= ( const TEMSurveyLineData& rhs ) {
155
+
156
+        if ( this->GetNumberOfRecords() != rhs.GetNumberOfRecords() ) {
157
+            throw std::runtime_error( "Record mismatch in TEMSurveyLineData +=" );
158
+        }
159
+
160
+        for (int irec=0; irec<this->GetNumberOfRecords(); ++irec ) {
161
+            *(*this)(irec) -= *rhs(irec);
162
+            //*LineData[irec] -= *rhs(irec);
163
+            //*LineData[irec] -= *rhs.GetLine(irec);
164
+        }
165
+        return ;
166
+    }		// -----  end of method TEMSurveyLineData::operator -=  -----
167
+
168
+
169
+    //--------------------------------------------------------------------------------------
170
+    //       Class:  TEMSurveyLineData
171
+    //      Method:  operator -
172
+    //--------------------------------------------------------------------------------------
173
+    TEMSurveyLineData* TEMSurveyLineData::operator - ( const TEMSurveyLineData& rhs) {
174
+        TEMSurveyLineData* clone = Clone();
175
+        *clone -= rhs;
176
+        return clone;
177
+    }		// -----  end of method TEMSurveyLineData::operator -  -----
178
+
179
+
180
+    // ====================  ACCESS        =======================
181
+
182
+    //--------------------------------------------------------------------------------------
183
+    //       Class:  TEMSurveyLineData
184
+    //      Method:  GetRecord
185
+    //--------------------------------------------------------------------------------------
186
+    TEMSurveyLineRecordData*    TEMSurveyLineData::GetRecord(const int& ir) const {
187
+        return RecordData[ir];
188
+    }		// -----  end of method TEMSurveyLineData::GetRecord  -----
189
+
190
+
191
+    //--------------------------------------------------------------------------------------
192
+    //       Class:  TEMSurveyLineRecordData
193
+    //      Method:  GetNumberOfRecords
194
+    //--------------------------------------------------------------------------------------
195
+    int TEMSurveyLineData::GetNumberOfRecords (  ) const {
196
+        return RecordData.size();
197
+    }		// -----  end of method TEMSurveyLineRecordData::GetNumberOfRecords  -----
198
+
199
+
200
+#ifdef HAVE_YAMLCPP
201
+    //--------------------------------------------------------------------------------------
202
+    //       Class:  TEMSurveyLineData
203
+    //      Method:  Serialize
204
+    //--------------------------------------------------------------------------------------
205
+    YAML::Node  TEMSurveyLineData::Serialize (  ) const {
206
+        YAML::Node node = LemmaObject::Serialize();;
207
+        node.SetTag( this->Name );
208
+        node["numberOfRecords"] = RecordData.size();
209
+        // FILL IN CLASS SPECIFICS HERE
210
+        for (unsigned int it = 0; it< RecordData.size();  ++it) {
211
+            node[std::string("record_") +  to_string(it)] = RecordData[it]->Serialize();
212
+        }
213
+        return node;
214
+    }		// -----  end of method TEMSurveyLineData::Serialize  -----
215
+
216
+
217
+    //--------------------------------------------------------------------------------------
218
+    //       Class:  TEMSurveyLineData
219
+    //      Method:  DeSerialize
220
+    //--------------------------------------------------------------------------------------
221
+    TEMSurveyLineData* TEMSurveyLineData::DeSerialize ( const YAML::Node& node  ) {
222
+        TEMSurveyLineData* Object = new TEMSurveyLineData(node);
223
+        Object->AttachTo(Object);
224
+        DESERIALIZECHECK( node, Object )
225
+            return Object ;
226
+    }		// -----  end of method TEMSurveyLineData::DeSerialize  -----
227
+#endif
228
+
229
+}		// -----  end of Lemma  name  -----
230
+

+ 254
- 0
Modules/TEM1D/src/TEMSurveyLineRecord.cpp View File

@@ -0,0 +1,254 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      10/10/2014 12:23:07 PM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#include "TEMSurveyLineRecord.h"
21
+
22
+namespace Lemma {
23
+
24
+
25
+    // ====================  FRIEND METHODS  =====================
26
+#ifdef HAVE_YAMLCPP
27
+    std::ostream &operator << (std::ostream &stream, const TEMSurveyLineRecord &ob) {
28
+        stream << ob.Serialize()  << "\n---\n"; // End of doc --- as a direct stream should encapulste thingy
29
+        return stream;
30
+    }
31
+#else
32
+    std::ostream &operator<<(std::ostream &stream, const TEMSurveyLineRecord& ob) {
33
+        stream << *(LemmaObject*)(&ob);
34
+        return stream;
35
+    }
36
+#endif
37
+
38
+    // ====================  LIFECYCLE     =======================
39
+
40
+    //--------------------------------------------------------------------------------------
41
+    //       Class:  TEMSurveyLineRecord
42
+    //      Method:  TEMSurveyLineRecord
43
+    // Description:  constructor (protected)
44
+    //--------------------------------------------------------------------------------------
45
+    TEMSurveyLineRecord::TEMSurveyLineRecord (const std::string& name) : LemmaObject(name),
46
+        numberOfPulseSequences(0)
47
+    {
48
+
49
+    }  // -----  end of method TEMSurveyLineRecord::TEMSurveyLineRecord  (constructor)  -----
50
+
51
+#ifdef HAVE_YAMLCPP
52
+    //--------------------------------------------------------------------------------------
53
+    //       Class:  TEMSurveyLineRecord
54
+    //      Method:  TEMSurveyLineRecord
55
+    // Description:  DeSerializing constructor (protected)
56
+    //--------------------------------------------------------------------------------------
57
+    TEMSurveyLineRecord::TEMSurveyLineRecord (const YAML::Node& node) : LemmaObject(node),
58
+        numberOfPulseSequences(0)
59
+    {
60
+
61
+    }  // -----  end of method TEMSurveyLineRecord::TEMSurveyLineRecord  (constructor)  -----
62
+#endif
63
+
64
+    //--------------------------------------------------------------------------------------
65
+    //       Class:  TEMSurveyLineRecord
66
+    //      Method:  ~TEMSurveyLineRecord
67
+    // Description:  destructor (protected)
68
+    //--------------------------------------------------------------------------------------
69
+    TEMSurveyLineRecord::~TEMSurveyLineRecord () {
70
+
71
+        for (unsigned int ip=0; ip<Transmitters.size(); ++ip) {
72
+            if (Transmitters[ip] != NULL) {
73
+                Transmitters[ip]->DetachFrom(this);
74
+            }
75
+        }
76
+        for (unsigned int ir=0; ir<Receivers.size(); ++ir) {
77
+            if (Receivers[ir] != NULL) {
78
+                Receivers[ir]->DetachFrom(this);
79
+            }
80
+        }
81
+
82
+    }  // -----  end of method TEMSurveyLineRecord::~TEMSurveyLineRecord  (destructor)  -----
83
+
84
+    //--------------------------------------------------------------------------------------
85
+    //       Class:  TEMSurveyLineRecord
86
+    //      Method:  Delete
87
+    // Description:  public destructor
88
+    //--------------------------------------------------------------------------------------
89
+    void TEMSurveyLineRecord::Delete() {
90
+        this->DetachFrom(this);
91
+    }
92
+
93
+    //--------------------------------------------------------------------------------------
94
+    //       Class:  TEMSurveyLineRecord
95
+    //      Method:  Release
96
+    // Description:  destructor (protected)
97
+    //--------------------------------------------------------------------------------------
98
+    void TEMSurveyLineRecord::Release() {
99
+        delete this;
100
+    }
101
+
102
+
103
+    //--------------------------------------------------------------------------------------
104
+    //       Class:  TEMSurveyLineRecord
105
+    //      Method:  SetPulseSequenceReceiverPair
106
+    //--------------------------------------------------------------------------------------
107
+    void TEMSurveyLineRecord::SetTransmitterReceiverPair ( const int& ii, TEMTransmitter* Tx, TEMReceiver* Rx  ) {
108
+        Receivers[ii] = Rx;
109
+        Rx->AttachTo(this);
110
+
111
+        Transmitters[ii] = Tx;
112
+        Tx->AttachTo(this);
113
+        return ;
114
+    }		// -----  end of method TEMSurveyLineRecord::SetPulseSequenceReceiverPair  -----
115
+
116
+
117
+    //--------------------------------------------------------------------------------------
118
+    //       Class:  TEMSurveyLineRecord
119
+    //      Method:  GetReceiver
120
+    //--------------------------------------------------------------------------------------
121
+    TEMReceiver* TEMSurveyLineRecord::GetReceiver ( const int& irec  ) {
122
+        if ( irec >= (int)(Receivers.size()) ) {
123
+            throw std::runtime_error( "TEMSurveyLineRecord::GetReceiver(const int& irec)--array bounds error" );
124
+        }
125
+        return Receivers[irec] ;
126
+    }		// -----  end of method TEMSurveyLineRecord::GetReceiver  -----
127
+
128
+
129
+#ifdef HAVE_YAMLCPP
130
+    //--------------------------------------------------------------------------------------
131
+    //       Class:  TEMSurveyLineRecord
132
+    //      Method:  Serialize
133
+    //--------------------------------------------------------------------------------------
134
+    YAML::Node  TEMSurveyLineRecord::Serialize (  ) const {
135
+        YAML::Node node;
136
+        node.SetTag( this->Name );
137
+        node["numberOfPulseSequences"] = numberOfPulseSequences;
138
+
139
+        // FILL IN CLASS SPECIFICS HERE
140
+
141
+        for( int is=0; is<numberOfPulseSequences; ++is) {
142
+            node[std::string("pulse_") + to_string(is)]    = Transmitters[is]->Serialize();
143
+            node[std::string("receiver_") + to_string(is)] = Receivers[is]->Serialize();
144
+        }
145
+
146
+
147
+        return node;
148
+    }		// -----  end of method TEMSurveyLineRecord::Serialize  -----
149
+
150
+
151
+    //--------------------------------------------------------------------------------------
152
+    //       Class:  TEMSurveyLineRecord
153
+    //      Method:  DeSerialize
154
+    //--------------------------------------------------------------------------------------
155
+    TEMSurveyLineRecord* TEMSurveyLineRecord::DeSerialize ( const YAML::Node& node  ) {
156
+        TEMSurveyLineRecord* Object = new TEMSurveyLineRecord(node);
157
+        Object->AttachTo(Object);
158
+        DESERIALIZECHECK( node, Object )
159
+            return Object ;
160
+    }		// -----  end of method TEMSurveyLineRecord::DeSerialize  -----
161
+#endif
162
+
163
+
164
+    //--------------------------------------------------------------------------------------
165
+    //       Class:  TEMSurveyLineRecord
166
+    //      Method:  SetNumberOfPulseSequences
167
+    //--------------------------------------------------------------------------------------
168
+    void TEMSurveyLineRecord::SetNumberOfPulseSequences ( const int& nseq ) {
169
+
170
+        for (unsigned int ip=0; ip<Transmitters.size(); ++ip) {
171
+            Transmitters[ip]->DetachFrom(this);
172
+        }
173
+        for (unsigned int ir=0; ir<Receivers.size(); ++ir) {
174
+            Receivers[ir]->DetachFrom(this);
175
+        }
176
+        Transmitters.clear();
177
+        Receivers.clear();
178
+
179
+        numberOfPulseSequences = nseq;
180
+
181
+        Receivers.reserve(nseq);
182
+        Transmitters.reserve(nseq);
183
+        for (int ir=0; ir<nseq; ++ir) {
184
+            Transmitters.push_back( NULL );
185
+            Receivers.push_back( NULL );
186
+        }
187
+
188
+        return ;
189
+    }		// -----  end of method TEMSurveyLineRecord::SetNumberOfPulseSequences  -----
190
+
191
+
192
+    //--------------------------------------------------------------------------------------
193
+    //       Class:  TEMSurveyLineRecord
194
+    //      Method:  GetNumberOfPulseSequences
195
+    //--------------------------------------------------------------------------------------
196
+    int TEMSurveyLineRecord::GetNumberOfPulseSequences (  ) {
197
+        return numberOfPulseSequences ;
198
+    }		// -----  end of method TEMSurveyLineRecord::GetNumberOfPulseSequences  -----
199
+
200
+
201
+    //--------------------------------------------------------------------------------------
202
+    //       Class:  TEMSurveyLineRecord
203
+    //      Method:  ForwardModel
204
+    //--------------------------------------------------------------------------------------
205
+    TEMSurveyLineRecordData* TEMSurveyLineRecord::ForwardModel ( LayeredEarthEM* model, bool additiveNoise ) {
206
+
207
+        TEMSurveyLineRecordData* Data = TEMSurveyLineRecordData::New();
208
+
209
+        // DO I want to work with InstrumentTem here? Or just roll it myself at this point?
210
+        for (unsigned int ip=0; ip<Transmitters.size(); ++ip) {
211
+
212
+            InstrumentTem *instrument = InstrumentTem::New();
213
+
214
+            // For thread safety...
215
+            TEMTransmitter*  TC =  Transmitters[ip]->Clone();
216
+            TEMReceiver* RC = Receivers[ip]->Clone();
217
+
218
+            // TODO some of this needs to be moved logic checked or use overriden functions, etc.
219
+            instrument->EMEarthModel(model);
220
+	        instrument->SetTransmitLoop( TC );
221
+            instrument->SetReferenceTime( RC->GetReferenceTime() );
222
+	        instrument->SetTimeGates( RC->GetWindowCentres(), RC->GetWindowWidths() );
223
+	        instrument->SetReceiver( RC );   // Clone??
224
+            instrument->SetReceiverType(INDUCTIVE);
225
+            instrument->SetPulse( TC->GetWfmAmps(), TC->GetWfmTimes() );
226
+
227
+            // TODO pass this
228
+            //instrument->MakeLaggedCalculation( FHTKEY51 );
229
+            instrument->MakeLaggedCalculation( ANDERSON801 );
230
+
231
+            Data->DataSeries.push_back( MU0*instrument->GetMeasurements().col(1) );
232
+            Data->GateCentres.push_back( RC->GetWindowCentres() );
233
+
234
+            if (additiveNoise) {
235
+                Data->DataSeries.back() += RC->SampleNoise();
236
+            }
237
+
238
+//                 int nlag = instrument->GetMeasurements().rows();
239
+//                 std::cout.precision(12);
240
+//                 std::cout << "// time [s]  dB/dt [T/s] \n";
241
+//                 for (int ii=0; ii<nlag; ii++) {
242
+//  		            std::cout<<"  "<<instrument->GetMeasurements()(ii,0)<<"  "<< MU0*instrument->GetMeasurements()(ii,1)<<std::endl;
243
+//  	            }
244
+
245
+            instrument->Delete();
246
+            TC->Delete();
247
+            RC->Delete();
248
+        }
249
+
250
+        return Data;
251
+    }		// -----  end of method TEMSurveyLineRecord::ForwardModel  -----
252
+
253
+
254
+}		// -----  end of Lemma  name  -----

+ 248
- 0
Modules/TEM1D/src/TEMSurveyLineRecordData.cpp View File

@@ -0,0 +1,248 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      03/03/2015 10:34:56
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2015, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2015, Trevor Irons
18
+ */
19
+
20
+#include "TEMSurveyLineRecordData.h"
21
+
22
+namespace Lemma {
23
+
24
+
25
+    // ====================  FRIEND METHODS  =====================
26
+#ifdef HAVE_YAMLCPP
27
+    std::ostream &operator << (std::ostream &stream, const TEMSurveyLineRecordData &ob) {
28
+        stream << ob.Serialize()  << "\n---\n"; // End of doc --- as a direct stream should encapulste thingy
29
+        return stream;
30
+    }
31
+#else
32
+    std::ostream &operator<<(std::ostream &stream, const TEMSurveyLineRecordData& ob) {
33
+        stream << *(LemmaObject*)(&ob);
34
+        return stream;
35
+    }
36
+#endif
37
+
38
+    // ====================  LIFECYCLE     =======================
39
+
40
+    //--------------------------------------------------------------------------------------
41
+    //       Class:  TEMSurveyLineRecordData
42
+    //      Method:  TEMSurveyLineRecordData
43
+    // Description:  constructor (protected)
44
+    //--------------------------------------------------------------------------------------
45
+    TEMSurveyLineRecordData::TEMSurveyLineRecordData (const std::string& name) : LemmaObject(name) {
46
+
47
+    }  // -----  end of method TEMSurveyLineRecordData::TEMSurveyLineRecordData  (constructor)  -----
48
+
49
+#ifdef HAVE_YAMLCPP
50
+    //--------------------------------------------------------------------------------------
51
+    //       Class:  TEMSurveyLineRecordData
52
+    //      Method:  TEMSurveyLineRecordData
53
+    // Description:  DeSerializing constructor (protected)
54
+    //--------------------------------------------------------------------------------------
55
+    TEMSurveyLineRecordData::TEMSurveyLineRecordData (const YAML::Node& node) : LemmaObject(node) {
56
+        for (int ii=0; ii< node["numberOfSeries"].as<int>( ); ++ii) {
57
+            DataSeries.push_back( node["DataSeries_" + to_string(ii)].as<VectorXr>() );
58
+            GateCentres.push_back( node["GateCentres_" + to_string(ii)].as<VectorXr>() );
59
+        }
60
+    }  // -----  end of method TEMSurveyLineRecordData::TEMSurveyLineRecordData  (constructor)  -----
61
+#endif
62
+
63
+    //--------------------------------------------------------------------------------------
64
+    //       Class:  TEMSurveyLineRecordData
65
+    //      Method:  New()
66
+    // Description:  public constructor
67
+    //--------------------------------------------------------------------------------------
68
+    TEMSurveyLineRecordData* TEMSurveyLineRecordData::New() {
69
+        TEMSurveyLineRecordData*  Obj = new TEMSurveyLineRecordData("TEMSurveyLineRecordData");
70
+        Obj->AttachTo(Obj);
71
+        return Obj;
72
+    }
73
+
74
+
75
+    //--------------------------------------------------------------------------------------
76
+    //       Class:  TEMSurveyLineRecordData
77
+    //      Method:  Clone
78
+    //--------------------------------------------------------------------------------------
79
+    TEMSurveyLineRecordData* TEMSurveyLineRecordData::Clone (  ) {
80
+        return DeSerialize( this->Serialize() )  ;
81
+    }		// -----  end of method TEMSurveyLineRecordData::Clone  -----
82
+
83
+
84
+    //--------------------------------------------------------------------------------------
85
+    //       Class:  TEMSurveyLineRecordData
86
+    //      Method:  ~TEMSurveyLineRecordData
87
+    // Description:  destructor (protected)
88
+    //--------------------------------------------------------------------------------------
89
+    TEMSurveyLineRecordData::~TEMSurveyLineRecordData () {
90
+
91
+    }  // -----  end of method TEMSurveyLineRecordData::~TEMSurveyLineRecordData  (destructor)  -----
92
+
93
+    //--------------------------------------------------------------------------------------
94
+    //       Class:  TEMSurveyLineRecordData
95
+    //      Method:  Delete
96
+    // Description:  public destructor
97
+    //--------------------------------------------------------------------------------------
98
+    void TEMSurveyLineRecordData::Delete() {
99
+        this->DetachFrom(this);
100
+    }
101
+
102
+    //--------------------------------------------------------------------------------------
103
+    //       Class:  TEMSurveyLineRecordData
104
+    //      Method:  Release
105
+    // Description:  destructor (protected)
106
+    //--------------------------------------------------------------------------------------
107
+    void TEMSurveyLineRecordData::Release() {
108
+        delete this;
109
+    }
110
+
111
+        // ====================  OPERATORS     =======================
112
+
113
+    //--------------------------------------------------------------------------------------
114
+    //       Class:  TEMSurveyLineRecordData
115
+    //      Method:  operator +
116
+    //--------------------------------------------------------------------------------------
117
+    TEMSurveyLineRecordData* TEMSurveyLineRecordData::operator + ( const TEMSurveyLineRecordData& Survey ) {
118
+        TEMSurveyLineRecordData* clone = this->Clone();
119
+        for (unsigned int ir=0; ir<DataSeries.size(); ++ir) {
120
+            clone->DataSeries[ir] += Survey.DataSeries[ir];
121
+        }
122
+        return clone;
123
+    }		// -----  end of method TEMSurveyLineRecordData::operator +  -----
124
+
125
+    //--------------------------------------------------------------------------------------
126
+    //       Class:  TEMSurveyLineRecordData
127
+    //      Method:  operator -
128
+    //--------------------------------------------------------------------------------------
129
+    TEMSurveyLineRecordData* TEMSurveyLineRecordData::operator - ( const TEMSurveyLineRecordData& Survey ) {
130
+        TEMSurveyLineRecordData* clone = this->Clone();
131
+        for (unsigned int ir=0; ir<DataSeries.size(); ++ir) {
132
+            clone->DataSeries[ir] -= Survey.DataSeries[ir];
133
+        }
134
+        return clone;
135
+    }		// -----  end of method TEMSurveyLineRecordData::operator -  -----
136
+
137
+    //--------------------------------------------------------------------------------------
138
+    //       Class:  TEMSurveyLineRecordData
139
+    //      Method:  operator +=
140
+    //--------------------------------------------------------------------------------------
141
+    void TEMSurveyLineRecordData::operator += ( const TEMSurveyLineRecordData& Survey ) {
142
+
143
+        if (DataSeries.size() != Survey.DataSeries.size()) {
144
+            throw std::runtime_error("size mismatch in TEMSurveyLineRecordData::operator +=");
145
+        }
146
+
147
+        for (unsigned int ii=0; ii<DataSeries.size(); ++ii) {
148
+            this->DataSeries[ii] += Survey.DataSeries[ii];
149
+        }
150
+
151
+        return ;
152
+    }		// -----  end of method TEMSurveyLineRecordData::operator +=  -----
153
+
154
+
155
+    //--------------------------------------------------------------------------------------
156
+    //       Class:  TEMSurveyLineRecordData
157
+    //      Method:  operator -=
158
+    //--------------------------------------------------------------------------------------
159
+    void TEMSurveyLineRecordData::operator -= ( const TEMSurveyLineRecordData& Survey ) {
160
+
161
+        if (DataSeries.size() != Survey.DataSeries.size()) {
162
+            throw std::runtime_error("size mismatch in TEMSurveyLineRecordData::operator +=");
163
+        }
164
+
165
+        for (unsigned int ii=0; ii<DataSeries.size(); ++ii) {
166
+            this->DataSeries[ii] -= Survey.DataSeries[ii];
167
+        }
168
+
169
+        return ;
170
+    }		// -----  end of method TEMSurveyLineRecordData::operator -=  -----
171
+
172
+
173
+        // ====================  ACCESS        =======================
174
+
175
+    //--------------------------------------------------------------------------------------
176
+    //       Class:  TEMSurveyLineRecordData
177
+    //      Method:  GetCombinedData
178
+    //--------------------------------------------------------------------------------------
179
+    VectorXr TEMSurveyLineRecordData::GetCombinedData (  ) {
180
+
181
+        int nd = 0;
182
+        for (unsigned int id=0; id<DataSeries.size(); ++id) {
183
+            nd += DataSeries[id].size();
184
+        }
185
+        VectorXr combined = VectorXr(nd);
186
+
187
+        nd = 0;
188
+        for (unsigned int id=0; id<DataSeries.size(); ++id) {
189
+            combined.segment(nd, DataSeries[id].size()) = DataSeries[id];
190
+            nd += DataSeries[id].size();
191
+        }
192
+
193
+        return  combined;
194
+    }		// -----  end of method TEMSurveyLineRecordData::GetCombinedData  -----
195
+
196
+
197
+    //--------------------------------------------------------------------------------------
198
+    //       Class:  TEMSurveyLineRecordData
199
+    //      Method:  GetCombinedGateCentres
200
+    //--------------------------------------------------------------------------------------
201
+    VectorXr TEMSurveyLineRecordData::GetCombinedGateCentres (  ) {
202
+        int nd = 0;
203
+        for (unsigned int id=0; id<GateCentres.size(); ++id) {
204
+            nd += GateCentres[id].size();
205
+        }
206
+        VectorXr combined = VectorXr(nd);
207
+
208
+        nd = 0;
209
+        for (unsigned int id=0; id<GateCentres.size(); ++id) {
210
+            combined.segment(nd, GateCentres[id].size()) = GateCentres[id];
211
+            nd += GateCentres[id].size();
212
+        }
213
+
214
+        return  combined;
215
+    }		// -----  end of method TEMSurveyLineRecordData::GetCombinedGateCentres  -----
216
+
217
+
218
+#ifdef HAVE_YAMLCPP
219
+    //--------------------------------------------------------------------------------------
220
+    //       Class:  TEMSurveyLineRecordData
221
+    //      Method:  Serialize
222
+    //--------------------------------------------------------------------------------------
223
+    YAML::Node  TEMSurveyLineRecordData::Serialize (  ) const {
224
+        YAML::Node node = LemmaObject::Serialize();;
225
+        node.SetTag( this->Name );
226
+        node["numberOfSeries"] = DataSeries.size();
227
+        for (unsigned int is=0; is<DataSeries.size(); ++is) {
228
+            node[std::string("DataSeries_") + to_string(is)] = DataSeries[is];
229
+            node[std::string("GateCentres_") + to_string(is)] = GateCentres[is];
230
+        }
231
+        return node;
232
+    }		// -----  end of method TEMSurveyLineRecordData::Serialize  -----
233
+
234
+
235
+    //--------------------------------------------------------------------------------------
236
+    //       Class:  TEMSurveyLineRecordData
237
+    //      Method:  DeSerialize
238
+    //--------------------------------------------------------------------------------------
239
+    TEMSurveyLineRecordData* TEMSurveyLineRecordData::DeSerialize ( const YAML::Node& node  ) {
240
+        TEMSurveyLineRecordData* Object = new TEMSurveyLineRecordData(node);
241
+        Object->AttachTo(Object);
242
+        DESERIALIZECHECK( node, Object )
243
+            return Object ;
244
+    }		// -----  end of method TEMSurveyLineRecordData::DeSerialize  -----
245
+#endif
246
+
247
+}		// -----  end of Lemma  name  -----
248
+

+ 227
- 0
Modules/TEM1D/src/TEMTransmitter.cpp View File

@@ -0,0 +1,227 @@
1
+/* This file is part of Lemma, a geophysical modelling and inversion API.
2
+ * More information is available at http://lemmasoftware.org
3
+ */
4
+
5
+/* This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ */
9
+
10
+/**
11
+ * @file
12
+ * @date      09/29/2014 11:43:28 AM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     Trevor.Irons@xri-geo.com
16
+ * @copyright Copyright (c) 2014, XRI Geophysics, LLC
17
+ * @copyright Copyright (c) 2014, Trevor Irons
18
+ */
19
+
20
+#include "TEMTransmitter.h"
21
+
22
+namespace Lemma {
23
+
24
+// ====================  FRIEND METHODS  =====================
25
+
26
+#ifdef HAVE_YAMLCPP
27
+std::ostream &operator << (std::ostream &stream, const TEMTransmitter &ob) {
28
+    stream << ob.Serialize()  << "\n---\n"; // End of doc --- as a direct stream should encapulste thingy
29
+    return stream;
30
+}
31
+// TODO CONSIDER INPUT OPERATOR TOO!
32
+//std::ostream &operator << (std::ostream &stream, const TEMTransmitter &ob) {
33
+//    stream << ob.Serialize()  << "\n---\n"; // End of doc --- as a direct stream should encapulste thingy
34
+//    return stream;
35
+//}
36
+#else
37
+std::ostream &operator << (std::ostream &stream, const TEMTransmitter &ob) {
38
+    stream << *(PolygonalWireAntenna*)(&ob);
39
+    stream << "YOU SHOULD COMPILE WITH YAML-CPP\n";
40
+    return stream;
41
+}
42
+#endif
43
+
44
+
45
+// ====================  LIFECYCLE     =======================
46
+
47
+//--------------------------------------------------------------------------------------
48
+//       Class:  TEMTransmitter
49
+//      Method:  TEMTransmitter
50
+// Description:  constructor (protected)
51
+//--------------------------------------------------------------------------------------
52
+TEMTransmitter::TEMTransmitter (const std::string& name) : PolygonalWireAntenna(name),
53
+    repFreq(0), repFreqUnits(HZ) {
54
+
55
+}  // -----  end of method TEMTransmitter::TEMTransmitter  (constructor)  -----
56
+
57
+#ifdef HAVE_YAMLCPP
58
+//--------------------------------------------------------------------------------------
59
+//       Class:  TEMTransmitter
60
+//      Method:  TEMTransmitter
61
+// Description:  Deserializing constructor (protected)
62
+//--------------------------------------------------------------------------------------
63
+TEMTransmitter::TEMTransmitter (const YAML::Node& node) : PolygonalWireAntenna(node) {
64
+
65
+    repFreq =  node["repFreq"].as<Real>();
66
+    repFreqUnits =  string2Enum<FREQUENCYUNITS>( node["repFreqUnits"].as<std::string>() );
67
+    wfmTimes = node["wfmTimes"].as<VectorXr>();
68
+    wfmTimes = node["wfmAmps"].as<VectorXr>();
69
+
70
+}  // -----  end of method TEMTransmitter::TEMTransmitter  (constructor)  -----
71
+#endif
72
+
73
+//--------------------------------------------------------------------------------------
74
+//       Class:  TEMTransmitter
75
+//      Method:  New()
76
+// Description:  public constructor
77
+//--------------------------------------------------------------------------------------
78
+TEMTransmitter* TEMTransmitter::New() {
79
+    TEMTransmitter*  Obj = new TEMTransmitter("TEMTransmitter");
80
+    Obj->AttachTo(Obj);
81
+    return Obj;
82
+}
83
+
84
+
85
+//--------------------------------------------------------------------------------------
86
+//       Class:  TEMTransmitter
87
+//      Method:  Clone
88
+//--------------------------------------------------------------------------------------
89
+TEMTransmitter* TEMTransmitter::Clone (  ) {
90
+    TEMTransmitter* copy = TEMTransmitter::New();
91
+    //copy->AttachTo(copy); // NO! Attached above!
92
+	copy->NumberOfPoints = this->NumberOfPoints;
93
+	copy->Freqs = this->Freqs;
94
+	copy->Current = this->Current;
95
+	copy->NumberOfTurns = this->NumberOfTurns;
96
+	copy->Points = this->Points;
97
+	//copy->Dipoles = this->Dipoles; // no, disaster
98
+
99
+    copy->repFreq = this->repFreq;
100
+    copy->repFreqUnits = this->repFreqUnits;
101
+    copy->wfmTimes = this->wfmTimes;
102
+    copy->wfmAmps = this->wfmAmps;
103
+
104
+	return copy;
105
+}		// -----  end of method TEMTransmitter::Clone  -----
106
+
107
+
108
+//--------------------------------------------------------------------------------------
109
+//       Class:  TEMTransmitter
110
+//      Method:  ~TEMTransmitter
111
+// Description:  destructor (protected)
112
+//--------------------------------------------------------------------------------------
113
+TEMTransmitter::~TEMTransmitter () {
114
+
115
+}  // -----  end of method TEMTransmitter::~TEMTransmitter  (destructor)  -----
116
+
117
+//--------------------------------------------------------------------------------------
118
+//       Class:  TEMTransmitter
119
+//      Method:  Delete
120
+// Description:  public destructor
121
+//--------------------------------------------------------------------------------------
122
+void TEMTransmitter::Delete() {
123
+    this->DetachFrom(this);
124
+}
125
+
126
+//--------------------------------------------------------------------------------------
127
+//       Class:  TEMTransmitter
128
+//      Method:  Release
129
+// Description:  destructor (protected)
130
+//--------------------------------------------------------------------------------------
131
+void TEMTransmitter::Release() {
132
+    delete this;
133
+}
134
+
135
+//--------------------------------------------------------------------------------------
136
+//       Class:  TEMTransmitter
137
+//      Method:  Serialize
138
+//--------------------------------------------------------------------------------------
139
+#ifdef HAVE_YAMLCPP
140
+YAML::Node TEMTransmitter::Serialize (  ) const {
141
+
142
+    YAML::Node node = PolygonalWireAntenna::Serialize();
143
+        // or we could do just like below. Same basic uglyness
144
+        node.SetTag( this->Name) ; //((PolygonalWireAntenna*)(&ob))->GetName() );
145
+        //node["address"] =  ss.str();
146
+
147
+        node["repFreq"]      = this->repFreq;
148
+        node["repFreqUnits"] = enum2String(repFreqUnits);
149
+        node["wfmTimes"] = wfmTimes;
150
+        node["wfmAmps"] = wfmAmps;
151
+
152
+    return node;
153
+}		// -----  end of method TEMTransmitter::Serialize  -----
154
+
155
+//--------------------------------------------------------------------------------------
156
+//       Class:  TEMTransmitter
157
+//      Method:  DeSerialize
158
+//--------------------------------------------------------------------------------------
159
+TEMTransmitter* TEMTransmitter::DeSerialize ( const  YAML::Node& node  ) {
160
+    TEMTransmitter* Object = new TEMTransmitter(node);
161
+    Object->AttachTo(Object);
162
+    DESERIALIZECHECK( node, Object )
163
+    return  Object;
164
+}		// -----  end of method TEMTransmitter::DeSerialize  -----
165
+#endif
166
+
167
+    // ====================  INQUIRY       =======================
168
+
169
+//--------------------------------------------------------------------------------------
170
+//       Class:  TEMTransmitter
171
+//      Method:  SetRepFrequency
172
+//--------------------------------------------------------------------------------------
173
+void TEMTransmitter::SetRepFrequency ( const Real& fr, const FREQUENCYUNITS& units ) {
174
+    repFreq = fr;
175
+    repFreqUnits = units;
176
+    return ;
177
+}		// -----  end of method TEMTransmitter::SetRepFrequency  -----
178
+
179
+
180
+//--------------------------------------------------------------------------------------
181
+//       Class:  TEMTransmitter
182
+//      Method:  SetWaveform
183
+//--------------------------------------------------------------------------------------
184
+void TEMTransmitter::SetWaveform (  const VectorXr& times, const VectorXr& amps, const TIMEUNITS& units ) {
185
+    // switch units ?
186
+    switch (units) {
187
+        case SEC:
188
+            wfmTimes = times;
189
+            break;
190
+        case MILLISEC:
191
+            wfmTimes = times*1e-3 ;
192
+            break;
193
+        case MICROSEC:
194
+            wfmTimes = times*1e-6 ;
195
+            break;
196
+        case NANOSEC:
197
+            wfmTimes = times*1e-9 ;
198
+            break;
199
+        case PICOSEC:
200
+            wfmTimes = times*1e-12 ;
201
+            break;
202
+    };
203
+    wfmAmps = amps;
204
+    return ;
205
+}		// -----  end of method TEMTransmitter::SetWaveform  -----
206
+
207
+
208
+//--------------------------------------------------------------------------------------
209
+//       Class:  TEMTransmitter
210
+//      Method:  GetWfmAmps
211
+//--------------------------------------------------------------------------------------
212
+VectorXr TEMTransmitter::GetWfmAmps (  ) {
213
+    return wfmAmps;
214
+}		// -----  end of method TEMTransmitter::GetWfmAmps  -----
215
+
216
+
217
+
218
+//--------------------------------------------------------------------------------------
219
+//       Class:  TEMTransmitter
220
+//      Method:  GetWfmTimes
221
+//--------------------------------------------------------------------------------------
222
+VectorXr TEMTransmitter::GetWfmTimes (  ) {
223
+    return wfmTimes;
224
+}		// -----  end of method TEMTransmitter::GetWfmTimes  -----
225
+
226
+
227
+} // namespace Lemma

+ 449
- 0
Modules/TEM1D/src/instrumenttem.cpp View File

@@ -0,0 +1,449 @@
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   M. Andy Kass, Edited Trevor Irons 02/28/2014
10
+  @date     02/10/2011
11
+  @version  $Id: instrumenttem.cpp 266 2015-04-01 03:24:00Z tirons $
12
+ **/
13
+#include "instrumenttem.h"
14
+
15
+namespace Lemma {
16
+
17
+	std::ostream &operator<<(std::ostream &stream,
18
+		const InstrumentTem &ob) {
19
+	stream << *(LemmaObject*)(&ob);
20
+	return stream;
21
+	}
22
+
23
+	// =======================  Lifecycle  ==================================
24
+
25
+	InstrumentTem::InstrumentTem(const std::string &name) : Instrument(name),
26
+		Antenna(NULL), Receiver(NULL), EarthMod(NULL), Dipole(NULL), bipolarWaveform(true),
27
+        NPreviousPulse(0), RefTime(0.0), PulseT(.06), TxFreq(0.30), RType(INDUCTIVE) {
28
+	}
29
+
30
+	InstrumentTem::~InstrumentTem() {
31
+		if (NumberOfReferences != 0) {
32
+			throw DeleteObjectWithReferences(this);
33
+		}
34
+
35
+        if (this->Antenna != NULL) {
36
+			this->Antenna->DetachFrom(this);
37
+		}
38
+
39
+		if (this->Dipole != NULL) {
40
+			this->Dipole->DetachFrom(this);
41
+		}
42
+
43
+        if (this->EarthMod != NULL) {
44
+			this->EarthMod->DetachFrom(this);
45
+		}
46
+
47
+        if (this->Receiver != NULL) {
48
+			this->Receiver->DetachFrom(this);
49
+		}
50
+
51
+	}
52
+
53
+	InstrumentTem* InstrumentTem::New() {
54
+		InstrumentTem* Obj = new InstrumentTem("InstrumentTem");
55
+		Obj->AttachTo(Obj);
56
+		return Obj;
57
+	}
58
+
59
+	void InstrumentTem::Delete() {
60
+		this->DetachFrom(this);
61
+	}
62
+
63
+	void InstrumentTem::Release() {
64
+		delete this;
65
+	}
66
+
67
+	// =======================  Operations  =================================
68
+	void InstrumentTem::MakeDirectCalculation( const HANKELTRANSFORMTYPE& hType) {
69
+
70
+		//int temp;
71
+		int NumTimes;
72
+		Real answer;
73
+		EMEarth1D *EMEarthLocal=EMEarth1D::New();
74
+		EMEarthLocal->AttachLayeredEarthEM(this->EarthMod);
75
+
76
+		//DigitalFilterCosTrans *DFIntegrate=DigitalFilterCosTrans::New();
77
+		DigitalFilterSinTrans *DFIntegrate=DigitalFilterSinTrans::New();
78
+
79
+		TemIntegrationKernel *TEMIntKern=TemIntegrationKernel::New();
80
+		TEMIntKern->SetEMEarth1D(EMEarthLocal);
81
+		//TEMIntKern->SetTransmitter(this->Antenna);
82
+		TEMIntKern->SetReceiver(this->Receiver);
83
+		DFIntegrate->AttachKernel(TEMIntKern);
84
+
85
+		if (this->Dipole != NULL) {  //AND this->Antenna == NULL
86
+			EMEarthLocal->AttachDipoleSource(this->Dipole);
87
+			TEMIntKern->SetDipole(this->Dipole);
88
+		}
89
+		if (this->Antenna != NULL) { //AND this->Dipole == NULL
90
+			EMEarthLocal->AttachWireAntenna(this->Antenna);
91
+			TEMIntKern->SetTransmitter(this->Antenna);
92
+		}
93
+		EMEarthLocal->SetFieldsToCalculate(H);
94
+		    //EMEarthLocal->SetHankelTransformMethod(DIGITALFILTERING);
95
+		    //EMEarthLocal->SetHankelTransformMethod(FHTKEY201);
96
+		    EMEarthLocal->SetHankelTransformMethod(hType);
97
+		    //EMEarthLocal->SetHankelTransformMethod(GAUSSIANQUADRATURE);
98
+
99
+		//EMEarthLocal->AttachReceiverPoints(this->Receiver);
100
+		// For testing with one time only
101
+		//DFIntegrate->Compute(1,1,1e-16);
102
+		//std::cout<<DFIntegrate->GetAnswer()<<std::endl;
103
+		//
104
+		NumTimes = this->TimeGates.size();
105
+		//Testing
106
+		//std::cout << "NumTimes: " << NumTimes << std::endl;
107
+		this->ModelledData.resize(NumTimes,2);
108
+		for (int ii=0;ii<NumTimes;ii++) {
109
+			//TESTING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
110
+			//RELAXING THE VALUE!
111
+			DFIntegrate->Compute(this->TimeGates(ii), 1, 1e-7);
112
+			//Testing
113
+			//std::cout << "DFIntegrate done computing" << std::endl;
114
+			answer = DFIntegrate->GetAnswer()(0);
115
+			answer = (2./PI)*answer;
116
+			this->ModelledData(ii,0) = this->TimeGates(ii);
117
+			this->ModelledData(ii,1) = answer;
118
+			//std::cout << "   " << TimeGates(ii) << "  " <<
119
+			//	answer << std::endl;
120
+			//std::cout << "   " << this->ModelledData(ii,0) << "  " <<
121
+			//	this->ModelledData(ii,1) << std::endl;
122
+			// Call cosine transform which calls argument
123
+		}
124
+		//
125
+		TEMIntKern->Delete();
126
+		EMEarthLocal->Delete();
127
+		DFIntegrate->Delete();
128
+
129
+	}
130
+
131
+    void InstrumentTem::MakeLaggedCalculation(const HANKELTRANSFORMTYPE& hType) {
132
+
133
+        EMEarth1D *EMEarthLocal=EMEarth1D::New();
134
+		    EMEarthLocal->AttachLayeredEarthEM(this->EarthMod);
135
+		    EMEarthLocal->SetFieldsToCalculate(H);
136
+		    EMEarthLocal->SetHankelTransformMethod(hType);
137
+            EMEarthLocal->AttachReceiverPoints(this->Receiver);
138
+
139
+		TemIntegrationKernel *TEMIntKern=TemIntegrationKernel::New();
140
+
141
+		    TEMIntKern->SetReceiver(this->Receiver);
142
+		    TEMIntKern->SetEMEarth1D(EMEarthLocal);
143
+
144
+
145
+		if (this->Dipole != NULL) {  //AND this->Antenna == NULL
146
+			EMEarthLocal->AttachDipoleSource(this->Dipole);
147
+			TEMIntKern->SetDipole(this->Dipole);
148
+            Dipole->SetNumberOfFrequencies(1);
149
+		}
150
+		if (this->Antenna != NULL) { //AND this->Dipole == NULL
151
+			EMEarthLocal->AttachWireAntenna(this->Antenna);
152
+            Antenna->SetCurrent(1);
153
+			TEMIntKern->SetTransmitter(this->Antenna);
154
+            Antenna->SetNumberOfFrequencies(1);
155
+		}
156
+
157
+
158
+        // TODO IMPORTANT!!
159
+        // Compute number of lagged convolutions to do, TODO, need to make sure we do these
160
+        // TO THE LATEST time needed for multiple pulse subtraction!!!
161
+        int ilag = 1;
162
+        Real sub = 2.1*PulseT + 2.*NPreviousPulse*PulseT;
163
+        if (!bipolarWaveform) sub = NPreviousPulse*PulseT;
164
+
165
+        //TimeGates.array() += RefTime;
166
+        //RefTime = 0;
167
+
168
+        // This is a critical line, for reasons I don't understand, it's important to calculate past the
169
+        // theoretical GateWidths(0)/2.
170
+        while ( (TimeGates.tail(1)(0)+sub)*std::pow(1./exp(.1), ilag-1) > TimeGates(0)-GateWidths(0) ) ++ ilag;
171
+
172
+		//DigitalFilterSinTrans *DFIntegrate=DigitalFilterSinTrans::New(); // use with step response kernel
173
+		DigitalFilterCosTrans *DFIntegrate=DigitalFilterCosTrans::New();   // use with impulse response kernel
174
+		    DFIntegrate->AttachKernel(TEMIntKern);
175
+            DFIntegrate->SetNumConv(ilag);
176
+		    DFIntegrate->Compute( this->TimeGates.tail(1)(0)+sub, 1, 1e-7 ); // rho ntol, tol=1e-7 to 1e-13
177
+
178
+        CubicSplineInterpolator *Spline = CubicSplineInterpolator::New();
179
+            //Spline->SetKnots( DFIntegrate->GetAbscissaArguments().array(), (2./PI) * DFIntegrate->GetAnswer().col(0).array() );
180
+            Spline->SetKnots( DFIntegrate->GetAbscissaArguments().array(), (.25/PI) * DFIntegrate->GetAnswer().col(0).array() );
181
+
182
+
183
+		this->ModelledData.resize(TimeGates.size(), 2);
184
+            this->ModelledData.col(0) = TimeGates;
185
+            this->ModelledData.col(1).setZero();
186
+
187
+        //  This is non-extrapolated times and values
188
+        //this->ModelledData.resize(ilag, 2);
189
+        //    this->ModelledData.col(0) = DFIntegrate->GetAbscissaArguments(); // this->TimeGates(ii);
190
+		//	this->ModelledData.col(1) = (2./PI)*DFIntegrate->GetAnswer();
191
+        //std::cout <<  (2./PI)*DFIntegrate->GetAnswer().transpose()  << std::endl;
192
+
193
+        // Take into account receiver gate integration and tx waveform
194
+        FoldAndConvolve(Spline);
195
+
196
+        // Direct caclulation, step response to use need re reset temintegrationkernel back to step!
197
+		//	this->ModelledData.col(1) = (2./PI)*Spline->InterpolateOrderedSet( TimeGates );
198
+
199
+        Spline->Delete();
200
+	    TEMIntKern->Delete();
201
+		EMEarthLocal->Delete();
202
+		DFIntegrate->Delete();
203
+
204
+	}
205
+
206
+	// =======================  Access  =====================================
207
+
208
+	void InstrumentTem::SetPulse( const VectorXr& Amp, const VectorXr& times, bool bipolar ) {
209
+
210
+        bipolarWaveform = bipolar;
211
+        assert(Amp.size() == times.size());
212
+
213
+        TxAmp = Amp;
214
+        TxAbs = times;
215
+
216
+        TxDiff = VectorXr::Zero(TxAmp.size());
217
+        TxDelta = VectorXr::Zero(TxAmp.size());
218
+
219
+        for (int ip=1; ip<TxAmp.size(); ++ ip) {
220
+            TxDiff(ip)  = (TxAmp(ip-1)-TxAmp(ip  )) /
221
+                          (TxAbs(ip  )-TxAbs(ip-1)) ;
222
+            TxDelta(ip) = (TxAmp(ip-1)-TxAmp(ip  )) ;
223
+        }
224
+
225
+        /*
226
+        std::cout << "diff "  << TxDiff.transpose() << std::endl;
227
+        std::cout << "delta "  << TxDelta.transpose() << std::endl;
228
+        std::cout << "amp "  << TxAmp.transpose() << std::endl;
229
+        std::cout << "abs "  << TxAbs.transpose() << std::endl;
230
+        */
231
+	}
232
+
233
+	void InstrumentTem::EMEarthModel(LayeredEarthEM* Earth) {
234
+		if (this->EarthMod != NULL) {
235
+			this->EarthMod->DetachFrom(this);
236
+		}
237
+		//std::cout << "InstrumentTem: EarthMod null test" << std::endl;
238
+		Earth->AttachTo(this);
239
+		//std::cout << "InstrumentTem: EarthMod attached" << std::endl;
240
+		this->EarthMod = Earth;
241
+		//std::cout << "InstrumentTem: EMEarthModel Attached" << std::endl;
242
+
243
+	}
244
+
245
+	void InstrumentTem::SetTransmitLoop(WireAntenna *antennae) {
246
+		if (this->Antenna != NULL) {
247
+			this->Antenna->DetachFrom(this);
248
+		}
249
+		antennae->AttachTo(this);
250
+		this->Antenna = antennae;
251
+		if (this->Dipole != NULL) {
252
+			this->Dipole->DetachFrom(this);
253
+		}
254
+		//std::cout << "InstrumentTem: TransmitLoop Attached" << std::endl;
255
+
256
+	}
257
+
258
+	void InstrumentTem::SetDipoleSource(DipoleSource* dipolesource) {
259
+		if (this->Dipole != NULL) {
260
+			this->Dipole->DetachFrom(this);
261
+		}
262
+		dipolesource->AttachTo(this);
263
+		this->Dipole = dipolesource;
264
+		if (this->Antenna != NULL) {
265
+			this->Antenna->DetachFrom(this);
266
+		}
267
+	}
268
+
269
+	void InstrumentTem::SetReceiver(ReceiverPoints* Receivers) {
270
+		if (this->Receiver != NULL) {
271
+			this->Receiver->DetachFrom(this);
272
+		}
273
+		Receivers->AttachTo(this);
274
+		this->Receiver = Receivers;
275
+		//std::cout << "InstrumentTem: Receivers Attached" << std::endl;
276
+
277
+	}
278
+
279
+	void InstrumentTem::SetTimes(const VectorXr &times) {
280
+		this->TimeGates = times;
281
+	}
282
+
283
+
284
+    //--------------------------------------------------------------------------------------
285
+    //       Class:  InstrumentTem
286
+    //      Method:  SetReceiverType
287
+    //--------------------------------------------------------------------------------------
288
+    void InstrumentTem::SetReceiverType ( const ReceiverType& rt ) {
289
+        RType = rt;
290
+        return ;
291
+    }		// -----  end of method InstrumentTem::SetReceiverType  -----
292
+
293
+
294
+    //--------------------------------------------------------------------------------------
295
+    //       Class:  InstrumentTEM
296
+    //      Method:  SetTimeGates
297
+    //--------------------------------------------------------------------------------------
298
+    void InstrumentTem::SetTimeGates ( const VectorXr &centres, const VectorXr& widths  ) {
299
+        assert (centres.size() == widths.size());
300
+        TimeGates = centres;
301
+        GateWidths = widths;
302
+        return ;
303
+    }		// -----  end of method InstrumentTEM::SetTimeGates  -----
304
+
305
+
306
+
307
+
308
+	int InstrumentTem::GetNumberOfTimes() {
309
+
310
+		return this->TimeGates.size();
311
+	}
312
+
313
+	MatrixXr InstrumentTem::GetMeasurements() {
314
+
315
+		return this->ModelledData;
316
+	}
317
+
318
+
319
+
320
+    //--------------------------------------------------------------------------------------
321
+    //       Class:  InstrumentTem
322
+    //      Method:  SetReferenceTime
323
+    //--------------------------------------------------------------------------------------
324
+    void InstrumentTem::SetReferenceTime ( const Real& rtime ) {
325
+        RefTime = rtime;
326
+        return ;
327
+    }		// -----  end of method InstrumentTem::SetReferenceTime  -----
328
+
329
+
330
+
331
+    //--------------------------------------------------------------------------------------
332
+    //       Class:  InstrumentTem
333
+    //      Method:  FoldAndConvolve
334
+    //--------------------------------------------------------------------------------------
335
+    void InstrumentTem::FoldAndConvolve ( CubicSplineInterpolator* Spline ) {
336
+
337
+        const static Real GLW[3] = {.5555556, .8888889, .5555556};
338
+        const static Real GLX[3] = {-.7745967, 0., .7745967};
339
+
340
+        // TODO BUG check against LEROI!!!
341
+        //SubtractPrevious(Spline);
342
+
343
+
344
+        switch (RType) {
345
+            case INDUCTIVE:
346
+                // Differentiate to compute impulse response for step input
347
+                // Iterate over time gate
348
+                for (int ig=0; ig<TimeGates.size(); ++ig) {
349
+                    this->ModelledData.col(1)[ig] =
350
+                                  ( ( ConvolveWaveform(Spline, RefTime + TimeGates[ig] - GateWidths[ig]/2.) -
351
+                                      ConvolveWaveform(Spline, RefTime + TimeGates[ig] + GateWidths[ig]/2.) ) / GateWidths[ig]);
352
+                }
353
+                break;
354
+
355
+            case MAGNETOMETER:
356
+                for (int ig=0; ig<TimeGates.size(); ++ig) {
357
+                    /*
358
+                    TC(2) = (TCLS(JT) + TOPN(JT)) / 2.
359
+                    TC(1) = TC(2) + HWIDTH * GLX(1)
360
+                    TC(3) = TC(2) + HWIDTH * GLX(3)
361
+                    */
362
+                    this->ModelledData.col(1)[ig] = 0;
363
+                    for (int ii=0; ii<3; ++ii) {
364
+                        //Real tt = RefTime + TimeGates[ig] + GLX[ii]*(GateWidths[ig]/2.);
365
+                        Real tt = RefTime + TimeGates[ig] + GLX[ii]*(GateWidths[ig]/2.);
366
+                        this->ModelledData.col(1)[ig] += ConvolveWaveform(Spline, tt) * GLW[ii]/2.;
367
+                    }
368
+                }
369
+                break;
370
+
371
+            case ELECTRIC:
372
+                throw std::runtime_error("InstrumentTEM->FoldAndConvolve with Electic Receivers is not implimented");
373
+                break;
374
+        }
375
+
376
+        return ;
377
+    }		// -----  end of method InstrumentTem::FoldAndConvolve  -----
378
+
379
+
380
+    //--------------------------------------------------------------------------------------
381
+    //       Class:  InstrumentTem
382
+    //      Method:  ConvolveWaveform
383
+    //--------------------------------------------------------------------------------------
384
+    Real InstrumentTem::ConvolveWaveform ( CubicSplineInterpolator* Spline, const Real& t ) {
385
+        static const Real T0MIN = 1e-7;
386
+        Real cnv(0);
387
+        Real tf = t - Spline->GetKnotAbscissa()[0];
388
+        bool der = false;
389
+        Real tend(0);
390
+        for (int ip=1; ip<TxAmp.size(); ++ip) {
391
+            if (TxAbs(ip) < T0MIN) continue;
392
+            if (TxAbs(ip-1) > tf)  break;
393
+
394
+            Real tb = t - std::min(tf, TxAbs(ip));
395
+            Real delt = TxAbs(ip) - TxAbs(ip-1);
396
+
397
+            der = false;
398
+            if (delt > T0MIN) {
399
+                tend = t - TxAbs(ip-1);
400
+                der = true;
401
+            }
402
+
403
+            if (der) {
404
+                //std::cout.precision(16);
405
+                // TODO Integrate seems to be kind of screwy!! Affecting early/on times
406
+                cnv += TxDiff(ip) * Spline->Integrate(tb, tend, 41200); //CUBINT (TRP,YPLS,NTYPLS,TB,TEND)
407
+                // TODO bug in direct spline integration, works sometimes
408
+                //cnv += TxDiff(ip) * Spline->Integrate(tb, tend);
409
+                //cnv += Spline->Integrate(tb, tend, 6264); //CUBINT (TRP,YPLS,NTYPLS,TB,TEND)
410
+                //Real temp = Spline->Integrate(tb, tend, 10036); //CUBINT (TRP,YPLS,NTYPLS,TB,TEND)
411
+                //Real temp2 = Spline->Integrate(tb, tend); //CUBINT (TRP,YPLS,NTYPLS,TB,TEND)
412
+                //std::cout << "der " << TxDiff(ip) << "\t" << std::scientific << tb << "\t" << tend << "\t" << MU0*temp2 << "\t" << MU0*temp << "\n";
413
+                //cnv += temp;
414
+            } else {
415
+                cnv += TxDelta(ip) * Spline->Interpolate(tb); //CUBVAL (TRP,YPLS,NTYPLS,TB)
416
+            }
417
+        }
418
+        return cnv;
419
+
420
+    }		// -----  end of method InstrumentTem::ConvolveWaveform  -----
421
+
422
+
423
+    //--------------------------------------------------------------------------------------
424
+    //       Class:  InstrumentTem
425
+    //      Method:  SubtractPrevious
426
+    //--------------------------------------------------------------------------------------
427
+    void InstrumentTem::SubtractPrevious ( CubicSplineInterpolator *Spline ) {
428
+        // Start by calculating impulse response of this pulse plus any arbitrary number of previous pulses at this
429
+        // repetition frequency
430
+        VectorXr aTimeGates = Spline->GetKnotAbscissa();
431
+        Real pol (1.);
432
+        if (bipolarWaveform) pol = -1.;
433
+        VectorXr PrevPulse = aTimeGates.array() + PulseT;
434
+		// TODO, if not bipolar what does convention say, is this added or should this be zero and handled only by nPreviousPulse?
435
+        VectorXr Fold = Spline->GetKnotOrdinate( ); // +
436
+        //VectorXr Fold =  pol*Spline->InterpolateOrderedSet( PrevPulse ) ;
437
+        VectorXr PrevPulse1; // = PrevPulse.array(); // + PulseT;
438
+        for (int ip=0; ip<NPreviousPulse; ++ip) {
439
+            PrevPulse1.array() += PrevPulse.array() + PulseT;
440
+            PrevPulse.array() += PrevPulse1.array() + PulseT;
441
+            Fold += Spline->InterpolateOrderedSet( PrevPulse1 ) + pol*Spline->InterpolateOrderedSet( PrevPulse ) ;
442
+        }
443
+        Spline->ResetKnotOrdinate(Fold);
444
+        return ;
445
+    }		// -----  end of method InstrumentTem::SubtractPrevious  -----
446
+
447
+
448
+
449
+} // namespace Lemma

+ 419
- 0
Modules/TEM1D/src/inversesolvertem1d.cpp View File

@@ -0,0 +1,419 @@
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   M. Andy Kass
10
+  @date     03/23/2011
11
+  @version  $Id: inversesolvertem1d.cpp 193 2014-11-10 23:51:41Z tirons $
12
+ **/
13
+
14
+#include "inversesolvertem1d.h"
15
+
16
+namespace Lemma {
17
+
18
+	std::ostream &operator<<(std::ostream &stream,
19
+		const InverseSolverTEM1D &ob) {
20
+		stream << *(LemmaObject*)(&ob);
21
+		stream << "Wire antenna source address: " << ob.Antenna << std::endl;
22
+		stream << "Dipole source address: " << ob.Dipole << std::endl;
23
+		stream << *ob.Receiver << std::endl;
24
+		stream << *ob.StartingMod << std::endl;
25
+		stream << *ob.RecoveredMod << std::endl;
26
+		stream << *ob.InstrumentFor << std::endl;
27
+		return stream;
28
+	}
29
+
30
+    // ====================  LIFECYCLE     =======================
31
+
32
+	InverseSolverTEM1D::InverseSolverTEM1D(const std::string &name) :
33
+		InverseSolver(name),Antenna(NULL), Dipole(NULL),
34
+		Receiver(NULL), StartingMod(NULL), RecoveredMod(NULL),
35
+		InstrumentFor(NULL) {
36
+
37
+		this->InstrumentFor = InstrumentTem::New();
38
+		//this->SCondIndex.resize(42);
39
+		//this->SThickIndex.resize(42);
40
+		//this->SCondIndex(0) = 42;
41
+		//this->SThickIndex(0) = 42;
42
+	}
43
+
44
+	InverseSolverTEM1D::~InverseSolverTEM1D() {
45
+		if (NumberOfReferences !=0) throw DeleteObjectWithReferences(this);
46
+
47
+		if (this->Antenna != NULL) this->Antenna->DetachFrom(this);
48
+
49
+		if (this->Dipole != NULL) this->Dipole->DetachFrom(this);
50
+
51
+		if (this->Receiver != NULL) this->Receiver->DetachFrom(this);
52
+
53
+		if (this->StartingMod != NULL) this->StartingMod->DetachFrom(this);
54
+
55
+		if (this->RecoveredMod != NULL) this->RecoveredMod->DetachFrom(this);
56
+
57
+		this->InstrumentFor->Delete();
58
+
59
+	}
60
+
61
+    InverseSolverTEM1D* InverseSolverTEM1D::New() {
62
+        InverseSolverTEM1D*  Obj =
63
+            new InverseSolverTEM1D( "InverseSolverTEM1D" );
64
+        Obj->AttachTo(Obj);
65
+        return Obj;
66
+
67
+    }
68
+
69
+    void InverseSolverTEM1D::Delete() {
70
+        this->DetachFrom(this);
71
+    }
72
+
73
+    void InverseSolverTEM1D::Release() {
74
+        delete this;
75
+    }
76
+
77
+    // ====================  OPERATIONS    =======================
78
+
79
+	void InverseSolverTEM1D::Calculate() {
80
+		MatrixXr jac;
81
+		VectorXr newthickness;
82
+		VectorXcr newconductivity;
83
+		VectorXr oldthickness;
84
+		VectorXcr oldconductivity;
85
+		MatrixXr olddata;
86
+		MatrixXr newdata;
87
+		VectorXr deltathick;
88
+		VectorXcr deltacond;
89
+		MatrixXr H;
90
+		VectorXr g;
91
+		VectorXr p;
92
+		VectorXr s;
93
+		VectorXr y;
94
+
95
+		//int nrec=42;
96
+		int nlayers=42;
97
+
98
+		this->InstrumentFor->EMEarthModel(this->RecoveredMod);
99
+		this->InstrumentFor->SetTransmitLoop(this->Antenna);
100
+		this->InstrumentFor->SetReceiver(this->Receiver);
101
+		this->InstrumentFor->SetTimes(this->Times);
102
+
103
+		nlayers = this->RecoveredMod->GetNumberOfLayers();
104
+		//nrec = this->Receiver->GetNumberOfReceivers();
105
+		//check for parameters set
106
+		if (this->SCondIndex.size() == 0 /*&& SCondIndex(0) == 42*/) {
107
+			//std::cout << "Cond Index is null" << std::endl;
108
+			this->SCondIndex.resize(nlayers-1);
109
+			for (int ii=1;ii<nlayers;ii++) {
110
+				this->SCondIndex(ii-1)=ii;
111
+			}
112
+		}
113
+		if (this->SThickIndex.size()==0 /*&& SThickIndex(0)==42*/) {
114
+			//std::cout << "Thickness Index is null" << std::endl;
115
+			this->SThickIndex.resize(nlayers-2);
116
+			for (int ii=0;ii<nlayers-2;ii++) {
117
+				this->SThickIndex(ii)=ii+1;
118
+			}
119
+		}
120
+
121
+		std::cout << "Thickness indices to solve for: " << this->SThickIndex
122
+			<< std::endl;
123
+		//std::cout << "Conductivity indices to solve for: " << this->SCondIndex
124
+		//	<< std::endl;
125
+
126
+
127
+		//Real alpha;
128
+
129
+		// while \nabla g > \epsilon
130
+		// Forward model from starting
131
+		this->InstrumentFor->MakeLaggedCalculation(FHTKEY201);
132
+		olddata = this->InstrumentFor->GetMeasurements();
133
+		// Get A Jacobian Matrix
134
+		jac = this->CalcJac(this->RecoveredMod);
135
+
136
+		// Output jacobian matrix
137
+		std::ofstream outfile2;
138
+		outfile2.open("jacobian.out");
139
+		for (int ii=0; ii<jac.rows();ii++) {
140
+			for (int jj=0;jj<jac.cols();jj++) {
141
+				outfile2 << jac(ii,jj) << "    ";
142
+			}
143
+			outfile2 << std::endl;
144
+		}
145
+		outfile2.close();
146
+
147
+		H = jac.transpose()*jac;
148
+		std::cout << "H: " << std::endl;
149
+		std::cout << H << std::endl;
150
+
151
+		//Temporary solution for only one linear step
152
+		//delta m = (JTJ)^-1JTd
153
+		//VectorXr x0;
154
+		//VectorXr md;
155
+		//x0.resize(jac.cols());
156
+		//x0.setZero();
157
+		//VectorXr jtd;
158
+		//md = this->MeasuredData.col(0);
159
+		//std::cout << md << std::endl;
160
+		//jtd = jac.transpose()*md;
161
+		//std::cout << jtd.size() << std::endl;
162
+		//Real tol;
163
+		//int iter;
164
+		//tol = 1.e-8;
165
+		//iter = 1000;
166
+		//this->RecModStep = CG(H,x0,jtd,iter,tol);
167
+		//std::cout << this->RecModStep << std::endl;
168
+
169
+		// Gauss-Newton Solution
170
+		//
171
+
172
+
173
+		// Quasi newton solution
174
+		// while ||\nabla g|| > \epsilon
175
+			// g = jac.transpose()*(olddata(:,1)-this->MeasuredData(:,1));
176
+			// p = H*g*(-1);
177
+			// newmod = oldmod + alpha * p
178
+			// s = alpha * p
179
+			// y = g(k+1) - g(k)
180
+			// H(k+1) = H - (H*s*s.transpose()*H)/(s.T*H*s) + (y*y.T)/(y.T*s)
181
+		// Solve for model perturbation
182
+		// end while
183
+
184
+
185
+	}
186
+
187
+	MatrixXr InverseSolverTEM1D::CalcJac(LayeredEarthEM* m0) {
188
+		MatrixXr jac;
189
+		int nrec;
190
+		int nlayers;
191
+		int nparams;
192
+		int nfsigs;
193
+		//int nflays;
194
+		Real step = 0.05;
195
+		VectorXr currentsigma;
196
+		VectorXr currentthick;
197
+		VectorXr newsigma;
198
+		VectorXr newthick;
199
+		Complex ctemp;
200
+		VectorXcr vctemp;
201
+		VectorXr params;
202
+		MatrixXr currentmeasurements;
203
+		MatrixXr perturbedmeasurements;
204
+		MatrixXr diffs;
205
+
206
+		nrec = this->Receiver->GetNumberOfReceivers();
207
+		nlayers = this->StartingMod->GetNumberOfLayers();
208
+		nfsigs = this->SCondIndex.size();
209
+		//nflays = this->SThickIndex.size();
210
+		nparams = this->SCondIndex.size() + this->SThickIndex.size();
211
+		jac.resize(nrec*this->Times.size(),nparams); /// TODO memory leak
212
+		params.resize(nparams);
213
+		std::cout << this->SThickIndex << std::endl;
214
+
215
+		//Need to set currentsigma and currentthick
216
+		//
217
+		currentsigma.resize(nlayers);
218
+		currentthick.resize(nlayers);
219
+		currentsigma = m0->GetLayerConductivity().array().real();
220
+		for (int ii=0;ii<nlayers;ii++) {
221
+			currentthick(ii) = m0->GetLayerThickness(ii);
222
+		}
223
+		newsigma = currentsigma;
224
+		newthick = currentthick;
225
+
226
+		currentmeasurements = this->InstrumentFor->GetMeasurements();
227
+
228
+		// Concatenate thicknesses and conductivities into one vector (params)
229
+		// Here is where I write over the original parameters
230
+		for (int ii=0;ii<SCondIndex.size();ii++) {
231
+			params(ii)=currentsigma(this->SCondIndex(ii));
232
+		}
233
+		int jj = 0;
234
+		for (int ii=SCondIndex.size();ii<nparams;ii++) {
235
+			params(ii) = currentthick(this->SThickIndex(jj)); //this was +1
236
+			jj++;
237
+		}
238
+		std::cout << "Size Params: " << params.size() << std::endl;
239
+		std::cout << "Size newsigma: " << newsigma.size() << std::endl;
240
+		std::cout << "Size newthick: " << newthick.size() << std::endl;
241
+		std::cout << "Size currentsigma: " << currentsigma.size() << std::endl;
242
+		std::cout << "Size currentthick: " << currentthick.size() << std::endl;
243
+		std::cout << "Thickness vector : " << currentthick << std::endl;
244
+		std::cout << "Sigma vector: " << currentsigma << std::endl;
245
+
246
+
247
+
248
+		//std::cout << "Jacobian size: " << jac.rows() << " x " <<
249
+		//	jac.cols() << std::endl;
250
+
251
+		Real tparam;
252
+		for (int jj=0;jj<nparams;jj++) {
253
+			tparam = params(jj)*step;
254
+			params(jj) = params(jj) + tparam;
255
+			newsigma = currentsigma;
256
+			newthick = currentthick;
257
+			std::cout << "New sigma, in loop: " << newsigma << std::endl;
258
+			std::cout << "New thick, in loop: " << newthick << std::endl;
259
+			//plop params back into newsigma and newthick
260
+			for (int kk=0;kk<nfsigs;kk++) {
261
+				std::cout << "Sigma index: " << this->SCondIndex(kk) << std::endl;
262
+				newsigma(this->SCondIndex(kk)) = params(kk);
263
+			}
264
+			int ii = 0;
265
+			std::cout << "Params, in loop: " << params << std::endl;
266
+			for (int kk=nfsigs;kk<nparams;kk++) {
267
+				std::cout << "Thick index: " << this->SThickIndex(ii) << std::endl;
268
+				newthick(this->SThickIndex(ii)) = params(kk); //here is the problem
269
+				//params is loaded incorrectly
270
+				ii++;
271
+			}
272
+			std::cout << "New thickness: " << newthick << std::endl;
273
+			std::cout << "New cond: " << newsigma << std::endl;
274
+			m0->SetLayerThickness(newthick.segment(1,newthick.size()-2));
275
+			m0->SetLayerConductivity(newsigma.cast<Complex>());
276
+			std::cout << *m0 << std::endl;
277
+
278
+			this->InstrumentFor->MakeLaggedCalculation(FHTKEY201);
279
+			perturbedmeasurements = this->InstrumentFor->GetMeasurements();
280
+			diffs = currentmeasurements - perturbedmeasurements;
281
+			diffs = diffs / tparam;
282
+			//Put the values back
283
+			params(jj) = params(jj) - tparam;
284
+			for (int ii=0;ii<jac.rows();ii++) {
285
+				jac(ii,jj)=diffs(ii,1);
286
+			}
287
+			std::cout << "Current Jacobian: " << std::endl;
288
+			std::cout << jac << std::endl;
289
+
290
+		}
291
+
292
+		return jac;
293
+
294
+	}
295
+
296
+	void InverseSolverTEM1D::AttachStartMod(LayeredEarthEM* inpstartmod) {
297
+		if (this->StartingMod != NULL) {
298
+			this->StartingMod->DetachFrom(this);
299
+		}
300
+		inpstartmod->AttachTo(this);
301
+		this->StartingMod = inpstartmod;
302
+	}
303
+
304
+	void InverseSolverTEM1D::AttachRecMod(LayeredEarthEM* inprecmod) {
305
+		if (this->RecoveredMod != NULL) {
306
+			this->RecoveredMod->DetachFrom(this);
307
+		}
308
+		inprecmod->AttachTo(this);
309
+		this->RecoveredMod = inprecmod;
310
+	}
311
+
312
+	void InverseSolverTEM1D::AttachWireAntenna(WireAntenna* inpwireantenna) {
313
+		if (this->Antenna != NULL) {
314
+			this->Antenna->DetachFrom(this);
315
+		}
316
+		inpwireantenna->AttachTo(this);
317
+		this->Antenna = inpwireantenna;
318
+	}
319
+
320
+	void InverseSolverTEM1D::AttachDipoleSource(DipoleSource* inpdipsource) {
321
+		if (this->Dipole != NULL) {
322
+			this->Dipole->DetachFrom(this);
323
+		}
324
+		inpdipsource->AttachTo(this);
325
+		this->Dipole = inpdipsource;
326
+	}
327
+
328
+	void InverseSolverTEM1D::AttachReceiver(ReceiverPoints* inpreceiver) {
329
+		if (this->Receiver != NULL) {
330
+			this->Receiver->DetachFrom(this);
331
+		}
332
+		inpreceiver->AttachTo(this);
333
+		this->Receiver = inpreceiver;
334
+	}
335
+
336
+	void InverseSolverTEM1D::SetTimes(VectorXr &inptimes) {
337
+		this->Times = inptimes;
338
+
339
+	}
340
+
341
+	void InverseSolverTEM1D::ShowSoln() {
342
+		int ntimes;
343
+		ntimes = this->InstrumentFor->GetNumberOfTimes();
344
+
345
+		for (int ii=0;ii<ntimes;ii++) {
346
+			std::cout<<"  "<<this->InstrumentFor->GetMeasurements()(ii,0)
347
+			<<"  "<<this->InstrumentFor->GetMeasurements()(ii,1)<<std::endl;
348
+		}
349
+	}
350
+
351
+	void InverseSolverTEM1D::WriteSoln(const std::string &filename) {
352
+		int nlayers;
353
+		VectorXcr conductivities;
354
+		VectorXr thicknesses;
355
+
356
+		nlayers = this->RecoveredMod->GetNumberOfLayers();
357
+		conductivities.resize(nlayers);
358
+		thicknesses.resize(nlayers);
359
+		conductivities = this->RecoveredMod->GetLayerConductivity();
360
+		for (int ii=0;ii<nlayers;ii++) {
361
+			thicknesses(ii) = this->RecoveredMod->GetLayerThickness(ii);
362
+		}
363
+
364
+		std::ofstream outfile1;
365
+		outfile1.open(filename.c_str());
366
+		// Model file has format:
367
+		// thickness (m) 	conductivity (S/m)
368
+		for (int ii=0;ii<nlayers;ii++) {
369
+			outfile1 << thicknesses(ii) << "    " << conductivities(ii) <<
370
+				"    " << std::endl;
371
+		}
372
+		outfile1.close();
373
+
374
+	}
375
+
376
+	void InverseSolverTEM1D::SetFreeParams(const VectorXi &layers,
377
+		const VectorXi &cond) {
378
+
379
+		this->SCondIndex = cond;
380
+		this->SThickIndex = layers;
381
+	}
382
+
383
+	void InverseSolverTEM1D::AttachMeasuredData(const MatrixXr &data) {
384
+		this->MeasuredData = data;
385
+
386
+	}
387
+
388
+	int InverseSolverTEM1D::NumberOfIterations() {
389
+
390
+		return 42;
391
+	}
392
+
393
+	bool InverseSolverTEM1D::Success() {
394
+
395
+		return false;
396
+	}
397
+
398
+	VectorXr InverseSolverTEM1D::GetPhiMVector() {
399
+		VectorXr temp;
400
+		temp.resize(1);
401
+
402
+		temp(0)=42;
403
+		return temp;
404
+	}
405
+
406
+	VectorXr InverseSolverTEM1D::GetPhiDVector() {
407
+		VectorXr temp;
408
+		temp.resize(1);
409
+		temp(0) = 42;
410
+		return temp;
411
+	}
412
+
413
+	void InverseSolverTEM1D::FillInG(const Vector3r& pos,
414
+		const Vector3r& step) {
415
+
416
+	}
417
+
418
+}
419
+

+ 0
- 0
Modules/TEM1D/src/modelreadertem1d.cpp View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save