(git:1f9fd2c)
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 (*, *) "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 (*, *) "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 (*, *) "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 (*, *) "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 (*, *) "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 (*, *) "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 LOGICAL :: almo_experimental
1404 TYPE(cp_logger_type), POINTER :: logger
1405 TYPE(dbcsr_type), ALLOCATABLE, DIMENSION(:) :: no_quench
1406 TYPE(optimizer_options_type) :: arbitrary_optimizer
1407
1408 CALL timeset(routinen, handle)
1409
1410 ! get a useful output_unit
1411 logger => cp_get_default_logger()
1412 IF (logger%para_env%is_source()) THEN
1413 unit_nr = cp_logger_get_default_unit_nr(logger, local=.true.)
1414 ELSE
1415 unit_nr = -1
1416 END IF
1417
1418 ! create a local optimizer that handles XALMO DIIS
1419 ! the options of this optimizer are arbitrary because
1420 ! XALMO DIIS SCF does not converge for yet unknown reasons and
1421 ! currently used in the code to get perturbative estimates only
1422 arbitrary_optimizer%optimizer_type = optimizer_diis
1423 arbitrary_optimizer%max_iter = 3
1424 arbitrary_optimizer%eps_error = 1.0e-6_dp
1425 arbitrary_optimizer%ndiis = 2
1426
1427 SELECT CASE (almo_scf_env%deloc_method)
1429
1430 ! RZK-warning hack into the quenched routine:
1431 ! create a quench matrix with all-all-all blocks 1.0
1432 ! it is a waste of memory but since matrices are distributed
1433 ! we can tolerate it for now
1434 ALLOCATE (no_quench(almo_scf_env%nspins))
1435 CALL dbcsr_create(no_quench(1), &
1436 template=almo_scf_env%matrix_t(1), &
1437 matrix_type=dbcsr_type_no_symmetry)
1438 CALL dbcsr_reserve_all_blocks(no_quench(1))
1439 CALL dbcsr_set(no_quench(1), 1.0_dp)
1440 IF (almo_scf_env%nspins > 1) THEN
1441 DO ispin = 2, almo_scf_env%nspins
1442 CALL dbcsr_create(no_quench(ispin), &
1443 template=almo_scf_env%matrix_t(1), &
1444 matrix_type=dbcsr_type_no_symmetry)
1445 CALL dbcsr_copy(no_quench(ispin), no_quench(1))
1446 END DO
1447 END IF
1448
1449 END SELECT
1450
1451 SELECT CASE (almo_scf_env%deloc_method)
1453
1454 DO ispin = 1, almo_scf_env%nspins
1455 CALL dbcsr_copy(almo_scf_env%matrix_t(ispin), &
1456 almo_scf_env%matrix_t_blk(ispin))
1457 END DO
1458
1460
1461 !!!! RZK-warning a whole class of delocalization methods
1462 !!!! are commented out at the moment because some of their
1463 !!!! routines have not been thoroughly tested.
1464
1465 !!!! if we have virtuals pre-optimize and truncate them
1466 !!!IF (almo_scf_env%need_virtuals) THEN
1467 !!! SELECT CASE (almo_scf_env%deloc_truncate_virt)
1468 !!! CASE (virt_full)
1469 !!! ! simply copy virtual orbitals from matrix_v_full_blk to matrix_v_blk
1470 !!! DO ispin=1,almo_scf_env%nspins
1471 !!! CALL dbcsr_copy(almo_scf_env%matrix_v_blk(ispin),&
1472 !!! almo_scf_env%matrix_v_full_blk(ispin))
1473 !!! ENDDO
1474 !!! CASE (virt_number,virt_occ_size)
1475 !!! CALL split_v_blk(almo_scf_env)
1476 !!! !CALL truncate_subspace_v_blk(qs_env,almo_scf_env)
1477 !!! CASE DEFAULT
1478 !!! CPErrorMessage(cp_failure_level,routineP,"illegal method for virtual space truncation")
1479 !!! CPPrecondition(.FALSE.,cp_failure_level,routineP,failure)
1480 !!! END SELECT
1481 !!!ENDIF
1482 !!!CALL harris_foulkes_correction(qs_env,almo_scf_env)
1483
1484 IF (almo_scf_env%xalmo_update_algorithm == almo_scf_pcg) THEN
1485
1486 CALL almo_scf_xalmo_pcg(qs_env=qs_env, &
1487 almo_scf_env=almo_scf_env, &
1488 optimizer=almo_scf_env%opt_xalmo_pcg, &
1489 quench_t=no_quench, &
1490 matrix_t_in=almo_scf_env%matrix_t_blk, &
1491 matrix_t_out=almo_scf_env%matrix_t, &
1492 assume_t0_q0x=(almo_scf_env%xalmo_trial_wf == xalmo_trial_r0_out), &
1493 perturbation_only=.true., &
1494 special_case=xalmo_case_fully_deloc)
1495
1496 ELSE IF (almo_scf_env%xalmo_update_algorithm == almo_scf_trustr) THEN
1497
1498 CALL almo_scf_xalmo_trustr(qs_env=qs_env, &
1499 almo_scf_env=almo_scf_env, &
1500 optimizer=almo_scf_env%opt_xalmo_trustr, &
1501 quench_t=no_quench, &
1502 matrix_t_in=almo_scf_env%matrix_t_blk, &
1503 matrix_t_out=almo_scf_env%matrix_t, &
1504 perturbation_only=.true., &
1505 special_case=xalmo_case_fully_deloc)
1506
1507 ELSE
1508
1509 cpabort("Other algorithms do not exist")
1510
1511 END IF
1512
1514
1515 IF (almo_scf_env%xalmo_update_algorithm == almo_scf_diag) THEN
1516
1517 almo_scf_env%perturbative_delocalization = .true.
1518 DO ispin = 1, almo_scf_env%nspins
1519 CALL dbcsr_copy(almo_scf_env%matrix_t(ispin), &
1520 almo_scf_env%matrix_t_blk(ispin))
1521 END DO
1522 CALL almo_scf_xalmo_eigensolver(qs_env, almo_scf_env, &
1523 arbitrary_optimizer)
1524
1525 ELSE
1526
1527 cpabort("Other algorithms do not exist")
1528
1529 END IF
1530
1531 CASE (almo_deloc_xalmo_x)
1532
1533 IF (almo_scf_env%xalmo_update_algorithm == almo_scf_pcg) THEN
1534
1535 CALL almo_scf_xalmo_pcg(qs_env=qs_env, &
1536 almo_scf_env=almo_scf_env, &
1537 optimizer=almo_scf_env%opt_xalmo_pcg, &
1538 quench_t=almo_scf_env%quench_t, &
1539 matrix_t_in=almo_scf_env%matrix_t_blk, &
1540 matrix_t_out=almo_scf_env%matrix_t, &
1541 assume_t0_q0x=(almo_scf_env%xalmo_trial_wf == xalmo_trial_r0_out), &
1542 perturbation_only=.true., &
1543 special_case=xalmo_case_normal)
1544
1545 ELSE IF (almo_scf_env%xalmo_update_algorithm == almo_scf_trustr) THEN
1546
1547 CALL almo_scf_xalmo_trustr(qs_env=qs_env, &
1548 almo_scf_env=almo_scf_env, &
1549 optimizer=almo_scf_env%opt_xalmo_trustr, &
1550 quench_t=almo_scf_env%quench_t, &
1551 matrix_t_in=almo_scf_env%matrix_t_blk, &
1552 matrix_t_out=almo_scf_env%matrix_t, &
1553 perturbation_only=.true., &
1554 special_case=xalmo_case_normal)
1555
1556 ELSE
1557
1558 cpabort("Other algorithms do not exist")
1559
1560 END IF
1561
1563
1564 IF (almo_scf_env%xalmo_update_algorithm == almo_scf_diag) THEN
1565
1566 cpabort("Should not be here: convergence will fail!")
1567
1568 almo_scf_env%perturbative_delocalization = .false.
1569 DO ispin = 1, almo_scf_env%nspins
1570 CALL dbcsr_copy(almo_scf_env%matrix_t(ispin), &
1571 almo_scf_env%matrix_t_blk(ispin))
1572 END DO
1573 CALL almo_scf_xalmo_eigensolver(qs_env, almo_scf_env, &
1574 arbitrary_optimizer)
1575
1576 ELSE IF (almo_scf_env%xalmo_update_algorithm == almo_scf_pcg) THEN
1577
1578 CALL almo_scf_xalmo_pcg(qs_env=qs_env, &
1579 almo_scf_env=almo_scf_env, &
1580 optimizer=almo_scf_env%opt_xalmo_pcg, &
1581 quench_t=almo_scf_env%quench_t, &
1582 matrix_t_in=almo_scf_env%matrix_t_blk, &
1583 matrix_t_out=almo_scf_env%matrix_t, &
1584 assume_t0_q0x=(almo_scf_env%xalmo_trial_wf == xalmo_trial_r0_out), &
1585 perturbation_only=.false., &
1586 special_case=xalmo_case_normal)
1587
1588 ! RZK-warning THIS IS A HACK TO GET ORBITAL ENERGIES
1589 almo_experimental = .false.
1590 IF (almo_experimental) THEN
1591 almo_scf_env%perturbative_delocalization = .true.
1592 !DO ispin=1,almo_scf_env%nspins
1593 ! CALL dbcsr_copy(almo_scf_env%matrix_t(ispin),&
1594 ! almo_scf_env%matrix_t_blk(ispin))
1595 !ENDDO
1596 CALL almo_scf_xalmo_eigensolver(qs_env, almo_scf_env, &
1597 arbitrary_optimizer)
1598 END IF ! experimental
1599
1600 ELSE IF (almo_scf_env%xalmo_update_algorithm == almo_scf_trustr) THEN
1601
1602 CALL almo_scf_xalmo_trustr(qs_env=qs_env, &
1603 almo_scf_env=almo_scf_env, &
1604 optimizer=almo_scf_env%opt_xalmo_trustr, &
1605 quench_t=almo_scf_env%quench_t, &
1606 matrix_t_in=almo_scf_env%matrix_t_blk, &
1607 matrix_t_out=almo_scf_env%matrix_t, &
1608 perturbation_only=.false., &
1609 special_case=xalmo_case_normal)
1610
1611 ELSE
1612
1613 cpabort("Other algorithms do not exist")
1614
1615 END IF
1616
1617 CASE DEFAULT
1618
1619 cpabort("Illegal delocalization method")
1620
1621 END SELECT
1622
1623 SELECT CASE (almo_scf_env%deloc_method)
1625
1626 IF (almo_scf_env%deloc_truncate_virt /= virt_full) THEN
1627 cpabort("full scf is NYI for truncated virtual space")
1628 END IF
1629
1630 IF (almo_scf_env%xalmo_update_algorithm == almo_scf_pcg) THEN
1631
1632 CALL almo_scf_xalmo_pcg(qs_env=qs_env, &
1633 almo_scf_env=almo_scf_env, &
1634 optimizer=almo_scf_env%opt_xalmo_pcg, &
1635 quench_t=no_quench, &
1636 matrix_t_in=almo_scf_env%matrix_t, &
1637 matrix_t_out=almo_scf_env%matrix_t, &
1638 assume_t0_q0x=.false., &
1639 perturbation_only=.false., &
1640 special_case=xalmo_case_fully_deloc)
1641
1642 ELSE IF (almo_scf_env%xalmo_update_algorithm == almo_scf_trustr) THEN
1643
1644 CALL almo_scf_xalmo_trustr(qs_env=qs_env, &
1645 almo_scf_env=almo_scf_env, &
1646 optimizer=almo_scf_env%opt_xalmo_trustr, &
1647 quench_t=no_quench, &
1648 matrix_t_in=almo_scf_env%matrix_t, &
1649 matrix_t_out=almo_scf_env%matrix_t, &
1650 perturbation_only=.false., &
1651 special_case=xalmo_case_fully_deloc)
1652
1653 ELSE
1654
1655 cpabort("Other algorithms do not exist")
1656
1657 END IF
1658
1659 END SELECT
1660
1661 ! clean up
1662 SELECT CASE (almo_scf_env%deloc_method)
1664 DO ispin = 1, almo_scf_env%nspins
1665 CALL dbcsr_release(no_quench(ispin))
1666 END DO
1667 DEALLOCATE (no_quench)
1668 END SELECT
1669
1670 CALL timestop(handle)
1671
1672 END SUBROUTINE almo_scf_delocalization
1673
1674! **************************************************************************************************
1675!> \brief orbital localization
1676!> \param qs_env ...
1677!> \param almo_scf_env ...
1678!> \par History
1679!> 2018.09 created [Ziling Luo]
1680!> \author Ziling Luo
1681! **************************************************************************************************
1682 SUBROUTINE construct_nlmos(qs_env, almo_scf_env)
1683
1684 TYPE(qs_environment_type), POINTER :: qs_env
1685 TYPE(almo_scf_env_type), INTENT(INOUT) :: almo_scf_env
1686
1687 INTEGER :: ispin
1688
1689 IF (almo_scf_env%construct_nlmos) THEN
1690
1691 DO ispin = 1, almo_scf_env%nspins
1692
1693 CALL orthogonalize_mos(ket=almo_scf_env%matrix_t(ispin), &
1694 overlap=almo_scf_env%matrix_sigma(ispin), &
1695 metric=almo_scf_env%matrix_s(1), &
1696 retain_locality=.false., &
1697 only_normalize=.false., &
1698 nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
1699 eps_filter=almo_scf_env%eps_filter, &
1700 order_lanczos=almo_scf_env%order_lanczos, &
1701 eps_lanczos=almo_scf_env%eps_lanczos, &
1702 max_iter_lanczos=almo_scf_env%max_iter_lanczos)
1703 END DO
1704
1705 CALL construct_nlmos_wrapper(qs_env, almo_scf_env, virtuals=.false.)
1706
1707 IF (almo_scf_env%opt_nlmo_pcg%opt_penalty%virtual_nlmos) THEN
1708 CALL construct_virtuals(almo_scf_env)
1709 CALL construct_nlmos_wrapper(qs_env, almo_scf_env, virtuals=.true.)
1710 END IF
1711
1712 IF (almo_scf_env%opt_nlmo_pcg%opt_penalty%compactification_filter_start > 0.0_dp) THEN
1713 CALL nlmo_compactification(qs_env, almo_scf_env, almo_scf_env%matrix_t)
1714 END IF
1715
1716 END IF
1717
1718 END SUBROUTINE construct_nlmos
1719
1720! **************************************************************************************************
1721!> \brief Calls NLMO optimization
1722!> \param qs_env ...
1723!> \param almo_scf_env ...
1724!> \param virtuals ...
1725!> \par History
1726!> 2019.10 created [Ziling Luo]
1727!> \author Ziling Luo
1728! **************************************************************************************************
1729 SUBROUTINE construct_nlmos_wrapper(qs_env, almo_scf_env, virtuals)
1730
1731 TYPE(qs_environment_type), POINTER :: qs_env
1732 TYPE(almo_scf_env_type), INTENT(INOUT) :: almo_scf_env
1733 LOGICAL, INTENT(IN) :: virtuals
1734
1735 REAL(kind=dp) :: det_diff, prev_determinant
1736
1737 almo_scf_env%overlap_determinant = 1.0
1738 ! KEEP: initial_vol_coeff = almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength
1739 almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength = &
1740 -1.0_dp*almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength !NEW1
1741
1742 ! loop over the strength of the orthogonalization penalty
1743 prev_determinant = 10.0_dp
1744 DO WHILE (almo_scf_env%overlap_determinant > almo_scf_env%opt_nlmo_pcg%opt_penalty%final_determinant)
1745
1746 IF (.NOT. virtuals) THEN
1747 CALL almo_scf_construct_nlmos(qs_env=qs_env, &
1748 optimizer=almo_scf_env%opt_nlmo_pcg, &
1749 matrix_s=almo_scf_env%matrix_s(1), &
1750 matrix_mo_in=almo_scf_env%matrix_t, &
1751 matrix_mo_out=almo_scf_env%matrix_t, &
1752 template_matrix_sigma=almo_scf_env%matrix_sigma_inv, &
1753 overlap_determinant=almo_scf_env%overlap_determinant, &
1754 mat_distr_aos=almo_scf_env%mat_distr_aos, &
1755 virtuals=virtuals, &
1756 eps_filter=almo_scf_env%eps_filter)
1757 ELSE
1758 CALL almo_scf_construct_nlmos(qs_env=qs_env, &
1759 optimizer=almo_scf_env%opt_nlmo_pcg, &
1760 matrix_s=almo_scf_env%matrix_s(1), &
1761 matrix_mo_in=almo_scf_env%matrix_v, &
1762 matrix_mo_out=almo_scf_env%matrix_v, &
1763 template_matrix_sigma=almo_scf_env%matrix_sigma_vv, &
1764 overlap_determinant=almo_scf_env%overlap_determinant, &
1765 mat_distr_aos=almo_scf_env%mat_distr_aos, &
1766 virtuals=virtuals, &
1767 eps_filter=almo_scf_env%eps_filter)
1768
1769 END IF
1770
1771 det_diff = prev_determinant - almo_scf_env%overlap_determinant
1772 almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength = &
1773 almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength/ &
1774 abs(almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength_dec_factor)
1775
1776 IF (det_diff < almo_scf_env%opt_nlmo_pcg%opt_penalty%determinant_tolerance) THEN
1777 EXIT
1778 END IF
1779 prev_determinant = almo_scf_env%overlap_determinant
1780
1781 END DO
1782
1783 END SUBROUTINE construct_nlmos_wrapper
1784
1785! **************************************************************************************************
1786!> \brief Construct virtual orbitals
1787!> \param almo_scf_env ...
1788!> \par History
1789!> 2019.10 created [Ziling Luo]
1790!> \author Ziling Luo
1791! **************************************************************************************************
1792 SUBROUTINE construct_virtuals(almo_scf_env)
1793
1794 TYPE(almo_scf_env_type), INTENT(INOUT) :: almo_scf_env
1795
1796 INTEGER :: ispin, n
1797 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: eigenvalues
1798 TYPE(dbcsr_type) :: tempnv1, tempvocc1, tempvocc2, tempvv1, &
1799 tempvv2
1800
1801 DO ispin = 1, almo_scf_env%nspins
1802
1803 CALL dbcsr_create(tempnv1, &
1804 template=almo_scf_env%matrix_v(ispin), &
1805 matrix_type=dbcsr_type_no_symmetry)
1806 CALL dbcsr_create(tempvocc1, &
1807 template=almo_scf_env%matrix_vo(ispin), &
1808 matrix_type=dbcsr_type_no_symmetry)
1809 CALL dbcsr_create(tempvocc2, &
1810 template=almo_scf_env%matrix_vo(ispin), &
1811 matrix_type=dbcsr_type_no_symmetry)
1812 CALL dbcsr_create(tempvv1, &
1813 template=almo_scf_env%matrix_sigma_vv(ispin), &
1814 matrix_type=dbcsr_type_no_symmetry)
1815 CALL dbcsr_create(tempvv2, &
1816 template=almo_scf_env%matrix_sigma_vv(ispin), &
1817 matrix_type=dbcsr_type_no_symmetry)
1818
1819 ! Generate random virtual matrix
1820 CALL dbcsr_init_random(almo_scf_env%matrix_v(ispin), &
1821 keep_sparsity=.false.)
1822
1823 ! Project the orbital subspace out
1824 CALL dbcsr_multiply("N", "N", 1.0_dp, &
1825 almo_scf_env%matrix_s(1), &
1826 almo_scf_env%matrix_v(ispin), &
1827 0.0_dp, tempnv1, &
1828 filter_eps=almo_scf_env%eps_filter)
1829
1830 CALL dbcsr_multiply("T", "N", 1.0_dp, &
1831 tempnv1, &
1832 almo_scf_env%matrix_t(ispin), &
1833 0.0_dp, tempvocc1, &
1834 filter_eps=almo_scf_env%eps_filter)
1835
1836 CALL dbcsr_multiply("N", "N", 1.0_dp, &
1837 tempvocc1, &
1838 almo_scf_env%matrix_sigma_inv(ispin), &
1839 0.0_dp, tempvocc2, &
1840 filter_eps=almo_scf_env%eps_filter)
1841
1842 CALL dbcsr_multiply("N", "T", 1.0_dp, &
1843 almo_scf_env%matrix_t(ispin), &
1844 tempvocc2, &
1845 0.0_dp, tempnv1, &
1846 filter_eps=almo_scf_env%eps_filter)
1847
1848 CALL dbcsr_add(almo_scf_env%matrix_v(ispin), tempnv1, 1.0_dp, -1.0_dp)
1849
1850 ! compute VxV overlap
1851 CALL dbcsr_multiply("N", "N", 1.0_dp, &
1852 almo_scf_env%matrix_s(1), &
1853 almo_scf_env%matrix_v(ispin), &
1854 0.0_dp, tempnv1, &
1855 filter_eps=almo_scf_env%eps_filter)
1856
1857 CALL dbcsr_multiply("T", "N", 1.0_dp, &
1858 almo_scf_env%matrix_v(ispin), &
1859 tempnv1, &
1860 0.0_dp, tempvv1, &
1861 filter_eps=almo_scf_env%eps_filter)
1862
1863 CALL orthogonalize_mos(ket=almo_scf_env%matrix_v(ispin), &
1864 overlap=tempvv1, &
1865 metric=almo_scf_env%matrix_s(1), &
1866 retain_locality=.false., &
1867 only_normalize=.false., &
1868 nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
1869 eps_filter=almo_scf_env%eps_filter, &
1870 order_lanczos=almo_scf_env%order_lanczos, &
1871 eps_lanczos=almo_scf_env%eps_lanczos, &
1872 max_iter_lanczos=almo_scf_env%max_iter_lanczos)
1873
1874 ! compute VxV block of the KS matrix
1875 CALL dbcsr_multiply("N", "N", 1.0_dp, &
1876 almo_scf_env%matrix_ks(ispin), &
1877 almo_scf_env%matrix_v(ispin), &
1878 0.0_dp, tempnv1, &
1879 filter_eps=almo_scf_env%eps_filter)
1880
1881 CALL dbcsr_multiply("T", "N", 1.0_dp, &
1882 almo_scf_env%matrix_v(ispin), &
1883 tempnv1, &
1884 0.0_dp, tempvv1, &
1885 filter_eps=almo_scf_env%eps_filter)
1886
1887 CALL dbcsr_get_info(tempvv1, nfullrows_total=n)
1888 ALLOCATE (eigenvalues(n))
1889 CALL cp_dbcsr_syevd(tempvv1, tempvv2, &
1890 eigenvalues, &
1891 para_env=almo_scf_env%para_env, &
1892 blacs_env=almo_scf_env%blacs_env)
1893 DEALLOCATE (eigenvalues)
1894
1895 CALL dbcsr_multiply("N", "N", 1.0_dp, &
1896 almo_scf_env%matrix_v(ispin), &
1897 tempvv2, &
1898 0.0_dp, tempnv1, &
1899 filter_eps=almo_scf_env%eps_filter)
1900
1901 CALL dbcsr_copy(almo_scf_env%matrix_v(ispin), tempnv1)
1902
1903 CALL dbcsr_release(tempnv1)
1904 CALL dbcsr_release(tempvocc1)
1905 CALL dbcsr_release(tempvocc2)
1906 CALL dbcsr_release(tempvv1)
1907 CALL dbcsr_release(tempvv2)
1908
1909 END DO
1910
1911 END SUBROUTINE construct_virtuals
1912
1913! **************************************************************************************************
1914!> \brief Compactify (set small blocks to zero) orbitals
1915!> \param qs_env ...
1916!> \param almo_scf_env ...
1917!> \param matrix ...
1918!> \par History
1919!> 2019.10 created [Ziling Luo]
1920!> \author Ziling Luo
1921! **************************************************************************************************
1922 SUBROUTINE nlmo_compactification(qs_env, almo_scf_env, matrix)
1923
1924 TYPE(qs_environment_type), POINTER :: qs_env
1925 TYPE(almo_scf_env_type), INTENT(INOUT) :: almo_scf_env
1926 TYPE(dbcsr_type), ALLOCATABLE, DIMENSION(:), &
1927 INTENT(IN) :: matrix
1928
1929 INTEGER :: iblock_col, iblock_col_size, iblock_row, &
1930 iblock_row_size, icol, irow, ispin, &
1931 ncols, nrows, nspins, unit_nr
1932 LOGICAL :: element_by_element
1933 REAL(kind=dp) :: energy, eps_local, eps_start, &
1934 max_element, spin_factor
1935 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: occ, retained
1936 REAL(kind=dp), DIMENSION(:, :), POINTER :: data_p
1937 TYPE(cp_logger_type), POINTER :: logger
1938 TYPE(dbcsr_iterator_type) :: iter
1939 TYPE(dbcsr_type), ALLOCATABLE, DIMENSION(:) :: matrix_p_tmp, matrix_t_tmp
1940 TYPE(mp_comm_type) :: group
1941
1942 ! define the output_unit
1943 logger => cp_get_default_logger()
1944 IF (logger%para_env%is_source()) THEN
1945 unit_nr = cp_logger_get_default_unit_nr(logger, local=.true.)
1946 ELSE
1947 unit_nr = -1
1948 END IF
1949
1950 nspins = SIZE(matrix)
1951 element_by_element = .false.
1952
1953 IF (nspins == 1) THEN
1954 spin_factor = 2.0_dp
1955 ELSE
1956 spin_factor = 1.0_dp
1957 END IF
1958
1959 ALLOCATE (matrix_t_tmp(nspins))
1960 ALLOCATE (matrix_p_tmp(nspins))
1961 ALLOCATE (retained(nspins))
1962 ALLOCATE (occ(2))
1963
1964 DO ispin = 1, nspins
1965
1966 ! init temporary storage
1967 CALL dbcsr_create(matrix_t_tmp(ispin), &
1968 template=matrix(ispin), &
1969 matrix_type=dbcsr_type_no_symmetry)
1970 CALL dbcsr_copy(matrix_t_tmp(ispin), matrix(ispin))
1971
1972 CALL dbcsr_create(matrix_p_tmp(ispin), &
1973 template=almo_scf_env%matrix_p(ispin), &
1974 matrix_type=dbcsr_type_no_symmetry)
1975 CALL dbcsr_copy(matrix_p_tmp(ispin), almo_scf_env%matrix_p(ispin))
1976
1977 END DO
1978
1979 IF (unit_nr > 0) THEN
1980 WRITE (unit_nr, *)
1981 WRITE (unit_nr, '(T2,A)') &
1982 "Energy dependence on the (block-by-block) filtering of the NLMO coefficients"
1983 IF (unit_nr > 0) WRITE (unit_nr, '(T2,A13,A20,A20,A25)') &
1984 "EPS filter", "Occupation Alpha", "Occupation Beta", "Energy"
1985 END IF
1986
1987 eps_start = almo_scf_env%opt_nlmo_pcg%opt_penalty%compactification_filter_start
1988 eps_local = max(eps_start, 10e-14_dp)
1989
1990 DO
1991
1992 IF (eps_local > 0.11_dp) EXIT
1993
1994 DO ispin = 1, nspins
1995
1996 retained(ispin) = 0
1997 CALL dbcsr_work_create(matrix_t_tmp(ispin), work_mutable=.true.)
1998 CALL dbcsr_iterator_start(iter, matrix_t_tmp(ispin))
1999 DO WHILE (dbcsr_iterator_blocks_left(iter))
2000 CALL dbcsr_iterator_next_block(iter, iblock_row, iblock_col, data_p, &
2001 row_size=iblock_row_size, col_size=iblock_col_size)
2002 DO icol = 1, iblock_col_size
2003
2004 IF (element_by_element) THEN
2005
2006 DO irow = 1, iblock_row_size
2007 IF (abs(data_p(irow, icol)) < eps_local) THEN
2008 data_p(irow, icol) = 0.0_dp
2009 ELSE
2010 retained(ispin) = retained(ispin) + 1
2011 END IF
2012 END DO
2013
2014 ELSE ! rows are blocked
2015
2016 max_element = 0.0_dp
2017 DO irow = 1, iblock_row_size
2018 IF (abs(data_p(irow, icol)) > max_element) THEN
2019 max_element = abs(data_p(irow, icol))
2020 END IF
2021 END DO
2022 IF (max_element < eps_local) THEN
2023 DO irow = 1, iblock_row_size
2024 data_p(irow, icol) = 0.0_dp
2025 END DO
2026 ELSE
2027 retained(ispin) = retained(ispin) + iblock_row_size
2028 END IF
2029
2030 END IF ! block rows?
2031 END DO ! icol
2032
2033 END DO ! iterator
2034 CALL dbcsr_iterator_stop(iter)
2035 CALL dbcsr_finalize(matrix_t_tmp(ispin))
2036 CALL dbcsr_filter(matrix_t_tmp(ispin), eps_local)
2037
2038 CALL dbcsr_get_info(matrix_t_tmp(ispin), group=group, &
2039 nfullrows_total=nrows, &
2040 nfullcols_total=ncols)
2041 CALL group%sum(retained(ispin))
2042
2043 !devide by the total no. elements
2044 occ(ispin) = retained(ispin)/nrows/ncols
2045
2046 ! compute the global projectors (for the density matrix)
2047 CALL almo_scf_t_to_proj( &
2048 t=matrix_t_tmp(ispin), &
2049 p=matrix_p_tmp(ispin), &
2050 eps_filter=almo_scf_env%eps_filter, &
2051 orthog_orbs=.false., &
2052 nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
2053 s=almo_scf_env%matrix_s(1), &
2054 sigma=almo_scf_env%matrix_sigma(ispin), &
2055 sigma_inv=almo_scf_env%matrix_sigma_inv(ispin), &
2056 use_guess=.false., &
2057 algorithm=almo_scf_env%sigma_inv_algorithm, &
2058 inv_eps_factor=almo_scf_env%matrix_iter_eps_error_factor, &
2059 inverse_accelerator=almo_scf_env%order_lanczos, &
2060 eps_lanczos=almo_scf_env%eps_lanczos, &
2061 max_iter_lanczos=almo_scf_env%max_iter_lanczos, &
2062 para_env=almo_scf_env%para_env, &
2063 blacs_env=almo_scf_env%blacs_env)
2064
2065 ! compute dm from the projector(s)
2066 CALL dbcsr_scale(matrix_p_tmp(ispin), spin_factor)
2067
2068 END DO
2069
2070 ! the KS matrix is updated outside the spin loop
2071 CALL almo_dm_to_almo_ks(qs_env, &
2072 matrix_p_tmp, &
2073 almo_scf_env%matrix_ks, &
2074 energy, &
2075 almo_scf_env%eps_filter, &
2076 almo_scf_env%mat_distr_aos)
2077
2078 IF (nspins < 2) occ(2) = occ(1)
2079 IF (unit_nr > 0) WRITE (unit_nr, '(T2,E13.3,F20.10,F20.10,F25.15)') &
2080 eps_local, occ(1), occ(2), energy
2081
2082 eps_local = 2.0_dp*eps_local
2083
2084 END DO
2085
2086 DO ispin = 1, nspins
2087
2088 CALL dbcsr_release(matrix_t_tmp(ispin))
2089 CALL dbcsr_release(matrix_p_tmp(ispin))
2090
2091 END DO
2092
2093 DEALLOCATE (matrix_t_tmp)
2094 DEALLOCATE (matrix_p_tmp)
2095 DEALLOCATE (occ)
2096 DEALLOCATE (retained)
2097
2098 END SUBROUTINE nlmo_compactification
2099
2100! *****************************************************************************
2101!> \brief after SCF we have the final density and KS matrices compute various
2102!> post-scf quantities
2103!> \param qs_env ...
2104!> \param almo_scf_env ...
2105!> \par History
2106!> 2015.03 created [Rustam Z. Khaliullin]
2107!> \author Rustam Z. Khaliullin
2108! **************************************************************************************************
2109 SUBROUTINE almo_scf_post(qs_env, almo_scf_env)
2110 TYPE(qs_environment_type), POINTER :: qs_env
2111 TYPE(almo_scf_env_type), INTENT(INOUT) :: almo_scf_env
2112
2113 CHARACTER(len=*), PARAMETER :: routinen = 'almo_scf_post'
2114
2115 INTEGER :: handle, ispin
2116 TYPE(cp_fm_type), POINTER :: mo_coeff
2117 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_w
2118 TYPE(dbcsr_type), ALLOCATABLE, DIMENSION(:) :: matrix_t_processed
2119 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
2120 TYPE(qs_scf_env_type), POINTER :: scf_env
2121
2122 CALL timeset(routinen, handle)
2123
2124 ! store matrices to speed up the next scf run
2125 CALL almo_scf_store_extrapolation_data(almo_scf_env)
2126
2127 ! orthogonalize orbitals before returning them to QS
2128 ALLOCATE (matrix_t_processed(almo_scf_env%nspins))
2129 !ALLOCATE (matrix_v_processed(almo_scf_env%nspins))
2130
2131 DO ispin = 1, almo_scf_env%nspins
2132
2133 CALL dbcsr_create(matrix_t_processed(ispin), &
2134 template=almo_scf_env%matrix_t(ispin), &
2135 matrix_type=dbcsr_type_no_symmetry)
2136
2137 CALL dbcsr_copy(matrix_t_processed(ispin), &
2138 almo_scf_env%matrix_t(ispin))
2139
2140 IF (almo_scf_env%return_orthogonalized_mos) THEN
2141
2142 CALL orthogonalize_mos(ket=matrix_t_processed(ispin), &
2143 overlap=almo_scf_env%matrix_sigma(ispin), &
2144 metric=almo_scf_env%matrix_s(1), &
2145 retain_locality=.false., &
2146 only_normalize=.false., &
2147 nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
2148 eps_filter=almo_scf_env%eps_filter, &
2149 order_lanczos=almo_scf_env%order_lanczos, &
2150 eps_lanczos=almo_scf_env%eps_lanczos, &
2151 max_iter_lanczos=almo_scf_env%max_iter_lanczos, &
2152 smear=almo_scf_env%smear)
2153 END IF
2154
2155 END DO
2156
2157 !! RS-WARNING: If smearing ALMO is requested, rescaled fully-occupied orbitals are returned to QS
2158 !! RS-WARNING: Beware that QS will not be informed about electronic entropy.
2159 !! If you want a quick and dirty transfer to QS energy, uncomment the following hack:
2160 !! IF (almo_scf_env%smear) THEN
2161 !! qs_env%energy%kTS = 0.0_dp
2162 !! DO ispin = 1, almo_scf_env%nspins
2163 !! qs_env%energy%kTS = qs_env%energy%kTS + almo_scf_env%kTS(ispin)
2164 !! END DO
2165 !! END IF
2166
2167 ! return orbitals to QS
2168 NULLIFY (mos, mo_coeff, scf_env)
2169
2170 CALL get_qs_env(qs_env, mos=mos, scf_env=scf_env)
2171
2172 DO ispin = 1, almo_scf_env%nspins
2173
2174 ! Currently only fm version of mo_set is usable.
2175 ! First transform the matrix_t to fm version
2176 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff)
2177 CALL copy_dbcsr_to_fm(matrix_t_processed(ispin), mo_coeff)
2178 CALL dbcsr_release(matrix_t_processed(ispin))
2179 END DO
2180 DO ispin = 1, almo_scf_env%nspins
2181 CALL dbcsr_release(matrix_t_processed(ispin))
2182 END DO
2183 DEALLOCATE (matrix_t_processed)
2184
2185 ! calculate post scf properties
2186
2187 CALL almo_post_scf_compute_properties(qs_env)
2188
2189 ! compute the W matrix if associated
2190 IF (almo_scf_env%calc_forces) THEN
2191 CALL get_qs_env(qs_env, matrix_w=matrix_w)
2192 IF (ASSOCIATED(matrix_w)) THEN
2193 CALL calculate_w_matrix_almo(matrix_w, almo_scf_env)
2194 ELSE
2195 cpabort("Matrix W is needed but not associated")
2196 END IF
2197 END IF
2198
2199 CALL timestop(handle)
2200
2201 END SUBROUTINE almo_scf_post
2202
2203! **************************************************************************************************
2204!> \brief create various matrices
2205!> \param almo_scf_env ...
2206!> \param matrix_s0 ...
2207!> \par History
2208!> 2011.07 created [Rustam Z Khaliullin]
2209!> \author Rustam Z Khaliullin
2210! **************************************************************************************************
2211 SUBROUTINE almo_scf_env_create_matrices(almo_scf_env, matrix_s0)
2212
2213 TYPE(almo_scf_env_type), INTENT(INOUT) :: almo_scf_env
2214 TYPE(dbcsr_type), INTENT(IN) :: matrix_s0
2215
2216 CHARACTER(len=*), PARAMETER :: routinen = 'almo_scf_env_create_matrices'
2217
2218 INTEGER :: handle, ispin, nspins
2219
2220 CALL timeset(routinen, handle)
2221
2222 nspins = almo_scf_env%nspins
2223
2224 ! AO overlap matrix and its various functions
2225 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_s(1), &
2226 matrix_qs=matrix_s0, &
2227 almo_scf_env=almo_scf_env, &
2228 name_new="S", &
2230 symmetry_new=dbcsr_type_symmetric, &
2231 spin_key=0, &
2232 init_domains=.false.)
2233 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_s_blk(1), &
2234 matrix_qs=matrix_s0, &
2235 almo_scf_env=almo_scf_env, &
2236 name_new="S_BLK", &
2238 symmetry_new=dbcsr_type_symmetric, &
2239 spin_key=0, &
2240 init_domains=.true.)
2241 IF (almo_scf_env%almo_update_algorithm == almo_scf_diag) THEN
2242 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_s_blk_sqrt_inv(1), &
2243 matrix_qs=matrix_s0, &
2244 almo_scf_env=almo_scf_env, &
2245 name_new="S_BLK_SQRT_INV", &
2247 symmetry_new=dbcsr_type_symmetric, &
2248 spin_key=0, &
2249 init_domains=.true.)
2250 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_s_blk_sqrt(1), &
2251 matrix_qs=matrix_s0, &
2252 almo_scf_env=almo_scf_env, &
2253 name_new="S_BLK_SQRT", &
2255 symmetry_new=dbcsr_type_symmetric, &
2256 spin_key=0, &
2257 init_domains=.true.)
2258 ELSE IF (almo_scf_env%almo_update_algorithm == almo_scf_dm_sign) THEN
2259 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_s_blk_inv(1), &
2260 matrix_qs=matrix_s0, &
2261 almo_scf_env=almo_scf_env, &
2262 name_new="S_BLK_INV", &
2264 symmetry_new=dbcsr_type_symmetric, &
2265 spin_key=0, &
2266 init_domains=.true.)
2267 END IF
2268
2269 ! MO coeff matrices and their derivatives
2270 ALLOCATE (almo_scf_env%matrix_t_blk(nspins))
2271 ALLOCATE (almo_scf_env%quench_t_blk(nspins))
2272 ALLOCATE (almo_scf_env%matrix_err_blk(nspins))
2273 ALLOCATE (almo_scf_env%matrix_err_xx(nspins))
2274 ALLOCATE (almo_scf_env%matrix_sigma(nspins))
2275 ALLOCATE (almo_scf_env%matrix_sigma_inv(nspins))
2276 ALLOCATE (almo_scf_env%matrix_sigma_sqrt(nspins))
2277 ALLOCATE (almo_scf_env%matrix_sigma_sqrt_inv(nspins))
2278 ALLOCATE (almo_scf_env%matrix_sigma_blk(nspins))
2279 ALLOCATE (almo_scf_env%matrix_sigma_inv_0deloc(nspins))
2280 ALLOCATE (almo_scf_env%matrix_t(nspins))
2281 ALLOCATE (almo_scf_env%matrix_t_tr(nspins))
2282 DO ispin = 1, nspins
2283 ! create the blocked quencher
2284 CALL matrix_almo_create(matrix_new=almo_scf_env%quench_t_blk(ispin), &
2285 matrix_qs=matrix_s0, &
2286 almo_scf_env=almo_scf_env, &
2287 name_new="Q_BLK", &
2289 symmetry_new=dbcsr_type_no_symmetry, &
2290 spin_key=ispin, &
2291 init_domains=.true.)
2292 ! create ALMO coefficient matrix
2293 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_t_blk(ispin), &
2294 matrix_qs=matrix_s0, &
2295 almo_scf_env=almo_scf_env, &
2296 name_new="T_BLK", &
2298 symmetry_new=dbcsr_type_no_symmetry, &
2299 spin_key=ispin, &
2300 init_domains=.true.)
2301 ! create the error matrix
2302 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_err_blk(ispin), &
2303 matrix_qs=matrix_s0, &
2304 almo_scf_env=almo_scf_env, &
2305 name_new="ERR_BLK", &
2307 symmetry_new=dbcsr_type_no_symmetry, &
2308 spin_key=ispin, &
2309 init_domains=.true.)
2310 ! create the error matrix for the quenched ALMOs
2311 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_err_xx(ispin), &
2312 matrix_qs=matrix_s0, &
2313 almo_scf_env=almo_scf_env, &
2314 name_new="ERR_XX", &
2316 symmetry_new=dbcsr_type_no_symmetry, &
2317 spin_key=ispin, &
2318 init_domains=.false.)
2319 ! create a matrix with dimensions of a transposed mo coefficient matrix
2320 ! it might be necessary to perform the correction step using cayley
2321 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_t_tr(ispin), &
2322 matrix_qs=matrix_s0, &
2323 almo_scf_env=almo_scf_env, &
2324 name_new="T_TR", &
2326 symmetry_new=dbcsr_type_no_symmetry, &
2327 spin_key=ispin, &
2328 init_domains=.false.)
2329 ! create mo overlap matrix
2330 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_sigma(ispin), &
2331 matrix_qs=matrix_s0, &
2332 almo_scf_env=almo_scf_env, &
2333 name_new="SIG", &
2334 size_keys=[almo_mat_dim_occ, almo_mat_dim_occ], &
2335 symmetry_new=dbcsr_type_symmetric, &
2336 spin_key=ispin, &
2337 init_domains=.false.)
2338 ! create blocked mo overlap matrix
2339 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_sigma_blk(ispin), &
2340 matrix_qs=matrix_s0, &
2341 almo_scf_env=almo_scf_env, &
2342 name_new="SIG_BLK", &
2343 size_keys=[almo_mat_dim_occ, almo_mat_dim_occ], &
2344 symmetry_new=dbcsr_type_symmetric, &
2345 spin_key=ispin, &
2346 init_domains=.true.)
2347 ! create blocked inverse mo overlap matrix
2348 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_sigma_inv_0deloc(ispin), &
2349 matrix_qs=matrix_s0, &
2350 almo_scf_env=almo_scf_env, &
2351 name_new="SIGINV_BLK", &
2352 size_keys=[almo_mat_dim_occ, almo_mat_dim_occ], &
2353 symmetry_new=dbcsr_type_symmetric, &
2354 spin_key=ispin, &
2355 init_domains=.true.)
2356 ! create inverse mo overlap matrix
2357 CALL matrix_almo_create( &
2358 matrix_new=almo_scf_env%matrix_sigma_inv(ispin), &
2359 matrix_qs=matrix_s0, &
2360 almo_scf_env=almo_scf_env, &
2361 name_new="SIGINV", &
2362 size_keys=[almo_mat_dim_occ, almo_mat_dim_occ], &
2363 symmetry_new=dbcsr_type_symmetric, &
2364 spin_key=ispin, &
2365 init_domains=.false.)
2366 ! create various templates that will be necessary later
2367 CALL matrix_almo_create( &
2368 matrix_new=almo_scf_env%matrix_t(ispin), &
2369 matrix_qs=matrix_s0, &
2370 almo_scf_env=almo_scf_env, &
2371 name_new="T", &
2373 symmetry_new=dbcsr_type_no_symmetry, &
2374 spin_key=ispin, &
2375 init_domains=.false.)
2376 CALL dbcsr_create(almo_scf_env%matrix_sigma_sqrt(ispin), &
2377 template=almo_scf_env%matrix_sigma(ispin), &
2378 matrix_type=dbcsr_type_no_symmetry)
2379 CALL dbcsr_create(almo_scf_env%matrix_sigma_sqrt_inv(ispin), &
2380 template=almo_scf_env%matrix_sigma(ispin), &
2381 matrix_type=dbcsr_type_no_symmetry)
2382 END DO
2383
2384 ! create virtual orbitals if necessary
2385 IF (almo_scf_env%need_virtuals) THEN
2386 ALLOCATE (almo_scf_env%matrix_v_blk(nspins))
2387 ALLOCATE (almo_scf_env%matrix_v_full_blk(nspins))
2388 ALLOCATE (almo_scf_env%matrix_v(nspins))
2389 ALLOCATE (almo_scf_env%matrix_vo(nspins))
2390 ALLOCATE (almo_scf_env%matrix_x(nspins))
2391 ALLOCATE (almo_scf_env%matrix_ov(nspins))
2392 ALLOCATE (almo_scf_env%matrix_ov_full(nspins))
2393 ALLOCATE (almo_scf_env%matrix_sigma_vv(nspins))
2394 ALLOCATE (almo_scf_env%matrix_sigma_vv_blk(nspins))
2395 ALLOCATE (almo_scf_env%matrix_sigma_vv_sqrt(nspins))
2396 ALLOCATE (almo_scf_env%matrix_sigma_vv_sqrt_inv(nspins))
2397 ALLOCATE (almo_scf_env%matrix_vv_full_blk(nspins))
2398
2399 IF (almo_scf_env%deloc_truncate_virt /= virt_full) THEN
2400 ALLOCATE (almo_scf_env%matrix_k_blk(nspins))
2401 ALLOCATE (almo_scf_env%matrix_k_blk_ones(nspins))
2402 ALLOCATE (almo_scf_env%matrix_k_tr(nspins))
2403 ALLOCATE (almo_scf_env%matrix_v_disc(nspins))
2404 ALLOCATE (almo_scf_env%matrix_v_disc_blk(nspins))
2405 ALLOCATE (almo_scf_env%matrix_ov_disc(nspins))
2406 ALLOCATE (almo_scf_env%matrix_vv_disc_blk(nspins))
2407 ALLOCATE (almo_scf_env%matrix_vv_disc(nspins))
2408 ALLOCATE (almo_scf_env%opt_k_t_dd(nspins))
2409 ALLOCATE (almo_scf_env%opt_k_t_rr(nspins))
2410 ALLOCATE (almo_scf_env%opt_k_denom(nspins))
2411 END IF
2412
2413 DO ispin = 1, nspins
2414 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_v_full_blk(ispin), &
2415 matrix_qs=matrix_s0, &
2416 almo_scf_env=almo_scf_env, &
2417 name_new="V_FULL_BLK", &
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_v_blk(ispin), &
2423 matrix_qs=matrix_s0, &
2424 almo_scf_env=almo_scf_env, &
2425 name_new="V_BLK", &
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_v(ispin), &
2431 matrix_qs=matrix_s0, &
2432 almo_scf_env=almo_scf_env, &
2433 name_new="V", &
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_ov_full(ispin), &
2439 matrix_qs=matrix_s0, &
2440 almo_scf_env=almo_scf_env, &
2441 name_new="OV_FULL", &
2443 symmetry_new=dbcsr_type_no_symmetry, &
2444 spin_key=ispin, &
2445 init_domains=.false.)
2446 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_ov(ispin), &
2447 matrix_qs=matrix_s0, &
2448 almo_scf_env=almo_scf_env, &
2449 name_new="OV", &
2450 size_keys=[almo_mat_dim_occ, almo_mat_dim_virt], &
2451 symmetry_new=dbcsr_type_no_symmetry, &
2452 spin_key=ispin, &
2453 init_domains=.false.)
2454 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_vo(ispin), &
2455 matrix_qs=matrix_s0, &
2456 almo_scf_env=almo_scf_env, &
2457 name_new="VO", &
2458 size_keys=[almo_mat_dim_virt, almo_mat_dim_occ], &
2459 symmetry_new=dbcsr_type_no_symmetry, &
2460 spin_key=ispin, &
2461 init_domains=.false.)
2462 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_x(ispin), &
2463 matrix_qs=matrix_s0, &
2464 almo_scf_env=almo_scf_env, &
2465 name_new="VO", &
2466 size_keys=[almo_mat_dim_virt, almo_mat_dim_occ], &
2467 symmetry_new=dbcsr_type_no_symmetry, &
2468 spin_key=ispin, &
2469 init_domains=.false.)
2470 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_sigma_vv(ispin), &
2471 matrix_qs=matrix_s0, &
2472 almo_scf_env=almo_scf_env, &
2473 name_new="SIG_VV", &
2474 size_keys=[almo_mat_dim_virt, almo_mat_dim_virt], &
2475 symmetry_new=dbcsr_type_symmetric, &
2476 spin_key=ispin, &
2477 init_domains=.false.)
2478 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_vv_full_blk(ispin), &
2479 matrix_qs=matrix_s0, &
2480 almo_scf_env=almo_scf_env, &
2481 name_new="VV_FULL_BLK", &
2483 symmetry_new=dbcsr_type_no_symmetry, &
2484 spin_key=ispin, &
2485 init_domains=.true.)
2486 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_sigma_vv_blk(ispin), &
2487 matrix_qs=matrix_s0, &
2488 almo_scf_env=almo_scf_env, &
2489 name_new="SIG_VV_BLK", &
2490 size_keys=[almo_mat_dim_virt, almo_mat_dim_virt], &
2491 symmetry_new=dbcsr_type_symmetric, &
2492 spin_key=ispin, &
2493 init_domains=.true.)
2494 CALL dbcsr_create(almo_scf_env%matrix_sigma_vv_sqrt(ispin), &
2495 template=almo_scf_env%matrix_sigma_vv(ispin), &
2496 matrix_type=dbcsr_type_no_symmetry)
2497 CALL dbcsr_create(almo_scf_env%matrix_sigma_vv_sqrt_inv(ispin), &
2498 template=almo_scf_env%matrix_sigma_vv(ispin), &
2499 matrix_type=dbcsr_type_no_symmetry)
2500
2501 IF (almo_scf_env%deloc_truncate_virt /= virt_full) THEN
2502 CALL matrix_almo_create(matrix_new=almo_scf_env%opt_k_t_rr(ispin), &
2503 matrix_qs=matrix_s0, &
2504 almo_scf_env=almo_scf_env, &
2505 name_new="OPT_K_U_RR", &
2506 size_keys=[almo_mat_dim_virt, almo_mat_dim_virt], &
2507 symmetry_new=dbcsr_type_no_symmetry, &
2508 spin_key=ispin, &
2509 init_domains=.false.)
2510 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_vv_disc(ispin), &
2511 matrix_qs=matrix_s0, &
2512 almo_scf_env=almo_scf_env, &
2513 name_new="VV_DISC", &
2515 symmetry_new=dbcsr_type_symmetric, &
2516 spin_key=ispin, &
2517 init_domains=.false.)
2518 CALL matrix_almo_create(matrix_new=almo_scf_env%opt_k_t_dd(ispin), &
2519 matrix_qs=matrix_s0, &
2520 almo_scf_env=almo_scf_env, &
2521 name_new="OPT_K_U_DD", &
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_vv_disc_blk(ispin), &
2527 matrix_qs=matrix_s0, &
2528 almo_scf_env=almo_scf_env, &
2529 name_new="VV_DISC_BLK", &
2531 symmetry_new=dbcsr_type_symmetric, &
2532 spin_key=ispin, &
2533 init_domains=.true.)
2534 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_k_blk(ispin), &
2535 matrix_qs=matrix_s0, &
2536 almo_scf_env=almo_scf_env, &
2537 name_new="K_BLK", &
2539 symmetry_new=dbcsr_type_no_symmetry, &
2540 spin_key=ispin, &
2541 init_domains=.true.)
2542 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_k_blk_ones(ispin), &
2543 matrix_qs=matrix_s0, &
2544 almo_scf_env=almo_scf_env, &
2545 name_new="K_BLK_1", &
2547 symmetry_new=dbcsr_type_no_symmetry, &
2548 spin_key=ispin, &
2549 init_domains=.true.)
2550 CALL matrix_almo_create(matrix_new=almo_scf_env%opt_k_denom(ispin), &
2551 matrix_qs=matrix_s0, &
2552 almo_scf_env=almo_scf_env, &
2553 name_new="OPT_K_DENOM", &
2555 symmetry_new=dbcsr_type_no_symmetry, &
2556 spin_key=ispin, &
2557 init_domains=.false.)
2558 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_k_tr(ispin), &
2559 matrix_qs=matrix_s0, &
2560 almo_scf_env=almo_scf_env, &
2561 name_new="K_TR", &
2563 symmetry_new=dbcsr_type_no_symmetry, &
2564 spin_key=ispin, &
2565 init_domains=.false.)
2566 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_v_disc_blk(ispin), &
2567 matrix_qs=matrix_s0, &
2568 almo_scf_env=almo_scf_env, &
2569 name_new="V_DISC_BLK", &
2571 symmetry_new=dbcsr_type_no_symmetry, &
2572 spin_key=ispin, &
2573 init_domains=.false.)
2574 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_v_disc(ispin), &
2575 matrix_qs=matrix_s0, &
2576 almo_scf_env=almo_scf_env, &
2577 name_new="V_DISC", &
2579 symmetry_new=dbcsr_type_no_symmetry, &
2580 spin_key=ispin, &
2581 init_domains=.false.)
2582 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_ov_disc(ispin), &
2583 matrix_qs=matrix_s0, &
2584 almo_scf_env=almo_scf_env, &
2585 name_new="OV_DISC", &
2587 symmetry_new=dbcsr_type_no_symmetry, &
2588 spin_key=ispin, &
2589 init_domains=.false.)
2590
2591 END IF ! end need_discarded_virtuals
2592
2593 END DO ! spin
2594 END IF
2595
2596 ! create matrices of orbital energies if necessary
2597 IF (almo_scf_env%need_orbital_energies) THEN
2598 ALLOCATE (almo_scf_env%matrix_eoo(nspins))
2599 ALLOCATE (almo_scf_env%matrix_evv_full(nspins))
2600 DO ispin = 1, nspins
2601 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_eoo(ispin), &
2602 matrix_qs=matrix_s0, &
2603 almo_scf_env=almo_scf_env, &
2604 name_new="E_OCC", &
2605 size_keys=[almo_mat_dim_occ, almo_mat_dim_occ], &
2606 symmetry_new=dbcsr_type_no_symmetry, &
2607 spin_key=ispin, &
2608 init_domains=.false.)
2609 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_evv_full(ispin), &
2610 matrix_qs=matrix_s0, &
2611 almo_scf_env=almo_scf_env, &
2612 name_new="E_VIRT", &
2614 symmetry_new=dbcsr_type_no_symmetry, &
2615 spin_key=ispin, &
2616 init_domains=.false.)
2617 END DO
2618 END IF
2619
2620 ! Density and KS matrices
2621 ALLOCATE (almo_scf_env%matrix_p(nspins))
2622 ALLOCATE (almo_scf_env%matrix_p_blk(nspins))
2623 ALLOCATE (almo_scf_env%matrix_ks(nspins))
2624 ALLOCATE (almo_scf_env%matrix_ks_blk(nspins))
2625 IF (almo_scf_env%need_previous_ks) &
2626 ALLOCATE (almo_scf_env%matrix_ks_0deloc(nspins))
2627 DO ispin = 1, nspins
2628 ! RZK-warning copy with symmery but remember that this might cause problems
2629 CALL dbcsr_create(almo_scf_env%matrix_p(ispin), &
2630 template=almo_scf_env%matrix_s(1), &
2631 matrix_type=dbcsr_type_symmetric)
2632 CALL dbcsr_create(almo_scf_env%matrix_ks(ispin), &
2633 template=almo_scf_env%matrix_s(1), &
2634 matrix_type=dbcsr_type_symmetric)
2635 IF (almo_scf_env%need_previous_ks) THEN
2636 CALL dbcsr_create(almo_scf_env%matrix_ks_0deloc(ispin), &
2637 template=almo_scf_env%matrix_s(1), &
2638 matrix_type=dbcsr_type_symmetric)
2639 END IF
2640 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_p_blk(ispin), &
2641 matrix_qs=matrix_s0, &
2642 almo_scf_env=almo_scf_env, &
2643 name_new="P_BLK", &
2645 symmetry_new=dbcsr_type_symmetric, &
2646 spin_key=ispin, &
2647 init_domains=.true.)
2648 CALL matrix_almo_create(matrix_new=almo_scf_env%matrix_ks_blk(ispin), &
2649 matrix_qs=matrix_s0, &
2650 almo_scf_env=almo_scf_env, &
2651 name_new="KS_BLK", &
2653 symmetry_new=dbcsr_type_symmetric, &
2654 spin_key=ispin, &
2655 init_domains=.true.)
2656 END DO
2657
2658 CALL timestop(handle)
2659
2660 END SUBROUTINE almo_scf_env_create_matrices
2661
2662! **************************************************************************************************
2663!> \brief clean up procedures for almo scf
2664!> \param almo_scf_env ...
2665!> \par History
2666!> 2011.06 created [Rustam Z Khaliullin]
2667!> 2018.09 smearing support [Ruben Staub]
2668!> \author Rustam Z Khaliullin
2669! **************************************************************************************************
2670 SUBROUTINE almo_scf_clean_up(almo_scf_env)
2671
2672 TYPE(almo_scf_env_type), INTENT(INOUT) :: almo_scf_env
2673
2674 CHARACTER(len=*), PARAMETER :: routinen = 'almo_scf_clean_up'
2675
2676 INTEGER :: handle, ispin, unit_nr
2677 TYPE(cp_logger_type), POINTER :: logger
2678
2679 CALL timeset(routinen, handle)
2680
2681 ! get a useful output_unit
2682 logger => cp_get_default_logger()
2683 IF (logger%para_env%is_source()) THEN
2684 unit_nr = cp_logger_get_default_unit_nr(logger, local=.true.)
2685 ELSE
2686 unit_nr = -1
2687 END IF
2688
2689 ! release matrices
2690 CALL dbcsr_release(almo_scf_env%matrix_s(1))
2691 CALL dbcsr_release(almo_scf_env%matrix_s_blk(1))
2692 IF (almo_scf_env%almo_update_algorithm == almo_scf_diag) THEN
2693 CALL dbcsr_release(almo_scf_env%matrix_s_blk_sqrt_inv(1))
2694 CALL dbcsr_release(almo_scf_env%matrix_s_blk_sqrt(1))
2695 ELSE IF (almo_scf_env%almo_update_algorithm == almo_scf_dm_sign) THEN
2696 CALL dbcsr_release(almo_scf_env%matrix_s_blk_inv(1))
2697 END IF
2698 DO ispin = 1, almo_scf_env%nspins
2699 CALL dbcsr_release(almo_scf_env%quench_t(ispin))
2700 CALL dbcsr_release(almo_scf_env%quench_t_blk(ispin))
2701 CALL dbcsr_release(almo_scf_env%matrix_t_blk(ispin))
2702 CALL dbcsr_release(almo_scf_env%matrix_err_blk(ispin))
2703 CALL dbcsr_release(almo_scf_env%matrix_err_xx(ispin))
2704 CALL dbcsr_release(almo_scf_env%matrix_t_tr(ispin))
2705 CALL dbcsr_release(almo_scf_env%matrix_sigma(ispin))
2706 CALL dbcsr_release(almo_scf_env%matrix_sigma_blk(ispin))
2707 CALL dbcsr_release(almo_scf_env%matrix_sigma_inv_0deloc(ispin))
2708 CALL dbcsr_release(almo_scf_env%matrix_sigma_inv(ispin))
2709 CALL dbcsr_release(almo_scf_env%matrix_t(ispin))
2710 CALL dbcsr_release(almo_scf_env%matrix_sigma_sqrt(ispin))
2711 CALL dbcsr_release(almo_scf_env%matrix_sigma_sqrt_inv(ispin))
2712 CALL dbcsr_release(almo_scf_env%matrix_p(ispin))
2713 CALL dbcsr_release(almo_scf_env%matrix_ks(ispin))
2714 CALL dbcsr_release(almo_scf_env%matrix_p_blk(ispin))
2715 CALL dbcsr_release(almo_scf_env%matrix_ks_blk(ispin))
2716 IF (almo_scf_env%need_previous_ks) THEN
2717 CALL dbcsr_release(almo_scf_env%matrix_ks_0deloc(ispin))
2718 END IF
2719 IF (almo_scf_env%need_virtuals) THEN
2720 CALL dbcsr_release(almo_scf_env%matrix_v_blk(ispin))
2721 CALL dbcsr_release(almo_scf_env%matrix_v_full_blk(ispin))
2722 CALL dbcsr_release(almo_scf_env%matrix_v(ispin))
2723 CALL dbcsr_release(almo_scf_env%matrix_vo(ispin))
2724 CALL dbcsr_release(almo_scf_env%matrix_x(ispin))
2725 CALL dbcsr_release(almo_scf_env%matrix_ov(ispin))
2726 CALL dbcsr_release(almo_scf_env%matrix_ov_full(ispin))
2727 CALL dbcsr_release(almo_scf_env%matrix_sigma_vv(ispin))
2728 CALL dbcsr_release(almo_scf_env%matrix_sigma_vv_blk(ispin))
2729 CALL dbcsr_release(almo_scf_env%matrix_sigma_vv_sqrt(ispin))
2730 CALL dbcsr_release(almo_scf_env%matrix_sigma_vv_sqrt_inv(ispin))
2731 CALL dbcsr_release(almo_scf_env%matrix_vv_full_blk(ispin))
2732 IF (almo_scf_env%deloc_truncate_virt /= virt_full) THEN
2733 CALL dbcsr_release(almo_scf_env%matrix_k_tr(ispin))
2734 CALL dbcsr_release(almo_scf_env%matrix_k_blk(ispin))
2735 CALL dbcsr_release(almo_scf_env%matrix_k_blk_ones(ispin))
2736 CALL dbcsr_release(almo_scf_env%matrix_v_disc(ispin))
2737 CALL dbcsr_release(almo_scf_env%matrix_v_disc_blk(ispin))
2738 CALL dbcsr_release(almo_scf_env%matrix_ov_disc(ispin))
2739 CALL dbcsr_release(almo_scf_env%matrix_vv_disc_blk(ispin))
2740 CALL dbcsr_release(almo_scf_env%matrix_vv_disc(ispin))
2741 CALL dbcsr_release(almo_scf_env%opt_k_t_dd(ispin))
2742 CALL dbcsr_release(almo_scf_env%opt_k_t_rr(ispin))
2743 CALL dbcsr_release(almo_scf_env%opt_k_denom(ispin))
2744 END IF
2745 END IF
2746 IF (almo_scf_env%need_orbital_energies) THEN
2747 CALL dbcsr_release(almo_scf_env%matrix_eoo(ispin))
2748 CALL dbcsr_release(almo_scf_env%matrix_evv_full(ispin))
2749 END IF
2750 END DO
2751
2752 ! deallocate matrices
2753 DEALLOCATE (almo_scf_env%matrix_p)
2754 DEALLOCATE (almo_scf_env%matrix_p_blk)
2755 DEALLOCATE (almo_scf_env%matrix_ks)
2756 DEALLOCATE (almo_scf_env%matrix_ks_blk)
2757 DEALLOCATE (almo_scf_env%matrix_t_blk)
2758 DEALLOCATE (almo_scf_env%matrix_err_blk)
2759 DEALLOCATE (almo_scf_env%matrix_err_xx)
2760 DEALLOCATE (almo_scf_env%matrix_t)
2761 DEALLOCATE (almo_scf_env%matrix_t_tr)
2762 DEALLOCATE (almo_scf_env%matrix_sigma)
2763 DEALLOCATE (almo_scf_env%matrix_sigma_blk)
2764 DEALLOCATE (almo_scf_env%matrix_sigma_inv_0deloc)
2765 DEALLOCATE (almo_scf_env%matrix_sigma_sqrt)
2766 DEALLOCATE (almo_scf_env%matrix_sigma_sqrt_inv)
2767 DEALLOCATE (almo_scf_env%matrix_sigma_inv)
2768 DEALLOCATE (almo_scf_env%quench_t)
2769 DEALLOCATE (almo_scf_env%quench_t_blk)
2770 IF (almo_scf_env%need_virtuals) THEN
2771 DEALLOCATE (almo_scf_env%matrix_v_blk)
2772 DEALLOCATE (almo_scf_env%matrix_v_full_blk)
2773 DEALLOCATE (almo_scf_env%matrix_v)
2774 DEALLOCATE (almo_scf_env%matrix_vo)
2775 DEALLOCATE (almo_scf_env%matrix_x)
2776 DEALLOCATE (almo_scf_env%matrix_ov)
2777 DEALLOCATE (almo_scf_env%matrix_ov_full)
2778 DEALLOCATE (almo_scf_env%matrix_sigma_vv)
2779 DEALLOCATE (almo_scf_env%matrix_sigma_vv_blk)
2780 DEALLOCATE (almo_scf_env%matrix_sigma_vv_sqrt)
2781 DEALLOCATE (almo_scf_env%matrix_sigma_vv_sqrt_inv)
2782 DEALLOCATE (almo_scf_env%matrix_vv_full_blk)
2783 IF (almo_scf_env%deloc_truncate_virt /= virt_full) THEN
2784 DEALLOCATE (almo_scf_env%matrix_k_tr)
2785 DEALLOCATE (almo_scf_env%matrix_k_blk)
2786 DEALLOCATE (almo_scf_env%matrix_v_disc)
2787 DEALLOCATE (almo_scf_env%matrix_v_disc_blk)
2788 DEALLOCATE (almo_scf_env%matrix_ov_disc)
2789 DEALLOCATE (almo_scf_env%matrix_vv_disc_blk)
2790 DEALLOCATE (almo_scf_env%matrix_vv_disc)
2791 DEALLOCATE (almo_scf_env%matrix_k_blk_ones)
2792 DEALLOCATE (almo_scf_env%opt_k_t_dd)
2793 DEALLOCATE (almo_scf_env%opt_k_t_rr)
2794 DEALLOCATE (almo_scf_env%opt_k_denom)
2795 END IF
2796 END IF
2797 IF (almo_scf_env%need_previous_ks) THEN
2798 DEALLOCATE (almo_scf_env%matrix_ks_0deloc)
2799 END IF
2800 IF (almo_scf_env%need_orbital_energies) THEN
2801 DEALLOCATE (almo_scf_env%matrix_eoo)
2802 DEALLOCATE (almo_scf_env%matrix_evv_full)
2803 END IF
2804
2805 ! clean up other variables
2806 DO ispin = 1, almo_scf_env%nspins
2807 CALL release_submatrices( &
2808 almo_scf_env%domain_preconditioner(:, ispin))
2809 CALL release_submatrices(almo_scf_env%domain_s_inv(:, ispin))
2810 CALL release_submatrices(almo_scf_env%domain_s_sqrt_inv(:, ispin))
2811 CALL release_submatrices(almo_scf_env%domain_s_sqrt(:, ispin))
2812 CALL release_submatrices(almo_scf_env%domain_ks_xx(:, ispin))
2813 CALL release_submatrices(almo_scf_env%domain_t(:, ispin))
2814 CALL release_submatrices(almo_scf_env%domain_err(:, ispin))
2815 CALL release_submatrices(almo_scf_env%domain_r_down_up(:, ispin))
2816 END DO
2817 DEALLOCATE (almo_scf_env%domain_preconditioner)
2818 DEALLOCATE (almo_scf_env%domain_s_inv)
2819 DEALLOCATE (almo_scf_env%domain_s_sqrt_inv)
2820 DEALLOCATE (almo_scf_env%domain_s_sqrt)
2821 DEALLOCATE (almo_scf_env%domain_ks_xx)
2822 DEALLOCATE (almo_scf_env%domain_t)
2823 DEALLOCATE (almo_scf_env%domain_err)
2824 DEALLOCATE (almo_scf_env%domain_r_down_up)
2825 DO ispin = 1, almo_scf_env%nspins
2826 DEALLOCATE (almo_scf_env%domain_map(ispin)%pairs)
2827 DEALLOCATE (almo_scf_env%domain_map(ispin)%index1)
2828 END DO
2829 DEALLOCATE (almo_scf_env%domain_map)
2830 DEALLOCATE (almo_scf_env%domain_index_of_ao)
2831 DEALLOCATE (almo_scf_env%domain_index_of_atom)
2832 DEALLOCATE (almo_scf_env%first_atom_of_domain)
2833 DEALLOCATE (almo_scf_env%last_atom_of_domain)
2834 DEALLOCATE (almo_scf_env%nbasis_of_domain)
2835 IF (ALLOCATED(almo_scf_env%nocc_of_domain)) THEN
2836 DEALLOCATE (almo_scf_env%nocc_of_domain)
2837 END IF
2838 DEALLOCATE (almo_scf_env%real_ne_of_domain)
2839 DEALLOCATE (almo_scf_env%nvirt_full_of_domain)
2840 DEALLOCATE (almo_scf_env%nvirt_of_domain)
2841 DEALLOCATE (almo_scf_env%nvirt_disc_of_domain)
2842 DEALLOCATE (almo_scf_env%mu_of_domain)
2843 DEALLOCATE (almo_scf_env%cpu_of_domain)
2844 DEALLOCATE (almo_scf_env%charge_of_domain)
2845 DEALLOCATE (almo_scf_env%multiplicity_of_domain)
2846 DEALLOCATE (almo_scf_env%activate)
2847 IF (almo_scf_env%smear) THEN
2848 DEALLOCATE (almo_scf_env%mo_energies)
2849 DEALLOCATE (almo_scf_env%kTS)
2850 END IF
2851
2852 DEALLOCATE (almo_scf_env%domain_index_of_ao_block)
2853 DEALLOCATE (almo_scf_env%domain_index_of_mo_block)
2854
2855 CALL mp_para_env_release(almo_scf_env%para_env)
2856 CALL cp_blacs_env_release(almo_scf_env%blacs_env)
2857
2858 CALL timestop(handle)
2859
2860 END SUBROUTINE almo_scf_clean_up
2861
2862! **************************************************************************************************
2863!> \brief Do post scf calculations with ALMO
2864!> WARNING: ALMO post scf calculation may not work for certain quantities,
2865!> like forces, since ALMO wave function is only 'partially' optimized
2866!> \param qs_env ...
2867!> \par History
2868!> 2016.12 created [Yifei Shi]
2869!> \author Yifei Shi
2870! **************************************************************************************************
2871 SUBROUTINE almo_post_scf_compute_properties(qs_env)
2872 TYPE(qs_environment_type), POINTER :: qs_env
2873
2874 CALL qs_scf_compute_properties(qs_env)
2875
2876 END SUBROUTINE almo_post_scf_compute_properties
2877
2878END MODULE almo_scf
2879
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:213
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, 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.