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.cpp 55KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473
  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.cpp 87 2013-09-05 22:44:05Z tirons $
  10. **/
  11. #include "octreegrid.h"
  12. #ifdef LEMMAUSEVTK
  13. namespace Lemma {
  14. std::ostream &operator<<(std::ostream &stream,
  15. const OctreeGrid &ob) {
  16. stream << *(Grid*)(&ob);
  17. return stream;
  18. }
  19. OctreeGrid::OctreeGrid(const std::string &name) :
  20. Grid(name),
  21. Size(Vector3r::Zero()), Origin(Vector3r::Zero()),
  22. step(Vector3r::Zero()), cpos(Vector3r::Zero()),
  23. level(0), maxlevel(12), index(0) ,counter(0), cvol(0), tvol(0), tol(0),
  24. SenseKernel( NULL ),
  25. Cubes(ReceiverCubes::New()),
  26. Model1D(NULL),
  27. Octree(vtkHyperOctree::New() ),
  28. Cursor(Octree->NewCellCursor()),
  29. OctSamp(vtkHyperOctreeSampleFunction::New() ),
  30. #ifdef LEMMA_SINGLE_PRECISION
  31. KernelArray(vtkFloatArray::New())
  32. #else // ----- not LEMMA_SINGLE_PRECISION -----
  33. KernelArray(vtkDoubleArray::New())
  34. #endif // ----- not LEMMA_SINGLE_PRECISION -----
  35. {
  36. // 8 children plus root
  37. Cubes->SetNumberOfReceivers(9);
  38. // TODO point caclulation fails if origin is < 0.
  39. // Generalise, TODO add method to set Origin Depth
  40. Octree->SetDimension(3);
  41. Octree->SetOrigin(0,0,0);
  42. Origin << 0, 0, 0;
  43. }
  44. OctreeGrid::~OctreeGrid() {
  45. if (this->NumberOfReferences != 0)
  46. throw DeleteObjectWithReferences( this );
  47. // Bug here
  48. if (SenseKernel != NULL) {
  49. //SenseKernel->SetFieldCubes(NULL);
  50. SenseKernel->DetachFrom(this);
  51. SenseKernel = NULL;
  52. }
  53. if (Model1D != NULL) {
  54. Model1D->DetachFrom(this);
  55. Model1D = NULL;
  56. }
  57. Cubes->Delete();
  58. // With VTK 5.2 memory issues, unconditional jump.
  59. // TODO check with more recent versions.
  60. Cursor->Delete();
  61. Octree->Delete();
  62. OctSamp->Delete();
  63. KernelArray->Delete();
  64. }
  65. OctreeGrid * OctreeGrid::New() {
  66. OctreeGrid* Obj = new OctreeGrid("OctreeGrid");
  67. Obj->AttachTo(Obj);
  68. return Obj;
  69. }
  70. void OctreeGrid::Delete() {
  71. this->DetachFrom(this);
  72. }
  73. void OctreeGrid::Release() {
  74. delete this;
  75. }
  76. // ==================== OPERATIONS =======================
  77. void OctreeGrid::GenerateMesh(const Real &tolerance) {
  78. this->tol = tolerance;
  79. KernelSum = 0.;
  80. Cursor->ToRoot();
  81. Cubes->SetNumberOfReceivers(8);
  82. EvaluateKids(1e9); // Large initial number don't waste time actually computing
  83. //EvaluateKids();
  84. //std::cout << "Kernel Sum from Generate Mesh "
  85. // << std::real(KernelSum) << "\t" << std::imag(KernelSum) << std::endl;
  86. // TODO uncomment
  87. SetLeafDataFromGridCreation();
  88. }
  89. void OctreeGrid::GenerateMesh(const Real &tolerance,
  90. vtkImplicitFunction* Impl, const Real& impltol) {
  91. this->tol = tolerance;
  92. KernelSum = 0.;
  93. // Initial cut based on implicit function
  94. //Octree->Delete();
  95. Cursor->Delete();
  96. std::cout << "Sampling model onto Octree grid " << std::endl;
  97. if (OctSamp->GetImplicitFunction() != Impl) {
  98. // TODO maybe should have accessors for some of this?
  99. OctSamp->SetImplicitFunction(Impl);
  100. OctSamp->SetDimension(3);
  101. OctSamp->SetMinLevels(2);
  102. OctSamp->SetLevels(10);
  103. OctSamp->SetThreshold(impltol);
  104. OctSamp->SetOrigin(Origin[0], Origin[1], Origin[2]);
  105. OctSamp->SetSize(Size[0], Size[1], Size[2]);
  106. OctSamp->Update();
  107. //this->Octree->DeepCopy( OctSamp->GetOutput() ); //->Copy();
  108. std::cout << "Octree Leaves from implicit function sampling "
  109. << OctSamp->GetOutput()->GetNumberOfLeaves() << std::endl;
  110. }
  111. // OK, now evaluate kernel function
  112. this->Octree->DeepCopy(OctSamp->GetOutput());//->DeepCopy();
  113. this->Cursor = Octree->NewCellCursor();
  114. //FillMeshWithKernel(Impl);
  115. counter=0;
  116. //EvaluateKernelOnMesh();
  117. //FillMeshWithKernel(Impl);
  118. this->tol = tolerance;
  119. KernelSum = 0.;
  120. Cursor->ToRoot();
  121. //EvaluateKids( Impl );
  122. // TODO -> Instead of going to root, I need to loop over the leaves and
  123. // call EvaluateKids on each Leaf of above Octree.
  124. TraverseLeaves(Impl);
  125. std::cout << "\nKernel Sum from Generate Mesh "
  126. << std::real(KernelSum) << "\t" << std::imag(KernelSum) << std::endl;
  127. std::cout << "Octree Leaves from second " << Octree->GetNumberOfLeaves() << std::endl;
  128. // TODO uncomment
  129. SetLeafDataFromGridCreation();
  130. //OctSamp->Delete();
  131. Octree = vtkHyperOctree::New();
  132. Octree->SetDimension(3);
  133. Octree->SetOrigin(0,0,0);
  134. }
  135. void OctreeGrid::GenerateMesh(const Real &tolerance, vtkImplicitFunction* Impl, vtkHyperOctreeSampleFunction* OctSamp2) {
  136. this->tol = tolerance;
  137. KernelSum = 0.;
  138. //Octree->Delete();
  139. Cursor->Delete();
  140. std::cout << "Sampling kernel onto Octree grid " << std::endl;
  141. if (OctSamp2->GetImplicitFunction() != Impl) {
  142. cerr << "Octree sample and Implicit function do not match! in octreegrid.cpp\n";
  143. exit(1);
  144. }
  145. // OK, now evaluate kernel function
  146. //this->Octree->DeepCopy(OctSamp2->GetOutput());//->DeepCopy();
  147. this->Cursor = this->Octree->NewCellCursor();
  148. this->Cursor->ToRoot();
  149. vtkHyperOctreeCursor* LeaderCurse = OctSamp2->GetOutput()->NewCellCursor();
  150. LeaderCurse->ToRoot();
  151. FollowExistingTree(OctSamp2->GetOutput(), LeaderCurse, Impl);
  152. SetLeafDataFromGridCreation();
  153. // //FillMeshWithKernel(Impl);
  154. // counter=0;
  155. //
  156. // // TODO -> Instead of going to root, I need to loop over the leaves and
  157. // // call EvaluateKids on each Leaf of above Octree.
  158. // //std::cout << *OctSamp2->GetOutput()->GetLeafData()->GetScalars() << std::endl;
  159. // //SampleArray = OctSamp2->GetOutput()->GetLeafData()->GetScalars();
  160. // Octree->SetDualGridFlag(1);
  161. // std::cout << "sampling function " << std::endl;
  162. // // vtkHyperOctree* sf = vtkHyperOctree::New();
  163. // // sf->DeepCopy(this->Octree);
  164. // // vtkHyperOctreeCursor* sfc = sf->NewCellCursor();
  165. // // sfc->ToRoot();
  166. // // sf->SubdivideLeaf(sfc);
  167. // // for (int child=0; child<sfc->GetNumberOfChildren(); ++child) {
  168. // // sfc->ToChild(child);
  169. // // sf->SubdivideLeaf(sfc);
  170. // // sfc->ToParent();
  171. // // }
  172. // // //SampleFunction(Impl);
  173. // // Octree->DeepCopy(sf);
  174. // //vtkHyperOctreeCursor *tcurse = Cursor->Clone();
  175. // Octree->SubdivideLeaf(Cursor);
  176. // //tcurse->ToSameNode(Cursor); // Save location for when we come out
  177. // for (int child=0; child<Cursor->GetNumberOfChildren(); ++child) {
  178. // Cursor->ToChild(child);
  179. // Octree->SubdivideLeaf(Cursor);
  180. // for (int i=0; i<8; ++i) {
  181. // Cursor->ToChild(i);
  182. // Real* p2 = Octree->GetPoint(Cursor->GetLeafId());
  183. // // if (i==0) {
  184. // // Octree->SubdivideLeaf(Cursor);
  185. // // for (int i=0; i<8; ++i) {
  186. // // Cursor->ToChild(i);
  187. // // Real* p2 = Octree->GetPoint(Cursor->GetLeafId());
  188. // // Cursor->ToParent();
  189. // // }
  190. // // }
  191. // Cursor->ToParent();
  192. // }
  193. // Cursor->ToParent();
  194. // }
  195. // Cursor->ToChild(0);
  196. // Cursor->ToChild(0);
  197. // Octree->SubdivideLeaf(Cursor);
  198. // for (int i=0; i<8; ++i) {
  199. // Cursor->ToChild(i);
  200. // Real* p2 = Octree->GetPoint(Cursor->GetLeafId());
  201. // Cursor->ToParent();
  202. // }
  203. // Cursor->ToRoot();
  204. // //Cursor->ToSameNode(tcurse);
  205. // //tcurse->Delete();
  206. // //this->Cursor->ToParent();
  207. // std::cout << "Traversing Leaves " << std::endl;
  208. // //Cursor->ToRoot();
  209. // //this->Octree->GetLeafData()->GetScalars()->Reset( );
  210. // TraverseLeaves(Impl); // split but don't fill
  211. // //TraverseAndCall(Impl);
  212. // //ReTraverseLeaves(Impl);
  213. // /*
  214. // std::cout << "\nKernel Sum from Generate Mesh "
  215. // << std::real(KernelSum) << "\t" << std::imag(KernelSum) << std::endl;
  216. // std::cout << "Octree Leaves from second " << Octree->GetNumberOfLeaves() << std::endl;
  217. // */
  218. // // TODO uncomment
  219. // std::cout << "counter " << counter << std::endl;
  220. // SetLeafDataFromGridCreation();
  221. // this->Cursor->Delete();
  222. }
  223. Complex OctreeGrid::EvaluateKernelOnMesh( ) {
  224. KernelSum = 0.;
  225. //Cursor->ToRoot();
  226. FillGrid();
  227. //std::cout << std::real(KernelSum) << "\t" << std::imag(KernelSum) << std::endl;
  228. //SetLeafDataFromGridCreation();
  229. return KernelSum;
  230. }
  231. void OctreeGrid::FillMeshWithKernel() {
  232. this->KernelArray->SetNumberOfTuples(Octree->GetNumberOfLeaves());
  233. FillGrid();
  234. this->Octree->GetLeafData()->SetScalars( KernelArray );
  235. }
  236. void OctreeGrid::FillMeshWithKernel(vtkImplicitFunction* Impl) {
  237. this->KernelArray->SetNumberOfTuples(Octree->GetNumberOfLeaves());
  238. std::cout << "Octree Leaves " << Octree->GetNumberOfLeaves() << std::endl;
  239. //Cursor->ToRoot();
  240. FillGrid( Impl );
  241. //this->Octree->GetLeafData()->SetScalars( KernelArray );
  242. }
  243. void OctreeGrid::ReceiverCubeRepresentation() {
  244. tvol = 0;
  245. Cursor->ToRoot();
  246. Cubes->SetNumberOfReceivers( Octree->GetNumberOfLeaves() );
  247. AssembleReceiverCubes();
  248. //std::cout << "Total volume " << tvol << std::endl;
  249. }
  250. ReceiverCubes* OctreeGrid::GetReceiverCubes() {
  251. return this->Cubes;
  252. }
  253. Complex OctreeGrid::GetKernelSum() {
  254. return this->KernelSum;
  255. }
  256. void OctreeGrid::CursorToRoot() {
  257. Cursor->ToRoot();
  258. }
  259. void OctreeGrid::AssembleReceiverCubes() {
  260. level = Cursor->GetCurrentLevel();
  261. index = Cursor->GetChildIndex() ;
  262. // current position
  263. // backtrack through parents calculate
  264. // TODO bug, if origin is not (0,0,0) this breaks :(
  265. vtkHyperOctreeCursor *tcurse = Cursor->Clone();
  266. tcurse->ToSameNode(Cursor);
  267. step = ((Size).array() / std::pow(2.,level));
  268. cvol = step[0]*step[1]*step[2];
  269. cpos = Origin + step/2;
  270. Vector3r leafstep = step;
  271. while (tcurse->GetCurrentLevel() > 0) {
  272. int lev = tcurse->GetCurrentLevel();
  273. index = tcurse->GetChildIndex();
  274. step = ((Size) / std::pow(2.,lev));
  275. Posadd << 0, 0, 0,
  276. step[0], 0, 0,
  277. 0, step[1], 0,
  278. step[0], step[1], 0,
  279. 0, 0, step[2],
  280. step[0], 0, step[2],
  281. 0, step[1], step[2],
  282. step[0], step[1], step[2];
  283. cpos += Posadd.row(index);
  284. tcurse->ToParent();
  285. }
  286. // Root level
  287. int lev = tcurse->GetCurrentLevel();
  288. index = tcurse->GetChildIndex();
  289. step = (Size).array() / (std::pow(2.,lev));
  290. Posadd << 0, 0, 0,
  291. step[0], 0, 0,
  292. 0, step[1], 0,
  293. step[0], step[1], 0,
  294. 0, 0, step[2],
  295. step[0], 0, step[2],
  296. 0, step[1], step[2],
  297. step[0], step[1], step[2];
  298. cpos += Posadd.row(index);
  299. // split if needed
  300. if (Cursor->CurrentIsLeaf()) {
  301. // Set this cube
  302. Cubes->SetLocation(Cursor->GetLeafId(), cpos);
  303. Cubes->SetLength(Cursor->GetLeafId(), leafstep);
  304. tvol += leafstep[0]*leafstep[1]*leafstep[2];
  305. } else {
  306. // Evaluate function at cell centre
  307. for (int child=0; child < Cursor->GetNumberOfChildren(); ++ child) {
  308. Cursor->ToChild(child);
  309. AssembleReceiverCubes( );
  310. Cursor->ToParent( );
  311. }
  312. }
  313. tcurse->Delete();
  314. }
  315. void OctreeGrid::FillGrid() {
  316. Cubes->SetNumberOfReceivers(1);
  317. level = Cursor->GetCurrentLevel();
  318. index = Cursor->GetChildIndex() ;
  319. // current position
  320. // backtrack through parents calculate
  321. // TODO bug, if origin is not (0,0,0) this breaks :(
  322. vtkHyperOctreeCursor *tcurse = Cursor->Clone();
  323. tcurse->ToSameNode(Cursor);
  324. step = ((Size).array() / std::pow(2.,level));
  325. cvol = step[0]*step[1]*step[2];
  326. cpos = Origin + step/2;
  327. while (tcurse->GetCurrentLevel() > 0) {
  328. int lev = tcurse->GetCurrentLevel();
  329. index = tcurse->GetChildIndex();
  330. step = ((Size) / std::pow(2.,lev));
  331. Posadd << 0, 0, 0,
  332. step[0], 0, 0,
  333. 0, step[1], 0,
  334. step[0], step[1], 0,
  335. 0, 0, step[2],
  336. step[0], 0, step[2],
  337. 0, step[1], step[2],
  338. step[0], step[1], step[2];
  339. cpos += Posadd.row(index);
  340. tcurse->ToParent();
  341. }
  342. // Root level
  343. int lev = tcurse->GetCurrentLevel();
  344. index = tcurse->GetChildIndex();
  345. step = (Size).array() / (std::pow(2.,lev));
  346. Posadd << 0, 0, 0,
  347. step[0], 0, 0,
  348. 0, step[1], 0,
  349. step[0], step[1], 0,
  350. 0, 0, step[2],
  351. step[0], 0, step[2],
  352. 0, step[1], step[2],
  353. step[0], step[1], step[2];
  354. cpos += Posadd.row(index);
  355. Cubes->SetLocation(0, cpos);
  356. Cubes->SetLength(0, step);
  357. //////////////////////////////////////////////
  358. // Next level step
  359. step = (Size).array() / (std::pow(2.,(level+1)));
  360. //Vector3r pos = cpos - step/2.;
  361. Posadd << 0, 0, 0,
  362. step[0], 0, 0,
  363. 0, step[1], 0,
  364. step[0], step[1], 0,
  365. 0, 0, step[2],
  366. step[0], 0, step[2],
  367. 0, step[1], step[2],
  368. step[0], step[1], step[2];
  369. // Evaluate kernel
  370. Cubes->ClearFields();
  371. VectorXcr f = SenseKernel->ComputeSensitivity();
  372. //Real val = cvol*std::abs(f(0));
  373. // split if needed
  374. if (Cursor->CurrentIsLeaf()) {
  375. if (f(0) == f(0)) {
  376. KernelSum += f(0); // catch NaNs
  377. KernelArray->InsertValue(Cursor->GetLeafId(), std::abs(f(0)));
  378. }
  379. else {
  380. std::cerr << "f(0) " << f(0) << std::endl;
  381. KernelArray->InsertValue(Cursor->GetLeafId(), 0);
  382. }
  383. } else {
  384. // Evaluate function at cell centre
  385. for (int child=0; child < Cursor->GetNumberOfChildren(); ++ child) {
  386. //Vector3r cp = pos + Posadd.row(child).transpose();
  387. Cursor->ToChild(child);
  388. FillGrid( );
  389. Cursor->ToParent();
  390. }
  391. }
  392. tcurse->Delete();
  393. Cubes->SetNumberOfReceivers(9);
  394. }
  395. void OctreeGrid::FillGrid(vtkImplicitFunction* Impl) {
  396. std::cout << "counter " << counter << std::endl;
  397. ++ counter;
  398. if (Cursor->CurrentIsLeaf()) {
  399. double pcords[3];
  400. double x[3];
  401. double *w(NULL);
  402. int id;
  403. Octree->GetCell(Cursor->GetLeafId())->GetParametricCenter(pcords);
  404. Octree->GetCell(Cursor->GetLeafId())->EvaluateLocation(id, pcords, x, w);
  405. KernelArray->InsertValue(Cursor->GetLeafId(), x[2]);
  406. cout << "pcords " << x[0] << "\t" << x[1] << "\t" << x[2] << std::endl;
  407. } else {
  408. for (int child=0; child < Cursor->GetNumberOfChildren(); ++ child) {
  409. Cursor->ToChild(child);
  410. FillGrid(Impl);
  411. Cursor->ToParent();
  412. }
  413. }
  414. // Cubes->SetNumberOfReceivers(1);
  415. // level = Cursor->GetCurrentLevel();
  416. // index = Cursor->GetChildIndex() ;
  417. // // current position
  418. // // backtrack through parents calculate
  419. // // TODO bug, if origin is not (0,0,0) this breaks :(
  420. // vtkHyperOctreeCursor *tcurse = Cursor->Clone();
  421. // tcurse->ToSameNode(Cursor);
  422. // step = ((Size-Origin).array() / std::pow(2.,level));
  423. // cvol = step[0]*step[1]*step[2];
  424. // cpos = Origin + step/2;
  425. // while (tcurse->GetCurrentLevel() > 0) {
  426. // int lev = tcurse->GetCurrentLevel();
  427. // index = tcurse->GetChildIndex();
  428. // step = ((Size-Origin) / std::pow(2.,lev));
  429. // Posadd << 0, 0, 0,
  430. // step[0], 0, 0,
  431. // 0, step[1], 0,
  432. // step[0], step[1], 0,
  433. // 0, 0, step[2],
  434. // step[0], 0, step[2],
  435. // 0, step[1], step[2],
  436. // step[0], step[1], step[2];
  437. // cpos += Posadd.row(index);
  438. // tcurse->ToParent();
  439. // }
  440. // // Root level
  441. // int lev = tcurse->GetCurrentLevel();
  442. // index = tcurse->GetChildIndex();
  443. // step = (Size-Origin).array() / (std::pow(2.,lev));
  444. // Posadd << 0, 0, 0,
  445. // step[0], 0, 0,
  446. // 0, step[1], 0,
  447. // step[0], step[1], 0,
  448. // 0, 0, step[2],
  449. // step[0], 0, step[2],
  450. // 0, step[1], step[2],
  451. // step[0], step[1], step[2];
  452. // cpos += Posadd.row(index);
  453. // Cubes->SetLocation(0, cpos);
  454. // Cubes->SetLength(0, step);
  455. // //////////////////////////////////////////////
  456. // // Next level step
  457. // step = (Size-Origin).array() / (std::pow(2.,(level+1)));
  458. // //Vector3r pos = cpos - step/2.;
  459. // Posadd << 0, 0, 0,
  460. // step[0], 0, 0,
  461. // 0, step[1], 0,
  462. // step[0], step[1], 0,
  463. // 0, 0, step[2],
  464. // step[0], 0, step[2],
  465. // 0, step[1], step[2],
  466. // step[0], step[1], step[2];
  467. // // Evaluate kernel
  468. // Cubes->ClearFields();
  469. // VectorXcr f = SenseKernel->ComputeSensitivity(Impl);
  470. // //Real val = cvol*std::abs(f(0));
  471. // // split if needed
  472. // if (Cursor->CurrentIsLeaf()) {
  473. // if (f(0) == f(0)) {
  474. // KernelSum += f(0); // catch NaNs
  475. // KernelArray->InsertValue(Cursor->GetLeafId(), std::abs(f(0)));
  476. // }
  477. // else {
  478. // std::cerr << "f(0) " << f(0) << std::endl;
  479. // KernelArray->InsertValue(Cursor->GetLeafId(), 0);
  480. // }
  481. // } else {
  482. // // Evaluate function at cell centre
  483. // for (int child=0; child < Cursor->GetNumberOfChildren(); ++ child) {
  484. // //Vector3r cp = pos + Posadd.row(child).transpose();
  485. // Cursor->ToChild(child);
  486. // FillGrid(Impl);
  487. // Cursor->ToParent();
  488. // }
  489. // }
  490. // tcurse->Delete();
  491. // Cubes->SetNumberOfReceivers(9);
  492. }
  493. void OctreeGrid::SampleScalar() {
  494. level = Cursor->GetCurrentLevel();
  495. index = Cursor->GetChildIndex() ;
  496. // current position
  497. // backtrack through parents calculate
  498. // TODO bug, if origin is not (0,0,0) this breaks :(
  499. vtkHyperOctreeCursor *tcurse = Cursor->Clone();
  500. tcurse->ToSameNode(Cursor);
  501. step = ((Size).array() / std::pow(2.,level));
  502. cvol = step[0]*step[1]*step[2];
  503. cpos = Origin + step/2;
  504. while (tcurse->GetCurrentLevel() > 0) {
  505. int lev = tcurse->GetCurrentLevel();
  506. index = tcurse->GetChildIndex();
  507. step = ((Size) / std::pow(2.,lev));
  508. Posadd << 0, 0, 0,
  509. step[0], 0, 0,
  510. 0, step[1], 0,
  511. step[0], step[1], 0,
  512. 0, 0, step[2],
  513. step[0], 0, step[2],
  514. 0, step[1], step[2],
  515. step[0], step[1], step[2];
  516. cpos += Posadd.row(index);
  517. tcurse->ToParent();
  518. }
  519. // Root level
  520. int lev = tcurse->GetCurrentLevel();
  521. index = tcurse->GetChildIndex();
  522. step = (Size).array() / (std::pow(2.,lev));
  523. Posadd << 0, 0, 0,
  524. step[0], 0, 0,
  525. 0, step[1], 0,
  526. step[0], step[1], 0,
  527. 0, 0, step[2],
  528. step[0], 0, step[2],
  529. 0, step[1], step[2],
  530. step[0], step[1], step[2];
  531. cpos += Posadd.row(index);
  532. // ######################################
  533. // # Next level step
  534. step = (Size).array() / (std::pow(2.,(level+1)));
  535. //Vector3r pos = cpos - step/2.;
  536. Posadd << 0, 0, 0,
  537. step[0], 0, 0,
  538. 0, step[1], 0,
  539. step[0], step[1], 0,
  540. 0, 0, step[2],
  541. step[0], 0, step[2],
  542. 0, step[1], step[2],
  543. step[0], step[1], step[2];
  544. // split if needed
  545. if (Cursor->CurrentIsLeaf()) {
  546. //KernelArray->InsertValue(Cursor->GetLeafId(),
  547. // SampleScalarFromLayeredEarthFD(GetLayerInt(cpos(2))));
  548. } else {
  549. // Evaluate function at cell centre
  550. for (int child=0; child < Cursor->GetNumberOfChildren(); ++ child) {
  551. Cursor->ToChild(child);
  552. SampleScalar( );
  553. Cursor->ToParent();
  554. }
  555. }
  556. tcurse->Delete();
  557. }
  558. void OctreeGrid::GetPosition( Real* p ) {
  559. Real ratio=1.0/(1<<(Cursor->GetCurrentLevel()));
  560. //step = ((Size).array() / std::pow(2.,Cursor->GetCurrentLevel()));
  561. p[0]=(Cursor->GetIndex(0)+.5)*ratio*this->Size[0]+this->Origin[0] ;//+ .5*step[0];
  562. p[1]=(Cursor->GetIndex(1)+.5)*ratio*this->Size[1]+this->Origin[1] ;//+ .5*step[1];
  563. p[2]=(Cursor->GetIndex(2)+.5)*ratio*this->Size[2]+this->Origin[2] ;//+ .5*step[2];
  564. }
  565. void OctreeGrid::SampleFunction( vtkImplicitFunction* Impl ) {
  566. assert(Cursor->CurrentIsLeaf());
  567. Real p[3];
  568. this->GetPosition(p);
  569. std::cout << "Before At " << p[0] << "\t" << p[1] << "\t" << p[2] << std::endl;
  570. //Octree->GetPoint(Cursor->GetLeafId(), p);
  571. //Octree->GetPoint(Cursor->GetLeafId(), p);
  572. //Real value = Impl->FunctionValue(p);
  573. Octree->SubdivideLeaf(Cursor);
  574. vtkHyperOctreeCursor *tcurse = Cursor->Clone();
  575. tcurse->ToSameNode(Cursor); // Save location for when we come out
  576. for (int child=0; child < Cursor->GetNumberOfChildren(); ++child) {
  577. Cursor->ToChild(child);
  578. // //Octree->GetPoint(Cursor->GetLeafId(), p);
  579. // //this->GetPosition(p);
  580. // //Real valueSm = Impl->FunctionValue(p);
  581. // //if (std::abs(value - valueSm) > 1e-1) {
  582. // //std::cout << "tcurse\t" << tcurse->GetLeafId() << "\t" << tcurse->GetCurrentLevel() << std::endl;
  583. // //this->GetPosition(p);
  584. //
  585. //
  586. // // SampleFunction(Impl);
  587. // //std::cout << "Dual Grid Flag after subdivide " << Octree->GetDualGridFlag() << std::endl;
  588. // // for (int child=0; child<Cursor->GetNumberOfChildren(); ++child) {
  589. // // Cursor->ToChild(child);
  590. // // Octree->GetPoint(Cursor->GetLeafId(), p);
  591. // // leafdata.push_back( p[2] ); // was value
  592. // // leafids.push_back(Cursor->GetLeafId());
  593. // // Cursor->ToParent();
  594. // // }
  595. // //EvaluateKids(Impl); // don't need to use Impl, will be constant here on
  596. // //Octree->SetDualGridFlag(1);
  597. // //EvaluateKids(value, Impl); // don't need to use Impl, will be constant here on
  598. // //leafdata.push_back( p2[0] );
  599. // //leafids.push_back(Cursor->GetLeafId());
  600. // //}
  601. //Cursor->ToParent( );
  602. Cursor->ToSameNode(tcurse);
  603. // //this->GetPosition(p);
  604. // //std::cout << "After At " << p[0] << "\t" << p[1] << "\t" << p[2] << std::endl;
  605. // //std::cout << "GOTO tcurse\t" << tcurse->GetLeafId() << "\t" << tcurse->GetCurrentLevel() << std::endl;
  606. }
  607. tcurse->Delete();
  608. }
  609. void OctreeGrid::FollowExistingTree( vtkHyperOctree* Leader, vtkHyperOctreeCursor* LeaderCursor, vtkImplicitFunction* Impl ) {
  610. assert(!LeaderCursor->CurrentIsLeaf());
  611. assert("Follow existing, CurrentIsLeaf" && Cursor->CurrentIsLeaf());
  612. Real p[3];
  613. // match Leader topology
  614. Octree->SubdivideLeaf(Cursor);
  615. for (int child=0; child<8; ++child) {
  616. LeaderCursor->ToChild(child);
  617. Cursor->ToChild(child);
  618. if (LeaderCursor->CurrentIsLeaf()) {
  619. GetPosition(p);
  620. // Fill-in Octree
  621. Real value = Impl->FunctionValue(p);
  622. EvaluateKids(value, Impl);
  623. //Octree->SubdivideLeaf(Cursor);
  624. } else {
  625. FollowExistingTree(Leader, LeaderCursor, Impl);
  626. }
  627. Cursor->ToParent();
  628. LeaderCursor->ToParent();
  629. }
  630. }
  631. void OctreeGrid::TraverseLeaves(vtkImplicitFunction* Impl) {
  632. //static int first = true;
  633. assert(!Cursor->CurrentIsLeaf());
  634. Real p[3];
  635. //Real* p2;
  636. //Real p2[3];
  637. //vtkHyperOctreeCursor *tcurse = Cursor->Clone();
  638. //tcurse->ToSameNode(Cursor); // Save location for when we come out
  639. //vtkIdList *ptIds = vtkIdList::New();
  640. //this->GetPosition(p);
  641. //std::cout << "Before At " << p[0] << "\t" << p[1] << "\t" << p[2] << std::endl;
  642. for (vtkIdType child=0; child < Cursor->GetNumberOfChildren(); ++child) {
  643. Cursor->ToChild(child);
  644. if (Cursor->CurrentIsLeaf()) {
  645. //std::cout << "tcurse\t" << tcurse->GetLeafId() << "\t" << tcurse->GetCurrentLevel() << std::endl;
  646. Octree->Modified();
  647. this->GetPosition(p);
  648. step = ((Size).array() / std::pow(2.,Cursor->GetCurrentLevel()));
  649. //vtkGenericCell *cell;
  650. //Octree->GetCell(Cursor->GetLeafId(),
  651. // vtkGenericCell *cell);
  652. //p[2] = cell->GetPoint(0);
  653. //Octree->GetCellPoints(Cursor->GetLeafId(), ptIds);
  654. //p2 = Octree->GetPoint(Cursor->GetLeafId());
  655. //Octree->GetPoint(Cursor->GetLeafId(), p2 );
  656. //std::cout << p[0] - p2[0] << "\t" << p[1] - p2[1] << "\t"
  657. // << p[2] - p2[2] << std::endl;
  658. //Real value=Impl->FunctionValue(p);
  659. //std::cout << "Dual Grid Flag b4 subdivide " << Octree->GetDualGridFlag() << std::endl;
  660. //Octree->SetDualGridFlag(0);
  661. /*
  662. if (first == true) {
  663. Octree->SubdivideLeaf(Cursor);
  664. //std::cout << "Dual Grid Flag after subdivide " << Octree->GetDualGridFlag() << std::endl;
  665. for (vtkIdType child=0; child<Cursor->GetNumberOfChildren(); ++child) {
  666. //vtkHyperOctreeCursor *ttcurse = Cursor->Clone();
  667. //ttcurse->ToSameNode(Cursor); // Save location for when we come out
  668. Cursor->ToChild(child);
  669. //Octree->GetPoint(Cursor->GetLeafId(), p);
  670. //leafdata.push_back( p2[2] ); // was value
  671. //leafids.push_back(Cursor->GetLeafId());
  672. Cursor->ToParent();
  673. //Cursor->ToSameNode(ttcurse);
  674. //ttcurse->Delete();
  675. }
  676. first = false;
  677. } else {
  678. */
  679. //EvaluateKids(Impl); // don't need to use Impl, will be constant here on
  680. //Octree->SetDualGridFlag(1);
  681. //EvaluateKids(value, Impl); // don't need to use Impl, will be constant here on
  682. leafdata.push_back( p[1] );
  683. ++counter;
  684. leafids.push_back(Cursor->GetLeafId());
  685. //vtkIdType id=Cursor->GetLeafId();
  686. //Octree->GetLeafData()->GetScalars()->InsertTuple1(id, p[2]);
  687. //}
  688. } else {
  689. TraverseLeaves(Impl);
  690. }
  691. //Cursor->ToSameNode(tcurse);
  692. Cursor->ToParent();
  693. //this->GetPosition(p);
  694. //std::cout << "After At " << p[0] << "\t" << p[1] << "\t" << p[2] << std::endl;
  695. //std::cout << "GOTO tcurse\t" << tcurse->GetLeafId() << "\t" << tcurse->GetCurrentLevel() << std::endl;
  696. }
  697. //tcurse->Delete();
  698. }
  699. void OctreeGrid::TraverseAndCall(InverseSolver* Inverse) {
  700. level = Cursor->GetCurrentLevel();
  701. index = Cursor->GetChildIndex() ;
  702. // current position
  703. // backtrack through parents calculate
  704. // TODO bug, if origin is not (0,0,0) this breaks :(
  705. vtkHyperOctreeCursor *tcurse = Cursor->Clone();
  706. tcurse->ToSameNode(Cursor);
  707. step = ((Size).array() / std::pow(2.,level));
  708. cvol = step[0]*step[1]*step[2];
  709. cpos = Origin + step/2;
  710. Vector3r leafstep = step;
  711. while (tcurse->GetCurrentLevel() > 0) {
  712. int lev = tcurse->GetCurrentLevel();
  713. index = tcurse->GetChildIndex();
  714. step = ((Size) / std::pow(2.,lev));
  715. Posadd << 0, 0, 0,
  716. step[0], 0, 0,
  717. 0, step[1], 0,
  718. step[0], step[1], 0,
  719. 0, 0, step[2],
  720. step[0], 0, step[2],
  721. 0, step[1], step[2],
  722. step[0], step[1], step[2];
  723. cpos += Posadd.row(index);
  724. tcurse->ToParent();
  725. }
  726. // Root level
  727. int lev = tcurse->GetCurrentLevel();
  728. index = tcurse->GetChildIndex();
  729. step = (Size).array() / (std::pow(2.,lev));
  730. Posadd << 0, 0, 0,
  731. step[0], 0, 0,
  732. 0, step[1], 0,
  733. step[0], step[1], 0,
  734. 0, 0, step[2],
  735. step[0], 0, step[2],
  736. 0, step[1], step[2],
  737. step[0], step[1], step[2];
  738. cpos += Posadd.row(index);
  739. // split if needed
  740. if (Cursor->CurrentIsLeaf()) {
  741. // Set this cube
  742. Inverse->FillInG( cpos, leafstep );
  743. tvol += leafstep[0]*leafstep[1]*leafstep[2];
  744. } else {
  745. // Evaluate function at cell centre
  746. for (int child=0; child < Cursor->GetNumberOfChildren(); ++ child) {
  747. Cursor->ToChild(child);
  748. TraverseAndCall(Inverse);
  749. Cursor->ToParent( );
  750. }
  751. }
  752. tcurse->Delete();
  753. }
  754. void OctreeGrid::TraverseAndCall( vtkImplicitFunction* Impl ) {
  755. level = Cursor->GetCurrentLevel();
  756. index = Cursor->GetChildIndex() ;
  757. // current position
  758. // backtrack through parents calculate
  759. // TODO bug, if origin is not (0,0,0) this breaks :(
  760. vtkHyperOctreeCursor *tcurse = Cursor->Clone();
  761. tcurse->ToSameNode(Cursor);
  762. step = ((Size).array() / std::pow(2.,level));
  763. cvol = step[0]*step[1]*step[2];
  764. cpos = Origin + step/2;
  765. Vector3r leafstep = step;
  766. while (tcurse->GetCurrentLevel() > 0) {
  767. int lev = tcurse->GetCurrentLevel();
  768. index = tcurse->GetChildIndex();
  769. step = ((Size) / std::pow(2.,lev));
  770. Posadd << 0, 0, 0,
  771. step[0], 0, 0,
  772. 0, step[1], 0,
  773. step[0], step[1], 0,
  774. 0, 0, step[2],
  775. step[0], 0, step[2],
  776. 0, step[1], step[2],
  777. step[0], step[1], step[2];
  778. cpos += Posadd.row(index);
  779. tcurse->ToParent();
  780. }
  781. // Root level
  782. int lev = tcurse->GetCurrentLevel();
  783. index = tcurse->GetChildIndex();
  784. step = (Size).array() / (std::pow(2.,lev));
  785. Posadd << 0, 0, 0,
  786. step[0], 0, 0,
  787. 0, step[1], 0,
  788. step[0], step[1], 0,
  789. 0, 0, step[2],
  790. step[0], 0, step[2],
  791. 0, step[1], step[2],
  792. step[0], step[1], step[2];
  793. cpos += Posadd.row(index);
  794. // split if needed
  795. if (Cursor->CurrentIsLeaf()) {
  796. // Set this cube
  797. leafdata.push_back( cpos[2] ); // was value
  798. leafids.push_back(Cursor->GetLeafId());
  799. tvol += leafstep[0]*leafstep[1]*leafstep[2];
  800. } else {
  801. // Evaluate function at cell centre
  802. for (int child=0; child < Cursor->GetNumberOfChildren(); ++ child) {
  803. Cursor->ToChild(child);
  804. TraverseAndCall(Impl);
  805. Cursor->ToParent( );
  806. }
  807. }
  808. tcurse->Delete();
  809. }
  810. void OctreeGrid::EvaluateKids( Complex kval ) {
  811. assert("Evaluate Kids pre" && Cursor->CurrentIsLeaf());
  812. vtkHyperOctreeCursor *tcurse = Cursor->Clone();
  813. Real p[3];
  814. Octree->SubdivideLeaf(Cursor);
  815. tcurse->ToSameNode(Cursor);
  816. std::cout << "\rPredivide Leaf count: " << Octree->GetNumberOfLeaves();
  817. //std::cout.flush();
  818. for (int child=0; child<8; ++child) {
  819. Cursor->ToChild(child);
  820. assert(Cursor->CurrentIsLeaf());
  821. // Build cube
  822. GetPosition(p);
  823. cpos << p[0], p[1], p[2];
  824. step = ((Size).array() / std::pow(2.,Cursor->GetCurrentLevel()));
  825. Cubes->SetLocation(child, cpos);
  826. Cubes->SetLength(child, step);
  827. //std::cout << "child " << child << " cpos\t" << cpos.transpose() << std::endl;
  828. //std::cout << "child " << child << " step\t" << step.transpose() << std::endl;
  829. Cursor->ToSameNode(tcurse);
  830. }
  831. // make calculation
  832. Cubes->ClearFields();
  833. VectorXcr f = SenseKernel->ComputeSensitivity();
  834. if ( std::abs(std::abs(kval) - std::abs(f.array().abs().sum())) <= tol ||
  835. Cursor->GetCurrentLevel() >= maxlevel ) {
  836. // stop subdividing, save result
  837. for (int child=0; child < 8; ++ child) {
  838. Cursor->ToChild(child);
  839. leafdata.push_back( std::abs(f(child)) / Cubes->GetVolume(child) );
  840. // TODO fval is just a test
  841. //leafdata.push_back( fval );
  842. leafids.push_back(Cursor->GetLeafId());
  843. KernelSum += f(child);
  844. Cursor->ToParent();
  845. }
  846. return;
  847. }
  848. //std::cout << std::abs(kval) << "\t" <<
  849. // std::abs(f.array().abs().sum()) << "\t" << tol << std::endl;
  850. for (int child=0; child < 8; ++ child) {
  851. //std::cout << "Down the rabit hole " <<std::endl;
  852. Cursor->ToChild(child);
  853. EvaluateKids( f(child) );
  854. //Cursor->ToParent();
  855. Cursor->ToSameNode(tcurse);
  856. }
  857. tcurse->Delete();
  858. }
  859. void OctreeGrid::EvaluateKids() {
  860. // TODO, rewrite to not dive into next virtual level do calculation, and then split.
  861. // instead pre-emptively split do analysis and then decide if it should be split again.
  862. // Also, start passing the kernel evaluation from the parent to the kid, so that does not
  863. // need to be repeated. We can purge a lot of recalculation this way.
  864. level = Cursor->GetCurrentLevel();
  865. index = Cursor->GetChildIndex() ;
  866. // current position
  867. // backtrack through parents calculate
  868. // TODO bug, if origin is not (0,0,0) this breaks :(
  869. vtkHyperOctreeCursor *tcurse = Cursor->Clone();
  870. tcurse->ToSameNode(Cursor);
  871. step = ((Size).array() / std::pow(2.,level));
  872. cvol = step[0]*step[1]*step[2];
  873. cpos = Origin + step/2;
  874. // step at this level
  875. Cubes->SetLength(0, step);
  876. //Real stepz0 = step[2];
  877. while (tcurse->GetCurrentLevel() > 0) {
  878. int lev = tcurse->GetCurrentLevel();
  879. index = tcurse->GetChildIndex();
  880. step = ((Size) / std::pow(2.,lev));
  881. Posadd << 0, 0, 0,
  882. step[0], 0, 0,
  883. 0, step[1], 0,
  884. step[0], step[1], 0,
  885. 0, 0, step[2],
  886. step[0], 0, step[2],
  887. 0, step[1], step[2],
  888. step[0], step[1], step[2];
  889. cpos += Posadd.row(index);
  890. tcurse->ToParent();
  891. }
  892. // Root level
  893. int lev = tcurse->GetCurrentLevel();
  894. index = tcurse->GetChildIndex();
  895. step = (Size).array() / (std::pow(2.,lev));
  896. Posadd << 0, 0, 0,
  897. step[0], 0, 0,
  898. 0, step[1], 0,
  899. step[0], step[1], 0,
  900. 0, 0, step[2],
  901. step[0], 0, step[2],
  902. 0, step[1], step[2],
  903. step[0], step[1], step[2];
  904. cpos += Posadd.row(index);
  905. // If this cube has any intersections in the 90% middle, then jump to
  906. // subdividing this up, TODO don't hard code this all in
  907. // NOTE: This works but it is very slow. Causes a TON of cells to be
  908. // created near interface if that interface happens to be in an
  909. // invonventien place. Instead moving this to kernel.
  910. // if ( Model1D->GetLayerAtThisDepth(cpos(2) - .45*stepz0) !=
  911. // Model1D->GetLayerAtThisDepth(cpos(2) + .45*stepz0) && stepz0 > 10) {
  912. // Octree->SubdivideLeaf(Cursor);
  913. // // Evaluate function at cell centre
  914. // for (int child=0; child < Cursor->GetNumberOfChildren(); ++ child) {
  915. // //Vector3r cp = pos + Posadd.row(child).transpose();
  916. // Cursor->ToChild(child);
  917. // EvaluateKids( );
  918. // Cursor->ToParent();
  919. // }
  920. // }
  921. Cubes->SetLocation(0, cpos);
  922. /////////////////////////////////////////
  923. // Next level step
  924. step = (Size).array() / (std::pow(2.,(level+1)));
  925. Vector3r pos = cpos - step/2.;
  926. Posadd << 0, 0, 0,
  927. step[0], 0, 0,
  928. 0, step[1], 0,
  929. step[0], step[1], 0,
  930. 0, 0, step[2],
  931. step[0], 0, step[2],
  932. 0, step[1], step[2],
  933. step[0], step[1], step[2];
  934. Real sum = 0;
  935. Real vv = 0;
  936. for (int child=0; child<8; ++ child) {
  937. // This cell centre and volume
  938. Vector3r cp = pos + Posadd.row(child).transpose();
  939. Cubes->SetLocation(child+1, cp);
  940. Cubes->SetLength(child+1, step);
  941. }
  942. // Evaluate kernel
  943. Cubes->ClearFields();
  944. VectorXcr f = SenseKernel->ComputeSensitivity();
  945. Real val = std::abs(f(0)); // *cvol not needed, kernel does it
  946. Real vol = step[0]*step[1]*step[2];
  947. for (int child=0; child<8; ++ child) {
  948. vv += vol;
  949. sum += std::abs(f(child+1)); // *vol not needed, kernel does it.
  950. }
  951. // split if needed
  952. //std::cout << "f" << f.transpose() << std::endl;
  953. //std::cout << "val " << sum << "\t" << val << "dif " << std::abs(sum - val)
  954. // << std::endl;
  955. //std::cout << "level " << level << "\t" << index << std::endl;
  956. // Volume based test
  957. //if ( (Cursor->CurrentIsLeaf() && std::abs(sum-val) > tol) || level < 4) {
  958. if ( (Cursor->CurrentIsLeaf() && std::abs(sum-val) > tol) || level < 3) {
  959. // Point difference
  960. //if ( Cursor->CurrentIsLeaf() &&
  961. // (f.tail<8>().array()-f(0)).array().abs().maxCoeff() > tol &&
  962. // level < maxlevel ) {
  963. //std::cout << "Subdividing\n";
  964. //if ( Cursor->CurrentIsLeaf() &&
  965. //((f.tail<8>().array()-f(0)).array().abs().maxCoeff()).cast<Real>().eval()[0] > tol ) {
  966. Octree->SubdivideLeaf(Cursor);
  967. std::cout << "\r Leaf count: " << Octree->GetNumberOfLeaves();
  968. std::cout.flush();
  969. // Evaluate function at cell centre
  970. for (int child=0; child < Cursor->GetNumberOfChildren(); ++ child) {
  971. //Vector3r cp = pos + Posadd.row(child).transpose();
  972. Cursor->ToChild(child);
  973. EvaluateKids( ); // TODO EvaluateKids(f(child+1));
  974. Cursor->ToParent();
  975. }
  976. } else if (Cursor->CurrentIsLeaf()) {
  977. // For theta imaging
  978. //Real intpart;
  979. //leafdata.push_back( 2.*std::abs(modf(std::abs(f(0))/(2.*PI), &intpart)-.5) );
  980. leafdata.push_back( std::abs(f(0)) / Cubes->GetVolume(0) );
  981. //Octree->CollapseTerminalNode(Cursor);
  982. leafids.push_back( Cursor->GetLeafId() );
  983. KernelSum += f(0);
  984. //std::cout << ( cvol*std::abs(f(0)) ) << "\n";
  985. }
  986. tcurse->Delete();
  987. }
  988. void OctreeGrid::EvaluateKids(vtkImplicitFunction* Impl) {
  989. level = Cursor->GetCurrentLevel();
  990. index = Cursor->GetChildIndex() ;
  991. // current position
  992. // backtrack through parents calculate
  993. // TODO bug, if origin is not (0,0,0) this breaks :(
  994. vtkHyperOctreeCursor *tcurse = Cursor->Clone();
  995. tcurse->ToSameNode(Cursor);
  996. step = ((Size).array() / std::pow(2.,level));
  997. cvol = step[0]*step[1]*step[2];
  998. cpos = Origin + step/2;
  999. // step at this level
  1000. Cubes->SetLength(0, step);
  1001. while (tcurse->GetCurrentLevel() > 0) {
  1002. int lev = tcurse->GetCurrentLevel();
  1003. index = tcurse->GetChildIndex();
  1004. step = ((Size) / std::pow(2.,lev));
  1005. Posadd << 0, 0, 0,
  1006. step[0], 0, 0,
  1007. 0, step[1], 0,
  1008. step[0], step[1], 0,
  1009. 0, 0, step[2],
  1010. step[0], 0, step[2],
  1011. 0, step[1], step[2],
  1012. step[0], step[1], step[2];
  1013. cpos += Posadd.row(index);
  1014. tcurse->ToParent();
  1015. }
  1016. // Root level
  1017. int lev = tcurse->GetCurrentLevel();
  1018. index = tcurse->GetChildIndex();
  1019. step = (Size).array() / (std::pow(2.,lev));
  1020. Posadd << 0, 0, 0,
  1021. step[0], 0, 0,
  1022. 0, step[1], 0,
  1023. step[0], step[1], 0,
  1024. 0, 0, step[2],
  1025. step[0], 0, step[2],
  1026. 0, step[1], step[2],
  1027. step[0], step[1], step[2];
  1028. cpos += Posadd.row(index);
  1029. Cubes->SetLocation(0, cpos);
  1030. /////////////////////////////////////////
  1031. // Next level step
  1032. step = (Size).array() / (std::pow(2.,(level+1)));
  1033. Vector3r pos = cpos - step/2.;
  1034. Posadd << 0, 0, 0,
  1035. step[0], 0, 0,
  1036. 0, step[1], 0,
  1037. step[0], step[1], 0,
  1038. 0, 0, step[2],
  1039. step[0], 0, step[2],
  1040. 0, step[1], step[2],
  1041. step[0], step[1], step[2];
  1042. Real sum = 0;
  1043. Real vv = 0;
  1044. for (int child=0; child<8; ++ child) {
  1045. // This cell centre and volume
  1046. Vector3r cp = pos + Posadd.row(child).transpose();
  1047. Cubes->SetLocation(child+1, cp);
  1048. Cubes->SetLength(child+1, step);
  1049. }
  1050. // Evaluate kernel
  1051. Cubes->ClearFields();
  1052. VectorXcr f = SenseKernel->ComputeSensitivity(Impl);
  1053. //std::cout << "f " << f.transpose() << std::endl;
  1054. Real val = std::abs(f(0)); // *cvol not needed, kernel does it
  1055. Real vol = step[0]*step[1]*step[2];
  1056. for (int child=0; child<8; ++ child) {
  1057. vv += vol;
  1058. sum += std::abs(f(child+1)); // *vol not needed, kernel does it.
  1059. }
  1060. // split if needed
  1061. // Volume based test
  1062. if ( (Cursor->CurrentIsLeaf() && std::abs(sum-val) > tol) || level < 3) {
  1063. Octree->SubdivideLeaf(Cursor);
  1064. std::cout << "\rLeaf count: " << Octree->GetNumberOfLeaves();
  1065. std::cout.flush();
  1066. // Evaluate function at cell centre
  1067. for (int child=0; child < Cursor->GetNumberOfChildren(); ++ child) {
  1068. //Vector3r cp = pos + Posadd.row(child).transpose();
  1069. Cursor->ToChild(child);
  1070. EvaluateKids( Impl );
  1071. Cursor->ToParent();
  1072. }
  1073. } else if (Cursor->CurrentIsLeaf()) {
  1074. // For theta imaging
  1075. //Real intpart;
  1076. //leafdata.push_back( 2.*std::abs(modf(std::abs(f(0))/(2.*PI), &intpart)-.5) );
  1077. leafdata.push_back( std::abs(f(0)) / Cubes->GetVolume(0) );
  1078. //leafdata.push_back( Impl->EvaluateFunction(cpos[0],cpos[1], cpos[2]) );
  1079. //leafdata.push_back( cpos[1] );
  1080. leafids.push_back(Cursor->GetLeafId());
  1081. KernelSum += f(0);
  1082. //if ( std::abs(f(0)) > 1e-30 ) {
  1083. // std::cout.precision(12);
  1084. // std::cout << "leaf data " << sum << "\t" << f(0) << "\t" << Cubes->GetVolume(0) << std::endl;
  1085. //}
  1086. } // else {
  1087. // for (int child=0; child < Cursor->GetNumberOfChildren(); ++ child) {
  1088. // //Vector3r cp = pos + Posadd.row(child).transpose();
  1089. // Cursor->ToChild(child);
  1090. // EvaluateKids( Impl );
  1091. // Cursor->ToParent();
  1092. // }
  1093. //}
  1094. tcurse->Delete();
  1095. }
  1096. void OctreeGrid::EvaluateKids(const Real& fval, vtkImplicitFunction* Impl) {
  1097. assert("Evaluate Kids pre" && Cursor->CurrentIsLeaf());
  1098. vtkHyperOctreeCursor *tcurse = Cursor->Clone();
  1099. VectorXr Values(9);
  1100. Values(0) = fval;
  1101. Real p[3];
  1102. // at this level
  1103. GetPosition(p);
  1104. cpos << p[0], p[1], p[2];
  1105. step = ((Size).array() / std::pow(2.,Cursor->GetCurrentLevel()));
  1106. Cubes->SetLocation(0, cpos);
  1107. Cubes->SetLength(0, step);
  1108. Octree->SubdivideLeaf(Cursor);
  1109. tcurse->ToSameNode(Cursor);
  1110. std::cout << "\r Leaf count: " << Octree->GetNumberOfLeaves();
  1111. // TODO can this be parallelised? I don't know if call to FunctionValue is thread safe
  1112. for (int child=0; child<Cursor->GetNumberOfChildren(); ++child) {
  1113. Cursor->ToChild(child);
  1114. assert(Cursor->CurrentIsLeaf());
  1115. // Build cube
  1116. GetPosition(p);
  1117. Values[child+1] = Impl->FunctionValue(p);
  1118. cpos << p[0], p[1], p[2];
  1119. step = ((Size).array() / std::pow(2.,Cursor->GetCurrentLevel()));
  1120. Cubes->SetLocation(child+1, cpos);
  1121. Cubes->SetLength(child+1, step);
  1122. Cursor->ToSameNode(tcurse);
  1123. }
  1124. // make calculation
  1125. Cubes->ClearFields();
  1126. // TODO if Values don't change much, we can set them static and use old logic
  1127. VectorXcr f = SenseKernel->ComputeSensitivity(Values); // TODO here
  1128. if ( std::abs(std::abs(f(0)) - std::abs(f.segment<8>(1).array().abs().sum())) < tol ||
  1129. Cursor->GetCurrentLevel() >= maxlevel ) {
  1130. // stop subdividing, save result
  1131. for (int child=0; child < Cursor->GetNumberOfChildren(); ++ child) {
  1132. Cursor->ToChild(child);
  1133. leafdata.push_back( std::abs(f(child+1)) / Cubes->GetVolume(child+1) );
  1134. // TODO fval is just a test
  1135. //leafdata.push_back( fval );
  1136. leafids.push_back(Cursor->GetLeafId());
  1137. KernelSum += f(child+1);
  1138. Cursor->ToParent();
  1139. }
  1140. return;
  1141. }
  1142. for (int child=0; child < Cursor->GetNumberOfChildren(); ++ child) {
  1143. Cursor->ToChild(child);
  1144. VectorXr nv = (Values.array()-Values(0));
  1145. if ( nv.norm() > 1e-2) { // TODO don't hard code this
  1146. EvaluateKids( fval , Impl);
  1147. } else {
  1148. EvaluateKidsStatic( Values[child+1] );
  1149. }
  1150. Cursor->ToParent();
  1151. }
  1152. tcurse->Delete();
  1153. }
  1154. void OctreeGrid::EvaluateKidsStatic(const Real& fval) {
  1155. assert("Evaluate Kids pre" && Cursor->CurrentIsLeaf());
  1156. vtkHyperOctreeCursor *tcurse = Cursor->Clone();
  1157. Real p[3];
  1158. // at this level
  1159. GetPosition(p);
  1160. cpos << p[0], p[1], p[2];
  1161. step = ((Size).array() / std::pow(2.,Cursor->GetCurrentLevel()));
  1162. Cubes->SetLocation(0, cpos);
  1163. Cubes->SetLength(0, step);
  1164. Octree->SubdivideLeaf(Cursor);
  1165. tcurse->ToSameNode(Cursor);
  1166. std::cout << "\rStatic Leaf count: " << Octree->GetNumberOfLeaves();
  1167. for (int child=0; child<Cursor->GetNumberOfChildren(); ++child) {
  1168. Cursor->ToChild(child);
  1169. assert(Cursor->CurrentIsLeaf());
  1170. // Build cube
  1171. GetPosition(p);
  1172. cpos << p[0], p[1], p[2];
  1173. step = ((Size).array() / std::pow(2.,Cursor->GetCurrentLevel()));
  1174. Cubes->SetLocation(child+1, cpos);
  1175. Cubes->SetLength(child+1, step);
  1176. Cursor->ToSameNode(tcurse);
  1177. }
  1178. // make calculation
  1179. Cubes->ClearFields();
  1180. // TODO if Values don't change much, we can set them static and use old logic
  1181. VectorXcr f = SenseKernel->ComputeSensitivity(fval); // TODO here
  1182. if ( std::abs(std::abs(f(0)) - std::abs(f.segment<8>(1).array().abs().sum())) < tol ||
  1183. Cursor->GetCurrentLevel() >= maxlevel ) {
  1184. // stop subdividing, save result
  1185. for (int child=0; child < Cursor->GetNumberOfChildren(); ++ child) {
  1186. Cursor->ToChild(child);
  1187. leafdata.push_back( std::abs(f(child+1)) / Cubes->GetVolume(child+1) );
  1188. //leafdata.push_back( 1 );
  1189. // TODO fval is just a test
  1190. //leafdata.push_back( fval );
  1191. leafids.push_back(Cursor->GetLeafId());
  1192. KernelSum += f(child+1);
  1193. Cursor->ToParent();
  1194. }
  1195. return;
  1196. }
  1197. for (int child=0; child < Cursor->GetNumberOfChildren(); ++ child) {
  1198. Cursor->ToChild(child);
  1199. EvaluateKidsStatic( fval );
  1200. Cursor->ToParent();
  1201. }
  1202. tcurse->Delete();
  1203. }
  1204. // ==================== ACCESS =======================
  1205. void OctreeGrid::SetLeafDataFromGridCreation() {
  1206. if ( (int)(leafdata.size()) != Octree->GetNumberOfLeaves() ) {
  1207. std::cerr << "BADNESS IN GRID CREATIONS" << std::endl;
  1208. std::cerr << "octreegrid.cpp:SetLeafDataFromGridCreation" << std::endl;
  1209. exit(EXIT_FAILURE);
  1210. }
  1211. this->KernelArray->SetName("unnormalised kernel");
  1212. this->KernelArray->SetNumberOfTuples(leafdata.size());
  1213. //Real maxval = *max_element(leafdata.begin(), leafdata.end());
  1214. for (unsigned int i=0; i<leafdata.size(); ++i) {
  1215. // KernelArray->SetValue(leafids[i], leafdata[i]/maxval);
  1216. KernelArray->SetValue(leafids[i], leafdata[i]); //maxval);
  1217. }
  1218. //this->KernelArray->SetArray(&leafdata[0], leafdata.size(), 0);
  1219. //this->Octree->GetLeafData()->AddArray( KernelArray );
  1220. this->Octree->GetLeafData()->SetScalars( KernelArray );
  1221. }
  1222. void OctreeGrid::SetSize(const Vector3r& size) {
  1223. this->Size = size;
  1224. Octree->SetSize(size[0], size[1], size[2]);
  1225. }
  1226. void OctreeGrid::SetOrigin(const Vector3r& origin) {
  1227. this->Origin = origin;
  1228. Octree->SetOrigin(origin[0], origin[1], origin[2]);
  1229. }
  1230. void OctreeGrid::SetSize(const Real&x, const Real &y, const Real &z) {
  1231. this->Size << x,y,z;
  1232. Octree->SetSize(x, y, z);
  1233. }
  1234. void OctreeGrid::SetMinimumDepth(const Real& depth) {
  1235. //Octree->SetOrigin(0,0,depth);
  1236. //Origin << 0,0,depth;
  1237. Octree->SetOrigin(Origin[0], Origin[1], depth);
  1238. Origin(2) = depth;
  1239. }
  1240. vtkHyperOctree* OctreeGrid::GetVtkHyperOctree() {
  1241. //this->Octree->Update();
  1242. return this->Octree;
  1243. }
  1244. void OctreeGrid::SetKernel(Kernel *kern) {
  1245. if (SenseKernel != NULL) {
  1246. SenseKernel->DetachFrom(this);
  1247. }
  1248. kern->AttachTo(this);
  1249. SenseKernel = kern;
  1250. // TODO bug here, detach fail
  1251. SenseKernel->SetFieldCubes(Cubes);
  1252. }
  1253. void OctreeGrid::SetLayeredEarth(LayeredEarth* model1d) {
  1254. if (Model1D != NULL) {
  1255. Model1D->DetachFrom(this);
  1256. }
  1257. model1d->AttachTo(this);
  1258. Model1D = model1d;
  1259. }
  1260. // ==================== OPERATIONS =======================
  1261. } // ----- end of Lemma name -----
  1262. #endif // LEMMAUSEVTK