!--------------------------------------------------------------------------------------------------! ! CP2K: A general program to perform molecular dynamics simulations ! ! Copyright (C) 2000 - 2019 CP2K developers group ! !--------------------------------------------------------------------------------------------------! ! ************************************************************************************************** !> \brief Defines CDFT control structures !> \par History !> separated from cp_control_types [03.2017] !> \author Nico Holmberg [03.2017] ! ************************************************************************************************** MODULE qs_cdft_types USE cp_array_utils, ONLY: cp_1d_r_p_type USE cp_fm_types, ONLY: cp_fm_p_type USE dbcsr_api, ONLY: dbcsr_p_type USE hirshfeld_types, ONLY: hirshfeld_type,& release_hirshfeld_type USE input_constants, ONLY: becke_cutoff_global,& outer_scf_none,& radius_single,& shape_function_gaussian USE kinds, ONLY: default_path_length,& dp USE outer_scf_control_types, ONLY: outer_scf_control_type,& qs_outer_scf_type USE pw_types, ONLY: pw_p_type USE qs_cdft_opt_types, ONLY: cdft_opt_type_release #include "./base/base_uses.f90" IMPLICIT NONE PRIVATE ! ************************************************************************************************** !> \brief some parameters useful for becke_constraints !> \param aij pairwise parameters used to adjust the Becke cell boundaries built from atomic radii !> \param adjust logical which determines if the Becke potential is adjusted with atomic radii !> \param cavity the Gaussian confinement cavity: the constraint is nonzero outside this cavity !> \param cavity_confine logical which determines if cavity confinement is active !> \param cavity_mat a compacted version of cavity !> \param cavity_shape the confinement cavity shape id !> \param cavity_env the structure used to build the Gaussian cavity !> \param confine_bounds grid point indices outside which the constraint vanishes along Z-axis !> \param cutoff_type the cutoff type to use for building the constraint !> \param cutoffs element specific cutoffs !> \param cutoffs_tmp same as cutoffs but a temporary read during parsing of this type !> \param eps_cavity threshold used screen small values of the Gaussian cavity density !> \param in_memory logical which determines if the gradients of the Becke potential should be !> \param print_cavity logical to print the Gaussian confinement cavity !> \param radii permanent copy of radii_tmp !> \param radii_tmp temporary list of element specific atomic radii used to adjust the Becke cells !> \param rcavity an optional global radius parameter used to define the Gaussian confinement cavity !> \param rglobal global cutoff to use for building the constraint !> computed simultaneously with the potential instead of separately !> \param should_skip logical which determines is grid points should be skipped if all constraint !> atoms are found to reside beyond the cutoff distance from it !> \param use_bohr decides whether to use angstrom or bohr units for the confinement cavity radius ! ************************************************************************************************** ! Utility vector container for building becke constraint TYPE becke_vector_buffer LOGICAL :: store_vectors REAL(kind=dp), ALLOCATABLE, & DIMENSION(:) :: distances REAL(kind=dp), ALLOCATABLE, & DIMENSION(:, :) :: distance_vecs, & position_vecs, & R12 REAL(kind=dp), ALLOCATABLE, & DIMENSION(:, :, :) :: pair_dist_vecs END TYPE becke_vector_buffer TYPE becke_constraint_type INTEGER :: cavity_shape, cutoff_type, & confine_bounds(2) LOGICAL :: in_memory, & adjust, cavity_confine, & should_skip, print_cavity, & use_bohr REAL(KIND=dp) :: rglobal, & rcavity, eps_cavity REAL(KIND=dp), DIMENSION(:), POINTER :: cutoffs, cutoffs_tmp, & radii_tmp, radii REAL(KIND=dp), POINTER, & DIMENSION(:, :) :: aij REAL(KIND=dp), POINTER, & DIMENSION(:, :, :) :: cavity_mat TYPE(becke_vector_buffer) :: vector_buffer TYPE(hirshfeld_type), POINTER :: cavity_env TYPE(pw_p_type) :: cavity END TYPE becke_constraint_type ! ************************************************************************************************** ! \brief control parameters for Hirshfeld constraints !> \param gaussian_shape the type of Gaussian to use (shape_function Gaussian) !> \param radii list of Gaussian radii for different atomic kinds !> \param radius Gaussian radius parameter !> \param shape_function the constraint type: atomic density or single Gaussian !> \param use_bohr determines whether to use angstrom or bohr units for the radii of Gaussians !> \param hirshfeld_env auxiliary type storing information about the Gaussians ! ************************************************************************************************** TYPE hirshfeld_constraint_type INTEGER :: gaussian_shape, shape_function LOGICAL :: use_bohr REAL(KIND=dp) :: radius REAL(KIND=dp), DIMENSION(:), POINTER :: radii TYPE(hirshfeld_type), POINTER :: hirshfeld_env END TYPE hirshfeld_constraint_type ! ************************************************************************************************** !> \brief control parameters for CDFT simulations !> \param fragment_a_fname filename of cube file holding the total electron density !> of isolated fragment a !> \param fragment_b_fname filename of cube file holding the total electron density !> of isolated fragment b !> \param fragment_a_spin_fname filename of cube file holding the spin difference density !> of isolated fragment a !> \param fragment_b_spin_fname filename of cube file holding the spin difference density !> of isolated fragment b !> \param ref_count the ref count !> \param need_pot logical which determines if the Becke potential needs to be built !> \param save_pot logical which determines if the Becke potential should be saved until forces !> have been evaluated !> \param atomic_charges flag that determines if atomic CDFT charges should be computed !> \param total_steps counter to keep track of the total number of SCF steps !> \param type the type of CDFT constraint to use !> \param precond_freq preconditioner can be used if SCF converged in less than precond_freq steps !> \param nreused determines how many times the current OT preconditioner has been reused !> \param max_reuse the same preconditioner can be used a maximum of max_reuse times !> \param purge_freq determines how large nbad_conv can grow before purging the wfn/constraint history !> \param nbad_conv a running counter keeping track of the number of CDFT SCF loops when the first !> CDFT SCF iteration required more than 1 outer SCF loop. Reset when convergence is !> smooth !> \param purge_offset purging is only allowed when more than purge_offset steps have passed since !> last purge !> \param istep a counter to keep track of how many steps have passed since the last purge !> \param ienergy a counter tracking the total number of CDFT energy evaluations !> \param natoms the total number of atoms included in constraint/dummy atom groups !> \param atoms list of constraint atoms !> \param need_pot logical which determines if the constraint potential needs to be built !> \param save_pot logical which determines if the constraint potential should be saved until forces !> have been evaluated !> \param do_et logical which determines if a ET coupling calculation was requested !> \param reuse_precond logical which determines if a preconditioner can be reused !> \param purge_history logical which determines if the wfn/constraint history can be purged !> \param should_purge logical which determines if purging should take place after this CDFT SCF loop !> \param calculate_metric logical which determines if the ET coupling reliablity metric is computed !> \param fragment_density use isolated fragment densities as a reference for the constraint !> \param fragments_integrated logical to determine if the fragment densities have been integrated !> \param flip_fragment should the spin difference density of the either fragment be flipped !> \param transfer_pot logical which determines if constraint should be saved for reuse later !> \param external_control logical which determines if the constraint has already been built !> in a mixed_env that holds multiple CDFT states !> \param first_iteration a flag to mark the first iteration for printing of additional data !> \param print_weight logical which determines if CDFT weight functions should be saved to a file !> \param is_constraint list of logicals which determines if an atom is included in a constraint group !> \param strength Lagrangian multipliers of the constraints !> \param target target values of the constraints !> \param value integrated values of the constraints !> \param charges_fragment atomic partial charges computed from the isolated fragment densities !> \param becke_control control parameters for Becke constraints !> \param group container for atom groups each defining their own constraint !> \param occupations occupation numbers in case non-uniform MO occupation (for do_et) !> \param mo_coeff save the MO coeffs (for do_et) !> \param matrix_s save the overlap matrix (for do_et) !> \param wmat matrix representation of the weight function (for do_et) !> \param matrix_p save the density matrix (for calculate_metric) !> \param hirshfeld_control control parameters for Hirshfeld constraints !> \param constraint_control the outer_scf_control_type for the CDFT constraints !> \param ot_control the outer_scf_control_type for OT where data is stashed when outside the OT !> outer loop !> \param charge atomic CDFT real space potentials needed to calculate CDFT charges !> \param fragments container for isolated fragment densities read from cube files !> \param constraint holds information about the CDFT SCF loop ! ************************************************************************************************** ! To build multiple constraints TYPE cdft_group_type ! Atoms of this constraint group INTEGER, POINTER, DIMENSION(:) :: atoms ! Constraint type: charge constraint, magnetization density constraint, or spin channel specific constraint INTEGER :: constraint_type ! Is the constraint fragment based LOGICAL :: is_fragment_constraint ! Temporary array holding a component of the weight function gradient that only includes ! terms defined on constraint atoms REAL(kind=dp), ALLOCATABLE, & DIMENSION(:, :) :: d_sum_const_dR ! Coefficients that determine how to sum up the atoms to form the constraint REAL(KIND=dp), POINTER, DIMENSION(:) :: coeff ! Result of integration dw/dR * rho_r dr where dw/dR is the weight function gradient REAL(KIND=dp), POINTER, & DIMENSION(:, :) :: integrated ! Atomic gradients of the weight function at every grid point REAL(KIND=dp), POINTER, & DIMENSION(:, :, :, :) :: gradients ! The weight function of this constraint group TYPE(pw_p_type) :: weight END TYPE cdft_group_type TYPE cdft_control_type CHARACTER(LEN=default_path_length) :: fragment_a_fname, & fragment_b_fname, & fragment_a_spin_fname, & fragment_b_spin_fname INTEGER :: ref_count, total_steps, TYPE, & precond_freq, nreused, max_reuse, & purge_freq, nbad_conv, purge_offset, & istep, ienergy, natoms INTEGER, POINTER, DIMENSION(:) :: atoms LOGICAL :: need_pot, save_pot, do_et, & reuse_precond, purge_history, & should_purge, calculate_metric, & atomic_charges, fragment_density, & fragments_integrated, flip_fragment(2), & transfer_pot, external_control, & first_iteration, print_weight LOGICAL, POINTER, DIMENSION(:) :: is_constraint REAL(KIND=dp), DIMENSION(:), POINTER :: strength, TARGET, value REAL(KIND=dp), POINTER, & DIMENSION(:, :) :: charges_fragment TYPE(becke_constraint_type), POINTER :: becke_control TYPE(cdft_group_type), POINTER, & DIMENSION(:) :: group TYPE(cp_1d_r_p_type), ALLOCATABLE, & DIMENSION(:) :: occupations TYPE(cp_fm_p_type), DIMENSION(:), & POINTER :: mo_coeff TYPE(dbcsr_p_type) :: matrix_s TYPE(dbcsr_p_type), DIMENSION(:), & POINTER :: wmat, matrix_p TYPE(hirshfeld_constraint_type), & POINTER :: hirshfeld_control TYPE(outer_scf_control_type) :: constraint_control, ot_control TYPE(pw_p_type), POINTER, & DIMENSION(:) :: charge TYPE(pw_p_type), POINTER, & DIMENSION(:, :) :: fragments TYPE(qs_outer_scf_type) :: constraint END TYPE cdft_control_type CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_cdft_types' ! Public data types PUBLIC :: becke_constraint_type, & cdft_control_type, & cdft_group_type, & hirshfeld_constraint_type ! Public subroutines PUBLIC :: cdft_control_create, & cdft_control_release CONTAINS ! ************************************************************************************************** !> \brief create the becke_constraint_type !> \param becke_control the structure to create !> \par History !> 02.2007 created [Florian Schiffmann] ! ************************************************************************************************** SUBROUTINE becke_control_create(becke_control) TYPE(becke_constraint_type), POINTER :: becke_control CHARACTER(len=*), PARAMETER :: routineN = 'becke_control_create', & routineP = moduleN//':'//routineN CPASSERT(.NOT. ASSOCIATED(becke_control)) ALLOCATE (becke_control) becke_control%adjust = .FALSE. becke_control%cutoff_type = becke_cutoff_global becke_control%cavity_confine = .FALSE. becke_control%should_skip = .FALSE. becke_control%print_cavity = .FALSE. becke_control%in_memory = .FALSE. becke_control%use_bohr = .FALSE. becke_control%confine_bounds = 0 becke_control%rcavity = 3.0_dp becke_control%rglobal = 6.0_dp becke_control%eps_cavity = 1.0e-6_dp becke_control%cavity_shape = radius_single becke_control%vector_buffer%store_vectors = .TRUE. NULLIFY (becke_control%cavity%pw) NULLIFY (becke_control%aij) NULLIFY (becke_control%cavity_mat) NULLIFY (becke_control%cavity_env) NULLIFY (becke_control%cutoffs) NULLIFY (becke_control%cutoffs_tmp) NULLIFY (becke_control%radii) NULLIFY (becke_control%radii_tmp) END SUBROUTINE becke_control_create ! ************************************************************************************************** !> \brief release the becke_constraint_type !> \param becke_control the structure to release !> \par History !> 02.2007 created [Florian Schiffmann] ! ************************************************************************************************** SUBROUTINE becke_control_release(becke_control) TYPE(becke_constraint_type), POINTER :: becke_control CHARACTER(len=*), PARAMETER :: routineN = 'becke_control_release', & routineP = moduleN//':'//routineN CPASSERT(ASSOCIATED(becke_control)) IF (becke_control%vector_buffer%store_vectors) THEN IF (ALLOCATED(becke_control%vector_buffer%distances)) & DEALLOCATE (becke_control%vector_buffer%distances) IF (ALLOCATED(becke_control%vector_buffer%distance_vecs)) & DEALLOCATE (becke_control%vector_buffer%distance_vecs) IF (ALLOCATED(becke_control%vector_buffer%position_vecs)) & DEALLOCATE (becke_control%vector_buffer%position_vecs) IF (ALLOCATED(becke_control%vector_buffer%R12)) & DEALLOCATE (becke_control%vector_buffer%R12) IF (ALLOCATED(becke_control%vector_buffer%pair_dist_vecs)) & DEALLOCATE (becke_control%vector_buffer%pair_dist_vecs) END IF IF (ASSOCIATED(becke_control%cutoffs)) & DEALLOCATE (becke_control%cutoffs) IF (ASSOCIATED(becke_control%cutoffs_tmp)) & DEALLOCATE (becke_control%cutoffs_tmp) IF (ASSOCIATED(becke_control%radii_tmp)) & DEALLOCATE (becke_control%radii_tmp) IF (ASSOCIATED(becke_control%radii)) & DEALLOCATE (becke_control%radii) IF (ASSOCIATED(becke_control%aij)) & DEALLOCATE (becke_control%aij) IF (ASSOCIATED(becke_control%cavity_mat)) & DEALLOCATE (becke_control%cavity_mat) IF (becke_control%cavity_confine) & CALL release_hirshfeld_type(becke_control%cavity_env) DEALLOCATE (becke_control) END SUBROUTINE becke_control_release ! ************************************************************************************************** !> \brief create the cdft_control_type !> \param cdft_control the structure to create !> \par History !> 12.2015 created [Nico Holmberg] ! ************************************************************************************************** SUBROUTINE cdft_control_create(cdft_control) TYPE(cdft_control_type), POINTER :: cdft_control CHARACTER(len=*), PARAMETER :: routineN = 'cdft_control_create', & routineP = moduleN//':'//routineN CPASSERT(.NOT. ASSOCIATED(cdft_control)) ALLOCATE (cdft_control) cdft_control%ref_count = 1 cdft_control%total_steps = 0 NULLIFY (cdft_control%strength) NULLIFY (cdft_control%target) NULLIFY (cdft_control%value) NULLIFY (cdft_control%atoms) NULLIFY (cdft_control%is_constraint) NULLIFY (cdft_control%charges_fragment) NULLIFY (cdft_control%fragments) NULLIFY (cdft_control%group) NULLIFY (cdft_control%charge) cdft_control%natoms = 0 cdft_control%type = outer_scf_none cdft_control%need_pot = .TRUE. cdft_control%save_pot = .FALSE. cdft_control%transfer_pot = .FALSE. cdft_control%atomic_charges = .FALSE. cdft_control%first_iteration = .TRUE. cdft_control%fragment_density = .FALSE. cdft_control%fragments_integrated = .FALSE. cdft_control%flip_fragment = .FALSE. cdft_control%external_control = .FALSE. cdft_control%do_et = .FALSE. cdft_control%reuse_precond = .FALSE. cdft_control%nreused = 0 cdft_control%precond_freq = 0 cdft_control%max_reuse = 0 cdft_control%should_purge = .FALSE. cdft_control%purge_history = .FALSE. cdft_control%calculate_metric = .FALSE. cdft_control%purge_freq = 0 cdft_control%nbad_conv = 0 cdft_control%purge_offset = 0 cdft_control%istep = 0 cdft_control%ienergy = 0 NULLIFY (cdft_control%becke_control) CALL becke_control_create(cdft_control%becke_control) NULLIFY (cdft_control%hirshfeld_control) CALL hirshfeld_control_create(cdft_control%hirshfeld_control) NULLIFY (cdft_control%wmat) NULLIFY (cdft_control%matrix_s%matrix) NULLIFY (cdft_control%mo_coeff) NULLIFY (cdft_control%matrix_p) ! Outer SCF default settings cdft_control%ot_control%have_scf = .FALSE. cdft_control%ot_control%max_scf = 0 cdft_control%ot_control%eps_scf = 0.0_dp cdft_control%ot_control%step_size = 0.0_dp cdft_control%ot_control%type = -1 cdft_control%ot_control%optimizer = -1 cdft_control%ot_control%diis_buffer_length = -1 NULLIFY (cdft_control%ot_control%cdft_opt_control) cdft_control%constraint_control%have_scf = .FALSE. cdft_control%constraint_control%max_scf = 0 cdft_control%constraint_control%eps_scf = 0.0_dp cdft_control%constraint_control%step_size = 0.0_dp cdft_control%constraint_control%type = -1 cdft_control%constraint_control%optimizer = -1 cdft_control%constraint_control%diis_buffer_length = -1 NULLIFY (cdft_control%constraint_control%cdft_opt_control) cdft_control%constraint%iter_count = 0 NULLIFY (cdft_control%constraint%variables) NULLIFY (cdft_control%constraint%gradient) NULLIFY (cdft_control%constraint%energy) NULLIFY (cdft_control%constraint%count) NULLIFY (cdft_control%constraint%inv_jacobian) cdft_control%constraint%deallocate_jacobian = .TRUE. END SUBROUTINE cdft_control_create ! ************************************************************************************************** !> \brief release the cdft_control_type !> \param cdft_control the structure to release !> \par History !> 12.2015 created [Nico Holmberg] ! ************************************************************************************************** SUBROUTINE cdft_control_release(cdft_control) TYPE(cdft_control_type), POINTER :: cdft_control CHARACTER(len=*), PARAMETER :: routineN = 'cdft_control_release', & routineP = moduleN//':'//routineN INTEGER :: i CPASSERT(ASSOCIATED(cdft_control)) CPASSERT(cdft_control%ref_count > 0) cdft_control%ref_count = cdft_control%ref_count - 1 IF (cdft_control%ref_count == 0) THEN ! Constraint settings IF (ASSOCIATED(cdft_control%atoms)) & DEALLOCATE (cdft_control%atoms) IF (ASSOCIATED(cdft_control%strength)) & DEALLOCATE (cdft_control%strength) IF (ASSOCIATED(cdft_control%target)) & DEALLOCATE (cdft_control%target) IF (ASSOCIATED(cdft_control%value)) & DEALLOCATE (cdft_control%value) IF (ASSOCIATED(cdft_control%charges_fragment)) & DEALLOCATE (cdft_control%charges_fragment) IF (ASSOCIATED(cdft_control%fragments)) & DEALLOCATE (cdft_control%fragments) IF (ASSOCIATED(cdft_control%is_constraint)) & DEALLOCATE (cdft_control%is_constraint) IF (ASSOCIATED(cdft_control%charge)) & DEALLOCATE (cdft_control%charge) ! Constraint atom groups IF (ASSOCIATED(cdft_control%group)) THEN DO i = 1, SIZE(cdft_control%group) IF (ASSOCIATED(cdft_control%group(i)%atoms)) & DEALLOCATE (cdft_control%group(i)%atoms) IF (ASSOCIATED(cdft_control%group(i)%coeff)) & DEALLOCATE (cdft_control%group(i)%coeff) IF (ALLOCATED(cdft_control%group(i)%d_sum_const_dR)) & DEALLOCATE (cdft_control%group(i)%d_sum_const_dR) IF (ASSOCIATED(cdft_control%group(i)%gradients)) & DEALLOCATE (cdft_control%group(i)%gradients) IF (ASSOCIATED(cdft_control%group(i)%integrated)) & DEALLOCATE (cdft_control%group(i)%integrated) END DO DEALLOCATE (cdft_control%group) END IF ! Constraint type specific deallocations IF (ASSOCIATED(cdft_control%becke_control)) THEN CALL becke_control_release(cdft_control%becke_control) END IF IF (ASSOCIATED(cdft_control%hirshfeld_control)) THEN CALL hirshfeld_control_release(cdft_control%hirshfeld_control) END IF ! Release OUTER_SCF types CALL cdft_opt_type_release(cdft_control%ot_control%cdft_opt_control) CALL cdft_opt_type_release(cdft_control%constraint_control%cdft_opt_control) IF (ASSOCIATED(cdft_control%constraint%variables)) & DEALLOCATE (cdft_control%constraint%variables) IF (ASSOCIATED(cdft_control%constraint%count)) & DEALLOCATE (cdft_control%constraint%count) IF (ASSOCIATED(cdft_control%constraint%gradient)) & DEALLOCATE (cdft_control%constraint%gradient) IF (ASSOCIATED(cdft_control%constraint%energy)) & DEALLOCATE (cdft_control%constraint%energy) IF (ASSOCIATED(cdft_control%constraint%inv_jacobian)) & DEALLOCATE (cdft_control%constraint%inv_jacobian) ! Storage for mixed CDFT calculations IF (ALLOCATED(cdft_control%occupations)) THEN DO i = 1, SIZE(cdft_control%occupations) IF (ASSOCIATED(cdft_control%occupations(i)%array)) & DEALLOCATE (cdft_control%occupations(i)%array) END DO DEALLOCATE (cdft_control%occupations) END IF ! Release control cdft_control%type = outer_scf_none DEALLOCATE (cdft_control) END IF END SUBROUTINE cdft_control_release ! ************************************************************************************************** !> \brief retain the cdft_control_type !> \param cdft_control the structure to retain !> \par History !> created 12.2015 [Nico Holmberg] ! ************************************************************************************************** SUBROUTINE cdft_control_retain(cdft_control) TYPE(cdft_control_type), POINTER :: cdft_control CHARACTER(len=*), PARAMETER :: routineN = 'cdft_control_retain', & routineP = moduleN//':'//routineN CPASSERT(ASSOCIATED(cdft_control)) cdft_control%ref_count = cdft_control%ref_count + 1 END SUBROUTINE cdft_control_retain ! ************************************************************************************************** !> \brief create the hirshfeld_constraint_type !> \param hirshfeld_control the structure to create !> \par History !> 09.2018 created [Nico Holmberg] ! ************************************************************************************************** SUBROUTINE hirshfeld_control_create(hirshfeld_control) TYPE(hirshfeld_constraint_type), POINTER :: hirshfeld_control CHARACTER(len=*), PARAMETER :: routineN = 'hirshfeld_control_create', & routineP = moduleN//':'//routineN CPASSERT(.NOT. ASSOCIATED(hirshfeld_control)) ALLOCATE (hirshfeld_control) hirshfeld_control%use_bohr = .FALSE. hirshfeld_control%radius = 3.0_dp hirshfeld_control%shape_function = shape_function_gaussian hirshfeld_control%gaussian_shape = radius_single NULLIFY (hirshfeld_control%hirshfeld_env) NULLIFY (hirshfeld_control%radii) END SUBROUTINE hirshfeld_control_create ! ************************************************************************************************** !> \brief release the hirshfeld_constraint_type !> \param hirshfeld_control the structure to release !> \par History !> 09.2018 created [Nico Holmberg] ! ************************************************************************************************** SUBROUTINE hirshfeld_control_release(hirshfeld_control) TYPE(hirshfeld_constraint_type), POINTER :: hirshfeld_control CHARACTER(len=*), PARAMETER :: routineN = 'hirshfeld_control_release', & routineP = moduleN//':'//routineN CPASSERT(ASSOCIATED(hirshfeld_control)) IF (ASSOCIATED(hirshfeld_control%radii)) & DEALLOCATE (hirshfeld_control%radii) CALL release_hirshfeld_type(hirshfeld_control%hirshfeld_env) DEALLOCATE (hirshfeld_control) END SUBROUTINE hirshfeld_control_release END MODULE qs_cdft_types