! Warning! This file is automatically generated from sirius_api.cpp using the generate_api.py script!

!> @file sirius.f90
!! @brief Autogenerated Fortran module for the SIRIUS API.
module sirius

use, intrinsic :: ISO_C_BINDING

INTEGER, PARAMETER, PUBLIC :: SIRIUS_INTEGER_TYPE = 1
INTEGER, PARAMETER, PUBLIC :: SIRIUS_LOGICAL_TYPE = 2
INTEGER, PARAMETER, PUBLIC :: SIRIUS_STRING_TYPE = 3
INTEGER, PARAMETER, PUBLIC :: SIRIUS_NUMBER_TYPE = 4
INTEGER, PARAMETER, PUBLIC :: SIRIUS_OBJECT_TYPE = 5
INTEGER, PARAMETER, PUBLIC :: SIRIUS_ARRAY_TYPE = 6

INTEGER, PARAMETER, PUBLIC :: SIRIUS_INTEGER_ARRAY_TYPE = 7
INTEGER, PARAMETER, PUBLIC :: SIRIUS_LOGICAL_ARRAY_TYPE = 8
INTEGER, PARAMETER, PUBLIC :: SIRIUS_NUMBER_ARRAY_TYPE = 9
INTEGER, PARAMETER, PUBLIC :: SIRIUS_STRING_ARRAY_TYPE = 10
INTEGER, PARAMETER, PUBLIC :: SIRIUS_OBJECT_ARRAY_TYPE = 11
INTEGER, PARAMETER, PUBLIC :: SIRIUS_ARRAY_ARRAY_TYPE = 12

!> @brief Opaque wrapper for simulation context handler.
type sirius_context_handler
    private
    type(C_PTR) :: handler_ptr_ = C_NULL_PTR
end type

!> @brief Opaque wrapper for DFT ground statee handler.
type sirius_ground_state_handler
    private
    type(C_PTR) :: handler_ptr_ = C_NULL_PTR
end type

!> @brief Opaque wrapper for K-point set handler.
type sirius_kpoint_set_handler
    private
    type(C_PTR) :: handler_ptr_ = C_NULL_PTR
end type

!> @brief Opaque wrapper for K-point independent Hamiltonian object.
type sirius_H0_handler
    private
    type(C_PTR) :: handler_ptr_ = C_NULL_PTR
end type

!> @brief Free any of the SIRIUS handlers (context, ground state or k-points).
interface sirius_free_handler
    module procedure sirius_free_handler_ctx, sirius_free_handler_ks, sirius_free_handler_dft, sirius_free_handler_H0
end interface

contains

!> Internal function that adds trailing null character to the string to make it C-style.
function string_f2c(f_string) result(res)
    implicit none
    character(kind=C_CHAR,len=*), intent(in)  :: f_string
    character(kind=C_CHAR,len=1) :: res(len_trim(f_string) + 1)
    integer i
    do i = 1, len_trim(f_string)
        res(i) = f_string(i:i)
    end do
    res(len_trim(f_string) + 1) = C_NULL_CHAR
end function string_f2c

!> Internal function that converts C-string (with trailing null character) to the Fortran string.
function string_c2f(c_string) result(res)
    implicit none
    character(kind=C_CHAR,len=1), intent(in) :: c_string(:)
    character(kind=C_CHAR,len=size(c_string) - 1) :: res
    character(C_CHAR) c
    integer i
    do i = 1, size(c_string)
        c = c_string(i)
        if (c == C_NULL_CHAR) then
            res(i:) = ' '
            exit
        endif
        res(i:i) = c
    end do
end function string_c2f
!
!> @brief Initialize the SIRIUS library.
!> @param [in] call_mpi_init If .true. then MPI_Init must be called prior to initialization.
!> @param [out] error_code Error code.
subroutine sirius_initialize(call_mpi_init,error_code)
implicit none
!
logical, target, intent(in) :: call_mpi_init
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: call_mpi_init_ptr
logical(C_BOOL), target :: call_mpi_init_c_type
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_initialize_aux(call_mpi_init,error_code)&
&bind(C, name="sirius_initialize")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: call_mpi_init
type(C_PTR), value :: error_code
end subroutine
end interface
!
call_mpi_init_ptr = C_NULL_PTR
call_mpi_init_c_type = call_mpi_init
call_mpi_init_ptr = C_LOC(call_mpi_init_c_type)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_initialize_aux(call_mpi_init_ptr,error_code_ptr)
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.
!> @param [out] error_code Error code.
subroutine sirius_finalize(call_mpi_fin,call_device_reset,call_fftw_fin,error_code)
implicit none
!
logical, optional, target, intent(in) :: call_mpi_fin
logical, optional, target, intent(in) :: call_device_reset
logical, optional, target, intent(in) :: call_fftw_fin
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: call_mpi_fin_ptr
logical(C_BOOL), target :: call_mpi_fin_c_type
type(C_PTR) :: call_device_reset_ptr
logical(C_BOOL), target :: call_device_reset_c_type
type(C_PTR) :: call_fftw_fin_ptr
logical(C_BOOL), target :: call_fftw_fin_c_type
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_finalize_aux(call_mpi_fin,call_device_reset,call_fftw_fin,error_code)&
&bind(C, name="sirius_finalize")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: call_mpi_fin
type(C_PTR), value :: call_device_reset
type(C_PTR), value :: call_fftw_fin
type(C_PTR), value :: error_code
end subroutine
end interface
!
call_mpi_fin_ptr = C_NULL_PTR
if (present(call_mpi_fin)) then
call_mpi_fin_c_type = call_mpi_fin
call_mpi_fin_ptr = C_LOC(call_mpi_fin_c_type)
endif
call_device_reset_ptr = C_NULL_PTR
if (present(call_device_reset)) then
call_device_reset_c_type = call_device_reset
call_device_reset_ptr = C_LOC(call_device_reset_c_type)
endif
call_fftw_fin_ptr = C_NULL_PTR
if (present(call_fftw_fin)) then
call_fftw_fin_c_type = call_fftw_fin
call_fftw_fin_ptr = C_LOC(call_fftw_fin_c_type)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_finalize_aux(call_mpi_fin_ptr,call_device_reset_ptr,call_fftw_fin_ptr,&
&error_code_ptr)
if (present(call_mpi_fin)) then
endif
if (present(call_device_reset)) then
endif
if (present(call_fftw_fin)) then
endif
end subroutine sirius_finalize

!
!> @brief Start the timer.
!> @param [in] name Timer label.
!> @param [out] error_code Error code.
subroutine sirius_start_timer(name,error_code)
implicit none
!
character(*), target, intent(in) :: name
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: name_ptr
character(C_CHAR), target, allocatable :: name_c_type(:)
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_start_timer_aux(name,error_code)&
&bind(C, name="sirius_start_timer")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: name
type(C_PTR), value :: error_code
end subroutine
end interface
!
name_ptr = C_NULL_PTR
allocate(name_c_type(len(name)+1))
name_c_type = string_f2c(name)
name_ptr = C_LOC(name_c_type)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_start_timer_aux(name_ptr,error_code_ptr)
deallocate(name_c_type)
end subroutine sirius_start_timer

!
!> @brief Stop the running timer.
!> @param [in] name Timer label.
!> @param [out] error_code Error code.
subroutine sirius_stop_timer(name,error_code)
implicit none
!
character(*), target, intent(in) :: name
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: name_ptr
character(C_CHAR), target, allocatable :: name_c_type(:)
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_stop_timer_aux(name,error_code)&
&bind(C, name="sirius_stop_timer")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: name
type(C_PTR), value :: error_code
end subroutine
end interface
!
name_ptr = C_NULL_PTR
allocate(name_c_type(len(name)+1))
name_c_type = string_f2c(name)
name_ptr = C_LOC(name_c_type)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_stop_timer_aux(name_ptr,error_code_ptr)
deallocate(name_c_type)
end subroutine sirius_stop_timer

!
!> @brief Print all timers.
!> @param [in] flatten If true, flat list of timers is printed.
!> @param [out] error_code Error code.
subroutine sirius_print_timers(flatten,error_code)
implicit none
!
logical, target, intent(in) :: flatten
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: flatten_ptr
logical(C_BOOL), target :: flatten_c_type
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_print_timers_aux(flatten,error_code)&
&bind(C, name="sirius_print_timers")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: flatten
type(C_PTR), value :: error_code
end subroutine
end interface
!
flatten_ptr = C_NULL_PTR
flatten_c_type = flatten
flatten_ptr = C_LOC(flatten_c_type)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_print_timers_aux(flatten_ptr,error_code_ptr)
end subroutine sirius_print_timers

!
!> @brief Save all timers to JSON file.
!> @param [in] fname Name of the output JSON file.
!> @param [out] error_code Error code.
subroutine sirius_serialize_timers(fname,error_code)
implicit none
!
character(*), target, intent(in) :: fname
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: fname_ptr
character(C_CHAR), target, allocatable :: fname_c_type(:)
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_serialize_timers_aux(fname,error_code)&
&bind(C, name="sirius_serialize_timers")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: fname
type(C_PTR), value :: error_code
end subroutine
end interface
!
fname_ptr = C_NULL_PTR
allocate(fname_c_type(len(fname)+1))
fname_c_type = string_f2c(fname)
fname_ptr = C_LOC(fname_c_type)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_serialize_timers_aux(fname_ptr,error_code_ptr)
deallocate(fname_c_type)
end subroutine sirius_serialize_timers

!
!> @brief Check if the simulation context is initialized.
!> @param [in] handler Simulation context handler.
!> @param [out] status Status of the library (true if initialized)
!> @param [out] error_code Error code.
subroutine sirius_context_initialized(handler,status,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
logical, target, intent(out) :: status
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: status_ptr
logical(C_BOOL), target :: status_c_type
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_context_initialized_aux(handler,status,error_code)&
&bind(C, name="sirius_context_initialized")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: status
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
status_ptr = C_NULL_PTR
status_ptr = C_LOC(status_c_type)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_context_initialized_aux(handler_ptr,status_ptr,error_code_ptr)
status = status_c_type
end subroutine 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.
!> @param [out] handler New empty simulation context.
!> @param [in] fcomm_k Communicator for k-point parallelization.
!> @param [in] fcomm_band Communicator for band parallelization.
!> @param [out] error_code Error code.
subroutine sirius_create_context(fcomm,handler,fcomm_k,fcomm_band,error_code)
implicit none
!
integer, value, intent(in) :: fcomm
type(sirius_context_handler), target, intent(out) :: handler
integer, optional, target, intent(in) :: fcomm_k
integer, optional, target, intent(in) :: fcomm_band
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: fcomm_k_ptr
type(C_PTR) :: fcomm_band_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_create_context_aux(fcomm,handler,fcomm_k,fcomm_band,error_code)&
&bind(C, name="sirius_create_context")
use, intrinsic :: ISO_C_BINDING
integer(C_INT), value :: fcomm
type(C_PTR), value :: handler
type(C_PTR), value :: fcomm_k
type(C_PTR), value :: fcomm_band
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
fcomm_k_ptr = C_NULL_PTR
if (present(fcomm_k)) then
fcomm_k_ptr = C_LOC(fcomm_k)
endif
fcomm_band_ptr = C_NULL_PTR
if (present(fcomm_band)) then
fcomm_band_ptr = C_LOC(fcomm_band)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_create_context_aux(fcomm,handler_ptr,fcomm_k_ptr,fcomm_band_ptr,error_code_ptr)
end subroutine sirius_create_context

!
!> @brief Import parameters of simulation from a JSON string
!> @param [in] handler Simulation context handler.
!> @param [in] str JSON string with parameters or a JSON file.
!> @param [out] error_code Error code
subroutine sirius_import_parameters(handler,str,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
character(*), target, intent(in) :: str
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: str_ptr
character(C_CHAR), target, allocatable :: str_c_type(:)
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_import_parameters_aux(handler,str,error_code)&
&bind(C, name="sirius_import_parameters")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: str
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
str_ptr = C_NULL_PTR
allocate(str_c_type(len(str)+1))
str_c_type = string_f2c(str)
str_ptr = C_LOC(str_c_type)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_import_parameters_aux(handler_ptr,str_ptr,error_code_ptr)
deallocate(str_c_type)
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] fft_grid_size Size of the fine-grain FFT grid.
!> @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] 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_full_orthogonalization Use all atomic orbitals found in all ps potentials to compute the orthogonalization operator.
!> @param [in] hubbard_constrained_calculation Use the constrained hubbard method to intiate the scf loop
!> @param [in] hubbard_orbitals Type of localized orbitals.
!> @param [in] sht_coverage Type of spherical coverage (0 for Lebedev-Laikov, 1 for uniform).
!> @param [in] min_occupancy Minimum band occupancy to trat is as "occupied".
!> @param [in] smearing Type of occupancy smearing.
!> @param [in] smearing_width Smearing width
!> @param [in] spglib_tol Tolerance for the spglib symmetry search.
!> @param [in] electronic_structure_method Type of electronic structure method.
!> @param [out] error_code Error code.
subroutine sirius_set_parameters(handler,lmax_apw,lmax_rho,lmax_pot,num_fv_states,&
&num_bands,num_mag_dims,pw_cutoff,gk_cutoff,fft_grid_size,auto_rmt,gamma_point,use_symmetry,&
&so_correction,valence_rel,core_rel,iter_solver_tol_empty,iter_solver_type,verbosity,&
&hubbard_correction,hubbard_correction_kind,hubbard_full_orthogonalization,hubbard_constrained_calculation,&
&hubbard_orbitals,sht_coverage,min_occupancy,smearing,smearing_width,spglib_tol,electronic_structure_method,&
&error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, optional, target, intent(in) :: lmax_apw
integer, optional, target, intent(in) :: lmax_rho
integer, optional, target, intent(in) :: lmax_pot
integer, optional, target, intent(in) :: num_fv_states
integer, optional, target, intent(in) :: num_bands
integer, optional, target, intent(in) :: num_mag_dims
real(8), optional, target, intent(in) :: pw_cutoff
real(8), optional, target, intent(in) :: gk_cutoff
integer, optional, target, intent(in) :: fft_grid_size(3)
integer, optional, target, intent(in) :: auto_rmt
logical, optional, target, intent(in) :: gamma_point
logical, optional, target, intent(in) :: use_symmetry
logical, optional, target, intent(in) :: so_correction
character(*), optional, target, intent(in) :: valence_rel
character(*), optional, target, intent(in) :: core_rel
real(8), optional, target, intent(in) :: iter_solver_tol_empty
character(*), optional, target, intent(in) :: iter_solver_type
integer, optional, target, intent(in) :: verbosity
logical, optional, target, intent(in) :: hubbard_correction
integer, optional, target, intent(in) :: hubbard_correction_kind
logical, optional, target, intent(in) :: hubbard_full_orthogonalization
logical, optional, target, intent(in) :: hubbard_constrained_calculation
character(*), optional, target, intent(in) :: hubbard_orbitals
integer, optional, target, intent(in) :: sht_coverage
real(8), optional, target, intent(in) :: min_occupancy
character(*), optional, target, intent(in) :: smearing
real(8), optional, target, intent(in) :: smearing_width
real(8), optional, target, intent(in) :: spglib_tol
character(*), optional, target, intent(in) :: electronic_structure_method
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
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) :: fft_grid_size_ptr
type(C_PTR) :: auto_rmt_ptr
type(C_PTR) :: gamma_point_ptr
logical(C_BOOL), target :: gamma_point_c_type
type(C_PTR) :: use_symmetry_ptr
logical(C_BOOL), target :: use_symmetry_c_type
type(C_PTR) :: so_correction_ptr
logical(C_BOOL), target :: so_correction_c_type
type(C_PTR) :: valence_rel_ptr
character(C_CHAR), target, allocatable :: valence_rel_c_type(:)
type(C_PTR) :: core_rel_ptr
character(C_CHAR), target, allocatable :: core_rel_c_type(:)
type(C_PTR) :: iter_solver_tol_empty_ptr
type(C_PTR) :: iter_solver_type_ptr
character(C_CHAR), target, allocatable :: iter_solver_type_c_type(:)
type(C_PTR) :: verbosity_ptr
type(C_PTR) :: hubbard_correction_ptr
logical(C_BOOL), target :: hubbard_correction_c_type
type(C_PTR) :: hubbard_correction_kind_ptr
type(C_PTR) :: hubbard_full_orthogonalization_ptr
logical(C_BOOL), target :: hubbard_full_orthogonalization_c_type
type(C_PTR) :: hubbard_constrained_calculation_ptr
logical(C_BOOL), target :: hubbard_constrained_calculation_c_type
type(C_PTR) :: hubbard_orbitals_ptr
character(C_CHAR), target, allocatable :: hubbard_orbitals_c_type(:)
type(C_PTR) :: sht_coverage_ptr
type(C_PTR) :: min_occupancy_ptr
type(C_PTR) :: smearing_ptr
character(C_CHAR), target, allocatable :: smearing_c_type(:)
type(C_PTR) :: smearing_width_ptr
type(C_PTR) :: spglib_tol_ptr
type(C_PTR) :: electronic_structure_method_ptr
character(C_CHAR), target, allocatable :: electronic_structure_method_c_type(:)
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_parameters_aux(handler,lmax_apw,lmax_rho,lmax_pot,num_fv_states,&
&num_bands,num_mag_dims,pw_cutoff,gk_cutoff,fft_grid_size,auto_rmt,gamma_point,use_symmetry,&
&so_correction,valence_rel,core_rel,iter_solver_tol_empty,iter_solver_type,verbosity,&
&hubbard_correction,hubbard_correction_kind,hubbard_full_orthogonalization,hubbard_constrained_calculation,&
&hubbard_orbitals,sht_coverage,min_occupancy,smearing,smearing_width,spglib_tol,electronic_structure_method,&
&error_code)&
&bind(C, name="sirius_set_parameters")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: lmax_apw
type(C_PTR), value :: lmax_rho
type(C_PTR), value :: lmax_pot
type(C_PTR), value :: num_fv_states
type(C_PTR), value :: num_bands
type(C_PTR), value :: num_mag_dims
type(C_PTR), value :: pw_cutoff
type(C_PTR), value :: gk_cutoff
type(C_PTR), value :: fft_grid_size
type(C_PTR), value :: auto_rmt
type(C_PTR), value :: gamma_point
type(C_PTR), value :: use_symmetry
type(C_PTR), value :: so_correction
type(C_PTR), value :: valence_rel
type(C_PTR), value :: core_rel
type(C_PTR), value :: iter_solver_tol_empty
type(C_PTR), value :: iter_solver_type
type(C_PTR), value :: verbosity
type(C_PTR), value :: hubbard_correction
type(C_PTR), value :: hubbard_correction_kind
type(C_PTR), value :: hubbard_full_orthogonalization
type(C_PTR), value :: hubbard_constrained_calculation
type(C_PTR), value :: hubbard_orbitals
type(C_PTR), value :: sht_coverage
type(C_PTR), value :: min_occupancy
type(C_PTR), value :: smearing
type(C_PTR), value :: smearing_width
type(C_PTR), value :: spglib_tol
type(C_PTR), value :: electronic_structure_method
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
lmax_apw_ptr = C_NULL_PTR
if (present(lmax_apw)) then
lmax_apw_ptr = C_LOC(lmax_apw)
endif
lmax_rho_ptr = C_NULL_PTR
if (present(lmax_rho)) then
lmax_rho_ptr = C_LOC(lmax_rho)
endif
lmax_pot_ptr = C_NULL_PTR
if (present(lmax_pot)) then
lmax_pot_ptr = C_LOC(lmax_pot)
endif
num_fv_states_ptr = C_NULL_PTR
if (present(num_fv_states)) then
num_fv_states_ptr = C_LOC(num_fv_states)
endif
num_bands_ptr = C_NULL_PTR
if (present(num_bands)) then
num_bands_ptr = C_LOC(num_bands)
endif
num_mag_dims_ptr = C_NULL_PTR
if (present(num_mag_dims)) then
num_mag_dims_ptr = C_LOC(num_mag_dims)
endif
pw_cutoff_ptr = C_NULL_PTR
if (present(pw_cutoff)) then
pw_cutoff_ptr = C_LOC(pw_cutoff)
endif
gk_cutoff_ptr = C_NULL_PTR
if (present(gk_cutoff)) then
gk_cutoff_ptr = C_LOC(gk_cutoff)
endif
fft_grid_size_ptr = C_NULL_PTR
if (present(fft_grid_size)) then
fft_grid_size_ptr = C_LOC(fft_grid_size)
endif
auto_rmt_ptr = C_NULL_PTR
if (present(auto_rmt)) then
auto_rmt_ptr = C_LOC(auto_rmt)
endif
gamma_point_ptr = C_NULL_PTR
if (present(gamma_point)) then
gamma_point_c_type = gamma_point
gamma_point_ptr = C_LOC(gamma_point_c_type)
endif
use_symmetry_ptr = C_NULL_PTR
if (present(use_symmetry)) then
use_symmetry_c_type = use_symmetry
use_symmetry_ptr = C_LOC(use_symmetry_c_type)
endif
so_correction_ptr = C_NULL_PTR
if (present(so_correction)) then
so_correction_c_type = so_correction
so_correction_ptr = C_LOC(so_correction_c_type)
endif
valence_rel_ptr = C_NULL_PTR
if (present(valence_rel)) then
allocate(valence_rel_c_type(len(valence_rel)+1))
valence_rel_c_type = string_f2c(valence_rel)
valence_rel_ptr = C_LOC(valence_rel_c_type)
endif
core_rel_ptr = C_NULL_PTR
if (present(core_rel)) then
allocate(core_rel_c_type(len(core_rel)+1))
core_rel_c_type = string_f2c(core_rel)
core_rel_ptr = C_LOC(core_rel_c_type)
endif
iter_solver_tol_empty_ptr = C_NULL_PTR
if (present(iter_solver_tol_empty)) then
iter_solver_tol_empty_ptr = C_LOC(iter_solver_tol_empty)
endif
iter_solver_type_ptr = C_NULL_PTR
if (present(iter_solver_type)) then
allocate(iter_solver_type_c_type(len(iter_solver_type)+1))
iter_solver_type_c_type = string_f2c(iter_solver_type)
iter_solver_type_ptr = C_LOC(iter_solver_type_c_type)
endif
verbosity_ptr = C_NULL_PTR
if (present(verbosity)) then
verbosity_ptr = C_LOC(verbosity)
endif
hubbard_correction_ptr = C_NULL_PTR
if (present(hubbard_correction)) then
hubbard_correction_c_type = hubbard_correction
hubbard_correction_ptr = C_LOC(hubbard_correction_c_type)
endif
hubbard_correction_kind_ptr = C_NULL_PTR
if (present(hubbard_correction_kind)) then
hubbard_correction_kind_ptr = C_LOC(hubbard_correction_kind)
endif
hubbard_full_orthogonalization_ptr = C_NULL_PTR
if (present(hubbard_full_orthogonalization)) then
hubbard_full_orthogonalization_c_type = hubbard_full_orthogonalization
hubbard_full_orthogonalization_ptr = C_LOC(hubbard_full_orthogonalization_c_type)
endif
hubbard_constrained_calculation_ptr = C_NULL_PTR
if (present(hubbard_constrained_calculation)) then
hubbard_constrained_calculation_c_type = hubbard_constrained_calculation
hubbard_constrained_calculation_ptr = C_LOC(hubbard_constrained_calculation_c_type)
endif
hubbard_orbitals_ptr = C_NULL_PTR
if (present(hubbard_orbitals)) then
allocate(hubbard_orbitals_c_type(len(hubbard_orbitals)+1))
hubbard_orbitals_c_type = string_f2c(hubbard_orbitals)
hubbard_orbitals_ptr = C_LOC(hubbard_orbitals_c_type)
endif
sht_coverage_ptr = C_NULL_PTR
if (present(sht_coverage)) then
sht_coverage_ptr = C_LOC(sht_coverage)
endif
min_occupancy_ptr = C_NULL_PTR
if (present(min_occupancy)) then
min_occupancy_ptr = C_LOC(min_occupancy)
endif
smearing_ptr = C_NULL_PTR
if (present(smearing)) then
allocate(smearing_c_type(len(smearing)+1))
smearing_c_type = string_f2c(smearing)
smearing_ptr = C_LOC(smearing_c_type)
endif
smearing_width_ptr = C_NULL_PTR
if (present(smearing_width)) then
smearing_width_ptr = C_LOC(smearing_width)
endif
spglib_tol_ptr = C_NULL_PTR
if (present(spglib_tol)) then
spglib_tol_ptr = C_LOC(spglib_tol)
endif
electronic_structure_method_ptr = C_NULL_PTR
if (present(electronic_structure_method)) then
allocate(electronic_structure_method_c_type(len(electronic_structure_method)+1))
electronic_structure_method_c_type = string_f2c(electronic_structure_method)
electronic_structure_method_ptr = C_LOC(electronic_structure_method_c_type)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_parameters_aux(handler_ptr,lmax_apw_ptr,lmax_rho_ptr,lmax_pot_ptr,&
&num_fv_states_ptr,num_bands_ptr,num_mag_dims_ptr,pw_cutoff_ptr,gk_cutoff_ptr,fft_grid_size_ptr,&
&auto_rmt_ptr,gamma_point_ptr,use_symmetry_ptr,so_correction_ptr,valence_rel_ptr,&
&core_rel_ptr,iter_solver_tol_empty_ptr,iter_solver_type_ptr,verbosity_ptr,hubbard_correction_ptr,&
&hubbard_correction_kind_ptr,hubbard_full_orthogonalization_ptr,hubbard_constrained_calculation_ptr,&
&hubbard_orbitals_ptr,sht_coverage_ptr,min_occupancy_ptr,smearing_ptr,smearing_width_ptr,&
&spglib_tol_ptr,electronic_structure_method_ptr,error_code_ptr)
if (present(gamma_point)) then
endif
if (present(use_symmetry)) then
endif
if (present(so_correction)) then
endif
if (present(valence_rel)) then
deallocate(valence_rel_c_type)
endif
if (present(core_rel)) then
deallocate(core_rel_c_type)
endif
if (present(iter_solver_type)) then
deallocate(iter_solver_type_c_type)
endif
if (present(hubbard_correction)) then
endif
if (present(hubbard_full_orthogonalization)) then
endif
if (present(hubbard_constrained_calculation)) then
endif
if (present(hubbard_orbitals)) then
deallocate(hubbard_orbitals_c_type)
endif
if (present(smearing)) then
deallocate(smearing_c_type)
endif
if (present(electronic_structure_method)) then
deallocate(electronic_structure_method_c_type)
endif
end subroutine sirius_set_parameters

