|
@@ -10,11 +10,11 @@
|
10
|
10
|
/**
|
11
|
11
|
* @file
|
12
|
12
|
* @date 11/11/2016 01:47:25 PM
|
13
|
|
- * @version $Id$
|
14
|
13
|
* @author Trevor Irons (ti)
|
15
|
14
|
* @email tirons@egi.utah.edu
|
16
|
15
|
* @copyright Copyright (c) 2016, University of Utah
|
17
|
16
|
* @copyright Copyright (c) 2016, Lemma Software, LLC
|
|
17
|
+ * @copyright Copyright (c) 2008, Colorado School of Mines
|
18
|
18
|
*/
|
19
|
19
|
|
20
|
20
|
|
|
@@ -145,16 +145,12 @@ namespace Lemma {
|
145
|
145
|
std::cout << "Layer " << ilay << std::endl; //<< " q " << iq << std::endl;
|
146
|
146
|
Size(2) = Interfaces(ilay+1) - Interfaces(ilay);
|
147
|
147
|
Origin(2) = Interfaces(ilay);
|
148
|
|
- //for (int iq=0; iq< PulseI.size(); ++iq) {
|
149
|
|
- // Ip = PulseI(iq);
|
150
|
|
- //Kern(ilay, iq) =
|
151
|
|
- IntegrateOnOctreeGrid( 0, vtkOutput );
|
152
|
|
- //}
|
|
148
|
+ IntegrateOnOctreeGrid( vtkOutput );
|
153
|
149
|
}
|
154
|
150
|
std::cout << "\rFinished KERNEL\n";
|
155
|
|
- std::cout << "real\n";
|
|
151
|
+ std::cout << "#real\n";
|
156
|
152
|
std::cout << Kern.real() << std::endl;
|
157
|
|
- std::cout << "imag\n";
|
|
153
|
+ std::cout << "#imag\n";
|
158
|
154
|
std::cout << Kern.imag() << std::endl;
|
159
|
155
|
}
|
160
|
156
|
|
|
@@ -162,7 +158,7 @@ namespace Lemma {
|
162
|
158
|
// Class: KernelV0
|
163
|
159
|
// Method: IntegrateOnOctreeGrid
|
164
|
160
|
//--------------------------------------------------------------------------------------
|
165
|
|
- Complex KernelV0::IntegrateOnOctreeGrid( const int& iq, bool vtkOutput) {
|
|
161
|
+ void KernelV0::IntegrateOnOctreeGrid( bool vtkOutput) {
|
166
|
162
|
|
167
|
163
|
Vector3r cpos = Origin + Size/2.;
|
168
|
164
|
|
|
@@ -179,7 +175,9 @@ namespace Lemma {
|
179
|
175
|
oct->SetSize( Size(0), Size(1), Size(2) );
|
180
|
176
|
vtkHyperOctreeCursor* curse = oct->NewCellCursor();
|
181
|
177
|
curse->ToRoot();
|
182
|
|
- EvaluateKids2( Size, 0, cpos, 1e6, oct, curse );
|
|
178
|
+ EvaluateKids2( Size, 0, cpos, VectorXcr::Ones(PulseI.size()), oct, curse );
|
|
179
|
+
|
|
180
|
+ for (int iq=0; iq<PulseI.size(); ++iq) {
|
183
|
181
|
|
184
|
182
|
// Fill in leaf data
|
185
|
183
|
vtkDoubleArray* kr = vtkDoubleArray::New();
|
|
@@ -204,9 +202,9 @@ namespace Lemma {
|
204
|
202
|
|
205
|
203
|
//Real LeafVol(0);
|
206
|
204
|
for (auto leaf : LeafDict) {
|
207
|
|
- kr->InsertTuple1( leaf.first, std::real(leaf.second) );
|
208
|
|
- ki->InsertTuple1( leaf.first, std::imag(leaf.second) );
|
209
|
|
- km->InsertTuple1( leaf.first, std::abs(leaf.second) );
|
|
205
|
+ kr->InsertTuple1( leaf.first, std::real(leaf.second(iq)) );
|
|
206
|
+ ki->InsertTuple1( leaf.first, std::imag(leaf.second(iq)) );
|
|
207
|
+ km->InsertTuple1( leaf.first, std::abs(leaf.second(iq)) );
|
210
|
208
|
kid->InsertTuple1( leaf.first, leaf.first );
|
211
|
209
|
//LeafVol += std::real(leaf.second);
|
212
|
210
|
}
|
|
@@ -216,11 +214,11 @@ namespace Lemma {
|
216
|
214
|
kerr->InsertTuple1( leaf.first, leaf.second );
|
217
|
215
|
}
|
218
|
216
|
|
219
|
|
- oct->GetLeafData()->AddArray(kr);
|
220
|
|
- oct->GetLeafData()->AddArray(ki);
|
221
|
|
- oct->GetLeafData()->AddArray(km);
|
222
|
|
- oct->GetLeafData()->AddArray(kid);
|
223
|
|
- oct->GetLeafData()->AddArray(kerr);
|
|
217
|
+ auto kri = oct->GetLeafData()->AddArray(kr);
|
|
218
|
+ auto kii = oct->GetLeafData()->AddArray(ki);
|
|
219
|
+ auto kmi = oct->GetLeafData()->AddArray(km);
|
|
220
|
+ auto kidi = oct->GetLeafData()->AddArray(kid);
|
|
221
|
+ auto keri = oct->GetLeafData()->AddArray(kerr);
|
224
|
222
|
|
225
|
223
|
auto write = vtkXMLHyperOctreeWriter::New();
|
226
|
224
|
//write.SetDataModeToAscii()
|
|
@@ -231,11 +229,20 @@ namespace Lemma {
|
231
|
229
|
write->Write();
|
232
|
230
|
write->Delete();
|
233
|
231
|
|
234
|
|
- //kerr->Delete();
|
|
232
|
+ oct->GetLeafData()->RemoveArray( kri );
|
|
233
|
+ oct->GetLeafData()->RemoveArray( kii );
|
|
234
|
+ oct->GetLeafData()->RemoveArray( kmi );
|
|
235
|
+ oct->GetLeafData()->RemoveArray( kidi );
|
|
236
|
+ oct->GetLeafData()->RemoveArray( keri );
|
|
237
|
+
|
|
238
|
+ kerr->Delete();
|
235
|
239
|
kid->Delete();
|
236
|
240
|
kr->Delete();
|
237
|
241
|
ki->Delete();
|
238
|
242
|
km->Delete();
|
|
243
|
+
|
|
244
|
+ }
|
|
245
|
+
|
239
|
246
|
curse->Delete();
|
240
|
247
|
oct->Delete();
|
241
|
248
|
#else
|
|
@@ -245,10 +252,6 @@ namespace Lemma {
|
245
|
252
|
}
|
246
|
253
|
std::cout << "\nVOLSUM=" << VOLSUM << "\tActual=" << Size(0)*Size(1)*Size(2)
|
247
|
254
|
<< "\tDifference=" << VOLSUM - (Size(0)*Size(1)*Size(2)) << std::endl;
|
248
|
|
- std::cout << "nleaves\t" << nleaves << std::endl;
|
249
|
|
- std::cout << "KSUM\t" << SUM << std::endl;
|
250
|
|
-
|
251
|
|
- return SUM;
|
252
|
255
|
}
|
253
|
256
|
|
254
|
257
|
//--------------------------------------------------------------------------------------
|
|
@@ -270,15 +273,16 @@ namespace Lemma {
|
270
|
273
|
Real Mn0Abs = Mn0.norm();
|
271
|
274
|
|
272
|
275
|
// Compute phase delay
|
273
|
|
- // TODO add transmiiter phase and delay time phase!
|
274
|
|
- Real phase = EBR.zeta+EBT.zeta;
|
|
276
|
+ // TODO add transmiiter current phase and delay induced apparent time phase!
|
|
277
|
+ Complex PhaseTerm = EBR.bhat.dot(EBT.bhat) + (B0hat.dot(EBR.bhat.cross(EBT.bhat) ));
|
|
278
|
+ Complex ejztr = std::exp(Complex(0, EBR.zeta + EBT.zeta));
|
275
|
279
|
|
276
|
280
|
// Calcuate vector of all responses
|
277
|
281
|
VectorXcr F = VectorXcr::Zero( PulseI.size() );
|
278
|
282
|
for (int iq=0; iq<PulseI.size(); ++iq) {
|
279
|
283
|
// Compute the tipping angle
|
280
|
284
|
Real sintheta = std::sin(0.5*GAMMA*PulseI(iq)*Taup*std::abs(EBT.alpha-EBT.beta));
|
281
|
|
- F(iq) = ComputeV0Cell(EBT, EBR, sintheta, phase, Mn0Abs, volume);
|
|
285
|
+ F(iq) = -volume*Complex(0,Larmor)*Mn0Abs*(EBR.alpha+EBR.beta)*ejztr*sintheta*PhaseTerm;
|
282
|
286
|
}
|
283
|
287
|
return F;
|
284
|
288
|
}
|
|
@@ -287,46 +291,20 @@ namespace Lemma {
|
287
|
291
|
// // Class: KernelV0
|
288
|
292
|
// // Method: ComputeV0Cell
|
289
|
293
|
// //--------------------------------------------------------------------------------------
|
290
|
|
-// Complex KernelV0::ComputeV0Cell(const Vector3cr& Bt,
|
291
|
|
-// const Vector3cr& Br, const Real& vol, const Real& phi) {
|
292
|
|
-//
|
293
|
|
-// // Compute the elliptic fields
|
|
294
|
+// Complex KernelV0::ComputeV0Cell(const EllipticB& EBT, const EllipticB& EBR,
|
|
295
|
+// const Real& sintheta, const Real& phase, const Real& Mn0Abs,
|
|
296
|
+// const Real& vol) {
|
|
297
|
+// // earth response of receiver adjoint field
|
294
|
298
|
// Vector3r B0hat = SigmaModel->GetMagneticFieldUnitVector();
|
295
|
|
-// Vector3r B0 = SigmaModel->GetMagneticField();
|
296
|
|
-//
|
297
|
|
-// // Elliptic representation
|
298
|
|
-// EllipticB EBT = EllipticFieldRep(Bt, B0hat);
|
299
|
|
-// EllipticB EBR = EllipticFieldRep(Br, B0hat);
|
300
|
|
-//
|
301
|
|
-// // Compute Mn0
|
302
|
|
-// Vector3r Mn0 = ComputeMn0(phi, B0);
|
303
|
|
-// Real Mn0Abs = Mn0.norm();
|
304
|
|
-//
|
305
|
|
-// // Compute phase delay, TODO add transmiiter phase and delay time phase!
|
306
|
|
-// Real phase = EBR.zeta+EBT.zeta;
|
307
|
|
-//
|
308
|
|
-// Real sintheta = std::sin(0.5*GAMMA*Ip*Taup*std::abs(EBT.alpha-EBT.beta));
|
309
|
|
-// return 0; ComputeV0Cell(EBT, EBR, sintheta, phase, Mn0Abs, vol);
|
|
299
|
+// Complex ejztr = std::exp(Complex(0, EBR.zeta + EBT.zeta));
|
|
300
|
+// Complex PhaseTerm = EBR.bhat.dot(EBT.bhat) + (B0hat.dot(EBR.bhat.cross(EBT.bhat) ));
|
|
301
|
+// return -vol*Complex(0,Larmor)*Mn0Abs*(EBR.alpha+EBR.beta)*ejztr*sintheta*PhaseTerm;
|
310
|
302
|
// }
|
311
|
303
|
|
312
|
304
|
//--------------------------------------------------------------------------------------
|
313
|
305
|
// Class: KernelV0
|
314
|
306
|
// Method: ComputeV0Cell
|
315
|
307
|
//--------------------------------------------------------------------------------------
|
316
|
|
- Complex KernelV0::ComputeV0Cell(const EllipticB& EBT, const EllipticB& EBR,
|
317
|
|
- const Real& sintheta, const Real& phase, const Real& Mn0Abs,
|
318
|
|
- const Real& vol) {
|
319
|
|
- // earth response of receiver adjoint field
|
320
|
|
- Vector3r B0hat = SigmaModel->GetMagneticFieldUnitVector();
|
321
|
|
- Complex ejztr = std::exp(Complex(0, EBR.zeta + EBT.zeta));
|
322
|
|
- Complex PhaseTerm = EBR.bhat.dot(EBT.bhat) + (B0hat.dot(EBR.bhat.cross(EBT.bhat) ));
|
323
|
|
- return -vol*Complex(0,Larmor)*Mn0Abs*(EBR.alpha+EBR.beta)*ejztr*sintheta*PhaseTerm;
|
324
|
|
- }
|
325
|
|
-
|
326
|
|
- //--------------------------------------------------------------------------------------
|
327
|
|
- // Class: KernelV0
|
328
|
|
- // Method: ComputeV0Cell
|
329
|
|
- //--------------------------------------------------------------------------------------
|
330
|
308
|
Vector3r KernelV0::ComputeMn0(const Real& Porosity, const Vector3r& B0) {
|
331
|
309
|
Real chi_n = NH2O*((GAMMA*GAMMA*HBAR*HBAR)/(4.*KB*Temperature));
|
332
|
310
|
return chi_n*Porosity*B0;
|
|
@@ -378,7 +356,6 @@ namespace Lemma {
|
378
|
356
|
0, step[1], step[2],
|
379
|
357
|
step[0], step[1], step[2] ).finished();
|
380
|
358
|
|
381
|
|
- //VectorXcr kvals(8); // individual kernel vals
|
382
|
359
|
MatrixXcr kvals(8, PulseI.size()); // individual kernel vals
|
383
|
360
|
cpoints->ClearFields();
|
384
|
361
|
for (int ichild=0; ichild<8; ++ichild) {
|
|
@@ -439,7 +416,7 @@ namespace Lemma {
|
439
|
416
|
// Method: EvaluateKids2 -- same as Evaluate Kids, but include VTK octree generation
|
440
|
417
|
//--------------------------------------------------------------------------------------
|
441
|
418
|
void KernelV0::EvaluateKids2( const Vector3r& size, const int& level, const Vector3r& cpos,
|
442
|
|
- const Complex& parentVal, vtkHyperOctree* oct, vtkHyperOctreeCursor* curse) {
|
|
419
|
+ const VectorXcr& parentVal, vtkHyperOctree* oct, vtkHyperOctreeCursor* curse) {
|
443
|
420
|
|
444
|
421
|
std::cout << "\r" << (int)(1e2*VOLSUM/(Size[0]*Size[1]*Size[2])) << "\t" << nleaves;
|
445
|
422
|
std::cout.flush();
|
|
@@ -460,7 +437,7 @@ namespace Lemma {
|
460
|
437
|
0, step[1], step[2],
|
461
|
438
|
step[0], step[1], step[2] ).finished();
|
462
|
439
|
|
463
|
|
- VectorXcr kvals(8); // individual kernel vals
|
|
440
|
+ MatrixXcr kvals(8, PulseI.size()); // individual kernel vals
|
464
|
441
|
cpoints->ClearFields();
|
465
|
442
|
for (int ichild=0; ichild<8; ++ichild) {
|
466
|
443
|
Vector3r cp = pos; // Eigen complains about combining these
|
|
@@ -490,15 +467,14 @@ namespace Lemma {
|
490
|
467
|
}
|
491
|
468
|
|
492
|
469
|
for (int ichild=0; ichild<8; ++ichild) {
|
493
|
|
- Vector3r cp = pos; // Eigen complains about combining these
|
|
470
|
+ Vector3r cp = pos; // Eigen complains about combining these
|
494
|
471
|
cp += posadd.row(ichild);
|
495
|
|
- kvals(ichild) = f(cp, vol, Ht.col(ichild), Hr.col(ichild))(0);
|
|
472
|
+ kvals.row(ichild) = f(cp, vol, Ht.col(ichild), Hr.col(ichild));
|
496
|
473
|
}
|
497
|
474
|
|
498
|
|
- Complex ksum = kvals.sum(); // Kernel sum
|
|
475
|
+ VectorXcr ksum = kvals.colwise().sum(); // Kernel sum
|
499
|
476
|
// Evaluate whether or not furthur splitting is needed
|
500
|
|
- if ( std::abs(ksum - parentVal) > tol || level < minLevel && level < maxLevel ) {
|
501
|
|
- //if ( std::abs(ksum.real()-parentVal.real())>tol || std::abs(ksum.imag()-parentVal.imag()) >tol ) {
|
|
477
|
+ if ( ((ksum - parentVal).array().abs() > tol).any() || level < minLevel && level < maxLevel ) {
|
502
|
478
|
oct->SubdivideLeaf(curse);
|
503
|
479
|
for (int ichild=0; ichild<8; ++ichild) {
|
504
|
480
|
curse->ToChild(ichild);
|
|
@@ -515,14 +491,14 @@ namespace Lemma {
|
515
|
491
|
}
|
516
|
492
|
*/
|
517
|
493
|
/* End of position test */
|
518
|
|
- EvaluateKids2( size, level+1, cp, kvals(ichild), oct, curse );
|
|
494
|
+ EvaluateKids2( size, level+1, cp, kvals.row(ichild), oct, curse );
|
519
|
495
|
curse->ToParent();
|
520
|
496
|
}
|
521
|
497
|
return; // not a leaf
|
522
|
498
|
}
|
523
|
|
- LeafDict[curse->GetLeafId()] = ksum/(8.*vol); //kvals(ichild) / vol; // VTK
|
524
|
|
- LeafDictIdx[curse->GetLeafId()] = nleaves; // VTK
|
525
|
|
- SUM += ksum;
|
|
499
|
+ LeafDict[curse->GetLeafId()] = ksum/(8.*vol);
|
|
500
|
+ LeafDictIdx[curse->GetLeafId()] = nleaves;
|
|
501
|
+ Kern.row(ilay) += ksum;
|
526
|
502
|
VOLSUM += 8*vol;
|
527
|
503
|
nleaves += 1;
|
528
|
504
|
return; // is a leaf
|