1 | #include "madx.h" |
---|
2 | |
---|
3 | static struct element* |
---|
4 | get_drift(double length) |
---|
5 | /* makes a drift space with the required length */ |
---|
6 | { |
---|
7 | const double tol = 1e-12; // length tolerance for sharing implicit drift |
---|
8 | struct element *p, *bt; |
---|
9 | struct command* clone; |
---|
10 | char key[NAME_L]; |
---|
11 | |
---|
12 | for (int i = 0; i < drift_list->curr; i++) { |
---|
13 | p = drift_list->elem[i]; |
---|
14 | if (fabs(p->length - length) < tol) return p; |
---|
15 | } |
---|
16 | |
---|
17 | sprintf(key, "drift_%d", drift_list->curr); |
---|
18 | bt = find_element("drift", base_type_list); |
---|
19 | clone = clone_command(bt->def); |
---|
20 | store_comm_par_value("l", length, clone); |
---|
21 | p = make_element(key, "drift", clone, 0); |
---|
22 | add_to_el_list(&p, 1, drift_list, 0); |
---|
23 | return p; |
---|
24 | } |
---|
25 | |
---|
26 | int |
---|
27 | add_drifts(struct node* c_node, struct node* end) |
---|
28 | { |
---|
29 | const double tol = 1e-6; |
---|
30 | int cnt; |
---|
31 | |
---|
32 | if (!c_node) return 0; |
---|
33 | |
---|
34 | for (cnt=1; c_node != end && c_node->next; c_node = c_node->next, cnt++) { |
---|
35 | double drift_beg = c_node->position + c_node->length / 2; |
---|
36 | double drift_end = c_node->next->position - c_node->next->length / 2; |
---|
37 | double drift_len = drift_end-drift_beg; |
---|
38 | |
---|
39 | if (drift_len < -tol) { |
---|
40 | // implicit drift with negative length |
---|
41 | char buf[256]; |
---|
42 | sprintf(buf, " %s and %s, length %e", c_node->name, c_node->next->name, drift_len); |
---|
43 | fatal_error("negative drift between elements", buf); |
---|
44 | } |
---|
45 | else if (drift_len > tol) { |
---|
46 | // create or share 'long-enough' implicit drift |
---|
47 | struct element *drift = get_drift(drift_len); |
---|
48 | struct node *drift_node = new_elem_node(drift, 0); |
---|
49 | link_in_front(drift_node, c_node->next); |
---|
50 | drift_node->position = drift_beg + drift_len / 2; |
---|
51 | cnt++; |
---|
52 | } |
---|
53 | else |
---|
54 | // length in [-tol, tol], nothing to do (no drift inserted) |
---|
55 | (void)0; |
---|
56 | } |
---|
57 | |
---|
58 | return cnt; |
---|
59 | } |
---|
60 | |
---|