!
!> @brief Get parameters of the simulation.
!> @param [in] handler Simulation context handler
!> @param [out] lmax_apw Maximum orbital quantum number for APW functions.
!> @param [out] lmax_rho Maximum orbital quantum number for density.
!> @param [out] lmax_pot Maximum orbital quantum number for potential.
!> @param [out] num_fv_states Number of first-variational states.
!> @param [out] num_bands Number of bands.
!> @param [out] num_spins Number of spins.
!> @param [out] num_mag_dims Number of magnetic dimensions.
!> @param [out] pw_cutoff Cutoff for G-vectors.
!> @param [out] gk_cutoff Cutoff for G+k-vectors.
!> @param [out] fft_grid_size Size of the fine-grain FFT grid.
!> @param [out] auto_rmt Set the automatic search of muffin-tin radii.
!> @param [out] gamma_point True if this is a Gamma-point calculation.
!> @param [out] use_symmetry True if crystal symmetry is taken into account.
!> @param [out] so_correction True if spin-orbit correnctio is enabled.
!> @param [out] iter_solver_tol Tolerance of the iterative solver (deprecated).
!> @param [out] iter_solver_tol_empty Tolerance for the empty states.
!> @param [out] verbosity Verbosity level.
!> @param [out] hubbard_correction True if LDA+U correction is enabled.
!> @param [out] evp_work_count Internal counter of total eigen-value problem work.
!> @param [out] num_loc_op_applied Internal counter of the number of wave-functions to which Hamiltonian was applied.
!> @param [out] num_sym_op Number of symmetry operations discovered by spglib
!> @param [out] electronic_structure_method Type of electronic structure method.
!> @param [out] error_code Error code.
subroutine sirius_get_parameters(handler,lmax_apw,lmax_rho,lmax_pot,num_fv_states,&
&num_bands,num_spins,num_mag_dims,pw_cutoff,gk_cutoff,fft_grid_size,auto_rmt,gamma_point,&
&use_symmetry,so_correction,iter_solver_tol,iter_solver_tol_empty,verbosity,hubbard_correction,&
&evp_work_count,num_loc_op_applied,num_sym_op,electronic_structure_method,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, optional, target, intent(out) :: lmax_apw
integer, optional, target, intent(out) :: lmax_rho
integer, optional, target, intent(out) :: lmax_pot
integer, optional, target, intent(out) :: num_fv_states
integer, optional, target, intent(out) :: num_bands
integer, optional, target, intent(out) :: num_spins
integer, optional, target, intent(out) :: num_mag_dims
real(8), optional, target, intent(out) :: pw_cutoff
real(8), optional, target, intent(out) :: gk_cutoff
integer, optional, target, intent(out) :: fft_grid_size(3)
integer, optional, target, intent(out) :: auto_rmt
logical, optional, target, intent(out) :: gamma_point
logical, optional, target, intent(out) :: use_symmetry
logical, optional, target, intent(out) :: so_correction
real(8), optional, target, intent(out) :: iter_solver_tol
real(8), optional, target, intent(out) :: iter_solver_tol_empty
integer, optional, target, intent(out) :: verbosity
logical, optional, target, intent(out) :: hubbard_correction
real(8), optional, target, intent(out) :: evp_work_count
integer, optional, target, intent(out) :: num_loc_op_applied
integer, optional, target, intent(out) :: num_sym_op
character(*), optional, target, intent(out) :: electronic_structure_method
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
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_spins_ptr
type(C_PTR) :: num_mag_dims_ptr
type(C_PTR) :: pw_cutoff_ptr
type(C_PTR) :: gk_cutoff_ptr
type(C_PTR) :: fft_grid_size_ptr
type(C_PTR) :: auto_rmt_ptr
type(C_PTR) :: gamma_point_ptr
logical(C_BOOL), target :: gamma_point_c_type
type(C_PTR) :: use_symmetry_ptr
logical(C_BOOL), target :: use_symmetry_c_type
type(C_PTR) :: so_correction_ptr
logical(C_BOOL), target :: so_correction_c_type
type(C_PTR) :: iter_solver_tol_ptr
type(C_PTR) :: iter_solver_tol_empty_ptr
type(C_PTR) :: verbosity_ptr
type(C_PTR) :: hubbard_correction_ptr
logical(C_BOOL), target :: hubbard_correction_c_type
type(C_PTR) :: evp_work_count_ptr
type(C_PTR) :: num_loc_op_applied_ptr
type(C_PTR) :: num_sym_op_ptr
type(C_PTR) :: electronic_structure_method_ptr
character(C_CHAR), target, allocatable :: electronic_structure_method_c_type(:)
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_parameters_aux(handler,lmax_apw,lmax_rho,lmax_pot,num_fv_states,&
&num_bands,num_spins,num_mag_dims,pw_cutoff,gk_cutoff,fft_grid_size,auto_rmt,gamma_point,&
&use_symmetry,so_correction,iter_solver_tol,iter_solver_tol_empty,verbosity,hubbard_correction,&
&evp_work_count,num_loc_op_applied,num_sym_op,electronic_structure_method,error_code)&
&bind(C, name="sirius_get_parameters")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: lmax_apw
type(C_PTR), value :: lmax_rho
type(C_PTR), value :: lmax_pot
type(C_PTR), value :: num_fv_states
type(C_PTR), value :: num_bands
type(C_PTR), value :: num_spins
type(C_PTR), value :: num_mag_dims
type(C_PTR), value :: pw_cutoff
type(C_PTR), value :: gk_cutoff
type(C_PTR), value :: fft_grid_size
type(C_PTR), value :: auto_rmt
type(C_PTR), value :: gamma_point
type(C_PTR), value :: use_symmetry
type(C_PTR), value :: so_correction
type(C_PTR), value :: iter_solver_tol
type(C_PTR), value :: iter_solver_tol_empty
type(C_PTR), value :: verbosity
type(C_PTR), value :: hubbard_correction
type(C_PTR), value :: evp_work_count
type(C_PTR), value :: num_loc_op_applied
type(C_PTR), value :: num_sym_op
type(C_PTR), value :: electronic_structure_method
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
lmax_apw_ptr = C_NULL_PTR
if (present(lmax_apw)) then
lmax_apw_ptr = C_LOC(lmax_apw)
endif
lmax_rho_ptr = C_NULL_PTR
if (present(lmax_rho)) then
lmax_rho_ptr = C_LOC(lmax_rho)
endif
lmax_pot_ptr = C_NULL_PTR
if (present(lmax_pot)) then
lmax_pot_ptr = C_LOC(lmax_pot)
endif
num_fv_states_ptr = C_NULL_PTR
if (present(num_fv_states)) then
num_fv_states_ptr = C_LOC(num_fv_states)
endif
num_bands_ptr = C_NULL_PTR
if (present(num_bands)) then
num_bands_ptr = C_LOC(num_bands)
endif
num_spins_ptr = C_NULL_PTR
if (present(num_spins)) then
num_spins_ptr = C_LOC(num_spins)
endif
num_mag_dims_ptr = C_NULL_PTR
if (present(num_mag_dims)) then
num_mag_dims_ptr = C_LOC(num_mag_dims)
endif
pw_cutoff_ptr = C_NULL_PTR
if (present(pw_cutoff)) then
pw_cutoff_ptr = C_LOC(pw_cutoff)
endif
gk_cutoff_ptr = C_NULL_PTR
if (present(gk_cutoff)) then
gk_cutoff_ptr = C_LOC(gk_cutoff)
endif
fft_grid_size_ptr = C_NULL_PTR
if (present(fft_grid_size)) then
fft_grid_size_ptr = C_LOC(fft_grid_size)
endif
auto_rmt_ptr = C_NULL_PTR
if (present(auto_rmt)) then
auto_rmt_ptr = C_LOC(auto_rmt)
endif
gamma_point_ptr = C_NULL_PTR
if (present(gamma_point)) then
gamma_point_ptr = C_LOC(gamma_point_c_type)
endif
use_symmetry_ptr = C_NULL_PTR
if (present(use_symmetry)) then
use_symmetry_ptr = C_LOC(use_symmetry_c_type)
endif
so_correction_ptr = C_NULL_PTR
if (present(so_correction)) then
so_correction_ptr = C_LOC(so_correction_c_type)
endif
iter_solver_tol_ptr = C_NULL_PTR
if (present(iter_solver_tol)) then
iter_solver_tol_ptr = C_LOC(iter_solver_tol)
endif
iter_solver_tol_empty_ptr = C_NULL_PTR
if (present(iter_solver_tol_empty)) then
iter_solver_tol_empty_ptr = C_LOC(iter_solver_tol_empty)
endif
verbosity_ptr = C_NULL_PTR
if (present(verbosity)) then
verbosity_ptr = C_LOC(verbosity)
endif
hubbard_correction_ptr = C_NULL_PTR
if (present(hubbard_correction)) then
hubbard_correction_ptr = C_LOC(hubbard_correction_c_type)
endif
evp_work_count_ptr = C_NULL_PTR
if (present(evp_work_count)) then
evp_work_count_ptr = C_LOC(evp_work_count)
endif
num_loc_op_applied_ptr = C_NULL_PTR
if (present(num_loc_op_applied)) then
num_loc_op_applied_ptr = C_LOC(num_loc_op_applied)
endif
num_sym_op_ptr = C_NULL_PTR
if (present(num_sym_op)) then
num_sym_op_ptr = C_LOC(num_sym_op)
endif
electronic_structure_method_ptr = C_NULL_PTR
if (present(electronic_structure_method)) then
allocate(electronic_structure_method_c_type(len(electronic_structure_method)+1))
electronic_structure_method_ptr = C_LOC(electronic_structure_method_c_type)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_parameters_aux(handler_ptr,lmax_apw_ptr,lmax_rho_ptr,lmax_pot_ptr,&
&num_fv_states_ptr,num_bands_ptr,num_spins_ptr,num_mag_dims_ptr,pw_cutoff_ptr,gk_cutoff_ptr,&
&fft_grid_size_ptr,auto_rmt_ptr,gamma_point_ptr,use_symmetry_ptr,so_correction_ptr,&
&iter_solver_tol_ptr,iter_solver_tol_empty_ptr,verbosity_ptr,hubbard_correction_ptr,&
&evp_work_count_ptr,num_loc_op_applied_ptr,num_sym_op_ptr,electronic_structure_method_ptr,&
&error_code_ptr)
if (present(gamma_point)) then
gamma_point = gamma_point_c_type
endif
if (present(use_symmetry)) then
use_symmetry = use_symmetry_c_type
endif
if (present(so_correction)) then
so_correction = so_correction_c_type
endif
if (present(hubbard_correction)) then
hubbard_correction = hubbard_correction_c_type
endif
if (present(electronic_structure_method)) then
electronic_structure_method = string_c2f(electronic_structure_method_c_type)
deallocate(electronic_structure_method_c_type)
endif
end subroutine sirius_get_parameters

!
!> @brief Add one of the XC functionals.
!> @param [in] handler Simulation context handler
!> @param [in] name LibXC label of the functional.
!> @param [out] error_code Error code.
subroutine sirius_add_xc_functional(handler,name,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
character(*), target, intent(in) :: name
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: name_ptr
character(C_CHAR), target, allocatable :: name_c_type(:)
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_add_xc_functional_aux(handler,name,error_code)&
&bind(C, name="sirius_add_xc_functional")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: name
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
name_ptr = C_NULL_PTR
allocate(name_c_type(len(name)+1))
name_c_type = string_f2c(name)
name_ptr = C_LOC(name_c_type)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_add_xc_functional_aux(handler_ptr,name_ptr,error_code_ptr)
deallocate(name_c_type)
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.
!> @param [out] error_code Error code.
subroutine sirius_set_mpi_grid_dims(handler,ndims,dims,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, target, intent(in) :: ndims
integer, target, intent(in) :: dims(ndims)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: ndims_ptr
type(C_PTR) :: dims_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_mpi_grid_dims_aux(handler,ndims,dims,error_code)&
&bind(C, name="sirius_set_mpi_grid_dims")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: ndims
type(C_PTR), value :: dims
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
ndims_ptr = C_NULL_PTR
ndims_ptr = C_LOC(ndims)
dims_ptr = C_NULL_PTR
dims_ptr = C_LOC(dims)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_mpi_grid_dims_aux(handler_ptr,ndims_ptr,dims_ptr,error_code_ptr)
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
!> @param [out] error_code Error code.
subroutine sirius_set_lattice_vectors(handler,a1,a2,a3,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
real(8), target, intent(in) :: a1(3)
real(8), target, intent(in) :: a2(3)
real(8), target, intent(in) :: a3(3)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: a1_ptr
type(C_PTR) :: a2_ptr
type(C_PTR) :: a3_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_lattice_vectors_aux(handler,a1,a2,a3,error_code)&
&bind(C, name="sirius_set_lattice_vectors")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: a1
type(C_PTR), value :: a2
type(C_PTR), value :: a3
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
a1_ptr = C_NULL_PTR
a1_ptr = C_LOC(a1)
a2_ptr = C_NULL_PTR
a2_ptr = C_LOC(a2)
a3_ptr = C_NULL_PTR
a3_ptr = C_LOC(a3)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_lattice_vectors_aux(handler_ptr,a1_ptr,a2_ptr,a3_ptr,error_code_ptr)
end subroutine sirius_set_lattice_vectors

!
!> @brief Initialize simulation context.
!> @param [in] handler Simulation context handler.
!> @param [out] error_code Error code.
subroutine sirius_initialize_context(handler,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_initialize_context_aux(handler,error_code)&
&bind(C, name="sirius_initialize_context")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_initialize_context_aux(handler_ptr,error_code_ptr)
end subroutine sirius_initialize_context

!
!> @brief Update simulation context after changing lattice or atomic positions.
!> @param [in] handler Simulation context handler.
!> @param [out] error_code Error code.
subroutine sirius_update_context(handler,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_update_context_aux(handler,error_code)&
&bind(C, name="sirius_update_context")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_update_context_aux(handler_ptr,error_code_ptr)
end subroutine sirius_update_context

!
!> @brief Print basic info
!> @param [in] handler Simulation context handler.
!> @param [out] error_code Error code.
subroutine sirius_print_info(handler,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_print_info_aux(handler,error_code)&
&bind(C, name="sirius_print_info")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_print_info_aux(handler_ptr,error_code_ptr)
end subroutine sirius_print_info

!
!> @brief Free any object handler created by SIRIUS.
!> @details
!> This is an internal function. Use sirius_free_handler() in your code.
!> @param [inout] handler Handler of the object.
!> @param [out] error_code Error code
subroutine sirius_free_object_handler(handler,error_code)
implicit none
!
type(C_PTR), target, intent(inout) :: handler
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_free_object_handler_aux(handler,error_code)&
&bind(C, name="sirius_free_object_handler")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_free_object_handler_aux(handler_ptr,error_code_ptr)
end subroutine sirius_free_object_handler

!
!> @brief Set pointer to density or magnetization.
!> @param [in] handler Simulation context handler.
!> @param [in] label Label of the function.
!> @param [in] f_mt Pointer to the muffin-tin part of the function.
!> @param [in] lmmax Number of lm components.
!> @param [in] nrmtmax Maximum number of muffin-tin points.
!> @param [in] num_atoms Total number of atoms.
!> @param [in] f_rg Pointer to the regular-grid part of the function.
!> @param [in] size_x Size of X-dimension of FFT grid.
!> @param [in] size_y Size of Y-dimension of FFT grid.
!> @param [in] size_z Local or global size of Z-dimension of FFT grid depending on offset_z
!> @param [in] offset_z Offset in the Z-dimension of FFT grid for this MPI rank.
!> @param [out] error_code Error code
subroutine sirius_set_periodic_function_ptr(handler,label,f_mt,lmmax,nrmtmax,num_atoms,&
&f_rg,size_x,size_y,size_z,offset_z,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
character(*), target, intent(in) :: label
real(8), optional, target, intent(in) :: f_mt(:,:,:)
integer, optional, target, intent(in) :: lmmax
integer, optional, target, intent(in) :: nrmtmax
integer, optional, target, intent(in) :: num_atoms
real(8), optional, target, intent(in) :: f_rg(:)
integer, optional, target, intent(in) :: size_x
integer, optional, target, intent(in) :: size_y
integer, optional, target, intent(in) :: size_z
integer, optional, target, intent(in) :: offset_z
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: f_mt_ptr
type(C_PTR) :: lmmax_ptr
type(C_PTR) :: nrmtmax_ptr
type(C_PTR) :: num_atoms_ptr
type(C_PTR) :: f_rg_ptr
type(C_PTR) :: size_x_ptr
type(C_PTR) :: size_y_ptr
type(C_PTR) :: size_z_ptr
type(C_PTR) :: offset_z_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_periodic_function_ptr_aux(handler,label,f_mt,lmmax,nrmtmax,&
&num_atoms,f_rg,size_x,size_y,size_z,offset_z,error_code)&
&bind(C, name="sirius_set_periodic_function_ptr")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: label
type(C_PTR), value :: f_mt
type(C_PTR), value :: lmmax
type(C_PTR), value :: nrmtmax
type(C_PTR), value :: num_atoms
type(C_PTR), value :: f_rg
type(C_PTR), value :: size_x
type(C_PTR), value :: size_y
type(C_PTR), value :: size_z
type(C_PTR), value :: offset_z
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
f_mt_ptr = C_NULL_PTR
if (present(f_mt)) then
f_mt_ptr = C_LOC(f_mt)
endif
lmmax_ptr = C_NULL_PTR
if (present(lmmax)) then
lmmax_ptr = C_LOC(lmmax)
endif
nrmtmax_ptr = C_NULL_PTR
if (present(nrmtmax)) then
nrmtmax_ptr = C_LOC(nrmtmax)
endif
num_atoms_ptr = C_NULL_PTR
if (present(num_atoms)) then
num_atoms_ptr = C_LOC(num_atoms)
endif
f_rg_ptr = C_NULL_PTR
if (present(f_rg)) then
f_rg_ptr = C_LOC(f_rg)
endif
size_x_ptr = C_NULL_PTR
if (present(size_x)) then
size_x_ptr = C_LOC(size_x)
endif
size_y_ptr = C_NULL_PTR
if (present(size_y)) then
size_y_ptr = C_LOC(size_y)
endif
size_z_ptr = C_NULL_PTR
if (present(size_z)) then
size_z_ptr = C_LOC(size_z)
endif
offset_z_ptr = C_NULL_PTR
if (present(offset_z)) then
offset_z_ptr = C_LOC(offset_z)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_periodic_function_ptr_aux(handler_ptr,label_ptr,f_mt_ptr,lmmax_ptr,&
&nrmtmax_ptr,num_atoms_ptr,f_rg_ptr,size_x_ptr,size_y_ptr,size_z_ptr,offset_z_ptr,&
&error_code_ptr)
deallocate(label_c_type)
end subroutine sirius_set_periodic_function_ptr

!
!> @brief Set values of the periodic function.
!> @param [in] gs_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] lmmax Number of lm components.
!> @param [in] nrmtmax Maximum number of muffin-tin points.
!> @param [in] num_atoms Total number of atoms.
!> @param [in] f_rg Pointer to the regular-grid part of the function.
!> @param [in] size_x Size of X-dimension of FFT grid.
!> @param [in] size_y Size of Y-dimension of FFT grid.
!> @param [in] size_z Local or global size of Z-dimension of FFT grid depending on offset_z
!> @param [in] offset_z Offset in the Z-dimension of FFT grid for this MPI rank.
!> @param [out] error_code Error code.
subroutine sirius_set_periodic_function(gs_handler,label,f_mt,lmmax,nrmtmax,num_atoms,&
&f_rg,size_x,size_y,size_z,offset_z,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
character(*), target, intent(in) :: label
real(8), optional, target, intent(in) :: f_mt(:,:,:)
integer, optional, target, intent(in) :: lmmax
integer, optional, target, intent(in) :: nrmtmax
integer, optional, target, intent(in) :: num_atoms
real(8), optional, target, intent(in) :: f_rg(:)
integer, optional, target, intent(in) :: size_x
integer, optional, target, intent(in) :: size_y
integer, optional, target, intent(in) :: size_z
integer, optional, target, intent(in) :: offset_z
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: f_mt_ptr
type(C_PTR) :: lmmax_ptr
type(C_PTR) :: nrmtmax_ptr
type(C_PTR) :: num_atoms_ptr
type(C_PTR) :: f_rg_ptr
type(C_PTR) :: size_x_ptr
type(C_PTR) :: size_y_ptr
type(C_PTR) :: size_z_ptr
type(C_PTR) :: offset_z_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_periodic_function_aux(gs_handler,label,f_mt,lmmax,nrmtmax,&
&num_atoms,f_rg,size_x,size_y,size_z,offset_z,error_code)&
&bind(C, name="sirius_set_periodic_function")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: label
type(C_PTR), value :: f_mt
type(C_PTR), value :: lmmax
type(C_PTR), value :: nrmtmax
type(C_PTR), value :: num_atoms
type(C_PTR), value :: f_rg
type(C_PTR), value :: size_x
type(C_PTR), value :: size_y
type(C_PTR), value :: size_z
type(C_PTR), value :: offset_z
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
f_mt_ptr = C_NULL_PTR
if (present(f_mt)) then
f_mt_ptr = C_LOC(f_mt)
endif
lmmax_ptr = C_NULL_PTR
if (present(lmmax)) then
lmmax_ptr = C_LOC(lmmax)
endif
nrmtmax_ptr = C_NULL_PTR
if (present(nrmtmax)) then
nrmtmax_ptr = C_LOC(nrmtmax)
endif
num_atoms_ptr = C_NULL_PTR
if (present(num_atoms)) then
num_atoms_ptr = C_LOC(num_atoms)
endif
f_rg_ptr = C_NULL_PTR
if (present(f_rg)) then
f_rg_ptr = C_LOC(f_rg)
endif
size_x_ptr = C_NULL_PTR
if (present(size_x)) then
size_x_ptr = C_LOC(size_x)
endif
size_y_ptr = C_NULL_PTR
if (present(size_y)) then
size_y_ptr = C_LOC(size_y)
endif
size_z_ptr = C_NULL_PTR
if (present(size_z)) then
size_z_ptr = C_LOC(size_z)
endif
offset_z_ptr = C_NULL_PTR
if (present(offset_z)) then
offset_z_ptr = C_LOC(offset_z)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_periodic_function_aux(gs_handler_ptr,label_ptr,f_mt_ptr,lmmax_ptr,&
&nrmtmax_ptr,num_atoms_ptr,f_rg_ptr,size_x_ptr,size_y_ptr,size_z_ptr,offset_z_ptr,&
&error_code_ptr)
deallocate(label_c_type)
end subroutine sirius_set_periodic_function

!
!> @brief Get values of the periodic function.
!> @param [in] gs_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] lmmax Number of lm components.
!> @param [in] nrmtmax Maximum number of muffin-tin points.
!> @param [in] num_atoms Total number of atoms.
!> @param [in] f_rg Pointer to the regular-grid part of the function.
!> @param [in] size_x Size of X-dimension of FFT grid.
!> @param [in] size_y Size of Y-dimension of FFT grid.
!> @param [in] size_z Local or global size of Z-dimension of FFT grid depending on offset_z
!> @param [in] offset_z Offset in the Z-dimension of FFT grid for this MPI rank.
!> @param [out] error_code Error code
subroutine sirius_get_periodic_function(gs_handler,label,f_mt,lmmax,nrmtmax,num_atoms,&
&f_rg,size_x,size_y,size_z,offset_z,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
character(*), target, intent(in) :: label
real(8), optional, target, intent(in) :: f_mt(:,:,:)
integer, optional, target, intent(in) :: lmmax
integer, optional, target, intent(in) :: nrmtmax
integer, optional, target, intent(in) :: num_atoms
real(8), optional, target, intent(in) :: f_rg(:)
integer, optional, target, intent(in) :: size_x
integer, optional, target, intent(in) :: size_y
integer, optional, target, intent(in) :: size_z
integer, optional, target, intent(in) :: offset_z
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: f_mt_ptr
type(C_PTR) :: lmmax_ptr
type(C_PTR) :: nrmtmax_ptr
type(C_PTR) :: num_atoms_ptr
type(C_PTR) :: f_rg_ptr
type(C_PTR) :: size_x_ptr
type(C_PTR) :: size_y_ptr
type(C_PTR) :: size_z_ptr
type(C_PTR) :: offset_z_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_periodic_function_aux(gs_handler,label,f_mt,lmmax,nrmtmax,&
&num_atoms,f_rg,size_x,size_y,size_z,offset_z,error_code)&
&bind(C, name="sirius_get_periodic_function")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: label
type(C_PTR), value :: f_mt
type(C_PTR), value :: lmmax
type(C_PTR), value :: nrmtmax
type(C_PTR), value :: num_atoms
type(C_PTR), value :: f_rg
type(C_PTR), value :: size_x
type(C_PTR), value :: size_y
type(C_PTR), value :: size_z
type(C_PTR), value :: offset_z
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
f_mt_ptr = C_NULL_PTR
if (present(f_mt)) then
f_mt_ptr = C_LOC(f_mt)
endif
lmmax_ptr = C_NULL_PTR
if (present(lmmax)) then
lmmax_ptr = C_LOC(lmmax)
endif
nrmtmax_ptr = C_NULL_PTR
if (present(nrmtmax)) then
nrmtmax_ptr = C_LOC(nrmtmax)
endif
num_atoms_ptr = C_NULL_PTR
if (present(num_atoms)) then
num_atoms_ptr = C_LOC(num_atoms)
endif
f_rg_ptr = C_NULL_PTR
if (present(f_rg)) then
f_rg_ptr = C_LOC(f_rg)
endif
size_x_ptr = C_NULL_PTR
if (present(size_x)) then
size_x_ptr = C_LOC(size_x)
endif
size_y_ptr = C_NULL_PTR
if (present(size_y)) then
size_y_ptr = C_LOC(size_y)
endif
size_z_ptr = C_NULL_PTR
if (present(size_z)) then
size_z_ptr = C_LOC(size_z)
endif
offset_z_ptr = C_NULL_PTR
if (present(offset_z)) then
offset_z_ptr = C_LOC(offset_z)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_periodic_function_aux(gs_handler_ptr,label_ptr,f_mt_ptr,lmmax_ptr,&
&nrmtmax_ptr,num_atoms_ptr,f_rg_ptr,size_x_ptr,size_y_ptr,size_z_ptr,offset_z_ptr,&
&error_code_ptr)
deallocate(label_c_type)
end subroutine sirius_get_periodic_function

!
!> @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.
!> @param [out] kset_handler Handler of the newly created k-point set.
!> @param [out] error_code Error code.
subroutine sirius_create_kset(handler,num_kpoints,kpoints,kpoint_weights,init_kset,&
&kset_handler,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, target, intent(in) :: num_kpoints
real(8), target, intent(in) :: kpoints(3,num_kpoints)
real(8), target, intent(in) :: kpoint_weights(num_kpoints)
logical, target, intent(in) :: init_kset
type(sirius_kpoint_set_handler), target, intent(out) :: kset_handler
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: num_kpoints_ptr
type(C_PTR) :: kpoints_ptr
type(C_PTR) :: kpoint_weights_ptr
type(C_PTR) :: init_kset_ptr
logical(C_BOOL), target :: init_kset_c_type
type(C_PTR) :: kset_handler_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_create_kset_aux(handler,num_kpoints,kpoints,kpoint_weights,init_kset,&
&kset_handler,error_code)&
&bind(C, name="sirius_create_kset")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: num_kpoints
type(C_PTR), value :: kpoints
type(C_PTR), value :: kpoint_weights
type(C_PTR), value :: init_kset
type(C_PTR), value :: kset_handler
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
num_kpoints_ptr = C_NULL_PTR
num_kpoints_ptr = C_LOC(num_kpoints)
kpoints_ptr = C_NULL_PTR
kpoints_ptr = C_LOC(kpoints)
kpoint_weights_ptr = C_NULL_PTR
kpoint_weights_ptr = C_LOC(kpoint_weights)
init_kset_ptr = C_NULL_PTR
init_kset_c_type = init_kset
init_kset_ptr = C_LOC(init_kset_c_type)
kset_handler_ptr = C_NULL_PTR
kset_handler_ptr = C_LOC(kset_handler%handler_ptr_)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_create_kset_aux(handler_ptr,num_kpoints_ptr,kpoints_ptr,kpoint_weights_ptr,&
&init_kset_ptr,kset_handler_ptr,error_code_ptr)
end subroutine 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.
!> @param [out] kset_handler Handler of the newly created k-point set.
!> @param [out] error_code Error code.
subroutine sirius_create_kset_from_grid(handler,k_grid,k_shift,use_symmetry,kset_handler,&
&error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, target, intent(in) :: k_grid(3)
integer, target, intent(in) :: k_shift(3)
logical, target, intent(in) :: use_symmetry
type(sirius_kpoint_set_handler), target, intent(out) :: kset_handler
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: k_grid_ptr
type(C_PTR) :: k_shift_ptr
type(C_PTR) :: use_symmetry_ptr
logical(C_BOOL), target :: use_symmetry_c_type
type(C_PTR) :: kset_handler_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_create_kset_from_grid_aux(handler,k_grid,k_shift,use_symmetry,&
&kset_handler,error_code)&
&bind(C, name="sirius_create_kset_from_grid")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: k_grid
type(C_PTR), value :: k_shift
type(C_PTR), value :: use_symmetry
type(C_PTR), value :: kset_handler
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
k_grid_ptr = C_NULL_PTR
k_grid_ptr = C_LOC(k_grid)
k_shift_ptr = C_NULL_PTR
k_shift_ptr = C_LOC(k_shift)
use_symmetry_ptr = C_NULL_PTR
use_symmetry_c_type = use_symmetry
use_symmetry_ptr = C_LOC(use_symmetry_c_type)
kset_handler_ptr = C_NULL_PTR
kset_handler_ptr = C_LOC(kset_handler%handler_ptr_)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_create_kset_from_grid_aux(handler_ptr,k_grid_ptr,k_shift_ptr,use_symmetry_ptr,&
&kset_handler_ptr,error_code_ptr)
end subroutine sirius_create_kset_from_grid

!
!> @brief Create a ground state object.
!> @param [in] ks_handler Handler of the k-point set.
!> @param [out] gs_handler Handler of the newly created ground state object.
!> @param [out] error_code Error code.
subroutine sirius_create_ground_state(ks_handler,gs_handler,error_code)
implicit none
!
type(sirius_kpoint_set_handler), target, intent(in) :: ks_handler
type(sirius_ground_state_handler), target, intent(out) :: gs_handler
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: ks_handler_ptr
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_create_ground_state_aux(ks_handler,gs_handler,error_code)&
&bind(C, name="sirius_create_ground_state")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: ks_handler
type(C_PTR), value :: gs_handler
type(C_PTR), value :: error_code
end subroutine
end interface
!
ks_handler_ptr = C_NULL_PTR
ks_handler_ptr = C_LOC(ks_handler%handler_ptr_)
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_create_ground_state_aux(ks_handler_ptr,gs_handler_ptr,error_code_ptr)
end subroutine sirius_create_ground_state

!
!> @brief Initialize k-point set.
!> @param [in] ks_handler K-point set handler.
!> @param [in] count Local number of k-points for each MPI rank.
!> @param [out] error_code Error code.
subroutine sirius_initialize_kset(ks_handler,count,error_code)
implicit none
!
type(sirius_kpoint_set_handler), target, intent(in) :: ks_handler
integer, optional, target, intent(in) :: count(:)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: ks_handler_ptr
type(C_PTR) :: count_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_initialize_kset_aux(ks_handler,count,error_code)&
&bind(C, name="sirius_initialize_kset")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: ks_handler
type(C_PTR), value :: count
type(C_PTR), value :: error_code
end subroutine
end interface
!
ks_handler_ptr = C_NULL_PTR
ks_handler_ptr = C_LOC(ks_handler%handler_ptr_)
count_ptr = C_NULL_PTR
if (present(count)) then
count_ptr = C_LOC(count)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_initialize_kset_aux(ks_handler_ptr,count_ptr,error_code_ptr)
end subroutine sirius_initialize_kset

!
!> @brief Find the ground state.
!> @param [in] gs_handler Handler of the ground state.
!> @param [in] density_tol Tolerance on RMS in density.
!> @param [in] energy_tol Tolerance in total energy difference.
!> @param [in] iter_solver_tol Initial tolerance of the iterative solver.
!> @param [in] initial_guess Boolean variable indicating if we want to start from the initial guess or from previous state.
!> @param [in] max_niter Maximum number of SCF iterations.
!> @param [in] save_state Boolean variable indicating if we want to save the ground state.
!> @param [out] converged Boolean variable indicating if the calculation has converged
!> @param [out] niter Actual number of SCF iterations.
!> @param [out] rho_min Minimum value of density on the real-space grid. If negative, total energy can't be trusted. Valid only if SCF calculation is converged.
!> @param [out] error_code Error code.
subroutine sirius_find_ground_state(gs_handler,density_tol,energy_tol,iter_solver_tol,&
&initial_guess,max_niter,save_state,converged,niter,rho_min,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
real(8), optional, target, intent(in) :: density_tol
real(8), optional, target, intent(in) :: energy_tol
real(8), optional, target, intent(in) :: iter_solver_tol
logical, optional, target, intent(in) :: initial_guess
integer, optional, target, intent(in) :: max_niter
logical, optional, target, intent(in) :: save_state
logical, optional, target, intent(out) :: converged
integer, optional, target, intent(out) :: niter
real(8), optional, target, intent(out) :: rho_min
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: density_tol_ptr
type(C_PTR) :: energy_tol_ptr
type(C_PTR) :: iter_solver_tol_ptr
type(C_PTR) :: initial_guess_ptr
logical(C_BOOL), target :: initial_guess_c_type
type(C_PTR) :: max_niter_ptr
type(C_PTR) :: save_state_ptr
logical(C_BOOL), target :: save_state_c_type
type(C_PTR) :: converged_ptr
logical(C_BOOL), target :: converged_c_type
type(C_PTR) :: niter_ptr
type(C_PTR) :: rho_min_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_find_ground_state_aux(gs_handler,density_tol,energy_tol,iter_solver_tol,&
&initial_guess,max_niter,save_state,converged,niter,rho_min,error_code)&
&bind(C, name="sirius_find_ground_state")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: density_tol
type(C_PTR), value :: energy_tol
type(C_PTR), value :: iter_solver_tol
type(C_PTR), value :: initial_guess
type(C_PTR), value :: max_niter
type(C_PTR), value :: save_state
type(C_PTR), value :: converged
type(C_PTR), value :: niter
type(C_PTR), value :: rho_min
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
density_tol_ptr = C_NULL_PTR
if (present(density_tol)) then
density_tol_ptr = C_LOC(density_tol)
endif
energy_tol_ptr = C_NULL_PTR
if (present(energy_tol)) then
energy_tol_ptr = C_LOC(energy_tol)
endif
iter_solver_tol_ptr = C_NULL_PTR
if (present(iter_solver_tol)) then
iter_solver_tol_ptr = C_LOC(iter_solver_tol)
endif
initial_guess_ptr = C_NULL_PTR
if (present(initial_guess)) then
initial_guess_c_type = initial_guess
initial_guess_ptr = C_LOC(initial_guess_c_type)
endif
max_niter_ptr = C_NULL_PTR
if (present(max_niter)) then
max_niter_ptr = C_LOC(max_niter)
endif
save_state_ptr = C_NULL_PTR
if (present(save_state)) then
save_state_c_type = save_state
save_state_ptr = C_LOC(save_state_c_type)
endif
converged_ptr = C_NULL_PTR
if (present(converged)) then
converged_ptr = C_LOC(converged_c_type)
endif
niter_ptr = C_NULL_PTR
if (present(niter)) then
niter_ptr = C_LOC(niter)
endif
rho_min_ptr = C_NULL_PTR
if (present(rho_min)) then
rho_min_ptr = C_LOC(rho_min)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_find_ground_state_aux(gs_handler_ptr,density_tol_ptr,energy_tol_ptr,&
&iter_solver_tol_ptr,initial_guess_ptr,max_niter_ptr,save_state_ptr,converged_ptr,&
&niter_ptr,rho_min_ptr,error_code_ptr)
if (present(initial_guess)) then
endif
if (present(save_state)) then
endif
if (present(converged)) then
converged = converged_c_type
endif
end subroutine sirius_find_ground_state

!
!> @brief Check the self-consistent density
!> @param [in] gs_handler Handler of the ground state.
!> @param [out] error_code Error code
subroutine sirius_check_scf_density(gs_handler,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_check_scf_density_aux(gs_handler,error_code)&
&bind(C, name="sirius_check_scf_density")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_check_scf_density_aux(gs_handler_ptr,error_code_ptr)
end subroutine sirius_check_scf_density

!
!> @brief Update a ground state object after change of atomic coordinates or lattice vectors.
!> @param [in] gs_handler Ground-state handler.
!> @param [out] error_code Error code
subroutine sirius_update_ground_state(gs_handler,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_update_ground_state_aux(gs_handler,error_code)&
&bind(C, name="sirius_update_ground_state")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_update_ground_state_aux(gs_handler_ptr,error_code_ptr)
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.
!> @param [out] error_code Error code.
subroutine sirius_add_atom_type(handler,label,fname,zn,symbol,mass,spin_orbit,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
character(*), target, intent(in) :: label
character(*), optional, target, intent(in) :: fname
integer, optional, target, intent(in) :: zn
character(*), optional, target, intent(in) :: symbol
real(8), optional, target, intent(in) :: mass
logical, optional, target, intent(in) :: spin_orbit
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: fname_ptr
character(C_CHAR), target, allocatable :: fname_c_type(:)
type(C_PTR) :: zn_ptr
type(C_PTR) :: symbol_ptr
character(C_CHAR), target, allocatable :: symbol_c_type(:)
type(C_PTR) :: mass_ptr
type(C_PTR) :: spin_orbit_ptr
logical(C_BOOL), target :: spin_orbit_c_type
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_add_atom_type_aux(handler,label,fname,zn,symbol,mass,spin_orbit,&
&error_code)&
&bind(C, name="sirius_add_atom_type")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: label
type(C_PTR), value :: fname
type(C_PTR), value :: zn
type(C_PTR), value :: symbol
type(C_PTR), value :: mass
type(C_PTR), value :: spin_orbit
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
fname_ptr = C_NULL_PTR
if (present(fname)) then
allocate(fname_c_type(len(fname)+1))
fname_c_type = string_f2c(fname)
fname_ptr = C_LOC(fname_c_type)
endif
zn_ptr = C_NULL_PTR
if (present(zn)) then
zn_ptr = C_LOC(zn)
endif
symbol_ptr = C_NULL_PTR
if (present(symbol)) then
allocate(symbol_c_type(len(symbol)+1))
symbol_c_type = string_f2c(symbol)
symbol_ptr = C_LOC(symbol_c_type)
endif
mass_ptr = C_NULL_PTR
if (present(mass)) then
mass_ptr = C_LOC(mass)
endif
spin_orbit_ptr = C_NULL_PTR
if (present(spin_orbit)) then
spin_orbit_c_type = spin_orbit
spin_orbit_ptr = C_LOC(spin_orbit_c_type)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_add_atom_type_aux(handler_ptr,label_ptr,fname_ptr,zn_ptr,symbol_ptr,&
&mass_ptr,spin_orbit_ptr,error_code_ptr)
deallocate(label_c_type)
if (present(fname)) then
deallocate(fname_c_type)
endif
if (present(symbol)) then
deallocate(symbol_c_type)
endif
if (present(spin_orbit)) then
endif
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.
!> @param [out] error_code Error code.
subroutine sirius_set_atom_type_radial_grid(handler,label,num_radial_points,radial_points,&
&error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
character(*), target, intent(in) :: label
integer, target, intent(in) :: num_radial_points
real(8), target, intent(in) :: radial_points(num_radial_points)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: num_radial_points_ptr
type(C_PTR) :: radial_points_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_atom_type_radial_grid_aux(handler,label,num_radial_points,&
&radial_points,error_code)&
&bind(C, name="sirius_set_atom_type_radial_grid")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: label
type(C_PTR), value :: num_radial_points
type(C_PTR), value :: radial_points
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
num_radial_points_ptr = C_NULL_PTR
num_radial_points_ptr = C_LOC(num_radial_points)
radial_points_ptr = C_NULL_PTR
radial_points_ptr = C_LOC(radial_points)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_atom_type_radial_grid_aux(handler_ptr,label_ptr,num_radial_points_ptr,&
&radial_points_ptr,error_code_ptr)
deallocate(label_c_type)
end subroutine sirius_set_atom_type_radial_grid

!
!> @brief Set radial grid of the free atom (up to effectice infinity).
!> @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.
!> @param [out] error_code Error code.
subroutine sirius_set_atom_type_radial_grid_inf(handler,label,num_radial_points,&
&radial_points,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
character(*), target, intent(in) :: label
integer, target, intent(in) :: num_radial_points
real(8), target, intent(in) :: radial_points(num_radial_points)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: num_radial_points_ptr
type(C_PTR) :: radial_points_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_atom_type_radial_grid_inf_aux(handler,label,num_radial_points,&
&radial_points,error_code)&
&bind(C, name="sirius_set_atom_type_radial_grid_inf")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: label
type(C_PTR), value :: num_radial_points
type(C_PTR), value :: radial_points
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
num_radial_points_ptr = C_NULL_PTR
num_radial_points_ptr = C_LOC(num_radial_points)
radial_points_ptr = C_NULL_PTR
radial_points_ptr = C_LOC(radial_points)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_atom_type_radial_grid_inf_aux(handler_ptr,label_ptr,num_radial_points_ptr,&
&radial_points_ptr,error_code_ptr)
deallocate(label_c_type)
end subroutine sirius_set_atom_type_radial_grid_inf

!
!> @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). Indices start from 1.
!> @param [in] idxrf2 Second index of radial function (for Q-operator). Indices start form 1.
!> @param [in] occ Occupancy of the wave-function.
!> @param [out] error_code Error code.
subroutine sirius_add_atom_type_radial_function(handler,atom_type,label,rf,num_points,&
&n,l,idxrf1,idxrf2,occ,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
character(*), target, intent(in) :: atom_type
character(*), target, intent(in) :: label
real(8), target, intent(in) :: rf(num_points)
integer, target, intent(in) :: num_points
integer, optional, target, intent(in) :: n
integer, optional, target, intent(in) :: l
integer, optional, target, intent(in) :: idxrf1
integer, optional, target, intent(in) :: idxrf2
real(8), optional, target, intent(in) :: occ
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: atom_type_ptr
character(C_CHAR), target, allocatable :: atom_type_c_type(:)
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: rf_ptr
type(C_PTR) :: num_points_ptr
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
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_add_atom_type_radial_function_aux(handler,atom_type,label,rf,num_points,&
&n,l,idxrf1,idxrf2,occ,error_code)&
&bind(C, name="sirius_add_atom_type_radial_function")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: atom_type
type(C_PTR), value :: label
type(C_PTR), value :: rf
type(C_PTR), value :: num_points
type(C_PTR), value :: n
type(C_PTR), value :: l
type(C_PTR), value :: idxrf1
type(C_PTR), value :: idxrf2
type(C_PTR), value :: occ
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
atom_type_ptr = C_NULL_PTR
allocate(atom_type_c_type(len(atom_type)+1))
atom_type_c_type = string_f2c(atom_type)
atom_type_ptr = C_LOC(atom_type_c_type)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
rf_ptr = C_NULL_PTR
rf_ptr = C_LOC(rf)
num_points_ptr = C_NULL_PTR
num_points_ptr = C_LOC(num_points)
n_ptr = C_NULL_PTR
if (present(n)) then
n_ptr = C_LOC(n)
endif
l_ptr = C_NULL_PTR
if (present(l)) then
l_ptr = C_LOC(l)
endif
idxrf1_ptr = C_NULL_PTR
if (present(idxrf1)) then
idxrf1_ptr = C_LOC(idxrf1)
endif
idxrf2_ptr = C_NULL_PTR
if (present(idxrf2)) then
idxrf2_ptr = C_LOC(idxrf2)
endif
occ_ptr = C_NULL_PTR
if (present(occ)) then
occ_ptr = C_LOC(occ)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_add_atom_type_radial_function_aux(handler_ptr,atom_type_ptr,label_ptr,&
&rf_ptr,num_points_ptr,n_ptr,l_ptr,idxrf1_ptr,idxrf2_ptr,occ_ptr,error_code_ptr)
deallocate(atom_type_c_type)
deallocate(label_c_type)
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.
!> @param [out] error_code Error code.
subroutine sirius_set_atom_type_hubbard(handler,label,l,n,occ,U,J,alpha,beta,J0,&
&error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
character(*), target, intent(in) :: label
integer, target, intent(in) :: l
integer, target, intent(in) :: n
real(8), target, intent(in) :: occ
real(8), target, intent(in) :: U
real(8), target, intent(in) :: J(3)
real(8), target, intent(in) :: alpha
real(8), target, intent(in) :: beta
real(8), target, intent(in) :: J0
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: l_ptr
type(C_PTR) :: n_ptr
type(C_PTR) :: occ_ptr
type(C_PTR) :: U_ptr
type(C_PTR) :: J_ptr
type(C_PTR) :: alpha_ptr
type(C_PTR) :: beta_ptr
type(C_PTR) :: J0_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_atom_type_hubbard_aux(handler,label,l,n,occ,U,J,alpha,beta,&
&J0,error_code)&
&bind(C, name="sirius_set_atom_type_hubbard")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: label
type(C_PTR), value :: l
type(C_PTR), value :: n
type(C_PTR), value :: occ
type(C_PTR), value :: U
type(C_PTR), value :: J
type(C_PTR), value :: alpha
type(C_PTR), value :: beta
type(C_PTR), value :: J0
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
l_ptr = C_NULL_PTR
l_ptr = C_LOC(l)
n_ptr = C_NULL_PTR
n_ptr = C_LOC(n)
occ_ptr = C_NULL_PTR
occ_ptr = C_LOC(occ)
U_ptr = C_NULL_PTR
U_ptr = C_LOC(U)
J_ptr = C_NULL_PTR
J_ptr = C_LOC(J)
alpha_ptr = C_NULL_PTR
alpha_ptr = C_LOC(alpha)
beta_ptr = C_NULL_PTR
beta_ptr = C_LOC(beta)
J0_ptr = C_NULL_PTR
J0_ptr = C_LOC(J0)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_atom_type_hubbard_aux(handler_ptr,label_ptr,l_ptr,n_ptr,occ_ptr,&
&U_ptr,J_ptr,alpha_ptr,beta_ptr,J0_ptr,error_code_ptr)
deallocate(label_c_type)
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.
!> @param [out] error_code Error code.
subroutine sirius_set_atom_type_dion(handler,label,num_beta,dion,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
character(*), target, intent(in) :: label
integer, target, intent(in) :: num_beta
real(8), target, intent(in) :: dion(num_beta, num_beta)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: num_beta_ptr
type(C_PTR) :: dion_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_atom_type_dion_aux(handler,label,num_beta,dion,error_code)&
&bind(C, name="sirius_set_atom_type_dion")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: label
type(C_PTR), value :: num_beta
type(C_PTR), value :: dion
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
num_beta_ptr = C_NULL_PTR
num_beta_ptr = C_LOC(num_beta)
dion_ptr = C_NULL_PTR
dion_ptr = C_LOC(dion)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_atom_type_dion_aux(handler_ptr,label_ptr,num_beta_ptr,dion_ptr,error_code_ptr)
deallocate(label_c_type)
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 array of orbital occupancies
!> @param [in] num_occ size of the occupations array
!> @param [out] error_code Error code.
subroutine sirius_set_atom_type_paw(handler,label,core_energy,occupations,num_occ,&
&error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
character(*), target, intent(in) :: label
real(8), target, intent(in) :: core_energy
real(8), target, intent(in) :: occupations(num_occ)
integer, target, intent(in) :: num_occ
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: core_energy_ptr
type(C_PTR) :: occupations_ptr
type(C_PTR) :: num_occ_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_atom_type_paw_aux(handler,label,core_energy,occupations,num_occ,&
&error_code)&
&bind(C, name="sirius_set_atom_type_paw")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: label
type(C_PTR), value :: core_energy
type(C_PTR), value :: occupations
type(C_PTR), value :: num_occ
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
core_energy_ptr = C_NULL_PTR
core_energy_ptr = C_LOC(core_energy)
occupations_ptr = C_NULL_PTR
occupations_ptr = C_LOC(occupations)
num_occ_ptr = C_NULL_PTR
num_occ_ptr = C_LOC(num_occ)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_atom_type_paw_aux(handler_ptr,label_ptr,core_energy_ptr,occupations_ptr,&
&num_occ_ptr,error_code_ptr)
deallocate(label_c_type)
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.
!> @param [out] error_code Error code.
subroutine sirius_add_atom(handler,label,position,vector_field,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
character(*), target, intent(in) :: label
real(8), target, intent(in) :: position(3)
real(8), optional, target, intent(in) :: vector_field(3)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: position_ptr
type(C_PTR) :: vector_field_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_add_atom_aux(handler,label,position,vector_field,error_code)&
&bind(C, name="sirius_add_atom")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: label
type(C_PTR), value :: position
type(C_PTR), value :: vector_field
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
position_ptr = C_NULL_PTR
position_ptr = C_LOC(position)
vector_field_ptr = C_NULL_PTR
if (present(vector_field)) then
vector_field_ptr = C_LOC(vector_field)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_add_atom_aux(handler_ptr,label_ptr,position_ptr,vector_field_ptr,error_code_ptr)
deallocate(label_c_type)
end subroutine sirius_add_atom

!
!> @brief Set new atomic position.
!> @param [in] handler Simulation context handler.
!> @param [in] ia Index of atom; index starts form 1
!> @param [in] position Atom position in lattice coordinates.
!> @param [out] error_code Error code.
subroutine sirius_set_atom_position(handler,ia,position,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, target, intent(in) :: ia
real(8), target, intent(in) :: position(3)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: ia_ptr
type(C_PTR) :: position_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_atom_position_aux(handler,ia,position,error_code)&
&bind(C, name="sirius_set_atom_position")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: ia
type(C_PTR), value :: position
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
ia_ptr = C_NULL_PTR
ia_ptr = C_LOC(ia)
position_ptr = C_NULL_PTR
position_ptr = C_LOC(position)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_atom_position_aux(handler_ptr,ia_ptr,position_ptr,error_code_ptr)
end subroutine sirius_set_atom_position

!
!> @brief Set plane-wave coefficients of a periodic function.
!> @param [in] gs_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
!> @param [out] error_code Error code.
subroutine sirius_set_pw_coeffs(gs_handler,label,pw_coeffs,transform_to_rg,ngv,gvl,&
&comm,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
character(*), target, intent(in) :: label
complex(8), target, intent(in) :: pw_coeffs(:)
logical, optional, target, intent(in) :: transform_to_rg
integer, optional, target, intent(in) :: ngv
integer, optional, target, intent(in) :: gvl(:,:)
integer, optional, target, intent(in) :: comm
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: pw_coeffs_ptr
type(C_PTR) :: transform_to_rg_ptr
logical(C_BOOL), target :: transform_to_rg_c_type
type(C_PTR) :: ngv_ptr
type(C_PTR) :: gvl_ptr
type(C_PTR) :: comm_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_pw_coeffs_aux(gs_handler,label,pw_coeffs,transform_to_rg,ngv,&
&gvl,comm,error_code)&
&bind(C, name="sirius_set_pw_coeffs")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: label
type(C_PTR), value :: pw_coeffs
type(C_PTR), value :: transform_to_rg
type(C_PTR), value :: ngv
type(C_PTR), value :: gvl
type(C_PTR), value :: comm
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
pw_coeffs_ptr = C_NULL_PTR
pw_coeffs_ptr = C_LOC(pw_coeffs)
transform_to_rg_ptr = C_NULL_PTR
if (present(transform_to_rg)) then
transform_to_rg_c_type = transform_to_rg
transform_to_rg_ptr = C_LOC(transform_to_rg_c_type)
endif
ngv_ptr = C_NULL_PTR
if (present(ngv)) then
ngv_ptr = C_LOC(ngv)
endif
gvl_ptr = C_NULL_PTR
if (present(gvl)) then
gvl_ptr = C_LOC(gvl)
endif
comm_ptr = C_NULL_PTR
if (present(comm)) then
comm_ptr = C_LOC(comm)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_pw_coeffs_aux(gs_handler_ptr,label_ptr,pw_coeffs_ptr,transform_to_rg_ptr,&
&ngv_ptr,gvl_ptr,comm_ptr,error_code_ptr)
deallocate(label_c_type)
if (present(transform_to_rg)) then
endif
end subroutine sirius_set_pw_coeffs

!
!> @brief Get plane-wave coefficients of a periodic function.
!> @param [in] gs_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
!> @param [out] error_code Error code.
subroutine sirius_get_pw_coeffs(gs_handler,label,pw_coeffs,ngv,gvl,comm,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
character(*), target, intent(in) :: label
complex(8), target, intent(in) :: pw_coeffs(:)
integer, optional, target, intent(in) :: ngv
integer, optional, target, intent(in) :: gvl(:,:)
integer, optional, target, intent(in) :: comm
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: pw_coeffs_ptr
type(C_PTR) :: ngv_ptr
type(C_PTR) :: gvl_ptr
type(C_PTR) :: comm_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_pw_coeffs_aux(gs_handler,label,pw_coeffs,ngv,gvl,comm,error_code)&
&bind(C, name="sirius_get_pw_coeffs")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: label
type(C_PTR), value :: pw_coeffs
type(C_PTR), value :: ngv
type(C_PTR), value :: gvl
type(C_PTR), value :: comm
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
pw_coeffs_ptr = C_NULL_PTR
pw_coeffs_ptr = C_LOC(pw_coeffs)
ngv_ptr = C_NULL_PTR
if (present(ngv)) then
ngv_ptr = C_LOC(ngv)
endif
gvl_ptr = C_NULL_PTR
if (present(gvl)) then
gvl_ptr = C_LOC(gvl)
endif
comm_ptr = C_NULL_PTR
if (present(comm)) then
comm_ptr = C_LOC(comm)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_pw_coeffs_aux(gs_handler_ptr,label_ptr,pw_coeffs_ptr,ngv_ptr,gvl_ptr,&
&comm_ptr,error_code_ptr)
deallocate(label_c_type)
end subroutine sirius_get_pw_coeffs

!
!> @brief Initialize the subspace of wave-functions.
!> @param [in] gs_handler Ground state handler.
!> @param [in] ks_handler K-point set handler.
!> @param [out] error_code Error code.
subroutine sirius_initialize_subspace(gs_handler,ks_handler,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
type(sirius_kpoint_set_handler), target, intent(in) :: ks_handler
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: ks_handler_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_initialize_subspace_aux(gs_handler,ks_handler,error_code)&
&bind(C, name="sirius_initialize_subspace")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: ks_handler
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
ks_handler_ptr = C_NULL_PTR
ks_handler_ptr = C_LOC(ks_handler%handler_ptr_)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_initialize_subspace_aux(gs_handler_ptr,ks_handler_ptr,error_code_ptr)
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_pw Generate plane-wave coefficients of the potential
!> @param [in] precompute_rf Generate radial functions
!> @param [in] precompute_ri Generate radial integrals
!> @param [in] iter_solver_tol Iterative solver tolerance.
!> @param [in] iter_solver_steps Iterative solver number of steps.
!> @param [out] error_code Error code.
subroutine sirius_find_eigen_states(gs_handler,ks_handler,precompute_pw,precompute_rf,&
&precompute_ri,iter_solver_tol,iter_solver_steps,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
type(sirius_kpoint_set_handler), target, intent(in) :: ks_handler
logical, optional, target, intent(in) :: precompute_pw
logical, optional, target, intent(in) :: precompute_rf
logical, optional, target, intent(in) :: precompute_ri
real(8), optional, target, intent(in) :: iter_solver_tol
integer, optional, target, intent(in) :: iter_solver_steps
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: ks_handler_ptr
type(C_PTR) :: precompute_pw_ptr
logical(C_BOOL), target :: precompute_pw_c_type
type(C_PTR) :: precompute_rf_ptr
logical(C_BOOL), target :: precompute_rf_c_type
type(C_PTR) :: precompute_ri_ptr
logical(C_BOOL), target :: precompute_ri_c_type
type(C_PTR) :: iter_solver_tol_ptr
type(C_PTR) :: iter_solver_steps_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_find_eigen_states_aux(gs_handler,ks_handler,precompute_pw,precompute_rf,&
&precompute_ri,iter_solver_tol,iter_solver_steps,error_code)&
&bind(C, name="sirius_find_eigen_states")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: ks_handler
type(C_PTR), value :: precompute_pw
type(C_PTR), value :: precompute_rf
type(C_PTR), value :: precompute_ri
type(C_PTR), value :: iter_solver_tol
type(C_PTR), value :: iter_solver_steps
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
ks_handler_ptr = C_NULL_PTR
ks_handler_ptr = C_LOC(ks_handler%handler_ptr_)
precompute_pw_ptr = C_NULL_PTR
if (present(precompute_pw)) then
precompute_pw_c_type = precompute_pw
precompute_pw_ptr = C_LOC(precompute_pw_c_type)
endif
precompute_rf_ptr = C_NULL_PTR
if (present(precompute_rf)) then
precompute_rf_c_type = precompute_rf
precompute_rf_ptr = C_LOC(precompute_rf_c_type)
endif
precompute_ri_ptr = C_NULL_PTR
if (present(precompute_ri)) then
precompute_ri_c_type = precompute_ri
precompute_ri_ptr = C_LOC(precompute_ri_c_type)
endif
iter_solver_tol_ptr = C_NULL_PTR
if (present(iter_solver_tol)) then
iter_solver_tol_ptr = C_LOC(iter_solver_tol)
endif
iter_solver_steps_ptr = C_NULL_PTR
if (present(iter_solver_steps)) then
iter_solver_steps_ptr = C_LOC(iter_solver_steps)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_find_eigen_states_aux(gs_handler_ptr,ks_handler_ptr,precompute_pw_ptr,&
&precompute_rf_ptr,precompute_ri_ptr,iter_solver_tol_ptr,iter_solver_steps_ptr,error_code_ptr)
if (present(precompute_pw)) then
endif
if (present(precompute_rf)) then
endif
if (present(precompute_ri)) then
endif
end subroutine sirius_find_eigen_states

!
!> @brief Generate initial density.
!> @param [in] gs_handler Ground state handler.
!> @param [out] error_code Error code.
subroutine sirius_generate_initial_density(gs_handler,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_generate_initial_density_aux(gs_handler,error_code)&
&bind(C, name="sirius_generate_initial_density")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_generate_initial_density_aux(gs_handler_ptr,error_code_ptr)
end subroutine sirius_generate_initial_density

!
!> @brief Generate effective potential and magnetic field.
!> @param [in] gs_handler Ground state handler.
!> @param [out] error_code Error code.
subroutine sirius_generate_effective_potential(gs_handler,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_generate_effective_potential_aux(gs_handler,error_code)&
&bind(C, name="sirius_generate_effective_potential")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_generate_effective_potential_aux(gs_handler_ptr,error_code_ptr)
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.
!> @param [in] paw_only it true, only local PAW density is generated
!> @param [out] error_code Error code.
subroutine sirius_generate_density(gs_handler,add_core,transform_to_rg,paw_only,&
&error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
logical, optional, target, intent(in) :: add_core
logical, optional, target, intent(in) :: transform_to_rg
logical, optional, target, intent(in) :: paw_only
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: add_core_ptr
logical(C_BOOL), target :: add_core_c_type
type(C_PTR) :: transform_to_rg_ptr
logical(C_BOOL), target :: transform_to_rg_c_type
type(C_PTR) :: paw_only_ptr
logical(C_BOOL), target :: paw_only_c_type
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_generate_density_aux(gs_handler,add_core,transform_to_rg,paw_only,&
&error_code)&
&bind(C, name="sirius_generate_density")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: add_core
type(C_PTR), value :: transform_to_rg
type(C_PTR), value :: paw_only
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
add_core_ptr = C_NULL_PTR
if (present(add_core)) then
add_core_c_type = add_core
add_core_ptr = C_LOC(add_core_c_type)
endif
transform_to_rg_ptr = C_NULL_PTR
if (present(transform_to_rg)) then
transform_to_rg_c_type = transform_to_rg
transform_to_rg_ptr = C_LOC(transform_to_rg_c_type)
endif
paw_only_ptr = C_NULL_PTR
if (present(paw_only)) then
paw_only_c_type = paw_only
paw_only_ptr = C_LOC(paw_only_c_type)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_generate_density_aux(gs_handler_ptr,add_core_ptr,transform_to_rg_ptr,&
&paw_only_ptr,error_code_ptr)
if (present(add_core)) then
endif
if (present(transform_to_rg)) then
endif
if (present(paw_only)) then
endif
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 index.
!> @param [in] band_occupancies Array of band occupancies.
!> @param [out] error_code Error code.
subroutine sirius_set_band_occupancies(ks_handler,ik,ispn,band_occupancies,error_code)
implicit none
!
type(sirius_kpoint_set_handler), target, intent(in) :: ks_handler
integer, target, intent(in) :: ik
integer, target, intent(in) :: ispn
real(8), target, intent(in) :: band_occupancies(:)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: ks_handler_ptr
type(C_PTR) :: ik_ptr
type(C_PTR) :: ispn_ptr
type(C_PTR) :: band_occupancies_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_band_occupancies_aux(ks_handler,ik,ispn,band_occupancies,error_code)&
&bind(C, name="sirius_set_band_occupancies")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: ks_handler
type(C_PTR), value :: ik
type(C_PTR), value :: ispn
type(C_PTR), value :: band_occupancies
type(C_PTR), value :: error_code
end subroutine
end interface
!
ks_handler_ptr = C_NULL_PTR
ks_handler_ptr = C_LOC(ks_handler%handler_ptr_)
ik_ptr = C_NULL_PTR
ik_ptr = C_LOC(ik)
ispn_ptr = C_NULL_PTR
ispn_ptr = C_LOC(ispn)
band_occupancies_ptr = C_NULL_PTR
band_occupancies_ptr = C_LOC(band_occupancies)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_band_occupancies_aux(ks_handler_ptr,ik_ptr,ispn_ptr,band_occupancies_ptr,&
&error_code_ptr)
end subroutine sirius_set_band_occupancies

!
!> @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 [out] band_occupancies Array of band occupancies.
!> @param [out] error_code Error code.
subroutine sirius_get_band_occupancies(ks_handler,ik,ispn,band_occupancies,error_code)
implicit none
!
type(sirius_kpoint_set_handler), target, intent(in) :: ks_handler
integer, target, intent(in) :: ik
integer, target, intent(in) :: ispn
real(8), target, intent(out) :: band_occupancies(:)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: ks_handler_ptr
type(C_PTR) :: ik_ptr
type(C_PTR) :: ispn_ptr
type(C_PTR) :: band_occupancies_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_band_occupancies_aux(ks_handler,ik,ispn,band_occupancies,error_code)&
&bind(C, name="sirius_get_band_occupancies")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: ks_handler
type(C_PTR), value :: ik
type(C_PTR), value :: ispn
type(C_PTR), value :: band_occupancies
type(C_PTR), value :: error_code
end subroutine
end interface
!
ks_handler_ptr = C_NULL_PTR
ks_handler_ptr = C_LOC(ks_handler%handler_ptr_)
ik_ptr = C_NULL_PTR
ik_ptr = C_LOC(ik)
ispn_ptr = C_NULL_PTR
ispn_ptr = C_LOC(ispn)
band_occupancies_ptr = C_NULL_PTR
band_occupancies_ptr = C_LOC(band_occupancies)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_band_occupancies_aux(ks_handler_ptr,ik_ptr,ispn_ptr,band_occupancies_ptr,&
&error_code_ptr)
end subroutine sirius_get_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.
!> @param [out] error_code Error code.
subroutine sirius_get_band_energies(ks_handler,ik,ispn,band_energies,error_code)
implicit none
!
type(sirius_kpoint_set_handler), target, intent(in) :: ks_handler
integer, target, intent(in) :: ik
integer, target, intent(in) :: ispn
real(8), target, intent(out) :: band_energies(:)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: ks_handler_ptr
type(C_PTR) :: ik_ptr
type(C_PTR) :: ispn_ptr
type(C_PTR) :: band_energies_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_band_energies_aux(ks_handler,ik,ispn,band_energies,error_code)&
&bind(C, name="sirius_get_band_energies")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: ks_handler
type(C_PTR), value :: ik
type(C_PTR), value :: ispn
type(C_PTR), value :: band_energies
type(C_PTR), value :: error_code
end subroutine
end interface
!
ks_handler_ptr = C_NULL_PTR
ks_handler_ptr = C_LOC(ks_handler%handler_ptr_)
ik_ptr = C_NULL_PTR
ik_ptr = C_LOC(ik)
ispn_ptr = C_NULL_PTR
ispn_ptr = C_LOC(ispn)
band_energies_ptr = C_NULL_PTR
band_energies_ptr = C_LOC(band_energies)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_band_energies_aux(ks_handler_ptr,ik_ptr,ispn_ptr,band_energies_ptr,&
&error_code_ptr)
end subroutine sirius_get_band_energies

!
!> @brief Get one of the total energy components.
!> @param [in] gs_handler DFT ground state handler.
!> @param [in] label Label of the energy component to get.
!> @param [out] energy Total energy component.
!> @param [out] error_code Error code.
subroutine sirius_get_energy(gs_handler,label,energy,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
character(*), target, intent(in) :: label
real(8), target, intent(out) :: energy
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: energy_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_energy_aux(gs_handler,label,energy,error_code)&
&bind(C, name="sirius_get_energy")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: label
type(C_PTR), value :: energy
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
energy_ptr = C_NULL_PTR
energy_ptr = C_LOC(energy)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_energy_aux(gs_handler_ptr,label_ptr,energy_ptr,error_code_ptr)
deallocate(label_c_type)
end subroutine sirius_get_energy

!
!> @brief Get one of the total force components.
!> @param [in] gs_handler DFT ground state handler.
!> @param [in] label Label of the force component to get.
!> @param [out] forces Total force component for each atom.
!> @param [out] error_code Error code.
subroutine sirius_get_forces(gs_handler,label,forces,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
character(*), target, intent(in) :: label
real(8), target, intent(out) :: forces(:,:)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: forces_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_forces_aux(gs_handler,label,forces,error_code)&
&bind(C, name="sirius_get_forces")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: label
type(C_PTR), value :: forces
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
forces_ptr = C_NULL_PTR
forces_ptr = C_LOC(forces)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_forces_aux(gs_handler_ptr,label_ptr,forces_ptr,error_code_ptr)
deallocate(label_c_type)
end subroutine sirius_get_forces

!
!> @brief Get one of the stress tensor components.
!> @param [in] gs_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.
!> @param [out] error_code Error code.
subroutine sirius_get_stress_tensor(gs_handler,label,stress_tensor,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
character(*), target, intent(in) :: label
real(8), target, intent(out) :: stress_tensor(3, 3)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: stress_tensor_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_stress_tensor_aux(gs_handler,label,stress_tensor,error_code)&
&bind(C, name="sirius_get_stress_tensor")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: label
type(C_PTR), value :: stress_tensor
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
stress_tensor_ptr = C_NULL_PTR
stress_tensor_ptr = C_LOC(stress_tensor)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_stress_tensor_aux(gs_handler_ptr,label_ptr,stress_tensor_ptr,error_code_ptr)
deallocate(label_c_type)
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.
!> @param [out] num_bp Number of beta projectors for each atom type.
!> @param [out] error_code Error code.
subroutine sirius_get_num_beta_projectors(handler,label,num_bp,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
character(*), target, intent(in) :: label
integer, target, intent(out) :: num_bp
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: num_bp_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_num_beta_projectors_aux(handler,label,num_bp,error_code)&
&bind(C, name="sirius_get_num_beta_projectors")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: label
type(C_PTR), value :: num_bp
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
num_bp_ptr = C_NULL_PTR
num_bp_ptr = C_LOC(num_bp)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_num_beta_projectors_aux(handler_ptr,label_ptr,num_bp_ptr,error_code_ptr)
deallocate(label_c_type)
end subroutine sirius_get_num_beta_projectors

!
!> @brief Get wave-functions.
!> @param [in] ks_handler K-point set handler.
!> @param [in] vkl Latttice coordinates of the k-point.
!> @param [in] spin Spin index in case of collinear magnetism.
!> @param [in] num_gvec_loc Local number of G-vectors for a k-point.
!> @param [in] gvec_loc List of G-vectors.
!> @param [out] evec Wave-functions.
!> @param [in] ld Leading dimension of evec array.
!> @param [in] num_spin_comp Number of spin components.
!> @param [out] error_code Error code
subroutine sirius_get_wave_functions(ks_handler,vkl,spin,num_gvec_loc,gvec_loc,evec,&
&ld,num_spin_comp,error_code)
implicit none
!
type(sirius_kpoint_set_handler), target, intent(in) :: ks_handler
real(8), optional, target, intent(in) :: vkl(3)
integer, optional, target, intent(in) :: spin
integer, optional, target, intent(in) :: num_gvec_loc
integer, optional, target, intent(in) :: gvec_loc(:,:)
complex(8), optional, target, intent(out) :: evec(:,:)
integer, optional, target, intent(in) :: ld
integer, optional, target, intent(in) :: num_spin_comp
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: ks_handler_ptr
type(C_PTR) :: vkl_ptr
type(C_PTR) :: spin_ptr
type(C_PTR) :: num_gvec_loc_ptr
type(C_PTR) :: gvec_loc_ptr
type(C_PTR) :: evec_ptr
type(C_PTR) :: ld_ptr
type(C_PTR) :: num_spin_comp_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_wave_functions_aux(ks_handler,vkl,spin,num_gvec_loc,gvec_loc,&
&evec,ld,num_spin_comp,error_code)&
&bind(C, name="sirius_get_wave_functions")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: ks_handler
type(C_PTR), value :: vkl
type(C_PTR), value :: spin
type(C_PTR), value :: num_gvec_loc
type(C_PTR), value :: gvec_loc
type(C_PTR), value :: evec
type(C_PTR), value :: ld
type(C_PTR), value :: num_spin_comp
type(C_PTR), value :: error_code
end subroutine
end interface
!
ks_handler_ptr = C_NULL_PTR
ks_handler_ptr = C_LOC(ks_handler%handler_ptr_)
vkl_ptr = C_NULL_PTR
if (present(vkl)) then
vkl_ptr = C_LOC(vkl)
endif
spin_ptr = C_NULL_PTR
if (present(spin)) then
spin_ptr = C_LOC(spin)
endif
num_gvec_loc_ptr = C_NULL_PTR
if (present(num_gvec_loc)) then
num_gvec_loc_ptr = C_LOC(num_gvec_loc)
endif
gvec_loc_ptr = C_NULL_PTR
if (present(gvec_loc)) then
gvec_loc_ptr = C_LOC(gvec_loc)
endif
evec_ptr = C_NULL_PTR
if (present(evec)) then
evec_ptr = C_LOC(evec)
endif
ld_ptr = C_NULL_PTR
if (present(ld)) then
ld_ptr = C_LOC(ld)
endif
num_spin_comp_ptr = C_NULL_PTR
if (present(num_spin_comp)) then
num_spin_comp_ptr = C_LOC(num_spin_comp)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_wave_functions_aux(ks_handler_ptr,vkl_ptr,spin_ptr,num_gvec_loc_ptr,&
&gvec_loc_ptr,evec_ptr,ld_ptr,num_spin_comp_ptr,error_code_ptr)
end subroutine sirius_get_wave_functions

!
!> @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.
!> @param [out] error_code Error code
subroutine sirius_add_atom_type_aw_descriptor(handler,label,n,l,enu,dme,auto_enu,&
&error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
character(*), target, intent(in) :: label
integer, target, intent(in) :: n
integer, target, intent(in) :: l
real(8), target, intent(in) :: enu
integer, target, intent(in) :: dme
logical, target, intent(in) :: auto_enu
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: n_ptr
type(C_PTR) :: l_ptr
type(C_PTR) :: enu_ptr
type(C_PTR) :: dme_ptr
type(C_PTR) :: auto_enu_ptr
logical(C_BOOL), target :: auto_enu_c_type
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_add_atom_type_aw_descriptor_aux(handler,label,n,l,enu,dme,auto_enu,&
&error_code)&
&bind(C, name="sirius_add_atom_type_aw_descriptor")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: label
type(C_PTR), value :: n
type(C_PTR), value :: l
type(C_PTR), value :: enu
type(C_PTR), value :: dme
type(C_PTR), value :: auto_enu
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
n_ptr = C_NULL_PTR
n_ptr = C_LOC(n)
l_ptr = C_NULL_PTR
l_ptr = C_LOC(l)
enu_ptr = C_NULL_PTR
enu_ptr = C_LOC(enu)
dme_ptr = C_NULL_PTR
dme_ptr = C_LOC(dme)
auto_enu_ptr = C_NULL_PTR
auto_enu_c_type = auto_enu
auto_enu_ptr = C_LOC(auto_enu_c_type)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_add_atom_type_aw_descriptor_aux(handler_ptr,label_ptr,n_ptr,l_ptr,enu_ptr,&
&dme_ptr,auto_enu_ptr,error_code_ptr)
deallocate(label_c_type)
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 descriptor 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.
!> @param [out] error_code Error code
subroutine sirius_add_atom_type_lo_descriptor(handler,label,ilo,n,l,enu,dme,auto_enu,&
&error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
character(*), target, intent(in) :: label
integer, target, intent(in) :: ilo
integer, target, intent(in) :: n
integer, target, intent(in) :: l
real(8), target, intent(in) :: enu
integer, target, intent(in) :: dme
logical, target, intent(in) :: auto_enu
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: ilo_ptr
type(C_PTR) :: n_ptr
type(C_PTR) :: l_ptr
type(C_PTR) :: enu_ptr
type(C_PTR) :: dme_ptr
type(C_PTR) :: auto_enu_ptr
logical(C_BOOL), target :: auto_enu_c_type
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_add_atom_type_lo_descriptor_aux(handler,label,ilo,n,l,enu,dme,&
&auto_enu,error_code)&
&bind(C, name="sirius_add_atom_type_lo_descriptor")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: label
type(C_PTR), value :: ilo
type(C_PTR), value :: n
type(C_PTR), value :: l
type(C_PTR), value :: enu
type(C_PTR), value :: dme
type(C_PTR), value :: auto_enu
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
ilo_ptr = C_NULL_PTR
ilo_ptr = C_LOC(ilo)
n_ptr = C_NULL_PTR
n_ptr = C_LOC(n)
l_ptr = C_NULL_PTR
l_ptr = C_LOC(l)
enu_ptr = C_NULL_PTR
enu_ptr = C_LOC(enu)
dme_ptr = C_NULL_PTR
dme_ptr = C_LOC(dme)
auto_enu_ptr = C_NULL_PTR
auto_enu_c_type = auto_enu
auto_enu_ptr = C_LOC(auto_enu_c_type)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_add_atom_type_lo_descriptor_aux(handler_ptr,label_ptr,ilo_ptr,n_ptr,&
&l_ptr,enu_ptr,dme_ptr,auto_enu_ptr,error_code_ptr)
deallocate(label_c_type)
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.
!> @param [out] error_code Error code
subroutine sirius_set_atom_type_configuration(handler,label,n,l,k,occupancy,core,&
&error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
character(*), target, intent(in) :: label
integer, target, intent(in) :: n
integer, target, intent(in) :: l
integer, target, intent(in) :: k
real(8), target, intent(in) :: occupancy
logical, target, intent(in) :: core
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: n_ptr
type(C_PTR) :: l_ptr
type(C_PTR) :: k_ptr
type(C_PTR) :: occupancy_ptr
type(C_PTR) :: core_ptr
logical(C_BOOL), target :: core_c_type
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_atom_type_configuration_aux(handler,label,n,l,k,occupancy,&
&core,error_code)&
&bind(C, name="sirius_set_atom_type_configuration")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: label
type(C_PTR), value :: n
type(C_PTR), value :: l
type(C_PTR), value :: k
type(C_PTR), value :: occupancy
type(C_PTR), value :: core
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
n_ptr = C_NULL_PTR
n_ptr = C_LOC(n)
l_ptr = C_NULL_PTR
l_ptr = C_LOC(l)
k_ptr = C_NULL_PTR
k_ptr = C_LOC(k)
occupancy_ptr = C_NULL_PTR
occupancy_ptr = C_LOC(occupancy)
core_ptr = C_NULL_PTR
core_c_type = core
core_ptr = C_LOC(core_c_type)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_atom_type_configuration_aux(handler_ptr,label_ptr,n_ptr,l_ptr,k_ptr,&
&occupancy_ptr,core_ptr,error_code_ptr)
deallocate(label_c_type)
end subroutine sirius_set_atom_type_configuration

!
!> @brief Generate Coulomb potential by solving Poisson equation
!> @param [in] gs_handler DFT ground state handler
!> @param [out] vh_el Electronic part of Hartree potential at each atom's origin.
!> @param [out] error_code Error code
subroutine sirius_generate_coulomb_potential(gs_handler,vh_el,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
real(8), optional, target, intent(out) :: vh_el(:)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: vh_el_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_generate_coulomb_potential_aux(gs_handler,vh_el,error_code)&
&bind(C, name="sirius_generate_coulomb_potential")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: vh_el
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
vh_el_ptr = C_NULL_PTR
if (present(vh_el)) then
vh_el_ptr = C_LOC(vh_el)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_generate_coulomb_potential_aux(gs_handler_ptr,vh_el_ptr,error_code_ptr)
end subroutine sirius_generate_coulomb_potential

!
!> @brief Generate XC potential using LibXC
!> @param [in] gs_handler Ground state handler
!> @param [out] error_code Error code
subroutine sirius_generate_xc_potential(gs_handler,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_generate_xc_potential_aux(gs_handler,error_code)&
&bind(C, name="sirius_generate_xc_potential")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_generate_xc_potential_aux(gs_handler_ptr,error_code_ptr)
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
!> @param [out] error_code Error code
subroutine sirius_get_kpoint_inter_comm(handler,fcomm,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, target, intent(out) :: fcomm
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: fcomm_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_kpoint_inter_comm_aux(handler,fcomm,error_code)&
&bind(C, name="sirius_get_kpoint_inter_comm")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: fcomm
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
fcomm_ptr = C_NULL_PTR
fcomm_ptr = C_LOC(fcomm)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_kpoint_inter_comm_aux(handler_ptr,fcomm_ptr,error_code_ptr)
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
!> @param [out] error_code Error code
subroutine sirius_get_kpoint_inner_comm(handler,fcomm,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, target, intent(out) :: fcomm
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: fcomm_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_kpoint_inner_comm_aux(handler,fcomm,error_code)&
&bind(C, name="sirius_get_kpoint_inner_comm")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: fcomm
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
fcomm_ptr = C_NULL_PTR
fcomm_ptr = C_LOC(fcomm)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_kpoint_inner_comm_aux(handler_ptr,fcomm_ptr,error_code_ptr)
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
!> @param [out] error_code Error code
subroutine sirius_get_fft_comm(handler,fcomm,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, target, intent(out) :: fcomm
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: fcomm_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_fft_comm_aux(handler,fcomm,error_code)&
&bind(C, name="sirius_get_fft_comm")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: fcomm
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
fcomm_ptr = C_NULL_PTR
fcomm_ptr = C_LOC(fcomm)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_fft_comm_aux(handler_ptr,fcomm_ptr,error_code_ptr)
end subroutine sirius_get_fft_comm

!
!> @brief Get total number of G-vectors on the fine grid.
!> @param [in] handler Simulation context handler
!> @param [out] num_gvec Total number of G-vectors
!> @param [out] error_code Error code
subroutine sirius_get_num_gvec(handler,num_gvec,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, target, intent(out) :: num_gvec
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: num_gvec_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_num_gvec_aux(handler,num_gvec,error_code)&
&bind(C, name="sirius_get_num_gvec")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: num_gvec
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
num_gvec_ptr = C_NULL_PTR
num_gvec_ptr = C_LOC(num_gvec)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_num_gvec_aux(handler_ptr,num_gvec_ptr,error_code_ptr)
end subroutine 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.
!> @param [out] error_code Error code
subroutine sirius_get_gvec_arrays(handler,gvec,gvec_cart,gvec_len,index_by_gvec,&
&error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, optional, target, intent(in) :: gvec(:,:)
real(8), optional, target, intent(in) :: gvec_cart(:,:)
real(8), optional, target, intent(in) :: gvec_len(:)
integer, optional, target, intent(in) :: index_by_gvec(:,:,:)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: gvec_ptr
type(C_PTR) :: gvec_cart_ptr
type(C_PTR) :: gvec_len_ptr
type(C_PTR) :: index_by_gvec_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_gvec_arrays_aux(handler,gvec,gvec_cart,gvec_len,index_by_gvec,&
&error_code)&
&bind(C, name="sirius_get_gvec_arrays")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: gvec
type(C_PTR), value :: gvec_cart
type(C_PTR), value :: gvec_len
type(C_PTR), value :: index_by_gvec
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
gvec_ptr = C_NULL_PTR
if (present(gvec)) then
gvec_ptr = C_LOC(gvec)
endif
gvec_cart_ptr = C_NULL_PTR
if (present(gvec_cart)) then
gvec_cart_ptr = C_LOC(gvec_cart)
endif
gvec_len_ptr = C_NULL_PTR
if (present(gvec_len)) then
gvec_len_ptr = C_LOC(gvec_len)
endif
index_by_gvec_ptr = C_NULL_PTR
if (present(index_by_gvec)) then
index_by_gvec_ptr = C_LOC(index_by_gvec)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_gvec_arrays_aux(handler_ptr,gvec_ptr,gvec_cart_ptr,gvec_len_ptr,&
&index_by_gvec_ptr,error_code_ptr)
end subroutine sirius_get_gvec_arrays

!
!> @brief Get local number of FFT grid points.
!> @param [in] handler Simulation context handler
!> @param [out] num_fft_grid_points Local number of FFT grid points in the real-space mesh.
!> @param [out] error_code Error code.
subroutine sirius_get_num_fft_grid_points(handler,num_fft_grid_points,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, target, intent(out) :: num_fft_grid_points
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: num_fft_grid_points_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_num_fft_grid_points_aux(handler,num_fft_grid_points,error_code)&
&bind(C, name="sirius_get_num_fft_grid_points")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: num_fft_grid_points
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
num_fft_grid_points_ptr = C_NULL_PTR
num_fft_grid_points_ptr = C_LOC(num_fft_grid_points)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_num_fft_grid_points_aux(handler_ptr,num_fft_grid_points_ptr,error_code_ptr)
end subroutine 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
!> @param [out] error_code Error code.
subroutine sirius_get_fft_index(handler,fft_index,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, target, intent(out) :: fft_index(:)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: fft_index_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_fft_index_aux(handler,fft_index,error_code)&
&bind(C, name="sirius_get_fft_index")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: fft_index
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
fft_index_ptr = C_NULL_PTR
fft_index_ptr = C_LOC(fft_index)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_fft_index_aux(handler_ptr,fft_index_ptr,error_code_ptr)
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.
!> @param [out] max_num_gkvec Maximum number of G+k vectors
!> @param [out] error_code Error code.
subroutine sirius_get_max_num_gkvec(ks_handler,max_num_gkvec,error_code)
implicit none
!
type(sirius_kpoint_set_handler), target, intent(in) :: ks_handler
integer, target, intent(out) :: max_num_gkvec
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: ks_handler_ptr
type(C_PTR) :: max_num_gkvec_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_max_num_gkvec_aux(ks_handler,max_num_gkvec,error_code)&
&bind(C, name="sirius_get_max_num_gkvec")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: ks_handler
type(C_PTR), value :: max_num_gkvec
type(C_PTR), value :: error_code
end subroutine
end interface
!
ks_handler_ptr = C_NULL_PTR
ks_handler_ptr = C_LOC(ks_handler%handler_ptr_)
max_num_gkvec_ptr = C_NULL_PTR
max_num_gkvec_ptr = C_LOC(max_num_gkvec)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_max_num_gkvec_aux(ks_handler_ptr,max_num_gkvec_ptr,error_code_ptr)
end subroutine 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.
!> @param [out] error_code Error code.
subroutine sirius_get_gkvec_arrays(ks_handler,ik,num_gkvec,gvec_index,gkvec,gkvec_cart,&
&gkvec_len,gkvec_tp,error_code)
implicit none
!
type(sirius_kpoint_set_handler), target, intent(in) :: ks_handler
integer, target, intent(in) :: ik
integer, target, intent(out) :: num_gkvec
integer, target, intent(out) :: gvec_index(:)
real(8), target, intent(out) :: gkvec(:,:)
real(8), target, intent(out) :: gkvec_cart(:,:)
real(8), target, intent(out) :: gkvec_len(:)
real(8), target, intent(out) :: gkvec_tp(:,:)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: ks_handler_ptr
type(C_PTR) :: ik_ptr
type(C_PTR) :: num_gkvec_ptr
type(C_PTR) :: gvec_index_ptr
type(C_PTR) :: gkvec_ptr
type(C_PTR) :: gkvec_cart_ptr
type(C_PTR) :: gkvec_len_ptr
type(C_PTR) :: gkvec_tp_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_gkvec_arrays_aux(ks_handler,ik,num_gkvec,gvec_index,gkvec,&
&gkvec_cart,gkvec_len,gkvec_tp,error_code)&
&bind(C, name="sirius_get_gkvec_arrays")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: ks_handler
type(C_PTR), value :: ik
type(C_PTR), value :: num_gkvec
type(C_PTR), value :: gvec_index
type(C_PTR), value :: gkvec
type(C_PTR), value :: gkvec_cart
type(C_PTR), value :: gkvec_len
type(C_PTR), value :: gkvec_tp
type(C_PTR), value :: error_code
end subroutine
end interface
!
ks_handler_ptr = C_NULL_PTR
ks_handler_ptr = C_LOC(ks_handler%handler_ptr_)
ik_ptr = C_NULL_PTR
ik_ptr = C_LOC(ik)
num_gkvec_ptr = C_NULL_PTR
num_gkvec_ptr = C_LOC(num_gkvec)
gvec_index_ptr = C_NULL_PTR
gvec_index_ptr = C_LOC(gvec_index)
gkvec_ptr = C_NULL_PTR
gkvec_ptr = C_LOC(gkvec)
gkvec_cart_ptr = C_NULL_PTR
gkvec_cart_ptr = C_LOC(gkvec_cart)
gkvec_len_ptr = C_NULL_PTR
gkvec_len_ptr = C_LOC(gkvec_len)
gkvec_tp_ptr = C_NULL_PTR
gkvec_tp_ptr = C_LOC(gkvec_tp)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_gkvec_arrays_aux(ks_handler_ptr,ik_ptr,num_gkvec_ptr,gvec_index_ptr,&
&gkvec_ptr,gkvec_cart_ptr,gkvec_len_ptr,gkvec_tp_ptr,error_code_ptr)
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.
!> @param [in] num_rg_points Number of real-space points.
!> @param [out] error_code Error code.
subroutine sirius_get_step_function(handler,cfunig,cfunrg,num_rg_points,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
complex(8), target, intent(out) :: cfunig(:)
real(8), target, intent(out) :: cfunrg(:)
integer, target, intent(in) :: num_rg_points
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: cfunig_ptr
type(C_PTR) :: cfunrg_ptr
type(C_PTR) :: num_rg_points_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_step_function_aux(handler,cfunig,cfunrg,num_rg_points,error_code)&
&bind(C, name="sirius_get_step_function")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: cfunig
type(C_PTR), value :: cfunrg
type(C_PTR), value :: num_rg_points
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
cfunig_ptr = C_NULL_PTR
cfunig_ptr = C_LOC(cfunig)
cfunrg_ptr = C_NULL_PTR
cfunrg_ptr = C_LOC(cfunrg)
num_rg_points_ptr = C_NULL_PTR
num_rg_points_ptr = C_LOC(num_rg_points)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_step_function_aux(handler_ptr,cfunig_ptr,cfunrg_ptr,num_rg_points_ptr,&
&error_code_ptr)
end subroutine sirius_get_step_function

!
!> @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.
!> @param [out] error_code Error code.
subroutine sirius_set_h_radial_integrals(handler,ia,lmmax,val,l1,o1,ilo1,l2,o2,ilo2,&
&error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, target, intent(in) :: ia
integer, target, intent(in) :: lmmax
real(8), target, intent(in) :: val
integer, optional, target, intent(in) :: l1
integer, optional, target, intent(in) :: o1
integer, optional, target, intent(in) :: ilo1
integer, optional, target, intent(in) :: l2
integer, optional, target, intent(in) :: o2
integer, optional, target, intent(in) :: ilo2
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: ia_ptr
type(C_PTR) :: lmmax_ptr
type(C_PTR) :: val_ptr
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
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_h_radial_integrals_aux(handler,ia,lmmax,val,l1,o1,ilo1,l2,&
&o2,ilo2,error_code)&
&bind(C, name="sirius_set_h_radial_integrals")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: ia
type(C_PTR), value :: lmmax
type(C_PTR), value :: val
type(C_PTR), value :: l1
type(C_PTR), value :: o1
type(C_PTR), value :: ilo1
type(C_PTR), value :: l2
type(C_PTR), value :: o2
type(C_PTR), value :: ilo2
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
ia_ptr = C_NULL_PTR
ia_ptr = C_LOC(ia)
lmmax_ptr = C_NULL_PTR
lmmax_ptr = C_LOC(lmmax)
val_ptr = C_NULL_PTR
val_ptr = C_LOC(val)
l1_ptr = C_NULL_PTR
if (present(l1)) then
l1_ptr = C_LOC(l1)
endif
o1_ptr = C_NULL_PTR
if (present(o1)) then
o1_ptr = C_LOC(o1)
endif
ilo1_ptr = C_NULL_PTR
if (present(ilo1)) then
ilo1_ptr = C_LOC(ilo1)
endif
l2_ptr = C_NULL_PTR
if (present(l2)) then
l2_ptr = C_LOC(l2)
endif
o2_ptr = C_NULL_PTR
if (present(o2)) then
o2_ptr = C_LOC(o2)
endif
ilo2_ptr = C_NULL_PTR
if (present(ilo2)) then
ilo2_ptr = C_LOC(ilo2)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_h_radial_integrals_aux(handler_ptr,ia_ptr,lmmax_ptr,val_ptr,l1_ptr,&
&o1_ptr,ilo1_ptr,l2_ptr,o2_ptr,ilo2_ptr,error_code_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.
!> @param [out] error_code Error code.
subroutine sirius_set_o_radial_integral(handler,ia,val,l,o1,ilo1,o2,ilo2,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, target, intent(in) :: ia
real(8), target, intent(in) :: val
integer, target, intent(in) :: l
integer, optional, target, intent(in) :: o1
integer, optional, target, intent(in) :: ilo1
integer, optional, target, intent(in) :: o2
integer, optional, target, intent(in) :: ilo2
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: ia_ptr
type(C_PTR) :: val_ptr
type(C_PTR) :: l_ptr
type(C_PTR) :: o1_ptr
type(C_PTR) :: ilo1_ptr
type(C_PTR) :: o2_ptr
type(C_PTR) :: ilo2_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_o_radial_integral_aux(handler,ia,val,l,o1,ilo1,o2,ilo2,error_code)&
&bind(C, name="sirius_set_o_radial_integral")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: ia
type(C_PTR), value :: val
type(C_PTR), value :: l
type(C_PTR), value :: o1
type(C_PTR), value :: ilo1
type(C_PTR), value :: o2
type(C_PTR), value :: ilo2
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
ia_ptr = C_NULL_PTR
ia_ptr = C_LOC(ia)
val_ptr = C_NULL_PTR
val_ptr = C_LOC(val)
l_ptr = C_NULL_PTR
l_ptr = C_LOC(l)
o1_ptr = C_NULL_PTR
if (present(o1)) then
o1_ptr = C_LOC(o1)
endif
ilo1_ptr = C_NULL_PTR
if (present(ilo1)) then
ilo1_ptr = C_LOC(ilo1)
endif
o2_ptr = C_NULL_PTR
if (present(o2)) then
o2_ptr = C_LOC(o2)
endif
ilo2_ptr = C_NULL_PTR
if (present(ilo2)) then
ilo2_ptr = C_LOC(ilo2)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_o_radial_integral_aux(handler_ptr,ia_ptr,val_ptr,l_ptr,o1_ptr,ilo1_ptr,&
&o2_ptr,ilo2_ptr,error_code_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.
!> @param [out] error_code Error code.
subroutine sirius_set_o1_radial_integral(handler,ia,val,l1,o1,ilo1,l2,o2,ilo2,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, target, intent(in) :: ia
real(8), target, intent(in) :: val
integer, optional, target, intent(in) :: l1
integer, optional, target, intent(in) :: o1
integer, optional, target, intent(in) :: ilo1
integer, optional, target, intent(in) :: l2
integer, optional, target, intent(in) :: o2
integer, optional, target, intent(in) :: ilo2
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: ia_ptr
type(C_PTR) :: val_ptr
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
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_o1_radial_integral_aux(handler,ia,val,l1,o1,ilo1,l2,o2,ilo2,&
&error_code)&
&bind(C, name="sirius_set_o1_radial_integral")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: ia
type(C_PTR), value :: val
type(C_PTR), value :: l1
type(C_PTR), value :: o1
type(C_PTR), value :: ilo1
type(C_PTR), value :: l2
type(C_PTR), value :: o2
type(C_PTR), value :: ilo2
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
ia_ptr = C_NULL_PTR
ia_ptr = C_LOC(ia)
val_ptr = C_NULL_PTR
val_ptr = C_LOC(val)
l1_ptr = C_NULL_PTR
if (present(l1)) then
l1_ptr = C_LOC(l1)
endif
o1_ptr = C_NULL_PTR
if (present(o1)) then
o1_ptr = C_LOC(o1)
endif
ilo1_ptr = C_NULL_PTR
if (present(ilo1)) then
ilo1_ptr = C_LOC(ilo1)
endif
l2_ptr = C_NULL_PTR
if (present(l2)) then
l2_ptr = C_LOC(l2)
endif
o2_ptr = C_NULL_PTR
if (present(o2)) then
o2_ptr = C_LOC(o2)
endif
ilo2_ptr = C_NULL_PTR
if (present(ilo2)) then
ilo2_ptr = C_LOC(ilo2)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_o1_radial_integral_aux(handler_ptr,ia_ptr,val_ptr,l1_ptr,o1_ptr,&
&ilo1_ptr,l2_ptr,o2_ptr,ilo2_ptr,error_code_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.
!> @param [out] error_code Error code.
subroutine sirius_set_radial_function(handler,ia,deriv_order,f,l,o,ilo,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, target, intent(in) :: ia
integer, target, intent(in) :: deriv_order
real(8), target, intent(in) :: f(:)
integer, optional, target, intent(in) :: l
integer, optional, target, intent(in) :: o
integer, optional, target, intent(in) :: ilo
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: ia_ptr
type(C_PTR) :: deriv_order_ptr
type(C_PTR) :: f_ptr
type(C_PTR) :: l_ptr
type(C_PTR) :: o_ptr
type(C_PTR) :: ilo_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_radial_function_aux(handler,ia,deriv_order,f,l,o,ilo,error_code)&
&bind(C, name="sirius_set_radial_function")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: ia
type(C_PTR), value :: deriv_order
type(C_PTR), value :: f
type(C_PTR), value :: l
type(C_PTR), value :: o
type(C_PTR), value :: ilo
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
ia_ptr = C_NULL_PTR
ia_ptr = C_LOC(ia)
deriv_order_ptr = C_NULL_PTR
deriv_order_ptr = C_LOC(deriv_order)
f_ptr = C_NULL_PTR
f_ptr = C_LOC(f)
l_ptr = C_NULL_PTR
if (present(l)) then
l_ptr = C_LOC(l)
endif
o_ptr = C_NULL_PTR
if (present(o)) then
o_ptr = C_LOC(o)
endif
ilo_ptr = C_NULL_PTR
if (present(ilo)) then
ilo_ptr = C_LOC(ilo)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_radial_function_aux(handler_ptr,ia_ptr,deriv_order_ptr,f_ptr,l_ptr,&
&o_ptr,ilo_ptr,error_code_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.
!> @param [out] error_code Error code.
subroutine sirius_set_equivalent_atoms(handler,equivalent_atoms,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, target, intent(in) :: equivalent_atoms(:)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: equivalent_atoms_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_equivalent_atoms_aux(handler,equivalent_atoms,error_code)&
&bind(C, name="sirius_set_equivalent_atoms")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: equivalent_atoms
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
equivalent_atoms_ptr = C_NULL_PTR
equivalent_atoms_ptr = C_LOC(equivalent_atoms)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_equivalent_atoms_aux(handler_ptr,equivalent_atoms_ptr,error_code_ptr)
end subroutine sirius_set_equivalent_atoms

!
!> @brief Set the new spherical potential.
!> @param [in] gs_handler Ground state handler.
!> @param [out] error_code Error code.
subroutine sirius_update_atomic_potential(gs_handler,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_update_atomic_potential_aux(gs_handler,error_code)&
&bind(C, name="sirius_update_atomic_potential")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_update_atomic_potential_aux(gs_handler_ptr,error_code_ptr)
end subroutine sirius_update_atomic_potential

!
!> @brief Return the total number of sections defined in the input JSON schema.
!> @param [out] length Number of sections.
!> @param [out] error_code Error code.
subroutine sirius_option_get_number_of_sections(length,error_code)
implicit none
!
integer, target, intent(out) :: length
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: length_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_option_get_number_of_sections_aux(length,error_code)&
&bind(C, name="sirius_option_get_number_of_sections")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: length
type(C_PTR), value :: error_code
end subroutine
end interface
!
length_ptr = C_NULL_PTR
length_ptr = C_LOC(length)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_option_get_number_of_sections_aux(length_ptr,error_code_ptr)
end subroutine sirius_option_get_number_of_sections

!
!> @brief Return the name of a given section.
!> @param [in] elem Index of the section (starting from 1).
!> @param [out] section_name Name of the section
!> @param [in] section_name_length Maximum length of the output string. Enough capacity should be provided.
!> @param [out] error_code Error code.
subroutine sirius_option_get_section_name(elem,section_name,section_name_length,&
&error_code)
implicit none
!
integer, value, intent(in) :: elem
character(*), target, intent(out) :: section_name
integer, value, intent(in) :: section_name_length
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: section_name_ptr
character(C_CHAR), target, allocatable :: section_name_c_type(:)
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_option_get_section_name_aux(elem,section_name,section_name_length,&
&error_code)&
&bind(C, name="sirius_option_get_section_name")
use, intrinsic :: ISO_C_BINDING
integer(C_INT), value :: elem
type(C_PTR), value :: section_name
integer(C_INT), value :: section_name_length
type(C_PTR), value :: error_code
end subroutine
end interface
!
section_name_ptr = C_NULL_PTR
allocate(section_name_c_type(len(section_name)+1))
section_name_ptr = C_LOC(section_name_c_type)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_option_get_section_name_aux(elem,section_name_ptr,section_name_length,&
&error_code_ptr)
section_name = string_c2f(section_name_c_type)
deallocate(section_name_c_type)
end subroutine sirius_option_get_section_name

!
!> @brief Return the number of options in a given section.
!> @param [in] section Name of the seciton.
!> @param [out] length Number of options contained in the section.
!> @param [out] error_code Error code.
subroutine sirius_option_get_section_length(section,length,error_code)
implicit none
!
character(*), target, intent(in) :: section
integer, target, intent(out) :: length
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: section_ptr
character(C_CHAR), target, allocatable :: section_c_type(:)
type(C_PTR) :: length_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_option_get_section_length_aux(section,length,error_code)&
&bind(C, name="sirius_option_get_section_length")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: section
type(C_PTR), value :: length
type(C_PTR), value :: error_code
end subroutine
end interface
!
section_ptr = C_NULL_PTR
allocate(section_c_type(len(section)+1))
section_c_type = string_f2c(section)
section_ptr = C_LOC(section_c_type)
length_ptr = C_NULL_PTR
length_ptr = C_LOC(length)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_option_get_section_length_aux(section_ptr,length_ptr,error_code_ptr)
deallocate(section_c_type)
end subroutine sirius_option_get_section_length

!
!> @brief Return information about the option.
!> @param [in] section Name of the section.
!> @param [in] elem Index of the option (starting from 1)
!> @param [out] key_name Name of the option.
!> @param [in] key_name_len Maximum length for the string (on the caller side). No allocation is done.
!> @param [out] type Type of the option (real, integer, boolean, string, or array of the same types).
!> @param [out] length Length of the default value (1 for the scalar types, otherwise the lenght of the array).
!> @param [out] enum_size Number of elements in the enum type, zero otherwise.
!> @param [out] title Short description of the option (can be empty).
!> @param [in] title_len Maximum length for the short description.
!> @param [out] description Detailed description of the option (can be empty).
!> @param [in] description_len Maximum length for the detailed description.
!> @param [out] error_code Error code.
subroutine sirius_option_get_info(section,elem,key_name,key_name_len,type,length,&
&enum_size,title,title_len,description,description_len,error_code)
implicit none
!
character(*), target, intent(in) :: section
integer, value, intent(in) :: elem
character(*), target, intent(out) :: key_name
integer, value, intent(in) :: key_name_len
integer, target, intent(out) :: type
integer, target, intent(out) :: length
integer, target, intent(out) :: enum_size
character(*), target, intent(out) :: title
integer, value, intent(in) :: title_len
character(*), target, intent(out) :: description
integer, value, intent(in) :: description_len
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: section_ptr
character(C_CHAR), target, allocatable :: section_c_type(:)
type(C_PTR) :: key_name_ptr
character(C_CHAR), target, allocatable :: key_name_c_type(:)
type(C_PTR) :: type_ptr
type(C_PTR) :: length_ptr
type(C_PTR) :: enum_size_ptr
type(C_PTR) :: title_ptr
character(C_CHAR), target, allocatable :: title_c_type(:)
type(C_PTR) :: description_ptr
character(C_CHAR), target, allocatable :: description_c_type(:)
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_option_get_info_aux(section,elem,key_name,key_name_len,type,length,&
&enum_size,title,title_len,description,description_len,error_code)&
&bind(C, name="sirius_option_get_info")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: section
integer(C_INT), value :: elem
type(C_PTR), value :: key_name
integer(C_INT), value :: key_name_len
type(C_PTR), value :: type
type(C_PTR), value :: length
type(C_PTR), value :: enum_size
type(C_PTR), value :: title
integer(C_INT), value :: title_len
type(C_PTR), value :: description
integer(C_INT), value :: description_len
type(C_PTR), value :: error_code
end subroutine
end interface
!
section_ptr = C_NULL_PTR
allocate(section_c_type(len(section)+1))
section_c_type = string_f2c(section)
section_ptr = C_LOC(section_c_type)
key_name_ptr = C_NULL_PTR
allocate(key_name_c_type(len(key_name)+1))
key_name_ptr = C_LOC(key_name_c_type)
type_ptr = C_NULL_PTR
type_ptr = C_LOC(type)
length_ptr = C_NULL_PTR
length_ptr = C_LOC(length)
enum_size_ptr = C_NULL_PTR
enum_size_ptr = C_LOC(enum_size)
title_ptr = C_NULL_PTR
allocate(title_c_type(len(title)+1))
title_ptr = C_LOC(title_c_type)
description_ptr = C_NULL_PTR
allocate(description_c_type(len(description)+1))
description_ptr = C_LOC(description_c_type)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_option_get_info_aux(section_ptr,elem,key_name_ptr,key_name_len,type_ptr,&
&length_ptr,enum_size_ptr,title_ptr,title_len,description_ptr,description_len,error_code_ptr)
deallocate(section_c_type)
key_name = string_c2f(key_name_c_type)
deallocate(key_name_c_type)
title = string_c2f(title_c_type)
deallocate(title_c_type)
description = string_c2f(description_c_type)
deallocate(description_c_type)
end subroutine sirius_option_get_info

!
!> @brief Return the default value of the option as defined in the JSON schema.
!> @param [in] section Name of the section of interest.
!> @param [in] name Name of the element
!> @param [in] type Type of the option (real, integer, boolean)
!> @param [in] data_ptr Output buffer for the default value or list of values.
!> @param [in] max_length Maximum length of the buffer containing the default values.
!> @param [in] enum_idx Index of the element in case of the enum type.
!> @param [out] error_code Error code.
subroutine sirius_option_get(section,name,type,data_ptr,max_length,enum_idx,error_code)
implicit none
!
character(*), target, intent(in) :: section
character(*), target, intent(in) :: name
integer, target, intent(in) :: type
type(C_PTR), value, intent(in) :: data_ptr
integer, optional, target, intent(in) :: max_length
integer, optional, target, intent(in) :: enum_idx
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: section_ptr
character(C_CHAR), target, allocatable :: section_c_type(:)
type(C_PTR) :: name_ptr
character(C_CHAR), target, allocatable :: name_c_type(:)
type(C_PTR) :: type_ptr
type(C_PTR) :: max_length_ptr
type(C_PTR) :: enum_idx_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_option_get_aux(section,name,type,data_ptr,max_length,enum_idx,&
&error_code)&
&bind(C, name="sirius_option_get")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: section
type(C_PTR), value :: name
type(C_PTR), value :: type
type(C_PTR), value :: data_ptr
type(C_PTR), value :: max_length
type(C_PTR), value :: enum_idx
type(C_PTR), value :: error_code
end subroutine
end interface
!
section_ptr = C_NULL_PTR
allocate(section_c_type(len(section)+1))
section_c_type = string_f2c(section)
section_ptr = C_LOC(section_c_type)
name_ptr = C_NULL_PTR
allocate(name_c_type(len(name)+1))
name_c_type = string_f2c(name)
name_ptr = C_LOC(name_c_type)
type_ptr = C_NULL_PTR
type_ptr = C_LOC(type)
max_length_ptr = C_NULL_PTR
if (present(max_length)) then
max_length_ptr = C_LOC(max_length)
endif
enum_idx_ptr = C_NULL_PTR
if (present(enum_idx)) then
enum_idx_ptr = C_LOC(enum_idx)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_option_get_aux(section_ptr,name_ptr,type_ptr,data_ptr,max_length_ptr,&
&enum_idx_ptr,error_code_ptr)
deallocate(section_c_type)
deallocate(name_c_type)
end subroutine sirius_option_get

!
!> @brief Set the value of the option name in a (internal) json dictionary
!> @param [in] handler Simulation context handler.
!> @param [in] section string containing the options in json format
!> @param [in] name name of the element to pick
!> @param [in] type Type of the option (real, integer, boolean)
!> @param [in] data_ptr Buffer for the value or list of values.
!> @param [in] max_length Maximum length of the buffer containing the default values.
!> @param [in] append If true then value is appended to the list of values.
!> @param [out] error_code Error code.
subroutine sirius_option_set(handler,section,name,type,data_ptr,max_length,append,&
&error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
character(*), target, intent(in) :: section
character(*), target, intent(in) :: name
integer, target, intent(in) :: type
type(C_PTR), value, intent(in) :: data_ptr
integer, optional, target, intent(in) :: max_length
logical, optional, target, intent(in) :: append
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: section_ptr
character(C_CHAR), target, allocatable :: section_c_type(:)
type(C_PTR) :: name_ptr
character(C_CHAR), target, allocatable :: name_c_type(:)
type(C_PTR) :: type_ptr
type(C_PTR) :: max_length_ptr
type(C_PTR) :: append_ptr
logical(C_BOOL), target :: append_c_type
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_option_set_aux(handler,section,name,type,data_ptr,max_length,append,&
&error_code)&
&bind(C, name="sirius_option_set")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: section
type(C_PTR), value :: name
type(C_PTR), value :: type
type(C_PTR), value :: data_ptr
type(C_PTR), value :: max_length
type(C_PTR), value :: append
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
section_ptr = C_NULL_PTR
allocate(section_c_type(len(section)+1))
section_c_type = string_f2c(section)
section_ptr = C_LOC(section_c_type)
name_ptr = C_NULL_PTR
allocate(name_c_type(len(name)+1))
name_c_type = string_f2c(name)
name_ptr = C_LOC(name_c_type)
type_ptr = C_NULL_PTR
type_ptr = C_LOC(type)
max_length_ptr = C_NULL_PTR
if (present(max_length)) then
max_length_ptr = C_LOC(max_length)
endif
append_ptr = C_NULL_PTR
if (present(append)) then
append_c_type = append
append_ptr = C_LOC(append_c_type)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_option_set_aux(handler_ptr,section_ptr,name_ptr,type_ptr,data_ptr,max_length_ptr,&
&append_ptr,error_code_ptr)
deallocate(section_c_type)
deallocate(name_c_type)
if (present(append)) then
endif
end subroutine sirius_option_set

!
!> @brief Dump the runtime setup in a file.
!> @param [in] handler Simulation context handler.
!> @param [in] filename String containing the name of the file.
!> @param [out] error_code Error code
subroutine sirius_dump_runtime_setup(handler,filename,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
character(*), target, intent(in) :: filename
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: filename_ptr
character(C_CHAR), target, allocatable :: filename_c_type(:)
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_dump_runtime_setup_aux(handler,filename,error_code)&
&bind(C, name="sirius_dump_runtime_setup")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: filename
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
filename_ptr = C_NULL_PTR
allocate(filename_c_type(len(filename)+1))
filename_c_type = string_f2c(filename)
filename_ptr = C_LOC(filename_c_type)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_dump_runtime_setup_aux(handler_ptr,filename_ptr,error_code_ptr)
deallocate(filename_c_type)
end subroutine sirius_dump_runtime_setup

!
!> @brief Get the first-variational eigen vectors
!> @param [in] ks_handler K-point set handler
!> @param [in] ik Global index of the k-point
!> @param [out] fv_evec Output first-variational eigenvector array
!> @param [in] ld Leading dimension of fv_evec
!> @param [in] num_fv_states Number of first-variational states
!> @param [out] error_code Error code
subroutine sirius_get_fv_eigen_vectors(ks_handler,ik,fv_evec,ld,num_fv_states,error_code)
implicit none
!
type(sirius_kpoint_set_handler), target, intent(in) :: ks_handler
integer, target, intent(in) :: ik
complex(8), target, intent(out) :: fv_evec(:,:)
integer, target, intent(in) :: ld
integer, target, intent(in) :: num_fv_states
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: ks_handler_ptr
type(C_PTR) :: ik_ptr
type(C_PTR) :: fv_evec_ptr
type(C_PTR) :: ld_ptr
type(C_PTR) :: num_fv_states_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_fv_eigen_vectors_aux(ks_handler,ik,fv_evec,ld,num_fv_states,&
&error_code)&
&bind(C, name="sirius_get_fv_eigen_vectors")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: ks_handler
type(C_PTR), value :: ik
type(C_PTR), value :: fv_evec
type(C_PTR), value :: ld
type(C_PTR), value :: num_fv_states
type(C_PTR), value :: error_code
end subroutine
end interface
!
ks_handler_ptr = C_NULL_PTR
ks_handler_ptr = C_LOC(ks_handler%handler_ptr_)
ik_ptr = C_NULL_PTR
ik_ptr = C_LOC(ik)
fv_evec_ptr = C_NULL_PTR
fv_evec_ptr = C_LOC(fv_evec)
ld_ptr = C_NULL_PTR
ld_ptr = C_LOC(ld)
num_fv_states_ptr = C_NULL_PTR
num_fv_states_ptr = C_LOC(num_fv_states)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_fv_eigen_vectors_aux(ks_handler_ptr,ik_ptr,fv_evec_ptr,ld_ptr,num_fv_states_ptr,&
&error_code_ptr)
end subroutine sirius_get_fv_eigen_vectors

!
!> @brief Get the first-variational eigen values
!> @param [in] ks_handler K-point set handler
!> @param [in] ik Global index of the k-point
!> @param [out] fv_eval Output first-variational eigenvector array
!> @param [in] num_fv_states Number of first-variational states
!> @param [out] error_code Error code
subroutine sirius_get_fv_eigen_values(ks_handler,ik,fv_eval,num_fv_states,error_code)
implicit none
!
type(sirius_kpoint_set_handler), target, intent(in) :: ks_handler
integer, target, intent(in) :: ik
real(8), target, intent(out) :: fv_eval(:)
integer, target, intent(in) :: num_fv_states
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: ks_handler_ptr
type(C_PTR) :: ik_ptr
type(C_PTR) :: fv_eval_ptr
type(C_PTR) :: num_fv_states_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_fv_eigen_values_aux(ks_handler,ik,fv_eval,num_fv_states,error_code)&
&bind(C, name="sirius_get_fv_eigen_values")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: ks_handler
type(C_PTR), value :: ik
type(C_PTR), value :: fv_eval
type(C_PTR), value :: num_fv_states
type(C_PTR), value :: error_code
end subroutine
end interface
!
ks_handler_ptr = C_NULL_PTR
ks_handler_ptr = C_LOC(ks_handler%handler_ptr_)
ik_ptr = C_NULL_PTR
ik_ptr = C_LOC(ik)
fv_eval_ptr = C_NULL_PTR
fv_eval_ptr = C_LOC(fv_eval)
num_fv_states_ptr = C_NULL_PTR
num_fv_states_ptr = C_LOC(num_fv_states)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_fv_eigen_values_aux(ks_handler_ptr,ik_ptr,fv_eval_ptr,num_fv_states_ptr,&
&error_code_ptr)
end subroutine sirius_get_fv_eigen_values

!
!> @brief Get the second-variational eigen vectors
!> @param [in] ks_handler K-point set handler
!> @param [in] ik Global index of the k-point
!> @param [out] sv_evec Output second-variational eigenvector array
!> @param [in] num_bands Number of second-variational bands.
!> @param [out] error_code Error code
subroutine sirius_get_sv_eigen_vectors(ks_handler,ik,sv_evec,num_bands,error_code)
implicit none
!
type(sirius_kpoint_set_handler), target, intent(in) :: ks_handler
integer, target, intent(in) :: ik
complex(8), target, intent(out) :: sv_evec(:,:)
integer, target, intent(in) :: num_bands
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: ks_handler_ptr
type(C_PTR) :: ik_ptr
type(C_PTR) :: sv_evec_ptr
type(C_PTR) :: num_bands_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_sv_eigen_vectors_aux(ks_handler,ik,sv_evec,num_bands,error_code)&
&bind(C, name="sirius_get_sv_eigen_vectors")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: ks_handler
type(C_PTR), value :: ik
type(C_PTR), value :: sv_evec
type(C_PTR), value :: num_bands
type(C_PTR), value :: error_code
end subroutine
end interface
!
ks_handler_ptr = C_NULL_PTR
ks_handler_ptr = C_LOC(ks_handler%handler_ptr_)
ik_ptr = C_NULL_PTR
ik_ptr = C_LOC(ik)
sv_evec_ptr = C_NULL_PTR
sv_evec_ptr = C_LOC(sv_evec)
num_bands_ptr = C_NULL_PTR
num_bands_ptr = C_LOC(num_bands)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_sv_eigen_vectors_aux(ks_handler_ptr,ik_ptr,sv_evec_ptr,num_bands_ptr,&
&error_code_ptr)
end subroutine sirius_get_sv_eigen_vectors

!
!> @brief Set the values of the function on the regular grid.
!> @param [in] gs_handler DFT ground state handler.
!> @param [in] label Label of the function.
!> @param [in] grid_dims Dimensions of the FFT grid.
!> @param [in] local_box_origin Coordinates of the local box origin for each MPI rank
!> @param [in] local_box_size Dimensions of the local box for each MPI rank.
!> @param [in] fcomm Fortran communicator used to partition FFT grid into local boxes.
!> @param [in] values Values of the function (local buffer for each MPI rank).
!> @param [in] transform_to_pw If true, transform function to PW domain.
!> @param [out] error_code Error code
subroutine sirius_set_rg_values(gs_handler,label,grid_dims,local_box_origin,local_box_size,&
&fcomm,values,transform_to_pw,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
character(*), target, intent(in) :: label
integer, target, intent(in) :: grid_dims(3)
integer, target, intent(in) :: local_box_origin(:,:)
integer, target, intent(in) :: local_box_size(:,:)
integer, target, intent(in) :: fcomm
real(8), target, intent(in) :: values
logical, optional, target, intent(in) :: transform_to_pw
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: grid_dims_ptr
type(C_PTR) :: local_box_origin_ptr
type(C_PTR) :: local_box_size_ptr
type(C_PTR) :: fcomm_ptr
type(C_PTR) :: values_ptr
type(C_PTR) :: transform_to_pw_ptr
logical(C_BOOL), target :: transform_to_pw_c_type
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_rg_values_aux(gs_handler,label,grid_dims,local_box_origin,&
&local_box_size,fcomm,values,transform_to_pw,error_code)&
&bind(C, name="sirius_set_rg_values")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: label
type(C_PTR), value :: grid_dims
type(C_PTR), value :: local_box_origin
type(C_PTR), value :: local_box_size
type(C_PTR), value :: fcomm
type(C_PTR), value :: values
type(C_PTR), value :: transform_to_pw
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
grid_dims_ptr = C_NULL_PTR
grid_dims_ptr = C_LOC(grid_dims)
local_box_origin_ptr = C_NULL_PTR
local_box_origin_ptr = C_LOC(local_box_origin)
local_box_size_ptr = C_NULL_PTR
local_box_size_ptr = C_LOC(local_box_size)
fcomm_ptr = C_NULL_PTR
fcomm_ptr = C_LOC(fcomm)
values_ptr = C_NULL_PTR
values_ptr = C_LOC(values)
transform_to_pw_ptr = C_NULL_PTR
if (present(transform_to_pw)) then
transform_to_pw_c_type = transform_to_pw
transform_to_pw_ptr = C_LOC(transform_to_pw_c_type)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_rg_values_aux(gs_handler_ptr,label_ptr,grid_dims_ptr,local_box_origin_ptr,&
&local_box_size_ptr,fcomm_ptr,values_ptr,transform_to_pw_ptr,error_code_ptr)
deallocate(label_c_type)
if (present(transform_to_pw)) then
endif
end subroutine sirius_set_rg_values

!
!> @brief Get the values of the function on the regular grid.
!> @param [in] gs_handler DFT ground state handler.
!> @param [in] label Label of the function.
!> @param [in] grid_dims Dimensions of the FFT grid.
!> @param [in] local_box_origin Coordinates of the local box origin for each MPI rank
!> @param [in] local_box_size Dimensions of the local box for each MPI rank.
!> @param [in] fcomm Fortran communicator used to partition FFT grid into local boxes.
!> @param [out] values Values of the function (local buffer for each MPI rank).
!> @param [in] transform_to_rg If true, transform function to regular grid before fetching the values.
!> @param [out] error_code Error code
subroutine sirius_get_rg_values(gs_handler,label,grid_dims,local_box_origin,local_box_size,&
&fcomm,values,transform_to_rg,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
character(*), target, intent(in) :: label
integer, target, intent(in) :: grid_dims(3)
integer, target, intent(in) :: local_box_origin(:,:)
integer, target, intent(in) :: local_box_size(:,:)
integer, target, intent(in) :: fcomm
real(8), target, intent(out) :: values
logical, optional, target, intent(in) :: transform_to_rg
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: grid_dims_ptr
type(C_PTR) :: local_box_origin_ptr
type(C_PTR) :: local_box_size_ptr
type(C_PTR) :: fcomm_ptr
type(C_PTR) :: values_ptr
type(C_PTR) :: transform_to_rg_ptr
logical(C_BOOL), target :: transform_to_rg_c_type
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_rg_values_aux(gs_handler,label,grid_dims,local_box_origin,&
&local_box_size,fcomm,values,transform_to_rg,error_code)&
&bind(C, name="sirius_get_rg_values")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: label
type(C_PTR), value :: grid_dims
type(C_PTR), value :: local_box_origin
type(C_PTR), value :: local_box_size
type(C_PTR), value :: fcomm
type(C_PTR), value :: values
type(C_PTR), value :: transform_to_rg
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
grid_dims_ptr = C_NULL_PTR
grid_dims_ptr = C_LOC(grid_dims)
local_box_origin_ptr = C_NULL_PTR
local_box_origin_ptr = C_LOC(local_box_origin)
local_box_size_ptr = C_NULL_PTR
local_box_size_ptr = C_LOC(local_box_size)
fcomm_ptr = C_NULL_PTR
fcomm_ptr = C_LOC(fcomm)
values_ptr = C_NULL_PTR
values_ptr = C_LOC(values)
transform_to_rg_ptr = C_NULL_PTR
if (present(transform_to_rg)) then
transform_to_rg_c_type = transform_to_rg
transform_to_rg_ptr = C_LOC(transform_to_rg_c_type)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_rg_values_aux(gs_handler_ptr,label_ptr,grid_dims_ptr,local_box_origin_ptr,&
&local_box_size_ptr,fcomm_ptr,values_ptr,transform_to_rg_ptr,error_code_ptr)
deallocate(label_c_type)
if (present(transform_to_rg)) then
endif
end subroutine sirius_get_rg_values

!
!> @brief Get the total magnetization of the system.
!> @param [in] gs_handler DFT ground state handler.
!> @param [out] mag 3D magnetization vector (x,y,z components).
!> @param [out] error_code Error code
subroutine sirius_get_total_magnetization(gs_handler,mag,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
real(8), target, intent(out) :: mag
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: mag_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_total_magnetization_aux(gs_handler,mag,error_code)&
&bind(C, name="sirius_get_total_magnetization")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: mag
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
mag_ptr = C_NULL_PTR
mag_ptr = C_LOC(mag)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_total_magnetization_aux(gs_handler_ptr,mag_ptr,error_code_ptr)
end subroutine sirius_get_total_magnetization

!
!> @brief Get the total number of kpoints
!> @param [in] ks_handler Kpoint set handler
!> @param [out] num_kpoints number of kpoints in the set
!> @param [out] error_code Error code.
subroutine sirius_get_num_kpoints(ks_handler,num_kpoints,error_code)
implicit none
!
type(sirius_kpoint_set_handler), target, intent(in) :: ks_handler
integer, target, intent(out) :: num_kpoints
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: ks_handler_ptr
type(C_PTR) :: num_kpoints_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_num_kpoints_aux(ks_handler,num_kpoints,error_code)&
&bind(C, name="sirius_get_num_kpoints")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: ks_handler
type(C_PTR), value :: num_kpoints
type(C_PTR), value :: error_code
end subroutine
end interface
!
ks_handler_ptr = C_NULL_PTR
ks_handler_ptr = C_LOC(ks_handler%handler_ptr_)
num_kpoints_ptr = C_NULL_PTR
num_kpoints_ptr = C_LOC(num_kpoints)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_num_kpoints_aux(ks_handler_ptr,num_kpoints_ptr,error_code_ptr)
end subroutine sirius_get_num_kpoints

!
!> @brief Get the kpoint properties
!> @param [in] ks_handler Kpoint set handler
!> @param [in] ik Index of the kpoint
!> @param [out] weight Weight of the kpoint
!> @param [out] coordinates Coordinates of the kpoint
!> @param [out] error_code Error code.
subroutine sirius_get_kpoint_properties(ks_handler,ik,weight,coordinates,error_code)
implicit none
!
type(sirius_kpoint_set_handler), target, intent(in) :: ks_handler
integer, target, intent(in) :: ik
real(8), target, intent(out) :: weight
real(8), optional, target, intent(out) :: coordinates
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: ks_handler_ptr
type(C_PTR) :: ik_ptr
type(C_PTR) :: weight_ptr
type(C_PTR) :: coordinates_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_kpoint_properties_aux(ks_handler,ik,weight,coordinates,error_code)&
&bind(C, name="sirius_get_kpoint_properties")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: ks_handler
type(C_PTR), value :: ik
type(C_PTR), value :: weight
type(C_PTR), value :: coordinates
type(C_PTR), value :: error_code
end subroutine
end interface
!
ks_handler_ptr = C_NULL_PTR
ks_handler_ptr = C_LOC(ks_handler%handler_ptr_)
ik_ptr = C_NULL_PTR
ik_ptr = C_LOC(ik)
weight_ptr = C_NULL_PTR
weight_ptr = C_LOC(weight)
coordinates_ptr = C_NULL_PTR
if (present(coordinates)) then
coordinates_ptr = C_LOC(coordinates)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_kpoint_properties_aux(ks_handler_ptr,ik_ptr,weight_ptr,coordinates_ptr,&
&error_code_ptr)
end subroutine sirius_get_kpoint_properties

!
!> @brief Set callback function to compute various radial integrals.
!> @param [in] handler Simulation context handler.
!> @param [in] label Lable of the callback function.
!> @param [in] fptr Pointer to callback function.
!> @param [out] error_code Error code.
subroutine sirius_set_callback_function(handler,label,fptr,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
character(*), target, intent(in) :: label
type(C_FUNPTR), value, intent(in) :: fptr
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_callback_function_aux(handler,label,fptr,error_code)&
&bind(C, name="sirius_set_callback_function")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: label
type(C_FUNPTR), value :: fptr
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_callback_function_aux(handler_ptr,label_ptr,fptr,error_code_ptr)
deallocate(label_c_type)
end subroutine sirius_set_callback_function

!
!> @brief Robust wave function optimizer.
!> @param [in] gs_handler Ground state handler.
!> @param [in] ks_handler K-point set handler.
!> @param [out] error_code Error code.
subroutine sirius_nlcg(gs_handler,ks_handler,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
type(sirius_kpoint_set_handler), target, intent(in) :: ks_handler
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: ks_handler_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_nlcg_aux(gs_handler,ks_handler,error_code)&
&bind(C, name="sirius_nlcg")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: ks_handler
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
ks_handler_ptr = C_NULL_PTR
ks_handler_ptr = C_LOC(ks_handler%handler_ptr_)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_nlcg_aux(gs_handler_ptr,ks_handler_ptr,error_code_ptr)
end subroutine sirius_nlcg

!
!> @brief Robust wave function optimizer
!> @param [in] gs_handler Ground state handler.
!> @param [in] ks_handler K-point set handler.
!> @param [in] temp Temperature in Kelvin
!> @param [in] smearing smearing label
!> @param [in] kappa pseudo-Hamiltonian scalar preconditioner
!> @param [in] tau backtracking search reduction parameter
!> @param [in] tol CG tolerance
!> @param [in] maxiter CG maxiter
!> @param [in] restart CG restart
!> @param [in] processing_unit processing_unit = ["cpu"|"gpu"|"none"]
!> @param [out] converged None
!> @param [out] error_code Error code.
subroutine sirius_nlcg_params(gs_handler,ks_handler,temp,smearing,kappa,tau,tol,&
&maxiter,restart,processing_unit,converged,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
type(sirius_kpoint_set_handler), target, intent(in) :: ks_handler
real(8), target, intent(in) :: temp
character(*), target, intent(in) :: smearing
real(8), target, intent(in) :: kappa
real(8), target, intent(in) :: tau
real(8), target, intent(in) :: tol
integer, target, intent(in) :: maxiter
integer, target, intent(in) :: restart
character(*), target, intent(in) :: processing_unit
logical, target, intent(out) :: converged
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: ks_handler_ptr
type(C_PTR) :: temp_ptr
type(C_PTR) :: smearing_ptr
character(C_CHAR), target, allocatable :: smearing_c_type(:)
type(C_PTR) :: kappa_ptr
type(C_PTR) :: tau_ptr
type(C_PTR) :: tol_ptr
type(C_PTR) :: maxiter_ptr
type(C_PTR) :: restart_ptr
type(C_PTR) :: processing_unit_ptr
character(C_CHAR), target, allocatable :: processing_unit_c_type(:)
type(C_PTR) :: converged_ptr
logical(C_BOOL), target :: converged_c_type
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_nlcg_params_aux(gs_handler,ks_handler,temp,smearing,kappa,tau,&
&tol,maxiter,restart,processing_unit,converged,error_code)&
&bind(C, name="sirius_nlcg_params")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: ks_handler
type(C_PTR), value :: temp
type(C_PTR), value :: smearing
type(C_PTR), value :: kappa
type(C_PTR), value :: tau
type(C_PTR), value :: tol
type(C_PTR), value :: maxiter
type(C_PTR), value :: restart
type(C_PTR), value :: processing_unit
type(C_PTR), value :: converged
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
ks_handler_ptr = C_NULL_PTR
ks_handler_ptr = C_LOC(ks_handler%handler_ptr_)
temp_ptr = C_NULL_PTR
temp_ptr = C_LOC(temp)
smearing_ptr = C_NULL_PTR
allocate(smearing_c_type(len(smearing)+1))
smearing_c_type = string_f2c(smearing)
smearing_ptr = C_LOC(smearing_c_type)
kappa_ptr = C_NULL_PTR
kappa_ptr = C_LOC(kappa)
tau_ptr = C_NULL_PTR
tau_ptr = C_LOC(tau)
tol_ptr = C_NULL_PTR
tol_ptr = C_LOC(tol)
maxiter_ptr = C_NULL_PTR
maxiter_ptr = C_LOC(maxiter)
restart_ptr = C_NULL_PTR
restart_ptr = C_LOC(restart)
processing_unit_ptr = C_NULL_PTR
allocate(processing_unit_c_type(len(processing_unit)+1))
processing_unit_c_type = string_f2c(processing_unit)
processing_unit_ptr = C_LOC(processing_unit_c_type)
converged_ptr = C_NULL_PTR
converged_ptr = C_LOC(converged_c_type)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_nlcg_params_aux(gs_handler_ptr,ks_handler_ptr,temp_ptr,smearing_ptr,&
&kappa_ptr,tau_ptr,tol_ptr,maxiter_ptr,restart_ptr,processing_unit_ptr,converged_ptr,&
&error_code_ptr)
deallocate(smearing_c_type)
deallocate(processing_unit_c_type)
converged = converged_c_type
end subroutine sirius_nlcg_params

!
!> @brief Add a non-local Hubbard interaction V for a pair of atoms.
!> @param [in] handler Simulation context handler.
!> @param [in] atom_pair atom pair for the V term
!> @param [in] translation translation vector between the two unit cells containing the atoms
!> @param [in] n principal quantum number of the atomic levels involved in the V correction
!> @param [in] l angular momentum of the atomic levels
!> @param [in] coupling value of the V constant
!> @param [out] error_code Error code.
subroutine sirius_add_hubbard_atom_pair(handler,atom_pair,translation,n,l,coupling,&
&error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, target, intent(in) :: atom_pair(2)
integer, target, intent(in) :: translation(3)
integer, target, intent(in) :: n(2)
integer, target, intent(in) :: l(2)
real(8), target, intent(in) :: coupling
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: atom_pair_ptr
type(C_PTR) :: translation_ptr
type(C_PTR) :: n_ptr
type(C_PTR) :: l_ptr
type(C_PTR) :: coupling_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_add_hubbard_atom_pair_aux(handler,atom_pair,translation,n,l,coupling,&
&error_code)&
&bind(C, name="sirius_add_hubbard_atom_pair")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: atom_pair
type(C_PTR), value :: translation
type(C_PTR), value :: n
type(C_PTR), value :: l
type(C_PTR), value :: coupling
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
atom_pair_ptr = C_NULL_PTR
atom_pair_ptr = C_LOC(atom_pair)
translation_ptr = C_NULL_PTR
translation_ptr = C_LOC(translation)
n_ptr = C_NULL_PTR
n_ptr = C_LOC(n)
l_ptr = C_NULL_PTR
l_ptr = C_LOC(l)
coupling_ptr = C_NULL_PTR
coupling_ptr = C_LOC(coupling)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_add_hubbard_atom_pair_aux(handler_ptr,atom_pair_ptr,translation_ptr,&
&n_ptr,l_ptr,coupling_ptr,error_code_ptr)
end subroutine sirius_add_hubbard_atom_pair

!
!> @brief Set the parameters controlling hubbard constrained calculation
!> @param [in] handler Simulation context handler.
!> @param [in] hubbard_conv_thr convergence threhold when the hubbard occupation is constrained
!> @param [in] hubbard_mixing_beta mixing parameter for the hubbard constraints
!> @param [in] hubbard_strength energy penalty when the effective occupation numbers deviate from the reference numbers
!> @param [in] hubbard_maxstep maximum number of constrained iterations
!> @param [in] hubbard_constraint_type type of constrain, energy or occupation
!> @param [out] error_code Error code.
subroutine sirius_set_hubbard_contrained_parameters(handler,hubbard_conv_thr,hubbard_mixing_beta,&
&hubbard_strength,hubbard_maxstep,hubbard_constraint_type,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
real(8), optional, target, intent(in) :: hubbard_conv_thr
real(8), optional, target, intent(in) :: hubbard_mixing_beta
real(8), optional, target, intent(in) :: hubbard_strength
integer, optional, target, intent(in) :: hubbard_maxstep
character(*), optional, target, intent(in) :: hubbard_constraint_type
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: hubbard_conv_thr_ptr
type(C_PTR) :: hubbard_mixing_beta_ptr
type(C_PTR) :: hubbard_strength_ptr
type(C_PTR) :: hubbard_maxstep_ptr
type(C_PTR) :: hubbard_constraint_type_ptr
character(C_CHAR), target, allocatable :: hubbard_constraint_type_c_type(:)
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_hubbard_contrained_parameters_aux(handler,hubbard_conv_thr,&
&hubbard_mixing_beta,hubbard_strength,hubbard_maxstep,hubbard_constraint_type,error_code)&
&bind(C, name="sirius_set_hubbard_contrained_parameters")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: hubbard_conv_thr
type(C_PTR), value :: hubbard_mixing_beta
type(C_PTR), value :: hubbard_strength
type(C_PTR), value :: hubbard_maxstep
type(C_PTR), value :: hubbard_constraint_type
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
hubbard_conv_thr_ptr = C_NULL_PTR
if (present(hubbard_conv_thr)) then
hubbard_conv_thr_ptr = C_LOC(hubbard_conv_thr)
endif
hubbard_mixing_beta_ptr = C_NULL_PTR
if (present(hubbard_mixing_beta)) then
hubbard_mixing_beta_ptr = C_LOC(hubbard_mixing_beta)
endif
hubbard_strength_ptr = C_NULL_PTR
if (present(hubbard_strength)) then
hubbard_strength_ptr = C_LOC(hubbard_strength)
endif
hubbard_maxstep_ptr = C_NULL_PTR
if (present(hubbard_maxstep)) then
hubbard_maxstep_ptr = C_LOC(hubbard_maxstep)
endif
hubbard_constraint_type_ptr = C_NULL_PTR
if (present(hubbard_constraint_type)) then
allocate(hubbard_constraint_type_c_type(len(hubbard_constraint_type)+1))
hubbard_constraint_type_c_type = string_f2c(hubbard_constraint_type)
hubbard_constraint_type_ptr = C_LOC(hubbard_constraint_type_c_type)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_hubbard_contrained_parameters_aux(handler_ptr,hubbard_conv_thr_ptr,&
&hubbard_mixing_beta_ptr,hubbard_strength_ptr,hubbard_maxstep_ptr,hubbard_constraint_type_ptr,&
&error_code_ptr)
if (present(hubbard_constraint_type)) then
deallocate(hubbard_constraint_type_c_type)
endif
end subroutine sirius_set_hubbard_contrained_parameters

!
!> @brief Information about the constrained atomic level
!> @param [in] handler Simulation context handler.
!> @param [in] atom_id atom iindex
!> @param [in] n principal quantum number of the atomic level for the constrained hubbard correction
!> @param [in] l angular momentum of the atomic level
!> @param [in] lmax_at maximum angular momentum
!> @param [in] occ value of the occupation matrix for this level
!> @param [in] orbital_order order or the Ylm by default it is SIRIUS order for Ylm
!> @param [out] error_code Error code.
subroutine sirius_add_hubbard_atom_constraint(handler,atom_id,n,l,lmax_at,occ,orbital_order,&
&error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, target, intent(in) :: atom_id
integer, target, intent(in) :: n
integer, target, intent(in) :: l
integer, target, intent(in) :: lmax_at
real(8), target, intent(in) :: occ(2 * lmax_at + 1, 2 * lmax_at + 1, 2)
integer, optional, target, intent(in) :: orbital_order(2 * l + 1)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: atom_id_ptr
type(C_PTR) :: n_ptr
type(C_PTR) :: l_ptr
type(C_PTR) :: lmax_at_ptr
type(C_PTR) :: occ_ptr
type(C_PTR) :: orbital_order_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_add_hubbard_atom_constraint_aux(handler,atom_id,n,l,lmax_at,occ,&
&orbital_order,error_code)&
&bind(C, name="sirius_add_hubbard_atom_constraint")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: atom_id
type(C_PTR), value :: n
type(C_PTR), value :: l
type(C_PTR), value :: lmax_at
type(C_PTR), value :: occ
type(C_PTR), value :: orbital_order
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
atom_id_ptr = C_NULL_PTR
atom_id_ptr = C_LOC(atom_id)
n_ptr = C_NULL_PTR
n_ptr = C_LOC(n)
l_ptr = C_NULL_PTR
l_ptr = C_LOC(l)
lmax_at_ptr = C_NULL_PTR
lmax_at_ptr = C_LOC(lmax_at)
occ_ptr = C_NULL_PTR
occ_ptr = C_LOC(occ)
orbital_order_ptr = C_NULL_PTR
if (present(orbital_order)) then
orbital_order_ptr = C_LOC(orbital_order)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_add_hubbard_atom_constraint_aux(handler_ptr,atom_id_ptr,n_ptr,l_ptr,&
&lmax_at_ptr,occ_ptr,orbital_order_ptr,error_code_ptr)
end subroutine sirius_add_hubbard_atom_constraint

!
!> @brief Generate H0.
!> @param [in] gs_handler Ground state handler.
!> @param [out] error_code Error code
subroutine sirius_create_H0(gs_handler,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_create_H0_aux(gs_handler,error_code)&
&bind(C, name="sirius_create_H0")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_create_H0_aux(gs_handler_ptr,error_code_ptr)
end subroutine sirius_create_H0

!
!> @brief Interface to linear solver.
!> @param [in] gs_handler DFT ground state handler.
!> @param [in] vkq K+q-point in lattice coordinates
!> @param [in] num_gvec_kq_loc Local number of G-vectors for k+q-point
!> @param [in] gvec_kq_loc Local list of G-vectors for k+q-point.
!> @param [inout] dpsi Left-hand side of the linear equation.
!> @param [in] psi Unperturbed eigenvectors.
!> @param [in] eigvals Unperturbed eigenvalues.
!> @param [inout] dvpsi Right-hand side of the linear equation (dV * psi)
!> @param [in] ld Leading dimension of dpsi, psi, dvpsi.
!> @param [in] num_spin_comp Number of spin components.
!> @param [in] alpha_pv Constant for the projector.
!> @param [in] spin Current spin channel.
!> @param [in] nbnd_occ_k Number of occupied bands at k.
!> @param [in] nbnd_occ_kq Number of occupied bands at k+q.
!> @param [in] tol Tolerance for the unconverged residuals (residual L2-norm should be below this value).
!> @param [out] niter Average number of iterations.
!> @param [out] error_code Error code
subroutine sirius_linear_solver(gs_handler,vkq,num_gvec_kq_loc,gvec_kq_loc,dpsi,&
&psi,eigvals,dvpsi,ld,num_spin_comp,alpha_pv,spin,nbnd_occ_k,nbnd_occ_kq,tol,niter,&
&error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
real(8), target, intent(in) :: vkq(3)
integer, target, intent(in) :: num_gvec_kq_loc
integer, target, intent(in) :: gvec_kq_loc(3, num_gvec_kq_loc)
complex(8), target, intent(inout) :: dpsi(ld, num_spin_comp)
complex(8), target, intent(in) :: psi(ld, num_spin_comp)
real(8), target, intent(in) :: eigvals(*)
complex(8), target, intent(inout) :: dvpsi(ld, num_spin_comp)
integer, target, intent(in) :: ld
integer, target, intent(in) :: num_spin_comp
real(8), target, intent(in) :: alpha_pv
integer, target, intent(in) :: spin
integer, target, intent(in) :: nbnd_occ_k
integer, target, intent(in) :: nbnd_occ_kq
real(8), optional, target, intent(in) :: tol
integer, optional, target, intent(out) :: niter
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: vkq_ptr
type(C_PTR) :: num_gvec_kq_loc_ptr
type(C_PTR) :: gvec_kq_loc_ptr
type(C_PTR) :: dpsi_ptr
type(C_PTR) :: psi_ptr
type(C_PTR) :: eigvals_ptr
type(C_PTR) :: dvpsi_ptr
type(C_PTR) :: ld_ptr
type(C_PTR) :: num_spin_comp_ptr
type(C_PTR) :: alpha_pv_ptr
type(C_PTR) :: spin_ptr
type(C_PTR) :: nbnd_occ_k_ptr
type(C_PTR) :: nbnd_occ_kq_ptr
type(C_PTR) :: tol_ptr
type(C_PTR) :: niter_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_linear_solver_aux(gs_handler,vkq,num_gvec_kq_loc,gvec_kq_loc,dpsi,&
&psi,eigvals,dvpsi,ld,num_spin_comp,alpha_pv,spin,nbnd_occ_k,nbnd_occ_kq,tol,niter,&
&error_code)&
&bind(C, name="sirius_linear_solver")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: vkq
type(C_PTR), value :: num_gvec_kq_loc
type(C_PTR), value :: gvec_kq_loc
type(C_PTR), value :: dpsi
type(C_PTR), value :: psi
type(C_PTR), value :: eigvals
type(C_PTR), value :: dvpsi
type(C_PTR), value :: ld
type(C_PTR), value :: num_spin_comp
type(C_PTR), value :: alpha_pv
type(C_PTR), value :: spin
type(C_PTR), value :: nbnd_occ_k
type(C_PTR), value :: nbnd_occ_kq
type(C_PTR), value :: tol
type(C_PTR), value :: niter
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
vkq_ptr = C_NULL_PTR
vkq_ptr = C_LOC(vkq)
num_gvec_kq_loc_ptr = C_NULL_PTR
num_gvec_kq_loc_ptr = C_LOC(num_gvec_kq_loc)
gvec_kq_loc_ptr = C_NULL_PTR
gvec_kq_loc_ptr = C_LOC(gvec_kq_loc)
dpsi_ptr = C_NULL_PTR
dpsi_ptr = C_LOC(dpsi)
psi_ptr = C_NULL_PTR
psi_ptr = C_LOC(psi)
eigvals_ptr = C_NULL_PTR
eigvals_ptr = C_LOC(eigvals)
dvpsi_ptr = C_NULL_PTR
dvpsi_ptr = C_LOC(dvpsi)
ld_ptr = C_NULL_PTR
ld_ptr = C_LOC(ld)
num_spin_comp_ptr = C_NULL_PTR
num_spin_comp_ptr = C_LOC(num_spin_comp)
alpha_pv_ptr = C_NULL_PTR
alpha_pv_ptr = C_LOC(alpha_pv)
spin_ptr = C_NULL_PTR
spin_ptr = C_LOC(spin)
nbnd_occ_k_ptr = C_NULL_PTR
nbnd_occ_k_ptr = C_LOC(nbnd_occ_k)
nbnd_occ_kq_ptr = C_NULL_PTR
nbnd_occ_kq_ptr = C_LOC(nbnd_occ_kq)
tol_ptr = C_NULL_PTR
if (present(tol)) then
tol_ptr = C_LOC(tol)
endif
niter_ptr = C_NULL_PTR
if (present(niter)) then
niter_ptr = C_LOC(niter)
endif
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_linear_solver_aux(gs_handler_ptr,vkq_ptr,num_gvec_kq_loc_ptr,gvec_kq_loc_ptr,&
&dpsi_ptr,psi_ptr,eigvals_ptr,dvpsi_ptr,ld_ptr,num_spin_comp_ptr,alpha_pv_ptr,spin_ptr,&
&nbnd_occ_k_ptr,nbnd_occ_kq_ptr,tol_ptr,niter_ptr,error_code_ptr)
end subroutine sirius_linear_solver

!
!> @brief Generate augmentation charge in case of complex density (linear response)
!> @param [in] gs_handler DFT ground state handler.
!> @param [in] iat Index of atom type.
!> @param [in] num_atoms Total number of atoms.
!> @param [in] num_gvec_loc Local number of G-vectors
!> @param [in] num_spin_comp Number of spin components.
!> @param [in] qpw Augmentation operator for a givem atom type.
!> @param [in] ldq Leading dimension of qpw array.
!> @param [in] phase_factors_q Phase factors exp(i*q*r_alpha)
!> @param [in] mill Miller indices (G-vectors in lattice coordinates)
!> @param [in] dens_mtrx Density matrix
!> @param [in] ldd Leading dimension of density matrix.
!> @param [inout] rho_aug Resulting augmentation charge.
!> @param [out] error_code Error code
subroutine sirius_generate_rhoaug_q(gs_handler,iat,num_atoms,num_gvec_loc,num_spin_comp,&
&qpw,ldq,phase_factors_q,mill,dens_mtrx,ldd,rho_aug,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
integer, target, intent(in) :: iat
integer, target, intent(in) :: num_atoms
integer, target, intent(in) :: num_gvec_loc
integer, target, intent(in) :: num_spin_comp
complex(8), target, intent(in) :: qpw(ldq, num_gvec_loc)
integer, target, intent(in) :: ldq
complex(8), target, intent(in) :: phase_factors_q(num_atoms)
integer, target, intent(in) :: mill(3, num_gvec_loc)
complex(8), target, intent(in) :: dens_mtrx(ldd, num_atoms, num_spin_comp)
integer, target, intent(in) :: ldd
complex(8), target, intent(inout) :: rho_aug(num_gvec_loc, num_spin_comp)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: iat_ptr
type(C_PTR) :: num_atoms_ptr
type(C_PTR) :: num_gvec_loc_ptr
type(C_PTR) :: num_spin_comp_ptr
type(C_PTR) :: qpw_ptr
type(C_PTR) :: ldq_ptr
type(C_PTR) :: phase_factors_q_ptr
type(C_PTR) :: mill_ptr
type(C_PTR) :: dens_mtrx_ptr
type(C_PTR) :: ldd_ptr
type(C_PTR) :: rho_aug_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_generate_rhoaug_q_aux(gs_handler,iat,num_atoms,num_gvec_loc,num_spin_comp,&
&qpw,ldq,phase_factors_q,mill,dens_mtrx,ldd,rho_aug,error_code)&
&bind(C, name="sirius_generate_rhoaug_q")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: iat
type(C_PTR), value :: num_atoms
type(C_PTR), value :: num_gvec_loc
type(C_PTR), value :: num_spin_comp
type(C_PTR), value :: qpw
type(C_PTR), value :: ldq
type(C_PTR), value :: phase_factors_q
type(C_PTR), value :: mill
type(C_PTR), value :: dens_mtrx
type(C_PTR), value :: ldd
type(C_PTR), value :: rho_aug
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
iat_ptr = C_NULL_PTR
iat_ptr = C_LOC(iat)
num_atoms_ptr = C_NULL_PTR
num_atoms_ptr = C_LOC(num_atoms)
num_gvec_loc_ptr = C_NULL_PTR
num_gvec_loc_ptr = C_LOC(num_gvec_loc)
num_spin_comp_ptr = C_NULL_PTR
num_spin_comp_ptr = C_LOC(num_spin_comp)
qpw_ptr = C_NULL_PTR
qpw_ptr = C_LOC(qpw)
ldq_ptr = C_NULL_PTR
ldq_ptr = C_LOC(ldq)
phase_factors_q_ptr = C_NULL_PTR
phase_factors_q_ptr = C_LOC(phase_factors_q)
mill_ptr = C_NULL_PTR
mill_ptr = C_LOC(mill)
dens_mtrx_ptr = C_NULL_PTR
dens_mtrx_ptr = C_LOC(dens_mtrx)
ldd_ptr = C_NULL_PTR
ldd_ptr = C_LOC(ldd)
rho_aug_ptr = C_NULL_PTR
rho_aug_ptr = C_LOC(rho_aug)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_generate_rhoaug_q_aux(gs_handler_ptr,iat_ptr,num_atoms_ptr,num_gvec_loc_ptr,&
&num_spin_comp_ptr,qpw_ptr,ldq_ptr,phase_factors_q_ptr,mill_ptr,dens_mtrx_ptr,ldd_ptr,&
&rho_aug_ptr,error_code_ptr)
end subroutine sirius_generate_rhoaug_q

!
!> @brief Generate D-operator matrix.
!> @param [in] gs_handler Ground state handler.
!> @param [out] error_code Error code
subroutine sirius_generate_d_operator_matrix(gs_handler,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_generate_d_operator_matrix_aux(gs_handler,error_code)&
&bind(C, name="sirius_generate_d_operator_matrix")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_generate_d_operator_matrix_aux(gs_handler_ptr,error_code_ptr)
end subroutine sirius_generate_d_operator_matrix

!
!> @brief Save DFT ground state (density and potential)
!> @param [in] gs_handler Ground-state handler.
!> @param [in] file_name Name of the file that stores the saved data.
!> @param [out] error_code Error code
subroutine sirius_save_state(gs_handler,file_name,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
character(*), target, intent(in) :: file_name
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: file_name_ptr
character(C_CHAR), target, allocatable :: file_name_c_type(:)
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_save_state_aux(gs_handler,file_name,error_code)&
&bind(C, name="sirius_save_state")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: file_name
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
file_name_ptr = C_NULL_PTR
allocate(file_name_c_type(len(file_name)+1))
file_name_c_type = string_f2c(file_name)
file_name_ptr = C_LOC(file_name_c_type)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_save_state_aux(gs_handler_ptr,file_name_ptr,error_code_ptr)
deallocate(file_name_c_type)
end subroutine sirius_save_state

!
!> @brief Save DFT ground state (density and potential)
!> @param [in] gs_handler Ground-state handler.
!> @param [in] file_name Name of the file that stores the saved data.
!> @param [out] error_code Error code
subroutine sirius_load_state(gs_handler,file_name,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
character(*), target, intent(in) :: file_name
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: file_name_ptr
character(C_CHAR), target, allocatable :: file_name_c_type(:)
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_load_state_aux(gs_handler,file_name,error_code)&
&bind(C, name="sirius_load_state")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: file_name
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
file_name_ptr = C_NULL_PTR
allocate(file_name_c_type(len(file_name)+1))
file_name_c_type = string_f2c(file_name)
file_name_ptr = C_LOC(file_name_c_type)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_load_state_aux(gs_handler_ptr,file_name_ptr,error_code_ptr)
deallocate(file_name_c_type)
end subroutine sirius_load_state

!
!> @brief Access (get or set) density matrix.
!> @param [in] gs_handler Ground-state handler.
!> @param [in] access_type Access type ("get" or "set").
!> @param [in] ia Index of atom.
!> @param [inout] dm Input density matrix.
!> @param [in] ld Leading dimension of the density matrix.
!> @param [out] error_code Error code.
subroutine sirius_access_density_matrix(gs_handler,access_type,ia,dm,ld,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
character(*), target, intent(in) :: access_type
integer, target, intent(in) :: ia
complex(8), target, intent(inout) :: dm(ld, ld, 3)
integer, target, intent(in) :: ld
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: access_type_ptr
character(C_CHAR), target, allocatable :: access_type_c_type(:)
type(C_PTR) :: ia_ptr
type(C_PTR) :: dm_ptr
type(C_PTR) :: ld_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_access_density_matrix_aux(gs_handler,access_type,ia,dm,ld,error_code)&
&bind(C, name="sirius_access_density_matrix")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: access_type
type(C_PTR), value :: ia
type(C_PTR), value :: dm
type(C_PTR), value :: ld
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
access_type_ptr = C_NULL_PTR
allocate(access_type_c_type(len(access_type)+1))
access_type_c_type = string_f2c(access_type)
access_type_ptr = C_LOC(access_type_c_type)
ia_ptr = C_NULL_PTR
ia_ptr = C_LOC(ia)
dm_ptr = C_NULL_PTR
dm_ptr = C_LOC(dm)
ld_ptr = C_NULL_PTR
ld_ptr = C_LOC(ld)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_access_density_matrix_aux(gs_handler_ptr,access_type_ptr,ia_ptr,dm_ptr,&
&ld_ptr,error_code_ptr)
deallocate(access_type_c_type)
end subroutine sirius_access_density_matrix

!
!> @brief Access (get or set) local occupation matrix of LDA+U+V method.
!> @param [in] handler Ground-state handler.
!> @param [in] access_type Access type ("get" or "set").
!> @param [in] ia Index of atom.
!> @param [in] n Principal quantum number.
!> @param [in] l Orbital quantum number.
!> @param [in] spin Spin index.
!> @param [inout] occ_mtrx Local occupation matrix.
!> @param [in] ld Leading dimension of the occupation matrix.
!> @param [out] error_code Error code.
subroutine sirius_access_local_occupation_matrix(handler,access_type,ia,n,l,spin,&
&occ_mtrx,ld,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: handler
character(*), target, intent(in) :: access_type
integer, target, intent(in) :: ia
integer, target, intent(in) :: n
integer, target, intent(in) :: l
integer, target, intent(in) :: spin
complex(8), target, intent(inout) :: occ_mtrx(ld, ld)
integer, target, intent(in) :: ld
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: access_type_ptr
character(C_CHAR), target, allocatable :: access_type_c_type(:)
type(C_PTR) :: ia_ptr
type(C_PTR) :: n_ptr
type(C_PTR) :: l_ptr
type(C_PTR) :: spin_ptr
type(C_PTR) :: occ_mtrx_ptr
type(C_PTR) :: ld_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_access_local_occupation_matrix_aux(handler,access_type,ia,n,l,&
&spin,occ_mtrx,ld,error_code)&
&bind(C, name="sirius_access_local_occupation_matrix")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: access_type
type(C_PTR), value :: ia
type(C_PTR), value :: n
type(C_PTR), value :: l
type(C_PTR), value :: spin
type(C_PTR), value :: occ_mtrx
type(C_PTR), value :: ld
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
access_type_ptr = C_NULL_PTR
allocate(access_type_c_type(len(access_type)+1))
access_type_c_type = string_f2c(access_type)
access_type_ptr = C_LOC(access_type_c_type)
ia_ptr = C_NULL_PTR
ia_ptr = C_LOC(ia)
n_ptr = C_NULL_PTR
n_ptr = C_LOC(n)
l_ptr = C_NULL_PTR
l_ptr = C_LOC(l)
spin_ptr = C_NULL_PTR
spin_ptr = C_LOC(spin)
occ_mtrx_ptr = C_NULL_PTR
occ_mtrx_ptr = C_LOC(occ_mtrx)
ld_ptr = C_NULL_PTR
ld_ptr = C_LOC(ld)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_access_local_occupation_matrix_aux(handler_ptr,access_type_ptr,ia_ptr,&
&n_ptr,l_ptr,spin_ptr,occ_mtrx_ptr,ld_ptr,error_code_ptr)
deallocate(access_type_c_type)
end subroutine sirius_access_local_occupation_matrix

!
!> @brief Access (get or set) nonlocal part of LDA+U+V occupation matrix.
!> @param [in] handler Ground-state handler.
!> @param [in] access_type Access type ("get" or "set").
!> @param [in] atom_pair Index of two atoms in the non-local V correction.
!> @param [in] n Pair of principal quantum numbers.
!> @param [in] l Pair of orbital quantum numbers.
!> @param [in] spin Spin index.
!> @param [in] T Translation vector that connects two atoms.
!> @param [inout] occ_mtrx Nonlocal occupation matrix.
!> @param [in] ld1 Leading dimension of the occupation matrix.
!> @param [in] ld2 Second dimension of the occupation matrix.
!> @param [out] error_code Error code.
subroutine sirius_access_nonlocal_occupation_matrix(handler,access_type,atom_pair,&
&n,l,spin,T,occ_mtrx,ld1,ld2,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: handler
character(*), target, intent(in) :: access_type
integer, target, intent(in) :: atom_pair(2)
integer, target, intent(in) :: n(2)
integer, target, intent(in) :: l(2)
integer, target, intent(in) :: spin
integer, target, intent(in) :: T(3)
complex(8), target, intent(inout) :: occ_mtrx(ld1, ld2)
integer, target, intent(in) :: ld1
integer, target, intent(in) :: ld2
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: access_type_ptr
character(C_CHAR), target, allocatable :: access_type_c_type(:)
type(C_PTR) :: atom_pair_ptr
type(C_PTR) :: n_ptr
type(C_PTR) :: l_ptr
type(C_PTR) :: spin_ptr
type(C_PTR) :: T_ptr
type(C_PTR) :: occ_mtrx_ptr
type(C_PTR) :: ld1_ptr
type(C_PTR) :: ld2_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_access_nonlocal_occupation_matrix_aux(handler,access_type,atom_pair,&
&n,l,spin,T,occ_mtrx,ld1,ld2,error_code)&
&bind(C, name="sirius_access_nonlocal_occupation_matrix")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: access_type
type(C_PTR), value :: atom_pair
type(C_PTR), value :: n
type(C_PTR), value :: l
type(C_PTR), value :: spin
type(C_PTR), value :: T
type(C_PTR), value :: occ_mtrx
type(C_PTR), value :: ld1
type(C_PTR), value :: ld2
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
access_type_ptr = C_NULL_PTR
allocate(access_type_c_type(len(access_type)+1))
access_type_c_type = string_f2c(access_type)
access_type_ptr = C_LOC(access_type_c_type)
atom_pair_ptr = C_NULL_PTR
atom_pair_ptr = C_LOC(atom_pair)
n_ptr = C_NULL_PTR
n_ptr = C_LOC(n)
l_ptr = C_NULL_PTR
l_ptr = C_LOC(l)
spin_ptr = C_NULL_PTR
spin_ptr = C_LOC(spin)
T_ptr = C_NULL_PTR
T_ptr = C_LOC(T)
occ_mtrx_ptr = C_NULL_PTR
occ_mtrx_ptr = C_LOC(occ_mtrx)
ld1_ptr = C_NULL_PTR
ld1_ptr = C_LOC(ld1)
ld2_ptr = C_NULL_PTR
ld2_ptr = C_LOC(ld2)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_access_nonlocal_occupation_matrix_aux(handler_ptr,access_type_ptr,atom_pair_ptr,&
&n_ptr,l_ptr,spin_ptr,T_ptr,occ_mtrx_ptr,ld1_ptr,ld2_ptr,error_code_ptr)
deallocate(access_type_c_type)
end subroutine sirius_access_nonlocal_occupation_matrix

!
!> @brief major version.
!> @param [out] version version
subroutine sirius_get_major_version(version)
implicit none
!
integer, target, intent(out) :: version
!
type(C_PTR) :: version_ptr
!
interface
subroutine sirius_get_major_version_aux(version)&
&bind(C, name="sirius_get_major_version")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: version
end subroutine
end interface
!
version_ptr = C_NULL_PTR
version_ptr = C_LOC(version)
call sirius_get_major_version_aux(version_ptr)
end subroutine sirius_get_major_version

!
!> @brief minor version.
!> @param [out] version version
subroutine sirius_get_minor_version(version)
implicit none
!
integer, target, intent(out) :: version
!
type(C_PTR) :: version_ptr
!
interface
subroutine sirius_get_minor_version_aux(version)&
&bind(C, name="sirius_get_minor_version")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: version
end subroutine
end interface
!
version_ptr = C_NULL_PTR
version_ptr = C_LOC(version)
call sirius_get_minor_version_aux(version_ptr)
end subroutine sirius_get_minor_version

!
!> @brief minor version.
!> @param [out] version version
subroutine sirius_get_revision(version)
implicit none
!
integer, target, intent(out) :: version
!
type(C_PTR) :: version_ptr
!
interface
subroutine sirius_get_revision_aux(version)&
&bind(C, name="sirius_get_revision")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: version
end subroutine
end interface
!
version_ptr = C_NULL_PTR
version_ptr = C_LOC(version)
call sirius_get_revision_aux(version_ptr)
end subroutine sirius_get_revision

!
!> @brief Checks if the library is initialized.
!> @param [out] status Status of the library (true if initialized).
!> @param [out] error_code Error code.
subroutine sirius_is_initialized(status,error_code)
implicit none
!
logical, target, intent(out) :: status
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: status_ptr
logical(C_BOOL), target :: status_c_type
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_is_initialized_aux(status,error_code)&
&bind(C, name="sirius_is_initialized")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: status
type(C_PTR), value :: error_code
end subroutine
end interface
!
status_ptr = C_NULL_PTR
status_ptr = C_LOC(status_c_type)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_is_initialized_aux(status_ptr,error_code_ptr)
status = status_c_type
end subroutine sirius_is_initialized

!
!> @brief Create context of the simulation, from a JSON file or string.
!> @param [in] fcomm Entire communicator of the simulation.
!> @param [out] handler New empty simulation context.
!> @param [in] fname file name or JSON string.
!> @param [out] error_code Error code.
subroutine sirius_create_context_from_json(fcomm,handler,fname,error_code)
implicit none
!
integer, value, intent(in) :: fcomm
type(sirius_context_handler), target, intent(out) :: handler
character(*), target, intent(in) :: fname
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: fname_ptr
character(C_CHAR), target, allocatable :: fname_c_type(:)
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_create_context_from_json_aux(fcomm,handler,fname,error_code)&
&bind(C, name="sirius_create_context_from_json")
use, intrinsic :: ISO_C_BINDING
integer(C_INT), value :: fcomm
type(C_PTR), value :: handler
type(C_PTR), value :: fname
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
fname_ptr = C_NULL_PTR
allocate(fname_c_type(len(fname)+1))
fname_c_type = string_f2c(fname)
fname_ptr = C_LOC(fname_c_type)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_create_context_from_json_aux(fcomm,handler_ptr,fname_ptr,error_code_ptr)
deallocate(fname_c_type)
end subroutine sirius_create_context_from_json

!
!> @brief Get the number of atoms in the simulation
!> @param [in] gs_handler Ground-state handler.
!> @param [out] num_atoms Number of atoms.
!> @param [out] error_code Error code.
subroutine sirius_get_num_atoms(gs_handler,num_atoms,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
integer, target, intent(out) :: num_atoms
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: num_atoms_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_num_atoms_aux(gs_handler,num_atoms,error_code)&
&bind(C, name="sirius_get_num_atoms")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: num_atoms
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
num_atoms_ptr = C_NULL_PTR
num_atoms_ptr = C_LOC(num_atoms)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_num_atoms_aux(gs_handler_ptr,num_atoms_ptr,error_code_ptr)
end subroutine sirius_get_num_atoms

!
!> @brief Get the k-point parameters from the simulation context.
!> @param [in] handler Simulation context handler.
!> @param [out] k_grid dimensions of the k points grid.
!> @param [out] k_shift k point shifts.
!> @param [out] use_symmetry If .true. k-set will be generated using symmetries.
!> @param [out] error_code Error code.
subroutine sirius_get_kp_params_from_ctx(handler,k_grid,k_shift,use_symmetry,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, target, intent(out) :: k_grid(3)
integer, target, intent(out) :: k_shift(3)
logical, target, intent(out) :: use_symmetry
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: k_grid_ptr
type(C_PTR) :: k_shift_ptr
type(C_PTR) :: use_symmetry_ptr
logical(C_BOOL), target :: use_symmetry_c_type
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_kp_params_from_ctx_aux(handler,k_grid,k_shift,use_symmetry,&
&error_code)&
&bind(C, name="sirius_get_kp_params_from_ctx")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: k_grid
type(C_PTR), value :: k_shift
type(C_PTR), value :: use_symmetry
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
k_grid_ptr = C_NULL_PTR
k_grid_ptr = C_LOC(k_grid)
k_shift_ptr = C_NULL_PTR
k_shift_ptr = C_LOC(k_shift)
use_symmetry_ptr = C_NULL_PTR
use_symmetry_ptr = C_LOC(use_symmetry_c_type)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_kp_params_from_ctx_aux(handler_ptr,k_grid_ptr,k_shift_ptr,use_symmetry_ptr,&
&error_code_ptr)
use_symmetry = use_symmetry_c_type
end subroutine sirius_get_kp_params_from_ctx

!
!> @brief Get the SCF parameters from the simulation context.
!> @param [in] handler Simulation context handler.
!> @param [out] density_tol__ Tolerance on RMS in density.
!> @param [out] energy_tol__ Tolerance in total energy difference.
!> @param [out] iter_solver_tol Initial tolerance of the iterative solver.
!> @param [out] max_niter Maximum number of SCF iterations.
!> @param [out] error_code Error code.
subroutine sirius_get_scf_params_from_ctx(handler,density_tol__,energy_tol__,iter_solver_tol,&
&max_niter,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
real(8), target, intent(out) :: density_tol__
real(8), target, intent(out) :: energy_tol__
real(8), target, intent(out) :: iter_solver_tol
integer, target, intent(out) :: max_niter
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: density_tol___ptr
type(C_PTR) :: energy_tol___ptr
type(C_PTR) :: iter_solver_tol_ptr
type(C_PTR) :: max_niter_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_scf_params_from_ctx_aux(handler,density_tol__,energy_tol__,&
&iter_solver_tol,max_niter,error_code)&
&bind(C, name="sirius_get_scf_params_from_ctx")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: density_tol__
type(C_PTR), value :: energy_tol__
type(C_PTR), value :: iter_solver_tol
type(C_PTR), value :: max_niter
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
density_tol___ptr = C_NULL_PTR
density_tol___ptr = C_LOC(density_tol__)
energy_tol___ptr = C_NULL_PTR
energy_tol___ptr = C_LOC(energy_tol__)
iter_solver_tol_ptr = C_NULL_PTR
iter_solver_tol_ptr = C_LOC(iter_solver_tol)
max_niter_ptr = C_NULL_PTR
max_niter_ptr = C_LOC(max_niter)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_scf_params_from_ctx_aux(handler_ptr,density_tol___ptr,energy_tol___ptr,&
&iter_solver_tol_ptr,max_niter_ptr,error_code_ptr)
end subroutine sirius_get_scf_params_from_ctx

!
!> @brief Create an Hamiltonian based on the density stored in the gs_handler.
!> @param [in] gs_handler Ground-state context handler.
!> @param [out] H0_handler The new handler for the Hamiltonian
!> @param [out] error_code Error code.
subroutine sirius_create_hamiltonian(gs_handler,H0_handler,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
type(sirius_H0_handler), target, intent(out) :: H0_handler
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: H0_handler_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_create_hamiltonian_aux(gs_handler,H0_handler,error_code)&
&bind(C, name="sirius_create_hamiltonian")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: H0_handler
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
H0_handler_ptr = C_NULL_PTR
H0_handler_ptr = C_LOC(H0_handler)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_create_hamiltonian_aux(gs_handler_ptr,H0_handler_ptr,error_code_ptr)
end subroutine sirius_create_hamiltonian

!
!> @brief Diagonalizes the Hamiltonian.
!> @param [in] handler Simulation context handler.
!> @param [in] gs_handler Ground-state context handler.
!> @param [in] H0_handler Hamiltonian contexct handler.
!> @param [in] iter_solver_tol Tolerance for the iterative solver.
!> @param [in] max_steps Maximum number of steps for the iterative solver.
!> @param [in] converge_by_energy Whether the solver should determine convergence by checking the energy different (1), or the L2 norm of the residual (0). Default is value is 1.
!> @param [in] exact_diagonalization Whether an exact diagonalization should take place (rather than iterative Davidson)
!> @param [out] converged Whether the iterative solver converged
!> @param [out] niter Number of steps for the solver to converge
!> @param [out] error_code Error code.
subroutine sirius_diagonalize_hamiltonian(handler,gs_handler,H0_handler,iter_solver_tol,&
&max_steps,converge_by_energy,exact_diagonalization,converged,niter,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
type(sirius_H0_handler), target, intent(in) :: H0_handler
real(8), target, intent(in) :: iter_solver_tol
integer, target, intent(in) :: max_steps
integer, optional, target, intent(in) :: converge_by_energy
logical, optional, target, intent(in) :: exact_diagonalization
logical, target, intent(out) :: converged
integer, target, intent(out) :: niter
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: H0_handler_ptr
type(C_PTR) :: iter_solver_tol_ptr
type(C_PTR) :: max_steps_ptr
type(C_PTR) :: converge_by_energy_ptr
type(C_PTR) :: exact_diagonalization_ptr
logical(C_BOOL), target :: exact_diagonalization_c_type
type(C_PTR) :: converged_ptr
logical(C_BOOL), target :: converged_c_type
type(C_PTR) :: niter_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_diagonalize_hamiltonian_aux(handler,gs_handler,H0_handler,iter_solver_tol,&
&max_steps,converge_by_energy,exact_diagonalization,converged,niter,error_code)&
&bind(C, name="sirius_diagonalize_hamiltonian")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: gs_handler
type(C_PTR), value :: H0_handler
type(C_PTR), value :: iter_solver_tol
type(C_PTR), value :: max_steps
type(C_PTR), value :: converge_by_energy
type(C_PTR), value :: exact_diagonalization
type(C_PTR), value :: converged
type(C_PTR), value :: niter
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
H0_handler_ptr = C_NULL_PTR
H0_handler_ptr = C_LOC(H0_handler)
iter_solver_tol_ptr = C_NULL_PTR
iter_solver_tol_ptr = C_LOC(iter_solver_tol)
max_steps_ptr = C_NULL_PTR
max_steps_ptr = C_LOC(max_steps)
converge_by_energy_ptr = C_NULL_PTR
if (present(converge_by_energy)) then
converge_by_energy_ptr = C_LOC(converge_by_energy)
endif
exact_diagonalization_ptr = C_NULL_PTR
if (present(exact_diagonalization)) then
exact_diagonalization_c_type = exact_diagonalization
exact_diagonalization_ptr = C_LOC(exact_diagonalization_c_type)
endif
converged_ptr = C_NULL_PTR
converged_ptr = C_LOC(converged_c_type)
niter_ptr = C_NULL_PTR
niter_ptr = C_LOC(niter)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_diagonalize_hamiltonian_aux(handler_ptr,gs_handler_ptr,H0_handler_ptr,&
&iter_solver_tol_ptr,max_steps_ptr,converge_by_energy_ptr,exact_diagonalization_ptr,&
&converged_ptr,niter_ptr,error_code_ptr)
if (present(exact_diagonalization)) then
endif
converged = converged_c_type
end subroutine sirius_diagonalize_hamiltonian

!
!> @brief Internally calculate the band occupancies.
!> @param [in] ks_handler Handler for the k-point set.
!> @param [out] error_code Error code.
subroutine sirius_find_band_occupancies(ks_handler,error_code)
implicit none
!
type(sirius_kpoint_set_handler), target, intent(in) :: ks_handler
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: ks_handler_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_find_band_occupancies_aux(ks_handler,error_code)&
&bind(C, name="sirius_find_band_occupancies")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: ks_handler
type(C_PTR), value :: error_code
end subroutine
end interface
!
ks_handler_ptr = C_NULL_PTR
ks_handler_ptr = C_LOC(ks_handler%handler_ptr_)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_find_band_occupancies_aux(ks_handler_ptr,error_code_ptr)
end subroutine sirius_find_band_occupancies

!
!> @brief Sets the number of bands in the simulation context.
!> @param [in] handler Simulation context handler.
!> @param [in] num_bands Number of bands to set.
!> @param [out] error_code Error code.
subroutine sirius_set_num_bands(handler,num_bands,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, target, intent(in) :: num_bands
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: num_bands_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_num_bands_aux(handler,num_bands,error_code)&
&bind(C, name="sirius_set_num_bands")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: num_bands
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
num_bands_ptr = C_NULL_PTR
num_bands_ptr = C_LOC(num_bands)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_num_bands_aux(handler_ptr,num_bands_ptr,error_code_ptr)
end subroutine sirius_set_num_bands

!
!> @brief Triggers an internal FFT transform of the given field, in the given direction
!> @param [in] gs_handler Ground-state handler.
!> @param [in] label Which field to FFT transform.
!> @param [in] direction FFT transform direction (1 forward, -1, backward)
!> @param [out] error_code Error code.
subroutine sirius_fft_transform(gs_handler,label,direction,error_code)
implicit none
!
type(sirius_ground_state_handler), target, intent(in) :: gs_handler
character(*), target, intent(in) :: label
integer, target, intent(in) :: direction
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: gs_handler_ptr
type(C_PTR) :: label_ptr
character(C_CHAR), target, allocatable :: label_c_type(:)
type(C_PTR) :: direction_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_fft_transform_aux(gs_handler,label,direction,error_code)&
&bind(C, name="sirius_fft_transform")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: gs_handler
type(C_PTR), value :: label
type(C_PTR), value :: direction
type(C_PTR), value :: error_code
end subroutine
end interface
!
gs_handler_ptr = C_NULL_PTR
gs_handler_ptr = C_LOC(gs_handler%handler_ptr_)
label_ptr = C_NULL_PTR
allocate(label_c_type(len(label)+1))
label_c_type = string_f2c(label)
label_ptr = C_LOC(label_c_type)
direction_ptr = C_NULL_PTR
direction_ptr = C_LOC(direction)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_fft_transform_aux(gs_handler_ptr,label_ptr,direction_ptr,error_code_ptr)
deallocate(label_c_type)
end subroutine sirius_fft_transform

!
!> @brief Gets the wave function for a given k-point and spin (all local, no MPI communication).
!> @param [in] ks_handler Handler for the k-point set.
!> @param [in] ik Index of the k-point.
!> @param [in] ispin Index of the spin.
!> @param [in] psi Pointer to the wave function coefficients.
!> @param [out] error_code Error code.
subroutine sirius_get_psi(ks_handler,ik,ispin,psi,error_code)
implicit none
!
type(sirius_kpoint_set_handler), target, intent(in) :: ks_handler
integer, target, intent(in) :: ik
integer, target, intent(in) :: ispin
complex(8), target, intent(in) :: psi(:)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: ks_handler_ptr
type(C_PTR) :: ik_ptr
type(C_PTR) :: ispin_ptr
type(C_PTR) :: psi_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_psi_aux(ks_handler,ik,ispin,psi,error_code)&
&bind(C, name="sirius_get_psi")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: ks_handler
type(C_PTR), value :: ik
type(C_PTR), value :: ispin
type(C_PTR), value :: psi
type(C_PTR), value :: error_code
end subroutine
end interface
!
ks_handler_ptr = C_NULL_PTR
ks_handler_ptr = C_LOC(ks_handler%handler_ptr_)
ik_ptr = C_NULL_PTR
ik_ptr = C_LOC(ik)
ispin_ptr = C_NULL_PTR
ispin_ptr = C_LOC(ispin)
psi_ptr = C_NULL_PTR
psi_ptr = C_LOC(psi)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_psi_aux(ks_handler_ptr,ik_ptr,ispin_ptr,psi_ptr,error_code_ptr)
end subroutine sirius_get_psi

!
!> @brief Gets the G+k integer coordinates for a given k-point.
!> @param [in] ks_handler Handler for the k-point set.
!> @param [in] ik Index of the k-point.
!> @param [in] gvec Pointer to the G+k vector coordinates.
!> @param [out] error_code Error code.
subroutine sirius_get_gkvec(ks_handler,ik,gvec,error_code)
implicit none
!
type(sirius_kpoint_set_handler), target, intent(in) :: ks_handler
integer, target, intent(in) :: ik
real(8), target, intent(in) :: gvec(:)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: ks_handler_ptr
type(C_PTR) :: ik_ptr
type(C_PTR) :: gvec_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_get_gkvec_aux(ks_handler,ik,gvec,error_code)&
&bind(C, name="sirius_get_gkvec")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: ks_handler
type(C_PTR), value :: ik
type(C_PTR), value :: gvec
type(C_PTR), value :: error_code
end subroutine
end interface
!
ks_handler_ptr = C_NULL_PTR
ks_handler_ptr = C_LOC(ks_handler%handler_ptr_)
ik_ptr = C_NULL_PTR
ik_ptr = C_LOC(ik)
gvec_ptr = C_NULL_PTR
gvec_ptr = C_LOC(gvec)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_get_gkvec_aux(ks_handler_ptr,ik_ptr,gvec_ptr,error_code_ptr)
end subroutine sirius_get_gkvec

!
!> @brief Sets the SIRIUS Fermi energy.
!> @param [in] ks_handler Handler for the k-point set.
!> @param [in] energy_fermi Fermi energy to be set.
!> @param [out] error_code Error code.
subroutine sirius_set_energy_fermi(ks_handler,energy_fermi,error_code)
implicit none
!
type(sirius_kpoint_set_handler), target, intent(in) :: ks_handler
real(8), target, intent(in) :: energy_fermi
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: ks_handler_ptr
type(C_PTR) :: energy_fermi_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_energy_fermi_aux(ks_handler,energy_fermi,error_code)&
&bind(C, name="sirius_set_energy_fermi")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: ks_handler
type(C_PTR), value :: energy_fermi
type(C_PTR), value :: error_code
end subroutine
end interface
!
ks_handler_ptr = C_NULL_PTR
ks_handler_ptr = C_LOC(ks_handler%handler_ptr_)
energy_fermi_ptr = C_NULL_PTR
energy_fermi_ptr = C_LOC(energy_fermi)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_energy_fermi_aux(ks_handler_ptr,energy_fermi_ptr,error_code_ptr)
end subroutine sirius_set_energy_fermi

!
!> @brief Set new atomic vector field (aka initial magnetization).
!> @param [in] handler Simulation context handler.
!> @param [in] ia Index of atom; index starts form 1
!> @param [in] vector_field Atom vector field.
!> @param [out] error_code Error code.
subroutine sirius_set_atom_vector_field(handler,ia,vector_field,error_code)
implicit none
!
type(sirius_context_handler), target, intent(in) :: handler
integer, target, intent(in) :: ia
real(8), target, intent(in) :: vector_field(3)
integer, optional, target, intent(out) :: error_code
!
type(C_PTR) :: handler_ptr
type(C_PTR) :: ia_ptr
type(C_PTR) :: vector_field_ptr
type(C_PTR) :: error_code_ptr
!
interface
subroutine sirius_set_atom_vector_field_aux(handler,ia,vector_field,error_code)&
&bind(C, name="sirius_set_atom_vector_field")
use, intrinsic :: ISO_C_BINDING
type(C_PTR), value :: handler
type(C_PTR), value :: ia
type(C_PTR), value :: vector_field
type(C_PTR), value :: error_code
end subroutine
end interface
!
handler_ptr = C_NULL_PTR
handler_ptr = C_LOC(handler%handler_ptr_)
ia_ptr = C_NULL_PTR
ia_ptr = C_LOC(ia)
vector_field_ptr = C_NULL_PTR
vector_field_ptr = C_LOC(vector_field)
error_code_ptr = C_NULL_PTR
if (present(error_code)) then
error_code_ptr = C_LOC(error_code)
endif
call sirius_set_atom_vector_field_aux(handler_ptr,ia_ptr,vector_field_ptr,error_code_ptr)
end subroutine sirius_set_atom_vector_field


subroutine sirius_free_handler_ctx(handler, error_code)
    implicit none
    type(sirius_context_handler), intent(inout) :: handler
    integer, optional, target, intent(out) :: error_code
    call sirius_free_object_handler(handler%handler_ptr_, error_code)
end subroutine sirius_free_handler_ctx

subroutine sirius_free_handler_ks(handler, error_code)
    implicit none
    type(sirius_kpoint_set_handler), intent(inout) :: handler
    integer, optional, target, intent(out) :: error_code
    call sirius_free_object_handler(handler%handler_ptr_, error_code)
end subroutine sirius_free_handler_ks

subroutine sirius_free_handler_dft(handler, error_code)
    implicit none
    type(sirius_ground_state_handler), intent(inout) :: handler
    integer, optional, target, intent(out) :: error_code
    call sirius_free_object_handler(handler%handler_ptr_, error_code)
end subroutine sirius_free_handler_dft

subroutine sirius_free_handler_H0(handler, error_code)
    implicit none
    type(sirius_H0_handler), intent(inout) :: handler
    integer, optional, target, intent(out) :: error_code
    call sirius_free_object_handler(handler%handler_ptr_, error_code)
end subroutine sirius_free_handler_H0

end module
