V3FIT
boozer_coords.f
1  SUBROUTINE boozer_coords(jrad)
2  USE booz_params
3  USE booz_persistent
4  IMPLICIT NONE
5 C-----------------------------------------------
6 C D u m m y A r g u m e n t s
7 C-----------------------------------------------
8  INTEGER :: jrad
9 C-----------------------------------------------
10 C L o c a l V a r i a b l e s
11 C-----------------------------------------------
12  INTEGER :: nparity, istat1, nv2_b, i1, nrep
13  INTEGER, SAVE :: jsurf = 0
14  REAL(rprec) :: bmodv(4), bmodb(4), err(4), jacfac
15  REAL(rprec) :: u_b(4), v_b(4), piu, piv
16  REAL(rprec), DIMENSION(:), ALLOCATABLE ::
17  1 r1, z1, rodd, zodd, r12, z12, p1, q1, xjac,
18  1 lt, lz, lam, wt, wz, wp
19  REAL(rprec), DIMENSION(:,:), ALLOCATABLE ::
20  1 cosmm, sinmm, cosnn, sinnn
21 C-----------------------------------------------
22 c jrad radial point where Boozer coords. are needed
23 c ns number of vmec radial grid points
24 c nu_boz number of theta points in integration
25 c nv_boz number of zeta points in integration
26 c mpol number of theta harmonics from vmec for r,z,l
27 c ntor number of zeta harmonics from vmec (no. zeta modes = 2*ntor+1) for r,z,l
28 c mpol_nyq number of theta harmonics from vmec for bsubumn, bsubvmn
29 c ntor_nyq number of zeta harmonics from vmec (no. zeta modes = 2*ntor+1) for bsubumn, bsubvmn
30 c mboz number of boozer theta harmonics
31 c nboz number of boozer zeta harmonics
32 c
33 
34 
35  IF (jsurf .eq. 0) THEN
36 !
37 ! ALLOCATE GLOBAL ARRAYS
38 !
39 
40  CALL setup_booz (ntorsum, ns, mnmax, ohs, xmb, xnb,
41  1 sfull, scl, mboz, nboz, mnboz, nu2_b, nu_boz,
42  2 nv_boz, nfp, lasym_b)
43 
44 !
45 ! SET UP FIXED ANGLE ARRAYS
46 !
47 
48  IF (lasym_b) THEN
49  nu3_b = nu_boz
50  ELSE
51  nu3_b = nu2_b !!ONLY need top half of theta mesh for symmetric plasma
52  END IF
53 
54  nunv = nu3_b*nv_boz
55 
56  CALL foranl (nu3_b, nv_boz, nfp, nunv, lasym_b)
57 
58  IF (lscreen) WRITE(6, 50) mboz-1, -nboz, nboz, nu_boz, nv_boz
59  50 FORMAT(' 0 <= mboz <= ',i4,3x,i4,' <= nboz <= ',i4,/,
60  1 ' nu_boz = ',i5,' nv_boz = ',i5,//,
61  1 13x,'OUTBOARD (u=0)',14x,'JS',10x,'INBOARD (u=pi)'
62  2 /,77('-')/,' v |B|vmec |B|booz Error',13x,
63  3 '|B|vmec |B|booz Error'/)
64 
65  ENDIF
66 
67  jsurf = jsurf + 1
68 !
69 ! ALLOCATE LOCAL MEMORY
70 !
71  ALLOCATE (r12(nunv), z12(nunv), r1(nunv), rodd(nunv), z1(nunv),
72  1 zodd(nunv), lt(nunv), lz(nunv), p1(nunv), q1(nunv),
73  2 xjac(nunv), stat=istat1 )
74  IF (istat1 .ne. 0) stop 'Allocation error #1 in boozer_coords'
75 
76 !
77 ! COMPUTE FOURIER COEFFICIENTS (pmn) OF THE "SOURCE" CONTRIBUTIONS (right of Eq.10)
78 ! OF THE BOOZER-TO-VMEC TRANSFORMATION FUNCTION P:
79 !
80 ! Theta-Booz = Theta-VMEC + Lambda + Iota*p
81 ! Zeta-Booz = Zeta-VMEC + p
82 !
83  CALL transpmn (pmns, bsubumnc(1,jrad), bsubvmnc(1,jrad),
84  1 pmnc, bsubumns(1,jrad), bsubvmns(1,jrad),
85  2 xm_nyq, xn_nyq, gpsi, ipsi, mnmax_nyq, jrad,
86  3 lasym_b)
87 
88 !
89 ! BEGIN CALCULATION OF BOOZER QUANTITIES AT HALF-RADIAL
90 ! MESH POINT JRAD
91 ! (ALL TRANSFORMED QUANTITIES MUST BE ON HALF-MESH FOR ACCURACY)
92 !
93 
94  ALLOCATE (lam(nunv), wt(nunv), wz(nunv), wp(nunv), stat=istat1)
95  IF (istat1 .ne. 0) stop 'Allocation error #2 in boozer_coords'
96 !
97 ! COMPUTE EVEN (in poloidal mode number) AND ODD COMPONENTS
98 ! OF R,Z, LAMDA IN REAL SPACE (VMEC) COORDINATES
99 !
100  nparity = 0
101  CALL vcoords_rz (rmnc, zmns, lmns, rmns, zmnc, lmnc, xm, xn,
102  1 ntorsum, ns, jrad, mnmax, r1, z1, lt, lz, lam, sfull,
103  2 nparity, nunv, nfp, lasym_b)
104 
105  nparity = 1
106  CALL vcoords_rz (rmnc, zmns, lmns, rmns, zmnc, lmnc, xm, xn,
107  1 ntorsum, ns, jrad, mnmax, rodd, zodd, lt, lz, lam, sfull,
108  2 nparity, nunv, nfp, lasym_b)
109 
110 ! COMPUTE "SOURCE" PART OF TRANSFORMATION FUNCTION p==wp (RIGHT-SIDE OF EQ.10), ITS DERIVATIVES,
111 ! AND |B| ALL IN VMEC COORDINATES
112  CALL vcoords_w (bmodmnc(1,jrad), bmodmns(1,jrad), pmns, pmnc,
113  1 xm_nyq, xn_nyq, jrad, mnmax_nyq, bmod_b, wt,
114  2 wz, wp, nunv, nfp, lasym_b)
115 
116 !
117 ! COMPUTE MAPPING FUNCTIONS P1 = lambda+iota*p, Q1 = p, AND MAPPING JACOBIAN (XJAC)
118 ! FOR DOING FOURIER INTEGRALS IN REAL SPACE (VMEC) COORDINATES
119 !
120  CALL harfun (jacfac, hiota, gpsi, ipsi, jrad, nunv,
121  1 lt, lz, lam, wt, wz, wp, p1, q1, xjac)
122  DEALLOCATE (lam, wt, wz, wp, stat=istat1)
123  IF (istat1 .ne. 0) stop 'Deallocation error in boozer_coords'
124 
125 !
126 ! COMPUTE R12, Z12 ON RADIAL HALF-GRID (IN ORIGINAL VMEC COORDINATES)
127 !
128  nrep = 1
129  CALL booz_rzhalf(r1, z1, rodd, zodd, r12, z12, ohs,
130  1 jrad, nunv, nrep)
131 !
132 ! Store VMEC-Space fixed point values for |B| for checking accuracy later
133 !
134  nv2_b = nv_boz/2+1 !Index of v=pi (for non-axisymetry)
135  bmodv(1) = bmod_b(1,1) !(v=0,u=0)
136  bmodv(2) = bmod_b(1,nu2_b) !(0,pi)
137  bmodv(3) = bmod_b(nv2_b,1) !(pi,0)
138  bmodv(4) = bmod_b(nv2_b,nu2_b) !(pi,pi)
139 
140  DEALLOCATE (r1, rodd, z1, zodd, lt, lz, stat=istat1)
141  IF (istat1 .ne. 0) stop 'Deallocation error in boozer_coords'
142 
143 !
144 ! COMPUTE BOOZER-SPACE FOURIER COEFFICIENTS FOR R,Z,P, AND |B|
145 !
146  ALLOCATE (cosmm(nunv,0:mboz), sinmm(nunv,0:mboz),
147  1 cosnn(nunv,0:nboz), sinnn(nunv,0:nboz), stat=istat1)
148  IF (istat1 .ne. 0) stop 'Deallocation error in boozer_coords'
149 
150 ! CRCook added jrad argument since we will need to use iota at jrad
151  CALL boozer (thgrd, ztgrd, bmod_b, r12, z12, xmb, xnb,
152  1 bmncb(1,jsurf), rmncb(1,jsurf), zmnsb(1,jsurf),
153  2 pmnsb(1,jsurf), gmncb(1,jsurf), bmnsb(1,jsurf),
154  3 rmnsb(1,jsurf), zmncb(1,jsurf), pmncb(1,jsurf),
155  4 gmnsb(1,jsurf), scl, p1, q1, xjac,
156  5 cosmm, sinmm, cosnn, sinnn, mnboz, nunv, mboz, nboz,
157  6 nfp, nu2_b, nv_boz, jacfac, jrad)
158 
159 !
160 ! STORE BOOZER ANGLES CORRESPONDING TO VMEC ANGLES (u,v) OF 0 and pi
161 !
162  piv = ztgrd(nv2_b)
163  u_b(1) = p1(1); v_b(1) = q1(1) !(u=0,v=0)
164  u_b(3) = p1(nv2_b); v_b(3) = piv+q1(nv2_b) !(u=0,v=pi)
165  i1 = 1+nv_boz*(nu2_b-1)
166  piu = thgrd(i1)
167  u_b(2) = piu+p1(i1); v_b(2) = q1(i1) !(u=pi,v=0)
168  i1 = nv2_b+nv_boz*(nu2_b-1)
169  u_b(4) = piu+p1(i1); v_b(4) = piv+q1(i1) !(u=pi,v=pi)
170 
171  DEALLOCATE (p1, q1, xjac, stat=istat1)
172  IF (istat1 .ne. 0) stop 'Deallocation error in boozer_coords'
173 
174 !
175 ! COMPUTE BOOZER-SPACE MOD-B FOR GENERAL CASE (LASYM = TRUE, CAN'T USE
176 ! FIXED-POINT SYMMETRY ANYMORE)
177 !
178  CALL modbooz(bmncb(1,jsurf), bmnsb(1,jsurf),
179  1 bmodb, xmb, xnb, u_b, v_b, cosmm, sinmm, cosnn, sinnn,
180  2 mnboz, mboz, nboz, nfp, lasym_b)
181 
182  err = abs(bmodb - bmodv)/max(bmodb,bmodv)
183  IF (lscreen) WRITE(6,100)
184  1 bmodv(1),bmodb(1),err(1),jrad,bmodv(2),bmodb(2),err(2),
185  2 bmodv(3),bmodb(3),err(3),bmodv(4),bmodb(4),err(4)
186  100 FORMAT(' 0 ',1p,3e11.3,i5,2x,3e11.3,/' pi ',2(3e11.3,7x) )
187 
188 !SPH ADDED 102309 - Write out flux surface shapes in Boozer coordinates (at nvplane=1 for now...)
189  ALLOCATE (r1(nunv), rodd(nunv), z1(nunv), zodd(nunv),
190  1 stat=istat1 )
191  IF (istat1 .ne. 0) stop 'Allocation error #3 in boozer_coords'
192 
193  CALL vcoords_rzb (rmncb, zmnsb, rmnsb, zmncb, xmb, xnb,
194  1 cosmm, sinmm, cosnn, sinnn, mboz, nboz,
195  2 mnboz, jsurf, ns, r1, z1, nunv, nfp, lasym_b)
196 
197  nrep = 2 !1 for vmec, 2 for booz
198  CALL booz_rzhalf(r1, z1, rodd, zodd, r12, z12, ohs,
199  1 jrad, nunv, nrep)
200 
201  DEALLOCATE (cosmm, sinmm, cosnn, sinnn,
202  1 r1, rodd, z1, zodd, r12, z12, stat=istat1)
203  IF (istat1 .ne. 0) stop 'Deallocation error in boozer_coords'
204 
205  END SUBROUTINE boozer_coords