VMEC 8.52
3D Equilibrium solver with nested flux surfaces.
Loading...
Searching...
No Matches
getbsubs.f90
Go to the documentation of this file.
1
3
13SUBROUTINE getbsubs (bsubsmn, frho, bsupu, bsupv, mmax, nmax, info)
14 USE stel_kinds
15 USE vmec_input, ONLY: nfp, nzeta, lasym
16 USE vmec_dim, ONLY: ntheta2, ntheta3
18 IMPLICIT NONE
19
20 REAL(rprec), INTENT(out) :: bsubsmn(0:mmax, -nmax:nmax, 0:1)
21 REAL(rprec), DIMENSION(nzeta, ntheta3), INTENT(in) :: frho
22 REAL(rprec), DIMENSION(nzeta, ntheta3), INTENT(in) :: bsupu
23 REAL(rprec), DIMENSION(nzeta, ntheta3), INTENT(in) :: bsupv
24 INTEGER, INTENT(in) :: mmax
25 INTEGER, INTENT(in) :: nmax
26 INTEGER, INTENT(out) :: info
27
28 REAL(rprec), PARAMETER :: p5 = 0.5_dp, one = 1
29
30 INTEGER :: i, j, m, n, nmax1, itotal, ijtot, mntot
31 REAL(rprec) :: ccmn, ssmn, csmn, scmn, dm, dn, termsc, termcs, termcc, termss, amn
32 REAL(rprec), ALLOCATABLE :: amatrix(:,:), save_matrix(:,:), brhs(:)
33 LOGICAL :: lpior0
34 EXTERNAL solver
35
36 ! Solves the radial force balance B dot bsubs = Fs for bsubs in real space using collocation.
37 ! Here, Fs = frho(mn) is the Fourier transform SQRT(g)*F (part of radial force
38 ! balance sans the B dot bsubs term)
39 !
40 ! Storage layout: bsubsmn(0:mmax, 0:nmax,0) :: coefficient of sin(mu)cos(nv)
41 ! bsubsmn(0:mmax,-1:nmax,0) :: coefficient of cos(mu)sin(nv)
42 ! for lasym = T
43 ! bsubsmn(0:mmax, 0:nmax,1) :: coefficient of cos(mu)cos(nv)
44 ! bsubsmn(0:mmax,-1:nmax,1) :: coefficient of sin(mu)sin(nv)
45 !
46 ! where 0<=m<=mmax and 0<=n<=nmax
47
48 info = -3
49 IF ((mmax+1 .ne. ntheta2) .or. (nmax .ne. nzeta/2)) RETURN
50
51 nmax1 = max(0,nmax-1)
52 itotal = ntheta3*nzeta
53 IF (.not.lasym) itotal = itotal - 2*nmax1
54 ALLOCATE (amatrix(itotal, itotal), brhs(itotal), save_matrix(itotal, itotal), stat=m)
55 IF (m .ne. 0) stop 'Allocation error in getbsubs'
56
57 amatrix = 0
58
59 ! bsubs = BSC(M,N)*SIN(MU)COS(NV) + BCS(M,N)*COS(MU)SIN(NV)
60 ! + BCC(M,N)*COS(MU)COS(NV) + BSS(M,N)*SIN(MU)SIN(NV) (LASYM=T ONLY)
61
62 ijtot = 0
63 brhs = 0
64
65 DO i = 1, ntheta3
66 DO j = 1, nzeta
67 ! IGNORE u=0,pi POINTS FOR v > pi: REFLECTIONAL SYMMETRY
68 lpior0 = ((i.eq.1 .or. i.eq.ntheta2) .and. (j.gt.nzeta/2+1))
69 IF (lpior0 .and. .not. lasym) cycle
70
71 ijtot = ijtot + 1
72
73 brhs(ijtot) = frho(j,i)
74
75 mntot = 0
76 DO m = 0, mmax
77 DO n = 0, nmax
78 IF (mntot .ge. itotal) EXIT
79 IF (m.eq.0 .and. n.eq.0 .and. lasym) cycle
80
81 mntot = mntot+1
82
83 ccmn = cosmu(i,m)*cosnv(j,n)
84 ssmn = sinmu(i,m)*sinnv(j,n)
85 dm = m * bsupu(j,i)
86 dn = n * bsupv(j,i) * nfp
87 termsc = dm*ccmn - dn*ssmn
88 termcs =-dm*ssmn + dn*ccmn
89 IF (n.eq.0 .or. n.eq.nmax) THEN
90 IF (m .gt. 0) THEN
91 ! ONLY bsc != 0 for n=0, nmax1
92 amatrix(ijtot,mntot) = termsc
93 ELSE IF (n .eq. 0) THEN
94 ! pedestal for m=0,n=0 mode, which should = 0
95 amatrix(ijtot,mntot) = bsupv(j,i)
96 ELSE
97 ! bcs(m=0,n=nmax)
98 amatrix(ijtot,mntot) = termcs
99 END IF
100 ELSE IF (m.eq.0 .or. m.eq.mmax) THEN
101 ! ONLY bcs != 0 for m=0,mmax
102 amatrix(ijtot,mntot) = termcs
103 ELSE
104 amatrix(ijtot,mntot) = termsc
105 mntot = mntot+1
106 amatrix(ijtot,mntot) = termcs
107 END IF
108
109 IF (lasym) then
110 IF (m.eq.0 .and. (n.eq.0 .or. n.eq.nmax)) cycle
111
112 IF (mntot .ge. itotal) EXIT
113
114 mntot = mntot+1
115
116 csmn = cosmu(i,m)*sinnv(j,n)
117 scmn = sinmu(i,m)*cosnv(j,n)
118 termcc =-dm*scmn - dn*csmn
119 termss = dm*csmn + dn*scmn
120
121 IF ((n.eq.0 .or. n.eq.nmax) .or. (m.eq.0 .or. m.eq.mmax)) THEN
122 ! ONLY bcc != 0 for m=0 or mmax
123 amatrix(ijtot,mntot) = termcc
124 ELSE
125 amatrix(ijtot,mntot) = termcc
126 mntot = mntot+1
127 amatrix(ijtot,mntot) = termss
128 END IF
129
130 end if ! lasym
131
132 END DO ! n
133 END DO ! m
134 END DO ! nzeta
135 END DO ! ntheta3
136
137 save_matrix = amatrix
138
139 info = -1
140 IF (ijtot .ne. itotal .or. mntot .ne. itotal) THEN
141 print *,' itotal = ', itotal,' ijtot = ', ijtot, ' mntot = ', mntot
142 print *,' ntheta3: ',ntheta3,' nzeta: ', nzeta, ' mnyq: ', mmax,' nnyq: ', nmax
143 GOTO 200
144 ELSE
145 CALL solver (amatrix, brhs, itotal, 1, info)
146 IF (info .ne. 0) GOTO 200
147 END IF
148
149 ! CHECK SOLUTION FROM SOLVER
150
151 ! GOTO 100 ! comment this in to skip below test
152
153 ijtot = 0
154 DO i = 1, ntheta3
155 DO j = 1, nzeta
156 lpior0 = ((i.eq.1 .or. i.eq.ntheta2) .and. (j.gt.nzeta/2+1))
157 IF (lpior0 .and. .not.lasym) cycle
158
159 ijtot = ijtot + 1
160
161 amn = sum(save_matrix(ijtot,:)*brhs(:))
162
163 IF (abs(amn) .lt. 1.e-12_dp) cycle
164 IF (abs(frho(j,i) - amn) .gt. 1.e-8_dp*abs(amn)) THEN
165 print 50,'In GETbsubs, i = ',i,' j = ',j, ' Original force = ', frho(j,i),' Final force = ', amn
166 END IF
167 END DO
168 END DO
169 50 FORMAT(a,i5,a,i5,a,1p,e10.3,a,1p,e10.3)
170
171! 100 CONTINUE ! comment this in to skip above test
172
173 ! CONVERT BACK TO BS*SIN(MU - NV) REPRESENTATION
174 ! AND (FOR lasym) BC*COS(MU - NV)
175
176 bsubsmn = 0
177
178 mntot = 0
179 DO m = 0, mmax
180 DO n = 0, nmax
181 IF (mntot .ge. itotal) EXIT
182 IF (m.eq.0 .and. n.eq.0 .and. lasym) cycle
183
184 mntot = mntot+1
185
186 IF (n.eq.0 .or. n.eq.nmax) THEN
187 IF (m .gt. 0) THEN
188 bsubsmn(m,n,0) = brhs(mntot)
189 ELSE IF (n .eq. 0) THEN
190 bsubsmn(m,n,0) = brhs(mntot)
191 ELSE
192 bsubsmn(m,-n,0) = brhs(mntot)
193 END IF
194 ELSE IF (m.eq.0 .or. m.eq.mmax) THEN
195 bsubsmn(m,-n,0) = brhs(mntot)
196 ELSE
197 bsubsmn(m,n,0) = brhs(mntot)
198 mntot = mntot+1
199 bsubsmn(m,-n,0) = brhs(mntot)
200 END IF
201
202 IF (lasym) then
203 IF (m.eq.0 .and. (n.eq.0 .or. n.eq.nmax)) cycle
204 IF (mntot .ge. itotal) EXIT
205
206 mntot = mntot+1
207
208 IF ((n.eq.0 .or. n.eq.nmax) .or. (m.eq.0 .or. m.eq.mmax)) THEN
209 bsubsmn(m,n,1) = brhs(mntot)
210 ELSE
211 bsubsmn(m,n,1) = brhs(mntot)
212 mntot = mntot+1
213 bsubsmn(m,-n,1)= brhs(mntot)
214 END IF
215 end if ! lasym
216
217 END DO ! n
218 END DO ! m
219
220 IF (mntot .ne. ijtot) info = -2
221
222200 CONTINUE ! error
223
224 DEALLOCATE (amatrix, save_matrix, brhs)
225
226END SUBROUTINE getbsubs
subroutine getbsubs(bsubsmn, frho, bsupu, bsupv, mmax, nmax, info)
Solves the radial force balance for in real space using collocation.
Definition getbsubs.f90:14
integer ntheta3
effective number of poloidal grid points
Definition vmec_dim.f90:11
integer ntheta2
Definition vmec_dim.f90:10
logical lasym
integer nfp
integer nzeta
real(rprec), dimension(:,:), allocatable cosmu
real(rprec), dimension(:,:), allocatable sinmu
real(rprec), dimension(:,:), allocatable sinnv
real(rprec), dimension(:,:), allocatable cosnv
subroutine solver(amat, b, m, nrhs, info)
Solve a linear system of equations using dgesv.
Definition solver.f90:12