Read parameters and calculate derived values
Note on parallelization: this function should be called from the root node only!
elseif(nfermi==0) then ! This happens when both found_fermi_energy=.false. and ! fermi_energy_scan=.false. Functionalities that require ! specifying a Fermi level should give an error message allocate(fermi_energy_list(1),stat=ierr) ! helps streamline things
AAM_2017-03-27: if nfermi is zero (ie, fermi_energy* parameters are not set in input file) then allocate fermi_energy_list with length 1 and set to zero as default.
subroutine param_read()
!==================================================================!
! !
!! Read parameters and calculate derived values
!!
!! Note on parallelization: this function should be called
!! from the root node only!
!!
! !
!===================================================================
use w90_constants, only: bohr, eps6, cmplx_i
use w90_utility, only: utility_recip_lattice, utility_metric
use w90_io, only: io_error, io_file_unit, seedname, post_proc_flag
implicit none
!local variables
real(kind=dp) :: real_lattice_tmp(3, 3)
integer :: nkp, i, j, n, k, itmp, i_temp, i_temp2, eig_unit, loop, ierr, iv_temp(3), rows
logical :: found, found2, lunits, chk_found
character(len=6) :: spin_str
real(kind=dp) :: cosa(3), rv_temp(3)
integer, allocatable, dimension(:, :) :: nnkpts_block
integer, allocatable, dimension(:) :: nnkpts_idx
call param_in_file
!%%%%%%%%%%%%%%%%
! Site symmetry
!%%%%%%%%%%%%%%%%
! default value is lsitesymmetry=.false.
call param_get_keyword('site_symmetry', found, l_value=lsitesymmetry)!YN:
! default value is symmetrize_eps=0.001
call param_get_keyword('symmetrize_eps', found, r_value=symmetrize_eps)!YN:
!%%%%%%%%%%%%%%%%
! Transport
!%%%%%%%%%%%%%%%%
transport = .false.
call param_get_keyword('transport', found, l_value=transport)
tran_read_ht = .false.
call param_get_keyword('tran_read_ht', found, l_value=tran_read_ht)
tran_easy_fix = .false.
call param_get_keyword('tran_easy_fix', found, l_value=tran_easy_fix)
if (transport .and. tran_read_ht) restart = ' '
!%%%%%%%%%%%%%%%%
!System variables
!%%%%%%%%%%%%%%%%
timing_level = 1 ! Verbosity of timing output info
call param_get_keyword('timing_level', found, i_value=timing_level)
iprint = 1 ! Verbosity
call param_get_keyword('iprint', found, i_value=iprint)
optimisation = 3 ! Verbosity
call param_get_keyword('optimisation', found, i_value=optimisation)
if (transport .and. tran_read_ht) goto 301
!ivo
call param_get_keyword('effective_model', found, l_value=effective_model)
energy_unit = 'ev' !
call param_get_keyword('energy_unit', found, c_value=energy_unit)
length_unit = 'ang' !
lenconfac = 1.0_dp
call param_get_keyword('length_unit', found, c_value=length_unit)
if (length_unit .ne. 'ang' .and. length_unit .ne. 'bohr') &
call io_error('Error: value of length_unit not recognised in param_read')
if (length_unit .eq. 'bohr') lenconfac = 1.0_dp/bohr
wvfn_formatted = .false. ! formatted or "binary" file
call param_get_keyword('wvfn_formatted', found, l_value=wvfn_formatted)
spn_formatted = .false. ! formatted or "binary" file
call param_get_keyword('spn_formatted', found, l_value=spn_formatted)
uHu_formatted = .false. ! formatted or "binary" file
call param_get_keyword('uhu_formatted', found, l_value=uHu_formatted)
spin = 1
call param_get_keyword('spin', found, c_value=spin_str)
if (found) then
if (index(spin_str, 'up') > 0) then
spin = 1
elseif (index(spin_str, 'down') > 0) then
spin = 2
else
call io_error('Error: unrecognised value of spin found: '//trim(spin_str))
end if
end if
num_wann = -99
call param_get_keyword('num_wann', found, i_value=num_wann)
if (.not. found) call io_error('Error: You must specify num_wann')
if (num_wann <= 0) call io_error('Error: num_wann must be greater than zero')
num_exclude_bands = 0
call param_get_range_vector('exclude_bands', found, num_exclude_bands, lcount=.true.)
if (found) then
if (num_exclude_bands < 1) call io_error('Error: problem reading exclude_bands')
if (allocated(exclude_bands)) deallocate (exclude_bands)
allocate (exclude_bands(num_exclude_bands), stat=ierr)
if (ierr /= 0) call io_error('Error allocating exclude_bands in param_read')
call param_get_range_vector('exclude_bands', found, num_exclude_bands, .false., exclude_bands)
if (any(exclude_bands < 1)) &
call io_error('Error: exclude_bands must contain positive numbers')
end if
! AAM_2016-09-16: some changes to logic to patch a problem with uninitialised num_bands in library mode
! num_bands = -1
call param_get_keyword('num_bands', found, i_value=i_temp)
if (found .and. library) write (stdout, '(/a)') ' Ignoring <num_bands> in input file'
if (.not. library .and. .not. effective_model) then
if (found) num_bands = i_temp
if (.not. found) num_bands = num_wann
end if
! GP: I subtract it here, but only the first time when I pass the total number of bands
! In later calls, I need to pass instead num_bands already subtracted.
if (library .and. library_param_read_first_pass) num_bands = num_bands - num_exclude_bands
if (.not. effective_model) then
if (found .and. num_bands < num_wann) then
write (stdout, *) 'num_bands', num_bands
write (stdout, *) 'num_wann', num_wann
call io_error('Error: num_bands must be greater than or equal to num_wann')
endif
endif
num_dump_cycles = 100 ! frequency to write backups at
call param_get_keyword('num_dump_cycles', found, i_value=num_dump_cycles)
if (num_dump_cycles < 0) call io_error('Error: num_dump_cycles must be positive')
num_print_cycles = 1 ! frequency to write at
call param_get_keyword('num_print_cycles', found, i_value=num_print_cycles)
if (num_print_cycles < 0) call io_error('Error: num_print_cycles must be positive')
devel_flag = ' ' !
call param_get_keyword('devel_flag', found, c_value=devel_flag)
! mp_grid=-99
call param_get_keyword_vector('mp_grid', found, 3, i_value=iv_temp)
if (found .and. library) write (stdout, '(a)') ' Ignoring <mp_grid> in input file'
if (.not. library .and. .not. effective_model) then
if (found) mp_grid = iv_temp
if (.not. found) then
call io_error('Error: You must specify dimensions of the Monkhorst-Pack grid by setting mp_grid')
elseif (any(mp_grid < 1)) then
call io_error('Error: mp_grid must be greater than zero')
end if
num_kpts = mp_grid(1)*mp_grid(2)*mp_grid(3)
end if
![ysl-b]
ltmp = .false.
call param_get_keyword('gamma_only', found, l_value=ltmp)
if (.not. library) then
gamma_only = ltmp
if (gamma_only .and. (num_kpts .ne. 1)) &
call io_error('Error: gamma_only is true, but num_kpts > 1')
else
if (found) write (stdout, '(a)') ' Ignoring <gamma_only> in input file'
endif
![ysl-e]
! aam: automatic_mp_grid no longer used
! automatic_mp_grid = .false.
! call param_get_keyword('automatic_mp_grid',found,l_value=automatic_mp_grid)
postproc_setup = .false. ! set to true to write .nnkp file and exit
call param_get_keyword('postproc_setup', found, l_value=postproc_setup)
! We allow this keyword to be overriden by a command line arg -pp
if (post_proc_flag) postproc_setup = .true.
cp_pp = .false. ! set to true if doing CP post-processing
call param_get_keyword('cp_pp', found, l_value=cp_pp)
calc_only_A = .false.
call param_get_keyword('calc_only_A', found, l_value=calc_only_A)
restart = ' '
call param_get_keyword('restart', found, c_value=restart)
if (found) then
if ((restart .ne. 'default') .and. (restart .ne. 'wannierise') &
.and. (restart .ne. 'plot') .and. (restart .ne. 'transport')) then
call io_error('Error in input file: value of restart not recognised')
else
inquire (file=trim(seedname)//'.chk', exist=chk_found)
if (.not. chk_found) &
call io_error('Error: restart requested but '//trim(seedname)//'.chk file not found')
endif
endif
!post processing takes priority (user is not warned of this)
if (postproc_setup) restart = ' '
write_r2mn = .false.
call param_get_keyword('write_r2mn', found, l_value=write_r2mn)
write_proj = .false.
call param_get_keyword('write_proj', found, l_value=write_proj)
ltmp = .false. ! by default our WF are not spinors
call param_get_keyword('spinors', found, l_value=ltmp)
if (.not. library) then
spinors = ltmp
else
if (found) write (stdout, '(a)') ' Ignoring <spinors> in input file'
endif
! if(spinors .and. (2*(num_wann/2))/=num_wann) &
! call io_error('Error: For spinor WF num_wann must be even')
! We need to know if the bands are double degenerate due to spin, e.g. when
! calculating the DOS
if (spinors) then
num_elec_per_state = 1
else
num_elec_per_state = 2
endif
call param_get_keyword('num_elec_per_state', found, i_value=num_elec_per_state)
if ((num_elec_per_state /= 1) .and. (num_elec_per_state /= 2)) &
call io_error('Error: num_elec_per_state can be only 1 or 2')
if (spinors .and. num_elec_per_state /= 1) &
call io_error('Error: when spinors = T num_elec_per_state must be 1')
translate_home_cell = .false.
call param_get_keyword('translate_home_cell', found, l_value=translate_home_cell)
write_xyz = .false.
call param_get_keyword('write_xyz', found, l_value=write_xyz)
write_hr_diag = .false.
call param_get_keyword('write_hr_diag', found, l_value=write_hr_diag)
!%%%%%%%%%%%
! Wannierise
!%%%%%%%%%%%
num_iter = 100
call param_get_keyword('num_iter', found, i_value=num_iter)
if (num_iter < 0) call io_error('Error: num_iter must be positive')
num_cg_steps = 5
call param_get_keyword('num_cg_steps', found, i_value=num_cg_steps)
if (num_cg_steps < 0) call io_error('Error: num_cg_steps must be positive')
conv_tol = 1.0e-10_dp
call param_get_keyword('conv_tol', found, r_value=conv_tol)
if (conv_tol < 0.0_dp) call io_error('Error: conv_tol must be positive')
conv_noise_amp = -1.0_dp
call param_get_keyword('conv_noise_amp', found, r_value=conv_noise_amp)
conv_window = -1
if (conv_noise_amp > 0.0_dp) conv_window = 5
call param_get_keyword('conv_window', found, i_value=conv_window)
conv_noise_num = 3
call param_get_keyword('conv_noise_num', found, i_value=conv_noise_num)
if (conv_noise_num < 0) call io_error('Error: conv_noise_num must be positive')
guiding_centres = .false.
call param_get_keyword('guiding_centres', found, l_value=guiding_centres)
num_guide_cycles = 1
call param_get_keyword('num_guide_cycles', found, i_value=num_guide_cycles)
if (num_guide_cycles < 0) call io_error('Error: num_guide_cycles must be >= 0')
num_no_guide_iter = 0
call param_get_keyword('num_no_guide_iter', found, i_value=num_no_guide_iter)
if (num_no_guide_iter < 0) call io_error('Error: num_no_guide_iter must be >= 0')
fixed_step = -999.0_dp; lfixstep = .false.
call param_get_keyword('fixed_step', found, r_value=fixed_step)
if (found .and. (fixed_step < 0.0_dp)) call io_error('Error: fixed_step must be > 0')
if (fixed_step > 0.0_dp) lfixstep = .true.
trial_step = 2.0_dp
call param_get_keyword('trial_step', found, r_value=trial_step)
if (found .and. lfixstep) call io_error('Error: cannot specify both fixed_step and trial_step')
precond = .false.
call param_get_keyword('precond', found, l_value=precond)
slwf_num = num_wann
selective_loc = .false.
call param_get_keyword('slwf_num', found, i_value=slwf_num)
if (found) then
if (slwf_num .gt. num_wann .or. slwf_num .lt. 1) then
call io_error('Error: slwf_num must be an integer between 1 and num_wann')
end if
if (slwf_num .lt. num_wann) selective_loc = .true.
end if
slwf_constrain = .false.
call param_get_keyword('slwf_constrain', found, l_value=slwf_constrain)
if (found .and. slwf_constrain) then
if (selective_loc) then
allocate (ccentres_frac(num_wann, 3), stat=ierr)
if (ierr /= 0) call io_error('Error allocating ccentres_frac in param_get_centre_constraints')
allocate (ccentres_cart(num_wann, 3), stat=ierr)
if (ierr /= 0) call io_error('Error allocating ccentres_cart in param_get_centre_constraints')
else
write (stdout, *) ' No selective localisation requested. Ignoring constraints on centres'
slwf_constrain = .false.
end if
end if
slwf_lambda = 1.0_dp
call param_get_keyword('slwf_lambda', found, r_value=slwf_lambda)
if (found) then
if (slwf_lambda < 0.0_dp) call io_error('Error: slwf_lambda must be positive.')
endif
!%%%%%%%%%
! Plotting
!%%%%%%%%%
wannier_plot = .false.
call param_get_keyword('wannier_plot', found, l_value=wannier_plot)
wannier_plot_supercell = 2
call param_get_vector_length('wannier_plot_supercell', found, length=i)
if (found) then
if (i .eq. 1) then
call param_get_keyword_vector('wannier_plot_supercell', found, 1, &
i_value=wannier_plot_supercell)
wannier_plot_supercell(2) = wannier_plot_supercell(1)
wannier_plot_supercell(3) = wannier_plot_supercell(1)
elseif (i .eq. 3) then
call param_get_keyword_vector('wannier_plot_supercell', found, 3, &
i_value=wannier_plot_supercell)
else
call io_error('Error: wannier_plot_supercell must be provided as either one integer or a vector of three integers')
end if
if (any(wannier_plot_supercell <= 0)) &
call io_error('Error: wannier_plot_supercell elements must be greater than zero')
end if
wannier_plot_format = 'xcrysden'
call param_get_keyword('wannier_plot_format', found, c_value=wannier_plot_format)
wannier_plot_mode = 'crystal'
call param_get_keyword('wannier_plot_mode', found, c_value=wannier_plot_mode)
wannier_plot_spinor_mode = 'total'
call param_get_keyword('wannier_plot_spinor_mode', found, c_value=wannier_plot_spinor_mode)
wannier_plot_spinor_phase = .true.
call param_get_keyword('wannier_plot_spinor_phase', found, l_value=wannier_plot_spinor_phase)
call param_get_range_vector('wannier_plot_list', found, num_wannier_plot, lcount=.true.)
if (found) then
if (num_wannier_plot < 1) call io_error('Error: problem reading wannier_plot_list')
if (allocated(wannier_plot_list)) deallocate (wannier_plot_list)
allocate (wannier_plot_list(num_wannier_plot), stat=ierr)
if (ierr /= 0) call io_error('Error allocating wannier_plot_list in param_read')
call param_get_range_vector('wannier_plot_list', found, num_wannier_plot, .false., wannier_plot_list)
if (any(wannier_plot_list < 1) .or. any(wannier_plot_list > num_wann)) &
call io_error('Error: wannier_plot_list asks for a non-valid wannier function to be plotted')
else
! we plot all wannier functions
num_wannier_plot = num_wann
if (allocated(wannier_plot_list)) deallocate (wannier_plot_list)
allocate (wannier_plot_list(num_wannier_plot), stat=ierr)
if (ierr /= 0) call io_error('Error allocating wannier_plot_list in param_read')
do loop = 1, num_wann
wannier_plot_list(loop) = loop
end do
end if
wannier_plot_radius = 3.5_dp
call param_get_keyword('wannier_plot_radius', found, r_value=wannier_plot_radius)
wannier_plot_scale = 1.0_dp
call param_get_keyword('wannier_plot_scale', found, r_value=wannier_plot_scale)
! checks
if (wannier_plot) then
if ((index(wannier_plot_format, 'xcrys') .eq. 0) .and. (index(wannier_plot_format, 'cub') .eq. 0)) &
call io_error('Error: wannier_plot_format not recognised')
if ((index(wannier_plot_mode, 'crys') .eq. 0) .and. (index(wannier_plot_mode, 'mol') .eq. 0)) &
call io_error('Error: wannier_plot_mode not recognised')
if ((index(wannier_plot_spinor_mode, 'total') .eq. 0) .and. (index(wannier_plot_spinor_mode, 'up') .eq. 0) &
.and. (index(wannier_plot_spinor_mode, 'down') .eq. 0)) &
call io_error('Error: wannier_plot_spinor_mode not recognised')
if (wannier_plot_radius < 0.0_dp) call io_error('Error: wannier_plot_radius must be positive')
if (wannier_plot_scale < 0.0_dp) call io_error('Error: wannier_plot_scale must be positive')
endif
write_u_matrices = .false.
call param_get_keyword('write_u_matrices', found, l_value=write_u_matrices)
bands_plot = .false.
call param_get_keyword('bands_plot', found, l_value=bands_plot)
write_bvec = .false.
call param_get_keyword('write_bvec', found, l_value=write_bvec)
bands_num_points = 100
call param_get_keyword('bands_num_points', found, i_value=bands_num_points)
bands_plot_format = 'gnuplot'
call param_get_keyword('bands_plot_format', found, c_value=bands_plot_format)
bands_plot_mode = 's-k'
call param_get_keyword('bands_plot_mode', found, c_value=bands_plot_mode)
bands_plot_dim = 3
call param_get_keyword('bands_plot_dim', found, i_value=bands_plot_dim)
num_bands_project = 0
call param_get_range_vector('bands_plot_project', found, num_bands_project, lcount=.true.)
if (found) then
if (num_bands_project < 1) call io_error('Error: problem reading bands_plot_project')
if (allocated(bands_plot_project)) deallocate (bands_plot_project)
allocate (bands_plot_project(num_bands_project), stat=ierr)
if (ierr /= 0) call io_error('Error allocating bands_plot_project in param_read')
call param_get_range_vector('bands_plot_project', found, num_bands_project, .false., bands_plot_project)
if (any(bands_plot_project < 1) .or. any(bands_plot_project > num_wann)) &
call io_error('Error: bands_plot_project asks for a non-valid wannier function to be projected')
endif
bands_num_spec_points = 0
call param_get_block_length('kpoint_path', found, i_temp)
if (found) then
bands_num_spec_points = i_temp*2
if (allocated(bands_label)) deallocate (bands_label)
allocate (bands_label(bands_num_spec_points), stat=ierr)
if (ierr /= 0) call io_error('Error allocating bands_label in param_read')
if (allocated(bands_spec_points)) deallocate (bands_spec_points)
allocate (bands_spec_points(3, bands_num_spec_points), stat=ierr)
if (ierr /= 0) call io_error('Error allocating bands_spec_points in param_read')
call param_get_keyword_kpath
end if
if (.not. found .and. bands_plot) &
call io_error('A bandstructure plot has been requested but there is no kpoint_path block')
! checks
if (bands_plot) then
if ((index(bands_plot_format, 'gnu') .eq. 0) .and. (index(bands_plot_format, 'xmgr') .eq. 0)) &
call io_error('Error: bands_plot_format not recognised')
if ((index(bands_plot_mode, 's-k') .eq. 0) .and. (index(bands_plot_mode, 'cut') .eq. 0)) &
call io_error('Error: bands_plot_mode not recognised')
if (bands_num_points < 0) call io_error('Error: bands_num_points must be positive')
endif
fermi_surface_plot = .false.
call param_get_keyword('fermi_surface_plot', found, l_value=fermi_surface_plot)
fermi_surface_num_points = 50
call param_get_keyword('fermi_surface_num_points', found, i_value=fermi_surface_num_points)
fermi_surface_plot_format = 'xcrysden'
call param_get_keyword('fermi_surface_plot_format', &
found, c_value=fermi_surface_plot_format)
nfermi = 0
found_fermi_energy = .false.
call param_get_keyword('fermi_energy', found, r_value=fermi_energy)
if (found) then
found_fermi_energy = .true.
nfermi = 1
endif
!
fermi_energy_scan = .false.
call param_get_keyword('fermi_energy_min', found, r_value=fermi_energy_min)
if (found) then
if (found_fermi_energy) call io_error( &
'Error: Cannot specify both fermi_energy and fermi_energy_min')
fermi_energy_scan = .true.
fermi_energy_max = fermi_energy_min + 1.0_dp
call param_get_keyword('fermi_energy_max', found, &
r_value=fermi_energy_max)
if (found .and. fermi_energy_max <= fermi_energy_min) call io_error( &
'Error: fermi_energy_max must be larger than fermi_energy_min')
fermi_energy_step = 0.01_dp
call param_get_keyword('fermi_energy_step', found, &
r_value=fermi_energy_step)
if (found .and. fermi_energy_step <= 0.0_dp) call io_error( &
'Error: fermi_energy_step must be positive')
nfermi = nint(abs((fermi_energy_max - fermi_energy_min)/fermi_energy_step)) + 1
endif
!
if (found_fermi_energy) then
if (allocated(fermi_energy_list)) deallocate (fermi_energy_list)
allocate (fermi_energy_list(1), stat=ierr)
fermi_energy_list(1) = fermi_energy
elseif (fermi_energy_scan) then
if (nfermi .eq. 1) then
fermi_energy_step = 0.0_dp
else
fermi_energy_step = (fermi_energy_max - fermi_energy_min)/real(nfermi - 1, dp)
endif
if (allocated(fermi_energy_list)) deallocate (fermi_energy_list)
allocate (fermi_energy_list(nfermi), stat=ierr)
do i = 1, nfermi
fermi_energy_list(i) = fermi_energy_min + (i - 1)*fermi_energy_step
enddo
!! elseif(nfermi==0) then
!! ! This happens when both found_fermi_energy=.false. and
!! ! fermi_energy_scan=.false. Functionalities that require
!! ! specifying a Fermi level should give an error message
!! allocate(fermi_energy_list(1),stat=ierr) ! helps streamline things
!!
!! AAM_2017-03-27: if nfermi is zero (ie, fermi_energy* parameters are not set in input file)
!! then allocate fermi_energy_list with length 1 and set to zero as default.
else
if (allocated(fermi_energy_list)) deallocate (fermi_energy_list)
allocate (fermi_energy_list(1), stat=ierr)
fermi_energy_list(1) = 0.0_dp
endif
if (ierr /= 0) call io_error( &
'Error allocating fermi_energy_list in param_read')
! checks
if (fermi_surface_plot) then
if ((index(fermi_surface_plot_format, 'xcrys') .eq. 0)) &
call io_error('Error: fermi_surface_plot_format not recognised')
if (fermi_surface_num_points < 0) &
call io_error('Error: fermi_surface_num_points must be positive')
endif
kslice = .false.
call param_get_keyword('kslice', found, l_value=kslice)
kslice_task = 'fermi_lines'
call param_get_keyword('kslice_task', found, c_value=kslice_task)
if (kslice .and. index(kslice_task, 'fermi_lines') == 0 .and. &
index(kslice_task, 'curv') == 0 .and. &
index(kslice_task, 'morb') == 0 .and. &
index(kslice_task, 'shc') == 0) call io_error &
('Error: value of kslice_task not recognised in param_read')
if (kslice .and. index(kslice_task, 'curv') > 0 .and. &
index(kslice_task, 'morb') > 0) call io_error &
("Error: kslice_task cannot include both 'curv' and 'morb'")
if (kslice .and. index(kslice_task, 'shc') > 0 .and. &
index(kslice_task, 'morb') > 0) call io_error &
("Error: kslice_task cannot include both 'shc' and 'morb'")
if (kslice .and. index(kslice_task, 'shc') > 0 .and. &
index(kslice_task, 'curv') > 0) call io_error &
("Error: kslice_task cannot include both 'shc' and 'curv'")
kslice_2dkmesh(1:2) = 50
call param_get_vector_length('kslice_2dkmesh', found, length=i)
if (found) then
if (i == 1) then
call param_get_keyword_vector('kslice_2dkmesh', found, 1, &
i_value=kslice_2dkmesh)
kslice_2dkmesh(2) = kslice_2dkmesh(1)
elseif (i == 2) then
call param_get_keyword_vector('kslice_2dkmesh', found, 2, &
i_value=kslice_2dkmesh)
else
call io_error('Error: kslice_2dkmesh must be provided as either' &
//' one integer or a vector of two integers')
endif
if (any(kslice_2dkmesh <= 0)) &
call io_error('Error: kslice_2dkmesh elements must be' &
//' greater than zero')
endif
kslice_corner = 0.0_dp
call param_get_keyword_vector('kslice_corner', found, 3, r_value=kslice_corner)
kslice_b1(1) = 1.0_dp
kslice_b1(2) = 0.0_dp
kslice_b1(3) = 0.0_dp
call param_get_keyword_vector('kslice_b1', found, 3, r_value=kslice_b1)
kslice_b2(1) = 0.0_dp
kslice_b2(2) = 1.0_dp
kslice_b2(3) = 0.0_dp
call param_get_keyword_vector('kslice_b2', found, 3, r_value=kslice_b2)
kslice_fermi_lines_colour = 'none'
call param_get_keyword('kslice_fermi_lines_colour', found, &
c_value=kslice_fermi_lines_colour)
if (kslice .and. index(kslice_fermi_lines_colour, 'none') == 0 .and. &
index(kslice_fermi_lines_colour, 'spin') == 0) call io_error &
('Error: value of kslice_fermi_lines_colour not recognised ' &
//'in param_read')
! slice_plot_format = 'plotmv'
! call param_get_keyword('slice_plot_format',found,c_value=slice_plot_format)
! [gp-begin, Apr 20, 2012]
! By default: Gaussian
smr_index = 0
call param_get_keyword('smr_type', found, c_value=ctmp)
if (found) smr_index = get_smearing_index(ctmp, 'smr_type')
! By default: adaptive smearing
adpt_smr = .true.
call param_get_keyword('adpt_smr', found, l_value=adpt_smr)
! By default: a=sqrt(2)
adpt_smr_fac = sqrt(2.0_dp)
call param_get_keyword('adpt_smr_fac', found, r_value=adpt_smr_fac)
if (found .and. (adpt_smr_fac <= 0._dp)) &
call io_error('Error: adpt_smr_fac must be greater than zero')
! By default: 1 eV
adpt_smr_max = 1.0_dp
call param_get_keyword('adpt_smr_max', found, r_value=adpt_smr_max)
if (adpt_smr_max <= 0._dp) &
call io_error('Error: adpt_smr_max must be greater than zero')
! By default: if adpt_smr is manually set to false by the user, but he/she doesn't
! define smr_fixed_en_width: NO smearing, i.e. just the histogram
smr_fixed_en_width = 0.0_dp
call param_get_keyword('smr_fixed_en_width', found, r_value=smr_fixed_en_width)
if (found .and. (smr_fixed_en_width < 0._dp)) &
call io_error('Error: smr_fixed_en_width must be greater than or equal to zero')
! [gp-end]
!IVO
dos = .false.
call param_get_keyword('dos', found, l_value=dos)
berry = .false.
call param_get_keyword('berry', found, l_value=berry)
transl_inv = .false.
call param_get_keyword('transl_inv', found, l_value=transl_inv)
berry_task = ' '
call param_get_keyword('berry_task', found, c_value=berry_task)
if (berry .and. .not. found) call io_error &
('Error: berry=T and berry_task is not set')
if (berry .and. index(berry_task, 'ahc') == 0 .and. index(berry_task, 'morb') == 0 &
.and. index(berry_task, 'kubo') == 0 .and. index(berry_task, 'sc') == 0 &
.and. index(berry_task, 'shc') == 0) call io_error &
('Error: value of berry_task not recognised in param_read')
! Stepan
gyrotropic = .false.
call param_get_keyword('gyrotropic', found, l_value=gyrotropic)
gyrotropic_task = 'all'
call param_get_keyword('gyrotropic_task', found, c_value=gyrotropic_task)
gyrotropic_box(:, :) = 0.0
gyrotropic_degen_thresh = 0.0_dp
call param_get_keyword('gyrotropic_degen_thresh', found, r_value=gyrotropic_degen_thresh)
do i = 1, 3
gyrotropic_box(i, i) = 1.0_dp
gyrotropic_box_tmp(:) = 0.0_dp
call param_get_keyword_vector('gyrotropic_box_b'//achar(48 + i), found, 3, r_value=gyrotropic_box_tmp)
if (found) gyrotropic_box(i, :) = gyrotropic_box_tmp(:)
enddo
gyrotropic_box_corner(:) = 0.0_dp
call param_get_keyword_vector('gyrotropic_box_center', found, 3, r_value=gyrotropic_box_tmp)
if (found) gyrotropic_box_corner(:) = &
gyrotropic_box_tmp(:) - 0.5*(gyrotropic_box(1, :) + gyrotropic_box(2, :) + gyrotropic_box(3, :))
call param_get_range_vector('gyrotropic_band_list', found, gyrotropic_num_bands, lcount=.true.)
if (found) then
if (gyrotropic_num_bands < 1) call io_error('Error: problem reading gyrotropic_band_list')
if (allocated(gyrotropic_band_list)) deallocate (gyrotropic_band_list)
allocate (gyrotropic_band_list(gyrotropic_num_bands), stat=ierr)
if (ierr /= 0) call io_error('Error allocating gyrotropic_band_list in param_read')
call param_get_range_vector('gyrotropic_band_list', found, gyrotropic_num_bands, .false., gyrotropic_band_list)
if (any(gyrotropic_band_list < 1) .or. any(gyrotropic_band_list > num_wann)) &
call io_error('Error: gyrotropic_band_list asks for a non-valid bands')
else
! include all bands in the calculation
gyrotropic_num_bands = num_wann
if (allocated(gyrotropic_band_list)) deallocate (gyrotropic_band_list)
allocate (gyrotropic_band_list(gyrotropic_num_bands), stat=ierr)
if (ierr /= 0) call io_error('Error allocating gyrotropic_band_list in param_read')
do loop = 1, num_wann
gyrotropic_band_list(loop) = loop
end do
end if
smr_max_arg = 5.0
call param_get_keyword('smr_max_arg', found, r_value=smr_max_arg)
if (found .and. (smr_max_arg <= 0._dp)) &
call io_error('Error: smr_max_arg must be greater than zero')
gyrotropic_smr_max_arg = smr_max_arg
call param_get_keyword('gyrotropic_smr_max_arg', found, &
r_value=gyrotropic_smr_max_arg)
if (found .and. (gyrotropic_smr_max_arg <= 0._dp)) call io_error &
('Error: gyrotropic_smr_max_arg must be greater than zero')
!-------------------------------------------------------
! alpha=0
! call param_get_keyword('alpha',found,i_value=alpha)
! beta=0
! call param_get_keyword('beta',found,i_value=beta)
! gamma=0
! call param_get_keyword('gamma',found,i_value=gamma)
!-------------------------------------------------------
berry_curv_adpt_kmesh = 1
call param_get_keyword('berry_curv_adpt_kmesh', found, &
i_value=berry_curv_adpt_kmesh)
if (berry_curv_adpt_kmesh < 1) &
call io_error( &
'Error: berry_curv_adpt_kmesh must be a positive integer')
berry_curv_adpt_kmesh_thresh = 100.0_dp
call param_get_keyword('berry_curv_adpt_kmesh_thresh', found, &
r_value=berry_curv_adpt_kmesh_thresh)
berry_curv_unit = 'ang2'
call param_get_keyword('berry_curv_unit', found, c_value=berry_curv_unit)
if (berry_curv_unit .ne. 'ang2' .and. berry_curv_unit .ne. 'bohr2') &
call io_error &
('Error: value of berry_curv_unit not recognised in param_read')
wanint_kpoint_file = .false.
call param_get_keyword('wanint_kpoint_file', found, &
l_value=wanint_kpoint_file)
! smear_temp = -1.0_dp
! call param_get_keyword('smear_temp',found,r_value=smear_temp)
kubo_adpt_smr = adpt_smr
call param_get_keyword('kubo_adpt_smr', found, l_value=kubo_adpt_smr)
kubo_adpt_smr_fac = adpt_smr_fac
call param_get_keyword('kubo_adpt_smr_fac', found, &
r_value=kubo_adpt_smr_fac)
if (found .and. (kubo_adpt_smr_fac <= 0._dp)) call io_error &
('Error: kubo_adpt_smr_fac must be greater than zero')
kubo_adpt_smr_max = adpt_smr_max
call param_get_keyword('kubo_adpt_smr_max', found, &
r_value=kubo_adpt_smr_max)
if (kubo_adpt_smr_max <= 0._dp) call io_error &
('Error: kubo_adpt_smr_max must be greater than zero')
kubo_smr_fixed_en_width = smr_fixed_en_width
call param_get_keyword('kubo_smr_fixed_en_width', found, &
r_value=kubo_smr_fixed_en_width)
if (found .and. (kubo_smr_fixed_en_width < 0._dp)) call io_error &
('Error: kubo_smr_fixed_en_width must be greater than or equal to zero')
gyrotropic_smr_fixed_en_width = smr_fixed_en_width
call param_get_keyword('gyrotropic_smr_fixed_en_width', found, &
r_value=gyrotropic_smr_fixed_en_width)
if (found .and. (gyrotropic_smr_fixed_en_width < 0._dp)) call io_error &
('Error: gyrotropic_smr_fixed_en_width must be greater than or equal to zero')
sc_phase_conv = 1
call param_get_keyword('sc_phase_conv', found, i_value=sc_phase_conv)
if ((sc_phase_conv .ne. 1) .and. ((sc_phase_conv .ne. 2))) call io_error('Error: sc_phase_conv must be either 1 or 2')
scissors_shift = 0.0_dp
call param_get_keyword('scissors_shift', found, &
r_value=scissors_shift)
shc_freq_scan = .false.
call param_get_keyword('shc_freq_scan', found, l_value=shc_freq_scan)
shc_alpha = 1
call param_get_keyword('shc_alpha', found, i_value=shc_alpha)
if (found .and. (shc_alpha < 1 .or. shc_alpha > 3)) call io_error &
('Error: shc_alpha must be 1, 2 or 3')
shc_beta = 2
call param_get_keyword('shc_beta', found, i_value=shc_beta)
if (found .and. (shc_beta < 1 .or. shc_beta > 3)) call io_error &
('Error: shc_beta must be 1, 2 or 3')
shc_gamma = 3
call param_get_keyword('shc_gamma', found, i_value=shc_gamma)
if (found .and. (shc_gamma < 1 .or. shc_gamma > 3)) call io_error &
('Error: shc_gamma must be 1, 2 or 3')
shc_bandshift = .false.
call param_get_keyword('shc_bandshift', found, l_value=shc_bandshift)
shc_bandshift = shc_bandshift .and. berry .and. .not. (index(berry_task, 'shc') == 0)
if ((abs(scissors_shift) > 1.0e-7_dp) .and. shc_bandshift) &
call io_error('Error: shc_bandshift and scissors_shift cannot be used simultaneously')
shc_bandshift_firstband = 0
call param_get_keyword('shc_bandshift_firstband', found, i_value=shc_bandshift_firstband)
if (shc_bandshift .and. (.not. found)) &
call io_error('Error: shc_bandshift required but no shc_bandshift_firstband provided')
if ((shc_bandshift_firstband < 1) .and. found) &
call io_error('Error: shc_bandshift_firstband must >= 1')
shc_bandshift_energyshift = 0._dp
call param_get_keyword('shc_bandshift_energyshift', found, r_value=shc_bandshift_energyshift)
if (shc_bandshift .and. (.not. found)) &
call io_error('Error: shc_bandshift required but no shc_bandshift_energyshift provided')
spin_moment = .false.
call param_get_keyword('spin_moment', found, &
l_value=spin_moment)
spin_axis_polar = 0.0_dp
call param_get_keyword('spin_axis_polar', found, &
r_value=spin_axis_polar)
spin_axis_azimuth = 0.0_dp
call param_get_keyword('spin_axis_azimuth', found, &
r_value=spin_axis_azimuth)
spin_decomp = .false.
call param_get_keyword('spin_decomp', found, l_value=spin_decomp)
if (spin_decomp .and. (num_elec_per_state .ne. 1)) then
call io_error('spin_decomp can be true only if num_elec_per_state is 1')
end if
use_degen_pert = .false.
call param_get_keyword('use_degen_pert', found, &
l_value=use_degen_pert)
degen_thr = 1.0d-4
call param_get_keyword('degen_thr', found, r_value=degen_thr)
kpath = .false.
call param_get_keyword('kpath', found, l_value=kpath)
kpath_task = 'bands'
call param_get_keyword('kpath_task', found, c_value=kpath_task)
if (kpath .and. index(kpath_task, 'bands') == 0 .and. &
index(kpath_task, 'curv') == 0 .and. &
index(kpath_task, 'morb') == 0 .and. &
index(kpath_task, 'shc') == 0) call io_error &
('Error: value of kpath_task not recognised in param_read')
if (bands_num_spec_points == 0 .and. kpath) &
call io_error('Error: a kpath plot has been requested but there is no kpoint_path block')
kpath_num_points = 100
call param_get_keyword('kpath_num_points', found, &
i_value=kpath_num_points)
if (kpath_num_points < 0) &
call io_error('Error: kpath_num_points must be positive')
kpath_bands_colour = 'none'
call param_get_keyword('kpath_bands_colour', found, &
c_value=kpath_bands_colour)
if (kpath .and. index(kpath_bands_colour, 'none') == 0 .and. &
index(kpath_bands_colour, 'spin') == 0 .and. &
index(kpath_bands_colour, 'shc') == 0) call io_error &
('Error: value of kpath_bands_colour not recognised in param_read')
if (kpath .and. index(kpath_task, 'shc') > 0 .and. &
index(kpath_task, 'spin') > 0) call io_error &
("Error: kpath_task cannot include both 'shc' and 'spin'")
! set to a negative default value
num_valence_bands = -99
call param_get_keyword('num_valence_bands', found, i_value=num_valence_bands)
if (found .and. (num_valence_bands .le. 0)) &
call io_error('Error: num_valence_bands should be greater than zero')
! there is a check on this parameter later
dos_task = 'dos_plot'
if (dos) then
dos_plot = .true.
else
dos_plot = .false.
endif
call param_get_keyword('dos_task', found, c_value=dos_task)
if (dos) then
if (index(dos_task, 'dos_plot') == 0 .and. &
index(dos_task, 'find_fermi_energy') == 0) call io_error &
('Error: value of dos_task not recognised in param_read')
if (index(dos_task, 'dos_plot') > 0) dos_plot = .true.
if (index(dos_task, 'find_fermi_energy') > 0 .and. found_fermi_energy) &
call io_error &
('Error: Cannot set "dos_task = find_fermi_energy" and give a value to "fermi_energy"')
end if
! sigma_abc_onlyorb=.false.
! call param_get_keyword('sigma_abc_onlyorb',found,l_value=sigma_abc_onlyorb)
! -------------------------------------------------------------------
!IVO_END
dos_energy_step = 0.01_dp
call param_get_keyword('dos_energy_step', found, r_value=dos_energy_step)
dos_adpt_smr = adpt_smr
call param_get_keyword('dos_adpt_smr', found, l_value=dos_adpt_smr)
dos_adpt_smr_fac = adpt_smr_fac
call param_get_keyword('dos_adpt_smr_fac', found, r_value=dos_adpt_smr_fac)
if (found .and. (dos_adpt_smr_fac <= 0._dp)) &
call io_error('Error: dos_adpt_smr_fac must be greater than zero')
dos_adpt_smr_max = adpt_smr_max
call param_get_keyword('dos_adpt_smr_max', found, r_value=dos_adpt_smr_max)
if (dos_adpt_smr_max <= 0._dp) call io_error &
('Error: dos_adpt_smr_max must be greater than zero')
dos_smr_fixed_en_width = smr_fixed_en_width
call param_get_keyword('dos_smr_fixed_en_width', found, r_value=dos_smr_fixed_en_width)
if (found .and. (dos_smr_fixed_en_width < 0._dp)) &
call io_error('Error: dos_smr_fixed_en_width must be greater than or equal to zero')
! dos_gaussian_width = 0.1_dp
! call param_get_keyword('dos_gaussian_width',found,r_value=dos_gaussian_width)
! dos_plot_format = 'gnuplot'
! call param_get_keyword('dos_plot_format',found,c_value=dos_plot_format)
call param_get_range_vector('dos_project', found, num_dos_project, &
lcount=.true.)
if (found) then
if (num_dos_project < 1) call io_error('Error: problem reading dos_project')
if (allocated(dos_project)) deallocate (dos_project)
allocate (dos_project(num_dos_project), stat=ierr)
if (ierr /= 0) call io_error('Error allocating dos_project in param_read')
call param_get_range_vector('dos_project', found, num_dos_project, &
.false., dos_project)
if (any(dos_project < 1) .or. any(dos_project > num_wann)) call io_error &
('Error: dos_project asks for out-of-range Wannier functions')
else
! by default plot all
num_dos_project = num_wann
if (allocated(dos_project)) deallocate (dos_project)
allocate (dos_project(num_dos_project), stat=ierr)
if (ierr /= 0) call io_error('Error allocating dos_project in param_read')
do i = 1, num_dos_project
dos_project(i) = i
end do
endif
hr_plot = .false.
call param_get_keyword('hr_plot', found, l_value=hr_plot)
if (found) call io_error('Input parameter hr_plot is no longer used. Please use write_hr instead.')
write_hr = .false.
call param_get_keyword('write_hr', found, l_value=write_hr)
write_rmn = .false.
call param_get_keyword('write_rmn', found, l_value=write_rmn)
write_tb = .false.
call param_get_keyword('write_tb', found, l_value=write_tb)
hr_cutoff = 0.0_dp
call param_get_keyword('hr_cutoff', found, r_value=hr_cutoff)
dist_cutoff_mode = 'three_dim'
call param_get_keyword('dist_cutoff_mode', found, c_value=dist_cutoff_mode)
if ((index(dist_cutoff_mode, 'three_dim') .eq. 0) &
.and. (index(dist_cutoff_mode, 'two_dim') .eq. 0) &
.and. (index(dist_cutoff_mode, 'one_dim') .eq. 0)) &
call io_error('Error: dist_cutoff_mode not recognised')
! aam_2012-04-13: moved later
! dist_cutoff = 1000.0_dp
! call param_get_keyword('dist_cutoff',found,r_value=dist_cutoff)
one_dim_axis = 'none'
call param_get_keyword('one_dim_axis', found, c_value=one_dim_axis)
one_dim_dir = 0
if (index(one_dim_axis, 'x') > 0) one_dim_dir = 1
if (index(one_dim_axis, 'y') > 0) one_dim_dir = 2
if (index(one_dim_axis, 'z') > 0) one_dim_dir = 3
if (transport .and. .not. tran_read_ht .and. (one_dim_dir .eq. 0)) call io_error('Error: one_dim_axis not recognised')
if (bands_plot .and. (index(bands_plot_mode, 'cut') .ne. 0)&
& .and. ((bands_plot_dim .ne. 3) .or. (index(dist_cutoff_mode, 'three_dim') .eq. 0))&
& .and. (one_dim_dir .eq. 0)) &
call io_error('Error: one_dim_axis not recognised')
301 continue
use_ws_distance = .true.
call param_get_keyword('use_ws_distance', found, l_value=use_ws_distance)
ws_distance_tol = 1.e-5_dp
call param_get_keyword('ws_distance_tol', found, r_value=ws_distance_tol)
ws_search_size = 2
call param_get_vector_length('ws_search_size', found, length=i)
if (found) then
if (i .eq. 1) then
call param_get_keyword_vector('ws_search_size', found, 1, &
i_value=ws_search_size)
ws_search_size(2) = ws_search_size(1)
ws_search_size(3) = ws_search_size(1)
elseif (i .eq. 3) then
call param_get_keyword_vector('ws_search_size', found, 3, &
i_value=ws_search_size)
else
call io_error('Error: ws_search_size must be provided as either one integer or a vector of three integers')
end if
if (any(ws_search_size <= 0)) &
call io_error('Error: ws_search_size elements must be greater than zero')
end if
!%%%%%%%%%%%%%%%%
! Transport
!%%%%%%%%%%%%%%%%
transport_mode = 'bulk'
call param_get_keyword('transport_mode', found, c_value=transport_mode)
! if ( .not.tran_read_ht .and. (index(transport_mode,'lcr').ne.0) ) &
! call io_error('Error: transport_mode.eq.lcr not compatible with tran_read_ht.eq.false')
tran_win_min = -3.0_dp
call param_get_keyword('tran_win_min', found, r_value=tran_win_min)
tran_win_max = 3.0_dp
call param_get_keyword('tran_win_max', found, r_value=tran_win_max)
tran_energy_step = 0.01_dp
call param_get_keyword('tran_energy_step', found, r_value=tran_energy_step)
tran_num_bb = 0
call param_get_keyword('tran_num_bb', found, i_value=tran_num_bb)
tran_num_ll = 0
call param_get_keyword('tran_num_ll', found, i_value=tran_num_ll)
tran_num_rr = 0
call param_get_keyword('tran_num_rr', found, i_value=tran_num_rr)
tran_num_cc = 0
call param_get_keyword('tran_num_cc', found, i_value=tran_num_cc)
tran_num_lc = 0
call param_get_keyword('tran_num_lc', found, i_value=tran_num_lc)
tran_num_cr = 0
call param_get_keyword('tran_num_cr', found, i_value=tran_num_cr)
tran_num_bandc = 0
call param_get_keyword('tran_num_bandc', found, i_value=tran_num_bandc)
tran_write_ht = .false.
call param_get_keyword('tran_write_ht', found, l_value=tran_write_ht)
tran_use_same_lead = .true.
call param_get_keyword('tran_use_same_lead', found, l_value=tran_use_same_lead)
tran_num_cell_ll = 0
call param_get_keyword('tran_num_cell_ll', found, i_value=tran_num_cell_ll)
tran_num_cell_rr = 0
call param_get_keyword('tran_num_cell_rr', found, i_value=tran_num_cell_rr)
tran_group_threshold = 0.15_dp
call param_get_keyword('tran_group_threshold', found, r_value=tran_group_threshold)
dist_cutoff = 1000.0_dp
call param_get_keyword('dist_cutoff', found, r_value=dist_cutoff)
dist_cutoff_hc = dist_cutoff
call param_get_keyword('dist_cutoff_hc', found, r_value=dist_cutoff_hc)
! checks
if (transport) then
if ((index(transport_mode, 'bulk') .eq. 0) .and. (index(transport_mode, 'lcr') .eq. 0)) &
call io_error('Error: transport_mode not recognised')
if (tran_num_bb < 0) call io_error('Error: tran_num_bb < 0')
if (tran_num_ll < 0) call io_error('Error: tran_num_ll < 0')
if (tran_num_rr < 0) call io_error('Error: tran_num_rr < 0')
if (tran_num_cc < 0) call io_error('Error: tran_num_cc < 0')
if (tran_num_lc < 0) call io_error('Error: tran_num_lc < 0')
if (tran_num_cr < 0) call io_error('Error: tran_num_cr < 0')
if (tran_num_bandc < 0) call io_error('Error: tran_num_bandc < 0')
if (tran_num_cell_ll < 0) call io_error('Error: tran_num_cell_ll < 0')
if (tran_num_cell_rr < 0) call io_error('Error: tran_num_cell_rr < 0')
if (tran_group_threshold < 0.0_dp) call io_error('Error: tran_group_threshold < 0')
endif
if (transport .and. tran_read_ht) goto 302
!%%%%%%%%%%%%%%%%
! Disentanglement
!%%%%%%%%%%%%%%%%
disentanglement = .false.
if (num_bands > num_wann) disentanglement = .true.
! These must be read here, before the check on the existence of the .eig file!
geninterp = .false.
call param_get_keyword('geninterp', found, l_value=geninterp)
boltzwann = .false.
call param_get_keyword('boltzwann', found, l_value=boltzwann)
! Read the eigenvalues from wannier.eig
eig_found = .false.
if (.not. library .and. .not. effective_model) then
if (.not. postproc_setup) then
inquire (file=trim(seedname)//'.eig', exist=eig_found)
if (.not. eig_found) then
if (disentanglement) then
call io_error('No '//trim(seedname)//'.eig file found. Needed for disentanglement')
else if ((bands_plot .or. dos_plot .or. fermi_surface_plot .or. write_hr .or. boltzwann &
.or. geninterp)) then
call io_error('No '//trim(seedname)//'.eig file found. Needed for interpolation')
end if
else
! Allocate only here
allocate (eigval(num_bands, num_kpts), stat=ierr)
if (ierr /= 0) call io_error('Error allocating eigval in param_read')
eig_unit = io_file_unit()
open (unit=eig_unit, file=trim(seedname)//'.eig', form='formatted', status='old', err=105)
do k = 1, num_kpts
do n = 1, num_bands
read (eig_unit, *, err=106, end=106) i, j, eigval(n, k)
if ((i .ne. n) .or. (j .ne. k)) then
write (stdout, '(a)') 'Found a mismatch in '//trim(seedname)//'.eig'
write (stdout, '(a,i0,a,i0)') 'Wanted band : ', n, ' found band : ', i
write (stdout, '(a,i0,a,i0)') 'Wanted kpoint: ', k, ' found kpoint: ', j
write (stdout, '(a)') ' '
write (stdout, '(a)') 'A common cause of this error is using the wrong'
write (stdout, '(a)') 'number of bands. Check your input files.'
write (stdout, '(a)') 'If your pseudopotentials have shallow core states remember'
write (stdout, '(a)') 'to account for these electrons.'
write (stdout, '(a)') ' '
call io_error('param_read: mismatch in '//trim(seedname)//'.eig')
end if
enddo
end do
close (eig_unit)
end if
end if
end if
if (library .and. allocated(eigval)) eig_found = .true.
dis_win_min = -1.0_dp; dis_win_max = 0.0_dp
if (eig_found) dis_win_min = minval(eigval)
call param_get_keyword('dis_win_min', found, r_value=dis_win_min)
if (eig_found) dis_win_max = maxval(eigval)
call param_get_keyword('dis_win_max', found, r_value=dis_win_max)
if (eig_found .and. (dis_win_max .lt. dis_win_min)) &
call io_error('Error: param_read: check disentanglement windows')
dis_froz_min = -1.0_dp; dis_froz_max = 0.0_dp
! no default for dis_froz_max
frozen_states = .false.
call param_get_keyword('dis_froz_max', found, r_value=dis_froz_max)
if (found) then
frozen_states = .true.
dis_froz_min = dis_win_min ! default value for the bottom of frozen window
end if
call param_get_keyword('dis_froz_min', found2, r_value=dis_froz_min)
if (eig_found) then
if (dis_froz_max .lt. dis_froz_min) &
call io_error('Error: param_read: check disentanglement frozen windows')
if (found2 .and. .not. found) &
call io_error('Error: param_read: found dis_froz_min but not dis_froz_max')
endif
dis_num_iter = 200
call param_get_keyword('dis_num_iter', found, i_value=dis_num_iter)
if (dis_num_iter < 0) call io_error('Error: dis_num_iter must be positive')
dis_mix_ratio = 0.5_dp
call param_get_keyword('dis_mix_ratio', found, r_value=dis_mix_ratio)
if (dis_mix_ratio <= 0.0_dp .or. dis_mix_ratio > 1.0_dp) &
call io_error('Error: dis_mix_ratio must be greater than 0.0 but not greater than 1.0')
dis_conv_tol = 1.0e-10_dp
call param_get_keyword('dis_conv_tol', found, r_value=dis_conv_tol)
if (dis_conv_tol < 0.0_dp) call io_error('Error: dis_conv_tol must be positive')
dis_conv_window = 3
call param_get_keyword('dis_conv_window', found, i_value=dis_conv_window)
if (dis_conv_window < 0) call io_error('Error: dis_conv_window must be positive')
! GS-start
dis_spheres_first_wann = 1
call param_get_keyword('dis_spheres_first_wann', found, i_value=dis_spheres_first_wann)
if (dis_spheres_first_wann < 1) call io_error('Error: dis_spheres_first_wann must be greater than 0')
if (dis_spheres_first_wann > num_bands - num_wann + 1) &
call io_error('Error: dis_spheres_first_wann is larger than num_bands-num_wann+1')
dis_spheres_num = 0
call param_get_keyword('dis_spheres_num', found, i_value=dis_spheres_num)
if (dis_spheres_num < 0) call io_error('Error: dis_spheres_num cannot be negative')
if (dis_spheres_num > 0) then
allocate (dis_spheres(4, dis_spheres_num), stat=ierr)
if (ierr /= 0) call io_error('Error allocating dis_spheres in param_read')
call param_get_keyword_block('dis_spheres', found, dis_spheres_num, 4, r_value=dis_spheres)
if (.not. found) call io_error('Error: Did not find dis_spheres in the input file')
do nkp = 1, dis_spheres_num
if (dis_spheres(4, nkp) < 1.0e-15_dp) &
call io_error('Error: radius for dis_spheres must be > 0')
enddo
endif
! GS-end
! [gp-begin, Jun 1, 2012]
!%%%%%%%%%%%%%%%%%%%%
! General band interpolator (geninterp)
!%%%%%%%%%%%%%%%%%%%%
geninterp_alsofirstder = .false.
call param_get_keyword('geninterp_alsofirstder', found, l_value=geninterp_alsofirstder)
geninterp_single_file = .true.
call param_get_keyword('geninterp_single_file', found, l_value=geninterp_single_file)
! [gp-end, Jun 1, 2012]
! [gp-begin, Apr 12, 2012]
!%%%%%%%%%%%%%%%%%%%%
! Boltzmann transport
!%%%%%%%%%%%%%%%%%%%%
! Note: to be put AFTER the disentanglement routines!
boltz_calc_also_dos = .false.
call param_get_keyword('boltz_calc_also_dos', found, l_value=boltz_calc_also_dos)
boltz_calc_also_dos = boltz_calc_also_dos .and. boltzwann
! 0 means the normal 3d case for the calculation of the Seebeck coefficient
! The other valid possibilities are 1,2,3 for x,y,z respectively
boltz_2d_dir_num = 0
call param_get_keyword('boltz_2d_dir', found, c_value=boltz_2d_dir)
if (found) then
if (trim(boltz_2d_dir) == 'no') then
boltz_2d_dir_num = 0
elseif (trim(boltz_2d_dir) == 'x') then
boltz_2d_dir_num = 1
elseif (trim(boltz_2d_dir) == 'y') then
boltz_2d_dir_num = 2
elseif (trim(boltz_2d_dir) == 'z') then
boltz_2d_dir_num = 3
else
call io_error('Error: boltz_2d_dir can only be "no", "x", "y" or "z".')
end if
end if
boltz_dos_energy_step = 0.001_dp
call param_get_keyword('boltz_dos_energy_step', found, r_value=boltz_dos_energy_step)
if (found .and. (boltz_dos_energy_step <= 0._dp)) &
call io_error('Error: boltz_dos_energy_step must be positive')
if (allocated(eigval)) then
boltz_dos_energy_min = minval(eigval) - 0.6667_dp
else
! Boltz_dos cannot run if eigval is not allocated.
! We just set here a default numerical value.
boltz_dos_energy_min = -1.0_dp
end if
call param_get_keyword('boltz_dos_energy_min', found, r_value=boltz_dos_energy_min)
if (allocated(eigval)) then
boltz_dos_energy_max = maxval(eigval) + 0.6667_dp
else
! Boltz_dos cannot run if eigval is not allocated.
! We just set here a default numerical value.
boltz_dos_energy_max = 0.0_dp
end if
call param_get_keyword('boltz_dos_energy_max', found, r_value=boltz_dos_energy_max)
if (boltz_dos_energy_max <= boltz_dos_energy_min) &
call io_error('Error: boltz_dos_energy_max must be greater than boltz_dos_energy_min')
boltz_dos_adpt_smr = adpt_smr
call param_get_keyword('boltz_dos_adpt_smr', found, l_value=boltz_dos_adpt_smr)
boltz_dos_adpt_smr_fac = adpt_smr_fac
call param_get_keyword('boltz_dos_adpt_smr_fac', found, r_value=boltz_dos_adpt_smr_fac)
if (found .and. (boltz_dos_adpt_smr_fac <= 0._dp)) &
call io_error('Error: boltz_dos_adpt_smr_fac must be greater than zero')
boltz_dos_adpt_smr_max = adpt_smr_max
call param_get_keyword('boltz_dos_adpt_smr_max', found, r_value=boltz_dos_adpt_smr_max)
if (boltz_dos_adpt_smr_max <= 0._dp) call io_error &
('Error: boltz_dos_adpt_smr_max must be greater than zero')
boltz_dos_smr_fixed_en_width = smr_fixed_en_width
call param_get_keyword('boltz_dos_smr_fixed_en_width', found, r_value=boltz_dos_smr_fixed_en_width)
if (found .and. (boltz_dos_smr_fixed_en_width < 0._dp)) &
call io_error('Error: boltz_dos_smr_fixed_en_width must be greater than or equal to zero')
boltz_mu_min = -999._dp
call param_get_keyword('boltz_mu_min', found, r_value=boltz_mu_min)
if ((.not. found) .and. boltzwann) &
call io_error('Error: BoltzWann required but no boltz_mu_min provided')
boltz_mu_max = -999._dp
call param_get_keyword('boltz_mu_max', found2, r_value=boltz_mu_max)
if ((.not. found2) .and. boltzwann) &
call io_error('Error: BoltzWann required but no boltz_mu_max provided')
if (found .and. found2 .and. (boltz_mu_max < boltz_mu_min)) &
call io_error('Error: boltz_mu_max must be greater than boltz_mu_min')
boltz_mu_step = 0._dp
call param_get_keyword('boltz_mu_step', found, r_value=boltz_mu_step)
if ((.not. found) .and. boltzwann) &
call io_error('Error: BoltzWann required but no boltz_mu_step provided')
if (found .and. (boltz_mu_step <= 0._dp)) &
call io_error('Error: boltz_mu_step must be greater than zero')
boltz_temp_min = -999._dp
call param_get_keyword('boltz_temp_min', found, r_value=boltz_temp_min)
if ((.not. found) .and. boltzwann) &
call io_error('Error: BoltzWann required but no boltz_temp_min provided')
boltz_temp_max = -999._dp
call param_get_keyword('boltz_temp_max', found2, r_value=boltz_temp_max)
if ((.not. found2) .and. boltzwann) &
call io_error('Error: BoltzWann required but no boltz_temp_max provided')
if (found .and. found2 .and. (boltz_temp_max < boltz_temp_min)) &
call io_error('Error: boltz_temp_max must be greater than boltz_temp_min')
if (found .and. (boltz_temp_min <= 0._dp)) &
call io_error('Error: boltz_temp_min must be greater than zero')
boltz_temp_step = 0._dp
call param_get_keyword('boltz_temp_step', found, r_value=boltz_temp_step)
if ((.not. found) .and. boltzwann) &
call io_error('Error: BoltzWann required but no boltz_temp_step provided')
if (found .and. (boltz_temp_step <= 0._dp)) &
call io_error('Error: boltz_temp_step must be greater than zero')
! The interpolation mesh is read later on
! By default, the energy step for the TDF is 1 meV
boltz_tdf_energy_step = 0.001_dp
call param_get_keyword('boltz_tdf_energy_step', found, r_value=boltz_tdf_energy_step)
if (boltz_tdf_energy_step <= 0._dp) &
call io_error('Error: boltz_tdf_energy_step must be greater than zero')
! For TDF: TDF smeared in a NON-adaptive way; value in eV, default = 0._dp
! (i.e., no smearing)
boltz_TDF_smr_fixed_en_width = smr_fixed_en_width
call param_get_keyword('boltz_tdf_smr_fixed_en_width', found, r_value=boltz_TDF_smr_fixed_en_width)
if (found .and. (boltz_TDF_smr_fixed_en_width < 0._dp)) &
call io_error('Error: boltz_TDF_smr_fixed_en_width must be greater than or equal to zero')
! By default: use the "global" smearing index
boltz_TDF_smr_index = smr_index
call param_get_keyword('boltz_tdf_smr_type', found, c_value=ctmp)
if (found) boltz_TDF_smr_index = get_smearing_index(ctmp, 'boltz_tdf_smr_type')
! By default: use the "global" smearing index
boltz_dos_smr_index = smr_index
call param_get_keyword('boltz_dos_smr_type', found, c_value=ctmp)
if (found) boltz_dos_smr_index = get_smearing_index(ctmp, 'boltz_dos_smr_type')
! By default: use the "global" smearing index
dos_smr_index = smr_index
call param_get_keyword('dos_smr_type', found, c_value=ctmp)
if (found) dos_smr_index = get_smearing_index(ctmp, 'dos_smr_type')
! By default: use the "global" smearing index
kubo_smr_index = smr_index
call param_get_keyword('kubo_smr_type', found, c_value=ctmp)
if (found) kubo_smr_index = get_smearing_index(ctmp, 'kubo_smr_type')
! By default: use the "global" smearing index
gyrotropic_smr_index = smr_index
call param_get_keyword('gyrotropic_smr_type', found, c_value=ctmp)
if (found) gyrotropic_smr_index = get_smearing_index(ctmp, 'gyrotropic_smr_type')
! By default: 10 fs relaxation time
boltz_relax_time = 10._dp
call param_get_keyword('boltz_relax_time', found, r_value=boltz_relax_time)
boltz_bandshift = .false.
call param_get_keyword('boltz_bandshift', found, l_value=boltz_bandshift)
boltz_bandshift = boltz_bandshift .and. boltzwann
boltz_bandshift_firstband = 0
call param_get_keyword('boltz_bandshift_firstband', found, i_value=boltz_bandshift_firstband)
if (boltz_bandshift .and. (.not. found)) &
call io_error('Error: boltz_bandshift required but no boltz_bandshift_firstband provided')
boltz_bandshift_energyshift = 0._dp
call param_get_keyword('boltz_bandshift_energyshift', found, r_value=boltz_bandshift_energyshift)
if (boltz_bandshift .and. (.not. found)) &
call io_error('Error: boltz_bandshift required but no boltz_bandshift_energyshift provided')
! [gp-end, Apr 12, 2012]
!%%%%%%%%%%%%%%%%
! Other Stuff
!%%%%%%%%%%%%%%%%
! aam: vdW
write_vdw_data = .false.
call param_get_keyword('write_vdw_data', found, l_value=write_vdw_data)
if (write_vdw_data) then
if ((.not. gamma_only) .or. (num_kpts .ne. 1)) &
call io_error('Error: write_vdw_data may only be used with a single k-point at Gamma')
endif
if (write_vdw_data .and. disentanglement .and. num_valence_bands .le. 0) &
call io_error('If writing vdw data and disentangling then num_valence_bands must be defined')
if (frozen_states) then
dos_energy_max = dis_froz_max + 0.6667_dp
elseif (allocated(eigval)) then
dos_energy_max = maxval(eigval) + 0.6667_dp
else
dos_energy_max = dis_win_max + 0.6667_dp
end if
call param_get_keyword('dos_energy_max', found, r_value=dos_energy_max)
if (allocated(eigval)) then
dos_energy_min = minval(eigval) - 0.6667_dp
else
dos_energy_min = dis_win_min - 0.6667_dp
end if
call param_get_keyword('dos_energy_min', found, r_value=dos_energy_min)
kubo_freq_min = 0.0_dp
gyrotropic_freq_min = kubo_freq_min
call param_get_keyword('kubo_freq_min', found, r_value=kubo_freq_min)
!
if (frozen_states) then
kubo_freq_max = dis_froz_max - fermi_energy_list(1) + 0.6667_dp
elseif (allocated(eigval)) then
kubo_freq_max = maxval(eigval) - minval(eigval) + 0.6667_dp
else
kubo_freq_max = dis_win_max - dis_win_min + 0.6667_dp
end if
gyrotropic_freq_max = kubo_freq_max
call param_get_keyword('kubo_freq_max', found, r_value=kubo_freq_max)
!
kubo_freq_step = 0.01_dp
call param_get_keyword('kubo_freq_step', found, r_value=kubo_freq_step)
if (found .and. kubo_freq_step < 0.0_dp) call io_error( &
'Error: kubo_freq_step must be positive')
!
kubo_nfreq = nint((kubo_freq_max - kubo_freq_min)/kubo_freq_step) + 1
if (kubo_nfreq <= 1) kubo_nfreq = 2
kubo_freq_step = (kubo_freq_max - kubo_freq_min)/(kubo_nfreq - 1)
!
if (allocated(kubo_freq_list)) deallocate (kubo_freq_list)
allocate (kubo_freq_list(kubo_nfreq), stat=ierr)
if (ierr /= 0) &
call io_error('Error allocating kubo_freq_list in param_read')
do i = 1, kubo_nfreq
kubo_freq_list(i) = kubo_freq_min &
+ (i - 1)*(kubo_freq_max - kubo_freq_min)/(kubo_nfreq - 1)
enddo
!
! TODO: Alternatively, read list of (complex) frequencies; kubo_nfreq is
! the length of the list
gyrotropic_freq_step = 0.01_dp
call param_get_keyword('gyrotropic_freq_min', found, r_value=gyrotropic_freq_min)
call param_get_keyword('gyrotropic_freq_max', found, r_value=gyrotropic_freq_max)
call param_get_keyword('gyrotropic_freq_step', found, r_value=gyrotropic_freq_step)
gyrotropic_nfreq = nint((gyrotropic_freq_max - gyrotropic_freq_min)/gyrotropic_freq_step) + 1
if (gyrotropic_nfreq <= 1) gyrotropic_nfreq = 2
gyrotropic_freq_step = (gyrotropic_freq_max - gyrotropic_freq_min)/(gyrotropic_nfreq - 1)
if (allocated(gyrotropic_freq_list)) deallocate (gyrotropic_freq_list)
allocate (gyrotropic_freq_list(gyrotropic_nfreq), stat=ierr)
if (ierr /= 0) &
call io_error('Error allocating gyrotropic_freq_list in param_read')
do i = 1, gyrotropic_nfreq
gyrotropic_freq_list(i) = gyrotropic_freq_min &
+ (i - 1)*(gyrotropic_freq_max - gyrotropic_freq_min)/(gyrotropic_nfreq - 1) &
+ cmplx_i*gyrotropic_smr_fixed_en_width
enddo
if (frozen_states) then
kubo_eigval_max = dis_froz_max + 0.6667_dp
elseif (allocated(eigval)) then
kubo_eigval_max = maxval(eigval) + 0.6667_dp
else
kubo_eigval_max = dis_win_max + 0.6667_dp
end if
gyrotropic_eigval_max = kubo_eigval_max
call param_get_keyword('kubo_eigval_max', found, r_value=kubo_eigval_max)
call param_get_keyword('gyrotropic_eigval_max', found, r_value=gyrotropic_eigval_max)
automatic_translation = .true.
translation_centre_frac = 0.0_dp
call param_get_keyword_vector('translation_centre_frac', found, 3, r_value=rv_temp)
if (found) then
translation_centre_frac = rv_temp
automatic_translation = .false.
endif
sc_eta = 0.04
call param_get_keyword('sc_eta', found, r_value=sc_eta)
sc_w_thr = 5.0d0
call param_get_keyword('sc_w_thr', found, r_value=sc_w_thr)
use_bloch_phases = .false.
call param_get_keyword('use_bloch_phases', found, l_value=use_bloch_phases)
if (disentanglement .and. use_bloch_phases) &
call io_error('Error: Cannot use bloch phases for disentanglement')
search_shells = 36
call param_get_keyword('search_shells', found, i_value=search_shells)
if (search_shells < 0) call io_error('Error: search_shells must be positive')
kmesh_tol = 0.000001_dp
call param_get_keyword('kmesh_tol', found, r_value=kmesh_tol)
if (kmesh_tol < 0.0_dp) call io_error('Error: kmesh_tol must be positive')
num_shells = 0
call param_get_range_vector('shell_list', found, num_shells, lcount=.true.)
if (found) then
if (num_shells < 0 .or. num_shells > max_shells) &
call io_error('Error: number of shell in shell_list must be between zero and six')
if (allocated(shell_list)) deallocate (shell_list)
allocate (shell_list(num_shells), stat=ierr)
if (ierr /= 0) call io_error('Error allocating shell_list in param_read')
call param_get_range_vector('shell_list', found, num_shells, .false., shell_list)
if (any(shell_list < 1)) &
call io_error('Error: shell_list must contain positive numbers')
else
if (allocated(shell_list)) deallocate (shell_list)
allocate (shell_list(max_shells), stat=ierr)
if (ierr /= 0) call io_error('Error allocating shell_list in param_read')
end if
call param_get_keyword('num_shells', found, i_value=itmp)
if (found .and. (itmp /= num_shells)) &
call io_error('Error: Found obsolete keyword num_shells. Its value does not agree with shell_list')
! If .true., does not perform the check of B1 of
! Marzari, Vanderbild, PRB 56, 12847 (1997)
! in kmesh.F90
! mainly needed for the interaction with Z2PACK
! By default: .false. (perform the tests)
skip_B1_tests = .false.
call param_get_keyword('skip_b1_tests', found, l_value=skip_B1_tests)
call param_get_keyword_block('unit_cell_cart', found, 3, 3, r_value=real_lattice_tmp)
if (found .and. library) write (stdout, '(a)') ' Ignoring <unit_cell_cart> in input file'
if (.not. library) then
real_lattice = transpose(real_lattice_tmp)
if (.not. found) call io_error('Error: Did not find the cell information in the input file')
end if
if (.not. library) &
call utility_recip_lattice(real_lattice, recip_lattice, cell_volume)
call utility_metric(real_lattice, recip_lattice, real_metric, recip_metric)
if (.not. effective_model) allocate (kpt_cart(3, num_kpts), stat=ierr)
if (ierr /= 0) call io_error('Error allocating kpt_cart in param_read')
if (.not. library .and. .not. effective_model) then
allocate (kpt_latt(3, num_kpts), stat=ierr)
if (ierr /= 0) call io_error('Error allocating kpt_latt in param_read')
end if
call param_get_keyword_block('kpoints', found, num_kpts, 3, r_value=kpt_cart)
if (found .and. library) write (stdout, '(a)') ' Ignoring <kpoints> in input file'
if (.not. library .and. .not. effective_model) then
kpt_latt = kpt_cart
if (.not. found) call io_error('Error: Did not find the kpoint information in the input file')
end if
! Calculate the kpoints in cartesian coordinates
if (.not. effective_model) then
do nkp = 1, num_kpts
kpt_cart(:, nkp) = matmul(kpt_latt(:, nkp), recip_lattice(:, :))
end do
endif
! get the nnkpts block -- this is allowed only in postproc-setup mode
call param_get_block_length('nnkpts', explicit_nnkpts, rows)
if (explicit_nnkpts) then
nntot = rows/num_kpts
if (modulo(rows, num_kpts) /= 0) then
call io_error('The number of rows in nnkpts must be a multiple of num_kpts')
end if
if (allocated(nnkpts_block)) deallocate (nnkpts_block)
allocate (nnkpts_block(5, rows), stat=ierr)
if (ierr /= 0) call io_error('Error allocating nnkpts_block in param_read')
call param_get_keyword_block('nnkpts', found, rows, 5, i_value=nnkpts_block)
! check that postproc_setup is true
if (.not. postproc_setup) &
call io_error('Input parameter nnkpts_block is allowed only if postproc_setup = .true.')
! assign the values in nnkpts_block to nnlist and nncell
! this keeps track of how many neighbours have been seen for each k-point
if (allocated(nnkpts_idx)) deallocate (nnkpts_idx)
allocate (nnkpts_idx(num_kpts), stat=ierr)
if (ierr /= 0) call io_error('Error allocating nnkpts_idx in param_read')
nnkpts_idx = 1
! allocating "global" nnlist & nncell
! These are deallocated in kmesh_dealloc
if (allocated(nnlist)) deallocate (nnlist)
allocate (nnlist(num_kpts, nntot), stat=ierr)
if (ierr /= 0) call io_error('Error allocating nnlist in param_read')
if (allocated(nncell)) deallocate (nncell)
allocate (nncell(3, num_kpts, nntot), stat=ierr)
if (ierr /= 0) call io_error('Error allocating nncell in param_read')
do i = 1, num_kpts*nntot
k = nnkpts_block(1, i)
nnlist(k, nnkpts_idx(k)) = nnkpts_block(2, i)
nncell(:, k, nnkpts_idx(k)) = nnkpts_block(3:, i)
nnkpts_idx(k) = nnkpts_idx(k) + 1
end do
! check that all k-points have the same number of neighbours
if (any(nnkpts_idx /= (/(nntot + 1, i=1, num_kpts)/))) then
call io_error('Inconsistent number of nearest neighbours.')
end if
deallocate (nnkpts_idx, stat=ierr)
if (ierr /= 0) call io_error('Error deallocating nnkpts_idx in param_read')
deallocate (nnkpts_block, stat=ierr)
if (ierr /= 0) call io_error('Error deallocating nnkpts_block in param_read')
end if
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
! k meshes !
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
! [GP-begin, Apr13, 2012]
! Global interpolation k-mesh; this is overridden by "local" meshes of a given submodule
! This bit of code must appear *before* all other codes for the local interpolation meshes,
! BUT *after* having calculated the reciprocal-space vectors.
global_kmesh_set = .false.
kmesh_spacing = -1._dp
kmesh = 0
call param_get_keyword('kmesh_spacing', found, r_value=kmesh_spacing)
if (found) then
if (kmesh_spacing .le. 0._dp) &
call io_error('Error: kmesh_spacing must be greater than zero')
global_kmesh_set = .true.
call internal_set_kmesh(kmesh_spacing, recip_lattice, kmesh)
end if
call param_get_vector_length('kmesh', found, length=i)
if (found) then
if (global_kmesh_set) &
call io_error('Error: cannot set both kmesh and kmesh_spacing')
if (i .eq. 1) then
global_kmesh_set = .true.
call param_get_keyword_vector('kmesh', found, 1, i_value=kmesh)
kmesh(2) = kmesh(1)
kmesh(3) = kmesh(1)
elseif (i .eq. 3) then
global_kmesh_set = .true.
call param_get_keyword_vector('kmesh', found, 3, i_value=kmesh)
else
call io_error('Error: kmesh must be provided as either one integer or a vector of three integers')
end if
if (any(kmesh <= 0)) &
call io_error('Error: kmesh elements must be greater than zero')
end if
! [GP-end]
! To be called after having read the global flag
call get_module_kmesh(moduleprefix='boltz', &
should_be_defined=boltzwann, &
module_kmesh=boltz_kmesh, &
module_kmesh_spacing=boltz_kmesh_spacing)
call get_module_kmesh(moduleprefix='berry', &
should_be_defined=berry, &
module_kmesh=berry_kmesh, &
module_kmesh_spacing=berry_kmesh_spacing)
call get_module_kmesh(moduleprefix='gyrotropic', &
should_be_defined=gyrotropic, &
module_kmesh=gyrotropic_kmesh, &
module_kmesh_spacing=gyrotropic_kmesh_spacing)
call get_module_kmesh(moduleprefix='spin', &
should_be_defined=spin_moment, &
module_kmesh=spin_kmesh, &
module_kmesh_spacing=spin_kmesh_spacing)
call get_module_kmesh(moduleprefix='dos', &
should_be_defined=dos, &
module_kmesh=dos_kmesh, &
module_kmesh_spacing=dos_kmesh_spacing)
! Atoms
if (.not. library) num_atoms = 0
call param_get_block_length('atoms_frac', found, i_temp)
if (found .and. library) write (stdout, '(a)') ' Ignoring <atoms_frac> in input file'
call param_get_block_length('atoms_cart', found2, i_temp2, lunits)
if (found2 .and. library) write (stdout, '(a)') ' Ignoring <atoms_cart> in input file'
if (.not. library) then
if (found .and. found2) call io_error('Error: Cannot specify both atoms_frac and atoms_cart')
if (found .and. i_temp > 0) then
lunits = .false.
num_atoms = i_temp
elseif (found2 .and. i_temp2 > 0) then
num_atoms = i_temp2
if (lunits) num_atoms = num_atoms - 1
end if
if (num_atoms > 0) then
call param_get_atoms(lunits)
end if
endif
! Projections
auto_projections = .false.
call param_get_keyword('auto_projections', found, l_value=auto_projections)
num_proj = 0
call param_get_block_length('projections', found, i_temp)
! check to see that there are no unrecognised keywords
if (found) then
if (auto_projections) call io_error('Error: Cannot specify both auto_projections and projections block')
lhasproj = .true.
call param_get_projections(num_proj, lcount=.true.)
else
if (guiding_centres .and. .not. (gamma_only .and. use_bloch_phases)) &
call io_error('param_read: Guiding centres requested, but no projection block found')
lhasproj = .false.
num_proj = num_wann
end if
lselproj = .false.
num_select_projections = 0
call param_get_range_vector('select_projections', found, num_select_projections, lcount=.true.)
if (found) then
if (num_select_projections < 1) call io_error('Error: problem reading select_projections')
if (allocated(select_projections)) deallocate (select_projections)
allocate (select_projections(num_select_projections), stat=ierr)
if (ierr /= 0) call io_error('Error allocating select_projections in param_read')
call param_get_range_vector('select_projections', found, num_select_projections, .false., select_projections)
if (any(select_projections < 1)) &
call io_error('Error: select_projections must contain positive numbers')
if (num_select_projections < num_wann) &
call io_error('Error: too few projections selected')
if (num_select_projections > num_wann) &
call io_error('Error: too many projections selected')
if (.not. lhasproj) &
call io_error('Error: select_projections cannot be used without defining the projections')
if (maxval(select_projections(:)) > num_proj) &
call io_error('Error: select_projections contains a number greater than num_proj')
lselproj = .true.
end if
if (allocated(proj2wann_map)) deallocate (proj2wann_map)
allocate (proj2wann_map(num_proj), stat=ierr)
if (ierr /= 0) call io_error('Error allocating proj2wann_map in param_read')
proj2wann_map = -1
if (lselproj) then
do i = 1, num_proj
do j = 1, num_wann
if (select_projections(j) == i) proj2wann_map(i) = j
enddo
enddo
else
do i = 1, num_wann
proj2wann_map(i) = i
enddo
endif
if (lhasproj) call param_get_projections(num_proj, lcount=.false.)
! Constrained centres
call param_get_block_length('slwf_centres', found, i_temp)
if (found) then
if (slwf_constrain) then
! Allocate array for constrained centres
call param_get_centre_constraints
else
write (stdout, '(a)') ' slwf_constrain set to false. Ignoring <slwf_centres> block '
end if
! Check that either projections or constrained centres are specified if slwf_constrain=.true.
elseif (.not. found) then
if (slwf_constrain) then
if (.not. allocated(proj_site)) then
call io_error('Error: slwf_constrain = true, but neither &
& <slwf_centre> block nor &
& <projection_block> are specified.')
else
! Allocate array for constrained centres
call param_get_centre_constraints
end if
end if
end if
! Warning
if (slwf_constrain .and. allocated(proj_site) .and. .not. found) &
& write (stdout, '(a)') ' Warning: No <slwf_centres> block found, but slwf_constrain set to true. &
& Desired centres for SLWF same as projection centres.'
302 continue
if (any(len_trim(in_data(:)) > 0)) then
write (stdout, '(1x,a)') 'The following section of file '//trim(seedname)//'.win contained unrecognised keywords'
write (stdout, *)
do loop = 1, num_lines
if (len_trim(in_data(loop)) > 0) then
write (stdout, '(1x,a)') trim(in_data(loop))
end if
end do
write (stdout, *)
call io_error('Unrecognised keyword(s) in input file, see also output file')
end if
if (transport .and. tran_read_ht) goto 303
! For aesthetic purposes, convert some things to uppercase
call param_uppercase()
303 continue
deallocate (in_data, stat=ierr)
if (ierr /= 0) call io_error('Error deallocating in_data in param_read')
if (transport .and. tran_read_ht) return
! =============================== !
! Some checks and initialisations !
! =============================== !
! if (restart.ne.' ') disentanglement=.false.
if (disentanglement) then
if (allocated(ndimwin)) deallocate (ndimwin)
allocate (ndimwin(num_kpts), stat=ierr)
if (ierr /= 0) call io_error('Error allocating ndimwin in param_read')
if (allocated(lwindow)) deallocate (lwindow)
allocate (lwindow(num_bands, num_kpts), stat=ierr)
if (ierr /= 0) call io_error('Error allocating lwindow in param_read')
endif
! if ( wannier_plot .and. (index(wannier_plot_format,'cub').ne.0) ) then
! cosa(1)=dot_product(real_lattice(1,:),real_lattice(2,:))
! cosa(2)=dot_product(real_lattice(1,:),real_lattice(3,:))
! cosa(3)=dot_product(real_lattice(2,:),real_lattice(3,:))
! cosa = abs(cosa)
! if (any(cosa.gt.eps6)) &
! call io_error('Error: plotting in cube format requires orthogonal lattice vectors')
! endif
! Initialise
omega_total = -999.0_dp
omega_tilde = -999.0_dp
omega_invariant = -999.0_dp
have_disentangled = .false.
if (allocated(wannier_centres)) deallocate (wannier_centres)
allocate (wannier_centres(3, num_wann), stat=ierr)
if (ierr /= 0) call io_error('Error allocating wannier_centres in param_read')
wannier_centres = 0.0_dp
if (allocated(wannier_spreads)) deallocate (wannier_spreads)
allocate (wannier_spreads(num_wann), stat=ierr)
if (ierr /= 0) call io_error('Error in allocating wannier_spreads in param_read')
wannier_spreads = 0.0_dp
return
105 call io_error('Error: Problem opening eigenvalue file '//trim(seedname)//'.eig')
106 call io_error('Error: Problem reading eigenvalue file '//trim(seedname)//'.eig')
end subroutine param_read