33  use, 
intrinsic :: iso_fortran_env
 
   68  integer, 
public, 
parameter ::      &
 
   69    XC_INV_METHOD_TWO_PARTICLE = 1,  &
 
   75  integer, 
public, 
parameter ::      &
 
   76    XC_KS_INVERSION_NONE      = 1,   &
 
   81  integer, 
public, 
parameter ::      &
 
   82    XC_ASYMPTOTICS_NONE    = 1,      &
 
   85  integer, 
parameter ::              &
 
   90    integer,             
public :: method
 
   91    integer                     :: level = xc_ks_inversion_none
 
   92    integer                     :: asymptotics
 
   93    real(real64), 
allocatable          :: vhxc_previous_step(:,:)
 
   94    type(states_elec_t), 
public :: aux_st
 
   95    type(hamiltonian_elec_t)    :: aux_hm
 
   96    type(eigensolver_t), 
public :: eigensolver
 
   99    type(partner_list_t) :: ext_partners
 
  101    integer,             
public :: max_iter
 
  109    type(xc_ks_inversion_t), 
intent(inout) :: ks_inv
 
  110    type(namespace_t),       
intent(in)    :: namespace
 
  111    type(grid_t),            
intent(inout) :: gr
 
  112    type(ions_t),            
intent(inout) :: ions
 
  113    type(states_elec_t),     
intent(in)    :: st
 
  114    type(xc_t),              
intent(in)    :: xc
 
  115    type(multicomm_t),       
intent(in)    :: mc
 
  116    class(space_t),          
intent(in)    :: space
 
  117    type(kpoints_t),         
intent(in)    :: kpoints
 
  119    class(lasers_t), 
pointer :: lasers
 
  123    if(gr%parallel_in_domains) 
