|
@@ -282,6 +282,7 @@ namespace Lemma {
|
282
|
282
|
// Class: KernelV0
|
283
|
283
|
// Method: f
|
284
|
284
|
//--------------------------------------------------------------------------------------
|
|
285
|
+#if 1
|
285
|
286
|
VectorXcr KernelV0::f( const Vector3r& r, const Real& volume, const Vector3cr& Ht, const Vector3cr& Hr ) {
|
286
|
287
|
|
287
|
288
|
// Compute the elliptic fields
|
|
@@ -294,6 +295,7 @@ namespace Lemma {
|
294
|
295
|
|
295
|
296
|
// Compute Mn0
|
296
|
297
|
Vector3r Mn0 = ComputeMn0(1.0, B0);
|
|
298
|
+ //std::cout << "Mn0\t" << Mn0.transpose() << std::endl;
|
297
|
299
|
Real Mn0Abs = Mn0.norm();
|
298
|
300
|
|
299
|
301
|
// Compute phase delay
|
|
@@ -305,11 +307,26 @@ namespace Lemma {
|
305
|
307
|
VectorXcr F = VectorXcr::Zero( PulseI.size() );
|
306
|
308
|
for (int iq=0; iq<PulseI.size(); ++iq) {
|
307
|
309
|
// Compute the tipping angle
|
308
|
|
- Real sintheta = std::sin(0.5*GAMMA*PulseI(iq)*Taup*(EBT.alpha-EBT.beta)); // why std::abs
|
|
310
|
+ Real sintheta = std::sin(0.5*GAMMA*PulseI(iq)*Taup*(EBT.alpha-EBT.beta));
|
309
|
311
|
F(iq) = -volume*Complex(0,Larmor)*Mn0Abs*(EBR.alpha+EBR.beta)*ejztr*sintheta*PhaseTerm;
|
|
312
|
+ //TODO TEST FOR ASYMETRY
|
|
313
|
+ //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() );
|
|
315
|
+ //F(iq) = volume * Complex(EBT.alpha, EBT.beta);
|
|
316
|
+ //F(iq) = volume * EBT.err;
|
|
317
|
+ //F(iq) = volume * sintheta;
|
310
|
318
|
}
|
|
319
|
+
|
|
320
|
+ return F;
|
|
321
|
+ }
|
|
322
|
+#endif
|
|
323
|
+#if 0
|
|
324
|
+ VectorXcr KernelV0::f( const Vector3r& r, const Real& volume, const Vector3cr& Ht, const Vector3cr& Hr ) {
|
|
325
|
+ VectorXcr F = VectorXcr::Ones( PulseI.size() );
|
|
326
|
+ F.array() *= volume * Complex(Ht.norm(), Hr.norm()); //*Ht.dot(Hr);
|
311
|
327
|
return F;
|
312
|
328
|
}
|
|
329
|
+#endif
|
313
|
330
|
|
314
|
331
|
// //--------------------------------------------------------------------------------------
|
315
|
332
|
// // Class: KernelV0
|
|
@@ -339,18 +356,32 @@ namespace Lemma {
|
339
|
356
|
// Method: ComputeV0Cell
|
340
|
357
|
//--------------------------------------------------------------------------------------
|
341
|
358
|
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.
|
342
|
361
|
EllipticB ElipB = EllipticB();
|
343
|
|
- Vector3cr Bperp = B.array() - B0hat.dot(B)*B0hat.array();
|
344
|
|
- Real BperpNorm = Bperp.norm();
|
|
362
|
+ Vector3cr Bperp = B - B0hat.dot(B)*B0hat; // complex - real??
|
|
363
|
+ //ElipB.BperpdotB = Bperp.dot(B0hat); // TODO remove
|
|
364
|
+ Real BperpNorm = Bperp.norm();
|
345
|
365
|
Complex Bp2 = Bperp.transpose() * Bperp;
|
346
|
366
|
VectorXcr iB0 = Complex(0,1)*B0hat.cast<Complex>().array();
|
347
|
367
|
ElipB.eizt = std::sqrt(Bp2 / std::abs(Bp2));
|
348
|
368
|
ElipB.alpha = INVSQRT2*std::sqrt(BperpNorm*BperpNorm + std::abs(Bp2));
|
349
|
|
- ElipB.beta = sgn(std::real(iB0.dot(Bperp.cross(Bperp.conjugate())))) *
|
350
|
|
- (INVSQRT2)*std::sqrt(std::abs(BperpNorm*BperpNorm-std::abs(Bp2)));
|
|
369
|
+ ElipB.beta = std::copysign(1, std::real(iB0.dot( Bperp.cross(Bperp.conjugate())) )) *
|
|
370
|
+ (INVSQRT2*std::sqrt(BperpNorm*BperpNorm - std::abs(Bp2)));
|
351
|
371
|
ElipB.bhat = ((Real)1./ElipB.alpha)*(((Real)1./ElipB.eizt)*Bperp.array()).real().array();
|
352
|
372
|
ElipB.bhatp = B0hat.cross(ElipB.bhat);
|
353
|
373
|
ElipB.zeta = std::real(std::log(ElipB.eizt)/Complex(0,1));
|
|
374
|
+ /* 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;
|
354
|
385
|
return ElipB;
|
355
|
386
|
}
|
356
|
387
|
|
|
@@ -391,6 +422,9 @@ namespace Lemma {
|
391
|
422
|
Eigen::Matrix<Complex, 3, 8> Ht = Eigen::Matrix<Complex, 3, 8>::Zero();
|
392
|
423
|
Eigen::Matrix<Complex, 3, 8> Hr = Eigen::Matrix<Complex, 3, 8>::Zero();
|
393
|
424
|
for ( auto EMCalc : EMEarths ) {
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
|
394
|
428
|
EMCalc.second->GetFieldPoints()->ClearFields();
|
395
|
429
|
EMCalc.second->CalculateWireAntennaFields();
|
396
|
430
|
switch (EMCalc.second->GetTxRxMode()) {
|