133#include "./base/base_uses.f90"
138 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'negf_methods'
139 LOGICAL,
PARAMETER,
PRIVATE :: debug_this_module = .true.
148 TYPE integration_status_type
149 INTEGER :: npoints = -1
150 REAL(kind=
dp) :: error = -1.0_dp
151 END TYPE integration_status_type
165 CHARACTER(LEN=*),
PARAMETER :: routinen =
'do_negf'
167 CHARACTER(len=default_string_length) :: contact_id_str, filename
168 INTEGER :: handle, icontact, ispin, log_unit, &
169 ncontacts, npoints, nspins, &
170 print_level, print_unit
171 LOGICAL :: debug_output, exist, should_output, &
173 REAL(kind=
dp) :: energy_max, energy_min
174 REAL(kind=
dp),
DIMENSION(2) :: current
187 negf_mixing_section, negf_section, &
188 print_section, root_section
190 CALL timeset(routinen, handle)
197 NULLIFY (blacs_env, cp_subsys, global_env, qs_env, root_section, sub_force_env)
198 CALL force_env_get(force_env, globenv=global_env, qs_env=qs_env, root_section=root_section, &
199 sub_force_env=sub_force_env, subsys=cp_subsys)
201 CALL get_qs_env(qs_env, blacs_env=blacs_env, para_env=para_env_global)
207 NULLIFY (negf_control)
210 CALL get_qs_env(qs_env, dft_control=dft_control)
213 log_unit =
cp_print_key_unit_nr(logger, negf_section,
"PRINT%PROGRAM_RUN_INFO", extension=
".Log")
215 IF (log_unit > 0)
THEN
216 WRITE (log_unit,
'(/,T2,79("-"))')
217 WRITE (log_unit,
'(T27,A,T62)')
"NEGF calculation is started"
218 WRITE (log_unit,
'(T2,79("-"))')
223 CALL section_vals_val_get(negf_section,
"PRINT%PROGRAM_RUN_INFO%PRINT_LEVEL", i_val=print_level)
224 SELECT CASE (print_level)
226 verbose_output = .true.
228 verbose_output = .true.
229 debug_output = .true.
231 verbose_output = .false.
232 debug_output = .false.
235 IF (log_unit > 0)
THEN
236 WRITE (log_unit,
"(/,' THE RELEVANT HAMILTONIAN AND OVERLAP MATRICES FROM DFT')")
237 WRITE (log_unit,
"( ' ------------------------------------------------------')")
240 CALL negf_sub_env_create(sub_env, negf_control, blacs_env, global_env%blacs_grid_layout, global_env%blacs_repeatable)
241 CALL negf_env_create(negf_env, sub_env, negf_control, force_env, negf_mixing_section, log_unit)
243 filename = trim(logger%iter_info%project_name)//
'-negf.restart'
244 INQUIRE (file=filename, exist=exist)
245 IF (exist)
CALL negf_read_restart(filename, negf_env, negf_control)
247 IF (log_unit > 0)
THEN
248 WRITE (log_unit,
"(/,' NEGF| The initial Hamiltonian and Overlap matrices are calculated.')")
251 CALL negf_output_initial(log_unit, negf_env, sub_env, negf_control, dft_control, verbose_output, debug_output)
258 ncontacts =
SIZE(negf_control%contacts)
259 DO icontact = 1, ncontacts
261 IF (negf_control%contacts(icontact)%force_env_index > 0)
THEN
262 CALL force_env_get(sub_force_env(negf_control%contacts(icontact)%force_env_index)%force_env, qs_env=qs_env)
267 CALL guess_fermi_level(icontact, negf_env, negf_control, sub_env, qs_env, log_unit)
272 IF (should_output)
THEN
280 middle_name=trim(adjustl(contact_id_str)), &
281 file_status=
"REPLACE")
282 CALL negf_print_dos(print_unit, energy_min, energy_max, npoints, &
283 v_shift=0.0_dp, negf_env=negf_env, negf_control=negf_control, &
284 sub_env=sub_env, base_contact=icontact, just_contact=icontact)
292 IF (ncontacts > 1)
THEN
297 CALL shift_potential(negf_env, negf_control, sub_env, qs_env, base_contact=1, log_unit=log_unit)
301 CALL converge_density(negf_env, negf_control, sub_env, negf_section, qs_env, negf_control%v_shift, &
302 base_contact=1, log_unit=log_unit)
307 IF (para_env_global%is_source() .AND. negf_control%write_common_restart_file) &
308 CALL negf_write_restart(filename, negf_env, negf_control)
312 CALL get_qs_env(qs_env, dft_control=dft_control)
314 nspins = dft_control%nspins
316 cpassert(nspins <= 2)
322 current(ispin) = negf_compute_current(contact_id1=1, contact_id2=2, &
323 v_shift=negf_control%v_shift, &
325 negf_control=negf_control, &
328 blacs_env_global=blacs_env)
331 IF (log_unit > 0)
THEN
333 WRITE (log_unit,
'(/,T2,A,T60,ES20.7E2)')
"NEGF| Alpha-spin electric current (A)", current(1)
334 WRITE (log_unit,
'(T2,A,T60,ES20.7E2)')
"NEGF| Beta-spin electric current (A)", current(2)
336 WRITE (log_unit,
'(/,T2,A,T60,ES20.7E2)')
"NEGF| Electric current (A)", 2.0_dp*current(1)
345 IF (should_output)
THEN
353 middle_name=trim(adjustl(contact_id_str)), &
354 file_status=
"REPLACE")
356 CALL negf_print_dos(print_unit, energy_min, energy_max, npoints, negf_control%v_shift, &
357 negf_env=negf_env, negf_control=negf_control, &
358 sub_env=sub_env, base_contact=1)
367 IF (should_output)
THEN
374 extension=
".transm", &
375 middle_name=trim(adjustl(contact_id_str)), &
376 file_status=
"REPLACE")
378 CALL negf_print_transmission(print_unit, energy_min, energy_max, npoints, negf_control%v_shift, &
379 negf_env=negf_env, negf_control=negf_control, &
380 sub_env=sub_env, contact_id1=1, contact_id2=2)
387 IF (log_unit > 0)
THEN
388 WRITE (log_unit,
'(/,T2,79("-"))')
389 WRITE (log_unit,
'(T27,A,T62)')
"NEGF calculation is finished"
390 WRITE (log_unit,
'(T2,79("-"))')
396 CALL timestop(handle)
411 SUBROUTINE guess_fermi_level(contact_id, negf_env, negf_control, sub_env, qs_env, log_unit)
412 INTEGER,
INTENT(in) :: contact_id
417 INTEGER,
INTENT(in) :: log_unit
419 CHARACTER(LEN=*),
PARAMETER :: routinen =
'guess_fermi_level'
422 CHARACTER(len=default_string_length) :: temperature_str
423 COMPLEX(kind=dp) :: lbound_cpath, lbound_lpath, ubound_lpath
424 INTEGER :: direction_axis_abs, handle, image, &
425 ispin, nao, nimages, nspins, step
426 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: index_to_cell
427 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index
428 LOGICAL :: do_kpoints
429 REAL(kind=
dp) :: delta_au, delta_ef, energy_ubound_minus_fermi, fermi_level_guess, &
430 fermi_level_max, fermi_level_min, nelectrons_guess, nelectrons_max, nelectrons_min, &
431 nelectrons_qs_cell0, nelectrons_qs_cell1, offset_au, rscale, t1, t2, trace
436 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_s_kp, rho_ao_qs_kp
439 TYPE(integration_status_type) :: stats
446 CALL timeset(routinen, handle)
448 IF (log_unit > 0)
THEN
449 WRITE (temperature_str,
'(F11.3)') negf_control%contacts(contact_id)%temperature*
kelvin
450 WRITE (log_unit,
'(/,T2,A,I3)')
"FERMI LEVEL OF CONTACT ", contact_id
451 WRITE (log_unit,
"( ' --------------------------')")
452 WRITE (log_unit,
'(A)')
" Temperature "//trim(adjustl(temperature_str))//
" Kelvin"
455 IF (.NOT. negf_control%contacts(contact_id)%is_restart)
THEN
458 blacs_env=blacs_env_global, &
459 dft_control=dft_control, &
460 do_kpoints=do_kpoints, &
462 matrix_s_kp=matrix_s_kp, &
463 para_env=para_env_global, &
464 rho=rho_struct, subsys=subsys)
465 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_qs_kp)
467 nimages = dft_control%nimages
468 nspins = dft_control%nspins
469 direction_axis_abs = abs(negf_env%contacts(contact_id)%direction_axis)
471 cpassert(
SIZE(negf_env%contacts(contact_id)%h_00) == nspins)
473 IF (sub_env%ngroups > 1)
THEN
474 NULLIFY (matrix_s_fm, fm_struct)
476 CALL cp_fm_get_info(negf_env%contacts(contact_id)%s_00, nrow_global=nao)
477 CALL cp_fm_struct_create(fm_struct, nrow_global=nao, ncol_global=nao, context=blacs_env_global)
480 ALLOCATE (matrix_s_fm)
484 IF (sub_env%group_distribution(sub_env%mepos_global) == 0)
THEN
485 CALL cp_fm_copy_general(negf_env%contacts(contact_id)%s_00, matrix_s_fm, para_env_global)
490 matrix_s_fm => negf_env%contacts(contact_id)%s_00
498 ALLOCATE (cell_to_index(0:0, 0:0, 0:0))
499 cell_to_index(0, 0, 0) = 1
502 ALLOCATE (index_to_cell(3, nimages))
504 IF (.NOT. do_kpoints)
DEALLOCATE (cell_to_index)
506 IF (nspins == 1)
THEN
514 nelectrons_qs_cell0 = 0.0_dp
515 nelectrons_qs_cell1 = 0.0_dp
516 IF (negf_control%contacts(contact_id)%force_env_index > 0)
THEN
517 DO image = 1, nimages
518 IF (index_to_cell(direction_axis_abs, image) == 0)
THEN
520 CALL dbcsr_dot(rho_ao_qs_kp(ispin, image)%matrix, matrix_s_kp(1, image)%matrix, trace)
521 nelectrons_qs_cell0 = nelectrons_qs_cell0 + trace
523 ELSE IF (abs(index_to_cell(direction_axis_abs, image)) == 1)
THEN
525 CALL dbcsr_dot(rho_ao_qs_kp(ispin, image)%matrix, matrix_s_kp(1, image)%matrix, trace)
526 nelectrons_qs_cell1 = nelectrons_qs_cell1 + trace
530 negf_env%contacts(contact_id)%nelectrons_qs_cell0 = nelectrons_qs_cell0
531 negf_env%contacts(contact_id)%nelectrons_qs_cell1 = nelectrons_qs_cell1
532 ELSE IF (negf_control%contacts(contact_id)%force_env_index <= 0)
THEN
534 CALL cp_fm_trace(negf_env%contacts(contact_id)%rho_00(ispin), &
535 negf_env%contacts(contact_id)%s_00, trace)
536 nelectrons_qs_cell0 = nelectrons_qs_cell0 + trace
537 CALL cp_fm_trace(negf_env%contacts(contact_id)%rho_01(ispin), &
538 negf_env%contacts(contact_id)%s_01, trace)
539 nelectrons_qs_cell1 = nelectrons_qs_cell1 + 2.0_dp*trace
541 negf_env%contacts(contact_id)%nelectrons_qs_cell0 = nelectrons_qs_cell0
542 negf_env%contacts(contact_id)%nelectrons_qs_cell1 = nelectrons_qs_cell1
545 DEALLOCATE (index_to_cell)
547 IF (sub_env%ngroups > 1)
THEN
549 DEALLOCATE (matrix_s_fm)
555 nelectrons_qs_cell0 = negf_env%contacts(contact_id)%nelectrons_qs_cell0
556 nelectrons_qs_cell1 = negf_env%contacts(contact_id)%nelectrons_qs_cell1
560 IF (negf_control%contacts(contact_id)%compute_fermi_level)
THEN
563 blacs_env=blacs_env_global, &
564 dft_control=dft_control, &
565 do_kpoints=do_kpoints, &
567 matrix_s_kp=matrix_s_kp, &
568 para_env=para_env_global, &
569 rho=rho_struct, subsys=subsys)
570 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_qs_kp)
572 nimages = dft_control%nimages
573 nspins = dft_control%nspins
574 direction_axis_abs = abs(negf_env%contacts(contact_id)%direction_axis)
575 IF (nspins == 1)
THEN
582 cpassert(
SIZE(negf_env%contacts(contact_id)%h_00) == nspins)
584 IF (sub_env%ngroups > 1)
THEN
585 NULLIFY (matrix_s_fm, fm_struct)
587 CALL cp_fm_get_info(negf_env%contacts(contact_id)%s_00, nrow_global=nao)
588 CALL cp_fm_struct_create(fm_struct, nrow_global=nao, ncol_global=nao, context=blacs_env_global)
591 ALLOCATE (matrix_s_fm)
595 IF (sub_env%group_distribution(sub_env%mepos_global) == 0)
THEN
596 CALL cp_fm_copy_general(negf_env%contacts(contact_id)%s_00, matrix_s_fm, para_env_global)
601 matrix_s_fm => negf_env%contacts(contact_id)%s_00
606 IF (log_unit > 0)
THEN
607 WRITE (log_unit,
'(A)')
" Computing the Fermi level of bulk electrode"
608 WRITE (log_unit,
'(T2,A,T60,F20.10,/)')
"Electronic density of the electrode unit cell:", &
609 -1.0_dp*(nelectrons_qs_cell0 + nelectrons_qs_cell1)
610 WRITE (log_unit,
'(T3,A)')
"Step Integration method Time Fermi level Convergence (density)"
611 WRITE (log_unit,
'(T3,78("-"))')
617 negf_env%contacts(contact_id)%fermi_energy = energy%efermi
618 IF (negf_control%homo_lumo_gap > 0.0_dp)
THEN
619 IF (negf_control%contacts(contact_id)%refine_fermi_level)
THEN
620 fermi_level_min = negf_control%contacts(contact_id)%fermi_level
622 fermi_level_min = energy%efermi
624 fermi_level_max = fermi_level_min + negf_control%homo_lumo_gap
626 IF (negf_control%contacts(contact_id)%refine_fermi_level)
THEN
627 fermi_level_max = negf_control%contacts(contact_id)%fermi_level
629 fermi_level_max = energy%efermi
631 fermi_level_min = fermi_level_max + negf_control%homo_lumo_gap
635 lbound_cpath = cmplx(negf_control%energy_lbound, negf_control%eta, kind=
dp)
636 delta_au = real(negf_control%delta_npoles, kind=
dp)*
twopi*negf_control%contacts(contact_id)%temperature
637 offset_au = real(negf_control%gamma_kT, kind=
dp)*negf_control%contacts(contact_id)%temperature
638 energy_ubound_minus_fermi = -2.0_dp*log(negf_control%conv_density)*negf_control%contacts(contact_id)%temperature
646 fermi_level_guess = fermi_level_min
648 fermi_level_guess = fermi_level_max
650 fermi_level_guess = fermi_level_min - (nelectrons_min - nelectrons_qs_cell0)* &
651 (fermi_level_max - fermi_level_min)/(nelectrons_max - nelectrons_min)
654 negf_control%contacts(contact_id)%fermi_level = fermi_level_guess
655 nelectrons_guess = 0.0_dp
657 lbound_lpath = cmplx(fermi_level_guess - offset_au, delta_au, kind=
dp)
658 ubound_lpath = cmplx(fermi_level_guess + energy_ubound_minus_fermi, delta_au, kind=
dp)
660 CALL integration_status_reset(stats)
663 CALL negf_init_rho_equiv_residuals(rho_ao_fm=rho_ao_fm, &
665 ignore_bias=.true., &
667 negf_control=negf_control, &
670 base_contact=contact_id, &
671 just_contact=contact_id)
673 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_fm, &
676 ignore_bias=.true., &
678 negf_control=negf_control, &
681 base_contact=contact_id, &
682 integr_lbound=lbound_cpath, &
683 integr_ubound=lbound_lpath, &
684 matrix_s_global=matrix_s_fm, &
685 is_circular=.true., &
686 g_surf_cache=g_surf_cache, &
687 just_contact=contact_id)
690 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_fm, &
693 ignore_bias=.true., &
695 negf_control=negf_control, &
698 base_contact=contact_id, &
699 integr_lbound=lbound_lpath, &
700 integr_ubound=ubound_lpath, &
701 matrix_s_global=matrix_s_fm, &
702 is_circular=.false., &
703 g_surf_cache=g_surf_cache, &
704 just_contact=contact_id)
708 nelectrons_guess = nelectrons_guess + trace
711 nelectrons_guess = nelectrons_guess*rscale
715 IF (log_unit > 0)
THEN
716 WRITE (log_unit,
'(T2,I5,T12,A,T32,F8.1,T42,F15.8,T60,ES20.5E2)') &
717 step, get_method_description_string(stats, negf_control%integr_method), &
718 t2 - t1, fermi_level_guess, nelectrons_guess - nelectrons_qs_cell0
721 IF (abs(nelectrons_qs_cell0 - nelectrons_guess) < negf_control%conv_density)
EXIT
725 nelectrons_min = nelectrons_guess
727 nelectrons_max = nelectrons_guess
729 IF (fermi_level_guess < fermi_level_min)
THEN
730 fermi_level_max = fermi_level_min
731 nelectrons_max = nelectrons_min
732 fermi_level_min = fermi_level_guess
733 nelectrons_min = nelectrons_guess
734 ELSE IF (fermi_level_guess > fermi_level_max)
THEN
735 fermi_level_min = fermi_level_max
736 nelectrons_min = nelectrons_max
737 fermi_level_max = fermi_level_guess
738 nelectrons_max = nelectrons_guess
739 ELSE IF (fermi_level_max - fermi_level_guess < fermi_level_guess - fermi_level_min)
THEN
740 fermi_level_max = fermi_level_guess
741 nelectrons_max = nelectrons_guess
743 fermi_level_min = fermi_level_guess
744 nelectrons_min = nelectrons_guess
751 negf_control%contacts(contact_id)%fermi_level = fermi_level_guess
753 IF (sub_env%ngroups > 1)
THEN
755 DEALLOCATE (matrix_s_fm)
761 IF (negf_control%contacts(contact_id)%shift_fermi_level)
THEN
762 delta_ef = negf_control%contacts(contact_id)%fermi_level_shifted - negf_control%contacts(contact_id)%fermi_level
763 IF (log_unit > 0)
WRITE (log_unit,
"(/,' The energies are shifted by (a.u.):',F18.8)") delta_ef
764 IF (log_unit > 0)
WRITE (log_unit,
"(' (eV):',F18.8)") delta_ef*
evolt
765 negf_control%contacts(contact_id)%fermi_level = negf_control%contacts(contact_id)%fermi_level_shifted
766 CALL get_qs_env(qs_env, dft_control=dft_control)
767 nspins = dft_control%nspins
768 CALL cp_fm_get_info(negf_env%contacts(contact_id)%s_00, nrow_global=nao)
776 IF (log_unit > 0)
THEN
777 WRITE (temperature_str,
'(F11.3)') negf_control%contacts(contact_id)%temperature*
kelvin
778 WRITE (log_unit,
'(/,T2,A,I0)')
"NEGF| Contact No. ", contact_id
779 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| Fermi level at "//trim(adjustl(temperature_str))// &
780 " Kelvin (a.u.):", negf_control%contacts(contact_id)%fermi_level
781 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| (eV):", &
782 negf_control%contacts(contact_id)%fermi_level*
evolt
783 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| Electric potential (a.u.):", &
784 negf_control%contacts(contact_id)%v_external
785 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| (Volt):", &
786 negf_control%contacts(contact_id)%v_external*
evolt
787 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| Electro-chemical potential Ef-|e|V (a.u.):", &
788 (negf_control%contacts(contact_id)%fermi_level - negf_control%contacts(contact_id)%v_external)
789 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| (eV):", &
790 (negf_control%contacts(contact_id)%fermi_level - negf_control%contacts(contact_id)%v_external)*
evolt
793 CALL timestop(handle)
794 END SUBROUTINE guess_fermi_level
807 SUBROUTINE shift_potential(negf_env, negf_control, sub_env, qs_env, base_contact, log_unit)
812 INTEGER,
INTENT(in) :: base_contact, log_unit
814 CHARACTER(LEN=*),
PARAMETER :: routinen =
'shift_potential'
817 COMPLEX(kind=dp) :: lbound_cpath, ubound_cpath, ubound_lpath
818 INTEGER :: handle, ispin, iter_count, nao, &
820 LOGICAL :: do_kpoints
821 REAL(kind=
dp) :: mu_base, nelectrons_guess, nelectrons_max, nelectrons_min, nelectrons_ref, &
822 t1, t2, temperature, trace, v_shift_guess, v_shift_max, v_shift_min
825 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: rho_ao_fm
827 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: rho_ao_qs_kp
830 DIMENSION(:) :: g_surf_circular, g_surf_linear
831 TYPE(integration_status_type) :: stats
836 ncontacts =
SIZE(negf_control%contacts)
838 IF (.NOT. (
ALLOCATED(negf_env%h_s) .AND.
ALLOCATED(negf_env%h_sc) .AND. &
839 ASSOCIATED(negf_env%s_s) .AND.
ALLOCATED(negf_env%s_sc)))
RETURN
840 IF (ncontacts < 2)
RETURN
841 IF (negf_control%v_shift_maxiters == 0)
RETURN
843 CALL timeset(routinen, handle)
845 CALL get_qs_env(qs_env, blacs_env=blacs_env, do_kpoints=do_kpoints, dft_control=dft_control, &
846 para_env=para_env, rho=rho_struct, subsys=subsys)
847 cpassert(.NOT. do_kpoints)
853 IF (sub_env%ngroups > 1)
THEN
854 NULLIFY (matrix_s_fm, fm_struct)
859 ALLOCATE (matrix_s_fm)
863 IF (sub_env%group_distribution(sub_env%mepos_global) == 0)
THEN
869 matrix_s_fm => negf_env%s_s
874 nspins =
SIZE(negf_env%h_s)
876 mu_base = negf_control%contacts(base_contact)%fermi_level
879 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_qs_kp)
882 nelectrons_ref = 0.0_dp
883 ALLOCATE (rho_ao_fm(nspins))
887 IF (.NOT. negf_control%is_restart)
THEN
890 fm=rho_ao_fm(ispin), &
891 atomlist_row=negf_control%atomlist_S_screening, &
892 atomlist_col=negf_control%atomlist_S_screening, &
893 subsys=subsys, mpi_comm_global=para_env, &
894 do_upper_diag=.true., do_lower=.true.)
896 CALL cp_fm_trace(rho_ao_fm(ispin), matrix_s_fm, trace)
897 nelectrons_ref = nelectrons_ref + trace
899 negf_env%nelectrons_ref = nelectrons_ref
901 nelectrons_ref = negf_env%nelectrons_ref
904 IF (log_unit > 0)
THEN
905 WRITE (log_unit,
'(/,T2,A)')
"COMPUTE SHIFT IN HARTREE POTENTIAL"
906 WRITE (log_unit,
"( ' ----------------------------------')")
907 WRITE (log_unit,
'(/,T2,A,T55,F25.14,/)')
"Initial electronic density of the scattering region:", -1.0_dp*nelectrons_ref
908 WRITE (log_unit,
'(T3,A)')
"Step Integration method Time V shift Convergence (density)"
909 WRITE (log_unit,
'(T3,78("-"))')
912 temperature = negf_control%contacts(base_contact)%temperature
915 lbound_cpath = cmplx(negf_control%energy_lbound, negf_control%eta, kind=
dp)
916 ubound_cpath = cmplx(mu_base - real(negf_control%gamma_kT, kind=
dp)*temperature, &
917 REAL(negf_control%delta_npoles, kind=
dp)*
twopi*temperature, kind=
dp)
920 ubound_lpath = cmplx(mu_base - log(negf_control%conv_density)*temperature, &
921 REAL(negf_control%delta_npoles, kind=
dp)*
twopi*temperature, kind=
dp)
923 v_shift_min = negf_control%v_shift
924 v_shift_max = negf_control%v_shift + negf_control%v_shift_offset
926 ALLOCATE (g_surf_circular(nspins), g_surf_linear(nspins))
928 DO iter_count = 1, negf_control%v_shift_maxiters
929 SELECT CASE (iter_count)
931 v_shift_guess = v_shift_min
933 v_shift_guess = v_shift_max
935 v_shift_guess = v_shift_min - (nelectrons_min - nelectrons_ref)* &
936 (v_shift_max - v_shift_min)/(nelectrons_max - nelectrons_min)
940 CALL integration_status_reset(stats)
944 CALL negf_init_rho_equiv_residuals(rho_ao_fm=rho_ao_fm(ispin), &
945 v_shift=v_shift_guess, &
946 ignore_bias=.true., &
948 negf_control=negf_control, &
951 base_contact=base_contact)
954 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_fm(ispin), &
956 v_shift=v_shift_guess, &
957 ignore_bias=.true., &
959 negf_control=negf_control, &
962 base_contact=base_contact, &
963 integr_lbound=lbound_cpath, &
964 integr_ubound=ubound_cpath, &
965 matrix_s_global=matrix_s_fm, &
966 is_circular=.true., &
967 g_surf_cache=g_surf_circular(ispin))
968 IF (negf_control%disable_cache) &
972 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_fm(ispin), &
974 v_shift=v_shift_guess, &
975 ignore_bias=.true., &
977 negf_control=negf_control, &
980 base_contact=base_contact, &
981 integr_lbound=ubound_cpath, &
982 integr_ubound=ubound_lpath, &
983 matrix_s_global=matrix_s_fm, &
984 is_circular=.false., &
985 g_surf_cache=g_surf_linear(ispin))
986 IF (negf_control%disable_cache) &
998 CALL cp_fm_trace(rho_ao_fm(1), matrix_s_fm, nelectrons_guess)
1002 IF (log_unit > 0)
THEN
1003 WRITE (log_unit,
'(T2,I5,T12,A,T32,F8.1,T42,F15.8,T60,ES20.5E2)') &
1004 iter_count, get_method_description_string(stats, negf_control%integr_method), &
1005 t2 - t1, v_shift_guess, nelectrons_guess - nelectrons_ref
1008 IF (abs(nelectrons_guess - nelectrons_ref) < negf_control%conv_scf)
EXIT
1011 SELECT CASE (iter_count)
1013 nelectrons_min = nelectrons_guess
1015 nelectrons_max = nelectrons_guess
1017 IF (v_shift_guess < v_shift_min)
THEN
1018 v_shift_max = v_shift_min
1019 nelectrons_max = nelectrons_min
1020 v_shift_min = v_shift_guess
1021 nelectrons_min = nelectrons_guess
1022 ELSE IF (v_shift_guess > v_shift_max)
THEN
1023 v_shift_min = v_shift_max
1024 nelectrons_min = nelectrons_max
1025 v_shift_max = v_shift_guess
1026 nelectrons_max = nelectrons_guess
1027 ELSE IF (v_shift_max - v_shift_guess < v_shift_guess - v_shift_min)
THEN
1028 v_shift_max = v_shift_guess
1029 nelectrons_max = nelectrons_guess
1031 v_shift_min = v_shift_guess
1032 nelectrons_min = nelectrons_guess
1039 negf_control%v_shift = v_shift_guess
1041 IF (log_unit > 0)
THEN
1042 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| Shift in Hartree potential (a.u.):", negf_control%v_shift
1043 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| (eV):", negf_control%v_shift*
evolt
1046 DO ispin = nspins, 1, -1
1050 DEALLOCATE (g_surf_circular, g_surf_linear)
1054 IF (sub_env%ngroups > 1 .AND.
ASSOCIATED(matrix_s_fm))
THEN
1056 DEALLOCATE (matrix_s_fm)
1059 CALL timestop(handle)
1060 END SUBROUTINE shift_potential
1076 SUBROUTINE converge_density(negf_env, negf_control, sub_env, negf_section, qs_env, v_shift, base_contact, log_unit)
1082 REAL(kind=
dp),
INTENT(in) :: v_shift
1083 INTEGER,
INTENT(in) :: base_contact, log_unit
1085 CHARACTER(LEN=*),
PARAMETER :: routinen =
'converge_density'
1086 REAL(kind=
dp),
PARAMETER :: threshold = 16.0_dp*epsilon(0.0_dp)
1089 CHARACTER(len=100) :: sfmt
1090 CHARACTER(LEN=default_path_length) :: filebase, filename
1091 COMPLEX(kind=dp) :: lbound_cpath, ubound_cpath, ubound_lpath
1092 INTEGER :: handle, i, icontact, image, ispin, &
1093 iter_count, j, nao, ncol, ncontacts, &
1094 nimages, nrow, nspins, print_unit
1095 LOGICAL :: do_kpoints, exist
1096 REAL(kind=
dp) :: delta, iter_delta, mu_base, nelectrons, &
1097 nelectrons_diff, t1, t2, temperature, &
1099 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: target_m
1102 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: rho_ao_delta_fm, rho_ao_new_fm
1105 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks_initial_kp, matrix_ks_qs_kp, &
1106 rho_ao_initial_kp, rho_ao_new_kp, &
1110 DIMENSION(:) :: g_surf_circular, g_surf_linear, &
1112 TYPE(integration_status_type) :: stats
1119 ncontacts =
SIZE(negf_control%contacts)
1121 IF (ncontacts > 2)
THEN
1122 cpabort(
"Poisson solver does not support the general NEGF setup (>2 contacts).")
1125 IF (.NOT. (
ALLOCATED(negf_env%h_s) .AND.
ALLOCATED(negf_env%h_sc) .AND. &
1126 ASSOCIATED(negf_env%s_s) .AND.
ALLOCATED(negf_env%s_sc)))
RETURN
1127 IF (ncontacts < 2)
RETURN
1128 IF (negf_control%max_scf == 0)
RETURN
1130 CALL timeset(routinen, handle)
1132 IF (log_unit > 0)
THEN
1133 WRITE (log_unit,
'(/,T2,A)')
"NEGF SELF-CONSISTENT PROCEDURE"
1134 WRITE (log_unit,
"( ' ------------------------------')")
1136 WRITE (log_unit,
'(T3,A)')
"Mixing method: Direct mixing of new and old density matrices"
1139 WRITE (log_unit,
'(T3,A)')
"Mixing method: Broyden mixing"
1142 WRITE (log_unit,
'(T3,A)')
"Mixing method: Modified Broyden mixing"
1145 WRITE (log_unit,
'(T3,A)')
"Mixing method: Pulay mixing"
1148 WRITE (log_unit,
'(T3,A)')
"Mixing method: Multisecant scheme for mixing"
1152 IF (negf_control%update_HS .AND. (.NOT. negf_control%is_dft_entire)) &
1153 CALL qs_energies(qs_env, consistent_energies=.false., calc_forces=.false.)
1155 CALL get_qs_env(qs_env, blacs_env=blacs_env, do_kpoints=do_kpoints, dft_control=dft_control, &
1156 matrix_ks_kp=matrix_ks_qs_kp, para_env=para_env, rho=rho_struct, subsys=subsys)
1157 cpassert(.NOT. do_kpoints)
1164 IF (sub_env%ngroups > 1)
THEN
1165 NULLIFY (matrix_s_fm, fm_struct)
1169 ALLOCATE (matrix_s_fm)
1173 IF (sub_env%group_distribution(sub_env%mepos_global) == 0)
THEN
1179 matrix_s_fm => negf_env%s_s
1184 nspins =
SIZE(negf_env%h_s)
1185 nimages = dft_control%nimages
1187 v_base = negf_control%contacts(base_contact)%v_external
1188 mu_base = negf_control%contacts(base_contact)%fermi_level - v_base
1191 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_qs_kp)
1193 ALLOCATE (target_m(nao, nao))
1194 ALLOCATE (rho_ao_delta_fm(nspins), rho_ao_new_fm(nspins))
1195 DO ispin = 1, nspins
1200 IF (negf_control%restart_scf)
THEN
1201 IF (para_env%is_source())
THEN
1204 CALL para_env%bcast(filebase)
1205 IF (nspins == 1)
THEN
1206 filename = trim(filebase)//
'.hs'
1207 INQUIRE (file=filename, exist=exist)
1208 IF (.NOT. exist)
THEN
1209 CALL cp_warn(__location__, &
1210 "User requested to read the KS matrix from the file named: "// &
1211 trim(filename)//
". This file does not exist. The initial KS matrix will be used.")
1214 CALL para_env%bcast(target_m)
1216 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
" H_s is read from "//trim(filename)
1218 filename = trim(filebase)//
'.rho'
1219 INQUIRE (file=filename, exist=exist)
1220 IF (.NOT. exist)
THEN
1221 CALL cp_warn(__location__, &
1222 "User requested to read the density matrix from the file named: "// &
1223 trim(filename)//
". This file does not exist. The initial density matrix will be used.")
1226 CALL para_env%bcast(target_m)
1228 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
" rho_s is read from "//trim(filename)
1230 matrix=rho_ao_qs_kp(1, 1)%matrix, &
1231 atomlist_row=negf_control%atomlist_S_screening, &
1232 atomlist_col=negf_control%atomlist_S_screening, &
1236 IF (nspins == 2)
THEN
1237 filename = trim(filebase)//
'-S1.hs'
1238 INQUIRE (file=filename, exist=exist)
1239 IF (.NOT. exist)
THEN
1240 CALL cp_warn(__location__, &
1241 "User requested to read the KS matrix from the file named: "// &
1242 trim(filename)//
". This file does not exist. The initial KS matrix will be used.")
1245 CALL para_env%bcast(target_m)
1247 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
" H_s is read from "//trim(filename)
1249 filename = trim(filebase)//
'-S2.hs'
1250 INQUIRE (file=filename, exist=exist)
1251 IF (.NOT. exist)
THEN
1252 CALL cp_warn(__location__, &
1253 "User requested to read the KS matrix from the file named: "// &
1254 trim(filename)//
". This file does not exist. The initial KS matrix will be used.")
1257 CALL para_env%bcast(target_m)
1259 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
" H_s is read from "//trim(filename)
1261 filename = trim(filebase)//
'-S1.rho'
1262 INQUIRE (file=filename, exist=exist)
1263 IF (.NOT. exist)
THEN
1264 CALL cp_warn(__location__, &
1265 "User requested to read the density matrix from the file named: "// &
1266 trim(filename)//
". This file does not exist. The initial density matrix will be used.")
1269 CALL para_env%bcast(target_m)
1271 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
" rho_s is read from "//trim(filename)
1273 matrix=rho_ao_qs_kp(1, 1)%matrix, &
1274 atomlist_row=negf_control%atomlist_S_screening, &
1275 atomlist_col=negf_control%atomlist_S_screening, &
1278 filename = trim(filebase)//
'-S2.rho'
1279 INQUIRE (file=filename, exist=exist)
1280 IF (.NOT. exist)
THEN
1281 CALL cp_warn(__location__, &
1282 "User requested to read the density matrix from the file named: "// &
1283 trim(filename)//
". This file does not exist. The initial density matrix will be used.")
1286 CALL para_env%bcast(target_m)
1288 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
" rho_s is read from "//trim(filename)
1290 matrix=rho_ao_qs_kp(2, 1)%matrix, &
1291 atomlist_row=negf_control%atomlist_S_screening, &
1292 atomlist_col=negf_control%atomlist_S_screening, &
1299 NULLIFY (matrix_ks_initial_kp, rho_ao_initial_kp, rho_ao_new_kp)
1304 DO image = 1, nimages
1305 DO ispin = 1, nspins
1306 CALL dbcsr_init_p(matrix_ks_initial_kp(ispin, image)%matrix)
1307 CALL dbcsr_copy(matrix_b=matrix_ks_initial_kp(ispin, image)%matrix, matrix_a=matrix_ks_qs_kp(ispin, image)%matrix)
1309 CALL dbcsr_init_p(rho_ao_initial_kp(ispin, image)%matrix)
1310 CALL dbcsr_copy(matrix_b=rho_ao_initial_kp(ispin, image)%matrix, matrix_a=rho_ao_qs_kp(ispin, image)%matrix)
1313 CALL dbcsr_copy(matrix_b=rho_ao_new_kp(ispin, image)%matrix, matrix_a=rho_ao_qs_kp(ispin, image)%matrix)
1319 DO ispin = 1, nspins
1321 fm=rho_ao_delta_fm(ispin), &
1322 atomlist_row=negf_control%atomlist_S_screening, &
1323 atomlist_col=negf_control%atomlist_S_screening, &
1324 subsys=subsys, mpi_comm_global=para_env, &
1325 do_upper_diag=.true., do_lower=.true.)
1327 CALL cp_fm_trace(rho_ao_delta_fm(ispin), matrix_s_fm, trace)
1328 nelectrons = nelectrons + trace
1330 negf_env%nelectrons = nelectrons
1334 CALL mixing_allocate(qs_env, negf_env%mixing_method, nspins=nspins, mixing_store=negf_env%mixing_storage)
1335 IF (dft_control%qs_control%dftb)
THEN
1336 cpabort(
'DFTB Code not available')
1337 ELSE IF (dft_control%qs_control%xtb)
THEN
1339 ELSE IF (dft_control%qs_control%semi_empirical)
THEN
1340 cpabort(
'SE Code not possible')
1342 CALL mixing_init(negf_env%mixing_method, rho_struct, negf_env%mixing_storage, para_env)
1346 IF (log_unit > 0)
THEN
1347 WRITE (log_unit,
'(/,T2,A,T55,F25.14,/)')
" Initial electronic density of the scattering region:", -1.0_dp*nelectrons
1348 WRITE (log_unit,
'(T3,A)')
"Step Integration method Time Electronic density Convergence"
1349 WRITE (log_unit,
'(T3,78("-"))')
1352 temperature = negf_control%contacts(base_contact)%temperature
1355 lbound_cpath = cmplx(negf_control%energy_lbound, negf_control%eta, kind=
dp)
1356 ubound_cpath = cmplx(mu_base - real(negf_control%gamma_kT, kind=
dp)*temperature, &
1357 REAL(negf_control%delta_npoles, kind=
dp)*
twopi*temperature, kind=
dp)
1360 ubound_lpath = cmplx(mu_base - log(negf_control%conv_density)*temperature, &
1361 REAL(negf_control%delta_npoles, kind=
dp)*
twopi*temperature, kind=
dp)
1363 ALLOCATE (g_surf_circular(nspins), g_surf_linear(nspins), g_surf_nonequiv(nspins))
1367 DO iter_count = 1, negf_control%max_scf
1369 CALL integration_status_reset(stats)
1370 CALL cp_iterate(logger%iter_info, last=.false., iter_nr=iter_count)
1372 DO ispin = 1, nspins
1374 CALL negf_init_rho_equiv_residuals(rho_ao_fm=rho_ao_new_fm(ispin), &
1376 ignore_bias=.false., &
1377 negf_env=negf_env, &
1378 negf_control=negf_control, &
1381 base_contact=base_contact)
1384 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_new_fm(ispin), &
1387 ignore_bias=.false., &
1388 negf_env=negf_env, &
1389 negf_control=negf_control, &
1392 base_contact=base_contact, &
1393 integr_lbound=lbound_cpath, &
1394 integr_ubound=ubound_cpath, &
1395 matrix_s_global=matrix_s_fm, &
1396 is_circular=.true., &
1397 g_surf_cache=g_surf_circular(ispin))
1398 IF (negf_control%disable_cache) &
1402 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_new_fm(ispin), &
1405 ignore_bias=.false., &
1406 negf_env=negf_env, &
1407 negf_control=negf_control, &
1410 base_contact=base_contact, &
1411 integr_lbound=ubound_cpath, &
1412 integr_ubound=ubound_lpath, &
1413 matrix_s_global=matrix_s_fm, &
1414 is_circular=.false., &
1415 g_surf_cache=g_surf_linear(ispin))
1416 IF (negf_control%disable_cache) &
1421 DO icontact = 1, ncontacts
1422 IF (icontact /= base_contact)
THEN
1423 delta = delta + abs(negf_control%contacts(icontact)%v_external - &
1424 negf_control%contacts(base_contact)%v_external) + &
1425 abs(negf_control%contacts(icontact)%fermi_level - &
1426 negf_control%contacts(base_contact)%fermi_level) + &
1427 abs(negf_control%contacts(icontact)%temperature - &
1428 negf_control%contacts(base_contact)%temperature)
1431 IF (delta >= threshold)
THEN
1432 CALL negf_add_rho_nonequiv(rho_ao_fm=rho_ao_new_fm(ispin), &
1435 negf_env=negf_env, &
1436 negf_control=negf_control, &
1439 base_contact=base_contact, &
1440 matrix_s_global=matrix_s_fm, &
1441 g_surf_cache=g_surf_nonequiv(ispin))
1442 IF (negf_control%disable_cache) &
1447 IF (nspins == 1)
CALL cp_fm_scale(2.0_dp, rho_ao_new_fm(1))
1450 nelectrons_diff = 0.0_dp
1451 DO ispin = 1, nspins
1452 CALL cp_fm_trace(rho_ao_new_fm(ispin), matrix_s_fm, trace)
1453 nelectrons = nelectrons + trace
1457 CALL cp_fm_trace(rho_ao_delta_fm(ispin), matrix_s_fm, trace)
1458 nelectrons_diff = nelectrons_diff + trace
1461 CALL cp_fm_to_fm(rho_ao_new_fm(ispin), rho_ao_delta_fm(ispin))
1466 IF (log_unit > 0)
THEN
1467 WRITE (log_unit,
'(T2,I5,T12,A,T32,F8.1,T43,F20.8,T65,ES15.5E2)') &
1468 iter_count, get_method_description_string(stats, negf_control%integr_method), &
1469 t2 - t1, -1.0_dp*nelectrons, nelectrons_diff
1472 IF (abs(nelectrons_diff) < negf_control%conv_scf)
EXIT
1478 DO image = 1, nimages
1479 DO ispin = 1, nspins
1480 CALL dbcsr_copy(matrix_b=rho_ao_new_kp(ispin, image)%matrix, &
1481 matrix_a=rho_ao_initial_kp(ispin, image)%matrix)
1485 DO ispin = 1, nspins
1487 matrix=rho_ao_new_kp(ispin, 1)%matrix, &
1488 atomlist_row=negf_control%atomlist_S_screening, &
1489 atomlist_col=negf_control%atomlist_S_screening, &
1494 para_env, iter_delta, iter_count)
1496 DO image = 1, nimages
1497 DO ispin = 1, nspins
1498 CALL dbcsr_copy(rho_ao_qs_kp(ispin, image)%matrix, rho_ao_new_kp(ispin, image)%matrix)
1504 DO image = 1, nimages
1505 DO ispin = 1, nspins
1506 CALL dbcsr_copy(matrix_b=rho_ao_qs_kp(ispin, image)%matrix, &
1507 matrix_a=rho_ao_initial_kp(ispin, image)%matrix)
1511 DO ispin = 1, nspins
1513 matrix=rho_ao_qs_kp(ispin, 1)%matrix, &
1514 atomlist_row=negf_control%atomlist_S_screening, &
1515 atomlist_col=negf_control%atomlist_S_screening, &
1523 CALL gspace_mixing(qs_env, negf_env%mixing_method, negf_env%mixing_storage, &
1524 rho_struct, para_env, iter_count)
1528 IF (negf_control%update_HS)
THEN
1531 DO ispin = 1, nspins
1533 fm=negf_env%h_s(ispin), &
1534 atomlist_row=negf_control%atomlist_S_screening, &
1535 atomlist_col=negf_control%atomlist_S_screening, &
1536 subsys=subsys, mpi_comm_global=para_env, &
1537 do_upper_diag=.true., do_lower=.true.)
1542 IF (nspins == 1)
THEN
1545 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1547 extension=
".hs", file_status=
"REPLACE", file_action=
"WRITE", &
1548 do_backup=.true., file_form=
"FORMATTED")
1549 nrow =
SIZE(target_m, 1)
1550 ncol =
SIZE(target_m, 2)
1551 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1552 WRITE (print_unit, *) nrow, ncol
1554 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1559 IF (nspins == 2)
THEN
1562 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1564 extension=
"-S1.hs", file_status=
"REPLACE", file_action=
"WRITE", &
1565 do_backup=.true., file_form=
"FORMATTED")
1566 nrow =
SIZE(target_m, 1)
1567 ncol =
SIZE(target_m, 2)
1568 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1569 WRITE (print_unit, *) nrow, ncol
1571 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1577 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1579 extension=
"-S2.hs", file_status=
"REPLACE", file_action=
"WRITE", &
1580 do_backup=.true., file_form=
"FORMATTED")
1581 nrow =
SIZE(target_m, 1)
1582 ncol =
SIZE(target_m, 2)
1583 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1584 WRITE (print_unit, *) nrow, ncol
1586 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1593 IF (nspins == 1)
THEN
1596 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1598 extension=
".rho", file_status=
"REPLACE", file_action=
"WRITE", &
1599 do_backup=.true., file_form=
"FORMATTED")
1600 nrow =
SIZE(target_m, 1)
1601 ncol =
SIZE(target_m, 2)
1602 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1603 WRITE (print_unit, *) nrow, ncol
1605 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1610 IF (nspins == 2)
THEN
1613 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1615 extension=
"-S1.rho", file_status=
"REPLACE", file_action=
"WRITE", &
1616 do_backup=.true., file_form=
"FORMATTED")
1617 nrow =
SIZE(target_m, 1)
1618 ncol =
SIZE(target_m, 2)
1619 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1620 WRITE (print_unit, *) nrow, ncol
1622 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1628 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1630 extension=
"-S2.rho", file_status=
"REPLACE", file_action=
"WRITE", &
1631 do_backup=.true., file_form=
"FORMATTED")
1632 nrow =
SIZE(target_m, 1)
1633 ncol =
SIZE(target_m, 2)
1634 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1635 WRITE (print_unit, *) nrow, ncol
1637 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1646 CALL cp_iterate(logger%iter_info, last=.true., iter_nr=iter_count)
1647 IF (nspins == 1)
THEN
1650 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1652 extension=
".hs", file_status=
"REPLACE", file_action=
"WRITE", &
1653 do_backup=.true., file_form=
"FORMATTED")
1654 nrow =
SIZE(target_m, 1)
1655 ncol =
SIZE(target_m, 2)
1656 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1657 WRITE (print_unit, *) nrow, ncol
1659 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1664 IF (nspins == 2)
THEN
1667 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1669 extension=
"-S1.hs", file_status=
"REPLACE", file_action=
"WRITE", &
1670 do_backup=.true., file_form=
"FORMATTED")
1671 nrow =
SIZE(target_m, 1)
1672 ncol =
SIZE(target_m, 2)
1673 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1674 WRITE (print_unit, *) nrow, ncol
1676 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1682 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1684 extension=
"-S2.hs", file_status=
"REPLACE", file_action=
"WRITE", &
1685 do_backup=.true., file_form=
"FORMATTED")
1686 nrow =
SIZE(target_m, 1)
1687 ncol =
SIZE(target_m, 2)
1688 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1689 WRITE (print_unit, *) nrow, ncol
1691 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1698 IF (nspins == 1)
THEN
1701 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1703 extension=
".rho", file_status=
"REPLACE", file_action=
"WRITE", &
1704 do_backup=.true., file_form=
"FORMATTED")
1705 nrow =
SIZE(target_m, 1)
1706 ncol =
SIZE(target_m, 2)
1707 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1708 WRITE (print_unit, *) nrow, ncol
1710 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1715 IF (nspins == 2)
THEN
1718 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1720 extension=
"-S1.rho", file_status=
"REPLACE", file_action=
"WRITE", &
1721 do_backup=.true., file_form=
"FORMATTED")
1722 nrow =
SIZE(target_m, 1)
1723 ncol =
SIZE(target_m, 2)
1724 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1725 WRITE (print_unit, *) nrow, ncol
1727 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1733 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1735 extension=
"-S2.rho", file_status=
"REPLACE", file_action=
"WRITE", &
1736 do_backup=.true., file_form=
"FORMATTED")
1737 nrow =
SIZE(target_m, 1)
1738 ncol =
SIZE(target_m, 2)
1739 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1740 WRITE (print_unit, *) nrow, ncol
1742 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1748 DEALLOCATE (target_m)
1753 IF (log_unit > 0)
THEN
1754 IF (iter_count <= negf_control%max_scf)
THEN
1755 WRITE (log_unit,
'(/,T11,1X,A,I0,A)')
"*** NEGF run converged in ", iter_count,
" iteration(s) ***"
1757 WRITE (log_unit,
'(/,T11,1X,A,I0,A)')
"*** NEGF run did NOT converge after ", iter_count - 1,
" iteration(s) ***"
1761 DO ispin = nspins, 1, -1
1766 DEALLOCATE (g_surf_circular, g_surf_linear, g_surf_nonequiv)
1771 DO image = 1, nimages
1772 DO ispin = 1, nspins
1773 CALL dbcsr_copy(matrix_b=matrix_ks_qs_kp(ispin, image)%matrix, matrix_a=matrix_ks_initial_kp(ispin, image)%matrix)
1774 CALL dbcsr_copy(matrix_b=rho_ao_qs_kp(ispin, image)%matrix, matrix_a=rho_ao_initial_kp(ispin, image)%matrix)
1781 DEALLOCATE (matrix_ks_initial_kp, rho_ao_new_kp, rho_ao_initial_kp)
1783 IF (sub_env%ngroups > 1 .AND.
ASSOCIATED(matrix_s_fm))
THEN
1785 DEALLOCATE (matrix_s_fm)
1788 CALL timestop(handle)
1789 END SUBROUTINE converge_density
1806 SUBROUTINE negf_surface_green_function_batch(g_surf, omega, h0, s0, h1, s1, sub_env, v_external, conv, transp)
1807 TYPE(
cp_cfm_type),
DIMENSION(:),
INTENT(inout) :: g_surf
1808 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(in) :: omega
1809 TYPE(
cp_fm_type),
INTENT(IN) :: h0, s0, h1, s1
1811 REAL(kind=
dp),
INTENT(in) :: v_external, conv
1812 LOGICAL,
INTENT(in) :: transp
1814 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_surface_green_function_batch'
1817 INTEGER :: handle, igroup, ipoint, npoints
1821 CALL timeset(routinen, handle)
1822 npoints =
SIZE(omega)
1827 igroup = sub_env%group_distribution(sub_env%mepos_global)
1829 g_surf(1:npoints) = cfm_null
1831 DO ipoint = igroup + 1, npoints, sub_env%ngroups
1832 IF (debug_this_module)
THEN
1833 cpassert(.NOT.
ASSOCIATED(g_surf(ipoint)%matrix_struct))
1837 CALL do_sancho(g_surf(ipoint), omega(ipoint) + v_external, &
1838 h0, s0, h1, s1, conv, transp, work)
1842 CALL timestop(handle)
1843 END SUBROUTINE negf_surface_green_function_batch
1875 SUBROUTINE negf_retarded_green_function_batch(omega, v_shift, ignore_bias, negf_env, negf_control, sub_env, ispin, &
1877 g_ret_s, g_ret_scale, gamma_contacts, gret_gamma_gadv, dos, &
1878 transm_coeff, transm_contact1, transm_contact2, just_contact)
1879 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(in) :: omega
1880 REAL(kind=
dp),
INTENT(in) :: v_shift
1881 LOGICAL,
INTENT(in) :: ignore_bias
1885 INTEGER,
INTENT(in) :: ispin
1886 TYPE(
cp_cfm_type),
DIMENSION(:, :),
INTENT(in) :: g_surf_contacts
1889 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(in), &
1890 OPTIONAL :: g_ret_scale
1892 OPTIONAL :: gamma_contacts, gret_gamma_gadv
1893 REAL(kind=
dp),
DIMENSION(:),
INTENT(out),
OPTIONAL :: dos
1894 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(out), &
1895 OPTIONAL :: transm_coeff
1896 INTEGER,
INTENT(in),
OPTIONAL :: transm_contact1, transm_contact2, &
1899 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_retarded_green_function_batch'
1901 INTEGER :: handle, icontact, igroup, ipoint, &
1902 ncontacts, npoints, nrows
1903 REAL(kind=
dp) :: v_external
1905 DIMENSION(:) :: info1
1907 DIMENSION(:, :) :: info2
1908 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: g_ret_s_group, self_energy_contacts, &
1909 zwork1_contacts, zwork2_contacts
1910 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:, :) :: gamma_contacts_group, &
1911 gret_gamma_gadv_group
1917 CALL timeset(routinen, handle)
1918 npoints =
SIZE(omega)
1919 ncontacts =
SIZE(negf_env%contacts)
1920 cpassert(
SIZE(negf_control%contacts) == ncontacts)
1922 IF (
PRESENT(just_contact))
THEN
1923 cpassert(just_contact <= ncontacts)
1927 cpassert(ncontacts >= 2)
1929 IF (ignore_bias) v_external = 0.0_dp
1931 IF (
PRESENT(transm_coeff) .OR.
PRESENT(transm_contact1) .OR.
PRESENT(transm_contact2))
THEN
1932 cpassert(
PRESENT(transm_coeff))
1933 cpassert(
PRESENT(transm_contact1))
1934 cpassert(
PRESENT(transm_contact2))
1935 cpassert(.NOT.
PRESENT(just_contact))
1938 ALLOCATE (self_energy_contacts(ncontacts), zwork1_contacts(ncontacts), zwork2_contacts(ncontacts))
1940 IF (
PRESENT(just_contact))
THEN
1941 CALL cp_fm_get_info(negf_env%contacts(just_contact)%s_01, matrix_struct=fm_struct)
1942 DO icontact = 1, ncontacts
1947 CALL cp_fm_get_info(negf_env%contacts(just_contact)%s_00, nrow_global=nrows, matrix_struct=fm_struct)
1948 DO icontact = 1, ncontacts
1949 CALL cp_cfm_create(self_energy_contacts(icontact), fm_struct)
1952 DO icontact = 1, ncontacts
1953 CALL cp_fm_get_info(negf_env%s_sc(icontact), matrix_struct=fm_struct)
1958 CALL cp_fm_get_info(negf_env%s_s, nrow_global=nrows, matrix_struct=fm_struct)
1959 DO icontact = 1, ncontacts
1960 CALL cp_cfm_create(self_energy_contacts(icontact), fm_struct)
1964 IF (
PRESENT(g_ret_s) .OR.
PRESENT(gret_gamma_gadv) .OR. &
1965 PRESENT(dos) .OR.
PRESENT(transm_coeff))
THEN
1966 ALLOCATE (g_ret_s_group(npoints))
1968 IF (sub_env%ngroups <= 1 .AND.
PRESENT(g_ret_s))
THEN
1969 g_ret_s_group(1:npoints) = g_ret_s(1:npoints)
1973 IF (
PRESENT(gamma_contacts) .OR.
PRESENT(gret_gamma_gadv) .OR.
PRESENT(transm_coeff))
THEN
1974 IF (debug_this_module .AND.
PRESENT(gamma_contacts))
THEN
1975 cpassert(
SIZE(gamma_contacts, 1) == ncontacts)
1978 ALLOCATE (gamma_contacts_group(ncontacts, npoints))
1979 IF (sub_env%ngroups <= 1 .AND.
PRESENT(gamma_contacts))
THEN
1980 gamma_contacts_group(1:ncontacts, 1:npoints) = gamma_contacts(1:ncontacts, 1:npoints)
1984 IF (
PRESENT(gret_gamma_gadv))
THEN
1985 IF (debug_this_module .AND.
PRESENT(gret_gamma_gadv))
THEN
1986 cpassert(
SIZE(gret_gamma_gadv, 1) == ncontacts)
1989 ALLOCATE (gret_gamma_gadv_group(ncontacts, npoints))
1990 IF (sub_env%ngroups <= 1)
THEN
1991 gret_gamma_gadv_group(1:ncontacts, 1:npoints) = gret_gamma_gadv(1:ncontacts, 1:npoints)
1995 igroup = sub_env%group_distribution(sub_env%mepos_global)
1997 DO ipoint = 1, npoints
1998 IF (
ASSOCIATED(g_surf_contacts(1, ipoint)%matrix_struct))
THEN
1999 IF (sub_env%ngroups > 1 .OR. .NOT.
PRESENT(g_ret_s))
THEN
2003 IF (
ALLOCATED(g_ret_s_group))
THEN
2008 IF (sub_env%ngroups > 1 .OR. .NOT.
PRESENT(gamma_contacts))
THEN
2009 IF (
ALLOCATED(gamma_contacts_group))
THEN
2010 DO icontact = 1, ncontacts
2011 CALL cp_cfm_create(gamma_contacts_group(icontact, ipoint), fm_struct)
2016 IF (sub_env%ngroups > 1)
THEN
2017 IF (
ALLOCATED(gret_gamma_gadv_group))
THEN
2018 DO icontact = 1, ncontacts
2019 IF (
ASSOCIATED(gret_gamma_gadv(icontact, ipoint)%matrix_struct))
THEN
2020 CALL cp_cfm_create(gret_gamma_gadv_group(icontact, ipoint), fm_struct)
2026 IF (
PRESENT(just_contact))
THEN
2028 DO icontact = 1, ncontacts
2030 omega=omega(ipoint), &
2031 g_surf_c=g_surf_contacts(icontact, ipoint), &
2032 h_sc0=negf_env%contacts(just_contact)%h_01(ispin), &
2033 s_sc0=negf_env%contacts(just_contact)%s_01, &
2034 zwork1=zwork1_contacts(icontact), &
2035 zwork2=zwork2_contacts(icontact), &
2036 transp=(icontact == 1))
2040 DO icontact = 1, ncontacts
2041 IF (.NOT. ignore_bias) v_external = negf_control%contacts(icontact)%v_external
2044 omega=omega(ipoint) + v_external, &
2045 g_surf_c=g_surf_contacts(icontact, ipoint), &
2046 h_sc0=negf_env%h_sc(ispin, icontact), &
2047 s_sc0=negf_env%s_sc(icontact), &
2048 zwork1=zwork1_contacts(icontact), &
2049 zwork2=zwork2_contacts(icontact), &
2055 IF (
ALLOCATED(gamma_contacts_group))
THEN
2056 DO icontact = 1, ncontacts
2058 self_energy_c=self_energy_contacts(icontact))
2062 IF (
ALLOCATED(g_ret_s_group))
THEN
2064 DO icontact = 2, ncontacts
2069 IF (
PRESENT(just_contact))
THEN
2071 omega=omega(ipoint) - v_shift, &
2072 self_energy_ret_sum=self_energy_contacts(1), &
2073 h_s=negf_env%contacts(just_contact)%h_00(ispin), &
2074 s_s=negf_env%contacts(just_contact)%s_00)
2075 ELSE IF (ignore_bias)
THEN
2077 omega=omega(ipoint) - v_shift, &
2078 self_energy_ret_sum=self_energy_contacts(1), &
2079 h_s=negf_env%h_s(ispin), &
2083 omega=omega(ipoint) - v_shift, &
2084 self_energy_ret_sum=self_energy_contacts(1), &
2085 h_s=negf_env%h_s(ispin), &
2087 v_hartree_s=negf_env%v_hartree_s)
2090 IF (
PRESENT(g_ret_scale))
THEN
2091 IF (g_ret_scale(ipoint) /=
z_one)
CALL cp_cfm_scale(g_ret_scale(ipoint), g_ret_s_group(ipoint))
2095 IF (
ALLOCATED(gret_gamma_gadv_group))
THEN
2098 DO icontact = 1, ncontacts
2099 IF (
ASSOCIATED(gret_gamma_gadv_group(icontact, ipoint)%matrix_struct))
THEN
2101 z_one, gamma_contacts_group(icontact, ipoint), &
2102 g_ret_s_group(ipoint), &
2103 z_zero, self_energy_contacts(icontact))
2105 z_one, g_ret_s_group(ipoint), &
2106 self_energy_contacts(icontact), &
2107 z_zero, gret_gamma_gadv_group(icontact, ipoint))
2115 IF (
PRESENT(g_ret_s))
THEN
2116 IF (sub_env%ngroups > 1)
THEN
2118 DO ipoint = 1, npoints
2119 IF (
ASSOCIATED(g_ret_s(ipoint)%matrix_struct))
THEN
2125 IF (
ASSOCIATED(para_env))
THEN
2126 ALLOCATE (info1(npoints))
2128 DO ipoint = 1, npoints
2131 para_env, info1(ipoint))
2134 DO ipoint = 1, npoints
2135 IF (
ASSOCIATED(g_ret_s(ipoint)%matrix_struct))
THEN
2137 IF (
ASSOCIATED(g_ret_s_group(ipoint)%matrix_struct)) &
2147 IF (
PRESENT(gamma_contacts))
THEN
2148 IF (sub_env%ngroups > 1)
THEN
2150 pnt1:
DO ipoint = 1, npoints
2151 DO icontact = 1, ncontacts
2152 IF (
ASSOCIATED(gamma_contacts(icontact, ipoint)%matrix_struct))
THEN
2153 CALL cp_cfm_get_info(gamma_contacts(icontact, ipoint), para_env=para_env)
2159 IF (
ASSOCIATED(para_env))
THEN
2160 ALLOCATE (info2(ncontacts, npoints))
2162 DO ipoint = 1, npoints
2163 DO icontact = 1, ncontacts
2165 gamma_contacts(icontact, ipoint), &
2166 para_env, info2(icontact, ipoint))
2170 DO ipoint = 1, npoints
2171 DO icontact = 1, ncontacts
2172 IF (
ASSOCIATED(gamma_contacts(icontact, ipoint)%matrix_struct))
THEN
2174 IF (
ASSOCIATED(gamma_contacts_group(icontact, ipoint)%matrix_struct))
THEN
2186 IF (
PRESENT(gret_gamma_gadv))
THEN
2187 IF (sub_env%ngroups > 1)
THEN
2189 pnt2:
DO ipoint = 1, npoints
2190 DO icontact = 1, ncontacts
2191 IF (
ASSOCIATED(gret_gamma_gadv(icontact, ipoint)%matrix_struct))
THEN
2192 CALL cp_cfm_get_info(gret_gamma_gadv(icontact, ipoint), para_env=para_env)
2198 IF (
ASSOCIATED(para_env))
THEN
2199 ALLOCATE (info2(ncontacts, npoints))
2201 DO ipoint = 1, npoints
2202 DO icontact = 1, ncontacts
2204 gret_gamma_gadv(icontact, ipoint), &
2205 para_env, info2(icontact, ipoint))
2209 DO ipoint = 1, npoints
2210 DO icontact = 1, ncontacts
2211 IF (
ASSOCIATED(gret_gamma_gadv(icontact, ipoint)%matrix_struct))
THEN
2213 IF (
ASSOCIATED(gret_gamma_gadv_group(icontact, ipoint)%matrix_struct))
THEN
2225 IF (
PRESENT(dos))
THEN
2228 IF (
PRESENT(just_contact))
THEN
2229 matrix_s => negf_env%contacts(just_contact)%s_00
2231 matrix_s => negf_env%s_s
2237 DO ipoint = 1, npoints
2238 IF (
ASSOCIATED(g_ret_s_group(ipoint)%matrix_struct))
THEN
2239 CALL cp_cfm_to_fm(g_ret_s_group(ipoint), mtargeti=g_ret_imag)
2240 CALL cp_fm_trace(g_ret_imag, matrix_s, dos(ipoint))
2241 IF (sub_env%para_env%mepos /= 0) dos(ipoint) = 0.0_dp
2247 CALL sub_env%mpi_comm_global%sum(dos)
2248 dos(:) = -1.0_dp/
pi*dos(:)
2251 IF (
PRESENT(transm_coeff))
THEN
2254 DO ipoint = 1, npoints
2255 IF (
ASSOCIATED(g_ret_s_group(ipoint)%matrix_struct))
THEN
2258 z_one, gamma_contacts_group(transm_contact1, ipoint), &
2259 g_ret_s_group(ipoint), &
2260 z_zero, self_energy_contacts(transm_contact1))
2262 z_one, self_energy_contacts(transm_contact1), &
2263 gamma_contacts_group(transm_contact2, ipoint), &
2264 z_zero, self_energy_contacts(transm_contact2))
2268 self_energy_contacts(transm_contact2), &
2269 transm_coeff(ipoint))
2270 IF (sub_env%para_env%mepos /= 0) transm_coeff(ipoint) = 0.0_dp
2275 CALL sub_env%mpi_comm_global%sum(transm_coeff)
2280 IF (
ALLOCATED(g_ret_s_group))
THEN
2281 DO ipoint = npoints, 1, -1
2282 IF (sub_env%ngroups > 1 .OR. .NOT.
PRESENT(g_ret_s))
THEN
2286 DEALLOCATE (g_ret_s_group)
2289 IF (
ALLOCATED(gamma_contacts_group))
THEN
2290 DO ipoint = npoints, 1, -1
2291 DO icontact = ncontacts, 1, -1
2292 IF (sub_env%ngroups > 1 .OR. .NOT.
PRESENT(gamma_contacts))
THEN
2297 DEALLOCATE (gamma_contacts_group)
2300 IF (
ALLOCATED(gret_gamma_gadv_group))
THEN
2301 DO ipoint = npoints, 1, -1
2302 DO icontact = ncontacts, 1, -1
2303 IF (sub_env%ngroups > 1)
THEN
2308 DEALLOCATE (gret_gamma_gadv_group)
2311 IF (
ALLOCATED(self_energy_contacts))
THEN
2312 DO icontact = ncontacts, 1, -1
2315 DEALLOCATE (self_energy_contacts)
2318 IF (
ALLOCATED(zwork1_contacts))
THEN
2319 DO icontact = ncontacts, 1, -1
2322 DEALLOCATE (zwork1_contacts)
2325 IF (
ALLOCATED(zwork2_contacts))
THEN
2326 DO icontact = ncontacts, 1, -1
2329 DEALLOCATE (zwork2_contacts)
2332 CALL timestop(handle)
2333 END SUBROUTINE negf_retarded_green_function_batch
2343 PURE FUNCTION fermi_function(omega, temperature)
RESULT(val)
2344 COMPLEX(kind=dp),
INTENT(in) :: omega
2345 REAL(kind=
dp),
INTENT(in) :: temperature
2346 COMPLEX(kind=dp) :: val
2348 REAL(kind=
dp),
PARAMETER :: max_ln_omega_over_t = log(huge(0.0_dp))/16.0_dp
2350 IF (real(omega, kind=
dp) <= temperature*max_ln_omega_over_t)
THEN
2356 END FUNCTION fermi_function
2371 SUBROUTINE negf_init_rho_equiv_residuals(rho_ao_fm, v_shift, ignore_bias, negf_env, &
2372 negf_control, sub_env, ispin, base_contact, just_contact)
2374 REAL(kind=
dp),
INTENT(in) :: v_shift
2375 LOGICAL,
INTENT(in) :: ignore_bias
2379 INTEGER,
INTENT(in) :: ispin, base_contact
2380 INTEGER,
INTENT(in),
OPTIONAL :: just_contact
2382 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_init_rho_equiv_residuals'
2384 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: omega
2385 INTEGER :: handle, icontact, ipole, ncontacts, &
2387 REAL(kind=
dp) :: mu_base, pi_temperature, temperature, &
2389 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: g_ret_s
2394 CALL timeset(routinen, handle)
2396 temperature = negf_control%contacts(base_contact)%temperature
2397 IF (ignore_bias)
THEN
2398 mu_base = negf_control%contacts(base_contact)%fermi_level
2401 mu_base = negf_control%contacts(base_contact)%fermi_level - negf_control%contacts(base_contact)%v_external
2404 pi_temperature =
pi*temperature
2405 npoles = negf_control%delta_npoles
2407 ncontacts =
SIZE(negf_env%contacts)
2408 cpassert(base_contact <= ncontacts)
2409 IF (
PRESENT(just_contact))
THEN
2411 cpassert(just_contact == base_contact)
2414 IF (npoles > 0)
THEN
2415 CALL cp_fm_get_info(rho_ao_fm, para_env=para_env, matrix_struct=fm_struct)
2417 ALLOCATE (omega(npoles), g_ret_s(npoles))
2419 DO ipole = 1, npoles
2422 omega(ipole) = cmplx(mu_base, real(2*ipole - 1, kind=
dp)*pi_temperature, kind=
dp)
2427 IF (
PRESENT(just_contact))
THEN
2432 DO icontact = 1, ncontacts
2433 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
2435 h0=negf_env%contacts(just_contact)%h_00(ispin), &
2436 s0=negf_env%contacts(just_contact)%s_00, &
2437 h1=negf_env%contacts(just_contact)%h_01(ispin), &
2438 s1=negf_env%contacts(just_contact)%s_01, &
2439 sub_env=sub_env, v_external=0.0_dp, &
2440 conv=negf_control%conv_green, transp=(icontact == 1))
2443 DO icontact = 1, ncontacts
2444 IF (.NOT. ignore_bias) v_external = negf_control%contacts(icontact)%v_external
2446 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
2448 h0=negf_env%contacts(icontact)%h_00(ispin), &
2449 s0=negf_env%contacts(icontact)%s_00, &
2450 h1=negf_env%contacts(icontact)%h_01(ispin), &
2451 s1=negf_env%contacts(icontact)%s_01, &
2453 v_external=v_external, &
2454 conv=negf_control%conv_green, transp=.false.)
2458 CALL negf_retarded_green_function_batch(omega=omega(:), &
2460 ignore_bias=ignore_bias, &
2461 negf_env=negf_env, &
2462 negf_control=negf_control, &
2465 g_surf_contacts=g_surf_cache%g_surf_contacts, &
2467 just_contact=just_contact)
2471 DO ipole = 2, npoles
2479 DO ipole = npoles, 1, -1
2482 DEALLOCATE (g_ret_s, omega)
2485 CALL timestop(handle)
2486 END SUBROUTINE negf_init_rho_equiv_residuals
2507 SUBROUTINE negf_add_rho_equiv_low(rho_ao_fm, stats, v_shift, ignore_bias, negf_env, negf_control, sub_env, &
2508 ispin, base_contact, integr_lbound, integr_ubound, matrix_s_global, &
2509 is_circular, g_surf_cache, just_contact)
2511 TYPE(integration_status_type),
INTENT(inout) :: stats
2512 REAL(kind=
dp),
INTENT(in) :: v_shift
2513 LOGICAL,
INTENT(in) :: ignore_bias
2517 INTEGER,
INTENT(in) :: ispin, base_contact
2518 COMPLEX(kind=dp),
INTENT(in) :: integr_lbound, integr_ubound
2519 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_s_global
2520 LOGICAL,
INTENT(in) :: is_circular
2522 INTEGER,
INTENT(in),
OPTIONAL :: just_contact
2524 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_add_rho_equiv_low'
2526 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: xnodes, zscale
2527 INTEGER :: handle, icontact, interval_id, ipoint, max_points, min_points, ncontacts, &
2528 npoints, npoints_exist, npoints_tmp, npoints_total, shape_id
2529 LOGICAL :: do_surface_green
2530 REAL(kind=
dp) :: conv_integr, mu_base, temperature, &
2533 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: zdata, zdata_tmp
2539 CALL timeset(routinen, handle)
2543 conv_integr = 0.5_dp*negf_control%conv_density*
pi
2545 IF (ignore_bias)
THEN
2546 mu_base = negf_control%contacts(base_contact)%fermi_level
2549 mu_base = negf_control%contacts(base_contact)%fermi_level - negf_control%contacts(base_contact)%v_external
2552 min_points = negf_control%integr_min_points
2553 max_points = negf_control%integr_max_points
2554 temperature = negf_control%contacts(base_contact)%temperature
2556 ncontacts =
SIZE(negf_env%contacts)
2557 cpassert(base_contact <= ncontacts)
2558 IF (
PRESENT(just_contact))
THEN
2560 cpassert(just_contact == base_contact)
2563 do_surface_green = .NOT.
ALLOCATED(g_surf_cache%tnodes)
2565 IF (do_surface_green)
THEN
2566 npoints = min_points
2568 npoints =
SIZE(g_surf_cache%tnodes)
2572 CALL cp_fm_get_info(rho_ao_fm, para_env=para_env, matrix_struct=fm_struct)
2575 SELECT CASE (negf_control%integr_method)
2578 ALLOCATE (xnodes(npoints))
2580 IF (is_circular)
THEN
2588 IF (do_surface_green)
THEN
2589 CALL ccquad_init(cc_env, xnodes, npoints, integr_lbound, integr_ubound, &
2590 interval_id, shape_id, matrix_s_global)
2592 CALL ccquad_init(cc_env, xnodes, npoints, integr_lbound, integr_ubound, &
2593 interval_id, shape_id, matrix_s_global, tnodes_restart=g_surf_cache%tnodes)
2596 ALLOCATE (zdata(npoints))
2597 DO ipoint = 1, npoints
2602 IF (do_surface_green)
THEN
2605 IF (
PRESENT(just_contact))
THEN
2607 DO icontact = 1, ncontacts
2608 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, npoints_total + 1:), &
2609 omega=xnodes(1:npoints), &
2610 h0=negf_env%contacts(just_contact)%h_00(ispin), &
2611 s0=negf_env%contacts(just_contact)%s_00, &
2612 h1=negf_env%contacts(just_contact)%h_01(ispin), &
2613 s1=negf_env%contacts(just_contact)%s_01, &
2614 sub_env=sub_env, v_external=0.0_dp, &
2615 conv=negf_control%conv_green, transp=(icontact == 1))
2618 DO icontact = 1, ncontacts
2619 IF (.NOT. ignore_bias) v_external = negf_control%contacts(icontact)%v_external
2621 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, npoints_total + 1:), &
2622 omega=xnodes(1:npoints), &
2623 h0=negf_env%contacts(icontact)%h_00(ispin), &
2624 s0=negf_env%contacts(icontact)%s_00, &
2625 h1=negf_env%contacts(icontact)%h_01(ispin), &
2626 s1=negf_env%contacts(icontact)%s_01, &
2628 v_external=v_external, &
2629 conv=negf_control%conv_green, transp=.false.)
2634 ALLOCATE (zscale(npoints))
2636 IF (temperature >= 0.0_dp)
THEN
2637 DO ipoint = 1, npoints
2638 zscale(ipoint) = fermi_function(xnodes(ipoint) - mu_base, temperature)
2644 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints), &
2646 ignore_bias=ignore_bias, &
2647 negf_env=negf_env, &
2648 negf_control=negf_control, &
2651 g_surf_contacts=g_surf_cache%g_surf_contacts(:, npoints_total + 1:), &
2652 g_ret_s=zdata(1:npoints), &
2653 g_ret_scale=zscale(1:npoints), &
2654 just_contact=just_contact)
2656 DEALLOCATE (xnodes, zscale)
2657 npoints_total = npoints_total + npoints
2660 CALL move_alloc(zdata, zdata_tmp)
2664 IF (cc_env%error <= conv_integr)
EXIT
2665 IF (2*(npoints_total - 1) + 1 > max_points)
EXIT
2669 do_surface_green = .true.
2671 npoints_tmp = npoints
2673 npoints =
SIZE(xnodes)
2675 ALLOCATE (zdata(npoints))
2678 DO ipoint = 1, npoints_tmp
2679 IF (
ASSOCIATED(zdata_tmp(ipoint)%matrix_struct))
THEN
2680 npoints_exist = npoints_exist + 1
2681 zdata(npoints_exist) = zdata_tmp(ipoint)
2684 DEALLOCATE (zdata_tmp)
2686 DO ipoint = npoints_exist + 1, npoints
2692 stats%error = stats%error + cc_env%error/
pi
2694 DO ipoint =
SIZE(zdata_tmp), 1, -1
2697 DEALLOCATE (zdata_tmp)
2699 CALL cp_cfm_to_fm(cc_env%integral, mtargeti=integral_imag)
2702 IF (do_surface_green)
THEN
2709 ALLOCATE (xnodes(npoints), zdata(npoints), zscale(npoints))
2711 IF (is_circular)
THEN
2717 IF (do_surface_green)
THEN
2718 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2719 shape_id, conv_integr, matrix_s_global)
2721 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2722 shape_id, conv_integr, matrix_s_global, tnodes_restart=g_surf_cache%tnodes)
2725 DO WHILE (npoints > 0 .AND. npoints_total < max_points)
2726 DO ipoint = 1, npoints
2730 IF (do_surface_green)
THEN
2733 IF (
PRESENT(just_contact))
THEN
2735 DO icontact = 1, ncontacts
2736 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, npoints_total + 1:), &
2737 omega=xnodes(1:npoints), &
2738 h0=negf_env%contacts(just_contact)%h_00(ispin), &
2739 s0=negf_env%contacts(just_contact)%s_00, &
2740 h1=negf_env%contacts(just_contact)%h_01(ispin), &
2741 s1=negf_env%contacts(just_contact)%s_01, &
2742 sub_env=sub_env, v_external=0.0_dp, &
2743 conv=negf_control%conv_green, transp=(icontact == 1))
2746 DO icontact = 1, ncontacts
2747 IF (.NOT. ignore_bias) v_external = negf_control%contacts(icontact)%v_external
2749 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, npoints_total + 1:), &
2750 omega=xnodes(1:npoints), &
2751 h0=negf_env%contacts(icontact)%h_00(ispin), &
2752 s0=negf_env%contacts(icontact)%s_00, &
2753 h1=negf_env%contacts(icontact)%h_01(ispin), &
2754 s1=negf_env%contacts(icontact)%s_01, &
2756 v_external=v_external, &
2757 conv=negf_control%conv_green, transp=.false.)
2762 IF (temperature >= 0.0_dp)
THEN
2763 DO ipoint = 1, npoints
2764 zscale(ipoint) = fermi_function(xnodes(ipoint) - mu_base, temperature)
2770 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints), &
2772 ignore_bias=ignore_bias, &
2773 negf_env=negf_env, &
2774 negf_control=negf_control, &
2777 g_surf_contacts=g_surf_cache%g_surf_contacts(:, npoints_total + 1:), &
2778 g_ret_s=zdata(1:npoints), &
2779 g_ret_scale=zscale(1:npoints), &
2780 just_contact=just_contact)
2782 npoints_total = npoints_total + npoints
2786 IF (sr_env%error <= conv_integr)
EXIT
2791 do_surface_green = .true.
2793 npoints = max_points - npoints_total
2794 IF (npoints <= 0)
EXIT
2795 IF (npoints >
SIZE(xnodes)) npoints =
SIZE(xnodes)
2801 stats%error = stats%error + sr_env%error/
pi
2803 CALL cp_cfm_to_fm(sr_env%integral, mtargeti=integral_imag)
2806 IF (do_surface_green)
THEN
2811 DEALLOCATE (xnodes, zdata, zscale)
2814 cpabort(
"Unimplemented integration method")
2817 stats%npoints = stats%npoints + npoints_total
2822 CALL timestop(handle)
2823 END SUBROUTINE negf_add_rho_equiv_low
2839 SUBROUTINE negf_add_rho_nonequiv(rho_ao_fm, stats, v_shift, negf_env, negf_control, sub_env, &
2840 ispin, base_contact, matrix_s_global, g_surf_cache)
2842 TYPE(integration_status_type),
INTENT(inout) :: stats
2843 REAL(kind=
dp),
INTENT(in) :: v_shift
2847 INTEGER,
INTENT(in) :: ispin, base_contact
2848 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_s_global
2851 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_add_rho_nonequiv'
2853 COMPLEX(kind=dp) :: fermi_base, fermi_contact, &
2854 integr_lbound, integr_ubound
2855 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: xnodes
2856 INTEGER :: handle, icontact, ipoint, jcontact, &
2857 max_points, min_points, ncontacts, &
2858 npoints, npoints_total
2859 LOGICAL :: do_surface_green
2860 REAL(kind=
dp) :: conv_density, conv_integr, eta, &
2861 ln_conv_density, mu_base, mu_contact, &
2862 temperature_base, temperature_contact
2863 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:, :) :: zdata
2869 CALL timeset(routinen, handle)
2871 ncontacts =
SIZE(negf_env%contacts)
2872 cpassert(base_contact <= ncontacts)
2875 IF (ncontacts > 2)
THEN
2876 cpabort(
"Poisson solver does not support the general NEGF setup (>2 contacts).")
2879 mu_base = negf_control%contacts(base_contact)%fermi_level - negf_control%contacts(base_contact)%v_external
2880 min_points = negf_control%integr_min_points
2881 max_points = negf_control%integr_max_points
2882 temperature_base = negf_control%contacts(base_contact)%temperature
2883 eta = negf_control%eta
2884 conv_density = negf_control%conv_density
2885 ln_conv_density = log(conv_density)
2889 conv_integr = 0.5_dp*conv_density*
pi
2891 DO icontact = 1, ncontacts
2892 IF (icontact /= base_contact)
THEN
2893 mu_contact = negf_control%contacts(icontact)%fermi_level - negf_control%contacts(icontact)%v_external
2894 temperature_contact = negf_control%contacts(icontact)%temperature
2896 integr_lbound = cmplx(min(mu_base + ln_conv_density*temperature_base, &
2897 mu_contact + ln_conv_density*temperature_contact), eta, kind=
dp)
2898 integr_ubound = cmplx(max(mu_base - ln_conv_density*temperature_base, &
2899 mu_contact - ln_conv_density*temperature_contact), eta, kind=
dp)
2901 do_surface_green = .NOT.
ALLOCATED(g_surf_cache%tnodes)
2903 IF (do_surface_green)
THEN
2904 npoints = min_points
2906 npoints =
SIZE(g_surf_cache%tnodes)
2910 ALLOCATE (xnodes(npoints))
2911 CALL cp_fm_get_info(rho_ao_fm, para_env=para_env, matrix_struct=fm_struct)
2913 IF (do_surface_green)
THEN
2914 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2917 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2918 sr_shape_linear, conv_integr, matrix_s_global, tnodes_restart=g_surf_cache%tnodes)
2921 DO WHILE (npoints > 0 .AND. npoints_total < max_points)
2923 IF (do_surface_green)
THEN
2926 DO jcontact = 1, ncontacts
2927 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(jcontact, npoints_total + 1:), &
2928 omega=xnodes(1:npoints), &
2929 h0=negf_env%contacts(jcontact)%h_00(ispin), &
2930 s0=negf_env%contacts(jcontact)%s_00, &
2931 h1=negf_env%contacts(jcontact)%h_01(ispin), &
2932 s1=negf_env%contacts(jcontact)%s_01, &
2934 v_external=negf_control%contacts(jcontact)%v_external, &
2935 conv=negf_control%conv_green, transp=.false.)
2939 ALLOCATE (zdata(ncontacts, npoints))
2941 DO ipoint = 1, npoints
2946 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints), &
2948 ignore_bias=.false., &
2949 negf_env=negf_env, &
2950 negf_control=negf_control, &
2953 g_surf_contacts=g_surf_cache%g_surf_contacts(:, npoints_total + 1:), &
2954 gret_gamma_gadv=zdata(:, 1:npoints))
2956 DO ipoint = 1, npoints
2957 fermi_base = fermi_function(cmplx(real(xnodes(ipoint), kind=
dp) - mu_base, 0.0_dp, kind=
dp), &
2959 fermi_contact = fermi_function(cmplx(real(xnodes(ipoint), kind=
dp) - mu_contact, 0.0_dp, kind=
dp), &
2960 temperature_contact)
2961 CALL cp_cfm_scale(fermi_contact - fermi_base, zdata(icontact, ipoint))
2964 npoints_total = npoints_total + npoints
2968 DO ipoint = 1, npoints
2974 IF (sr_env%error <= conv_integr)
EXIT
2977 do_surface_green = .true.
2979 npoints = max_points - npoints_total
2980 IF (npoints <= 0)
EXIT
2981 IF (npoints >
SIZE(xnodes)) npoints =
SIZE(xnodes)
2989 CALL cp_cfm_to_fm(sr_env%integral, mtargetr=integral_real)
2996 stats%error = stats%error + sr_env%error*0.5_dp/
pi
2997 stats%npoints = stats%npoints + npoints_total
3000 IF (do_surface_green)
THEN
3008 CALL timestop(handle)
3009 END SUBROUTINE negf_add_rho_nonequiv
3016 ELEMENTAL SUBROUTINE integration_status_reset(stats)
3017 TYPE(integration_status_type),
INTENT(out) :: stats
3020 stats%error = 0.0_dp
3021 END SUBROUTINE integration_status_reset
3030 ELEMENTAL FUNCTION get_method_description_string(stats, integration_method)
RESULT(method_descr)
3031 TYPE(integration_status_type),
INTENT(in) :: stats
3032 INTEGER,
INTENT(in) :: integration_method
3033 CHARACTER(len=18) :: method_descr
3035 CHARACTER(len=2) :: method_abbr
3036 CHARACTER(len=6) :: npoints_str
3038 SELECT CASE (integration_method)
3049 WRITE (npoints_str,
'(I6)') stats%npoints
3050 WRITE (method_descr,
'(A2,T4,A,T11,ES8.2E2)') method_abbr, trim(adjustl(npoints_str)), stats%error
3051 END FUNCTION get_method_description_string
3066 FUNCTION negf_compute_current(contact_id1, contact_id2, v_shift, negf_env, negf_control, sub_env, ispin, &
3067 blacs_env_global)
RESULT(current)
3068 INTEGER,
INTENT(in) :: contact_id1, contact_id2
3069 REAL(kind=
dp),
INTENT(in) :: v_shift
3073 INTEGER,
INTENT(in) :: ispin
3075 REAL(kind=
dp) :: current
3077 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_compute_current'
3078 REAL(kind=
dp),
PARAMETER :: threshold = 16.0_dp*epsilon(0.0_dp)
3080 COMPLEX(kind=dp) :: fermi_contact1, fermi_contact2, &
3081 integr_lbound, integr_ubound
3082 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: transm_coeff, xnodes
3083 COMPLEX(kind=dp),
DIMENSION(1, 1) :: transmission
3084 INTEGER :: handle, icontact, ipoint, max_points, &
3085 min_points, ncontacts, npoints, &
3087 REAL(kind=
dp) :: conv_density, energy, eta, ln_conv_density, mu_contact1, mu_contact2, &
3088 temperature_contact1, temperature_contact2, v_contact1, v_contact2
3089 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: zdata
3097 IF (.NOT.
ASSOCIATED(negf_env%s_s))
RETURN
3099 CALL timeset(routinen, handle)
3101 ncontacts =
SIZE(negf_env%contacts)
3102 cpassert(contact_id1 <= ncontacts)
3103 cpassert(contact_id2 <= ncontacts)
3104 cpassert(contact_id1 /= contact_id2)
3106 v_contact1 = negf_control%contacts(contact_id1)%v_external
3107 mu_contact1 = negf_control%contacts(contact_id1)%fermi_level - v_contact1
3108 v_contact2 = negf_control%contacts(contact_id2)%v_external
3109 mu_contact2 = negf_control%contacts(contact_id2)%fermi_level - v_contact2
3111 IF (abs(mu_contact1 - mu_contact2) < threshold)
THEN
3112 CALL timestop(handle)
3116 min_points = negf_control%integr_min_points
3117 max_points = negf_control%integr_max_points
3118 temperature_contact1 = negf_control%contacts(contact_id1)%temperature
3119 temperature_contact2 = negf_control%contacts(contact_id2)%temperature
3120 eta = negf_control%eta
3121 conv_density = negf_control%conv_density
3122 ln_conv_density = log(conv_density)
3124 integr_lbound = cmplx(min(mu_contact1 + ln_conv_density*temperature_contact1, &
3125 mu_contact2 + ln_conv_density*temperature_contact2), eta, kind=
dp)
3126 integr_ubound = cmplx(max(mu_contact1 - ln_conv_density*temperature_contact1, &
3127 mu_contact2 - ln_conv_density*temperature_contact2), eta, kind=
dp)
3130 npoints = min_points
3132 NULLIFY (fm_struct_single)
3133 CALL cp_fm_struct_create(fm_struct_single, nrow_global=1, ncol_global=1, context=blacs_env_global)
3137 ALLOCATE (transm_coeff(npoints), xnodes(npoints), zdata(npoints))
3139 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
3142 DO WHILE (npoints > 0 .AND. npoints_total < max_points)
3145 DO icontact = 1, ncontacts
3146 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, 1:npoints), &
3147 omega=xnodes(1:npoints), &
3148 h0=negf_env%contacts(icontact)%h_00(ispin), &
3149 s0=negf_env%contacts(icontact)%s_00, &
3150 h1=negf_env%contacts(icontact)%h_01(ispin), &
3151 s1=negf_env%contacts(icontact)%s_01, &
3153 v_external=negf_control%contacts(icontact)%v_external, &
3154 conv=negf_control%conv_green, transp=.false.)
3157 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints), &
3159 ignore_bias=.false., &
3160 negf_env=negf_env, &
3161 negf_control=negf_control, &
3164 g_surf_contacts=g_surf_cache%g_surf_contacts(:, 1:npoints), &
3165 transm_coeff=transm_coeff(1:npoints), &
3166 transm_contact1=contact_id1, &
3167 transm_contact2=contact_id2)
3169 DO ipoint = 1, npoints
3172 energy = real(xnodes(ipoint), kind=
dp)
3173 fermi_contact1 = fermi_function(cmplx(energy - mu_contact1, 0.0_dp, kind=
dp), temperature_contact1)
3174 fermi_contact2 = fermi_function(cmplx(energy - mu_contact2, 0.0_dp, kind=
dp), temperature_contact2)
3176 transmission(1, 1) = transm_coeff(ipoint)*(fermi_contact1 - fermi_contact2)
3182 npoints_total = npoints_total + npoints
3186 IF (sr_env%error <= negf_control%conv_density)
EXIT
3188 npoints = max_points - npoints_total
3189 IF (npoints <= 0)
EXIT
3190 IF (npoints >
SIZE(xnodes)) npoints =
SIZE(xnodes)
3203 DEALLOCATE (transm_coeff, xnodes, zdata)
3205 CALL timestop(handle)
3206 END FUNCTION negf_compute_current
3223 SUBROUTINE negf_print_dos(log_unit, energy_min, energy_max, npoints, v_shift, negf_env, &
3224 negf_control, sub_env, base_contact, just_contact, volume)
3225 INTEGER,
INTENT(in) :: log_unit
3226 REAL(kind=
dp),
INTENT(in) :: energy_min, energy_max
3227 INTEGER,
INTENT(in) :: npoints
3228 REAL(kind=
dp),
INTENT(in) :: v_shift
3232 INTEGER,
INTENT(in) :: base_contact
3233 INTEGER,
INTENT(in),
OPTIONAL :: just_contact
3234 REAL(kind=
dp),
INTENT(in),
OPTIONAL :: volume
3236 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_print_dos'
3238 CHARACTER :: uks_str
3239 CHARACTER(len=15) :: units_str
3240 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: xnodes
3241 INTEGER :: handle, icontact, ipoint, ispin, &
3242 ncontacts, npoints_bundle, &
3243 npoints_remain, nspins
3244 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: dos
3247 CALL timeset(routinen, handle)
3249 IF (
PRESENT(just_contact))
THEN
3250 nspins =
SIZE(negf_env%contacts(just_contact)%h_00)
3252 nspins =
SIZE(negf_env%h_s)
3255 IF (log_unit > 0)
THEN
3256 IF (
PRESENT(volume))
THEN
3257 units_str =
' (angstroms^-3)'
3262 IF (nspins > 1)
THEN
3270 IF (
PRESENT(just_contact))
THEN
3271 WRITE (log_unit,
'(3A,T70,I11)')
"# Density of states", trim(units_str),
" for the contact No. ", just_contact
3273 WRITE (log_unit,
'(3A)')
"# Density of states", trim(units_str),
" for the scattering region"
3276 WRITE (log_unit,
'(A,T10,A,T43,3A)')
"#",
"Energy (a.u.)",
"Number of states [alpha ", uks_str,
" beta]"
3278 WRITE (log_unit,
'("#", T3,78("-"))')
3281 ncontacts =
SIZE(negf_env%contacts)
3282 cpassert(base_contact <= ncontacts)
3283 IF (
PRESENT(just_contact))
THEN
3285 cpassert(just_contact == base_contact)
3287 mark_used(base_contact)
3289 npoints_bundle = 4*sub_env%ngroups
3290 IF (npoints_bundle > npoints) npoints_bundle = npoints
3292 ALLOCATE (dos(npoints_bundle, nspins), xnodes(npoints_bundle))
3294 npoints_remain = npoints
3295 DO WHILE (npoints_remain > 0)
3296 IF (npoints_bundle > npoints_remain) npoints_bundle = npoints_remain
3298 IF (npoints > 1)
THEN
3299 DO ipoint = 1, npoints_bundle
3300 xnodes(ipoint) = cmplx(energy_min + real(npoints - npoints_remain + ipoint - 1, kind=
dp)/ &
3301 REAL(npoints - 1, kind=
dp)*(energy_max - energy_min), negf_control%eta, kind=
dp)
3304 xnodes(ipoint) = cmplx(energy_min, negf_control%eta, kind=
dp)
3307 DO ispin = 1, nspins
3310 IF (
PRESENT(just_contact))
THEN
3311 DO icontact = 1, ncontacts
3312 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
3313 omega=xnodes(1:npoints_bundle), &
3314 h0=negf_env%contacts(just_contact)%h_00(ispin), &
3315 s0=negf_env%contacts(just_contact)%s_00, &
3316 h1=negf_env%contacts(just_contact)%h_01(ispin), &
3317 s1=negf_env%contacts(just_contact)%s_01, &
3318 sub_env=sub_env, v_external=0.0_dp, &
3319 conv=negf_control%conv_green, transp=(icontact == 1))
3322 DO icontact = 1, ncontacts
3323 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
3324 omega=xnodes(1:npoints_bundle), &
3325 h0=negf_env%contacts(icontact)%h_00(ispin), &
3326 s0=negf_env%contacts(icontact)%s_00, &
3327 h1=negf_env%contacts(icontact)%h_01(ispin), &
3328 s1=negf_env%contacts(icontact)%s_01, &
3330 v_external=negf_control%contacts(icontact)%v_external, &
3331 conv=negf_control%conv_green, transp=.false.)
3335 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints_bundle), &
3337 ignore_bias=.false., &
3338 negf_env=negf_env, &
3339 negf_control=negf_control, &
3342 g_surf_contacts=g_surf_cache%g_surf_contacts, &
3343 dos=dos(1:npoints_bundle, ispin), &
3344 just_contact=just_contact)
3349 IF (log_unit > 0)
THEN
3350 DO ipoint = 1, npoints_bundle
3351 IF (nspins > 1)
THEN
3353 WRITE (log_unit,
'(T2,F20.8,T30,2ES25.11E3)') real(xnodes(ipoint), kind=
dp), dos(ipoint, 1), dos(ipoint, 2)
3356 WRITE (log_unit,
'(T2,F20.8,T43,ES25.11E3)') real(xnodes(ipoint), kind=
dp), 2.0_dp*dos(ipoint, 1)
3361 npoints_remain = npoints_remain - npoints_bundle
3364 DEALLOCATE (dos, xnodes)
3365 CALL timestop(handle)
3366 END SUBROUTINE negf_print_dos
3382 SUBROUTINE negf_print_transmission(log_unit, energy_min, energy_max, npoints, v_shift, negf_env, &
3383 negf_control, sub_env, contact_id1, contact_id2)
3384 INTEGER,
INTENT(in) :: log_unit
3385 REAL(kind=
dp),
INTENT(in) :: energy_min, energy_max
3386 INTEGER,
INTENT(in) :: npoints
3387 REAL(kind=
dp),
INTENT(in) :: v_shift
3391 INTEGER,
INTENT(in) :: contact_id1, contact_id2
3393 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_print_transmission'
3395 CHARACTER :: uks_str
3396 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: xnodes
3397 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:, :) :: transm_coeff
3398 INTEGER :: handle, icontact, ipoint, ispin, &
3399 ncontacts, npoints_bundle, &
3400 npoints_remain, nspins
3401 REAL(kind=
dp) :: rscale
3404 CALL timeset(routinen, handle)
3406 nspins =
SIZE(negf_env%h_s)
3408 IF (nspins > 1)
THEN
3416 IF (log_unit > 0)
THEN
3417 WRITE (log_unit,
'(A)')
"# Transmission coefficient (G0 = 2 e^2/h) for the scattering region"
3419 WRITE (log_unit,
'(A,T10,A,T39,3A)')
"#",
"Energy (a.u.)",
"Transmission coefficient [alpha ", uks_str,
" beta]"
3420 WRITE (log_unit,
'("#", T3,78("-"))')
3423 ncontacts =
SIZE(negf_env%contacts)
3424 cpassert(contact_id1 <= ncontacts)
3425 cpassert(contact_id2 <= ncontacts)
3427 IF (nspins == 1)
THEN
3435 rscale = 0.5_dp*rscale
3437 npoints_bundle = 4*sub_env%ngroups
3438 IF (npoints_bundle > npoints) npoints_bundle = npoints
3440 ALLOCATE (transm_coeff(npoints_bundle, nspins), xnodes(npoints_bundle))
3442 npoints_remain = npoints
3443 DO WHILE (npoints_remain > 0)
3444 IF (npoints_bundle > npoints_remain) npoints_bundle = npoints_remain
3446 IF (npoints > 1)
THEN
3447 DO ipoint = 1, npoints_bundle
3448 xnodes(ipoint) = cmplx(energy_min + real(npoints - npoints_remain + ipoint - 1, kind=
dp)/ &
3449 REAL(npoints - 1, kind=
dp)*(energy_max - energy_min), negf_control%eta, kind=
dp)
3452 xnodes(ipoint) = cmplx(energy_min, negf_control%eta, kind=
dp)
3455 DO ispin = 1, nspins
3458 DO icontact = 1, ncontacts
3459 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
3460 omega=xnodes(1:npoints_bundle), &
3461 h0=negf_env%contacts(icontact)%h_00(ispin), &
3462 s0=negf_env%contacts(icontact)%s_00, &
3463 h1=negf_env%contacts(icontact)%h_01(ispin), &
3464 s1=negf_env%contacts(icontact)%s_01, &
3466 v_external=negf_control%contacts(icontact)%v_external, &
3467 conv=negf_control%conv_green, transp=.false.)
3470 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints_bundle), &
3472 ignore_bias=.false., &
3473 negf_env=negf_env, &
3474 negf_control=negf_control, &
3477 g_surf_contacts=g_surf_cache%g_surf_contacts, &
3478 transm_coeff=transm_coeff(1:npoints_bundle, ispin), &
3479 transm_contact1=contact_id1, &
3480 transm_contact2=contact_id2)
3485 IF (log_unit > 0)
THEN
3486 DO ipoint = 1, npoints_bundle
3487 IF (nspins > 1)
THEN
3489 WRITE (log_unit,
'(T2,F20.8,T30,2ES25.11E3)') &
3490 REAL(xnodes(ipoint), kind=
dp), rscale*real(transm_coeff(ipoint, 1:2), kind=
dp)
3493 WRITE (log_unit,
'(T2,F20.8,T43,ES25.11E3)') &
3494 REAL(xnodes(ipoint), kind=
dp), rscale*real(transm_coeff(ipoint, 1), kind=
dp)
3499 npoints_remain = npoints_remain - npoints_bundle
3502 DEALLOCATE (transm_coeff, xnodes)
3503 CALL timestop(handle)
3504 END SUBROUTINE negf_print_transmission
3518 SUBROUTINE negf_output_initial(log_unit, negf_env, sub_env, negf_control, dft_control, verbose_output, &
3520 INTEGER,
INTENT(in) :: log_unit
3525 LOGICAL,
INTENT(in) :: verbose_output, debug_output
3527 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_output_initial'
3529 CHARACTER(len=100) :: sfmt
3530 INTEGER :: handle, i, icontact, j, k, n, nrow
3531 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: target_m
3533 CALL timeset(routinen, handle)
3536 DO icontact = 1,
SIZE(negf_control%contacts)
3537 IF (log_unit > 0)
THEN
3538 WRITE (log_unit,
"(/,' The electrode',I5)") icontact
3539 WRITE (log_unit,
"( ' ------------------')")
3540 WRITE (log_unit,
"(' From the force environment:',I16)") negf_control%contacts(icontact)%force_env_index
3541 WRITE (log_unit,
"(' Number of atoms:',I27)")
SIZE(negf_control%contacts(icontact)%atomlist_bulk)
3542 IF (verbose_output)
WRITE (log_unit,
"(' Atoms belonging to a contact (from the entire system):')")
3543 IF (verbose_output)
WRITE (log_unit,
"(16I5)") negf_control%contacts(icontact)%atomlist_bulk
3544 WRITE (log_unit,
"(' Number of atoms in a primary unit cell:',I4)") &
3545 SIZE(negf_env%contacts(icontact)%atomlist_cell0)
3547 IF (log_unit > 0 .AND. verbose_output)
THEN
3548 WRITE (log_unit,
"(' Atoms belonging to a primary unit cell (from the entire system):')")
3549 WRITE (log_unit,
"(16I5)") negf_env%contacts(icontact)%atomlist_cell0
3550 WRITE (log_unit,
"(' Direction of an electrode: ',I16)") negf_env%contacts(icontact)%direction_axis
3553 IF (debug_output)
THEN
3554 CALL cp_fm_get_info(negf_env%contacts(icontact)%s_00, nrow_global=nrow)
3555 ALLOCATE (target_m(nrow, nrow))
3556 IF (log_unit > 0)
WRITE (log_unit,
"(' The number of atomic orbitals:',I13)") nrow
3557 DO k = 1, dft_control%nspins
3559 IF (log_unit > 0)
THEN
3560 WRITE (sfmt,
"('(',i0,'(E15.5))')") nrow
3561 WRITE (log_unit,
"(' The H_00 electrode Hamiltonian for spin',I2)") k
3563 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3567 IF (log_unit > 0)
THEN
3568 WRITE (log_unit,
"(' The H_01 electrode Hamiltonian for spin',I2)") k
3570 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3575 IF (log_unit > 0)
THEN
3576 WRITE (log_unit,
"(' The S_00 overlap matrix')")
3578 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3582 IF (log_unit > 0)
THEN
3583 WRITE (log_unit,
"(' The S_01 overlap matrix')")
3585 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3588 DEALLOCATE (target_m)
3593 IF (log_unit > 0)
THEN
3594 WRITE (log_unit,
"(/,' The full scattering region')")
3595 WRITE (log_unit,
"( ' --------------------------')")
3596 WRITE (log_unit,
"(' Number of atoms:',I27)")
SIZE(negf_control%atomlist_S_screening)
3597 IF (verbose_output)
WRITE (log_unit,
"(' Atoms belonging to a full scattering region:')")
3598 IF (verbose_output)
WRITE (log_unit,
"(16I5)") negf_control%atomlist_S_screening
3601 IF (debug_output)
THEN
3603 ALLOCATE (target_m(n, n))
3604 WRITE (sfmt,
"('(',i0,'(E15.5))')") n
3605 IF (log_unit > 0)
WRITE (log_unit,
"(' The number of atomic orbitals:',I14)") n
3606 DO k = 1, dft_control%nspins
3607 IF (log_unit > 0)
WRITE (log_unit,
"(' The H_s Hamiltonian for spin',I2)") k
3610 IF (log_unit > 0)
WRITE (log_unit, sfmt) (target_m(i, j), j=1, n)
3613 IF (log_unit > 0)
WRITE (log_unit,
"(' The S_s overlap matrix')")
3616 IF (log_unit > 0)
WRITE (log_unit, sfmt) (target_m(i, j), j=1, n)
3618 DEALLOCATE (target_m)
3619 IF (log_unit > 0)
WRITE (log_unit,
"(/,' Scattering region - electrode contacts')")
3620 IF (log_unit > 0)
WRITE (log_unit,
"( ' ---------------------------------------')")
3621 ALLOCATE (target_m(n, nrow))
3622 DO icontact = 1,
SIZE(negf_control%contacts)
3623 IF (log_unit > 0)
WRITE (log_unit,
"(/,' The contact',I5)") icontact
3624 IF (log_unit > 0)
WRITE (log_unit,
"( ' ----------------')")
3625 DO k = 1, dft_control%nspins
3627 IF (log_unit > 0)
THEN
3628 WRITE (log_unit,
"(' The H_sc Hamiltonian for spin',I2)") k
3630 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3635 IF (log_unit > 0)
THEN
3636 WRITE (log_unit,
"(' The S_sc overlap matrix')")
3638 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3642 DEALLOCATE (target_m)
3645 IF (log_unit > 0)
THEN
3646 WRITE (log_unit,
"(/,' NEGF| Number of MPI processes: ',I5)") sub_env%mpi_comm_global%num_pe
3647 WRITE (log_unit,
"(' NEGF| Maximal number of processes per energy point:',I5)") negf_control%nprocs
3648 WRITE (log_unit,
"(' NEGF| Number of parallel MPI (energy) groups: ',I5)") sub_env%ngroups
3651 CALL timestop(handle)
3652 END SUBROUTINE negf_output_initial
3662 SUBROUTINE negf_write_restart(filename, negf_env, negf_control)
3663 CHARACTER(LEN=*),
INTENT(IN) :: filename
3667 INTEGER :: icontact, ncontacts, print_unit
3669 CALL open_file(file_name=filename, file_status=
"REPLACE", &
3670 file_form=
"FORMATTED", file_action=
"WRITE", &
3671 file_position=
"REWIND", unit_number=print_unit)
3673 WRITE (print_unit, *)
'This file is created automatically with restart files.'
3674 WRITE (print_unit, *)
'Do not remove it if you use any of restart files!'
3676 ncontacts =
SIZE(negf_control%contacts)
3678 DO icontact = 1, ncontacts
3679 WRITE (print_unit, *)
'icontact', icontact,
' fermi_energy', negf_env%contacts(icontact)%fermi_energy
3680 WRITE (print_unit, *)
'icontact', icontact,
' nelectrons_qs_cell0', negf_env%contacts(icontact)%nelectrons_qs_cell0
3681 WRITE (print_unit, *)
'icontact', icontact,
' nelectrons_qs_cell1', negf_env%contacts(icontact)%nelectrons_qs_cell1
3684 WRITE (print_unit, *)
'nelectrons_ref', negf_env%nelectrons_ref
3685 WRITE (print_unit, *)
'nelectrons ', negf_env%nelectrons
3689 END SUBROUTINE negf_write_restart
3699 SUBROUTINE negf_read_restart(filename, negf_env, negf_control)
3700 CHARACTER(LEN=*),
INTENT(IN) :: filename
3705 INTEGER :: i, icontact, ncontacts, print_unit
3707 CALL open_file(file_name=filename, file_status=
"OLD", &
3708 file_form=
"FORMATTED", file_action=
"READ", &
3709 file_position=
"REWIND", unit_number=print_unit)
3711 READ (print_unit, *) a
3712 READ (print_unit, *) a
3714 ncontacts =
SIZE(negf_control%contacts)
3716 DO icontact = 1, ncontacts
3717 READ (print_unit, *) a, i, a, negf_env%contacts(icontact)%fermi_energy
3718 READ (print_unit, *) a, i, a, negf_env%contacts(icontact)%nelectrons_qs_cell0
3719 READ (print_unit, *) a, i, a, negf_env%contacts(icontact)%nelectrons_qs_cell1
3722 READ (print_unit, *) a, negf_env%nelectrons_ref
3723 READ (print_unit, *) a, negf_env%nelectrons
3727 END SUBROUTINE negf_read_restart
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public papior2017
integer, save, public bailey2006
methods related to the blacs parallel environment
Basic linear algebra operations for complex full matrices.
subroutine, public cp_cfm_scale_and_add(alpha, matrix_a, beta, matrix_b)
Scale and add two BLACS matrices (a = alpha*a + beta*b).
subroutine, public cp_cfm_trace(matrix_a, matrix_b, trace)
Returns the trace of matrix_a^T matrix_b, i.e sum_{i,j}(matrix_a(i,j)*matrix_b(i,j)) .
Represents a complex full matrix distributed on many processors.
subroutine, public cp_cfm_get_submatrix(fm, target_m, start_row, start_col, n_rows, n_cols, transpose)
Extract a sub-matrix from the full matrix: op(target_m)(1:n_rows,1:n_cols) = fm(start_row:start_row+n...
subroutine, public cp_cfm_release(matrix)
Releases a full matrix.
subroutine, public cp_cfm_start_copy_general(source, destination, para_env, info)
Initiate the copy operation: get distribution data, post MPI isend and irecvs.
subroutine, public cp_cfm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
Creates a new full matrix with the given structure.
subroutine, public cp_cfm_cleanup_copy_general(info)
Complete the copy operation: wait for comms clean up MPI state.
subroutine, public cp_cfm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, matrix_struct, para_env)
Returns information about a full matrix.
subroutine, public cp_cfm_set_submatrix(matrix, new_values, start_row, start_col, n_rows, n_cols, alpha, beta, transpose)
Set a sub-matrix of the full matrix: matrix(start_row:start_row+n_rows,start_col:start_col+n_cols) = ...
subroutine, public cp_cfm_to_fm(msource, mtargetr, mtargeti)
Copy real and imaginary parts of a complex full matrix into separate real-value full matrices.
subroutine, public cp_cfm_finish_copy_general(destination, info)
Complete the copy operation: wait for comms, unpack, clean up MPI state.
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_deallocate_matrix(matrix)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_init_p(matrix)
...
subroutine, public dbcsr_dot(matrix_a, matrix_b, trace)
Computes the dot product of two matrices, also known as the trace of their matrix product.
DBCSR operations in CP2K.
Utility routines to open and close files. Tracking of preconnections.
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_scale_and_add(alpha, matrix_a, beta, matrix_b)
calc A <- alpha*A + beta*B optimized for alpha == 1.0 (just add beta*B) and beta == 0....
subroutine, public cp_fm_scale(alpha, matrix_a)
scales a matrix matrix_a = alpha * matrix_b
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
subroutine, public cp_fm_copy_general(source, destination, para_env)
General copy of a fm matrix to another fm matrix. Uses non-blocking MPI rather than ScaLAPACK.
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp, nrow, ncol, set_zero)
creates a new full matrix with the given structure
subroutine, public cp_fm_add_to_element(matrix, irow_global, icol_global, alpha)
...
subroutine, public cp_fm_set_submatrix(fm, new_values, start_row, start_col, n_rows, n_cols, alpha, beta, transpose)
sets a submatrix of a full matrix fm(start_row:start_row+n_rows,start_col:start_col+n_cols) = alpha*o...
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_get_submatrix(fm, target_m, start_row, start_col, n_rows, n_cols, transpose)
gets a submatrix of a full matrix op(target_m)(1:n_rows,1:n_cols) =fm(start_row:start_row+n_rows,...
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer, parameter, public debug_print_level
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
integer, parameter, public cp_p_file
integer, parameter, public high_print_level
subroutine, public cp_iterate(iteration_info, last, iter_nr, increment, iter_nr_out)
adds one to the actual iteration
subroutine, public cp_rm_iter_level(iteration_info, level_name, n_rlevel_att)
Removes an iteration level.
integer function, public cp_print_key_should_output(iteration_info, basis_section, print_key_path, used_print_key, first_time)
returns what should be done with the given property if btest(res,cp_p_store) then the property should...
subroutine, public cp_add_iter_level(iteration_info, level_name, n_rlevel_new)
Adds an iteration level.
types that represent a subsys, i.e. a part of the system
Interface for the force calculations.
recursive subroutine, public force_env_get(force_env, in_use, fist_env, qs_env, meta_env, fp_env, subsys, para_env, potential_energy, additional_potential, kinetic_energy, harmonic_shell, kinetic_shell, cell, sub_force_env, qmmm_env, qmmmx_env, eip_env, pwdft_env, globenv, input, force_env_section, method_name_id, root_section, mixed_env, nnp_env, embed_env, ipi_env)
returns various attributes about the force environment
Define type storing the global information of a run. Keep the amount of stored data small....
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
integer, parameter, public default_path_length
Types and basic routines needed for a kpoint calculation.
subroutine, public get_kpoint_info(kpoint, kp_scheme, nkp_grid, kp_shift, symmetry, verbose, full_grid, use_real_wfn, eps_geo, parallel_group_size, kp_range, nkp, xkp, wkp, para_env, blacs_env_all, para_env_kp, para_env_inter_kp, blacs_env, kp_env, kp_aux_env, mpools, iogrp, nkp_groups, kp_dist, cell_to_index, index_to_cell, sab_nl, sab_nl_nosym, inversion_symmetry_only, symmetry_backend, symmetry_reduction_method, gamma_centered)
Retrieve information from a kpoint environment.
Machine interface based on Fortran 2003 and POSIX.
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
complex(kind=dp), parameter, public z_one
real(kind=dp), parameter, public twopi
complex(kind=dp), parameter, public z_zero
Interface to the message passing library MPI.
Input control types for NEGF based quantum transport calculations.
subroutine, public negf_control_create(negf_control)
allocate control options for Non-equilibrium Green's Function calculation
subroutine, public read_negf_control(negf_control, input, subsys)
Read NEGF input parameters.
subroutine, public negf_control_release(negf_control)
release memory allocated for NEGF control options
Environment for NEGF based quantum transport calculations.
subroutine, public negf_env_release(negf_env)
Release a NEGF environment variable.
subroutine, public negf_env_create(negf_env, sub_env, negf_control, force_env, negf_mixing_section, log_unit)
Create a new NEGF environment and compute the relevant Kohn-Sham matrices.
Storage to keep precomputed surface Green's functions.
subroutine, public green_functions_cache_reorder(cache, tnodes)
Sort cached items in ascending order.
subroutine, public green_functions_cache_release(cache)
Release storage.
subroutine, public green_functions_cache_expand(cache, ncontacts, nnodes_extra)
Reallocate storage so it can handle extra 'nnodes_extra' items for each contact.
Subroutines to compute Green functions.
subroutine, public sancho_work_matrices_create(work, fm_struct)
Create work matrices required for the Lopez-Sancho algorithm.
subroutine, public sancho_work_matrices_release(work)
Release work matrices.
subroutine, public negf_contact_self_energy(self_energy_c, omega, g_surf_c, h_sc0, s_sc0, zwork1, zwork2, transp)
Compute the contact self energy at point 'omega' as self_energy_C = [omega * S_SC0 - KS_SC0] * g_surf...
subroutine, public negf_contact_broadening_matrix(gamma_c, self_energy_c)
Compute contact broadening matrix as gamma_C = i (self_energy_c^{ret.} - (self_energy_c^{ret....
subroutine, public do_sancho(g_surf, omega, h0, s0, h1, s1, conv, transp, work)
Iterative method to compute a retarded surface Green's function at the point omega.
subroutine, public negf_retarded_green_function(g_ret_s, omega, self_energy_ret_sum, h_s, s_s, v_hartree_s)
Compute the retarded Green's function at point 'omega' as G_S^{ret.} = [ omega * S_S - KS_S - \sum_{c...
Adaptive Clenshaw-Curtis quadrature algorithm to integrate a complex-valued function in a complex pla...
integer, parameter, public cc_shape_linear
subroutine, public ccquad_refine_integral(cc_env)
Refine approximated integral.
integer, parameter, public cc_interval_full
subroutine, public ccquad_double_number_of_points(cc_env, xnodes_next)
Get the next set of points at which the integrand needs to be computed. These points are then can be ...
subroutine, public ccquad_release(cc_env)
Release a Clenshaw-Curtis quadrature environment variable.
integer, parameter, public cc_interval_half
subroutine, public ccquad_init(cc_env, xnodes, nnodes, a, b, interval_id, shape_id, weights, tnodes_restart)
Initialise a Clenshaw-Curtis quadrature environment variable.
integer, parameter, public cc_shape_arc
subroutine, public ccquad_reduce_and_append_zdata(cc_env, zdata_next)
Prepare Clenshaw-Curtis environment for the subsequent refinement of the integral.
Adaptive Simpson's rule algorithm to integrate a complex-valued function in a complex plane.
integer, parameter, public sr_shape_arc
subroutine, public simpsonrule_refine_integral(sr_env, zdata_next)
Compute integral using the simpson's rules.
subroutine, public simpsonrule_init(sr_env, xnodes, nnodes, a, b, shape_id, conv, weights, tnodes_restart)
Initialise a Simpson's rule environment variable.
subroutine, public simpsonrule_release(sr_env)
Release a Simpson's rule environment variable.
integer, parameter, public sr_shape_linear
subroutine, public simpsonrule_get_next_nodes(sr_env, xnodes_next, nnodes)
Get the next set of nodes where to compute integrand.
Routines for reading and writing NEGF restart files.
subroutine, public negf_restart_file_name(filename, exist, negf_section, logger, icontact, ispin, h00, h01, s00, s01, h, s, hc, sc, h_scf)
Checks if the restart file exists and returns the filename.
subroutine, public negf_read_matrix_from_file(filename, matrix)
Reads full matrix from a file.
Helper routines to manipulate with matrices.
subroutine, public invert_cell_to_index(cell_to_index, nimages, index_to_cell)
Invert cell_to_index mapping between unit cells and DBCSR matrix images.
subroutine, public negf_copy_fm_submat_to_dbcsr(fm, matrix, atomlist_row, atomlist_col, subsys)
Populate relevant blocks of the DBCSR matrix using data from a ScaLAPACK matrix. Irrelevant blocks of...
subroutine, public negf_copy_sym_dbcsr_to_fm_submat(matrix, fm, atomlist_row, atomlist_col, subsys, mpi_comm_global, do_upper_diag, do_lower)
Extract part of the DBCSR matrix based on selected atoms and copy it into a dense matrix.
NEGF based quantum transport calculations.
subroutine, public do_negf(force_env)
Perform NEGF calculation.
Environment for NEGF based quantum transport calculations.
subroutine, public negf_sub_env_release(sub_env)
Release a parallel (sub)group environment.
subroutine, public negf_sub_env_create(sub_env, negf_control, blacs_env_global, blacs_grid_layout, blacs_repeatable)
Split MPI communicator to create a set of parallel (sub)groups.
basic linear algebra operations for full matrixes
Definition of physical constants:
real(kind=dp), parameter, public e_charge
real(kind=dp), parameter, public kelvin
real(kind=dp), parameter, public seconds
real(kind=dp), parameter, public evolt
module that contains the definitions of the scf types
integer, parameter, public broyden_mixing_nr
integer, parameter, public modified_broyden_mixing_nr
integer, parameter, public direct_mixing_nr
integer, parameter, public multisecant_mixing_nr
integer, parameter, public pulay_mixing_nr
integer, parameter, public gspace_mixing_nr
Perform a QUICKSTEP wavefunction optimization (single point)
subroutine, public qs_energies(qs_env, consistent_energies, calc_forces)
Driver routine for QUICKSTEP single point wavefunction optimization.
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.
subroutine, public gspace_mixing(qs_env, mixing_method, mixing_store, rho, para_env, iter_count)
Driver for the g-space mixing, calls the proper routine given the requested method.
routines that build the Kohn-Sham matrix (i.e calculate the coulomb and xc parts
subroutine, public rebuild_ks_matrix(qs_env, calculate_forces, just_energy, print_active)
Constructs a new Khon-Sham matrix.
elemental subroutine, public charge_mixing_init(mixing_store)
initialiation needed when charge mixing is used
subroutine, public mixing_init(mixing_method, rho, mixing_store, para_env, rho_atom)
initialiation needed when gspace mixing is used
subroutine, public mixing_allocate(qs_env, mixing_method, p_mix_new, p_delta, nspins, mixing_store)
allocation needed when density mixing is used
methods of the rho structure (defined in qs_rho_types)
subroutine, public qs_rho_update_rho(rho_struct, qs_env, rho_xc_external, local_rho_set, task_list_external, task_list_external_soft, pw_env_external, para_env_external)
updates rho_r and rho_g to the rhorho_ao. if use_kinetic_energy_density also computes tau_r and tau_g...
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...
groups fairly general SCF methods, so that modules other than qs_scf can use them too split off from ...
subroutine, public scf_env_density_mixing(p_mix_new, mixing_store, rho_ao, para_env, iter_delta, iter_count, diis, invert)
perform (if requested) a density mixing
types that represent a quickstep subsys
Utilities for string manipulations.
subroutine, public integer_to_string(inumber, string)
Converts an integer number to a string. The WRITE statement will return an error message,...
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
Stores the state of a copy between cp_cfm_start_copy_general and cp_cfm_finish_copy_general.
Represent a complex full matrix.
keeps the information about the structure of a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
represents a system: atoms, molecules, their pos,vel,...
allows for the creation of an array of force_env
wrapper to abstract the force evaluation of the various methods
contains the initially parsed file and the initial parallel environment
Contains information about kpoints.
stores all the informations relevant to an mpi environment
Input parameters related to the NEGF run.
Storage to keep surface Green's functions.
Adaptive Clenshaw-Curtis environment.
A structure to store data needed for adaptive Simpson's rule algorithm.
Parallel (sub)group environment.
keeps the density in various representations, keeping track of which ones are valid.