then 
  147    if (ks_inv%method < xc_inv_method_two_particle &
 
  179    call parse_variable(namespace, 
'KSInversionAsymptotics', xc_asymptotics_none, ks_inv%asymptotics)
 
  180    if (ks_inv%asymptotics /= xc_asymptotics_none .and. space%dim > 1) 
then 
  189    if (ks_inv%level /= xc_ks_inversion_none) 
then 
  203      if(lasers%no_lasers > 0) 
then 
  204        call ks_inv%ext_partners%add(lasers)
 
  210      call hamiltonian_elec_init(ks_inv%aux_hm, namespace, space, gr, ions, ks_inv%ext_partners, ks_inv%aux_st, &
 
  212      call eigensolver_init(ks_inv%eigensolver, namespace, gr, ks_inv%aux_st, mc, space)
 
  228    if (ks_inv%level /= xc_ks_inversion_none) 
then 
  234      call iter%start(ks_inv%ext_partners)
 
  235      do while (iter%has_next())
 
  236        partner => iter%get_next()
 
  237        safe_deallocate_p(partner)
 
  239      call ks_inv%ext_partners%empty()
 
  250    integer,           
optional, 
intent(in) :: iunit
 
  251    type(
namespace_t), 
optional, 
intent(in) :: namespace
 
  253    if (ks_inversion%level == xc_ks_inversion_none) 
return 
  269  subroutine invertks_2part(ks_inv, target_rho, nspin, aux_hm, gr, st, eigensolver, &
 
  270    namespace, space, ext_partners)
 
  272    real(real64),             
intent(in)    :: target_rho(:,:)
 
  273    integer,                  
intent(in)    :: nspin
 
  275    type(
grid_t),             
intent(in)    :: gr
 
  279    class(
space_t),           
intent(in)    :: space
 
  282    integer :: asym1, asym2, ip, ispin
 
  284    real(real64)   :: rr, shift
 
  285    real(real64), 
parameter :: smalldensity = 5e-12_real64
 
  286    real(real64), 
allocatable :: sqrtrho(:,:), laplace(:,:), vks(:,:), x_shifted(:)
 
  291    assert(.not. gr%parallel_in_domains)
 
  295    assert(space%periodic_dim == 0)
 
  298    assert(space%dim == 1)
 
  302    safe_allocate(sqrtrho(1:gr%np_part, 1:nspin))
 
  303    safe_allocate(vks(1:np, 1:nspin))
 
  304    safe_allocate(laplace(1:gr%np, 1:nspin))
 
  306    if (any(target_rho(:,:) < -
m_epsilon)) 
then 
  307      write(
message(1),*) 
"Target density has negative points. min value = ", minval(target_rho(:,:))
 
  316        sqrtrho(ip, ispin) = 
sqrt(target_rho(ip, ispin))
 
  323    if (space%dim == 1) 
then 
  328        call spline_fit(gr%np, gr%x(:, 1), sqrtrho(:, ispin), spl)
 
  338        safe_deallocate_a(x_shifted)
 
  342          laplace(ip, ispin) = 
spline_eval(lapl_spl, gr%x(ip, 1))
 
  368        if (target_rho(ip, ispin) < smalldensity) 
then 
  369          vks(ip, ispin) = aux_hm%ep%vpsl(ip) + aux_hm%vhartree(ip)
 
  372        if (target_rho(np-ip+1, ispin) < smalldensity) 
then 
  373          vks(np-ip+1, ispin) = aux_hm%ep%vpsl(np-ip+1) + aux_hm%vhartree(np-ip+1)
 
  381      do ip = asym1+1, asym2-1
 
  382        vks(ip, ispin) = 
m_half * laplace(ip, ispin) / (sqrtrho(ip, ispin) + 
m_tiny)
 
  388        aux_hm%vxc(ip, ispin) = vks(ip, ispin) - aux_hm%ep%vpsl(ip) - aux_hm%vhartree(ip)
 
  399          aux_hm%vxc(ip, ispin) = -st%qtot/
sqrt(rr**2 + 
m_one)
 
  404        call mesh_r(gr, asym1+1, rr)
 
  405        shift  = aux_hm%vxc(asym1+1, ispin) + st%qtot/
sqrt(rr**2 + 
m_one)
 
  408        do ip = asym1+1, asym2-1
 
  409          aux_hm%vxc(ip, ispin) = aux_hm%vxc(ip, ispin) - shift
 
  414        call mesh_r(gr, asym2-1, rr)
 
  415        shift  = aux_hm%vxc(asym2-1, ispin) + st%qtot/
sqrt(rr**2 + 
m_one)
 
  420          aux_hm%vxc(ip, ispin) = aux_hm%vxc(ip, ispin) - shift
 
  427          aux_hm%vxc(ip, ispin) = -st%qtot/
sqrt(rr**2 + 
m_one)
 
  435    if (ks_inv%asymptotics == xc_asymptotics_none) 
then 
  442        shift  = aux_hm%vxc(asym1+1, ispin)
 
  444        do ip = asym1+1, asym2-1
 
  445          aux_hm%vxc(ip, ispin) = aux_hm%vxc(ip, ispin) - shift
 
  449        shift  = aux_hm%vxc(asym2-1, ispin)
 
  452          aux_hm%vxc(ip, ispin) = aux_hm%vxc(ip, ispin) - shift
 
  460      aux_hm%vhxc(1:gr%np, ispin) = aux_hm%vxc(1:gr%np, ispin) + aux_hm%vhartree(1:gr%np)
 
  466    safe_deallocate_a(sqrtrho)
 
  467    safe_deallocate_a(laplace)
 
  468    safe_deallocate_a(vks)
 
  476    type(
grid_t),             
intent(in)    :: gr
 
  477    class(
space_t),           
intent(in)    :: space
 
  482    integer,                  
intent(in)    :: max_iter
 
  485    integer :: iter, nst_conv
 
  489    call hm%update(gr, namespace, space, ext_partners)
 
  492    nst_conv = 
floor(st%qtot/st%smear%el_per_state)
 
  494    do iter = 1, max_iter
 
  495      call eigensolver%run(namespace, gr, st, hm, 1, converged, nst_conv)
 
  506      message(1) = 
'All states converged.' 
  509      message(1) = 
'Some of the states are not fully converged!' 
  513    write(
message(1),
'(a, e17.6)') 
'Criterion = ', eigensolver%tolerance
 
  525      character(len=50) :: str
 
  529      write(str, 
'(a,i5)') 
'Kohn-Sham inversion eigensolver iteration #', iter
 
  532      write(
message(1),
'(a,i6,a,i6)') 
'Converged states: ', minval(eigensolver%converged(1:st%nik))
 
  536        eigensolver%diff, compact = .
true., namespace=namespace)
 
  549  subroutine invertks_iter(ks_inv, target_rho, namespace, space, ext_partners, nspin, aux_hm, gr, &
 
  552    real(real64),             
intent(in)    :: target_rho(:,:)
 
  553    type(
grid_t),             
intent(in)    :: gr
 
  555    class(
space_t),           
intent(in)    :: space
 
  560    integer,                  
intent(in)    :: nspin
 
  562    integer :: ip, ispin, ierr, asym1, asym2
 
  563    integer :: iunit, verbosity, counter, np
 
  566    real(real64) :: rr, shift
 
  567    real(real64) :: alpha, beta
 
  568    real(real64) :: mu, npower, npower_in 
 
  569    real(real64) :: convdensity, diffdensity
 
  570    real(real64), 
allocatable :: vhxc(:,:)
 
  571    real(real64), 
parameter :: small_density = 5e-12_real64
 
  573    character(len=256) :: fname
 
  578    assert(space%dim == 1)
 
  590    call parse_variable(namespace, 
'InvertKSConvAbsDens', 1e-5_real64, convdensity)
 
  599    call parse_variable(namespace, 
'InvertKSStellaBeta', 1e-6_real64, beta)
 
  608    call parse_variable(namespace, 
'InvertKSStellaAlpha', 0.25_real64, alpha)
 
  627    call parse_variable(namespace, 
'InvertKSGodbyPower', 0.05_real64, npower_in)
 
  646    if (verbosity < 0 .or. verbosity > 2) 
then 
  660    safe_allocate(vhxc(1:np, 1:nspin))
 
  661    call lalg_copy(np, nspin, aux_hm%vhxc, vhxc)
 
  663    if (verbosity == 1 .or. verbosity == 2) 
then 
  664      iunit = 
io_open(
'InvertKSconvergence', namespace, action = 
'write')
 
  673        if (abs(st%rho(ip, ispin)-target_rho(ip, ispin)) > diffdensity) 
then 
  674          diffdensity = abs(st%rho(ip, ispin)-target_rho(ip, ispin))
 
  681    do while(diffdensity > convdensity .and. counter < max_iter)
 
  683      counter = counter + 1
 
  685      if (verbosity == 2) 
then 
  686        write(fname,
'(i6.6)') counter
 
  688          gr, aux_hm%vhxc(:,1), 
units_out%energy, ierr)
 
  690          gr, st%rho(:,1), 
units_out%length**(-space%dim), ierr)
 
  697      select case(ks_inv%method)
 
  703            vhxc(ip, ispin) = vhxc(ip, ispin) &
 
  704              + ((st%rho(ip, ispin) - target_rho(ip, ispin))/(target_rho(ip, ispin) + beta))*alpha
 
  713        beta = diffdensity*1e-3_real64 
 
  716        alpha = max(0.05_real64, 
m_half - diffdensity*100.0_real64*0.45_real64)
 
  717        write(
message(1),
'(a,2E15.4,3I8, 2E15.4)') &
 
  718          ' KSinversion: diffdensity, convdensity, imax, counter, max_iter, alpha, beta ', &
 
  719          diffdensity, convdensity, imax, counter, max_iter, alpha, beta
 
  726            vhxc(ip, ispin) = vhxc(ip, ispin) &
 
  727              + ((st%rho(ip, ispin) - target_rho(ip, ispin))/(target_rho(ip, ispin) + beta))*alpha
 
  738        write(
message(1),
'(a,2E15.4,3I8, 2E15.4)') &
 
  739          ' KSinversion: diffdensity, convdensity, imax, counter, max_iter, power, mu ', &
 
  740          diffdensity, convdensity, imax, counter, max_iter, npower, mu
 
  747            vhxc(ip, ispin) = vhxc(ip, ispin) &
 
  748              + (st%rho(ip, ispin)**npower - target_rho(ip, ispin)**npower)*mu
 
  763      assert(.not. gr%parallel_in_domains)
 
  767          if (abs(st%rho(ip, ispin)-target_rho(ip, ispin)) > diffdensity) 
