123#include "./base/base_uses.f90"
128 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'negf_methods'
129 LOGICAL,
PARAMETER,
PRIVATE :: debug_this_module = .true.
138 TYPE integration_status_type
139 INTEGER :: npoints = -1
140 REAL(kind=
dp) :: error = -1.0_dp
141 END TYPE integration_status_type
155 CHARACTER(LEN=*),
PARAMETER :: routinen =
'do_negf'
157 CHARACTER(len=default_string_length) :: contact_id_str
158 INTEGER :: handle, icontact, ispin, log_unit, &
159 ncontacts, npoints, nspins, &
160 print_level, print_unit
161 LOGICAL :: debug_output, should_output, &
163 REAL(kind=
dp) :: energy_max, energy_min
164 REAL(kind=
dp),
DIMENSION(2) :: current
177 negf_mixing_section, negf_section, &
178 print_section, root_section
180 CALL timeset(routinen, handle)
187 NULLIFY (blacs_env, cp_subsys, global_env, qs_env, root_section, sub_force_env)
188 CALL force_env_get(force_env, globenv=global_env, qs_env=qs_env, root_section=root_section, &
189 sub_force_env=sub_force_env, subsys=cp_subsys)
191 CALL get_qs_env(qs_env, blacs_env=blacs_env, para_env=para_env_global)
197 NULLIFY (negf_control)
200 CALL get_qs_env(qs_env, dft_control=dft_control)
203 log_unit =
cp_print_key_unit_nr(logger, negf_section,
"PRINT%PROGRAM_RUN_INFO", extension=
".Log")
205 IF (log_unit > 0)
THEN
206 WRITE (log_unit,
'(/,T2,79("-"))')
207 WRITE (log_unit,
'(T27,A,T62)')
"NEGF calculation is started"
208 WRITE (log_unit,
'(T2,79("-"))')
213 CALL section_vals_val_get(negf_section,
"PRINT%PROGRAM_RUN_INFO%PRINT_LEVEL", i_val=print_level)
214 SELECT CASE (print_level)
216 verbose_output = .true.
218 verbose_output = .true.
219 debug_output = .true.
221 verbose_output = .false.
222 debug_output = .false.
225 IF (log_unit > 0)
THEN
226 WRITE (log_unit,
"(/,' THE RELEVANT HAMILTONIAN AND OVERLAP MATRICES FROM DFT')")
227 WRITE (log_unit,
"( ' ------------------------------------------------------')")
230 CALL negf_sub_env_create(sub_env, negf_control, blacs_env, global_env%blacs_grid_layout, global_env%blacs_repeatable)
231 CALL negf_env_create(negf_env, sub_env, negf_control, force_env, negf_mixing_section, log_unit)
233 IF (log_unit > 0)
THEN
234 WRITE (log_unit,
"(/,' NEGF| The initial Hamiltonian and Overlap matrices are calculated.')")
237 CALL negf_output_initial(log_unit, negf_env, sub_env, negf_control, dft_control, verbose_output, debug_output)
244 ncontacts =
SIZE(negf_control%contacts)
245 DO icontact = 1, ncontacts
247 IF (negf_control%contacts(icontact)%force_env_index > 0)
THEN
248 CALL force_env_get(sub_force_env(negf_control%contacts(icontact)%force_env_index)%force_env, qs_env=qs_env)
253 CALL guess_fermi_level(icontact, negf_env, negf_control, sub_env, qs_env, log_unit)
258 IF (should_output)
THEN
266 middle_name=trim(adjustl(contact_id_str)), &
267 file_status=
"REPLACE")
268 CALL negf_print_dos(print_unit, energy_min, energy_max, npoints, &
269 v_shift=0.0_dp, negf_env=negf_env, negf_control=negf_control, &
270 sub_env=sub_env, base_contact=icontact, just_contact=icontact)
278 IF (ncontacts > 1)
THEN
283 CALL shift_potential(negf_env, negf_control, sub_env, qs_env, base_contact=1, log_unit=log_unit)
287 CALL converge_density(negf_env, negf_control, sub_env, qs_env, negf_control%v_shift, base_contact=1, log_unit=log_unit)
291 CALL get_qs_env(qs_env, dft_control=dft_control)
293 nspins = dft_control%nspins
295 cpassert(nspins <= 2)
301 current(ispin) = negf_compute_current(contact_id1=1, contact_id2=2, &
302 v_shift=negf_control%v_shift, &
304 negf_control=negf_control, &
307 blacs_env_global=blacs_env)
310 IF (log_unit > 0)
THEN
312 WRITE (log_unit,
'(/,T2,A,T60,ES20.7E2)')
"NEGF| Alpha-spin electric current (A)", current(1)
313 WRITE (log_unit,
'(T2,A,T60,ES20.7E2)')
"NEGF| Beta-spin electric current (A)", current(2)
315 WRITE (log_unit,
'(/,T2,A,T60,ES20.7E2)')
"NEGF| Electric current (A)", 2.0_dp*current(1)
324 IF (should_output)
THEN
332 middle_name=trim(adjustl(contact_id_str)), &
333 file_status=
"REPLACE")
335 CALL negf_print_dos(print_unit, energy_min, energy_max, npoints, negf_control%v_shift, &
336 negf_env=negf_env, negf_control=negf_control, &
337 sub_env=sub_env, base_contact=1)
346 IF (should_output)
THEN
353 extension=
".transm", &
354 middle_name=trim(adjustl(contact_id_str)), &
355 file_status=
"REPLACE")
357 CALL negf_print_transmission(print_unit, energy_min, energy_max, npoints, negf_control%v_shift, &
358 negf_env=negf_env, negf_control=negf_control, &
359 sub_env=sub_env, contact_id1=1, contact_id2=2)
366 IF (log_unit > 0)
THEN
367 WRITE (log_unit,
'(/,T2,79("-"))')
368 WRITE (log_unit,
'(T27,A,T62)')
"NEGF calculation is finished"
369 WRITE (log_unit,
'(T2,79("-"))')
375 CALL timestop(handle)
390 SUBROUTINE guess_fermi_level(contact_id, negf_env, negf_control, sub_env, qs_env, log_unit)
391 INTEGER,
INTENT(in) :: contact_id
396 INTEGER,
INTENT(in) :: log_unit
398 CHARACTER(LEN=*),
PARAMETER :: routinen =
'guess_fermi_level'
401 CHARACTER(len=default_string_length) :: temperature_str
402 COMPLEX(kind=dp) :: lbound_cpath, lbound_lpath, ubound_lpath
403 INTEGER :: direction_axis_abs, handle, image, &
404 ispin, nao, nimages, nspins, step
405 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: index_to_cell
406 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index
407 LOGICAL :: do_kpoints
408 REAL(kind=
dp) :: delta_au, delta_ef, energy_ubound_minus_fermi, fermi_level_guess, &
409 fermi_level_max, fermi_level_min, nelectrons_guess, nelectrons_max, nelectrons_min, &
410 nelectrons_qs_cell0, nelectrons_qs_cell1, offset_au, rscale, t1, t2, trace
415 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_s_kp, rho_ao_qs_kp
418 TYPE(integration_status_type) :: stats
425 CALL timeset(routinen, handle)
427 IF (log_unit > 0)
THEN
428 WRITE (temperature_str,
'(F11.3)') negf_control%contacts(contact_id)%temperature*
kelvin
429 WRITE (log_unit,
'(/,T2,A,I3)')
"FERMI LEVEL OF CONTACT ", contact_id
430 WRITE (log_unit,
"( ' --------------------------')")
431 WRITE (log_unit,
'(A)')
" Temperature "//trim(adjustl(temperature_str))//
" Kelvin"
434 IF (negf_control%contacts(contact_id)%compute_fermi_level)
THEN
437 blacs_env=blacs_env_global, &
438 dft_control=dft_control, &
439 do_kpoints=do_kpoints, &
441 matrix_s_kp=matrix_s_kp, &
442 para_env=para_env_global, &
443 rho=rho_struct, subsys=subsys)
444 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_qs_kp)
446 nimages = dft_control%nimages
447 nspins = dft_control%nspins
448 direction_axis_abs = abs(negf_env%contacts(contact_id)%direction_axis)
450 cpassert(
SIZE(negf_env%contacts(contact_id)%h_00) == nspins)
452 IF (sub_env%ngroups > 1)
THEN
453 NULLIFY (matrix_s_fm, fm_struct)
455 CALL cp_fm_get_info(negf_env%contacts(contact_id)%s_00, nrow_global=nao)
456 CALL cp_fm_struct_create(fm_struct, nrow_global=nao, ncol_global=nao, context=blacs_env_global)
459 ALLOCATE (matrix_s_fm)
463 IF (sub_env%group_distribution(sub_env%mepos_global) == 0)
THEN
464 CALL cp_fm_copy_general(negf_env%contacts(contact_id)%s_00, matrix_s_fm, para_env_global)
469 matrix_s_fm => negf_env%contacts(contact_id)%s_00
477 ALLOCATE (cell_to_index(0:0, 0:0, 0:0))
478 cell_to_index(0, 0, 0) = 1
481 ALLOCATE (index_to_cell(3, nimages))
483 IF (.NOT. do_kpoints)
DEALLOCATE (cell_to_index)
485 IF (nspins == 1)
THEN
493 nelectrons_qs_cell0 = 0.0_dp
494 nelectrons_qs_cell1 = 0.0_dp
495 IF (negf_control%contacts(contact_id)%force_env_index > 0)
THEN
496 DO image = 1, nimages
497 IF (index_to_cell(direction_axis_abs, image) == 0)
THEN
499 CALL dbcsr_dot(rho_ao_qs_kp(ispin, image)%matrix, matrix_s_kp(1, image)%matrix, trace)
500 nelectrons_qs_cell0 = nelectrons_qs_cell0 + trace
502 ELSE IF (abs(index_to_cell(direction_axis_abs, image)) == 1)
THEN
504 CALL dbcsr_dot(rho_ao_qs_kp(ispin, image)%matrix, matrix_s_kp(1, image)%matrix, trace)
505 nelectrons_qs_cell1 = nelectrons_qs_cell1 + trace
511 CALL cp_fm_trace(negf_env%contacts(contact_id)%rho_00(ispin), &
512 negf_env%contacts(contact_id)%s_00, trace)
513 nelectrons_qs_cell0 = nelectrons_qs_cell0 + trace
514 CALL cp_fm_trace(negf_env%contacts(contact_id)%rho_01(ispin), &
515 negf_env%contacts(contact_id)%s_01, trace)
516 nelectrons_qs_cell1 = nelectrons_qs_cell1 + 2.0_dp*trace
520 DEALLOCATE (index_to_cell)
522 IF (log_unit > 0)
THEN
523 WRITE (log_unit,
'(A)')
" Computing the Fermi level of bulk electrode"
524 WRITE (log_unit,
'(T2,A,T60,F20.10,/)')
"Electronic density of the electrode unit cell:", &
525 -1.0_dp*(nelectrons_qs_cell0 + nelectrons_qs_cell1)
526 WRITE (log_unit,
'(T3,A)')
"Step Integration method Time Fermi level Convergence (density)"
527 WRITE (log_unit,
'(T3,78("-"))')
533 IF (negf_control%homo_lumo_gap > 0.0_dp)
THEN
534 IF (negf_control%contacts(contact_id)%refine_fermi_level)
THEN
535 fermi_level_min = negf_control%contacts(contact_id)%fermi_level
537 fermi_level_min = energy%efermi
539 fermi_level_max = fermi_level_min + negf_control%homo_lumo_gap
541 IF (negf_control%contacts(contact_id)%refine_fermi_level)
THEN
542 fermi_level_max = negf_control%contacts(contact_id)%fermi_level
544 fermi_level_max = energy%efermi
546 fermi_level_min = fermi_level_max + negf_control%homo_lumo_gap
550 lbound_cpath = cmplx(negf_control%energy_lbound, negf_control%eta, kind=
dp)
551 delta_au = real(negf_control%delta_npoles, kind=
dp)*
twopi*negf_control%contacts(contact_id)%temperature
552 offset_au = real(negf_control%gamma_kT, kind=
dp)*negf_control%contacts(contact_id)%temperature
553 energy_ubound_minus_fermi = -2.0_dp*log(negf_control%conv_density)*negf_control%contacts(contact_id)%temperature
561 fermi_level_guess = fermi_level_min
563 fermi_level_guess = fermi_level_max
565 fermi_level_guess = fermi_level_min - (nelectrons_min - nelectrons_qs_cell0)* &
566 (fermi_level_max - fermi_level_min)/(nelectrons_max - nelectrons_min)
569 negf_control%contacts(contact_id)%fermi_level = fermi_level_guess
570 nelectrons_guess = 0.0_dp
572 lbound_lpath = cmplx(fermi_level_guess - offset_au, delta_au, kind=
dp)
573 ubound_lpath = cmplx(fermi_level_guess + energy_ubound_minus_fermi, delta_au, kind=
dp)
575 CALL integration_status_reset(stats)
578 CALL negf_init_rho_equiv_residuals(rho_ao_fm=rho_ao_fm, &
580 ignore_bias=.true., &
582 negf_control=negf_control, &
585 base_contact=contact_id, &
586 just_contact=contact_id)
588 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_fm, &
591 ignore_bias=.true., &
593 negf_control=negf_control, &
596 base_contact=contact_id, &
597 integr_lbound=lbound_cpath, &
598 integr_ubound=lbound_lpath, &
599 matrix_s_global=matrix_s_fm, &
600 is_circular=.true., &
601 g_surf_cache=g_surf_cache, &
602 just_contact=contact_id)
605 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_fm, &
608 ignore_bias=.true., &
610 negf_control=negf_control, &
613 base_contact=contact_id, &
614 integr_lbound=lbound_lpath, &
615 integr_ubound=ubound_lpath, &
616 matrix_s_global=matrix_s_fm, &
617 is_circular=.false., &
618 g_surf_cache=g_surf_cache, &
619 just_contact=contact_id)
623 nelectrons_guess = nelectrons_guess + trace
625 nelectrons_guess = nelectrons_guess*rscale
629 IF (log_unit > 0)
THEN
630 WRITE (log_unit,
'(T2,I5,T12,A,T32,F8.1,T42,F15.8,T60,ES20.5E2)') &
631 step, get_method_description_string(stats, negf_control%integr_method), &
632 t2 - t1, fermi_level_guess, nelectrons_guess - nelectrons_qs_cell0
635 IF (abs(nelectrons_qs_cell0 - nelectrons_guess) < negf_control%conv_density)
EXIT
639 nelectrons_min = nelectrons_guess
641 nelectrons_max = nelectrons_guess
643 IF (fermi_level_guess < fermi_level_min)
THEN
644 fermi_level_max = fermi_level_min
645 nelectrons_max = nelectrons_min
646 fermi_level_min = fermi_level_guess
647 nelectrons_min = nelectrons_guess
648 ELSE IF (fermi_level_guess > fermi_level_max)
THEN
649 fermi_level_min = fermi_level_max
650 nelectrons_min = nelectrons_max
651 fermi_level_max = fermi_level_guess
652 nelectrons_max = nelectrons_guess
653 ELSE IF (fermi_level_max - fermi_level_guess < fermi_level_guess - fermi_level_min)
THEN
654 fermi_level_max = fermi_level_guess
655 nelectrons_max = nelectrons_guess
657 fermi_level_min = fermi_level_guess
658 nelectrons_min = nelectrons_guess
665 negf_control%contacts(contact_id)%fermi_level = fermi_level_guess
667 IF (sub_env%ngroups > 1)
THEN
669 DEALLOCATE (matrix_s_fm)
674 IF (negf_control%contacts(contact_id)%shift_fermi_level)
THEN
675 delta_ef = negf_control%contacts(contact_id)%fermi_level_shifted - negf_control%contacts(contact_id)%fermi_level
676 IF (log_unit > 0)
WRITE (log_unit,
"(/,' The energies are shifted by (a.u.):',F18.8)") delta_ef
677 IF (log_unit > 0)
WRITE (log_unit,
"(' (eV):',F18.8)") delta_ef*
evolt
678 negf_control%contacts(contact_id)%fermi_level = negf_control%contacts(contact_id)%fermi_level_shifted
679 CALL get_qs_env(qs_env, dft_control=dft_control)
680 nspins = dft_control%nspins
681 CALL cp_fm_get_info(negf_env%contacts(contact_id)%s_00, nrow_global=nao)
689 IF (log_unit > 0)
THEN
690 WRITE (temperature_str,
'(F11.3)') negf_control%contacts(contact_id)%temperature*
kelvin
691 WRITE (log_unit,
'(/,T2,A,I0)')
"NEGF| Contact No. ", contact_id
692 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| Fermi level at "//trim(adjustl(temperature_str))// &
693 " Kelvin (a.u.):", negf_control%contacts(contact_id)%fermi_level
694 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| (eV):", &
695 negf_control%contacts(contact_id)%fermi_level*
evolt
696 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| Electric potential (a.u.):", &
697 negf_control%contacts(contact_id)%v_external
698 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| (Volt):", &
699 negf_control%contacts(contact_id)%v_external*
evolt
700 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| Electro-chemical potential Ef-|e|V (a.u.):", &
701 (negf_control%contacts(contact_id)%fermi_level - negf_control%contacts(contact_id)%v_external)
702 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| (eV):", &
703 (negf_control%contacts(contact_id)%fermi_level - negf_control%contacts(contact_id)%v_external)*
evolt
706 CALL timestop(handle)
707 END SUBROUTINE guess_fermi_level
720 SUBROUTINE shift_potential(negf_env, negf_control, sub_env, qs_env, base_contact, log_unit)
725 INTEGER,
INTENT(in) :: base_contact, log_unit
727 CHARACTER(LEN=*),
PARAMETER :: routinen =
'shift_potential'
730 COMPLEX(kind=dp) :: lbound_cpath, ubound_cpath, ubound_lpath
731 INTEGER :: handle, ispin, iter_count, nao, &
733 LOGICAL :: do_kpoints
734 REAL(kind=
dp) :: mu_base, nelectrons_guess, nelectrons_max, nelectrons_min, nelectrons_ref, &
735 t1, t2, temperature, trace, v_shift_guess, v_shift_max, v_shift_min
738 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: rho_ao_fm
740 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: rho_ao_qs_kp
743 DIMENSION(:) :: g_surf_circular, g_surf_linear
744 TYPE(integration_status_type) :: stats
749 ncontacts =
SIZE(negf_control%contacts)
751 IF (.NOT. (
ALLOCATED(negf_env%h_s) .AND.
ALLOCATED(negf_env%h_sc) .AND. &
752 ASSOCIATED(negf_env%s_s) .AND.
ALLOCATED(negf_env%s_sc)))
RETURN
753 IF (ncontacts < 2)
RETURN
754 IF (negf_control%v_shift_maxiters == 0)
RETURN
756 CALL timeset(routinen, handle)
758 CALL get_qs_env(qs_env, blacs_env=blacs_env, do_kpoints=do_kpoints, dft_control=dft_control, &
759 para_env=para_env, rho=rho_struct, subsys=subsys)
760 cpassert(.NOT. do_kpoints)
766 IF (sub_env%ngroups > 1)
THEN
767 NULLIFY (matrix_s_fm, fm_struct)
772 ALLOCATE (matrix_s_fm)
776 IF (sub_env%group_distribution(sub_env%mepos_global) == 0)
THEN
782 matrix_s_fm => negf_env%s_s
787 nspins =
SIZE(negf_env%h_s)
789 mu_base = negf_control%contacts(base_contact)%fermi_level
792 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_qs_kp)
795 nelectrons_ref = 0.0_dp
796 ALLOCATE (rho_ao_fm(nspins))
801 fm=rho_ao_fm(ispin), &
802 atomlist_row=negf_control%atomlist_S_screening, &
803 atomlist_col=negf_control%atomlist_S_screening, &
804 subsys=subsys, mpi_comm_global=para_env, &
805 do_upper_diag=.true., do_lower=.true.)
807 CALL cp_fm_trace(rho_ao_fm(ispin), matrix_s_fm, trace)
808 nelectrons_ref = nelectrons_ref + trace
811 IF (log_unit > 0)
THEN
812 WRITE (log_unit,
'(/,T2,A)')
"COMPUTE SHIFT IN HARTREE POTENTIAL"
813 WRITE (log_unit,
"( ' ----------------------------------')")
814 WRITE (log_unit,
'(/,T2,A,T55,F25.14,/)')
"Initial electronic density of the scattering region:", -1.0_dp*nelectrons_ref
815 WRITE (log_unit,
'(T3,A)')
"Step Integration method Time V shift Convergence (density)"
816 WRITE (log_unit,
'(T3,78("-"))')
819 temperature = negf_control%contacts(base_contact)%temperature
822 lbound_cpath = cmplx(negf_control%energy_lbound, negf_control%eta, kind=
dp)
823 ubound_cpath = cmplx(mu_base - real(negf_control%gamma_kT, kind=
dp)*temperature, &
824 REAL(negf_control%delta_npoles, kind=
dp)*
twopi*temperature, kind=
dp)
827 ubound_lpath = cmplx(mu_base - log(negf_control%conv_density)*temperature, &
828 REAL(negf_control%delta_npoles, kind=
dp)*
twopi*temperature, kind=
dp)
830 v_shift_min = negf_control%v_shift
831 v_shift_max = negf_control%v_shift + negf_control%v_shift_offset
833 ALLOCATE (g_surf_circular(nspins), g_surf_linear(nspins))
835 DO iter_count = 1, negf_control%v_shift_maxiters
836 SELECT CASE (iter_count)
838 v_shift_guess = v_shift_min
840 v_shift_guess = v_shift_max
842 v_shift_guess = v_shift_min - (nelectrons_min - nelectrons_ref)* &
843 (v_shift_max - v_shift_min)/(nelectrons_max - nelectrons_min)
847 CALL integration_status_reset(stats)
851 CALL negf_init_rho_equiv_residuals(rho_ao_fm=rho_ao_fm(ispin), &
852 v_shift=v_shift_guess, &
853 ignore_bias=.true., &
855 negf_control=negf_control, &
858 base_contact=base_contact)
861 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_fm(ispin), &
863 v_shift=v_shift_guess, &
864 ignore_bias=.true., &
866 negf_control=negf_control, &
869 base_contact=base_contact, &
870 integr_lbound=lbound_cpath, &
871 integr_ubound=ubound_cpath, &
872 matrix_s_global=matrix_s_fm, &
873 is_circular=.true., &
874 g_surf_cache=g_surf_circular(ispin))
875 IF (negf_control%disable_cache) &
879 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_fm(ispin), &
881 v_shift=v_shift_guess, &
882 ignore_bias=.true., &
884 negf_control=negf_control, &
887 base_contact=base_contact, &
888 integr_lbound=ubound_cpath, &
889 integr_ubound=ubound_lpath, &
890 matrix_s_global=matrix_s_fm, &
891 is_circular=.false., &
892 g_surf_cache=g_surf_linear(ispin))
893 IF (negf_control%disable_cache) &
905 CALL cp_fm_trace(rho_ao_fm(1), matrix_s_fm, nelectrons_guess)
909 IF (log_unit > 0)
THEN
910 WRITE (log_unit,
'(T2,I5,T12,A,T32,F8.1,T42,F15.8,T60,ES20.5E2)') &
911 iter_count, get_method_description_string(stats, negf_control%integr_method), &
912 t2 - t1, v_shift_guess, nelectrons_guess - nelectrons_ref
915 IF (abs(nelectrons_guess - nelectrons_ref) < negf_control%conv_scf)
EXIT
918 SELECT CASE (iter_count)
920 nelectrons_min = nelectrons_guess
922 nelectrons_max = nelectrons_guess
924 IF (v_shift_guess < v_shift_min)
THEN
925 v_shift_max = v_shift_min
926 nelectrons_max = nelectrons_min
927 v_shift_min = v_shift_guess
928 nelectrons_min = nelectrons_guess
929 ELSE IF (v_shift_guess > v_shift_max)
THEN
930 v_shift_min = v_shift_max
931 nelectrons_min = nelectrons_max
932 v_shift_max = v_shift_guess
933 nelectrons_max = nelectrons_guess
934 ELSE IF (v_shift_max - v_shift_guess < v_shift_guess - v_shift_min)
THEN
935 v_shift_max = v_shift_guess
936 nelectrons_max = nelectrons_guess
938 v_shift_min = v_shift_guess
939 nelectrons_min = nelectrons_guess
946 negf_control%v_shift = v_shift_guess
948 IF (log_unit > 0)
THEN
949 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| Shift in Hartree potential (a.u.):", negf_control%v_shift
950 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| (eV):", negf_control%v_shift*
evolt
953 DO ispin = nspins, 1, -1
957 DEALLOCATE (g_surf_circular, g_surf_linear)
961 IF (sub_env%ngroups > 1 .AND.
ASSOCIATED(matrix_s_fm))
THEN
963 DEALLOCATE (matrix_s_fm)
966 CALL timestop(handle)
967 END SUBROUTINE shift_potential
982 SUBROUTINE converge_density(negf_env, negf_control, sub_env, qs_env, v_shift, base_contact, log_unit)
987 REAL(kind=
dp),
INTENT(in) :: v_shift
988 INTEGER,
INTENT(in) :: base_contact, log_unit
990 CHARACTER(LEN=*),
PARAMETER :: routinen =
'converge_density'
991 REAL(kind=
dp),
PARAMETER :: threshold = 16.0_dp*epsilon(0.0_dp)
994 COMPLEX(kind=dp) :: lbound_cpath, ubound_cpath, ubound_lpath
995 INTEGER :: handle, icontact, image, ispin, &
996 iter_count, nao, ncontacts, nimages, &
998 LOGICAL :: do_kpoints
999 REAL(kind=
dp) :: delta, iter_delta, mu_base, nelectrons, &
1000 nelectrons_diff, t1, t2, temperature, &
1004 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: rho_ao_delta_fm, rho_ao_new_fm
1006 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks_initial_kp, matrix_ks_qs_kp, &
1007 rho_ao_initial_kp, rho_ao_new_kp, &
1011 DIMENSION(:) :: g_surf_circular, g_surf_linear, &
1013 TYPE(integration_status_type) :: stats
1018 ncontacts =
SIZE(negf_control%contacts)
1020 IF (ncontacts > 2)
THEN
1021 cpabort(
"Poisson solver does not support the general NEGF setup (>2 contacts).")
1024 IF (.NOT. (
ALLOCATED(negf_env%h_s) .AND.
ALLOCATED(negf_env%h_sc) .AND. &
1025 ASSOCIATED(negf_env%s_s) .AND.
ALLOCATED(negf_env%s_sc)))
RETURN
1026 IF (ncontacts < 2)
RETURN
1027 IF (negf_control%max_scf == 0)
RETURN
1029 CALL timeset(routinen, handle)
1031 CALL get_qs_env(qs_env, blacs_env=blacs_env, do_kpoints=do_kpoints, dft_control=dft_control, &
1032 matrix_ks_kp=matrix_ks_qs_kp, para_env=para_env, rho=rho_struct, subsys=subsys)
1033 cpassert(.NOT. do_kpoints)
1039 IF (sub_env%ngroups > 1)
THEN
1040 NULLIFY (matrix_s_fm, fm_struct)
1045 ALLOCATE (matrix_s_fm)
1049 IF (sub_env%group_distribution(sub_env%mepos_global) == 0)
THEN
1055 matrix_s_fm => negf_env%s_s
1060 nspins =
SIZE(negf_env%h_s)
1061 nimages = dft_control%nimages
1063 v_base = negf_control%contacts(base_contact)%v_external
1064 mu_base = negf_control%contacts(base_contact)%fermi_level - v_base
1067 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_qs_kp)
1069 NULLIFY (matrix_ks_initial_kp, rho_ao_initial_kp, rho_ao_new_kp)
1074 DO image = 1, nimages
1075 DO ispin = 1, nspins
1076 CALL dbcsr_init_p(matrix_ks_initial_kp(ispin, image)%matrix)
1077 CALL dbcsr_copy(matrix_b=matrix_ks_initial_kp(ispin, image)%matrix, matrix_a=matrix_ks_qs_kp(ispin, image)%matrix)
1079 CALL dbcsr_init_p(rho_ao_initial_kp(ispin, image)%matrix)
1080 CALL dbcsr_copy(matrix_b=rho_ao_initial_kp(ispin, image)%matrix, matrix_a=rho_ao_qs_kp(ispin, image)%matrix)
1083 CALL dbcsr_copy(matrix_b=rho_ao_new_kp(ispin, image)%matrix, matrix_a=rho_ao_qs_kp(ispin, image)%matrix)
1089 ALLOCATE (rho_ao_delta_fm(nspins), rho_ao_new_fm(nspins))
1090 DO ispin = 1, nspins
1095 fm=rho_ao_delta_fm(ispin), &
1096 atomlist_row=negf_control%atomlist_S_screening, &
1097 atomlist_col=negf_control%atomlist_S_screening, &
1098 subsys=subsys, mpi_comm_global=para_env, &
1099 do_upper_diag=.true., do_lower=.true.)
1101 CALL cp_fm_trace(rho_ao_delta_fm(ispin), matrix_s_fm, trace)
1102 nelectrons = nelectrons + trace
1107 CALL mixing_allocate(qs_env, negf_env%mixing_method, nspins=nspins, mixing_store=negf_env%mixing_storage)
1108 IF (dft_control%qs_control%dftb .OR. dft_control%qs_control%xtb)
THEN
1109 cpabort(
'TB Code not available')
1110 ELSE IF (dft_control%qs_control%semi_empirical)
THEN
1111 cpabort(
'SE Code not possible')
1113 CALL mixing_init(negf_env%mixing_method, rho_struct, negf_env%mixing_storage, para_env)
1117 IF (log_unit > 0)
THEN
1118 WRITE (log_unit,
'(/,T2,A)')
"NEGF SELF-CONSISTENT PROCEDURE"
1119 WRITE (log_unit,
"( ' ------------------------------')")
1120 WRITE (log_unit,
'(/,T2,A,T55,F25.14,/)')
"Initial electronic density of the scattering region:", -1.0_dp*nelectrons
1121 WRITE (log_unit,
'(T3,A)')
"Step Integration method Time Electronic density Convergence"
1122 WRITE (log_unit,
'(T3,78("-"))')
1125 temperature = negf_control%contacts(base_contact)%temperature
1128 lbound_cpath = cmplx(negf_control%energy_lbound, negf_control%eta, kind=
dp)
1129 ubound_cpath = cmplx(mu_base - real(negf_control%gamma_kT, kind=
dp)*temperature, &
1130 REAL(negf_control%delta_npoles, kind=
dp)*
twopi*temperature, kind=
dp)
1133 ubound_lpath = cmplx(mu_base - log(negf_control%conv_density)*temperature, &
1134 REAL(negf_control%delta_npoles, kind=
dp)*
twopi*temperature, kind=
dp)
1136 ALLOCATE (g_surf_circular(nspins), g_surf_linear(nspins), g_surf_nonequiv(nspins))
1139 DO iter_count = 1, negf_control%max_scf
1141 CALL integration_status_reset(stats)
1143 DO ispin = 1, nspins
1145 CALL negf_init_rho_equiv_residuals(rho_ao_fm=rho_ao_new_fm(ispin), &
1147 ignore_bias=.false., &
1148 negf_env=negf_env, &
1149 negf_control=negf_control, &
1152 base_contact=base_contact)
1155 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_new_fm(ispin), &
1158 ignore_bias=.false., &
1159 negf_env=negf_env, &
1160 negf_control=negf_control, &
1163 base_contact=base_contact, &
1164 integr_lbound=lbound_cpath, &
1165 integr_ubound=ubound_cpath, &
1166 matrix_s_global=matrix_s_fm, &
1167 is_circular=.true., &
1168 g_surf_cache=g_surf_circular(ispin))
1169 IF (negf_control%disable_cache) &
1173 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_new_fm(ispin), &
1176 ignore_bias=.false., &
1177 negf_env=negf_env, &
1178 negf_control=negf_control, &
1181 base_contact=base_contact, &
1182 integr_lbound=ubound_cpath, &
1183 integr_ubound=ubound_lpath, &
1184 matrix_s_global=matrix_s_fm, &
1185 is_circular=.false., &
1186 g_surf_cache=g_surf_linear(ispin))
1187 IF (negf_control%disable_cache) &
1192 DO icontact = 1, ncontacts
1193 IF (icontact /= base_contact)
THEN
1194 delta = delta + abs(negf_control%contacts(icontact)%v_external - &
1195 negf_control%contacts(base_contact)%v_external) + &
1196 abs(negf_control%contacts(icontact)%fermi_level - &
1197 negf_control%contacts(base_contact)%fermi_level) + &
1198 abs(negf_control%contacts(icontact)%temperature - &
1199 negf_control%contacts(base_contact)%temperature)
1202 IF (delta >= threshold)
THEN
1203 CALL negf_add_rho_nonequiv(rho_ao_fm=rho_ao_new_fm(ispin), &
1206 negf_env=negf_env, &
1207 negf_control=negf_control, &
1210 base_contact=base_contact, &
1211 matrix_s_global=matrix_s_fm, &
1212 g_surf_cache=g_surf_nonequiv(ispin))
1213 IF (negf_control%disable_cache) &
1218 IF (nspins == 1)
CALL cp_fm_scale(2.0_dp, rho_ao_new_fm(1))
1221 nelectrons_diff = 0.0_dp
1222 DO ispin = 1, nspins
1223 CALL cp_fm_trace(rho_ao_new_fm(ispin), matrix_s_fm, trace)
1224 nelectrons = nelectrons + trace
1228 CALL cp_fm_trace(rho_ao_delta_fm(ispin), matrix_s_fm, trace)
1229 nelectrons_diff = nelectrons_diff + trace
1232 CALL cp_fm_to_fm(rho_ao_new_fm(ispin), rho_ao_delta_fm(ispin))
1237 IF (log_unit > 0)
THEN
1238 WRITE (log_unit,
'(T2,I5,T12,A,T32,F8.1,T43,F20.8,T65,ES15.5E2)') &
1239 iter_count, get_method_description_string(stats, negf_control%integr_method), &
1240 t2 - t1, -1.0_dp*nelectrons, nelectrons_diff
1243 IF (abs(nelectrons_diff) < negf_control%conv_scf)
EXIT
1249 DO image = 1, nimages
1250 DO ispin = 1, nspins
1251 CALL dbcsr_copy(matrix_b=rho_ao_new_kp(ispin, image)%matrix, &
1252 matrix_a=rho_ao_initial_kp(ispin, image)%matrix)
1256 DO ispin = 1, nspins
1258 matrix=rho_ao_new_kp(ispin, 1)%matrix, &
1259 atomlist_row=negf_control%atomlist_S_screening, &
1260 atomlist_col=negf_control%atomlist_S_screening, &
1265 para_env, iter_delta, iter_count)
1267 DO image = 1, nimages
1268 DO ispin = 1, nspins
1269 CALL dbcsr_copy(rho_ao_qs_kp(ispin, image)%matrix, rho_ao_new_kp(ispin, image)%matrix)
1275 DO image = 1, nimages
1276 DO ispin = 1, nspins
1277 CALL dbcsr_copy(matrix_b=rho_ao_qs_kp(ispin, image)%matrix, &
1278 matrix_a=rho_ao_initial_kp(ispin, image)%matrix)
1282 DO ispin = 1, nspins
1284 matrix=rho_ao_qs_kp(ispin, 1)%matrix, &
1285 atomlist_row=negf_control%atomlist_S_screening, &
1286 atomlist_col=negf_control%atomlist_S_screening, &
1294 CALL gspace_mixing(qs_env, negf_env%mixing_method, negf_env%mixing_storage, &
1295 rho_struct, para_env, iter_count)
1302 DO ispin = 1, nspins
1304 fm=negf_env%h_s(ispin), &
1305 atomlist_row=negf_control%atomlist_S_screening, &
1306 atomlist_col=negf_control%atomlist_S_screening, &
1307 subsys=subsys, mpi_comm_global=para_env, &
1308 do_upper_diag=.true., do_lower=.true.)
1315 IF (log_unit > 0)
THEN
1316 IF (iter_count <= negf_control%max_scf)
THEN
1317 WRITE (log_unit,
'(/,T11,1X,A,I0,A)')
"*** NEGF run converged in ", iter_count,
" iteration(s) ***"
1319 WRITE (log_unit,
'(/,T11,1X,A,I0,A)')
"*** NEGF run did NOT converge after ", iter_count - 1,
" iteration(s) ***"
1323 DO ispin = nspins, 1, -1
1328 DEALLOCATE (g_surf_circular, g_surf_linear, g_surf_nonequiv)
1333 DO image = 1, nimages
1334 DO ispin = 1, nspins
1335 CALL dbcsr_copy(matrix_b=matrix_ks_qs_kp(ispin, image)%matrix, matrix_a=matrix_ks_initial_kp(ispin, image)%matrix)
1336 CALL dbcsr_copy(matrix_b=rho_ao_qs_kp(ispin, image)%matrix, matrix_a=rho_ao_initial_kp(ispin, image)%matrix)
1343 DEALLOCATE (matrix_ks_initial_kp, rho_ao_new_kp, rho_ao_initial_kp)
1345 IF (sub_env%ngroups > 1 .AND.
ASSOCIATED(matrix_s_fm))
THEN
1347 DEALLOCATE (matrix_s_fm)
1350 CALL timestop(handle)
1351 END SUBROUTINE converge_density
1368 SUBROUTINE negf_surface_green_function_batch(g_surf, omega, h0, s0, h1, s1, sub_env, v_external, conv, transp)
1369 TYPE(
cp_cfm_type),
DIMENSION(:),
INTENT(inout) :: g_surf
1370 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(in) :: omega
1371 TYPE(
cp_fm_type),
INTENT(IN) :: h0, s0, h1, s1
1373 REAL(kind=
dp),
INTENT(in) :: v_external, conv
1374 LOGICAL,
INTENT(in) :: transp
1376 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_surface_green_function_batch'
1379 INTEGER :: handle, igroup, ipoint, npoints
1383 CALL timeset(routinen, handle)
1384 npoints =
SIZE(omega)
1389 igroup = sub_env%group_distribution(sub_env%mepos_global)
1391 g_surf(1:npoints) = cfm_null
1393 DO ipoint = igroup + 1, npoints, sub_env%ngroups
1394 IF (debug_this_module)
THEN
1395 cpassert(.NOT.
ASSOCIATED(g_surf(ipoint)%matrix_struct))
1399 CALL do_sancho(g_surf(ipoint), omega(ipoint) + v_external, &
1400 h0, s0, h1, s1, conv, transp, work)
1404 CALL timestop(handle)
1405 END SUBROUTINE negf_surface_green_function_batch
1437 SUBROUTINE negf_retarded_green_function_batch(omega, v_shift, ignore_bias, negf_env, negf_control, sub_env, ispin, &
1439 g_ret_s, g_ret_scale, gamma_contacts, gret_gamma_gadv, dos, &
1440 transm_coeff, transm_contact1, transm_contact2, just_contact)
1441 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(in) :: omega
1442 REAL(kind=
dp),
INTENT(in) :: v_shift
1443 LOGICAL,
INTENT(in) :: ignore_bias
1447 INTEGER,
INTENT(in) :: ispin
1448 TYPE(
cp_cfm_type),
DIMENSION(:, :),
INTENT(in) :: g_surf_contacts
1451 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(in), &
1452 OPTIONAL :: g_ret_scale
1454 OPTIONAL :: gamma_contacts, gret_gamma_gadv
1455 REAL(kind=
dp),
DIMENSION(:),
INTENT(out),
OPTIONAL :: dos
1456 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(out), &
1457 OPTIONAL :: transm_coeff
1458 INTEGER,
INTENT(in),
OPTIONAL :: transm_contact1, transm_contact2, &
1461 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_retarded_green_function_batch'
1463 INTEGER :: handle, icontact, igroup, ipoint, &
1464 ncontacts, npoints, nrows
1465 REAL(kind=
dp) :: v_external
1467 DIMENSION(:) :: info1
1469 DIMENSION(:, :) :: info2
1470 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: g_ret_s_group, self_energy_contacts, &
1471 zwork1_contacts, zwork2_contacts
1472 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:, :) :: gamma_contacts_group, &
1473 gret_gamma_gadv_group
1479 CALL timeset(routinen, handle)
1480 npoints =
SIZE(omega)
1481 ncontacts =
SIZE(negf_env%contacts)
1482 cpassert(
SIZE(negf_control%contacts) == ncontacts)
1484 IF (
PRESENT(just_contact))
THEN
1485 cpassert(just_contact <= ncontacts)
1489 cpassert(ncontacts >= 2)
1491 IF (ignore_bias) v_external = 0.0_dp
1493 IF (
PRESENT(transm_coeff) .OR.
PRESENT(transm_contact1) .OR.
PRESENT(transm_contact2))
THEN
1494 cpassert(
PRESENT(transm_coeff))
1495 cpassert(
PRESENT(transm_contact1))
1496 cpassert(
PRESENT(transm_contact2))
1497 cpassert(.NOT.
PRESENT(just_contact))
1500 ALLOCATE (self_energy_contacts(ncontacts), zwork1_contacts(ncontacts), zwork2_contacts(ncontacts))
1502 IF (
PRESENT(just_contact))
THEN
1503 CALL cp_fm_get_info(negf_env%contacts(just_contact)%s_01, matrix_struct=fm_struct)
1504 DO icontact = 1, ncontacts
1509 CALL cp_fm_get_info(negf_env%contacts(just_contact)%s_00, nrow_global=nrows, matrix_struct=fm_struct)
1510 DO icontact = 1, ncontacts
1511 CALL cp_cfm_create(self_energy_contacts(icontact), fm_struct)
1514 DO icontact = 1, ncontacts
1515 CALL cp_fm_get_info(negf_env%s_sc(icontact), matrix_struct=fm_struct)
1520 CALL cp_fm_get_info(negf_env%s_s, nrow_global=nrows, matrix_struct=fm_struct)
1521 DO icontact = 1, ncontacts
1522 CALL cp_cfm_create(self_energy_contacts(icontact), fm_struct)
1526 IF (
PRESENT(g_ret_s) .OR.
PRESENT(gret_gamma_gadv) .OR. &
1527 PRESENT(dos) .OR.
PRESENT(transm_coeff))
THEN
1528 ALLOCATE (g_ret_s_group(npoints))
1530 IF (sub_env%ngroups <= 1 .AND.
PRESENT(g_ret_s))
THEN
1531 g_ret_s_group(1:npoints) = g_ret_s(1:npoints)
1535 IF (
PRESENT(gamma_contacts) .OR.
PRESENT(gret_gamma_gadv) .OR.
PRESENT(transm_coeff))
THEN
1536 IF (debug_this_module .AND.
PRESENT(gamma_contacts))
THEN
1537 cpassert(
SIZE(gamma_contacts, 1) == ncontacts)
1540 ALLOCATE (gamma_contacts_group(ncontacts, npoints))
1541 IF (sub_env%ngroups <= 1 .AND.
PRESENT(gamma_contacts))
THEN
1542 gamma_contacts_group(1:ncontacts, 1:npoints) = gamma_contacts(1:ncontacts, 1:npoints)
1546 IF (
PRESENT(gret_gamma_gadv))
THEN
1547 IF (debug_this_module .AND.
PRESENT(gret_gamma_gadv))
THEN
1548 cpassert(
SIZE(gret_gamma_gadv, 1) == ncontacts)
1551 ALLOCATE (gret_gamma_gadv_group(ncontacts, npoints))
1552 IF (sub_env%ngroups <= 1)
THEN
1553 gret_gamma_gadv_group(1:ncontacts, 1:npoints) = gret_gamma_gadv(1:ncontacts, 1:npoints)
1557 igroup = sub_env%group_distribution(sub_env%mepos_global)
1559 DO ipoint = 1, npoints
1560 IF (
ASSOCIATED(g_surf_contacts(1, ipoint)%matrix_struct))
THEN
1561 IF (sub_env%ngroups > 1 .OR. .NOT.
PRESENT(g_ret_s))
THEN
1565 IF (
ALLOCATED(g_ret_s_group))
THEN
1570 IF (sub_env%ngroups > 1 .OR. .NOT.
PRESENT(gamma_contacts))
THEN
1571 IF (
ALLOCATED(gamma_contacts_group))
THEN
1572 DO icontact = 1, ncontacts
1573 CALL cp_cfm_create(gamma_contacts_group(icontact, ipoint), fm_struct)
1578 IF (sub_env%ngroups > 1)
THEN
1579 IF (
ALLOCATED(gret_gamma_gadv_group))
THEN
1580 DO icontact = 1, ncontacts
1581 IF (
ASSOCIATED(gret_gamma_gadv(icontact, ipoint)%matrix_struct))
THEN
1582 CALL cp_cfm_create(gret_gamma_gadv_group(icontact, ipoint), fm_struct)
1588 IF (
PRESENT(just_contact))
THEN
1590 DO icontact = 1, ncontacts
1592 omega=omega(ipoint), &
1593 g_surf_c=g_surf_contacts(icontact, ipoint), &
1594 h_sc0=negf_env%contacts(just_contact)%h_01(ispin), &
1595 s_sc0=negf_env%contacts(just_contact)%s_01, &
1596 zwork1=zwork1_contacts(icontact), &
1597 zwork2=zwork2_contacts(icontact), &
1598 transp=(icontact == 1))
1602 DO icontact = 1, ncontacts
1603 IF (.NOT. ignore_bias) v_external = negf_control%contacts(icontact)%v_external
1606 omega=omega(ipoint) + v_external, &
1607 g_surf_c=g_surf_contacts(icontact, ipoint), &
1608 h_sc0=negf_env%h_sc(ispin, icontact), &
1609 s_sc0=negf_env%s_sc(icontact), &
1610 zwork1=zwork1_contacts(icontact), &
1611 zwork2=zwork2_contacts(icontact), &
1617 IF (
ALLOCATED(gamma_contacts_group))
THEN
1618 DO icontact = 1, ncontacts
1620 self_energy_c=self_energy_contacts(icontact))
1624 IF (
ALLOCATED(g_ret_s_group))
THEN
1626 DO icontact = 2, ncontacts
1631 IF (
PRESENT(just_contact))
THEN
1633 omega=omega(ipoint) - v_shift, &
1634 self_energy_ret_sum=self_energy_contacts(1), &
1635 h_s=negf_env%contacts(just_contact)%h_00(ispin), &
1636 s_s=negf_env%contacts(just_contact)%s_00)
1637 ELSE IF (ignore_bias)
THEN
1639 omega=omega(ipoint) - v_shift, &
1640 self_energy_ret_sum=self_energy_contacts(1), &
1641 h_s=negf_env%h_s(ispin), &
1645 omega=omega(ipoint) - v_shift, &
1646 self_energy_ret_sum=self_energy_contacts(1), &
1647 h_s=negf_env%h_s(ispin), &
1649 v_hartree_s=negf_env%v_hartree_s)
1652 IF (
PRESENT(g_ret_scale))
THEN
1653 IF (g_ret_scale(ipoint) /=
z_one)
CALL cp_cfm_scale(g_ret_scale(ipoint), g_ret_s_group(ipoint))
1657 IF (
ALLOCATED(gret_gamma_gadv_group))
THEN
1660 DO icontact = 1, ncontacts
1661 IF (
ASSOCIATED(gret_gamma_gadv_group(icontact, ipoint)%matrix_struct))
THEN
1663 z_one, gamma_contacts_group(icontact, ipoint), &
1664 g_ret_s_group(ipoint), &
1665 z_zero, self_energy_contacts(icontact))
1667 z_one, g_ret_s_group(ipoint), &
1668 self_energy_contacts(icontact), &
1669 z_zero, gret_gamma_gadv_group(icontact, ipoint))
1677 IF (
PRESENT(g_ret_s))
THEN
1678 IF (sub_env%ngroups > 1)
THEN
1680 DO ipoint = 1, npoints
1681 IF (
ASSOCIATED(g_ret_s(ipoint)%matrix_struct))
THEN
1687 IF (
ASSOCIATED(para_env))
THEN
1688 ALLOCATE (info1(npoints))
1690 DO ipoint = 1, npoints
1693 para_env, info1(ipoint))
1696 DO ipoint = 1, npoints
1697 IF (
ASSOCIATED(g_ret_s(ipoint)%matrix_struct))
THEN
1699 IF (
ASSOCIATED(g_ret_s_group(ipoint)%matrix_struct)) &
1709 IF (
PRESENT(gamma_contacts))
THEN
1710 IF (sub_env%ngroups > 1)
THEN
1712 pnt1:
DO ipoint = 1, npoints
1713 DO icontact = 1, ncontacts
1714 IF (
ASSOCIATED(gamma_contacts(icontact, ipoint)%matrix_struct))
THEN
1715 CALL cp_cfm_get_info(gamma_contacts(icontact, ipoint), para_env=para_env)
1721 IF (
ASSOCIATED(para_env))
THEN
1722 ALLOCATE (info2(ncontacts, npoints))
1724 DO ipoint = 1, npoints
1725 DO icontact = 1, ncontacts
1727 gamma_contacts(icontact, ipoint), &
1728 para_env, info2(icontact, ipoint))
1732 DO ipoint = 1, npoints
1733 DO icontact = 1, ncontacts
1734 IF (
ASSOCIATED(gamma_contacts(icontact, ipoint)%matrix_struct))
THEN
1736 IF (
ASSOCIATED(gamma_contacts_group(icontact, ipoint)%matrix_struct))
THEN
1748 IF (
PRESENT(gret_gamma_gadv))
THEN
1749 IF (sub_env%ngroups > 1)
THEN
1751 pnt2:
DO ipoint = 1, npoints
1752 DO icontact = 1, ncontacts
1753 IF (
ASSOCIATED(gret_gamma_gadv(icontact, ipoint)%matrix_struct))
THEN
1754 CALL cp_cfm_get_info(gret_gamma_gadv(icontact, ipoint), para_env=para_env)
1760 IF (
ASSOCIATED(para_env))
THEN
1761 ALLOCATE (info2(ncontacts, npoints))
1763 DO ipoint = 1, npoints
1764 DO icontact = 1, ncontacts
1766 gret_gamma_gadv(icontact, ipoint), &
1767 para_env, info2(icontact, ipoint))
1771 DO ipoint = 1, npoints
1772 DO icontact = 1, ncontacts
1773 IF (
ASSOCIATED(gret_gamma_gadv(icontact, ipoint)%matrix_struct))
THEN
1775 IF (
ASSOCIATED(gret_gamma_gadv_group(icontact, ipoint)%matrix_struct))
THEN
1787 IF (
PRESENT(dos))
THEN
1790 IF (
PRESENT(just_contact))
THEN
1791 matrix_s => negf_env%contacts(just_contact)%s_00
1793 matrix_s => negf_env%s_s
1799 DO ipoint = 1, npoints
1800 IF (
ASSOCIATED(g_ret_s_group(ipoint)%matrix_struct))
THEN
1801 CALL cp_cfm_to_fm(g_ret_s_group(ipoint), mtargeti=g_ret_imag)
1802 CALL cp_fm_trace(g_ret_imag, matrix_s, dos(ipoint))
1803 IF (sub_env%para_env%mepos /= 0) dos(ipoint) = 0.0_dp
1809 CALL sub_env%mpi_comm_global%sum(dos)
1810 dos(:) = -1.0_dp/
pi*dos(:)
1813 IF (
PRESENT(transm_coeff))
THEN
1816 DO ipoint = 1, npoints
1817 IF (
ASSOCIATED(g_ret_s_group(ipoint)%matrix_struct))
THEN
1820 z_one, gamma_contacts_group(transm_contact1, ipoint), &
1821 g_ret_s_group(ipoint), &
1822 z_zero, self_energy_contacts(transm_contact1))
1824 z_one, self_energy_contacts(transm_contact1), &
1825 gamma_contacts_group(transm_contact2, ipoint), &
1826 z_zero, self_energy_contacts(transm_contact2))
1830 self_energy_contacts(transm_contact2), &
1831 transm_coeff(ipoint))
1832 IF (sub_env%para_env%mepos /= 0) transm_coeff(ipoint) = 0.0_dp
1837 CALL sub_env%mpi_comm_global%sum(transm_coeff)
1842 IF (
ALLOCATED(g_ret_s_group))
THEN
1843 DO ipoint = npoints, 1, -1
1844 IF (sub_env%ngroups > 1 .OR. .NOT.
PRESENT(g_ret_s))
THEN
1848 DEALLOCATE (g_ret_s_group)
1851 IF (
ALLOCATED(gamma_contacts_group))
THEN
1852 DO ipoint = npoints, 1, -1
1853 DO icontact = ncontacts, 1, -1
1854 IF (sub_env%ngroups > 1 .OR. .NOT.
PRESENT(gamma_contacts))
THEN
1859 DEALLOCATE (gamma_contacts_group)
1862 IF (
ALLOCATED(gret_gamma_gadv_group))
THEN
1863 DO ipoint = npoints, 1, -1
1864 DO icontact = ncontacts, 1, -1
1865 IF (sub_env%ngroups > 1)
THEN
1870 DEALLOCATE (gret_gamma_gadv_group)
1873 IF (
ALLOCATED(self_energy_contacts))
THEN
1874 DO icontact = ncontacts, 1, -1
1877 DEALLOCATE (self_energy_contacts)
1880 IF (
ALLOCATED(zwork1_contacts))
THEN
1881 DO icontact = ncontacts, 1, -1
1884 DEALLOCATE (zwork1_contacts)
1887 IF (
ALLOCATED(zwork2_contacts))
THEN
1888 DO icontact = ncontacts, 1, -1
1891 DEALLOCATE (zwork2_contacts)
1894 CALL timestop(handle)
1895 END SUBROUTINE negf_retarded_green_function_batch
1905 PURE FUNCTION fermi_function(omega, temperature)
RESULT(val)
1906 COMPLEX(kind=dp),
INTENT(in) :: omega
1907 REAL(kind=
dp),
INTENT(in) :: temperature
1908 COMPLEX(kind=dp) :: val
1910 REAL(kind=
dp),
PARAMETER :: max_ln_omega_over_t = log(huge(0.0_dp))/16.0_dp
1912 IF (real(omega, kind=
dp) <= temperature*max_ln_omega_over_t)
THEN
1918 END FUNCTION fermi_function
1933 SUBROUTINE negf_init_rho_equiv_residuals(rho_ao_fm, v_shift, ignore_bias, negf_env, &
1934 negf_control, sub_env, ispin, base_contact, just_contact)
1936 REAL(kind=
dp),
INTENT(in) :: v_shift
1937 LOGICAL,
INTENT(in) :: ignore_bias
1941 INTEGER,
INTENT(in) :: ispin, base_contact
1942 INTEGER,
INTENT(in),
OPTIONAL :: just_contact
1944 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_init_rho_equiv_residuals'
1946 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: omega
1947 INTEGER :: handle, icontact, ipole, ncontacts, &
1949 REAL(kind=
dp) :: mu_base, pi_temperature, temperature, &
1951 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: g_ret_s
1956 CALL timeset(routinen, handle)
1958 temperature = negf_control%contacts(base_contact)%temperature
1959 IF (ignore_bias)
THEN
1960 mu_base = negf_control%contacts(base_contact)%fermi_level
1963 mu_base = negf_control%contacts(base_contact)%fermi_level - negf_control%contacts(base_contact)%v_external
1966 pi_temperature =
pi*temperature
1967 npoles = negf_control%delta_npoles
1969 ncontacts =
SIZE(negf_env%contacts)
1970 cpassert(base_contact <= ncontacts)
1971 IF (
PRESENT(just_contact))
THEN
1973 cpassert(just_contact == base_contact)
1976 IF (npoles > 0)
THEN
1977 CALL cp_fm_get_info(rho_ao_fm, para_env=para_env, matrix_struct=fm_struct)
1979 ALLOCATE (omega(npoles), g_ret_s(npoles))
1981 DO ipole = 1, npoles
1984 omega(ipole) = cmplx(mu_base, real(2*ipole - 1, kind=
dp)*pi_temperature, kind=
dp)
1989 IF (
PRESENT(just_contact))
THEN
1994 DO icontact = 1, ncontacts
1995 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
1997 h0=negf_env%contacts(just_contact)%h_00(ispin), &
1998 s0=negf_env%contacts(just_contact)%s_00, &
1999 h1=negf_env%contacts(just_contact)%h_01(ispin), &
2000 s1=negf_env%contacts(just_contact)%s_01, &
2001 sub_env=sub_env, v_external=0.0_dp, &
2002 conv=negf_control%conv_green, transp=(icontact == 1))
2005 DO icontact = 1, ncontacts
2006 IF (.NOT. ignore_bias) v_external = negf_control%contacts(icontact)%v_external
2008 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
2010 h0=negf_env%contacts(icontact)%h_00(ispin), &
2011 s0=negf_env%contacts(icontact)%s_00, &
2012 h1=negf_env%contacts(icontact)%h_01(ispin), &
2013 s1=negf_env%contacts(icontact)%s_01, &
2015 v_external=v_external, &
2016 conv=negf_control%conv_green, transp=.false.)
2020 CALL negf_retarded_green_function_batch(omega=omega(:), &
2022 ignore_bias=ignore_bias, &
2023 negf_env=negf_env, &
2024 negf_control=negf_control, &
2027 g_surf_contacts=g_surf_cache%g_surf_contacts, &
2029 just_contact=just_contact)
2033 DO ipole = 2, npoles
2041 DO ipole = npoles, 1, -1
2044 DEALLOCATE (g_ret_s, omega)
2047 CALL timestop(handle)
2048 END SUBROUTINE negf_init_rho_equiv_residuals
2069 SUBROUTINE negf_add_rho_equiv_low(rho_ao_fm, stats, v_shift, ignore_bias, negf_env, negf_control, sub_env, &
2070 ispin, base_contact, integr_lbound, integr_ubound, matrix_s_global, &
2071 is_circular, g_surf_cache, just_contact)
2073 TYPE(integration_status_type),
INTENT(inout) :: stats
2074 REAL(kind=
dp),
INTENT(in) :: v_shift
2075 LOGICAL,
INTENT(in) :: ignore_bias
2079 INTEGER,
INTENT(in) :: ispin, base_contact
2080 COMPLEX(kind=dp),
INTENT(in) :: integr_lbound, integr_ubound
2081 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_s_global
2082 LOGICAL,
INTENT(in) :: is_circular
2084 INTEGER,
INTENT(in),
OPTIONAL :: just_contact
2086 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_add_rho_equiv_low'
2088 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: xnodes, zscale
2089 INTEGER :: handle, icontact, interval_id, ipoint, max_points, min_points, ncontacts, &
2090 npoints, npoints_exist, npoints_tmp, npoints_total, shape_id
2091 LOGICAL :: do_surface_green
2092 REAL(kind=
dp) :: conv_integr, mu_base, temperature, &
2095 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: zdata, zdata_tmp
2101 CALL timeset(routinen, handle)
2105 conv_integr = 0.5_dp*negf_control%conv_density*
pi
2107 IF (ignore_bias)
THEN
2108 mu_base = negf_control%contacts(base_contact)%fermi_level
2111 mu_base = negf_control%contacts(base_contact)%fermi_level - negf_control%contacts(base_contact)%v_external
2114 min_points = negf_control%integr_min_points
2115 max_points = negf_control%integr_max_points
2116 temperature = negf_control%contacts(base_contact)%temperature
2118 ncontacts =
SIZE(negf_env%contacts)
2119 cpassert(base_contact <= ncontacts)
2120 IF (
PRESENT(just_contact))
THEN
2122 cpassert(just_contact == base_contact)
2125 do_surface_green = .NOT.
ALLOCATED(g_surf_cache%tnodes)
2127 IF (do_surface_green)
THEN
2128 npoints = min_points
2130 npoints =
SIZE(g_surf_cache%tnodes)
2134 CALL cp_fm_get_info(rho_ao_fm, para_env=para_env, matrix_struct=fm_struct)
2137 SELECT CASE (negf_control%integr_method)
2140 ALLOCATE (xnodes(npoints))
2142 IF (is_circular)
THEN
2150 IF (do_surface_green)
THEN
2151 CALL ccquad_init(cc_env, xnodes, npoints, integr_lbound, integr_ubound, &
2152 interval_id, shape_id, matrix_s_global)
2154 CALL ccquad_init(cc_env, xnodes, npoints, integr_lbound, integr_ubound, &
2155 interval_id, shape_id, matrix_s_global, tnodes_restart=g_surf_cache%tnodes)
2158 ALLOCATE (zdata(npoints))
2159 DO ipoint = 1, npoints
2164 IF (do_surface_green)
THEN
2167 IF (
PRESENT(just_contact))
THEN
2169 DO icontact = 1, ncontacts
2170 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, npoints_total + 1:), &
2171 omega=xnodes(1:npoints), &
2172 h0=negf_env%contacts(just_contact)%h_00(ispin), &
2173 s0=negf_env%contacts(just_contact)%s_00, &
2174 h1=negf_env%contacts(just_contact)%h_01(ispin), &
2175 s1=negf_env%contacts(just_contact)%s_01, &
2176 sub_env=sub_env, v_external=0.0_dp, &
2177 conv=negf_control%conv_green, transp=(icontact == 1))
2180 DO icontact = 1, ncontacts
2181 IF (.NOT. ignore_bias) v_external = negf_control%contacts(icontact)%v_external
2183 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, npoints_total + 1:), &
2184 omega=xnodes(1:npoints), &
2185 h0=negf_env%contacts(icontact)%h_00(ispin), &
2186 s0=negf_env%contacts(icontact)%s_00, &
2187 h1=negf_env%contacts(icontact)%h_01(ispin), &
2188 s1=negf_env%contacts(icontact)%s_01, &
2190 v_external=v_external, &
2191 conv=negf_control%conv_green, transp=.false.)
2196 ALLOCATE (zscale(npoints))
2198 IF (temperature >= 0.0_dp)
THEN
2199 DO ipoint = 1, npoints
2200 zscale(ipoint) = fermi_function(xnodes(ipoint) - mu_base, temperature)
2206 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints), &
2208 ignore_bias=ignore_bias, &
2209 negf_env=negf_env, &
2210 negf_control=negf_control, &
2213 g_surf_contacts=g_surf_cache%g_surf_contacts(:, npoints_total + 1:), &
2214 g_ret_s=zdata(1:npoints), &
2215 g_ret_scale=zscale(1:npoints), &
2216 just_contact=just_contact)
2218 DEALLOCATE (xnodes, zscale)
2219 npoints_total = npoints_total + npoints
2222 CALL move_alloc(zdata, zdata_tmp)
2226 IF (cc_env%error <= conv_integr)
EXIT
2227 IF (2*(npoints_total - 1) + 1 > max_points)
EXIT
2231 do_surface_green = .true.
2233 npoints_tmp = npoints
2235 npoints =
SIZE(xnodes)
2237 ALLOCATE (zdata(npoints))
2240 DO ipoint = 1, npoints_tmp
2241 IF (
ASSOCIATED(zdata_tmp(ipoint)%matrix_struct))
THEN
2242 npoints_exist = npoints_exist + 1
2243 zdata(npoints_exist) = zdata_tmp(ipoint)
2246 DEALLOCATE (zdata_tmp)
2248 DO ipoint = npoints_exist + 1, npoints
2254 stats%error = stats%error + cc_env%error/
pi
2256 DO ipoint =
SIZE(zdata_tmp), 1, -1
2259 DEALLOCATE (zdata_tmp)
2261 CALL cp_cfm_to_fm(cc_env%integral, mtargeti=integral_imag)
2264 IF (do_surface_green)
THEN
2271 ALLOCATE (xnodes(npoints), zdata(npoints), zscale(npoints))
2273 IF (is_circular)
THEN
2279 IF (do_surface_green)
THEN
2280 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2281 shape_id, conv_integr, matrix_s_global)
2283 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2284 shape_id, conv_integr, matrix_s_global, tnodes_restart=g_surf_cache%tnodes)
2287 DO WHILE (npoints > 0 .AND. npoints_total < max_points)
2288 DO ipoint = 1, npoints
2292 IF (do_surface_green)
THEN
2295 IF (
PRESENT(just_contact))
THEN
2297 DO icontact = 1, ncontacts
2298 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, npoints_total + 1:), &
2299 omega=xnodes(1:npoints), &
2300 h0=negf_env%contacts(just_contact)%h_00(ispin), &
2301 s0=negf_env%contacts(just_contact)%s_00, &
2302 h1=negf_env%contacts(just_contact)%h_01(ispin), &
2303 s1=negf_env%contacts(just_contact)%s_01, &
2304 sub_env=sub_env, v_external=0.0_dp, &
2305 conv=negf_control%conv_green, transp=(icontact == 1))
2308 DO icontact = 1, ncontacts
2309 IF (.NOT. ignore_bias) v_external = negf_control%contacts(icontact)%v_external
2311 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, npoints_total + 1:), &
2312 omega=xnodes(1:npoints), &
2313 h0=negf_env%contacts(icontact)%h_00(ispin), &
2314 s0=negf_env%contacts(icontact)%s_00, &
2315 h1=negf_env%contacts(icontact)%h_01(ispin), &
2316 s1=negf_env%contacts(icontact)%s_01, &
2318 v_external=v_external, &
2319 conv=negf_control%conv_green, transp=.false.)
2324 IF (temperature >= 0.0_dp)
THEN
2325 DO ipoint = 1, npoints
2326 zscale(ipoint) = fermi_function(xnodes(ipoint) - mu_base, temperature)
2332 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints), &
2334 ignore_bias=ignore_bias, &
2335 negf_env=negf_env, &
2336 negf_control=negf_control, &
2339 g_surf_contacts=g_surf_cache%g_surf_contacts(:, npoints_total + 1:), &
2340 g_ret_s=zdata(1:npoints), &
2341 g_ret_scale=zscale(1:npoints), &
2342 just_contact=just_contact)
2344 npoints_total = npoints_total + npoints
2348 IF (sr_env%error <= conv_integr)
EXIT
2353 do_surface_green = .true.
2355 npoints = max_points - npoints_total
2356 IF (npoints <= 0)
EXIT
2357 IF (npoints >
SIZE(xnodes)) npoints =
SIZE(xnodes)
2363 stats%error = stats%error + sr_env%error/
pi
2365 CALL cp_cfm_to_fm(sr_env%integral, mtargeti=integral_imag)
2368 IF (do_surface_green)
THEN
2373 DEALLOCATE (xnodes, zdata, zscale)
2376 cpabort(
"Unimplemented integration method")
2379 stats%npoints = stats%npoints + npoints_total
2384 CALL timestop(handle)
2385 END SUBROUTINE negf_add_rho_equiv_low
2401 SUBROUTINE negf_add_rho_nonequiv(rho_ao_fm, stats, v_shift, negf_env, negf_control, sub_env, &
2402 ispin, base_contact, matrix_s_global, g_surf_cache)
2404 TYPE(integration_status_type),
INTENT(inout) :: stats
2405 REAL(kind=
dp),
INTENT(in) :: v_shift
2409 INTEGER,
INTENT(in) :: ispin, base_contact
2410 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_s_global
2413 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_add_rho_nonequiv'
2415 COMPLEX(kind=dp) :: fermi_base, fermi_contact, &
2416 integr_lbound, integr_ubound
2417 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: xnodes
2418 INTEGER :: handle, icontact, ipoint, jcontact, &
2419 max_points, min_points, ncontacts, &
2420 npoints, npoints_total
2421 LOGICAL :: do_surface_green
2422 REAL(kind=
dp) :: conv_density, conv_integr, eta, &
2423 ln_conv_density, mu_base, mu_contact, &
2424 temperature_base, temperature_contact
2425 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:, :) :: zdata
2431 CALL timeset(routinen, handle)
2433 ncontacts =
SIZE(negf_env%contacts)
2434 cpassert(base_contact <= ncontacts)
2437 IF (ncontacts > 2)
THEN
2438 cpabort(
"Poisson solver does not support the general NEGF setup (>2 contacts).")
2441 mu_base = negf_control%contacts(base_contact)%fermi_level - negf_control%contacts(base_contact)%v_external
2442 min_points = negf_control%integr_min_points
2443 max_points = negf_control%integr_max_points
2444 temperature_base = negf_control%contacts(base_contact)%temperature
2445 eta = negf_control%eta
2446 conv_density = negf_control%conv_density
2447 ln_conv_density = log(conv_density)
2451 conv_integr = 0.5_dp*conv_density*
pi
2453 DO icontact = 1, ncontacts
2454 IF (icontact /= base_contact)
THEN
2455 mu_contact = negf_control%contacts(icontact)%fermi_level - negf_control%contacts(icontact)%v_external
2456 temperature_contact = negf_control%contacts(icontact)%temperature
2458 integr_lbound = cmplx(min(mu_base + ln_conv_density*temperature_base, &
2459 mu_contact + ln_conv_density*temperature_contact), eta, kind=
dp)
2460 integr_ubound = cmplx(max(mu_base - ln_conv_density*temperature_base, &
2461 mu_contact - ln_conv_density*temperature_contact), eta, kind=
dp)
2463 do_surface_green = .NOT.
ALLOCATED(g_surf_cache%tnodes)
2465 IF (do_surface_green)
THEN
2466 npoints = min_points
2468 npoints =
SIZE(g_surf_cache%tnodes)
2472 ALLOCATE (xnodes(npoints))
2473 CALL cp_fm_get_info(rho_ao_fm, para_env=para_env, matrix_struct=fm_struct)
2475 IF (do_surface_green)
THEN
2476 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2479 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2480 sr_shape_linear, conv_integr, matrix_s_global, tnodes_restart=g_surf_cache%tnodes)
2483 DO WHILE (npoints > 0 .AND. npoints_total < max_points)
2485 IF (do_surface_green)
THEN
2488 DO jcontact = 1, ncontacts
2489 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(jcontact, npoints_total + 1:), &
2490 omega=xnodes(1:npoints), &
2491 h0=negf_env%contacts(jcontact)%h_00(ispin), &
2492 s0=negf_env%contacts(jcontact)%s_00, &
2493 h1=negf_env%contacts(jcontact)%h_01(ispin), &
2494 s1=negf_env%contacts(jcontact)%s_01, &
2496 v_external=negf_control%contacts(jcontact)%v_external, &
2497 conv=negf_control%conv_green, transp=.false.)
2501 ALLOCATE (zdata(ncontacts, npoints))
2503 DO ipoint = 1, npoints
2508 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints), &
2510 ignore_bias=.false., &
2511 negf_env=negf_env, &
2512 negf_control=negf_control, &
2515 g_surf_contacts=g_surf_cache%g_surf_contacts(:, npoints_total + 1:), &
2516 gret_gamma_gadv=zdata(:, 1:npoints))
2518 DO ipoint = 1, npoints
2519 fermi_base = fermi_function(cmplx(real(xnodes(ipoint), kind=
dp) - mu_base, 0.0_dp, kind=
dp), &
2521 fermi_contact = fermi_function(cmplx(real(xnodes(ipoint), kind=
dp) - mu_contact, 0.0_dp, kind=
dp), &
2522 temperature_contact)
2523 CALL cp_cfm_scale(fermi_contact - fermi_base, zdata(icontact, ipoint))
2526 npoints_total = npoints_total + npoints
2530 DO ipoint = 1, npoints
2536 IF (sr_env%error <= conv_integr)
EXIT
2539 do_surface_green = .true.
2541 npoints = max_points - npoints_total
2542 IF (npoints <= 0)
EXIT
2543 IF (npoints >
SIZE(xnodes)) npoints =
SIZE(xnodes)
2551 CALL cp_cfm_to_fm(sr_env%integral, mtargetr=integral_real)
2558 stats%error = stats%error + sr_env%error*0.5_dp/
pi
2559 stats%npoints = stats%npoints + npoints_total
2562 IF (do_surface_green)
THEN
2570 CALL timestop(handle)
2571 END SUBROUTINE negf_add_rho_nonequiv
2578 ELEMENTAL SUBROUTINE integration_status_reset(stats)
2579 TYPE(integration_status_type),
INTENT(out) :: stats
2582 stats%error = 0.0_dp
2583 END SUBROUTINE integration_status_reset
2592 ELEMENTAL FUNCTION get_method_description_string(stats, integration_method)
RESULT(method_descr)
2593 TYPE(integration_status_type),
INTENT(in) :: stats
2594 INTEGER,
INTENT(in) :: integration_method
2595 CHARACTER(len=18) :: method_descr
2597 CHARACTER(len=2) :: method_abbr
2598 CHARACTER(len=6) :: npoints_str
2600 SELECT CASE (integration_method)
2611 WRITE (npoints_str,
'(I6)') stats%npoints
2612 WRITE (method_descr,
'(A2,T4,A,T11,ES8.2E2)') method_abbr, trim(adjustl(npoints_str)), stats%error
2613 END FUNCTION get_method_description_string
2628 FUNCTION negf_compute_current(contact_id1, contact_id2, v_shift, negf_env, negf_control, sub_env, ispin, &
2629 blacs_env_global)
RESULT(current)
2630 INTEGER,
INTENT(in) :: contact_id1, contact_id2
2631 REAL(kind=
dp),
INTENT(in) :: v_shift
2635 INTEGER,
INTENT(in) :: ispin
2637 REAL(kind=
dp) :: current
2639 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_compute_current'
2640 REAL(kind=
dp),
PARAMETER :: threshold = 16.0_dp*epsilon(0.0_dp)
2642 COMPLEX(kind=dp) :: fermi_contact1, fermi_contact2, &
2643 integr_lbound, integr_ubound
2644 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: transm_coeff, xnodes
2645 COMPLEX(kind=dp),
DIMENSION(1, 1) :: transmission
2646 INTEGER :: handle, icontact, ipoint, max_points, &
2647 min_points, ncontacts, npoints, &
2649 REAL(kind=
dp) :: conv_density, energy, eta, ln_conv_density, mu_contact1, mu_contact2, &
2650 temperature_contact1, temperature_contact2, v_contact1, v_contact2
2651 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: zdata
2659 IF (.NOT.
ASSOCIATED(negf_env%s_s))
RETURN
2661 CALL timeset(routinen, handle)
2663 ncontacts =
SIZE(negf_env%contacts)
2664 cpassert(contact_id1 <= ncontacts)
2665 cpassert(contact_id2 <= ncontacts)
2666 cpassert(contact_id1 /= contact_id2)
2668 v_contact1 = negf_control%contacts(contact_id1)%v_external
2669 mu_contact1 = negf_control%contacts(contact_id1)%fermi_level - v_contact1
2670 v_contact2 = negf_control%contacts(contact_id2)%v_external
2671 mu_contact2 = negf_control%contacts(contact_id2)%fermi_level - v_contact2
2673 IF (abs(mu_contact1 - mu_contact2) < threshold)
THEN
2674 CALL timestop(handle)
2678 min_points = negf_control%integr_min_points
2679 max_points = negf_control%integr_max_points
2680 temperature_contact1 = negf_control%contacts(contact_id1)%temperature
2681 temperature_contact2 = negf_control%contacts(contact_id2)%temperature
2682 eta = negf_control%eta
2683 conv_density = negf_control%conv_density
2684 ln_conv_density = log(conv_density)
2686 integr_lbound = cmplx(min(mu_contact1 + ln_conv_density*temperature_contact1, &
2687 mu_contact2 + ln_conv_density*temperature_contact2), eta, kind=
dp)
2688 integr_ubound = cmplx(max(mu_contact1 - ln_conv_density*temperature_contact1, &
2689 mu_contact2 - ln_conv_density*temperature_contact2), eta, kind=
dp)
2692 npoints = min_points
2694 NULLIFY (fm_struct_single)
2695 CALL cp_fm_struct_create(fm_struct_single, nrow_global=1, ncol_global=1, context=blacs_env_global)
2699 ALLOCATE (transm_coeff(npoints), xnodes(npoints), zdata(npoints))
2701 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2704 DO WHILE (npoints > 0 .AND. npoints_total < max_points)
2707 DO icontact = 1, ncontacts
2708 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, 1:npoints), &
2709 omega=xnodes(1:npoints), &
2710 h0=negf_env%contacts(icontact)%h_00(ispin), &
2711 s0=negf_env%contacts(icontact)%s_00, &
2712 h1=negf_env%contacts(icontact)%h_01(ispin), &
2713 s1=negf_env%contacts(icontact)%s_01, &
2715 v_external=negf_control%contacts(icontact)%v_external, &
2716 conv=negf_control%conv_green, transp=.false.)
2719 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints), &
2721 ignore_bias=.false., &
2722 negf_env=negf_env, &
2723 negf_control=negf_control, &
2726 g_surf_contacts=g_surf_cache%g_surf_contacts(:, 1:npoints), &
2727 transm_coeff=transm_coeff(1:npoints), &
2728 transm_contact1=contact_id1, &
2729 transm_contact2=contact_id2)
2731 DO ipoint = 1, npoints
2734 energy = real(xnodes(ipoint), kind=
dp)
2735 fermi_contact1 = fermi_function(cmplx(energy - mu_contact1, 0.0_dp, kind=
dp), temperature_contact1)
2736 fermi_contact2 = fermi_function(cmplx(energy - mu_contact2, 0.0_dp, kind=
dp), temperature_contact2)
2738 transmission(1, 1) = transm_coeff(ipoint)*(fermi_contact1 - fermi_contact2)
2744 npoints_total = npoints_total + npoints
2748 IF (sr_env%error <= negf_control%conv_density)
EXIT
2750 npoints = max_points - npoints_total
2751 IF (npoints <= 0)
EXIT
2752 IF (npoints >
SIZE(xnodes)) npoints =
SIZE(xnodes)
2765 DEALLOCATE (transm_coeff, xnodes, zdata)
2767 CALL timestop(handle)
2768 END FUNCTION negf_compute_current
2785 SUBROUTINE negf_print_dos(log_unit, energy_min, energy_max, npoints, v_shift, negf_env, &
2786 negf_control, sub_env, base_contact, just_contact, volume)
2787 INTEGER,
INTENT(in) :: log_unit
2788 REAL(kind=
dp),
INTENT(in) :: energy_min, energy_max
2789 INTEGER,
INTENT(in) :: npoints
2790 REAL(kind=
dp),
INTENT(in) :: v_shift
2794 INTEGER,
INTENT(in) :: base_contact
2795 INTEGER,
INTENT(in),
OPTIONAL :: just_contact
2796 REAL(kind=
dp),
INTENT(in),
OPTIONAL :: volume
2798 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_print_dos'
2800 CHARACTER :: uks_str
2801 CHARACTER(len=15) :: units_str
2802 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: xnodes
2803 INTEGER :: handle, icontact, ipoint, ispin, &
2804 ncontacts, npoints_bundle, &
2805 npoints_remain, nspins
2806 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: dos
2809 CALL timeset(routinen, handle)
2811 IF (
PRESENT(just_contact))
THEN
2812 nspins =
SIZE(negf_env%contacts(just_contact)%h_00)
2814 nspins =
SIZE(negf_env%h_s)
2817 IF (log_unit > 0)
THEN
2818 IF (
PRESENT(volume))
THEN
2819 units_str =
' (angstroms^-3)'
2824 IF (nspins > 1)
THEN
2832 IF (
PRESENT(just_contact))
THEN
2833 WRITE (log_unit,
'(3A,T70,I11)')
"# Density of states", trim(units_str),
" for the contact No. ", just_contact
2835 WRITE (log_unit,
'(3A)')
"# Density of states", trim(units_str),
" for the scattering region"
2838 WRITE (log_unit,
'(A,T10,A,T43,3A)')
"#",
"Energy (a.u.)",
"Number of states [alpha ", uks_str,
" beta]"
2840 WRITE (log_unit,
'("#", T3,78("-"))')
2843 ncontacts =
SIZE(negf_env%contacts)
2844 cpassert(base_contact <= ncontacts)
2845 IF (
PRESENT(just_contact))
THEN
2847 cpassert(just_contact == base_contact)
2849 mark_used(base_contact)
2851 npoints_bundle = 4*sub_env%ngroups
2852 IF (npoints_bundle > npoints) npoints_bundle = npoints
2854 ALLOCATE (dos(npoints_bundle, nspins), xnodes(npoints_bundle))
2856 npoints_remain = npoints
2857 DO WHILE (npoints_remain > 0)
2858 IF (npoints_bundle > npoints_remain) npoints_bundle = npoints_remain
2860 IF (npoints > 1)
THEN
2861 DO ipoint = 1, npoints_bundle
2862 xnodes(ipoint) = cmplx(energy_min + real(npoints - npoints_remain + ipoint - 1, kind=
dp)/ &
2863 REAL(npoints - 1, kind=
dp)*(energy_max - energy_min), negf_control%eta, kind=
dp)
2866 xnodes(ipoint) = cmplx(energy_min, negf_control%eta, kind=
dp)
2869 DO ispin = 1, nspins
2872 IF (
PRESENT(just_contact))
THEN
2873 DO icontact = 1, ncontacts
2874 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
2875 omega=xnodes(1:npoints_bundle), &
2876 h0=negf_env%contacts(just_contact)%h_00(ispin), &
2877 s0=negf_env%contacts(just_contact)%s_00, &
2878 h1=negf_env%contacts(just_contact)%h_01(ispin), &
2879 s1=negf_env%contacts(just_contact)%s_01, &
2880 sub_env=sub_env, v_external=0.0_dp, &
2881 conv=negf_control%conv_green, transp=(icontact == 1))
2884 DO icontact = 1, ncontacts
2885 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
2886 omega=xnodes(1:npoints_bundle), &
2887 h0=negf_env%contacts(icontact)%h_00(ispin), &
2888 s0=negf_env%contacts(icontact)%s_00, &
2889 h1=negf_env%contacts(icontact)%h_01(ispin), &
2890 s1=negf_env%contacts(icontact)%s_01, &
2892 v_external=negf_control%contacts(icontact)%v_external, &
2893 conv=negf_control%conv_green, transp=.false.)
2897 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints_bundle), &
2899 ignore_bias=.false., &
2900 negf_env=negf_env, &
2901 negf_control=negf_control, &
2904 g_surf_contacts=g_surf_cache%g_surf_contacts, &
2905 dos=dos(1:npoints_bundle, ispin), &
2906 just_contact=just_contact)
2911 IF (log_unit > 0)
THEN
2912 DO ipoint = 1, npoints_bundle
2913 IF (nspins > 1)
THEN
2915 WRITE (log_unit,
'(T2,F20.8,T30,2ES25.11E3)') real(xnodes(ipoint), kind=
dp), dos(ipoint, 1), dos(ipoint, 2)
2918 WRITE (log_unit,
'(T2,F20.8,T43,ES25.11E3)') real(xnodes(ipoint), kind=
dp), 2.0_dp*dos(ipoint, 1)
2923 npoints_remain = npoints_remain - npoints_bundle
2926 DEALLOCATE (dos, xnodes)
2927 CALL timestop(handle)
2928 END SUBROUTINE negf_print_dos
2944 SUBROUTINE negf_print_transmission(log_unit, energy_min, energy_max, npoints, v_shift, negf_env, &
2945 negf_control, sub_env, contact_id1, contact_id2)
2946 INTEGER,
INTENT(in) :: log_unit
2947 REAL(kind=
dp),
INTENT(in) :: energy_min, energy_max
2948 INTEGER,
INTENT(in) :: npoints
2949 REAL(kind=
dp),
INTENT(in) :: v_shift
2953 INTEGER,
INTENT(in) :: contact_id1, contact_id2
2955 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_print_transmission'
2957 CHARACTER :: uks_str
2958 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: xnodes
2959 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:, :) :: transm_coeff
2960 INTEGER :: handle, icontact, ipoint, ispin, &
2961 ncontacts, npoints_bundle, &
2962 npoints_remain, nspins
2963 REAL(kind=
dp) :: rscale
2966 CALL timeset(routinen, handle)
2968 nspins =
SIZE(negf_env%h_s)
2970 IF (nspins > 1)
THEN
2978 IF (log_unit > 0)
THEN
2979 WRITE (log_unit,
'(A)')
"# Transmission coefficient (G0 = 2 e^2/h) for the scattering region"
2981 WRITE (log_unit,
'(A,T10,A,T39,3A)')
"#",
"Energy (a.u.)",
"Transmission coefficient [alpha ", uks_str,
" beta]"
2982 WRITE (log_unit,
'("#", T3,78("-"))')
2985 ncontacts =
SIZE(negf_env%contacts)
2986 cpassert(contact_id1 <= ncontacts)
2987 cpassert(contact_id2 <= ncontacts)
2989 IF (nspins == 1)
THEN
2997 rscale = 0.5_dp*rscale
2999 npoints_bundle = 4*sub_env%ngroups
3000 IF (npoints_bundle > npoints) npoints_bundle = npoints
3002 ALLOCATE (transm_coeff(npoints_bundle, nspins), xnodes(npoints_bundle))
3004 npoints_remain = npoints
3005 DO WHILE (npoints_remain > 0)
3006 IF (npoints_bundle > npoints_remain) npoints_bundle = npoints_remain
3008 IF (npoints > 1)
THEN
3009 DO ipoint = 1, npoints_bundle
3010 xnodes(ipoint) = cmplx(energy_min + real(npoints - npoints_remain + ipoint - 1, kind=
dp)/ &
3011 REAL(npoints - 1, kind=
dp)*(energy_max - energy_min), negf_control%eta, kind=
dp)
3014 xnodes(ipoint) = cmplx(energy_min, negf_control%eta, kind=
dp)
3017 DO ispin = 1, nspins
3020 DO icontact = 1, ncontacts
3021 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
3022 omega=xnodes(1:npoints_bundle), &
3023 h0=negf_env%contacts(icontact)%h_00(ispin), &
3024 s0=negf_env%contacts(icontact)%s_00, &
3025 h1=negf_env%contacts(icontact)%h_01(ispin), &
3026 s1=negf_env%contacts(icontact)%s_01, &
3028 v_external=negf_control%contacts(icontact)%v_external, &
3029 conv=negf_control%conv_green, transp=.false.)
3032 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints_bundle), &
3034 ignore_bias=.false., &
3035 negf_env=negf_env, &
3036 negf_control=negf_control, &
3039 g_surf_contacts=g_surf_cache%g_surf_contacts, &
3040 transm_coeff=transm_coeff(1:npoints_bundle, ispin), &
3041 transm_contact1=contact_id1, &
3042 transm_contact2=contact_id2)
3047 IF (log_unit > 0)
THEN
3048 DO ipoint = 1, npoints_bundle
3049 IF (nspins > 1)
THEN
3051 WRITE (log_unit,
'(T2,F20.8,T30,2ES25.11E3)') &
3052 REAL(xnodes(ipoint), kind=
dp), rscale*real(transm_coeff(ipoint, 1:2), kind=
dp)
3055 WRITE (log_unit,
'(T2,F20.8,T43,ES25.11E3)') &
3056 REAL(xnodes(ipoint), kind=
dp), rscale*real(transm_coeff(ipoint, 1), kind=
dp)
3061 npoints_remain = npoints_remain - npoints_bundle
3064 DEALLOCATE (transm_coeff, xnodes)
3065 CALL timestop(handle)
3066 END SUBROUTINE negf_print_transmission
3080 SUBROUTINE negf_output_initial(log_unit, negf_env, sub_env, negf_control, dft_control, verbose_output, &
3082 INTEGER,
INTENT(in) :: log_unit
3087 LOGICAL,
INTENT(in) :: verbose_output, debug_output
3089 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_output_initial'
3091 CHARACTER(len=100) :: sfmt
3092 INTEGER :: handle, i, icontact, j, k, n, nrow
3093 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: target_m
3095 CALL timeset(routinen, handle)
3098 DO icontact = 1,
SIZE(negf_control%contacts)
3099 IF (log_unit > 0)
THEN
3100 WRITE (log_unit,
"(/,' The electrode',I5)") icontact
3101 WRITE (log_unit,
"( ' ------------------')")
3102 WRITE (log_unit,
"(' From the force environment:',I16)") negf_control%contacts(icontact)%force_env_index
3103 WRITE (log_unit,
"(' Number of atoms:',I27)")
SIZE(negf_control%contacts(icontact)%atomlist_bulk)
3104 IF (verbose_output)
WRITE (log_unit,
"(' Atoms belonging to a contact (from the entire system):')")
3105 IF (verbose_output)
WRITE (log_unit,
"(16I5)") negf_control%contacts(icontact)%atomlist_bulk
3106 WRITE (log_unit,
"(' Number of atoms in a primary unit cell:',I4)") &
3107 SIZE(negf_env%contacts(icontact)%atomlist_cell0)
3109 IF (log_unit > 0 .AND. verbose_output)
THEN
3110 WRITE (log_unit,
"(' Atoms belonging to a primary unit cell (from the entire system):')")
3111 WRITE (log_unit,
"(16I5)") negf_env%contacts(icontact)%atomlist_cell0
3112 WRITE (log_unit,
"(' Direction of an electrode: ',I16)") negf_env%contacts(icontact)%direction_axis
3115 IF (debug_output)
THEN
3116 CALL cp_fm_get_info(negf_env%contacts(icontact)%s_00, nrow_global=nrow)
3117 ALLOCATE (target_m(nrow, nrow))
3118 IF (log_unit > 0)
WRITE (log_unit,
"(' The number of atomic orbitals:',I13)") nrow
3119 DO k = 1, dft_control%nspins
3121 IF (log_unit > 0)
THEN
3122 WRITE (sfmt,
"('(',i0,'(E15.5))')") nrow
3123 WRITE (log_unit,
"(' The H_00 electrode Hamiltonian for spin',I2)") k
3125 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3129 IF (log_unit > 0)
THEN
3130 WRITE (log_unit,
"(' The H_01 electrode Hamiltonian for spin',I2)") k
3132 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3137 IF (log_unit > 0)
THEN
3138 WRITE (log_unit,
"(' The S_00 overlap matrix')")
3140 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3144 IF (log_unit > 0)
THEN
3145 WRITE (log_unit,
"(' The S_01 overlap matrix')")
3147 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3150 DEALLOCATE (target_m)
3155 IF (log_unit > 0)
THEN
3156 WRITE (log_unit,
"(/,' The full scattering region')")
3157 WRITE (log_unit,
"( ' --------------------------')")
3158 WRITE (log_unit,
"(' Number of atoms:',I27)")
SIZE(negf_control%atomlist_S_screening)
3159 IF (verbose_output)
WRITE (log_unit,
"(' Atoms belonging to a full scattering region:')")
3160 IF (verbose_output)
WRITE (log_unit,
"(16I5)") negf_control%atomlist_S_screening
3163 IF (debug_output)
THEN
3165 ALLOCATE (target_m(n, n))
3166 WRITE (sfmt,
"('(',i0,'(E15.5))')") n
3167 IF (log_unit > 0)
WRITE (log_unit,
"(' The number of atomic orbitals:',I14)") n
3168 DO k = 1, dft_control%nspins
3169 IF (log_unit > 0)
WRITE (log_unit,
"(' The H_s Hamiltonian for spin',I2)") k
3172 IF (log_unit > 0)
WRITE (log_unit, sfmt) (target_m(i, j), j=1, n)
3175 IF (log_unit > 0)
WRITE (log_unit,
"(' The S_s overlap matrix')")
3178 IF (log_unit > 0)
WRITE (log_unit, sfmt) (target_m(i, j), j=1, n)
3180 DEALLOCATE (target_m)
3181 IF (log_unit > 0)
WRITE (log_unit,
"(/,' Scattering region - electrode contacts')")
3182 IF (log_unit > 0)
WRITE (log_unit,
"( ' ---------------------------------------')")
3183 ALLOCATE (target_m(n, nrow))
3184 DO icontact = 1,
SIZE(negf_control%contacts)
3185 IF (log_unit > 0)
WRITE (log_unit,
"(/,' The contact',I5)") icontact
3186 IF (log_unit > 0)
WRITE (log_unit,
"( ' ----------------')")
3187 DO k = 1, dft_control%nspins
3189 IF (log_unit > 0)
THEN
3190 WRITE (log_unit,
"(' The H_sc Hamiltonian for spin',I2)") k
3192 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3197 IF (log_unit > 0)
THEN
3198 WRITE (log_unit,
"(' The S_sc overlap matrix')")
3200 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3204 DEALLOCATE (target_m)
3207 IF (log_unit > 0)
THEN
3208 WRITE (log_unit,
"(/,' NEGF| Number of MPI processes: ',I5)") sub_env%mpi_comm_global%num_pe
3209 WRITE (log_unit,
"(' NEGF| Maximal number of processes per energy point:',I5)") negf_control%nprocs
3210 WRITE (log_unit,
"(' NEGF| Number of parallel MPI (energy) groups: ',I5)") sub_env%ngroups
3213 CALL timestop(handle)
3214 END SUBROUTINE negf_output_initial
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.
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_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
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...
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
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)
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.
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 direct_mixing_nr
integer, parameter, public gspace_mixing_nr
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, 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, 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 qs_ks_build_kohn_sham_matrix(qs_env, calculate_forces, just_energy, print_active, ext_ks_matrix, ext_xc_section)
routine where the real calculations are made: the KS matrix is calculated
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.