mpi_complete_tree_debug/
mpi_complete_tree_debug.rsuse bempp_octree::{
morton::MortonKey,
octree::{is_complete_linear_and_balanced, KeyType, Octree},
tools::{gather_to_all, generate_random_points},
};
use itertools::Itertools;
use mpi::traits::Communicator;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
pub fn main() {
let universe = mpi::initialize().unwrap();
let comm = universe.world();
let mut rng = ChaCha8Rng::seed_from_u64(comm.rank() as u64);
let npoints = 10000;
let mut points = generate_random_points(npoints, &mut rng, &comm);
for point in points.iter_mut() {
let len = point.coords()[0] * point.coords()[0]
+ point.coords()[1] * point.coords()[1]
+ point.coords()[2] * point.coords()[2];
let len = len.sqrt();
point.coords_mut()[0] /= len;
point.coords_mut()[1] /= len;
point.coords_mut()[2] /= len;
}
let tree = Octree::new(&points, 15, 50, &comm);
let leaf_tree = tree.leaf_keys();
let all_keys = tree.all_keys();
assert!(is_complete_linear_and_balanced(leaf_tree, &comm));
for &key in leaf_tree {
let mut parent = key.parent();
while parent.level() > 0 {
assert!(all_keys.contains_key(&key));
for neighbor in parent.neighbours().iter().filter(|&key| key.is_valid()) {
assert!(all_keys.contains_key(neighbor));
}
parent = parent.parent();
assert!(all_keys.contains_key(&parent));
}
}
assert!(all_keys.contains_key(&MortonKey::root()));
let nghosts = all_keys
.iter()
.filter_map(|(_, &value)| {
if let KeyType::Ghost(rank) = value {
assert!(rank != comm.size() as usize);
Some(rank)
} else {
None
}
})
.count();
if comm.size() == 1 {
assert_eq!(nghosts, 0);
} else {
assert!(nghosts > 0);
}
let nglobal = all_keys
.iter()
.filter(|(_, &value)| matches!(value, KeyType::Global))
.count();
let nglobals = gather_to_all(std::slice::from_ref(&nglobal), &comm);
assert_eq!(nglobals.iter().unique().count(), 1);
let mut npoints = 0;
let leaf_point_map = tree.leaf_keys_to_local_point_indices();
for (key, point_indices) in leaf_point_map {
for &index in point_indices {
assert!(key.is_ancestor(tree.point_keys()[index]));
}
npoints += point_indices.len();
}
assert_eq!(npoints, tree.points().len());
assert_eq!(npoints, tree.point_keys().len());
let all_neighbours = tree.neighbour_map();
let all_keys = tree.all_keys();
for (key, key_type) in all_keys {
match key_type {
KeyType::Ghost(_) => assert!(!all_neighbours.contains_key(key)),
_ => {
assert!(all_neighbours.contains_key(key));
}
}
}
if comm.rank() == 0 {
println!("No errors were found in setting up tree.");
}
}