then 
  768            diffdensity = abs(st%rho(ip, ispin)-target_rho(ip, ispin))
 
  774      if (verbosity == 1 .or. verbosity == 2) 
then 
  775        write(iunit,
'(i6.6)', advance = 
'no') counter
 
  776        write(iunit,
'(es18.10)') diffdensity
 
  783      call lalg_copy(np, nspin, vhxc, aux_hm%vhxc)
 
  785        aux_hm%vxc(1:np, ispin) = vhxc(1:np, ispin) - aux_hm%vhartree(1:np)
 
  794      call lalg_copy(np, nspin, aux_hm%vxc, vhxc)
 
  802          if (target_rho(ip, ispin) < small_density) 
then 
  804            vhxc(ip, ispin) = -st%qtot/
sqrt(rr**2 + 
m_one)
 
  807          if (target_rho(np-ip+1, ispin) < small_density) 
then 
  813        call mesh_r(gr, asym1+1, rr)
 
  814        shift  = vhxc(asym1+1, ispin) + st%qtot/
sqrt(rr**2 + 
m_one)
 
  817        do ip = asym1+1, asym2-1
 
  818          vhxc(ip, ispin) = vhxc(ip, ispin) - shift
 
  822        call mesh_r(gr, asym2-1, rr)
 
  823        shift  = vhxc(asym2-1, ispin) + st%qtot/
