source: PSPA/madxPSPA/src/mad_beam.c @ 445

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

import madx-5.01.00

File size: 16.2 KB
Line 
1#include "madx.h"
2
3#if 0 // not used...
4static double
5get_beam_value(char* name, char* par)
6  /* this function is used by fortran to get the parameters values of beams;
7     returns parameter value "par" for beam of sequence "name" if present,
8     where "name" may be "current", or "default", or the name of a sequence;
9     else returns INVALID */
10{
11  struct command* cmd;
12  mycpy(c_dum->c, name);
13  mycpy(aux_buff->c, par);
14  if (strcmp(c_dum->c, "current") == 0 && current_beam != NULL)
15    return get_value("beam", par);
16  else if (strcmp(c_dum->c, "default") == 0)
17  {
18    cmd = find_command("default_beam", beam_list);
19    return command_par_value(aux_buff->c, cmd);
20  }
21  else if ((cmd = find_command(c_dum->c, beam_list)) != NULL)
22    return command_par_value(aux_buff->c, cmd);
23  else return INVALID;
24}
25#endif
26
27// public interface
28
29void
30exec_beam(struct in_cmd* cmd, int flag)
31  /* chooses correct beam for beam definitions, upgrades, and resets */
32{
33  char* name;
34  char name_def[] = "default_beam";
35  struct command* keep_beam = current_beam;
36  struct command_parameter_list* pl = cmd->clone->par;
37  struct name_list* nl = cmd->clone->par_names;
38  int pos = name_list_pos("sequence", nl);
39  int bpos = name_list_pos("sequence", current_beam->par_names);
40  if (nl->inform[pos])
41  {
42    name = pl->parameters[pos]->string;
43    if ((current_beam = find_command(name, beam_list)) == NULL)
44    {
45      set_defaults("beam");
46      add_to_command_list(name, current_beam, beam_list, 0);
47    }
48  }
49  else
50  {
51    name = name_def;
52    current_beam = find_command(name, beam_list);
53  }
54  current_beam->par->parameters[bpos]->string = permbuff(name);
55  current_beam->beam_def = 1;
56  if (flag == 0) update_beam(cmd->clone);
57  else if (flag == 1)  set_defaults("beam");
58  current_beam = keep_beam;
59}
60
61void
62save_beam(struct sequence* sequ, FILE* file)
63{
64  struct command* comm;
65  char beam_buff[AUX_LG];
66  int i, def = 0;
67  if ((comm = find_command(sequ->name, beam_list)) == NULL)
68  {
69    if (default_beam_saved == 0)
70    {
71      def = default_beam_saved = 1;
72      comm = find_command("default_beam", beam_list);
73    }
74  }
75  if (comm != NULL)
76  {
77    beam_buff[0] = '\0';
78    strcat(beam_buff, "beam");
79    for (i = 0; i < comm->par->curr; i++)
80    {
81      if (comm->par_names->inform[i])
82      {
83        if (strcmp(comm->par_names->names[i], "sequence") != 0
84            || def == 0)
85          export_comm_par(comm->par->parameters[i], beam_buff);
86      }
87    }
88    write_nice(beam_buff, file);
89  }
90}
91
92void
93show_beam(char* tok)
94{
95  struct command* comm;
96  if (strlen(tok) > 5 && tok[4] == '%')
97    comm = find_command(&tok[5], beam_list);
98  else comm = find_command("default_beam", beam_list);
99  if (comm != NULL) dump_command(comm);
100}
101
102void
103update_beam(struct command* comm)
104  /* calculates consistent values for modified beam data set.
105     beam command values are evaluated in the order:
106     particle->(mass+charge)
107     energy->pc->gamma->beta
108     ex->exn
109     ey->eyn
110     current->npart
111     et->sigt->sige
112     where any item to the left takes precendence over the others;
113     for ions, the input energy is multiplied by the charge, and the
114  */
115{
116  struct name_list* nlc = comm->par_names;
117  struct command_parameter_list* plc = comm->par;
118  struct command_parameter_list* pl = current_beam->par;
119  int pos, lp;
120  char* name = blank;
121  double energy = 0, beta = 0, gamma = 0, charge = 0, freq0 = 0, bcurrent = 0,
122    npart = 0, mass = 0, pc = 0, ex, exn, ey, eyn, alfa, circ = 0,
123    arad = 0;
124  pos = name_list_pos("particle", nlc);
125  if (nlc->inform[pos])  /* parameter has been read */
126  {
127    pl->parameters[pos]->string = name
128      = plc->parameters[pos]->string;
129    if ((lp = name_list_pos(name, defined_commands->list)) > -1)
130    {
131      mass = command_par_value("mass", defined_commands->commands[lp]);
132      charge = command_par_value("charge", defined_commands->commands[lp]);
133    }
134    else /* unknown particle, then mass and charge must be given as well */
135    {
136      pos = name_list_pos("mass", nlc);
137      if (nlc->inform[pos]) mass = command_par_value("mass", comm);
138      else
139      {
140        warning("emass given to unknown particle:", name);
141        mass = get_variable("emass");
142      }
143      pos = name_list_pos("charge", nlc);
144      if (nlc->inform[pos]) charge = command_par_value("charge", comm);
145      else
146      {
147        warning("charge +1 given to unknown particle:", name);
148        charge = 1;
149      }
150    }
151  }
152  else if (nlc->inform[name_list_pos("mass", nlc)])
153  {
154    mass = command_par_value("mass", comm);
155    pl->parameters[pos]->string = name = permbuff("default");
156    pos = name_list_pos("charge", nlc);
157    if (nlc->inform[pos]) charge = command_par_value("charge", comm);
158    else
159    {
160      warning("charge +1 given to user particle:", name);
161      charge = 1;
162    }
163  }
164  else name = pl->parameters[pos]->string;
165  if (strcmp(name, "ion") == 0)
166  {
167    pos = name_list_pos("mass", nlc);
168    if (nlc->inform[pos]) mass = command_par_value("mass", comm);
169    pos = name_list_pos("charge", nlc);
170    if (nlc->inform[pos]) charge = command_par_value("charge", comm);
171    else charge = command_par_value("charge", current_beam);
172  }
173  if (mass == zero) mass = command_par_value("mass", current_beam);
174  if (charge == zero) charge = command_par_value("charge", current_beam);
175  arad = ten_m_16 * charge * charge * get_variable("qelect")
176    * clight * clight / mass;
177  if ((pos = name_list_pos("energy", nlc)) > -1 && nlc->inform[pos])
178  {
179    energy = command_par_value("energy", comm);
180    if (energy <= mass) fatal_error("energy must be","> mass");
181    pc = sqrt(energy*energy - mass*mass);
182    gamma = energy / mass;
183    beta = pc / energy;
184  }
185  else if((pos = name_list_pos("pc", nlc)) > -1 && nlc->inform[pos])
186  {
187    pc = command_par_value("pc", comm);
188    energy = sqrt(pc*pc + mass*mass);
189    gamma = energy / mass;
190    beta = pc / energy;
191  }
192  else if((pos = name_list_pos("gamma", nlc)) > -1 && nlc->inform[pos])
193  {
194    if ((gamma = command_par_value("gamma", comm)) <= one)
195      fatal_error("gamma must be","> 1");
196    energy = gamma * mass;
197    pc = sqrt(energy*energy - mass*mass);
198    beta = pc / energy;
199  }
200  else if((pos = name_list_pos("beta", nlc)) > -1 && nlc->inform[pos])
201  {
202    if ((beta = command_par_value("beta", comm)) >= one)
203      fatal_error("beta must be","< 1");
204    gamma = one / sqrt(one - beta*beta);
205    energy = gamma * mass;
206    pc = sqrt(energy*energy - mass*mass);
207  }
208  else
209  {
210    energy = command_par_value("energy", current_beam);
211    if (energy <= mass) fatal_error("energy must be","> mass");
212    pc = sqrt(energy*energy - mass*mass);
213    gamma = energy / mass;
214    beta = pc / energy;
215  }
216  if (nlc->inform[name_list_pos("ex", nlc)])
217  {
218    ex = command_par_value("ex", comm);
219    exn = ex * 4 * beta * gamma;
220  }
221  else if (nlc->inform[name_list_pos("exn", nlc)])
222  {
223    exn = command_par_value("exn", comm);
224    ex = exn / (4 * beta * gamma);
225  }
226  else
227  {
228    ex = command_par_value("ex", current_beam);
229    exn = ex * 4 * beta * gamma;
230  }
231  if (nlc->inform[name_list_pos("ey", nlc)])
232  {
233    ey = command_par_value("ey", comm);
234    eyn = ey * 4 * beta * gamma;
235  }
236  else if (nlc->inform[name_list_pos("eyn", nlc)])
237  {
238    eyn = command_par_value("eyn", comm);
239    ey = eyn / (4 * beta * gamma);
240  }
241  else
242  {
243    ey = command_par_value("ey", current_beam);
244    eyn = ey * 4 * beta * gamma;
245  }
246  alfa = one / (gamma * gamma);
247  if (nlc->inform[name_list_pos("circ", nlc)])
248  {
249    circ = command_par_value("circ", comm);
250    if (circ > zero) freq0 = (beta * clight) / (ten_p_6 * circ);
251  }
252  else if (nlc->inform[name_list_pos("freq0", nlc)])
253  {
254    freq0 = command_par_value("eyn", comm);
255    if (freq0 > zero) circ = (beta * clight) / (ten_p_6 * freq0);
256  }
257  else if ((pos = name_list_pos(name, sequences->list)) >= 0)
258  {
259    circ = sequence_length(sequences->sequs[pos]);
260    freq0 = (beta * clight) / (ten_p_6 * circ);
261  }
262  if (nlc->inform[name_list_pos("bcurrent", nlc)])
263  {
264    bcurrent = command_par_value("bcurrent", comm);
265    if (bcurrent > zero && freq0 > zero)
266      npart = bcurrent / (beta * freq0 * ten_p_6 * get_variable("qelect"));
267    else if (nlc->inform[name_list_pos("npart", nlc)])
268    {
269      npart = command_par_value("npart", comm);
270      bcurrent = npart * beta * freq0 * ten_p_6 * get_variable("qelect");
271    }
272  }
273  else if (nlc->inform[name_list_pos("npart", nlc)])
274  {
275    npart = command_par_value("npart", comm);
276    bcurrent = npart * beta * freq0 * ten_p_6 * get_variable("qelect");
277  }
278  pos = name_list_pos("bunched", nlc);
279  if (nlc->inform[pos])
280    pl->parameters[pos]->double_value = plc->parameters[pos]->double_value;
281  pos = name_list_pos("radiate", nlc);
282  if (nlc->inform[pos])
283    pl->parameters[pos]->double_value = plc->parameters[pos]->double_value;
284  pos = name_list_pos("et", nlc);
285  if (nlc->inform[pos])
286    pl->parameters[pos]->double_value = plc->parameters[pos]->double_value;
287  pos = name_list_pos("sigt", nlc);
288  if (nlc->inform[pos])
289    pl->parameters[pos]->double_value = plc->parameters[pos]->double_value;
290  pos = name_list_pos("sige", nlc);
291  if (nlc->inform[pos])
292    pl->parameters[pos]->double_value = plc->parameters[pos]->double_value;
293  pos = name_list_pos("kbunch", nlc);
294  if (nlc->inform[pos])
295    pl->parameters[pos]->double_value = plc->parameters[pos]->double_value;
296  pos = name_list_pos("bv", nlc);
297  if (nlc->inform[pos])
298    pl->parameters[pos]->double_value = plc->parameters[pos]->double_value;
299  pos = name_list_pos("pdamp", nlc);
300  if (nlc->inform[pos])
301    copy_double(plc->parameters[pos]->double_array->a, pl->parameters[pos]->double_array->a, 3);
302  store_comm_par_value("mass", mass, current_beam);
303  store_comm_par_value("charge", charge, current_beam);
304  store_comm_par_value("energy", energy, current_beam);
305  store_comm_par_value("pc", pc, current_beam);
306  store_comm_par_value("gamma", gamma, current_beam);
307  store_comm_par_value("ex", ex, current_beam);
308  store_comm_par_value("exn", exn, current_beam);
309  store_comm_par_value("ey", ey, current_beam);
310  store_comm_par_value("eyn", eyn, current_beam);
311  store_comm_par_value("npart", npart, current_beam);
312  store_comm_par_value("bcurrent", bcurrent, current_beam);
313  store_comm_par_value("freq0", freq0, current_beam);
314  store_comm_par_value("circ", circ, current_beam);
315  store_comm_par_value("beta", beta, current_beam);
316  store_comm_par_value("alfa", alfa, current_beam);
317  store_comm_par_value("arad", arad, current_beam);
318}
319
320void
321adjust_beam(void)
322  /* adjusts beam parameters to current beta, gamma, bcurrent, npart */
323{
324  struct name_list* nl = current_beam->par_names;
325  double circ = one, freq0, alfa, beta, gamma, bcurrent = zero, npart = 0;
326  if (current_sequ != NULL && sequence_length(current_sequ) != zero)
327    circ = current_sequ->length;
328  beta = command_par_value("beta", current_beam);
329  gamma = command_par_value("gamma", current_beam);
330  alfa = one / (gamma * gamma);
331  freq0 = (beta * clight) / (ten_p_6 * circ);
332  if (nl->inform[name_list_pos("bcurrent", nl)] &&
333      (bcurrent = command_par_value("bcurrent", current_beam)) > zero)
334    npart = bcurrent / (freq0 * ten_p_6 * get_variable("qelect"));
335  else if (nl->inform[name_list_pos("npart", nl)] &&
336           (npart = command_par_value("npart", current_beam)) > zero)
337    bcurrent = npart * freq0 * ten_p_6 * get_variable("qelect");
338  store_comm_par_value("alfa", alfa, current_beam);
339  store_comm_par_value("freq0", freq0, current_beam);
340  store_comm_par_value("circ", circ, current_beam);
341  store_comm_par_value("npart", npart, current_beam);
342  store_comm_par_value("bcurrent", bcurrent, current_beam);
343}
344
345int
346attach_beam(struct sequence* sequ)
347  /* attaches the beam belonging to the current sequence */
348{
349  if (!sequ || (current_beam = find_command(sequ->name, beam_list)) == NULL)
350    current_beam = find_command("default_beam", beam_list);
351  return current_beam->beam_def;
352}
353
354void
355expand_line(struct char_p_array* l_buff)
356  /* expands a beam line, applies rep. count and inversion */
357{
358  /* first get all bracket pairs with their level; keep max. level */
359  int add=0, i=0, j=0, k=0, n=0, number=0, dummy=0, rep=-1, pos=0;
360  int level = 0, l_max = 0, b_cnt = 0;
361  char* p;
362  struct int_array* lbpos = new_int_array(l_buff->curr);
363  struct int_array* rbpos = new_int_array(l_buff->curr);
364  struct int_array* b_level = new_int_array(l_buff->curr);
365
366  for (i = 0; i < l_buff->curr; i++)
367  {
368    if (*l_buff->p[i] == '(')
369    {
370      lbpos->i[b_cnt] = i;
371      b_level->i[b_cnt++] = level++;
372      if (level > l_max) l_max = level;
373    }
374    else if (*l_buff->p[i] == ')')  level--;
375  }
376  l_max--;
377  for (i = 0; i < b_cnt; i++)
378    get_bracket_t_range(l_buff->p, '(', ')', lbpos->i[i],
379                        l_buff->curr-1, &dummy, &rbpos->i[i]);
380  lbpos->curr = rbpos->curr = b_level->curr = b_cnt;
381  /* now loop over level from highest down to zero, expand '*' in each pair */
382  for (level = l_max; level >=0; level--)
383  {
384    for (i = 0; i < b_cnt; i++)
385    {
386      if (b_level->i[i] == level && (pos = lbpos->i[i]) > 1)
387      {
388        if (*l_buff->p[pos-1] == '*')
389        {
390          sscanf(l_buff->p[pos-2], "%d", &rep);
391          add = rep - 1;
392          number = rbpos->i[i] - pos - 1; /* inside bracket */
393          n = number * add; /* extra tokens */
394          while (l_buff->curr + n >= l_buff->max)
395            grow_char_p_array(l_buff);
396          for (j = l_buff->curr; j > pos + number; j--) /* shift upwards */
397            l_buff->p[j+n] = l_buff->p[j];
398          l_buff->curr += n;
399          for (k = 1; k <= add; k++)
400          {
401            for (j = pos+1; j <= pos+number; j++)
402              l_buff->p[j+k*number] = tmpbuff(l_buff->p[j]);
403          }
404          for (j = 0; j < b_cnt; j++)  /* reset bracket pointers */
405          {
406            if (lbpos->i[j] > pos + number) lbpos->i[j] += n;
407            if (rbpos->i[j] > pos + number) rbpos->i[j] += n;
408          }
409          l_buff->p[pos-1] = l_buff->p[pos-2] = blank;
410        }
411      }
412    }
413  }
414  /* loop over buffer, expand simple element repetition */
415  for (pos = 2; pos < l_buff->curr; pos++)
416  {
417    if (*l_buff->p[pos] == '*')
418    {
419      rep = -1;
420      sscanf(l_buff->p[pos-1], "%d", &rep);
421      if (rep < 0)
422      {
423        fatal_error("expand_line","Problem with reading number of copies");
424      }
425      n = add = rep - 1;
426      while (l_buff->curr + n >= l_buff->max) grow_char_p_array(l_buff);
427      for (j = l_buff->curr; j > pos + 1; j--) /* shift upwards */
428        l_buff->p[j+n] = l_buff->p[j];
429      l_buff->curr += n;
430      for (k = 1; k <= add; k++)
431      {
432        j = pos+1;
433        l_buff->p[j+k] = l_buff->p[j];
434      }
435      for (j = 0; j < b_cnt; j++)  /* reset bracket pointers */
436      {
437        if (lbpos->i[j] > pos + 1) lbpos->i[j] += n;
438        if (rbpos->i[j] > pos + 1) rbpos->i[j] += n;
439      }
440      l_buff->p[pos-1] = l_buff->p[pos-2] = blank;
441    }
442  }
443  /* get bracket pointers including new ones */
444  while (b_level->max < l_buff->curr) grow_int_array(b_level);
445  while (lbpos->max < l_buff->curr) grow_int_array(lbpos);
446  while (rbpos->max < l_buff->curr) grow_int_array(rbpos);
447  level = b_cnt = 0;
448  for (i = 0; i < l_buff->curr; i++)
449  {
450    if (*l_buff->p[i] == '(')
451    {
452      lbpos->i[b_cnt] = i;
453      b_level->i[b_cnt++] = level++;
454    }
455    else if (*l_buff->p[i] == ')')  level--;
456  }
457  for (i = 0; i < b_cnt; i++)
458    get_bracket_t_range(l_buff->p, '(', ')', lbpos->i[i],
459                        l_buff->curr-1, &dummy, &rbpos->i[i]);
460  lbpos->curr = rbpos->curr = b_level->curr = b_cnt;
461  /* now loop over level from highest down to zero, invert if '-' */
462  for (level = l_max; level >= 0; level--)
463  {
464    for (i = 0; i < b_cnt; i++)
465    {
466      pos = lbpos->i[i];
467      if (b_level->i[i] == level)
468      {
469        p = blank;
470        for (j = pos - 1; j > 0; j--)
471        {
472          p = l_buff->p[j];
473          if (*p != ' ')  break;
474        }
475        if (*p == '-')
476        {
477          number = rbpos->i[i] - pos - 1;
478          n = number / 2;
479          for (j = 0; j < n; j++)
480          {
481            p = l_buff->p[pos+j+1];
482            l_buff->p[pos+j+1] = l_buff->p[pos+number-j];
483            l_buff->p[pos+number-j] = p;
484          }
485        }
486      }
487    }
488  }
489  /* finally remove all non-alpha tokens */
490  n = 0;
491  for (i = 0; i < l_buff->curr; i++)
492  {
493    if (isalpha(*l_buff->p[i])) l_buff->p[n++] = l_buff->p[i];
494  }
495  l_buff->curr = n;
496  lbpos = delete_int_array(lbpos);
497  rbpos = delete_int_array(rbpos);
498  b_level = delete_int_array(b_level);
499}
500
Note: See TracBrowser for help on using the repository browser.