mpi_complete_tree_debug/
mpi_complete_tree_debug.rs1use bempp_octree::{
4 morton::MortonKey,
5 octree::{is_complete_linear_and_balanced, KeyType, Octree},
6 tools::{gather_to_all, generate_random_points},
7};
8use itertools::Itertools;
9use mpi::traits::Communicator;
10use rand::prelude::*;
11use rand_chacha::ChaCha8Rng;
12
13pub fn main() {
14 let universe = mpi::initialize().unwrap();
16
17 let comm = universe.world();
19
20 let mut rng = ChaCha8Rng::seed_from_u64(comm.rank() as u64);
22
23 let npoints = 10000;
25
26 let mut points = generate_random_points(npoints, &mut rng, &comm);
29 for point in points.iter_mut() {
31 let len = point.coords()[0] * point.coords()[0]
32 + point.coords()[1] * point.coords()[1]
33 + point.coords()[2] * point.coords()[2];
34 let len = len.sqrt();
35 point.coords_mut()[0] /= len;
36 point.coords_mut()[1] /= len;
37 point.coords_mut()[2] /= len;
38 }
39
40 let tree = Octree::new(&points, 15, 50, &comm);
41
42 let leaf_tree = tree.leaf_keys();
45 let all_keys = tree.all_keys();
46
47 assert!(is_complete_linear_and_balanced(leaf_tree, &comm));
48 for &key in leaf_tree {
49 let mut parent = key.parent();
52 while parent.level() > 0 {
53 assert!(all_keys.contains_key(&key));
55 for neighbor in parent.neighbours().iter().filter(|&key| key.is_valid()) {
57 assert!(all_keys.contains_key(neighbor));
58 }
59 parent = parent.parent();
60 assert!(all_keys.contains_key(&parent));
62 }
63 }
64
65 assert!(all_keys.contains_key(&MortonKey::root()));
67
68 let nghosts = all_keys
74 .iter()
75 .filter_map(|(_, &value)| {
76 if let KeyType::Ghost(rank) = value {
77 assert!(rank != comm.size() as usize);
78 Some(rank)
79 } else {
80 None
81 }
82 })
83 .count();
84
85 if comm.size() == 1 {
86 assert_eq!(nghosts, 0);
87 } else {
88 assert!(nghosts > 0);
89 }
90
91 let nglobal = all_keys
92 .iter()
93 .filter(|(_, &value)| matches!(value, KeyType::Global))
94 .count();
95
96 let nglobals = gather_to_all(std::slice::from_ref(&nglobal), &comm);
99
100 assert_eq!(nglobals.iter().unique().count(), 1);
101
102 let mut npoints = 0;
104 let leaf_point_map = tree.leaf_keys_to_local_point_indices();
105
106 for (key, point_indices) in leaf_point_map {
107 for &index in point_indices {
108 assert!(key.is_ancestor(tree.point_keys()[index]));
109 }
110 npoints += point_indices.len();
111 }
112
113 assert_eq!(npoints, tree.points().len());
116 assert_eq!(npoints, tree.point_keys().len());
117
118 let all_neighbours = tree.neighbour_map();
121 let all_keys = tree.all_keys();
122
123 for (key, key_type) in all_keys {
124 match key_type {
126 KeyType::Ghost(_) => assert!(!all_neighbours.contains_key(key)),
127 _ => {
128 assert!(all_neighbours.contains_key(key));
130 }
131 }
132 }
133
134 if comm.rank() == 0 {
135 println!("No errors were found in setting up tree.");
136 }
137}