sqrt(rr**2 + 
m_one)
 
  828          vhxc(ip, ispin) = vhxc(ip, ispin) - shift
 
  835          vhxc(ip, ispin) = -st%qtot/
sqrt(rr**2 + 
m_one)
 
  842      call lalg_copy(np, nspin, vhxc, aux_hm%vxc)
 
  844        aux_hm%vhxc(1:np, ispin) = vhxc(1:np, ispin) + aux_hm%vhartree(1:np)
 
  853    write(
message(1),
'(a,I8)') 
"Iterative KS inversion, iterations needed:", counter
 
  858    safe_deallocate_a(vhxc)
 
  864  subroutine xc_ks_inversion_calc(ks_inversion, namespace, space, gr, hm, ext_partners, st, vxc, time)
 
  867    class(
space_t),           
intent(in)    :: space
 
  868    type(
grid_t),             
intent(in)    :: gr
 
  872    real(real64),             
intent(inout) :: vxc(:,:)
 
  873    real(real64), 
optional,   
intent(in)    :: time
 
  877    if (ks_inversion%level == xc_ks_inversion_none) 
return 
  881    if (
present(time) .and. time > 
m_zero) 
then 
  882      write(
message(1),
'(A,F18.12)') 
'xc_ks_inversion_calc - time:', time
 
  886    ks_inversion%aux_hm%energy%intnvxc     = 
m_zero 
  887    ks_inversion%aux_hm%energy%hartree     = 
m_zero 
  888    ks_inversion%aux_hm%energy%exchange    = 
m_zero 
  889    ks_inversion%aux_hm%energy%correlation = 
m_zero 
  891    ks_inversion%aux_hm%vhartree = hm%vhartree
 
  893    if (
present(time) .and. time > 
m_zero) 
then 
  894      call lalg_copy(gr%np, st%d%nspin, ks_inversion%vhxc_previous_step, ks_inversion%aux_hm%vhxc)
 
  898      do ispin = 1, st%d%nspin
 
  899        ks_inversion%aux_hm%vxc(1:gr%np, ispin)  = 
m_zero  
  900        ks_inversion%aux_hm%vhxc(1:gr%np, ispin) = hm%vhartree(1:gr%np) + ks_inversion%aux_hm%vxc(1:gr%np, ispin)
 
  908    call lalg_copy(gr%np, hm%ep%vpsl, ks_inversion%aux_hm%ep%vpsl)
 
  913      ks_inversion%eigensolver, ks_inversion%aux_st, ks_inversion%aux_hm, ks_inversion%max_iter)
 
  918    select case (ks_inversion%method)
 
  920    case (xc_inv_method_two_particle)
 
  921      call invertks_2part(ks_inversion, ks_inversion%aux_st%rho, st%d%nspin, ks_inversion%aux_hm, gr, &
 
  922        ks_inversion%aux_st, ks_inversion%eigensolver, namespace, space, ext_partners)
 
  925      call invertks_iter(ks_inversion, st%rho, namespace, space, ext_partners, st%d%nspin, ks_inversion%aux_hm, gr, &
 
  926        ks_inversion%aux_st, ks_inversion%eigensolver)
 
  932    do ispin = 1, st%d%nspin
 
  933      call lalg_axpy(gr%np, -
m_one, hm%vhartree, ks_inversion%aux_hm%vhxc(:,ispin))
 
  936    vxc = ks_inversion%aux_hm%vxc
 
  939    if (
present(time)) 
then 
  940      ks_inversion%vhxc_previous_step = ks_inversion%aux_hm%vhxc
 
constant times a vector plus a vector
 
Copies a vector x, to a vector y.
 
Some operations may be done for one spline-function, or for an array of them.
 
