source: PSPA/madxPSPA/src/mad_node.c @ 430

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

import madx-5.01.00

File size: 18.5 KB
Line 
1#include "madx.h"
2
3static void
4remove_from_node_list(struct node* node, struct node_list* nodes)
5{
6  int i;
7  if ((i = remove_from_name_list(node->name, nodes->list)) > -1)
8    nodes->nodes[i] = nodes->nodes[--nodes->curr];
9}
10
11#if 0 // not used...
12static double
13spec_node_value(char* par, int* number)
14  /* returns value for parameter par of specified node (start = 1 !!) */
15{
16  double value = zero;
17  struct node* node = current_node;
18  int n = *number + current_sequ->start_node - 1;
19  if (0 <= n && n < current_sequ->n_nodes)
20  {
21    current_node = current_sequ->all_nodes[n];
22    value = node_value(par);
23    current_node = node;
24  }
25  return value;
26}
27#endif
28
29// public interface
30
31struct node*
32new_node(char* name)
33{
34  char rout_name[] = "new_node";
35  struct node* p = mycalloc(rout_name,1, sizeof(struct node));
36  strcpy(p->name, name);
37  p->stamp = 123456;
38  if (watch_flag) fprintf(debug_file, "creating ++> %s\n", p->name);
39  return p;
40}
41
42struct node*
43clone_node(struct node* p, int flag)
44{
45  /* Transfers errors from original nodes if flag != 0;
46     this is needed for SXF input  */
47  struct node* clone = new_node(p->name);
48  strcpy(clone->name,p->name);
49  clone->base_name = p->base_name;
50  clone->occ_cnt = p->occ_cnt;
51  clone->sel_err = p->sel_err;
52  clone->position = p->position;
53  clone->at_value = p->at_value;
54  clone->length = p->length;
55  clone->at_expr = p->at_expr;
56  clone->from_name = p->from_name;
57  clone->p_elem = p->p_elem;
58  clone->p_sequ = p->p_sequ;
59  clone->savebeta = p->savebeta;
60  if (flag)
61  {
62    clone->p_al_err = p->p_al_err;
63    clone->p_fd_err = p->p_fd_err;
64    // AL: RF-Multipole errors (EFCOMP)
65    clone->p_ph_err = p->p_ph_err;
66  }
67  // AL: RF-Multipole
68  //clone->pnl = p->pnl;
69  //clone->psl = p->psl;
70  clone->rfm_lag = p->rfm_lag;
71  clone->rfm_freq = p->rfm_freq;
72  clone->rfm_volt = p->rfm_volt;
73  clone->rfm_harmon = p->rfm_harmon;
74  // 
75  return clone;
76}
77
78struct node*
79delete_node(struct node* p)
80{
81  char rout_name[] = "delete_node";
82  if (p == NULL) return NULL;
83  if (stamp_flag && p->stamp != 123456)
84    fprintf(stamp_file, "d_n double delete --> %s\n", p->name);
85  if (watch_flag) fprintf(debug_file, "deleting --> %s\n", p->name);
86  if (p->p_al_err) p->p_al_err = delete_double_array(p->p_al_err);
87  if (p->p_fd_err) p->p_fd_err = delete_double_array(p->p_fd_err);
88  // AL: RF-Multipole errors (EFCOMP)
89  if (p->p_ph_err) p->p_ph_err = delete_double_array(p->p_ph_err);
90  // AL: RF-Multipole
91  // if (p->pnl) p->pnl = delete_double_array(p->pnl);
92  // if (p->psl) p->psl = delete_double_array(p->psl);
93  //
94  myfree(rout_name, p);
95  return NULL;
96}
97
98struct node_list*
99new_node_list(int length)
100{
101  char rout_name[] = "new_node_list";
102  struct node_list* nll = mycalloc(rout_name,1, sizeof(struct node_list));
103  strcpy(nll->name, "node_list");
104  nll->stamp = 123456;
105  if (watch_flag) fprintf(debug_file, "creating ++> %s\n", nll->name);
106  nll->list = new_name_list(nll->name, length);
107  nll->nodes = mycalloc(rout_name,length, sizeof(struct node*));
108  nll->max = length;
109  return nll;
110}
111
112struct node_list*
113delete_node_list(struct node_list* l)
114{
115  char rout_name[] = "delete_node_list";
116  if (l == NULL)  return NULL;
117  if (stamp_flag && l->stamp != 123456)
118    fprintf(stamp_file, "d_no_l double delete --> %s\n", l->name);
119  if (watch_flag) fprintf(debug_file, "deleting --> %s\n", l->name);
120  if (l->nodes != NULL)  myfree(rout_name, l->nodes);
121  if (l->list != NULL)  delete_name_list(l->list);
122  myfree(rout_name, l);
123  return NULL;
124}
125
126struct node*
127delete_node_ring(struct node* start)
128{
129  struct node *p, *q;
130  if (start == NULL) return NULL;
131  if (watch_flag) fprintf(debug_file, "deleting --> %s\n", "node_ring");
132  q = start->next;
133  while (q != NULL && q != start)
134  {
135    p = q; q = q->next; delete_node(p);
136  }
137  delete_node(start);
138  return NULL;
139}
140
141static void
142grow_node_list(struct node_list* p)
143{
144  char rout_name[] = "grow_node_list";
145  struct node** n_loc = p->nodes;
146  int j, new = 2*p->max;
147  p->max = new;
148  p->nodes = (struct node**) mycalloc(rout_name,new, sizeof(struct node*));
149  for (j = 0; j < p->curr; j++) p->nodes[j] = n_loc[j];
150  myfree(rout_name, n_loc);
151}
152
153void
154dump_node(struct node* node)
155{
156  int i;
157  char pname[NAME_L] = "NULL", nname[NAME_L] = "NULL", 
158    from_name[NAME_L] = "NULL";
159  if (node->previous != NULL) strcpy(pname, node->previous->name);
160  if (node->next != NULL) strcpy(nname, node->next->name);
161  if (node->from_name != NULL) strcpy(from_name, node->from_name);
162  fprintf(prt_file, 
163          v_format("name: %S  occ: %I base: %S  from_name: %S at_value: %F  position: %F\n"),
164          node->name, node->occ_cnt, node->base_name, from_name, 
165          node->at_value, node->position);
166  fprintf(prt_file, v_format("  names of - previous: %S  next: %S\n"),
167          pname, nname);
168  if (node->cl != NULL)  for (i = 0; i < node->cl->curr; i++)
169    dump_constraint(node->cl->constraints[i]);
170}
171
172struct node*
173expand_node(struct node* node, struct sequence* top_sequ, struct sequence* sequ, double position)
174  /* replaces a (sequence) node by a sequence of nodes - recursive */
175{
176  struct sequence* nodesequ = node->p_sequ;
177  struct node *p, *q = nodesequ->start;
178  int i;
179  (void)sequ;
180
181  p = clone_node(q, 0);
182  if ((i = name_list_pos(p->p_elem->name, occ_list)) < 0)
183    i = add_to_name_list(p->p_elem->name, 1, occ_list);
184  else strcpy(p->name, compound(p->p_elem->name, ++occ_list->inform[i]));
185  add_to_node_list(p, 0, top_sequ->ex_nodes);
186  p->previous = node->previous;
187  p->previous->next = p;
188  p->position = position + get_node_pos(p, nodesequ)
189    - get_refpos(nodesequ);
190  while (p != NULL)
191  {
192    if (q == nodesequ->end) break;
193    if (strcmp(p->base_name, "rfcavity") == 0 &&
194        find_element(p->p_elem->name, top_sequ->cavities) == NULL)
195      add_to_el_list(&p->p_elem, 0, top_sequ->cavities, 0);
196    p->next = clone_node(q->next, 0);
197    p->next->previous = p;
198    p = p->next;
199    q = q->next;
200    p->position = position + get_node_pos(p, nodesequ)
201      - get_refpos(nodesequ);
202    if (p->p_sequ != NULL) p = expand_node(p, top_sequ,
203                                           p->p_sequ, p->position);
204    else
205    {
206      p->share = top_sequ->share;
207      add_to_node_list(p, 0, top_sequ->ex_nodes);
208    }
209  }
210  delete_node(node);
211  return p;
212}
213
214double
215get_node_pos(struct node* node, struct sequence* sequ) /*recursive */
216  /* returns node position from declaration for expansion */
217{
218  double fact = 0.5 * sequ->ref_flag; /* element half-length offset */
219  double pos, from = 0;
220  if (loop_cnt++ == MAX_LOOP)
221  {
222    sprintf(c_dum->c, "%s   occurrence: %d", node->p_elem->name,
223            node->occ_cnt);
224    fatal_error("circular call in position of", c_dum->c);
225  }
226  if (node->at_expr == NULL) pos = node->at_value;
227  else                       pos = expression_value(node->at_expr, 2);
228  pos += fact * node->length; /* make centre position */
229  if (node->from_name != NULL)
230  {
231    if ((from = hidden_node_pos(node->from_name, sequ)) == INVALID)
232      fatal_error("'from' reference to unknown element:", node->from_name);
233  }
234  loop_cnt--;
235  pos += from;
236  return pos;
237}
238
239double
240node_value(char* par)
241  /* returns value for parameter par of current element */
242{
243  double value;
244  char lpar[NAME_L];
245  mycpy(lpar, par);
246  if (strcmp(lpar, "l") == 0) value = current_node->length;
247/*  else if (strcmp(lpar, "dipole_bv") == 0) value = current_node->dipole_bv;*/
248  else if (strcmp(lpar, "other_bv") == 0) value = current_node->other_bv;
249  else if (strcmp(lpar, "chkick") == 0) value = current_node->chkick;
250  else if (strcmp(lpar, "cvkick") == 0) value = current_node->cvkick;
251  else if (strcmp(lpar, "obs_point") == 0) value = current_node->obs_point;
252  else if (strcmp(lpar, "sel_sector") == 0) value = current_node->sel_sector;
253  else if (strcmp(lpar, "enable") == 0) value = current_node->enable;
254  else if (strcmp(lpar, "occ_cnt") == 0) value = current_node->occ_cnt;
255  else if (strcmp(lpar, "pass_flag") == 0) value = current_node->pass_flag;
256/* AL: added by A. Latina 16 Feb 2012 */
257  else if (strcmp(lpar, "rfm_freq") == 0) value = current_node->rfm_freq;
258  else if (strcmp(lpar, "rfm_volt") == 0) value = current_node->rfm_volt;
259  else if (strcmp(lpar, "rfm_lag") == 0) value = current_node->rfm_lag;
260  else if (strcmp(lpar, "rfm_harmon") == 0) value = current_node->rfm_harmon;
261//
262  else value =  element_value(current_node, lpar);
263  return value;
264}
265
266void
267link_in_front(struct node* new, struct node* el)
268  /* links a node 'new' in front of a node 'el' */
269{
270  el->previous->next = new;
271  new->previous = el->previous; new->next = el;
272  el->previous = new;
273}
274
275double
276hidden_node_pos(char* name, struct sequence* sequ) /*recursive */
277  /* (for 'from' calculation:) returns the position of a node
278     in the current or a sub-sequence (hence hidden) */
279{
280  double pos;
281  struct node* c_node;
282  char tmp[NAME_L];
283  int i;
284  strcpy(tmp, name);
285  square_to_colon(tmp);
286  if ((i = name_list_pos(tmp, sequ->nodes->list)) > -1)
287    return get_node_pos(sequ->nodes->nodes[i], sequ);
288  else
289  {
290    c_node = sequ->start;
291    while (c_node != NULL)
292    {
293      if (c_node->p_sequ != NULL)
294      {
295        if ((pos = hidden_node_pos(name, c_node->p_sequ)) != INVALID)
296        {
297          pos += get_node_pos(c_node, sequ) - get_refpos(c_node->p_sequ);
298          return pos;
299        }
300      }
301      if (c_node == sequ->end) break;
302      c_node = c_node->next;
303    }
304    return INVALID;
305  }
306}
307
308void
309resequence_nodes(struct sequence* sequ)
310  /* resequences occurrence list */
311{
312  struct node* c_node = sequ->start;
313  int i, cnt;
314  while (c_node != NULL)
315  {
316    if (c_node->p_elem != NULL)
317    {
318      if ((i = name_list_pos(c_node->p_elem->name, occ_list)) < 0)
319      {
320        i = add_to_name_list(c_node->p_elem->name, 1, occ_list);
321        cnt = 1;
322      }
323      else cnt = ++occ_list->inform[i];
324      strcpy(c_node->name, compound(c_node->p_elem->name, cnt));
325    }
326    if (c_node == sequ->end) break;
327    c_node = c_node->next;
328  }
329}
330
331int
332retreat_node(void)
333  /* replaces current node by previous node; 0 = already at start, else 1 */
334{
335  if (current_node == current_sequ->range_start)  return 0;
336  current_node = current_node->previous;
337  return 1;
338}
339
340void
341store_node_value(char* par, double* value)
342  /* stores value for parameter par at current node */
343{
344  char lpar[NAME_L];
345  struct element* el = current_node->p_elem;
346
347  mycpy(lpar, par);
348  if (strcmp(lpar, "chkick") == 0) current_node->chkick = *value;
349  else if (strcmp(lpar, "cvkick") == 0) current_node->cvkick = *value;
350/*  else if (strcmp(lpar, "dipole_bv") == 0) current_node->dipole_bv = *value;*/
351  else if (strcmp(lpar, "other_bv") == 0) current_node->other_bv = *value;
352  else if (strcmp(lpar, "obs_point") == 0) current_node->obs_point = *value;
353  else if (strcmp(lpar, "sel_sector") == 0) current_node->sel_sector = *value;
354  else if (strcmp(lpar, "enable") == 0) current_node->enable = *value;
355
356  /* added by E. T. d'Amico 27 feb 2004 */
357
358  else if (strcmp(lpar, "e1") == 0) store_comm_par_value("e1",*value,el->def);
359  else if (strcmp(lpar, "e2") == 0) store_comm_par_value("e2",*value,el->def);
360  else if (strcmp(lpar, "angle") == 0) store_comm_par_value("angle",*value,el->def);
361
362  /* added by E. T. d'Amico 12 may 2004 */
363
364  else if (strcmp(lpar, "h1") == 0) store_comm_par_value("h1",*value,el->def);
365  else if (strcmp(lpar, "h2") == 0) store_comm_par_value("h2",*value,el->def);
366  else if (strcmp(lpar, "fint") == 0) store_comm_par_value("fint",*value,el->def);
367  else if (strcmp(lpar, "fintx") == 0) store_comm_par_value("fintx",*value,el->def);
368  else if (strcmp(lpar, "hgap") == 0) store_comm_par_value("hgap",*value,el->def);
369  else if (strcmp(lpar, "pass_flag") == 0) current_node->pass_flag = *value;
370
371  /* AL: added by A. Latina 16 Feb 2012 */
372
373  else if (strcmp(lpar, "rfm_freq") == 0) store_comm_par_value("rfm_freq", *value, el->def);
374  else if (strcmp(lpar, "rfm_volt") == 0) store_comm_par_value("rfm_volt", *value, el->def);
375  else if (strcmp(lpar, "rfm_lag") == 0) store_comm_par_value("rfm_lag", *value, el->def);
376  else if (strcmp(lpar, "rfm_harmon") == 0) store_comm_par_value("rfm_harmon", *value, el->def);
377 
378  /* end of additions */
379}
380
381void
382set_new_position(struct sequence* sequ)
383  /* sets a new node position for all nodes */
384{
385  struct node* c_node = sequ->start;
386  double zero_pos = c_node->position;
387  int flag = 0;
388  while (c_node != NULL)
389  {
390    if (c_node->from_name == NULL)
391    {
392      c_node->position -= zero_pos;
393      if (c_node->position < zero || (flag && c_node->position == zero))
394        c_node->position += sequence_length(sequ);
395      if (c_node->position > zero) flag = 1;
396      c_node->at_value = c_node->position;
397      c_node->at_expr = NULL;
398    }
399    if (c_node == sequ->end) break;
400    c_node = c_node->next;
401  }
402  c_node->position = c_node->at_value = sequence_length(sequ);
403}
404
405void
406set_node_bv(struct sequence* sequ)
407  /* sets bv flag for all nodes */
408{
409  struct node* c_node = sequ->ex_start;
410  double beam_bv;
411  beam_bv = command_par_value("bv", current_beam);
412  while (c_node != NULL)
413  {
414    c_node->other_bv = beam_bv;
415    c_node->dipole_bv = beam_bv;
416/* dipole_bv kill initiative SF TR FS */
417/*      if (c_node->p_elem->bv) c_node->dipole_bv = beam_bv;
418        else                    c_node->dipole_bv = 1;*/
419    if (c_node == sequ->ex_end) break;
420    c_node = c_node->next;
421  }
422}
423
424void
425add_to_node_list( /* adds node to alphabetic node list */
426  struct node* node, int inf, struct node_list* nll)
427{
428  // int j, pos; // not used
429  if (name_list_pos(node->name, nll->list) < 0) // (pos = not used
430  {
431    if (nll->curr == nll->max) grow_node_list(nll);
432    add_to_name_list(node->name, inf, nll->list); // j = not used
433    nll->nodes[nll->curr++] = node;
434  }
435}
436
437int
438count_nodes(struct sequence* sequ)
439{
440  int count = 1;
441  struct node* c_node = sequ->start;
442  while(c_node != sequ->end)
443  {
444    c_node = c_node->next;
445    count++;
446  }
447  return count;
448}
449
450void
451current_node_name(char* name, int* lg)
452/* returns node_name blank padded up to lg */
453{
454  int i;
455  strncpy(name, current_node->name, *lg);
456  for (i = strlen(current_node->name); i < *lg; i++)  name[i] = ' ';
457}
458
459void
460node_name(char* name, int* l)
461  /* returns current node name in Fortran format */
462  /* l is max. allowed length in name */
463{
464  int ename_l = strlen(current_node->name);
465  int i, ncp = ename_l < *l ? ename_l : *l;
466  int nbl = *l - ncp;
467  for (i = 0; i < ncp; i++) name[i] = toupper(current_node->name[i]);
468  for (i = 0; i < nbl; i++) name[ncp+i] = ' ';
469}
470
471int
472get_node_count(struct node* node)
473  /* finds the count of a node in the current expanded sequence */
474{
475  int cnt = 0;
476  current_node = current_sequ->ex_start;
477  while (current_node != NULL)
478  {
479    if (current_node == node) return cnt;
480    cnt++;
481    if (current_node == current_sequ->ex_end) break;
482    current_node = current_node->next;
483  }
484  return -1;
485}
486
487void
488store_node_vector(char* par, int* length, double* vector)
489  /* stores vector at node */
490{
491  char lpar[NAME_L];
492  mycpy(lpar, par);
493  if (strcmp(lpar, "orbit0") == 0)  copy_double(vector, orbit0, 6);
494  else if (strcmp(lpar, "orbit_ref") == 0)
495  {
496    if (current_node->orbit_ref)
497    {
498      while (*length > current_node->orbit_ref->max)
499        grow_double_array(current_node->orbit_ref);
500    }
501    else current_node->orbit_ref = new_double_array(*length);
502    copy_double(vector, current_node->orbit_ref->a, *length);
503    current_node->orbit_ref->curr = *length;
504  }
505  else if (strcmp(lpar, "surv_data") == 0) 
506        copy_double(vector, current_node->surv_data, *length);
507
508}
509
510int
511advance_node(void)
512  /* advances to next node in expanded sequence;
513     returns 0 if end of range, else 1 */
514{
515  if (current_node == current_sequ->range_end)  return 0;
516  current_node = current_node->next;
517  return 1;
518}
519
520int
521advance_to_pos(char* table, int* t_pos)
522  /* advances current_node to node at t_pos in table */
523{
524  struct table* t;
525  int pos, cnt = 0, ret = 0;
526  mycpy(c_dum->c, table);
527  if ((pos = name_list_pos(c_dum->c, table_register->names)) > -1)
528  {
529    ret = 1;
530    t = table_register->tables[pos];
531    if (t->origin == 1)  return 0; /* table is read, has no node pointers */
532    while (current_node)
533    {
534      if (current_node == t->p_nodes[*t_pos-1]) break;
535      if ((current_node = current_node->next)
536          == current_sequ->ex_start) cnt++;
537      if (cnt > 1) return 0;
538    }
539  }
540  return ret;
541}
542
543double
544line_nodes(struct char_p_array* flat)
545  /* creates a linked node list from a flat element list of a line */
546{
547  int i, j, k;
548  double pos = zero, val;
549  struct element* el;
550  for (j = 0; j < flat->curr; j++)
551  {
552    if ((el = find_element(flat->p[j], element_list)) == NULL)
553      fatal_error("line contains unknown element:", flat->p[j]);
554    if (strcmp(el->base_type->name, "rfcavity") == 0 &&
555        find_element(el->name, current_sequ->cavities) == NULL)
556      add_to_el_list(&el, 0, current_sequ->cavities, 0);
557    val = el_par_value("l", el);
558    pos += val / 2;
559    k = 1;
560    if ((i = name_list_pos(el->name, occ_list)) < 0)
561      i = add_to_name_list(el->name, k, occ_list);
562    else k = ++occ_list->inform[i];
563    make_elem_node(el, k);
564    current_node->at_value = current_node->position = pos;
565    pos += val / 2;
566  }
567  return pos;
568}
569
570void
571node_string(char* key, char* string, int* l)
572  /* returns current node string value for "key" in Fortran format */
573  /* l is max. allowed length in string */
574{
575  char tmp[2*NAME_L];
576  char* p;
577  int i, l_p, nbl, ncp = 0;
578  mycpy(tmp, key);
579  if ((p = command_par_string(tmp, current_node->p_elem->def)))
580  {
581    l_p = strlen(p);
582    ncp = l_p < *l ? l_p : *l;
583  }
584  nbl = *l - ncp;
585  for (i = 0; i < ncp; i++) string[i] = p[i];
586  for (i = 0; i < nbl; i++) string[ncp+i] = ' ';
587}
588
589int
590remove_one(struct node* node)
591{
592  int pos;
593  /* removes a node from a sequence being edited */
594  if ((pos = name_list_pos(node->p_elem->name, occ_list)) < 0)  return 0;
595  if (node->previous != NULL) node->previous->next = node->next;
596  if (node->next != NULL) node->next->previous = node->previous;
597  if (occ_list->inform[pos] == 1)
598  {
599    remove_from_node_list(node, edit_sequ->nodes);
600    remove_from_name_list(node->p_elem->name, occ_list);
601  }
602  else --occ_list->inform[pos];
603  /* myfree(rout_name, node); */
604  return 1;
605}
606
607void
608replace_one(struct node* node, struct element* el)
609  /* replaces an existing node by a new one made from el */
610{
611  int i, k = 1;
612  remove_from_node_list(node, edit_sequ->nodes);
613  if ((i = name_list_pos(el->name, occ_list)) < 0)
614    i = add_to_name_list(el->name, 1, occ_list);
615  else k = ++occ_list->inform[i];
616  strcpy(node->name, compound(el->name, k));
617  add_to_node_list(node, 0, edit_sequ->nodes);
618  node->p_elem = el;
619  node->base_name = el->base_type->name;
620  node->length = el->length;
621  if (strcmp(el->base_type->name, "rfcavity") == 0 &&
622      find_element(el->name, edit_sequ->cavities) == NULL)
623    add_to_el_list(&el, 0, edit_sequ->cavities, 0);
624}
625
Note: See TracBrowser for help on using the repository browser.