! Warning! This file is automatically generated using cpp_f90.py script!

!> @file generated.f90
!! @brief Autogenerated interface to Fortran.
!
!> @brief Initialize the SIRIUS library.
!> @param [in] call_mpi_init If .true. then MPI_Init must be called prior to initialization.
subroutine sirius_initialize(call_mpi_init)
implicit none
logical(C_BOOL), intent(in) :: call_mpi_init
interface
subroutine sirius_initialize_aux(call_mpi_init)&
&bind(C, name="sirius_initialize")
use, intrinsic :: ISO_C_BINDING
logical(C_BOOL), intent(in) :: call_mpi_init
end subroutine
end interface

call sirius_initialize_aux(call_mpi_init)
end subroutine sirius_initialize

!> @brief Shut down the SIRIUS library
!> @param [in] call_mpi_fin If .true. then MPI_Finalize must be called after the shutdown.
!> @param [in] call_device_reset If .true. then cuda device is reset after shutdown.
!> @param [in] call_fftw_fin If .true. then fft_cleanup must be called after the shutdown.
subroutine sirius_finalize(call_mpi_fin,call_device_reset,call_fftw_fin)
implicit none
logical(C_BOOL), optional, target, intent(in) :: call_mpi_fin
logical(C_BOOL), optional, target, intent(in) :: call_device_reset
logical(C_BOOL), optional, target, intent(in) :: call_fftw_fin
type(C_PTR) :: call_mpi_fin_ptr
type(C_PTR) :: call_device_reset_ptr
type(C_PTR) :: call_fftw_fin_ptr
interface
subroutine sirius_finalize_aux(call_mpi_fin,call_device_reset,call_fftw_fin)&
&bind(C, name="sirius_finalize")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value, intent(in) :: call_mpi_fin
type(C_PTR), value, intent(in) :: call_device_reset
type(C_PTR), value, intent(in) :: call_fftw_fin
end subroutine
end interface

call_mpi_fin_ptr = C_NULL_PTR
if (present(call_mpi_fin)) call_mpi_fin_ptr = C_LOC(call_mpi_fin)

call_device_reset_ptr = C_NULL_PTR
if (present(call_device_reset)) call_device_reset_ptr = C_LOC(call_device_reset)

call_fftw_fin_ptr = C_NULL_PTR
if (present(call_fftw_fin)) call_fftw_fin_ptr = C_LOC(call_fftw_fin)

call sirius_finalize_aux(call_mpi_fin_ptr,call_device_reset_ptr,call_fftw_fin_pt&
&r)
end subroutine sirius_finalize

!> @brief Start the timer.
!> @param [in] name Timer label.
subroutine sirius_start_timer(name)
implicit none
character(C_CHAR), dimension(*), intent(in) :: name
interface
subroutine sirius_start_timer_aux(name)&
&bind(C, name="sirius_start_timer")
use, intrinsic :: ISO_C_BINDING
character(C_CHAR), dimension(*), intent(in) :: name
end subroutine
end interface

call sirius_start_timer_aux(name)
end subroutine sirius_start_timer

!> @brief Stop the running timer.
!> @param [in] name Timer label.
subroutine sirius_stop_timer(name)
implicit none
character(C_CHAR), dimension(*), intent(in) :: name
interface
subroutine sirius_stop_timer_aux(name)&
&bind(C, name="sirius_stop_timer")
use, intrinsic :: ISO_C_BINDING
character(C_CHAR), dimension(*), intent(in) :: name
end subroutine
end interface

call sirius_stop_timer_aux(name)
end subroutine sirius_stop_timer

!> @brief Print all timers.
subroutine sirius_print_timers()
implicit none
interface
subroutine sirius_print_timers_aux()&
&bind(C, name="sirius_print_timers")
use, intrinsic :: ISO_C_BINDING
end subroutine
end interface

call sirius_print_timers_aux()
end subroutine sirius_print_timers

!> @brief Save all timers to JSON file.
!> @param [in] fname Name of the output JSON file.
subroutine sirius_serialize_timers(fname)
implicit none
character(C_CHAR), dimension(*), intent(in) :: fname
interface
subroutine sirius_serialize_timers_aux(fname)&
&bind(C, name="sirius_serialize_timers")
use, intrinsic :: ISO_C_BINDING
character(C_CHAR), dimension(*), intent(in) :: fname
end subroutine
end interface

call sirius_serialize_timers_aux(fname)
end subroutine sirius_serialize_timers

!> @brief Spline integration of f(x)*x^m.
!> @param [in] m Defines the x^{m} factor.
!> @param [in] np Number of x-points.
!> @param [in] x List of x-points.
!> @param [in] f List of function values.
!> @param [out] result Resulting value.
subroutine sirius_integrate(m,np,x,f,result)
implicit none
integer(C_INT), intent(in) :: m
integer(C_INT), intent(in) :: np
real(C_DOUBLE), intent(in) :: x
real(C_DOUBLE), intent(in) :: f
real(C_DOUBLE), intent(out) :: result
interface
subroutine sirius_integrate_aux(m,np,x,f,result)&
&bind(C, name="sirius_integrate")
use, intrinsic :: ISO_C_BINDING
integer(C_INT), intent(in) :: m
integer(C_INT), intent(in) :: np
real(C_DOUBLE), intent(in) :: x
real(C_DOUBLE), intent(in) :: f
real(C_DOUBLE), intent(out) :: result
end subroutine
end interface

call sirius_integrate_aux(m,np,x,f,result)
end subroutine sirius_integrate

!> @brief Check if the simulation context is initialized.
!> @param [in] handler Simulation context handler.
function sirius_context_initialized(handler) result(res)
implicit none
type(C_PTR), intent(in) :: handler
logical(C_BOOL) :: res
interface
function sirius_context_initialized_aux(handler) result(res)&
&bind(C, name="sirius_context_initialized")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
logical(C_BOOL) :: res
end function
end interface

res = sirius_context_initialized_aux(handler)
end function sirius_context_initialized

!> @brief Create context of the simulation.
!> @details Simulation context is the complex data structure that holds all the parameters of the individual simulation.
!> The context must be created, populated with the correct parameters and initialized before using all subsequent
!> SIRIUS functions.
!> @param [in] fcomm Entire communicator of the simulation.
function sirius_create_context(fcomm) result(res)
implicit none
integer(C_INT), intent(in) :: fcomm
type(C_PTR) :: res
interface
function sirius_create_context_aux(fcomm) result(res)&
&bind(C, name="sirius_create_context")
use, intrinsic :: ISO_C_BINDING
integer(C_INT), intent(in) :: fcomm
type(C_PTR) :: res
end function
end interface

res = sirius_create_context_aux(fcomm)
end function sirius_create_context

!> @brief Import parameters of simulation from a JSON string
!> @param [in] handler Simulation context handler.
!> @param [in] json_str JSON string with parameters or a JSON file.
subroutine sirius_import_parameters(handler,json_str)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: json_str
interface
subroutine sirius_import_parameters_aux(handler,json_str)&
&bind(C, name="sirius_import_parameters")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: json_str
end subroutine
end interface

call sirius_import_parameters_aux(handler,json_str)
end subroutine sirius_import_parameters

!> @brief Set parameters of the simulation.
!> @param [in] handler Simulation context handler
!> @param [in] lmax_apw Maximum orbital quantum number for APW functions.
!> @param [in] lmax_rho Maximum orbital quantum number for density.
!> @param [in] lmax_pot Maximum orbital quantum number for potential.
!> @param [in] num_fv_states Number of first-variational states.
!> @param [in] num_bands Number of bands.
!> @param [in] num_mag_dims Number of magnetic dimensions.
!> @param [in] pw_cutoff Cutoff for G-vectors.
!> @param [in] gk_cutoff Cutoff for G+k-vectors.
!> @param [in] aw_cutoff This is R_{mt} * gk_cutoff.
!> @param [in] auto_rmt Set the automatic search of muffin-tin radii.
!> @param [in] gamma_point True if this is a Gamma-point calculation.
!> @param [in] use_symmetry True if crystal symmetry is taken into account.
!> @param [in] so_correction True if spin-orbit correnctio is enabled.
!> @param [in] valence_rel Valence relativity treatment.
!> @param [in] core_rel Core relativity treatment.
!> @param [in] esm_bc Type of boundary condition for effective screened medium.
!> @param [in] iter_solver_tol Tolerance of the iterative solver.
!> @param [in] iter_solver_tol_empty Tolerance for the empty states.
!> @param [in] iter_solver_type Type of iterative solver.
!> @param [in] verbosity Verbosity level.
!> @param [in] hubbard_correction True if LDA+U correction is enabled.
!> @param [in] hubbard_correction_kind Type of LDA+U implementation (simplified or full).
!> @param [in] hubbard_orbitals Type of localized orbitals.
subroutine sirius_set_parameters(handler,lmax_apw,lmax_rho,lmax_pot,num_fv_state&
&s,num_bands,num_mag_dims,pw_cutoff,gk_cutoff,aw_cutoff,auto_rmt,gamma_point,use_&
&symmetry,so_correction,valence_rel,core_rel,esm_bc,iter_solver_tol,iter_solver_t&
&ol_empty,iter_solver_type,verbosity,hubbard_correction,hubbard_correction_kind,h&
&ubbard_orbitals)
implicit none
type(C_PTR), intent(in) :: handler
integer(C_INT), optional, target, intent(in) :: lmax_apw
integer(C_INT), optional, target, intent(in) :: lmax_rho
integer(C_INT), optional, target, intent(in) :: lmax_pot
integer(C_INT), optional, target, intent(in) :: num_fv_states
integer(C_INT), optional, target, intent(in) :: num_bands
integer(C_INT), optional, target, intent(in) :: num_mag_dims
real(C_DOUBLE), optional, target, intent(in) :: pw_cutoff
real(C_DOUBLE), optional, target, intent(in) :: gk_cutoff
real(C_DOUBLE), optional, target, intent(in) :: aw_cutoff
integer(C_INT), optional, target, intent(in) :: auto_rmt
logical(C_BOOL), optional, target, intent(in) :: gamma_point
logical(C_BOOL), optional, target, intent(in) :: use_symmetry
logical(C_BOOL), optional, target, intent(in) :: so_correction
character(C_CHAR), optional, target, dimension(*), intent(in) :: valence_rel
character(C_CHAR), optional, target, dimension(*), intent(in) :: core_rel
character(C_CHAR), optional, target, dimension(*), intent(in) :: esm_bc
real(C_DOUBLE), optional, target, intent(in) :: iter_solver_tol
real(C_DOUBLE), optional, target, intent(in) :: iter_solver_tol_empty
character(C_CHAR), optional, target, dimension(*), intent(in) :: iter_solver_type
integer(C_INT), optional, target, intent(in) :: verbosity
logical(C_BOOL), optional, target, intent(in) :: hubbard_correction
integer(C_INT), optional, target, intent(in) :: hubbard_correction_kind
character(C_CHAR), optional, target, dimension(*), intent(in) :: hubbard_orbitals
type(C_PTR) :: lmax_apw_ptr
type(C_PTR) :: lmax_rho_ptr
type(C_PTR) :: lmax_pot_ptr
type(C_PTR) :: num_fv_states_ptr
type(C_PTR) :: num_bands_ptr
type(C_PTR) :: num_mag_dims_ptr
type(C_PTR) :: pw_cutoff_ptr
type(C_PTR) :: gk_cutoff_ptr
type(C_PTR) :: aw_cutoff_ptr
type(C_PTR) :: auto_rmt_ptr
type(C_PTR) :: gamma_point_ptr
type(C_PTR) :: use_symmetry_ptr
type(C_PTR) :: so_correction_ptr
type(C_PTR) :: valence_rel_ptr
type(C_PTR) :: core_rel_ptr
type(C_PTR) :: esm_bc_ptr
type(C_PTR) :: iter_solver_tol_ptr
type(C_PTR) :: iter_solver_tol_empty_ptr
type(C_PTR) :: iter_solver_type_ptr
type(C_PTR) :: verbosity_ptr
type(C_PTR) :: hubbard_correction_ptr
type(C_PTR) :: hubbard_correction_kind_ptr
type(C_PTR) :: hubbard_orbitals_ptr
interface
subroutine sirius_set_parameters_aux(handler,lmax_apw,lmax_rho,lmax_pot,num_fv_s&
&tates,num_bands,num_mag_dims,pw_cutoff,gk_cutoff,aw_cutoff,auto_rmt,gamma_point,&
&use_symmetry,so_correction,valence_rel,core_rel,esm_bc,iter_solver_tol,iter_solv&
&er_tol_empty,iter_solver_type,verbosity,hubbard_correction,hubbard_correction_ki&
&nd,hubbard_orbitals)&
&bind(C, name="sirius_set_parameters")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
type(C_PTR), value, intent(in) :: lmax_apw
type(C_PTR), value, intent(in) :: lmax_rho
type(C_PTR), value, intent(in) :: lmax_pot
type(C_PTR), value, intent(in) :: num_fv_states
type(C_PTR), value, intent(in) :: num_bands
type(C_PTR), value, intent(in) :: num_mag_dims
type(C_PTR), value, intent(in) :: pw_cutoff
type(C_PTR), value, intent(in) :: gk_cutoff
type(C_PTR), value, intent(in) :: aw_cutoff
type(C_PTR), value, intent(in) :: auto_rmt
type(C_PTR), value, intent(in) :: gamma_point
type(C_PTR), value, intent(in) :: use_symmetry
type(C_PTR), value, intent(in) :: so_correction
type(C_PTR), value, intent(in) :: valence_rel
type(C_PTR), value, intent(in) :: core_rel
type(C_PTR), value, intent(in) :: esm_bc
type(C_PTR), value, intent(in) :: iter_solver_tol
type(C_PTR), value, intent(in) :: iter_solver_tol_empty
type(C_PTR), value, intent(in) :: iter_solver_type
type(C_PTR), value, intent(in) :: verbosity
type(C_PTR), value, intent(in) :: hubbard_correction
type(C_PTR), value, intent(in) :: hubbard_correction_kind
type(C_PTR), value, intent(in) :: hubbard_orbitals
end subroutine
end interface

