source: PSPA/madxPSPA/src/survey.f90 @ 447

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

import madx-5.01.00

File size: 11.2 KB
Line 
1!  Routines for the survey command in MADX / A. Verdier (started October 2001)
2subroutine survey
3
4
5
6  implicit none
7  !----------------------------------------------------------------------*
8  ! Purpose:                                                             *
9  !   Execute SURVEY command.                                            *
10  ! Attributes, must be given in this order in the dictionary:           *
11  !   X0        (real)    Initial X position.                            *
12  !   Y0        (real)    Initial Y position.                            *
13  !   Z0        (real)    Initial Z position.                            *
14  !   THETA0    (real)    Initial azimuthal angle.                       *
15  !   PHI0      (real)    Initial elevation angle.                       *
16  !   PSI0      (real)    Initial roll angle.                            *
17  !----------------------------------------------------------------------*
18  ! Modified: 01-APR-1999, M. Woodley (SLAC)                             *
19  !   If we're doing tape file output and there are LCAVITY elements in  *
20  !   the current beamline, initialize ENER1 (in COMMON /OPTIC1/) using  *
21  !   ENERGY from BEAM common, and call TMLCAV for each one to update    *
22  !   ENERGY                                                             *
23  !----------------------------------------------------------------------*
24
25  integer i,j,code,restart_sequ,advance_node,add_pass,passes,n_add_angle
26  integer angle_count, node_count, node_ref(100),set_cont_sequence
27  double precision dphi,dpsi,dtheta,phi,phi0,proxim,psi,psi0,sums,  &
28       theta,theta0,v(3),v0(3),ve(3),w(3,3),w0(3,3),we(3,3),tx(3),       &
29       node_value,el,suml,get_value,tilt,globaltilt,zero,add_angle(10), &
30       org_ang(100)
31  parameter(zero=0d0)
32
33  !---- Retrieve command attributes.
34  v0(1)=  get_value('survey ','x0 ')
35  v0(2)=  get_value('survey ','y0 ')
36  v0(3)=  get_value('survey ','z0 ')
37  theta0 = get_value('survey ','theta0 ')
38  phi0 =   get_value('survey ','phi0 ')
39  psi0 =   get_value('survey ','psi0 ')
40
41  !---- Initialise the angles
42  theta = theta0
43  phi = phi0
44  psi = psi0
45
46  !---- Set up initial V and W.
47  suml = zero
48  sums = zero
49  call sumtrx(theta0, phi0, psi0, w0)
50  !      theta = theta0
51  !      phi =  phi0
52  !      psi =  psi0
53
54
55  !---- (replaces SUCOPY)
56  do j = 1, 3
57     v(j) = v0(j)
58     do i = 1, 3
59        w(i,j) = w0(i,j)
60     enddo
61  enddo
625 continue
63
64  !---- loop over elements  NO SYMMETRIC SUPERPERIOD ANYMORE!   *******
65  !      print *,"suml  length   theta(x)   phi(y)    psi(z)   coord."
66  add_pass = get_value('sequence ','add_pass ')
67  ! multiple passes allowed
68  do passes = 0, add_pass
69     j = restart_sequ()
70     angle_count = 0
71     node_count = 0
7210   continue
73     node_count = node_count + 1
74     if (passes .gt. 0)  then
75        call get_node_vector('add_angle ',n_add_angle,add_angle)
76        if (n_add_angle .gt. 0 .and. add_angle(passes) .ne. 0.) then
77           if (passes .eq. 1) then
78              angle_count = angle_count + 1
79              node_ref(angle_count) = node_count
80              org_ang(angle_count) = node_value('angle ')
81           endif
82           call store_node_value('angle ', add_angle(passes))
83        endif
84     endif
85     code = node_value('mad8_type ')
86     if(code.eq.39) code=15
87     if(code.eq.38) code=24
88     !      print *,"code   ", code
89     !**** el is the arc length for all bends  ********
90     el = node_value('l ')
91     call suelem(el, ve, we,tilt)
92     !      print *,"el, tilt", el, tilt
93     suml = suml + el
94     !**  Compute the coordinates at each point
95     call sutrak(v, w, ve, we)
96     !**  Compute globaltilt HERE : it's the value at the entrance
97     globaltilt=psi+tilt
98     !**  Compute the survey angles at each point
99     call suangl(w, theta, phi, psi)
100     !**  Fill the survey table
101     call sufill(suml,v, theta, phi, psi,globaltilt)
102     if (advance_node().ne.0)  goto 10
103     !---- end of loop over elements  ***********************************
104  enddo
105  ! restore original angle to node if necessary
106  if (add_pass .gt. 0) then
107     j = restart_sequ()
108     angle_count = 1
109     node_count = 0
11020   continue
111     node_count = node_count+1
112     if (node_ref(angle_count) .eq. node_count)  then
113        call store_node_value('angle ', org_ang(angle_count))
114        angle_count = angle_count+1
115     endif
116     if (advance_node().ne.0)  goto 20
117  endif
118  if (set_cont_sequence() .ne. 0)  goto 5
119
120  !---- Centre of machine.
121  do i = 1, 3
122     tx(i) = v(i) - v0(i)
123  enddo
124  dtheta = theta - proxim(theta0, theta)
125  dphi = phi - proxim(phi0, phi)
126  dpsi = psi - proxim(psi0, psi)
127  !      print *,v, theta, phi, psi
128end subroutine survey
129!-----------------  end of survey  subroutine -------------------------
130
131!***********************************************************************
132!  Subroutines necessary : suangl sutrak suelem
133!**********************************************************************
134
135subroutine suangl(w, theta, phi, psi)
136  implicit none
137  !----------------------------------------------------------------------*
138  ! Purpose:                                                             *
139  !   Given a rotation matrix, compute the survey angles.                *
140  ! Input:                                                               *
141  !   W(3,3)    (real)    Rotation matrix.                               *
142  ! Output:                                                              *
143  !   THETA     (real)    Azimuthal angle.                               *
144  !   PHI       (real)    Elevation angle.                               *
145  !   PSI       (real)    Roll angle.                                    *
146  !----------------------------------------------------------------------*
147  double precision arg,theta,phi,psi,w(3,3),proxim
148
149  arg = sqrt(w(2,1)**2 + w(2,2)**2)
150  phi = atan2(w(2,3), arg)
151  !      print *,"SUANGL: phi =",phi," arg=",arg,"  w23 =",w(2,3),
152  !      "  w22 =",w(2,2),"  w21 =",w(2,1)
153
154  !*****  old procedure commented as incompatiblr with YROT
155  !      if (arg .gt. 1.0e-20) then
156  theta = proxim(atan2(w(1,3), w(3,3)), theta)
157  psi = proxim(atan2(w(2,1), w(2,2)), psi)
158  !      else
159  !        theta = atan2(w(1,3), w(3,3))
160  !        psi = proxim(atan2(-w(1,2), w(1,1))-theta, psi)
161  !      endif
162end subroutine suangl
163!-----------------  end of suangl  subroutine -------------------------
164!
165!**********************************************************************
166
167
168subroutine sutrak(v, w, ve, we)
169  implicit none
170  !----------------------------------------------------------------------*
171  ! Purpose:                                                             *
172  !   Update global position.                                            *
173  ! Input:                                                               *
174  !   V(3)      (real)    Global displacement before element.            *
175  !   W(3,3)    (real)    Global rotation matrix before element.         *
176  !   VE(3)     (real)    Displacement due to element.                   *
177  !   WE(3,3)   (real)    Rotation due to element.                       *
178  ! Output:                                                              *
179  !   V(3)      (real)    Global displacement after element.             *
180  !   W(3,3)    (real)    Global rotation matrix after element.          *
181  !----------------------------------------------------------------------*
182  integer i
183  double precision v(3),ve(3),w(3,3),we(3,3),wt1,wt2,wt3
184
185  do i = 1, 3
186     v(i) = v(i) + w(i,1)*ve(1) + w(i,2)*ve(2) + w(i,3)*ve(3)
187     wt1 = w(i,1)*we(1,1) + w(i,2)*we(2,1) + w(i,3)*we(3,1)
188     wt2 = w(i,1)*we(1,2) + w(i,2)*we(2,2) + w(i,3)*we(3,2)
189     wt3 = w(i,1)*we(1,3) + w(i,2)*we(2,3) + w(i,3)*we(3,3)
190     w(i,1) = wt1
191     w(i,2) = wt2
192     w(i,3) = wt3
193  enddo
194end subroutine sutrak
195!-----------------  end of sutrak subroutine --------------------------
196!
197
198!**********************************************************************
199subroutine sufill(suml,v, theta, phi, psi,globaltilt)
200
201
202  use twtrrfi
203  implicit none
204  !----------------------------------------------------------------------*
205  ! Purpose:                                                             *
206  !   writes the survey output in the table "survey"                     *
207  ! Output:                                                              *
208  !   EL       (real)    Element length along design orbit.              *
209  !   V(3)     (real)    Coordinate at the end of the element            *
210  ! theta, phi, psi(real) : the survey angles                            *
211  !----------------------------------------------------------------------*
212  integer code,nn, i
213  double precision ang,el,v(3),theta,phi,psi,node_value,suml,       &
214       normal(0:maxmul),globaltilt,tmp, surv_vect(7)
215
216  el = node_value('l ')
217  call string_to_table_curr('survey ', 'name ', 'name ')
218  call double_to_table_curr('survey ', 's ',suml )
219  call double_to_table_curr('survey ', 'l ',el )
220  call double_to_table_curr('survey ', 'x ',v(1) )
221  call double_to_table_curr('survey ', 'y ',v(2) )
222  call double_to_table_curr('survey ', 'z ',v(3) )
223  call double_to_table_curr('survey ', 'theta ',theta)
224  call double_to_table_curr('survey ', 'phi ',phi)
225  call double_to_table_curr('survey ', 'psi ',psi)
226  call double_to_table_curr('survey ', 'globaltilt ',globaltilt)
227  i = node_value('pass_flag ')
228  if (i .eq. 0) then
229     surv_vect(1) = v(1)
230     surv_vect(2) = v(2)
231     surv_vect(3) = v(3)
232     surv_vect(4) = theta
233     surv_vect(5) = phi
234     surv_vect(6) = psi
235     surv_vect(7) = suml
236     tmp = 1
237     call store_node_value('pass_flag ', tmp)
238     i = 7
239     call store_node_vector('surv_data ', i, surv_vect)
240  endif
241  code = node_value('mad8_type ')
242  if(code.eq.39) code=15
243  if(code.eq.38) code=24
244  if(code.eq.2.or.code.eq.3) then
245     ang = node_value('angle ')*node_value('other_bv ')
246  else if(code.eq.8) then
247     call get_node_vector('knl ',nn,normal)
248     if (nn .ne. 0) then
249        ang = normal(0)
250     else
251        ang = 0d0
252     endif
253  else
254     ang = 0d0
255  endif
256  call double_to_table_curr('survey ', 'angle ',ang)
257
258  !---------------- --------------------------
259  !     copy over the attributes 'mech_sep' and 'assembly_id'
260  !     FT 06.06.2008
261
262  tmp = node_value('slot_id ')
263  call double_to_table_curr('survey ', 'slot_id ',tmp)
264
265  tmp = node_value('assembly_id ')
266  call double_to_table_curr('survey ', 'assembly_id ',tmp)
267
268  tmp = node_value('mech_sep ')
269  call double_to_table_curr('survey ', 'mech_sep ',tmp)
270
271  !== jln dealt with the new property v_pos as for mech_sep
272  tmp = node_value('v_pos ')
273  call double_to_table_curr('survey ', 'v_pos ',tmp)
274  !==
275
276  call augment_count('survey ')
277end subroutine sufill
278!-----------------  end of sufill subroutine --------------------------
279subroutine survtest
280  integer j, length, advance_node
281  double precision vector(7)
282  integer, external :: restart_sequ
283  ! test routine for USE with option SURVEY
284  call set_sequence('combseq ')
285  print *, "# sequence combseq"
286  j = restart_sequ()
28710 continue
288  call get_node_vector('surv_data ', length, vector)
289  print *, vector
290  if (advance_node() .ne. 0)  goto 10
291  call set_sequence('new3 ')
292  print *, "# sequence newcont"
293  j = restart_sequ()
29420 continue
295  call get_node_vector('surv_data ', length, vector)
296  print *, vector
297  if (advance_node() .ne. 0)  goto 20
298end subroutine survtest
299!-----------------  end of surtest subroutine --------------------------
Note: See TracBrowser for help on using the repository browser.