V3FIT
tomnsp_mod.f
1  MODULE tomnsp_mod
2  USE timer_sub
3  IMPLICIT NONE
4 
5  CONTAINS
6 
7  SUBROUTINE tomnsps_par(frzl_array, armn, brmn, crmn, azmn,
8  & bzmn, czmn, blmn, clmn, arcon, azcon)
9  USE realspace, ONLY: wint, phip
10  USE vmec_main, p5 => cp5
11  USE vmec_params, ONLY: jlam, jmin2, ntmax, rcc, rss, zsc, zcs,
12  & nscale
13  USE fbal, ONLY: rru_fac, rzu_fac, frcc_fac, fzsc_fac
14  USE precon2d, ONLY: ictrl_prec2d
15  USE parallel_include_module
16  USE xstuff
17 !-----------------------------------------------
18 ! D u m m y A r g u m e n t s
19 !-----------------------------------------------
20  REAL(dp), DIMENSION(0:ntor,0:mpol1,ns,3*ntmax),
21  & TARGET, INTENT(out) :: frzl_array
22  REAL(dp), DIMENSION(nzeta,ntheta3,ns,0:1), INTENT(INout) ::
23  & armn, brmn, crmn, azmn, bzmn, czmn, blmn, clmn, arcon, azcon
24 !-----------------------------------------------
25 ! L o c a l V a r i a b l e s
26 !-----------------------------------------------
27  INTEGER, PARAMETER :: m0 = 0, m1 = 1, n0 = 0
28  INTEGER :: jmax, m, mparity, i, n, k, l, nsz
29  INTEGER :: ioff, joff, mj, ni, nsl, j2, j2l, jl, jll, jmaxl
30  REAL(dp), DIMENSION(:,:,:), POINTER ::
31  & frcc, frss, fzcs, fzsc, flcs, flsc
32  REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: work1
33  REAL(dp), DIMENSION(:,:), ALLOCATABLE :: tempr, tempz
34  REAL(dp) :: t1
35  INTEGER :: j, nsmin, nsmax, ub1, lb1, ub2, lb2, js
36 !-----------------------------------------------
37  CALL second0 (tffton)
38 
39  frcc => frzl_array(:,:,:,rcc) !!COS(mu) COS(nv)
40  fzsc => frzl_array(:,:,:,zsc+ntmax) !!SIN(mu) COS(nv)
41  flsc => frzl_array(:,:,:,zsc+2*ntmax) !!SIN(mu) COS(nv)
42  IF (lthreed) THEN
43  frss => frzl_array(:,:,:,rss) !!SIN(mu) SIN(nv)
44  fzcs => frzl_array(:,:,:,zcs+ntmax) !!COS(mu) SIN(nv)
45  flcs => frzl_array(:,:,:,zcs+2*ntmax) !!COS(mu) SIN(nv)
46  END IF
47 
48  nsz = ns*nzeta
49 
50  nsmin = tlglob
51  nsmax = trglob
52 
53  ALLOCATE (work1(12,nzeta,nsmin:nsmax), stat=i)
54  ALLOCATE (tempr(nzeta,nsmin:nsmax), stat=i)
55  ALLOCATE (tempz(nzeta,nsmin:nsmax), stat=i)
56  IF (i .ne. 0) THEN
57  stop 'Allocation error in VMEC2000 tomnsps'
58  END IF
59 
60  ioff = lbound(frcc,1)
61  joff = lbound(frcc,2)
62 
63  jmax = ns
64  IF (ivac .LT. 1) THEN
65  jmax = ns1
66  END IF
67 
68 !
69 ! BEGIN FOURIER TRANSFORM
70 !
71 ! FRmn = ARmn - d(BRmn)/du + d(CRmn)/dv
72 ! FZmn = AZmn - d(BZmn)/du + d(CZmn)/dv
73 ! FLmn = - d(BLmn)/du + d(CLmn)/dv
74 !
75 ! NOTE: sinmumi = -m sin(mu), sinnvn = -n sin(nv)
76 !
77  DO js = nsmin, nsmax
78  frzl_array(:,:,js,:) = 0
79  DO m = 0, mpol1
80  mparity = mod(m,2)
81  work1(:,:,js) = 0
82 
83 ! DO THETA (U) INTEGRATION FIRST ON HALF INTERVAL (0 < U < PI)
84  DO i = 1, ntheta2
85  DO k = 1, nzeta
86  tempr(k,js) = armn(k,i,js,mparity)
87 #ifndef _HBANGLE
88  & + xmpq(m,1)*arcon(k,i,js,mparity)
89 #endif
90  tempz(k,js) = azmn(k,i,js,mparity)
91 #ifndef _HBANGLE
92  & + xmpq(m,1)*azcon(k,i,js,mparity)
93 #endif
94  work1(1,k,js) = work1(1,k,js)
95  & + tempr(k,js)*cosmui(i,m)
96  & + brmn(k,i,js,mparity)*sinmumi(i,m)
97  work1(7,k,js) = work1(7,k,js)
98  & + tempz(k,js)*sinmui(i,m)
99  & + bzmn(k,i,js,mparity)*cosmumi(i,m)
100  work1(11,k,js) = work1(11,k,js)
101  & + blmn(k,i,js,mparity)*cosmumi(i,m)
102 
103  IF (.NOT.lthreed) cycle
104 
105  work1(2,k,js) = work1(2,k,js)
106  & - crmn(k,i,js,mparity)*cosmui(i,m)
107  work1(3,k,js) = work1(3,k,js)
108  & + tempr(k,js)*sinmui(i,m)
109  & + brmn(k,i,js,mparity)*cosmumi(i,m)
110  work1(4,k,js) = work1(4,k,js)
111  & - crmn(k,i,js,mparity)*sinmui(i,m)
112  work1(5,k,js) = work1(5,k,js)
113  & + tempz(k,js)*cosmui(i,m)
114  & + bzmn(k,i,js,mparity)*sinmumi(i,m)
115  work1(6,k,js) = work1(6,k,js)
116  & - czmn(k,i,js,mparity)*cosmui(i,m)
117  work1(8,k,js) = work1(8,k,js)
118  & - czmn(k,i,js,mparity)*sinmui(i,m)
119  work1(9,k,js) = work1(9,k,js)
120  & + blmn(k,i,js,mparity)*sinmumi(i,m)
121  work1(10,k,js) = work1(10,k,js)
122  & - clmn(k,i,js,mparity)*cosmui(i,m)
123  work1(12,k,js) = work1(12,k,js)
124  & - clmn(k,i,js,mparity)*sinmui(i,m)
125  END DO
126  END DO
127 
128 !
129 ! NEXT, DO ZETA (V) TRANSFORM
130  mj = m + joff
131  j2 = jmin2(m)
132  jl = jlam(m)
133 
134  lb1 = max(tlglob,j2)
135  ub1 = min(trglob,jmax)
136  lb2 = max(tlglob,jl)
137  ub2 = trglob
138 
139 
140  DO n = 0, ntor
141  ni = n+ioff
142  DO k = 1, nzeta
143 
144  IF (lb1 .LE. js .AND. js .LE. ub1) THEN
145  frcc(ni,mj,js) = frcc(ni,mj,js)
146  & + work1(1,k,js)*cosnv(k,n)
147 
148  fzsc(ni,mj,js) = fzsc(ni,mj,js)
149  & + work1(7,k,js)*cosnv(k,n)
150  END IF
151 
152  IF (lb2 .LE. js .AND. js .LE. ub2) THEN
153  flsc(ni,mj,js) = flsc(ni,mj,js)
154  & + work1(11,k,js)*cosnv(k,n)
155  END IF
156 
157  IF (.NOT.lthreed) cycle
158 
159  IF (lb1 .LE. js .AND. js .LE. ub1) THEN
160  frcc(ni,mj,js) = frcc(ni,mj,js)
161  & + work1(2,k,js)*sinnvn(k,n)
162 
163  fzsc(ni,mj,js) = fzsc(ni,mj,js)
164  & + work1(8,k,js)*sinnvn(k,n)
165 
166  frss(ni,mj,js) = frss(ni,mj,js)
167  & + work1(3,k,js)*sinnv(k,n)
168  & + work1(4,k,js)*cosnvn(k,n)
169 
170  fzcs(ni,mj,js) = fzcs(ni,mj,js)
171  & + work1(5,k,js)*sinnv(k,n)
172  & + work1(6,k,js)*cosnvn(k,n)
173  END IF
174 
175  IF (lb2 .LE. js .AND. js .LE. ub2) THEN
176  flsc(ni,mj,js) = flsc(ni,mj,js)
177  & + work1(12,k,js)*sinnvn(k,n)
178 
179  flcs(ni,mj,js) = flcs(ni,mj,js)
180  & + work1(9,k,js)*sinnv(k,n)
181  & + work1(10,k,js)*cosnvn(k,n)
182  END IF
183  END DO
184  END DO
185  END DO
186  END DO
187 
188 !
189 ! COMPUTE IOTA EVOLUTION EQUATION [STORED IN LMNSC(0,0) COMPONENT]
190 !
191 !SPH071017
192 #if defined(CHI_FORCE)
193  IF (ictrl_prec2d .NE. 0 .AND. ncurr .EQ. 1) THEN
194  ni = n0 + ioff
195  mj = m0 + joff
196  t1 = r0scale
197  nsmin = max(2,tlglob)
198  nsmax = trglob
199  DO js = nsmin, nsmax
200  flsc(ni, mj, js) = -t1*(buco(js) - icurv(js))
201  END DO
202  END IF
203 #endif
204 !
205 ! MAKE R,Z(m=1,n=0) SATISFY AVERAGE FORCE BALANCE EXACTLY
206 ! NOTE: for m=1, FR ~ Z1*(f0 + f2), FZ ~ R1*(f0 - f2), WHERE
207 ! f0 is the m=0 component of frho, f2 is m=2 component.
208  IF (lforbal) THEN
209  ni = m0 + ioff
210  mj = m1 + joff
211  t1 = nscale(n0)*r0scale !/4 !!v8.52
212  nsmin = max(2,tlglob)
213  nsmax = min(trglob,ns-1)
214  DO jl = nsmin, nsmax
215  DO k = 1, nzeta
216  work1(k,1,jl) = frcc_fac(jl)*frcc(ni,mj,jl)
217  & + fzsc_fac(jl)*fzsc(ni,mj,jl)
218  frcc(ni,mj,jl) = rzu_fac(jl)*(t1*equif(jl)
219  & + work1(k,1,jl))
220  fzsc(ni,mj,jl) = rru_fac(jl)*(t1*equif(jl)
221  & - work1(k,1,jl))
222  END DO
223  END DO
224  END IF
225 
226  DEALLOCATE (work1, tempr, tempz)
227 
228  CALL second0 (tfftoff)
229  tomnsps_time = tomnsps_time + (tfftoff - tffton)
230  timer(tffi) = timer(tffi) + (tfftoff - tffton)
231 
232  END SUBROUTINE tomnsps_par
233 
234  SUBROUTINE tomnspa_par(frzl_array, armn, brmn, crmn, azmn, bzmn,
235  & czmn, blmn, clmn, arcon, azcon)
236  USE vmec_main
237  USE vmec_params, ONLY: jlam, jmin2, ntmax, rsc, rcs, zcc, zss
238  USE parallel_include_module
239 !-----------------------------------------------
240 ! D u m m y A r g u m e n t s
241 !-----------------------------------------------
242  REAL(dp), DIMENSION(0:ntor,0:mpol1,ns,3*ntmax),
243  & TARGET, INTENT(inout) :: frzl_array
244  REAL(dp), DIMENSION(nzeta,ntheta3,ns,0:1), INTENT(in) ::
245  & armn, brmn, crmn, azmn, bzmn, czmn, blmn, clmn, arcon, azcon
246 !-----------------------------------------------
247 ! L o c a l V a r i a b l e s
248 !-----------------------------------------------
249  INTEGER :: jmax, m, mparity, i, n, k, l
250  INTEGER :: ioff, joff, mj, ni, nsl, j2, j2l, jl, jll, jmaxl
251  REAL(dp), DIMENSION(:,:,:), POINTER ::
252  & frcs, frsc, fzcc, fzss, flcc, flss
253 ! REAL(dp), DIMENSION(ns*nzeta) :: temp1, temp3
254  REAL(dp), DIMENSION(:,:), ALLOCATABLE :: temp1, temp3
255  REAL(dp), DIMENSION(:,:,:), ALLOCATABLE :: work1
256  INTEGER :: j, nsmin, nsmax, ub1, lb1, ub2, lb2, js
257 !-----------------------------------------------
258  CALL second0(tffton)
259 
260  frsc => frzl_array(:,:,:,rsc) !!R-SIN(mu) COS(nv)
261  fzcc => frzl_array(:,:,:,zcc+ntmax) !!Z-COS(mu) COS(nv)
262  flcc => frzl_array(:,:,:,zcc+2*ntmax) !!L-COS(mu) COS(nv)
263  IF (lthreed) THEN
264  frcs => frzl_array(:,:,:,rcs) !!R-COS(mu) SIN(nv)
265  fzss => frzl_array(:,:,:,zss+ntmax) !!Z-SIN(mu) SIN(nv)
266  flss => frzl_array(:,:,:,zss+2*ntmax) !!L-SIN(mu) SIN(nv)
267  END IF
268 
269  nsmin = tlglob
270  nsmax = trglob
271  ALLOCATE (work1(12,nzeta,nsmin:nsmax),
272  & temp1(nzeta,nsmin:nsmax),
273  & temp3(nzeta,nsmin:nsmax), stat=i)
274  IF (i .NE. 0) THEN
275  stop 'Allocation error in VMEC tomnspa'
276  END IF
277 
278  ioff = lbound(frsc,1)
279  joff = lbound(frsc,2)
280 
281  jmax = ns
282  IF (ivac .LT. 1) THEN
283  jmax = ns1
284  END IF
285 
286 !
287 ! BEGIN FOURIER TRANSFORM
288 !
289  DO js = nsmin, nsmax
290  DO m = 0, mpol1
291  mparity = mod(m,2)
292  mj = m + joff
293  j2 = jmin2(m)
294  jl = jlam(m)
295  work1(:,:,js) = 0
296 !
297 ! DO THETA (U) TRANSFORM FIRST
298 !
299  DO i = 1, ntheta2
300  DO k = 1, nzeta
301  temp1(k,js) = armn(k,i,js,mparity)
302 #ifndef _HBANGLE
303  & + xmpq(m,1)*arcon(k,i,js,mparity)
304 #endif
305  temp3(k,js) = azmn(k,i,js,mparity)
306 #ifndef _HBANGLE
307  & + xmpq(m,1)*azcon(k,i,js,mparity)
308 #endif
309  work1(3,k,js) = work1(3,k,js)
310  & + temp1(k,js)*sinmui(i,m)
311  & + brmn(k,i,js,mparity)*cosmumi(i,m)
312  work1(5,k,js) = work1(5,k,js)
313  & + temp3(k,js)*cosmui(i,m)
314  & + bzmn(k,i,js,mparity)*sinmumi(i,m)
315  work1(9,k,js) = work1(9,k,js)
316  & + blmn(k,i,js,mparity)*sinmumi(i,m)
317 
318  IF (.not.lthreed) cycle
319 
320  work1(1,k,js) = work1(1,k,js)
321  & + temp1(k,js)*cosmui(i,m)
322  & + brmn(k,i,js,mparity)*sinmumi(i,m)
323  work1(2,k,js) = work1(2,k,js)
324  & - crmn(k,i,js,mparity)*cosmui(i,m)
325  work1(4,k,js) = work1(4,k,js)
326  & - crmn(k,i,js,mparity)*sinmui(i,m)
327  work1(6,k,js) = work1(6,k,js)
328  & - czmn(k,i,js,mparity)*cosmui(i,m)
329  work1(7,k,js) = work1(7,k,js)
330  & + temp3(k,js)*sinmui(i,m)
331  & + bzmn(k,i,js,mparity)*cosmumi(i,m)
332  work1(8,k,js) = work1(8,k,js)
333  & - czmn(k,i,js,mparity)*sinmui(i,m)
334  work1(10,k,js) = work1(10,k,js)
335  & - clmn(k,i,js,mparity)*cosmui(i,m)
336  work1(11,k,js) = work1(11,k,js)
337  & + blmn(k,i,js,mparity)*cosmumi(i,m)
338  work1(12,k,js) = work1(12,k,js)
339  & - clmn(k,i,js,mparity)*sinmui(i,m)
340  END DO
341  END DO
342 !
343 ! NEXT, DO ZETA (V) TRANSFORM
344 !
345 
346  lb1 = max(tlglob,j2)
347  ub1 = min(trglob,jmax)
348  lb2 = max(tlglob,jl)
349  ub2 = trglob
350 
351  DO n = 0, ntor
352  ni = n + ioff
353  DO k = 1, nzeta
354 
355  IF (lb1 .LE. js .AND. js .LE. ub1) THEN
356  frsc(ni,mj,js) = frsc(ni,mj,js)
357  & + work1(3,k,js)*cosnv(k,n)
358  fzcc(ni,mj,js) = fzcc(ni,mj,js)
359  & + work1(5,k,js)*cosnv(k,n)
360  END IF
361 
362  IF (lb2 .LE. js .AND. js .LE. ub2) THEN
363  flcc(ni,mj,js) = flcc(ni,mj,js)
364  & + work1(9,k,js)*cosnv(k,n)
365  END IF
366 
367  IF (.not.lthreed) cycle
368 
369  IF (lb1 .LE. js .AND. js .LE. ub1) THEN
370  frsc(ni,mj,js) = frsc(ni,mj,js)
371  & + work1(4,k,js)*sinnvn(k,n)
372  fzcc(ni,mj,js) = fzcc(ni,mj,js)
373  & + work1(6,k,js)*sinnvn(k,n)
374  frcs(ni,mj,js) = frcs(ni,mj,js)
375  & + work1(1,k,js)*sinnv(k,n)
376  & + work1(2,k,js)*cosnvn(k,n)
377  fzss(ni,mj,js) = fzss(ni,mj,js)
378  & + work1(7,k,js)*sinnv(k,n)
379  & + work1(8,k,js)*cosnvn(k,n)
380  END IF
381 
382  IF (lb2 .LE. js .AND. js .LE. ub2) THEN
383  flcc(ni,mj,js) = flcc(ni,mj,js)
384  & + work1(10,k,js)*sinnvn(k,n)
385  flss(ni,mj,js) = flss(ni,mj,js)
386  & + work1(11,k,js)*sinnv(k,n)
387  & + work1(12,k,js)*cosnvn(k,n)
388  END IF
389  END DO
390  END DO
391  END DO
392  END DO
393 
394 ! IF THE SYMMETRIZED MODE USED, NEED EXTRA FACTOR OF 2
395 ! IF ntheta3 USED INSTEAD OF ntheta3, DO NOT NEED THIS FACTOR
396 ! frzl_array(:,:,nsmin:nsmax,:) = 2*frzl_array(:,:,nsmin:nsmax,:)
397 
398  DEALLOCATE (work1, temp1, temp3)
399  CALL second0(tfftoff)
400  tomnspa_time = tomnspa_time + (tfftoff - tffton)
401  timer(tffi) = timer(tffi) + (tfftoff - tffton)
402 
403  END SUBROUTINE tomnspa_par
404 
405  SUBROUTINE tomnsps(frzl_array, armn, brmn, crmn, azmn,
406  1 bzmn, czmn, blmn, clmn, arcon, azcon)
407  USE realspace, ONLY: wint, phip
408  USE vmec_main, p5 => cp5
409  USE vmec_params, ONLY: jlam, jmin2, ntmax, rcc, rss, zsc, zcs,
410  1 nscale
411  USE fbal, ONLY: rru_fac, rzu_fac, frcc_fac, fzsc_fac
412  USE precon2d, ONLY: ictrl_prec2d
413 !-----------------------------------------------
414 ! D u m m y A r g u m e n t s
415 !-----------------------------------------------
416  REAL(dp), DIMENSION(ns,0:ntor,0:mpol1,3*ntmax),
417  1 TARGET, INTENT(out) :: frzl_array
418  REAL(dp), DIMENSION(ns*nzeta*ntheta3,0:1), INTENT(in) ::
419  1 armn, brmn, crmn, azmn, bzmn, czmn, blmn, clmn, arcon, azcon
420 !-----------------------------------------------
421 ! L o c a l V a r i a b l e s
422 !-----------------------------------------------
423  INTEGER :: jmax, m, mparity, i, n, k, l, nsz
424  INTEGER :: ioff, joff, mj, ni, nsl, j2, j2l, jl, jll, jmaxl
425  REAL(dp), DIMENSION(:,:,:), POINTER ::
426  1 frcc, frss, fzcs, fzsc, flcs, flsc
427  REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: work1
428  REAL(dp), DIMENSION(:), ALLOCATABLE :: tempr, tempz
429  REAL(dp) :: t1
430 !-----------------------------------------------
431  frcc => frzl_array(:,:,:,rcc) !!COS(mu) COS(nv)
432  fzsc => frzl_array(:,:,:,zsc+ntmax) !!SIN(mu) COS(nv)
433  flsc => frzl_array(:,:,:,zsc+2*ntmax) !!SIN(mu) COS(nv)
434  IF (lthreed) THEN
435  frss => frzl_array(:,:,:,rss) !!SIN(mu) SIN(nv)
436  fzcs => frzl_array(:,:,:,zcs+ntmax) !!COS(mu) SIN(nv)
437  flcs => frzl_array(:,:,:,zcs+2*ntmax) !!COS(mu) SIN(nv)
438  END IF
439 
440  nsz = ns*nzeta
441 
442  ALLOCATE (work1(nsz,12), tempr(nsz), tempz(nsz),
443  1 stat=i)
444  IF (i .ne. 0) THEN
445  stop 'Allocation error in VMEC2000 tomnsps'
446  END IF
447 
448  ioff = lbound(frcc,2)
449  joff = lbound(frcc,3)
450 
451  frzl_array = 0
452 
453  jmax = ns
454  IF (ivac .lt. 1) THEN
455  jmax = ns1
456  END IF
457 
458 !
459 ! BEGIN FOURIER TRANSFORM
460 !
461 ! FRmn = ARmn - d(BRmn)/du + d(CRmn)/dv
462 ! FZmn = AZmn - d(BZmn)/du + d(CZmn)/dv
463 ! FLmn = - d(BLmn)/du + d(CLmn)/dv
464 !
465 ! NOTE: sinmumi = -m sin(mu), sinnvn = -n sin(nv)
466 !
467  DO m = 0, mpol1
468  mparity = mod(m,2)
469  work1 = 0
470 ! DO THETA (U) INTEGRATION FIRST ON HALF INTERVAL (0 < U < PI)
471 !
472  l = 0
473  DO i = 1, ntheta2
474  jll = l + 1
475  nsl = nsz + l
476  l = l + nsz
477  tempr(:) = armn(jll:nsl,mparity)
478 #ifndef _HBANGLE
479  & + xmpq(m,1)*arcon(jll:nsl,mparity)
480 #endif
481  tempz(:) = azmn(jll:nsl,mparity)
482 #ifndef _HBANGLE
483  & + xmpq(m,1)*azcon(jll:nsl,mparity)
484 #endif
485  work1(:,1) = work1(:,1) + tempr(:)*cosmui(i,m)
486  & + brmn(jll:nsl,mparity)*sinmumi(i,m)
487  work1(:,7) = work1(:,7) + tempz(:)*sinmui(i,m)
488  & + bzmn(jll:nsl,mparity)*cosmumi(i,m)
489  work1(:,11)= work1(:,11)+ blmn(jll:nsl,mparity)*cosmumi(i,m)
490 
491  IF (.not.lthreed) cycle
492 
493  work1(:,2) = work1(:,2) - crmn(jll:nsl,mparity)*cosmui(i,m)
494  work1(:,3) = work1(:,3) + tempr(:)*sinmui(i,m)
495  & + brmn(jll:nsl,mparity)*cosmumi(i,m)
496  work1(:,4) = work1(:,4) - crmn(jll:nsl,mparity)*sinmui(i,m)
497  work1(:,5) = work1(:,5) + tempz(:)*cosmui(i,m)
498  & + bzmn(jll:nsl,mparity)*sinmumi(i,m)
499  work1(:,6) = work1(:,6) - czmn(jll:nsl,mparity)*cosmui(i,m)
500  work1(:,8) = work1(:,8) - czmn(jll:nsl,mparity)*sinmui(i,m)
501 
502  work1(:,9) = work1(:,9) + blmn(jll:nsl,mparity)*sinmumi(i,m)
503  work1(:,10) =work1(:,10)- clmn(jll:nsl,mparity)*cosmui(i,m)
504  work1(:,12) =work1(:,12)- clmn(jll:nsl,mparity)*sinmui(i,m)
505  END DO
506 
507 !
508 ! NEXT, DO ZETA (V) TRANSFORM
509  mj = m + joff
510  j2 = jmin2(m)
511  jl = jlam(m)
512 
513  DO n = 0, ntor
514  ni = n+ioff
515  l = 0
516  DO k = 1, nzeta
517  j2l = j2 + l
518  jmaxl = jmax + l
519  jll = jl + l
520  nsl = ns + l
521  l = l + ns
522  frcc(j2:jmax,ni,mj) = frcc(j2:jmax,ni,mj)
523  & + work1(j2l:jmaxl,1)*cosnv(k,n)
524  fzsc(j2:jmax,ni,mj) = fzsc(j2:jmax,ni,mj)
525  & + work1(j2l:jmaxl,7)*cosnv(k,n)
526  flsc(jl:ns,ni,mj) = flsc(jl:ns,ni,mj)
527  & + work1(jll:nsl,11)*cosnv(k,n)
528 
529  IF (.not.lthreed) cycle
530 
531  frcc(j2:jmax,ni,mj) = frcc(j2:jmax,ni,mj)
532  & + work1(j2l:jmaxl,2)*sinnvn(k,n)
533  fzsc(j2:jmax,ni,mj) = fzsc(j2:jmax,ni,mj)
534  & + work1(j2l:jmaxl,8)*sinnvn(k,n)
535  frss(j2:jmax,ni,mj) = frss(j2:jmax,ni,mj)
536  & + work1(j2l:jmaxl,3)*sinnv(k,n)
537  & + work1(j2l:jmaxl,4)*cosnvn(k,n)
538  fzcs(j2:jmax,ni,mj) = fzcs(j2:jmax,ni,mj)
539  & + work1(j2l:jmaxl,5)*sinnv(k,n)
540  & + work1(j2l:jmaxl,6)*cosnvn(k,n)
541 
542  flsc(jl:ns,ni,mj) = flsc(jl:ns,ni,mj)
543  & + work1(jll:nsl,12)*sinnvn(k,n)
544  flcs(jl:ns,ni,mj) = flcs(jl:ns,ni,mj)
545  & + work1(jll:nsl,9)*sinnv(k,n)
546  & + work1(jll:nsl,10)*cosnvn(k,n)
547  END DO
548  END DO
549  END DO
550 
551 !
552 ! COMPUTE IOTA EVOLUTION EQUATION [STORED IN LMNSC(0,0) COMPONENT]
553 !
554 #if defined(CHI_FORCE)
555  IF (ictrl_prec2d.gt.0 .and. ncurr.eq.1) THEN
556  ni = 0 + ioff
557  mj = 0 + joff
558  t1 = r0scale
559  DO jl = 2, ns
560  flsc(jl, ni, mj) = -t1*(buco(jl) - icurv(jl))
561  END DO
562  END IF
563 #endif
564 !
565 ! MAKE R,Z(m=1,n=0) SATISFY AVERAGE FORCE BALANCE EXACTLY
566 ! NOTE: for m=1, FR ~ Z1*(f0 + f2), FZ ~ R1*(f0 - f2), WHERE
567 ! f0 is the m=0 component of frho, f2 is m=2 component.
568  IF (lforbal) THEN
569  mj = 1 + joff
570  ni = 0 + ioff
571  t1 = nscale(0)*r0scale !/4 !!v8.52
572  DO jl = 2, ns - 1
573  work1(jl,1) = frcc_fac(jl)*frcc(jl,ni,mj)
574  & + fzsc_fac(jl)*fzsc(jl,ni,mj)
575  frcc(jl,ni,mj) = rzu_fac(jl)*(t1*equif(jl) + work1(jl,1))
576  fzsc(jl,ni,mj) = rru_fac(jl)*(t1*equif(jl) - work1(jl,1))
577  END DO
578  END IF
579 
580  DEALLOCATE (work1, tempr, tempz)
581 
582  END SUBROUTINE tomnsps
583 
584  SUBROUTINE tomnspa(frzl_array, armn, brmn, crmn, azmn, bzmn,
585  & czmn, blmn, clmn, arcon, azcon)
586  USE vmec_main
587  USE vmec_params, ONLY: jlam, jmin2, ntmax, rsc, rcs, zcc, zss
588 !-----------------------------------------------
589 ! D u m m y A r g u m e n t s
590 !-----------------------------------------------
591  REAL(dp), DIMENSION(ns,0:ntor,0:mpol1,3*ntmax),
592  & TARGET, INTENT(inout) :: frzl_array
593  REAL(dp), DIMENSION(ns*nzeta,ntheta3,0:1), INTENT(in) ::
594  & armn, brmn, crmn, azmn, bzmn, czmn, blmn, clmn, arcon, azcon
595 !-----------------------------------------------
596 ! L o c a l V a r i a b l e s
597 !-----------------------------------------------
598  INTEGER :: jmax, m, mparity, i, n, k, l
599  INTEGER :: ioff, joff, mj, ni, nsl, j2, j2l, jl, jll, jmaxl
600  REAL(dp), DIMENSION(:,:,:), POINTER ::
601  & frcs, frsc, fzcc, fzss, flcc, flss
602  REAL(dp), DIMENSION(ns*nzeta) :: temp1, temp3
603  REAL(dp), DIMENSION(:,:), ALLOCATABLE :: work1
604 !-----------------------------------------------
605  frsc => frzl_array(:,:,:,rsc) !!R-SIN(mu) COS(nv)
606  fzcc => frzl_array(:,:,:,zcc+ntmax) !!Z-COS(mu) COS(nv)
607  flcc => frzl_array(:,:,:,zcc+2*ntmax) !!L-COS(mu) COS(nv)
608  IF (lthreed) THEN
609  frcs => frzl_array(:,:,:,rcs) !!R-COS(mu) SIN(nv)
610  fzss => frzl_array(:,:,:,zss+ntmax) !!Z-SIN(mu) SIN(nv)
611  flss => frzl_array(:,:,:,zss+2*ntmax) !!L-SIN(mu) SIN(nv)
612  END IF
613 
614  ALLOCATE (work1(ns*nzeta,12), stat=i)
615  IF (i .ne. 0) THEN
616  stop 'Allocation error in VMEC tomnspa'
617  END IF
618 
619  ioff = lbound(frsc,2)
620  joff = lbound(frsc,3)
621 
622  jmax = ns
623  IF (ivac .lt. 1) jmax = ns1
624 !
625 ! BEGIN FOURIER TRANSFORM
626 !
627  DO m = 0, mpol1
628  mparity = mod(m,2)
629  mj = m + joff
630  j2 = jmin2(m)
631  jl = jlam(m)
632  work1 = 0
633 !
634 ! DO THETA (U) TRANSFORM FIRST
635 !
636  DO i = 1, ntheta2
637  temp1(:) = armn(:,i,mparity)
638 #ifndef _HBANGLE
639  & + xmpq(m,1)*arcon(:,i,mparity)
640 #endif
641  temp3(:) = azmn(:,i,mparity)
642 #ifndef _HBANGLE
643  & + xmpq(m,1)*azcon(:,i,mparity)
644 #endif
645  work1(:,3) = work1(:,3) + temp1(:)*sinmui(i,m)
646  & + brmn(:,i,mparity)*cosmumi(i,m)
647  work1(:,5) = work1(:,5) + temp3(:)*cosmui(i,m)
648  & + bzmn(:,i,mparity)*sinmumi(i,m)
649  work1(:,9) = work1(:,9) + blmn(:,i,mparity)*sinmumi(i,m)
650 
651  IF (.not.lthreed) cycle
652 
653  work1(:,1) = work1(:,1) + temp1(:)*cosmui(i,m)
654  & + brmn(:,i,mparity)*sinmumi(i,m)
655  work1(:,2) = work1(:,2) - crmn(:,i,mparity)*cosmui(i,m)
656  work1(:,4) = work1(:,4) - crmn(:,i,mparity)*sinmui(i,m)
657  work1(:,6) = work1(:,6) - czmn(:,i,mparity)*cosmui(i,m)
658  work1(:,7) = work1(:,7) + temp3(:)*sinmui(i,m)
659  & + bzmn(:,i,mparity)*cosmumi(i,m)
660  work1(:,8) = work1(:,8) - czmn(:,i,mparity)*sinmui(i,m)
661  work1(:,10) = work1(:,10) - clmn(:,i,mparity)*cosmui(i,m)
662  work1(:,11) = work1(:,11) + blmn(:,i,mparity)*cosmumi(i,m)
663  work1(:,12) = work1(:,12) - clmn(:,i,mparity)*sinmui(i,m)
664  END DO
665 !
666 ! NEXT, DO ZETA (V) TRANSFORM
667 !
668  DO n = 0, ntor
669  ni = n + ioff
670  DO k = 1, nzeta
671  l = ns*(k - 1)
672  j2l = j2 + l
673  jmaxl = jmax + l
674  jll = jl + l
675  nsl = ns + l
676  frsc(j2:jmax,ni,mj) = frsc(j2:jmax,ni,mj)
677  & + work1(j2l:jmaxl,3)*cosnv(k,n)
678  fzcc(j2:jmax,ni,mj) = fzcc(j2:jmax,ni,mj)
679  & + work1(j2l:jmaxl,5)*cosnv(k,n)
680  flcc(jl:ns,ni,mj) = flcc(jl:ns,ni,mj)
681  & + work1(jll:nsl,9)*cosnv(k,n)
682 
683  IF (.not.lthreed) cycle
684 
685  frsc(j2:jmax,ni,mj) = frsc(j2:jmax,ni,mj)
686  & + work1(j2l:jmaxl,4)*sinnvn(k,n)
687  fzcc(j2:jmax,ni,mj) = fzcc(j2:jmax,ni,mj)
688  & + work1(j2l:jmaxl,6)*sinnvn(k,n)
689  frcs(j2:jmax,ni,mj) = frcs(j2:jmax,ni,mj)
690  & + work1(j2l:jmaxl,1)*sinnv(k,n)
691  & + work1(j2l:jmaxl,2)*cosnvn(k,n)
692  fzss(j2:jmax,ni,mj) = fzss(j2:jmax,ni,mj)
693  & + work1(j2l:jmaxl,7)*sinnv(k,n)
694  & + work1(j2l:jmaxl,8)*cosnvn(k,n)
695  flcc(jl:ns,ni,mj) = flcc(jl:ns,ni,mj)
696  & + work1(jll:nsl,10)*sinnvn(k,n)
697  flss(jl:ns,ni,mj) = flss(jl:ns,ni,mj)
698  & + work1(jll:nsl,11)*sinnv(k,n)
699  & + work1(jll:nsl,12)*cosnvn(k,n)
700  END DO
701  END DO
702  END DO
703 
704 ! IF THE SYMMETRIZED MODE USED, NEED EXTRA FACTOR OF 2
705 ! IF ntheta3 USED INSTEAD OF ntheta3, DO NOT NEED THIS FACTOR
706 ! frzl_array = 2*frzl_array
707 
708  DEALLOCATE (work1)
709 
710  END SUBROUTINE tomnspa
711 
712  END MODULE tomnsp_mod