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