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