|
@@ -19,7 +19,6 @@
|
19
|
19
|
|
20
|
20
|
|
21
|
21
|
#include "KernelV0.h"
|
22
|
|
-#include "EMEarth1D.h"
|
23
|
22
|
#include "FieldPoints.h"
|
24
|
23
|
|
25
|
24
|
namespace Lemma {
|
|
@@ -103,30 +102,23 @@ namespace Lemma {
|
103
|
102
|
// Class: KernelV0
|
104
|
103
|
// Method: DeSerialize
|
105
|
104
|
//--------------------------------------------------------------------------------------
|
106
|
|
- void KernelV0::CalculateK0 (const std::vector< std::string>& Tx, const std::vector<std::string >& Rx ) {
|
|
105
|
+ void KernelV0::CalculateK0 (const std::vector< std::string>& Tx, const std::vector<std::string >& Rx,
|
|
106
|
+ bool vtkOutput ) {
|
107
|
107
|
|
|
108
|
+ // All EM calculations will share same field points
|
|
109
|
+ auto points = FieldPoints::NewSP();
|
|
110
|
+ points->SetNumberOfPoints(8);
|
108
|
111
|
for (auto tx : Tx) {
|
109
|
112
|
// Set up EMEarth
|
110
|
|
- auto EmEarth = EMEarth1D::NewSP();
|
111
|
|
- EmEarth->AttachWireAntenna(TxRx[tx]);
|
112
|
|
- EmEarth->AttachLayeredEarthEM(SigmaModel);
|
113
|
|
- EmEarth->SetFieldsToCalculate(H);
|
|
113
|
+ EMEarths.push_back( EMEarth1D::NewSP() );
|
|
114
|
+ EMEarths.back()->AttachWireAntenna(TxRx[tx]);
|
|
115
|
+ EMEarths.back()->AttachLayeredEarthEM(SigmaModel);
|
|
116
|
+ EMEarths.back()->AttachFieldPoints( points );
|
|
117
|
+ EMEarths.back()->SetFieldsToCalculate(H);
|
114
|
118
|
// TODO query for method, altough with flat antennae, this is fastest
|
115
|
|
- EmEarth->SetHankelTransformMethod(ANDERSON801);
|
116
|
|
-
|
117
|
|
- IntegrateOnOctreeGrid( 1e-2 );
|
118
|
|
-
|
119
|
|
-// EmEarth->AttachFieldPoints(receivers);
|
120
|
|
-// //EmEarth->SetHankelTransformMethod(FHTKEY101);
|
121
|
|
-// EmEarth->CalculateWireAntennaFields();
|
122
|
|
-// Vector3Xcr Rx1 = receivers->GetHfield(0);
|
123
|
|
-// //receivers->ClearFields();
|
124
|
|
-//
|
125
|
|
-// //EmEarth->AttachWireAntenna(Tx2);
|
126
|
|
-// EmEarth->CalculateWireAntennaFields();
|
127
|
|
-// Rx1 += receivers->GetHfield(0);
|
128
|
|
-
|
|
119
|
+ EMEarths.back()->SetHankelTransformMethod(ANDERSON801);
|
129
|
120
|
}
|
|
121
|
+ IntegrateOnOctreeGrid( 1e-7, vtkOutput );
|
130
|
122
|
|
131
|
123
|
}
|
132
|
124
|
|
|
@@ -134,19 +126,43 @@ namespace Lemma {
|
134
|
126
|
// Class: KernelV0
|
135
|
127
|
// Method: IntegrateOnOctreeGrid
|
136
|
128
|
//--------------------------------------------------------------------------------------
|
137
|
|
- void KernelV0::IntegrateOnOctreeGrid( const Real& tolerance) {
|
|
129
|
+ void KernelV0::IntegrateOnOctreeGrid( const Real& tolerance, bool vtkOutput) {
|
138
|
130
|
|
139
|
131
|
this->tol = tolerance;
|
140
|
132
|
Vector3r Size;
|
141
|
133
|
Size << 100,100,100;
|
142
|
|
- //Vector3r Origin;
|
|
134
|
+ Vector3r Origin;
|
|
135
|
+ Origin << 0,0,0;
|
143
|
136
|
Vector3r cpos;
|
144
|
137
|
cpos << 50,50,50;
|
145
|
138
|
int maxlevel;
|
146
|
139
|
|
147
|
140
|
SUM = 0;
|
148
|
141
|
nleaves = 0;
|
149
|
|
- EvaluateKids( Size, 0, cpos, -1e2 );
|
|
142
|
+ if (!vtkOutput) {
|
|
143
|
+ EvaluateKids( Size, 0, cpos, 1e6 );
|
|
144
|
+ } else {
|
|
145
|
+ #ifdef LEMMAUSEVTK
|
|
146
|
+ vtkHyperOctree* oct = vtkHyperOctree::New();
|
|
147
|
+ oct->SetDimension(3);
|
|
148
|
+ oct->SetOrigin( Origin(0), Origin(1), Origin(2) );
|
|
149
|
+ oct->SetSize( Size(0), Size(1), Size(2) );
|
|
150
|
+ vtkHyperOctreeCursor* curse = oct->NewCellCursor();
|
|
151
|
+ curse->ToRoot();
|
|
152
|
+ EvaluateKids2( Size, 0, cpos, 1e6, oct, curse );
|
|
153
|
+ auto write = vtkXMLHyperOctreeWriter::New();
|
|
154
|
+ //write.SetDataModeToAscii()
|
|
155
|
+ write->SetInputData(oct);
|
|
156
|
+ write->SetFileName("octree.vto");
|
|
157
|
+ write->Write();
|
|
158
|
+ write->Delete();
|
|
159
|
+ curse->Delete();
|
|
160
|
+ oct->Delete();
|
|
161
|
+ #else
|
|
162
|
+ throw std::runtime_error("IntegrateOnOctreeGrid with vtkOutput requires Lemma with VTK support");
|
|
163
|
+ #endif
|
|
164
|
+
|
|
165
|
+ }
|
150
|
166
|
std::cout << "SUM\t" << SUM << "\t" << 100*100*100 << "\t" << SUM - Complex(100.*100.*100.) << std::endl;
|
151
|
167
|
std::cout << "nleaves\t" << nleaves << std::endl;
|
152
|
168
|
|
|
@@ -156,8 +172,10 @@ namespace Lemma {
|
156
|
172
|
// Class: KernelV0
|
157
|
173
|
// Method: f
|
158
|
174
|
//--------------------------------------------------------------------------------------
|
159
|
|
- Complex KernelV0::f( const Vector3r& r, const Real& volume ) {
|
160
|
|
- return Complex(volume);
|
|
175
|
+ Complex KernelV0::f( const Vector3r& r, const Real& volume, const Vector3cr& Bt ) {
|
|
176
|
+ //std::cout << volume*Bt.norm() << std::endl;
|
|
177
|
+ return Complex(volume*Bt.norm());
|
|
178
|
+ //return Complex(volume);
|
161
|
179
|
}
|
162
|
180
|
|
163
|
181
|
//--------------------------------------------------------------------------------------
|
|
@@ -184,31 +202,118 @@ namespace Lemma {
|
184
|
202
|
0, step[1], step[2],
|
185
|
203
|
step[0], step[1], step[2] ).finished();
|
186
|
204
|
|
|
205
|
+ VectorXcr kvals(8); // individual kernel vals
|
|
206
|
+ FieldPoints* cpoints = EMEarths[0]->GetFieldPoints();
|
|
207
|
+ cpoints->ClearFields();
|
|
208
|
+ for (int ichild=0; ichild<8; ++ichild) {
|
|
209
|
+ Vector3r cp = pos; // Eigen complains about combining these
|
|
210
|
+ cp += posadd.row(ichild);
|
|
211
|
+ cpoints->SetLocation( ichild, cp );
|
|
212
|
+ }
|
|
213
|
+
|
|
214
|
+ Vector3Xcr Bt;
|
|
215
|
+ //Eigen::Matrix< Complex, 8, 3 > Bt;
|
|
216
|
+ for ( auto EMCalc : EMEarths ) {
|
|
217
|
+ //EMCalc->GetFieldPoints()->ClearFields();
|
|
218
|
+ EMCalc->CalculateWireAntennaFields();
|
|
219
|
+ Bt = EMCalc->GetFieldPoints()->GetHfield(0);
|
|
220
|
+ }
|
|
221
|
+
|
|
222
|
+ for (int ichild=0; ichild<8; ++ichild) {
|
|
223
|
+ Vector3r cp = pos; // Eigen complains about combining these
|
|
224
|
+ cp += posadd.row(ichild);
|
|
225
|
+ kvals(ichild) = f(cp, vol, Bt.col(ichild));
|
|
226
|
+ }
|
|
227
|
+
|
|
228
|
+ Complex ksum = kvals.sum(); // Kernel sum
|
|
229
|
+ // Evaluate whether or not furthur splitting is needed
|
|
230
|
+ if ( std::abs(ksum - parentVal) > tol || level < 5 ) {
|
|
231
|
+ for (int ichild=0; ichild<8; ++ichild) {
|
|
232
|
+ Vector3r cp = pos; // Eigen complains about combining these
|
|
233
|
+ cp += posadd.row(ichild);
|
|
234
|
+ bool isleaf = EvaluateKids( size, level+1, cp, kvals(ichild) );
|
|
235
|
+ if (isleaf) { // Include result in final integral
|
|
236
|
+ SUM += ksum;
|
|
237
|
+ nleaves += 1;
|
|
238
|
+ }
|
|
239
|
+ }
|
|
240
|
+ return false; // not leaf
|
|
241
|
+ }
|
|
242
|
+ // Save here instead?
|
|
243
|
+ return true; // leaf
|
|
244
|
+ }
|
|
245
|
+
|
|
246
|
+ #ifdef LEMMAUSEVTK
|
|
247
|
+ //--------------------------------------------------------------------------------------
|
|
248
|
+ // Class: KernelV0
|
|
249
|
+ // Method: EvaluateKids2 -- same as Evaluate Kids, but include VTK octree generation
|
|
250
|
+ //--------------------------------------------------------------------------------------
|
|
251
|
+ bool KernelV0::EvaluateKids2( const Vector3r& size, const int& level, const Vector3r& cpos,
|
|
252
|
+ const Complex& parentVal, vtkHyperOctree* oct, vtkHyperOctreeCursor* curse) {
|
|
253
|
+
|
|
254
|
+ std::cout << "\rlevel " << level << "\t" << nleaves;
|
|
255
|
+ std::cout.flush();
|
|
256
|
+
|
|
257
|
+ // Next level step, interested in one level below
|
|
258
|
+ // bitshift requires one extra, faster than, and equivalent to std::pow(2, level+1)
|
|
259
|
+ Vector3r step = size.array() / (Real)(1 << (level+2) );
|
|
260
|
+
|
|
261
|
+ Real vol = step(0)*step(1)*step(2); // volume of each child
|
|
262
|
+
|
|
263
|
+ Vector3r pos = cpos - step/2.;
|
|
264
|
+ Eigen::Matrix<Real, 8, 3> posadd = (Eigen::Matrix<Real, 8, 3>() <<
|
|
265
|
+ 0, 0, 0,
|
|
266
|
+ step[0], 0, 0,
|
|
267
|
+ 0, step[1], 0,
|
|
268
|
+ step[0], step[1], 0,
|
|
269
|
+ 0, 0, step[2],
|
|
270
|
+ step[0], 0, step[2],
|
|
271
|
+ 0, step[1], step[2],
|
|
272
|
+ step[0], step[1], step[2] ).finished();
|
|
273
|
+
|
187
|
274
|
VectorXcr kvals(8); // individual kernel vals
|
|
275
|
+ FieldPoints* cpoints = EMEarths[0]->GetFieldPoints();
|
|
276
|
+ cpoints->ClearFields();
|
|
277
|
+ for (int ichild=0; ichild<8; ++ichild) {
|
|
278
|
+ Vector3r cp = pos; // Eigen complains about combining these
|
|
279
|
+ cp += posadd.row(ichild);
|
|
280
|
+ cpoints->SetLocation( ichild, cp );
|
|
281
|
+ }
|
|
282
|
+
|
|
283
|
+ Vector3Xcr Bt;
|
|
284
|
+ for ( auto EMCalc : EMEarths ) {
|
|
285
|
+ //EMCalc->GetFieldPoints()->ClearFields();
|
|
286
|
+ EMCalc->CalculateWireAntennaFields();
|
|
287
|
+ Bt = EMCalc->GetFieldPoints()->GetHfield(0);
|
|
288
|
+ }
|
|
289
|
+
|
188
|
290
|
for (int ichild=0; ichild<8; ++ichild) {
|
189
|
291
|
Vector3r cp = pos; // Eigen complains about combining these
|
190
|
292
|
cp += posadd.row(ichild);
|
191
|
|
- kvals(ichild) = f(cp, vol);
|
|
293
|
+ kvals(ichild) = f(cp, vol, Bt.col(ichild));
|
192
|
294
|
}
|
193
|
|
- Complex ksum = kvals.sum(); // Kernel sum
|
194
|
295
|
|
|
296
|
+ Complex ksum = kvals.sum(); // Kernel sum
|
195
|
297
|
// Evaluate whether or not furthur splitting is needed
|
196
|
|
- if ( std::abs(ksum - parentVal) > tol || level < 5 ) {
|
|
298
|
+ if ( std::abs(ksum - parentVal) > tol || level < 3 ) {
|
|
299
|
+ oct->SubdivideLeaf(curse);
|
197
|
300
|
for (int ichild=0; ichild<8; ++ichild) {
|
|
301
|
+ curse->ToChild(ichild);
|
198
|
302
|
Vector3r cp = pos; // Eigen complains about combining these
|
199
|
303
|
cp += posadd.row(ichild);
|
200
|
|
- bool isleaf = EvaluateKids( size, level+1, pos, kvals(ichild) );
|
|
304
|
+ bool isleaf = EvaluateKids2( size, level+1, cp, kvals(ichild), oct, curse );
|
201
|
305
|
if (isleaf) { // Include result in final integral
|
202
|
|
-// Id = curse.GetLeafId() // VTK
|
203
|
|
-// LeafDict[Id] = vals[child] // VTK
|
|
306
|
+ LeafDict[curse->GetLeafId()] = kvals(ichild); // VTK
|
204
|
307
|
SUM += ksum;
|
205
|
308
|
nleaves += 1;
|
206
|
309
|
}
|
|
310
|
+ curse->ToParent();
|
207
|
311
|
}
|
208
|
312
|
return false; // not leaf
|
209
|
313
|
}
|
210
|
314
|
return true; // leaf
|
211
|
315
|
}
|
|
316
|
+ #endif
|
212
|
317
|
|
213
|
318
|
} // ---- end of namespace Lemma ----
|
214
|
319
|
|