102#include "./base/base_uses.f90"
108 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'almo_scf'
112 LOGICAL,
PARAMETER :: debug_mode = .false.
113 LOGICAL,
PARAMETER :: safe_mode = .false.
127 LOGICAL,
INTENT(IN) :: calc_forces
129 CHARACTER(len=*),
PARAMETER :: routinen =
'almo_entry_scf'
134 CALL timeset(routinen, handle)
139 CALL get_qs_env(qs_env, almo_scf_env=almo_scf_env)
142 CALL almo_scf_init(qs_env, almo_scf_env, calc_forces)
145 CALL almo_scf_initial_guess(qs_env, almo_scf_env)
148 CALL almo_scf_main(qs_env, almo_scf_env)
151 CALL almo_scf_delocalization(qs_env, almo_scf_env)
154 CALL construct_nlmos(qs_env, almo_scf_env)
160 CALL almo_scf_post(qs_env, almo_scf_env)
163 CALL almo_scf_clean_up(almo_scf_env)
165 CALL timestop(handle)
179 SUBROUTINE almo_scf_init(qs_env, almo_scf_env, calc_forces)
182 LOGICAL,
INTENT(IN) :: calc_forces
184 CHARACTER(len=*),
PARAMETER :: routinen =
'almo_scf_init'
186 INTEGER :: ao, handle, i, iao, idomain, ispin, &
187 multip, naos, natoms, ndomains, nelec, &
188 nelec_a, nelec_b, nmols, nspins, &
196 CALL timeset(routinen, handle)
200 IF (logger%para_env%is_source())
THEN
208 almo_scf_env%opt_block_diag_pcg%optimizer_type =
optimizer_pcg
218 nelectron_total=almo_scf_env%nelectrons_total, &
220 dft_control=dft_control, &
221 molecule_set=molecule_set, &
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()
231 almo_scf_env%nspins = dft_control%nspins
232 almo_scf_env%nmolecules =
SIZE(molecule_set)
234 nfullrows_total=naos, nblkrows_total=almo_scf_env%natoms)
235 almo_scf_env%naos = naos
237 almo_scf_env%smear = dft_control%smear
238 IF (almo_scf_env%smear)
THEN
240 IF ((almo_scf_env%almo_update_algorithm /=
almo_scf_diag) .OR. &
242 (almo_scf_env%xalmo_update_algorithm /=
almo_scf_diag)))
THEN
243 cpabort(
"ALMO smearing is currently implemented for DIAG algorithm only")
246 cpabort(
"Only Fermi-Dirac smearing is currently compatible with ALMO")
248 almo_scf_env%smear_e_temp = qs_env%scf_control%smear%electronic_temperature
251 cpabort(
"ALMO smearing was designed to work with molecular fragments only")
256 nmols = almo_scf_env%nmolecules
257 natoms = almo_scf_env%natoms
261 almo_scf_env%ndomains = almo_scf_env%nmolecules
263 almo_scf_env%ndomains = almo_scf_env%natoms
266 IF (
ALLOCATED(almo_scf_env%activate))
THEN
267 IF (almo_scf_env%activate(1) > 1)
THEN
268 DEALLOCATE (almo_scf_env%activate)
272 IF (.NOT.
ALLOCATED(almo_scf_env%activate))
THEN
273 ALLOCATE (almo_scf_env%activate(1))
274 almo_scf_env%activate = 0
277 IF (almo_scf_env%activate(1) == 1)
THEN
279 ndomains =
SIZE(almo_scf_env%multiplicity_of_domain)
280 nspins =
SIZE(almo_scf_env%multiplicity_of_domain)
282 nspins = almo_scf_env%nspins
283 ndomains = almo_scf_env%ndomains
286 IF (almo_scf_env%activate(1) == 0)
THEN
288 ALLOCATE (almo_scf_env%charge_of_domain(ndomains))
289 ALLOCATE (almo_scf_env%multiplicity_of_domain(ndomains))
294 ALLOCATE (almo_scf_env%domain_index_of_atom(natoms))
295 ALLOCATE (almo_scf_env%domain_index_of_ao(naos))
296 ALLOCATE (almo_scf_env%first_atom_of_domain(ndomains))
297 ALLOCATE (almo_scf_env%last_atom_of_domain(ndomains))
298 ALLOCATE (almo_scf_env%nbasis_of_domain(ndomains))
299 ALLOCATE (almo_scf_env%nocc_of_domain(ndomains, nspins))
300 ALLOCATE (almo_scf_env%real_ne_of_domain(ndomains, nspins))
301 ALLOCATE (almo_scf_env%nvirt_full_of_domain(ndomains, nspins))
302 ALLOCATE (almo_scf_env%nvirt_of_domain(ndomains, nspins))
303 ALLOCATE (almo_scf_env%nvirt_disc_of_domain(ndomains, nspins))
304 ALLOCATE (almo_scf_env%mu_of_domain(ndomains, nspins))
305 ALLOCATE (almo_scf_env%cpu_of_domain(ndomains))
310 IF (almo_scf_env%activate(1) == 1)
THEN
312 atom_to_mol=almo_scf_env%domain_index_of_atom, &
313 mol_to_first_atom=almo_scf_env%first_atom_of_domain, &
314 mol_to_last_atom=almo_scf_env%last_atom_of_domain, &
315 mol_to_nelectrons=almo_scf_env%nocc_of_domain(1:ndomains, 1), &
316 mol_to_nbasis=almo_scf_env%nbasis_of_domain)
320 atom_to_mol=almo_scf_env%domain_index_of_atom, &
321 mol_to_first_atom=almo_scf_env%first_atom_of_domain, &
322 mol_to_last_atom=almo_scf_env%last_atom_of_domain, &
323 mol_to_nelectrons=almo_scf_env%nocc_of_domain(1:ndomains, 1), &
324 mol_to_nbasis=almo_scf_env%nbasis_of_domain, &
325 mol_to_charge=almo_scf_env%charge_of_domain, &
326 mol_to_multiplicity=almo_scf_env%multiplicity_of_domain)
332 DO idomain = 1, ndomains
333 IF (almo_scf_env%activate(1) == 1)
THEN
334 nelec = almo_scf_env%nocc_of_domain(idomain, 1) - almo_scf_env%charge_of_domain(idomain)
336 nelec = almo_scf_env%nocc_of_domain(idomain, 1)
339 multip = almo_scf_env%multiplicity_of_domain(idomain)
340 nelec_a = (nelec + multip - 1)/2
343 IF (almo_scf_env%smear)
THEN
344 cpwarn_if(multip > 1,
"BEWARE: Non singlet state detected, treating it as closed-shell")
347 almo_scf_env%real_ne_of_domain(idomain, :) = real(nelec, kind=
dp)/2.0_dp
350 almo_scf_env%nocc_of_domain(idomain, :) = ceiling(almo_scf_env%real_ne_of_domain(idomain, :)) &
351 + (almo_scf_env%last_atom_of_domain(idomain) &
352 - almo_scf_env%first_atom_of_domain(idomain) + 1)
354 almo_scf_env%nocc_of_domain(idomain, 1) = nelec_a
355 nelec_b = nelec - nelec_a
356 IF (almo_scf_env%activate(1) == 1)
THEN
357 almo_scf_env%nocc_of_domain(idomain, 2) = nelec_b
360 IF (nelec_a /= nelec_b)
THEN
361 IF (nspins == 1)
THEN
363 cpabort(
"odd e- -- use unrestricted methods")
371 almo_scf_env%nvirt_full_of_domain(:, ispin) = &
372 almo_scf_env%nbasis_of_domain(:) - &
373 almo_scf_env%nocc_of_domain(:, ispin)
375 SELECT CASE (almo_scf_env%deloc_truncate_virt)
377 almo_scf_env%nvirt_of_domain(:, ispin) = &
378 almo_scf_env%nvirt_full_of_domain(:, ispin)
379 almo_scf_env%nvirt_disc_of_domain(:, ispin) = 0
381 DO idomain = 1, ndomains
382 almo_scf_env%nvirt_of_domain(idomain, ispin) = &
383 min(almo_scf_env%deloc_virt_per_domain, &
384 almo_scf_env%nvirt_full_of_domain(idomain, ispin))
385 almo_scf_env%nvirt_disc_of_domain(idomain, ispin) = &
386 almo_scf_env%nvirt_full_of_domain(idomain, ispin) - &
387 almo_scf_env%nvirt_of_domain(idomain, ispin)
390 DO idomain = 1, ndomains
391 almo_scf_env%nvirt_of_domain(idomain, ispin) = &
392 min(almo_scf_env%nocc_of_domain(idomain, ispin), &
393 almo_scf_env%nvirt_full_of_domain(idomain, ispin))
394 almo_scf_env%nvirt_disc_of_domain(idomain, ispin) = &
395 almo_scf_env%nvirt_full_of_domain(idomain, ispin) - &
396 almo_scf_env%nvirt_of_domain(idomain, ispin)
399 cpabort(
"illegal method for virtual space truncation")
404 almo_scf_env%domain_index_of_atom(1:natoms) = [(i, i=1, natoms)]
408 DO idomain = 1, ndomains
409 DO iao = 1, almo_scf_env%nbasis_of_domain(idomain)
410 almo_scf_env%domain_index_of_ao(ao) = idomain
415 almo_scf_env%mu_of_domain(:, :) = almo_scf_env%mu
420 ALLOCATE (almo_scf_env%domain_index_of_ao_block(natoms))
421 almo_scf_env%domain_index_of_ao_block(:) = &
422 almo_scf_env%domain_index_of_atom(:)
424 ALLOCATE (almo_scf_env%domain_index_of_ao_block(nmols))
426 almo_scf_env%domain_index_of_ao_block(:) = [(i, i=1, nmols)]
430 ALLOCATE (almo_scf_env%domain_index_of_mo_block(natoms))
431 almo_scf_env%domain_index_of_mo_block(:) = &
432 almo_scf_env%domain_index_of_atom(:)
434 ALLOCATE (almo_scf_env%domain_index_of_mo_block(nmols))
436 almo_scf_env%domain_index_of_mo_block(:) = [(i, i=1, nmols)]
442 almo_scf_env%need_previous_ks = .true.
448 almo_scf_env%need_virtuals = .true.
449 almo_scf_env%need_orbital_energies = .true.
452 almo_scf_env%calc_forces = calc_forces
453 IF (calc_forces)
THEN
458 cpabort(
"Forces for perturbative methods are NYI. Change DELOCALIZE_METHOD")
461 IF (almo_scf_env%almo_history%istore > (almo_scf_env%almo_history%nstore + 1))
THEN
462 IF (almo_scf_env%opt_block_diag_pcg%eps_error_early > 0.0_dp)
THEN
463 almo_scf_env%opt_block_diag_pcg%eps_error = almo_scf_env%opt_block_diag_pcg%eps_error_early
464 almo_scf_env%opt_block_diag_pcg%early_stopping_on = .true.
465 IF (unit_nr > 0)
WRITE (unit_nr,
"(/,T2,A)")
"ALMO_OPTIMIZER_PCG: EPS_ERROR_EARLY is on"
467 IF (almo_scf_env%opt_block_diag_diis%eps_error_early > 0.0_dp)
THEN
468 almo_scf_env%opt_block_diag_diis%eps_error = almo_scf_env%opt_block_diag_diis%eps_error_early
469 almo_scf_env%opt_block_diag_diis%early_stopping_on = .true.
470 IF (unit_nr > 0)
WRITE (unit_nr,
"(/,T2,A)")
"ALMO_OPTIMIZER_DIIS: EPS_ERROR_EARLY is on"
472 IF (almo_scf_env%opt_block_diag_pcg%max_iter_early > 0)
THEN
473 almo_scf_env%opt_block_diag_pcg%max_iter = almo_scf_env%opt_block_diag_pcg%max_iter_early
474 almo_scf_env%opt_block_diag_pcg%early_stopping_on = .true.
475 IF (unit_nr > 0)
WRITE (unit_nr,
"(/,T2,A)")
"ALMO_OPTIMIZER_PCG: MAX_ITER_EARLY is on"
477 IF (almo_scf_env%opt_block_diag_diis%max_iter_early > 0)
THEN
478 almo_scf_env%opt_block_diag_diis%max_iter = almo_scf_env%opt_block_diag_diis%max_iter_early
479 almo_scf_env%opt_block_diag_diis%early_stopping_on = .true.
480 IF (unit_nr > 0)
WRITE (unit_nr,
"(/,T2,A)")
"ALMO_OPTIMIZER_DIIS: MAX_ITER_EARLY is on"
483 almo_scf_env%opt_block_diag_diis%early_stopping_on = .false.
484 almo_scf_env%opt_block_diag_pcg%early_stopping_on = .false.
486 IF (almo_scf_env%xalmo_history%istore > (almo_scf_env%xalmo_history%nstore + 1))
THEN
487 IF (almo_scf_env%opt_xalmo_pcg%eps_error_early > 0.0_dp)
THEN
488 almo_scf_env%opt_xalmo_pcg%eps_error = almo_scf_env%opt_xalmo_pcg%eps_error_early
489 almo_scf_env%opt_xalmo_pcg%early_stopping_on = .true.
490 IF (unit_nr > 0)
WRITE (unit_nr,
"(/,T2,A)")
"XALMO_OPTIMIZER_PCG: EPS_ERROR_EARLY is on"
492 IF (almo_scf_env%opt_xalmo_pcg%max_iter_early > 0.0_dp)
THEN
493 almo_scf_env%opt_xalmo_pcg%max_iter = almo_scf_env%opt_xalmo_pcg%max_iter_early
494 almo_scf_env%opt_xalmo_pcg%early_stopping_on = .true.
495 IF (unit_nr > 0)
WRITE (unit_nr,
"(/,T2,A)")
"XALMO_OPTIMIZER_PCG: MAX_ITER_EARLY is on"
498 almo_scf_env%opt_xalmo_pcg%early_stopping_on = .false.
503 CALL almo_scf_env_create_matrices(almo_scf_env, matrix_s(1)%matrix)
506 almo_scf_env%s_inv_done = .false.
507 almo_scf_env%s_sqrt_done = .false.
508 CALL almo_scf_init_ao_overlap(matrix_s(1)%matrix, almo_scf_env)
515 CALL almo_scf_print_job_info(almo_scf_env, unit_nr)
518 ALLOCATE (almo_scf_env%domain_preconditioner(ndomains, nspins))
522 ALLOCATE (almo_scf_env%domain_ks_xx(ndomains, nspins))
526 ALLOCATE (almo_scf_env%domain_s_inv(ndomains, nspins))
528 ALLOCATE (almo_scf_env%domain_s_sqrt_inv(ndomains, nspins))
530 ALLOCATE (almo_scf_env%domain_s_sqrt(ndomains, nspins))
532 ALLOCATE (almo_scf_env%domain_t(ndomains, nspins))
534 ALLOCATE (almo_scf_env%domain_err(ndomains, nspins))
536 ALLOCATE (almo_scf_env%domain_r_down_up(ndomains, nspins))
541 almo_scf_env%matrix_ks, &
542 almo_scf_env%mat_distr_aos, &
543 almo_scf_env%eps_filter)
546 CALL timestop(handle)
548 END SUBROUTINE almo_scf_init
559 SUBROUTINE almo_scf_initial_guess(qs_env, almo_scf_env)
563 CHARACTER(len=*),
PARAMETER :: routinen =
'almo_scf_initial_guess'
565 CHARACTER(LEN=default_path_length) :: file_name, project_name
566 INTEGER :: handle, iaspc, ispin, istore, naspc, &
568 INTEGER,
DIMENSION(2) :: nelectron_spin
569 LOGICAL :: aspc_guess, has_unit_metric
570 REAL(kind=
dp) :: alpha, cs_pos, energy, kts_sum
574 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_s, rho_ao
579 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
582 CALL timeset(routinen, handle)
584 NULLIFY (rho, rho_ao)
588 IF (logger%para_env%is_source())
THEN
596 dft_control=dft_control, &
598 atomic_kind_set=atomic_kind_set, &
599 qs_kind_set=qs_kind_set, &
600 particle_set=particle_set, &
601 has_unit_metric=has_unit_metric, &
603 nelectron_spin=nelectron_spin, &
604 mscfg_env=mscfg_env, &
608 cpassert(
ASSOCIATED(mscfg_env))
614 IF (almo_scf_env%almo_history%istore == 0)
THEN
620 nspins = almo_scf_env%nspins
623 IF (.NOT. aspc_guess)
THEN
625 SELECT CASE (almo_scf_env%almo_scf_guess)
634 almo_scf_env%matrix_t_blk(ispin), ispin)
636 almo_scf_env%eps_filter)
642 IF (dft_control%qs_control%dftb .OR. dft_control%qs_control%semi_empirical .OR. &
643 dft_control%qs_control%xtb)
THEN
645 matrix_s(1)%matrix, has_unit_metric, &
646 dft_control, particle_set, atomic_kind_set, qs_kind_set, &
647 nspins, nelectron_spin, &
651 nspins, nelectron_spin, unit_nr, para_env)
657 almo_scf_env%matrix_p_blk(ispin), almo_scf_env%mat_distr_aos)
659 almo_scf_env%eps_filter)
668 project_name = logger%iter_info%project_name
671 WRITE (file_name,
'(A,I0,A)') trim(project_name)//
"_ALMO_SPIN_", ispin,
"_RESTART.mo"
672 CALL dbcsr_get_info(almo_scf_env%matrix_t_blk(ispin), distribution=dist)
673 CALL dbcsr_binary_read(file_name, distribution=dist, matrix_new=almo_scf_env%matrix_t_blk(ispin))
674 cs_pos =
dbcsr_checksum(almo_scf_env%matrix_t_blk(ispin), pos=.true.)
675 IF (unit_nr > 0)
THEN
676 WRITE (unit_nr,
'(T2,A,E20.8)')
"Read restart ALMO "//trim(file_name)//
" with checksum: ", cs_pos
686 naspc = min(almo_scf_env%almo_history%istore, almo_scf_env%almo_history%nstore)
687 IF (unit_nr > 0)
THEN
688 WRITE (unit_nr, fmt=
"(/,T2,A,/,/,T3,A,I0)") &
689 "Parameters for the always stable predictor-corrector (ASPC) method:", &
690 "ASPC order: ", naspc
697 istore = mod(almo_scf_env%almo_history%istore - iaspc, almo_scf_env%almo_history%nstore) + 1
698 alpha = (-1.0_dp)**(iaspc + 1)*real(iaspc, kind=
dp)* &
700 IF (unit_nr > 0)
THEN
701 WRITE (unit_nr, fmt=
"(T3,A2,I0,A4,F10.6)") &
702 "B(", iaspc,
") = ", alpha
705 CALL dbcsr_copy(almo_scf_env%matrix_t_blk(ispin), &
706 almo_scf_env%almo_history%matrix_t(ispin), &
707 keep_sparsity=.true.)
708 CALL dbcsr_scale(almo_scf_env%matrix_t_blk(ispin), alpha)
711 almo_scf_env%almo_history%matrix_p_up_down(ispin, istore), &
712 almo_scf_env%almo_history%matrix_t(ispin), &
713 1.0_dp, almo_scf_env%matrix_t_blk(ispin), &
714 retain_sparsity=.true.)
725 overlap=almo_scf_env%matrix_sigma_blk(ispin), &
726 metric=almo_scf_env%matrix_s_blk(1), &
727 retain_locality=.true., &
728 only_normalize=.false., &
729 nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
730 eps_filter=almo_scf_env%eps_filter, &
731 order_lanczos=almo_scf_env%order_lanczos, &
732 eps_lanczos=almo_scf_env%eps_lanczos, &
733 max_iter_lanczos=almo_scf_env%max_iter_lanczos)
736 IF (almo_scf_env%smear)
THEN
738 mo_energies=almo_scf_env%mo_energies(:, ispin), &
739 mu_of_domain=almo_scf_env%mu_of_domain(:, ispin), &
740 real_ne_of_domain=almo_scf_env%real_ne_of_domain(:, ispin), &
741 spin_kts=almo_scf_env%kTS(ispin), &
742 smear_e_temp=almo_scf_env%smear_e_temp, &
743 ndomains=almo_scf_env%ndomains, &
744 nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin))
748 p=almo_scf_env%matrix_p(ispin), &
749 eps_filter=almo_scf_env%eps_filter, &
750 orthog_orbs=.false., &
751 nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
752 s=almo_scf_env%matrix_s(1), &
753 sigma=almo_scf_env%matrix_sigma(ispin), &
754 sigma_inv=almo_scf_env%matrix_sigma_inv(ispin), &
756 smear=almo_scf_env%smear, &
757 algorithm=almo_scf_env%sigma_inv_algorithm, &
758 eps_lanczos=almo_scf_env%eps_lanczos, &
759 max_iter_lanczos=almo_scf_env%max_iter_lanczos, &
760 inv_eps_factor=almo_scf_env%matrix_iter_eps_error_factor, &
761 para_env=almo_scf_env%para_env, &
762 blacs_env=almo_scf_env%blacs_env)
767 IF (nspins == 1)
THEN
770 IF (almo_scf_env%smear)
THEN
771 almo_scf_env%kTS(1) = almo_scf_env%kTS(1)*2.0_dp
775 IF (almo_scf_env%smear)
THEN
776 kts_sum = sum(almo_scf_env%kTS)
782 almo_scf_env%matrix_p, &
783 almo_scf_env%matrix_ks, &
785 almo_scf_env%eps_filter, &
786 almo_scf_env%mat_distr_aos, &
787 smear=almo_scf_env%smear, &
790 IF (unit_nr > 0)
THEN
792 WRITE (unit_nr,
'(T2,A38,F40.10)')
"Single-molecule energy:", &
793 sum(mscfg_env%energy_of_frag)
795 WRITE (unit_nr,
'(T2,A38,F40.10)')
"Energy of the initial guess:", energy
796 WRITE (unit_nr,
'()')
799 CALL timestop(handle)
801 END SUBROUTINE almo_scf_initial_guess
810 SUBROUTINE almo_scf_store_extrapolation_data(almo_scf_env)
813 CHARACTER(len=*),
PARAMETER :: routinen =
'almo_scf_store_extrapolation_data'
815 INTEGER :: handle, ispin, istore, unit_nr
816 LOGICAL :: delocalization_uses_extrapolation
818 TYPE(
dbcsr_type) :: matrix_no_tmp1, matrix_no_tmp2, &
819 matrix_no_tmp3, matrix_no_tmp4
821 CALL timeset(routinen, handle)
825 IF (logger%para_env%is_source())
THEN
831 IF (almo_scf_env%almo_history%nstore > 0)
THEN
833 almo_scf_env%almo_history%istore = almo_scf_env%almo_history%istore + 1
835 DO ispin = 1,
SIZE(almo_scf_env%matrix_t_blk)
837 istore = mod(almo_scf_env%almo_history%istore - 1, almo_scf_env%almo_history%nstore) + 1
839 IF (almo_scf_env%almo_history%istore == 1)
THEN
840 CALL dbcsr_create(almo_scf_env%almo_history%matrix_t(ispin), &
841 template=almo_scf_env%matrix_t_blk(ispin), &
842 matrix_type=dbcsr_type_no_symmetry)
844 CALL dbcsr_copy(almo_scf_env%almo_history%matrix_t(ispin), &
845 almo_scf_env%matrix_t_blk(ispin))
847 IF (almo_scf_env%almo_history%istore <= almo_scf_env%almo_history%nstore)
THEN
848 CALL dbcsr_create(almo_scf_env%almo_history%matrix_p_up_down(ispin, istore), &
849 template=almo_scf_env%matrix_s(1), &
850 matrix_type=dbcsr_type_no_symmetry)
853 CALL dbcsr_create(matrix_no_tmp1, template=almo_scf_env%matrix_t_blk(ispin), &
854 matrix_type=dbcsr_type_no_symmetry)
855 CALL dbcsr_create(matrix_no_tmp2, template=almo_scf_env%matrix_t_blk(ispin), &
856 matrix_type=dbcsr_type_no_symmetry)
860 almo_scf_env%matrix_t_blk(ispin), &
861 0.0_dp, matrix_no_tmp1, &
862 filter_eps=almo_scf_env%eps_filter)
864 almo_scf_env%matrix_sigma_inv_0deloc(ispin), &
865 0.0_dp, matrix_no_tmp2, &
866 filter_eps=almo_scf_env%eps_filter)
868 almo_scf_env%matrix_t_blk(ispin), &
870 0.0_dp, almo_scf_env%almo_history%matrix_p_up_down(ispin, istore), &
871 filter_eps=almo_scf_env%eps_filter)
881 delocalization_uses_extrapolation = &
884 IF (almo_scf_env%xalmo_history%nstore > 0 .AND. &
885 delocalization_uses_extrapolation)
THEN
887 almo_scf_env%xalmo_history%istore = almo_scf_env%xalmo_history%istore + 1
889 DO ispin = 1,
SIZE(almo_scf_env%matrix_t)
891 istore = mod(almo_scf_env%xalmo_history%istore - 1, almo_scf_env%xalmo_history%nstore) + 1
893 IF (almo_scf_env%xalmo_history%istore == 1)
THEN
894 CALL dbcsr_create(almo_scf_env%xalmo_history%matrix_t(ispin), &
895 template=almo_scf_env%matrix_t(ispin), &
896 matrix_type=dbcsr_type_no_symmetry)
898 CALL dbcsr_copy(almo_scf_env%xalmo_history%matrix_t(ispin), &
899 almo_scf_env%matrix_t(ispin))
901 IF (almo_scf_env%xalmo_history%istore <= almo_scf_env%xalmo_history%nstore)
THEN
906 CALL dbcsr_create(almo_scf_env%xalmo_history%matrix_p_up_down(ispin, istore), &
907 template=almo_scf_env%matrix_s(1), &
908 matrix_type=dbcsr_type_no_symmetry)
911 CALL dbcsr_create(matrix_no_tmp3, template=almo_scf_env%matrix_t(ispin), &
912 matrix_type=dbcsr_type_no_symmetry)
913 CALL dbcsr_create(matrix_no_tmp4, template=almo_scf_env%matrix_t(ispin), &
914 matrix_type=dbcsr_type_no_symmetry)
918 almo_scf_env%matrix_t(ispin), &
919 0.0_dp, matrix_no_tmp3, &
920 filter_eps=almo_scf_env%eps_filter)
922 almo_scf_env%matrix_sigma_inv(ispin), &
923 0.0_dp, matrix_no_tmp4, &
924 filter_eps=almo_scf_env%eps_filter)
926 almo_scf_env%matrix_t(ispin), &
928 0.0_dp, almo_scf_env%xalmo_history%matrix_p_up_down(ispin, istore), &
929 filter_eps=almo_scf_env%eps_filter)
944 CALL timestop(handle)
946 END SUBROUTINE almo_scf_store_extrapolation_data
956 SUBROUTINE almo_scf_print_job_info(almo_scf_env, unit_nr)
959 INTEGER,
INTENT(IN) :: unit_nr
961 CHARACTER(len=*),
PARAMETER :: routinen =
'almo_scf_print_job_info'
963 CHARACTER(len=13) :: neig_string
964 CHARACTER(len=33) :: deloc_method_string
965 INTEGER :: handle, idomain, index1_prev, sum_temp
966 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: nneighbors
968 CALL timeset(routinen, handle)
970 IF (unit_nr > 0)
THEN
971 WRITE (unit_nr,
'()')
972 WRITE (unit_nr,
'(T2,A,A,A)') repeat(
"-", 32),
" ALMO SETTINGS ", repeat(
"-", 32)
974 WRITE (unit_nr,
'(T2,A,T48,E33.3)')
"eps_filter:", almo_scf_env%eps_filter
976 IF (almo_scf_env%almo_update_algorithm ==
almo_scf_skip)
THEN
977 WRITE (unit_nr,
'(T2,A)')
"skip optimization of block-diagonal ALMOs"
979 WRITE (unit_nr,
'(T2,A)')
"optimization of block-diagonal ALMOs:"
980 SELECT CASE (almo_scf_env%almo_update_algorithm)
993 SELECT CASE (almo_scf_env%deloc_method)
995 deloc_method_string =
"NONE"
997 deloc_method_string =
"FULL_X"
999 deloc_method_string =
"FULL_SCF"
1001 deloc_method_string =
"FULL_X_THEN_SCF"
1003 deloc_method_string =
"XALMO_1DIAG"
1005 deloc_method_string =
"XALMO_X"
1007 deloc_method_string =
"XALMO_SCF"
1009 WRITE (unit_nr,
'(T2,A,T48,A33)')
"delocalization:", trim(deloc_method_string)
1013 SELECT CASE (almo_scf_env%deloc_method)
1015 WRITE (unit_nr,
'(T2,A,T48,A33)')
"delocalization cutoff radius:", &
1017 deloc_method_string =
"FULL_X_THEN_SCF"
1019 WRITE (unit_nr,
'(T2,A,T48,F33.5)')
"XALMO cutoff radius:", &
1020 almo_scf_env%quencher_r0_factor
1026 WRITE (unit_nr,
'(T2,A)')
"optimization of extended orbitals:"
1027 SELECT CASE (almo_scf_env%xalmo_update_algorithm)
1070 WRITE (unit_nr,
'(T2,A)') repeat(
"-", 79)
1071 WRITE (unit_nr,
'(T2,A,T48,I33)')
"Total fragments:", &
1072 almo_scf_env%ndomains
1074 sum_temp = sum(almo_scf_env%nbasis_of_domain(:))
1075 WRITE (unit_nr,
'(T2,A,T53,I5,F9.2,I5,I9)') &
1076 "Basis set size per fragment (min, av, max, total):", &
1077 minval(almo_scf_env%nbasis_of_domain(:)), &
1078 (1.0_dp*sum_temp)/almo_scf_env%ndomains, &
1079 maxval(almo_scf_env%nbasis_of_domain(:)), &
1087 sum_temp = sum(almo_scf_env%nocc_of_domain(:, :))
1088 WRITE (unit_nr,
'(T2,A,T53,I5,F9.2,I5,I9)') &
1089 "Occupied MOs per fragment (min, av, max, total):", &
1090 minval(sum(almo_scf_env%nocc_of_domain, dim=2)), &
1091 (1.0_dp*sum_temp)/almo_scf_env%ndomains, &
1092 maxval(sum(almo_scf_env%nocc_of_domain, dim=2)), &
1100 sum_temp = sum(almo_scf_env%nvirt_of_domain(:, :))
1101 WRITE (unit_nr,
'(T2,A,T53,I5,F9.2,I5,I9)') &
1102 "Virtual MOs per fragment (min, av, max, total):", &
1103 minval(sum(almo_scf_env%nvirt_of_domain, dim=2)), &
1104 (1.0_dp*sum_temp)/almo_scf_env%ndomains, &
1105 maxval(sum(almo_scf_env%nvirt_of_domain, dim=2)), &
1113 sum_temp = sum(almo_scf_env%charge_of_domain(:))
1114 WRITE (unit_nr,
'(T2,A,T53,I5,F9.2,I5,I9)') &
1115 "Charges per fragment (min, av, max, total):", &
1116 minval(almo_scf_env%charge_of_domain(:)), &
1117 (1.0_dp*sum_temp)/almo_scf_env%ndomains, &
1118 maxval(almo_scf_env%charge_of_domain(:)), &
1127 ALLOCATE (nneighbors(almo_scf_env%ndomains))
1129 DO idomain = 1, almo_scf_env%ndomains
1131 IF (idomain == 1)
THEN
1134 index1_prev = almo_scf_env%domain_map(1)%index1(idomain - 1)
1137 SELECT CASE (almo_scf_env%deloc_method)
1139 nneighbors(idomain) = 0
1141 nneighbors(idomain) = almo_scf_env%ndomains - 1
1143 nneighbors(idomain) = almo_scf_env%domain_map(1)%index1(idomain) - index1_prev - 1
1145 nneighbors(idomain) = -1
1150 sum_temp = sum(nneighbors(:))
1151 WRITE (unit_nr,
'(T2,A,T53,I5,F9.2,I5,I9)') &
1152 "Deloc. neighbors of fragment (min, av, max, total):", &
1153 minval(nneighbors(:)), &
1154 (1.0_dp*sum_temp)/almo_scf_env%ndomains, &
1155 maxval(nneighbors(:)), &
1158 WRITE (unit_nr,
'(T2,A)') repeat(
"-", 79)
1159 WRITE (unit_nr,
'()')
1161 IF (almo_scf_env%ndomains <= 64)
THEN
1164 WRITE (unit_nr,
'(T2,A10,A13,A13,A13,A13,A13)') &
1165 "Fragment",
"Basis Set",
"Occupied",
"Virtual",
"Charge",
"Deloc Neig"
1166 WRITE (unit_nr,
'(T2,A)') repeat(
"-", 79)
1167 DO idomain = 1, almo_scf_env%ndomains
1169 SELECT CASE (almo_scf_env%deloc_method)
1171 neig_string =
"NONE"
1175 WRITE (neig_string,
'(I13)') nneighbors(idomain)
1180 WRITE (unit_nr,
'(T2,I10,I13,I13,I13,I13,A13)') &
1181 idomain, almo_scf_env%nbasis_of_domain(idomain), &
1182 sum(almo_scf_env%nocc_of_domain(idomain, :)), &
1183 sum(almo_scf_env%nvirt_of_domain(idomain, :)), &
1185 almo_scf_env%charge_of_domain(idomain), &
1186 adjustr(trim(neig_string))
1190 SELECT CASE (almo_scf_env%deloc_method)
1193 WRITE (unit_nr,
'(T2,A)') repeat(
"-", 79)
1196 WRITE (unit_nr,
'(T2,A78)') &
1197 "Neighbor lists (including self)"
1198 WRITE (unit_nr,
'(T2,A)') repeat(
"-", 79)
1199 DO idomain = 1, almo_scf_env%ndomains
1201 IF (idomain == 1)
THEN
1204 index1_prev = almo_scf_env%domain_map(1)%index1(idomain - 1)
1207 WRITE (unit_nr,
'(T2,I10,":")') idomain
1208 WRITE (unit_nr,
'(T12,11I6)') &
1209 almo_scf_env%domain_map(1)%pairs &
1210 (index1_prev:almo_scf_env%domain_map(1)%index1(idomain) - 1, 1)
1218 WRITE (unit_nr,
'(T2,A)')
"The system is too big to print details for each fragment."
1222 WRITE (unit_nr,
'(T2,A)') repeat(
"-", 79)
1224 WRITE (unit_nr,
'()')
1226 DEALLOCATE (nneighbors)
1230 CALL timestop(handle)
1232 END SUBROUTINE almo_scf_print_job_info
1243 SUBROUTINE almo_scf_init_ao_overlap(matrix_s, almo_scf_env)
1247 CHARACTER(len=*),
PARAMETER :: routinen =
'almo_scf_init_ao_overlap'
1249 INTEGER :: handle, unit_nr
1252 CALL timeset(routinen, handle)
1256 IF (logger%para_env%is_source())
THEN
1264 IF (almo_scf_env%orthogonal_basis)
THEN
1265 CALL dbcsr_set(almo_scf_env%matrix_s(1), 0.0_dp)
1267 CALL dbcsr_set(almo_scf_env%matrix_s_blk(1), 0.0_dp)
1270 CALL matrix_qs_to_almo(matrix_s, almo_scf_env%matrix_s(1), almo_scf_env%mat_distr_aos)
1271 CALL dbcsr_copy(almo_scf_env%matrix_s_blk(1), &
1272 almo_scf_env%matrix_s(1), keep_sparsity=.true.)
1275 CALL dbcsr_filter(almo_scf_env%matrix_s(1), almo_scf_env%eps_filter)
1276 CALL dbcsr_filter(almo_scf_env%matrix_s_blk(1), almo_scf_env%eps_filter)
1278 IF (almo_scf_env%almo_update_algorithm ==
almo_scf_diag)
THEN
1280 almo_scf_env%matrix_s_blk_sqrt_inv(1), &
1281 almo_scf_env%matrix_s_blk(1), &
1282 threshold=almo_scf_env%eps_filter, &
1283 order=almo_scf_env%order_lanczos, &
1285 eps_lanczos=almo_scf_env%eps_lanczos, &
1286 max_iter_lanczos=almo_scf_env%max_iter_lanczos)
1289 almo_scf_env%matrix_s_blk(1), &
1290 threshold=almo_scf_env%eps_filter, &
1291 filter_eps=almo_scf_env%eps_filter)
1294 CALL timestop(handle)
1296 END SUBROUTINE almo_scf_init_ao_overlap
1307 SUBROUTINE almo_scf_main(qs_env, almo_scf_env)
1311 CHARACTER(len=*),
PARAMETER :: routinen =
'almo_scf_main'
1313 INTEGER :: handle, ispin, unit_nr
1316 CALL timeset(routinen, handle)
1320 IF (logger%para_env%is_source())
THEN
1326 SELECT CASE (almo_scf_env%almo_update_algorithm)
1329 SELECT CASE (almo_scf_env%almo_update_algorithm)
1334 almo_scf_env=almo_scf_env, &
1335 optimizer=almo_scf_env%opt_block_diag_pcg, &
1336 quench_t=almo_scf_env%quench_t_blk, &
1337 matrix_t_in=almo_scf_env%matrix_t_blk, &
1338 matrix_t_out=almo_scf_env%matrix_t_blk, &
1339 assume_t0_q0x=.false., &
1340 perturbation_only=.false., &
1346 almo_scf_env=almo_scf_env, &
1347 optimizer=almo_scf_env%opt_block_diag_trustr, &
1348 quench_t=almo_scf_env%quench_t_blk, &
1349 matrix_t_in=almo_scf_env%matrix_t_blk, &
1350 matrix_t_out=almo_scf_env%matrix_t_blk, &
1351 perturbation_only=.false., &
1356 DO ispin = 1, almo_scf_env%nspins
1358 overlap=almo_scf_env%matrix_sigma_blk(ispin), &
1359 metric=almo_scf_env%matrix_s_blk(1), &
1360 retain_locality=.true., &
1361 only_normalize=.false., &
1362 nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
1363 eps_filter=almo_scf_env%eps_filter, &
1364 order_lanczos=almo_scf_env%order_lanczos, &
1365 eps_lanczos=almo_scf_env%eps_lanczos, &
1366 max_iter_lanczos=almo_scf_env%max_iter_lanczos)
1373 almo_scf_env%opt_block_diag_diis)
1378 DO ispin = 1, almo_scf_env%nspins
1379 CALL dbcsr_copy(almo_scf_env%matrix_ks_0deloc(ispin), &
1380 almo_scf_env%matrix_ks(ispin))
1381 CALL dbcsr_copy(almo_scf_env%matrix_sigma_inv_0deloc(ispin), &
1382 almo_scf_env%matrix_sigma_inv(ispin))
1385 CALL timestop(handle)
1387 END SUBROUTINE almo_scf_main
1397 SUBROUTINE almo_scf_delocalization(qs_env, almo_scf_env)
1402 CHARACTER(len=*),
PARAMETER :: routinen =
'almo_scf_delocalization'
1404 INTEGER :: handle, ispin, unit_nr
1406 TYPE(
dbcsr_type),
ALLOCATABLE,
DIMENSION(:) :: no_quench
1409 CALL timeset(routinen, handle)
1413 IF (logger%para_env%is_source())
THEN
1424 arbitrary_optimizer%max_iter = 3
1425 arbitrary_optimizer%eps_error = 1.0e-6_dp
1426 arbitrary_optimizer%ndiis = 2
1428 SELECT CASE (almo_scf_env%deloc_method)
1435 ALLOCATE (no_quench(almo_scf_env%nspins))
1437 template=almo_scf_env%matrix_t(1), &
1438 matrix_type=dbcsr_type_no_symmetry)
1441 IF (almo_scf_env%nspins > 1)
THEN
1442 DO ispin = 2, almo_scf_env%nspins
1444 template=almo_scf_env%matrix_t(1), &
1445 matrix_type=dbcsr_type_no_symmetry)
1446 CALL dbcsr_copy(no_quench(ispin), no_quench(1))
1452 SELECT CASE (almo_scf_env%deloc_method)
1455 DO ispin = 1, almo_scf_env%nspins
1456 CALL dbcsr_copy(almo_scf_env%matrix_t(ispin), &
1457 almo_scf_env%matrix_t_blk(ispin))
1466 IF (almo_scf_env%xalmo_update_algorithm ==
almo_scf_pcg)
THEN
1469 almo_scf_env=almo_scf_env, &
1470 optimizer=almo_scf_env%opt_xalmo_pcg, &
1471 quench_t=no_quench, &
1472 matrix_t_in=almo_scf_env%matrix_t_blk, &
1473 matrix_t_out=almo_scf_env%matrix_t, &
1475 perturbation_only=.true., &
1481 almo_scf_env=almo_scf_env, &
1482 optimizer=almo_scf_env%opt_xalmo_trustr, &
1483 quench_t=no_quench, &
1484 matrix_t_in=almo_scf_env%matrix_t_blk, &
1485 matrix_t_out=almo_scf_env%matrix_t, &
1486 perturbation_only=.true., &
1491 cpabort(
"Other algorithms do not exist")
1497 IF (almo_scf_env%xalmo_update_algorithm ==
almo_scf_diag)
THEN
1499 almo_scf_env%perturbative_delocalization = .true.
1500 DO ispin = 1, almo_scf_env%nspins
1501 CALL dbcsr_copy(almo_scf_env%matrix_t(ispin), &
1502 almo_scf_env%matrix_t_blk(ispin))
1505 arbitrary_optimizer)
1509 cpabort(
"Other algorithms do not exist")
1515 IF (almo_scf_env%xalmo_update_algorithm ==
almo_scf_pcg)
THEN
1518 almo_scf_env=almo_scf_env, &
1519 optimizer=almo_scf_env%opt_xalmo_pcg, &
1520 quench_t=almo_scf_env%quench_t, &
1521 matrix_t_in=almo_scf_env%matrix_t_blk, &
1522 matrix_t_out=almo_scf_env%matrix_t, &
1524 perturbation_only=.true., &
1530 almo_scf_env=almo_scf_env, &
1531 optimizer=almo_scf_env%opt_xalmo_trustr, &
1532 quench_t=almo_scf_env%quench_t, &
1533 matrix_t_in=almo_scf_env%matrix_t_blk, &
1534 matrix_t_out=almo_scf_env%matrix_t, &
1535 perturbation_only=.true., &
1540 cpabort(
"Other algorithms do not exist")
1546 IF (almo_scf_env%xalmo_update_algorithm ==
almo_scf_diag)
THEN
1548 cpabort(
"Should not be here: convergence will fail!")
1550 almo_scf_env%perturbative_delocalization = .false.
1551 DO ispin = 1, almo_scf_env%nspins
1552 CALL dbcsr_copy(almo_scf_env%matrix_t(ispin), &
1553 almo_scf_env%matrix_t_blk(ispin))
1556 arbitrary_optimizer)
1558 ELSE IF (almo_scf_env%xalmo_update_algorithm ==
almo_scf_pcg)
THEN
1561 almo_scf_env=almo_scf_env, &
1562 optimizer=almo_scf_env%opt_xalmo_pcg, &
1563 quench_t=almo_scf_env%quench_t, &
1564 matrix_t_in=almo_scf_env%matrix_t_blk, &
1565 matrix_t_out=almo_scf_env%matrix_t, &
1567 perturbation_only=.false., &
1573 almo_scf_env=almo_scf_env, &
1574 optimizer=almo_scf_env%opt_xalmo_trustr, &
1575 quench_t=almo_scf_env%quench_t, &
1576 matrix_t_in=almo_scf_env%matrix_t_blk, &
1577 matrix_t_out=almo_scf_env%matrix_t, &
1578 perturbation_only=.false., &
1583 cpabort(
"Other algorithms do not exist")
1589 cpabort(
"Illegal delocalization method")
1593 SELECT CASE (almo_scf_env%deloc_method)
1596 IF (almo_scf_env%deloc_truncate_virt /=
virt_full)
THEN
1597 cpabort(
"full scf is NYI for truncated virtual space")
1600 IF (almo_scf_env%xalmo_update_algorithm ==
almo_scf_pcg)
THEN
1603 almo_scf_env=almo_scf_env, &
1604 optimizer=almo_scf_env%opt_xalmo_pcg, &
1605 quench_t=no_quench, &
1606 matrix_t_in=almo_scf_env%matrix_t, &
1607 matrix_t_out=almo_scf_env%matrix_t, &
1608 assume_t0_q0x=.false., &
1609 perturbation_only=.false., &
1615 almo_scf_env=almo_scf_env, &
1616 optimizer=almo_scf_env%opt_xalmo_trustr, &
1617 quench_t=no_quench, &
1618 matrix_t_in=almo_scf_env%matrix_t, &
1619 matrix_t_out=almo_scf_env%matrix_t, &
1620 perturbation_only=.false., &
1625 cpabort(
"Other algorithms do not exist")
1632 SELECT CASE (almo_scf_env%deloc_method)
1634 DO ispin = 1, almo_scf_env%nspins
1637 DEALLOCATE (no_quench)
1640 CALL timestop(handle)
1642 END SUBROUTINE almo_scf_delocalization
1652 SUBROUTINE construct_nlmos(qs_env, almo_scf_env)
1659 IF (almo_scf_env%construct_nlmos)
THEN
1661 DO ispin = 1, almo_scf_env%nspins
1664 overlap=almo_scf_env%matrix_sigma(ispin), &
1665 metric=almo_scf_env%matrix_s(1), &
1666 retain_locality=.false., &
1667 only_normalize=.false., &
1668 nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
1669 eps_filter=almo_scf_env%eps_filter, &
1670 order_lanczos=almo_scf_env%order_lanczos, &
1671 eps_lanczos=almo_scf_env%eps_lanczos, &
1672 max_iter_lanczos=almo_scf_env%max_iter_lanczos)
1675 CALL construct_nlmos_wrapper(qs_env, almo_scf_env, virtuals=.false.)
1677 IF (almo_scf_env%opt_nlmo_pcg%opt_penalty%virtual_nlmos)
THEN
1678 CALL construct_virtuals(almo_scf_env)
1679 CALL construct_nlmos_wrapper(qs_env, almo_scf_env, virtuals=.true.)
1682 IF (almo_scf_env%opt_nlmo_pcg%opt_penalty%compactification_filter_start > 0.0_dp)
THEN
1683 CALL nlmo_compactification(qs_env, almo_scf_env, almo_scf_env%matrix_t)
1688 END SUBROUTINE construct_nlmos
1699 SUBROUTINE construct_nlmos_wrapper(qs_env, almo_scf_env, virtuals)
1703 LOGICAL,
INTENT(IN) :: virtuals
1705 REAL(kind=
dp) :: det_diff, prev_determinant
1707 almo_scf_env%overlap_determinant = 1.0_dp
1709 almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength = &
1710 -1.0_dp*almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength
1713 prev_determinant = 10.0_dp
1714 DO WHILE (almo_scf_env%overlap_determinant > almo_scf_env%opt_nlmo_pcg%opt_penalty%final_determinant)
1716 IF (.NOT. virtuals)
THEN
1718 optimizer=almo_scf_env%opt_nlmo_pcg, &
1719 matrix_s=almo_scf_env%matrix_s(1), &
1720 matrix_mo_in=almo_scf_env%matrix_t, &
1721 matrix_mo_out=almo_scf_env%matrix_t, &
1722 template_matrix_sigma=almo_scf_env%matrix_sigma_inv, &
1723 overlap_determinant=almo_scf_env%overlap_determinant, &
1724 mat_distr_aos=almo_scf_env%mat_distr_aos, &
1725 virtuals=virtuals, &
1726 eps_filter=almo_scf_env%eps_filter)
1729 optimizer=almo_scf_env%opt_nlmo_pcg, &
1730 matrix_s=almo_scf_env%matrix_s(1), &
1731 matrix_mo_in=almo_scf_env%matrix_v, &
1732 matrix_mo_out=almo_scf_env%matrix_v, &
1733 template_matrix_sigma=almo_scf_env%matrix_sigma_vv, &
1734 overlap_determinant=almo_scf_env%overlap_determinant, &
1735 mat_distr_aos=almo_scf_env%mat_distr_aos, &
1736 virtuals=virtuals, &
1737 eps_filter=almo_scf_env%eps_filter)
1741 det_diff = prev_determinant - almo_scf_env%overlap_determinant
1742 almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength = &
1743 almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength/ &
1744 abs(almo_scf_env%opt_nlmo_pcg%opt_penalty%penalty_strength_dec_factor)
1746 IF (det_diff < almo_scf_env%opt_nlmo_pcg%opt_penalty%determinant_tolerance)
THEN
1749 prev_determinant = almo_scf_env%overlap_determinant
1753 END SUBROUTINE construct_nlmos_wrapper
1762 SUBROUTINE construct_virtuals(almo_scf_env)
1767 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues
1768 TYPE(
dbcsr_type) :: tempnv1, tempvocc1, tempvocc2, tempvv1, &
1771 DO ispin = 1, almo_scf_env%nspins
1774 template=almo_scf_env%matrix_v(ispin), &
1775 matrix_type=dbcsr_type_no_symmetry)
1777 template=almo_scf_env%matrix_vo(ispin), &
1778 matrix_type=dbcsr_type_no_symmetry)
1780 template=almo_scf_env%matrix_vo(ispin), &
1781 matrix_type=dbcsr_type_no_symmetry)
1783 template=almo_scf_env%matrix_sigma_vv(ispin), &
1784 matrix_type=dbcsr_type_no_symmetry)
1786 template=almo_scf_env%matrix_sigma_vv(ispin), &
1787 matrix_type=dbcsr_type_no_symmetry)
1791 keep_sparsity=.false.)
1795 almo_scf_env%matrix_s(1), &
1796 almo_scf_env%matrix_v(ispin), &
1798 filter_eps=almo_scf_env%eps_filter)
1802 almo_scf_env%matrix_t(ispin), &
1803 0.0_dp, tempvocc1, &
1804 filter_eps=almo_scf_env%eps_filter)
1808 almo_scf_env%matrix_sigma_inv(ispin), &
1809 0.0_dp, tempvocc2, &
1810 filter_eps=almo_scf_env%eps_filter)
1813 almo_scf_env%matrix_t(ispin), &
1816 filter_eps=almo_scf_env%eps_filter)
1818 CALL dbcsr_add(almo_scf_env%matrix_v(ispin), tempnv1, 1.0_dp, -1.0_dp)
1822 almo_scf_env%matrix_s(1), &
1823 almo_scf_env%matrix_v(ispin), &
1825 filter_eps=almo_scf_env%eps_filter)
1828 almo_scf_env%matrix_v(ispin), &
1831 filter_eps=almo_scf_env%eps_filter)
1835 metric=almo_scf_env%matrix_s(1), &
1836 retain_locality=.false., &
1837 only_normalize=.false., &
1838 nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
1839 eps_filter=almo_scf_env%eps_filter, &
1840 order_lanczos=almo_scf_env%order_lanczos, &
1841 eps_lanczos=almo_scf_env%eps_lanczos, &
1842 max_iter_lanczos=almo_scf_env%max_iter_lanczos)
1846 almo_scf_env%matrix_ks(ispin), &
1847 almo_scf_env%matrix_v(ispin), &
1849 filter_eps=almo_scf_env%eps_filter)
1852 almo_scf_env%matrix_v(ispin), &
1855 filter_eps=almo_scf_env%eps_filter)
1858 ALLOCATE (eigenvalues(n))
1861 para_env=almo_scf_env%para_env, &
1862 blacs_env=almo_scf_env%blacs_env)
1863 DEALLOCATE (eigenvalues)
1866 almo_scf_env%matrix_v(ispin), &
1869 filter_eps=almo_scf_env%eps_filter)
1871 CALL dbcsr_copy(almo_scf_env%matrix_v(ispin), tempnv1)
1881 END SUBROUTINE construct_virtuals
1892 SUBROUTINE nlmo_compactification(qs_env, almo_scf_env, matrix)
1896 TYPE(
dbcsr_type),
ALLOCATABLE,
DIMENSION(:), &
1897 INTENT(IN) :: matrix
1899 INTEGER :: iblock_col, iblock_col_size, iblock_row, &
1900 iblock_row_size, icol, irow, ispin, &
1901 ncols, nrows, nspins, unit_nr
1902 LOGICAL :: element_by_element
1903 REAL(kind=
dp) :: energy, eps_local, eps_start, &
1904 max_element, spin_factor
1905 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: occ, retained
1906 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: data_p
1909 TYPE(
dbcsr_type),
ALLOCATABLE,
DIMENSION(:) :: matrix_p_tmp, matrix_t_tmp
1914 IF (logger%para_env%is_source())
THEN
1920 nspins =
SIZE(matrix)
1921 element_by_element = .false.
1923 IF (nspins == 1)
THEN
1924 spin_factor = 2.0_dp
1926 spin_factor = 1.0_dp
1929 ALLOCATE (matrix_t_tmp(nspins))
1930 ALLOCATE (matrix_p_tmp(nspins))
1931 ALLOCATE (retained(nspins))
1934 DO ispin = 1, nspins
1938 template=matrix(ispin), &
1939 matrix_type=dbcsr_type_no_symmetry)
1940 CALL dbcsr_copy(matrix_t_tmp(ispin), matrix(ispin))
1943 template=almo_scf_env%matrix_p(ispin), &
1944 matrix_type=dbcsr_type_no_symmetry)
1945 CALL dbcsr_copy(matrix_p_tmp(ispin), almo_scf_env%matrix_p(ispin))
1949 IF (unit_nr > 0)
THEN
1951 WRITE (unit_nr,
'(T2,A)') &
1952 "Energy dependence on the (block-by-block) filtering of the NLMO coefficients"
1953 IF (unit_nr > 0)
WRITE (unit_nr,
'(T2,A13,A20,A20,A25)') &
1954 "EPS filter",
"Occupation Alpha",
"Occupation Beta",
"Energy"
1957 eps_start = almo_scf_env%opt_nlmo_pcg%opt_penalty%compactification_filter_start
1958 eps_local = max(eps_start, 10e-14_dp)
1962 IF (eps_local > 0.11_dp)
EXIT
1964 DO ispin = 1, nspins
1971 row_size=iblock_row_size, col_size=iblock_col_size)
1972 DO icol = 1, iblock_col_size
1974 IF (element_by_element)
THEN
1976 DO irow = 1, iblock_row_size
1977 IF (abs(data_p(irow, icol)) < eps_local)
THEN
1978 data_p(irow, icol) = 0.0_dp
1980 retained(ispin) = retained(ispin) + 1
1986 max_element = 0.0_dp
1987 DO irow = 1, iblock_row_size
1988 IF (abs(data_p(irow, icol)) > max_element)
THEN
1989 max_element = abs(data_p(irow, icol))
1992 IF (max_element < eps_local)
THEN
1993 DO irow = 1, iblock_row_size
1994 data_p(irow, icol) = 0.0_dp
1997 retained(ispin) = retained(ispin) + iblock_row_size
2009 nfullrows_total=nrows, &
2010 nfullcols_total=ncols)
2011 CALL group%sum(retained(ispin))
2014 occ(ispin) = retained(ispin)/nrows/ncols
2018 t=matrix_t_tmp(ispin), &
2019 p=matrix_p_tmp(ispin), &
2020 eps_filter=almo_scf_env%eps_filter, &
2021 orthog_orbs=.false., &
2022 nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
2023 s=almo_scf_env%matrix_s(1), &
2024 sigma=almo_scf_env%matrix_sigma(ispin), &
2025 sigma_inv=almo_scf_env%matrix_sigma_inv(ispin), &
2026 use_guess=.false., &
2027 algorithm=almo_scf_env%sigma_inv_algorithm, &
2028 inv_eps_factor=almo_scf_env%matrix_iter_eps_error_factor, &
2029 inverse_accelerator=almo_scf_env%order_lanczos, &
2030 eps_lanczos=almo_scf_env%eps_lanczos, &
2031 max_iter_lanczos=almo_scf_env%max_iter_lanczos, &
2032 para_env=almo_scf_env%para_env, &
2033 blacs_env=almo_scf_env%blacs_env)
2036 CALL dbcsr_scale(matrix_p_tmp(ispin), spin_factor)
2043 almo_scf_env%matrix_ks, &
2045 almo_scf_env%eps_filter, &
2046 almo_scf_env%mat_distr_aos)
2048 IF (nspins < 2) occ(2) = occ(1)
2049 IF (unit_nr > 0)
WRITE (unit_nr,
'(T2,E13.3,F20.10,F20.10,F25.15)') &
2050 eps_local, occ(1), occ(2), energy
2052 eps_local = 2.0_dp*eps_local
2056 DO ispin = 1, nspins
2063 DEALLOCATE (matrix_t_tmp)
2064 DEALLOCATE (matrix_p_tmp)
2066 DEALLOCATE (retained)
2068 END SUBROUTINE nlmo_compactification
2079 SUBROUTINE almo_scf_post(qs_env, almo_scf_env)
2083 CHARACTER(len=*),
PARAMETER :: routinen =
'almo_scf_post'
2085 INTEGER :: handle, ispin
2088 TYPE(
dbcsr_type),
ALLOCATABLE,
DIMENSION(:) :: matrix_t_processed
2092 CALL timeset(routinen, handle)
2095 CALL almo_scf_store_extrapolation_data(almo_scf_env)
2098 ALLOCATE (matrix_t_processed(almo_scf_env%nspins))
2101 DO ispin = 1, almo_scf_env%nspins
2104 template=almo_scf_env%matrix_t(ispin), &
2105 matrix_type=dbcsr_type_no_symmetry)
2108 almo_scf_env%matrix_t(ispin))
2110 IF (almo_scf_env%return_orthogonalized_mos)
THEN
2113 overlap=almo_scf_env%matrix_sigma(ispin), &
2114 metric=almo_scf_env%matrix_s(1), &
2115 retain_locality=.false., &
2116 only_normalize=.false., &
2117 nocc_of_domain=almo_scf_env%nocc_of_domain(:, ispin), &
2118 eps_filter=almo_scf_env%eps_filter, &
2119 order_lanczos=almo_scf_env%order_lanczos, &
2120 eps_lanczos=almo_scf_env%eps_lanczos, &
2121 max_iter_lanczos=almo_scf_env%max_iter_lanczos, &
2122 smear=almo_scf_env%smear)
2138 NULLIFY (mos, mo_coeff, scf_env)
2140 CALL get_qs_env(qs_env, mos=mos, scf_env=scf_env)
2142 DO ispin = 1, almo_scf_env%nspins
2146 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff)
2150 DO ispin = 1, almo_scf_env%nspins
2153 DEALLOCATE (matrix_t_processed)
2157 CALL almo_post_scf_compute_properties(qs_env)
2160 IF (almo_scf_env%calc_forces)
THEN
2162 IF (
ASSOCIATED(matrix_w))
THEN
2165 cpabort(
"Matrix W is needed but not associated")
2169 CALL timestop(handle)
2171 END SUBROUTINE almo_scf_post
2181 SUBROUTINE almo_scf_env_create_matrices(almo_scf_env, matrix_s0)
2186 CHARACTER(len=*),
PARAMETER :: routinen =
'almo_scf_env_create_matrices'
2188 INTEGER :: handle, ispin, nspins
2190 CALL timeset(routinen, handle)
2192 nspins = almo_scf_env%nspins
2196 matrix_qs=matrix_s0, &
2197 almo_scf_env=almo_scf_env, &
2200 symmetry_new=dbcsr_type_symmetric, &
2202 init_domains=.false.)
2204 matrix_qs=matrix_s0, &
2205 almo_scf_env=almo_scf_env, &
2208 symmetry_new=dbcsr_type_symmetric, &
2210 init_domains=.true.)
2211 IF (almo_scf_env%almo_update_algorithm ==
almo_scf_diag)
THEN
2213 matrix_qs=matrix_s0, &
2214 almo_scf_env=almo_scf_env, &
2215 name_new=
"S_BLK_SQRT_INV", &
2217 symmetry_new=dbcsr_type_symmetric, &
2219 init_domains=.true.)
2221 matrix_qs=matrix_s0, &
2222 almo_scf_env=almo_scf_env, &
2223 name_new=
"S_BLK_SQRT", &
2225 symmetry_new=dbcsr_type_symmetric, &
2227 init_domains=.true.)
2230 matrix_qs=matrix_s0, &
2231 almo_scf_env=almo_scf_env, &
2232 name_new=
"S_BLK_INV", &
2234 symmetry_new=dbcsr_type_symmetric, &
2236 init_domains=.true.)
2240 ALLOCATE (almo_scf_env%matrix_t_blk(nspins))
2241 ALLOCATE (almo_scf_env%quench_t_blk(nspins))
2242 ALLOCATE (almo_scf_env%matrix_err_blk(nspins))
2243 ALLOCATE (almo_scf_env%matrix_err_xx(nspins))
2244 ALLOCATE (almo_scf_env%matrix_sigma(nspins))
2245 ALLOCATE (almo_scf_env%matrix_sigma_inv(nspins))
2246 ALLOCATE (almo_scf_env%matrix_sigma_sqrt(nspins))
2247 ALLOCATE (almo_scf_env%matrix_sigma_sqrt_inv(nspins))
2248 ALLOCATE (almo_scf_env%matrix_sigma_blk(nspins))
2249 ALLOCATE (almo_scf_env%matrix_sigma_inv_0deloc(nspins))
2250 ALLOCATE (almo_scf_env%matrix_t(nspins))
2251 ALLOCATE (almo_scf_env%matrix_t_tr(nspins))
2252 DO ispin = 1, nspins
2255 matrix_qs=matrix_s0, &
2256 almo_scf_env=almo_scf_env, &
2259 symmetry_new=dbcsr_type_no_symmetry, &
2261 init_domains=.true.)
2264 matrix_qs=matrix_s0, &
2265 almo_scf_env=almo_scf_env, &
2268 symmetry_new=dbcsr_type_no_symmetry, &
2270 init_domains=.true.)
2273 matrix_qs=matrix_s0, &
2274 almo_scf_env=almo_scf_env, &
2275 name_new=
"ERR_BLK", &
2277 symmetry_new=dbcsr_type_no_symmetry, &
2279 init_domains=.true.)
2282 matrix_qs=matrix_s0, &
2283 almo_scf_env=almo_scf_env, &
2284 name_new=
"ERR_XX", &
2286 symmetry_new=dbcsr_type_no_symmetry, &
2288 init_domains=.false.)
2292 matrix_qs=matrix_s0, &
2293 almo_scf_env=almo_scf_env, &
2296 symmetry_new=dbcsr_type_no_symmetry, &
2298 init_domains=.false.)
2301 matrix_qs=matrix_s0, &
2302 almo_scf_env=almo_scf_env, &
2305 symmetry_new=dbcsr_type_symmetric, &
2307 init_domains=.false.)
2310 matrix_qs=matrix_s0, &
2311 almo_scf_env=almo_scf_env, &
2312 name_new=
"SIG_BLK", &
2314 symmetry_new=dbcsr_type_symmetric, &
2316 init_domains=.true.)
2319 matrix_qs=matrix_s0, &
2320 almo_scf_env=almo_scf_env, &
2321 name_new=
"SIGINV_BLK", &
2323 symmetry_new=dbcsr_type_symmetric, &
2325 init_domains=.true.)
2328 matrix_new=almo_scf_env%matrix_sigma_inv(ispin), &
2329 matrix_qs=matrix_s0, &
2330 almo_scf_env=almo_scf_env, &
2331 name_new=
"SIGINV", &
2333 symmetry_new=dbcsr_type_symmetric, &
2335 init_domains=.false.)
2338 matrix_new=almo_scf_env%matrix_t(ispin), &
2339 matrix_qs=matrix_s0, &
2340 almo_scf_env=almo_scf_env, &
2343 symmetry_new=dbcsr_type_no_symmetry, &
2345 init_domains=.false.)
2346 CALL dbcsr_create(almo_scf_env%matrix_sigma_sqrt(ispin), &
2347 template=almo_scf_env%matrix_sigma(ispin), &
2348 matrix_type=dbcsr_type_no_symmetry)
2349 CALL dbcsr_create(almo_scf_env%matrix_sigma_sqrt_inv(ispin), &
2350 template=almo_scf_env%matrix_sigma(ispin), &
2351 matrix_type=dbcsr_type_no_symmetry)
2355 IF (almo_scf_env%need_virtuals)
THEN
2356 ALLOCATE (almo_scf_env%matrix_v_blk(nspins))
2357 ALLOCATE (almo_scf_env%matrix_v_full_blk(nspins))
2358 ALLOCATE (almo_scf_env%matrix_v(nspins))
2359 ALLOCATE (almo_scf_env%matrix_vo(nspins))
2360 ALLOCATE (almo_scf_env%matrix_x(nspins))
2361 ALLOCATE (almo_scf_env%matrix_ov(nspins))
2362 ALLOCATE (almo_scf_env%matrix_ov_full(nspins))
2363 ALLOCATE (almo_scf_env%matrix_sigma_vv(nspins))
2364 ALLOCATE (almo_scf_env%matrix_sigma_vv_blk(nspins))
2365 ALLOCATE (almo_scf_env%matrix_sigma_vv_sqrt(nspins))
2366 ALLOCATE (almo_scf_env%matrix_sigma_vv_sqrt_inv(nspins))
2367 ALLOCATE (almo_scf_env%matrix_vv_full_blk(nspins))
2369 IF (almo_scf_env%deloc_truncate_virt /=
virt_full)
THEN
2370 ALLOCATE (almo_scf_env%matrix_k_blk(nspins))
2371 ALLOCATE (almo_scf_env%matrix_k_blk_ones(nspins))
2372 ALLOCATE (almo_scf_env%matrix_k_tr(nspins))
2373 ALLOCATE (almo_scf_env%matrix_v_disc(nspins))
2374 ALLOCATE (almo_scf_env%matrix_v_disc_blk(nspins))
2375 ALLOCATE (almo_scf_env%matrix_ov_disc(nspins))
2376 ALLOCATE (almo_scf_env%matrix_vv_disc_blk(nspins))
2377 ALLOCATE (almo_scf_env%matrix_vv_disc(nspins))
2378 ALLOCATE (almo_scf_env%opt_k_t_dd(nspins))
2379 ALLOCATE (almo_scf_env%opt_k_t_rr(nspins))
2380 ALLOCATE (almo_scf_env%opt_k_denom(nspins))
2383 DO ispin = 1, nspins
2385 matrix_qs=matrix_s0, &
2386 almo_scf_env=almo_scf_env, &
2387 name_new=
"V_FULL_BLK", &
2389 symmetry_new=dbcsr_type_no_symmetry, &
2391 init_domains=.false.)
2393 matrix_qs=matrix_s0, &
2394 almo_scf_env=almo_scf_env, &
2397 symmetry_new=dbcsr_type_no_symmetry, &
2399 init_domains=.false.)
2401 matrix_qs=matrix_s0, &
2402 almo_scf_env=almo_scf_env, &
2405 symmetry_new=dbcsr_type_no_symmetry, &
2407 init_domains=.false.)
2409 matrix_qs=matrix_s0, &
2410 almo_scf_env=almo_scf_env, &
2411 name_new=
"OV_FULL", &
2413 symmetry_new=dbcsr_type_no_symmetry, &
2415 init_domains=.false.)
2417 matrix_qs=matrix_s0, &
2418 almo_scf_env=almo_scf_env, &
2421 symmetry_new=dbcsr_type_no_symmetry, &
2423 init_domains=.false.)
2425 matrix_qs=matrix_s0, &
2426 almo_scf_env=almo_scf_env, &
2429 symmetry_new=dbcsr_type_no_symmetry, &
2431 init_domains=.false.)
2433 matrix_qs=matrix_s0, &
2434 almo_scf_env=almo_scf_env, &
2437 symmetry_new=dbcsr_type_no_symmetry, &
2439 init_domains=.false.)
2441 matrix_qs=matrix_s0, &
2442 almo_scf_env=almo_scf_env, &
2443 name_new=
"SIG_VV", &
2445 symmetry_new=dbcsr_type_symmetric, &
2447 init_domains=.false.)
2449 matrix_qs=matrix_s0, &
2450 almo_scf_env=almo_scf_env, &
2451 name_new=
"VV_FULL_BLK", &
2453 symmetry_new=dbcsr_type_no_symmetry, &
2455 init_domains=.true.)
2457 matrix_qs=matrix_s0, &
2458 almo_scf_env=almo_scf_env, &
2459 name_new=
"SIG_VV_BLK", &
2461 symmetry_new=dbcsr_type_symmetric, &
2463 init_domains=.true.)
2464 CALL dbcsr_create(almo_scf_env%matrix_sigma_vv_sqrt(ispin), &
2465 template=almo_scf_env%matrix_sigma_vv(ispin), &
2466 matrix_type=dbcsr_type_no_symmetry)
2467 CALL dbcsr_create(almo_scf_env%matrix_sigma_vv_sqrt_inv(ispin), &
2468 template=almo_scf_env%matrix_sigma_vv(ispin), &
2469 matrix_type=dbcsr_type_no_symmetry)
2471 IF (almo_scf_env%deloc_truncate_virt /=
virt_full)
THEN
2473 matrix_qs=matrix_s0, &
2474 almo_scf_env=almo_scf_env, &
2475 name_new=
"OPT_K_U_RR", &
2477 symmetry_new=dbcsr_type_no_symmetry, &
2479 init_domains=.false.)
2481 matrix_qs=matrix_s0, &
2482 almo_scf_env=almo_scf_env, &
2483 name_new=
"VV_DISC", &
2485 symmetry_new=dbcsr_type_symmetric, &
2487 init_domains=.false.)
2489 matrix_qs=matrix_s0, &
2490 almo_scf_env=almo_scf_env, &
2491 name_new=
"OPT_K_U_DD", &
2493 symmetry_new=dbcsr_type_no_symmetry, &
2495 init_domains=.false.)
2497 matrix_qs=matrix_s0, &
2498 almo_scf_env=almo_scf_env, &
2499 name_new=
"VV_DISC_BLK", &
2501 symmetry_new=dbcsr_type_symmetric, &
2503 init_domains=.true.)
2505 matrix_qs=matrix_s0, &
2506 almo_scf_env=almo_scf_env, &
2509 symmetry_new=dbcsr_type_no_symmetry, &
2511 init_domains=.true.)
2513 matrix_qs=matrix_s0, &
2514 almo_scf_env=almo_scf_env, &
2515 name_new=
"K_BLK_1", &
2517 symmetry_new=dbcsr_type_no_symmetry, &
2519 init_domains=.true.)
2521 matrix_qs=matrix_s0, &
2522 almo_scf_env=almo_scf_env, &
2523 name_new=
"OPT_K_DENOM", &
2525 symmetry_new=dbcsr_type_no_symmetry, &
2527 init_domains=.false.)
2529 matrix_qs=matrix_s0, &
2530 almo_scf_env=almo_scf_env, &
2533 symmetry_new=dbcsr_type_no_symmetry, &
2535 init_domains=.false.)
2537 matrix_qs=matrix_s0, &
2538 almo_scf_env=almo_scf_env, &
2539 name_new=
"V_DISC_BLK", &
2541 symmetry_new=dbcsr_type_no_symmetry, &
2543 init_domains=.false.)
2545 matrix_qs=matrix_s0, &
2546 almo_scf_env=almo_scf_env, &
2547 name_new=
"V_DISC", &
2549 symmetry_new=dbcsr_type_no_symmetry, &
2551 init_domains=.false.)
2553 matrix_qs=matrix_s0, &
2554 almo_scf_env=almo_scf_env, &
2555 name_new=
"OV_DISC", &
2557 symmetry_new=dbcsr_type_no_symmetry, &
2559 init_domains=.false.)
2567 IF (almo_scf_env%need_orbital_energies)
THEN
2568 ALLOCATE (almo_scf_env%matrix_eoo(nspins))
2569 ALLOCATE (almo_scf_env%matrix_evv_full(nspins))
2570 DO ispin = 1, nspins
2572 matrix_qs=matrix_s0, &
2573 almo_scf_env=almo_scf_env, &
2576 symmetry_new=dbcsr_type_no_symmetry, &
2578 init_domains=.false.)
2580 matrix_qs=matrix_s0, &
2581 almo_scf_env=almo_scf_env, &
2582 name_new=
"E_VIRT", &
2584 symmetry_new=dbcsr_type_no_symmetry, &
2586 init_domains=.false.)
2591 ALLOCATE (almo_scf_env%matrix_p(nspins))
2592 ALLOCATE (almo_scf_env%matrix_p_blk(nspins))
2593 ALLOCATE (almo_scf_env%matrix_ks(nspins))
2594 ALLOCATE (almo_scf_env%matrix_ks_blk(nspins))
2595 IF (almo_scf_env%need_previous_ks)
THEN
2596 ALLOCATE (almo_scf_env%matrix_ks_0deloc(nspins))
2598 DO ispin = 1, nspins
2601 template=almo_scf_env%matrix_s(1), &
2602 matrix_type=dbcsr_type_symmetric)
2604 template=almo_scf_env%matrix_s(1), &
2605 matrix_type=dbcsr_type_symmetric)
2606 IF (almo_scf_env%need_previous_ks)
THEN
2607 CALL dbcsr_create(almo_scf_env%matrix_ks_0deloc(ispin), &
2608 template=almo_scf_env%matrix_s(1), &
2609 matrix_type=dbcsr_type_symmetric)
2612 matrix_qs=matrix_s0, &
2613 almo_scf_env=almo_scf_env, &
2616 symmetry_new=dbcsr_type_symmetric, &
2618 init_domains=.true.)
2620 matrix_qs=matrix_s0, &
2621 almo_scf_env=almo_scf_env, &
2622 name_new=
"KS_BLK", &
2624 symmetry_new=dbcsr_type_symmetric, &
2626 init_domains=.true.)
2629 CALL timestop(handle)
2631 END SUBROUTINE almo_scf_env_create_matrices
2641 SUBROUTINE almo_scf_clean_up(almo_scf_env)
2645 CHARACTER(len=*),
PARAMETER :: routinen =
'almo_scf_clean_up'
2647 INTEGER :: handle, ispin, unit_nr
2650 CALL timeset(routinen, handle)
2654 IF (logger%para_env%is_source())
THEN
2663 IF (almo_scf_env%almo_update_algorithm ==
almo_scf_diag)
THEN
2669 DO ispin = 1, almo_scf_env%nspins
2678 CALL dbcsr_release(almo_scf_env%matrix_sigma_inv_0deloc(ispin))
2682 CALL dbcsr_release(almo_scf_env%matrix_sigma_sqrt_inv(ispin))
2687 IF (almo_scf_env%need_previous_ks)
THEN
2690 IF (almo_scf_env%need_virtuals)
THEN
2700 CALL dbcsr_release(almo_scf_env%matrix_sigma_vv_sqrt(ispin))
2701 CALL dbcsr_release(almo_scf_env%matrix_sigma_vv_sqrt_inv(ispin))
2703 IF (almo_scf_env%deloc_truncate_virt /=
virt_full)
THEN
2717 IF (almo_scf_env%need_orbital_energies)
THEN
2724 DEALLOCATE (almo_scf_env%matrix_p)
2725 DEALLOCATE (almo_scf_env%matrix_p_blk)
2726 DEALLOCATE (almo_scf_env%matrix_ks)
2727 DEALLOCATE (almo_scf_env%matrix_ks_blk)
2728 DEALLOCATE (almo_scf_env%matrix_t_blk)
2729 DEALLOCATE (almo_scf_env%matrix_err_blk)
2730 DEALLOCATE (almo_scf_env%matrix_err_xx)
2731 DEALLOCATE (almo_scf_env%matrix_t)
2732 DEALLOCATE (almo_scf_env%matrix_t_tr)
2733 DEALLOCATE (almo_scf_env%matrix_sigma)
2734 DEALLOCATE (almo_scf_env%matrix_sigma_blk)
2735 DEALLOCATE (almo_scf_env%matrix_sigma_inv_0deloc)
2736 DEALLOCATE (almo_scf_env%matrix_sigma_sqrt)
2737 DEALLOCATE (almo_scf_env%matrix_sigma_sqrt_inv)
2738 DEALLOCATE (almo_scf_env%matrix_sigma_inv)
2739 DEALLOCATE (almo_scf_env%quench_t)
2740 DEALLOCATE (almo_scf_env%quench_t_blk)
2741 IF (almo_scf_env%need_virtuals)
THEN
2742 DEALLOCATE (almo_scf_env%matrix_v_blk)
2743 DEALLOCATE (almo_scf_env%matrix_v_full_blk)
2744 DEALLOCATE (almo_scf_env%matrix_v)
2745 DEALLOCATE (almo_scf_env%matrix_vo)
2746 DEALLOCATE (almo_scf_env%matrix_x)
2747 DEALLOCATE (almo_scf_env%matrix_ov)
2748 DEALLOCATE (almo_scf_env%matrix_ov_full)
2749 DEALLOCATE (almo_scf_env%matrix_sigma_vv)
2750 DEALLOCATE (almo_scf_env%matrix_sigma_vv_blk)
2751 DEALLOCATE (almo_scf_env%matrix_sigma_vv_sqrt)
2752 DEALLOCATE (almo_scf_env%matrix_sigma_vv_sqrt_inv)
2753 DEALLOCATE (almo_scf_env%matrix_vv_full_blk)
2754 IF (almo_scf_env%deloc_truncate_virt /=
virt_full)
THEN
2755 DEALLOCATE (almo_scf_env%matrix_k_tr)
2756 DEALLOCATE (almo_scf_env%matrix_k_blk)
2757 DEALLOCATE (almo_scf_env%matrix_v_disc)
2758 DEALLOCATE (almo_scf_env%matrix_v_disc_blk)
2759 DEALLOCATE (almo_scf_env%matrix_ov_disc)
2760 DEALLOCATE (almo_scf_env%matrix_vv_disc_blk)
2761 DEALLOCATE (almo_scf_env%matrix_vv_disc)
2762 DEALLOCATE (almo_scf_env%matrix_k_blk_ones)
2763 DEALLOCATE (almo_scf_env%opt_k_t_dd)
2764 DEALLOCATE (almo_scf_env%opt_k_t_rr)
2765 DEALLOCATE (almo_scf_env%opt_k_denom)
2768 IF (almo_scf_env%need_previous_ks)
THEN
2769 DEALLOCATE (almo_scf_env%matrix_ks_0deloc)
2771 IF (almo_scf_env%need_orbital_energies)
THEN
2772 DEALLOCATE (almo_scf_env%matrix_eoo)
2773 DEALLOCATE (almo_scf_env%matrix_evv_full)
2777 DO ispin = 1, almo_scf_env%nspins
2779 almo_scf_env%domain_preconditioner(:, ispin))
2788 DEALLOCATE (almo_scf_env%domain_preconditioner)
2789 DEALLOCATE (almo_scf_env%domain_s_inv)
2790 DEALLOCATE (almo_scf_env%domain_s_sqrt_inv)
2791 DEALLOCATE (almo_scf_env%domain_s_sqrt)
2792 DEALLOCATE (almo_scf_env%domain_ks_xx)
2793 DEALLOCATE (almo_scf_env%domain_t)
2794 DEALLOCATE (almo_scf_env%domain_err)
2795 DEALLOCATE (almo_scf_env%domain_r_down_up)
2796 DO ispin = 1, almo_scf_env%nspins
2797 DEALLOCATE (almo_scf_env%domain_map(ispin)%pairs)
2798 DEALLOCATE (almo_scf_env%domain_map(ispin)%index1)
2800 DEALLOCATE (almo_scf_env%domain_map)
2801 DEALLOCATE (almo_scf_env%domain_index_of_ao)
2802 DEALLOCATE (almo_scf_env%domain_index_of_atom)
2803 DEALLOCATE (almo_scf_env%first_atom_of_domain)
2804 DEALLOCATE (almo_scf_env%last_atom_of_domain)
2805 DEALLOCATE (almo_scf_env%nbasis_of_domain)
2806 IF (
ALLOCATED(almo_scf_env%nocc_of_domain))
THEN
2807 DEALLOCATE (almo_scf_env%nocc_of_domain)
2809 DEALLOCATE (almo_scf_env%real_ne_of_domain)
2810 DEALLOCATE (almo_scf_env%nvirt_full_of_domain)
2811 DEALLOCATE (almo_scf_env%nvirt_of_domain)
2812 DEALLOCATE (almo_scf_env%nvirt_disc_of_domain)
2813 DEALLOCATE (almo_scf_env%mu_of_domain)
2814 DEALLOCATE (almo_scf_env%cpu_of_domain)
2815 DEALLOCATE (almo_scf_env%charge_of_domain)
2816 DEALLOCATE (almo_scf_env%multiplicity_of_domain)
2817 DEALLOCATE (almo_scf_env%activate)
2818 IF (almo_scf_env%smear)
THEN
2819 DEALLOCATE (almo_scf_env%mo_energies)
2820 DEALLOCATE (almo_scf_env%kTS)
2823 DEALLOCATE (almo_scf_env%domain_index_of_ao_block)
2824 DEALLOCATE (almo_scf_env%domain_index_of_mo_block)
2829 CALL timestop(handle)
2831 END SUBROUTINE almo_scf_clean_up
2842 SUBROUTINE almo_post_scf_compute_properties(qs_env)
2847 END SUBROUTINE almo_post_scf_compute_properties
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.
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.
subroutine, public almo_entry_scf(qs_env, calc_forces)
The entry point into ALMO SCF routines.
Define the atomic kind types and their sub types.
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public scheiber2018
integer, save, public kuhne2007
integer, save, public staub2019
integer, save, public khaliullin2013
integer, save, public rullan2026
integer, save, public kolafa2004
methods related to the blacs parallel environment
subroutine, public cp_blacs_env_release(blacs_env)
releases the given blacs_env
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_scale(matrix, alpha_scalar)
...
logical function, public dbcsr_iterator_blocks_left(iterator)
...
subroutine, public dbcsr_iterator_stop(iterator)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_multiply(transa, transb, alpha, matrix_a, matrix_b, beta, matrix_c, first_row, last_row, first_column, last_column, first_k, last_k, retain_sparsity, filter_eps, flop)
...
subroutine, public dbcsr_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...
subroutine, public dbcsr_work_create(matrix, nblks_guess, sizedata_guess, n, work_mutable)
...
subroutine, public dbcsr_iterator_next_block(iterator, row, column, block, block_number_argument_has_been_removed, row_size, col_size, row_offset, col_offset, transposed)
...
subroutine, public dbcsr_filter(matrix, eps)
...
subroutine, public dbcsr_finalize(matrix)
...
subroutine, public dbcsr_iterator_start(iterator, matrix, shared, dynamic, dynamic_byrows)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_binary_read(filepath, distribution, matrix_new)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
real(kind=dp) function, public dbcsr_checksum(matrix, pos)
Calculates the checksum of a DBCSR matrix.
subroutine, public dbcsr_add_on_diag(matrix, alpha)
Adds the given scalar to the diagonal of the matrix. Reserves any missing diagonal blocks.
subroutine, public dbcsr_reserve_all_blocks(matrix)
Reserves all blocks.
subroutine, public dbcsr_init_random(matrix, keep_sparsity)
Fills the given matrix with random numbers.
Interface to (sca)lapack for the Cholesky based procedures.
subroutine, public cp_dbcsr_syevd(matrix, eigenvectors, eigenvalues, para_env, blacs_env)
...
DBCSR operations in CP2K.
subroutine, public copy_dbcsr_to_fm(matrix, fm, plan)
Copy a DBCSR matrix to a BLACS matrix.
represent a full matrix distributed on many processors
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.
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.
integer, parameter, public dp
integer, parameter, public default_path_length
Collection of simple mathematical functions and subroutines.
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.
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.
subroutine, public get_matrix_from_submatrices(mscfg_env, matrix_out, iset)
Creates a distributed matrix from MOs on fragments.
Define the data structure for the particle information.
Routine to return block diagonal density matrix. Blocks correspond to the atomic densities.
subroutine, public calculate_atomic_block_dm(pmatrix, matrix_s, atomic_kind_set, qs_kind_set, nspin, nelectron_spin, ounit, para_env)
returns a block diagonal density matrix. Blocks correspond to the atomic densities.
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, matrix_vhxc, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Routines to somehow generate an initial guess.
subroutine, public calculate_mopac_dm(pmat, matrix_s, has_unit_metric, dft_control, particle_set, atomic_kind_set, qs_kind_set, nspin, nelectron_spin, para_env)
returns a block diagonal density matrix. Blocks correspond to the mopac initial guess.
Define the quickstep kind type and their sub types.
Definition and initialisation of the mo data type.
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kts, mu, flexible_electron_count, cmo_coeff)
Get the components of a MO set data structure.
superstucture that hold various representations of the density and keeps track of which ones are vali...
subroutine, public qs_rho_get(rho_struct, rho_ao, rho_ao_im, rho_ao_kp, rho_ao_im_kp, rho_r, drho_r, rho_g, drho_g, tau_r, tau_g, rho_r_valid, drho_r_valid, rho_g_valid, drho_g_valid, tau_r_valid, tau_g_valid, tot_rho_r, tot_rho_g, rho_r_sccs, soft_valid, complex_rho_ao)
returns info about the density described by this object. If some representation is not available an e...
Utility routines for qs_scf.
subroutine, public qs_scf_compute_properties(qs_env, wf_type, do_mp2)
computes properties for a given hamilonian using the current wfn
module that contains the definitions of the scf types
Provides all information about an atomic kind.
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.