lmax_apw_ptr = C_NULL_PTR
if (present(lmax_apw)) lmax_apw_ptr = C_LOC(lmax_apw)

lmax_rho_ptr = C_NULL_PTR
if (present(lmax_rho)) lmax_rho_ptr = C_LOC(lmax_rho)

lmax_pot_ptr = C_NULL_PTR
if (present(lmax_pot)) lmax_pot_ptr = C_LOC(lmax_pot)

num_fv_states_ptr = C_NULL_PTR
if (present(num_fv_states)) num_fv_states_ptr = C_LOC(num_fv_states)

num_bands_ptr = C_NULL_PTR
if (present(num_bands)) num_bands_ptr = C_LOC(num_bands)

num_mag_dims_ptr = C_NULL_PTR
if (present(num_mag_dims)) num_mag_dims_ptr = C_LOC(num_mag_dims)

pw_cutoff_ptr = C_NULL_PTR
if (present(pw_cutoff)) pw_cutoff_ptr = C_LOC(pw_cutoff)

gk_cutoff_ptr = C_NULL_PTR
if (present(gk_cutoff)) gk_cutoff_ptr = C_LOC(gk_cutoff)

aw_cutoff_ptr = C_NULL_PTR
if (present(aw_cutoff)) aw_cutoff_ptr = C_LOC(aw_cutoff)

auto_rmt_ptr = C_NULL_PTR
if (present(auto_rmt)) auto_rmt_ptr = C_LOC(auto_rmt)

gamma_point_ptr = C_NULL_PTR
if (present(gamma_point)) gamma_point_ptr = C_LOC(gamma_point)

use_symmetry_ptr = C_NULL_PTR
if (present(use_symmetry)) use_symmetry_ptr = C_LOC(use_symmetry)

so_correction_ptr = C_NULL_PTR
if (present(so_correction)) so_correction_ptr = C_LOC(so_correction)

valence_rel_ptr = C_NULL_PTR
if (present(valence_rel)) valence_rel_ptr = C_LOC(valence_rel)

core_rel_ptr = C_NULL_PTR
if (present(core_rel)) core_rel_ptr = C_LOC(core_rel)

esm_bc_ptr = C_NULL_PTR
if (present(esm_bc)) esm_bc_ptr = C_LOC(esm_bc)

iter_solver_tol_ptr = C_NULL_PTR
if (present(iter_solver_tol)) iter_solver_tol_ptr = C_LOC(iter_solver_tol)

iter_solver_tol_empty_ptr = C_NULL_PTR
if (present(iter_solver_tol_empty)) iter_solver_tol_empty_ptr = C_LOC(iter_solver_tol_empty)

iter_solver_type_ptr = C_NULL_PTR
if (present(iter_solver_type)) iter_solver_type_ptr = C_LOC(iter_solver_type)

verbosity_ptr = C_NULL_PTR
if (present(verbosity)) verbosity_ptr = C_LOC(verbosity)

hubbard_correction_ptr = C_NULL_PTR
if (present(hubbard_correction)) hubbard_correction_ptr = C_LOC(hubbard_correction)

hubbard_correction_kind_ptr = C_NULL_PTR
if (present(hubbard_correction_kind)) hubbard_correction_kind_ptr = C_LOC(hubbard_correction_kind)

hubbard_orbitals_ptr = C_NULL_PTR
if (present(hubbard_orbitals)) hubbard_orbitals_ptr = C_LOC(hubbard_orbitals)

call sirius_set_parameters_aux(handler,lmax_apw_ptr,lmax_rho_ptr,lmax_pot_ptr,nu&
&m_fv_states_ptr,num_bands_ptr,num_mag_dims_ptr,pw_cutoff_ptr,gk_cutoff_ptr,aw_cu&
&toff_ptr,auto_rmt_ptr,gamma_point_ptr,use_symmetry_ptr,so_correction_ptr,valence&
&_rel_ptr,core_rel_ptr,esm_bc_ptr,iter_solver_tol_ptr,iter_solver_tol_empty_ptr,i&
&ter_solver_type_ptr,verbosity_ptr,hubbard_correction_ptr,hubbard_correction_kind&
&_ptr,hubbard_orbitals_ptr)
end subroutine sirius_set_parameters

!> @brief Add one of the XC functionals.
!> @param [in] handler Simulation context handler
!> @param [in] name LibXC label of the functional.
subroutine sirius_add_xc_functional(handler,name)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: name
interface
subroutine sirius_add_xc_functional_aux(handler,name)&
&bind(C, name="sirius_add_xc_functional")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: name
end subroutine
end interface

call sirius_add_xc_functional_aux(handler,name)
end subroutine sirius_add_xc_functional

!> @brief Set dimensions of the MPI grid.
!> @param [in] handler Simulation context handler
!> @param [in] ndims Number of dimensions.
!> @param [in] dims Size of each dimension.
subroutine sirius_set_mpi_grid_dims(handler,ndims,dims)
implicit none
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: ndims
integer(C_INT), intent(in) :: dims
interface
subroutine sirius_set_mpi_grid_dims_aux(handler,ndims,dims)&
&bind(C, name="sirius_set_mpi_grid_dims")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: ndims
integer(C_INT), intent(in) :: dims
end subroutine
end interface

call sirius_set_mpi_grid_dims_aux(handler,ndims,dims)
end subroutine sirius_set_mpi_grid_dims

!> @brief Set vectors of the unit cell.
!> @param [in] handler Simulation context handler
!> @param [in] a1 1st vector
!> @param [in] a2 2nd vector
!> @param [in] a3 3rd vector
subroutine sirius_set_lattice_vectors(handler,a1,a2,a3)
implicit none
type(C_PTR), intent(in) :: handler
real(C_DOUBLE), intent(in) :: a1
real(C_DOUBLE), intent(in) :: a2
real(C_DOUBLE), intent(in) :: a3
interface
subroutine sirius_set_lattice_vectors_aux(handler,a1,a2,a3)&
&bind(C, name="sirius_set_lattice_vectors")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
real(C_DOUBLE), intent(in) :: a1
real(C_DOUBLE), intent(in) :: a2
real(C_DOUBLE), intent(in) :: a3
end subroutine
end interface

call sirius_set_lattice_vectors_aux(handler,a1,a2,a3)
end subroutine sirius_set_lattice_vectors

!> @brief Initialize simulation context.
!> @param [in] handler Simulation context handler.
subroutine sirius_initialize_context(handler)
implicit none
type(C_PTR), intent(in) :: handler
interface
subroutine sirius_initialize_context_aux(handler)&
&bind(C, name="sirius_initialize_context")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
end subroutine
end interface

call sirius_initialize_context_aux(handler)
end subroutine sirius_initialize_context

!> @brief Update simulation context after changing lattice or atomic positions.
!> @param [in] handler Simulation context handler.
subroutine sirius_update_context(handler)
implicit none
type(C_PTR), intent(in) :: handler
interface
subroutine sirius_update_context_aux(handler)&
&bind(C, name="sirius_update_context")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
end subroutine
end interface

call sirius_update_context_aux(handler)
end subroutine sirius_update_context

!> @brief Print basic info
!> @param [in] handler Simulation context handler.
subroutine sirius_print_info(handler)
implicit none
type(C_PTR), intent(in) :: handler
interface
subroutine sirius_print_info_aux(handler)&
&bind(C, name="sirius_print_info")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
end subroutine
end interface

call sirius_print_info_aux(handler)
end subroutine sirius_print_info

!> @brief Free any handler of object created by SIRIUS.
!> @param [inout] handler Handler of the object.
subroutine sirius_free_handler(handler)
implicit none
type(C_PTR), intent(inout) :: handler
interface
subroutine sirius_free_handler_aux(handler)&
&bind(C, name="sirius_free_handler")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(inout) :: handler
end subroutine
end interface

call sirius_free_handler_aux(handler)
end subroutine sirius_free_handler

!> @brief Set pointer to density or megnetization.
!> @param [in] handler Handler of the DFT ground state object.
!> @param [in] label Label of the function.
!> @param [in] f_mt Pointer to the muffin-tin part of the function.
!> @param [in] f_rg Pointer to the regualr-grid part of the function.
subroutine sirius_set_periodic_function_ptr(handler,label,f_mt,f_rg)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
real(C_DOUBLE), optional, target, intent(in) :: f_mt
real(C_DOUBLE), optional, target, intent(in) :: f_rg
type(C_PTR) :: f_mt_ptr
type(C_PTR) :: f_rg_ptr
interface
subroutine sirius_set_periodic_function_ptr_aux(handler,label,f_mt,f_rg)&
&bind(C, name="sirius_set_periodic_function_ptr")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
type(C_PTR), value, intent(in) :: f_mt
type(C_PTR), value, intent(in) :: f_rg
end subroutine
end interface

f_mt_ptr = C_NULL_PTR
if (present(f_mt)) f_mt_ptr = C_LOC(f_mt)

f_rg_ptr = C_NULL_PTR
if (present(f_rg)) f_rg_ptr = C_LOC(f_rg)

call sirius_set_periodic_function_ptr_aux(handler,label,f_mt_ptr,f_rg_ptr)
end subroutine sirius_set_periodic_function_ptr

