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 Routines for all ALMO-based SCF methods
10 : !> 'RZK-warning' marks unresolved issues
11 : !> \par History
12 : !> 2011.05 created [Rustam Z Khaliullin]
13 : !> \author Rustam Z Khaliullin
14 : ! **************************************************************************************************
15 : MODULE almo_scf
16 : USE almo_scf_methods, ONLY: almo_scf_p_blk_to_t_blk,&
17 : almo_scf_t_rescaling,&
18 : almo_scf_t_to_proj,&
19 : distribute_domains,&
20 : orthogonalize_mos
21 : USE almo_scf_optimizer, ONLY: almo_scf_block_diagonal,&
22 : almo_scf_construct_nlmos,&
23 : almo_scf_xalmo_eigensolver,&
24 : almo_scf_xalmo_pcg,&
25 : almo_scf_xalmo_trustr
26 : USE almo_scf_qs, ONLY: almo_dm_to_almo_ks,&
27 : almo_scf_construct_quencher,&
28 : calculate_w_matrix_almo,&
29 : construct_qs_mos,&
30 : init_almo_ks_matrix_via_qs,&
31 : matrix_almo_create,&
32 : matrix_qs_to_almo
33 : USE almo_scf_types, ONLY: almo_mat_dim_aobasis,&
34 : almo_mat_dim_occ,&
35 : almo_mat_dim_virt,&
36 : almo_mat_dim_virt_disc,&
37 : almo_mat_dim_virt_full,&
38 : almo_scf_env_type,&
39 : optimizer_options_type,&
40 : print_optimizer_options
41 : USE atomic_kind_types, ONLY: atomic_kind_type
42 : USE bibliography, ONLY: Khaliullin2013,&
43 : Kolafa2004,&
44 : Kuhne2007,&
45 : Scheiber2018,&
46 : Staub2019,&
47 : cite_reference
48 : USE cp_blacs_env, ONLY: cp_blacs_env_release
49 : USE cp_control_types, ONLY: dft_control_type
50 : USE cp_dbcsr_diag, ONLY: cp_dbcsr_syevd
51 : USE cp_dbcsr_operations, ONLY: copy_dbcsr_to_fm
52 : USE cp_fm_types, ONLY: cp_fm_type
53 : USE cp_log_handling, ONLY: cp_get_default_logger,&
54 : cp_logger_get_default_unit_nr,&
55 : cp_logger_type
56 : USE dbcsr_api, ONLY: &
57 : dbcsr_add, dbcsr_add_on_diag, dbcsr_binary_read, dbcsr_checksum, dbcsr_copy, dbcsr_create, &
58 : dbcsr_distribution_get, dbcsr_distribution_type, dbcsr_filter, dbcsr_finalize, &
59 : dbcsr_get_info, dbcsr_get_stored_coordinates, dbcsr_init_random, &
60 : dbcsr_iterator_blocks_left, dbcsr_iterator_next_block, dbcsr_iterator_start, &
61 : dbcsr_iterator_stop, dbcsr_iterator_type, dbcsr_multiply, dbcsr_nblkcols_total, &
62 : dbcsr_nblkrows_total, dbcsr_p_type, dbcsr_release, dbcsr_reserve_block2d, dbcsr_scale, &
63 : dbcsr_set, dbcsr_type, dbcsr_type_no_symmetry, dbcsr_type_symmetric, dbcsr_work_create
64 : USE domain_submatrix_methods, ONLY: init_submatrices,&
65 : release_submatrices
66 : USE input_constants, ONLY: &
67 : almo_deloc_none, almo_deloc_scf, almo_deloc_x, almo_deloc_x_then_scf, &
68 : almo_deloc_xalmo_1diag, almo_deloc_xalmo_scf, almo_deloc_xalmo_x, almo_deloc_xk, &
69 : almo_domain_layout_molecular, almo_mat_distr_atomic, almo_mat_distr_molecular, &
70 : almo_scf_diag, almo_scf_dm_sign, almo_scf_pcg, almo_scf_skip, almo_scf_trustr, &
71 : atomic_guess, molecular_guess, optimizer_diis, optimizer_lin_eq_pcg, optimizer_pcg, &
72 : optimizer_trustr, restart_guess, smear_fermi_dirac, virt_full, virt_number, virt_occ_size, &
73 : xalmo_case_block_diag, xalmo_case_fully_deloc, xalmo_case_normal, xalmo_trial_r0_out
74 : USE input_section_types, ONLY: section_vals_type
75 : USE iterate_matrix, ONLY: invert_Hotelling,&
76 : matrix_sqrt_Newton_Schulz
77 : USE kinds, ONLY: default_path_length,&
78 : dp
79 : USE mathlib, ONLY: binomial
80 : USE message_passing, ONLY: mp_comm_type,&
81 : mp_para_env_release,&
82 : mp_para_env_type
83 : USE molecule_types, ONLY: get_molecule_set_info,&
84 : molecule_type
85 : USE mscfg_types, ONLY: get_matrix_from_submatrices,&
86 : molecular_scf_guess_env_type
87 : USE particle_types, ONLY: particle_type
88 : USE qs_atomic_block, ONLY: calculate_atomic_block_dm
89 : USE qs_environment_types, ONLY: get_qs_env,&
90 : qs_environment_type
91 : USE qs_initial_guess, ONLY: calculate_mopac_dm
92 : USE qs_kind_types, ONLY: qs_kind_type
93 : USE qs_mo_types, ONLY: get_mo_set,&
94 : mo_set_type
95 : USE qs_rho_types, ONLY: qs_rho_get,&
96 : qs_rho_type
97 : USE qs_scf_post_scf, ONLY: qs_scf_compute_properties
98 : USE qs_scf_types, ONLY: qs_scf_env_type
99 : #include "./base/base_uses.f90"
100 :
101 : IMPLICIT NONE
102 :
103 : PRIVATE
104 :
105 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'almo_scf'
106 :
107 : PUBLIC :: almo_entry_scf
108 :
109 : LOGICAL, PARAMETER :: debug_mode = .FALSE.
110 : LOGICAL, PARAMETER :: safe_mode = .FALSE.
111 :
112 : CONTAINS
113 :
114 : ! **************************************************************************************************
115 : !> \brief The entry point into ALMO SCF routines
116 : !> \param qs_env pointer to the QS environment
117 : !> \param calc_forces calculate forces?
118 : !> \par History
119 : !> 2011.05 created [Rustam Z Khaliullin]
120 : !> \author Rustam Z Khaliullin
121 : ! **************************************************************************************************
122 116 : SUBROUTINE almo_entry_scf(qs_env, calc_forces)
123 : TYPE(qs_environment_type), POINTER :: qs_env
124 : LOGICAL, INTENT(IN) :: calc_forces
125 :
126 : CHARACTER(len=*), PARAMETER :: routineN = 'almo_entry_scf'
127 :
128 : INTEGER :: handle
129 : TYPE(almo_scf_env_type), POINTER :: almo_scf_env
130 :
131 116 : CALL timeset(routineN, handle)
132 :
133 116 : CALL cite_reference(Khaliullin2013)
134 :
135 : ! get a pointer to the almo environment
136 116 : CALL get_qs_env(qs_env, almo_scf_env=almo_scf_env)
137 :
138 : ! initialize scf
139 116 : CALL almo_scf_init(qs_env, almo_scf_env, calc_forces)
140 :
141 : ! create the initial guess for ALMOs
142 116 : CALL almo_scf_initial_guess(qs_env, almo_scf_env)
143 :
144 : ! perform SCF for block diagonal ALMOs
145 116 : CALL almo_scf_main(qs_env, almo_scf_env)
146 :
147 : ! allow electron delocalization
148 116 : CALL almo_scf_delocalization(qs_env, almo_scf_env)
149 :
150 : ! construct NLMOs
151 116 : CALL construct_nlmos(qs_env, almo_scf_env)
152 :
153 : ! electron correlation methods
154 : !CALL almo_correlation_main(qs_env,almo_scf_env)
155 :
156 : ! do post scf processing
157 116 : CALL almo_scf_post(qs_env, almo_scf_env)
158 :
159 : ! clean up the mess
160 116 : CALL almo_scf_clean_up(almo_scf_env)
161 :
162 116 : CALL timestop(handle)
163 :
164 116 : END SUBROUTINE almo_entry_scf
165 :
166 : ! **************************************************************************************************
167 : !> \brief Initialization of the almo_scf_env_type.
168 : !> \param qs_env ...
169 : !> \param almo_scf_env ...
170 : !> \param calc_forces ...
171 : !> \par History
172 : !> 2011.05 created [Rustam Z Khaliullin]
173 : !> 2018.09 smearing support [Ruben Staub]
174 : !> \author Rustam Z Khaliullin
175 : ! **************************************************************************************************
176 116 : SUBROUTINE almo_scf_init(qs_env, almo_scf_env, calc_forces)
177 : TYPE(qs_environment_type), POINTER :: qs_env
178 : TYPE(almo_scf_env_type), INTENT(INOUT) :: almo_scf_env
179 : LOGICAL, INTENT(IN) :: calc_forces
180 :
181 : CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_init'
182 :
183 : INTEGER :: ao, handle, i, iao, idomain, ispin, &
184 : multip, naos, natoms, ndomains, nelec, &
185 : nelec_a, nelec_b, nmols, nspins, &
186 : unit_nr
187 : TYPE(cp_logger_type), POINTER :: logger
188 116 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
189 : TYPE(dft_control_type), POINTER :: dft_control
190 116 : TYPE(molecule_type), DIMENSION(:), POINTER :: molecule_set
191 : TYPE(section_vals_type), POINTER :: input
192 :
193 116 : CALL timeset(routineN, handle)
194 :
195 : ! define the output_unit
196 116 : logger => cp_get_default_logger()
197 116 : IF (logger%para_env%is_source()) THEN
198 58 : unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
199 : ELSE
200 58 : unit_nr = -1
201 : END IF
202 :
203 : ! set optimizers' types
204 116 : almo_scf_env%opt_block_diag_diis%optimizer_type = optimizer_diis
205 116 : almo_scf_env%opt_block_diag_pcg%optimizer_type = optimizer_pcg
206 116 : almo_scf_env%opt_xalmo_diis%optimizer_type = optimizer_diis
207 116 : almo_scf_env%opt_xalmo_pcg%optimizer_type = optimizer_pcg
208 116 : almo_scf_env%opt_xalmo_trustr%optimizer_type = optimizer_trustr
209 116 : almo_scf_env%opt_nlmo_pcg%optimizer_type = optimizer_pcg
210 116 : almo_scf_env%opt_block_diag_trustr%optimizer_type = optimizer_trustr
211 116 : almo_scf_env%opt_xalmo_newton_pcg_solver%optimizer_type = optimizer_lin_eq_pcg
212 :
213 : ! get info from the qs_env
214 : CALL get_qs_env(qs_env, &
215 : nelectron_total=almo_scf_env%nelectrons_total, &
216 : matrix_s=matrix_s, &
217 : dft_control=dft_control, &
218 : molecule_set=molecule_set, &
219 : input=input, &
220 : has_unit_metric=almo_scf_env%orthogonal_basis, &
221 : para_env=almo_scf_env%para_env, &
222 : blacs_env=almo_scf_env%blacs_env, &
223 116 : nelectron_spin=almo_scf_env%nelectrons_spin)
224 116 : CALL almo_scf_env%para_env%retain()
225 116 : CALL almo_scf_env%blacs_env%retain()
226 :
227 : ! copy basic quantities
228 116 : almo_scf_env%nspins = dft_control%nspins
229 116 : almo_scf_env%natoms = dbcsr_nblkrows_total(matrix_s(1)%matrix)
230 116 : almo_scf_env%nmolecules = SIZE(molecule_set)
231 116 : CALL dbcsr_get_info(matrix_s(1)%matrix, nfullrows_total=naos)
232 116 : almo_scf_env%naos = naos
233 :
234 : !! retrieve smearing parameters, and check compatibility of methods requested
235 116 : almo_scf_env%smear = dft_control%smear
236 116 : IF (almo_scf_env%smear) THEN
237 4 : CALL cite_reference(Staub2019)
238 4 : IF ((almo_scf_env%almo_update_algorithm .NE. almo_scf_diag) .OR. &
239 : ((almo_scf_env%deloc_method .NE. almo_deloc_none) .AND. &
240 : (almo_scf_env%xalmo_update_algorithm .NE. almo_scf_diag))) THEN
241 0 : CPABORT("ALMO smearing is currently implemented for DIAG algorithm only")
242 : END IF
243 4 : IF (qs_env%scf_control%smear%method .NE. smear_fermi_dirac) THEN
244 0 : CPABORT("Only Fermi-Dirac smearing is currently compatible with ALMO")
245 : END IF
246 4 : almo_scf_env%smear_e_temp = qs_env%scf_control%smear%electronic_temperature
247 4 : IF ((almo_scf_env%mat_distr_aos .NE. almo_mat_distr_molecular) .OR. &
248 : (almo_scf_env%domain_layout_mos .NE. almo_domain_layout_molecular)) THEN
249 0 : CPABORT("ALMO smearing was designed to work with molecular fragments only")
250 : END IF
251 : END IF
252 :
253 : ! convenient local varibales
254 116 : nspins = almo_scf_env%nspins
255 116 : nmols = almo_scf_env%nmolecules
256 116 : natoms = almo_scf_env%natoms
257 :
258 : ! Define groups: either atomic or molecular
259 116 : IF (almo_scf_env%domain_layout_mos == almo_domain_layout_molecular) THEN
260 116 : almo_scf_env%ndomains = almo_scf_env%nmolecules
261 : ELSE
262 0 : almo_scf_env%ndomains = almo_scf_env%natoms
263 : END IF
264 :
265 : ! allocate domain descriptors
266 116 : ndomains = almo_scf_env%ndomains
267 348 : ALLOCATE (almo_scf_env%domain_index_of_atom(natoms))
268 348 : ALLOCATE (almo_scf_env%domain_index_of_ao(naos))
269 348 : ALLOCATE (almo_scf_env%first_atom_of_domain(ndomains))
270 348 : ALLOCATE (almo_scf_env%last_atom_of_domain(ndomains))
271 348 : ALLOCATE (almo_scf_env%nbasis_of_domain(ndomains))
272 464 : ALLOCATE (almo_scf_env%nocc_of_domain(ndomains, nspins)) !! with smearing, nb of available orbitals for occupation
273 464 : ALLOCATE (almo_scf_env%real_ne_of_domain(ndomains, nspins)) !! with smearing, nb of fully-occupied orbitals
274 464 : ALLOCATE (almo_scf_env%nvirt_full_of_domain(ndomains, nspins))
275 464 : ALLOCATE (almo_scf_env%nvirt_of_domain(ndomains, nspins))
276 464 : ALLOCATE (almo_scf_env%nvirt_disc_of_domain(ndomains, nspins))
277 464 : ALLOCATE (almo_scf_env%mu_of_domain(ndomains, nspins))
278 348 : ALLOCATE (almo_scf_env%cpu_of_domain(ndomains))
279 348 : ALLOCATE (almo_scf_env%charge_of_domain(ndomains))
280 348 : ALLOCATE (almo_scf_env%multiplicity_of_domain(ndomains))
281 :
282 : ! fill out domain descriptors and group descriptors
283 116 : IF (almo_scf_env%domain_layout_mos == almo_domain_layout_molecular) THEN
284 : ! get domain info from molecule_set
285 : CALL get_molecule_set_info(molecule_set, &
286 : atom_to_mol=almo_scf_env%domain_index_of_atom, &
287 : mol_to_first_atom=almo_scf_env%first_atom_of_domain, &
288 : mol_to_last_atom=almo_scf_env%last_atom_of_domain, &
289 : mol_to_nelectrons=almo_scf_env%nocc_of_domain(1:ndomains, 1), &
290 : mol_to_nbasis=almo_scf_env%nbasis_of_domain, &
291 : mol_to_charge=almo_scf_env%charge_of_domain, &
292 116 : mol_to_multiplicity=almo_scf_env%multiplicity_of_domain)
293 : ! calculate number of alpha and beta occupied orbitals from
294 : ! the number of electrons and multiplicity of each molecule
295 : ! Na + Nb = Ne
296 : ! Na - Nb = Mult - 1 (assume Na > Nb as we do not have more info from get_molecule_set_info)
297 926 : DO idomain = 1, ndomains
298 810 : nelec = almo_scf_env%nocc_of_domain(idomain, 1)
299 810 : multip = almo_scf_env%multiplicity_of_domain(idomain)
300 810 : nelec_a = (nelec + multip - 1)/2
301 810 : nelec_b = nelec - nelec_a
302 : !! Initializing an occupation-rescaling trick if smearing is on
303 926 : IF (almo_scf_env%smear) THEN
304 8 : IF (multip .GT. 1) THEN
305 2 : CPWARN("BEWARE: Non singlet state detected, treating it as closed-shell")
306 : END IF
307 : !! Save real number of electrons of each spin, as it is required for Fermi-dirac smearing
308 : !! BEWARE : Non singlet states are allowed but treated as closed-shell
309 16 : almo_scf_env%real_ne_of_domain(idomain, :) = REAL(nelec, KIND=dp)/2.0_dp
310 : !! Add a number of added_mos equal to the number of atoms in domain
311 : !! (since fragments were computed this way with smearing)
312 : almo_scf_env%nocc_of_domain(idomain, :) = CEILING(almo_scf_env%real_ne_of_domain(idomain, :)) &
313 : + (almo_scf_env%last_atom_of_domain(idomain) &
314 16 : - almo_scf_env%first_atom_of_domain(idomain) + 1)
315 : ELSE
316 802 : almo_scf_env%nocc_of_domain(idomain, 1) = nelec_a
317 802 : IF (nelec_a .NE. nelec_b) THEN
318 0 : IF (nspins .EQ. 1) THEN
319 0 : WRITE (*, *) "Domain ", idomain, " out of ", ndomains, ". Electrons = ", nelec
320 0 : CPABORT("odd e- -- use unrestricted methods")
321 : END IF
322 0 : almo_scf_env%nocc_of_domain(idomain, 2) = nelec_b
323 : ! RZK-warning: open-shell procedures have not been tested yet
324 : ! Stop the program now
325 0 : CPABORT("Unrestricted ALMO methods are NYI")
326 : END IF
327 : END IF
328 : END DO
329 232 : DO ispin = 1, nspins
330 : ! take care of the full virtual subspace
331 : almo_scf_env%nvirt_full_of_domain(:, ispin) = &
332 : almo_scf_env%nbasis_of_domain(:) - &
333 926 : almo_scf_env%nocc_of_domain(:, ispin)
334 : ! and the truncated virtual subspace
335 116 : SELECT CASE (almo_scf_env%deloc_truncate_virt)
336 : CASE (virt_full)
337 : almo_scf_env%nvirt_of_domain(:, ispin) = &
338 926 : almo_scf_env%nvirt_full_of_domain(:, ispin)
339 926 : almo_scf_env%nvirt_disc_of_domain(:, ispin) = 0
340 : CASE (virt_number)
341 0 : DO idomain = 1, ndomains
342 : almo_scf_env%nvirt_of_domain(idomain, ispin) = &
343 : MIN(almo_scf_env%deloc_virt_per_domain, &
344 0 : almo_scf_env%nvirt_full_of_domain(idomain, ispin))
345 : almo_scf_env%nvirt_disc_of_domain(idomain, ispin) = &
346 : almo_scf_env%nvirt_full_of_domain(idomain, ispin) - &
347 0 : almo_scf_env%nvirt_of_domain(idomain, ispin)
348 : END DO
349 : CASE (virt_occ_size)
350 0 : DO idomain = 1, ndomains
351 : almo_scf_env%nvirt_of_domain(idomain, ispin) = &
352 : MIN(almo_scf_env%nocc_of_domain(idomain, ispin), &
353 0 : almo_scf_env%nvirt_full_of_domain(idomain, ispin))
354 : almo_scf_env%nvirt_disc_of_domain(idomain, ispin) = &
355 : almo_scf_env%nvirt_full_of_domain(idomain, ispin) - &
356 0 : almo_scf_env%nvirt_of_domain(idomain, ispin)
357 : END DO
358 : CASE DEFAULT
359 116 : CPABORT("illegal method for virtual space truncation")
360 : END SELECT
361 : END DO ! spin
362 : ELSE ! domains are atomic
363 : ! RZK-warning do the same for atomic domains/groups
364 0 : almo_scf_env%domain_index_of_atom(1:natoms) = (/(i, i=1, natoms)/)
365 : END IF
366 :
367 116 : ao = 1
368 926 : DO idomain = 1, ndomains
369 9252 : DO iao = 1, almo_scf_env%nbasis_of_domain(idomain)
370 8326 : almo_scf_env%domain_index_of_ao(ao) = idomain
371 9136 : ao = ao + 1
372 : END DO
373 : END DO
374 :
375 1042 : almo_scf_env%mu_of_domain(:, :) = almo_scf_env%mu
376 :
377 : ! build domain (i.e. layout) indices for distribution blocks
378 : ! ao blocks
379 116 : IF (almo_scf_env%mat_distr_aos == almo_mat_distr_atomic) THEN
380 0 : ALLOCATE (almo_scf_env%domain_index_of_ao_block(natoms))
381 : almo_scf_env%domain_index_of_ao_block(:) = &
382 0 : almo_scf_env%domain_index_of_atom(:)
383 116 : ELSE IF (almo_scf_env%mat_distr_aos == almo_mat_distr_molecular) THEN
384 348 : ALLOCATE (almo_scf_env%domain_index_of_ao_block(nmols))
385 : ! if distr blocks are molecular then domain layout is also molecular
386 1736 : almo_scf_env%domain_index_of_ao_block(:) = (/(i, i=1, nmols)/)
387 : END IF
388 : ! mo blocks
389 116 : IF (almo_scf_env%mat_distr_mos == almo_mat_distr_atomic) THEN
390 0 : ALLOCATE (almo_scf_env%domain_index_of_mo_block(natoms))
391 : almo_scf_env%domain_index_of_mo_block(:) = &
392 0 : almo_scf_env%domain_index_of_atom(:)
393 116 : ELSE IF (almo_scf_env%mat_distr_mos == almo_mat_distr_molecular) THEN
394 348 : ALLOCATE (almo_scf_env%domain_index_of_mo_block(nmols))
395 : ! if distr blocks are molecular then domain layout is also molecular
396 1736 : almo_scf_env%domain_index_of_mo_block(:) = (/(i, i=1, nmols)/)
397 : END IF
398 :
399 : ! set all flags
400 : !almo_scf_env%need_previous_ks=.FALSE.
401 : !IF (almo_scf_env%deloc_method==almo_deloc_harris) THEN
402 116 : almo_scf_env%need_previous_ks = .TRUE.
403 : !ENDIF
404 :
405 : !almo_scf_env%need_virtuals=.FALSE.
406 : !almo_scf_env%need_orbital_energies=.FALSE.
407 : !IF (almo_scf_env%almo_update_algorithm==almo_scf_diag) THEN
408 116 : almo_scf_env%need_virtuals = .TRUE.
409 116 : almo_scf_env%need_orbital_energies = .TRUE.
410 : !ENDIF
411 :
412 116 : almo_scf_env%calc_forces = calc_forces
413 116 : IF (calc_forces) THEN
414 66 : CALL cite_reference(Scheiber2018)
415 : IF (almo_scf_env%deloc_method .EQ. almo_deloc_x .OR. &
416 66 : almo_scf_env%deloc_method .EQ. almo_deloc_xalmo_x .OR. &
417 : almo_scf_env%deloc_method .EQ. almo_deloc_xalmo_1diag) THEN
418 0 : CPABORT("Forces for perturbative methods are NYI. Change DELOCALIZE_METHOD")
419 : END IF
420 : ! switch to ASPC after a certain number of exact steps is done
421 66 : IF (almo_scf_env%almo_history%istore .GT. (almo_scf_env%almo_history%nstore + 1)) THEN
422 2 : IF (almo_scf_env%opt_block_diag_pcg%eps_error_early .GT. 0.0_dp) THEN
423 0 : almo_scf_env%opt_block_diag_pcg%eps_error = almo_scf_env%opt_block_diag_pcg%eps_error_early
424 0 : almo_scf_env%opt_block_diag_pcg%early_stopping_on = .TRUE.
425 0 : IF (unit_nr > 0) WRITE (*, *) "ALMO_OPTIMIZER_PCG: EPS_ERROR_EARLY is on"
426 : END IF
427 2 : IF (almo_scf_env%opt_block_diag_diis%eps_error_early .GT. 0.0_dp) THEN
428 0 : almo_scf_env%opt_block_diag_diis%eps_error = almo_scf_env%opt_block_diag_diis%eps_error_early
429 0 : almo_scf_env%opt_block_diag_diis%early_stopping_on = .TRUE.
430 0 : IF (unit_nr > 0) WRITE (*, *) "ALMO_OPTIMIZER_DIIS: EPS_ERROR_EARLY is on"
431 : END IF
432 2 : IF (almo_scf_env%opt_block_diag_pcg%max_iter_early .GT. 0) THEN
433 0 : almo_scf_env%opt_block_diag_pcg%max_iter = almo_scf_env%opt_block_diag_pcg%max_iter_early
434 0 : almo_scf_env%opt_block_diag_pcg%early_stopping_on = .TRUE.
435 0 : IF (unit_nr > 0) WRITE (*, *) "ALMO_OPTIMIZER_PCG: MAX_ITER_EARLY is on"
436 : END IF
437 2 : IF (almo_scf_env%opt_block_diag_diis%max_iter_early .GT. 0) THEN
438 0 : almo_scf_env%opt_block_diag_diis%max_iter = almo_scf_env%opt_block_diag_diis%max_iter_early
439 0 : almo_scf_env%opt_block_diag_diis%early_stopping_on = .TRUE.
440 0 : IF (unit_nr > 0) WRITE (*, *) "ALMO_OPTIMIZER_DIIS: MAX_ITER_EARLY is on"
441 : END IF
442 : ELSE
443 64 : almo_scf_env%opt_block_diag_diis%early_stopping_on = .FALSE.
444 64 : almo_scf_env%opt_block_diag_pcg%early_stopping_on = .FALSE.
445 : END IF
446 66 : IF (almo_scf_env%xalmo_history%istore .GT. (almo_scf_env%xalmo_history%nstore + 1)) THEN
447 4 : IF (almo_scf_env%opt_xalmo_pcg%eps_error_early .GT. 0.0_dp) THEN
448 0 : almo_scf_env%opt_xalmo_pcg%eps_error = almo_scf_env%opt_xalmo_pcg%eps_error_early
449 0 : almo_scf_env%opt_xalmo_pcg%early_stopping_on = .TRUE.
450 0 : IF (unit_nr > 0) WRITE (*, *) "XALMO_OPTIMIZER_PCG: EPS_ERROR_EARLY is on"
451 : END IF
452 4 : IF (almo_scf_env%opt_xalmo_pcg%max_iter_early .GT. 0.0_dp) THEN
453 0 : almo_scf_env%opt_xalmo_pcg%max_iter = almo_scf_env%opt_xalmo_pcg%max_iter_early
454 0 : almo_scf_env%opt_xalmo_pcg%early_stopping_on = .TRUE.
455 0 : IF (unit_nr > 0) WRITE (*, *) "XALMO_OPTIMIZER_PCG: MAX_ITER_EARLY is on"
456 : END IF
457 : ELSE
458 62 : almo_scf_env%opt_xalmo_pcg%early_stopping_on = .FALSE.
459 : END IF
460 : END IF
461 :
462 : ! create all matrices
463 116 : CALL almo_scf_env_create_matrices(almo_scf_env, matrix_s(1)%matrix)
464 :
465 : ! set up matrix S and all required functions of S
466 116 : almo_scf_env%s_inv_done = .FALSE.
467 116 : almo_scf_env%s_sqrt_done = .FALSE.
468 116 : CALL almo_scf_init_ao_overlap(matrix_s(1)%matrix, almo_scf_env)
469 :
470 : ! create the quencher (imposes sparsity template)
471 116 : CALL almo_scf_construct_quencher(qs_env, almo_scf_env)
472 116 : CALL distribute_domains(almo_scf_env)
473 :
474 : ! FINISH setting job parameters here, print out job info
475 116 : CALL almo_scf_print_job_info(almo_scf_env, unit_nr)
476 :
477 : ! allocate and init the domain preconditioner
478 1390 : ALLOCATE (almo_scf_env%domain_preconditioner(ndomains, nspins))
479 116 : CALL init_submatrices(almo_scf_env%domain_preconditioner)
480 :
481 : ! allocate and init projected KS for domains
482 1390 : ALLOCATE (almo_scf_env%domain_ks_xx(ndomains, nspins))
483 116 : CALL init_submatrices(almo_scf_env%domain_ks_xx)
484 :
485 : ! init ao-overlap subblocks
486 1390 : ALLOCATE (almo_scf_env%domain_s_inv(ndomains, nspins))
487 116 : CALL init_submatrices(almo_scf_env%domain_s_inv)
488 1390 : ALLOCATE (almo_scf_env%domain_s_sqrt_inv(ndomains, nspins))
489 116 : CALL init_submatrices(almo_scf_env%domain_s_sqrt_inv)
490 1390 : ALLOCATE (almo_scf_env%domain_s_sqrt(ndomains, nspins))
491 116 : CALL init_submatrices(almo_scf_env%domain_s_sqrt)
492 1390 : ALLOCATE (almo_scf_env%domain_t(ndomains, nspins))
493 116 : CALL init_submatrices(almo_scf_env%domain_t)
494 1390 : ALLOCATE (almo_scf_env%domain_err(ndomains, nspins))
495 116 : CALL init_submatrices(almo_scf_env%domain_err)
496 1390 : ALLOCATE (almo_scf_env%domain_r_down_up(ndomains, nspins))
497 116 : CALL init_submatrices(almo_scf_env%domain_r_down_up)
498 :
499 : ! initialization of the KS matrix
500 : CALL init_almo_ks_matrix_via_qs(qs_env, &
501 : almo_scf_env%matrix_ks, &
502 : almo_scf_env%mat_distr_aos, &
503 116 : almo_scf_env%eps_filter)
504 116 : CALL construct_qs_mos(qs_env, almo_scf_env)
505 :
506 116 : CALL timestop(handle)
507 :
508 232 : END SUBROUTINE almo_scf_init
509 :
510 : ! **************************************************************************************************
511 : !> \brief create the scf initial guess for ALMOs
512 : !> \param qs_env ...
513 : !> \param almo_scf_env ...
514 : !> \par History
515 : !> 2016.11 created [Rustam Z Khaliullin]
516 : !> 2018.09 smearing support [Ruben Staub]
517 : !> \author Rustam Z Khaliullin
518 : ! **************************************************************************************************
519 116 : SUBROUTINE almo_scf_initial_guess(qs_env, almo_scf_env)
520 : TYPE(qs_environment_type), POINTER :: qs_env
521 : TYPE(almo_scf_env_type), INTENT(INOUT) :: almo_scf_env
522 :
523 : CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_initial_guess'
524 :
525 : CHARACTER(LEN=default_path_length) :: file_name, project_name
526 : INTEGER :: handle, iaspc, ispin, istore, naspc, &
527 : nspins, unit_nr
528 : INTEGER, DIMENSION(2) :: nelectron_spin
529 : LOGICAL :: aspc_guess, has_unit_metric
530 : REAL(KIND=dp) :: alpha, cs_pos, energy, kTS_sum
531 116 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
532 : TYPE(cp_logger_type), POINTER :: logger
533 : TYPE(dbcsr_distribution_type) :: dist
534 116 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s, rho_ao
535 : TYPE(dft_control_type), POINTER :: dft_control
536 : TYPE(molecular_scf_guess_env_type), POINTER :: mscfg_env
537 : TYPE(mp_para_env_type), POINTER :: para_env
538 116 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
539 116 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
540 : TYPE(qs_rho_type), POINTER :: rho
541 :
542 116 : CALL timeset(routineN, handle)
543 :
544 116 : NULLIFY (rho, rho_ao)
545 :
546 : ! get a useful output_unit
547 116 : logger => cp_get_default_logger()
548 116 : IF (logger%para_env%is_source()) THEN
549 58 : unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
550 : ELSE
551 58 : unit_nr = -1
552 : END IF
553 :
554 : ! get basic quantities from the qs_env
555 : CALL get_qs_env(qs_env, &
556 : dft_control=dft_control, &
557 : matrix_s=matrix_s, &
558 : atomic_kind_set=atomic_kind_set, &
559 : qs_kind_set=qs_kind_set, &
560 : particle_set=particle_set, &
561 : has_unit_metric=has_unit_metric, &
562 : para_env=para_env, &
563 : nelectron_spin=nelectron_spin, &
564 : mscfg_env=mscfg_env, &
565 116 : rho=rho)
566 :
567 116 : CALL qs_rho_get(rho, rho_ao=rho_ao)
568 116 : CPASSERT(ASSOCIATED(mscfg_env))
569 :
570 : ! initial guess on the first simulation step is determined by almo_scf_env%almo_scf_guess
571 : ! the subsequent simulation steps are determined by extrapolation_order
572 : ! if extrapolation order is zero then again almo_scf_env%almo_scf_guess is used
573 : ! ... the number of stored history points will remain zero if extrapolation order is zero
574 116 : IF (almo_scf_env%almo_history%istore == 0) THEN
575 : aspc_guess = .FALSE.
576 : ELSE
577 46 : aspc_guess = .TRUE.
578 : END IF
579 :
580 116 : nspins = almo_scf_env%nspins
581 :
582 : ! create an initial guess
583 116 : IF (.NOT. aspc_guess) THEN
584 :
585 80 : SELECT CASE (almo_scf_env%almo_scf_guess)
586 : CASE (molecular_guess)
587 :
588 20 : DO ispin = 1, nspins
589 :
590 : ! the calculations on "isolated" molecules has already been done
591 : ! all we need to do is convert the MOs of molecules into
592 : ! the ALMO matrix taking into account different distributions
593 : CALL get_matrix_from_submatrices(mscfg_env, &
594 10 : almo_scf_env%matrix_t_blk(ispin), ispin)
595 : CALL dbcsr_filter(almo_scf_env%matrix_t_blk(ispin), &
596 20 : almo_scf_env%eps_filter)
597 :
598 : END DO
599 :
600 : CASE (atomic_guess)
601 :
602 60 : IF (dft_control%qs_control%dftb .OR. dft_control%qs_control%semi_empirical .OR. &
603 : dft_control%qs_control%xtb) THEN
604 : CALL calculate_mopac_dm(rho_ao, &
605 : matrix_s(1)%matrix, has_unit_metric, &
606 : dft_control, particle_set, atomic_kind_set, qs_kind_set, &
607 : nspins, nelectron_spin, &
608 0 : para_env)
609 : ELSE
610 : CALL calculate_atomic_block_dm(rho_ao, matrix_s(1)%matrix, atomic_kind_set, qs_kind_set, &
611 60 : nspins, nelectron_spin, unit_nr, para_env)
612 : END IF
613 :
614 120 : DO ispin = 1, nspins
615 : ! copy the atomic-block dm into matrix_p_blk
616 : CALL matrix_qs_to_almo(rho_ao(ispin)%matrix, &
617 : almo_scf_env%matrix_p_blk(ispin), almo_scf_env%mat_distr_aos, &
618 60 : .FALSE.)
619 : CALL dbcsr_filter(almo_scf_env%matrix_p_blk(ispin), &
620 120 : almo_scf_env%eps_filter)
621 : END DO ! ispin
622 :
623 : ! obtain orbitals from the density matrix
624 : ! (the current version of ALMO SCF needs orbitals)
625 60 : CALL almo_scf_p_blk_to_t_blk(almo_scf_env, ionic=.FALSE.)
626 :
627 : CASE (restart_guess)
628 :
629 0 : project_name = logger%iter_info%project_name
630 :
631 70 : DO ispin = 1, nspins
632 0 : WRITE (file_name, '(A,I0,A)') TRIM(project_name)//"_ALMO_SPIN_", ispin, "_RESTART.mo"
633 0 : CALL dbcsr_get_info(almo_scf_env%matrix_t_blk(ispin), distribution=dist)
634 0 : CALL dbcsr_binary_read(file_name, distribution=dist, matrix_new=almo_scf_env%matrix_t_blk(ispin))
635 0 : cs_pos = dbcsr_checksum(almo_scf_env%matrix_t_blk(ispin), pos=.TRUE.)
636 0 : IF (unit_nr > 0) THEN
637 0 : WRITE (unit_nr, '(T2,A,E20.8)') "Read restart ALMO "//TRIM(file_name)//" with checksum: ", cs_pos
638 : END IF
639 : END DO
640 : END SELECT
641 :
642 : ELSE !aspc_guess
643 :
644 46 : CALL cite_reference(Kolafa2004)
645 46 : CALL cite_reference(Kuhne2007)
646 :
647 46 : naspc = MIN(almo_scf_env%almo_history%istore, almo_scf_env%almo_history%nstore)
648 46 : IF (unit_nr > 0) THEN
649 : WRITE (unit_nr, FMT="(/,T2,A,/,/,T3,A,I0)") &
650 23 : "Parameters for the always stable predictor-corrector (ASPC) method:", &
651 46 : "ASPC order: ", naspc
652 : END IF
653 :
654 92 : DO ispin = 1, nspins
655 :
656 : ! extrapolation
657 186 : DO iaspc = 1, naspc
658 94 : istore = MOD(almo_scf_env%almo_history%istore - iaspc, almo_scf_env%almo_history%nstore) + 1
659 : alpha = (-1.0_dp)**(iaspc + 1)*REAL(iaspc, KIND=dp)* &
660 94 : binomial(2*naspc, naspc - iaspc)/binomial(2*naspc - 2, naspc - 1)
661 94 : IF (unit_nr > 0) THEN
662 : WRITE (unit_nr, FMT="(T3,A2,I0,A4,F10.6)") &
663 47 : "B(", iaspc, ") = ", alpha
664 : END IF
665 140 : IF (iaspc == 1) THEN
666 : CALL dbcsr_copy(almo_scf_env%matrix_t_blk(ispin), &
667 : almo_scf_env%almo_history%matrix_t(ispin), &
668 46 : keep_sparsity=.TRUE.)
669 46 : CALL dbcsr_scale(almo_scf_env%matrix_t_blk(ispin), alpha)
670 : ELSE
671 : CALL dbcsr_multiply("N", "N", alpha, &
672 : almo_scf_env%almo_history%matrix_p_up_down(ispin, istore), &
673 : almo_scf_env%almo_history%matrix_t(ispin), &
674 : 1.0_dp, almo_scf_env%matrix_t_blk(ispin), &
675 48 : retain_sparsity=.TRUE.)
676 : END IF
677 : END DO !iaspc
678 :
679 : END DO !ispin
680 :
681 : END IF !aspc_guess?
682 :
683 232 : DO ispin = 1, nspins
684 :
685 : CALL orthogonalize_mos(ket=almo_scf_env%matrix_t_blk(ispin), &
686 : overlap=almo_scf_env%matrix_sigma_blk(ispin), &
687 : metric=almo_scf_env%matrix_s_blk(1), &
688 : retain_locality=.TRUE., &
689 : only_normalize=.FALSE., &
690 : nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
691 : eps_filter=almo_scf_env%eps_filter, &
692 : order_lanczos=almo_scf_env%order_lanczos, &
693 : eps_lanczos=almo_scf_env%eps_lanczos, &
694 116 : max_iter_lanczos=almo_scf_env%max_iter_lanczos)
695 :
696 : !! Application of an occupation-rescaling trick for smearing, if requested
697 116 : IF (almo_scf_env%smear) THEN
698 : CALL almo_scf_t_rescaling(matrix_t=almo_scf_env%matrix_t_blk(ispin), &
699 : mo_energies=almo_scf_env%mo_energies(:, ispin), &
700 : mu_of_domain=almo_scf_env%mu_of_domain(:, ispin), &
701 : real_ne_of_domain=almo_scf_env%real_ne_of_domain(:, ispin), &
702 : spin_kTS=almo_scf_env%kTS(ispin), &
703 : smear_e_temp=almo_scf_env%smear_e_temp, &
704 : ndomains=almo_scf_env%ndomains, &
705 4 : nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin))
706 : END IF
707 :
708 : CALL almo_scf_t_to_proj(t=almo_scf_env%matrix_t_blk(ispin), &
709 : p=almo_scf_env%matrix_p(ispin), &
710 : eps_filter=almo_scf_env%eps_filter, &
711 : orthog_orbs=.FALSE., &
712 : nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
713 : s=almo_scf_env%matrix_s(1), &
714 : sigma=almo_scf_env%matrix_sigma(ispin), &
715 : sigma_inv=almo_scf_env%matrix_sigma_inv(ispin), &
716 : use_guess=.FALSE., &
717 : smear=almo_scf_env%smear, &
718 : algorithm=almo_scf_env%sigma_inv_algorithm, &
719 : eps_lanczos=almo_scf_env%eps_lanczos, &
720 : max_iter_lanczos=almo_scf_env%max_iter_lanczos, &
721 : inv_eps_factor=almo_scf_env%matrix_iter_eps_error_factor, &
722 : para_env=almo_scf_env%para_env, &
723 232 : blacs_env=almo_scf_env%blacs_env)
724 :
725 : END DO
726 :
727 : ! compute dm from the projector(s)
728 116 : IF (nspins == 1) THEN
729 116 : CALL dbcsr_scale(almo_scf_env%matrix_p(1), 2.0_dp)
730 : !! Rescaling electronic entropy contribution by spin_factor
731 116 : IF (almo_scf_env%smear) THEN
732 4 : almo_scf_env%kTS(1) = almo_scf_env%kTS(1)*2.0_dp
733 : END IF
734 : END IF
735 :
736 116 : IF (almo_scf_env%smear) THEN
737 8 : kTS_sum = SUM(almo_scf_env%kTS)
738 : ELSE
739 112 : kTS_sum = 0.0_dp
740 : END IF
741 :
742 : CALL almo_dm_to_almo_ks(qs_env, &
743 : almo_scf_env%matrix_p, &
744 : almo_scf_env%matrix_ks, &
745 : energy, &
746 : almo_scf_env%eps_filter, &
747 : almo_scf_env%mat_distr_aos, &
748 : smear=almo_scf_env%smear, &
749 116 : kTS_sum=kTS_sum)
750 :
751 116 : IF (unit_nr > 0) THEN
752 58 : IF (almo_scf_env%almo_scf_guess .EQ. molecular_guess) THEN
753 5 : WRITE (unit_nr, '(T2,A38,F40.10)') "Single-molecule energy:", &
754 26 : SUM(mscfg_env%energy_of_frag)
755 : END IF
756 58 : WRITE (unit_nr, '(T2,A38,F40.10)') "Energy of the initial guess:", energy
757 58 : WRITE (unit_nr, '()')
758 : END IF
759 :
760 116 : CALL timestop(handle)
761 :
762 116 : END SUBROUTINE almo_scf_initial_guess
763 :
764 : ! **************************************************************************************************
765 : !> \brief store a history of matrices for later use in almo_scf_initial_guess
766 : !> \param almo_scf_env ...
767 : !> \par History
768 : !> 2016.11 created [Rustam Z Khaliullin]
769 : !> \author Rustam Khaliullin
770 : ! **************************************************************************************************
771 116 : SUBROUTINE almo_scf_store_extrapolation_data(almo_scf_env)
772 : TYPE(almo_scf_env_type), INTENT(INOUT) :: almo_scf_env
773 :
774 : CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_store_extrapolation_data'
775 :
776 : INTEGER :: handle, ispin, istore, unit_nr
777 : LOGICAL :: delocalization_uses_extrapolation
778 : TYPE(cp_logger_type), POINTER :: logger
779 : TYPE(dbcsr_type) :: matrix_no_tmp1, matrix_no_tmp2, &
780 : matrix_no_tmp3, matrix_no_tmp4
781 :
782 116 : CALL timeset(routineN, handle)
783 :
784 : ! get a useful output_unit
785 116 : logger => cp_get_default_logger()
786 116 : IF (logger%para_env%is_source()) THEN
787 58 : unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
788 : ELSE
789 : unit_nr = -1
790 : END IF
791 :
792 116 : IF (almo_scf_env%almo_history%nstore > 0) THEN
793 :
794 110 : almo_scf_env%almo_history%istore = almo_scf_env%almo_history%istore + 1
795 :
796 220 : DO ispin = 1, SIZE(almo_scf_env%matrix_t_blk)
797 :
798 110 : istore = MOD(almo_scf_env%almo_history%istore - 1, almo_scf_env%almo_history%nstore) + 1
799 :
800 110 : IF (almo_scf_env%almo_history%istore == 1) THEN
801 : CALL dbcsr_create(almo_scf_env%almo_history%matrix_t(ispin), &
802 : template=almo_scf_env%matrix_t_blk(ispin), &
803 64 : matrix_type=dbcsr_type_no_symmetry)
804 : END IF
805 : CALL dbcsr_copy(almo_scf_env%almo_history%matrix_t(ispin), &
806 110 : almo_scf_env%matrix_t_blk(ispin))
807 :
808 110 : IF (almo_scf_env%almo_history%istore <= almo_scf_env%almo_history%nstore) THEN
809 : CALL dbcsr_create(almo_scf_env%almo_history%matrix_p_up_down(ispin, istore), &
810 : template=almo_scf_env%matrix_s(1), &
811 88 : matrix_type=dbcsr_type_no_symmetry)
812 : END IF
813 :
814 : CALL dbcsr_create(matrix_no_tmp1, template=almo_scf_env%matrix_t_blk(ispin), &
815 110 : matrix_type=dbcsr_type_no_symmetry)
816 : CALL dbcsr_create(matrix_no_tmp2, template=almo_scf_env%matrix_t_blk(ispin), &
817 110 : matrix_type=dbcsr_type_no_symmetry)
818 :
819 : ! compute contra-covariant density matrix
820 : CALL dbcsr_multiply("N", "N", 1.0_dp, almo_scf_env%matrix_s(1), &
821 : almo_scf_env%matrix_t_blk(ispin), &
822 : 0.0_dp, matrix_no_tmp1, &
823 110 : filter_eps=almo_scf_env%eps_filter)
824 : CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_no_tmp1, &
825 : almo_scf_env%matrix_sigma_inv_0deloc(ispin), &
826 : 0.0_dp, matrix_no_tmp2, &
827 110 : filter_eps=almo_scf_env%eps_filter)
828 : CALL dbcsr_multiply("N", "T", 1.0_dp, &
829 : almo_scf_env%matrix_t_blk(ispin), &
830 : matrix_no_tmp2, &
831 : 0.0_dp, almo_scf_env%almo_history%matrix_p_up_down(ispin, istore), &
832 110 : filter_eps=almo_scf_env%eps_filter)
833 :
834 110 : CALL dbcsr_release(matrix_no_tmp1)
835 220 : CALL dbcsr_release(matrix_no_tmp2)
836 :
837 : END DO
838 :
839 : END IF
840 :
841 : ! exrapolate xalmos?
842 : delocalization_uses_extrapolation = &
843 : .NOT. ((almo_scf_env%deloc_method .EQ. almo_deloc_none) .OR. &
844 116 : (almo_scf_env%deloc_method .EQ. almo_deloc_xalmo_1diag))
845 116 : IF (almo_scf_env%xalmo_history%nstore > 0 .AND. &
846 : delocalization_uses_extrapolation) THEN
847 :
848 44 : almo_scf_env%xalmo_history%istore = almo_scf_env%xalmo_history%istore + 1
849 :
850 88 : DO ispin = 1, SIZE(almo_scf_env%matrix_t)
851 :
852 44 : istore = MOD(almo_scf_env%xalmo_history%istore - 1, almo_scf_env%xalmo_history%nstore) + 1
853 :
854 44 : IF (almo_scf_env%xalmo_history%istore == 1) THEN
855 : CALL dbcsr_create(almo_scf_env%xalmo_history%matrix_t(ispin), &
856 : template=almo_scf_env%matrix_t(ispin), &
857 10 : matrix_type=dbcsr_type_no_symmetry)
858 : END IF
859 : CALL dbcsr_copy(almo_scf_env%xalmo_history%matrix_t(ispin), &
860 44 : almo_scf_env%matrix_t(ispin))
861 :
862 44 : IF (almo_scf_env%xalmo_history%istore <= almo_scf_env%xalmo_history%nstore) THEN
863 : !CALL dbcsr_init(almo_scf_env%xalmo_history%matrix_x(ispin, istore))
864 : !CALL dbcsr_create(almo_scf_env%xalmo_history%matrix_x(ispin, istore), &
865 : ! template=almo_scf_env%matrix_t(ispin), &
866 : ! matrix_type=dbcsr_type_no_symmetry)
867 : CALL dbcsr_create(almo_scf_env%xalmo_history%matrix_p_up_down(ispin, istore), &
868 : template=almo_scf_env%matrix_s(1), &
869 24 : matrix_type=dbcsr_type_no_symmetry)
870 : END IF
871 :
872 : CALL dbcsr_create(matrix_no_tmp3, template=almo_scf_env%matrix_t(ispin), &
873 44 : matrix_type=dbcsr_type_no_symmetry)
874 : CALL dbcsr_create(matrix_no_tmp4, template=almo_scf_env%matrix_t(ispin), &
875 44 : matrix_type=dbcsr_type_no_symmetry)
876 :
877 : ! compute contra-covariant density matrix
878 : CALL dbcsr_multiply("N", "N", 1.0_dp, almo_scf_env%matrix_s(1), &
879 : almo_scf_env%matrix_t(ispin), &
880 : 0.0_dp, matrix_no_tmp3, &
881 44 : filter_eps=almo_scf_env%eps_filter)
882 : CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_no_tmp3, &
883 : almo_scf_env%matrix_sigma_inv(ispin), &
884 : 0.0_dp, matrix_no_tmp4, &
885 44 : filter_eps=almo_scf_env%eps_filter)
886 : CALL dbcsr_multiply("N", "T", 1.0_dp, &
887 : almo_scf_env%matrix_t(ispin), &
888 : matrix_no_tmp4, &
889 : 0.0_dp, almo_scf_env%xalmo_history%matrix_p_up_down(ispin, istore), &
890 44 : filter_eps=almo_scf_env%eps_filter)
891 :
892 : ! store the difference between t and t0
893 : !CALL dbcsr_copy(almo_scf_env%xalmo_history%matrix_x(ispin, istore),&
894 : ! almo_scf_env%matrix_t(ispin))
895 : !CALL dbcsr_add(almo_scf_env%xalmo_history%matrix_x(ispin, istore),&
896 : ! almo_scf_env%matrix_t_blk(ispin),1.0_dp,-1.0_dp)
897 :
898 44 : CALL dbcsr_release(matrix_no_tmp3)
899 88 : CALL dbcsr_release(matrix_no_tmp4)
900 :
901 : END DO
902 :
903 : END IF
904 :
905 116 : CALL timestop(handle)
906 :
907 116 : END SUBROUTINE almo_scf_store_extrapolation_data
908 :
909 : ! **************************************************************************************************
910 : !> \brief Prints out a short summary about the ALMO SCF job
911 : !> \param almo_scf_env ...
912 : !> \param unit_nr ...
913 : !> \par History
914 : !> 2011.10 created [Rustam Z Khaliullin]
915 : !> \author Rustam Z Khaliullin
916 : ! **************************************************************************************************
917 116 : SUBROUTINE almo_scf_print_job_info(almo_scf_env, unit_nr)
918 :
919 : TYPE(almo_scf_env_type), INTENT(INOUT) :: almo_scf_env
920 : INTEGER, INTENT(IN) :: unit_nr
921 :
922 : CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_print_job_info'
923 :
924 : CHARACTER(len=13) :: neig_string
925 : CHARACTER(len=33) :: deloc_method_string
926 : INTEGER :: handle, idomain, index1_prev, sum_temp
927 116 : INTEGER, ALLOCATABLE, DIMENSION(:) :: nneighbors
928 :
929 116 : CALL timeset(routineN, handle)
930 :
931 116 : IF (unit_nr > 0) THEN
932 58 : WRITE (unit_nr, '()')
933 58 : WRITE (unit_nr, '(T2,A,A,A)') REPEAT("-", 32), " ALMO SETTINGS ", REPEAT("-", 32)
934 :
935 58 : WRITE (unit_nr, '(T2,A,T48,E33.3)') "eps_filter:", almo_scf_env%eps_filter
936 :
937 58 : IF (almo_scf_env%almo_update_algorithm .EQ. almo_scf_skip) THEN
938 17 : WRITE (unit_nr, '(T2,A)') "skip optimization of block-diagonal ALMOs"
939 : ELSE
940 41 : WRITE (unit_nr, '(T2,A)') "optimization of block-diagonal ALMOs:"
941 79 : SELECT CASE (almo_scf_env%almo_update_algorithm)
942 : CASE (almo_scf_diag)
943 : ! the DIIS algorith is the only choice for the diagonlaization-based algorithm
944 38 : CALL print_optimizer_options(almo_scf_env%opt_block_diag_diis, unit_nr)
945 : CASE (almo_scf_pcg)
946 : ! print out PCG options
947 2 : CALL print_optimizer_options(almo_scf_env%opt_block_diag_pcg, unit_nr)
948 : CASE (almo_scf_trustr)
949 : ! print out TRUST REGION options
950 41 : CALL print_optimizer_options(almo_scf_env%opt_block_diag_trustr, unit_nr)
951 : END SELECT
952 : END IF
953 :
954 73 : SELECT CASE (almo_scf_env%deloc_method)
955 : CASE (almo_deloc_none)
956 15 : deloc_method_string = "NONE"
957 : CASE (almo_deloc_x)
958 2 : deloc_method_string = "FULL_X"
959 : CASE (almo_deloc_scf)
960 6 : deloc_method_string = "FULL_SCF"
961 : CASE (almo_deloc_x_then_scf)
962 7 : deloc_method_string = "FULL_X_THEN_SCF"
963 : CASE (almo_deloc_xalmo_1diag)
964 1 : deloc_method_string = "XALMO_1DIAG"
965 : CASE (almo_deloc_xalmo_x)
966 3 : deloc_method_string = "XALMO_X"
967 : CASE (almo_deloc_xalmo_scf)
968 58 : deloc_method_string = "XALMO_SCF"
969 : END SELECT
970 58 : WRITE (unit_nr, '(T2,A,T48,A33)') "delocalization:", TRIM(deloc_method_string)
971 :
972 58 : IF (almo_scf_env%deloc_method .NE. almo_deloc_none) THEN
973 :
974 15 : SELECT CASE (almo_scf_env%deloc_method)
975 : CASE (almo_deloc_x, almo_deloc_scf, almo_deloc_x_then_scf)
976 15 : WRITE (unit_nr, '(T2,A,T48,A33)') "delocalization cutoff radius:", &
977 30 : "infinite"
978 15 : deloc_method_string = "FULL_X_THEN_SCF"
979 : CASE (almo_deloc_xalmo_1diag, almo_deloc_xalmo_x, almo_deloc_xalmo_scf)
980 28 : WRITE (unit_nr, '(T2,A,T48,F33.5)') "XALMO cutoff radius:", &
981 71 : almo_scf_env%quencher_r0_factor
982 : END SELECT
983 :
984 43 : IF (almo_scf_env%deloc_method .EQ. almo_deloc_xalmo_1diag) THEN
985 : ! print nothing because no actual optimization is done
986 : ELSE
987 42 : WRITE (unit_nr, '(T2,A)') "optimization of extended orbitals:"
988 42 : SELECT CASE (almo_scf_env%xalmo_update_algorithm)
989 : CASE (almo_scf_diag)
990 0 : CALL print_optimizer_options(almo_scf_env%opt_xalmo_diis, unit_nr)
991 : CASE (almo_scf_trustr)
992 8 : CALL print_optimizer_options(almo_scf_env%opt_xalmo_trustr, unit_nr)
993 : CASE (almo_scf_pcg)
994 42 : CALL print_optimizer_options(almo_scf_env%opt_xalmo_pcg, unit_nr)
995 : END SELECT
996 : END IF
997 :
998 : END IF
999 :
1000 : !SELECT CASE(almo_scf_env%domain_layout_mos)
1001 : !CASE(almo_domain_layout_orbital)
1002 : ! WRITE(unit_nr,'(T2,A,T48,A33)') "Delocalization constraints","ORBITAL"
1003 : !CASE(almo_domain_layout_atomic)
1004 : ! WRITE(unit_nr,'(T2,A,T48,A33)') "Delocalization constraints","ATOMIC"
1005 : !CASE(almo_domain_layout_molecular)
1006 : ! WRITE(unit_nr,'(T2,A,T48,A33)') "Delocalization constraints","MOLECULAR"
1007 : !END SELECT
1008 :
1009 : !SELECT CASE(almo_scf_env%domain_layout_aos)
1010 : !CASE(almo_domain_layout_atomic)
1011 : ! WRITE(unit_nr,'(T2,A,T48,A33)') "Basis function domains","ATOMIC"
1012 : !CASE(almo_domain_layout_molecular)
1013 : ! WRITE(unit_nr,'(T2,A,T48,A33)') "Basis function domains","MOLECULAR"
1014 : !END SELECT
1015 :
1016 : !SELECT CASE(almo_scf_env%mat_distr_aos)
1017 : !CASE(almo_mat_distr_atomic)
1018 : ! WRITE(unit_nr,'(T2,A,T48,A33)') "Parallel distribution for AOs","ATOMIC"
1019 : !CASE(almo_mat_distr_molecular)
1020 : ! WRITE(unit_nr,'(T2,A,T48,A33)') "Parallel distribution for AOs","MOLECULAR"
1021 : !END SELECT
1022 :
1023 : !SELECT CASE(almo_scf_env%mat_distr_mos)
1024 : !CASE(almo_mat_distr_atomic)
1025 : ! WRITE(unit_nr,'(T2,A,T48,A33)') "Parallel distribution for MOs","ATOMIC"
1026 : !CASE(almo_mat_distr_molecular)
1027 : ! WRITE(unit_nr,'(T2,A,T48,A33)') "Parallel distribution for MOs","MOLECULAR"
1028 : !END SELECT
1029 :
1030 : ! print fragment's statistics
1031 58 : WRITE (unit_nr, '(T2,A)') REPEAT("-", 79)
1032 58 : WRITE (unit_nr, '(T2,A,T48,I33)') "Total fragments:", &
1033 116 : almo_scf_env%ndomains
1034 :
1035 463 : sum_temp = SUM(almo_scf_env%nbasis_of_domain(:))
1036 : WRITE (unit_nr, '(T2,A,T53,I5,F9.2,I5,I9)') &
1037 58 : "Basis set size per fragment (min, av, max, total):", &
1038 463 : MINVAL(almo_scf_env%nbasis_of_domain(:)), &
1039 58 : (1.0_dp*sum_temp)/almo_scf_env%ndomains, &
1040 463 : MAXVAL(almo_scf_env%nbasis_of_domain(:)), &
1041 116 : sum_temp
1042 : !WRITE (unit_nr, '(T2,I13,F13.3,I13,I13)') &
1043 : ! MINVAL(almo_scf_env%nbasis_of_domain(:)), &
1044 : ! (1.0_dp*sum_temp) / almo_scf_env%ndomains, &
1045 : ! MAXVAL(almo_scf_env%nbasis_of_domain(:)), &
1046 : ! sum_temp
1047 :
1048 521 : sum_temp = SUM(almo_scf_env%nocc_of_domain(:, :))
1049 : WRITE (unit_nr, '(T2,A,T53,I5,F9.2,I5,I9)') &
1050 58 : "Occupied MOs per fragment (min, av, max, total):", &
1051 868 : MINVAL(SUM(almo_scf_env%nocc_of_domain, DIM=2)), &
1052 58 : (1.0_dp*sum_temp)/almo_scf_env%ndomains, &
1053 868 : MAXVAL(SUM(almo_scf_env%nocc_of_domain, DIM=2)), &
1054 116 : sum_temp
1055 : !WRITE (unit_nr, '(T2,I13,F13.3,I13,I13)') &
1056 : ! MINVAL( SUM(almo_scf_env%nocc_of_domain, DIM=2) ), &
1057 : ! (1.0_dp*sum_temp) / almo_scf_env%ndomains, &
1058 : ! MAXVAL( SUM(almo_scf_env%nocc_of_domain, DIM=2) ), &
1059 : ! sum_temp
1060 :
1061 521 : sum_temp = SUM(almo_scf_env%nvirt_of_domain(:, :))
1062 : WRITE (unit_nr, '(T2,A,T53,I5,F9.2,I5,I9)') &
1063 58 : "Virtual MOs per fragment (min, av, max, total):", &
1064 868 : MINVAL(SUM(almo_scf_env%nvirt_of_domain, DIM=2)), &
1065 58 : (1.0_dp*sum_temp)/almo_scf_env%ndomains, &
1066 868 : MAXVAL(SUM(almo_scf_env%nvirt_of_domain, DIM=2)), &
1067 116 : sum_temp
1068 : !WRITE (unit_nr, '(T2,I13,F13.3,I13,I13)') &
1069 : ! MINVAL( SUM(almo_scf_env%nvirt_of_domain, DIM=2) ), &
1070 : ! (1.0_dp*sum_temp) / almo_scf_env%ndomains, &
1071 : ! MAXVAL( SUM(almo_scf_env%nvirt_of_domain, DIM=2) ), &
1072 : ! sum_temp
1073 :
1074 463 : sum_temp = SUM(almo_scf_env%charge_of_domain(:))
1075 : WRITE (unit_nr, '(T2,A,T53,I5,F9.2,I5,I9)') &
1076 58 : "Charges per fragment (min, av, max, total):", &
1077 463 : MINVAL(almo_scf_env%charge_of_domain(:)), &
1078 58 : (1.0_dp*sum_temp)/almo_scf_env%ndomains, &
1079 463 : MAXVAL(almo_scf_env%charge_of_domain(:)), &
1080 116 : sum_temp
1081 : !WRITE (unit_nr, '(T2,I13,F13.3,I13,I13)') &
1082 : ! MINVAL(almo_scf_env%charge_of_domain(:)), &
1083 : ! (1.0_dp*sum_temp) / almo_scf_env%ndomains, &
1084 : ! MAXVAL(almo_scf_env%charge_of_domain(:)), &
1085 : ! sum_temp
1086 :
1087 : ! compute the number of neighbors of each fragment
1088 174 : ALLOCATE (nneighbors(almo_scf_env%ndomains))
1089 :
1090 463 : DO idomain = 1, almo_scf_env%ndomains
1091 :
1092 405 : IF (idomain .EQ. 1) THEN
1093 : index1_prev = 1
1094 : ELSE
1095 347 : index1_prev = almo_scf_env%domain_map(1)%index1(idomain - 1)
1096 : END IF
1097 :
1098 58 : SELECT CASE (almo_scf_env%deloc_method)
1099 : CASE (almo_deloc_none)
1100 108 : nneighbors(idomain) = 0
1101 : CASE (almo_deloc_x, almo_deloc_scf, almo_deloc_x_then_scf)
1102 113 : nneighbors(idomain) = almo_scf_env%ndomains - 1 ! minus self
1103 : CASE (almo_deloc_xalmo_1diag, almo_deloc_xalmo_x, almo_deloc_xalmo_scf)
1104 184 : nneighbors(idomain) = almo_scf_env%domain_map(1)%index1(idomain) - index1_prev - 1 ! minus self
1105 : CASE DEFAULT
1106 405 : nneighbors(idomain) = -1
1107 : END SELECT
1108 :
1109 : END DO ! cycle over domains
1110 :
1111 463 : sum_temp = SUM(nneighbors(:))
1112 : WRITE (unit_nr, '(T2,A,T53,I5,F9.2,I5,I9)') &
1113 58 : "Deloc. neighbors of fragment (min, av, max, total):", &
1114 463 : MINVAL(nneighbors(:)), &
1115 58 : (1.0_dp*sum_temp)/almo_scf_env%ndomains, &
1116 463 : MAXVAL(nneighbors(:)), &
1117 116 : sum_temp
1118 :
1119 58 : WRITE (unit_nr, '(T2,A)') REPEAT("-", 79)
1120 58 : WRITE (unit_nr, '()')
1121 :
1122 58 : IF (almo_scf_env%ndomains .LE. 64) THEN
1123 :
1124 : ! print fragment info
1125 : WRITE (unit_nr, '(T2,A10,A13,A13,A13,A13,A13)') &
1126 58 : "Fragment", "Basis Set", "Occupied", "Virtual", "Charge", "Deloc Neig" !,"Discarded Virt"
1127 58 : WRITE (unit_nr, '(T2,A)') REPEAT("-", 79)
1128 463 : DO idomain = 1, almo_scf_env%ndomains
1129 :
1130 513 : SELECT CASE (almo_scf_env%deloc_method)
1131 : CASE (almo_deloc_none)
1132 108 : neig_string = "NONE"
1133 : CASE (almo_deloc_x, almo_deloc_scf, almo_deloc_x_then_scf)
1134 113 : neig_string = "ALL"
1135 : CASE (almo_deloc_xalmo_1diag, almo_deloc_xalmo_x, almo_deloc_xalmo_scf)
1136 184 : WRITE (neig_string, '(I13)') nneighbors(idomain)
1137 : CASE DEFAULT
1138 405 : neig_string = "N/A"
1139 : END SELECT
1140 :
1141 : WRITE (unit_nr, '(T2,I10,I13,I13,I13,I13,A13)') &
1142 405 : idomain, almo_scf_env%nbasis_of_domain(idomain), &
1143 810 : SUM(almo_scf_env%nocc_of_domain(idomain, :)), &
1144 810 : SUM(almo_scf_env%nvirt_of_domain(idomain, :)), &
1145 : !SUM(almo_scf_env%nvirt_disc_of_domain(idomain,:)),&
1146 405 : almo_scf_env%charge_of_domain(idomain), &
1147 868 : ADJUSTR(TRIM(neig_string))
1148 :
1149 : END DO ! cycle over domains
1150 :
1151 86 : SELECT CASE (almo_scf_env%deloc_method)
1152 : CASE (almo_deloc_xalmo_1diag, almo_deloc_xalmo_x, almo_deloc_xalmo_scf)
1153 :
1154 28 : WRITE (unit_nr, '(T2,A)') REPEAT("-", 79)
1155 :
1156 : ! print fragment neighbors
1157 : WRITE (unit_nr, '(T2,A78)') &
1158 28 : "Neighbor lists (including self)"
1159 28 : WRITE (unit_nr, '(T2,A)') REPEAT("-", 79)
1160 270 : DO idomain = 1, almo_scf_env%ndomains
1161 :
1162 184 : IF (idomain .EQ. 1) THEN
1163 : index1_prev = 1
1164 : ELSE
1165 156 : index1_prev = almo_scf_env%domain_map(1)%index1(idomain - 1)
1166 : END IF
1167 :
1168 184 : WRITE (unit_nr, '(T2,I10,":")') idomain
1169 : WRITE (unit_nr, '(T12,11I6)') &
1170 : almo_scf_env%domain_map(1)%pairs &
1171 1046 : (index1_prev:almo_scf_env%domain_map(1)%index1(idomain) - 1, 1) ! includes self
1172 :
1173 : END DO ! cycle over domains
1174 :
1175 : END SELECT
1176 :
1177 : ELSE ! too big to print details for each fragment
1178 :
1179 0 : WRITE (unit_nr, '(T2,A)') "The system is too big to print details for each fragment."
1180 :
1181 : END IF ! how many fragments?
1182 :
1183 58 : WRITE (unit_nr, '(T2,A)') REPEAT("-", 79)
1184 :
1185 58 : WRITE (unit_nr, '()')
1186 :
1187 58 : DEALLOCATE (nneighbors)
1188 :
1189 : END IF ! unit_nr > 0
1190 :
1191 116 : CALL timestop(handle)
1192 :
1193 116 : END SUBROUTINE almo_scf_print_job_info
1194 :
1195 : ! **************************************************************************************************
1196 : !> \brief Initializes the ALMO SCF copy of the AO overlap matrix
1197 : !> and all necessary functions (sqrt, inverse...)
1198 : !> \param matrix_s ...
1199 : !> \param almo_scf_env ...
1200 : !> \par History
1201 : !> 2011.06 created [Rustam Z Khaliullin]
1202 : !> \author Rustam Z Khaliullin
1203 : ! **************************************************************************************************
1204 116 : SUBROUTINE almo_scf_init_ao_overlap(matrix_s, almo_scf_env)
1205 : TYPE(dbcsr_type), INTENT(IN) :: matrix_s
1206 : TYPE(almo_scf_env_type), INTENT(INOUT) :: almo_scf_env
1207 :
1208 : CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_init_ao_overlap'
1209 :
1210 : INTEGER :: handle, unit_nr
1211 : TYPE(cp_logger_type), POINTER :: logger
1212 :
1213 116 : CALL timeset(routineN, handle)
1214 :
1215 : ! get a useful output_unit
1216 116 : logger => cp_get_default_logger()
1217 116 : IF (logger%para_env%is_source()) THEN
1218 58 : unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
1219 : ELSE
1220 : unit_nr = -1
1221 : END IF
1222 :
1223 : ! make almo copy of S
1224 : ! also copy S to S_blk (i.e. to S with the domain structure imposed)
1225 116 : IF (almo_scf_env%orthogonal_basis) THEN
1226 0 : CALL dbcsr_set(almo_scf_env%matrix_s(1), 0.0_dp)
1227 0 : CALL dbcsr_add_on_diag(almo_scf_env%matrix_s(1), 1.0_dp)
1228 0 : CALL dbcsr_set(almo_scf_env%matrix_s_blk(1), 0.0_dp)
1229 0 : CALL dbcsr_add_on_diag(almo_scf_env%matrix_s_blk(1), 1.0_dp)
1230 : ELSE
1231 : CALL matrix_qs_to_almo(matrix_s, almo_scf_env%matrix_s(1), &
1232 116 : almo_scf_env%mat_distr_aos, .FALSE.)
1233 : CALL dbcsr_copy(almo_scf_env%matrix_s_blk(1), &
1234 116 : almo_scf_env%matrix_s(1), keep_sparsity=.TRUE.)
1235 : END IF
1236 :
1237 116 : CALL dbcsr_filter(almo_scf_env%matrix_s(1), almo_scf_env%eps_filter)
1238 116 : CALL dbcsr_filter(almo_scf_env%matrix_s_blk(1), almo_scf_env%eps_filter)
1239 :
1240 116 : IF (almo_scf_env%almo_update_algorithm .EQ. almo_scf_diag) THEN
1241 : CALL matrix_sqrt_Newton_Schulz(almo_scf_env%matrix_s_blk_sqrt(1), &
1242 : almo_scf_env%matrix_s_blk_sqrt_inv(1), &
1243 : almo_scf_env%matrix_s_blk(1), &
1244 : threshold=almo_scf_env%eps_filter, &
1245 : order=almo_scf_env%order_lanczos, &
1246 : !order=0, &
1247 : eps_lanczos=almo_scf_env%eps_lanczos, &
1248 76 : max_iter_lanczos=almo_scf_env%max_iter_lanczos)
1249 40 : ELSE IF (almo_scf_env%almo_update_algorithm .EQ. almo_scf_dm_sign) THEN
1250 : CALL invert_Hotelling(almo_scf_env%matrix_s_blk_inv(1), &
1251 : almo_scf_env%matrix_s_blk(1), &
1252 : threshold=almo_scf_env%eps_filter, &
1253 0 : filter_eps=almo_scf_env%eps_filter)
1254 : END IF
1255 :
1256 116 : CALL timestop(handle)
1257 :
1258 116 : END SUBROUTINE almo_scf_init_ao_overlap
1259 :
1260 : ! **************************************************************************************************
1261 : !> \brief Selects the subroutine for the optimization of block-daigonal ALMOs.
1262 : !> Keep it short and clean.
1263 : !> \param qs_env ...
1264 : !> \param almo_scf_env ...
1265 : !> \par History
1266 : !> 2011.11 created [Rustam Z Khaliullin]
1267 : !> \author Rustam Z Khaliullin
1268 : ! **************************************************************************************************
1269 116 : SUBROUTINE almo_scf_main(qs_env, almo_scf_env)
1270 : TYPE(qs_environment_type), POINTER :: qs_env
1271 : TYPE(almo_scf_env_type), INTENT(INOUT) :: almo_scf_env
1272 :
1273 : CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_main'
1274 :
1275 : INTEGER :: handle, ispin, unit_nr
1276 : TYPE(cp_logger_type), POINTER :: logger
1277 :
1278 116 : CALL timeset(routineN, handle)
1279 :
1280 : ! get a useful output_unit
1281 116 : logger => cp_get_default_logger()
1282 116 : IF (logger%para_env%is_source()) THEN
1283 58 : unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
1284 : ELSE
1285 : unit_nr = -1
1286 : END IF
1287 :
1288 40 : SELECT CASE (almo_scf_env%almo_update_algorithm)
1289 : CASE (almo_scf_pcg, almo_scf_trustr, almo_scf_skip)
1290 :
1291 4 : SELECT CASE (almo_scf_env%almo_update_algorithm)
1292 : CASE (almo_scf_pcg)
1293 :
1294 : ! ALMO PCG optimizer as a special case of XALMO PCG
1295 : CALL almo_scf_xalmo_pcg(qs_env=qs_env, &
1296 : almo_scf_env=almo_scf_env, &
1297 : optimizer=almo_scf_env%opt_block_diag_pcg, &
1298 : quench_t=almo_scf_env%quench_t_blk, &
1299 : matrix_t_in=almo_scf_env%matrix_t_blk, &
1300 : matrix_t_out=almo_scf_env%matrix_t_blk, &
1301 : assume_t0_q0x=.FALSE., &
1302 : perturbation_only=.FALSE., &
1303 4 : special_case=xalmo_case_block_diag)
1304 :
1305 : CASE (almo_scf_trustr)
1306 :
1307 : CALL almo_scf_xalmo_trustr(qs_env=qs_env, &
1308 : almo_scf_env=almo_scf_env, &
1309 : optimizer=almo_scf_env%opt_block_diag_trustr, &
1310 : quench_t=almo_scf_env%quench_t_blk, &
1311 : matrix_t_in=almo_scf_env%matrix_t_blk, &
1312 : matrix_t_out=almo_scf_env%matrix_t_blk, &
1313 : perturbation_only=.FALSE., &
1314 2 : special_case=xalmo_case_block_diag)
1315 :
1316 : END SELECT
1317 :
1318 80 : DO ispin = 1, almo_scf_env%nspins
1319 : CALL orthogonalize_mos(ket=almo_scf_env%matrix_t_blk(ispin), &
1320 : overlap=almo_scf_env%matrix_sigma_blk(ispin), &
1321 : metric=almo_scf_env%matrix_s_blk(1), &
1322 : retain_locality=.TRUE., &
1323 : only_normalize=.FALSE., &
1324 : nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
1325 : eps_filter=almo_scf_env%eps_filter, &
1326 : order_lanczos=almo_scf_env%order_lanczos, &
1327 : eps_lanczos=almo_scf_env%eps_lanczos, &
1328 80 : max_iter_lanczos=almo_scf_env%max_iter_lanczos)
1329 : END DO
1330 :
1331 : CASE (almo_scf_diag)
1332 :
1333 : ! mixing/DIIS optimizer
1334 : CALL almo_scf_block_diagonal(qs_env, almo_scf_env, &
1335 116 : almo_scf_env%opt_block_diag_diis)
1336 :
1337 : END SELECT
1338 :
1339 : ! we might need a copy of the converged KS and sigma_inv
1340 232 : DO ispin = 1, almo_scf_env%nspins
1341 : CALL dbcsr_copy(almo_scf_env%matrix_ks_0deloc(ispin), &
1342 116 : almo_scf_env%matrix_ks(ispin))
1343 : CALL dbcsr_copy(almo_scf_env%matrix_sigma_inv_0deloc(ispin), &
1344 232 : almo_scf_env%matrix_sigma_inv(ispin))
1345 : END DO
1346 :
1347 116 : CALL timestop(handle)
1348 :
1349 116 : END SUBROUTINE almo_scf_main
1350 :
1351 : ! **************************************************************************************************
1352 : !> \brief selects various post scf routines
1353 : !> \param qs_env ...
1354 : !> \param almo_scf_env ...
1355 : !> \par History
1356 : !> 2011.06 created [Rustam Z Khaliullin]
1357 : !> \author Rustam Z Khaliullin
1358 : ! **************************************************************************************************
1359 116 : SUBROUTINE almo_scf_delocalization(qs_env, almo_scf_env)
1360 :
1361 : TYPE(qs_environment_type), POINTER :: qs_env
1362 : TYPE(almo_scf_env_type), INTENT(INOUT) :: almo_scf_env
1363 :
1364 : CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_delocalization'
1365 :
1366 : INTEGER :: col, handle, hold, iblock_col, &
1367 : iblock_row, ispin, mynode, &
1368 : nblkcols_tot, nblkrows_tot, row, &
1369 : unit_nr
1370 : LOGICAL :: almo_experimental, tr
1371 116 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: p_new_block
1372 : TYPE(cp_logger_type), POINTER :: logger
1373 : TYPE(dbcsr_distribution_type) :: dist
1374 116 : TYPE(dbcsr_type), ALLOCATABLE, DIMENSION(:) :: no_quench
1375 : TYPE(optimizer_options_type) :: arbitrary_optimizer
1376 :
1377 116 : CALL timeset(routineN, handle)
1378 :
1379 : ! get a useful output_unit
1380 116 : logger => cp_get_default_logger()
1381 116 : IF (logger%para_env%is_source()) THEN
1382 58 : unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
1383 : ELSE
1384 : unit_nr = -1
1385 : END IF
1386 :
1387 : ! create a local optimizer that handles XALMO DIIS
1388 : ! the options of this optimizer are arbitrary because
1389 : ! XALMO DIIS SCF does not converge for yet unknown reasons and
1390 : ! currently used in the code to get perturbative estimates only
1391 116 : arbitrary_optimizer%optimizer_type = optimizer_diis
1392 116 : arbitrary_optimizer%max_iter = 3
1393 116 : arbitrary_optimizer%eps_error = 1.0E-6_dp
1394 116 : arbitrary_optimizer%ndiis = 2
1395 :
1396 146 : SELECT CASE (almo_scf_env%deloc_method)
1397 : CASE (almo_deloc_x, almo_deloc_scf, almo_deloc_x_then_scf)
1398 :
1399 : ! RZK-warning hack into the quenched routine:
1400 : ! create a quench matrix with all-all-all blocks 1.0
1401 : ! it is a waste of memory but since matrices are distributed
1402 : ! we can tolerate it for now
1403 120 : ALLOCATE (no_quench(almo_scf_env%nspins))
1404 : CALL dbcsr_create(no_quench(1), &
1405 : template=almo_scf_env%matrix_t(1), &
1406 30 : matrix_type=dbcsr_type_no_symmetry)
1407 30 : CALL dbcsr_get_info(no_quench(1), distribution=dist)
1408 30 : CALL dbcsr_distribution_get(dist, mynode=mynode)
1409 : CALL dbcsr_work_create(no_quench(1), &
1410 30 : work_mutable=.TRUE.)
1411 30 : nblkrows_tot = dbcsr_nblkrows_total(no_quench(1))
1412 30 : nblkcols_tot = dbcsr_nblkcols_total(no_quench(1))
1413 : ! RZK-warning: is it a quadratic-scaling routine?
1414 : ! As a matter of fact it is! But this block treats
1415 : ! fully delocalized MOs. So it is unavoidable.
1416 : ! C'est la vie
1417 256 : DO row = 1, nblkrows_tot
1418 2050 : DO col = 1, nblkcols_tot
1419 1794 : tr = .FALSE.
1420 1794 : iblock_row = row
1421 1794 : iblock_col = col
1422 : CALL dbcsr_get_stored_coordinates(no_quench(1), &
1423 1794 : iblock_row, iblock_col, hold)
1424 2020 : IF (hold .EQ. mynode) THEN
1425 897 : NULLIFY (p_new_block)
1426 : CALL dbcsr_reserve_block2d(no_quench(1), &
1427 897 : iblock_row, iblock_col, p_new_block)
1428 897 : CPASSERT(ASSOCIATED(p_new_block))
1429 43234 : p_new_block(:, :) = 1.0_dp
1430 : END IF
1431 : END DO
1432 : END DO
1433 30 : CALL dbcsr_finalize(no_quench(1))
1434 176 : IF (almo_scf_env%nspins .GT. 1) THEN
1435 0 : DO ispin = 2, almo_scf_env%nspins
1436 : CALL dbcsr_create(no_quench(ispin), &
1437 : template=almo_scf_env%matrix_t(1), &
1438 0 : matrix_type=dbcsr_type_no_symmetry)
1439 0 : CALL dbcsr_copy(no_quench(ispin), no_quench(1))
1440 : END DO
1441 : END IF
1442 :
1443 : END SELECT
1444 :
1445 158 : SELECT CASE (almo_scf_env%deloc_method)
1446 : CASE (almo_deloc_none, almo_deloc_scf)
1447 :
1448 84 : DO ispin = 1, almo_scf_env%nspins
1449 : CALL dbcsr_copy(almo_scf_env%matrix_t(ispin), &
1450 84 : almo_scf_env%matrix_t_blk(ispin))
1451 : END DO
1452 :
1453 : CASE (almo_deloc_x, almo_deloc_xk, almo_deloc_x_then_scf)
1454 :
1455 : !!!! RZK-warning a whole class of delocalization methods
1456 : !!!! are commented out at the moment because some of their
1457 : !!!! routines have not been thoroughly tested.
1458 :
1459 : !!!! if we have virtuals pre-optimize and truncate them
1460 : !!!IF (almo_scf_env%need_virtuals) THEN
1461 : !!! SELECT CASE (almo_scf_env%deloc_truncate_virt)
1462 : !!! CASE (virt_full)
1463 : !!! ! simply copy virtual orbitals from matrix_v_full_blk to matrix_v_blk
1464 : !!! DO ispin=1,almo_scf_env%nspins
1465 : !!! CALL dbcsr_copy(almo_scf_env%matrix_v_blk(ispin),&
1466 : !!! almo_scf_env%matrix_v_full_blk(ispin))
1467 : !!! ENDDO
1468 : !!! CASE (virt_number,virt_occ_size)
1469 : !!! CALL split_v_blk(almo_scf_env)
1470 : !!! !CALL truncate_subspace_v_blk(qs_env,almo_scf_env)
1471 : !!! CASE DEFAULT
1472 : !!! CPErrorMessage(cp_failure_level,routineP,"illegal method for virtual space truncation")
1473 : !!! CPPrecondition(.FALSE.,cp_failure_level,routineP,failure)
1474 : !!! END SELECT
1475 : !!!ENDIF
1476 : !!!CALL harris_foulkes_correction(qs_env,almo_scf_env)
1477 :
1478 18 : IF (almo_scf_env%xalmo_update_algorithm .EQ. almo_scf_pcg) THEN
1479 :
1480 : CALL almo_scf_xalmo_pcg(qs_env=qs_env, &
1481 : almo_scf_env=almo_scf_env, &
1482 : optimizer=almo_scf_env%opt_xalmo_pcg, &
1483 : quench_t=no_quench, &
1484 : matrix_t_in=almo_scf_env%matrix_t_blk, &
1485 : matrix_t_out=almo_scf_env%matrix_t, &
1486 : assume_t0_q0x=(almo_scf_env%xalmo_trial_wf .EQ. xalmo_trial_r0_out), &
1487 : perturbation_only=.TRUE., &
1488 18 : special_case=xalmo_case_fully_deloc)
1489 :
1490 0 : ELSE IF (almo_scf_env%xalmo_update_algorithm .EQ. almo_scf_trustr) THEN
1491 :
1492 : CALL almo_scf_xalmo_trustr(qs_env=qs_env, &
1493 : almo_scf_env=almo_scf_env, &
1494 : optimizer=almo_scf_env%opt_xalmo_trustr, &
1495 : quench_t=no_quench, &
1496 : matrix_t_in=almo_scf_env%matrix_t_blk, &
1497 : matrix_t_out=almo_scf_env%matrix_t, &
1498 : perturbation_only=.TRUE., &
1499 0 : special_case=xalmo_case_fully_deloc)
1500 :
1501 : ELSE
1502 :
1503 0 : CPABORT("Other algorithms do not exist")
1504 :
1505 : END IF
1506 :
1507 : CASE (almo_deloc_xalmo_1diag)
1508 :
1509 2 : IF (almo_scf_env%xalmo_update_algorithm .EQ. almo_scf_diag) THEN
1510 :
1511 2 : almo_scf_env%perturbative_delocalization = .TRUE.
1512 4 : DO ispin = 1, almo_scf_env%nspins
1513 : CALL dbcsr_copy(almo_scf_env%matrix_t(ispin), &
1514 4 : almo_scf_env%matrix_t_blk(ispin))
1515 : END DO
1516 : CALL almo_scf_xalmo_eigensolver(qs_env, almo_scf_env, &
1517 2 : arbitrary_optimizer)
1518 :
1519 : ELSE
1520 :
1521 0 : CPABORT("Other algorithms do not exist")
1522 :
1523 : END IF
1524 :
1525 : CASE (almo_deloc_xalmo_x)
1526 :
1527 6 : IF (almo_scf_env%xalmo_update_algorithm .EQ. almo_scf_pcg) THEN
1528 :
1529 : CALL almo_scf_xalmo_pcg(qs_env=qs_env, &
1530 : almo_scf_env=almo_scf_env, &
1531 : optimizer=almo_scf_env%opt_xalmo_pcg, &
1532 : quench_t=almo_scf_env%quench_t, &
1533 : matrix_t_in=almo_scf_env%matrix_t_blk, &
1534 : matrix_t_out=almo_scf_env%matrix_t, &
1535 : assume_t0_q0x=(almo_scf_env%xalmo_trial_wf .EQ. xalmo_trial_r0_out), &
1536 : perturbation_only=.TRUE., &
1537 6 : special_case=xalmo_case_normal)
1538 :
1539 0 : ELSE IF (almo_scf_env%xalmo_update_algorithm .EQ. almo_scf_trustr) THEN
1540 :
1541 : CALL almo_scf_xalmo_trustr(qs_env=qs_env, &
1542 : almo_scf_env=almo_scf_env, &
1543 : optimizer=almo_scf_env%opt_xalmo_trustr, &
1544 : quench_t=almo_scf_env%quench_t, &
1545 : matrix_t_in=almo_scf_env%matrix_t_blk, &
1546 : matrix_t_out=almo_scf_env%matrix_t, &
1547 : perturbation_only=.TRUE., &
1548 0 : special_case=xalmo_case_normal)
1549 :
1550 : ELSE
1551 :
1552 0 : CPABORT("Other algorithms do not exist")
1553 :
1554 : END IF
1555 :
1556 : CASE (almo_deloc_xalmo_scf)
1557 :
1558 48 : IF (almo_scf_env%xalmo_update_algorithm .EQ. almo_scf_diag) THEN
1559 :
1560 0 : CPABORT("Should not be here: convergence will fail!")
1561 :
1562 0 : almo_scf_env%perturbative_delocalization = .FALSE.
1563 0 : DO ispin = 1, almo_scf_env%nspins
1564 : CALL dbcsr_copy(almo_scf_env%matrix_t(ispin), &
1565 0 : almo_scf_env%matrix_t_blk(ispin))
1566 : END DO
1567 : CALL almo_scf_xalmo_eigensolver(qs_env, almo_scf_env, &
1568 0 : arbitrary_optimizer)
1569 :
1570 48 : ELSE IF (almo_scf_env%xalmo_update_algorithm .EQ. almo_scf_pcg) THEN
1571 :
1572 : CALL almo_scf_xalmo_pcg(qs_env=qs_env, &
1573 : almo_scf_env=almo_scf_env, &
1574 : optimizer=almo_scf_env%opt_xalmo_pcg, &
1575 : quench_t=almo_scf_env%quench_t, &
1576 : matrix_t_in=almo_scf_env%matrix_t_blk, &
1577 : matrix_t_out=almo_scf_env%matrix_t, &
1578 : assume_t0_q0x=(almo_scf_env%xalmo_trial_wf .EQ. xalmo_trial_r0_out), &
1579 : perturbation_only=.FALSE., &
1580 32 : special_case=xalmo_case_normal)
1581 :
1582 : ! RZK-warning THIS IS A HACK TO GET ORBITAL ENERGIES
1583 32 : almo_experimental = .FALSE.
1584 : IF (almo_experimental) THEN
1585 : almo_scf_env%perturbative_delocalization = .TRUE.
1586 : !DO ispin=1,almo_scf_env%nspins
1587 : ! CALL dbcsr_copy(almo_scf_env%matrix_t(ispin),&
1588 : ! almo_scf_env%matrix_t_blk(ispin))
1589 : !ENDDO
1590 : CALL almo_scf_xalmo_eigensolver(qs_env, almo_scf_env, &
1591 : arbitrary_optimizer)
1592 : END IF ! experimental
1593 :
1594 16 : ELSE IF (almo_scf_env%xalmo_update_algorithm .EQ. almo_scf_trustr) THEN
1595 :
1596 : CALL almo_scf_xalmo_trustr(qs_env=qs_env, &
1597 : almo_scf_env=almo_scf_env, &
1598 : optimizer=almo_scf_env%opt_xalmo_trustr, &
1599 : quench_t=almo_scf_env%quench_t, &
1600 : matrix_t_in=almo_scf_env%matrix_t_blk, &
1601 : matrix_t_out=almo_scf_env%matrix_t, &
1602 : perturbation_only=.FALSE., &
1603 16 : special_case=xalmo_case_normal)
1604 :
1605 : ELSE
1606 :
1607 0 : CPABORT("Other algorithms do not exist")
1608 :
1609 : END IF
1610 :
1611 : CASE DEFAULT
1612 :
1613 116 : CPABORT("Illegal delocalization method")
1614 :
1615 : END SELECT
1616 :
1617 142 : SELECT CASE (almo_scf_env%deloc_method)
1618 : CASE (almo_deloc_scf, almo_deloc_x_then_scf)
1619 :
1620 26 : IF (almo_scf_env%deloc_truncate_virt .NE. virt_full) THEN
1621 0 : CPABORT("full scf is NYI for truncated virtual space")
1622 : END IF
1623 :
1624 142 : IF (almo_scf_env%xalmo_update_algorithm .EQ. almo_scf_pcg) THEN
1625 :
1626 : CALL almo_scf_xalmo_pcg(qs_env=qs_env, &
1627 : almo_scf_env=almo_scf_env, &
1628 : optimizer=almo_scf_env%opt_xalmo_pcg, &
1629 : quench_t=no_quench, &
1630 : matrix_t_in=almo_scf_env%matrix_t, &
1631 : matrix_t_out=almo_scf_env%matrix_t, &
1632 : assume_t0_q0x=.FALSE., &
1633 : perturbation_only=.FALSE., &
1634 26 : special_case=xalmo_case_fully_deloc)
1635 :
1636 0 : ELSE IF (almo_scf_env%xalmo_update_algorithm .EQ. almo_scf_trustr) THEN
1637 :
1638 : CALL almo_scf_xalmo_trustr(qs_env=qs_env, &
1639 : almo_scf_env=almo_scf_env, &
1640 : optimizer=almo_scf_env%opt_xalmo_trustr, &
1641 : quench_t=no_quench, &
1642 : matrix_t_in=almo_scf_env%matrix_t, &
1643 : matrix_t_out=almo_scf_env%matrix_t, &
1644 : perturbation_only=.FALSE., &
1645 0 : special_case=xalmo_case_fully_deloc)
1646 :
1647 : ELSE
1648 :
1649 0 : CPABORT("Other algorithms do not exist")
1650 :
1651 : END IF
1652 :
1653 : END SELECT
1654 :
1655 : ! clean up
1656 146 : SELECT CASE (almo_scf_env%deloc_method)
1657 : CASE (almo_deloc_x, almo_deloc_scf, almo_deloc_x_then_scf)
1658 60 : DO ispin = 1, almo_scf_env%nspins
1659 60 : CALL dbcsr_release(no_quench(ispin))
1660 : END DO
1661 146 : DEALLOCATE (no_quench)
1662 : END SELECT
1663 :
1664 116 : CALL timestop(handle)
1665 :
1666 232 : END SUBROUTINE almo_scf_delocalization
1667 :
1668 : ! **************************************************************************************************
1669 : !> \brief orbital localization
1670 : !> \param qs_env ...
1671 : !> \param almo_scf_env ...
1672 : !> \par History
1673 : !> 2018.09 created [Ziling Luo]
1674 : !> \author Ziling Luo
1675 : ! **************************************************************************************************
1676 116 : SUBROUTINE construct_nlmos(qs_env, almo_scf_env)
1677 :
1678 : TYPE(qs_environment_type), POINTER :: qs_env
1679 : TYPE(almo_scf_env_type), INTENT(INOUT) :: almo_scf_env
1680 :
1681 : INTEGER :: ispin
1682 :
1683 116 : IF (almo_scf_env%construct_nlmos) THEN
1684 :
1685 8 : DO ispin = 1, almo_scf_env%nspins
1686 :
1687 : CALL orthogonalize_mos(ket=almo_scf_env%matrix_t(ispin), &
1688 : overlap=almo_scf_env%matrix_sigma(ispin), &
1689 : metric=almo_scf_env%matrix_s(1), &
1690 : retain_locality=.FALSE., &
1691 : only_normalize=.FALSE., &
1692 : nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
1693 : eps_filter=almo_scf_env%eps_filter, &
1694 : order_lanczos=almo_scf_env%order_lanczos, &
1695 : eps_lanczos=almo_scf_env%eps_lanczos, &
1696 8 : max_iter_lanczos=almo_scf_env%max_iter_lanczos)
1697 : END DO
1698 :
1699 4 : CALL construct_nlmos_wrapper(qs_env, almo_scf_env, virtuals=.FALSE.)
1700 :
1701 4 : IF (almo_scf_env%opt_nlmo_pcg%opt_penalty%virtual_nlmos) THEN
1702 0 : CALL construct_virtuals(almo_scf_env)
1703 0 : CALL construct_nlmos_wrapper(qs_env, almo_scf_env, virtuals=.TRUE.)
1704 : END IF
1705 :
1706 4 : IF (almo_scf_env%opt_nlmo_pcg%opt_penalty%compactification_filter_start .GT. 0.0_dp) THEN
1707 2 : CALL nlmo_compactification(qs_env, almo_scf_env, almo_scf_env%matrix_t)
1708 : END IF
1709 :
1710 : END IF
1711 :
1712 116 : END SUBROUTINE construct_nlmos
1713 :
1714 : ! **************************************************************************************************
1715 : !> \brief Calls NLMO optimization
1716 : !> \param qs_env ...
1717 : !> \param almo_scf_env ...
1718 : !> \param virtuals ...
1719 : !> \par History
1720 : !> 2019.10 created [Ziling Luo]
1721 : !> \author Ziling Luo
1722 : ! **************************************************************************************************
1723 4 : SUBROUTINE construct_nlmos_wrapper(qs_env, almo_scf_env, virtuals)
1724 :
1725 : TYPE(qs_environment_type), POINTER :: qs_env
1726 : TYPE(almo_scf_env_type), INTENT(INOUT) :: almo_scf_env
1727 : LOGICAL, INTENT(IN) :: virtuals
1728 :
1729 : REAL(KIND=dp) :: det_diff, prev_determinant
1730 :
1731 4 : almo_scf_env%overlap_determinant = 1.0
1732 : ! KEEP: initial_vol_coeff = almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength
1733 : almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength = &
1734 4 : -1.0_dp*almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength !NEW1
1735 :
1736 : ! loop over the strength of the orthogonalization penalty
1737 4 : prev_determinant = 10.0_dp
1738 10 : DO WHILE (almo_scf_env%overlap_determinant .GT. almo_scf_env%opt_nlmo_pcg%opt_penalty%final_determinant)
1739 :
1740 8 : IF (.NOT. virtuals) THEN
1741 : CALL almo_scf_construct_nlmos(qs_env=qs_env, &
1742 : optimizer=almo_scf_env%opt_nlmo_pcg, &
1743 : matrix_s=almo_scf_env%matrix_s(1), &
1744 : matrix_mo_in=almo_scf_env%matrix_t, &
1745 : matrix_mo_out=almo_scf_env%matrix_t, &
1746 : template_matrix_sigma=almo_scf_env%matrix_sigma_inv, &
1747 : overlap_determinant=almo_scf_env%overlap_determinant, &
1748 : mat_distr_aos=almo_scf_env%mat_distr_aos, &
1749 : virtuals=virtuals, &
1750 8 : eps_filter=almo_scf_env%eps_filter)
1751 : ELSE
1752 : CALL almo_scf_construct_nlmos(qs_env=qs_env, &
1753 : optimizer=almo_scf_env%opt_nlmo_pcg, &
1754 : matrix_s=almo_scf_env%matrix_s(1), &
1755 : matrix_mo_in=almo_scf_env%matrix_v, &
1756 : matrix_mo_out=almo_scf_env%matrix_v, &
1757 : template_matrix_sigma=almo_scf_env%matrix_sigma_vv, &
1758 : overlap_determinant=almo_scf_env%overlap_determinant, &
1759 : mat_distr_aos=almo_scf_env%mat_distr_aos, &
1760 : virtuals=virtuals, &
1761 0 : eps_filter=almo_scf_env%eps_filter)
1762 :
1763 : END IF
1764 :
1765 8 : det_diff = prev_determinant - almo_scf_env%overlap_determinant
1766 : almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength = &
1767 : almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength/ &
1768 8 : ABS(almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength_dec_factor)
1769 :
1770 8 : IF (det_diff < almo_scf_env%opt_nlmo_pcg%opt_penalty%determinant_tolerance) THEN
1771 : EXIT
1772 : END IF
1773 4 : prev_determinant = almo_scf_env%overlap_determinant
1774 :
1775 : END DO
1776 :
1777 4 : END SUBROUTINE construct_nlmos_wrapper
1778 :
1779 : ! **************************************************************************************************
1780 : !> \brief Construct virtual orbitals
1781 : !> \param almo_scf_env ...
1782 : !> \par History
1783 : !> 2019.10 created [Ziling Luo]
1784 : !> \author Ziling Luo
1785 : ! **************************************************************************************************
1786 0 : SUBROUTINE construct_virtuals(almo_scf_env)
1787 :
1788 : TYPE(almo_scf_env_type), INTENT(INOUT) :: almo_scf_env
1789 :
1790 : INTEGER :: ispin, n
1791 0 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: eigenvalues
1792 : TYPE(dbcsr_type) :: tempNV1, tempVOcc1, tempVOcc2, tempVV1, &
1793 : tempVV2
1794 :
1795 0 : DO ispin = 1, almo_scf_env%nspins
1796 :
1797 : CALL dbcsr_create(tempNV1, &
1798 : template=almo_scf_env%matrix_v(ispin), &
1799 0 : matrix_type=dbcsr_type_no_symmetry)
1800 : CALL dbcsr_create(tempVOcc1, &
1801 : template=almo_scf_env%matrix_vo(ispin), &
1802 0 : matrix_type=dbcsr_type_no_symmetry)
1803 : CALL dbcsr_create(tempVOcc2, &
1804 : template=almo_scf_env%matrix_vo(ispin), &
1805 0 : matrix_type=dbcsr_type_no_symmetry)
1806 : CALL dbcsr_create(tempVV1, &
1807 : template=almo_scf_env%matrix_sigma_vv(ispin), &
1808 0 : matrix_type=dbcsr_type_no_symmetry)
1809 : CALL dbcsr_create(tempVV2, &
1810 : template=almo_scf_env%matrix_sigma_vv(ispin), &
1811 0 : matrix_type=dbcsr_type_no_symmetry)
1812 :
1813 : ! Generate random virtual matrix
1814 : CALL dbcsr_init_random(almo_scf_env%matrix_v(ispin), &
1815 0 : keep_sparsity=.FALSE.)
1816 :
1817 : ! Project the orbital subspace out
1818 : CALL dbcsr_multiply("N", "N", 1.0_dp, &
1819 : almo_scf_env%matrix_s(1), &
1820 : almo_scf_env%matrix_v(ispin), &
1821 : 0.0_dp, tempNV1, &
1822 0 : filter_eps=almo_scf_env%eps_filter)
1823 :
1824 : CALL dbcsr_multiply("T", "N", 1.0_dp, &
1825 : tempNV1, &
1826 : almo_scf_env%matrix_t(ispin), &
1827 : 0.0_dp, tempVOcc1, &
1828 0 : filter_eps=almo_scf_env%eps_filter)
1829 :
1830 : CALL dbcsr_multiply("N", "N", 1.0_dp, &
1831 : tempVOcc1, &
1832 : almo_scf_env%matrix_sigma_inv(ispin), &
1833 : 0.0_dp, tempVOcc2, &
1834 0 : filter_eps=almo_scf_env%eps_filter)
1835 :
1836 : CALL dbcsr_multiply("N", "T", 1.0_dp, &
1837 : almo_scf_env%matrix_t(ispin), &
1838 : tempVOcc2, &
1839 : 0.0_dp, tempNV1, &
1840 0 : filter_eps=almo_scf_env%eps_filter)
1841 :
1842 0 : CALL dbcsr_add(almo_scf_env%matrix_v(ispin), tempNV1, 1.0_dp, -1.0_dp)
1843 :
1844 : ! compute VxV overlap
1845 : CALL dbcsr_multiply("N", "N", 1.0_dp, &
1846 : almo_scf_env%matrix_s(1), &
1847 : almo_scf_env%matrix_v(ispin), &
1848 : 0.0_dp, tempNV1, &
1849 0 : filter_eps=almo_scf_env%eps_filter)
1850 :
1851 : CALL dbcsr_multiply("T", "N", 1.0_dp, &
1852 : almo_scf_env%matrix_v(ispin), &
1853 : tempNV1, &
1854 : 0.0_dp, tempVV1, &
1855 0 : filter_eps=almo_scf_env%eps_filter)
1856 :
1857 : CALL orthogonalize_mos(ket=almo_scf_env%matrix_v(ispin), &
1858 : overlap=tempVV1, &
1859 : metric=almo_scf_env%matrix_s(1), &
1860 : retain_locality=.FALSE., &
1861 : only_normalize=.FALSE., &
1862 : nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
1863 : eps_filter=almo_scf_env%eps_filter, &
1864 : order_lanczos=almo_scf_env%order_lanczos, &
1865 : eps_lanczos=almo_scf_env%eps_lanczos, &
1866 0 : max_iter_lanczos=almo_scf_env%max_iter_lanczos)
1867 :
1868 : ! compute VxV block of the KS matrix
1869 : CALL dbcsr_multiply("N", "N", 1.0_dp, &
1870 : almo_scf_env%matrix_ks(ispin), &
1871 : almo_scf_env%matrix_v(ispin), &
1872 : 0.0_dp, tempNV1, &
1873 0 : filter_eps=almo_scf_env%eps_filter)
1874 :
1875 : CALL dbcsr_multiply("T", "N", 1.0_dp, &
1876 : almo_scf_env%matrix_v(ispin), &
1877 : tempNV1, &
1878 : 0.0_dp, tempVV1, &
1879 0 : filter_eps=almo_scf_env%eps_filter)
1880 :
1881 0 : CALL dbcsr_get_info(tempVV1, nfullrows_total=n)
1882 0 : ALLOCATE (eigenvalues(n))
1883 : CALL cp_dbcsr_syevd(tempVV1, tempVV2, &
1884 : eigenvalues, &
1885 : para_env=almo_scf_env%para_env, &
1886 0 : blacs_env=almo_scf_env%blacs_env)
1887 0 : DEALLOCATE (eigenvalues)
1888 :
1889 : CALL dbcsr_multiply("N", "N", 1.0_dp, &
1890 : almo_scf_env%matrix_v(ispin), &
1891 : tempVV2, &
1892 : 0.0_dp, tempNV1, &
1893 0 : filter_eps=almo_scf_env%eps_filter)
1894 :
1895 0 : CALL dbcsr_copy(almo_scf_env%matrix_v(ispin), tempNV1)
1896 :
1897 0 : CALL dbcsr_release(tempNV1)
1898 0 : CALL dbcsr_release(tempVOcc1)
1899 0 : CALL dbcsr_release(tempVOcc2)
1900 0 : CALL dbcsr_release(tempVV1)
1901 0 : CALL dbcsr_release(tempVV2)
1902 :
1903 : END DO
1904 :
1905 0 : END SUBROUTINE construct_virtuals
1906 :
1907 : ! **************************************************************************************************
1908 : !> \brief Compactify (set small blocks to zero) orbitals
1909 : !> \param qs_env ...
1910 : !> \param almo_scf_env ...
1911 : !> \param matrix ...
1912 : !> \par History
1913 : !> 2019.10 created [Ziling Luo]
1914 : !> \author Ziling Luo
1915 : ! **************************************************************************************************
1916 2 : SUBROUTINE nlmo_compactification(qs_env, almo_scf_env, matrix)
1917 :
1918 : TYPE(qs_environment_type), POINTER :: qs_env
1919 : TYPE(almo_scf_env_type), INTENT(INOUT) :: almo_scf_env
1920 : TYPE(dbcsr_type), ALLOCATABLE, DIMENSION(:), &
1921 : INTENT(IN) :: matrix
1922 :
1923 : INTEGER :: iblock_col, iblock_col_size, iblock_row, iblock_row_size, icol, irow, ispin, &
1924 : Ncols, Nrows, nspins, para_group_handle, unit_nr
1925 : LOGICAL :: element_by_element
1926 : REAL(KIND=dp) :: energy, eps_local, eps_start, &
1927 : max_element, spin_factor
1928 2 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: occ, retained
1929 2 : REAL(kind=dp), DIMENSION(:, :), POINTER :: data_p
1930 : TYPE(cp_logger_type), POINTER :: logger
1931 : TYPE(dbcsr_iterator_type) :: iter
1932 2 : TYPE(dbcsr_type), ALLOCATABLE, DIMENSION(:) :: matrix_p_tmp, matrix_t_tmp
1933 : TYPE(mp_comm_type) :: para_group
1934 :
1935 : ! define the output_unit
1936 4 : logger => cp_get_default_logger()
1937 2 : IF (logger%para_env%is_source()) THEN
1938 1 : unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
1939 : ELSE
1940 : unit_nr = -1
1941 : END IF
1942 :
1943 2 : nspins = SIZE(matrix)
1944 2 : element_by_element = .FALSE.
1945 :
1946 2 : IF (nspins .EQ. 1) THEN
1947 2 : spin_factor = 2.0_dp
1948 : ELSE
1949 0 : spin_factor = 1.0_dp
1950 : END IF
1951 :
1952 8 : ALLOCATE (matrix_t_tmp(nspins))
1953 8 : ALLOCATE (matrix_p_tmp(nspins))
1954 6 : ALLOCATE (retained(nspins))
1955 2 : ALLOCATE (occ(2))
1956 :
1957 4 : DO ispin = 1, nspins
1958 :
1959 : ! init temporary storage
1960 : CALL dbcsr_create(matrix_t_tmp(ispin), &
1961 : template=matrix(ispin), &
1962 2 : matrix_type=dbcsr_type_no_symmetry)
1963 2 : CALL dbcsr_copy(matrix_t_tmp(ispin), matrix(ispin))
1964 :
1965 : CALL dbcsr_create(matrix_p_tmp(ispin), &
1966 : template=almo_scf_env%matrix_p(ispin), &
1967 2 : matrix_type=dbcsr_type_no_symmetry)
1968 4 : CALL dbcsr_copy(matrix_p_tmp(ispin), almo_scf_env%matrix_p(ispin))
1969 :
1970 : END DO
1971 :
1972 2 : IF (unit_nr > 0) THEN
1973 1 : WRITE (unit_nr, *)
1974 : WRITE (unit_nr, '(T2,A)') &
1975 1 : "Energy dependence on the (block-by-block) filtering of the NLMO coefficients"
1976 : IF (unit_nr > 0) WRITE (unit_nr, '(T2,A13,A20,A20,A25)') &
1977 1 : "EPS filter", "Occupation Alpha", "Occupation Beta", "Energy"
1978 : END IF
1979 :
1980 2 : eps_start = almo_scf_env%opt_nlmo_pcg%opt_penalty%compactification_filter_start
1981 2 : eps_local = MAX(eps_start, 10E-14_dp)
1982 :
1983 8 : DO
1984 :
1985 10 : IF (eps_local > 0.11_dp) EXIT
1986 :
1987 16 : DO ispin = 1, nspins
1988 :
1989 8 : retained(ispin) = 0
1990 8 : CALL dbcsr_work_create(matrix_t_tmp(ispin), work_mutable=.TRUE.)
1991 8 : CALL dbcsr_iterator_start(iter, matrix_t_tmp(ispin))
1992 264 : DO WHILE (dbcsr_iterator_blocks_left(iter))
1993 : CALL dbcsr_iterator_next_block(iter, iblock_row, iblock_col, data_p, &
1994 256 : row_size=iblock_row_size, col_size=iblock_col_size)
1995 776 : DO icol = 1, iblock_col_size
1996 :
1997 256 : IF (element_by_element) THEN
1998 :
1999 : DO irow = 1, iblock_row_size
2000 : IF (ABS(data_p(irow, icol)) .LT. eps_local) THEN
2001 : data_p(irow, icol) = 0.0_dp
2002 : ELSE
2003 : retained(ispin) = retained(ispin) + 1
2004 : END IF
2005 : END DO
2006 :
2007 : ELSE ! rows are blocked
2008 :
2009 512 : max_element = 0.0_dp
2010 2560 : DO irow = 1, iblock_row_size
2011 2560 : IF (ABS(data_p(irow, icol)) .GT. max_element) THEN
2012 1088 : max_element = ABS(data_p(irow, icol))
2013 : END IF
2014 : END DO
2015 512 : IF (max_element .LT. eps_local) THEN
2016 155 : DO irow = 1, iblock_row_size
2017 155 : data_p(irow, icol) = 0.0_dp
2018 : END DO
2019 : ELSE
2020 481 : retained(ispin) = retained(ispin) + iblock_row_size
2021 : END IF
2022 :
2023 : END IF ! block rows?
2024 : END DO ! icol
2025 :
2026 : END DO ! iterator
2027 8 : CALL dbcsr_iterator_stop(iter)
2028 8 : CALL dbcsr_finalize(matrix_t_tmp(ispin))
2029 8 : CALL dbcsr_filter(matrix_t_tmp(ispin), eps_local)
2030 :
2031 : CALL dbcsr_get_info(matrix_t_tmp(ispin), group=para_group_handle, &
2032 : nfullrows_total=Nrows, &
2033 8 : nfullcols_total=Ncols)
2034 8 : CALL para_group%set_handle(para_group_handle)
2035 8 : CALL para_group%sum(retained(ispin))
2036 :
2037 : !devide by the total no. elements
2038 8 : occ(ispin) = retained(ispin)/Nrows/Ncols
2039 :
2040 : ! compute the global projectors (for the density matrix)
2041 : CALL almo_scf_t_to_proj( &
2042 : t=matrix_t_tmp(ispin), &
2043 : p=matrix_p_tmp(ispin), &
2044 : eps_filter=almo_scf_env%eps_filter, &
2045 : orthog_orbs=.FALSE., &
2046 : nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
2047 : s=almo_scf_env%matrix_s(1), &
2048 : sigma=almo_scf_env%matrix_sigma(ispin), &
2049 : sigma_inv=almo_scf_env%matrix_sigma_inv(ispin), &
2050 : use_guess=.FALSE., &
2051 : algorithm=almo_scf_env%sigma_inv_algorithm, &
2052 : inv_eps_factor=almo_scf_env%matrix_iter_eps_error_factor, &
2053 : inverse_accelerator=almo_scf_env%order_lanczos, &
2054 : eps_lanczos=almo_scf_env%eps_lanczos, &
2055 : max_iter_lanczos=almo_scf_env%max_iter_lanczos, &
2056 : para_env=almo_scf_env%para_env, &
2057 8 : blacs_env=almo_scf_env%blacs_env)
2058 :
2059 : ! compute dm from the projector(s)
2060 24 : CALL dbcsr_scale(matrix_p_tmp(ispin), spin_factor)
2061 :
2062 : END DO
2063 :
2064 : ! the KS matrix is updated outside the spin loop
2065 : CALL almo_dm_to_almo_ks(qs_env, &
2066 : matrix_p_tmp, &
2067 : almo_scf_env%matrix_ks, &
2068 : energy, &
2069 : almo_scf_env%eps_filter, &
2070 8 : almo_scf_env%mat_distr_aos)
2071 :
2072 8 : IF (nspins .LT. 2) occ(2) = occ(1)
2073 8 : IF (unit_nr > 0) WRITE (unit_nr, '(T2,E13.3,F20.10,F20.10,F25.15)') &
2074 4 : eps_local, occ(1), occ(2), energy
2075 :
2076 8 : eps_local = 2.0_dp*eps_local
2077 :
2078 : END DO
2079 :
2080 4 : DO ispin = 1, nspins
2081 :
2082 2 : CALL dbcsr_release(matrix_t_tmp(ispin))
2083 4 : CALL dbcsr_release(matrix_p_tmp(ispin))
2084 :
2085 : END DO
2086 :
2087 2 : DEALLOCATE (matrix_t_tmp)
2088 2 : DEALLOCATE (matrix_p_tmp)
2089 2 : DEALLOCATE (occ)
2090 2 : DEALLOCATE (retained)
2091 :
2092 2 : END SUBROUTINE nlmo_compactification
2093 :
2094 : ! *****************************************************************************
2095 : !> \brief after SCF we have the final density and KS matrices compute various
2096 : !> post-scf quantities
2097 : !> \param qs_env ...
2098 : !> \param almo_scf_env ...
2099 : !> \par History
2100 : !> 2015.03 created [Rustam Z. Khaliullin]
2101 : !> \author Rustam Z. Khaliullin
2102 : ! **************************************************************************************************
2103 116 : SUBROUTINE almo_scf_post(qs_env, almo_scf_env)
2104 : TYPE(qs_environment_type), POINTER :: qs_env
2105 : TYPE(almo_scf_env_type), INTENT(INOUT) :: almo_scf_env
2106 :
2107 : CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_post'
2108 :
2109 : INTEGER :: handle, ispin
2110 : TYPE(cp_fm_type), POINTER :: mo_coeff
2111 116 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_w
2112 116 : TYPE(dbcsr_type), ALLOCATABLE, DIMENSION(:) :: matrix_t_processed
2113 116 : TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
2114 : TYPE(qs_scf_env_type), POINTER :: scf_env
2115 :
2116 116 : CALL timeset(routineN, handle)
2117 :
2118 : ! store matrices to speed up the next scf run
2119 116 : CALL almo_scf_store_extrapolation_data(almo_scf_env)
2120 :
2121 : ! orthogonalize orbitals before returning them to QS
2122 464 : ALLOCATE (matrix_t_processed(almo_scf_env%nspins))
2123 : !ALLOCATE (matrix_v_processed(almo_scf_env%nspins))
2124 :
2125 232 : DO ispin = 1, almo_scf_env%nspins
2126 :
2127 : CALL dbcsr_create(matrix_t_processed(ispin), &
2128 : template=almo_scf_env%matrix_t(ispin), &
2129 116 : matrix_type=dbcsr_type_no_symmetry)
2130 :
2131 : CALL dbcsr_copy(matrix_t_processed(ispin), &
2132 116 : almo_scf_env%matrix_t(ispin))
2133 :
2134 : !CALL dbcsr_create(matrix_v_processed(ispin), &
2135 : ! template=almo_scf_env%matrix_v(ispin), &
2136 : ! matrix_type=dbcsr_type_no_symmetry)
2137 :
2138 : !CALL dbcsr_copy(matrix_v_processed(ispin), &
2139 : ! almo_scf_env%matrix_v(ispin))
2140 :
2141 232 : IF (almo_scf_env%return_orthogonalized_mos) THEN
2142 :
2143 : CALL orthogonalize_mos(ket=matrix_t_processed(ispin), &
2144 : overlap=almo_scf_env%matrix_sigma(ispin), &
2145 : metric=almo_scf_env%matrix_s(1), &
2146 : retain_locality=.FALSE., &
2147 : only_normalize=.FALSE., &
2148 : nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
2149 : eps_filter=almo_scf_env%eps_filter, &
2150 : order_lanczos=almo_scf_env%order_lanczos, &
2151 : eps_lanczos=almo_scf_env%eps_lanczos, &
2152 : max_iter_lanczos=almo_scf_env%max_iter_lanczos, &
2153 94 : smear=almo_scf_env%smear)
2154 : END IF
2155 :
2156 : END DO
2157 :
2158 : !! RS-WARNING: If smearing ALMO is requested, rescaled fully-occupied orbitals are returned to QS
2159 : !! RS-WARNING: Beware that QS will not be informed about electronic entropy.
2160 : !! If you want a quick and dirty transfer to QS energy, uncomment the following hack:
2161 : !! IF (almo_scf_env%smear) THEN
2162 : !! qs_env%energy%kTS = 0.0_dp
2163 : !! DO ispin = 1, almo_scf_env%nspins
2164 : !! qs_env%energy%kTS = qs_env%energy%kTS + almo_scf_env%kTS(ispin)
2165 : !! END DO
2166 : !! END IF
2167 :
2168 : ! return orbitals to QS
2169 116 : NULLIFY (mos, mo_coeff, scf_env)
2170 :
2171 116 : CALL get_qs_env(qs_env, mos=mos, scf_env=scf_env)
2172 :
2173 232 : DO ispin = 1, almo_scf_env%nspins
2174 : ! Currently only fm version of mo_set is usable.
2175 : ! First transform the matrix_t to fm version
2176 116 : CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff)
2177 116 : CALL copy_dbcsr_to_fm(matrix_t_processed(ispin), mo_coeff)
2178 232 : CALL dbcsr_release(matrix_t_processed(ispin))
2179 : END DO
2180 232 : DO ispin = 1, almo_scf_env%nspins
2181 232 : CALL dbcsr_release(matrix_t_processed(ispin))
2182 : END DO
2183 116 : DEALLOCATE (matrix_t_processed)
2184 :
2185 : ! calculate post scf properties
2186 : ! CALL almo_post_scf_compute_properties(qs_env, almo_scf_env)
2187 116 : CALL almo_post_scf_compute_properties(qs_env)
2188 :
2189 : ! compute the W matrix if associated
2190 116 : IF (almo_scf_env%calc_forces) THEN
2191 66 : CALL get_qs_env(qs_env, matrix_w=matrix_w)
2192 66 : IF (ASSOCIATED(matrix_w)) THEN
2193 66 : CALL calculate_w_matrix_almo(matrix_w, almo_scf_env)
2194 : ELSE
2195 0 : CPABORT("Matrix W is needed but not associated")
2196 : END IF
2197 : END IF
2198 :
2199 116 : CALL timestop(handle)
2200 :
2201 116 : END SUBROUTINE almo_scf_post
2202 :
2203 : ! **************************************************************************************************
2204 : !> \brief create various matrices
2205 : !> \param almo_scf_env ...
2206 : !> \param matrix_s0 ...
2207 : !> \par History
2208 : !> 2011.07 created [Rustam Z Khaliullin]
2209 : !> \author Rustam Z Khaliullin
2210 : ! **************************************************************************************************
2211 116 : SUBROUTINE almo_scf_env_create_matrices(almo_scf_env, matrix_s0)
2212 :
2213 : TYPE(almo_scf_env_type), INTENT(INOUT) :: almo_scf_env
2214 : TYPE(dbcsr_type), INTENT(IN) :: matrix_s0
2215 :
2216 : CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_env_create_matrices'
2217 :
2218 : INTEGER :: handle, ispin, nspins
2219 :
2220 116 : CALL timeset(routineN, handle)
2221 :
2222 116 : nspins = almo_scf_env%nspins
2223 :
2224 : ! AO overlap matrix and its various functions
2225 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_s(1), &
2226 : matrix_qs=matrix_s0, &
2227 : almo_scf_env=almo_scf_env, &
2228 : name_new="S", &
2229 : size_keys=(/almo_mat_dim_aobasis, almo_mat_dim_aobasis/), &
2230 : symmetry_new=dbcsr_type_symmetric, &
2231 : spin_key=0, &
2232 116 : init_domains=.FALSE.)
2233 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_s_blk(1), &
2234 : matrix_qs=matrix_s0, &
2235 : almo_scf_env=almo_scf_env, &
2236 : name_new="S_BLK", &
2237 : size_keys=(/almo_mat_dim_aobasis, almo_mat_dim_aobasis/), &
2238 : symmetry_new=dbcsr_type_symmetric, &
2239 : spin_key=0, &
2240 116 : init_domains=.TRUE.)
2241 116 : IF (almo_scf_env%almo_update_algorithm .EQ. almo_scf_diag) THEN
2242 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_s_blk_sqrt_inv(1), &
2243 : matrix_qs=matrix_s0, &
2244 : almo_scf_env=almo_scf_env, &
2245 : name_new="S_BLK_SQRT_INV", &
2246 : size_keys=(/almo_mat_dim_aobasis, almo_mat_dim_aobasis/), &
2247 : symmetry_new=dbcsr_type_symmetric, &
2248 : spin_key=0, &
2249 76 : init_domains=.TRUE.)
2250 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_s_blk_sqrt(1), &
2251 : matrix_qs=matrix_s0, &
2252 : almo_scf_env=almo_scf_env, &
2253 : name_new="S_BLK_SQRT", &
2254 : size_keys=(/almo_mat_dim_aobasis, almo_mat_dim_aobasis/), &
2255 : symmetry_new=dbcsr_type_symmetric, &
2256 : spin_key=0, &
2257 76 : init_domains=.TRUE.)
2258 40 : ELSE IF (almo_scf_env%almo_update_algorithm .EQ. almo_scf_dm_sign) THEN
2259 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_s_blk_inv(1), &
2260 : matrix_qs=matrix_s0, &
2261 : almo_scf_env=almo_scf_env, &
2262 : name_new="S_BLK_INV", &
2263 : size_keys=(/almo_mat_dim_aobasis, almo_mat_dim_aobasis/), &
2264 : symmetry_new=dbcsr_type_symmetric, &
2265 : spin_key=0, &
2266 0 : init_domains=.TRUE.)
2267 : END IF
2268 :
2269 : ! MO coeff matrices and their derivatives
2270 464 : ALLOCATE (almo_scf_env%matrix_t_blk(nspins))
2271 464 : ALLOCATE (almo_scf_env%quench_t_blk(nspins))
2272 464 : ALLOCATE (almo_scf_env%matrix_err_blk(nspins))
2273 464 : ALLOCATE (almo_scf_env%matrix_err_xx(nspins))
2274 464 : ALLOCATE (almo_scf_env%matrix_sigma(nspins))
2275 464 : ALLOCATE (almo_scf_env%matrix_sigma_inv(nspins))
2276 464 : ALLOCATE (almo_scf_env%matrix_sigma_sqrt(nspins))
2277 464 : ALLOCATE (almo_scf_env%matrix_sigma_sqrt_inv(nspins))
2278 464 : ALLOCATE (almo_scf_env%matrix_sigma_blk(nspins))
2279 464 : ALLOCATE (almo_scf_env%matrix_sigma_inv_0deloc(nspins))
2280 464 : ALLOCATE (almo_scf_env%matrix_t(nspins))
2281 464 : ALLOCATE (almo_scf_env%matrix_t_tr(nspins))
2282 232 : DO ispin = 1, nspins
2283 : ! create the blocked quencher
2284 : CALL matrix_almo_create(matrix_new=almo_scf_env%quench_t_blk(ispin), &
2285 : matrix_qs=matrix_s0, &
2286 : almo_scf_env=almo_scf_env, &
2287 : name_new="Q_BLK", &
2288 : size_keys=(/almo_mat_dim_aobasis, almo_mat_dim_occ/), &
2289 : symmetry_new=dbcsr_type_no_symmetry, &
2290 : spin_key=ispin, &
2291 116 : init_domains=.TRUE.)
2292 : ! create ALMO coefficient matrix
2293 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_t_blk(ispin), &
2294 : matrix_qs=matrix_s0, &
2295 : almo_scf_env=almo_scf_env, &
2296 : name_new="T_BLK", &
2297 : size_keys=(/almo_mat_dim_aobasis, almo_mat_dim_occ/), &
2298 : symmetry_new=dbcsr_type_no_symmetry, &
2299 : spin_key=ispin, &
2300 116 : init_domains=.TRUE.)
2301 : ! create the error matrix
2302 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_err_blk(ispin), &
2303 : matrix_qs=matrix_s0, &
2304 : almo_scf_env=almo_scf_env, &
2305 : name_new="ERR_BLK", &
2306 : size_keys=(/almo_mat_dim_aobasis, almo_mat_dim_aobasis/), &
2307 : symmetry_new=dbcsr_type_no_symmetry, &
2308 : spin_key=ispin, &
2309 116 : init_domains=.TRUE.)
2310 : ! create the error matrix for the quenched ALMOs
2311 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_err_xx(ispin), &
2312 : matrix_qs=matrix_s0, &
2313 : almo_scf_env=almo_scf_env, &
2314 : name_new="ERR_XX", &
2315 : size_keys=(/almo_mat_dim_aobasis, almo_mat_dim_occ/), &
2316 : symmetry_new=dbcsr_type_no_symmetry, &
2317 : spin_key=ispin, &
2318 116 : init_domains=.FALSE.)
2319 : ! create a matrix with dimensions of a transposed mo coefficient matrix
2320 : ! it might be necessary to perform the correction step using cayley
2321 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_t_tr(ispin), &
2322 : matrix_qs=matrix_s0, &
2323 : almo_scf_env=almo_scf_env, &
2324 : name_new="T_TR", &
2325 : size_keys=(/almo_mat_dim_occ, almo_mat_dim_aobasis/), &
2326 : symmetry_new=dbcsr_type_no_symmetry, &
2327 : spin_key=ispin, &
2328 116 : init_domains=.FALSE.)
2329 : ! create mo overlap matrix
2330 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_sigma(ispin), &
2331 : matrix_qs=matrix_s0, &
2332 : almo_scf_env=almo_scf_env, &
2333 : name_new="SIG", &
2334 : size_keys=(/almo_mat_dim_occ, almo_mat_dim_occ/), &
2335 : symmetry_new=dbcsr_type_symmetric, &
2336 : spin_key=ispin, &
2337 116 : init_domains=.FALSE.)
2338 : ! create blocked mo overlap matrix
2339 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_sigma_blk(ispin), &
2340 : matrix_qs=matrix_s0, &
2341 : almo_scf_env=almo_scf_env, &
2342 : name_new="SIG_BLK", &
2343 : size_keys=(/almo_mat_dim_occ, almo_mat_dim_occ/), &
2344 : symmetry_new=dbcsr_type_symmetric, &
2345 : spin_key=ispin, &
2346 116 : init_domains=.TRUE.)
2347 : ! create blocked inverse mo overlap matrix
2348 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_sigma_inv_0deloc(ispin), &
2349 : matrix_qs=matrix_s0, &
2350 : almo_scf_env=almo_scf_env, &
2351 : name_new="SIGINV_BLK", &
2352 : size_keys=(/almo_mat_dim_occ, almo_mat_dim_occ/), &
2353 : symmetry_new=dbcsr_type_symmetric, &
2354 : spin_key=ispin, &
2355 116 : init_domains=.TRUE.)
2356 : ! create inverse mo overlap matrix
2357 : CALL matrix_almo_create( &
2358 : matrix_new=almo_scf_env%matrix_sigma_inv(ispin), &
2359 : matrix_qs=matrix_s0, &
2360 : almo_scf_env=almo_scf_env, &
2361 : name_new="SIGINV", &
2362 : size_keys=(/almo_mat_dim_occ, almo_mat_dim_occ/), &
2363 : symmetry_new=dbcsr_type_symmetric, &
2364 : spin_key=ispin, &
2365 116 : init_domains=.FALSE.)
2366 : ! create various templates that will be necessary later
2367 : CALL matrix_almo_create( &
2368 : matrix_new=almo_scf_env%matrix_t(ispin), &
2369 : matrix_qs=matrix_s0, &
2370 : almo_scf_env=almo_scf_env, &
2371 : name_new="T", &
2372 : size_keys=(/almo_mat_dim_aobasis, almo_mat_dim_occ/), &
2373 : symmetry_new=dbcsr_type_no_symmetry, &
2374 : spin_key=ispin, &
2375 116 : init_domains=.FALSE.)
2376 : CALL dbcsr_create(almo_scf_env%matrix_sigma_sqrt(ispin), &
2377 : template=almo_scf_env%matrix_sigma(ispin), &
2378 116 : matrix_type=dbcsr_type_no_symmetry)
2379 : CALL dbcsr_create(almo_scf_env%matrix_sigma_sqrt_inv(ispin), &
2380 : template=almo_scf_env%matrix_sigma(ispin), &
2381 232 : matrix_type=dbcsr_type_no_symmetry)
2382 : END DO
2383 :
2384 : ! create virtual orbitals if necessary
2385 116 : IF (almo_scf_env%need_virtuals) THEN
2386 464 : ALLOCATE (almo_scf_env%matrix_v_blk(nspins))
2387 464 : ALLOCATE (almo_scf_env%matrix_v_full_blk(nspins))
2388 464 : ALLOCATE (almo_scf_env%matrix_v(nspins))
2389 464 : ALLOCATE (almo_scf_env%matrix_vo(nspins))
2390 464 : ALLOCATE (almo_scf_env%matrix_x(nspins))
2391 464 : ALLOCATE (almo_scf_env%matrix_ov(nspins))
2392 464 : ALLOCATE (almo_scf_env%matrix_ov_full(nspins))
2393 464 : ALLOCATE (almo_scf_env%matrix_sigma_vv(nspins))
2394 464 : ALLOCATE (almo_scf_env%matrix_sigma_vv_blk(nspins))
2395 464 : ALLOCATE (almo_scf_env%matrix_sigma_vv_sqrt(nspins))
2396 464 : ALLOCATE (almo_scf_env%matrix_sigma_vv_sqrt_inv(nspins))
2397 464 : ALLOCATE (almo_scf_env%matrix_vv_full_blk(nspins))
2398 :
2399 116 : IF (almo_scf_env%deloc_truncate_virt .NE. virt_full) THEN
2400 0 : ALLOCATE (almo_scf_env%matrix_k_blk(nspins))
2401 0 : ALLOCATE (almo_scf_env%matrix_k_blk_ones(nspins))
2402 0 : ALLOCATE (almo_scf_env%matrix_k_tr(nspins))
2403 0 : ALLOCATE (almo_scf_env%matrix_v_disc(nspins))
2404 0 : ALLOCATE (almo_scf_env%matrix_v_disc_blk(nspins))
2405 0 : ALLOCATE (almo_scf_env%matrix_ov_disc(nspins))
2406 0 : ALLOCATE (almo_scf_env%matrix_vv_disc_blk(nspins))
2407 0 : ALLOCATE (almo_scf_env%matrix_vv_disc(nspins))
2408 0 : ALLOCATE (almo_scf_env%opt_k_t_dd(nspins))
2409 0 : ALLOCATE (almo_scf_env%opt_k_t_rr(nspins))
2410 0 : ALLOCATE (almo_scf_env%opt_k_denom(nspins))
2411 : END IF
2412 :
2413 232 : DO ispin = 1, nspins
2414 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_v_full_blk(ispin), &
2415 : matrix_qs=matrix_s0, &
2416 : almo_scf_env=almo_scf_env, &
2417 : name_new="V_FULL_BLK", &
2418 : size_keys=(/almo_mat_dim_aobasis, almo_mat_dim_virt_full/), &
2419 : symmetry_new=dbcsr_type_no_symmetry, &
2420 : spin_key=ispin, &
2421 116 : init_domains=.FALSE.)
2422 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_v_blk(ispin), &
2423 : matrix_qs=matrix_s0, &
2424 : almo_scf_env=almo_scf_env, &
2425 : name_new="V_BLK", &
2426 : size_keys=(/almo_mat_dim_aobasis, almo_mat_dim_virt/), &
2427 : symmetry_new=dbcsr_type_no_symmetry, &
2428 : spin_key=ispin, &
2429 116 : init_domains=.FALSE.)
2430 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_v(ispin), &
2431 : matrix_qs=matrix_s0, &
2432 : almo_scf_env=almo_scf_env, &
2433 : name_new="V", &
2434 : size_keys=(/almo_mat_dim_aobasis, almo_mat_dim_virt/), &
2435 : symmetry_new=dbcsr_type_no_symmetry, &
2436 : spin_key=ispin, &
2437 116 : init_domains=.FALSE.)
2438 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_ov_full(ispin), &
2439 : matrix_qs=matrix_s0, &
2440 : almo_scf_env=almo_scf_env, &
2441 : name_new="OV_FULL", &
2442 : size_keys=(/almo_mat_dim_occ, almo_mat_dim_virt_full/), &
2443 : symmetry_new=dbcsr_type_no_symmetry, &
2444 : spin_key=ispin, &
2445 116 : init_domains=.FALSE.)
2446 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_ov(ispin), &
2447 : matrix_qs=matrix_s0, &
2448 : almo_scf_env=almo_scf_env, &
2449 : name_new="OV", &
2450 : size_keys=(/almo_mat_dim_occ, almo_mat_dim_virt/), &
2451 : symmetry_new=dbcsr_type_no_symmetry, &
2452 : spin_key=ispin, &
2453 116 : init_domains=.FALSE.)
2454 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_vo(ispin), &
2455 : matrix_qs=matrix_s0, &
2456 : almo_scf_env=almo_scf_env, &
2457 : name_new="VO", &
2458 : size_keys=(/almo_mat_dim_virt, almo_mat_dim_occ/), &
2459 : symmetry_new=dbcsr_type_no_symmetry, &
2460 : spin_key=ispin, &
2461 116 : init_domains=.FALSE.)
2462 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_x(ispin), &
2463 : matrix_qs=matrix_s0, &
2464 : almo_scf_env=almo_scf_env, &
2465 : name_new="VO", &
2466 : size_keys=(/almo_mat_dim_virt, almo_mat_dim_occ/), &
2467 : symmetry_new=dbcsr_type_no_symmetry, &
2468 : spin_key=ispin, &
2469 116 : init_domains=.FALSE.)
2470 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_sigma_vv(ispin), &
2471 : matrix_qs=matrix_s0, &
2472 : almo_scf_env=almo_scf_env, &
2473 : name_new="SIG_VV", &
2474 : size_keys=(/almo_mat_dim_virt, almo_mat_dim_virt/), &
2475 : symmetry_new=dbcsr_type_symmetric, &
2476 : spin_key=ispin, &
2477 116 : init_domains=.FALSE.)
2478 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_vv_full_blk(ispin), &
2479 : matrix_qs=matrix_s0, &
2480 : almo_scf_env=almo_scf_env, &
2481 : name_new="VV_FULL_BLK", &
2482 : size_keys=(/almo_mat_dim_virt_full, almo_mat_dim_virt_full/), &
2483 : symmetry_new=dbcsr_type_no_symmetry, &
2484 : spin_key=ispin, &
2485 116 : init_domains=.TRUE.)
2486 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_sigma_vv_blk(ispin), &
2487 : matrix_qs=matrix_s0, &
2488 : almo_scf_env=almo_scf_env, &
2489 : name_new="SIG_VV_BLK", &
2490 : size_keys=(/almo_mat_dim_virt, almo_mat_dim_virt/), &
2491 : symmetry_new=dbcsr_type_symmetric, &
2492 : spin_key=ispin, &
2493 116 : init_domains=.TRUE.)
2494 : CALL dbcsr_create(almo_scf_env%matrix_sigma_vv_sqrt(ispin), &
2495 : template=almo_scf_env%matrix_sigma_vv(ispin), &
2496 116 : matrix_type=dbcsr_type_no_symmetry)
2497 : CALL dbcsr_create(almo_scf_env%matrix_sigma_vv_sqrt_inv(ispin), &
2498 : template=almo_scf_env%matrix_sigma_vv(ispin), &
2499 116 : matrix_type=dbcsr_type_no_symmetry)
2500 :
2501 232 : IF (almo_scf_env%deloc_truncate_virt .NE. virt_full) THEN
2502 : CALL matrix_almo_create(matrix_new=almo_scf_env%opt_k_t_rr(ispin), &
2503 : matrix_qs=matrix_s0, &
2504 : almo_scf_env=almo_scf_env, &
2505 : name_new="OPT_K_U_RR", &
2506 : size_keys=(/almo_mat_dim_virt, almo_mat_dim_virt/), &
2507 : symmetry_new=dbcsr_type_no_symmetry, &
2508 : spin_key=ispin, &
2509 0 : init_domains=.FALSE.)
2510 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_vv_disc(ispin), &
2511 : matrix_qs=matrix_s0, &
2512 : almo_scf_env=almo_scf_env, &
2513 : name_new="VV_DISC", &
2514 : size_keys=(/almo_mat_dim_virt_disc, almo_mat_dim_virt_disc/), &
2515 : symmetry_new=dbcsr_type_symmetric, &
2516 : spin_key=ispin, &
2517 0 : init_domains=.FALSE.)
2518 : CALL matrix_almo_create(matrix_new=almo_scf_env%opt_k_t_dd(ispin), &
2519 : matrix_qs=matrix_s0, &
2520 : almo_scf_env=almo_scf_env, &
2521 : name_new="OPT_K_U_DD", &
2522 : size_keys=(/almo_mat_dim_virt_disc, almo_mat_dim_virt_disc/), &
2523 : symmetry_new=dbcsr_type_no_symmetry, &
2524 : spin_key=ispin, &
2525 0 : init_domains=.FALSE.)
2526 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_vv_disc_blk(ispin), &
2527 : matrix_qs=matrix_s0, &
2528 : almo_scf_env=almo_scf_env, &
2529 : name_new="VV_DISC_BLK", &
2530 : size_keys=(/almo_mat_dim_virt_disc, almo_mat_dim_virt_disc/), &
2531 : symmetry_new=dbcsr_type_symmetric, &
2532 : spin_key=ispin, &
2533 0 : init_domains=.TRUE.)
2534 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_k_blk(ispin), &
2535 : matrix_qs=matrix_s0, &
2536 : almo_scf_env=almo_scf_env, &
2537 : name_new="K_BLK", &
2538 : size_keys=(/almo_mat_dim_virt_disc, almo_mat_dim_virt/), &
2539 : symmetry_new=dbcsr_type_no_symmetry, &
2540 : spin_key=ispin, &
2541 0 : init_domains=.TRUE.)
2542 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_k_blk_ones(ispin), &
2543 : matrix_qs=matrix_s0, &
2544 : almo_scf_env=almo_scf_env, &
2545 : name_new="K_BLK_1", &
2546 : size_keys=(/almo_mat_dim_virt_disc, almo_mat_dim_virt/), &
2547 : symmetry_new=dbcsr_type_no_symmetry, &
2548 : spin_key=ispin, &
2549 0 : init_domains=.TRUE.)
2550 : CALL matrix_almo_create(matrix_new=almo_scf_env%opt_k_denom(ispin), &
2551 : matrix_qs=matrix_s0, &
2552 : almo_scf_env=almo_scf_env, &
2553 : name_new="OPT_K_DENOM", &
2554 : size_keys=(/almo_mat_dim_virt_disc, almo_mat_dim_virt/), &
2555 : symmetry_new=dbcsr_type_no_symmetry, &
2556 : spin_key=ispin, &
2557 0 : init_domains=.FALSE.)
2558 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_k_tr(ispin), &
2559 : matrix_qs=matrix_s0, &
2560 : almo_scf_env=almo_scf_env, &
2561 : name_new="K_TR", &
2562 : size_keys=(/almo_mat_dim_virt, almo_mat_dim_virt_disc/), &
2563 : symmetry_new=dbcsr_type_no_symmetry, &
2564 : spin_key=ispin, &
2565 0 : init_domains=.FALSE.)
2566 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_v_disc_blk(ispin), &
2567 : matrix_qs=matrix_s0, &
2568 : almo_scf_env=almo_scf_env, &
2569 : name_new="V_DISC_BLK", &
2570 : size_keys=(/almo_mat_dim_aobasis, almo_mat_dim_virt_disc/), &
2571 : symmetry_new=dbcsr_type_no_symmetry, &
2572 : spin_key=ispin, &
2573 0 : init_domains=.FALSE.)
2574 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_v_disc(ispin), &
2575 : matrix_qs=matrix_s0, &
2576 : almo_scf_env=almo_scf_env, &
2577 : name_new="V_DISC", &
2578 : size_keys=(/almo_mat_dim_aobasis, almo_mat_dim_virt_disc/), &
2579 : symmetry_new=dbcsr_type_no_symmetry, &
2580 : spin_key=ispin, &
2581 0 : init_domains=.FALSE.)
2582 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_ov_disc(ispin), &
2583 : matrix_qs=matrix_s0, &
2584 : almo_scf_env=almo_scf_env, &
2585 : name_new="OV_DISC", &
2586 : size_keys=(/almo_mat_dim_occ, almo_mat_dim_virt_disc/), &
2587 : symmetry_new=dbcsr_type_no_symmetry, &
2588 : spin_key=ispin, &
2589 0 : init_domains=.FALSE.)
2590 :
2591 : END IF ! end need_discarded_virtuals
2592 :
2593 : END DO ! spin
2594 : END IF
2595 :
2596 : ! create matrices of orbital energies if necessary
2597 116 : IF (almo_scf_env%need_orbital_energies) THEN
2598 464 : ALLOCATE (almo_scf_env%matrix_eoo(nspins))
2599 464 : ALLOCATE (almo_scf_env%matrix_evv_full(nspins))
2600 232 : DO ispin = 1, nspins
2601 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_eoo(ispin), &
2602 : matrix_qs=matrix_s0, &
2603 : almo_scf_env=almo_scf_env, &
2604 : name_new="E_OCC", &
2605 : size_keys=(/almo_mat_dim_occ, almo_mat_dim_occ/), &
2606 : symmetry_new=dbcsr_type_no_symmetry, &
2607 : spin_key=ispin, &
2608 116 : init_domains=.FALSE.)
2609 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_evv_full(ispin), &
2610 : matrix_qs=matrix_s0, &
2611 : almo_scf_env=almo_scf_env, &
2612 : name_new="E_VIRT", &
2613 : size_keys=(/almo_mat_dim_virt_full, almo_mat_dim_virt_full/), &
2614 : symmetry_new=dbcsr_type_no_symmetry, &
2615 : spin_key=ispin, &
2616 232 : init_domains=.FALSE.)
2617 : END DO
2618 : END IF
2619 :
2620 : ! Density and KS matrices
2621 464 : ALLOCATE (almo_scf_env%matrix_p(nspins))
2622 464 : ALLOCATE (almo_scf_env%matrix_p_blk(nspins))
2623 464 : ALLOCATE (almo_scf_env%matrix_ks(nspins))
2624 464 : ALLOCATE (almo_scf_env%matrix_ks_blk(nspins))
2625 116 : IF (almo_scf_env%need_previous_ks) &
2626 464 : ALLOCATE (almo_scf_env%matrix_ks_0deloc(nspins))
2627 232 : DO ispin = 1, nspins
2628 : ! RZK-warning copy with symmery but remember that this might cause problems
2629 : CALL dbcsr_create(almo_scf_env%matrix_p(ispin), &
2630 : template=almo_scf_env%matrix_s(1), &
2631 116 : matrix_type=dbcsr_type_symmetric)
2632 : CALL dbcsr_create(almo_scf_env%matrix_ks(ispin), &
2633 : template=almo_scf_env%matrix_s(1), &
2634 116 : matrix_type=dbcsr_type_symmetric)
2635 116 : IF (almo_scf_env%need_previous_ks) THEN
2636 : CALL dbcsr_create(almo_scf_env%matrix_ks_0deloc(ispin), &
2637 : template=almo_scf_env%matrix_s(1), &
2638 116 : matrix_type=dbcsr_type_symmetric)
2639 : END IF
2640 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_p_blk(ispin), &
2641 : matrix_qs=matrix_s0, &
2642 : almo_scf_env=almo_scf_env, &
2643 : name_new="P_BLK", &
2644 : size_keys=(/almo_mat_dim_aobasis, almo_mat_dim_aobasis/), &
2645 : symmetry_new=dbcsr_type_symmetric, &
2646 : spin_key=ispin, &
2647 116 : init_domains=.TRUE.)
2648 : CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_ks_blk(ispin), &
2649 : matrix_qs=matrix_s0, &
2650 : almo_scf_env=almo_scf_env, &
2651 : name_new="KS_BLK", &
2652 : size_keys=(/almo_mat_dim_aobasis, almo_mat_dim_aobasis/), &
2653 : symmetry_new=dbcsr_type_symmetric, &
2654 : spin_key=ispin, &
2655 232 : init_domains=.TRUE.)
2656 : END DO
2657 :
2658 116 : CALL timestop(handle)
2659 :
2660 116 : END SUBROUTINE almo_scf_env_create_matrices
2661 :
2662 : ! **************************************************************************************************
2663 : !> \brief clean up procedures for almo scf
2664 : !> \param almo_scf_env ...
2665 : !> \par History
2666 : !> 2011.06 created [Rustam Z Khaliullin]
2667 : !> 2018.09 smearing support [Ruben Staub]
2668 : !> \author Rustam Z Khaliullin
2669 : ! **************************************************************************************************
2670 116 : SUBROUTINE almo_scf_clean_up(almo_scf_env)
2671 :
2672 : TYPE(almo_scf_env_type), INTENT(INOUT) :: almo_scf_env
2673 :
2674 : CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_clean_up'
2675 :
2676 : INTEGER :: handle, ispin, unit_nr
2677 : TYPE(cp_logger_type), POINTER :: logger
2678 :
2679 116 : CALL timeset(routineN, handle)
2680 :
2681 : ! get a useful output_unit
2682 116 : logger => cp_get_default_logger()
2683 116 : IF (logger%para_env%is_source()) THEN
2684 58 : unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
2685 : ELSE
2686 : unit_nr = -1
2687 : END IF
2688 :
2689 : ! release matrices
2690 116 : CALL dbcsr_release(almo_scf_env%matrix_s(1))
2691 116 : CALL dbcsr_release(almo_scf_env%matrix_s_blk(1))
2692 116 : IF (almo_scf_env%almo_update_algorithm .EQ. almo_scf_diag) THEN
2693 76 : CALL dbcsr_release(almo_scf_env%matrix_s_blk_sqrt_inv(1))
2694 76 : CALL dbcsr_release(almo_scf_env%matrix_s_blk_sqrt(1))
2695 40 : ELSE IF (almo_scf_env%almo_update_algorithm .EQ. almo_scf_dm_sign) THEN
2696 0 : CALL dbcsr_release(almo_scf_env%matrix_s_blk_inv(1))
2697 : END IF
2698 232 : DO ispin = 1, almo_scf_env%nspins
2699 116 : CALL dbcsr_release(almo_scf_env%quench_t(ispin))
2700 116 : CALL dbcsr_release(almo_scf_env%quench_t_blk(ispin))
2701 116 : CALL dbcsr_release(almo_scf_env%matrix_t_blk(ispin))
2702 116 : CALL dbcsr_release(almo_scf_env%matrix_err_blk(ispin))
2703 116 : CALL dbcsr_release(almo_scf_env%matrix_err_xx(ispin))
2704 116 : CALL dbcsr_release(almo_scf_env%matrix_t_tr(ispin))
2705 116 : CALL dbcsr_release(almo_scf_env%matrix_sigma(ispin))
2706 116 : CALL dbcsr_release(almo_scf_env%matrix_sigma_blk(ispin))
2707 116 : CALL dbcsr_release(almo_scf_env%matrix_sigma_inv_0deloc(ispin))
2708 116 : CALL dbcsr_release(almo_scf_env%matrix_sigma_inv(ispin))
2709 116 : CALL dbcsr_release(almo_scf_env%matrix_t(ispin))
2710 116 : CALL dbcsr_release(almo_scf_env%matrix_sigma_sqrt(ispin))
2711 116 : CALL dbcsr_release(almo_scf_env%matrix_sigma_sqrt_inv(ispin))
2712 116 : CALL dbcsr_release(almo_scf_env%matrix_p(ispin))
2713 116 : CALL dbcsr_release(almo_scf_env%matrix_ks(ispin))
2714 116 : CALL dbcsr_release(almo_scf_env%matrix_p_blk(ispin))
2715 116 : CALL dbcsr_release(almo_scf_env%matrix_ks_blk(ispin))
2716 116 : IF (almo_scf_env%need_previous_ks) THEN
2717 116 : CALL dbcsr_release(almo_scf_env%matrix_ks_0deloc(ispin))
2718 : END IF
2719 116 : IF (almo_scf_env%need_virtuals) THEN
2720 116 : CALL dbcsr_release(almo_scf_env%matrix_v_blk(ispin))
2721 116 : CALL dbcsr_release(almo_scf_env%matrix_v_full_blk(ispin))
2722 116 : CALL dbcsr_release(almo_scf_env%matrix_v(ispin))
2723 116 : CALL dbcsr_release(almo_scf_env%matrix_vo(ispin))
2724 116 : CALL dbcsr_release(almo_scf_env%matrix_x(ispin))
2725 116 : CALL dbcsr_release(almo_scf_env%matrix_ov(ispin))
2726 116 : CALL dbcsr_release(almo_scf_env%matrix_ov_full(ispin))
2727 116 : CALL dbcsr_release(almo_scf_env%matrix_sigma_vv(ispin))
2728 116 : CALL dbcsr_release(almo_scf_env%matrix_sigma_vv_blk(ispin))
2729 116 : CALL dbcsr_release(almo_scf_env%matrix_sigma_vv_sqrt(ispin))
2730 116 : CALL dbcsr_release(almo_scf_env%matrix_sigma_vv_sqrt_inv(ispin))
2731 116 : CALL dbcsr_release(almo_scf_env%matrix_vv_full_blk(ispin))
2732 116 : IF (almo_scf_env%deloc_truncate_virt .NE. virt_full) THEN
2733 0 : CALL dbcsr_release(almo_scf_env%matrix_k_tr(ispin))
2734 0 : CALL dbcsr_release(almo_scf_env%matrix_k_blk(ispin))
2735 0 : CALL dbcsr_release(almo_scf_env%matrix_k_blk_ones(ispin))
2736 0 : CALL dbcsr_release(almo_scf_env%matrix_v_disc(ispin))
2737 0 : CALL dbcsr_release(almo_scf_env%matrix_v_disc_blk(ispin))
2738 0 : CALL dbcsr_release(almo_scf_env%matrix_ov_disc(ispin))
2739 0 : CALL dbcsr_release(almo_scf_env%matrix_vv_disc_blk(ispin))
2740 0 : CALL dbcsr_release(almo_scf_env%matrix_vv_disc(ispin))
2741 0 : CALL dbcsr_release(almo_scf_env%opt_k_t_dd(ispin))
2742 0 : CALL dbcsr_release(almo_scf_env%opt_k_t_rr(ispin))
2743 0 : CALL dbcsr_release(almo_scf_env%opt_k_denom(ispin))
2744 : END IF
2745 : END IF
2746 232 : IF (almo_scf_env%need_orbital_energies) THEN
2747 116 : CALL dbcsr_release(almo_scf_env%matrix_eoo(ispin))
2748 116 : CALL dbcsr_release(almo_scf_env%matrix_evv_full(ispin))
2749 : END IF
2750 : END DO
2751 :
2752 : ! deallocate matrices
2753 116 : DEALLOCATE (almo_scf_env%matrix_p)
2754 116 : DEALLOCATE (almo_scf_env%matrix_p_blk)
2755 116 : DEALLOCATE (almo_scf_env%matrix_ks)
2756 116 : DEALLOCATE (almo_scf_env%matrix_ks_blk)
2757 116 : DEALLOCATE (almo_scf_env%matrix_t_blk)
2758 116 : DEALLOCATE (almo_scf_env%matrix_err_blk)
2759 116 : DEALLOCATE (almo_scf_env%matrix_err_xx)
2760 116 : DEALLOCATE (almo_scf_env%matrix_t)
2761 116 : DEALLOCATE (almo_scf_env%matrix_t_tr)
2762 116 : DEALLOCATE (almo_scf_env%matrix_sigma)
2763 116 : DEALLOCATE (almo_scf_env%matrix_sigma_blk)
2764 116 : DEALLOCATE (almo_scf_env%matrix_sigma_inv_0deloc)
2765 116 : DEALLOCATE (almo_scf_env%matrix_sigma_sqrt)
2766 116 : DEALLOCATE (almo_scf_env%matrix_sigma_sqrt_inv)
2767 116 : DEALLOCATE (almo_scf_env%matrix_sigma_inv)
2768 116 : DEALLOCATE (almo_scf_env%quench_t)
2769 116 : DEALLOCATE (almo_scf_env%quench_t_blk)
2770 116 : IF (almo_scf_env%need_virtuals) THEN
2771 116 : DEALLOCATE (almo_scf_env%matrix_v_blk)
2772 116 : DEALLOCATE (almo_scf_env%matrix_v_full_blk)
2773 116 : DEALLOCATE (almo_scf_env%matrix_v)
2774 116 : DEALLOCATE (almo_scf_env%matrix_vo)
2775 116 : DEALLOCATE (almo_scf_env%matrix_x)
2776 116 : DEALLOCATE (almo_scf_env%matrix_ov)
2777 116 : DEALLOCATE (almo_scf_env%matrix_ov_full)
2778 116 : DEALLOCATE (almo_scf_env%matrix_sigma_vv)
2779 116 : DEALLOCATE (almo_scf_env%matrix_sigma_vv_blk)
2780 116 : DEALLOCATE (almo_scf_env%matrix_sigma_vv_sqrt)
2781 116 : DEALLOCATE (almo_scf_env%matrix_sigma_vv_sqrt_inv)
2782 116 : DEALLOCATE (almo_scf_env%matrix_vv_full_blk)
2783 116 : IF (almo_scf_env%deloc_truncate_virt .NE. virt_full) THEN
2784 0 : DEALLOCATE (almo_scf_env%matrix_k_tr)
2785 0 : DEALLOCATE (almo_scf_env%matrix_k_blk)
2786 0 : DEALLOCATE (almo_scf_env%matrix_v_disc)
2787 0 : DEALLOCATE (almo_scf_env%matrix_v_disc_blk)
2788 0 : DEALLOCATE (almo_scf_env%matrix_ov_disc)
2789 0 : DEALLOCATE (almo_scf_env%matrix_vv_disc_blk)
2790 0 : DEALLOCATE (almo_scf_env%matrix_vv_disc)
2791 0 : DEALLOCATE (almo_scf_env%matrix_k_blk_ones)
2792 0 : DEALLOCATE (almo_scf_env%opt_k_t_dd)
2793 0 : DEALLOCATE (almo_scf_env%opt_k_t_rr)
2794 0 : DEALLOCATE (almo_scf_env%opt_k_denom)
2795 : END IF
2796 : END IF
2797 116 : IF (almo_scf_env%need_previous_ks) THEN
2798 116 : DEALLOCATE (almo_scf_env%matrix_ks_0deloc)
2799 : END IF
2800 116 : IF (almo_scf_env%need_orbital_energies) THEN
2801 116 : DEALLOCATE (almo_scf_env%matrix_eoo)
2802 116 : DEALLOCATE (almo_scf_env%matrix_evv_full)
2803 : END IF
2804 :
2805 : ! clean up other variables
2806 232 : DO ispin = 1, almo_scf_env%nspins
2807 : CALL release_submatrices( &
2808 116 : almo_scf_env%domain_preconditioner(:, ispin))
2809 116 : CALL release_submatrices(almo_scf_env%domain_s_inv(:, ispin))
2810 116 : CALL release_submatrices(almo_scf_env%domain_s_sqrt_inv(:, ispin))
2811 116 : CALL release_submatrices(almo_scf_env%domain_s_sqrt(:, ispin))
2812 116 : CALL release_submatrices(almo_scf_env%domain_ks_xx(:, ispin))
2813 116 : CALL release_submatrices(almo_scf_env%domain_t(:, ispin))
2814 116 : CALL release_submatrices(almo_scf_env%domain_err(:, ispin))
2815 232 : CALL release_submatrices(almo_scf_env%domain_r_down_up(:, ispin))
2816 : END DO
2817 926 : DEALLOCATE (almo_scf_env%domain_preconditioner)
2818 926 : DEALLOCATE (almo_scf_env%domain_s_inv)
2819 926 : DEALLOCATE (almo_scf_env%domain_s_sqrt_inv)
2820 926 : DEALLOCATE (almo_scf_env%domain_s_sqrt)
2821 926 : DEALLOCATE (almo_scf_env%domain_ks_xx)
2822 926 : DEALLOCATE (almo_scf_env%domain_t)
2823 926 : DEALLOCATE (almo_scf_env%domain_err)
2824 926 : DEALLOCATE (almo_scf_env%domain_r_down_up)
2825 232 : DO ispin = 1, almo_scf_env%nspins
2826 116 : DEALLOCATE (almo_scf_env%domain_map(ispin)%pairs)
2827 232 : DEALLOCATE (almo_scf_env%domain_map(ispin)%index1)
2828 : END DO
2829 232 : DEALLOCATE (almo_scf_env%domain_map)
2830 116 : DEALLOCATE (almo_scf_env%domain_index_of_ao)
2831 116 : DEALLOCATE (almo_scf_env%domain_index_of_atom)
2832 116 : DEALLOCATE (almo_scf_env%first_atom_of_domain)
2833 116 : DEALLOCATE (almo_scf_env%last_atom_of_domain)
2834 116 : DEALLOCATE (almo_scf_env%nbasis_of_domain)
2835 116 : DEALLOCATE (almo_scf_env%nocc_of_domain)
2836 116 : DEALLOCATE (almo_scf_env%real_ne_of_domain)
2837 116 : DEALLOCATE (almo_scf_env%nvirt_full_of_domain)
2838 116 : DEALLOCATE (almo_scf_env%nvirt_of_domain)
2839 116 : DEALLOCATE (almo_scf_env%nvirt_disc_of_domain)
2840 116 : DEALLOCATE (almo_scf_env%mu_of_domain)
2841 116 : DEALLOCATE (almo_scf_env%cpu_of_domain)
2842 116 : DEALLOCATE (almo_scf_env%charge_of_domain)
2843 116 : DEALLOCATE (almo_scf_env%multiplicity_of_domain)
2844 116 : IF (almo_scf_env%smear) THEN
2845 4 : DEALLOCATE (almo_scf_env%mo_energies)
2846 4 : DEALLOCATE (almo_scf_env%kTS)
2847 : END IF
2848 :
2849 116 : DEALLOCATE (almo_scf_env%domain_index_of_ao_block)
2850 116 : DEALLOCATE (almo_scf_env%domain_index_of_mo_block)
2851 :
2852 116 : CALL mp_para_env_release(almo_scf_env%para_env)
2853 116 : CALL cp_blacs_env_release(almo_scf_env%blacs_env)
2854 :
2855 116 : CALL timestop(handle)
2856 :
2857 116 : END SUBROUTINE almo_scf_clean_up
2858 :
2859 : ! **************************************************************************************************
2860 : !> \brief Do post scf calculations with ALMO
2861 : !> WARNING: ALMO post scf calculation may not work for certain quantities,
2862 : !> like forces, since ALMO wave function is only 'partially' optimized
2863 : !> \param qs_env ...
2864 : !> \par History
2865 : !> 2016.12 created [Yifei Shi]
2866 : !> \author Yifei Shi
2867 : ! **************************************************************************************************
2868 116 : SUBROUTINE almo_post_scf_compute_properties(qs_env)
2869 : TYPE(qs_environment_type), POINTER :: qs_env
2870 :
2871 116 : CALL qs_scf_compute_properties(qs_env)
2872 :
2873 116 : END SUBROUTINE almo_post_scf_compute_properties
2874 :
2875 : END MODULE almo_scf
2876 :
|