Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief
10 : ! **************************************************************************************************
11 : MODULE qs_loc_states
12 : USE cp_array_utils, ONLY: cp_1d_r_p_type
13 : USE cp_control_types, ONLY: dft_control_type
14 : USE cp_dbcsr_api, ONLY: dbcsr_p_type
15 : USE cp_fm_types, ONLY: cp_fm_type
16 : USE cp_log_handling, ONLY: cp_get_default_logger,&
17 : cp_logger_get_default_io_unit,&
18 : cp_logger_type
19 : USE cp_output_handling, ONLY: cp_p_file,&
20 : cp_print_key_should_output
21 : USE input_section_types, ONLY: section_get_lval,&
22 : section_vals_get_subs_vals,&
23 : section_vals_type
24 : USE kinds, ONLY: dp
25 : USE molecular_dipoles, ONLY: calculate_molecular_dipole
26 : USE molecular_moments, ONLY: calculate_molecular_moments
27 : USE molecular_states, ONLY: construct_molecular_states
28 : USE molecule_types, ONLY: molecule_type
29 : USE particle_list_types, ONLY: particle_list_type
30 : USE pw_types, ONLY: pw_c1d_gs_type,&
31 : pw_r3d_rs_type
32 : USE qs_environment_types, ONLY: get_qs_env,&
33 : qs_environment_type,&
34 : set_qs_env
35 : USE qs_loc_main, ONLY: qs_loc_driver
36 : USE qs_loc_methods, ONLY: centers_second_moments_berry,&
37 : centers_second_moments_loc
38 : USE qs_loc_molecules, ONLY: wfc_to_molecule
39 : USE qs_loc_types, ONLY: qs_loc_env_type
40 : USE qs_mo_types, ONLY: mo_set_type
41 : USE wannier_states, ONLY: construct_wannier_states
42 : USE wannier_states_types, ONLY: wannier_centres_type
43 : #include "./base/base_uses.f90"
44 :
45 : IMPLICIT NONE
46 : PRIVATE
47 :
48 : ! Global parameters
49 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_loc_states'
50 : PUBLIC :: get_localization_info
51 :
52 : ! **************************************************************************************************
53 :
54 : CONTAINS
55 :
56 : ! **************************************************************************************************
57 : !> \brief Performs localization of the orbitals
58 : !> \param qs_env ...
59 : !> \param qs_loc_env ...
60 : !> \param loc_section ...
61 : !> \param mo_local ...
62 : !> \param wf_r ...
63 : !> \param wf_g ...
64 : !> \param particles ...
65 : !> \param coeff ...
66 : !> \param evals ...
67 : !> \param marked_states ...
68 : ! **************************************************************************************************
69 104 : SUBROUTINE get_localization_info(qs_env, qs_loc_env, loc_section, mo_local, &
70 104 : wf_r, wf_g, particles, coeff, evals, marked_states)
71 :
72 : TYPE(qs_environment_type), POINTER :: qs_env
73 : TYPE(qs_loc_env_type), POINTER :: qs_loc_env
74 : TYPE(section_vals_type), POINTER :: loc_section
75 : TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: mo_local
76 : TYPE(pw_r3d_rs_type), INTENT(INOUT) :: wf_r
77 : TYPE(pw_c1d_gs_type), INTENT(INOUT) :: wf_g
78 : TYPE(particle_list_type), POINTER :: particles
79 : TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: coeff
80 : TYPE(cp_1d_r_p_type), DIMENSION(:), POINTER :: evals
81 : INTEGER, DIMENSION(:, :, :), POINTER :: marked_states
82 :
83 : CHARACTER(len=*), PARAMETER :: routineN = 'get_localization_info'
84 :
85 : INTEGER :: handle, ispin, mystate, ns, nspins, &
86 : output_unit
87 104 : INTEGER, DIMENSION(:), POINTER :: lstates, marked_states_spin
88 : LOGICAL :: do_homo, do_mixed
89 104 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: scenter
90 : TYPE(cp_logger_type), POINTER :: logger
91 104 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: ks_rmpv, matrix_s
92 : TYPE(dft_control_type), POINTER :: dft_control
93 104 : TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
94 104 : TYPE(molecule_type), DIMENSION(:), POINTER :: molecule_set
95 : TYPE(section_vals_type), POINTER :: loc_print_section
96 104 : TYPE(wannier_centres_type), DIMENSION(:), POINTER :: wc
97 :
98 104 : CALL timeset(routineN, handle)
99 104 : NULLIFY (mos, ks_rmpv, dft_control, loc_print_section, marked_states_spin, &
100 104 : matrix_s, scenter, wc)
101 : CALL get_qs_env(qs_env, mos=mos, matrix_ks=ks_rmpv, molecule_set=molecule_set, &
102 104 : dft_control=dft_control, matrix_s=matrix_s)
103 104 : logger => cp_get_default_logger()
104 104 : output_unit = cp_logger_get_default_io_unit(logger)
105 104 : loc_print_section => section_vals_get_subs_vals(loc_section, "PRINT")
106 104 : do_homo = qs_loc_env%localized_wfn_control%do_homo
107 104 : do_mixed = qs_loc_env%localized_wfn_control%do_mixed
108 104 : IF (BTEST(cp_print_key_should_output(logger%iter_info, loc_print_section, &
109 : "WANNIER_STATES"), cp_p_file)) THEN
110 32 : CALL get_qs_env(qs_env=qs_env, WannierCentres=wc)
111 32 : IF (.NOT. ASSOCIATED(wc)) THEN
112 24 : ALLOCATE (wc(dft_control%nspins))
113 : END IF
114 : END IF
115 :
116 104 : IF (dft_control%restricted) THEN
117 : !For ROKS usefull only first term
118 : nspins = 1
119 : ELSE
120 104 : nspins = dft_control%nspins
121 : END IF
122 : !
123 232 : DO ispin = 1, nspins
124 : !
125 128 : IF (do_homo) THEN
126 114 : qs_loc_env%tag_mo = "HOMO"
127 : ELSE
128 14 : qs_loc_env%tag_mo = "LUMO"
129 : END IF
130 :
131 128 : IF (qs_loc_env%do_localize) THEN
132 : ! Do the Real localization..
133 112 : IF (output_unit > 0 .AND. do_homo) WRITE (output_unit, "(/,T2,A,I3)") &
134 : "LOCALIZATION| Computing localization properties "// &
135 49 : "for OCCUPIED ORBITALS. Spin:", ispin
136 112 : IF (output_unit > 0 .AND. do_mixed) WRITE (output_unit, "(/,T2,A,/,T16,A,I3)") &
137 1 : "LOCALIZATION| Computing localization properties for OCCUPIED, ", &
138 2 : "PARTIALLY OCCUPIED and UNOCCUPIED ORBITALS. Spin:", ispin
139 112 : IF (output_unit > 0 .AND. (.NOT. do_homo) .AND. (.NOT. do_mixed)) &
140 : WRITE (output_unit, "(/,T2,A,I3)") &
141 : "LOCALIZATION| Computing localization properties "// &
142 6 : "for UNOCCUPIED ORBITALS. Spin:", ispin
143 :
144 112 : scenter => qs_loc_env%localized_wfn_control%centers_set(ispin)%array
145 :
146 : CALL qs_loc_driver(qs_env, qs_loc_env, loc_print_section, &
147 112 : myspin=ispin, ext_mo_coeff=mo_local(ispin))
148 :
149 : ! maps wfc to molecules, and compute the molecular dipoles if required
150 112 : IF ((BTEST(cp_print_key_should_output(logger%iter_info, loc_print_section, &
151 : "MOLECULAR_DIPOLES"), cp_p_file) .OR. &
152 : BTEST(cp_print_key_should_output(logger%iter_info, loc_print_section, &
153 : "MOLECULAR_MOMENTS"), cp_p_file) .OR. &
154 : BTEST(cp_print_key_should_output(logger%iter_info, loc_print_section, &
155 : "MOLECULAR_STATES"), cp_p_file))) THEN
156 42 : CALL wfc_to_molecule(qs_loc_env, scenter, molecule_set, ispin, dft_control%nspins)
157 : END IF
158 :
159 : ! Compute the wannier states
160 112 : IF (BTEST(cp_print_key_should_output(logger%iter_info, loc_print_section, &
161 : "WANNIER_STATES"), cp_p_file)) THEN
162 16 : ns = SIZE(qs_loc_env%localized_wfn_control%loc_states, 1)
163 16 : IF (.NOT. ASSOCIATED(wc(ispin)%centres)) THEN
164 18 : ALLOCATE (wc(ispin)%WannierHamDiag(ns))
165 18 : ALLOCATE (wc(ispin)%centres(3, ns))
166 : END IF
167 :
168 944 : wc(ispin)%centres(:, :) = scenter(1 + (ispin - 1)*3:ispin*3, :)
169 16 : lstates => qs_loc_env%localized_wfn_control%loc_states(:, ispin)
170 : CALL construct_wannier_states(mo_local(ispin), &
171 : ks_rmpv(ispin)%matrix, qs_env, loc_print_section=loc_print_section, &
172 16 : WannierCentres=wc(ispin), ns=ns, states=lstates)
173 : END IF
174 : ! Compute the molecular states
175 112 : IF (BTEST(cp_print_key_should_output(logger%iter_info, loc_print_section, &
176 : "MOLECULAR_STATES"), cp_p_file)) THEN
177 : CALL construct_molecular_states( &
178 : molecule_set, mo_local(ispin), coeff(ispin), &
179 : evals(ispin)%array, ks_rmpv(ispin)%matrix, matrix_s(1)%matrix, qs_env, wf_r, wf_g, &
180 : loc_print_section=loc_print_section, particles=particles, tag=TRIM(qs_loc_env%tag_mo), &
181 28 : marked_states=marked_states_spin, ispin=ispin)
182 28 : IF (ASSOCIATED(marked_states_spin)) THEN
183 28 : IF (.NOT. ASSOCIATED(marked_states)) THEN
184 90 : ALLOCATE (marked_states(SIZE(marked_states_spin), dft_control%nspins, 2))
185 : END IF
186 28 : mystate = 1
187 28 : IF (qs_loc_env%tag_mo == "LUMO") mystate = 2
188 100 : marked_states(:, ispin, mystate) = marked_states_spin(:)
189 28 : DEALLOCATE (marked_states_spin)
190 : END IF
191 : END IF
192 : END IF
193 :
194 : ! Compute all the second moments of the Wannier states
195 232 : IF (section_get_lval(loc_print_section, "WANNIER_SPREADS%SECOND_MOMENTS")) THEN
196 0 : IF (section_get_lval(loc_print_section, "WANNIER_SPREADS%PERIODIC")) THEN
197 0 : IF (dft_control%qs_control%gapw_control%lmax_sphere .LT. 6) THEN
198 0 : CPABORT("Periodic second moments require LMAXN1>=6 In QS section")
199 : END IF
200 0 : CALL centers_second_moments_berry(qs_env, qs_loc_env, loc_print_section, ispin)
201 : ELSE
202 0 : CALL centers_second_moments_loc(qs_env, qs_loc_env, loc_print_section, ispin)
203 : END IF
204 : END IF
205 : END DO
206 :
207 : ! Compute molecular dipoles
208 104 : IF (BTEST(cp_print_key_should_output(logger%iter_info, loc_print_section, &
209 : "MOLECULAR_DIPOLES"), cp_p_file)) THEN
210 16 : CALL calculate_molecular_dipole(qs_env, qs_loc_env, loc_print_section, molecule_set)
211 : END IF
212 :
213 : ! Compute molecular multipole moments
214 104 : IF (BTEST(cp_print_key_should_output(logger%iter_info, loc_print_section, &
215 : "MOLECULAR_MOMENTS"), cp_p_file)) THEN
216 2 : CALL calculate_molecular_moments(qs_env, qs_loc_env, mo_local, loc_print_section, molecule_set)
217 : END IF
218 : !
219 104 : IF (BTEST(cp_print_key_should_output(logger%iter_info, loc_print_section, &
220 : "WANNIER_STATES"), cp_p_file)) THEN
221 32 : CALL set_qs_env(qs_env=qs_env, WannierCentres=wc)
222 : END IF
223 :
224 104 : CALL timestop(handle)
225 :
226 104 : END SUBROUTINE get_localization_info
227 :
228 : END MODULE qs_loc_states
|