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