5#include <PB3D_macros.h>
23 logical :: debug_run_driver_sol = .false.
24 logical :: debug_interp_V = .false.
25 integer :: ivs_stats(3)
61 character(*),
parameter :: rout_name =
'run_driver_sol'
65 type(
grid_type),
intent(in),
target :: grid_x
66 type(
grid_type),
intent(inout) :: grid_sol
77 integer :: sol_limits(2)
78 integer :: rich_lvl_name
79 real(
dp),
allocatable :: r_f_sol(:)
81 character(len=max_str_ln) :: err_msg
96 call writo(
'Set up solution grid')
99 call writo(
'Calculate the grid')
106 call writo(
'Write to output file')
122 &grid_limits=sol_limits)
137 call grid_sol_trim%dealloc()
163 call writo(
'Write to output file')
174 ierr = grid_x_sol%init([1,
n_alpha,grid_sol%n(3)],&
175 &[grid_sol%i_min,grid_sol%i_max],grid_sol%divided)
177 grid_x_sol%r_F = grid_sol%r_F
178 grid_x_sol%r_E = grid_sol%r_E
179 grid_x_sol%loc_r_F = grid_sol%loc_r_F
180 grid_x_sol%loc_r_E = grid_sol%loc_r_E
186 call writo(
'Redistribute and interpolate the perturbation &
187 &variables to solution grid')
197 call x_sol%init(
mds_sol,grid_x_sol,is_field_averaged=.true.)
205 call x_rdst%dealloc()
206 call grid_x_rdst%dealloc()
211 call writo(
'Copy the perturbation variables to solution grid')
215 call x%copy(
mds_sol,grid_x,x_sol)
223 if (debug_run_driver_sol)
then
230 call grid_x_sol%dealloc()
233 call writo(
'Solving the system')
241 err_msg =
'No EV solver style associated with '//&
247 call writo(
'System solved')
251 &remove_previous_arrs=&
283 integer function interp_v(mds_i,grid_i,X_i,mds_o,grid_o,X_o)
result(ierr)
294 character(*),
parameter :: rout_name =
'interp_V'
298 type(grid_type),
intent(in) :: grid_i
299 type(
x_2_type),
intent(in),
target :: x_i
301 type(grid_type),
intent(in) :: grid_o
302 type(
x_2_type),
intent(inout),
target :: x_o
307 integer :: c_loc_i(2)
308 integer :: c_loc_o(2)
310 integer :: kdl_i(2), kdl_o(2)
311 integer :: id_lim_i(2), id_lim_o(2)
312 integer :: ivs_stat(6)
313 integer,
pointer :: sec_i_loc(:,:), sec_o_loc(:,:)
314 real(
dp),
pointer :: r_i_loc(:), r_o_loc(:)
315 complex(dp),
pointer :: v_i(:,:,:), v_o(:,:,:)
316 logical :: calc_this(2)
317 logical :: extrap = .true.
318 character(len=max_str_ln) :: err_msg
321 integer,
allocatable :: norm_ext_i(:,:)
322 real(
dp),
allocatable :: r_loc_tot(:,:,:)
323 character(len=max_str_ln) :: ivs_stats_names(3)
331 if (grid_i%n(2).ne.grid_o%n(2))
then
333 err_msg =
'input and output grid are not compatible in the &
334 &geodesic coordinate: '//trim(
i2str(grid_i%n(2)))//
' vs. '//&
335 &trim(
i2str(grid_o%n(2)))
349 ierr =
trim_modes(mds_i,mds_o,id_lim_i,id_lim_o)
351 sec_i_loc => mds_i%sec(id_lim_i(1):id_lim_i(2),:)
352 sec_o_loc => mds_o%sec(id_lim_o(1):id_lim_o(2),:)
355 n_mod_tot =
size(sec_o_loc,1)
357 allocate(r_loc_tot(2,n_mod_tot**2,3))
358 allocate(norm_ext_i(n_mod_tot,n_mod_tot))
366 if (sec_i_loc(k,1).ne.sec_o_loc(k,1) .or. &
367 &sec_i_loc(
m,1).ne.sec_o_loc(
m,1))
then
369 err_msg =
'For ('//trim(
i2str(k))//
','//trim(
i2str(
m))//&
370 &
'), no consistency for modes in grid_i and grid_o'
376 kdl_i(1) = max(sec_i_loc(k,2),sec_i_loc(
m,2))
377 kdl_i(2) = min(sec_i_loc(k,3),sec_i_loc(
m,3))
378 kdl_o(1) = max(sec_o_loc(k,2),sec_o_loc(
m,2))
379 kdl_o(2) = min(sec_o_loc(k,3),sec_o_loc(
m,3))
382 kdl_i(1) = max(kdl_i(1),grid_i%i_min)
383 kdl_i(2) = min(kdl_i(2),grid_i%i_max)
384 kdl_o(1) = max(kdl_o(1),grid_o%i_min)
385 kdl_o(2) = min(kdl_o(2),grid_o%i_max)
388 if (.not.extrap)
then
389 do kd = kdl_o(1),kdl_o(2)
390 if (grid_o%r_F(kd).ge.grid_i%r_F(kdl_i(1)))
exit
394 do kd = kdl_o(2),kdl_o(1),-1
395 if (grid_o%r_F(kd).le.grid_i%r_F(kdl_i(2)))
exit
401 if (kdl_i(1).gt.kdl_i(2) .or. kdl_o(1).gt.kdl_o(2)) cycle
404 kdl_i = kdl_i - grid_i%i_min + 1
405 kdl_o = kdl_o - grid_o%i_min + 1
408 r_i_loc => grid_i%loc_r_F(kdl_i(1):kdl_i(2))
409 r_o_loc => grid_o%loc_r_F(kdl_o(1):kdl_o(2))
413 &[sec_o_loc(k,1),sec_o_loc(
m,1)])
415 &[sec_o_loc(k,1),sec_o_loc(
m,1)])
419 r_loc_tot(:,km_id,1) = [r_i_loc(1),r_i_loc(
size(r_i_loc))]
420 r_loc_tot(:,km_id,2) = [r_o_loc(1),r_o_loc(
size(r_o_loc))]
421 r_loc_tot(:,km_id,3) = km_id
422 norm_ext_i(k,
m) =
size(r_i_loc)
423 if (debug_interp_v)
write(*,*)
'k, m', k,
m,
'of', n_mod_tot, &
424 &
'with calc_this = ', calc_this
428 c_loc_i(1) =
c([sec_i_loc(k,4),sec_i_loc(
m,4)],.true.,
n_mod_x)
429 c_loc_i(2) =
c([sec_i_loc(k,4),sec_i_loc(
m,4)],.false.,
n_mod_x)
430 c_loc_o(1) =
c([sec_o_loc(k,4),sec_o_loc(
m,4)],.true.,
n_mod_x)
431 c_loc_o(2) =
c([sec_o_loc(k,4),sec_o_loc(
m,4)],.false.,
n_mod_x)
433 if (calc_this(1))
then
434 v_i => x_i%PV_0(:,:,kdl_i(1):kdl_i(2),c_loc_i(1))
435 v_o => x_o%PV_0(:,:,kdl_o(1):kdl_o(2),c_loc_o(1))
440 v_i => x_i%PV_2(:,:,kdl_i(1):kdl_i(2),c_loc_i(1))
441 v_o => x_o%PV_2(:,:,kdl_o(1):kdl_o(2),c_loc_o(1))
446 v_i => x_i%KV_0(:,:,kdl_i(1):kdl_i(2),c_loc_i(1))
447 v_o => x_o%KV_0(:,:,kdl_o(1):kdl_o(2),c_loc_o(1))
452 v_i => x_i%KV_2(:,:,kdl_i(1):kdl_i(2),c_loc_i(1))
453 v_o => x_o%KV_2(:,:,kdl_o(1):kdl_o(2),c_loc_o(1))
459 if (debug_interp_v)
then
492 if (calc_this(2))
then
493 v_i => x_i%PV_1(:,:,kdl_i(1):kdl_i(2),c_loc_i(2))
494 v_o => x_o%PV_1(:,:,kdl_o(1):kdl_o(2),c_loc_o(2))
499 v_i => x_i%KV_1(:,:,kdl_i(1):kdl_i(2),c_loc_i(2))
500 v_o => x_o%KV_1(:,:,kdl_o(1):kdl_o(2),c_loc_o(2))
506 do kd = 1,
size(ivs_stat)
511 ivs_stats(ivs_stat(kd)) = ivs_stats(ivs_stat(kd)) + 1
518 call writo(
'interp_V_spline statistics:')
520 ivs_stats_names(1) =
'direct copy'
521 ivs_stats_names(2) =
'linear interpolation'
522 ivs_stats_names(3) =
'spline interpolation'
524 call writo(trim(ivs_stats_names(kd))//
' was performed '//&
525 &trim(
i2str(ivs_stats(kd)))//
' times: '//&
526 &trim(
r2strt(100._dp*ivs_stats(kd)/sum(ivs_stats)))//
'%')
528 if (ivs_stats(1).gt.0)
then
529 call writo(
'It is possible that more secondary modes and/or a &
530 &lower max_njq_change are needed.',warning=.true.)
531 call writo(
'If unphysical modes appear, consider changing these &
532 &variables.',warning=.true.)
536 &r_loc_tot(:,1:km_id,1)/
max_flux_f*2*
pi,x=r_loc_tot(:,1:km_id,3),&
541 &r_loc_tot(:,1:km_id,2)/
max_flux_f*2*
pi,x=r_loc_tot(:,1:km_id,3),&
546 &reshape(norm_ext_i*1._dp,[n_mod_tot,n_mod_tot,1]))
550 nullify(r_i_loc,r_o_loc)
551 nullify(sec_i_loc,sec_o_loc)
Prints variables vars with names var_names in an HDF5 file with name c file_name and accompanying XDM...
Print 2-D output on a file.
Redistribute the perturbation variables.
Driver of the solution part of PB3D.
integer function interp_v(mds_i, grid_i, x_i, mds_o, grid_o, x_o)
Interpolate tensorial perturbation quantities in the third dimension.
integer function, public run_driver_sol(grid_eq, grid_x, grid_sol, x, vac, sol)
Main driver of PB3D solution part.
Variables that have to do with equilibrium quantities and the grid used in the calculations:
real(dp), public max_flux_f
max. flux in Flux coordinates, set in calc_norm_range_PB3D_in
Operations that have to do with the grids and different coordinate systems.
integer function, public print_output_grid(grid, grid_name, data_name, rich_lvl, par_div, remove_previous_arrs)
Print grid variables to an output file.
integer function, public calc_norm_range(style, in_limits, eq_limits, x_limits, sol_limits, r_f_eq, r_f_x, r_f_sol, jq)
Calculates normal range for the input grid, the equilibrium grid and/or the solution grid.
integer function, public redistribute_output_grid(grid, grid_out, no_outer_trim)
Redistribute a grid to match the normal distribution of solution grid.
integer function, public setup_grid_sol(grid_eq, grid_x, grid_sol, r_f_sol, sol_limits)
Sets up the general solution grid, in which the solution variables are calculated.
Numerical utilities related to the grids and different coordinate systems.
integer function, public trim_grid(grid_in, grid_out, norm_id)
Trim a grid, removing any overlap between the different regions.
Variables pertaining to the different grids used.
integer, public n_alpha
nr. of field-lines
integer, public n_r_sol
nr. of normal points in solution grid
Numerical utilities related to giving output.
subroutine, public lvl_ud(inc)
Increases/decreases lvl of output.
subroutine, public writo(input_str, persistent, error, warning, alert)
Write output to file identified by output_i.
integer function, public c(ij, sym, n, lim_n)
Convert 2-D coordinates (i,j) to the storage convention used in matrices.
integer, dimension(:,:), allocatable, public m
1-D array indices of metric indices
Numerical variables used by most other modules.
integer, parameter, public dp
double precision
real(dp), parameter, public pi
integer, public n_procs
nr. of MPI processes
complex(dp), parameter, public iu
complex unit
integer, parameter, public max_str_ln
maximum length of strings
integer, public x_grid_style
style for normal component of X grid (1: eq, 2: sol, 3: enriched)
integer, public eq_style
either 1 (VMEC) or 2 (HELENA)
integer, public ex_plot_style
external plot style (1: GNUPlot, 2: Bokeh for 2D, Mayavi for 3D)
integer, public ev_style
determines the method used for solving an EV problem
integer, public rank
MPI rank.
integer, public rich_restart_lvl
starting Richardson level (0: none [default])
logical, public jump_to_sol
jump to solution
Operations concerning giving output, on the screen as well as in output files.
subroutine, public draw_ex(var_names, draw_name, nplt, draw_dim, plot_on_screen, ex_plot_style, data_name, draw_ops, extra_ops, is_animated, ranges, delay, persistent)
Use external program to draw a plot.
Operations on PB3D output.
integer function, public reconstruct_pb3d_grid(grid, data_name, rich_lvl, tot_rich, lim_pos, grid_limits)
Reconstructs grid variables from PB3D HDF5 output.
integer function, public reconstruct_pb3d_sol(mds, grid_sol, sol, data_name, rich_lvl, lim_sec_sol, lim_pos)
Reconstructs the solution variables from PB3D HDF5 output.
Operations concerning Richardson extrapolation.
subroutine, public calc_rich_ex(sol_val)
Calculates the coefficients of the Eigenvalues in the Richardson extrapolation.
Variables concerning Richardson extrapolation.
integer, public rich_lvl
current level of Richardson extrapolation
Operations that use SLEPC (and PETSC) routines.
integer function, public solve_ev_system_slepc(mds, grid_sol, x, vac, sol)
Solve the eigenvalue system using SLEPC.
Operations on the solution vectors such as decompososing the energy, etc...
integer function, public print_output_sol(grid, sol, data_name, rich_lvl, remove_previous_arrs)
Print solution quantities to an output file:
Numerical utilities related to the solution vectors.
integer function, public interp_v_spline(v_i, v_o, r_i, r_o, extrap, ivs_stat)
Interpolation for a quantity V using splines.
Variables pertaining to the solution quantities.
elemental character(len=max_str_ln) function, public i2str(k)
Convert an integer to string.
elemental character(len=max_str_ln) function, public r2strt(k)
Convert a real (double) to string.
Operations and variables pertaining to the vacuum response.
integer function, public calc_vac_res(mds, vac)
Calculates the vacuum response.
integer function, public print_output_vac(vac, data_name, rich_lvl)
Print vacuum quantities of a certain order to an output file.
Variables pertaining to the vacuum quantities.
Operations considering perturbation quantities.
integer function, public setup_modes(mds, grid_eq, grid, plot_name)
Sets up some variables concerning the mode numbers.
integer function, public print_debug_x_2(mds, grid_x, x_2_int)
Prints debug information for X_2 driver.
Numerical utilities related to perturbation operations.
logical function, public is_necessary_x(sym, sec_x_id, lim_sec_x)
Determines whether a variable needs to be considered:
integer function, public trim_modes(mds_i, mds_o, id_lim_i, id_lim_o)
Limit input mode range to output mode range.
Variables pertaining to the perturbation quantities.
integer, public n_mod_x
size of m_X (pol. flux) or n_X (tor. flux)
type(modes_type), public mds_x
modes variables for perturbation grid
type(modes_type), public mds_sol
modes variables for solution grid
tensorial perturbation type