127#include "./base/base_uses.f90"
132 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'negf_methods'
133 LOGICAL,
PARAMETER,
PRIVATE :: debug_this_module = .true.
142 TYPE integration_status_type
143 INTEGER :: npoints = -1
144 REAL(kind=
dp) :: error = -1.0_dp
145 END TYPE integration_status_type
158 CHARACTER(LEN=*),
PARAMETER :: routinen =
'do_negf'
160 CHARACTER(len=default_string_length) :: contact_id_str
161 INTEGER :: handle, icontact, ispin, log_unit, &
162 ncontacts, npoints, nspins, &
163 print_level, print_unit
164 LOGICAL :: should_output, verbose_output
165 REAL(kind=
dp) :: energy_max, energy_min
166 REAL(kind=
dp),
DIMENSION(2) :: current
178 negf_mixing_section, negf_section, &
179 print_section, root_section
181 CALL timeset(routinen, handle)
188 NULLIFY (blacs_env, cp_subsys, global_env, qs_env, root_section, sub_force_env)
189 CALL force_env_get(force_env, globenv=global_env, qs_env=qs_env, root_section=root_section, &
190 sub_force_env=sub_force_env, subsys=cp_subsys)
198 NULLIFY (negf_control)
203 log_unit =
cp_print_key_unit_nr(logger, negf_section,
"PRINT%PROGRAM_RUN_INFO", extension=
".Log")
206 IF (log_unit > 0)
THEN
207 CALL section_vals_val_get(negf_section,
"PRINT%PROGRAM_RUN_INFO%PRINT_LEVEL", i_val=print_level)
208 SELECT CASE (print_level)
210 verbose_output = .true.
212 verbose_output = .false.
216 IF (log_unit > 0)
THEN
217 WRITE (log_unit,
'(/,T2,A,T62)')
"COMPUTE THE RELEVANT HAMILTONIAN MATRICES"
220 CALL negf_sub_env_create(sub_env, negf_control, blacs_env, global_env%blacs_grid_layout, global_env%blacs_repeatable)
221 CALL negf_env_create(negf_env, sub_env, negf_control, force_env, negf_mixing_section, log_unit)
223 IF (log_unit > 0 .AND. verbose_output)
THEN
224 DO icontact = 1,
SIZE(negf_control%contacts)
225 WRITE (log_unit,
"(/,' NEGF| Atoms in the contact region',I2,':',I4)") &
226 icontact,
SIZE(negf_control%contacts(icontact)%atomlist_bulk)
227 WRITE (log_unit,
"(16I5)") negf_control%contacts(icontact)%atomlist_bulk
229 WRITE (log_unit,
"(/,' NEGF| Atoms in the full scattering region:',I4)")
SIZE(negf_control%atomlist_S_screening)
230 WRITE (log_unit,
"(16I5)") negf_control%atomlist_S_screening
235 ncontacts =
SIZE(negf_control%contacts)
236 DO icontact = 1, ncontacts
238 IF (negf_control%contacts(icontact)%force_env_index > 0)
THEN
239 CALL force_env_get(sub_force_env(negf_control%contacts(icontact)%force_env_index)%force_env, qs_env=qs_env)
243 CALL guess_fermi_level(icontact, negf_env, negf_control, sub_env, qs_env, log_unit)
248 IF (should_output)
THEN
256 middle_name=trim(adjustl(contact_id_str)), &
257 file_status=
"REPLACE")
259 CALL negf_print_dos(print_unit, energy_min, energy_max, npoints, &
260 v_shift=0.0_dp, negf_env=negf_env, negf_control=negf_control, &
261 sub_env=sub_env, base_contact=icontact, just_contact=icontact)
267 IF (ncontacts > 1)
THEN
269 CALL shift_potential(negf_env, negf_control, sub_env, qs_env, base_contact=1, log_unit=log_unit)
271 CALL converge_density(negf_env, negf_control, sub_env, qs_env, negf_control%v_shift, base_contact=1, log_unit=log_unit)
274 CALL get_qs_env(qs_env, dft_control=dft_control)
276 nspins = dft_control%nspins
278 cpassert(nspins <= 2)
284 current(ispin) = negf_compute_current(contact_id1=1, contact_id2=2, &
285 v_shift=negf_control%v_shift, &
287 negf_control=negf_control, &
290 blacs_env_global=blacs_env)
293 IF (log_unit > 0)
THEN
295 WRITE (log_unit,
'(/,T2,A,T60,ES20.7E2)')
"NEGF| Alpha-spin electric current (A)", current(1)
296 WRITE (log_unit,
'(T2,A,T60,ES20.7E2)')
"NEGF| Beta-spin electric current (A)", current(2)
298 WRITE (log_unit,
'(/,T2,A,T60,ES20.7E2)')
"NEGF| Electric current (A)", 2.0_dp*current(1)
306 IF (should_output)
THEN
314 middle_name=trim(adjustl(contact_id_str)), &
315 file_status=
"REPLACE")
317 CALL negf_print_dos(print_unit, energy_min, energy_max, npoints, negf_control%v_shift, &
318 negf_env=negf_env, negf_control=negf_control, &
319 sub_env=sub_env, base_contact=1)
327 IF (should_output)
THEN
334 extension=
".transm", &
335 middle_name=trim(adjustl(contact_id_str)), &
336 file_status=
"REPLACE")
338 CALL negf_print_transmission(print_unit, energy_min, energy_max, npoints, negf_control%v_shift, &
339 negf_env=negf_env, negf_control=negf_control, &
340 sub_env=sub_env, contact_id1=1, contact_id2=2)
351 CALL timestop(handle)
365 SUBROUTINE guess_fermi_level(contact_id, negf_env, negf_control, sub_env, qs_env, log_unit)
366 INTEGER,
INTENT(in) :: contact_id
371 INTEGER,
INTENT(in) :: log_unit
373 CHARACTER(LEN=*),
PARAMETER :: routinen =
'guess_fermi_level'
376 CHARACTER(len=default_string_length) :: temperature_str
377 COMPLEX(kind=dp) :: lbound_cpath, lbound_lpath, ubound_lpath
378 INTEGER :: direction_axis_abs, handle, image, &
379 ispin, nao, nimages, nspins, step
380 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: index_to_cell
381 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index
382 LOGICAL :: do_kpoints
383 REAL(kind=
dp) :: delta_au, energy_ubound_minus_fermi, fermi_level_guess, fermi_level_max, &
384 fermi_level_min, nelectrons_guess, nelectrons_max, nelectrons_min, nelectrons_qs_cell0, &
385 nelectrons_qs_cell1, offset_au, rscale, t1, t2, trace
390 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_s_kp, rho_ao_qs_kp
393 TYPE(integration_status_type) :: stats
399 CALL timeset(routinen, handle)
401 IF (negf_control%contacts(contact_id)%compute_fermi_level)
THEN
403 blacs_env=blacs_env_global, &
404 dft_control=dft_control, &
405 do_kpoints=do_kpoints, &
407 matrix_s_kp=matrix_s_kp, &
408 para_env=para_env_global, &
409 rho=rho_struct, subsys=subsys)
410 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_qs_kp)
412 nimages = dft_control%nimages
413 nspins = dft_control%nspins
414 direction_axis_abs = abs(negf_env%contacts(contact_id)%direction_axis)
416 cpassert(
SIZE(negf_env%contacts(contact_id)%h_00) == nspins)
418 IF (sub_env%ngroups > 1)
THEN
419 NULLIFY (matrix_s_fm, fm_struct)
421 CALL cp_fm_get_info(negf_env%contacts(contact_id)%s_00, nrow_global=nao)
422 CALL cp_fm_struct_create(fm_struct, nrow_global=nao, ncol_global=nao, context=blacs_env_global)
425 ALLOCATE (matrix_s_fm)
429 IF (sub_env%group_distribution(sub_env%mepos_global) == 0)
THEN
430 CALL cp_fm_copy_general(negf_env%contacts(contact_id)%s_00, matrix_s_fm, para_env_global)
435 matrix_s_fm => negf_env%contacts(contact_id)%s_00
443 ALLOCATE (cell_to_index(0:0, 0:0, 0:0))
444 cell_to_index(0, 0, 0) = 1
447 ALLOCATE (index_to_cell(3, nimages))
449 IF (.NOT. do_kpoints)
DEALLOCATE (cell_to_index)
451 IF (nspins == 1)
THEN
459 nelectrons_qs_cell0 = 0.0_dp
460 nelectrons_qs_cell1 = 0.0_dp
461 DO image = 1, nimages
462 IF (index_to_cell(direction_axis_abs, image) == 0)
THEN
464 CALL dbcsr_dot(rho_ao_qs_kp(ispin, image)%matrix, matrix_s_kp(1, image)%matrix, trace)
465 nelectrons_qs_cell0 = nelectrons_qs_cell0 + trace
467 ELSE IF (abs(index_to_cell(direction_axis_abs, image)) == 1)
THEN
469 CALL dbcsr_dot(rho_ao_qs_kp(ispin, image)%matrix, matrix_s_kp(1, image)%matrix, trace)
470 nelectrons_qs_cell1 = nelectrons_qs_cell1 + trace
474 DEALLOCATE (index_to_cell)
476 IF (log_unit > 0)
THEN
477 WRITE (temperature_str,
'(F11.3)') negf_control%contacts(contact_id)%temperature*
kelvin
478 WRITE (log_unit,
'(/,T2,A,I0,A)')
"COMPUTE FERMI LEVEL OF CONTACT ", &
479 contact_id,
" AT "//trim(adjustl(temperature_str))//
" KELVIN"
480 WRITE (log_unit,
'(/,T2,A,T60,F20.10,/)')
"Electronic density of the isolated contact unit cell:", &
481 -1.0_dp*(nelectrons_qs_cell0 + nelectrons_qs_cell1)
482 WRITE (log_unit,
'(T3,A)')
"Step Integration method Time Fermi level Convergence (density)"
483 WRITE (log_unit,
'(T3,78("-"))')
486 nelectrons_qs_cell0 = 0.0_dp
488 CALL cp_fm_trace(negf_env%contacts(contact_id)%rho_00(ispin), &
489 negf_env%contacts(contact_id)%s_00, trace)
490 nelectrons_qs_cell0 = nelectrons_qs_cell0 + trace
495 IF (negf_control%homo_lumo_gap > 0.0_dp)
THEN
496 IF (negf_control%contacts(contact_id)%refine_fermi_level)
THEN
497 fermi_level_min = negf_control%contacts(contact_id)%fermi_level
499 fermi_level_min = negf_env%contacts(contact_id)%homo_energy
501 fermi_level_max = fermi_level_min + negf_control%homo_lumo_gap
503 IF (negf_control%contacts(contact_id)%refine_fermi_level)
THEN
504 fermi_level_max = negf_control%contacts(contact_id)%fermi_level
506 fermi_level_max = negf_env%contacts(contact_id)%homo_energy
508 fermi_level_min = fermi_level_max + negf_control%homo_lumo_gap
512 lbound_cpath = cmplx(negf_control%energy_lbound, negf_control%eta, kind=
dp)
513 delta_au = real(negf_control%delta_npoles, kind=
dp)*
twopi*negf_control%contacts(contact_id)%temperature
514 offset_au = real(negf_control%gamma_kT, kind=
dp)*negf_control%contacts(contact_id)%temperature
515 energy_ubound_minus_fermi = -2.0_dp*log(negf_control%conv_density)*negf_control%contacts(contact_id)%temperature
523 fermi_level_guess = fermi_level_min
525 fermi_level_guess = fermi_level_max
527 fermi_level_guess = fermi_level_min - (nelectrons_min - nelectrons_qs_cell0)* &
528 (fermi_level_max - fermi_level_min)/(nelectrons_max - nelectrons_min)
531 negf_control%contacts(contact_id)%fermi_level = fermi_level_guess
532 nelectrons_guess = 0.0_dp
534 lbound_lpath = cmplx(fermi_level_guess - offset_au, delta_au, kind=
dp)
535 ubound_lpath = cmplx(fermi_level_guess + energy_ubound_minus_fermi, delta_au, kind=
dp)
537 CALL integration_status_reset(stats)
540 CALL negf_init_rho_equiv_residuals(rho_ao_fm=rho_ao_fm, &
542 ignore_bias=.true., &
544 negf_control=negf_control, &
547 base_contact=contact_id, &
548 just_contact=contact_id)
550 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_fm, &
553 ignore_bias=.true., &
555 negf_control=negf_control, &
558 base_contact=contact_id, &
559 integr_lbound=lbound_cpath, &
560 integr_ubound=lbound_lpath, &
561 matrix_s_global=matrix_s_fm, &
562 is_circular=.true., &
563 g_surf_cache=g_surf_cache, &
564 just_contact=contact_id)
567 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_fm, &
570 ignore_bias=.true., &
572 negf_control=negf_control, &
575 base_contact=contact_id, &
576 integr_lbound=lbound_lpath, &
577 integr_ubound=ubound_lpath, &
578 matrix_s_global=matrix_s_fm, &
579 is_circular=.false., &
580 g_surf_cache=g_surf_cache, &
581 just_contact=contact_id)
585 nelectrons_guess = nelectrons_guess + trace
587 nelectrons_guess = nelectrons_guess*rscale
591 IF (log_unit > 0)
THEN
592 WRITE (log_unit,
'(T2,I5,T12,A,T32,F8.1,T42,F15.8,T60,ES20.5E2)') &
593 step, get_method_description_string(stats, negf_control%integr_method), &
594 t2 - t1, fermi_level_guess, nelectrons_guess - nelectrons_qs_cell0
597 IF (abs(nelectrons_qs_cell0 - nelectrons_guess) < negf_control%conv_density)
EXIT
601 nelectrons_min = nelectrons_guess
603 nelectrons_max = nelectrons_guess
605 IF (fermi_level_guess < fermi_level_min)
THEN
606 fermi_level_max = fermi_level_min
607 nelectrons_max = nelectrons_min
608 fermi_level_min = fermi_level_guess
609 nelectrons_min = nelectrons_guess
610 ELSE IF (fermi_level_guess > fermi_level_max)
THEN
611 fermi_level_min = fermi_level_max
612 nelectrons_min = nelectrons_max
613 fermi_level_max = fermi_level_guess
614 nelectrons_max = nelectrons_guess
615 ELSE IF (fermi_level_max - fermi_level_guess < fermi_level_guess - fermi_level_min)
THEN
616 fermi_level_max = fermi_level_guess
617 nelectrons_max = nelectrons_guess
619 fermi_level_min = fermi_level_guess
620 nelectrons_min = nelectrons_guess
627 negf_control%contacts(contact_id)%fermi_level = fermi_level_guess
629 IF (sub_env%ngroups > 1)
THEN
631 DEALLOCATE (matrix_s_fm)
636 IF (log_unit > 0)
THEN
637 WRITE (temperature_str,
'(F11.3)') negf_control%contacts(contact_id)%temperature*
kelvin
638 WRITE (log_unit,
'(/,T2,A,I0)')
"NEGF| Contact No. ", contact_id
639 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| Fermi level at "//trim(adjustl(temperature_str))// &
640 " Kelvin (a.u.):", negf_control%contacts(contact_id)%fermi_level
641 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| Electric potential (V):", &
642 negf_control%contacts(contact_id)%v_external*
evolt
645 CALL timestop(handle)
646 END SUBROUTINE guess_fermi_level
657 SUBROUTINE shift_potential(negf_env, negf_control, sub_env, qs_env, base_contact, log_unit)
662 INTEGER,
INTENT(in) :: base_contact, log_unit
664 CHARACTER(LEN=*),
PARAMETER :: routinen =
'shift_potential'
667 COMPLEX(kind=dp) :: lbound_cpath, ubound_cpath, ubound_lpath
668 INTEGER :: handle, ispin, iter_count, nao, &
670 LOGICAL :: do_kpoints
671 REAL(kind=
dp) :: mu_base, nelectrons_guess, nelectrons_max, nelectrons_min, nelectrons_ref, &
672 t1, t2, temperature, trace, v_shift_guess, v_shift_max, v_shift_min
675 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: rho_ao_fm
677 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: rho_ao_qs_kp
680 DIMENSION(:) :: g_surf_circular, g_surf_linear
681 TYPE(integration_status_type) :: stats
686 ncontacts =
SIZE(negf_control%contacts)
688 IF (.NOT. (
ALLOCATED(negf_env%h_s) .AND.
ALLOCATED(negf_env%h_sc) .AND. &
689 ASSOCIATED(negf_env%s_s) .AND.
ALLOCATED(negf_env%s_sc)))
RETURN
690 IF (ncontacts < 2)
RETURN
692 CALL timeset(routinen, handle)
694 CALL get_qs_env(qs_env, blacs_env=blacs_env, do_kpoints=do_kpoints, dft_control=dft_control, &
695 para_env=para_env, rho=rho_struct, subsys=subsys)
696 cpassert(.NOT. do_kpoints)
702 IF (sub_env%ngroups > 1)
THEN
703 NULLIFY (matrix_s_fm, fm_struct)
708 ALLOCATE (matrix_s_fm)
712 IF (sub_env%group_distribution(sub_env%mepos_global) == 0)
THEN
718 matrix_s_fm => negf_env%s_s
723 nspins =
SIZE(negf_env%h_s)
725 mu_base = negf_control%contacts(base_contact)%fermi_level
728 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_qs_kp)
731 nelectrons_ref = 0.0_dp
732 ALLOCATE (rho_ao_fm(nspins))
737 fm=rho_ao_fm(ispin), &
738 atomlist_row=negf_control%atomlist_S_screening, &
739 atomlist_col=negf_control%atomlist_S_screening, &
740 subsys=subsys, mpi_comm_global=para_env, &
741 do_upper_diag=.true., do_lower=.true.)
743 CALL cp_fm_trace(rho_ao_fm(ispin), matrix_s_fm, trace)
744 nelectrons_ref = nelectrons_ref + trace
747 IF (log_unit > 0)
THEN
748 WRITE (log_unit,
'(/,T2,A)')
"COMPUTE SHIFT IN HARTREE POTENTIAL"
749 WRITE (log_unit,
'(/,T2,A,T55,F25.14,/)')
"Initial electronic density of the scattering region:", -1.0_dp*nelectrons_ref
750 WRITE (log_unit,
'(T3,A)')
"Step Integration method Time V shift Convergence (density)"
751 WRITE (log_unit,
'(T3,78("-"))')
754 temperature = negf_control%contacts(base_contact)%temperature
757 lbound_cpath = cmplx(negf_control%energy_lbound, negf_control%eta, kind=
dp)
758 ubound_cpath = cmplx(mu_base - real(negf_control%gamma_kT, kind=
dp)*temperature, &
759 REAL(negf_control%delta_npoles, kind=
dp)*
twopi*temperature, kind=
dp)
762 ubound_lpath = cmplx(mu_base - log(negf_control%conv_density)*temperature, &
763 REAL(negf_control%delta_npoles, kind=
dp)*
twopi*temperature, kind=
dp)
765 v_shift_min = negf_control%v_shift
766 v_shift_max = negf_control%v_shift + negf_control%v_shift_offset
768 ALLOCATE (g_surf_circular(nspins), g_surf_linear(nspins))
770 DO iter_count = 1, negf_control%v_shift_maxiters
771 SELECT CASE (iter_count)
773 v_shift_guess = v_shift_min
775 v_shift_guess = v_shift_max
777 v_shift_guess = v_shift_min - (nelectrons_min - nelectrons_ref)* &
778 (v_shift_max - v_shift_min)/(nelectrons_max - nelectrons_min)
782 CALL integration_status_reset(stats)
786 CALL negf_init_rho_equiv_residuals(rho_ao_fm=rho_ao_fm(ispin), &
787 v_shift=v_shift_guess, &
788 ignore_bias=.true., &
790 negf_control=negf_control, &
793 base_contact=base_contact)
796 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_fm(ispin), &
798 v_shift=v_shift_guess, &
799 ignore_bias=.true., &
801 negf_control=negf_control, &
804 base_contact=base_contact, &
805 integr_lbound=lbound_cpath, &
806 integr_ubound=ubound_cpath, &
807 matrix_s_global=matrix_s_fm, &
808 is_circular=.true., &
809 g_surf_cache=g_surf_circular(ispin))
810 IF (negf_control%disable_cache) &
814 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_fm(ispin), &
816 v_shift=v_shift_guess, &
817 ignore_bias=.true., &
819 negf_control=negf_control, &
822 base_contact=base_contact, &
823 integr_lbound=ubound_cpath, &
824 integr_ubound=ubound_lpath, &
825 matrix_s_global=matrix_s_fm, &
826 is_circular=.false., &
827 g_surf_cache=g_surf_linear(ispin))
828 IF (negf_control%disable_cache) &
840 CALL cp_fm_trace(rho_ao_fm(1), matrix_s_fm, nelectrons_guess)
844 IF (log_unit > 0)
THEN
845 WRITE (log_unit,
'(T2,I5,T12,A,T32,F8.1,T42,F15.8,T60,ES20.5E2)') &
846 iter_count, get_method_description_string(stats, negf_control%integr_method), &
847 t2 - t1, v_shift_guess, nelectrons_guess - nelectrons_ref
850 IF (abs(nelectrons_guess - nelectrons_ref) < negf_control%conv_scf)
EXIT
853 SELECT CASE (iter_count)
855 nelectrons_min = nelectrons_guess
857 nelectrons_max = nelectrons_guess
859 IF (v_shift_guess < v_shift_min)
THEN
860 v_shift_max = v_shift_min
861 nelectrons_max = nelectrons_min
862 v_shift_min = v_shift_guess
863 nelectrons_min = nelectrons_guess
864 ELSE IF (v_shift_guess > v_shift_max)
THEN
865 v_shift_min = v_shift_max
866 nelectrons_min = nelectrons_max
867 v_shift_max = v_shift_guess
868 nelectrons_max = nelectrons_guess
869 ELSE IF (v_shift_max - v_shift_guess < v_shift_guess - v_shift_min)
THEN
870 v_shift_max = v_shift_guess
871 nelectrons_max = nelectrons_guess
873 v_shift_min = v_shift_guess
874 nelectrons_min = nelectrons_guess
881 negf_control%v_shift = v_shift_guess
883 IF (log_unit > 0)
THEN
884 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| Shift in Hartree potential", negf_control%v_shift
887 DO ispin = nspins, 1, -1
891 DEALLOCATE (g_surf_circular, g_surf_linear)
895 IF (sub_env%ngroups > 1 .AND.
ASSOCIATED(matrix_s_fm))
THEN
897 DEALLOCATE (matrix_s_fm)
900 CALL timestop(handle)
901 END SUBROUTINE shift_potential
915 SUBROUTINE converge_density(negf_env, negf_control, sub_env, qs_env, v_shift, base_contact, log_unit)
920 REAL(kind=
dp),
INTENT(in) :: v_shift
921 INTEGER,
INTENT(in) :: base_contact, log_unit
923 CHARACTER(LEN=*),
PARAMETER :: routinen =
'converge_density'
924 REAL(kind=
dp),
PARAMETER :: threshold = 16.0_dp*epsilon(0.0_dp)
927 COMPLEX(kind=dp) :: lbound_cpath, ubound_cpath, ubound_lpath
928 INTEGER :: handle, icontact, image, ispin, &
929 iter_count, nao, ncontacts, nimages, &
931 LOGICAL :: do_kpoints
932 REAL(kind=
dp) :: iter_delta, mu_base, nelectrons, &
933 nelectrons_diff, t1, t2, temperature, &
934 trace, v_base, v_contact
937 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: rho_ao_delta_fm, rho_ao_new_fm
939 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks_initial_kp, matrix_ks_qs_kp, &
940 rho_ao_initial_kp, rho_ao_new_kp, &
944 DIMENSION(:) :: g_surf_circular, g_surf_linear, &
946 TYPE(integration_status_type) :: stats
951 ncontacts =
SIZE(negf_control%contacts)
953 IF (.NOT. (
ALLOCATED(negf_env%h_s) .AND.
ALLOCATED(negf_env%h_sc) .AND. &
954 ASSOCIATED(negf_env%s_s) .AND.
ALLOCATED(negf_env%s_sc)))
RETURN
955 IF (ncontacts < 2)
RETURN
957 CALL timeset(routinen, handle)
959 CALL get_qs_env(qs_env, blacs_env=blacs_env, do_kpoints=do_kpoints, dft_control=dft_control, &
960 matrix_ks_kp=matrix_ks_qs_kp, para_env=para_env, rho=rho_struct, subsys=subsys)
961 cpassert(.NOT. do_kpoints)
967 IF (sub_env%ngroups > 1)
THEN
968 NULLIFY (matrix_s_fm, fm_struct)
973 ALLOCATE (matrix_s_fm)
977 IF (sub_env%group_distribution(sub_env%mepos_global) == 0)
THEN
983 matrix_s_fm => negf_env%s_s
988 nspins =
SIZE(negf_env%h_s)
989 nimages = dft_control%nimages
991 v_base = negf_control%contacts(base_contact)%v_external
992 mu_base = negf_control%contacts(base_contact)%fermi_level + v_base
995 IF (ncontacts > 2)
THEN
996 cpabort(
"Poisson solver does not support the general NEGF setup (>2 contacts).")
1000 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_qs_kp)
1002 NULLIFY (matrix_ks_initial_kp, rho_ao_initial_kp, rho_ao_new_kp)
1007 DO image = 1, nimages
1008 DO ispin = 1, nspins
1009 CALL dbcsr_init_p(matrix_ks_initial_kp(ispin, image)%matrix)
1010 CALL dbcsr_copy(matrix_b=matrix_ks_initial_kp(ispin, image)%matrix, matrix_a=matrix_ks_qs_kp(ispin, image)%matrix)
1012 CALL dbcsr_init_p(rho_ao_initial_kp(ispin, image)%matrix)
1013 CALL dbcsr_copy(matrix_b=rho_ao_initial_kp(ispin, image)%matrix, matrix_a=rho_ao_qs_kp(ispin, image)%matrix)
1016 CALL dbcsr_copy(matrix_b=rho_ao_new_kp(ispin, image)%matrix, matrix_a=rho_ao_qs_kp(ispin, image)%matrix)
1022 ALLOCATE (rho_ao_delta_fm(nspins), rho_ao_new_fm(nspins))
1023 DO ispin = 1, nspins
1028 fm=rho_ao_delta_fm(ispin), &
1029 atomlist_row=negf_control%atomlist_S_screening, &
1030 atomlist_col=negf_control%atomlist_S_screening, &
1031 subsys=subsys, mpi_comm_global=para_env, &
1032 do_upper_diag=.true., do_lower=.true.)
1034 CALL cp_fm_trace(rho_ao_delta_fm(ispin), matrix_s_fm, trace)
1035 nelectrons = nelectrons + trace
1040 CALL mixing_allocate(qs_env, negf_env%mixing_method, nspins=nspins, mixing_store=negf_env%mixing_storage)
1041 IF (dft_control%qs_control%dftb .OR. dft_control%qs_control%xtb)
THEN
1042 cpabort(
'TB Code not available')
1043 ELSE IF (dft_control%qs_control%semi_empirical)
THEN
1044 cpabort(
'SE Code not possible')
1046 CALL mixing_init(negf_env%mixing_method, rho_struct, negf_env%mixing_storage, para_env)
1050 IF (log_unit > 0)
THEN
1051 WRITE (log_unit,
'(/,T2,A)')
"NEGF SELF-CONSISTENT PROCEDURE"
1052 WRITE (log_unit,
'(/,T2,A,T55,F25.14,/)')
"Initial electronic density of the scattering region:", -1.0_dp*nelectrons
1053 WRITE (log_unit,
'(T3,A)')
"Step Integration method Time Electronic density Convergence"
1054 WRITE (log_unit,
'(T3,78("-"))')
1057 temperature = negf_control%contacts(base_contact)%temperature
1059 DO icontact = 1, ncontacts
1060 IF (icontact /= base_contact)
THEN
1061 v_contact = negf_control%contacts(icontact)%v_external
1064 lbound_cpath = cmplx(negf_control%energy_lbound, negf_control%eta, kind=
dp)
1065 ubound_cpath = cmplx(mu_base - real(negf_control%gamma_kT, kind=
dp)*temperature, &
1066 REAL(negf_control%delta_npoles, kind=
dp)*
twopi*temperature, kind=
dp)
1069 ubound_lpath = cmplx(mu_base - log(negf_control%conv_density)*temperature, &
1070 REAL(negf_control%delta_npoles, kind=
dp)*
twopi*temperature, kind=
dp)
1072 ALLOCATE (g_surf_circular(nspins), g_surf_linear(nspins), g_surf_nonequiv(nspins))
1074 DO iter_count = 1, negf_control%max_scf
1076 CALL integration_status_reset(stats)
1078 DO ispin = 1, nspins
1080 CALL negf_init_rho_equiv_residuals(rho_ao_fm=rho_ao_new_fm(ispin), &
1082 ignore_bias=.false., &
1083 negf_env=negf_env, &
1084 negf_control=negf_control, &
1087 base_contact=base_contact)
1090 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_new_fm(ispin), &
1093 ignore_bias=.false., &
1094 negf_env=negf_env, &
1095 negf_control=negf_control, &
1098 base_contact=base_contact, &
1099 integr_lbound=lbound_cpath, &
1100 integr_ubound=ubound_cpath, &
1101 matrix_s_global=matrix_s_fm, &
1102 is_circular=.true., &
1103 g_surf_cache=g_surf_circular(ispin))
1104 IF (negf_control%disable_cache) &
1108 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_new_fm(ispin), &
1111 ignore_bias=.false., &
1112 negf_env=negf_env, &
1113 negf_control=negf_control, &
1116 base_contact=base_contact, &
1117 integr_lbound=ubound_cpath, &
1118 integr_ubound=ubound_lpath, &
1119 matrix_s_global=matrix_s_fm, &
1120 is_circular=.false., &
1121 g_surf_cache=g_surf_linear(ispin))
1122 IF (negf_control%disable_cache) &
1126 IF (abs(negf_control%contacts(icontact)%v_external - &
1127 negf_control%contacts(base_contact)%v_external) >= threshold)
THEN
1128 CALL negf_add_rho_nonequiv(rho_ao_fm=rho_ao_new_fm(ispin), &
1131 negf_env=negf_env, &
1132 negf_control=negf_control, &
1135 base_contact=base_contact, &
1136 matrix_s_global=matrix_s_fm, &
1137 g_surf_cache=g_surf_nonequiv(ispin))
1138 IF (negf_control%disable_cache) &
1143 IF (nspins == 1)
CALL cp_fm_scale(2.0_dp, rho_ao_new_fm(1))
1146 nelectrons_diff = 0.0_dp
1147 DO ispin = 1, nspins
1148 CALL cp_fm_trace(rho_ao_new_fm(ispin), matrix_s_fm, trace)
1149 nelectrons = nelectrons + trace
1153 CALL cp_fm_trace(rho_ao_delta_fm(ispin), matrix_s_fm, trace)
1154 nelectrons_diff = nelectrons_diff + trace
1157 CALL cp_fm_to_fm(rho_ao_new_fm(ispin), rho_ao_delta_fm(ispin))
1162 IF (log_unit > 0)
THEN
1163 WRITE (log_unit,
'(T2,I5,T12,A,T32,F8.1,T43,F20.8,T65,ES15.5E2)') &
1164 iter_count, get_method_description_string(stats, negf_control%integr_method), &
1165 t2 - t1, -1.0_dp*nelectrons, nelectrons_diff
1168 IF (abs(nelectrons_diff) < negf_control%conv_scf)
EXIT
1174 DO image = 1, nimages
1175 DO ispin = 1, nspins
1176 CALL dbcsr_copy(matrix_b=rho_ao_new_kp(ispin, image)%matrix, &
1177 matrix_a=rho_ao_initial_kp(ispin, image)%matrix)
1181 DO ispin = 1, nspins
1183 matrix=rho_ao_new_kp(ispin, 1)%matrix, &
1184 atomlist_row=negf_control%atomlist_S_screening, &
1185 atomlist_col=negf_control%atomlist_S_screening, &
1190 para_env, iter_delta, iter_count)
1192 DO image = 1, nimages
1193 DO ispin = 1, nspins
1194 CALL dbcsr_copy(rho_ao_qs_kp(ispin, image)%matrix, rho_ao_new_kp(ispin, image)%matrix)
1200 DO image = 1, nimages
1201 DO ispin = 1, nspins
1202 CALL dbcsr_copy(matrix_b=rho_ao_qs_kp(ispin, image)%matrix, &
1203 matrix_a=rho_ao_initial_kp(ispin, image)%matrix)
1207 DO ispin = 1, nspins
1209 matrix=rho_ao_qs_kp(ispin, 1)%matrix, &
1210 atomlist_row=negf_control%atomlist_S_screening, &
1211 atomlist_col=negf_control%atomlist_S_screening, &
1219 CALL gspace_mixing(qs_env, negf_env%mixing_method, negf_env%mixing_storage, &
1220 rho_struct, para_env, iter_count)
1227 DO ispin = 1, nspins
1229 fm=negf_env%h_s(ispin), &
1230 atomlist_row=negf_control%atomlist_S_screening, &
1231 atomlist_col=negf_control%atomlist_S_screening, &
1232 subsys=subsys, mpi_comm_global=para_env, &
1233 do_upper_diag=.true., do_lower=.true.)
1238 IF (log_unit > 0)
THEN
1239 IF (iter_count <= negf_control%max_scf)
THEN
1240 WRITE (log_unit,
'(/,T11,1X,A,I0,A)')
"*** NEGF run converged in ", iter_count,
" iteration(s) ***"
1242 WRITE (log_unit,
'(/,T11,1X,A,I0,A)')
"*** NEGF run did NOT converge after ", iter_count - 1,
" iteration(s) ***"
1246 DO ispin = nspins, 1, -1
1251 DEALLOCATE (g_surf_circular, g_surf_linear, g_surf_nonequiv)
1258 DO image = 1, nimages
1259 DO ispin = 1, nspins
1260 CALL dbcsr_copy(matrix_b=matrix_ks_qs_kp(ispin, image)%matrix, matrix_a=matrix_ks_initial_kp(ispin, image)%matrix)
1261 CALL dbcsr_copy(matrix_b=rho_ao_qs_kp(ispin, image)%matrix, matrix_a=rho_ao_initial_kp(ispin, image)%matrix)
1268 DEALLOCATE (matrix_ks_initial_kp, rho_ao_new_kp, rho_ao_initial_kp)
1270 IF (sub_env%ngroups > 1 .AND.
ASSOCIATED(matrix_s_fm))
THEN
1272 DEALLOCATE (matrix_s_fm)
1275 CALL timestop(handle)
1276 END SUBROUTINE converge_density
1293 SUBROUTINE negf_surface_green_function_batch(g_surf, omega, h0, s0, h1, s1, sub_env, v_external, conv, transp)
1294 TYPE(
cp_cfm_type),
DIMENSION(:),
INTENT(inout) :: g_surf
1295 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(in) :: omega
1296 TYPE(
cp_fm_type),
INTENT(IN) :: h0, s0, h1, s1
1298 REAL(kind=
dp),
INTENT(in) :: v_external, conv
1299 LOGICAL,
INTENT(in) :: transp
1301 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_surface_green_function_batch'
1304 INTEGER :: handle, igroup, ipoint, npoints
1308 CALL timeset(routinen, handle)
1309 npoints =
SIZE(omega)
1314 igroup = sub_env%group_distribution(sub_env%mepos_global)
1316 g_surf(1:npoints) = cfm_null
1318 DO ipoint = igroup + 1, npoints, sub_env%ngroups
1319 IF (debug_this_module)
THEN
1320 cpassert(.NOT.
ASSOCIATED(g_surf(ipoint)%matrix_struct))
1324 CALL do_sancho(g_surf(ipoint), omega(ipoint) - v_external, &
1325 h0, s0, h1, s1, conv, transp, work)
1329 CALL timestop(handle)
1330 END SUBROUTINE negf_surface_green_function_batch
1362 SUBROUTINE negf_retarded_green_function_batch(omega, v_shift, ignore_bias, negf_env, negf_control, sub_env, ispin, &
1364 g_ret_s, g_ret_scale, gamma_contacts, gret_gamma_gadv, dos, &
1365 transm_coeff, transm_contact1, transm_contact2, just_contact)
1366 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(in) :: omega
1367 REAL(kind=
dp),
INTENT(in) :: v_shift
1368 LOGICAL,
INTENT(in) :: ignore_bias
1372 INTEGER,
INTENT(in) :: ispin
1373 TYPE(
cp_cfm_type),
DIMENSION(:, :),
INTENT(in) :: g_surf_contacts
1376 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(in), &
1377 OPTIONAL :: g_ret_scale
1379 OPTIONAL :: gamma_contacts, gret_gamma_gadv
1380 REAL(kind=
dp),
DIMENSION(:),
INTENT(out),
OPTIONAL :: dos
1381 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(out), &
1382 OPTIONAL :: transm_coeff
1383 INTEGER,
INTENT(in),
OPTIONAL :: transm_contact1, transm_contact2, &
1386 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_retarded_green_function_batch'
1388 INTEGER :: handle, icontact, igroup, ipoint, &
1389 ncontacts, npoints, nrows
1390 REAL(kind=
dp) :: v_external
1392 DIMENSION(:) :: info1
1394 DIMENSION(:, :) :: info2
1395 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: g_ret_s_group, self_energy_contacts, &
1396 zwork1_contacts, zwork2_contacts
1397 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:, :) :: gamma_contacts_group, &
1398 gret_gamma_gadv_group
1404 CALL timeset(routinen, handle)
1405 npoints =
SIZE(omega)
1406 ncontacts =
SIZE(negf_env%contacts)
1407 cpassert(
SIZE(negf_control%contacts) == ncontacts)
1409 IF (
PRESENT(just_contact))
THEN
1410 cpassert(just_contact <= ncontacts)
1414 cpassert(ncontacts >= 2)
1416 IF (ignore_bias) v_external = 0.0_dp
1418 IF (
PRESENT(transm_coeff) .OR.
PRESENT(transm_contact1) .OR.
PRESENT(transm_contact2))
THEN
1419 cpassert(
PRESENT(transm_coeff))
1420 cpassert(
PRESENT(transm_contact1))
1421 cpassert(
PRESENT(transm_contact2))
1422 cpassert(.NOT.
PRESENT(just_contact))
1425 ALLOCATE (self_energy_contacts(ncontacts), zwork1_contacts(ncontacts), zwork2_contacts(ncontacts))
1427 IF (
PRESENT(just_contact))
THEN
1428 CALL cp_fm_get_info(negf_env%contacts(just_contact)%s_01, matrix_struct=fm_struct)
1429 DO icontact = 1, ncontacts
1434 CALL cp_fm_get_info(negf_env%contacts(just_contact)%s_00, nrow_global=nrows, matrix_struct=fm_struct)
1435 DO icontact = 1, ncontacts
1436 CALL cp_cfm_create(self_energy_contacts(icontact), fm_struct)
1439 DO icontact = 1, ncontacts
1440 CALL cp_fm_get_info(negf_env%s_sc(icontact), matrix_struct=fm_struct)
1445 CALL cp_fm_get_info(negf_env%s_s, nrow_global=nrows, matrix_struct=fm_struct)
1446 DO icontact = 1, ncontacts
1447 CALL cp_cfm_create(self_energy_contacts(icontact), fm_struct)
1451 IF (
PRESENT(g_ret_s) .OR.
PRESENT(gret_gamma_gadv) .OR. &
1452 PRESENT(dos) .OR.
PRESENT(transm_coeff))
THEN
1453 ALLOCATE (g_ret_s_group(npoints))
1455 IF (sub_env%ngroups <= 1 .AND.
PRESENT(g_ret_s))
THEN
1456 g_ret_s_group(1:npoints) = g_ret_s(1:npoints)
1460 IF (
PRESENT(gamma_contacts) .OR.
PRESENT(gret_gamma_gadv) .OR.
PRESENT(transm_coeff))
THEN
1461 IF (debug_this_module .AND.
PRESENT(gamma_contacts))
THEN
1462 cpassert(
SIZE(gamma_contacts, 1) == ncontacts)
1465 ALLOCATE (gamma_contacts_group(ncontacts, npoints))
1466 IF (sub_env%ngroups <= 1 .AND.
PRESENT(gamma_contacts))
THEN
1467 gamma_contacts_group(1:ncontacts, 1:npoints) = gamma_contacts(1:ncontacts, 1:npoints)
1471 IF (
PRESENT(gret_gamma_gadv))
THEN
1472 IF (debug_this_module .AND.
PRESENT(gret_gamma_gadv))
THEN
1473 cpassert(
SIZE(gret_gamma_gadv, 1) == ncontacts)
1476 ALLOCATE (gret_gamma_gadv_group(ncontacts, npoints))
1477 IF (sub_env%ngroups <= 1)
THEN
1478 gret_gamma_gadv_group(1:ncontacts, 1:npoints) = gret_gamma_gadv(1:ncontacts, 1:npoints)
1482 igroup = sub_env%group_distribution(sub_env%mepos_global)
1484 DO ipoint = 1, npoints
1485 IF (
ASSOCIATED(g_surf_contacts(1, ipoint)%matrix_struct))
THEN
1486 IF (sub_env%ngroups > 1 .OR. .NOT.
PRESENT(g_ret_s))
THEN
1490 IF (
ALLOCATED(g_ret_s_group))
THEN
1495 IF (sub_env%ngroups > 1 .OR. .NOT.
PRESENT(gamma_contacts))
THEN
1496 IF (
ALLOCATED(gamma_contacts_group))
THEN
1497 DO icontact = 1, ncontacts
1498 CALL cp_cfm_create(gamma_contacts_group(icontact, ipoint), fm_struct)
1503 IF (sub_env%ngroups > 1)
THEN
1504 IF (
ALLOCATED(gret_gamma_gadv_group))
THEN
1505 DO icontact = 1, ncontacts
1506 IF (
ASSOCIATED(gret_gamma_gadv(icontact, ipoint)%matrix_struct))
THEN
1507 CALL cp_cfm_create(gret_gamma_gadv_group(icontact, ipoint), fm_struct)
1513 IF (
PRESENT(just_contact))
THEN
1515 DO icontact = 1, ncontacts
1517 omega=omega(ipoint), &
1518 g_surf_c=g_surf_contacts(icontact, ipoint), &
1519 h_sc0=negf_env%contacts(just_contact)%h_01(ispin), &
1520 s_sc0=negf_env%contacts(just_contact)%s_01, &
1521 zwork1=zwork1_contacts(icontact), &
1522 zwork2=zwork2_contacts(icontact), &
1523 transp=(icontact == 1))
1527 DO icontact = 1, ncontacts
1528 IF (.NOT. ignore_bias) v_external = negf_control%contacts(icontact)%v_external
1531 omega=omega(ipoint) - v_external, &
1532 g_surf_c=g_surf_contacts(icontact, ipoint), &
1533 h_sc0=negf_env%h_sc(ispin, icontact), &
1534 s_sc0=negf_env%s_sc(icontact), &
1535 zwork1=zwork1_contacts(icontact), &
1536 zwork2=zwork2_contacts(icontact), &
1542 IF (
ALLOCATED(gamma_contacts_group))
THEN
1543 DO icontact = 1, ncontacts
1545 self_energy_c=self_energy_contacts(icontact))
1549 IF (
ALLOCATED(g_ret_s_group))
THEN
1551 DO icontact = 2, ncontacts
1556 IF (
PRESENT(just_contact))
THEN
1558 omega=omega(ipoint) - v_shift, &
1559 self_energy_ret_sum=self_energy_contacts(1), &
1560 h_s=negf_env%contacts(just_contact)%h_00(ispin), &
1561 s_s=negf_env%contacts(just_contact)%s_00)
1562 ELSE IF (ignore_bias)
THEN
1564 omega=omega(ipoint) - v_shift, &
1565 self_energy_ret_sum=self_energy_contacts(1), &
1566 h_s=negf_env%h_s(ispin), &
1570 omega=omega(ipoint) - v_shift, &
1571 self_energy_ret_sum=self_energy_contacts(1), &
1572 h_s=negf_env%h_s(ispin), &
1574 v_hartree_s=negf_env%v_hartree_s)
1577 IF (
PRESENT(g_ret_scale))
THEN
1578 IF (g_ret_scale(ipoint) /=
z_one)
CALL cp_cfm_scale(g_ret_scale(ipoint), g_ret_s_group(ipoint))
1582 IF (
ALLOCATED(gret_gamma_gadv_group))
THEN
1585 DO icontact = 1, ncontacts
1586 IF (
ASSOCIATED(gret_gamma_gadv_group(icontact, ipoint)%matrix_struct))
THEN
1588 z_one, gamma_contacts_group(icontact, ipoint), &
1589 g_ret_s_group(ipoint), &
1590 z_zero, self_energy_contacts(icontact))
1592 z_one, g_ret_s_group(ipoint), &
1593 self_energy_contacts(icontact), &
1594 z_zero, gret_gamma_gadv_group(icontact, ipoint))
1602 IF (
PRESENT(g_ret_s))
THEN
1603 IF (sub_env%ngroups > 1)
THEN
1605 DO ipoint = 1, npoints
1606 IF (
ASSOCIATED(g_ret_s(ipoint)%matrix_struct))
THEN
1612 IF (
ASSOCIATED(para_env))
THEN
1613 ALLOCATE (info1(npoints))
1615 DO ipoint = 1, npoints
1618 para_env, info1(ipoint))
1621 DO ipoint = 1, npoints
1622 IF (
ASSOCIATED(g_ret_s(ipoint)%matrix_struct))
THEN
1624 IF (
ASSOCIATED(g_ret_s_group(ipoint)%matrix_struct)) &
1634 IF (
PRESENT(gamma_contacts))
THEN
1635 IF (sub_env%ngroups > 1)
THEN
1637 pnt1:
DO ipoint = 1, npoints
1638 DO icontact = 1, ncontacts
1639 IF (
ASSOCIATED(gamma_contacts(icontact, ipoint)%matrix_struct))
THEN
1640 CALL cp_cfm_get_info(gamma_contacts(icontact, ipoint), para_env=para_env)
1646 IF (
ASSOCIATED(para_env))
THEN
1647 ALLOCATE (info2(ncontacts, npoints))
1649 DO ipoint = 1, npoints
1650 DO icontact = 1, ncontacts
1652 gamma_contacts(icontact, ipoint), &
1653 para_env, info2(icontact, ipoint))
1657 DO ipoint = 1, npoints
1658 DO icontact = 1, ncontacts
1659 IF (
ASSOCIATED(gamma_contacts(icontact, ipoint)%matrix_struct))
THEN
1661 IF (
ASSOCIATED(gamma_contacts_group(icontact, ipoint)%matrix_struct))
THEN
1673 IF (
PRESENT(gret_gamma_gadv))
THEN
1674 IF (sub_env%ngroups > 1)
THEN
1677 pnt2:
DO ipoint = 1, npoints
1678 DO icontact = 1, ncontacts
1679 IF (
ASSOCIATED(gret_gamma_gadv(icontact, ipoint)%matrix_struct))
THEN
1680 CALL cp_cfm_get_info(gret_gamma_gadv(icontact, ipoint), para_env=para_env)
1686 IF (
ASSOCIATED(para_env))
THEN
1687 ALLOCATE (info2(ncontacts, npoints))
1689 DO ipoint = 1, npoints
1690 DO icontact = 1, ncontacts
1692 gret_gamma_gadv(icontact, ipoint), &
1693 para_env, info2(icontact, ipoint))
1697 DO ipoint = 1, npoints
1698 DO icontact = 1, ncontacts
1699 IF (
ASSOCIATED(gret_gamma_gadv(icontact, ipoint)%matrix_struct))
THEN
1701 IF (
ASSOCIATED(gret_gamma_gadv_group(icontact, ipoint)%matrix_struct))
THEN
1713 IF (
PRESENT(dos))
THEN
1716 IF (
PRESENT(just_contact))
THEN
1717 matrix_s => negf_env%contacts(just_contact)%s_00
1719 matrix_s => negf_env%s_s
1725 DO ipoint = 1, npoints
1726 IF (
ASSOCIATED(g_ret_s_group(ipoint)%matrix_struct))
THEN
1727 CALL cp_cfm_to_fm(g_ret_s_group(ipoint), mtargeti=g_ret_imag)
1728 CALL cp_fm_trace(g_ret_imag, matrix_s, dos(ipoint))
1729 IF (sub_env%para_env%mepos /= 0) dos(ipoint) = 0.0_dp
1735 CALL sub_env%mpi_comm_global%sum(dos)
1736 dos(:) = -1.0_dp/
pi*dos(:)
1739 IF (
PRESENT(transm_coeff))
THEN
1742 DO ipoint = 1, npoints
1743 IF (
ASSOCIATED(g_ret_s_group(ipoint)%matrix_struct))
THEN
1746 z_one, gamma_contacts_group(transm_contact1, ipoint), &
1747 g_ret_s_group(ipoint), &
1748 z_zero, self_energy_contacts(transm_contact1))
1750 z_one, self_energy_contacts(transm_contact1), &
1751 gamma_contacts_group(transm_contact2, ipoint), &
1752 z_zero, self_energy_contacts(transm_contact2))
1756 self_energy_contacts(transm_contact2), &
1757 transm_coeff(ipoint))
1758 IF (sub_env%para_env%mepos /= 0) transm_coeff(ipoint) = 0.0_dp
1763 CALL sub_env%mpi_comm_global%sum(transm_coeff)
1768 IF (
ALLOCATED(g_ret_s_group))
THEN
1769 DO ipoint = npoints, 1, -1
1770 IF (sub_env%ngroups > 1 .OR. .NOT.
PRESENT(g_ret_s))
THEN
1774 DEALLOCATE (g_ret_s_group)
1777 IF (
ALLOCATED(gamma_contacts_group))
THEN
1778 DO ipoint = npoints, 1, -1
1779 DO icontact = ncontacts, 1, -1
1780 IF (sub_env%ngroups > 1 .OR. .NOT.
PRESENT(gamma_contacts))
THEN
1785 DEALLOCATE (gamma_contacts_group)
1788 IF (
ALLOCATED(gret_gamma_gadv_group))
THEN
1789 DO ipoint = npoints, 1, -1
1790 DO icontact = ncontacts, 1, -1
1791 IF (sub_env%ngroups > 1)
THEN
1796 DEALLOCATE (gret_gamma_gadv_group)
1799 IF (
ALLOCATED(self_energy_contacts))
THEN
1800 DO icontact = ncontacts, 1, -1
1803 DEALLOCATE (self_energy_contacts)
1806 IF (
ALLOCATED(zwork1_contacts))
THEN
1807 DO icontact = ncontacts, 1, -1
1810 DEALLOCATE (zwork1_contacts)
1813 IF (
ALLOCATED(zwork2_contacts))
THEN
1814 DO icontact = ncontacts, 1, -1
1817 DEALLOCATE (zwork2_contacts)
1820 CALL timestop(handle)
1821 END SUBROUTINE negf_retarded_green_function_batch
1831 PURE FUNCTION fermi_function(omega, temperature)
RESULT(val)
1832 COMPLEX(kind=dp),
INTENT(in) :: omega
1833 REAL(kind=
dp),
INTENT(in) :: temperature
1834 COMPLEX(kind=dp) :: val
1836 REAL(kind=
dp),
PARAMETER :: max_ln_omega_over_t = log(huge(0.0_dp))/16.0_dp
1838 IF (real(omega, kind=
dp) <= temperature*max_ln_omega_over_t)
THEN
1844 END FUNCTION fermi_function
1859 SUBROUTINE negf_init_rho_equiv_residuals(rho_ao_fm, v_shift, ignore_bias, negf_env, &
1860 negf_control, sub_env, ispin, base_contact, just_contact)
1862 REAL(kind=
dp),
INTENT(in) :: v_shift
1863 LOGICAL,
INTENT(in) :: ignore_bias
1867 INTEGER,
INTENT(in) :: ispin, base_contact
1868 INTEGER,
INTENT(in),
OPTIONAL :: just_contact
1870 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_init_rho_equiv_residuals'
1872 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: omega
1873 INTEGER :: handle, icontact, ipole, ncontacts, &
1875 REAL(kind=
dp) :: mu_base, pi_temperature, temperature, &
1877 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: g_ret_s
1882 CALL timeset(routinen, handle)
1884 temperature = negf_control%contacts(base_contact)%temperature
1885 IF (ignore_bias)
THEN
1886 mu_base = negf_control%contacts(base_contact)%fermi_level
1889 mu_base = negf_control%contacts(base_contact)%fermi_level + negf_control%contacts(base_contact)%v_external
1892 pi_temperature =
pi*temperature
1893 npoles = negf_control%delta_npoles
1895 ncontacts =
SIZE(negf_env%contacts)
1896 cpassert(base_contact <= ncontacts)
1897 IF (
PRESENT(just_contact))
THEN
1899 cpassert(just_contact == base_contact)
1902 IF (npoles > 0)
THEN
1903 CALL cp_fm_get_info(rho_ao_fm, para_env=para_env, matrix_struct=fm_struct)
1905 ALLOCATE (omega(npoles), g_ret_s(npoles))
1907 DO ipole = 1, npoles
1910 omega(ipole) = cmplx(mu_base, real(2*ipole - 1, kind=
dp)*pi_temperature, kind=
dp)
1915 IF (
PRESENT(just_contact))
THEN
1920 DO icontact = 1, ncontacts
1921 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
1923 h0=negf_env%contacts(just_contact)%h_00(ispin), &
1924 s0=negf_env%contacts(just_contact)%s_00, &
1925 h1=negf_env%contacts(just_contact)%h_01(ispin), &
1926 s1=negf_env%contacts(just_contact)%s_01, &
1927 sub_env=sub_env, v_external=0.0_dp, &
1928 conv=negf_control%conv_green, transp=(icontact == 1))
1931 DO icontact = 1, ncontacts
1932 IF (.NOT. ignore_bias) v_external = negf_control%contacts(icontact)%v_external
1934 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
1936 h0=negf_env%contacts(icontact)%h_00(ispin), &
1937 s0=negf_env%contacts(icontact)%s_00, &
1938 h1=negf_env%contacts(icontact)%h_01(ispin), &
1939 s1=negf_env%contacts(icontact)%s_01, &
1941 v_external=v_external, &
1942 conv=negf_control%conv_green, transp=.false.)
1946 CALL negf_retarded_green_function_batch(omega=omega(:), &
1948 ignore_bias=ignore_bias, &
1949 negf_env=negf_env, &
1950 negf_control=negf_control, &
1953 g_surf_contacts=g_surf_cache%g_surf_contacts, &
1955 just_contact=just_contact)
1959 DO ipole = 2, npoles
1967 DO ipole = npoles, 1, -1
1970 DEALLOCATE (g_ret_s, omega)
1973 CALL timestop(handle)
1974 END SUBROUTINE negf_init_rho_equiv_residuals
1995 SUBROUTINE negf_add_rho_equiv_low(rho_ao_fm, stats, v_shift, ignore_bias, negf_env, negf_control, sub_env, &
1996 ispin, base_contact, integr_lbound, integr_ubound, matrix_s_global, &
1997 is_circular, g_surf_cache, just_contact)
1999 TYPE(integration_status_type),
INTENT(inout) :: stats
2000 REAL(kind=
dp),
INTENT(in) :: v_shift
2001 LOGICAL,
INTENT(in) :: ignore_bias
2005 INTEGER,
INTENT(in) :: ispin, base_contact
2006 COMPLEX(kind=dp),
INTENT(in) :: integr_lbound, integr_ubound
2007 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_s_global
2008 LOGICAL,
INTENT(in) :: is_circular
2010 INTEGER,
INTENT(in),
OPTIONAL :: just_contact
2012 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_add_rho_equiv_low'
2014 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: xnodes, zscale
2015 INTEGER :: handle, icontact, interval_id, ipoint, max_points, min_points, ncontacts, &
2016 npoints, npoints_exist, npoints_tmp, npoints_total, shape_id
2017 LOGICAL :: do_surface_green
2018 REAL(kind=
dp) :: conv_integr, mu_base, temperature, &
2021 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: zdata, zdata_tmp
2027 CALL timeset(routinen, handle)
2031 conv_integr = 0.5_dp*negf_control%conv_density*
pi
2033 IF (ignore_bias)
THEN
2034 mu_base = negf_control%contacts(base_contact)%fermi_level
2037 mu_base = negf_control%contacts(base_contact)%fermi_level + negf_control%contacts(base_contact)%v_external
2040 min_points = negf_control%integr_min_points
2041 max_points = negf_control%integr_max_points
2042 temperature = negf_control%contacts(base_contact)%temperature
2044 ncontacts =
SIZE(negf_env%contacts)
2045 cpassert(base_contact <= ncontacts)
2046 IF (
PRESENT(just_contact))
THEN
2048 cpassert(just_contact == base_contact)
2051 do_surface_green = .NOT.
ALLOCATED(g_surf_cache%tnodes)
2053 IF (do_surface_green)
THEN
2054 npoints = min_points
2056 npoints =
SIZE(g_surf_cache%tnodes)
2060 CALL cp_fm_get_info(rho_ao_fm, para_env=para_env, matrix_struct=fm_struct)
2063 SELECT CASE (negf_control%integr_method)
2066 ALLOCATE (xnodes(npoints))
2068 IF (is_circular)
THEN
2076 IF (do_surface_green)
THEN
2077 CALL ccquad_init(cc_env, xnodes, npoints, integr_lbound, integr_ubound, &
2078 interval_id, shape_id, matrix_s_global)
2080 CALL ccquad_init(cc_env, xnodes, npoints, integr_lbound, integr_ubound, &
2081 interval_id, shape_id, matrix_s_global, tnodes_restart=g_surf_cache%tnodes)
2084 ALLOCATE (zdata(npoints))
2085 DO ipoint = 1, npoints
2090 IF (do_surface_green)
THEN
2093 IF (
PRESENT(just_contact))
THEN
2095 DO icontact = 1, ncontacts
2096 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, npoints_total + 1:), &
2097 omega=xnodes(1:npoints), &
2098 h0=negf_env%contacts(just_contact)%h_00(ispin), &
2099 s0=negf_env%contacts(just_contact)%s_00, &
2100 h1=negf_env%contacts(just_contact)%h_01(ispin), &
2101 s1=negf_env%contacts(just_contact)%s_01, &
2102 sub_env=sub_env, v_external=0.0_dp, &
2103 conv=negf_control%conv_green, transp=(icontact == 1))
2106 DO icontact = 1, ncontacts
2107 IF (.NOT. ignore_bias) v_external = negf_control%contacts(icontact)%v_external
2109 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, npoints_total + 1:), &
2110 omega=xnodes(1:npoints), &
2111 h0=negf_env%contacts(icontact)%h_00(ispin), &
2112 s0=negf_env%contacts(icontact)%s_00, &
2113 h1=negf_env%contacts(icontact)%h_01(ispin), &
2114 s1=negf_env%contacts(icontact)%s_01, &
2116 v_external=v_external, &
2117 conv=negf_control%conv_green, transp=.false.)
2122 ALLOCATE (zscale(npoints))
2124 IF (temperature >= 0.0_dp)
THEN
2125 DO ipoint = 1, npoints
2126 zscale(ipoint) = fermi_function(xnodes(ipoint) - mu_base, temperature)
2132 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints), &
2134 ignore_bias=ignore_bias, &
2135 negf_env=negf_env, &
2136 negf_control=negf_control, &
2139 g_surf_contacts=g_surf_cache%g_surf_contacts(:, npoints_total + 1:), &
2140 g_ret_s=zdata(1:npoints), &
2141 g_ret_scale=zscale(1:npoints), &
2142 just_contact=just_contact)
2144 DEALLOCATE (xnodes, zscale)
2145 npoints_total = npoints_total + npoints
2148 CALL move_alloc(zdata, zdata_tmp)
2152 IF (cc_env%error <= conv_integr)
EXIT
2153 IF (2*(npoints_total - 1) + 1 > max_points)
EXIT
2157 do_surface_green = .true.
2159 npoints_tmp = npoints
2161 npoints =
SIZE(xnodes)
2163 ALLOCATE (zdata(npoints))
2166 DO ipoint = 1, npoints_tmp
2167 IF (
ASSOCIATED(zdata_tmp(ipoint)%matrix_struct))
THEN
2168 npoints_exist = npoints_exist + 1
2169 zdata(npoints_exist) = zdata_tmp(ipoint)
2172 DEALLOCATE (zdata_tmp)
2174 DO ipoint = npoints_exist + 1, npoints
2180 stats%error = stats%error + cc_env%error/
pi
2182 DO ipoint =
SIZE(zdata_tmp), 1, -1
2185 DEALLOCATE (zdata_tmp)
2187 CALL cp_cfm_to_fm(cc_env%integral, mtargeti=integral_imag)
2190 IF (do_surface_green)
THEN
2197 ALLOCATE (xnodes(npoints), zdata(npoints), zscale(npoints))
2199 IF (is_circular)
THEN
2205 IF (do_surface_green)
THEN
2206 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2207 shape_id, conv_integr, matrix_s_global)
2209 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2210 shape_id, conv_integr, matrix_s_global, tnodes_restart=g_surf_cache%tnodes)
2213 DO WHILE (npoints > 0 .AND. npoints_total < max_points)
2214 DO ipoint = 1, npoints
2218 IF (do_surface_green)
THEN
2221 IF (
PRESENT(just_contact))
THEN
2223 DO icontact = 1, ncontacts
2224 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, npoints_total + 1:), &
2225 omega=xnodes(1:npoints), &
2226 h0=negf_env%contacts(just_contact)%h_00(ispin), &
2227 s0=negf_env%contacts(just_contact)%s_00, &
2228 h1=negf_env%contacts(just_contact)%h_01(ispin), &
2229 s1=negf_env%contacts(just_contact)%s_01, &
2230 sub_env=sub_env, v_external=0.0_dp, &
2231 conv=negf_control%conv_green, transp=(icontact == 1))
2234 DO icontact = 1, ncontacts
2235 IF (.NOT. ignore_bias) v_external = negf_control%contacts(icontact)%v_external
2237 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, npoints_total + 1:), &
2238 omega=xnodes(1:npoints), &
2239 h0=negf_env%contacts(icontact)%h_00(ispin), &
2240 s0=negf_env%contacts(icontact)%s_00, &
2241 h1=negf_env%contacts(icontact)%h_01(ispin), &
2242 s1=negf_env%contacts(icontact)%s_01, &
2244 v_external=v_external, &
2245 conv=negf_control%conv_green, transp=.false.)
2250 IF (temperature >= 0.0_dp)
THEN
2251 DO ipoint = 1, npoints
2252 zscale(ipoint) = fermi_function(xnodes(ipoint) - mu_base, temperature)
2258 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints), &
2260 ignore_bias=ignore_bias, &
2261 negf_env=negf_env, &
2262 negf_control=negf_control, &
2265 g_surf_contacts=g_surf_cache%g_surf_contacts(:, npoints_total + 1:), &
2266 g_ret_s=zdata(1:npoints), &
2267 g_ret_scale=zscale(1:npoints), &
2268 just_contact=just_contact)
2270 npoints_total = npoints_total + npoints
2274 IF (sr_env%error <= conv_integr)
EXIT
2279 do_surface_green = .true.
2281 npoints = max_points - npoints_total
2282 IF (npoints <= 0)
EXIT
2283 IF (npoints >
SIZE(xnodes)) npoints =
SIZE(xnodes)
2289 stats%error = stats%error + sr_env%error/
pi
2291 CALL cp_cfm_to_fm(sr_env%integral, mtargeti=integral_imag)
2294 IF (do_surface_green)
THEN
2299 DEALLOCATE (xnodes, zdata, zscale)
2302 cpabort(
"Unimplemented integration method")
2305 stats%npoints = stats%npoints + npoints_total
2310 CALL timestop(handle)
2311 END SUBROUTINE negf_add_rho_equiv_low
2327 SUBROUTINE negf_add_rho_nonequiv(rho_ao_fm, stats, v_shift, negf_env, negf_control, sub_env, &
2328 ispin, base_contact, matrix_s_global, g_surf_cache)
2330 TYPE(integration_status_type),
INTENT(inout) :: stats
2331 REAL(kind=
dp),
INTENT(in) :: v_shift
2335 INTEGER,
INTENT(in) :: ispin, base_contact
2336 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_s_global
2339 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_add_rho_nonequiv'
2341 COMPLEX(kind=dp) :: fermi_base, fermi_contact, &
2342 integr_lbound, integr_ubound
2343 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: xnodes
2344 INTEGER :: handle, icontact, ipoint, jcontact, &
2345 max_points, min_points, ncontacts, &
2346 npoints, npoints_total
2347 LOGICAL :: do_surface_green
2348 REAL(kind=
dp) :: conv_density, conv_integr, eta, &
2349 ln_conv_density, mu_base, mu_contact, &
2350 temperature_base, temperature_contact
2351 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:, :) :: zdata
2356 CALL timeset(routinen, handle)
2358 ncontacts =
SIZE(negf_env%contacts)
2359 cpassert(base_contact <= ncontacts)
2362 IF (ncontacts > 2)
THEN
2363 cpabort(
"Poisson solver does not support the general NEGF setup (>2 contacts).")
2366 mu_base = negf_control%contacts(base_contact)%fermi_level + negf_control%contacts(base_contact)%v_external
2367 min_points = negf_control%integr_min_points
2368 max_points = negf_control%integr_max_points
2369 temperature_base = negf_control%contacts(base_contact)%temperature
2370 eta = negf_control%eta
2371 conv_density = negf_control%conv_density
2372 ln_conv_density = log(conv_density)
2376 conv_integr = 0.5_dp*conv_density*
pi
2378 DO icontact = 1, ncontacts
2379 IF (icontact /= base_contact)
THEN
2380 mu_contact = negf_control%contacts(icontact)%fermi_level + negf_control%contacts(icontact)%v_external
2381 temperature_contact = negf_control%contacts(icontact)%temperature
2383 integr_lbound = cmplx(min(mu_base + ln_conv_density*temperature_base, &
2384 mu_contact + ln_conv_density*temperature_contact), eta, kind=
dp)
2385 integr_ubound = cmplx(max(mu_base - ln_conv_density*temperature_base, &
2386 mu_contact - ln_conv_density*temperature_contact), eta, kind=
dp)
2388 do_surface_green = .NOT.
ALLOCATED(g_surf_cache%tnodes)
2390 IF (do_surface_green)
THEN
2391 npoints = min_points
2393 npoints =
SIZE(g_surf_cache%tnodes)
2399 ALLOCATE (xnodes(npoints), zdata(ncontacts, npoints))
2401 IF (do_surface_green)
THEN
2402 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2405 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2406 sr_shape_linear, conv_integr, matrix_s_global, tnodes_restart=g_surf_cache%tnodes)
2409 DO WHILE (npoints > 0 .AND. npoints_total < max_points)
2410 IF (do_surface_green)
THEN
2413 DO jcontact = 1, ncontacts
2414 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(jcontact, npoints_total + 1:), &
2415 omega=xnodes(1:npoints), &
2416 h0=negf_env%contacts(jcontact)%h_00(ispin), &
2417 s0=negf_env%contacts(jcontact)%s_00, &
2418 h1=negf_env%contacts(jcontact)%h_01(ispin), &
2419 s1=negf_env%contacts(jcontact)%s_01, &
2421 v_external=negf_control%contacts(jcontact)%v_external, &
2422 conv=negf_control%conv_green, transp=.false.)
2426 DO ipoint = 1, npoints
2430 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints), &
2432 ignore_bias=.false., &
2433 negf_env=negf_env, &
2434 negf_control=negf_control, &
2437 g_surf_contacts=g_surf_cache%g_surf_contacts(:, npoints_total + 1:), &
2438 gret_gamma_gadv=zdata(:, 1:npoints))
2440 DO ipoint = 1, npoints
2441 fermi_base = fermi_function(cmplx(real(xnodes(ipoint), kind=
dp) - mu_base, 0.0_dp, kind=
dp), &
2443 fermi_contact = fermi_function(cmplx(real(xnodes(ipoint), kind=
dp) - mu_contact, 0.0_dp, kind=
dp), &
2444 temperature_contact)
2445 CALL cp_cfm_scale(fermi_contact - fermi_base, zdata(icontact, ipoint))
2448 npoints_total = npoints_total + npoints
2452 IF (sr_env%error <= conv_integr)
EXIT
2455 do_surface_green = .true.
2457 npoints = max_points - npoints_total
2458 IF (npoints <= 0)
EXIT
2459 IF (npoints >
SIZE(xnodes)) npoints =
SIZE(xnodes)
2466 CALL cp_cfm_to_fm(sr_env%integral, mtargetr=integral_real)
2471 DEALLOCATE (xnodes, zdata)
2473 stats%error = stats%error + sr_env%error*0.5_dp/
pi
2474 stats%npoints = stats%npoints + npoints_total
2477 IF (do_surface_green)
THEN
2485 CALL timestop(handle)
2486 END SUBROUTINE negf_add_rho_nonequiv
2493 ELEMENTAL SUBROUTINE integration_status_reset(stats)
2494 TYPE(integration_status_type),
INTENT(out) :: stats
2497 stats%error = 0.0_dp
2498 END SUBROUTINE integration_status_reset
2507 ELEMENTAL FUNCTION get_method_description_string(stats, integration_method)
RESULT(method_descr)
2508 TYPE(integration_status_type),
INTENT(in) :: stats
2509 INTEGER,
INTENT(in) :: integration_method
2510 CHARACTER(len=18) :: method_descr
2512 CHARACTER(len=2) :: method_abbr
2513 CHARACTER(len=6) :: npoints_str
2515 SELECT CASE (integration_method)
2526 WRITE (npoints_str,
'(I6)') stats%npoints
2527 WRITE (method_descr,
'(A2,T4,A,T11,ES8.2E2)') method_abbr, trim(adjustl(npoints_str)), stats%error
2528 END FUNCTION get_method_description_string
2543 FUNCTION negf_compute_current(contact_id1, contact_id2, v_shift, negf_env, negf_control, sub_env, ispin, &
2544 blacs_env_global)
RESULT(current)
2545 INTEGER,
INTENT(in) :: contact_id1, contact_id2
2546 REAL(kind=
dp),
INTENT(in) :: v_shift
2550 INTEGER,
INTENT(in) :: ispin
2552 REAL(kind=
dp) :: current
2554 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_compute_current'
2555 REAL(kind=
dp),
PARAMETER :: threshold = 16.0_dp*epsilon(0.0_dp)
2557 COMPLEX(kind=dp) :: fermi_contact1, fermi_contact2, &
2558 integr_lbound, integr_ubound
2559 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: transm_coeff, xnodes
2560 COMPLEX(kind=dp),
DIMENSION(1, 1) :: transmission
2561 INTEGER :: handle, icontact, ipoint, max_points, &
2562 min_points, ncontacts, npoints, &
2564 REAL(kind=
dp) :: conv_density, energy, eta, ln_conv_density, mu_contact1, mu_contact2, &
2565 temperature_contact1, temperature_contact2, v_contact1, v_contact2
2566 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: zdata
2574 IF (.NOT.
ASSOCIATED(negf_env%s_s))
RETURN
2576 CALL timeset(routinen, handle)
2578 ncontacts =
SIZE(negf_env%contacts)
2579 cpassert(contact_id1 <= ncontacts)
2580 cpassert(contact_id2 <= ncontacts)
2581 cpassert(contact_id1 /= contact_id2)
2583 v_contact1 = negf_control%contacts(contact_id1)%v_external
2584 mu_contact1 = negf_control%contacts(contact_id1)%fermi_level + v_contact1
2585 v_contact2 = negf_control%contacts(contact_id2)%v_external
2586 mu_contact2 = negf_control%contacts(contact_id2)%fermi_level + v_contact2
2588 IF (abs(mu_contact1 - mu_contact2) < threshold)
THEN
2589 CALL timestop(handle)
2593 min_points = negf_control%integr_min_points
2594 max_points = negf_control%integr_max_points
2595 temperature_contact1 = negf_control%contacts(contact_id1)%temperature
2596 temperature_contact2 = negf_control%contacts(contact_id2)%temperature
2597 eta = negf_control%eta
2598 conv_density = negf_control%conv_density
2599 ln_conv_density = log(conv_density)
2601 integr_lbound = cmplx(min(mu_contact1 + ln_conv_density*temperature_contact1, &
2602 mu_contact2 + ln_conv_density*temperature_contact2), eta, kind=
dp)
2603 integr_ubound = cmplx(max(mu_contact1 - ln_conv_density*temperature_contact1, &
2604 mu_contact2 - ln_conv_density*temperature_contact2), eta, kind=
dp)
2607 npoints = min_points
2609 NULLIFY (fm_struct_single)
2610 CALL cp_fm_struct_create(fm_struct_single, nrow_global=1, ncol_global=1, context=blacs_env_global)
2614 ALLOCATE (transm_coeff(npoints), xnodes(npoints), zdata(npoints))
2616 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2619 DO WHILE (npoints > 0 .AND. npoints_total < max_points)
2622 DO icontact = 1, ncontacts
2623 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, 1:npoints), &
2624 omega=xnodes(1:npoints), &
2625 h0=negf_env%contacts(icontact)%h_00(ispin), &
2626 s0=negf_env%contacts(icontact)%s_00, &
2627 h1=negf_env%contacts(icontact)%h_01(ispin), &
2628 s1=negf_env%contacts(icontact)%s_01, &
2630 v_external=negf_control%contacts(icontact)%v_external, &
2631 conv=negf_control%conv_green, transp=.false.)
2634 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints), &
2636 ignore_bias=.false., &
2637 negf_env=negf_env, &
2638 negf_control=negf_control, &
2641 g_surf_contacts=g_surf_cache%g_surf_contacts(:, 1:npoints), &
2642 transm_coeff=transm_coeff(1:npoints), &
2643 transm_contact1=contact_id1, &
2644 transm_contact2=contact_id2)
2646 DO ipoint = 1, npoints
2649 energy = real(xnodes(ipoint), kind=
dp)
2650 fermi_contact1 = fermi_function(cmplx(energy - mu_contact1, 0.0_dp, kind=
dp), temperature_contact1)
2651 fermi_contact2 = fermi_function(cmplx(energy - mu_contact2, 0.0_dp, kind=
dp), temperature_contact2)
2653 transmission(1, 1) = transm_coeff(ipoint)*(fermi_contact1 - fermi_contact2)
2659 npoints_total = npoints_total + npoints
2663 IF (sr_env%error <= negf_control%conv_density)
EXIT
2665 npoints = max_points - npoints_total
2666 IF (npoints <= 0)
EXIT
2667 IF (npoints >
SIZE(xnodes)) npoints =
SIZE(xnodes)
2680 DEALLOCATE (transm_coeff, xnodes, zdata)
2682 CALL timestop(handle)
2683 END FUNCTION negf_compute_current
2700 SUBROUTINE negf_print_dos(log_unit, energy_min, energy_max, npoints, v_shift, negf_env, &
2701 negf_control, sub_env, base_contact, just_contact, volume)
2702 INTEGER,
INTENT(in) :: log_unit
2703 REAL(kind=
dp),
INTENT(in) :: energy_min, energy_max
2704 INTEGER,
INTENT(in) :: npoints
2705 REAL(kind=
dp),
INTENT(in) :: v_shift
2709 INTEGER,
INTENT(in) :: base_contact
2710 INTEGER,
INTENT(in),
OPTIONAL :: just_contact
2711 REAL(kind=
dp),
INTENT(in),
OPTIONAL :: volume
2713 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_print_dos'
2715 CHARACTER :: uks_str
2716 CHARACTER(len=15) :: units_str
2717 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: xnodes
2718 INTEGER :: handle, icontact, ipoint, ispin, &
2719 ncontacts, npoints_bundle, &
2720 npoints_remain, nspins
2721 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: dos
2724 CALL timeset(routinen, handle)
2726 IF (
PRESENT(just_contact))
THEN
2727 nspins =
SIZE(negf_env%contacts(just_contact)%h_00)
2729 nspins =
SIZE(negf_env%h_s)
2732 IF (log_unit > 0)
THEN
2733 IF (
PRESENT(volume))
THEN
2734 units_str =
' (angstroms^-3)'
2739 IF (nspins > 1)
THEN
2747 IF (
PRESENT(just_contact))
THEN
2748 WRITE (log_unit,
'(3A,T70,I11)')
"# Density of states", trim(units_str),
" for the contact No. ", just_contact
2750 WRITE (log_unit,
'(3A)')
"# Density of states", trim(units_str),
" for the scattering region"
2753 WRITE (log_unit,
'(A,T10,A,T43,3A)')
"#",
"Energy (a.u.)",
"Number of states [alpha ", uks_str,
" beta]"
2755 WRITE (log_unit,
'("#", T3,78("-"))')
2758 ncontacts =
SIZE(negf_env%contacts)
2759 cpassert(base_contact <= ncontacts)
2760 IF (
PRESENT(just_contact))
THEN
2762 cpassert(just_contact == base_contact)
2764 mark_used(base_contact)
2766 npoints_bundle = 4*sub_env%ngroups
2767 IF (npoints_bundle > npoints) npoints_bundle = npoints
2769 ALLOCATE (dos(npoints_bundle, nspins), xnodes(npoints_bundle))
2771 npoints_remain = npoints
2772 DO WHILE (npoints_remain > 0)
2773 IF (npoints_bundle > npoints_remain) npoints_bundle = npoints_remain
2775 IF (npoints > 1)
THEN
2776 DO ipoint = 1, npoints_bundle
2777 xnodes(ipoint) = cmplx(energy_min + real(npoints - npoints_remain + ipoint - 1, kind=
dp)/ &
2778 REAL(npoints - 1, kind=
dp)*(energy_max - energy_min), negf_control%eta, kind=
dp)
2781 xnodes(ipoint) = cmplx(energy_min, negf_control%eta, kind=
dp)
2784 DO ispin = 1, nspins
2787 IF (
PRESENT(just_contact))
THEN
2788 DO icontact = 1, ncontacts
2789 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
2790 omega=xnodes(1:npoints_bundle), &
2791 h0=negf_env%contacts(just_contact)%h_00(ispin), &
2792 s0=negf_env%contacts(just_contact)%s_00, &
2793 h1=negf_env%contacts(just_contact)%h_01(ispin), &
2794 s1=negf_env%contacts(just_contact)%s_01, &
2795 sub_env=sub_env, v_external=0.0_dp, &
2796 conv=negf_control%conv_green, transp=(icontact == 1))
2799 DO icontact = 1, ncontacts
2800 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
2801 omega=xnodes(1:npoints_bundle), &
2802 h0=negf_env%contacts(icontact)%h_00(ispin), &
2803 s0=negf_env%contacts(icontact)%s_00, &
2804 h1=negf_env%contacts(icontact)%h_01(ispin), &
2805 s1=negf_env%contacts(icontact)%s_01, &
2807 v_external=negf_control%contacts(icontact)%v_external, &
2808 conv=negf_control%conv_green, transp=.false.)
2812 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints_bundle), &
2814 ignore_bias=.false., &
2815 negf_env=negf_env, &
2816 negf_control=negf_control, &
2819 g_surf_contacts=g_surf_cache%g_surf_contacts, &
2820 dos=dos(1:npoints_bundle, ispin), &
2821 just_contact=just_contact)
2826 IF (log_unit > 0)
THEN
2827 DO ipoint = 1, npoints_bundle
2828 IF (nspins > 1)
THEN
2830 WRITE (log_unit,
'(T2,F20.8,T30,2ES25.11E3)') real(xnodes(ipoint), kind=
dp), dos(ipoint, 1), dos(ipoint, 2)
2833 WRITE (log_unit,
'(T2,F20.8,T43,ES25.11E3)') real(xnodes(ipoint), kind=
dp), 2.0_dp*dos(ipoint, 1)
2838 npoints_remain = npoints_remain - npoints_bundle
2841 DEALLOCATE (dos, xnodes)
2842 CALL timestop(handle)
2843 END SUBROUTINE negf_print_dos
2859 SUBROUTINE negf_print_transmission(log_unit, energy_min, energy_max, npoints, v_shift, negf_env, &
2860 negf_control, sub_env, contact_id1, contact_id2)
2861 INTEGER,
INTENT(in) :: log_unit
2862 REAL(kind=
dp),
INTENT(in) :: energy_min, energy_max
2863 INTEGER,
INTENT(in) :: npoints
2864 REAL(kind=
dp),
INTENT(in) :: v_shift
2868 INTEGER,
INTENT(in) :: contact_id1, contact_id2
2870 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_print_transmission'
2872 CHARACTER :: uks_str
2873 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: xnodes
2874 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:, :) :: transm_coeff
2875 INTEGER :: handle, icontact, ipoint, ispin, &
2876 ncontacts, npoints_bundle, &
2877 npoints_remain, nspins
2878 REAL(kind=
dp) :: rscale
2881 CALL timeset(routinen, handle)
2883 nspins =
SIZE(negf_env%h_s)
2885 IF (nspins > 1)
THEN
2893 IF (log_unit > 0)
THEN
2894 WRITE (log_unit,
'(A)')
"# Transmission coefficient (G0 = 2 e^2/h) for the scattering region"
2896 WRITE (log_unit,
'(A,T10,A,T39,3A)')
"#",
"Energy (a.u.)",
"Transmission coefficient [alpha ", uks_str,
" beta]"
2897 WRITE (log_unit,
'("#", T3,78("-"))')
2900 ncontacts =
SIZE(negf_env%contacts)
2901 cpassert(contact_id1 <= ncontacts)
2902 cpassert(contact_id2 <= ncontacts)
2904 IF (nspins == 1)
THEN
2912 rscale = 0.5_dp*rscale
2914 npoints_bundle = 4*sub_env%ngroups
2915 IF (npoints_bundle > npoints) npoints_bundle = npoints
2917 ALLOCATE (transm_coeff(npoints_bundle, nspins), xnodes(npoints_bundle))
2919 npoints_remain = npoints
2920 DO WHILE (npoints_remain > 0)
2921 IF (npoints_bundle > npoints_remain) npoints_bundle = npoints_remain
2923 IF (npoints > 1)
THEN
2924 DO ipoint = 1, npoints_bundle
2925 xnodes(ipoint) = cmplx(energy_min + real(npoints - npoints_remain + ipoint - 1, kind=
dp)/ &
2926 REAL(npoints - 1, kind=
dp)*(energy_max - energy_min), negf_control%eta, kind=
dp)
2929 xnodes(ipoint) = cmplx(energy_min, negf_control%eta, kind=
dp)
2932 DO ispin = 1, nspins
2935 DO icontact = 1, ncontacts
2936 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
2937 omega=xnodes(1:npoints_bundle), &
2938 h0=negf_env%contacts(icontact)%h_00(ispin), &
2939 s0=negf_env%contacts(icontact)%s_00, &
2940 h1=negf_env%contacts(icontact)%h_01(ispin), &
2941 s1=negf_env%contacts(icontact)%s_01, &
2943 v_external=negf_control%contacts(icontact)%v_external, &
2944 conv=negf_control%conv_green, transp=.false.)
2947 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints_bundle), &
2949 ignore_bias=.false., &
2950 negf_env=negf_env, &
2951 negf_control=negf_control, &
2954 g_surf_contacts=g_surf_cache%g_surf_contacts, &
2955 transm_coeff=transm_coeff(1:npoints_bundle, ispin), &
2956 transm_contact1=contact_id1, &
2957 transm_contact2=contact_id2)
2962 IF (log_unit > 0)
THEN
2963 DO ipoint = 1, npoints_bundle
2964 IF (nspins > 1)
THEN
2966 WRITE (log_unit,
'(T2,F20.8,T30,2ES25.11E3)') &
2967 REAL(xnodes(ipoint), kind=
dp), rscale*real(transm_coeff(ipoint, 1:2), kind=
dp)
2970 WRITE (log_unit,
'(T2,F20.8,T43,ES25.11E3)') &
2971 REAL(xnodes(ipoint), kind=
dp), rscale*real(transm_coeff(ipoint, 1), kind=
dp)
2976 npoints_remain = npoints_remain - npoints_bundle
2979 DEALLOCATE (transm_coeff, xnodes)
2980 CALL timestop(handle)
2981 END SUBROUTINE negf_print_transmission
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_create(matrix, matrix_struct, name)
Creates a new full matrix with the given structure.
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_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_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_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
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, 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, ecoul_1c, rho0_s_rs, rho0_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)
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)
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.