libtree.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #include <sctl.hpp>
  2. namespace SCTL_NAMESPACE {
  3. template <class Real, Integer DIM> class ParticleTreeWrapper {
  4. public:
  5. ParticleTreeWrapper(Comm comm = Comm::World()) : tree_(comm) {}
  6. void GetTree(const Real*& node_coord, const int32_t*& parent_lst, const int32_t*& child_lst, const int8_t*& node_depth, const int8_t*& node_ghost, const int8_t*& node_leaf, int32_t& Nnodes) const {
  7. static constexpr Integer MAX_CHILD = (1u << DIM);
  8. const auto& node_mid_ = tree_.GetNodeMID();
  9. const auto& node_attr_ = tree_.GetNodeAttr();
  10. SCTL_ASSERT(node_mid_.Dim() == node_attr_.Dim());
  11. Nnodes = node_mid_.Dim();
  12. if (node_coord_.Dim() != Nnodes*DIM ) node_coord_.ReInit(Nnodes*DIM );
  13. if (parent_lst_.Dim() != Nnodes ) parent_lst_.ReInit(Nnodes );
  14. if (child_lst_ .Dim() != Nnodes*MAX_CHILD) child_lst_ .ReInit(Nnodes*MAX_CHILD);
  15. if (node_depth_.Dim() != Nnodes ) node_depth_.ReInit(Nnodes );
  16. if (node_ghost_.Dim() != Nnodes ) node_ghost_.ReInit(Nnodes );
  17. if (node_leaf_ .Dim() != Nnodes ) node_leaf_ .ReInit(Nnodes );
  18. Vector<Long> ancestors(Morton<DIM>::MAX_DEPTH);
  19. Vector<Long> child_cnt(Morton<DIM>::MAX_DEPTH);
  20. #pragma omp parallel for schedule(static)
  21. for (Long i = 0; i < Nnodes; i++) {
  22. node_mid_[i].template Coord<Real>(node_coord_.begin() + i*DIM);
  23. node_depth_[i] = node_mid_[i].Depth();
  24. node_ghost_[i] = node_attr_[i].Ghost;
  25. node_leaf_ [i] = node_attr_[i].Leaf;
  26. parent_lst_[i] = -1;
  27. for (Integer j = 0; j < MAX_CHILD; j++) child_lst_[i*MAX_CHILD+j] = -1;
  28. }
  29. for (Long i = 0; i < Nnodes; i++) { // Set parent_lst, child_lst_
  30. Integer depth = node_mid_[i].Depth();
  31. ancestors[depth] = i;
  32. child_cnt[depth] = 0;
  33. if (depth) {
  34. Long p = ancestors[depth-1];
  35. Long& c = child_cnt[depth-1];
  36. parent_lst_[i] = p+1; // +1 because indexing starts from 1 in fortran
  37. child_lst_[p*MAX_CHILD+c] = i+1; // +1 because indexing starts from 1 in fortran
  38. c++;
  39. }
  40. }
  41. node_coord = &node_coord_[0];
  42. parent_lst = &parent_lst_[0];
  43. child_lst = &child_lst_ [0];
  44. node_depth = &node_depth_[0];
  45. node_ghost = &node_ghost_[0];
  46. node_leaf = &node_leaf_ [0];
  47. }
  48. void UpdateRefinement(const Real* pt_coord_, int32_t Npt, int32_t max_pts, bool level_restrict, bool periodic) {
  49. const Vector<Real> pt_coord(Npt*DIM, Ptr2Itr<Real>((Real*)pt_coord_,Npt*DIM), false);
  50. tree_.UpdateRefinement(pt_coord, max_pts, level_restrict, periodic);
  51. }
  52. void AddData(const char* name, const Real* data, int32_t Ndata, const int32_t* cnt, int32_t Ncnt) {
  53. SCTL_ASSERT(Ncnt == tree_.GetNodeMID().Dim());
  54. const Vector<Real> data_(Ndata, Ptr2Itr<Real>((Real*)data, Ndata), false);
  55. Vector<Long> cnt_(Ncnt);
  56. for (Long i = 0; i < Ncnt; i++) cnt_[i] = cnt[i];
  57. tree_.AddData(name, data_, cnt_);
  58. }
  59. void GetData(Real*& data, int32_t& Ndata, const int32_t*& cnt, int32_t& Ncnt, const char* name) {
  60. Vector<Real> data_;
  61. Vector<Long> cnt_;
  62. tree_.GetData(data_, cnt_, name);
  63. data = &data_[0];
  64. Ndata = data_.Dim();
  65. Ncnt = cnt_.Dim();
  66. Vector<int32_t>& data_cnt = data_cnt_[name];
  67. data_cnt.ReInit(Ncnt);
  68. for (Long i = 0; i < Ncnt; i++) data_cnt[i] = cnt_[i];
  69. cnt = &data_cnt[0];
  70. }
  71. void DeleteData(const char* name) {
  72. tree_.DeleteData(name);
  73. }
  74. void WriteTreeVTK(const char* fname, bool show_ghost) const {
  75. tree_.WriteTreeVTK(fname, show_ghost);
  76. }
  77. void AddParticles(const char* name, const Real* coord, int32_t Npt) {
  78. const Vector<Real> coord_(Npt*DIM, Ptr2Itr<Real>((Real*)coord,Npt*DIM), false);
  79. tree_.AddParticles(name, coord_);
  80. }
  81. void AddParticleData(const char* name, const char* particle_name, const Real* data, int32_t Ndata) {
  82. const Vector<Real> data_(Ndata, Ptr2Itr<Real>((Real*)data,Ndata), false);
  83. tree_.AddParticleData(name, particle_name, data_);
  84. }
  85. void GetParticleData(Real*& data, int32_t& N, const char* name) const {
  86. Vector<Real>& data_ = pt_data_[name];
  87. tree_.GetParticleData(data_, name);
  88. N = data_.Dim();
  89. data = &data_[0];
  90. }
  91. void DeleteParticleData(const char* name) {
  92. tree_.DeleteParticleData(name);
  93. }
  94. void WriteParticleVTK(const char* fname, const char* data_name, bool show_ghost) const {
  95. tree_.WriteParticleVTK(fname, data_name, show_ghost);
  96. }
  97. private:
  98. PtTree<Real,DIM> tree_;
  99. mutable Vector<Real> node_coord_;
  100. mutable Vector<int32_t> parent_lst_;
  101. mutable Vector<int32_t> child_lst_;
  102. mutable Vector<int8_t> node_depth_;
  103. mutable Vector<int8_t> node_ghost_;
  104. mutable Vector<int8_t> node_leaf_;
  105. mutable std::map<std::string,Vector<int32_t>> data_cnt_;
  106. mutable std::map<std::string,Vector<Real>> pt_data_;
  107. };
  108. }
  109. #ifdef __cplusplus
  110. extern "C" {
  111. #endif
  112. void createtree_(void** tree) {
  113. tree[0] = (void*) new sctl::ParticleTreeWrapper<double,3>(sctl::Comm::World());
  114. }
  115. void deletetree_(void** tree) {
  116. delete (sctl::ParticleTreeWrapper<double,3>*)tree[0];
  117. tree[0] = nullptr;
  118. }
  119. void gettree_(const double** node_coord, const int32_t** parent_lst, const int32_t** child_lst, const int8_t** node_depth, const int8_t** node_ghost, const int8_t** node_leaf, int32_t* Nnodes, const void** tree_ctx) {
  120. const sctl::ParticleTreeWrapper<double,3>& tree = *(sctl::ParticleTreeWrapper<double,3>*)tree_ctx[0];
  121. tree.GetTree(*node_coord, *parent_lst, *child_lst, *node_depth, *node_ghost, *node_leaf, *Nnodes);
  122. }
  123. void updaterefinement_(const double* pt_coord_, const int32_t* Npt, const int32_t* max_pts, bool* level_restrict, bool* periodic, void** tree_ctx) {
  124. sctl::ParticleTreeWrapper<double,3>& tree = *(sctl::ParticleTreeWrapper<double,3>*)tree_ctx[0];
  125. tree.UpdateRefinement(pt_coord_, *Npt, *max_pts, *level_restrict, *periodic);
  126. }
  127. void adddata_(const char* name, const double* data, const int32_t* Ndata, const int32_t* cnt, const int32_t* Ncnt, void** tree_ctx) {
  128. sctl::ParticleTreeWrapper<double,3>& tree = *(sctl::ParticleTreeWrapper<double,3>*)tree_ctx[0];
  129. tree.AddData(name, data, *Ndata, cnt, *Ncnt);
  130. }
  131. void getdata_(double** data, int32_t* Ndata, const int32_t** cnt, int32_t* Ncnt, const char* name, void** tree_ctx) {
  132. sctl::ParticleTreeWrapper<double,3>& tree = *(sctl::ParticleTreeWrapper<double,3>*)tree_ctx[0];
  133. tree.GetData(*data, *Ndata, *cnt, *Ncnt, name);
  134. }
  135. void deletedata_(const char* name, void** tree_ctx) {
  136. sctl::ParticleTreeWrapper<double,3>& tree = *(sctl::ParticleTreeWrapper<double,3>*)tree_ctx[0];
  137. tree.DeleteData(name);
  138. }
  139. void writetreevtk_(const char* fname, const bool* show_ghost, const void** tree_ctx) {
  140. const sctl::ParticleTreeWrapper<double,3>& tree = *(sctl::ParticleTreeWrapper<double,3>*)tree_ctx[0];
  141. tree.WriteTreeVTK(fname, *show_ghost);
  142. }
  143. void addparticles_(const char* name, const double* coord, const int32_t* Npt, void** tree_ctx) {
  144. sctl::ParticleTreeWrapper<double,3>& tree = *(sctl::ParticleTreeWrapper<double,3>*)tree_ctx[0];
  145. tree.AddParticles(name, coord, *Npt);
  146. }
  147. void addparticledata_(const char* name, const char* particle_name, const double* data, const int32_t* Ndata, void** tree_ctx) {
  148. sctl::ParticleTreeWrapper<double,3>& tree = *(sctl::ParticleTreeWrapper<double,3>*)tree_ctx[0];
  149. tree.AddParticleData(name, particle_name, data, *Ndata);
  150. }
  151. void getparticledata_(double** data, int32_t* N, const char* name, const void** tree_ctx) {
  152. const sctl::ParticleTreeWrapper<double,3>& tree = *(sctl::ParticleTreeWrapper<double,3>*)tree_ctx[0];
  153. tree.GetParticleData(*data, *N, name);
  154. }
  155. void deleteparticledata_(const char* name, void** tree_ctx) {
  156. sctl::ParticleTreeWrapper<double,3>& tree = *(sctl::ParticleTreeWrapper<double,3>*)tree_ctx[0];
  157. tree.DeleteParticleData(name);
  158. }
  159. void writeparticlevtk_(const char* fname, const char* data_name, bool* show_ghost, const void** tree_ctx) {
  160. const sctl::ParticleTreeWrapper<double,3>& tree = *(sctl::ParticleTreeWrapper<double,3>*)tree_ctx[0];
  161. tree.WriteParticleVTK(fname, data_name, *show_ghost);
  162. }
  163. #ifdef __cplusplus
  164. }
  165. #endif