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
         Kern->PushCoil( "Coil 2", Rx1 );
41
         Kern->PushCoil( "Coil 2", Rx1 );
42
         Kern->SetLayeredEarthEM( earth );
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
         Kern->SetTolerance( tol ); // 1e-12
47
         Kern->SetTolerance( tol ); // 1e-12
48
 
48
 
49
 //         Kern->AlignWithAkvoDataset( YAML::LoadFile(argv[2]) );
49
 //         Kern->AlignWithAkvoDataset( YAML::LoadFile(argv[2]) );
65
         //VectorXr interfaces = VectorXr::LinSpaced( 41, .5, 45.5 ); // nlay, low, high
65
         //VectorXr interfaces = VectorXr::LinSpaced( 41, .5, 45.5 ); // nlay, low, high
66
         //VectorXr interfaces = VectorXr::LinSpaced( 61, .5, 45.5 ); // nlay, low, high
66
         //VectorXr interfaces = VectorXr::LinSpaced( 61, .5, 45.5 ); // nlay, low, high
67
         VectorXr interfaces = VectorXr::LinSpaced( 2, .5, 45.5 ); // nlay, low, high
67
         VectorXr interfaces = VectorXr::LinSpaced( 2, .5, 45.5 ); // nlay, low, high
68
-        Real thick = .5;
68
+        Real thick = .1;
69
         for (int ilay=1; ilay<interfaces.size(); ++ilay) {
69
         for (int ilay=1; ilay<interfaces.size(); ++ilay) {
70
             interfaces(ilay) = interfaces(ilay-1) + thick;
70
             interfaces(ilay) = interfaces(ilay-1) + thick;
71
             thick *= 1.05;
71
             thick *= 1.05;

+ 9
- 5
include/KernelV0.h View File

34
 
34
 
35
 namespace Lemma {
35
 namespace Lemma {
36
 
36
 
37
+    // Holds the elliptic field construction of Bperp
38
+    // commented out variables are for error checking
37
     struct EllipticB {
39
     struct EllipticB {
38
         Real      alpha;
40
         Real      alpha;
39
         Real      beta;
41
         Real      beta;
40
         Real      zeta;
42
         Real      zeta;
41
-        Real      err;
43
+//        Real      err;
42
         Complex   eizt;
44
         Complex   eizt;
43
 //        Complex   BperpdotB;
45
 //        Complex   BperpdotB;
44
         Vector3r  bhat;
46
         Vector3r  bhat;
188
          *   @param[in] rx is the list of receivers to use for a kernel, use the same labels as
190
          *   @param[in] rx is the list of receivers to use for a kernel, use the same labels as
189
          *              used in PushCoil. @see PushCoil
191
          *              used in PushCoil. @see PushCoil
190
          *   @param[in] vtkOutput generates a VTK hyperoctree file as well, useful for visualization.
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
         void CalculateK0 (const std::vector< std::string >& tx, const std::vector< std::string >& rx,
195
         void CalculateK0 (const std::vector< std::string >& tx, const std::vector< std::string >& rx,
194
                 bool vtkOutput=false );
196
                 bool vtkOutput=false );
306
         std::map< std::string , std::shared_ptr< EMEarth1D > >             EMEarths;
308
         std::map< std::string , std::shared_ptr< EMEarth1D > >             EMEarths;
307
 
309
 
308
         #ifdef LEMMAUSEVTK
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
         #endif
316
         #endif
313
 
317
 
314
         // Physical constants and conversion factors
318
         // Physical constants and conversion factors

+ 34
- 16
src/KernelV0.cpp View File

148
                 EMEarths[tx]->AttachFieldPoints( cpoints );
148
                 EMEarths[tx]->AttachFieldPoints( cpoints );
149
          		EMEarths[tx]->SetFieldsToCalculate(H);
149
          		EMEarths[tx]->SetFieldsToCalculate(H);
150
                 // TODO query for method, altough with flat antennae, this is fastest
150
                 // TODO query for method, altough with flat antennae, this is fastest
151
+                //EMEarths[tx]->SetHankelTransformMethod(FHTKEY201);
151
                 EMEarths[tx]->SetHankelTransformMethod(ANDERSON801);
152
                 EMEarths[tx]->SetHankelTransformMethod(ANDERSON801);
152
                 EMEarths[tx]->SetTxRxMode(TX);
153
                 EMEarths[tx]->SetTxRxMode(TX);
153
                 TxRx[tx]->SetCurrent(1.);
154
                 TxRx[tx]->SetCurrent(1.);
162
                     EMEarths[rx]->AttachFieldPoints( cpoints );
163
                     EMEarths[rx]->AttachFieldPoints( cpoints );
163
          		    EMEarths[rx]->SetFieldsToCalculate(H);
164
          		    EMEarths[rx]->SetFieldsToCalculate(H);
164
                     // TODO query for method, altough with flat antennae, this is fastest
165
                     // TODO query for method, altough with flat antennae, this is fastest
166
+                    //EMEarths[rx]->SetHankelTransformMethod(FHTKEY201);
165
                     EMEarths[rx]->SetHankelTransformMethod(ANDERSON801);
167
                     EMEarths[rx]->SetHankelTransformMethod(ANDERSON801);
166
                     EMEarths[rx]->SetTxRxMode(RX);
168
                     EMEarths[rx]->SetTxRxMode(RX);
167
                     TxRx[rx]->SetCurrent(1.);
169
                     TxRx[rx]->SetCurrent(1.);
313
             //Real sintheta = std::sin(0.5*GAMMA*PulseI(iq)*Taup*(EBT.alpha-EBT.beta));
315
             //Real sintheta = std::sin(0.5*GAMMA*PulseI(iq)*Taup*(EBT.alpha-EBT.beta));
314
             //F(iq) = volume * Complex(EBT.Bperp.real().norm(), EBT.Bperp.imag().norm()); //Complex(sintheta, EBT.Bperp.norm() );
316
             //F(iq) = volume * Complex(EBT.Bperp.real().norm(), EBT.Bperp.imag().norm()); //Complex(sintheta, EBT.Bperp.norm() );
315
             //F(iq) = volume * Complex(EBT.alpha, EBT.beta);
317
             //F(iq) = volume * Complex(EBT.alpha, EBT.beta);
318
+            //F(iq) = volume * MU0*Hr.norm();
316
             //F(iq) = volume * EBT.err;
319
             //F(iq) = volume * EBT.err;
317
             //F(iq) = volume * sintheta;
320
             //F(iq) = volume * sintheta;
318
         }
321
         }
356
     //      Method:  ComputeV0Cell
359
     //      Method:  ComputeV0Cell
357
     //--------------------------------------------------------------------------------------
360
     //--------------------------------------------------------------------------------------
358
     EllipticB KernelV0::EllipticFieldRep (const Vector3cr& B, const Vector3r& B0hat) {
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
         EllipticB ElipB = EllipticB();
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
         //ElipB.BperpdotB = Bperp.dot(B0hat);       // TODO remove
372
         //ElipB.BperpdotB = Bperp.dot(B0hat);       // TODO remove
364
         Real BperpNorm  = Bperp.norm();
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
         VectorXcr iB0 = Complex(0,1)*B0hat.cast<Complex>().array();
376
         VectorXcr iB0 = Complex(0,1)*B0hat.cast<Complex>().array();
367
         ElipB.eizt = std::sqrt(Bp2 / std::abs(Bp2));
377
         ElipB.eizt = std::sqrt(Bp2 / std::abs(Bp2));
368
         ElipB.alpha = INVSQRT2*std::sqrt(BperpNorm*BperpNorm + std::abs(Bp2));
378
         ElipB.alpha = INVSQRT2*std::sqrt(BperpNorm*BperpNorm + std::abs(Bp2));
372
         ElipB.bhatp = B0hat.cross(ElipB.bhat);
382
         ElipB.bhatp = B0hat.cross(ElipB.bhat);
373
         ElipB.zeta = std::real(std::log(ElipB.eizt)/Complex(0,1));
383
         ElipB.zeta = std::real(std::log(ElipB.eizt)/Complex(0,1));
374
         /* use as an error check decomposed field - computed actual */
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
         return ElipB;
403
         return ElipB;
386
     }
404
     }
387
 
405
 
423
         Eigen::Matrix<Complex, 3, 8> Hr = Eigen::Matrix<Complex, 3, 8>::Zero();
441
         Eigen::Matrix<Complex, 3, 8> Hr = Eigen::Matrix<Complex, 3, 8>::Zero();
424
         for ( auto EMCalc : EMEarths ) {
442
         for ( auto EMCalc : EMEarths ) {
425
 
443
 
426
-
427
-
428
             EMCalc.second->GetFieldPoints()->ClearFields();
444
             EMCalc.second->GetFieldPoints()->ClearFields();
429
             EMCalc.second->CalculateWireAntennaFields();
445
             EMCalc.second->CalculateWireAntennaFields();
430
             switch (EMCalc.second->GetTxRxMode()) {
446
             switch (EMCalc.second->GetTxRxMode()) {
565
         for (int ichild=0; ichild<8; ++ichild) {
581
         for (int ichild=0; ichild<8; ++ichild) {
566
             curse->ToChild(ichild);
582
             curse->ToChild(ichild);
567
             LeafDict[curse->GetLeafId()] = ksum/(8.*vol);
583
             LeafDict[curse->GetLeafId()] = ksum/(8.*vol);
584
+            LeafHt[curse->GetLeafId()] = Ht.col(ichild);
585
+            LeafHr[curse->GetLeafId()] = Hr.col(ichild);
568
             LeafDictIdx[curse->GetLeafId()] = nleaves;
586
             LeafDictIdx[curse->GetLeafId()] = nleaves;
569
             curse->ToParent();
587
             curse->ToParent();
570
         }
588
         }

Loading…
Cancel
Save