Lemma is an Electromagnetics API
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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