73 SUBROUTINE wfn_mix(mos, particle_set, dft_section, qs_kind_set, para_env, output_unit, &
74 unoccupied_orbs, scf_env, matrix_s, marked_states, for_rtp)
81 INTEGER :: output_unit
83 OPTIONAL,
POINTER :: unoccupied_orbs
87 INTEGER,
DIMENSION(:, :, :),
OPTIONAL,
POINTER :: marked_states
88 LOGICAL,
OPTIONAL :: for_rtp
90 CHARACTER(len=*),
PARAMETER :: routinen =
'wfn_mix'
92 CHARACTER(LEN=default_path_length) :: read_file_name
93 INTEGER :: handle, homo, i_rep, ispin, mark_ind, mark_number, n_rep, nmo, orig_mo_index, &
94 orig_spin_index, orig_type, restart_unit, result_mo_index, result_spin_index
95 LOGICAL :: explicit, is_file, my_for_rtp, &
96 overwrite_mos, reverse_mo_index
97 REAL(kind=
dp) :: orig_scale, orthonormality, result_scale
100 TYPE(
mo_set_type),
ALLOCATABLE,
DIMENSION(:) :: mos_new, mos_orig_ext
103 CALL timeset(routinen, handle)
110 IF (
PRESENT(for_rtp))
THEN
116 IF (output_unit > 0)
THEN
117 WRITE (output_unit,
'()')
118 WRITE (output_unit,
'(T2,A)')
"Performing wfn mixing"
119 WRITE (output_unit,
'(T2,A)')
"====================="
122 ALLOCATE (mos_new(
SIZE(mos)))
123 DO ispin = 1,
SIZE(mos)
128 NULLIFY (fm_struct_vector)
129 CALL cp_fm_struct_create(fm_struct_vector, template_fmstruct=mos(1)%mo_coeff%matrix_struct, &
138 IF (.NOT. explicit) n_rep = 0
143 CALL section_vals_val_get(update_section,
"RESULT_MO_INDEX", i_rep_section=i_rep, i_val=result_mo_index)
144 CALL section_vals_val_get(update_section,
"RESULT_MARKED_STATE", i_rep_section=i_rep, i_val=mark_number)
145 CALL section_vals_val_get(update_section,
"RESULT_SPIN_INDEX", i_rep_section=i_rep, i_val=result_spin_index)
147 CALL section_vals_val_get(update_section,
"RESULT_SCALE", i_rep_section=i_rep, r_val=result_scale)
150 IF (mark_number > 0) result_mo_index = marked_states(mark_number, result_spin_index, mark_ind)
155 CALL section_vals_val_get(update_section,
"ORIG_MO_INDEX", i_rep_section=i_rep, i_val=orig_mo_index)
156 CALL section_vals_val_get(update_section,
"ORIG_MARKED_STATE", i_rep_section=i_rep, i_val=mark_number)
157 CALL section_vals_val_get(update_section,
"ORIG_SPIN_INDEX", i_rep_section=i_rep, i_val=orig_spin_index)
162 IF (mark_number > 0) orig_mo_index = marked_states(mark_number, orig_spin_index, mark_ind)
166 CALL section_vals_val_get(update_section,
"REVERSE_MO_INDEX", i_rep_section=i_rep, l_val=reverse_mo_index)
171 IF (reverse_mo_index)
THEN
172 CALL cp_fm_to_fm(mos(orig_spin_index)%mo_coeff, matrix_x, 1, &
175 CALL cp_fm_to_fm(mos(orig_spin_index)%mo_coeff, matrix_x, 1, &
176 mos(orig_spin_index)%nmo - orig_mo_index + 1, 1)
180 CALL get_mo_set(mos(orig_spin_index), homo=homo, nmo=nmo)
182 IF (orig_mo_index + homo <= nmo)
THEN
183 CALL cp_fm_to_fm(mos(orig_spin_index)%mo_coeff, matrix_x, 1, orig_mo_index + homo, 1)
184 ELSE IF (.NOT.
ASSOCIATED(unoccupied_orbs))
THEN
185 CALL cp_abort(__location__, &
186 "If ORIG_TYPE is set to VIRTUAL, the array unoccupied_orbs must be associated! "// &
187 "For instance, ask in the SCF section to compute virtual orbitals after the GS optimization.")
189 CALL cp_fm_to_fm(unoccupied_orbs(orig_spin_index), matrix_x, 1, orig_mo_index, 1)
195 c_val=read_file_name)
196 IF (read_file_name ==
"EMPTY")
THEN
197 CALL cp_abort(__location__, &
198 "If ORIG_TYPE is set to EXTERNAL, a file name should be set in ORIG_EXT_FILE_NAME "// &
199 "so that it can be used as the orginal MO.")
202 ALLOCATE (mos_orig_ext(
SIZE(mos)))
203 DO ispin = 1,
SIZE(mos)
207 IF (para_env%is_source())
THEN
208 INQUIRE (file=trim(read_file_name), exist=is_file)
209 IF (.NOT. is_file)
THEN
210 CALL cp_abort(__location__, &
211 "Reference file not found! Name of the file CP2K looked for: "//trim(read_file_name))
214 CALL open_file(file_name=read_file_name, &
215 file_action=
"READ", &
216 file_form=
"UNFORMATTED", &
218 unit_number=restart_unit)
221 particle_set=particle_set, natom=
SIZE(particle_set, 1), &
222 rst_unit=restart_unit)
223 IF (para_env%is_source())
CALL close_file(unit_number=restart_unit)
225 IF (reverse_mo_index)
THEN
226 CALL cp_fm_to_fm(mos_orig_ext(orig_spin_index)%mo_coeff, matrix_x, 1, &
229 CALL cp_fm_to_fm(mos_orig_ext(orig_spin_index)%mo_coeff, matrix_x, 1, &
230 mos_orig_ext(orig_spin_index)%nmo - orig_mo_index + 1, 1)
232 DO ispin = 1,
SIZE(mos_orig_ext)
235 DEALLOCATE (mos_orig_ext)
239 IF (reverse_mo_index)
THEN
240 CALL cp_fm_to_fm(mos_new(result_spin_index)%mo_coeff, matrix_y, &
241 1, result_mo_index, 1)
243 CALL cp_fm_to_fm(mos_new(result_spin_index)%mo_coeff, matrix_y, &
244 1, mos_new(result_spin_index)%nmo - result_mo_index + 1, 1)
251 IF (reverse_mo_index)
THEN
252 CALL cp_fm_to_fm(matrix_y, mos_new(result_spin_index)%mo_coeff, &
253 1, 1, result_mo_index)
255 CALL cp_fm_to_fm(matrix_y, mos_new(result_spin_index)%mo_coeff, &
256 1, 1, mos_new(result_spin_index)%nmo - result_mo_index + 1)
264 DO ispin = 1,
SIZE(mos_new)
265 CALL cp_fm_to_fm(mos_new(ispin)%mo_coeff, mos(ispin)%mo_coeff)
266 IF (mos_new(1)%use_mo_coeff_b)
THEN
269 IF (mos(1)%use_mo_coeff_b)
THEN
280 IF (output_unit > 0)
THEN
281 WRITE (unit=output_unit, fmt=
"(/,T2,A,T61,E20.4)") &
282 "Maximum deviation from MO S-orthonormality", orthonormality
283 WRITE (unit=output_unit, fmt=
"(T2,A)")
"Writing new MOs to file"
287 DO ispin = 1,
SIZE(mos_new)
288 IF (overwrite_mos)
THEN
289 CALL cp_fm_to_fm(mos_new(ispin)%mo_coeff, mos(ispin)%mo_coeff)
290 IF (mos_new(1)%use_mo_coeff_b)
THEN
294 IF (mos(1)%use_mo_coeff_b)
THEN
299 qs_kind_set=qs_kind_set)
302 DO ispin = 1,
SIZE(mos_new)
309 CALL timestop(handle)