Browse Source

Added integration on octree grid, independent of VTK, for faster performance. Need to add optional VTK method for visualization.

master
T-bone 7 years ago
parent
commit
777faf6674
2 changed files with 83 additions and 85 deletions
  1. 23
    3
      include/KernelV0.h
  2. 60
    82
      src/KernelV0.cpp

+ 23
- 3
include/KernelV0.h View File

@@ -145,14 +145,34 @@ namespace Lemma {
145 145
 
146 146
         private:
147 147
 
148
-        void IntegrateOnOctreeGrid( const Real& tolerance );
148
+        /**
149
+         *  Returns the kernel value for an input prism
150
+         */
151
+        Complex f( const Vector3r& r, const Real& volume );
149 152
 
150
-        void EvaluateKids();
153
+        void IntegrateOnOctreeGrid( const Real& tolerance );
151 154
 
152
-        void EvaluateKids( const Complex& parentVal );
155
+        /**
156
+         *  Recursive call to integrate a function on an adaptive Octree Grid.
157
+         *  For efficiency's sake the octree grid is not stored, as only the
158
+         *  integral (sum) is of interest. The logic for grid refinement is based
159
+         *  on an Octree representation of the domain. If an Octree representation
160
+         *  of the kernel is desired, call alternative version @see EvaluateKids2
161
+         *  @param[in] size gives the domain size, in  metres
162
+         *  @param[in] level gives the current level of the octree grid, call with 0 initially
163
+         *  @param[in] cpos is the centre position of the parent cuboid
164
+         */
165
+        bool EvaluateKids(  const Vector3r& size, const int& level, const Vector3r& cpos,
166
+                            const Complex& parentVal );
153 167
 
154 168
         // ====================  DATA MEMBERS  =========================
155 169
 
170
+        Complex                                  SUM;
171
+
172
+        Real                                     tol=1e-3;
173
+
174
+        int                                      nleaves;
175
+
156 176
         std::shared_ptr< LayeredEarthEM >        SigmaModel = nullptr;
157 177
 
158 178
         std::map< std::string , std::shared_ptr< PolygonalWireAntenna > >  TxRx;

+ 60
- 82
src/KernelV0.cpp View File

@@ -114,6 +114,8 @@ namespace Lemma {
114 114
                 // TODO query for method, altough with flat antennae, this is fastest
115 115
                 EmEarth->SetHankelTransformMethod(ANDERSON801);
116 116
 
117
+        IntegrateOnOctreeGrid( 1e-2 );
118
+
117 119
 // 		EmEarth->AttachFieldPoints(receivers);
118 120
 //         //EmEarth->SetHankelTransformMethod(FHTKEY101);
119 121
 // 	    EmEarth->CalculateWireAntennaFields();
@@ -134,102 +136,78 @@ namespace Lemma {
134 136
     //--------------------------------------------------------------------------------------
135 137
     void KernelV0::IntegrateOnOctreeGrid( const Real& tolerance) {
136 138
 
139
+        this->tol = tolerance;
137 140
         Vector3r                Size;
138
-        Vector3r                Origin;
139
-        Vector3r                step;
141
+            Size << 100,100,100;
142
+        //Vector3r                Origin;
140 143
         Vector3r                cpos;
141
-
142
-        int                     level;
144
+            cpos << 50,50,50;
143 145
         int                     maxlevel;
144
-        int                     index;
145
-        int                     counter;
146
-
147
-        Real                    cvol;
148
-        Real                    tvol;
149
-        Real                    tol;
150
-        Complex                 KernelSum;
151
-
152
-        //this->tol = tolerance;
153
-        Real KernelSum = 0.;
154
-        //Cursor->ToRoot();
155
-        //Cubes->SetNumberOfReceivers(8);
156
-        EvaluateKids( 1e9 ); // Large initial number don't waste time actually computing
157
-        //EvaluateKids();
158
-        //std::cout << "Kernel Sum from Generate Mesh "
159
-        //    << std::real(KernelSum) << "\t" << std::imag(KernelSum) << std::endl;
160
-
161
-        // old VTK thingy
162
-        //SetLeafDataFromGridCreation();
146
+
147
+        SUM = 0;
148
+        nleaves = 0;
149
+        EvaluateKids( Size, 0, cpos, -1e2 );
150
+        std::cout << "SUM\t" << SUM << "\t" << 100*100*100 << "\t" << SUM - Complex(100.*100.*100.) <<  std::endl;
151
+        std::cout << "nleaves\t" << nleaves << std::endl;
152
+
163 153
     }
164 154
 
165 155
     //--------------------------------------------------------------------------------------
166 156
     //       Class:  KernelV0
167
-    //      Method:  EvaluateKids
157
+    //      Method:  f
168 158
     //--------------------------------------------------------------------------------------
169
-    void KernelV0::EvaluateKids(const Complex& kval) {
170
-
171
-        assert("Evaluate Kids pre" && Cursor->CurrentIsLeaf());
172
-        vtkHyperOctreeCursor *tcurse = Cursor->Clone();
173
-        Real p[3];
174
-        Octree->SubdivideLeaf(Cursor);
175
-        tcurse->ToSameNode(Cursor);
176
-        std::cout << "\rPredivide Leaf count: " << Octree->GetNumberOfLeaves();
177
-
178
-        //std::cout.flush();
179
-        for (int child=0; child<8; ++child) {
180
-            Cursor->ToChild(child);
181
-            assert(Cursor->CurrentIsLeaf());
182
-            // Build cube
183
-            GetPosition(p);
184
-            cpos <<  p[0], p[1], p[2];
185
-            step  = ((Size).array() / std::pow(2.,Cursor->GetCurrentLevel()));
186
-            Cubes->SetLocation(child, cpos);
187
-            Cubes->SetLength(child, step);
188
-            //std::cout << "child " << child << " cpos\t" << cpos.transpose() << std::endl;
189
-            //std::cout << "child " << child << " step\t" << step.transpose() << std::endl;
190
-            Cursor->ToSameNode(tcurse);
191
-        }
192
-
193
-        // make calculation
194
-        Cubes->ClearFields();
195
-        VectorXcr f = SenseKernel->ComputeSensitivity();
196
-        if ( std::abs(std::abs(kval) - std::abs(f.array().abs().sum())) <= tol ||
197
-            Cursor->GetCurrentLevel() >= maxlevel ) {
198
-    	    // stop subdividing, save result
199
-    	    for (int child=0; child < 8; ++ child) {
200
-    	        Cursor->ToChild(child);
201
-    	        leafdata.push_back( std::abs(f(child)) / Cubes->GetVolume(child) );
202
-    	        // TODO fval is just a test
203
-    	        //leafdata.push_back( fval );
204
-    	        leafids.push_back(Cursor->GetLeafId());
205
-    	        KernelSum += f(child);
206
-    	        Cursor->ToParent();
207
-            }
208
-    	    return;
209
-        }
210
-
211
-        //std::cout << std::abs(kval) << "\t" <<
212
-        //         std::abs(f.array().abs().sum()) << "\t" << tol << std::endl;
213
-        for (int child=0; child < 8; ++ child) {
214
-            //std::cout << "Down the rabit hole " <<std::endl;
215
-            Cursor->ToChild(child);
216
-            EvaluateKids( f(child) );
217
-            //Cursor->ToParent();
218
-            Cursor->ToSameNode(tcurse);
219
-        }
220
-        tcurse->Delete();
159
+    Complex KernelV0::f( const Vector3r& r, const Real& volume ) {
160
+        return Complex(volume);
221 161
     }
222 162
 
223 163
     //--------------------------------------------------------------------------------------
224 164
     //       Class:  KernelV0
225 165
     //      Method:  EvaluateKids
226 166
     //--------------------------------------------------------------------------------------
227
-    void OctreeGrid::GetPosition( Real* p ) {
228
-        Real ratio=1.0/(1<<(Cursor->GetCurrentLevel()));
229
-        //step  = ((Size).array() / std::pow(2.,Cursor->GetCurrentLevel()));
230
-        p[0]=(Cursor->GetIndex(0)+.5)*ratio*Size[0]+Origin[0] ;//+ .5*step[0];
231
-        p[1]=(Cursor->GetIndex(1)+.5)*ratio*Size[1]+Origin[1] ;//+ .5*step[1];
232
-        p[2]=(Cursor->GetIndex(2)+.5)*ratio*Size[2]+Origin[2] ;//+ .5*step[2];
167
+    bool KernelV0::EvaluateKids( const Vector3r& size, const int& level, const Vector3r& cpos,
168
+        const Complex& parentVal ) {
169
+
170
+        // Next level step, interested in one level below
171
+        // bitshift requires one extra, faster than, and equivalent to std::pow(2, level+1)
172
+        Vector3r step = size.array() / (Real)(1 << (level+2) );
173
+
174
+        Real vol = step(0)*step(1)*step(2);     // volume of each child
175
+
176
+        Vector3r pos =  cpos - step/2.;
177
+        Eigen::Matrix<Real, 8, 3> posadd = (Eigen::Matrix<Real, 8, 3>() <<
178
+                        0,       0,       0,
179
+                  step[0],       0,       0,
180
+                        0, step[1],       0,
181
+                  step[0], step[1],       0,
182
+                        0,       0, step[2],
183
+                  step[0],       0, step[2],
184
+                        0, step[1], step[2],
185
+                  step[0], step[1], step[2] ).finished();
186
+
187
+        VectorXcr kvals(8);                     // individual kernel vals
188
+        for (int ichild=0; ichild<8; ++ichild) {
189
+            Vector3r cp = pos; // Eigen complains about combining these
190
+            cp += posadd.row(ichild);
191
+            kvals(ichild) = f(cp, vol);
192
+        }
193
+        Complex ksum = kvals.sum();     // Kernel sum
194
+
195
+        // Evaluate whether or not furthur splitting is needed
196
+        if ( std::abs(ksum - parentVal) > tol || level < 5 ) {
197
+            for (int ichild=0; ichild<8; ++ichild) {
198
+                Vector3r cp = pos; // Eigen complains about combining these
199
+                cp += posadd.row(ichild);
200
+                bool isleaf = EvaluateKids( size, level+1, pos, kvals(ichild) );
201
+                if (isleaf) {  // Include result in final integral
202
+//                  Id = curse.GetLeafId()     // VTK
203
+//                  LeafDict[Id] = vals[child] // VTK
204
+                    SUM += ksum;
205
+                    nleaves += 1;
206
+                }
207
+            }
208
+            return false;  // not leaf
209
+        }
210
+        return true;       // leaf
233 211
     }
234 212
 
235 213
 } // ----  end of namespace Lemma  ----

Loading…
Cancel
Save