!> @brief Create k-point set from the list of k-points.
!> @param [in] handler Simulation context handler.
!> @param [in] num_kpoints Total number of k-points in the set.
!> @param [in] kpoints List of k-points in lattice coordinates.
!> @param [in] kpoint_weights Weights of k-points.
!> @param [in] init_kset If .true. k-set will be initialized.
function sirius_create_kset(handler,num_kpoints,kpoints,kpoint_weights,init_kset&
&) result(res)
implicit none
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: num_kpoints
real(C_DOUBLE), intent(in) :: kpoints
real(C_DOUBLE), intent(in) :: kpoint_weights
logical(C_BOOL), intent(in) :: init_kset
type(C_PTR) :: res
interface
function sirius_create_kset_aux(handler,num_kpoints,kpoints,kpoint_weights,init_&
&kset) result(res)&
&bind(C, name="sirius_create_kset")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: num_kpoints
real(C_DOUBLE), intent(in) :: kpoints
real(C_DOUBLE), intent(in) :: kpoint_weights
logical(C_BOOL), intent(in) :: init_kset
type(C_PTR) :: res
end function
end interface

res = sirius_create_kset_aux(handler,num_kpoints,kpoints,kpoint_weights,init_kse&
&t)
end function sirius_create_kset

!> @brief Create k-point set from a grid.
!> @param [in] handler Simulation context handler.
!> @param [in] k_grid dimensions of the k points grid.
!> @param [in] k_shift k point shifts.
!> @param [in] use_symmetry If .true. k-set will be generated using symmetries.
function sirius_create_kset_from_grid(handler,k_grid,k_shift,use_symmetry) resul&
&t(res)
implicit none
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: k_grid
integer(C_INT), intent(in) :: k_shift
logical(C_BOOL), intent(in) :: use_symmetry
type(C_PTR) :: res
interface
function sirius_create_kset_from_grid_aux(handler,k_grid,k_shift,use_symmetry) r&
&esult(res)&
&bind(C, name="sirius_create_kset_from_grid")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: k_grid
integer(C_INT), intent(in) :: k_shift
logical(C_BOOL), intent(in) :: use_symmetry
type(C_PTR) :: res
end function
end interface

res = sirius_create_kset_from_grid_aux(handler,k_grid,k_shift,use_symmetry)
end function sirius_create_kset_from_grid

!> @brief Create a ground state object.
!> @param [in] ks_handler Handler of the k-point set.
function sirius_create_ground_state(ks_handler) result(res)
implicit none
type(C_PTR), intent(in) :: ks_handler
type(C_PTR) :: res
interface
function sirius_create_ground_state_aux(ks_handler) result(res)&
&bind(C, name="sirius_create_ground_state")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: ks_handler
type(C_PTR) :: res
end function
end interface

res = sirius_create_ground_state_aux(ks_handler)
end function sirius_create_ground_state

!> @brief Find the ground state
!> @param [in] gs_handler Handler of the ground state
!> @param [in] save__ boolean variable indicating if we want to save the ground state
subroutine sirius_find_ground_state(gs_handler,save__)
implicit none
type(C_PTR), intent(in) :: gs_handler
logical(C_BOOL), optional, target, intent(in) :: save__
type(C_PTR) :: save___ptr
interface
subroutine sirius_find_ground_state_aux(gs_handler,save__)&
&bind(C, name="sirius_find_ground_state")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: gs_handler
type(C_PTR), value, intent(in) :: save__
end subroutine
end interface

save___ptr = C_NULL_PTR
if (present(save__)) save___ptr = C_LOC(save__)

call sirius_find_ground_state_aux(gs_handler,save___ptr)
end subroutine sirius_find_ground_state

!> @brief Update a ground state object after change of atomic coordinates or lattice vectors.
!> @param [in] gs_handler Ground-state handler.
subroutine sirius_update_ground_state(gs_handler)
implicit none
type(C_PTR), intent(in) :: gs_handler
interface
subroutine sirius_update_ground_state_aux(gs_handler)&
&bind(C, name="sirius_update_ground_state")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: gs_handler
end subroutine
end interface

call sirius_update_ground_state_aux(gs_handler)
end subroutine sirius_update_ground_state

!> @brief Add new atom type to the unit cell.
!> @param [in] handler Simulation context handler.
!> @param [in] label Atom type unique label.
!> @param [in] fname Species file name (in JSON format).
!> @param [in] zn Nucleus charge.
!> @param [in] symbol Atomic symbol.
!> @param [in] mass Atomic mass.
!> @param [in] spin_orbit True if spin-orbit correction is enabled for this atom type.
subroutine sirius_add_atom_type(handler,label,fname,zn,symbol,mass,spin_orbit)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
character(C_CHAR), optional, target, dimension(*), intent(in) :: fname
integer(C_INT), optional, target, intent(in) :: zn
character(C_CHAR), optional, target, dimension(*), intent(in) :: symbol
real(C_DOUBLE), optional, target, intent(in) :: mass
logical(C_BOOL), optional, target, intent(in) :: spin_orbit
type(C_PTR) :: fname_ptr
type(C_PTR) :: zn_ptr
type(C_PTR) :: symbol_ptr
type(C_PTR) :: mass_ptr
type(C_PTR) :: spin_orbit_ptr
interface
subroutine sirius_add_atom_type_aux(handler,label,fname,zn,symbol,mass,spin_orbi&
&t)&
&bind(C, name="sirius_add_atom_type")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
type(C_PTR), value, intent(in) :: fname
type(C_PTR), value, intent(in) :: zn
type(C_PTR), value, intent(in) :: symbol
type(C_PTR), value, intent(in) :: mass
type(C_PTR), value, intent(in) :: spin_orbit
end subroutine
end interface

fname_ptr = C_NULL_PTR
if (present(fname)) fname_ptr = C_LOC(fname)

zn_ptr = C_NULL_PTR
if (present(zn)) zn_ptr = C_LOC(zn)

symbol_ptr = C_NULL_PTR
if (present(symbol)) symbol_ptr = C_LOC(symbol)

mass_ptr = C_NULL_PTR
if (present(mass)) mass_ptr = C_LOC(mass)

spin_orbit_ptr = C_NULL_PTR
if (present(spin_orbit)) spin_orbit_ptr = C_LOC(spin_orbit)

call sirius_add_atom_type_aux(handler,label,fname_ptr,zn_ptr,symbol_ptr,mass_ptr&
&,spin_orbit_ptr)
end subroutine sirius_add_atom_type

!> @brief Set radial grid of the atom type.
!> @param [in] handler Simulation context handler.
!> @param [in] label Atom type label.
!> @param [in] num_radial_points Number of radial grid points.
!> @param [in] radial_points List of radial grid points.
subroutine sirius_set_atom_type_radial_grid(handler,label,num_radial_points,radi&
&al_points)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
integer(C_INT), intent(in) :: num_radial_points
real(C_DOUBLE), intent(in) :: radial_points
interface
subroutine sirius_set_atom_type_radial_grid_aux(handler,label,num_radial_points,&
&radial_points)&
&bind(C, name="sirius_set_atom_type_radial_grid")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
integer(C_INT), intent(in) :: num_radial_points
real(C_DOUBLE), intent(in) :: radial_points
end subroutine
end interface

call sirius_set_atom_type_radial_grid_aux(handler,label,num_radial_points,radial&
&_points)
end subroutine sirius_set_atom_type_radial_grid

!> @brief Add one of the radial functions.
!> @param [in] handler Simulation context handler.
!> @param [in] atom_type Label of the atom type.
!> @param [in] label Label of the radial function.
!> @param [in] rf Array with radial function values.
!> @param [in] num_points Length of radial function array.
!> @param [in] n Orbital quantum number.
!> @param [in] l angular momentum.
!> @param [in] idxrf1 First index of radial function (for Q-operator).
!> @param [in] idxrf2 Second index of radial function (for Q-operator).
!> @param [in] occ Occupancy of the wave-function.
subroutine sirius_add_atom_type_radial_function(handler,atom_type,label,rf,num_p&
&oints,n,l,idxrf1,idxrf2,occ)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: atom_type
character(C_CHAR), dimension(*), intent(in) :: label
real(C_DOUBLE), intent(in) :: rf
integer(C_INT), intent(in) :: num_points
integer(C_INT), optional, target, intent(in) :: n
integer(C_INT), optional, target, intent(in) :: l
integer(C_INT), optional, target, intent(in) :: idxrf1
integer(C_INT), optional, target, intent(in) :: idxrf2
real(C_DOUBLE), optional, target, intent(in) :: occ
type(C_PTR) :: n_ptr
type(C_PTR) :: l_ptr
type(C_PTR) :: idxrf1_ptr
type(C_PTR) :: idxrf2_ptr
type(C_PTR) :: occ_ptr
interface
subroutine sirius_add_atom_type_radial_function_aux(handler,atom_type,label,rf,n&
&um_points,n,l,idxrf1,idxrf2,occ)&
&bind(C, name="sirius_add_atom_type_radial_function")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: atom_type
character(C_CHAR), dimension(*), intent(in) :: label
real(C_DOUBLE), intent(in) :: rf
integer(C_INT), intent(in) :: num_points
type(C_PTR), value, intent(in) :: n
type(C_PTR), value, intent(in) :: l
type(C_PTR), value, intent(in) :: idxrf1
type(C_PTR), value, intent(in) :: idxrf2
type(C_PTR), value, intent(in) :: occ
end subroutine
end interface

n_ptr = C_NULL_PTR
if (present(n)) n_ptr = C_LOC(n)

l_ptr = C_NULL_PTR
if (present(l)) l_ptr = C_LOC(l)

idxrf1_ptr = C_NULL_PTR
if (present(idxrf1)) idxrf1_ptr = C_LOC(idxrf1)

idxrf2_ptr = C_NULL_PTR
if (present(idxrf2)) idxrf2_ptr = C_LOC(idxrf2)

occ_ptr = C_NULL_PTR
if (present(occ)) occ_ptr = C_LOC(occ)

call sirius_add_atom_type_radial_function_aux(handler,atom_type,label,rf,num_poi&
&nts,n_ptr,l_ptr,idxrf1_ptr,idxrf2_ptr,occ_ptr)
end subroutine sirius_add_atom_type_radial_function

!> @brief Set the hubbard correction for the atomic type.
!> @param [in] handler Simulation context handler.
!> @param [in] label Atom type label.
!> @param [in] l Orbital quantum number.
!> @param [in] n principal quantum number (s, p, d, f)
!> @param [in] occ Atomic shell occupancy.
!> @param [in] U Hubbard U parameter.
!> @param [in] J Exchange J parameter for the full interaction treatment.
!> @param [in] alpha J_alpha for the simple interaction treatment.
!> @param [in] beta J_beta for the simple interaction treatment.
!> @param [in] J0 J0 for the simple interaction treatment.
subroutine sirius_set_atom_type_hubbard(handler,label,l,n,occ,U,J,alpha,beta,J0)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
integer(C_INT), intent(in) :: l
integer(C_INT), intent(in) :: n
real(C_DOUBLE), intent(in) :: occ
real(C_DOUBLE), intent(in) :: U
real(C_DOUBLE), intent(in) :: J
real(C_DOUBLE), intent(in) :: alpha
real(C_DOUBLE), intent(in) :: beta
real(C_DOUBLE), intent(in) :: J0
interface
subroutine sirius_set_atom_type_hubbard_aux(handler,label,l,n,occ,U,J,alpha,beta&
&,J0)&
&bind(C, name="sirius_set_atom_type_hubbard")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
integer(C_INT), intent(in) :: l
integer(C_INT), intent(in) :: n
real(C_DOUBLE), intent(in) :: occ
real(C_DOUBLE), intent(in) :: U
real(C_DOUBLE), intent(in) :: J
real(C_DOUBLE), intent(in) :: alpha
real(C_DOUBLE), intent(in) :: beta
real(C_DOUBLE), intent(in) :: J0
end subroutine
end interface

call sirius_set_atom_type_hubbard_aux(handler,label,l,n,occ,U,J,alpha,beta,J0)
end subroutine sirius_set_atom_type_hubbard

