Lemma is an Electromagnetics API
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

octreegrid.h 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. /* This file is part of Lemma, a geophysical modelling and inversion API */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. /**
  6. @file
  7. @author Trevor Irons
  8. @date 03/19/2010
  9. @version $Id: octreegrid.h 193 2014-11-10 23:51:41Z tirons $
  10. **/
  11. #ifndef OCTREEGRID_INC
  12. #define OCTREEGRID_INC
  13. // This class depends on VTK!
  14. #ifdef LEMMAUSEVTK
  15. #include "grid.h"
  16. #include "vtkHyperOctree.h" // In Filtering
  17. #include "vtkHyperOctreeCursor.h"
  18. #include "vtkHyperOctreeSampleFunction.h"
  19. #include "vtkImplicitFunction.h"
  20. #include "vtkCell.h"
  21. #include "vtkGenericCell.h"
  22. #ifdef LEMMA_SINGLE_PRECISION
  23. #include "vtkFloatArray.h"
  24. #else // ----- not LEMMA_SINGLE_PRECISION -----
  25. #include "vtkDoubleArray.h"
  26. #endif // ----- not LEMMA_SINGLE_PRECISION -----
  27. #include "kernel.h"
  28. #include "receiverpoints.h"
  29. #include "receivercubes.h"
  30. #include "layeredearth.h"
  31. //#include "layeredearthnmr.h"
  32. #include "inversesolver.h"
  33. //#include "FastDelegate.h"
  34. //#include "FastDelegateBind.h"
  35. namespace Lemma {
  36. // forward declaration
  37. class InverseSolver ;
  38. // ===================================================================
  39. // Class: OctreeGrid
  40. /** An Octree class, builds off VtkHyperOctree so this class can
  41. only be used when compiled with VTK libs.
  42. An Octree is a heirarchial 3D mesh with rectangular cells containing
  43. either 0 or 8 children.
  44. */
  45. // ===================================================================
  46. class OctreeGrid : public Grid {
  47. friend class InverseSolver;
  48. //friend class SNMRInversion1D; // From Merlin Module
  49. friend std::ostream &operator<<(std::ostream &stream,
  50. const OctreeGrid &ob);
  51. public:
  52. // ==================== LIFECYCLE =======================
  53. /**
  54. * new grid octreee
  55. */
  56. static OctreeGrid* New();
  57. /**
  58. * @copybrief LemmaObject::Delete()
  59. * @copydetails LemmaObject::Delete()
  60. */
  61. void Delete();
  62. // ==================== OPERATORS =======================
  63. // ==================== ACCESS =======================
  64. /** Sets the kernel function to be used to make the mesh.
  65. * @param[in] kern is a kernel that is used to generate a mesh.
  66. */
  67. void SetKernel(Kernel* kern);
  68. /// Sets a 1D model associated with this kernel.
  69. /// @param[in] model1d is a pointer to a LayeredEarth model that
  70. /// will be used to pre-subdivide leaves that overlap several
  71. /// layers.
  72. void SetLayeredEarth(LayeredEarth* model1d);
  73. /** Sets the size of the mesh
  74. @param[in] size is the size of the mesh. The mesh must start at
  75. [0,0,0] and goes to [sizex, sizey, sizez].
  76. */
  77. void SetSize(const Vector3r& size);
  78. /** Sets the origin of the mesh
  79. @param[in] origin is the origin of the mesh.
  80. */
  81. void SetOrigin(const Vector3r& origin);
  82. /** Sets the minimum depth to model. This must be greater than 0.
  83. @param[in] depth is the new minimum depth.
  84. */
  85. void SetMinimumDepth(const Real& depth);
  86. /** Fills in the leaf data with the kernel sensitivity
  87. */
  88. void FillMeshWithKernel();
  89. /** Fills in the leaf data with the kernel sensitivity
  90. */
  91. void FillMeshWithKernel(vtkImplicitFunction* Impl);
  92. /** Sets the size of the mesh
  93. */
  94. void SetSize(const Real &x, const Real &y, const Real &z);
  95. /** Generates mesh to specified tolerance.
  96. * @param[in] tol is the kernel tolerance.
  97. */
  98. void GenerateMesh(const Real &tol);
  99. /** Generates a mesh to specified tolerance, but initially splits
  100. * based on implicit function.
  101. * @param[in] tol is the kernel tolerance.
  102. * @param[in] Impl is the implicit dataset used for initial
  103. * subdivision
  104. * @param[in] impltol is the tolerance for the initial model based
  105. * subdividing.
  106. */
  107. void GenerateMesh(const Real& tol, vtkImplicitFunction* Impl,
  108. const Real& impltol);
  109. /** Generates an Octree mesh using a pre-sampled input Octree Dataset.
  110. Speeds up repeated kernel calculations when the underlying model in
  111. the above ImplicitFunction needs to be called often or is complex.
  112. */
  113. void GenerateMesh(const Real& tol, vtkImplicitFunction* Impl,
  114. vtkHyperOctreeSampleFunction* OctSamp);
  115. /** Evaluates the kernel on the mesh. In some cases this is the same thing
  116. as generate mesh, but if more that one calculation are needed on a
  117. mesh you can use this method. It interfaces with the kernels by
  118. calling
  119. */
  120. Complex EvaluateKernelOnMesh();
  121. /** Returns a receiver cube class that represents the same Geometry as the
  122. HyperOctree. This is useful as it can be passed directly to em1dearth,
  123. and currently, an Octree cannot. But this requires storage of all the
  124. cell volumes and locations. In the future, you should be able to pass
  125. around this class just like a ReceiverCubes.
  126. */
  127. void ReceiverCubeRepresentation();
  128. /** Returns the receiver cube class. */
  129. ReceiverCubes* GetReceiverCubes();
  130. /** returns the kernel sum from generation */
  131. Complex GetKernelSum();
  132. /** Accessor to underlying vtkClass.
  133. * @return a vtkHyperOctree that can be used for visualization.
  134. */
  135. vtkHyperOctree* GetVtkHyperOctree( );
  136. /** Traverse the data structure and call a function at each leaf
  137. */
  138. void TraverseAndCall(InverseSolver* Inverse);
  139. /** Traverse the data structure and call a function at each leaf
  140. */
  141. void TraverseAndCall( vtkImplicitFunction* Impl );
  142. /**
  143. */
  144. void TraverseLeaves(vtkImplicitFunction* Impl);
  145. /**
  146. */
  147. void FollowExistingTree(vtkHyperOctree* Leader, vtkHyperOctreeCursor* LeaderCursor,
  148. vtkImplicitFunction* Impl);
  149. // ==================== OPERATIONS =======================
  150. /** Binds any derived member function of a derived class of
  151. LayeredEarth to SampleScalarFromLayeredEarthFD. This function is then
  152. used to sample the Octree mesh for that parameter. The member function
  153. needs to be of the type GetLayerXXX(const int Layer& lay).
  154. @param[in] earth is a pointer to a derived class of LayeredEarth
  155. @param[in] fcnptr is a function pointer to a member function. It
  156. should be called like &LayeredEarthNMR::GetLayerPorosity
  157. @param[in] name is a std::string identifier.
  158. */
  159. template <class Derived>
  160. void SampleScalarFromLayeredEarth(LayeredEarth* earth,
  161. Real (Derived::*fcnptr)(const int& id), const std::string &name) {
  162. std::cerr << "In octreegrid.h SampleScalrFromLayeredEarth FastDelegate method was "
  163. << "removed, need to fix with move semantics or function pointer." << std::endl;
  164. exit(3);
  165. //TODO fix SampleScalar below, as call to SampleScalarFromLayeredEarthFD is
  166. // removed there.
  167. /*
  168. SampleScalarFromLayeredEarthFD.bind(static_cast<Derived*>(earth), fcnptr);
  169. GetLayerInt.bind(earth, &LayeredEarth::GetLayerAtThisDepth);
  170. // TODO, don't use KernelArray, instead create new Array, and set it
  171. // in there. Then delete?
  172. this->KernelArray->SetName(name.c_str());
  173. this->KernelArray->SetNumberOfTuples(Octree->GetNumberOfLeaves());
  174. SampleScalar();
  175. this->Octree->GetLeafData()->SetScalars( KernelArray );
  176. this->Octree->GetLeafData()->AddArray( KernelArray );
  177. */
  178. }
  179. /** Sends cursor to root
  180. */
  181. void CursorToRoot();
  182. // ==================== INQUIRY =======================
  183. protected:
  184. // ==================== LIFECYCLE =======================
  185. /** Default protected constructor. */
  186. OctreeGrid (const std::string &name);
  187. /** Default protected constructor. */
  188. ~OctreeGrid ();
  189. /**
  190. * @copybrief LemmaObject::Release()
  191. * @copydetails LemmaObject::Release()
  192. */
  193. void Release();
  194. // ==================== OPERATIONS =======================
  195. /** Used internally. The leaf data is saved and then set as the vtk leaf
  196. * data.
  197. */
  198. void SetLeafDataFromGridCreation();
  199. /** Return position of leaf, returns centre location
  200. */
  201. void GetPosition( Real* p );
  202. /* Used to fill leaf data with a scalar value from a layered earth
  203. * model
  204. */
  205. //fastdelegate::FastDelegate1< const int&, Real > SampleScalarFromLayeredEarthFD;
  206. /* Used to get the Layer of delagated model.
  207. */
  208. //fastdelegate::FastDelegate1< const Real&, int > GetLayerInt;
  209. /** Recursively determines the mesh to use
  210. */
  211. void EvaluateKids( );
  212. /** Recursively determines the mesh to use
  213. @param[in] kval is the current leaf kernel value
  214. which may be reused in analysis.
  215. */
  216. void EvaluateKids( Complex kval );
  217. /** Same as above, but uses an implict function.
  218. */
  219. void EvaluateKids (vtkImplicitFunction* Impl);
  220. /** Same as above, but lets function value be passed directly
  221. */
  222. void EvaluateKids (const Real& fval, vtkImplicitFunction* Impl);
  223. /** Same as above but is passed a static fval to reuse. Useful when underlying model is smooth
  224. */
  225. void EvaluateKidsStatic(const Real& fval);
  226. /** Same as above, but lets function value be passed directly
  227. */
  228. void SampleFunction(vtkImplicitFunction* Impl);
  229. /** Recursively determines the mesh to use
  230. */
  231. void FillGrid( );
  232. /** Recursively determines the mesh to use
  233. */
  234. void FillGrid(vtkImplicitFunction* Impl);
  235. /** Used internally to build a receiver cube representation
  236. */
  237. void AssembleReceiverCubes( );
  238. /** Samples a scalar from a LayeredEarth object. Used internally and calls
  239. * SampleScalarFromLayeredEarthFD, which can be set using
  240. * SampleScalarFromLayeredEarth.
  241. */
  242. void SampleScalar();
  243. // Returns ReceiverPoints for the Octree.
  244. //void ComputeFieldOnOctree( WireAntenna* loop );
  245. // ==================== DATA MEMBERS =========================
  246. private:
  247. Vector3r Size;
  248. Vector3r Origin;
  249. Vector3r step;
  250. Vector3r cpos;
  251. int level;
  252. int maxlevel;
  253. int index;
  254. int counter;
  255. Real cvol;
  256. Real tvol;
  257. Real tol;
  258. Complex KernelSum;
  259. Eigen::Matrix<Real, 8, 3> Posadd;
  260. std::vector<Real> leafdata;
  261. std::vector<vtkIdType> leafids;
  262. Kernel *SenseKernel;
  263. ReceiverCubes *Cubes;
  264. LayeredEarth *Model1D;
  265. vtkHyperOctree *Octree;
  266. vtkHyperOctreeCursor *Cursor;
  267. vtkHyperOctreeSampleFunction *OctSamp;
  268. #ifdef LEMMA_SINGLE_PRECISION
  269. vtkFloatArray *KernelArray;
  270. #else // ----- not LEMMA_SINGLE_PRECISION -----
  271. vtkDoubleArray *KernelArray;
  272. #endif // ----- not LEMMA_SINGLE_PRECISION -----
  273. vtkDataArray *SampleArray;
  274. }; // ----- end of class OctreeGrid -----
  275. } // ----- end of Lemma name -----
  276. #endif // ----- not LEMMAUSEVTK -----
  277. #endif // ----- #ifndef OCTREEGRID_INC -----