1 SUBROUTINE runvmec(ictrl_array, input_file0,
2 & lscreen, COMM_WORLD, reset_file_name)
4 USE vmec_params,
ONLY: bad_jacobian_flag, more_iter_flag,
5 & norm_term_flag, successful_term_flag,
6 & restart_flag, readin_flag,
7 & timestep_flag, ns_error_flag,
8 & reset_jacdt_flag, lamscale
10 USE vmec_params,
ONLY: ntmax
11 USE vacmod,
ONLY: nuv, nuv3
13 USE parallel_include_module
14 USE parallel_vmec_module,
ONLY: myenvvariables
15 USE parallel_vmec_module,
ONLY: initrunvmec
16 USE parallel_vmec_module,
ONLY: finalizerunvmec
17 USE parallel_vmec_module,
ONLY: initsurfacecomm
18 USE parallel_vmec_module,
ONLY: finalizesurfacecomm
19 USE parallel_vmec_module,
ONLY: setvacuumcommunicator
20 USE blocktridiagonalsolver_bst,
ONLY: initialize_bst
21 USE blocktridiagonalsolver_bst,
ONLY: finalize_bst
28 INTEGER,
INTENT(inout),
TARGET :: ictrl_array(5)
29 LOGICAL,
INTENT(in) :: lscreen
30 CHARACTER(LEN=*),
INTENT(in) :: input_file0
31 CHARACTER(LEN=*),
OPTIONAL :: reset_file_name
32 INTEGER,
INTENT(IN),
OPTIONAL :: COMM_WORLD
36 INTEGER,
POINTER :: ier_flag
37 INTEGER :: ictrl_flag, iseq_count
38 INTEGER :: ns_index, ns_min, nsval,
40 INTEGER :: igrid, index_end, index_dat,
41 & jacob_off, niter_store
42 INTEGER,
SAVE :: igrid0
43 INTEGER :: max_grid_size, flag
44 CHARACTER(LEN=120) :: input_file
46 REAL(dp) :: rvton, rvtoff, tiniton, tinitoff
47 REAL(dp) :: gridton, gridtoff
48 REAL(dp) :: bcastton, bcasttoff
49 REAL(dp),
ALLOCATABLE,
DIMENSION(:) :: bcastarr
50 INTEGER :: blklength, grid_id, i, js,
52 CHARACTER(LEN=20) :: fname
103 SUBROUTINE initialize_radial(nsval, ns_old, delt0,
104 & lscreen, reset_file_name)
107 INTEGER,
INTENT(in) :: nsval
108 INTEGER,
INTENT(inout) :: ns_old
109 CHARACTER(LEN=*),
OPTIONAL :: reset_file_name
110 LOGICAL,
INTENT(in) :: lscreen
111 REAL(rprec),
INTENT(out) :: delt0
112 END SUBROUTINE initialize_radial
115 runvmec_pass = runvmec_pass + 1
118 CALL initrunvmec(comm_world,lfreeb)
121 IF (runvmec_pass.GT.1)
THEN
122 CALL serial2parallel4x(xc,pxc)
123 CALL serial2parallel4x(xcdot,pxcdot)
124 CALL serial2parallel4x(xstore,pxstore)
125 CALL second0(bcastton)
126 CALL mpi_bcast(pxc,
SIZE(pxc), mpi_real8, 0,
127 & runvmec_comm_world, mpi_err)
128 CALL mpi_bcast(pxcdot,
SIZE(pxcdot), mpi_real8, 0,
129 & runvmec_comm_world, mpi_err)
130 CALL mpi_bcast(pxstore,
SIZE(pxstore), mpi_real8, 0,
131 & runvmec_comm_world, mpi_err)
132 CALL mpi_bcast(iotas,
SIZE(iotas), mpi_real8, 0,
133 & runvmec_comm_world, mpi_err)
134 CALL mpi_bcast(iotaf,
SIZE(iotaf), mpi_real8, 0,
135 & runvmec_comm_world, mpi_err)
136 CALL mpi_bcast(phips,
SIZE(phips), mpi_real8, 0,
137 & runvmec_comm_world, mpi_err)
138 CALL mpi_bcast(phipf,
SIZE(phipf), mpi_real8, 0,
139 & runvmec_comm_world, mpi_err)
140 CALL mpi_bcast(chips,
SIZE(chips), mpi_real8, 0,
141 & runvmec_comm_world, mpi_err)
142 CALL mpi_bcast(chipf,
SIZE(chipf), mpi_real8, 0,
143 & runvmec_comm_world, mpi_err)
144 CALL mpi_bcast(mass,
SIZE(mass), mpi_real8, 0,
145 & runvmec_comm_world, mpi_err)
146 CALL mpi_bcast(icurv,
SIZE(icurv), mpi_real8, 0,
147 & runvmec_comm_world, mpi_err)
148 CALL mpi_bcast(lamscale, 1, mpi_real8, 0,
149 & runvmec_comm_world, mpi_err)
151 nsmin = t1lglob; nsmax = t1rglob
153 pphip(:,js) = phips(js)
154 pchip(:,js) = chips(js)
157 CALL second0(bcasttoff)
158 broadcast_time = broadcast_time + (bcasttoff - bcastton)
162 ictrl_flag = ictrl_array(1)
163 numsteps = ictrl_array(3)
164 ier_flag => ictrl_array(2)
165 ns_index = ictrl_array(4)
166 iseq_count = ictrl_array(5)
172 index_dat = index(input_file0,
'input.')
173 index_end = len_trim(input_file0)
174 IF (index_dat .gt. 0)
THEN
175 input_file = trim(input_file0)
176 input_extension = input_file0(index_dat+6:index_end)
178 input_extension = input_file0(1:index_end)
179 input_file =
'input.'//trim(input_extension)
185 lreset = (iand(ictrl_flag, restart_flag) .ne. 0)
192 IF (iand(ictrl_flag, reset_jacdt_flag) .NE. 0)
THEN
197 IF (iand(ictrl_flag, readin_flag) .NE. 0)
THEN
201 CALL vsetup (iseq_count)
203 CALL readin (input_file, iseq_count, ier_flag, lscreen)
204 max_grid_size = ns_array(multi_ns_grid)
206 IF (ier_flag .NE. 0)
GOTO 1000
224 IF (
PRESENT(reset_file_name) .AND.
225 & len_trim(reset_file_name) .ne. 0)
THEN
226 igrid0 = multi_ns_grid
228 IF (grank .EQ. 0)
WRITE (nthreed, 30)
232 30
FORMAT(
' FSQR, FSQZ = Normalized Physical Force Residuals',/,
233 &
' fsqr, fsqz = Preconditioned Force Residuals',/,
234 & 1x,23(
'-'),/,
' BEGIN FORCE ITERATIONS',/,1x,23(
'-'),/)
236 IF (all(ns_array .eq. 0) .and. ns_index .le. 0)
THEN
237 ier_flag = ns_error_flag
243 IF (iand(ictrl_flag, timestep_flag) .EQ. 0)
GOTO 1000
245 IF(lfreeb)
CALL setvacuumcommunicator(nuv, nuv3, max_grid_size)
249 IF (lfreeb .and. jacob_off .eq. 1) ivac = 1
253 num_grids = multi_ns_grid
254 IF(.NOT.
ALLOCATED(grid_procs))
THEN
255 ALLOCATE(grid_procs(num_grids))
256 ALLOCATE(grid_size(num_grids))
257 ALLOCATE(grid_time(num_grids))
258 ALLOCATE(f3d_time(num_grids))
259 ALLOCATE(f3d_num(num_grids))
260 IF (lfreeb)
ALLOCATE(vgrid_time(num_grids))
263 f3d_time = 0; f3d_num=0
264 blklength = (ntor + 1)*(mpol1 + 1)
269 DO igrid = igrid0 - jacob_off, multi_ns_grid
270 CALL second0(gridton)
272 IF (igrid .lt. igrid0)
THEN
276 ELSE IF (ns_index .gt. 0)
THEN
277 IF (ns_index .gt.
SIZE(ns_array))
THEN
278 ier_flag = ns_error_flag
281 nsval = ns_array(ns_index)
282 IF (nsval .le. 0) stop
'NSVAL <= 0: WRONG INDEX VALUE'
283 ftolv = ftol_array(ns_index)
284 niter = niter_array(ns_index)
286 nsval = ns_array(igrid)
287 IF (nsval .lt. ns_min) cycle
289 ictrl_array(4) = igrid
290 ftolv = ftol_array(igrid)
291 niter = niter_array(igrid)
294 CALL second0(tiniton)
295 IF (parvmec .AND. ns_resltn .GE. 1)
THEN
297 CALL gather4xarray(pscalxc)
298 CALL gather4xarray(pxc)
300 CALL finalizesurfacecomm(ns_comm)
302 CALL second0(bcastton)
303 CALL mpi_bcast(pscalxc,
SIZE(pscalxc), mpi_real8, 0,
304 & runvmec_comm_world, mpi_err)
305 CALL mpi_bcast(pxc,
SIZE(pxc), mpi_real8, 0,
306 & runvmec_comm_world, mpi_err)
307 CALL second0(bcasttoff)
308 broadcast_time = broadcast_time + (bcasttoff - bcastton)
311 CALL initsurfacecomm(nsval, nzeta, ntheta3, ntmax, ntor, mpol1)
312 CALL second0(tinitoff)
313 init_parallel_time = init_parallel_time + (tinitoff-tiniton)
315 grid_size(grid_id) = nsval
316 grid_procs(grid_id) = nranks
321 IF (l_v3fit .AND. ns_old .ne. nsval)
THEN
322 CALL initialize_radial(nsval, ns_old, delt0r, lscreen,
324 ELSE IF (ns_old .le. nsval)
THEN
325 CALL initialize_radial(nsval, ns_old, delt0r, lscreen,
329 CALL initialize_bst(.false., nsval, blklength)
332 IF (numsteps .GT. 0)
THEN
334 niter = numsteps + iter2 - 1
337 CALL eqsolve (ier_flag, lscreen)
339 IF (numsteps .GT. 0)
THEN
343 IF (ier_flag .ne. norm_term_flag .and.
344 & ier_flag .ne. successful_term_flag .and.
345 & ier_flag .ne. more_iter_flag)
EXIT
346 IF (numsteps .GT. 0 .or. ns_index .GT. 0)
EXIT
356 IF (lgiveup .and. (fsqr .gt. ftolv*fgiveup .or.
357 & fsqz .gt. ftolv*fgiveup .or.
358 & fsql .gt. ftolv*fgiveup ))
THEN
359 print *,
"runvmec: giving up due to poor convergence"
363 CALL finalize_bst(.false.)
364 CALL second0(gridtoff)
365 grid_time(grid_id) = gridtoff - gridton
368 vgrid_time(grid_id) = vacuum_time - old_vacuum_time
369 old_vacuum_time = vacuum_time
371 vgrid_time(grid_id) = s_vacuum_time - old_vacuum_time
372 old_vacuum_time = s_vacuum_time
375 grid_id = grid_id + 1
381 IF (ier_flag .eq. bad_jacobian_flag .and. jacob_off .eq. 0)
THEN
386 CALL second0 (timeoff)
387 timer(tsum) = timer(tsum) + timeoff - timeon
391 1000
IF (lmoreiter .AND.
392 & ier_flag .EQ. more_iter_flag .AND.
394 print *,
'runvmec: Running some more iterations',
395 &
' -> Skipping call to fileout!'
396 ELSE IF (ier_flag .NE. more_iter_flag)
THEN
398 CALL fileout_par(iseq_count, ictrl_flag, ier_flag, lscreen)
400 CALL fileout(iseq_count, ictrl_flag, ier_flag, lscreen)
404 IF(lv3fitcall)
CALL finalizerunvmec(runvmec_comm_world)
406 runvmec_time = runvmec_time + (rvtoff - rvton)
408 END SUBROUTINE runvmec