!> @brief Set ionic part of D-operator matrix.
!> @param [in] handler Simulation context handler.
!> @param [in] label Atom type label.
!> @param [in] num_beta Number of beta-projectors.
!> @param [in] dion Ionic part of D-operator matrix.
subroutine sirius_set_atom_type_dion(handler,label,num_beta,dion)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
integer(C_INT), intent(in) :: num_beta
real(C_DOUBLE), intent(in) :: dion
interface
subroutine sirius_set_atom_type_dion_aux(handler,label,num_beta,dion)&
&bind(C, name="sirius_set_atom_type_dion")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
integer(C_INT), intent(in) :: num_beta
real(C_DOUBLE), intent(in) :: dion
end subroutine
end interface

call sirius_set_atom_type_dion_aux(handler,label,num_beta,dion)
end subroutine sirius_set_atom_type_dion

!> @brief Set PAW related data.
!> @param [in] handler Simulation context handler.
!> @param [in] label Atom type label.
!> @param [in] core_energy Core-electrons energy contribution.
!> @param [in] occupations ?
!> @param [in] num_occ ?
subroutine sirius_set_atom_type_paw(handler,label,core_energy,occupations,num_oc&
&c)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
real(C_DOUBLE), intent(in) :: core_energy
real(C_DOUBLE), intent(in) :: occupations
integer(C_INT), intent(in) :: num_occ
interface
subroutine sirius_set_atom_type_paw_aux(handler,label,core_energy,occupations,nu&
&m_occ)&
&bind(C, name="sirius_set_atom_type_paw")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
real(C_DOUBLE), intent(in) :: core_energy
real(C_DOUBLE), intent(in) :: occupations
integer(C_INT), intent(in) :: num_occ
end subroutine
end interface

call sirius_set_atom_type_paw_aux(handler,label,core_energy,occupations,num_occ)
end subroutine sirius_set_atom_type_paw

!> @brief Add atom to the unit cell.
!> @param [in] handler Simulation context handler.
!> @param [in] label Atom type label.
!> @param [in] position Atom position in lattice coordinates.
!> @param [in] vector_field Starting magnetization.
subroutine sirius_add_atom(handler,label,position,vector_field)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
real(C_DOUBLE), intent(in) :: position
real(C_DOUBLE), optional, target, intent(in) :: vector_field
type(C_PTR) :: vector_field_ptr
interface
subroutine sirius_add_atom_aux(handler,label,position,vector_field)&
&bind(C, name="sirius_add_atom")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
real(C_DOUBLE), intent(in) :: position
type(C_PTR), value, intent(in) :: vector_field
end subroutine
end interface

vector_field_ptr = C_NULL_PTR
if (present(vector_field)) vector_field_ptr = C_LOC(vector_field)

call sirius_add_atom_aux(handler,label,position,vector_field_ptr)
end subroutine sirius_add_atom

!> @brief Set new atomic position.
!> @param [in] handler Simulation context handler.
!> @param [in] ia Index of atom.
!> @param [in] position Atom position in lattice coordinates.
subroutine sirius_set_atom_position(handler,ia,position)
implicit none
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: ia
real(C_DOUBLE), intent(in) :: position
interface
subroutine sirius_set_atom_position_aux(handler,ia,position)&
&bind(C, name="sirius_set_atom_position")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: ia
real(C_DOUBLE), intent(in) :: position
end subroutine
end interface

call sirius_set_atom_position_aux(handler,ia,position)
end subroutine sirius_set_atom_position

!> @brief Set plane-wave coefficients of a periodic function.
!> @param [in] handler Ground state handler.
!> @param [in] label Label of the function.
!> @param [in] pw_coeffs Local array of plane-wave coefficients.
!> @param [in] transform_to_rg True if function has to be transformed to real-space grid.
!> @param [in] ngv Local number of G-vectors.
!> @param [in] gvl List of G-vectors in lattice coordinates (Miller indices).
!> @param [in] comm MPI communicator used in distribution of G-vectors
subroutine sirius_set_pw_coeffs(handler,label,pw_coeffs,transform_to_rg,ngv,gvl,&
&comm)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
complex(C_DOUBLE), intent(in) :: pw_coeffs
logical(C_BOOL), optional, target, intent(in) :: transform_to_rg
integer(C_INT), optional, target, intent(in) :: ngv
integer(C_INT), optional, target, intent(in) :: gvl
integer(C_INT), optional, target, intent(in) :: comm
type(C_PTR) :: transform_to_rg_ptr
type(C_PTR) :: ngv_ptr
type(C_PTR) :: gvl_ptr
type(C_PTR) :: comm_ptr
interface
subroutine sirius_set_pw_coeffs_aux(handler,label,pw_coeffs,transform_to_rg,ngv,&
&gvl,comm)&
&bind(C, name="sirius_set_pw_coeffs")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
complex(C_DOUBLE), intent(in) :: pw_coeffs
type(C_PTR), value, intent(in) :: transform_to_rg
type(C_PTR), value, intent(in) :: ngv
type(C_PTR), value, intent(in) :: gvl
type(C_PTR), value, intent(in) :: comm
end subroutine
end interface

transform_to_rg_ptr = C_NULL_PTR
if (present(transform_to_rg)) transform_to_rg_ptr = C_LOC(transform_to_rg)

ngv_ptr = C_NULL_PTR
if (present(ngv)) ngv_ptr = C_LOC(ngv)

gvl_ptr = C_NULL_PTR
if (present(gvl)) gvl_ptr = C_LOC(gvl)

comm_ptr = C_NULL_PTR
if (present(comm)) comm_ptr = C_LOC(comm)

call sirius_set_pw_coeffs_aux(handler,label,pw_coeffs,transform_to_rg_ptr,ngv_pt&
&r,gvl_ptr,comm_ptr)
end subroutine sirius_set_pw_coeffs

!> @brief Get plane-wave coefficients of a periodic function.
!> @param [in] handler Ground state handler.
!> @param [in] label Label of the function.
!> @param [in] pw_coeffs Local array of plane-wave coefficients.
!> @param [in] ngv Local number of G-vectors.
!> @param [in] gvl List of G-vectors in lattice coordinates (Miller indices).
!> @param [in] comm MPI communicator used in distribution of G-vectors
subroutine sirius_get_pw_coeffs(handler,label,pw_coeffs,ngv,gvl,comm)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
complex(C_DOUBLE), intent(in) :: pw_coeffs
integer(C_INT), optional, target, intent(in) :: ngv
integer(C_INT), optional, target, intent(in) :: gvl
integer(C_INT), optional, target, intent(in) :: comm
type(C_PTR) :: ngv_ptr
type(C_PTR) :: gvl_ptr
type(C_PTR) :: comm_ptr
interface
subroutine sirius_get_pw_coeffs_aux(handler,label,pw_coeffs,ngv,gvl,comm)&
&bind(C, name="sirius_get_pw_coeffs")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
complex(C_DOUBLE), intent(in) :: pw_coeffs
type(C_PTR), value, intent(in) :: ngv
type(C_PTR), value, intent(in) :: gvl
type(C_PTR), value, intent(in) :: comm
end subroutine
end interface

ngv_ptr = C_NULL_PTR
if (present(ngv)) ngv_ptr = C_LOC(ngv)

gvl_ptr = C_NULL_PTR
if (present(gvl)) gvl_ptr = C_LOC(gvl)

comm_ptr = C_NULL_PTR
if (present(comm)) comm_ptr = C_LOC(comm)

call sirius_get_pw_coeffs_aux(handler,label,pw_coeffs,ngv_ptr,gvl_ptr,comm_ptr)
end subroutine sirius_get_pw_coeffs

!> @brief Get atom type contribution to plane-wave coefficients of a periodic function.
!> @param [in] handler Simulation context handler.
!> @param [in] atom_type Label of the atom type.
!> @param [in] label Label of the function.
!> @param [in] pw_coeffs Local array of plane-wave coefficients.
!> @param [in] ngv Local number of G-vectors.
!> @param [in] gvl List of G-vectors in lattice coordinates (Miller indices).
!> @param [in] comm MPI communicator used in distribution of G-vectors
subroutine sirius_get_pw_coeffs_real(handler,atom_type,label,pw_coeffs,ngv,gvl,c&
&omm)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: atom_type
character(C_CHAR), dimension(*), intent(in) :: label
real(C_DOUBLE), intent(in) :: pw_coeffs
integer(C_INT), optional, target, intent(in) :: ngv
integer(C_INT), optional, target, intent(in) :: gvl
integer(C_INT), optional, target, intent(in) :: comm
type(C_PTR) :: ngv_ptr
type(C_PTR) :: gvl_ptr
type(C_PTR) :: comm_ptr
interface
subroutine sirius_get_pw_coeffs_real_aux(handler,atom_type,label,pw_coeffs,ngv,g&
&vl,comm)&
&bind(C, name="sirius_get_pw_coeffs_real")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: atom_type
character(C_CHAR), dimension(*), intent(in) :: label
real(C_DOUBLE), intent(in) :: pw_coeffs
type(C_PTR), value, intent(in) :: ngv
type(C_PTR), value, intent(in) :: gvl
type(C_PTR), value, intent(in) :: comm
end subroutine
end interface

ngv_ptr = C_NULL_PTR
if (present(ngv)) ngv_ptr = C_LOC(ngv)

gvl_ptr = C_NULL_PTR
if (present(gvl)) gvl_ptr = C_LOC(gvl)

comm_ptr = C_NULL_PTR
if (present(comm)) comm_ptr = C_LOC(comm)

call sirius_get_pw_coeffs_real_aux(handler,atom_type,label,pw_coeffs,ngv_ptr,gvl&
&_ptr,comm_ptr)
end subroutine sirius_get_pw_coeffs_real

!> @brief Initialize the subspace of wave-functions.
!> @param [in] gs_handler Ground state handler.
!> @param [in] ks_handler K-point set handler.
subroutine sirius_initialize_subspace(gs_handler,ks_handler)
implicit none
type(C_PTR), intent(in) :: gs_handler
type(C_PTR), intent(in) :: ks_handler
interface
subroutine sirius_initialize_subspace_aux(gs_handler,ks_handler)&
&bind(C, name="sirius_initialize_subspace")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: gs_handler
type(C_PTR), intent(in) :: ks_handler
end subroutine
end interface

call sirius_initialize_subspace_aux(gs_handler,ks_handler)
end subroutine sirius_initialize_subspace

!> @brief Find eigen-states of the Hamiltonian/
!> @param [in] gs_handler Ground state handler.
!> @param [in] ks_handler K-point set handler.
!> @param [in] precompute True if neccessary data to setup eigen-value problem must be automatically precomputed.
!> @param [in] iter_solver_tol Iterative solver tolerance.
subroutine sirius_find_eigen_states(gs_handler,ks_handler,precompute,iter_solver&
&_tol)
implicit none
type(C_PTR), intent(in) :: gs_handler
type(C_PTR), intent(in) :: ks_handler
logical(C_BOOL), intent(in) :: precompute
real(C_DOUBLE), optional, target, intent(in) :: iter_solver_tol
type(C_PTR) :: iter_solver_tol_ptr
interface
subroutine sirius_find_eigen_states_aux(gs_handler,ks_handler,precompute,iter_so&
&lver_tol)&
&bind(C, name="sirius_find_eigen_states")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: gs_handler
type(C_PTR), intent(in) :: ks_handler
logical(C_BOOL), intent(in) :: precompute
type(C_PTR), value, intent(in) :: iter_solver_tol
end subroutine
end interface

iter_solver_tol_ptr = C_NULL_PTR
if (present(iter_solver_tol)) iter_solver_tol_ptr = C_LOC(iter_solver_tol)

call sirius_find_eigen_states_aux(gs_handler,ks_handler,precompute,iter_solver_t&
&ol_ptr)
end subroutine sirius_find_eigen_states

!> @brief Generate D-operator matrix.
!> @param [in] handler Ground state handler.
subroutine sirius_generate_d_operator_matrix(handler)
implicit none
type(C_PTR), intent(in) :: handler
interface
subroutine sirius_generate_d_operator_matrix_aux(handler)&
&bind(C, name="sirius_generate_d_operator_matrix")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
end subroutine
end interface

