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

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

69
                 /** Returns the name of the underlying class, similiar to Python's type */
69
                 /** Returns the name of the underlying class, similiar to Python's type */
70
                 virtual inline std::string GetName() const = 0 ;
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
                 // ====================  DATA MEMBERS  =======================
80
                 // ====================  DATA MEMBERS  =======================
73
 
81
 
74
             protected:
82
             protected:

+ 140
- 0
Modules/FDEM1D/include/HankelTransformFactory.h View File

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

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

376
     //      Method:  ComputeLaggedRelated
376
     //      Method:  ComputeLaggedRelated
377
     //--------------------------------------------------------------------------------------
377
     //--------------------------------------------------------------------------------------
378
     void FHTKey201::ComputeLaggedRelated ( const Real& rho, const int& nlag, std::shared_ptr<KernelEM1DManager> KernelManager ) {
378
     void FHTKey201::ComputeLaggedRelated ( const Real& rho, const int& nlag, std::shared_ptr<KernelEM1DManager> KernelManager ) {
379
-
380
         int nrel = (int)(KernelManager->GetSTLVector().size());
379
         int nrel = (int)(KernelManager->GetSTLVector().size());
381
         Eigen::Matrix<Complex, 201, Eigen::Dynamic > Zwork;
380
         Eigen::Matrix<Complex, 201, Eigen::Dynamic > Zwork;
382
         Zans= Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic>::Zero(nlag, nrel);
381
         Zans= Eigen::Matrix<Complex, Eigen::Dynamic, Eigen::Dynamic>::Zero(nlag, nrel);
385
         int NumFun = 0;
384
         int NumFun = 0;
386
         int idx = 0;
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
         // Get Kernel values
393
         // Get Kernel values
389
         for (int ir=0; ir<lambda.size(); ++ir) {
394
         for (int ir=0; ir<lambda.size(); ++ir) {
390
             // irelated loop
395
             // irelated loop
402
         // in the interests of making them as generic and reusable as possible. This approach requires slightly
407
         // in the interests of making them as generic and reusable as possible. This approach requires slightly
403
         // more multiplies, but the same number of kernel evaluations, which is the expensive part.
408
         // more multiplies, but the same number of kernel evaluations, which is the expensive part.
404
         // Inner product and scale
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
         return ;
436
         return ;
415
     //      Method:  GetABSER
442
     //      Method:  GetABSER
416
     //--------------------------------------------------------------------------------------
443
     //--------------------------------------------------------------------------------------
417
     Real FHTKey201::GetABSER (  ) {
444
     Real FHTKey201::GetABSER (  ) {
418
-        return WT201(1,0)/WT201(0,0);
445
+        return WT201(0,0)/WT201(1,0);
419
     }		// -----  end of method FHTKey201::GetABSER  -----
446
     }		// -----  end of method FHTKey201::GetABSER  -----
420
 
447
 
421
 
448
 
431
         return ;
458
         return ;
432
     }		// -----  end of method FHTKey201::SetLaggedArg  -----
459
     }		// -----  end of method FHTKey201::SetLaggedArg  -----
433
 
460
 
434
-
435
 }		// -----  end of Lemma  name  -----
461
 }		// -----  end of Lemma  name  -----

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

178
         }
178
         }
179
         --i;
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
         return Spline.a[i] + Spline.b[i]*(x-Spline.x[i]) + Spline.c[i]*((x-Spline.x[i])*(x-Spline.x[i])) +
186
         return Spline.a[i] + Spline.b[i]*(x-Spline.x[i]) + Spline.c[i]*((x-Spline.x[i])*(x-Spline.x[i])) +
186
                Spline.d[i]*((x-Spline.x[i])*(x-Spline.x[i])*(x-Spline.x[i]) );
187
                Spline.d[i]*((x-Spline.x[i])*(x-Spline.x[i])*(x-Spline.x[i]) );

Loading…
Cancel
Save