Browse Source

work towards lagged Key201

lagkey
Trevor Irons 6 years ago
parent
commit
e9e1001bf6

+ 4
- 1
Modules/FDEM1D/include/EMEarth1D.h View File

@@ -22,6 +22,9 @@
22 22
 //#include "KernelEM1DManager.h"
23 23
 
24 24
 #include "KernelEM1DSpec.h"
25
+
26
+#include "HankelTransformFactory.h"
27
+
25 28
 #include "GQChave.h"
26 29
 #include "FHTAnderson801.h"
27 30
 #include "FHTKey201.h"
@@ -174,7 +177,7 @@ namespace Lemma {
174 177
             /** Used internally, this is the innermost loop of the MakeCalc3,
175 178
              *  and CalculateWireAntennaField routines.
176 179
              */
177
-            void SolveLaggedTxRxPair(const int &irec, FHTAnderson801* Hankel,
180
+            void SolveLaggedTxRxPair(const int &irec, HankelTransform* Hankel,
178 181
                     const Real &wavef, const int &ifreq,
179 182
                     PolygonalWireAntenna* antenna);
180 183
 

+ 8
- 0
Modules/FDEM1D/include/HankelTransform.h View File

@@ -69,6 +69,14 @@ namespace Lemma {
69 69
                 /** Returns the name of the underlying class, similiar to Python's type */
70 70
                 virtual inline std::string GetName() const = 0 ;
71 71
 
72
+
73
+                virtual Real GetABSER() { return 0; }
74
+
75
+                virtual void ComputeLaggedRelated( const Real& rhomax, const int& nlag, std::shared_ptr<KernelEM1DManager> Manager ) {
76
+                }
77
+
78
+                virtual void SetLaggedArg( const Real& rho ) {}
79
+
72 80
                 // ====================  DATA MEMBERS  =======================
73 81
 
74 82
             protected:

+ 140
- 0
Modules/FDEM1D/include/HankelTransformFactory.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      04/18/2018 11:59:00 AM
13
+ * @version   $Id$
14
+ * @author    Trevor Irons (ti)
15
+ * @email     tirons@egi.utah.edu
16
+ * @copyright Copyright (c) 2018, University of Utah
17
+ * @copyright Copyright (c) 2018, Lemma Software, LLC
18
+ */
19
+
20
+
21
+#pragma once
22
+#include "LemmaObject.h"
23
+
24
+#include "FHTAnderson801.h"
25
+#include "FHTKey201.h"
26
+
27
+namespace Lemma {
28
+
29
+    /**
30
+     * \ingroup FDEM1D
31
+     * \brief  Factory generator of HankelTranform types
32
+     * \details
33
+     */
34
+    class HankelTransformFactory : public LemmaObject {
35
+
36
+        friend std::ostream &operator<<(std::ostream &stream, const HankelTransformFactory &ob);
37
+
38
+        protected:
39
+        /*
40
+         *  This key is used to lock the constructor. It is protected so that inhereted
41
+         *  classes also have the key to contruct their base class.
42
+         */
43
+        struct ctor_key {};
44
+
45
+        public:
46
+
47
+        // ====================  LIFECYCLE     =======================
48
+
49
+        /**
50
+         * Default constructor.
51
+         * @note This method is locked, and cannot be called directly.
52
+         *       The reason that the method is public is to enable the use
53
+         *       of make_shared whilst enforcing the use of shared_ptr,
54
+         *       in c++-17, this curiosity may be resolved.
55
+         * @see HankelTransformFactory::NewSP
56
+         */
57
+        explicit HankelTransformFactory ( const ctor_key& );
58
+
59
+        /**
60
+         * DeSerializing constructor.
61
+         * @note This method is locked, and cannot be called directly.
62
+         *       The reason that the method is public is to enable the use
63
+         *       of make_shared whilst enforcing the use of shared_ptr,
64
+         *       in c++-17, this curiosity may be resolved.
65
+         * @see HankelTransformFactory::DeSerialize
66
+         */
67
+        HankelTransformFactory ( const YAML::Node& node, const ctor_key& );
68
+
69
+        /**
70
+         * Default destructor.
71
+         * @note This method should never be called due to the mandated
72
+         *       use of smart pointers. It is necessary to keep the method
73
+         *       public in order to allow for the use of the more efficient
74
+         *       make_shared constructor.
75
+         */
76
+        virtual ~HankelTransformFactory ();
77
+
78
+        /**
79
+         *  Uses YAML to serialize this object.
80
+         *  @return a YAML::Node
81
+         *  @see HankelTransformFactory::DeSerialize
82
+         */
83
+        virtual YAML::Node Serialize() const;
84
+
85
+        /*
86
+         *  Factory method for generating concrete class.
87
+         *  @return a std::shared_ptr of type HankelTransformFactory
88
+         */
89
+        //static std::shared_ptr< HankelTransformFactory > NewSP();
90
+        static std::shared_ptr< HankelTransform > NewSP( const HANKELTRANSFORMTYPE Type) {
91
+            switch (Type) {
92
+                case ANDERSON801:
93
+                    break;
94
+            }
95
+            return FHTKey201::NewSP();
96
+            //return FHTAnderson801::NewSP();
97
+        }
98
+
99
+        /**
100
+         *   Constructs an HankelTransformFactory object from a YAML::Node.
101
+         *   @see HankelTransformFactory::Serialize
102
+         */
103
+        static std::shared_ptr<HankelTransformFactory> DeSerialize(const YAML::Node& node);
104
+
105
+        // ====================  OPERATORS     =======================
106
+
107
+        // ====================  OPERATIONS    =======================
108
+
109
+        // ====================  ACCESS        =======================
110
+
111
+        // ====================  INQUIRY       =======================
112
+        /**
113
+         *  Returns the name of the underlying class, similiar to Python's type
114
+         *  @return string of class name
115
+         */
116
+        virtual inline std::string GetName() const {
117
+            return CName;
118
+        }
119
+
120
+        protected:
121
+
122
+        // ====================  LIFECYCLE     =======================
123
+
124
+        /** Copy is disabled */
125
+        HankelTransformFactory( const HankelTransformFactory& ) = delete;
126
+
127
+        // ====================  DATA MEMBERS  =========================
128
+
129
+        private:
130
+
131
+        /** ASCII string representation of the class name */
132
+        static constexpr auto CName = "HankelTransformFactory";
133
+
134
+    }; // -----  end of class  HankelTransformFactory  -----
135
+}  // -----  end of namespace Lemma ----
136
+
137
+/* vim: set tabstop=4 expandtab: */
138
+/* vim: set filetype=cpp: */
139
+
140
+

+ 3
- 10
Modules/FDEM1D/src/EMEarth1D.cpp View File

@@ -231,7 +231,7 @@ namespace Lemma {
231 231
         if (Antenna->GetName() == std::string("PolygonalWireAntenna") || Antenna->GetName() == std::string("TEMTransmitter") ) {
232 232
             icalc += 1;
233 233
             // Check to see if they are all on a plane? If so we can do this fast
234
-            if (Antenna->IsHorizontallyPlanar() && 1==2 && ( HankelType == ANDERSON801 || HankelType== FHTKEY201  )) {
234
+            if (Antenna->IsHorizontallyPlanar() && ( HankelType == ANDERSON801 || HankelType== FHTKEY201  )) {
235 235
                 #ifdef HAVE_BOOST_PROGRESS
236 236
                 if (progressbar) {
237 237
                     disp = new boost::progress_display( Receivers->GetNumberOfPoints()*Antenna->GetNumberOfFrequencies() );
@@ -243,12 +243,7 @@ namespace Lemma {
243 243
                     #pragma omp parallel
244 244
                     {
245 245
                     #endif
246
-                    //if (HankelType == ANDERSON801) {
247
-                        auto Hankel = FHTAnderson801::NewSP();
248
-                    //}
249
-                    //else if(HankelType == FHTKEY201) {
250
-                    //    auto Hankel = FHTKey201::NewSP();
251
-                    //}
246
+                    auto Hankel = HankelTransformFactory::NewSP( HankelType );
252 247
                     #ifdef LEMMAUSEOMP
253 248
                     #pragma omp for schedule(static, 1)
254 249
                     #endif
@@ -767,7 +762,7 @@ namespace Lemma {
767 762
 //         //tDipole->UpdateFields( ifreq,  Hankel, wavef );
768 763
 //     }
769 764
 
770
-    void EMEarth1D::SolveLaggedTxRxPair(const int &irec, FHTAnderson801* Hankel,
765
+    void EMEarth1D::SolveLaggedTxRxPair(const int &irec, HankelTransform* Hankel,
771 766
                     const Real &wavef, const int &ifreq, PolygonalWireAntenna* antenna) {
772 767
 
773 768
         antenna->ApproximateWithElectricDipoles(Receivers->GetLocation(irec));
@@ -781,7 +776,6 @@ namespace Lemma {
781 776
             rhomin = std::min(rhomin, rho);
782 777
             rhomax = std::max(rhomax, rho);
783 778
         }
784
-        //std::cout << "rhomin\t" << rhomin << "\trhomax" << rhomax << std::endl;
785 779
 
786 780
         // Determine number of lagged convolutions to do
787 781
         // TODO, can Hankel2 adjust the lagg spacing safely?
@@ -811,7 +805,6 @@ namespace Lemma {
811 805
             Real rho = (Receivers->GetLocation(irec).head<2>() - tDipole->GetLocation().head<2>()).norm();
812 806
             //std::cout << " in Lagged " <<  rho << "\t" << rhomin << "\t" << rhomax << std::endl;
813 807
             Hankel->SetLaggedArg( rho );
814
-            //std::cout << "out Lagged" << std::endl;
815 808
             tDipole->UpdateFields( ifreq,  Hankel, wavef );
816 809
         }
817 810
         //std::cout << "Spline\n";

+ 31
- 5
Modules/FDEM1D/src/FHTKey201.cpp View File

@@ -376,7 +376,6 @@ namespace Lemma {
376 376
     //      Method:  ComputeLaggedRelated
377 377
     //--------------------------------------------------------------------------------------
378 378
     void FHTKey201::ComputeLaggedRelated ( const Real& rho, const int& nlag, std::shared_ptr<KernelEM1DManager> KernelManager ) {
379
-
380 379
         int nrel = (int)(KernelManager->GetSTLVector().size());
381 380
         Eigen::Matrix<Complex, 201, Eigen::Dynamic > Zwork;
382 381
         Zans= Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic>::Zero(nlag, nrel);
@@ -385,6 +384,12 @@ namespace Lemma {
385 384
         int NumFun = 0;
386 385
         int idx = 0;
387 386
 
387
+        VectorXr Arg(nlag);
388
+        Arg(nlag-1) = rho;
389
+        for (int ilag=nlag-2; ilag>=0; --ilag) {
390
+            Arg(ilag) = Arg(ilag+1) * GetABSER();
391
+        }
392
+
388 393
         // Get Kernel values
389 394
         for (int ir=0; ir<lambda.size(); ++ir) {
390 395
             // irelated loop
@@ -402,8 +407,30 @@ namespace Lemma {
402 407
         // in the interests of making them as generic and reusable as possible. This approach requires slightly
403 408
         // more multiplies, but the same number of kernel evaluations, which is the expensive part.
404 409
         // Inner product and scale
405
-        for (int ir2=0; ir2<nrel; ++ir2) {
406
-            Zans(0, ir2) = Zwork.col(ir2).dot(WT201.col(KernelManager->GetSTLVector()[ir2]->GetBesselOrder() + 1))/rho;
410
+
411
+        for (int ilag=0; ilag<nlag; ++ilag) {
412
+            for (int ir2=0; ir2<nrel; ++ir2) {
413
+                //Zans(ilag, ir2) = Zwork.col(ir2).dot(WT201.col(KernelManager->GetSTLVector()[ir2]->GetBesselOrder() + 1))/rho;
414
+                Zans(ilag, ir2) = Zwork.col(ir2).dot(WT201.col(KernelManager->GetSTLVector()[ir2]->GetBesselOrder() + 1))/Arg(ilag);
415
+            }
416
+        }
417
+
418
+        // make sure vectors are empty
419
+        splineVecReal.clear();
420
+        splineVecImag.clear();
421
+
422
+        // Now do cubic spline
423
+        // TODO Check that knots are set in right order, Eigen has reverse()
424
+        //std::cout << "Arg\n" << Arg << std::endl;
425
+        //std::cout << "Zans\n" << Zans.col(0) << std::endl;
426
+        for (int ii=0; ii<Zans.cols(); ++ii) {
427
+            auto Spline = CubicSplineInterpolator::NewSP();
428
+            Spline->SetKnots( Arg, Zans.col(ii).real() );
429
+            splineVecReal.push_back(Spline);
430
+
431
+            auto SplineI = CubicSplineInterpolator::NewSP();
432
+            SplineI->SetKnots( Arg, Zans.col(ii).imag() );
433
+            splineVecImag.push_back(SplineI);
407 434
         }
408 435
 
409 436
         return ;
@@ -415,7 +442,7 @@ namespace Lemma {
415 442
     //      Method:  GetABSER
416 443
     //--------------------------------------------------------------------------------------
417 444
     Real FHTKey201::GetABSER (  ) {
418
-        return WT201(1,0)/WT201(0,0);
445
+        return WT201(0,0)/WT201(1,0);
419 446
     }		// -----  end of method FHTKey201::GetABSER  -----
420 447
 
421 448
 
@@ -431,5 +458,4 @@ namespace Lemma {
431 458
         return ;
432 459
     }		// -----  end of method FHTKey201::SetLaggedArg  -----
433 460
 
434
-
435 461
 }		// -----  end of Lemma  name  -----

+ 4
- 3
Modules/LemmaCore/src/CubicSplineInterpolator.cpp View File

@@ -178,9 +178,10 @@ namespace Lemma {
178 178
         }
179 179
         --i;
180 180
 
181
-        //if ( x > Spline.x[i] ) {
182
-        //    throw std::runtime_error("CubicSplineInterpolator::Interpolate ATTEMPT TO INTERPOLATE PAST LAST KNOT");
183
-        //}
181
+//         if ( x > Spline.x[i] ) {
182
+//             std::cout << "DOOM\t" << x << "\t" << i << "\t" << Spline.x[i];
183
+//             throw std::runtime_error("CubicSplineInterpolator::Interpolate ATTEMPT TO INTERPOLATE PAST LAST KNOT");
184
+//         }
184 185
 
185 186
         return Spline.a[i] + Spline.b[i]*(x-Spline.x[i]) + Spline.c[i]*((x-Spline.x[i])*(x-Spline.x[i])) +
186 187
                Spline.d[i]*((x-Spline.x[i])*(x-Spline.x[i])*(x-Spline.x[i]) );

Loading…
Cancel
Save