call sirius_generate_d_operator_matrix_aux(handler)
end subroutine sirius_generate_d_operator_matrix

!> @brief Generate initial density.
!> @param [in] handler Ground state handler.
subroutine sirius_generate_initial_density(handler)
implicit none
type(C_PTR), intent(in) :: handler
interface
subroutine sirius_generate_initial_density_aux(handler)&
&bind(C, name="sirius_generate_initial_density")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
end subroutine
end interface

call sirius_generate_initial_density_aux(handler)
end subroutine sirius_generate_initial_density

!> @brief Generate effective potential and magnetic field.
!> @param [in] handler Ground state handler.
subroutine sirius_generate_effective_potential(handler)
implicit none
type(C_PTR), intent(in) :: handler
interface
subroutine sirius_generate_effective_potential_aux(handler)&
&bind(C, name="sirius_generate_effective_potential")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
end subroutine
end interface

call sirius_generate_effective_potential_aux(handler)
end subroutine sirius_generate_effective_potential

!> @brief Generate charge density and magnetization.
!> @param [in] gs_handler Ground state handler.
!> @param [in] add_core Add core charge density in the muffin-tins.
!> @param [in] transform_to_rg If true, density and magnetization are transformed to real-space grid.
subroutine sirius_generate_density(gs_handler,add_core,transform_to_rg)
implicit none
type(C_PTR), intent(in) :: gs_handler
logical(C_BOOL), optional, target, intent(in) :: add_core
logical(C_BOOL), optional, target, intent(in) :: transform_to_rg
type(C_PTR) :: add_core_ptr
type(C_PTR) :: transform_to_rg_ptr
interface
subroutine sirius_generate_density_aux(gs_handler,add_core,transform_to_rg)&
&bind(C, name="sirius_generate_density")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: gs_handler
type(C_PTR), value, intent(in) :: add_core
type(C_PTR), value, intent(in) :: transform_to_rg
end subroutine
end interface

add_core_ptr = C_NULL_PTR
if (present(add_core)) add_core_ptr = C_LOC(add_core)

transform_to_rg_ptr = C_NULL_PTR
if (present(transform_to_rg)) transform_to_rg_ptr = C_LOC(transform_to_rg)

call sirius_generate_density_aux(gs_handler,add_core_ptr,transform_to_rg_ptr)
end subroutine sirius_generate_density

!> @brief Set band occupancies.
!> @param [in] ks_handler K-point set handler.
!> @param [in] ik Global index of k-point.
!> @param [in] ispn Spin component.
!> @param [in] band_occupancies Array of band occupancies.
subroutine sirius_set_band_occupancies(ks_handler,ik,ispn,band_occupancies)
implicit none
type(C_PTR), intent(in) :: ks_handler
integer(C_INT), intent(in) :: ik
integer(C_INT), intent(in) :: ispn
real(C_DOUBLE), intent(in) :: band_occupancies
interface
subroutine sirius_set_band_occupancies_aux(ks_handler,ik,ispn,band_occupancies)&
&bind(C, name="sirius_set_band_occupancies")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: ks_handler
integer(C_INT), intent(in) :: ik
integer(C_INT), intent(in) :: ispn
real(C_DOUBLE), intent(in) :: band_occupancies
end subroutine
end interface

call sirius_set_band_occupancies_aux(ks_handler,ik,ispn,band_occupancies)
end subroutine sirius_set_band_occupancies

!> @brief Get band energies.
!> @param [in] ks_handler K-point set handler.
!> @param [in] ik Global index of k-point.
!> @param [in] ispn Spin component.
!> @param [out] band_energies Array of band energies.
subroutine sirius_get_band_energies(ks_handler,ik,ispn,band_energies)
implicit none
type(C_PTR), intent(in) :: ks_handler
integer(C_INT), intent(in) :: ik
integer(C_INT), intent(in) :: ispn
real(C_DOUBLE), intent(out) :: band_energies
interface
subroutine sirius_get_band_energies_aux(ks_handler,ik,ispn,band_energies)&
&bind(C, name="sirius_get_band_energies")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: ks_handler
integer(C_INT), intent(in) :: ik
integer(C_INT), intent(in) :: ispn
real(C_DOUBLE), intent(out) :: band_energies
end subroutine
end interface

call sirius_get_band_energies_aux(ks_handler,ik,ispn,band_energies)
end subroutine sirius_get_band_energies

!> @brief Get D-operator matrix
!> @param [in] handler Simulation context handler.
!> @param [in] ia Global index of atom.
!> @param [in] ispn Spin component.
!> @param [out] d_mtrx D-matrix.
!> @param [in] ld Leading dimention of D-matrix.
subroutine sirius_get_d_operator_matrix(handler,ia,ispn,d_mtrx,ld)
implicit none
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: ia
integer(C_INT), intent(in) :: ispn
real(C_DOUBLE), intent(out) :: d_mtrx
integer(C_INT), intent(in) :: ld
interface
subroutine sirius_get_d_operator_matrix_aux(handler,ia,ispn,d_mtrx,ld)&
&bind(C, name="sirius_get_d_operator_matrix")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: ia
integer(C_INT), intent(in) :: ispn
real(C_DOUBLE), intent(out) :: d_mtrx
integer(C_INT), intent(in) :: ld
end subroutine
end interface

call sirius_get_d_operator_matrix_aux(handler,ia,ispn,d_mtrx,ld)
end subroutine sirius_get_d_operator_matrix

!> @brief Set D-operator matrix
!> @param [in] handler Simulation context handler.
!> @param [in] ia Global index of atom.
!> @param [in] ispn Spin component.
!> @param [out] d_mtrx D-matrix.
!> @param [in] ld Leading dimention of D-matrix.
subroutine sirius_set_d_operator_matrix(handler,ia,ispn,d_mtrx,ld)
implicit none
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: ia
integer(C_INT), intent(in) :: ispn
real(C_DOUBLE), intent(out) :: d_mtrx
integer(C_INT), intent(in) :: ld
interface
subroutine sirius_set_d_operator_matrix_aux(handler,ia,ispn,d_mtrx,ld)&
&bind(C, name="sirius_set_d_operator_matrix")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: ia
integer(C_INT), intent(in) :: ispn
real(C_DOUBLE), intent(out) :: d_mtrx
integer(C_INT), intent(in) :: ld
end subroutine
end interface

call sirius_set_d_operator_matrix_aux(handler,ia,ispn,d_mtrx,ld)
end subroutine sirius_set_d_operator_matrix

!> @brief Set Q-operator matrix
!> @param [in] handler Simulation context handler.
!> @param [in] label Atom type label.
!> @param [out] q_mtrx Q-matrix.
!> @param [in] ld Leading dimention of Q-matrix.
subroutine sirius_set_q_operator_matrix(handler,label,q_mtrx,ld)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
real(C_DOUBLE), intent(out) :: q_mtrx
integer(C_INT), intent(in) :: ld
interface
subroutine sirius_set_q_operator_matrix_aux(handler,label,q_mtrx,ld)&
&bind(C, name="sirius_set_q_operator_matrix")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
real(C_DOUBLE), intent(out) :: q_mtrx
integer(C_INT), intent(in) :: ld
end subroutine
end interface

call sirius_set_q_operator_matrix_aux(handler,label,q_mtrx,ld)
end subroutine sirius_set_q_operator_matrix

!> @brief Get Q-operator matrix
!> @param [in] handler Simulation context handler.
!> @param [in] label Atom type label.
!> @param [out] q_mtrx Q-matrix.
!> @param [in] ld Leading dimention of Q-matrix.
subroutine sirius_get_q_operator_matrix(handler,label,q_mtrx,ld)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
real(C_DOUBLE), intent(out) :: q_mtrx
integer(C_INT), intent(in) :: ld
interface
subroutine sirius_get_q_operator_matrix_aux(handler,label,q_mtrx,ld)&
&bind(C, name="sirius_get_q_operator_matrix")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
real(C_DOUBLE), intent(out) :: q_mtrx
integer(C_INT), intent(in) :: ld
end subroutine
end interface

call sirius_get_q_operator_matrix_aux(handler,label,q_mtrx,ld)
end subroutine sirius_get_q_operator_matrix

!> @brief Get all components of complex density matrix.
!> @param [in] handler DFT ground state handler.
!> @param [in] ia Global index of atom.
!> @param [out] dm Complex density matrix.
!> @param [in] ld Leading dimention of the density matrix.
subroutine sirius_get_density_matrix(handler,ia,dm,ld)
implicit none
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: ia
complex(C_DOUBLE), intent(out) :: dm
integer(C_INT), intent(in) :: ld
interface
subroutine sirius_get_density_matrix_aux(handler,ia,dm,ld)&
&bind(C, name="sirius_get_density_matrix")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: ia
complex(C_DOUBLE), intent(out) :: dm
integer(C_INT), intent(in) :: ld
end subroutine
end interface

call sirius_get_density_matrix_aux(handler,ia,dm,ld)
end subroutine sirius_get_density_matrix

!> @brief Set all components of complex density matrix.
!> @param [in] handler DFT ground state handler.
!> @param [in] ia Global index of atom.
!> @param [out] dm Complex density matrix.
!> @param [in] ld Leading dimention of the density matrix.
subroutine sirius_set_density_matrix(handler,ia,dm,ld)
implicit none
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: ia
complex(C_DOUBLE), intent(out) :: dm
integer(C_INT), intent(in) :: ld
interface
subroutine sirius_set_density_matrix_aux(handler,ia,dm,ld)&
&bind(C, name="sirius_set_density_matrix")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: ia
complex(C_DOUBLE), intent(out) :: dm
integer(C_INT), intent(in) :: ld
end subroutine
end interface

call sirius_set_density_matrix_aux(handler,ia,dm,ld)
end subroutine sirius_set_density_matrix

!> @brief Get one of the total energy components.
!> @param [in] handler DFT ground state handler.
!> @param [in] label Label of the energy component to get.
!> @param [out] energy Total energy component.
subroutine sirius_get_energy(handler,label,energy)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
real(C_DOUBLE), intent(out) :: energy
interface
subroutine sirius_get_energy_aux(handler,label,energy)&
&bind(C, name="sirius_get_energy")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
real(C_DOUBLE), intent(out) :: energy
end subroutine
end interface

call sirius_get_energy_aux(handler,label,energy)
end subroutine sirius_get_energy

!> @brief Get one of the total force components.
!> @param [in] handler DFT ground state handler.
!> @param [in] label Label of the force component to get.
!> @param [out] forces Total force component for each atom.
subroutine sirius_get_forces(handler,label,forces)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
real(C_DOUBLE), intent(out) :: forces
interface
subroutine sirius_get_forces_aux(handler,label,forces)&
&bind(C, name="sirius_get_forces")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
real(C_DOUBLE), intent(out) :: forces
end subroutine
end interface

call sirius_get_forces_aux(handler,label,forces)
end subroutine sirius_get_forces

!> @brief Get one of the stress tensor components.
!> @param [in] handler DFT ground state handler.
!> @param [in] label Label of the stress tensor component to get.
!> @param [out] stress_tensor Component of the total stress tensor.
subroutine sirius_get_stress_tensor(handler,label,stress_tensor)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
real(C_DOUBLE), intent(out) :: stress_tensor
interface
subroutine sirius_get_stress_tensor_aux(handler,label,stress_tensor)&
&bind(C, name="sirius_get_stress_tensor")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
real(C_DOUBLE), intent(out) :: stress_tensor
end subroutine
end interface

call sirius_get_stress_tensor_aux(handler,label,stress_tensor)
end subroutine sirius_get_stress_tensor

!> @brief Get the number of beta-projectors for an atom type.
!> @param [in] handler Simulation context handler.
!> @param [in] label Atom type label.
function sirius_get_num_beta_projectors(handler,label) result(res)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
integer(C_INT) :: res
interface
function sirius_get_num_beta_projectors_aux(handler,label) result(res)&
&bind(C, name="sirius_get_num_beta_projectors")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
integer(C_INT) :: res
end function
end interface

res = sirius_get_num_beta_projectors_aux(handler,label)
end function sirius_get_num_beta_projectors

!> @brief Get plane-wave coefficients of Q-operator
!> @param [in] handler Simulation context handler.
!> @param [in] label Label of the atom type.
!> @param [in] xi1 First index of beta-projector atomic function.
!> @param [in] xi2 Second index of beta-projector atomic function.
!> @param [in] ngv Number of G-vectors.
!> @param [in] gvl G-vectors in lattice coordinats.
!> @param [out] q_pw Plane-wave coefficients of Q augmentation operator.
subroutine sirius_get_q_operator(handler,label,xi1,xi2,ngv,gvl,q_pw)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
integer(C_INT), intent(in) :: xi1
integer(C_INT), intent(in) :: xi2
integer(C_INT), intent(in) :: ngv
integer(C_INT), intent(in) :: gvl
complex(C_DOUBLE), intent(out) :: q_pw
interface
subroutine sirius_get_q_operator_aux(handler,label,xi1,xi2,ngv,gvl,q_pw)&
&bind(C, name="sirius_get_q_operator")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
integer(C_INT), intent(in) :: xi1
integer(C_INT), intent(in) :: xi2
integer(C_INT), intent(in) :: ngv
integer(C_INT), intent(in) :: gvl
complex(C_DOUBLE), intent(out) :: q_pw
end subroutine
end interface

call sirius_get_q_operator_aux(handler,label,xi1,xi2,ngv,gvl,q_pw)
end subroutine sirius_get_q_operator

!> @brief Get wave-functions.
!> @param [in] ks_handler K-point set handler.
!> @param [in] ik Global index of k-point
!> @param [in] ispn Spin index.
!> @param [in] npw Local number of G+k vectors.
!> @param [in] gvec_k List of G-vectors.
!> @param [out] evc Wave-functions.
!> @param [in] ld1 Leading dimention of evc array.
!> @param [in] ld2 Second dimention of evc array.
subroutine sirius_get_wave_functions(ks_handler,ik,ispn,npw,gvec_k,evc,ld1,ld2)
implicit none
type(C_PTR), intent(in) :: ks_handler
integer(C_INT), intent(in) :: ik
integer(C_INT), intent(in) :: ispn
integer(C_INT), intent(in) :: npw
integer(C_INT), intent(in) :: gvec_k
complex(C_DOUBLE), intent(out) :: evc
integer(C_INT), intent(in) :: ld1
integer(C_INT), intent(in) :: ld2
interface
subroutine sirius_get_wave_functions_aux(ks_handler,ik,ispn,npw,gvec_k,evc,ld1,l&
&d2)&
&bind(C, name="sirius_get_wave_functions")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: ks_handler
integer(C_INT), intent(in) :: ik
integer(C_INT), intent(in) :: ispn
integer(C_INT), intent(in) :: npw
integer(C_INT), intent(in) :: gvec_k
complex(C_DOUBLE), intent(out) :: evc
integer(C_INT), intent(in) :: ld1
integer(C_INT), intent(in) :: ld2
end subroutine
end interface

call sirius_get_wave_functions_aux(ks_handler,ik,ispn,npw,gvec_k,evc,ld1,ld2)
end subroutine sirius_get_wave_functions

!> @brief Get value of the radial integral.
!> @param [in] handler Simulation context handler.
!> @param [in] atom_type Label of the atom type.
!> @param [in] label Label of the radial integral.
!> @param [in] q Length of the reciprocal wave-vector.
!> @param [in] idx Index of the radial integral.
!> @param [in] l Orbital quantum number (for Q-radial integrals).
function sirius_get_radial_integral(handler,atom_type,label,q,idx,l) result(res)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: atom_type
character(C_CHAR), dimension(*), intent(in) :: label
real(C_DOUBLE), intent(in) :: q
integer(C_INT), intent(in) :: idx
integer(C_INT), optional, target, intent(in) :: l
real(C_DOUBLE) :: res
type(C_PTR) :: l_ptr
interface
function sirius_get_radial_integral_aux(handler,atom_type,label,q,idx,l) result(&
&res)&
&bind(C, name="sirius_get_radial_integral")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: atom_type
character(C_CHAR), dimension(*), intent(in) :: label
real(C_DOUBLE), intent(in) :: q
integer(C_INT), intent(in) :: idx
type(C_PTR), value, intent(in) :: l
real(C_DOUBLE) :: res
end function
end interface

l_ptr = C_NULL_PTR
if (present(l)) l_ptr = C_LOC(l)

res = sirius_get_radial_integral_aux(handler,atom_type,label,q,idx,l_ptr)
end function sirius_get_radial_integral

!> @brief Compute occupation matrix.
!> @param [in] handler Ground state handler.
subroutine sirius_calculate_hubbard_occupancies(handler)
implicit none
type(C_PTR), intent(in) :: handler
interface
subroutine sirius_calculate_hubbard_occupancies_aux(handler)&
&bind(C, name="sirius_calculate_hubbard_occupancies")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
end subroutine
end interface

call sirius_calculate_hubbard_occupancies_aux(handler)
end subroutine sirius_calculate_hubbard_occupancies

!> @brief Set occupation matrix for LDA+U.
!> @param [in] handler Ground state handler.
!> @param [inout] occ Occupation matrix.
!> @param [in] ld Leading dimensions of the occupation matrix.
subroutine sirius_set_hubbard_occupancies(handler,occ,ld)
implicit none
type(C_PTR), intent(in) :: handler
complex(C_DOUBLE), intent(inout) :: occ
integer(C_INT), intent(in) :: ld
interface
subroutine sirius_set_hubbard_occupancies_aux(handler,occ,ld)&
&bind(C, name="sirius_set_hubbard_occupancies")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
complex(C_DOUBLE), intent(inout) :: occ
integer(C_INT), intent(in) :: ld
end subroutine
end interface

call sirius_set_hubbard_occupancies_aux(handler,occ,ld)
end subroutine sirius_set_hubbard_occupancies

!> @brief Get occupation matrix for LDA+U.
!> @param [in] handler Ground state handler.
!> @param [inout] occ Occupation matrix.
!> @param [in] ld Leading dimensions of the occupation matrix.
subroutine sirius_get_hubbard_occupancies(handler,occ,ld)
implicit none
type(C_PTR), intent(in) :: handler
complex(C_DOUBLE), intent(inout) :: occ
integer(C_INT), intent(in) :: ld
interface
subroutine sirius_get_hubbard_occupancies_aux(handler,occ,ld)&
&bind(C, name="sirius_get_hubbard_occupancies")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
complex(C_DOUBLE), intent(inout) :: occ
integer(C_INT), intent(in) :: ld
end subroutine
end interface

call sirius_get_hubbard_occupancies_aux(handler,occ,ld)
end subroutine sirius_get_hubbard_occupancies

!> @brief Set LDA+U potential matrix.
!> @param [in] handler Ground state handler.
!> @param [inout] pot Potential correction matrix.
!> @param [in] ld Leading dimensions of the matrix.
subroutine sirius_set_hubbard_potential(handler,pot,ld)
implicit none
type(C_PTR), intent(in) :: handler
complex(C_DOUBLE), intent(inout) :: pot
integer(C_INT), intent(in) :: ld
interface
subroutine sirius_set_hubbard_potential_aux(handler,pot,ld)&
&bind(C, name="sirius_set_hubbard_potential")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
complex(C_DOUBLE), intent(inout) :: pot
integer(C_INT), intent(in) :: ld
end subroutine
end interface

call sirius_set_hubbard_potential_aux(handler,pot,ld)
end subroutine sirius_set_hubbard_potential

!> @brief Set LDA+U potential matrix.
!> @param [in] handler Ground state handler.
!> @param [inout] pot Potential correction matrix.
!> @param [in] ld Leading dimensions of the matrix.
subroutine sirius_get_hubbard_potential(handler,pot,ld)
implicit none
type(C_PTR), intent(in) :: handler
complex(C_DOUBLE), intent(inout) :: pot
integer(C_INT), intent(in) :: ld
interface
subroutine sirius_get_hubbard_potential_aux(handler,pot,ld)&
&bind(C, name="sirius_get_hubbard_potential")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
complex(C_DOUBLE), intent(inout) :: pot
integer(C_INT), intent(in) :: ld
end subroutine
end interface

call sirius_get_hubbard_potential_aux(handler,pot,ld)
end subroutine sirius_get_hubbard_potential

!> @brief Add descriptor of the augmented wave radial function.
!> @param [in] handler Simulation context handler.
!> @param [in] label Atom type label.
!> @param [in] n Principal quantum number.
!> @param [in] l Orbital quantum number.
!> @param [in] enu Linearization energy.
!> @param [in] dme Order of energy derivative.
!> @param [in] auto_enu True if automatic search of linearization energy is allowed for this radial solution.
subroutine sirius_add_atom_type_aw_descriptor(handler,label,n,l,enu,dme,auto_enu&
&)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
integer(C_INT), intent(in) :: n
integer(C_INT), intent(in) :: l
real(C_DOUBLE), intent(in) :: enu
integer(C_INT), intent(in) :: dme
logical(C_BOOL), intent(in) :: auto_enu
interface
subroutine sirius_add_atom_type_aw_descriptor_aux(handler,label,n,l,enu,dme,auto&
&_enu)&
&bind(C, name="sirius_add_atom_type_aw_descriptor")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
integer(C_INT), intent(in) :: n
integer(C_INT), intent(in) :: l
real(C_DOUBLE), intent(in) :: enu
integer(C_INT), intent(in) :: dme
logical(C_BOOL), intent(in) :: auto_enu
end subroutine
end interface

call sirius_add_atom_type_aw_descriptor_aux(handler,label,n,l,enu,dme,auto_enu)
end subroutine sirius_add_atom_type_aw_descriptor

!> @brief Add descriptor of the local orbital radial function.
!> @param [in] handler Simulation context handler.
!> @param [in] label Atom type label.
!> @param [in] ilo Index of the local orbital to which the descriptro is added.
!> @param [in] n Principal quantum number.
!> @param [in] l Orbital quantum number.
!> @param [in] enu Linearization energy.
!> @param [in] dme Order of energy derivative.
!> @param [in] auto_enu True if automatic search of linearization energy is allowed for this radial solution.
subroutine sirius_add_atom_type_lo_descriptor(handler,label,ilo,n,l,enu,dme,auto&
&_enu)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
integer(C_INT), intent(in) :: ilo
integer(C_INT), intent(in) :: n
integer(C_INT), intent(in) :: l
real(C_DOUBLE), intent(in) :: enu
integer(C_INT), intent(in) :: dme
logical(C_BOOL), intent(in) :: auto_enu
interface
subroutine sirius_add_atom_type_lo_descriptor_aux(handler,label,ilo,n,l,enu,dme,&
&auto_enu)&
&bind(C, name="sirius_add_atom_type_lo_descriptor")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
integer(C_INT), intent(in) :: ilo
integer(C_INT), intent(in) :: n
integer(C_INT), intent(in) :: l
real(C_DOUBLE), intent(in) :: enu
integer(C_INT), intent(in) :: dme
logical(C_BOOL), intent(in) :: auto_enu
end subroutine
end interface

call sirius_add_atom_type_lo_descriptor_aux(handler,label,ilo,n,l,enu,dme,auto_e&
&nu)
end subroutine sirius_add_atom_type_lo_descriptor

