Commit d07a6169 authored by DUFOYER Benjamin's avatar DUFOYER Benjamin

adding function for linear_tree

parent f0b25975
......@@ -70,6 +70,8 @@ using node_info_from_range = node::info<T::value_type::position_t::Dim>;
/**
* [INFO] : Every leaf of the returned linear tree don't have necessarily
* the same level
* \brief Create a distributed linear tree from a sorted particle list
*
* \warning The particle list must be sorted accross the processes.
......@@ -104,8 +106,8 @@ create_balanced_linear_tree(
if(! sorted_particles.empty()) {
auto min_idx = get_morton_index(sorted_particles.front().position(), box, level_);
min_oct = node_info_t{min_idx, level_};
auto max_idx = get_morton_index(sorted_particles.back().position(), box, level_);
max_oct = node_info_t{max_idx, level_};
auto max_morton_idx = get_morton_index(sorted_particles.back().position(), box, level_);
max_oct = node_info_t{max_morton_idx, level_};
}
// Complete the local region based on sorted particles
......@@ -122,10 +124,12 @@ create_balanced_linear_tree(
return level(n) > min_level;
}),
end(local_region));
// Complete distributed octree
std::vector<node_info_t> local_tree;
distributed_regions_to_linear_tree(conf, begin(local_region), end(local_region), local_tree);
// Compute the weight of each octant to redistribute them among processes
gather_octants_weight(conf, begin(local_tree), end(local_tree),
begin(sorted_particles), end(sorted_particles), box);
......@@ -138,6 +142,9 @@ create_balanced_linear_tree(
}
/**
* \brief Create a distributed linear tree from a particle list
*
......@@ -172,6 +179,122 @@ create_balanced_linear_tree(
return create_balanced_linear_tree(conf, level_, box, sorted_particles);
}
/**
* send_get_max_morton_idx this function send the max morton index of the current proc
* to the proc n+1.
* The current proc recev the max morton index of the proc n-1 and return it
* @author benjamin.dufoyer@inria.fr
* @param conf MPI conf
* @param max_morton_idx max morton_index of the current proc
* @return [description]
*/
std::size_t send_get_max_morton_idx(
inria::mpi_config& conf,
std::size_t& max_morton_idx
)
{
// Setting parametter
const int nb_proc = conf.comm.size();
const int my_rank = conf.comm.rank();
// compute the buffer size
std::size_t buff_recev{max_morton_idx+1};
if(nb_proc != 1 ){
inria::mpi::request tab_mpi_status[1];
// compute the buffer size
int size_buff = (int)sizeof(std::size_t);
// if i'm not the last proc
if(my_rank != nb_proc-1){
// Sending my max
conf.comm.isend(&max_morton_idx,
size_buff,
MPI_CHAR,
my_rank+1,1);
}
// if i'm not the first proc
if(my_rank != 0){
// Receiv the max of the left proc
tab_mpi_status[0] = conf.comm.irecv(&buff_recev,
size_buff,
MPI_CHAR,
my_rank-1,1);
}
// Waiting for the result of the request, if my rank is 0
// I don't need to wait
if(my_rank != 0)
inria::mpi::request::waitall(1,tab_mpi_status);
}
return buff_recev;
}
/**
* This function create a linear tree from a level, he compute every leaf
* at the level put in parameter
*
* 1 ) The first step is to send my max morton index of leaf to the right (n+1)
* proc
*
* 2) Compute the number of morton index to alloc the vector
*
* 3) stock all morton index in vector
*
* @author benjamin.dufoyer@inria.fr
* @param level_ to compute the leaf
* @param box box to compute morton index
* @param sorted_particle particles, they will be sorted BEFORE calling this
* function
* @return linear tree with leaf at the same level
*/
template<class Range, class Box>
std::vector<details::cblt::node_info_from_range<Range>> create_balanced_linear_tree_at_level(
inria::mpi_config conf,
std::size_t level_,
Box& box,
Range& sorted_particles)
{
// define type
using particle_t = typename Range::value_type;
using node_info_t = details::weighted_node_info<particle_t>;
// compute the max morton index to create the linear tree
size_t max_morton_idx{};
if(! sorted_particles.empty()) {
max_morton_idx = get_morton_index(sorted_particles.back().position(), box, level_);
}
// Send my max morton index
size_t maxMortonBeforeMe {send_get_max_morton_idx(conf,max_morton_idx)};
// Compute the number of morton index
unsigned nb_leaf = 0;
std::size_t last_morton_index = max_morton_idx;
for(unsigned i = 0; i < sorted_particles.size() ; i++ ){
size_t curr_idx_morton = get_morton_index(sorted_particles.at(i).position(),box,level_);
if(curr_idx_morton != last_morton_index && curr_idx_morton != maxMortonBeforeMe){
last_morton_index = curr_idx_morton;
++nb_leaf;
}
}
// initialise the linear tree
std::vector<node_info_t> lin_tree{nb_leaf};
// Compute the number of leaf
// the idea is to get every morton_index at the level_
// when we find a new morton_index, it's a new leaf so we put her in
// the linear tree
nb_leaf = 0;
last_morton_index = -1;
for(unsigned i = 0; i < sorted_particles.size(); ++i){
size_t curr_idx_morton = get_morton_index(sorted_particles.at(i).position(),box,level_);
// Check if it's a new morton index
if(curr_idx_morton != last_morton_index && curr_idx_morton != maxMortonBeforeMe){ // creation of the leaf
node_info_t newleaf{curr_idx_morton,level_};
// adding the leaf in the linear_tree
lin_tree.at(nb_leaf) = newleaf;
// increment variable
last_morton_index = curr_idx_morton;
++nb_leaf;
}
}
return {begin(lin_tree), end(lin_tree)};
}
namespace details {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment