72 SUBROUTINE wfn_mix(mos, particle_set, dft_section, qs_kind_set, para_env, output_unit, &
73 unoccupied_orbs, scf_env, matrix_s, marked_states, for_rtp)
80 INTEGER :: output_unit
82 OPTIONAL,
POINTER :: unoccupied_orbs
86 INTEGER,
DIMENSION(:, :, :),
OPTIONAL,
POINTER :: marked_states
87 LOGICAL,
OPTIONAL :: for_rtp
89 CHARACTER(len=*),
PARAMETER :: routinen =
'wfn_mix'
91 CHARACTER(LEN=default_path_length) :: read_file_name
92 INTEGER :: handle, i_rep, ispin, mark_ind, mark_number, n_rep, orig_mo_index, &
93 orig_spin_index, orig_type, restart_unit, result_mo_index, result_spin_index
94 LOGICAL :: explicit, is_file, my_for_rtp, &
95 overwrite_mos, reverse_mo_index
96 REAL(kind=
dp) :: orig_scale, orthonormality, result_scale
99 TYPE(
mo_set_type),
ALLOCATABLE,
DIMENSION(:) :: mos_new, mos_orig_ext
102 CALL timeset(routinen, handle)
109 IF (
PRESENT(for_rtp))
THEN
115 IF (output_unit > 0)
THEN
116 WRITE (output_unit,
'()')
117 WRITE (output_unit,
'(T2,A)')
"Performing wfn mixing"
118 WRITE (output_unit,
'(T2,A)')
"====================="
121 ALLOCATE (mos_new(
SIZE(mos)))
122 DO ispin = 1,
SIZE(mos)
127 NULLIFY (fm_struct_vector)
128 CALL cp_fm_struct_create(fm_struct_vector, template_fmstruct=mos(1)%mo_coeff%matrix_struct, &
137 IF (.NOT. explicit) n_rep = 0
142 CALL section_vals_val_get(update_section,
"RESULT_MO_INDEX", i_rep_section=i_rep, i_val=result_mo_index)
143 CALL section_vals_val_get(update_section,
"RESULT_MARKED_STATE", i_rep_section=i_rep, i_val=mark_number)
144 CALL section_vals_val_get(update_section,
"RESULT_SPIN_INDEX", i_rep_section=i_rep, i_val=result_spin_index)
146 CALL section_vals_val_get(update_section,
"RESULT_SCALE", i_rep_section=i_rep, r_val=result_scale)
149 IF (mark_number .GT. 0) result_mo_index = marked_states(mark_number, result_spin_index, mark_ind)
154 CALL section_vals_val_get(update_section,
"ORIG_MO_INDEX", i_rep_section=i_rep, i_val=orig_mo_index)
155 CALL section_vals_val_get(update_section,
"ORIG_MARKED_STATE", i_rep_section=i_rep, i_val=mark_number)
156 CALL section_vals_val_get(update_section,
"ORIG_SPIN_INDEX", i_rep_section=i_rep, i_val=orig_spin_index)
161 IF (mark_number .GT. 0) orig_mo_index = marked_states(mark_number, orig_spin_index, mark_ind)
165 CALL section_vals_val_get(update_section,
"REVERSE_MO_INDEX", i_rep_section=i_rep, l_val=reverse_mo_index)
170 IF (reverse_mo_index)
THEN
171 CALL cp_fm_to_fm(mos(orig_spin_index)%mo_coeff, matrix_x, 1, &
174 CALL cp_fm_to_fm(mos(orig_spin_index)%mo_coeff, matrix_x, 1, &
175 mos(orig_spin_index)%nmo - orig_mo_index + 1, 1)
179 IF (.NOT.
ASSOCIATED(unoccupied_orbs)) &
180 CALL cp_abort(__location__, &
181 "If ORIG_TYPE is set to VIRTUAL, the array unoccupied_orbs must be associated! "// &
182 "For instance, ask in the SCF section to compute virtual orbitals after the GS optimization.")
183 CALL cp_fm_to_fm(unoccupied_orbs(orig_spin_index), matrix_x, 1, orig_mo_index, 1)
188 c_val=read_file_name)
189 IF (read_file_name ==
"EMPTY") &
190 CALL cp_abort(__location__, &
191 "If ORIG_TYPE is set to EXTERNAL, a file name should be set in ORIG_EXT_FILE_NAME "// &
192 "so that it can be used as the orginal MO.")
194 ALLOCATE (mos_orig_ext(
SIZE(mos)))
195 DO ispin = 1,
SIZE(mos)
199 IF (para_env%is_source())
THEN
200 INQUIRE (file=trim(read_file_name), exist=is_file)
202 CALL cp_abort(__location__, &
203 "Reference file not found! Name of the file CP2K looked for: "//trim(read_file_name))
205 CALL open_file(file_name=read_file_name, &
206 file_action=
"READ", &
207 file_form=
"UNFORMATTED", &
209 unit_number=restart_unit)
212 particle_set=particle_set, natom=
SIZE(particle_set, 1), &
213 rst_unit=restart_unit)
214 IF (para_env%is_source())
CALL close_file(unit_number=restart_unit)
216 IF (reverse_mo_index)
THEN
217 CALL cp_fm_to_fm(mos_orig_ext(orig_spin_index)%mo_coeff, matrix_x, 1, &
220 CALL cp_fm_to_fm(mos_orig_ext(orig_spin_index)%mo_coeff, matrix_x, 1, &
221 mos_orig_ext(orig_spin_index)%nmo - orig_mo_index + 1, 1)
223 DO ispin = 1,
SIZE(mos_orig_ext)
226 DEALLOCATE (mos_orig_ext)
230 IF (reverse_mo_index)
THEN
231 CALL cp_fm_to_fm(mos_new(result_spin_index)%mo_coeff, matrix_y, &
232 1, result_mo_index, 1)
234 CALL cp_fm_to_fm(mos_new(result_spin_index)%mo_coeff, matrix_y, &
235 1, mos_new(result_spin_index)%nmo - result_mo_index + 1, 1)
242 IF (reverse_mo_index)
THEN
243 CALL cp_fm_to_fm(matrix_y, mos_new(result_spin_index)%mo_coeff, &
244 1, 1, result_mo_index)
246 CALL cp_fm_to_fm(matrix_y, mos_new(result_spin_index)%mo_coeff, &
247 1, 1, mos_new(result_spin_index)%nmo - result_mo_index + 1)
255 DO ispin = 1,
SIZE(mos_new)
256 CALL cp_fm_to_fm(mos_new(ispin)%mo_coeff, mos(ispin)%mo_coeff)
257 IF (mos_new(1)%use_mo_coeff_b) &
259 IF (mos(1)%use_mo_coeff_b) &
269 IF (output_unit > 0)
THEN
270 WRITE (output_unit,
'()')
271 WRITE (output_unit,
'(T2,A,T61,E20.4)') &
272 "Maximum deviation from MO S-orthonormality", orthonormality
273 WRITE (output_unit,
'(T2,A)')
"Writing new MOs to file"
278 DO ispin = 1,
SIZE(mos_new)
279 IF (overwrite_mos)
THEN
280 CALL cp_fm_to_fm(mos_new(ispin)%mo_coeff, mos(ispin)%mo_coeff)
281 IF (mos_new(1)%use_mo_coeff_b) &
284 IF (mos(1)%use_mo_coeff_b) &
290 DO ispin = 1,
SIZE(mos_new)
297 CALL timestop(handle)