!> @brief Set configuration of atomic levels.
!> @param [in] handler Simulation context handler.
!> @param [in] label Atom type label.
!> @param [in] n Principal quantum number.
!> @param [in] l Orbital quantum number.
!> @param [in] k kappa (used in relativistic solver).
!> @param [in] occupancy Level occupancy.
!> @param [in] core Tru if this is a core state.
subroutine sirius_set_atom_type_configuration(handler,label,n,l,k,occupancy,core&
&)
implicit none
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
integer(C_INT), intent(in) :: n
integer(C_INT), intent(in) :: l
integer(C_INT), intent(in) :: k
real(C_DOUBLE), intent(in) :: occupancy
logical(C_BOOL), intent(in) :: core
interface
subroutine sirius_set_atom_type_configuration_aux(handler,label,n,l,k,occupancy,&
&core)&
&bind(C, name="sirius_set_atom_type_configuration")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
character(C_CHAR), dimension(*), intent(in) :: label
integer(C_INT), intent(in) :: n
integer(C_INT), intent(in) :: l
integer(C_INT), intent(in) :: k
real(C_DOUBLE), intent(in) :: occupancy
logical(C_BOOL), intent(in) :: core
end subroutine
end interface

call sirius_set_atom_type_configuration_aux(handler,label,n,l,k,occupancy,core)
end subroutine sirius_set_atom_type_configuration

!> @brief Generate Coulomb potential by solving Poisson equation
!> @param [in] handler Ground state handler
!> @param [out] vclmt Muffin-tin part of potential
!> @param [out] vclrg Regular-grid part of potential
subroutine sirius_generate_coulomb_potential(handler,vclmt,vclrg)
implicit none
type(C_PTR), intent(in) :: handler
real(C_DOUBLE), intent(out) :: vclmt
real(C_DOUBLE), intent(out) :: vclrg
interface
subroutine sirius_generate_coulomb_potential_aux(handler,vclmt,vclrg)&
&bind(C, name="sirius_generate_coulomb_potential")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
real(C_DOUBLE), intent(out) :: vclmt
real(C_DOUBLE), intent(out) :: vclrg
end subroutine
end interface

call sirius_generate_coulomb_potential_aux(handler,vclmt,vclrg)
end subroutine sirius_generate_coulomb_potential

!> @brief Generate XC potential using LibXC
!> @param [in] handler Ground state handler
!> @param [out] vxcmt Muffin-tin part of potential
!> @param [out] vxcrg Regular-grid part of potential
!> @param [out] bxcmt Muffin-tin part of effective magentic field
!> @param [out] bxcrg Regular-grid part of effective magnetic field
subroutine sirius_generate_xc_potential(handler,vxcmt,vxcrg,bxcmt,bxcrg)
implicit none
type(C_PTR), intent(in) :: handler
real(C_DOUBLE), intent(out) :: vxcmt
real(C_DOUBLE), intent(out) :: vxcrg
real(C_DOUBLE), intent(out) :: bxcmt
real(C_DOUBLE), intent(out) :: bxcrg
interface
subroutine sirius_generate_xc_potential_aux(handler,vxcmt,vxcrg,bxcmt,bxcrg)&
&bind(C, name="sirius_generate_xc_potential")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
real(C_DOUBLE), intent(out) :: vxcmt
real(C_DOUBLE), intent(out) :: vxcrg
real(C_DOUBLE), intent(out) :: bxcmt
real(C_DOUBLE), intent(out) :: bxcrg
end subroutine
end interface

call sirius_generate_xc_potential_aux(handler,vxcmt,vxcrg,bxcmt,bxcrg)
end subroutine sirius_generate_xc_potential

!> @brief Get communicator which is used to split k-points
!> @param [in] handler Simulation context handler
!> @param [out] fcomm Fortran communicator
subroutine sirius_get_kpoint_inter_comm(handler,fcomm)
implicit none
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(out) :: fcomm
interface
subroutine sirius_get_kpoint_inter_comm_aux(handler,fcomm)&
&bind(C, name="sirius_get_kpoint_inter_comm")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(out) :: fcomm
end subroutine
end interface

call sirius_get_kpoint_inter_comm_aux(handler,fcomm)
end subroutine sirius_get_kpoint_inter_comm

!> @brief Get communicator which is used to parallise band problem
!> @param [in] handler Simulation context handler
!> @param [out] fcomm Fortran communicator
subroutine sirius_get_kpoint_inner_comm(handler,fcomm)
implicit none
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(out) :: fcomm
interface
subroutine sirius_get_kpoint_inner_comm_aux(handler,fcomm)&
&bind(C, name="sirius_get_kpoint_inner_comm")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(out) :: fcomm
end subroutine
end interface

call sirius_get_kpoint_inner_comm_aux(handler,fcomm)
end subroutine sirius_get_kpoint_inner_comm

!> @brief Get communicator which is used to parallise FFT
!> @param [in] handler Simulation context handler
!> @param [out] fcomm Fortran communicator
subroutine sirius_get_fft_comm(handler,fcomm)
implicit none
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(out) :: fcomm
interface
subroutine sirius_get_fft_comm_aux(handler,fcomm)&
&bind(C, name="sirius_get_fft_comm")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(out) :: fcomm
end subroutine
end interface

call sirius_get_fft_comm_aux(handler,fcomm)
end subroutine sirius_get_fft_comm

!> @brief Get total number of G-vectors
!> @param [in] handler Simulation context handler
function sirius_get_num_gvec(handler) result(res)
implicit none
type(C_PTR), intent(in) :: handler
integer(C_INT) :: res
interface
function sirius_get_num_gvec_aux(handler) result(res)&
&bind(C, name="sirius_get_num_gvec")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
integer(C_INT) :: res
end function
end interface

res = sirius_get_num_gvec_aux(handler)
end function sirius_get_num_gvec

!> @brief Get G-vector arrays.
!> @param [in] handler Simulation context handler
!> @param [in] gvec G-vectors in lattice coordinates.
!> @param [in] gvec_cart G-vectors in Cartesian coordinates.
!> @param [in] gvec_len Length of G-vectors.
!> @param [in] index_by_gvec G-vector index by lattice coordinates.
subroutine sirius_get_gvec_arrays(handler,gvec,gvec_cart,gvec_len,index_by_gvec)
implicit none
type(C_PTR), intent(in) :: handler
integer(C_INT), optional, target, intent(in) :: gvec
real(C_DOUBLE), optional, target, intent(in) :: gvec_cart
real(C_DOUBLE), optional, target, intent(in) :: gvec_len
integer(C_INT), optional, target, intent(in) :: index_by_gvec
type(C_PTR) :: gvec_ptr
type(C_PTR) :: gvec_cart_ptr
type(C_PTR) :: gvec_len_ptr
type(C_PTR) :: index_by_gvec_ptr
interface
subroutine sirius_get_gvec_arrays_aux(handler,gvec,gvec_cart,gvec_len,index_by_g&
&vec)&
&bind(C, name="sirius_get_gvec_arrays")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
type(C_PTR), value, intent(in) :: gvec
type(C_PTR), value, intent(in) :: gvec_cart
type(C_PTR), value, intent(in) :: gvec_len
type(C_PTR), value, intent(in) :: index_by_gvec
end subroutine
end interface

gvec_ptr = C_NULL_PTR
if (present(gvec)) gvec_ptr = C_LOC(gvec)

gvec_cart_ptr = C_NULL_PTR
if (present(gvec_cart)) gvec_cart_ptr = C_LOC(gvec_cart)

gvec_len_ptr = C_NULL_PTR
if (present(gvec_len)) gvec_len_ptr = C_LOC(gvec_len)

index_by_gvec_ptr = C_NULL_PTR
if (present(index_by_gvec)) index_by_gvec_ptr = C_LOC(index_by_gvec)

call sirius_get_gvec_arrays_aux(handler,gvec_ptr,gvec_cart_ptr,gvec_len_ptr,inde&
&x_by_gvec_ptr)
end subroutine sirius_get_gvec_arrays

!> @brief Get local number of FFT grid points.
!> @param [in] handler Simulation context handler
function sirius_get_num_fft_grid_points(handler) result(res)
implicit none
type(C_PTR), intent(in) :: handler
integer(C_INT) :: res
interface
function sirius_get_num_fft_grid_points_aux(handler) result(res)&
&bind(C, name="sirius_get_num_fft_grid_points")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
integer(C_INT) :: res
end function
end interface

res = sirius_get_num_fft_grid_points_aux(handler)
end function sirius_get_num_fft_grid_points

!> @brief Get mapping between G-vector index and FFT index
!> @param [in] handler Simulation context handler
!> @param [out] fft_index Index inside FFT buffer
subroutine sirius_get_fft_index(handler,fft_index)
implicit none
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(out) :: fft_index
interface
subroutine sirius_get_fft_index_aux(handler,fft_index)&
&bind(C, name="sirius_get_fft_index")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(out) :: fft_index
end subroutine
end interface

call sirius_get_fft_index_aux(handler,fft_index)
end subroutine sirius_get_fft_index

!> @brief Get maximum number of G+k vectors across all k-points in the set
!> @param [in] ks_handler K-point set handler.
function sirius_get_max_num_gkvec(ks_handler) result(res)
implicit none
type(C_PTR), intent(in) :: ks_handler
integer(C_INT) :: res
interface
function sirius_get_max_num_gkvec_aux(ks_handler) result(res)&
&bind(C, name="sirius_get_max_num_gkvec")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: ks_handler
integer(C_INT) :: res
end function
end interface

res = sirius_get_max_num_gkvec_aux(ks_handler)
end function sirius_get_max_num_gkvec

!> @brief Get all G+k vector related arrays
!> @param [in] ks_handler K-point set handler.
!> @param [in] ik Global index of k-point
!> @param [out] num_gkvec Number of G+k vectors.
!> @param [out] gvec_index Index of the G-vector part of G+k vector.
!> @param [out] gkvec G+k vectors in fractional coordinates.
!> @param [out] gkvec_cart G+k vectors in Cartesian coordinates.
!> @param [out] gkvec_len Length of G+k vectors.
!> @param [out] gkvec_tp Theta and Phi angles of G+k vectors.
subroutine sirius_get_gkvec_arrays(ks_handler,ik,num_gkvec,gvec_index,gkvec,gkve&
&c_cart,gkvec_len,gkvec_tp)
implicit none
type(C_PTR), intent(in) :: ks_handler
integer(C_INT), intent(in) :: ik
integer(C_INT), intent(out) :: num_gkvec
integer(C_INT), intent(out) :: gvec_index
real(C_DOUBLE), intent(out) :: gkvec
real(C_DOUBLE), intent(out) :: gkvec_cart
real(C_DOUBLE), intent(out) :: gkvec_len
real(C_DOUBLE), intent(out) :: gkvec_tp
interface
subroutine sirius_get_gkvec_arrays_aux(ks_handler,ik,num_gkvec,gvec_index,gkvec,&
&gkvec_cart,gkvec_len,gkvec_tp)&
&bind(C, name="sirius_get_gkvec_arrays")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: ks_handler
integer(C_INT), intent(in) :: ik
integer(C_INT), intent(out) :: num_gkvec
integer(C_INT), intent(out) :: gvec_index
real(C_DOUBLE), intent(out) :: gkvec
real(C_DOUBLE), intent(out) :: gkvec_cart
real(C_DOUBLE), intent(out) :: gkvec_len
real(C_DOUBLE), intent(out) :: gkvec_tp
end subroutine
end interface

call sirius_get_gkvec_arrays_aux(ks_handler,ik,num_gkvec,gvec_index,gkvec,gkvec_&
&cart,gkvec_len,gkvec_tp)
end subroutine sirius_get_gkvec_arrays

!> @brief Get the unit-step function.
!> @param [in] handler Simulation context handler
!> @param [out] cfunig Plane-wave coefficients of step function.
!> @param [out] cfunrg Values of the step function on the regular grid.
subroutine sirius_get_step_function(handler,cfunig,cfunrg)
implicit none
type(C_PTR), intent(in) :: handler
complex(C_DOUBLE), intent(out) :: cfunig
real(C_DOUBLE), intent(out) :: cfunrg
interface
subroutine sirius_get_step_function_aux(handler,cfunig,cfunrg)&
&bind(C, name="sirius_get_step_function")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
complex(C_DOUBLE), intent(out) :: cfunig
real(C_DOUBLE), intent(out) :: cfunrg
end subroutine
end interface

