(git:374b731)
Loading...
Searching...
No Matches
qs_scf_wfn_mix.F
Go to the documentation of this file.
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 Does all kind of post scf calculations for GPW/GAPW
10!> \par History
11!> Started as a copy from the relevant part of qs_scf
12!> \author Joost VandeVondele (10.2003)
13! **************************************************************************************************
16 USE cp_files, ONLY: close_file,&
22 USE cp_fm_types, ONLY: cp_fm_create,&
26 USE dbcsr_api, ONLY: dbcsr_p_type
34 USE kinds, ONLY: default_path_length,&
35 dp
45 USE qs_scf_types, ONLY: qs_scf_env_type,&
47#include "./base/base_uses.f90"
48
49 IMPLICIT NONE
50 PRIVATE
51
52 ! Global parameters
53 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_scf_wfn_mix'
54 PUBLIC :: wfn_mix
55
56CONTAINS
57
58! **************************************************************************************************
59!> \brief writes a new 'mixed' set of mos to restart file, without touching the current MOs
60!> \param mos ...
61!> \param particle_set ...
62!> \param dft_section ...
63!> \param qs_kind_set ...
64!> \param para_env ...
65!> \param output_unit ...
66!> \param unoccupied_orbs ...
67!> \param scf_env ...
68!> \param matrix_s ...
69!> \param marked_states ...
70!> \param for_rtp ...
71! **************************************************************************************************
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)
74
75 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
76 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
77 TYPE(section_vals_type), POINTER :: dft_section
78 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
79 TYPE(mp_para_env_type), POINTER :: para_env
80 INTEGER :: output_unit
81 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN), &
82 OPTIONAL, POINTER :: unoccupied_orbs
83 TYPE(qs_scf_env_type), OPTIONAL, POINTER :: scf_env
84 TYPE(dbcsr_p_type), DIMENSION(:), OPTIONAL, &
85 POINTER :: matrix_s
86 INTEGER, DIMENSION(:, :, :), OPTIONAL, POINTER :: marked_states
87 LOGICAL, OPTIONAL :: for_rtp
88
89 CHARACTER(len=*), PARAMETER :: routinen = 'wfn_mix'
90
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
96 REAL(kind=dp) :: orig_scale, orthonormality, result_scale
97 TYPE(cp_fm_struct_type), POINTER :: fm_struct_vector
98 TYPE(cp_fm_type) :: matrix_x, matrix_y
99 TYPE(mo_set_type), ALLOCATABLE, DIMENSION(:) :: mos_new, mos_orig_ext
100 TYPE(section_vals_type), POINTER :: update_section, wfn_mix_section
101
102 CALL timeset(routinen, handle)
103 wfn_mix_section => section_vals_get_subs_vals(dft_section, "PRINT%WFN_MIX")
104 CALL section_vals_get(wfn_mix_section, explicit=explicit)
105
106 ! only perform action if explicitly required
107 IF (explicit) THEN
108
109 IF (PRESENT(for_rtp)) THEN
110 my_for_rtp = for_rtp
111 ELSE
112 my_for_rtp = .false.
113 END IF
114
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)') "====================="
119 END IF
120
121 ALLOCATE (mos_new(SIZE(mos)))
122 DO ispin = 1, SIZE(mos)
123 CALL duplicate_mo_set(mos_new(ispin), mos(ispin))
124 END DO
125
126 ! a single vector matrix structure
127 NULLIFY (fm_struct_vector)
128 CALL cp_fm_struct_create(fm_struct_vector, template_fmstruct=mos(1)%mo_coeff%matrix_struct, &
129 ncol_global=1)
130 CALL cp_fm_create(matrix_x, fm_struct_vector, name="x")
131 CALL cp_fm_create(matrix_y, fm_struct_vector, name="y")
132 CALL cp_fm_struct_release(fm_struct_vector)
133
134 update_section => section_vals_get_subs_vals(wfn_mix_section, "UPDATE")
135 CALL section_vals_get(update_section, n_repetition=n_rep)
136 CALL section_vals_get(update_section, explicit=explicit)
137 IF (.NOT. explicit) n_rep = 0
138
139 ! Mix the MOs as : y = ay + bx
140 DO i_rep = 1, n_rep
141 ! The occupied MO that will be modified or saved, 'y'
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)
145 ! result_scale is the 'b' coefficient
146 CALL section_vals_val_get(update_section, "RESULT_SCALE", i_rep_section=i_rep, r_val=result_scale)
147
148 mark_ind = 1
149 IF (mark_number .GT. 0) result_mo_index = marked_states(mark_number, result_spin_index, mark_ind)
150
151 ! The MO that will be added to the previous one, 'x'
152 CALL section_vals_val_get(update_section, "ORIG_TYPE", i_rep_section=i_rep, &
153 i_val=orig_type)
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)
157 ! orig_scal is the 'a' coefficient
158 CALL section_vals_val_get(update_section, "ORIG_SCALE", i_rep_section=i_rep, r_val=orig_scale)
159
160 IF (orig_type == wfn_mix_orig_virtual) mark_ind = 2
161 IF (mark_number .GT. 0) orig_mo_index = marked_states(mark_number, orig_spin_index, mark_ind)
162
163 CALL section_vals_val_get(wfn_mix_section, "OVERWRITE_MOS", l_val=overwrite_mos)
164
165 ! First get a copy of the proper orig
166 ! Origin is in the MO matrix
167 IF (orig_type == wfn_mix_orig_occ) THEN
168 CALL cp_fm_to_fm(mos(orig_spin_index)%mo_coeff, matrix_x, 1, &
169 mos(orig_spin_index)%nmo - orig_mo_index + 1, 1)
170
171 ! Orgin is in the virtual matrix
172 ELSE IF (orig_type == wfn_mix_orig_virtual) THEN
173 IF (.NOT. ASSOCIATED(unoccupied_orbs)) &
174 CALL cp_abort(__location__, &
175 "If ORIG_TYPE is set to VIRTUAL, the array unoccupied_orbs must be associated! "// &
176 "For instance, ask in the SCF section to compute virtual orbitals after the GS optimization.")
177 CALL cp_fm_to_fm(unoccupied_orbs(orig_spin_index), matrix_x, 1, orig_mo_index, 1)
178
179 ! Orgin is to be read from an external .wfn file
180 ELSE IF (orig_type == wfn_mix_orig_external) THEN
181 CALL section_vals_val_get(update_section, "ORIG_EXT_FILE_NAME", i_rep_section=i_rep, &
182 c_val=read_file_name)
183 IF (read_file_name == "EMPTY") &
184 CALL cp_abort(__location__, &
185 "If ORIG_TYPE is set to EXTERNAL, a file name should be set in ORIG_EXT_FILE_NAME "// &
186 "so that it can be used as the orginal MO.")
187
188 ALLOCATE (mos_orig_ext(SIZE(mos)))
189 DO ispin = 1, SIZE(mos)
190 CALL duplicate_mo_set(mos_orig_ext(ispin), mos(ispin))
191 END DO
192
193 IF (para_env%is_source()) THEN
194 INQUIRE (file=trim(read_file_name), exist=is_file)
195 IF (.NOT. is_file) &
196 CALL cp_abort(__location__, &
197 "Reference file not found! Name of the file CP2K looked for: "//trim(read_file_name))
198
199 CALL open_file(file_name=read_file_name, &
200 file_action="READ", &
201 file_form="UNFORMATTED", &
202 file_status="OLD", &
203 unit_number=restart_unit)
204 END IF
205 CALL read_mos_restart_low(mos_orig_ext, para_env=para_env, qs_kind_set=qs_kind_set, &
206 particle_set=particle_set, natom=SIZE(particle_set, 1), &
207 rst_unit=restart_unit)
208 IF (para_env%is_source()) CALL close_file(unit_number=restart_unit)
209
210 CALL cp_fm_to_fm(mos_orig_ext(orig_spin_index)%mo_coeff, matrix_x, 1, &
211 mos_orig_ext(orig_spin_index)%nmo - orig_mo_index + 1, 1)
212
213 DO ispin = 1, SIZE(mos_orig_ext)
214 CALL deallocate_mo_set(mos_orig_ext(ispin))
215 END DO
216 DEALLOCATE (mos_orig_ext)
217 END IF
218
219 ! Second, get a copy of the target
220 CALL cp_fm_to_fm(mos_new(result_spin_index)%mo_coeff, matrix_y, &
221 1, mos_new(result_spin_index)%nmo - result_mo_index + 1, 1)
222
223 ! Third, perform the mix
224 CALL cp_fm_scale_and_add(result_scale, matrix_y, orig_scale, matrix_x)
225 ! and copy back in the result mos
226 CALL cp_fm_to_fm(matrix_y, mos_new(result_spin_index)%mo_coeff, &
227 1, 1, mos_new(result_spin_index)%nmo - result_mo_index + 1)
228 END DO
229
230 CALL cp_fm_release(matrix_x)
231 CALL cp_fm_release(matrix_y)
232
233 IF (my_for_rtp) THEN
234 DO ispin = 1, SIZE(mos_new)
235 CALL cp_fm_to_fm(mos_new(ispin)%mo_coeff, mos(ispin)%mo_coeff)
236 IF (mos_new(1)%use_mo_coeff_b) &
237 CALL copy_fm_to_dbcsr(mos_new(ispin)%mo_coeff, mos_new(ispin)%mo_coeff_b)
238 IF (mos(1)%use_mo_coeff_b) &
239 CALL copy_fm_to_dbcsr(mos_new(ispin)%mo_coeff, mos(ispin)%mo_coeff_b)
240 END DO
241 ELSE
242 IF (scf_env%method == special_diag_method_nr) THEN
243 CALL calculate_orthonormality(orthonormality, mos)
244 ELSE
245 CALL calculate_orthonormality(orthonormality, mos, matrix_s(1)%matrix)
246 END IF
247
248 IF (output_unit > 0) THEN
249 WRITE (output_unit, '()')
250 WRITE (output_unit, '(T2,A,T61,E20.4)') &
251 "Maximum deviation from MO S-orthonormality", orthonormality
252 WRITE (output_unit, '(T2,A)') "Writing new MOs to file"
253 END IF
254
255 ! *** Write WaveFunction restart file ***
256
257 DO ispin = 1, SIZE(mos_new)
258 IF (overwrite_mos) THEN
259 CALL cp_fm_to_fm(mos_new(ispin)%mo_coeff, mos(ispin)%mo_coeff)
260 IF (mos_new(1)%use_mo_coeff_b) &
261 CALL copy_fm_to_dbcsr(mos_new(ispin)%mo_coeff, mos_new(ispin)%mo_coeff_b)
262 END IF
263 IF (mos(1)%use_mo_coeff_b) &
264 CALL copy_fm_to_dbcsr(mos_new(ispin)%mo_coeff, mos(ispin)%mo_coeff_b)
265 END DO
266 CALL write_mo_set_to_restart(mos_new, particle_set, dft_section=dft_section, qs_kind_set=qs_kind_set)
267 END IF
268
269 DO ispin = 1, SIZE(mos_new)
270 CALL deallocate_mo_set(mos_new(ispin))
271 END DO
272 DEALLOCATE (mos_new)
273
274 END IF
275
276 CALL timestop(handle)
277
278 END SUBROUTINE wfn_mix
279
280END MODULE qs_scf_wfn_mix
DBCSR operations in CP2K.
subroutine, public copy_fm_to_dbcsr(fm, matrix, keep_sparsity)
Copy a BLACS matrix to a dbcsr matrix.
Utility routines to open and close files. Tracking of preconnections.
Definition cp_files.F:16
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
Definition cp_files.F:308
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
Definition cp_files.F:119
basic linear algebra operations for full matrices
subroutine, public cp_fm_scale_and_add(alpha, matrix_a, beta, matrix_b)
calc A <- alpha*A + beta*B optimized for alpha == 1.0 (just add beta*B) and beta == 0....
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public wfn_mix_orig_virtual
integer, parameter, public wfn_mix_orig_external
integer, parameter, public wfn_mix_orig_occ
objects that represent the structure of input sections and the data contained in an input section
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_get(section_vals, ref_count, n_repetition, n_subs_vals_rep, section, explicit)
returns various attributes about the section_vals
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_path_length
Definition kinds.F:58
Interface to the message passing library MPI.
Define the data structure for the particle information.
Define the quickstep kind type and their sub types.
Definition and initialisation of the mo data type.
Definition qs_mo_io.F:21
subroutine, public write_mo_set_to_restart(mo_array, particle_set, dft_section, qs_kind_set)
...
Definition qs_mo_io.F:107
subroutine, public read_mos_restart_low(mos, para_env, qs_kind_set, particle_set, natom, rst_unit, multiplicity, rt_mos, natom_mismatch)
Reading the mos from apreviously defined restart file.
Definition qs_mo_io.F:670
collects routines that perform operations directly related to MOs
subroutine, public calculate_orthonormality(orthonormality, mo_array, matrix_s)
...
Definition and initialisation of the mo data type.
Definition qs_mo_types.F:22
subroutine, public duplicate_mo_set(mo_set_new, mo_set_old)
allocate a new mo_set, and copy the old data
subroutine, public deallocate_mo_set(mo_set)
Deallocate a wavefunction data structure.
module that contains the definitions of the scf types
integer, parameter, public special_diag_method_nr
Does all kind of post scf calculations for GPW/GAPW.
subroutine, public wfn_mix(mos, particle_set, dft_section, qs_kind_set, para_env, output_unit, unoccupied_orbs, scf_env, matrix_s, marked_states, for_rtp)
writes a new 'mixed' set of mos to restart file, without touching the current MOs
keeps the information about the structure of a full matrix
represent a full matrix
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.