瀏覽代碼

Kernel calculation seems to be working.

master
Trevor Irons 8 年之前
父節點
當前提交
79e743c9c6
共有 3 個檔案被更改,包括 100 行新增41 行删除
  1. 10
    11
      examples/KernelV0.cpp
  2. 54
    5
      include/KernelV0.h
  3. 36
    25
      src/KernelV0.cpp

+ 10
- 11
examples/KernelV0.cpp 查看文件

@@ -33,8 +33,8 @@ int main() {
33 33
         earth->SetMagneticFieldIncDecMag( 67, 0, 52750, NANOTESLA );
34 34
 
35 35
     // Transmitter loops
36
-    auto Tx1 = CircularLoop(65, 15, 100, 100);
37
-    auto Tx2 = CircularLoop(65, 15, 100, 120);
36
+    auto Tx1 = CircularLoop(31, 15, 100, 100);
37
+    auto Tx2 = CircularLoop(31, 15, 100, 120);
38 38
     //auto Tx1 = CircularLoop(60, 15, 0, 0); // was 60
39 39
 
40 40
     auto Kern = KernelV0::NewSP();
@@ -43,20 +43,19 @@ int main() {
43 43
         Kern->SetLayeredEarthEM( earth );
44 44
         // std::cout << *Kern << std::endl;
45 45
 
46
-        // Kern->SetPulseDuration();
47
-        // Kern->SetPulseCurrent();
48
-        // Kern->SetPulseMoments();
49
-        // Kern->SetDepthLayers();
50
-        // Kern->SetIntegrationOrigin();
51
-        // Kern->SetIntegrationSize();
46
+        Kern->SetIntegrationSize( (Vector3r() << 200,200,2).finished() );
47
+        Kern->SetIntegrationOrigin( (Vector3r() << 0,0,15).finished() );
48
+        Kern->SetTolerance( 1e-11 );
52 49
 
50
+        Kern->SetPulseDuration(0.020);
51
+        Kern->SetPulseCurrent( VectorXr::LinSpaced( 20, .01, 200 )  ); // nbins, low, high
52
+        Kern->SetDepthLayerInterfaces( VectorXr::LinSpaced( 20, .5, 50 ) );
53 53
 
54 54
     // We could, I suppose, take the earth model in here? For non-linear that
55 55
     // may be more natural to work with?
56 56
     std::vector<std::string> tx = {std::string("Coil 1")};
57 57
     std::vector<std::string> rx = {std::string("Coil 1")};
58
-    Kern->CalculateK0( tx, rx , true ); //, false );
59
-    //Kern->CalculateK0( "Coil 1", "Coil 1" );
58
+    Kern->CalculateK0( tx, rx, true );
60 59
 
61 60
 }
62 61
 
@@ -75,7 +74,7 @@ std::shared_ptr<Lemma::PolygonalWireAntenna> CircularLoop ( int nd, Real Radius,
75 74
     Tx1->SetCurrent(1.);
76 75
     Tx1->SetNumberOfTurns(1);
77 76
     Tx1->SetNumberOfFrequencies(1);
78
-    Tx1->SetFrequency(0,2500);
77
+    Tx1->SetFrequency(0,2246);
79 78
 
80 79
     return Tx1;
81 80
 }

+ 54
- 5
include/KernelV0.h 查看文件

@@ -135,6 +135,30 @@ namespace Lemma {
135 135
         }		// -----  end of method KernelV0::set_SigmaModel  -----
136 136
 
137 137
         /**
138
+         *
139
+         */
140
+        inline void SetIntegrationSize ( const Vector3r& size ) {
141
+            Size = size;
142
+            return ;
143
+        }		// -----  end of method KernelV0::SetIntegrationSize  -----
144
+
145
+        /**
146
+         *
147
+         */
148
+        inline void SetIntegrationOrigin ( const Vector3r& origin ) {
149
+            Origin = origin;
150
+            return ;
151
+        }		// -----  end of method KernelV0::SetIntegrationOrigin  -----
152
+
153
+        /**
154
+         *
155
+         */
156
+        inline void SetPulseCurrent ( const VectorXr& Amps ) {
157
+            PulseI = Amps;
158
+            return ;
159
+        }		// -----  end of method KernelV0::SetIntegrationOrigin  -----
160
+
161
+        /**
138 162
          *   Assign transmiter coils
139 163
          */
140 164
         inline void PushCoil( const std::string& label, std::shared_ptr<PolygonalWireAntenna> ant ) {
@@ -158,10 +182,26 @@ namespace Lemma {
158 182
          *  Sets the temperature, which has implications in calculation of \f$ M_N^{(0)}\f$. Units in
159 183
          *  Kelvin.
160 184
          */
161
-        void SetTemperature(const Real& tempK) {
185
+        inline void SetTemperature(const Real& tempK) {
162 186
             Temperature = tempK;
163 187
         }
164 188
 
189
+        /**
190
+         *  Sets the tolerance to use for making the adaptive mesh
191
+         *
192
+         */
193
+        inline void SetTolerance(const Real& ttol) {
194
+            tol = ttol;
195
+        }
196
+
197
+        inline void SetPulseDuration(const Real& taup) {
198
+            Taup = taup;
199
+        }
200
+
201
+        inline void SetDepthLayerInterfaces( const VectorXr& iface ){
202
+            Interfaces = iface;
203
+        }
204
+
165 205
         // ====================  INQUIRY       =======================
166 206
         /**
167 207
          *  Returns the name of the underlying class, similiar to Python's type
@@ -196,7 +236,7 @@ namespace Lemma {
196 236
 
197 237
         Vector3r ComputeMn0(const Real& Porosity, const Vector3r& B0);
198 238
 
199
-        void IntegrateOnOctreeGrid( const Real& tolerance , bool vtkOutput=false );
239
+        Complex IntegrateOnOctreeGrid( const int& ilay, const int& iq, bool vtkOutput=false );
200 240
 
201 241
         /**
202 242
          *  Recursive call to integrate a function on an adaptive Octree Grid.
@@ -225,15 +265,23 @@ namespace Lemma {
225 265
         // ====================  DATA MEMBERS  =========================
226 266
 
227 267
         int                                       nleaves;
268
+        int                                       minLevel=3;
269
+        int                                       maxLevel=10;
228 270
 
229 271
         Real                                      VOLSUM;
230
-        Real                                      tol=1e-3;
272
+        Real                                      tol=1e-11;
231 273
         Real                                      Temperature=283.;
274
+        Real                                      Taup = .020;  // Sec
275
+        Real                                      Ip = 10;      // Amps
276
+        Real                                      Larmor;
232 277
 
233 278
         Complex                                   SUM;
234 279
 
235
-        Vector3r   Size;
236
-        Vector3r   Origin;
280
+        Vector3r                                  Size;
281
+        Vector3r                                  Origin;
282
+
283
+        VectorXr   PulseI;
284
+        VectorXr   Interfaces;
237 285
 
238 286
         std::shared_ptr< LayeredEarthEM >         SigmaModel = nullptr;
239 287
 
@@ -245,6 +293,7 @@ namespace Lemma {
245 293
 
246 294
         #ifdef LEMMAUSEVTK
247 295
         std::map< int, Complex  >                 LeafDict;
296
+        std::map< int, int     >                  LeafDictIdx;
248 297
         std::map< int, Real     >                 LeafDictErr;
249 298
         #endif
250 299
 

+ 36
- 25
src/KernelV0.cpp 查看文件

@@ -105,6 +105,9 @@ namespace Lemma {
105 105
     void KernelV0::CalculateK0 (const std::vector< std::string>& Tx, const std::vector<std::string >& Rx,
106 106
             bool vtkOutput ) {
107 107
 
108
+        // Set up
109
+        Larmor = SigmaModel->GetMagneticFieldMagnitude()*GAMMA; // in rad  2246.*2.*PI;
110
+
108 111
         // All EM calculations will share same field points
109 112
         cpoints = FieldPoints::NewSP();
110 113
             cpoints->SetNumberOfPoints(8);
@@ -133,24 +136,30 @@ namespace Lemma {
133 136
                     EMEarths[rx]->SetTxRxMode(RX);
134 137
             }
135 138
         }
136
-        IntegrateOnOctreeGrid( 1e-13, vtkOutput );
139
+
140
+        std::cout << "Calculating K0 kernel\n";
141
+        MatrixXcr Kern = MatrixXcr::Zero( Interfaces.size() - 1, PulseI.size() );
142
+        for (int ilay=0; ilay< Interfaces.size()-1; ++ilay) {
143
+            for (int iq=0; iq< PulseI.size()-1; ++iq) {
144
+                std::cout << "Layer " << ilay << " q " << iq << std::endl;
145
+                Size(2) = Interfaces(ilay+1) - Interfaces(ilay);
146
+                Origin(2) = Interfaces(ilay);
147
+                Ip = PulseI(iq);
148
+                Kern(ilay, iq) = IntegrateOnOctreeGrid( ilay, iq, vtkOutput );
149
+            }
150
+        }
151
+        std::cout << "\rFinished KERNEL\n";
152
+        std::cout << Kern << std::endl;
153
+        //IntegrateOnOctreeGrid( vtkOutput );
137 154
     }
138 155
 
139 156
     //--------------------------------------------------------------------------------------
140 157
     //       Class:  KernelV0
141 158
     //      Method:  IntegrateOnOctreeGrid
142 159
     //--------------------------------------------------------------------------------------
143
-    void KernelV0::IntegrateOnOctreeGrid( const Real& tolerance, bool vtkOutput) {
160
+    Complex KernelV0::IntegrateOnOctreeGrid( const int& ilay, const int& iq, bool vtkOutput) {
144 161
 
145
-        this->tol = tolerance;
146
-        //Vector3r                Size;
147
-            Size << 200,200,2;
148
-        //Vector3r                Origin;
149
-            Origin << 0,0,5.0;
150
-        Vector3r                cpos;  // centre position
151
-            //cpos << 100,100,50;
152
-            cpos = (Size-Origin).array() / 2.;
153
-        int                     maxlevel;
162
+        Vector3r cpos = (Size-Origin).array() / 2.;
154 163
 
155 164
         SUM = 0;
156 165
         VOLSUM = 0;
@@ -184,30 +193,33 @@ namespace Lemma {
184 193
                 kid->SetNumberOfComponents(1);
185 194
                 kid->SetName("ID");
186 195
                 kid->SetNumberOfTuples( oct->GetNumberOfLeaves() );
187
-            //vtkDoubleArray* kerr = vtkDoubleArray::New();
188
-            //    kerr->SetNumberOfComponents(1);
189
-            //    kerr->SetName("Error");
196
+            vtkIntArray* kerr = vtkIntArray::New();
197
+                kerr->SetNumberOfComponents(1);
198
+                kerr->SetName("nleaf");
190 199
 
191 200
             for (auto leaf : LeafDict) {
192 201
                 kr->InsertTuple1( leaf.first, std::real(leaf.second) );
193 202
                 ki->InsertTuple1( leaf.first, std::imag(leaf.second) );
203
+                km->InsertTuple1( leaf.first, std::abs(leaf.second) );
194 204
                 kid->InsertTuple1( leaf.first, leaf.first );
195 205
             }
196 206
 
197
-            //for (auto leaf : LeafDictErr) {
198
-            //    kerr->InsertTuple1( leaf.first, std::imag(leaf.second) );
199
-            //}
207
+            for (auto leaf : LeafDictIdx) {
208
+                kerr->InsertTuple1( leaf.first, leaf.second );
209
+            }
200 210
 
201 211
             oct->GetLeafData()->AddArray(kr);
202 212
             oct->GetLeafData()->AddArray(ki);
203 213
             oct->GetLeafData()->AddArray(km);
204 214
             oct->GetLeafData()->AddArray(kid);
205
-            //oct->GetLeafData()->AddArray(kerr);
215
+            oct->GetLeafData()->AddArray(kerr);
206 216
 
207 217
             auto write = vtkXMLHyperOctreeWriter::New();
208 218
                 //write.SetDataModeToAscii()
209 219
                 write->SetInputData(oct);
210
-                write->SetFileName("octree.vto");
220
+                std::string fname = std::string("octree-") + to_string(ilay)
221
+                                  + std::string("-") + to_string(iq) + std::string(".vto");
222
+                write->SetFileName(fname.c_str());
211 223
                 write->Write();
212 224
                 write->Delete();
213 225
 
@@ -228,6 +240,7 @@ namespace Lemma {
228 240
         std::cout << "nleaves\t" << nleaves << std::endl;
229 241
         std::cout << "KSUM\t" << SUM << std::endl;
230 242
 
243
+        return SUM;
231 244
     }
232 245
 
233 246
     //--------------------------------------------------------------------------------------
@@ -258,9 +271,6 @@ namespace Lemma {
258 271
         Vector3r Mn0 = ComputeMn0(phi, B0);
259 272
         Real Mn0Abs = Mn0.norm();
260 273
 
261
-        Real Taup = 0.020; // s
262
-        Real Ip   = 10;      // A
263
-
264 274
         // Compute the tipping angle
265 275
         Real sintheta = std::sin(0.5*GAMMA*Ip*Taup*std::abs(EBT.alpha-EBT.beta));
266 276
 
@@ -279,7 +289,6 @@ namespace Lemma {
279 289
                 const Real& vol) {
280 290
 
281 291
         Vector3r B0hat = {1,0,0};
282
-        Real Larmor = 2500.*2.*PI;
283 292
 
284 293
         // earth response of receiver adjoint field
285 294
         Complex ejztr = std::exp(Complex(0, EBR.zeta + EBT.zeta));
@@ -384,7 +393,7 @@ namespace Lemma {
384 393
 
385 394
         Complex ksum = kvals.sum();     // Kernel sum
386 395
         // Evaluate whether or not furthur splitting is needed
387
-        if ( std::abs(ksum - parentVal) > tol || level < 2 ) {
396
+        if ( std::abs(ksum - parentVal) > tol || level < minLevel && level < maxLevel ) {
388 397
             for (int ichild=0; ichild<8; ++ichild) {
389 398
                 Vector3r cp = pos; // Eigen complains about combining these
390 399
                 cp += posadd.row(ichild);
@@ -467,7 +476,8 @@ namespace Lemma {
467 476
 
468 477
         Complex ksum = kvals.sum();     // Kernel sum
469 478
         // Evaluate whether or not furthur splitting is needed
470
-        if ( std::abs(ksum - parentVal) > tol || level < 2 ) {
479
+        Real err = std::abs(ksum - parentVal);
480
+        if ( std::abs(ksum - parentVal) > tol || level < minLevel && level < maxLevel ) {
471 481
             oct->SubdivideLeaf(curse);
472 482
             for (int ichild=0; ichild<8; ++ichild) {
473 483
                 curse->ToChild(ichild);
@@ -482,6 +492,7 @@ namespace Lemma {
482 492
                 bool isleaf = EvaluateKids2( size, level+1, cp, kvals(ichild), oct, curse );
483 493
                 if (isleaf) {  // Include result in final integral
484 494
                     LeafDict[curse->GetLeafId()] = kvals(ichild);       // VTK
495
+                    LeafDictIdx[curse->GetLeafId()] = nleaves;          // VTK
485 496
                     SUM += ksum;
486 497
                     VOLSUM += 8*vol;
487 498
                     nleaves += 1;

Loading…
取消
儲存