source: PSPA/madxPSPA/src/mad_inter.c @ 457

Last change on this file since 457 was 430, checked in by touze, 11 years ago

import madx-5.01.00

File size: 7.4 KB
Line 
1#include "madx.h"
2
3static struct backup {
4  struct node*       node;
5  int                rbend;
6  double             length;
7  double             e1, e2;
8  int                angle_type;
9  struct expression* angle_expr;
10  double             angle_value;
11} backup;
12
13// Creates interpolating nodes for the plotting routine
14int
15interpolate_node(int *nint)
16{
17  struct node *first_node, *clone;
18  struct element* el;
19  struct command_parameter* cp;
20  int i, j, number_nodes;
21  double bvk, angle, e1, e2, h1, h2, fint, hgap;
22  double zero = 0.0, minus_one = -1.0, numint;
23  char *elem_name;
24  int rbend_flag, bend_flag = 0;
25
26  numint = *nint;
27  number_nodes = *nint - 1;
28
29  /* Set up length, angle and e2 of the first slice
30     (first node in the original sequence) */
31 
32  if (backup.node)
33    warning("interpolate_node: node interpolation ongoing, undefined behavior will follow", "");
34
35  first_node = current_node;
36  backup.node = first_node;
37
38  el = first_node->p_elem;
39  elem_name = el->base_type->name;
40  rbend_flag = strcmp(elem_name, "rbend") == 0;
41   bend_flag = strcmp(elem_name, "sbend") == 0 || rbend_flag;
42  backup.rbend = rbend_flag;
43
44//  bv = node_value("dipole_bv");
45  bvk = node_value("other_bv");
46
47  if (bend_flag)
48  {
49    angle = command_par_value("angle", el->def);
50    e1 = command_par_value("e1", el->def);
51    e2 = command_par_value("e2", el->def);
52    h1 = command_par_value("h1", el->def);
53    h2 = command_par_value("h2", el->def);
54    fint = command_par_value("fint", el->def);
55    fintx_plot = command_par_value("fintx", el->def);
56    hgap = command_par_value("hgap", el->def);
57
58    if (rbend_flag)
59    {
60      backup.e1 = e1;
61      backup.e2 = e2;
62
63      e1 += bvk * angle / 2.0;
64      e2 += bvk * angle / 2.0;
65      strcpy(elem_name,"sbend");
66      el->def->mad8_type = 3;
67    }
68
69    angle /= numint;
70    // store_node_value("angle",&angle);
71    i = name_list_pos("angle", el->def->par_names);
72    cp = el->def->par->parameters[i];
73
74    backup.angle_type  = cp->type;
75    backup.angle_expr  = cp->expr;
76    backup.angle_value = cp->double_value;
77    cp->type = 2;
78    cp->expr = NULL;
79    cp->double_value = angle;
80
81    store_node_value("e1",&e1);
82    store_node_value("e2",&zero);
83    store_node_value("h1",&h1);
84    store_node_value("h2",&zero);
85    store_node_value("fint",&fint);
86    store_node_value("fintx",&zero);
87    store_node_value("hgap",&hgap);
88  }
89  backup.length = first_node->length; 
90  first_node->length /= numint;
91
92  // set first_node in range_start of the sequence
93  current_sequ->range_start = first_node;
94
95  // clone the current node
96  clone = clone_node(first_node,0);
97  if (bend_flag) {
98    clone->p_elem = clone_element(first_node->p_elem);
99    clone->p_elem->def = clone_command(first_node->p_elem->def);
100  }
101
102  // Reset to first node
103  current_node = first_node;
104
105  // advance to next node
106  current_node = current_node->next;
107
108  // set last node in the range to the current node
109  current_sequ->range_end = current_node;
110
111  // insert nint - 1 nodes in between the two main nodes
112  for (j = 1; j <= number_nodes; j++) {
113    link_in_front(clone,current_node);
114    current_node = current_node->previous;
115    current_node->previous->next = current_node;
116    store_node_value("angle",&angle);
117/*    store_node_value("dipole_bv",&bv); */
118    store_node_value("other_bv",&bvk);
119    if (bend_flag) {
120      if (j == 1) {
121        store_node_value("e2",&e2);
122        store_node_value("h2",&h2);
123        store_node_value("hgap",&hgap);
124        if (fintx_plot < zero)
125          store_node_value("fintx",&fint);
126        else
127          store_node_value("fintx",&fintx_plot);
128        store_node_value("fint",&zero);
129      }
130      else {
131        store_node_value("e2",&zero);
132        store_node_value("h2",&zero);
133        store_node_value("fint",&zero);
134        store_node_value("fintx",&minus_one);
135        store_node_value("hgap",&zero);
136      }
137      store_node_value("e1",&zero);
138      store_node_value("h1",&zero);
139    }
140    clone = clone_node(first_node,0);
141    if (bend_flag) {
142      clone->p_elem = clone_element(first_node->p_elem);
143      clone->p_elem->def = clone_command(first_node->p_elem->def);
144    }
145  }
146
147  current_node = current_node->previous;
148
149  return 0;
150}
151
152int
153reset_interpolation(int *nint)
154{
155  struct node *c_node, *second_node;
156  struct command_parameter* cp;
157  int i, j, rbend_flag, bend_flag = 0;
158  double e1, e2, h1, h2, fint, hgap; // not used, angle=0, numint, bvk;
159
160  // Deletes the interpolating nodes expanded by the routine interp_node
161  // numint = *nint;
162
163  // reset first and last node in the sequence range
164  current_sequ->range_start = current_sequ->ex_start;
165  current_sequ->range_end = current_sequ->ex_end;
166
167  // reset current_node at first node
168  for (j = 1; j <= *nint ; j++) {
169    if (!current_node)
170      error("reset_interpolation: missing current node (deleted?) since last interpolation, undefined behavior will follow", "");
171    current_node = current_node->previous;
172  }
173
174  if (!backup.node || backup.node != current_node)
175    warning("reset_interpolation: current node changed since last interpolation, undefined behavior will follow", "");
176
177  // reset length of first node
178  current_node->length = backup.length;
179
180  // resets angle and saves e1 if the element is a bending magnet
181  rbend_flag = strcmp(current_node->p_elem->base_type->name, "rbend") == 0 || backup.rbend;
182  bend_flag = strcmp(current_node->p_elem->base_type->name, "sbend") == 0 || rbend_flag;
183
184  if (bend_flag) {
185//    angle = numint*node_value("angle");
186    i = name_list_pos("angle", current_node->p_elem->def->par_names);
187    cp = current_node->p_elem->def->par->parameters[i];
188    cp->expr = backup.angle_expr;
189    cp->type = backup.angle_type;
190    cp->double_value = backup.angle_value;
191
192    // store_node_value("angle",&angle);
193    e1 = node_value("e1");
194    h1 = node_value("h1");
195    fint = node_value("fint");
196    hgap = node_value("hgap");
197  }
198
199  // advance to nint-th  node (second node in original sequence)
200  for (j = 1; j <= *nint; j++) advance_node();
201  second_node = current_node;
202
203  // back to the last interpolated node
204  retreat_node();
205
206  // saves e2 if the element is a bending magnet
207  if (bend_flag) {
208    e2 = node_value("e2");
209    h2 = node_value("h2");
210  }
211
212  // delete the interpolating nodes
213  for (j = 2; j <= *nint; j++) {
214    c_node = current_node;
215
216    retreat_node();
217    if (bend_flag) {
218      c_node->p_elem->def = delete_command(c_node->p_elem->def);
219      c_node->p_elem = delete_element(c_node->p_elem);
220    }
221    delete_node(c_node);
222  }
223
224  /* current_node points now to the first node of the original sequence
225     sets next pointer of first node to second node of original sequence */
226  current_node->next = second_node;
227
228  // sets pointer of second node to first node of original sequence
229  current_node->next->previous = current_node;
230
231  // Updates the values of e1 and e2 and stores them in first node
232  //  bv = node_value("dipole_bv");
233  // bvk = node_value("other_bv");
234
235  if (bend_flag) {
236    if (rbend_flag) {
237      strcpy(current_node->p_elem->base_type->name, "rbend");
238      current_node->p_elem->def->mad8_type = 2;
239      e1 = backup.e1; // e1 = e1 - bvk * angle / 2.0;
240      e2 = backup.e2; // e2 = e2 - bvk * angle / 2.0;
241    }
242
243    store_node_value("e1",&e1);
244    store_node_value("e2",&e2);
245    store_node_value("h1",&h1);
246    store_node_value("h2",&h2);
247    store_node_value("fint",&fint);
248    store_node_value("fintx",&fintx_plot);
249    store_node_value("hgap",&hgap);
250  }
251
252  // reset backup
253  backup.node = 0;
254
255  return 0;
256}
257
Note: See TracBrowser for help on using the repository browser.