VMEC 8.52
3D Equilibrium solver with nested flux surfaces.
Loading...
Searching...
No Matches
convert.f90
Go to the documentation of this file.
1
4
16SUBROUTINE convert(rmnc, zmns, lmns, rmns, zmnc, lmnc, rzl_array, js)
17
18 USE vmec_main
19 USE vmec_params
20
21 IMPLICIT NONE
22
23 REAL(rprec), DIMENSION(mnmax), INTENT(out) :: rmnc
24 REAL(rprec), DIMENSION(mnmax), INTENT(out) :: zmns
25 REAL(rprec), DIMENSION(mnmax), INTENT(out) :: lmns
26 REAL(rprec), DIMENSION(mnmax), INTENT(out) :: rmns
27 REAL(rprec), DIMENSION(mnmax), INTENT(out) :: zmnc
28 REAL(rprec), DIMENSION(mnmax), INTENT(out) :: lmnc
29 REAL(rprec), DIMENSION(ns, 0:ntor, 0:mpol1, 3*ntmax), INTENT(in) :: rzl_array
30 INTEGER, INTENT(in) :: js
31
32 REAL(rprec), PARAMETER :: p5 = 0.5_dp
33
34 INTEGER :: rmncc, rmnss, rmncs, rmnsc, zmncs, zmnsc, &
35 zmncc, zmnss, lmncs, lmnsc, lmncc, lmnss
36 INTEGER :: mn, m, n, n1
37 REAL(rprec) :: t1, sign0
38
39 ! CONVERTS INTERNAL MODE REPRESENTATION TO STANDARD FORM FOR OUTPUT
40 ! (COEFFICIENTS OF COS(mu-nv), SIN(mu-nv) WITHOUT internal mscale,nscale norms)
41
42 rmncc = rcc
43 rmnss = rss
44 rmnsc = rsc
45 rmncs = rcs
46 zmnsc = zsc + ntmax
47 zmncc = zcc + ntmax
48 zmncs = zcs + ntmax
49 zmnss = zss + ntmax
50 lmnsc = zsc + 2*ntmax
51 lmncc = zcc + 2*ntmax
52 lmncs = zcs + 2*ntmax
53 lmnss = zss + 2*ntmax
54
55 ! init to zero, since not assigned if .not. lthreed
56 zmns(1:ntor+1) = 0
57 lmns(1:ntor+1) = 0
58
59 ! DO M = 0 MODES SEPARATELY (ONLY KEEP N >= 0 HERE: COS(-NV), SIN(-NV))
60 mn = 0
61 m = 0
62 DO n = 0, ntor
63 t1 = mscale(m)*nscale(n)
64 mn = mn + 1
65 rmnc(mn) = t1*rzl_array(js,n,m,rmncc)
66 IF (.not. lthreed) cycle
67 zmns(mn) =-t1*rzl_array(js,n,m,zmncs)
68 lmns(mn) =-t1*rzl_array(js,n,m,lmncs)
69 END DO
70
71 IF (lthreed .and. js.eq.1) THEN
72 ! extrapolate to axis if 3D
73 mn = 0
74 DO n = 0, ntor
75 t1 = mscale(m)*nscale(n)
76 mn = mn + 1
77 lmns(mn) =-t1*(2*rzl_array(2,n,m,lmncs) - rzl_array(3,n,m,lmncs))
78 END DO
79 END IF
80
81 ! safeguard against spurious DC component in lambda (?)
82 ! may have been used for storing iota variation...
83 lmns(1) = 0
84
85 ! now come the m>0, n=-ntor, ..., ntor entries
86 DO m = 1, mpol1
87 DO n = -ntor, ntor
88 n1 = abs(n)
89 t1 = mscale(m)*nscale(n1)
90 mn = mn + 1
91 IF (n .eq. 0) THEN
92 rmnc(mn) = t1*rzl_array(js,n,m,rmncc)
93 zmns(mn) = t1*rzl_array(js,n,m,zmnsc)
94 lmns(mn) = t1*rzl_array(js,n,m,lmnsc)
95 ELSE IF (js .gt. 1) THEN
96 sign0 = n/n1
97 IF (.not.lthreed) sign0 = 0
98 rmnc(mn) = p5*t1*(rzl_array(js,n1,m,rmncc)+sign0*rzl_array(js,n1,m,rmnss))
99 zmns(mn) = p5*t1*(rzl_array(js,n1,m,zmnsc)-sign0*rzl_array(js,n1,m,zmncs))
100 lmns(mn) = p5*t1*(rzl_array(js,n1,m,lmnsc)-sign0*rzl_array(js,n1,m,lmncs))
101 ELSE IF (js .eq. 1) THEN
102 ! no m>=1 component in magnetic axis (js==1)
103 rmnc(mn) = 0
104 zmns(mn) = 0
105 lmns(mn) = 0
106 END IF
107 END DO
108 END DO
109
110 IF (mn .ne. mnmax) stop 'Error in Convert!'
111
112 IF (.not.lasym) THEN
113 rmns = 0
114 zmnc = 0
115 lmnc = 0
116 RETURN
117 END IF
118
119 ! add non-stellarator-symmetric terms now
120
121 mn = 0; m = 0
122 rmns(1:ntor+1) = 0
123 DO n = 0, ntor
124 t1 = mscale(m)*nscale(n)
125 mn = mn + 1
126 zmnc(mn) = t1*rzl_array(js,n,m,zmncc)
127 lmnc(mn) = t1*rzl_array(js,n,m,lmncc)
128 IF (.not.lthreed) cycle
129 rmns(mn) =-t1*rzl_array(js,n,m,rmncs) !ers-fixed sign
130 END DO
131
132 DO m = 1, mpol1
133 DO n = -ntor, ntor
134 n1 = abs(n)
135 t1 = mscale(m)*nscale(n1)
136 mn = mn + 1
137 IF (n .eq. 0) THEN
138 rmns(mn) = t1*rzl_array(js,n,m,rmnsc)
139 zmnc(mn) = t1*rzl_array(js,n,m,zmncc)
140 lmnc(mn) = t1*rzl_array(js,n,m,lmncc)
141 ELSE IF (js .gt. 1) THEN
142 sign0 = n/n1
143 ! ers-corrected rmnsc <-> rmncs
144 rmns(mn) = p5*t1*(rzl_array(js,n1,m,rmnsc)-sign0*rzl_array(js,n1,m,rmncs))
145 zmnc(mn) = p5*t1*(rzl_array(js,n1,m,zmncc)+sign0*rzl_array(js,n1,m,zmnss))
146 lmnc(mn) = p5*t1*(rzl_array(js,n1,m,lmncc)+sign0*rzl_array(js,n1,m,lmnss))
147 ELSE IF (js .eq. 1) THEN
148 rmns(mn) = 0
149 zmnc(mn) = 0
150 lmnc(mn) = 0
151 END IF
152 END DO
153 END DO
154
155END SUBROUTINE convert
subroutine convert(rmnc, zmns, lmns, rmns, zmnc, lmnc, rzl_array, js)
Convert internal mode representation to standard form for output (coefficients of cos(mu-nv),...
Definition convert.f90:17
logical lthreed
real(rprec), dimension(:), allocatable mscale
array for norming theta-trig functions (internal use only) so that the discrete SUM[cos(mu)*cos(m'u)]...
real(rprec), dimension(:), allocatable nscale
array for norming zeta -trig functions (internal use only)
integer ntmax
number of contributing Fourier basis function (can be 1, 2 or 4); assigned in read_indata()