Browse Source

Adding more info into VTK files in kernel calculation.

master
T-bone 7 years ago
parent
commit
a626f6ce43
3 changed files with 47 additions and 25 deletions
  1. 4
    4
      examples/KernelV0-2.cpp
  2. 9
    5
      include/KernelV0.h
  3. 34
    16
      src/KernelV0.cpp

+ 4
- 4
examples/KernelV0-2.cpp View File

@@ -41,9 +41,9 @@ int main(int argc, char** argv) {
41 41
         Kern->PushCoil( "Coil 2", Rx1 );
42 42
         Kern->SetLayeredEarthEM( earth );
43 43
 
44
-        Kern->SetIntegrationSize( (Vector3r() << 200,200,100).finished() );
45
-        Kern->SetIntegrationOrigin( (Vector3r() << -100, -100, .5).finished() );
46
-        Real tol(1e-11); // 13
44
+        Kern->SetIntegrationSize( (Vector3r() << 20.2151538,20.438572,100).finished() );
45
+        Kern->SetIntegrationOrigin( (Vector3r() << -10, -10, .5).finished() );
46
+        Real tol(1e-13); // 13
47 47
         Kern->SetTolerance( tol ); // 1e-12
48 48
 
49 49
 //         Kern->AlignWithAkvoDataset( YAML::LoadFile(argv[2]) );
@@ -65,7 +65,7 @@ int main(int argc, char** argv) {
65 65
         //VectorXr interfaces = VectorXr::LinSpaced( 41, .5, 45.5 ); // nlay, low, high
66 66
         //VectorXr interfaces = VectorXr::LinSpaced( 61, .5, 45.5 ); // nlay, low, high
67 67
         VectorXr interfaces = VectorXr::LinSpaced( 2, .5, 45.5 ); // nlay, low, high
68
-        Real thick = .5;
68
+        Real thick = .1;
69 69
         for (int ilay=1; ilay<interfaces.size(); ++ilay) {
70 70
             interfaces(ilay) = interfaces(ilay-1) + thick;
71 71
             thick *= 1.05;

+ 9
- 5
include/KernelV0.h View File

@@ -34,11 +34,13 @@
34 34
 
35 35
 namespace Lemma {
36 36
 
37
+    // Holds the elliptic field construction of Bperp
38
+    // commented out variables are for error checking
37 39
     struct EllipticB {
38 40
         Real      alpha;
39 41
         Real      beta;
40 42
         Real      zeta;
41
-        Real      err;
43
+//        Real      err;
42 44
         Complex   eizt;
43 45
 //        Complex   BperpdotB;
44 46
         Vector3r  bhat;
@@ -188,7 +190,7 @@ namespace Lemma {
188 190
          *   @param[in] rx is the list of receivers to use for a kernel, use the same labels as
189 191
          *              used in PushCoil. @see PushCoil
190 192
          *   @param[in] vtkOutput generates a VTK hyperoctree file as well, useful for visualization.
191
-         *              requires compilation of Lemma with VTK.
193
+         *              requires compilation of Lemma with VTK. The VTK files can become very large.
192 194
          */
193 195
         void CalculateK0 (const std::vector< std::string >& tx, const std::vector< std::string >& rx,
194 196
                 bool vtkOutput=false );
@@ -306,9 +308,11 @@ namespace Lemma {
306 308
         std::map< std::string , std::shared_ptr< EMEarth1D > >             EMEarths;
307 309
 
308 310
         #ifdef LEMMAUSEVTK
309
-        std::map< int, VectorXcr  >               LeafDict;
310
-        std::map< int, int     >                  LeafDictIdx;
311
-        std::map< int, Real     >                 LeafDictErr;
311
+        std::map< int, VectorXcr >                LeafDict;      // kernel sum for each q
312
+        std::map< int, VectorXcr >                LeafHt;        // Transmitter field
313
+        std::map< int, VectorXcr >                LeafHr;        // Receiver field
314
+        std::map< int, int >                      LeafDictIdx;   // index
315
+        std::map< int, Real >                     LeafDictErr;   // error value
312 316
         #endif
313 317
 
314 318
         // Physical constants and conversion factors

+ 34
- 16
src/KernelV0.cpp View File

@@ -148,6 +148,7 @@ namespace Lemma {
148 148
                 EMEarths[tx]->AttachFieldPoints( cpoints );
149 149
          		EMEarths[tx]->SetFieldsToCalculate(H);
150 150
                 // TODO query for method, altough with flat antennae, this is fastest
151
+                //EMEarths[tx]->SetHankelTransformMethod(FHTKEY201);
151 152
                 EMEarths[tx]->SetHankelTransformMethod(ANDERSON801);
152 153
                 EMEarths[tx]->SetTxRxMode(TX);
153 154
                 TxRx[tx]->SetCurrent(1.);
@@ -162,6 +163,7 @@ namespace Lemma {
162 163
                     EMEarths[rx]->AttachFieldPoints( cpoints );
163 164
          		    EMEarths[rx]->SetFieldsToCalculate(H);
164 165
                     // TODO query for method, altough with flat antennae, this is fastest
166
+                    //EMEarths[rx]->SetHankelTransformMethod(FHTKEY201);
165 167
                     EMEarths[rx]->SetHankelTransformMethod(ANDERSON801);
166 168
                     EMEarths[rx]->SetTxRxMode(RX);
167 169
                     TxRx[rx]->SetCurrent(1.);
@@ -313,6 +315,7 @@ namespace Lemma {
313 315
             //Real sintheta = std::sin(0.5*GAMMA*PulseI(iq)*Taup*(EBT.alpha-EBT.beta));
314 316
             //F(iq) = volume * Complex(EBT.Bperp.real().norm(), EBT.Bperp.imag().norm()); //Complex(sintheta, EBT.Bperp.norm() );
315 317
             //F(iq) = volume * Complex(EBT.alpha, EBT.beta);
318
+            //F(iq) = volume * MU0*Hr.norm();
316 319
             //F(iq) = volume * EBT.err;
317 320
             //F(iq) = volume * sintheta;
318 321
         }
@@ -356,13 +359,20 @@ namespace Lemma {
356 359
     //      Method:  ComputeV0Cell
357 360
     //--------------------------------------------------------------------------------------
358 361
     EllipticB KernelV0::EllipticFieldRep (const Vector3cr& B, const Vector3r& B0hat) {
359
-        // This all follows Weichman et. al., 2000. There are some numerical stability isseus
360
-        // below. Reformulating may be welcome, may be in B field calculation too.
362
+        // This all follows Weichman et al., 2000.
363
+        // There are some numerical stability issues that arise when the two terms in the beta
364
+        // formulation are nearly equivalent. The current formulation will result in a null-valued
365
+        // beta, although this does not entirely recreate the true value of B perp.
366
+        // Reformulating may be welcome
361 367
         EllipticB ElipB = EllipticB();
362
-        Vector3cr Bperp = B - B0hat.dot(B)*B0hat; // complex - real??
368
+        Vector3cr Bperp = B - B0hat.dot(B)*B0hat; // Eigen is OK with this
369
+        //Vector3r  Bperpr = B.real() - B0hat.dot(B.real())*B0hat;
370
+        //Vector3r  Bperpi = B.imag() - B0hat.dot(B.imag())*B0hat;
371
+        //Vector3cr Bperp = Bperpr + Complex(0,1)*Bperpi;
363 372
         //ElipB.BperpdotB = Bperp.dot(B0hat);       // TODO remove
364 373
         Real BperpNorm  = Bperp.norm();
365
-        Complex Bp2 = Bperp.transpose() * Bperp;
374
+        //Complex Bp2 = Bperp.transpose() * Bperp;
375
+        Complex Bp2 = Bperp.conjugate().dot(Bperp);
366 376
         VectorXcr iB0 = Complex(0,1)*B0hat.cast<Complex>().array();
367 377
         ElipB.eizt = std::sqrt(Bp2 / std::abs(Bp2));
368 378
         ElipB.alpha = INVSQRT2*std::sqrt(BperpNorm*BperpNorm + std::abs(Bp2));
@@ -372,16 +382,24 @@ namespace Lemma {
372 382
         ElipB.bhatp = B0hat.cross(ElipB.bhat);
373 383
         ElipB.zeta = std::real(std::log(ElipB.eizt)/Complex(0,1));
374 384
         /* use as an error check decomposed field - computed actual */
375
-        Vector3cr Bperp2 = ElipB.eizt * (ElipB.alpha * ElipB.bhat
376
-                       + (Complex(0,1) * ElipB.beta * ElipB.bhatp) );
377
-        ElipB.err = (Bperp-Bperp2).norm();
378
-        if (ElipB.err > 1e-12) {
379
-            std::cout << "Elip error\n";
380
-            std::cout << "Bperp \t" << Bperp.transpose() << std::endl;
381
-            std::cout << "Bperp2\t" << Bperp2.transpose() << std::endl;
382
-            std::cout << "err   \t" << ElipB.err << std::endl;
383
-        }
384
-        //std::cout << "B0\t" << B0hat.transpose() << std::endl;
385
+//         Vector3cr Bperp2 = ElipB.eizt * (ElipB.alpha * ElipB.bhat
386
+//                        + (Complex(0,1) * ElipB.beta * ElipB.bhatp) );
387
+//         ElipB.err = (Bperp-Bperp2).norm();
388
+//         if (ElipB.err > .01*Bperp.norm() ) {
389
+//             std::cout << "Elip error\n";
390
+//             Real Beta2 = sgn( std::real(iB0.dot( Bperp.cross(Bperp.conjugate())) )) *
391
+//                      (INVSQRT2*std::sqrt(BperpNorm*BperpNorm - std::abs(Bp2)));
392
+//             Vector3cr Bperp3 = ElipB.eizt * (ElipB.alpha * ElipB.bhat
393
+//                            + (Complex(0,1) * Beta2 * ElipB.bhatp) );
394
+//             std::cout << "Beta term0\t" << (INVSQRT2*std::sqrt(BperpNorm*BperpNorm - std::abs(Bp2))) << std::endl;
395
+//             std::cout << "Beta term1\t" << BperpNorm*BperpNorm << "\t" << std::abs(Bp2) << std::endl;
396
+//             std::cout << "Beta  \t" << ElipB.beta << std::endl;
397
+//             std::cout << "Beta2 \t" << Beta2 << std::endl;
398
+//             std::cout << "Bperp \t" << Bperp.transpose() << std::endl;
399
+//             std::cout << "Bperp2\t" << Bperp2.transpose() << std::endl;
400
+//             std::cout << "Bperp3\t" << Bperp3.transpose() << std::endl;
401
+//             std::cout << "err   \t" << ElipB.err << std::endl;
402
+//         }
385 403
         return ElipB;
386 404
     }
387 405
 
@@ -423,8 +441,6 @@ namespace Lemma {
423 441
         Eigen::Matrix<Complex, 3, 8> Hr = Eigen::Matrix<Complex, 3, 8>::Zero();
424 442
         for ( auto EMCalc : EMEarths ) {
425 443
 
426
-
427
-
428 444
             EMCalc.second->GetFieldPoints()->ClearFields();
429 445
             EMCalc.second->CalculateWireAntennaFields();
430 446
             switch (EMCalc.second->GetTxRxMode()) {
@@ -565,6 +581,8 @@ namespace Lemma {
565 581
         for (int ichild=0; ichild<8; ++ichild) {
566 582
             curse->ToChild(ichild);
567 583
             LeafDict[curse->GetLeafId()] = ksum/(8.*vol);
584
+            LeafHt[curse->GetLeafId()] = Ht.col(ichild);
585
+            LeafHr[curse->GetLeafId()] = Hr.col(ichild);
568 586
             LeafDictIdx[curse->GetLeafId()] = nleaves;
569 587
             curse->ToParent();
570 588
         }

Loading…
Cancel
Save