powerio_matrix/synth/
tree.rs1use rand::Rng;
4use rand::SeedableRng;
5use rand_chacha::ChaCha8Rng;
6
7use crate::network::{Branch, Bus, BusId, BusType, Network};
8
9use super::SynthSpec;
10
11pub fn generate_tree(spec: &SynthSpec) -> Network {
12 let n = spec.n.max(2);
13 let mut rng = ChaCha8Rng::seed_from_u64(spec.seed);
14 let buses = make_buses(n);
15
16 let mut branches = Vec::with_capacity(n - 1);
18 for k in 1..n {
19 let parent = rng.random_range(0..k);
20 branches.push(make_branch(parent + 1, k + 1, spec, &mut rng));
21 }
22
23 net(format!("synth_tree_n{n}"), buses, branches)
24}
25
26pub(super) fn net(name: String, buses: Vec<Bus>, branches: Vec<Branch>) -> Network {
29 Network::in_memory(name, 100.0, buses, branches)
30}
31
32pub(crate) fn make_buses(n: usize) -> Vec<Bus> {
37 let mut buses: Vec<Bus> = (0..n).map(|i| make_bus(i + 1)).collect();
38 buses[0].kind = BusType::Ref;
39 buses
40}
41
42pub(crate) fn make_bus(id: usize) -> Bus {
43 Bus::new(BusId(id), BusType::Pq, 345.0)
44}
45
46pub(crate) fn make_branch(
47 from: usize,
48 to: usize,
49 spec: &SynthSpec,
50 rng: &mut ChaCha8Rng,
51) -> Branch {
52 let log_low = (spec.mean_x * 0.5).ln();
54 let log_high = (spec.mean_x * 2.0).ln();
55 let log_x: f64 = rng.random_range(log_low..log_high);
56 let x = log_x.exp().max(1e-6);
57 let r = spec.r_over_x * x;
58 Branch::new(BusId(from), BusId(to), r, x)
59}