VMEC 8.52
3D Equilibrium solver with nested flux surfaces.
Loading...
Searching...
No Matches
vmec.f90
Go to the documentation of this file.
1
3
5PROGRAM xvmec
6
7 implicit none
8
9 call vmec
10
11end program xvmec
12
14subroutine vmec
15
16 USE vmec_input
18 USE vparams, ONLY: nthreed
19 USE vmec_params
20 USE vmec_main
21 use mgrid_mod, only: free_mgrid
22 use xstuff, only: xc, scalxc
23
24 use dbgout
25
26 IMPLICIT NONE
27
28 CHARACTER(LEN=*), PARAMETER :: bad_jacobian = "The jacobian was non-definite!"
29 CHARACTER(LEN=*), PARAMETER :: Warning = "Error deallocating global memory!"
30
31 CHARACTER(LEN=120), DIMENSION(10) :: command_arg
32 CHARACTER(LEN=120) :: arg
33 CHARACTER(LEN=120) :: input_file
34 INTEGER :: numargs
35 INTEGER :: ier_flag
36 INTEGER :: index_end
37 INTEGER :: iseq
38 INTEGER :: index_dat
39 INTEGER :: istat1
40 INTEGER :: ns_min
41 INTEGER :: nsval
42 INTEGER :: ns_old=0
43 INTEGER :: igrid
44 INTEGER :: jacob_off
45
46 integer :: i, js
47
48 ! Read in command-line arguments to get input file or sequence file,
49 ! screen display information, and restart information
50 numargs = iargc()
51 DO iseq = 1, numargs
52 CALL getarg(iseq, command_arg(iseq))
53 END DO
54
55 IF (numargs .lt. 1) THEN
56 stop 'Invalid command line'
57 ELSE IF (command_arg(1).eq.'-h' .or. command_arg(1).eq.'/h') THEN
58 ! print help text
59 print *,' ENTER INPUT FILE NAME OR INPUT-FILE SUFFIX ON COMMAND LINE'
60 print *
61 print *,' For example: '
62 print *,' xvmec input.tftr OR xvmec tftr OR xvmec ../input.tftr'
63
64 stop
65 END IF
66
67 ! PARSE input_file into path/input.ext
68 arg = command_arg(1)
69 index_dat = index(arg, '.') ! find position of '.'
70 index_end = len_trim(arg)
71 IF (index_dat .gt. 0) THEN
72 ! found '.' in arg
73 input_extension = arg(index_dat+1:index_end) ! extension is rest of arg after first '.'
74 input_file = trim(arg)
75 ELSE
76 ! no '.' found --> extension given directly
77 input_extension = trim(arg)
78 input_file = 'input.'//trim(input_extension)
79 END IF
80
81
82 ier_flag = norm_term_flag
83
84 ! initial reset of global counters for debugging output
85 vacuum_calls = 0
87 !profil3d_calls = 0
88 !funct3d_calls = 0
89
90 ! INITIALIZE PARAMETERS
91 CALL reset_params ! no further calls
92
93 ! READ INPUT FILE (INDATA NAMELIST), MGRID_FILE (VACUUM FIELD DATA)
94 CALL readin (input_file, ier_flag) ! calls read_indata, heading, read_mgrid, allocate_nunv (,flip_theta if required)
95
96 IF (ier_flag .eq. 0) then
97 ! reading of input file was successful, so start computation
98
99 ! COMPUTE NS-INVARIANT ARRAYS
100 CALL fixaray
101
102 ns_old = 0
103 delt0r = delt
104
105 WRITE (nthreed, 30)
10630 FORMAT(' FSQR, FSQZ = Normalized Physical Force Residuals',/, &
107 ' fsqr, fsqz = Preconditioned Force Residuals',/,1x,23('-'),/,&
108 ' BEGIN FORCE ITERATIONS',/,1x,23('-'),/)
109
110 do jacob_off = 0, 1
111 ! jacob_off=1 indicates that an initial run with ns=3 shall be inserted
112 ! before the user-provided ns values from ns_array are processed
113 ! in the multi-grid run
114
115 ! convergence flag: initially not converged yet
116 iequi = 0
117
118 IF (lfreeb .and. jacob_off.eq.1) then
119 ! jacob_off=1 indicates that in the previous iteration, the Jacobian was bad
120 ! --> also need to restart vacuum calculations
121 ivac = 1
122 end if
123
124 ns_min = 3
125
126 ! multi-grid iterations: loop over ns_array
127 ! jacob_off=0,1 is required to insert one ns=3 run before
128 ! starting to work with the user-provided ns_array
129 ! if the first ns value from ns_array gave a bad jacobian
130 iterations: DO igrid = 1-jacob_off, multi_ns_grid
131
132 ! retrieve settings for (ns, ftol, niter) for current multi-grid iteration
133 IF (igrid .lt. 1) THEN
134 ! igrid .lt. 1 can only happen when jacob_off == 1 (then igrid==0)
135
136 ! TRY TO GET NON-SINGULAR JACOBIAN ON A 3 PT RADIAL MESH
137 ! COMPUTE INITIAL SOLUTION ON COARSE GRID
138 ! IF PREVIOUS SEQUENCE DID NOT CONVERGE WELL
139 nsval = 3
140 ftolv = 1.e-4_dp
141
142 ! fully restart vacuum (why then assign ivac=1 then above???)
143 ivac = -1
144
145 ELSE
146 ! proceed regularly with ns values from ns_array
147 nsval = ns_array(igrid)
148 IF (nsval .lt. ns_min) then
149 ! skip entries that have less flux surfaces than previous iteration
150 cycle
151 end if
152
153 ! update ns_min --> reduction in number of flux surfaces not allowed
154 ns_min = nsval
155
156 ftolv = ftol_array(igrid)
157 niterv = niter_array(igrid)
158 END IF
159
160 IF (ns_old .le. nsval) then
161 ! initialize ns-dependent arrays
162 ! and (if previous solution is available) interpolate to current ns value
163 CALL initialize_radial(nsval, ns_old, delt0r)
164 end if
165
166 ! *HERE* is the *ACTUAL* call to the equilibrium solver !
167 CALL eqsolve (ier_flag)
168
169 ! break the multi-grid sequence if current number of flux surfaced
170 ! did not reach convergence
171 IF (ier_flag.ne.norm_term_flag .and. ier_flag.ne.successful_term_flag) then
172 EXIT
173 end if
174
175
176 ! If this point is reached, the current multi-grid step should have properly converged.
177 ! Now dump the current state vector for debugging.
178 if (open_dbg_context("multigrid_result", jacob_off)) then
179
180 call add_int("ns", nsval)
181 call add_int("iter2", iter2)
182 call add_int("ncurr", ncurr)
183 call add_real("phiedge", phiedge)
184 call add_int("ntmax", ntmax)
185
186 call add_real_1d("pres", ns-1, pres(2:ns))
187 call add_real_1d("iotas", ns-1, iotas(2:ns))
188 call add_real_1d("chips", ns-1, chips(2:ns))
189
190 call add_real_5d("xc", 3, ntmax, ns, ntor1, mpol, xc, order=(/ 3, 4, 5, 2, 1 /) )
191 call add_real_5d("scalxc", 3, ntmax, ns, ntor1, mpol, scalxc, order=(/ 3, 4, 5, 2, 1 /) )
192
193 call close_dbg_out()
194 end if
195
196 END DO iterations
197
198
199 ! if did not converge only because jacobian was bad
200 ! and the intermediate ns=3 run was not performed yet (jacob_off is still == 0),
201 ! retry the whole thing again
202 IF (ier_flag.ne.bad_jacobian_flag) THEN
203 exit ! jacob_off loop
204 ! otherwise, retry with initial ns=3 to fix bad jacobian
205 END IF
206
207 ! if ier_flag .eq. bad_jacobian_flag, repeat once again with ns=3 before
208 end do ! jacob_off = 0, 1
209
210 end if ! (ier_flag .eq. 0) after readin
211
212
213
214 ! write output files
215 CALL fileout (ier_flag)
216
217
218
219
220
221
222 ! free memory
223 IF (ALLOCATED(cosmu)) then
224 DEALLOCATE(cosmu, sinmu, cosmum, sinmum, cosmui, cosmumi, &
225 sinmui, sinmumi, cosnv, sinnv, cosnvn, sinnvn, &
226 cosmui3, cosmumi3, cos01, sin01, stat=istat1)
227 IF (istat1 .ne. 0) print *, warning // "#1"
228 end if
229
230 IF (ALLOCATED(xm)) then
231 DEALLOCATE (xm, xn, ixm, xm_nyq, xn_nyq, &
232 jmin3, mscale, nscale, uminus, stat=istat1)
233 IF (istat1 .ne. 0) print *, warning // "#2"
234 end if
235
236
237
239 CALL free_mem_ns
240 CALL free_mem_nunv
241
242 CALL free_mgrid (istat1)
243 IF (istat1.ne.0) THEN
244 print *,'problem in free_mgrid'
245 print *,' istat1 = ',istat1
246 ENDIF
247
248 ! verbose error message
249 SELECT CASE (ier_flag)
250 CASE (bad_jacobian_flag)
251 ! Bad jacobian even after axis reset and ns->3
252 WRITE ( 6, '(/,1x,a)') bad_jacobian
253 WRITE (nthreed, '(/,1x,a)') bad_jacobian
254 CASE DEFAULT
255 END SELECT
256
257 ! close threed1 file
258 IF (nthreed .gt. 0) CLOSE (nthreed)
259
260END subroutine vmec
subroutine eqsolve(ier_flag)
Iteratively evolve the Fourier coefficients that specify the equilibrium.
Definition eqsolve.f90:8
subroutine fileout(ier_flag)
Write the output files.
Definition fileout.f90:8
subroutine fixaray
allocate and fill some fixed-size arrays (only depending on Fourier resolution).
Definition fixaray.f90:7
subroutine free_mem_funct3d
Free memory required by funct3d()
subroutine free_mem_ns
Free memory depending on the number of flux surfaces ns.
subroutine free_mem_nunv
Free arrays depending on the number of Fourier coefficients nunv.
subroutine initialize_radial(nsval, ns_old, delt0)
Allocates memory for radial arrays and initializes radial profiles.
logical function open_dbg_context(context_name, repetition, id)
check if any output is desired for the current iteration check if the given context should be openend...
Definition dbgout.f90:17
subroutine free_mgrid(istat)
Definition mgrid_mod.f:711
fault-tolerant file opening routines
logical lfreeb
real(rprec) delt
character(len=100) input_extension
integer, dimension(100) niter_array
real(rprec) phiedge
value of real toroidal flux at plasma edge (s=1)
integer mpol
real(rprec), dimension(100) ftol_array
integer, dimension(100) ns_array
integer ncurr
real(rprec) ftolv
real(rprec), dimension(:), allocatable chips
poloidal flux (same as chip), one-dimensional array
Definition vmec_main.f90:67
integer iequi
counter used to call -EQFOR- at end of run
real(rprec) delt0r
integer ivac
counts number of free-boundary iterations
real(rprec), dimension(:), allocatable pres
pressure profile
Definition vmec_main.f90:55
integer niterv
max iterations for current multi-grid iteration
integer multi_ns_grid
integer num_eqsolve_retries
integer vacuum_calls
integer iter2
total number of iterations
real(rprec), dimension(:), allocatable iotas
rotational transform , on half radial mesh
Definition vmec_main.f90:69
integer, parameter bad_jacobian_flag
real(rprec), dimension(:), allocatable mscale
array for norming theta-trig functions (internal use only) so that the discrete SUM[cos(mu)*cos(m'u)]...
integer, dimension(:), allocatable uminus
integer, parameter successful_term_flag
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()
integer, parameter norm_term_flag
integer nthreed
Definition vparams.f90:28
real(rprec), dimension(:), allocatable, target xc
stacked array of scaled R, Z, Lambda Fourier coefficients (see above for stack order)
Definition xstuff.f90:40
real(rprec), dimension(:), allocatable scalxc
Definition xstuff.f90:50
subroutine readin(input_file, ier_flag)
Read the input file.
Definition readin.f90:9
subroutine reset_params
Reset some flow-control parameters to their default values.
subroutine vmec
Main driver for VMEC.
Definition vmec.f90:15
program xvmec
Main program of VMEC.
Definition vmec.f90:5