call sirius_get_step_function_aux(handler,cfunig,cfunrg)
end subroutine sirius_get_step_function

!> @brief Get electronic part of Hartree potential at atom origins.
!> @param [in] handler DFT ground state handler.
!> @param [out] vha_el Electronic part of Hartree potential at each atom's origin.
subroutine sirius_get_vha_el(handler,vha_el)
implicit none
type(C_PTR), intent(in) :: handler
real(C_DOUBLE), intent(out) :: vha_el
interface
subroutine sirius_get_vha_el_aux(handler,vha_el)&
&bind(C, name="sirius_get_vha_el")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
real(C_DOUBLE), intent(out) :: vha_el
end subroutine
end interface

call sirius_get_vha_el_aux(handler,vha_el)
end subroutine sirius_get_vha_el

!> @brief Set LAPW Hamiltonian radial integrals.
!> @param [in] handler Simulation context handler.
!> @param [in] ia Index of atom.
!> @param [in] lmmax Number of lm-component of the potential.
!> @param [in] val Values of the radial integrals.
!> @param [in] l1 1st index of orbital quantum number.
!> @param [in] o1 1st index of radial function order for l1.
!> @param [in] ilo1 1st index or local orbital.
!> @param [in] l2 2nd index of orbital quantum number.
!> @param [in] o2 2nd index of radial function order for l2.
!> @param [in] ilo2 2nd index or local orbital.
subroutine sirius_set_h_radial_integrals(handler,ia,lmmax,val,l1,o1,ilo1,l2,o2,i&
&lo2)
implicit none
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: ia
integer(C_INT), intent(in) :: lmmax
real(C_DOUBLE), intent(in) :: val
integer(C_INT), optional, target, intent(in) :: l1
integer(C_INT), optional, target, intent(in) :: o1
integer(C_INT), optional, target, intent(in) :: ilo1
integer(C_INT), optional, target, intent(in) :: l2
integer(C_INT), optional, target, intent(in) :: o2
integer(C_INT), optional, target, intent(in) :: ilo2
type(C_PTR) :: l1_ptr
type(C_PTR) :: o1_ptr
type(C_PTR) :: ilo1_ptr
type(C_PTR) :: l2_ptr
type(C_PTR) :: o2_ptr
type(C_PTR) :: ilo2_ptr
interface
subroutine sirius_set_h_radial_integrals_aux(handler,ia,lmmax,val,l1,o1,ilo1,l2,&
&o2,ilo2)&
&bind(C, name="sirius_set_h_radial_integrals")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: ia
integer(C_INT), intent(in) :: lmmax
real(C_DOUBLE), intent(in) :: val
type(C_PTR), value, intent(in) :: l1
type(C_PTR), value, intent(in) :: o1
type(C_PTR), value, intent(in) :: ilo1
type(C_PTR), value, intent(in) :: l2
type(C_PTR), value, intent(in) :: o2
type(C_PTR), value, intent(in) :: ilo2
end subroutine
end interface

l1_ptr = C_NULL_PTR
if (present(l1)) l1_ptr = C_LOC(l1)

o1_ptr = C_NULL_PTR
if (present(o1)) o1_ptr = C_LOC(o1)

ilo1_ptr = C_NULL_PTR
if (present(ilo1)) ilo1_ptr = C_LOC(ilo1)

l2_ptr = C_NULL_PTR
if (present(l2)) l2_ptr = C_LOC(l2)

o2_ptr = C_NULL_PTR
if (present(o2)) o2_ptr = C_LOC(o2)

ilo2_ptr = C_NULL_PTR
if (present(ilo2)) ilo2_ptr = C_LOC(ilo2)

call sirius_set_h_radial_integrals_aux(handler,ia,lmmax,val,l1_ptr,o1_ptr,ilo1_p&
&tr,l2_ptr,o2_ptr,ilo2_ptr)
end subroutine sirius_set_h_radial_integrals

!> @brief Set LAPW overlap radial integral.
!> @param [in] handler Simulation context handler.
!> @param [in] ia Index of atom.
!> @param [in] val Value of the radial integral.
!> @param [in] l Orbital quantum number.
!> @param [in] o1 1st index of radial function order.
!> @param [in] ilo1 1st index or local orbital.
!> @param [in] o2 2nd index of radial function order.
!> @param [in] ilo2 2nd index or local orbital.
subroutine sirius_set_o_radial_integral(handler,ia,val,l,o1,ilo1,o2,ilo2)
implicit none
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: ia
real(C_DOUBLE), intent(in) :: val
integer(C_INT), intent(in) :: l
integer(C_INT), optional, target, intent(in) :: o1
integer(C_INT), optional, target, intent(in) :: ilo1
integer(C_INT), optional, target, intent(in) :: o2
integer(C_INT), optional, target, intent(in) :: ilo2
type(C_PTR) :: o1_ptr
type(C_PTR) :: ilo1_ptr
type(C_PTR) :: o2_ptr
type(C_PTR) :: ilo2_ptr
interface
subroutine sirius_set_o_radial_integral_aux(handler,ia,val,l,o1,ilo1,o2,ilo2)&
&bind(C, name="sirius_set_o_radial_integral")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: ia
real(C_DOUBLE), intent(in) :: val
integer(C_INT), intent(in) :: l
type(C_PTR), value, intent(in) :: o1
type(C_PTR), value, intent(in) :: ilo1
type(C_PTR), value, intent(in) :: o2
type(C_PTR), value, intent(in) :: ilo2
end subroutine
end interface

o1_ptr = C_NULL_PTR
if (present(o1)) o1_ptr = C_LOC(o1)

ilo1_ptr = C_NULL_PTR
if (present(ilo1)) ilo1_ptr = C_LOC(ilo1)

o2_ptr = C_NULL_PTR
if (present(o2)) o2_ptr = C_LOC(o2)

ilo2_ptr = C_NULL_PTR
if (present(ilo2)) ilo2_ptr = C_LOC(ilo2)

call sirius_set_o_radial_integral_aux(handler,ia,val,l,o1_ptr,ilo1_ptr,o2_ptr,il&
&o2_ptr)
end subroutine sirius_set_o_radial_integral

!> @brief Set a correction to LAPW overlap radial integral.
!> @param [in] handler Simulation context handler.
!> @param [in] ia Index of atom.
!> @param [in] val Value of the radial integral.
!> @param [in] l1 1st index of orbital quantum number.
!> @param [in] o1 1st index of radial function order for l1.
!> @param [in] ilo1 1st index or local orbital.
!> @param [in] l2 2nd index of orbital quantum number.
!> @param [in] o2 2nd index of radial function order for l2.
!> @param [in] ilo2 2nd index or local orbital.
subroutine sirius_set_o1_radial_integral(handler,ia,val,l1,o1,ilo1,l2,o2,ilo2)
implicit none
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: ia
real(C_DOUBLE), intent(in) :: val
integer(C_INT), optional, target, intent(in) :: l1
integer(C_INT), optional, target, intent(in) :: o1
integer(C_INT), optional, target, intent(in) :: ilo1
integer(C_INT), optional, target, intent(in) :: l2
integer(C_INT), optional, target, intent(in) :: o2
integer(C_INT), optional, target, intent(in) :: ilo2
type(C_PTR) :: l1_ptr
type(C_PTR) :: o1_ptr
type(C_PTR) :: ilo1_ptr
type(C_PTR) :: l2_ptr
type(C_PTR) :: o2_ptr
type(C_PTR) :: ilo2_ptr
interface
subroutine sirius_set_o1_radial_integral_aux(handler,ia,val,l1,o1,ilo1,l2,o2,ilo&
&2)&
&bind(C, name="sirius_set_o1_radial_integral")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: ia
real(C_DOUBLE), intent(in) :: val
type(C_PTR), value, intent(in) :: l1
type(C_PTR), value, intent(in) :: o1
type(C_PTR), value, intent(in) :: ilo1
type(C_PTR), value, intent(in) :: l2
type(C_PTR), value, intent(in) :: o2
type(C_PTR), value, intent(in) :: ilo2
end subroutine
end interface

l1_ptr = C_NULL_PTR
if (present(l1)) l1_ptr = C_LOC(l1)

o1_ptr = C_NULL_PTR
if (present(o1)) o1_ptr = C_LOC(o1)

ilo1_ptr = C_NULL_PTR
if (present(ilo1)) ilo1_ptr = C_LOC(ilo1)

l2_ptr = C_NULL_PTR
if (present(l2)) l2_ptr = C_LOC(l2)

o2_ptr = C_NULL_PTR
if (present(o2)) o2_ptr = C_LOC(o2)

ilo2_ptr = C_NULL_PTR
if (present(ilo2)) ilo2_ptr = C_LOC(ilo2)

call sirius_set_o1_radial_integral_aux(handler,ia,val,l1_ptr,o1_ptr,ilo1_ptr,l2_&
&ptr,o2_ptr,ilo2_ptr)
end subroutine sirius_set_o1_radial_integral

!> @brief Set LAPW radial functions
!> @param [in] handler Simulation context handler.
!> @param [in] ia Index of atom.
!> @param [in] deriv_order Radial derivative order.
!> @param [in] f Values of the radial function.
!> @param [in] l Orbital quantum number.
!> @param [in] o Order of radial function for l.
!> @param [in] ilo Local orbital index.
subroutine sirius_set_radial_function(handler,ia,deriv_order,f,l,o,ilo)
implicit none
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: ia
integer(C_INT), intent(in) :: deriv_order
real(C_DOUBLE), intent(in) :: f
integer(C_INT), optional, target, intent(in) :: l
integer(C_INT), optional, target, intent(in) :: o
integer(C_INT), optional, target, intent(in) :: ilo
type(C_PTR) :: l_ptr
type(C_PTR) :: o_ptr
type(C_PTR) :: ilo_ptr
interface
subroutine sirius_set_radial_function_aux(handler,ia,deriv_order,f,l,o,ilo)&
&bind(C, name="sirius_set_radial_function")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: ia
integer(C_INT), intent(in) :: deriv_order
real(C_DOUBLE), intent(in) :: f
type(C_PTR), value, intent(in) :: l
type(C_PTR), value, intent(in) :: o
type(C_PTR), value, intent(in) :: ilo
end subroutine
end interface

l_ptr = C_NULL_PTR
if (present(l)) l_ptr = C_LOC(l)

o_ptr = C_NULL_PTR
if (present(o)) o_ptr = C_LOC(o)

ilo_ptr = C_NULL_PTR
if (present(ilo)) ilo_ptr = C_LOC(ilo)

call sirius_set_radial_function_aux(handler,ia,deriv_order,f,l_ptr,o_ptr,ilo_ptr&
&)
end subroutine sirius_set_radial_function

!> @brief Set equivalent atoms.
!> @param [in] handler Simulation context handler.
!> @param [in] equivalent_atoms Array with equivalent atom IDs.
subroutine sirius_set_equivalent_atoms(handler,equivalent_atoms)
implicit none
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: equivalent_atoms
interface
subroutine sirius_set_equivalent_atoms_aux(handler,equivalent_atoms)&
&bind(C, name="sirius_set_equivalent_atoms")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
integer(C_INT), intent(in) :: equivalent_atoms
end subroutine
end interface

call sirius_set_equivalent_atoms_aux(handler,equivalent_atoms)
end subroutine sirius_set_equivalent_atoms

!> @brief Set the new spherical potential.
!> @param [in] handler Ground state handler.
subroutine sirius_update_atomic_potential(handler)
implicit none
type(C_PTR), intent(in) :: handler
interface
subroutine sirius_update_atomic_potential_aux(handler)&
&bind(C, name="sirius_update_atomic_potential")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), intent(in) :: handler
end subroutine
end interface

call sirius_update_atomic_potential_aux(handler)
end subroutine sirius_update_atomic_potential