double floor(double __x) __attribute__((__nothrow__
 
This module implements a calculator for the density and defines related functions.
 
subroutine, public density_calc(st, gr, density, istin)
Computes the density from the orbitals in st.
 
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
 
subroutine, public dderivatives_lapl(der, ff, op_ff, ghost_update, set_bc, factor)
apply the Laplacian to a mesh function
 
subroutine, public eigensolver_init(eigens, namespace, gr, st, mc, space)
 
subroutine, public eigensolver_end(eigens)
 
real(real64), parameter, public m_zero
 
real(real64), parameter, public m_tiny
 
real(real64), parameter, public m_epsilon
 
real(real64), parameter, public m_half
 
real(real64), parameter, public m_one
 
This module implements the underlying real-space grid.
 
subroutine, public hamiltonian_elec_end(hm)
 
subroutine, public hamiltonian_elec_init(hm, namespace, space, gr, ions, ext_partners, st, theory_level, xc, mc, kpoints, need_exchange, xc_photons)
 
integer, parameter, public kohn_sham_dft
 
This module defines classes and functions for interaction partners.
 
subroutine, public dio_function_output(how, dir, fname, namespace, space, mesh, ff, unit, ierr, pos, atoms, grp, root)
 
integer(int64) function, public io_function_fill_how(where)
Use this function to quickly plot functions for debugging purposes: call dio_function_output(io_funct...
 
subroutine, public io_close(iunit, grp)
 
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
 
subroutine, public lasers_check_symmetries(this, kpoints)
 
subroutine, public lasers_parse_external_fields(this)
 
subroutine, public lasers_generate_potentials(this, mesh, space, latt)
 
This module defines the meshes, which are used in Octopus.
 
pure subroutine, public mesh_r(mesh, ip, rr, origin, coords)
return the distance to the origin for a given grid point
 
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
 
subroutine, public messages_not_implemented(feature, namespace)
 
character(len=512), private msg
 
subroutine, public messages_warning(no_lines, all_nodes, namespace)
 
subroutine, public messages_obsolete_variable(namespace, name, rep)
 
subroutine, public messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, namespace)
 
subroutine, public messages_new_line()
 
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
 
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
 
subroutine, public messages_input_error(namespace, var, details, row, column)
 
subroutine, public messages_experimental(name, namespace)
 
This module handles the communicators for the various parallelization strategies.
 
subroutine, public spline_fit(nrc, rofi, ffit, spl, threshold)
 
subroutine, public spline_der2(spl, dspl, threshold, grid)
Returns a spline that contains the second derivative of the original spline.
 
real(real64) function, public spline_eval(spl, x)
 
subroutine, public spline_generate_shifted_grid(this, x_shifted)
 
This module handles spin dimensions of the states and the k-point distribution.
 
This module defines routines to write information about states.
 
subroutine, public states_elec_write_eigenvalues(nst, st, space, kpoints, error, st_start, compact, iunit, namespace)
write the eigenvalues for some states to a file.
 
subroutine, public states_elec_densities_init(st, gr)
 
subroutine, public states_elec_end(st)
finalize the states_elec_t object
 
subroutine, public states_elec_allocate_wfns(st, mesh, wfs_type, skip, packed)
Allocates the KS wavefunctions defined within a states_elec_t structure.
 
subroutine, public states_elec_copy(stout, stin, exclude_wfns, exclude_eigenval, special)
make a (selective) copy of a states_elec_t object
 
subroutine, public states_elec_generate_random(st, mesh, kpoints, ist_start_, ist_end_, ikpt_start_, ikpt_end_, normalized)
randomize states
 
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
 
This module defines the unit system, used for input and output.
 
type(unit_system_t), public units_out
 
subroutine, public xc_ks_inversion_end(ks_inv)
 
integer, parameter, public xc_inv_method_iter_godby
 
subroutine, public invertks_2part(ks_inv, target_rho, nspin, aux_hm, gr, st, eigensolver, namespace, space, ext_partners)
Given a density, it performs the Kohn-Sham inversion, assuming a two-particle, one orbital case.
 
integer, parameter, public xc_ks_inversion_td_exact
 
integer, parameter, public xc_ks_inversion_adiabatic
 
integer, parameter, public xc_inv_method_vs_iter
 
integer, parameter, public xc_asymptotics_sc
 
subroutine, public xc_ks_inversion_write_info(ks_inversion, iunit, namespace)
 
subroutine, public invertks_iter(ks_inv, target_rho, namespace, space, ext_partners, nspin, aux_hm, gr, st, eigensolver)
Iterative inversion of KS potential from the density.
 
subroutine, public xc_ks_inversion_init(ks_inv, namespace, gr, ions, st, xc, mc, space, kpoints)
 
integer, parameter, public xc_inv_method_iter_stella
 
subroutine, public xc_ks_inversion_calc(ks_inversion, namespace, space, gr, hm, ext_partners, st, vxc, time)
 
subroutine, public invertks_update_hamiltonian(namespace, gr, space, ext_partners, eigensolver, st, hm, max_iter)
A small auxiliary function to perform the update of the Hamiltonian, run the eigensolver,...
 
Description of the grid, containing information on derivatives, stencil, and symmetries.
 
abstract class for general interaction partners
 
iterator for the list of partners
 
the basic spline datatype
 
The states_elec_t class contains all electronic wave functions.