134#include "./base/base_uses.f90"
139 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'negf_methods'
140 LOGICAL,
PARAMETER,
PRIVATE :: debug_this_module = .true.
149 TYPE integration_status_type
150 INTEGER :: npoints = -1
151 REAL(kind=
dp) :: error = -1.0_dp
152 END TYPE integration_status_type
166 CHARACTER(LEN=*),
PARAMETER :: routinen =
'do_negf'
168 CHARACTER(len=default_string_length) :: contact_id_str, filename
169 INTEGER :: energy_unit, handle, icontact, ispin, &
170 log_unit, ncontacts, npoints, nspins, &
171 print_level, print_unit
172 LOGICAL :: debug_output, exist, should_output, &
174 REAL(kind=
dp) :: energy_max, energy_min
175 REAL(kind=
dp),
DIMENSION(2) :: current
188 negf_mixing_section, negf_section, &
189 print_section, root_section
191 CALL timeset(routinen, handle)
198 NULLIFY (blacs_env, cp_subsys, global_env, qs_env, root_section, sub_force_env)
199 CALL force_env_get(force_env, globenv=global_env, qs_env=qs_env, root_section=root_section, &
200 sub_force_env=sub_force_env, subsys=cp_subsys)
202 CALL get_qs_env(qs_env, blacs_env=blacs_env, para_env=para_env_global)
208 NULLIFY (negf_control)
211 CALL get_qs_env(qs_env, dft_control=dft_control)
214 log_unit =
cp_print_key_unit_nr(logger, negf_section,
"PRINT%PROGRAM_RUN_INFO", extension=
".Log")
216 IF (log_unit > 0)
THEN
217 WRITE (log_unit,
'(/,T2,79("-"))')
218 WRITE (log_unit,
'(T27,A,T62)')
"NEGF calculation is started"
219 WRITE (log_unit,
'(T2,79("-"))')
224 debug_output = .false.
225 CALL section_vals_val_get(negf_section,
"PRINT%PROGRAM_RUN_INFO%PRINT_LEVEL", i_val=print_level)
226 SELECT CASE (print_level)
228 verbose_output = .true.
230 verbose_output = .true.
231 debug_output = .true.
233 verbose_output = .false.
236 IF (log_unit > 0)
THEN
237 WRITE (log_unit,
"(/,' THE RELEVANT HAMILTONIAN AND OVERLAP MATRICES FROM DFT')")
238 WRITE (log_unit,
"( ' ------------------------------------------------------')")
241 CALL negf_sub_env_create(sub_env, negf_control, blacs_env, global_env%blacs_grid_layout, global_env%blacs_repeatable)
242 CALL negf_env_create(negf_env, sub_env, negf_control, force_env, negf_mixing_section, log_unit)
244 filename = trim(logger%iter_info%project_name)//
'-negf.restart'
245 INQUIRE (file=filename, exist=exist)
246 IF (exist)
CALL negf_read_restart(filename, negf_env, negf_control)
248 IF (log_unit > 0)
THEN
249 WRITE (log_unit,
"(/,' NEGF| The initial Hamiltonian and Overlap matrices are calculated.')")
252 CALL negf_output_initial(log_unit, negf_env, sub_env, negf_control, dft_control, verbose_output, debug_output)
259 ncontacts =
SIZE(negf_control%contacts)
260 DO icontact = 1, ncontacts
262 IF (negf_control%contacts(icontact)%force_env_index > 0)
THEN
263 CALL force_env_get(sub_force_env(negf_control%contacts(icontact)%force_env_index)%force_env, qs_env=qs_env)
268 CALL guess_fermi_level(icontact, negf_env, negf_control, sub_env, qs_env, log_unit)
273 IF (should_output)
THEN
281 middle_name=trim(adjustl(contact_id_str)), &
282 file_status=
"REPLACE")
283 CALL negf_print_dos(print_unit, energy_min, energy_max, npoints, energy_unit, &
284 v_shift=0.0_dp, negf_env=negf_env, negf_control=negf_control, &
285 sub_env=sub_env, base_contact=icontact, just_contact=icontact)
293 IF (ncontacts > 1)
THEN
298 CALL shift_potential(negf_env, negf_control, sub_env, qs_env, base_contact=1, log_unit=log_unit)
302 CALL converge_density(negf_env, negf_control, sub_env, negf_section, qs_env, negf_control%v_shift, &
303 base_contact=1, log_unit=log_unit)
308 IF (para_env_global%is_source() .AND. negf_control%write_common_restart_file)
THEN
309 CALL negf_write_restart(filename, negf_env, negf_control)
314 CALL get_qs_env(qs_env, dft_control=dft_control)
316 nspins = dft_control%nspins
318 cpassert(nspins <= 2)
324 current(ispin) = negf_compute_current(contact_id1=1, contact_id2=2, &
325 v_shift=negf_control%v_shift, &
327 negf_control=negf_control, &
330 blacs_env_global=blacs_env)
333 IF (log_unit > 0)
THEN
335 WRITE (log_unit,
'(/,T2,A,T60,ES20.7E2)')
"NEGF| Alpha-spin electric current (A)", current(1)
336 WRITE (log_unit,
'(T2,A,T60,ES20.7E2)')
"NEGF| Beta-spin electric current (A)", current(2)
338 WRITE (log_unit,
'(/,T2,A,T60,ES20.7E2)')
"NEGF| Electric current (A)", 2.0_dp*current(1)
347 IF (should_output)
THEN
356 middle_name=trim(adjustl(contact_id_str)), &
357 file_status=
"REPLACE")
359 CALL negf_print_dos(print_unit, energy_min, energy_max, npoints, energy_unit, negf_control%v_shift, &
360 negf_env=negf_env, negf_control=negf_control, &
361 sub_env=sub_env, base_contact=1)
370 IF (should_output)
THEN
378 extension=
".trans", &
379 middle_name=trim(adjustl(contact_id_str)), &
380 file_status=
"REPLACE")
382 CALL negf_print_transmission(print_unit, energy_min, energy_max, npoints, energy_unit, &
383 negf_control%v_shift, negf_env=negf_env, negf_control=negf_control, &
384 sub_env=sub_env, contact_id1=1, contact_id2=2)
391 IF (log_unit > 0)
THEN
392 WRITE (log_unit,
'(/,T2,79("-"))')
393 WRITE (log_unit,
'(T27,A,T62)')
"NEGF calculation is finished"
394 WRITE (log_unit,
'(T2,79("-"))')
400 CALL timestop(handle)
415 SUBROUTINE guess_fermi_level(contact_id, negf_env, negf_control, sub_env, qs_env, log_unit)
416 INTEGER,
INTENT(in) :: contact_id
421 INTEGER,
INTENT(in) :: log_unit
423 CHARACTER(LEN=*),
PARAMETER :: routinen =
'guess_fermi_level'
426 CHARACTER(len=default_string_length) :: temperature_str
427 COMPLEX(kind=dp) :: lbound_cpath, lbound_lpath, ubound_lpath
428 INTEGER :: direction_axis_abs, handle, image, &
429 ispin, nao, nimages, nspins, step
430 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: index_to_cell
431 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index
432 LOGICAL :: do_kpoints
433 REAL(kind=
dp) :: delta_au, delta_ef, energy_ubound_minus_fermi, fermi_level_guess, &
434 fermi_level_max, fermi_level_min, nelectrons_guess, nelectrons_max, nelectrons_min, &
435 nelectrons_qs_cell0, nelectrons_qs_cell1, offset_au, rscale, t1, t2, trace
440 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_s_kp, rho_ao_qs_kp
443 TYPE(integration_status_type) :: stats
450 CALL timeset(routinen, handle)
452 IF (log_unit > 0)
THEN
453 WRITE (temperature_str,
'(F11.3)') negf_control%contacts(contact_id)%temperature*
kelvin
454 WRITE (log_unit,
'(/,T2,A,I3)')
"FERMI LEVEL OF CONTACT ", contact_id
455 WRITE (log_unit,
"( ' --------------------------')")
456 WRITE (log_unit,
'(A)')
" Temperature "//trim(adjustl(temperature_str))//
" Kelvin"
459 IF (.NOT. negf_control%contacts(contact_id)%is_restart)
THEN
462 blacs_env=blacs_env_global, &
463 dft_control=dft_control, &
464 do_kpoints=do_kpoints, &
466 matrix_s_kp=matrix_s_kp, &
467 para_env=para_env_global, &
468 rho=rho_struct, subsys=subsys)
469 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_qs_kp)
471 nimages = dft_control%nimages
472 nspins = dft_control%nspins
473 direction_axis_abs = abs(negf_env%contacts(contact_id)%direction_axis)
475 cpassert(
SIZE(negf_env%contacts(contact_id)%h_00) == nspins)
477 IF (sub_env%ngroups > 1)
THEN
478 NULLIFY (matrix_s_fm, fm_struct)
480 CALL cp_fm_get_info(negf_env%contacts(contact_id)%s_00, nrow_global=nao)
481 CALL cp_fm_struct_create(fm_struct, nrow_global=nao, ncol_global=nao, context=blacs_env_global)
484 ALLOCATE (matrix_s_fm)
488 IF (sub_env%group_distribution(sub_env%mepos_global) == 0)
THEN
489 CALL cp_fm_copy_general(negf_env%contacts(contact_id)%s_00, matrix_s_fm, para_env_global)
494 matrix_s_fm => negf_env%contacts(contact_id)%s_00
502 ALLOCATE (cell_to_index(0:0, 0:0, 0:0))
503 cell_to_index(0, 0, 0) = 1
506 ALLOCATE (index_to_cell(3, nimages))
508 IF (.NOT. do_kpoints)
DEALLOCATE (cell_to_index)
510 IF (nspins == 1)
THEN
518 nelectrons_qs_cell0 = 0.0_dp
519 nelectrons_qs_cell1 = 0.0_dp
520 IF (negf_control%contacts(contact_id)%force_env_index > 0)
THEN
521 DO image = 1, nimages
522 IF (index_to_cell(direction_axis_abs, image) == 0)
THEN
524 CALL dbcsr_dot(rho_ao_qs_kp(ispin, image)%matrix, matrix_s_kp(1, image)%matrix, trace)
525 nelectrons_qs_cell0 = nelectrons_qs_cell0 + trace
527 ELSE IF (abs(index_to_cell(direction_axis_abs, image)) == 1)
THEN
529 CALL dbcsr_dot(rho_ao_qs_kp(ispin, image)%matrix, matrix_s_kp(1, image)%matrix, trace)
530 nelectrons_qs_cell1 = nelectrons_qs_cell1 + trace
534 negf_env%contacts(contact_id)%nelectrons_qs_cell0 = nelectrons_qs_cell0
535 negf_env%contacts(contact_id)%nelectrons_qs_cell1 = nelectrons_qs_cell1
536 ELSE IF (negf_control%contacts(contact_id)%force_env_index <= 0)
THEN
538 CALL cp_fm_trace(negf_env%contacts(contact_id)%rho_00(ispin), &
539 negf_env%contacts(contact_id)%s_00, trace)
540 nelectrons_qs_cell0 = nelectrons_qs_cell0 + trace
541 CALL cp_fm_trace(negf_env%contacts(contact_id)%rho_01(ispin), &
542 negf_env%contacts(contact_id)%s_01, trace)
543 nelectrons_qs_cell1 = nelectrons_qs_cell1 + 2.0_dp*trace
545 negf_env%contacts(contact_id)%nelectrons_qs_cell0 = nelectrons_qs_cell0
546 negf_env%contacts(contact_id)%nelectrons_qs_cell1 = nelectrons_qs_cell1
549 DEALLOCATE (index_to_cell)
551 IF (sub_env%ngroups > 1)
THEN
553 DEALLOCATE (matrix_s_fm)
559 nelectrons_qs_cell0 = negf_env%contacts(contact_id)%nelectrons_qs_cell0
560 nelectrons_qs_cell1 = negf_env%contacts(contact_id)%nelectrons_qs_cell1
564 IF (negf_control%contacts(contact_id)%compute_fermi_level)
THEN
567 blacs_env=blacs_env_global, &
568 dft_control=dft_control, &
569 do_kpoints=do_kpoints, &
571 matrix_s_kp=matrix_s_kp, &
572 para_env=para_env_global, &
573 rho=rho_struct, subsys=subsys)
574 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_qs_kp)
576 nimages = dft_control%nimages
577 nspins = dft_control%nspins
578 direction_axis_abs = abs(negf_env%contacts(contact_id)%direction_axis)
579 IF (nspins == 1)
THEN
586 cpassert(
SIZE(negf_env%contacts(contact_id)%h_00) == nspins)
588 IF (sub_env%ngroups > 1)
THEN
589 NULLIFY (matrix_s_fm, fm_struct)
591 CALL cp_fm_get_info(negf_env%contacts(contact_id)%s_00, nrow_global=nao)
592 CALL cp_fm_struct_create(fm_struct, nrow_global=nao, ncol_global=nao, context=blacs_env_global)
595 ALLOCATE (matrix_s_fm)
599 IF (sub_env%group_distribution(sub_env%mepos_global) == 0)
THEN
600 CALL cp_fm_copy_general(negf_env%contacts(contact_id)%s_00, matrix_s_fm, para_env_global)
605 matrix_s_fm => negf_env%contacts(contact_id)%s_00
610 IF (log_unit > 0)
THEN
611 WRITE (log_unit,
'(A)')
" Computing the Fermi level of bulk electrode"
612 WRITE (log_unit,
'(T2,A,T60,F20.10,/)')
"Electronic density of the electrode unit cell:", &
613 -1.0_dp*(nelectrons_qs_cell0 + nelectrons_qs_cell1)
614 WRITE (log_unit,
'(T3,A)')
"Step Integration method Time Fermi level Convergence (density)"
615 WRITE (log_unit,
'(T3,78("-"))')
621 negf_env%contacts(contact_id)%fermi_energy = energy%efermi
622 IF (negf_control%homo_lumo_gap > 0.0_dp)
THEN
623 IF (negf_control%contacts(contact_id)%refine_fermi_level)
THEN
624 fermi_level_min = negf_control%contacts(contact_id)%fermi_level
626 fermi_level_min = energy%efermi
628 fermi_level_max = fermi_level_min + negf_control%homo_lumo_gap
630 IF (negf_control%contacts(contact_id)%refine_fermi_level)
THEN
631 fermi_level_max = negf_control%contacts(contact_id)%fermi_level
633 fermi_level_max = energy%efermi
635 fermi_level_min = fermi_level_max + negf_control%homo_lumo_gap
639 lbound_cpath = cmplx(negf_control%energy_lbound, negf_control%eta, kind=
dp)
640 delta_au = real(negf_control%delta_npoles, kind=
dp)*
twopi*negf_control%contacts(contact_id)%temperature
641 offset_au = real(negf_control%gamma_kT, kind=
dp)*negf_control%contacts(contact_id)%temperature
642 energy_ubound_minus_fermi = -2.0_dp*log(negf_control%conv_density)*negf_control%contacts(contact_id)%temperature
650 fermi_level_guess = fermi_level_min
652 fermi_level_guess = fermi_level_max
654 fermi_level_guess = fermi_level_min - (nelectrons_min - nelectrons_qs_cell0)* &
655 (fermi_level_max - fermi_level_min)/(nelectrons_max - nelectrons_min)
658 negf_control%contacts(contact_id)%fermi_level = fermi_level_guess
659 nelectrons_guess = 0.0_dp
661 lbound_lpath = cmplx(fermi_level_guess - offset_au, delta_au, kind=
dp)
662 ubound_lpath = cmplx(fermi_level_guess + energy_ubound_minus_fermi, delta_au, kind=
dp)
664 CALL integration_status_reset(stats)
667 CALL negf_init_rho_equiv_residuals(rho_ao_fm=rho_ao_fm, &
669 ignore_bias=.true., &
671 negf_control=negf_control, &
674 base_contact=contact_id, &
675 just_contact=contact_id)
677 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_fm, &
680 ignore_bias=.true., &
682 negf_control=negf_control, &
685 base_contact=contact_id, &
686 integr_lbound=lbound_cpath, &
687 integr_ubound=lbound_lpath, &
688 matrix_s_global=matrix_s_fm, &
689 is_circular=.true., &
690 g_surf_cache=g_surf_cache, &
691 just_contact=contact_id)
694 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_fm, &
697 ignore_bias=.true., &
699 negf_control=negf_control, &
702 base_contact=contact_id, &
703 integr_lbound=lbound_lpath, &
704 integr_ubound=ubound_lpath, &
705 matrix_s_global=matrix_s_fm, &
706 is_circular=.false., &
707 g_surf_cache=g_surf_cache, &
708 just_contact=contact_id)
712 nelectrons_guess = nelectrons_guess + trace
715 nelectrons_guess = nelectrons_guess*rscale
719 IF (log_unit > 0)
THEN
720 WRITE (log_unit,
'(T2,I5,T12,A,T32,F8.1,T42,F15.8,T60,ES20.5E2)') &
721 step, get_method_description_string(stats, negf_control%integr_method), &
722 t2 - t1, fermi_level_guess, nelectrons_guess - nelectrons_qs_cell0
725 IF (abs(nelectrons_qs_cell0 - nelectrons_guess) < negf_control%conv_density)
EXIT
729 nelectrons_min = nelectrons_guess
731 nelectrons_max = nelectrons_guess
733 IF (fermi_level_guess < fermi_level_min)
THEN
734 fermi_level_max = fermi_level_min
735 nelectrons_max = nelectrons_min
736 fermi_level_min = fermi_level_guess
737 nelectrons_min = nelectrons_guess
738 ELSE IF (fermi_level_guess > fermi_level_max)
THEN
739 fermi_level_min = fermi_level_max
740 nelectrons_min = nelectrons_max
741 fermi_level_max = fermi_level_guess
742 nelectrons_max = nelectrons_guess
743 ELSE IF (fermi_level_max - fermi_level_guess < fermi_level_guess - fermi_level_min)
THEN
744 fermi_level_max = fermi_level_guess
745 nelectrons_max = nelectrons_guess
747 fermi_level_min = fermi_level_guess
748 nelectrons_min = nelectrons_guess
755 negf_control%contacts(contact_id)%fermi_level = fermi_level_guess
757 IF (sub_env%ngroups > 1)
THEN
759 DEALLOCATE (matrix_s_fm)
765 IF (negf_control%contacts(contact_id)%shift_fermi_level)
THEN
766 delta_ef = negf_control%contacts(contact_id)%fermi_level_shifted - negf_control%contacts(contact_id)%fermi_level
767 IF (log_unit > 0)
WRITE (log_unit,
"(/,' The energies are shifted by (a.u.):',F18.8)") delta_ef
768 IF (log_unit > 0)
WRITE (log_unit,
"(' (eV):',F18.8)") delta_ef*
evolt
769 negf_control%contacts(contact_id)%fermi_level = negf_control%contacts(contact_id)%fermi_level_shifted
770 CALL get_qs_env(qs_env, dft_control=dft_control)
771 nspins = dft_control%nspins
772 CALL cp_fm_get_info(negf_env%contacts(contact_id)%s_00, nrow_global=nao)
780 IF (log_unit > 0)
THEN
781 WRITE (temperature_str,
'(F11.3)') negf_control%contacts(contact_id)%temperature*
kelvin
782 WRITE (log_unit,
'(/,T2,A,I0)')
"NEGF| Contact No. ", contact_id
783 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| Fermi level at "//trim(adjustl(temperature_str))// &
784 " Kelvin (a.u.):", negf_control%contacts(contact_id)%fermi_level
785 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| (eV):", &
786 negf_control%contacts(contact_id)%fermi_level*
evolt
787 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| Electric potential (a.u.):", &
788 negf_control%contacts(contact_id)%v_external
789 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| (Volt):", &
790 negf_control%contacts(contact_id)%v_external*
evolt
791 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| Electro-chemical potential Ef-|e|V (a.u.):", &
792 (negf_control%contacts(contact_id)%fermi_level - negf_control%contacts(contact_id)%v_external)
793 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| (eV):", &
794 (negf_control%contacts(contact_id)%fermi_level - negf_control%contacts(contact_id)%v_external)*
evolt
797 CALL timestop(handle)
798 END SUBROUTINE guess_fermi_level
811 SUBROUTINE shift_potential(negf_env, negf_control, sub_env, qs_env, base_contact, log_unit)
816 INTEGER,
INTENT(in) :: base_contact, log_unit
818 CHARACTER(LEN=*),
PARAMETER :: routinen =
'shift_potential'
821 COMPLEX(kind=dp) :: lbound_cpath, ubound_cpath, ubound_lpath
822 INTEGER :: handle, ispin, iter_count, nao, &
824 LOGICAL :: do_kpoints
825 REAL(kind=
dp) :: mu_base, nelectrons_guess, nelectrons_max, nelectrons_min, nelectrons_ref, &
826 t1, t2, temperature, trace, v_shift_guess, v_shift_max, v_shift_min
829 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: rho_ao_fm
831 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: rho_ao_qs_kp
834 DIMENSION(:) :: g_surf_circular, g_surf_linear
835 TYPE(integration_status_type) :: stats
840 ncontacts =
SIZE(negf_control%contacts)
842 IF (.NOT. (
ALLOCATED(negf_env%h_s) .AND.
ALLOCATED(negf_env%h_sc) .AND. &
843 ASSOCIATED(negf_env%s_s) .AND.
ALLOCATED(negf_env%s_sc)))
RETURN
844 IF (ncontacts < 2)
RETURN
845 IF (negf_control%v_shift_maxiters == 0)
RETURN
847 CALL timeset(routinen, handle)
849 CALL get_qs_env(qs_env, blacs_env=blacs_env, do_kpoints=do_kpoints, dft_control=dft_control, &
850 para_env=para_env, rho=rho_struct, subsys=subsys)
851 cpassert(.NOT. do_kpoints)
857 IF (sub_env%ngroups > 1)
THEN
858 NULLIFY (matrix_s_fm, fm_struct)
863 ALLOCATE (matrix_s_fm)
867 IF (sub_env%group_distribution(sub_env%mepos_global) == 0)
THEN
873 matrix_s_fm => negf_env%s_s
878 nspins =
SIZE(negf_env%h_s)
880 mu_base = negf_control%contacts(base_contact)%fermi_level
883 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_qs_kp)
886 nelectrons_ref = 0.0_dp
887 ALLOCATE (rho_ao_fm(nspins))
891 IF (.NOT. negf_control%is_restart)
THEN
894 fm=rho_ao_fm(ispin), &
895 atomlist_row=negf_control%atomlist_S_screening, &
896 atomlist_col=negf_control%atomlist_S_screening, &
897 subsys=subsys, mpi_comm_global=para_env, &
898 do_upper_diag=.true., do_lower=.true.)
900 CALL cp_fm_trace(rho_ao_fm(ispin), matrix_s_fm, trace)
901 nelectrons_ref = nelectrons_ref + trace
903 negf_env%nelectrons_ref = nelectrons_ref
905 nelectrons_ref = negf_env%nelectrons_ref
908 IF (log_unit > 0)
THEN
909 WRITE (log_unit,
'(/,T2,A)')
"COMPUTE SHIFT IN HARTREE POTENTIAL"
910 WRITE (log_unit,
"( ' ----------------------------------')")
911 WRITE (log_unit,
'(/,T2,A,T55,F25.14,/)')
"Initial electronic density of the scattering region:", -1.0_dp*nelectrons_ref
912 WRITE (log_unit,
'(T3,A)')
"Step Integration method Time V shift Convergence (density)"
913 WRITE (log_unit,
'(T3,78("-"))')
916 temperature = negf_control%contacts(base_contact)%temperature
919 lbound_cpath = cmplx(negf_control%energy_lbound, negf_control%eta, kind=
dp)
920 ubound_cpath = cmplx(mu_base - real(negf_control%gamma_kT, kind=
dp)*temperature, &
921 REAL(negf_control%delta_npoles, kind=
dp)*
twopi*temperature, kind=
dp)
924 ubound_lpath = cmplx(mu_base - log(negf_control%conv_density)*temperature, &
925 REAL(negf_control%delta_npoles, kind=
dp)*
twopi*temperature, kind=
dp)
927 v_shift_min = negf_control%v_shift
928 v_shift_max = negf_control%v_shift + negf_control%v_shift_offset
930 ALLOCATE (g_surf_circular(nspins), g_surf_linear(nspins))
932 DO iter_count = 1, negf_control%v_shift_maxiters
933 SELECT CASE (iter_count)
935 v_shift_guess = v_shift_min
937 v_shift_guess = v_shift_max
939 v_shift_guess = v_shift_min - (nelectrons_min - nelectrons_ref)* &
940 (v_shift_max - v_shift_min)/(nelectrons_max - nelectrons_min)
944 CALL integration_status_reset(stats)
948 CALL negf_init_rho_equiv_residuals(rho_ao_fm=rho_ao_fm(ispin), &
949 v_shift=v_shift_guess, &
950 ignore_bias=.true., &
952 negf_control=negf_control, &
955 base_contact=base_contact)
958 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_fm(ispin), &
960 v_shift=v_shift_guess, &
961 ignore_bias=.true., &
963 negf_control=negf_control, &
966 base_contact=base_contact, &
967 integr_lbound=lbound_cpath, &
968 integr_ubound=ubound_cpath, &
969 matrix_s_global=matrix_s_fm, &
970 is_circular=.true., &
971 g_surf_cache=g_surf_circular(ispin))
972 IF (negf_control%disable_cache)
THEN
977 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_fm(ispin), &
979 v_shift=v_shift_guess, &
980 ignore_bias=.true., &
982 negf_control=negf_control, &
985 base_contact=base_contact, &
986 integr_lbound=ubound_cpath, &
987 integr_ubound=ubound_lpath, &
988 matrix_s_global=matrix_s_fm, &
989 is_circular=.false., &
990 g_surf_cache=g_surf_linear(ispin))
991 IF (negf_control%disable_cache)
THEN
1004 CALL cp_fm_trace(rho_ao_fm(1), matrix_s_fm, nelectrons_guess)
1008 IF (log_unit > 0)
THEN
1009 WRITE (log_unit,
'(T2,I5,T12,A,T32,F8.1,T42,F15.8,T60,ES20.5E2)') &
1010 iter_count, get_method_description_string(stats, negf_control%integr_method), &
1011 t2 - t1, v_shift_guess, nelectrons_guess - nelectrons_ref
1014 IF (abs(nelectrons_guess - nelectrons_ref) < negf_control%conv_scf)
EXIT
1017 SELECT CASE (iter_count)
1019 nelectrons_min = nelectrons_guess
1021 nelectrons_max = nelectrons_guess
1023 IF (v_shift_guess < v_shift_min)
THEN
1024 v_shift_max = v_shift_min
1025 nelectrons_max = nelectrons_min
1026 v_shift_min = v_shift_guess
1027 nelectrons_min = nelectrons_guess
1028 ELSE IF (v_shift_guess > v_shift_max)
THEN
1029 v_shift_min = v_shift_max
1030 nelectrons_min = nelectrons_max
1031 v_shift_max = v_shift_guess
1032 nelectrons_max = nelectrons_guess
1033 ELSE IF (v_shift_max - v_shift_guess < v_shift_guess - v_shift_min)
THEN
1034 v_shift_max = v_shift_guess
1035 nelectrons_max = nelectrons_guess
1037 v_shift_min = v_shift_guess
1038 nelectrons_min = nelectrons_guess
1045 negf_control%v_shift = v_shift_guess
1047 IF (log_unit > 0)
THEN
1048 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| Shift in Hartree potential (a.u.):", negf_control%v_shift
1049 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| (eV):", negf_control%v_shift*
evolt
1052 DO ispin = nspins, 1, -1
1056 DEALLOCATE (g_surf_circular, g_surf_linear)
1060 IF (sub_env%ngroups > 1 .AND.
ASSOCIATED(matrix_s_fm))
THEN
1062 DEALLOCATE (matrix_s_fm)
1065 CALL timestop(handle)
1066 END SUBROUTINE shift_potential
1082 SUBROUTINE converge_density(negf_env, negf_control, sub_env, negf_section, qs_env, v_shift, base_contact, log_unit)
1088 REAL(kind=
dp),
INTENT(in) :: v_shift
1089 INTEGER,
INTENT(in) :: base_contact, log_unit
1091 CHARACTER(LEN=*),
PARAMETER :: routinen =
'converge_density'
1092 REAL(kind=
dp),
PARAMETER :: threshold = 16.0_dp*epsilon(0.0_dp)
1095 CHARACTER(len=100) :: sfmt
1096 CHARACTER(LEN=default_path_length) :: filebase, filename
1097 COMPLEX(kind=dp) :: lbound_cpath, ubound_cpath, ubound_lpath
1098 INTEGER :: handle, i, icontact, image, ispin, &
1099 iter_count, j, nao, ncol, ncontacts, &
1100 nimages, nrow, nspins, print_unit
1101 LOGICAL :: do_kpoints, exist
1102 REAL(kind=
dp) :: delta, iter_delta, mu_base, nelectrons, &
1103 nelectrons_diff, t1, t2, temperature, &
1105 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: target_m
1108 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: rho_ao_delta_fm, rho_ao_new_fm
1111 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks_initial_kp, matrix_ks_qs_kp, &
1112 rho_ao_initial_kp, rho_ao_new_kp, &
1116 DIMENSION(:) :: g_surf_circular, g_surf_linear, &
1118 TYPE(integration_status_type) :: stats
1125 ncontacts =
SIZE(negf_control%contacts)
1127 IF (ncontacts > 2)
THEN
1128 cpabort(
"Poisson solver does not support the general NEGF setup (>2 contacts).")
1131 IF (.NOT. (
ALLOCATED(negf_env%h_s) .AND.
ALLOCATED(negf_env%h_sc) .AND. &
1132 ASSOCIATED(negf_env%s_s) .AND.
ALLOCATED(negf_env%s_sc)))
RETURN
1133 IF (ncontacts < 2)
RETURN
1134 IF (negf_control%max_scf == 0)
RETURN
1136 CALL timeset(routinen, handle)
1138 IF (log_unit > 0)
THEN
1139 WRITE (log_unit,
'(/,T2,A)')
"NEGF SELF-CONSISTENT PROCEDURE"
1140 WRITE (log_unit,
"( ' ------------------------------')")
1142 WRITE (log_unit,
'(T3,A)')
"Mixing method: Direct mixing of new and old density matrices"
1145 WRITE (log_unit,
'(T3,A)')
"Mixing method: Broyden mixing"
1148 WRITE (log_unit,
'(T3,A)')
"Mixing method: Modified Broyden mixing"
1151 WRITE (log_unit,
'(T3,A)')
"Mixing method: Pulay mixing"
1154 WRITE (log_unit,
'(T3,A)')
"Mixing method: Multisecant scheme for mixing"
1158 IF (negf_control%update_HS .AND. (.NOT. negf_control%is_dft_entire))
THEN
1159 CALL qs_energies(qs_env, consistent_energies=.false., calc_forces=.false.)
1162 CALL get_qs_env(qs_env, blacs_env=blacs_env, do_kpoints=do_kpoints, dft_control=dft_control, &
1163 matrix_ks_kp=matrix_ks_qs_kp, para_env=para_env, rho=rho_struct, subsys=subsys)
1164 cpassert(.NOT. do_kpoints)
1171 IF (sub_env%ngroups > 1)
THEN
1172 NULLIFY (matrix_s_fm, fm_struct)
1176 ALLOCATE (matrix_s_fm)
1180 IF (sub_env%group_distribution(sub_env%mepos_global) == 0)
THEN
1186 matrix_s_fm => negf_env%s_s
1191 nspins =
SIZE(negf_env%h_s)
1192 nimages = dft_control%nimages
1194 v_base = negf_control%contacts(base_contact)%v_external
1195 mu_base = negf_control%contacts(base_contact)%fermi_level - v_base
1198 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_qs_kp)
1200 ALLOCATE (target_m(nao, nao))
1201 ALLOCATE (rho_ao_delta_fm(nspins), rho_ao_new_fm(nspins))
1202 DO ispin = 1, nspins
1207 IF (negf_control%restart_scf)
THEN
1208 IF (para_env%is_source())
THEN
1211 CALL para_env%bcast(filebase)
1212 IF (nspins == 1)
THEN
1213 filename = trim(filebase)//
'.hs'
1214 INQUIRE (file=filename, exist=exist)
1215 IF (.NOT. exist)
THEN
1216 CALL cp_warn(__location__, &
1217 "User requested to read the KS matrix from the file named: "// &
1218 trim(filename)//
". This file does not exist. The initial KS matrix will be used.")
1221 CALL para_env%bcast(target_m)
1223 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
" H_s is read from "//trim(filename)
1225 filename = trim(filebase)//
'.rho'
1226 INQUIRE (file=filename, exist=exist)
1227 IF (.NOT. exist)
THEN
1228 CALL cp_warn(__location__, &
1229 "User requested to read the density matrix from the file named: "// &
1230 trim(filename)//
". This file does not exist. The initial density matrix will be used.")
1233 CALL para_env%bcast(target_m)
1235 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
" rho_s is read from "//trim(filename)
1237 matrix=rho_ao_qs_kp(1, 1)%matrix, &
1238 atomlist_row=negf_control%atomlist_S_screening, &
1239 atomlist_col=negf_control%atomlist_S_screening, &
1243 IF (nspins == 2)
THEN
1244 filename = trim(filebase)//
'-S1.hs'
1245 INQUIRE (file=filename, exist=exist)
1246 IF (.NOT. exist)
THEN
1247 CALL cp_warn(__location__, &
1248 "User requested to read the KS matrix from the file named: "// &
1249 trim(filename)//
". This file does not exist. The initial KS matrix will be used.")
1252 CALL para_env%bcast(target_m)
1254 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
" H_s is read from "//trim(filename)
1256 filename = trim(filebase)//
'-S2.hs'
1257 INQUIRE (file=filename, exist=exist)
1258 IF (.NOT. exist)
THEN
1259 CALL cp_warn(__location__, &
1260 "User requested to read the KS matrix from the file named: "// &
1261 trim(filename)//
". This file does not exist. The initial KS matrix will be used.")
1264 CALL para_env%bcast(target_m)
1266 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
" H_s is read from "//trim(filename)
1268 filename = trim(filebase)//
'-S1.rho'
1269 INQUIRE (file=filename, exist=exist)
1270 IF (.NOT. exist)
THEN
1271 CALL cp_warn(__location__, &
1272 "User requested to read the density matrix from the file named: "// &
1273 trim(filename)//
". This file does not exist. The initial density matrix will be used.")
1276 CALL para_env%bcast(target_m)
1278 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
" rho_s is read from "//trim(filename)
1280 matrix=rho_ao_qs_kp(1, 1)%matrix, &
1281 atomlist_row=negf_control%atomlist_S_screening, &
1282 atomlist_col=negf_control%atomlist_S_screening, &
1285 filename = trim(filebase)//
'-S2.rho'
1286 INQUIRE (file=filename, exist=exist)
1287 IF (.NOT. exist)
THEN
1288 CALL cp_warn(__location__, &
1289 "User requested to read the density matrix from the file named: "// &
1290 trim(filename)//
". This file does not exist. The initial density matrix will be used.")
1293 CALL para_env%bcast(target_m)
1295 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
" rho_s is read from "//trim(filename)
1297 matrix=rho_ao_qs_kp(2, 1)%matrix, &
1298 atomlist_row=negf_control%atomlist_S_screening, &
1299 atomlist_col=negf_control%atomlist_S_screening, &
1306 NULLIFY (matrix_ks_initial_kp, rho_ao_initial_kp, rho_ao_new_kp)
1311 DO image = 1, nimages
1312 DO ispin = 1, nspins
1313 CALL dbcsr_init_p(matrix_ks_initial_kp(ispin, image)%matrix)
1314 CALL dbcsr_copy(matrix_b=matrix_ks_initial_kp(ispin, image)%matrix, matrix_a=matrix_ks_qs_kp(ispin, image)%matrix)
1316 CALL dbcsr_init_p(rho_ao_initial_kp(ispin, image)%matrix)
1317 CALL dbcsr_copy(matrix_b=rho_ao_initial_kp(ispin, image)%matrix, matrix_a=rho_ao_qs_kp(ispin, image)%matrix)
1320 CALL dbcsr_copy(matrix_b=rho_ao_new_kp(ispin, image)%matrix, matrix_a=rho_ao_qs_kp(ispin, image)%matrix)
1326 DO ispin = 1, nspins
1328 fm=rho_ao_delta_fm(ispin), &
1329 atomlist_row=negf_control%atomlist_S_screening, &
1330 atomlist_col=negf_control%atomlist_S_screening, &
1331 subsys=subsys, mpi_comm_global=para_env, &
1332 do_upper_diag=.true., do_lower=.true.)
1334 CALL cp_fm_trace(rho_ao_delta_fm(ispin), matrix_s_fm, trace)
1335 nelectrons = nelectrons + trace
1337 negf_env%nelectrons = nelectrons
1341 CALL mixing_allocate(qs_env, negf_env%mixing_method, nspins=nspins, mixing_store=negf_env%mixing_storage)
1342 IF (dft_control%qs_control%dftb)
THEN
1343 cpabort(
'DFTB Code not available')
1344 ELSE IF (dft_control%qs_control%xtb)
THEN
1346 ELSE IF (dft_control%qs_control%semi_empirical)
THEN
1347 cpabort(
'SE Code not possible')
1349 CALL mixing_init(negf_env%mixing_method, rho_struct, negf_env%mixing_storage, para_env)
1353 IF (log_unit > 0)
THEN
1354 WRITE (log_unit,
'(/,T2,A,T55,F25.14,/)')
" Initial electronic density of the scattering region:", -1.0_dp*nelectrons
1355 WRITE (log_unit,
'(T3,A)')
"Step Integration method Time Electronic density Convergence"
1356 WRITE (log_unit,
'(T3,78("-"))')
1359 temperature = negf_control%contacts(base_contact)%temperature
1362 lbound_cpath = cmplx(negf_control%energy_lbound, negf_control%eta, kind=
dp)
1363 ubound_cpath = cmplx(mu_base - real(negf_control%gamma_kT, kind=
dp)*temperature, &
1364 REAL(negf_control%delta_npoles, kind=
dp)*
twopi*temperature, kind=
dp)
1367 ubound_lpath = cmplx(mu_base - log(negf_control%conv_density)*temperature, &
1368 REAL(negf_control%delta_npoles, kind=
dp)*
twopi*temperature, kind=
dp)
1370 ALLOCATE (g_surf_circular(nspins), g_surf_linear(nspins), g_surf_nonequiv(nspins))
1374 DO iter_count = 1, negf_control%max_scf
1376 CALL integration_status_reset(stats)
1377 CALL cp_iterate(logger%iter_info, last=.false., iter_nr=iter_count)
1379 DO ispin = 1, nspins
1381 CALL negf_init_rho_equiv_residuals(rho_ao_fm=rho_ao_new_fm(ispin), &
1383 ignore_bias=.false., &
1384 negf_env=negf_env, &
1385 negf_control=negf_control, &
1388 base_contact=base_contact)
1391 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_new_fm(ispin), &
1394 ignore_bias=.false., &
1395 negf_env=negf_env, &
1396 negf_control=negf_control, &
1399 base_contact=base_contact, &
1400 integr_lbound=lbound_cpath, &
1401 integr_ubound=ubound_cpath, &
1402 matrix_s_global=matrix_s_fm, &
1403 is_circular=.true., &
1404 g_surf_cache=g_surf_circular(ispin))
1405 IF (negf_control%disable_cache)
THEN
1410 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_new_fm(ispin), &
1413 ignore_bias=.false., &
1414 negf_env=negf_env, &
1415 negf_control=negf_control, &
1418 base_contact=base_contact, &
1419 integr_lbound=ubound_cpath, &
1420 integr_ubound=ubound_lpath, &
1421 matrix_s_global=matrix_s_fm, &
1422 is_circular=.false., &
1423 g_surf_cache=g_surf_linear(ispin))
1424 IF (negf_control%disable_cache)
THEN
1430 DO icontact = 1, ncontacts
1431 IF (icontact /= base_contact)
THEN
1432 delta = delta + abs(negf_control%contacts(icontact)%v_external - &
1433 negf_control%contacts(base_contact)%v_external) + &
1434 abs(negf_control%contacts(icontact)%fermi_level - &
1435 negf_control%contacts(base_contact)%fermi_level) + &
1436 abs(negf_control%contacts(icontact)%temperature - &
1437 negf_control%contacts(base_contact)%temperature)
1440 IF (delta >= threshold)
THEN
1441 CALL negf_add_rho_nonequiv(rho_ao_fm=rho_ao_new_fm(ispin), &
1444 negf_env=negf_env, &
1445 negf_control=negf_control, &
1448 base_contact=base_contact, &
1449 matrix_s_global=matrix_s_fm, &
1450 g_surf_cache=g_surf_nonequiv(ispin))
1451 IF (negf_control%disable_cache)
THEN
1457 IF (nspins == 1)
CALL cp_fm_scale(2.0_dp, rho_ao_new_fm(1))
1460 nelectrons_diff = 0.0_dp
1461 DO ispin = 1, nspins
1462 CALL cp_fm_trace(rho_ao_new_fm(ispin), matrix_s_fm, trace)
1463 nelectrons = nelectrons + trace
1467 CALL cp_fm_trace(rho_ao_delta_fm(ispin), matrix_s_fm, trace)
1468 nelectrons_diff = nelectrons_diff + trace
1471 CALL cp_fm_to_fm(rho_ao_new_fm(ispin), rho_ao_delta_fm(ispin))
1476 IF (log_unit > 0)
THEN
1477 WRITE (log_unit,
'(T2,I5,T12,A,T32,F8.1,T43,F20.8,T65,ES15.5E2)') &
1478 iter_count, get_method_description_string(stats, negf_control%integr_method), &
1479 t2 - t1, -1.0_dp*nelectrons, nelectrons_diff
1482 IF (abs(nelectrons_diff) < negf_control%conv_scf)
EXIT
1488 DO image = 1, nimages
1489 DO ispin = 1, nspins
1490 CALL dbcsr_copy(matrix_b=rho_ao_new_kp(ispin, image)%matrix, &
1491 matrix_a=rho_ao_initial_kp(ispin, image)%matrix)
1495 DO ispin = 1, nspins
1497 matrix=rho_ao_new_kp(ispin, 1)%matrix, &
1498 atomlist_row=negf_control%atomlist_S_screening, &
1499 atomlist_col=negf_control%atomlist_S_screening, &
1504 para_env, iter_delta, iter_count)
1506 DO image = 1, nimages
1507 DO ispin = 1, nspins
1508 CALL dbcsr_copy(rho_ao_qs_kp(ispin, image)%matrix, rho_ao_new_kp(ispin, image)%matrix)
1514 DO image = 1, nimages
1515 DO ispin = 1, nspins
1516 CALL dbcsr_copy(matrix_b=rho_ao_qs_kp(ispin, image)%matrix, &
1517 matrix_a=rho_ao_initial_kp(ispin, image)%matrix)
1521 DO ispin = 1, nspins
1523 matrix=rho_ao_qs_kp(ispin, 1)%matrix, &
1524 atomlist_row=negf_control%atomlist_S_screening, &
1525 atomlist_col=negf_control%atomlist_S_screening, &
1533 CALL gspace_mixing(qs_env, negf_env%mixing_method, negf_env%mixing_storage, &
1534 rho_struct, para_env, iter_count)
1538 IF (negf_control%update_HS)
THEN
1541 DO ispin = 1, nspins
1543 fm=negf_env%h_s(ispin), &
1544 atomlist_row=negf_control%atomlist_S_screening, &
1545 atomlist_col=negf_control%atomlist_S_screening, &
1546 subsys=subsys, mpi_comm_global=para_env, &
1547 do_upper_diag=.true., do_lower=.true.)
1552 IF (nspins == 1)
THEN
1555 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1557 extension=
".hs", file_status=
"REPLACE", file_action=
"WRITE", &
1558 do_backup=.true., file_form=
"FORMATTED")
1559 nrow =
SIZE(target_m, 1)
1560 ncol =
SIZE(target_m, 2)
1561 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1562 WRITE (print_unit, *) nrow, ncol
1564 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1569 IF (nspins == 2)
THEN
1572 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1574 extension=
"-S1.hs", file_status=
"REPLACE", file_action=
"WRITE", &
1575 do_backup=.true., file_form=
"FORMATTED")
1576 nrow =
SIZE(target_m, 1)
1577 ncol =
SIZE(target_m, 2)
1578 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1579 WRITE (print_unit, *) nrow, ncol
1581 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1587 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1589 extension=
"-S2.hs", file_status=
"REPLACE", file_action=
"WRITE", &
1590 do_backup=.true., file_form=
"FORMATTED")
1591 nrow =
SIZE(target_m, 1)
1592 ncol =
SIZE(target_m, 2)
1593 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1594 WRITE (print_unit, *) nrow, ncol
1596 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1603 IF (nspins == 1)
THEN
1606 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1608 extension=
".rho", file_status=
"REPLACE", file_action=
"WRITE", &
1609 do_backup=.true., file_form=
"FORMATTED")
1610 nrow =
SIZE(target_m, 1)
1611 ncol =
SIZE(target_m, 2)
1612 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1613 WRITE (print_unit, *) nrow, ncol
1615 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1620 IF (nspins == 2)
THEN
1623 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1625 extension=
"-S1.rho", file_status=
"REPLACE", file_action=
"WRITE", &
1626 do_backup=.true., file_form=
"FORMATTED")
1627 nrow =
SIZE(target_m, 1)
1628 ncol =
SIZE(target_m, 2)
1629 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1630 WRITE (print_unit, *) nrow, ncol
1632 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1638 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1640 extension=
"-S2.rho", file_status=
"REPLACE", file_action=
"WRITE", &
1641 do_backup=.true., file_form=
"FORMATTED")
1642 nrow =
SIZE(target_m, 1)
1643 ncol =
SIZE(target_m, 2)
1644 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1645 WRITE (print_unit, *) nrow, ncol
1647 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1656 CALL cp_iterate(logger%iter_info, last=.true., iter_nr=iter_count)
1657 IF (nspins == 1)
THEN
1660 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1662 extension=
".hs", file_status=
"REPLACE", file_action=
"WRITE", &
1663 do_backup=.true., file_form=
"FORMATTED")
1664 nrow =
SIZE(target_m, 1)
1665 ncol =
SIZE(target_m, 2)
1666 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1667 WRITE (print_unit, *) nrow, ncol
1669 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1674 IF (nspins == 2)
THEN
1677 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1679 extension=
"-S1.hs", file_status=
"REPLACE", file_action=
"WRITE", &
1680 do_backup=.true., file_form=
"FORMATTED")
1681 nrow =
SIZE(target_m, 1)
1682 ncol =
SIZE(target_m, 2)
1683 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1684 WRITE (print_unit, *) nrow, ncol
1686 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1692 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1694 extension=
"-S2.hs", file_status=
"REPLACE", file_action=
"WRITE", &
1695 do_backup=.true., file_form=
"FORMATTED")
1696 nrow =
SIZE(target_m, 1)
1697 ncol =
SIZE(target_m, 2)
1698 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1699 WRITE (print_unit, *) nrow, ncol
1701 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1708 IF (nspins == 1)
THEN
1711 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1713 extension=
".rho", file_status=
"REPLACE", file_action=
"WRITE", &
1714 do_backup=.true., file_form=
"FORMATTED")
1715 nrow =
SIZE(target_m, 1)
1716 ncol =
SIZE(target_m, 2)
1717 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1718 WRITE (print_unit, *) nrow, ncol
1720 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1725 IF (nspins == 2)
THEN
1728 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1730 extension=
"-S1.rho", file_status=
"REPLACE", file_action=
"WRITE", &
1731 do_backup=.true., file_form=
"FORMATTED")
1732 nrow =
SIZE(target_m, 1)
1733 ncol =
SIZE(target_m, 2)
1734 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1735 WRITE (print_unit, *) nrow, ncol
1737 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1743 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1745 extension=
"-S2.rho", file_status=
"REPLACE", file_action=
"WRITE", &
1746 do_backup=.true., file_form=
"FORMATTED")
1747 nrow =
SIZE(target_m, 1)
1748 ncol =
SIZE(target_m, 2)
1749 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1750 WRITE (print_unit, *) nrow, ncol
1752 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1758 DEALLOCATE (target_m)
1763 IF (log_unit > 0)
THEN
1764 IF (iter_count <= negf_control%max_scf)
THEN
1765 WRITE (log_unit,
'(/,T11,1X,A,I0,A)')
"*** NEGF run converged in ", iter_count,
" iteration(s) ***"
1767 WRITE (log_unit,
'(/,T11,1X,A,I0,A)')
"*** NEGF run did NOT converge after ", iter_count - 1,
" iteration(s) ***"
1771 DO ispin = nspins, 1, -1
1776 DEALLOCATE (g_surf_circular, g_surf_linear, g_surf_nonequiv)
1781 DO image = 1, nimages
1782 DO ispin = 1, nspins
1783 CALL dbcsr_copy(matrix_b=matrix_ks_qs_kp(ispin, image)%matrix, matrix_a=matrix_ks_initial_kp(ispin, image)%matrix)
1784 CALL dbcsr_copy(matrix_b=rho_ao_qs_kp(ispin, image)%matrix, matrix_a=rho_ao_initial_kp(ispin, image)%matrix)
1791 DEALLOCATE (matrix_ks_initial_kp, rho_ao_new_kp, rho_ao_initial_kp)
1793 IF (sub_env%ngroups > 1 .AND.
ASSOCIATED(matrix_s_fm))
THEN
1795 DEALLOCATE (matrix_s_fm)
1798 CALL timestop(handle)
1799 END SUBROUTINE converge_density
1816 SUBROUTINE negf_surface_green_function_batch(g_surf, omega, h0, s0, h1, s1, sub_env, v_external, conv, transp)
1817 TYPE(
cp_cfm_type),
DIMENSION(:),
INTENT(inout) :: g_surf
1818 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(in) :: omega
1819 TYPE(
cp_fm_type),
INTENT(IN) :: h0, s0, h1, s1
1821 REAL(kind=
dp),
INTENT(in) :: v_external, conv
1822 LOGICAL,
INTENT(in) :: transp
1824 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_surface_green_function_batch'
1827 INTEGER :: handle, igroup, ipoint, npoints
1831 CALL timeset(routinen, handle)
1832 npoints =
SIZE(omega)
1837 igroup = sub_env%group_distribution(sub_env%mepos_global)
1839 g_surf(1:npoints) = cfm_null
1841 DO ipoint = igroup + 1, npoints, sub_env%ngroups
1842 IF (debug_this_module)
THEN
1843 cpassert(.NOT.
ASSOCIATED(g_surf(ipoint)%matrix_struct))
1847 CALL do_sancho(g_surf(ipoint), omega(ipoint) + v_external, &
1848 h0, s0, h1, s1, conv, transp, work)
1852 CALL timestop(handle)
1853 END SUBROUTINE negf_surface_green_function_batch
1885 SUBROUTINE negf_retarded_green_function_batch(omega, v_shift, ignore_bias, negf_env, negf_control, sub_env, ispin, &
1887 g_ret_s, g_ret_scale, gamma_contacts, gret_gamma_gadv, dos, &
1888 transm_coeff, transm_contact1, transm_contact2, just_contact)
1889 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(IN) :: omega
1890 REAL(kind=
dp),
INTENT(IN) :: v_shift
1891 LOGICAL,
INTENT(in) :: ignore_bias
1895 INTEGER,
INTENT(in) :: ispin
1896 TYPE(
cp_cfm_type),
DIMENSION(:, :),
INTENT(IN) :: g_surf_contacts
1899 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(in), &
1900 OPTIONAL :: g_ret_scale
1902 OPTIONAL :: gamma_contacts, gret_gamma_gadv
1903 REAL(kind=
dp),
DIMENSION(:),
INTENT(out),
OPTIONAL :: dos
1904 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(out), &
1905 OPTIONAL :: transm_coeff
1906 INTEGER,
INTENT(in),
OPTIONAL :: transm_contact1, transm_contact2, &
1909 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_retarded_green_function_batch'
1911 INTEGER :: handle, icontact, igroup, ipoint, &
1912 ncontacts, npoints, nrows
1913 REAL(kind=
dp) :: v_external
1915 DIMENSION(:) :: info1
1917 DIMENSION(:, :) :: info2
1918 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: g_ret_s_group, self_energy_contacts, &
1919 zwork1_contacts, zwork2_contacts
1920 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:, :) :: gamma_contacts_group, &
1921 gret_gamma_gadv_group
1927 CALL timeset(routinen, handle)
1928 npoints =
SIZE(omega)
1929 ncontacts =
SIZE(negf_env%contacts)
1930 cpassert(
SIZE(negf_control%contacts) == ncontacts)
1932 IF (
PRESENT(just_contact))
THEN
1933 cpassert(just_contact <= ncontacts)
1937 cpassert(ncontacts >= 2)
1939 IF (ignore_bias) v_external = 0.0_dp
1941 IF (
PRESENT(transm_coeff) .OR.
PRESENT(transm_contact1) .OR.
PRESENT(transm_contact2))
THEN
1942 cpassert(
PRESENT(transm_coeff))
1943 cpassert(
PRESENT(transm_contact1))
1944 cpassert(
PRESENT(transm_contact2))
1945 cpassert(.NOT.
PRESENT(just_contact))
1948 ALLOCATE (self_energy_contacts(ncontacts), zwork1_contacts(ncontacts), zwork2_contacts(ncontacts))
1950 IF (
PRESENT(just_contact))
THEN
1951 CALL cp_fm_get_info(negf_env%contacts(just_contact)%s_01, matrix_struct=fm_struct)
1952 DO icontact = 1, ncontacts
1957 CALL cp_fm_get_info(negf_env%contacts(just_contact)%s_00, nrow_global=nrows, matrix_struct=fm_struct)
1958 DO icontact = 1, ncontacts
1959 CALL cp_cfm_create(self_energy_contacts(icontact), fm_struct)
1962 DO icontact = 1, ncontacts
1963 CALL cp_fm_get_info(negf_env%s_sc(icontact), matrix_struct=fm_struct)
1968 CALL cp_fm_get_info(negf_env%s_s, nrow_global=nrows, matrix_struct=fm_struct)
1969 DO icontact = 1, ncontacts
1970 CALL cp_cfm_create(self_energy_contacts(icontact), fm_struct)
1974 IF (
PRESENT(g_ret_s) .OR.
PRESENT(gret_gamma_gadv) .OR. &
1975 PRESENT(dos) .OR.
PRESENT(transm_coeff))
THEN
1976 ALLOCATE (g_ret_s_group(npoints))
1978 IF (sub_env%ngroups <= 1 .AND.
PRESENT(g_ret_s))
THEN
1979 g_ret_s_group(1:npoints) = g_ret_s(1:npoints)
1983 IF (
PRESENT(gamma_contacts) .OR.
PRESENT(gret_gamma_gadv) .OR.
PRESENT(transm_coeff))
THEN
1984 IF (debug_this_module .AND.
PRESENT(gamma_contacts))
THEN
1985 cpassert(
SIZE(gamma_contacts, 1) == ncontacts)
1988 ALLOCATE (gamma_contacts_group(ncontacts, npoints))
1989 IF (sub_env%ngroups <= 1 .AND.
PRESENT(gamma_contacts))
THEN
1990 gamma_contacts_group(1:ncontacts, 1:npoints) = gamma_contacts(1:ncontacts, 1:npoints)
1994 IF (
PRESENT(gret_gamma_gadv))
THEN
1995 IF (debug_this_module .AND.
PRESENT(gret_gamma_gadv))
THEN
1996 cpassert(
SIZE(gret_gamma_gadv, 1) == ncontacts)
1999 ALLOCATE (gret_gamma_gadv_group(ncontacts, npoints))
2000 IF (sub_env%ngroups <= 1)
THEN
2001 gret_gamma_gadv_group(1:ncontacts, 1:npoints) = gret_gamma_gadv(1:ncontacts, 1:npoints)
2005 igroup = sub_env%group_distribution(sub_env%mepos_global)
2007 DO ipoint = 1, npoints
2008 IF (
ASSOCIATED(g_surf_contacts(1, ipoint)%matrix_struct))
THEN
2009 IF (sub_env%ngroups > 1 .OR. .NOT.
PRESENT(g_ret_s))
THEN
2013 IF (
ALLOCATED(g_ret_s_group))
THEN
2018 IF (sub_env%ngroups > 1 .OR. .NOT.
PRESENT(gamma_contacts))
THEN
2019 IF (
ALLOCATED(gamma_contacts_group))
THEN
2020 DO icontact = 1, ncontacts
2021 CALL cp_cfm_create(gamma_contacts_group(icontact, ipoint), fm_struct)
2026 IF (sub_env%ngroups > 1)
THEN
2027 IF (
ALLOCATED(gret_gamma_gadv_group))
THEN
2028 DO icontact = 1, ncontacts
2029 IF (
ASSOCIATED(gret_gamma_gadv(icontact, ipoint)%matrix_struct))
THEN
2030 CALL cp_cfm_create(gret_gamma_gadv_group(icontact, ipoint), fm_struct)
2036 IF (
PRESENT(just_contact))
THEN
2038 DO icontact = 1, ncontacts
2040 omega=omega(ipoint), &
2041 g_surf_c=g_surf_contacts(icontact, ipoint), &
2042 h_sc0=negf_env%contacts(just_contact)%h_01(ispin), &
2043 s_sc0=negf_env%contacts(just_contact)%s_01, &
2044 zwork1=zwork1_contacts(icontact), &
2045 zwork2=zwork2_contacts(icontact), &
2046 transp=(icontact == 1))
2050 DO icontact = 1, ncontacts
2051 IF (.NOT. ignore_bias) v_external = negf_control%contacts(icontact)%v_external
2054 omega=omega(ipoint) + v_external, &
2055 g_surf_c=g_surf_contacts(icontact, ipoint), &
2056 h_sc0=negf_env%h_sc(ispin, icontact), &
2057 s_sc0=negf_env%s_sc(icontact), &
2058 zwork1=zwork1_contacts(icontact), &
2059 zwork2=zwork2_contacts(icontact), &
2065 IF (
ALLOCATED(gamma_contacts_group))
THEN
2066 DO icontact = 1, ncontacts
2068 self_energy_c=self_energy_contacts(icontact))
2072 IF (
ALLOCATED(g_ret_s_group))
THEN
2074 DO icontact = 2, ncontacts
2079 IF (
PRESENT(just_contact))
THEN
2081 omega=omega(ipoint) - v_shift, &
2082 self_energy_ret_sum=self_energy_contacts(1), &
2083 h_s=negf_env%contacts(just_contact)%h_00(ispin), &
2084 s_s=negf_env%contacts(just_contact)%s_00)
2085 ELSE IF (ignore_bias)
THEN
2087 omega=omega(ipoint) - v_shift, &
2088 self_energy_ret_sum=self_energy_contacts(1), &
2089 h_s=negf_env%h_s(ispin), &
2093 omega=omega(ipoint) - v_shift, &
2094 self_energy_ret_sum=self_energy_contacts(1), &
2095 h_s=negf_env%h_s(ispin), &
2097 v_hartree_s=negf_env%v_hartree_s)
2100 IF (
PRESENT(g_ret_scale))
THEN
2101 IF (g_ret_scale(ipoint) /=
z_one)
CALL cp_cfm_scale(g_ret_scale(ipoint), g_ret_s_group(ipoint))
2105 IF (
ALLOCATED(gret_gamma_gadv_group))
THEN
2108 DO icontact = 1, ncontacts
2109 IF (
ASSOCIATED(gret_gamma_gadv_group(icontact, ipoint)%matrix_struct))
THEN
2111 z_one, gamma_contacts_group(icontact, ipoint), &
2112 g_ret_s_group(ipoint), &
2113 z_zero, self_energy_contacts(icontact))
2115 z_one, g_ret_s_group(ipoint), &
2116 self_energy_contacts(icontact), &
2117 z_zero, gret_gamma_gadv_group(icontact, ipoint))
2125 IF (
PRESENT(g_ret_s))
THEN
2126 IF (sub_env%ngroups > 1)
THEN
2128 DO ipoint = 1, npoints
2129 IF (
ASSOCIATED(g_ret_s(ipoint)%matrix_struct))
THEN
2135 IF (
ASSOCIATED(para_env))
THEN
2136 ALLOCATE (info1(npoints))
2138 DO ipoint = 1, npoints
2141 para_env, info1(ipoint))
2144 DO ipoint = 1, npoints
2145 IF (
ASSOCIATED(g_ret_s(ipoint)%matrix_struct))
THEN
2147 IF (
ASSOCIATED(g_ret_s_group(ipoint)%matrix_struct))
THEN
2158 IF (
PRESENT(gamma_contacts))
THEN
2159 IF (sub_env%ngroups > 1)
THEN
2161 pnt1:
DO ipoint = 1, npoints
2162 DO icontact = 1, ncontacts
2163 IF (
ASSOCIATED(gamma_contacts(icontact, ipoint)%matrix_struct))
THEN
2164 CALL cp_cfm_get_info(gamma_contacts(icontact, ipoint), para_env=para_env)
2170 IF (
ASSOCIATED(para_env))
THEN
2171 ALLOCATE (info2(ncontacts, npoints))
2173 DO ipoint = 1, npoints
2174 DO icontact = 1, ncontacts
2176 gamma_contacts(icontact, ipoint), &
2177 para_env, info2(icontact, ipoint))
2181 DO ipoint = 1, npoints
2182 DO icontact = 1, ncontacts
2183 IF (
ASSOCIATED(gamma_contacts(icontact, ipoint)%matrix_struct))
THEN
2185 IF (
ASSOCIATED(gamma_contacts_group(icontact, ipoint)%matrix_struct))
THEN
2197 IF (
PRESENT(gret_gamma_gadv))
THEN
2198 IF (sub_env%ngroups > 1)
THEN
2200 pnt2:
DO ipoint = 1, npoints
2201 DO icontact = 1, ncontacts
2202 IF (
ASSOCIATED(gret_gamma_gadv(icontact, ipoint)%matrix_struct))
THEN
2203 CALL cp_cfm_get_info(gret_gamma_gadv(icontact, ipoint), para_env=para_env)
2209 IF (
ASSOCIATED(para_env))
THEN
2210 ALLOCATE (info2(ncontacts, npoints))
2212 DO ipoint = 1, npoints
2213 DO icontact = 1, ncontacts
2215 gret_gamma_gadv(icontact, ipoint), &
2216 para_env, info2(icontact, ipoint))
2220 DO ipoint = 1, npoints
2221 DO icontact = 1, ncontacts
2222 IF (
ASSOCIATED(gret_gamma_gadv(icontact, ipoint)%matrix_struct))
THEN
2224 IF (
ASSOCIATED(gret_gamma_gadv_group(icontact, ipoint)%matrix_struct))
THEN
2236 IF (
PRESENT(dos))
THEN
2239 IF (
PRESENT(just_contact))
THEN
2240 matrix_s => negf_env%contacts(just_contact)%s_00
2242 matrix_s => negf_env%s_s
2248 DO ipoint = 1, npoints
2249 IF (
ASSOCIATED(g_ret_s_group(ipoint)%matrix_struct))
THEN
2250 CALL cp_cfm_to_fm(g_ret_s_group(ipoint), mtargeti=g_ret_imag)
2251 CALL cp_fm_trace(g_ret_imag, matrix_s, dos(ipoint))
2252 IF (sub_env%para_env%mepos /= 0) dos(ipoint) = 0.0_dp
2258 CALL sub_env%mpi_comm_global%sum(dos)
2259 dos(:) = -1.0_dp/
pi*dos(:)
2262 IF (
PRESENT(transm_coeff))
THEN
2265 DO ipoint = 1, npoints
2266 IF (
ASSOCIATED(g_ret_s_group(ipoint)%matrix_struct))
THEN
2269 z_one, gamma_contacts_group(transm_contact1, ipoint), &
2270 g_ret_s_group(ipoint), &
2271 z_zero, self_energy_contacts(transm_contact1))
2273 z_one, self_energy_contacts(transm_contact1), &
2274 gamma_contacts_group(transm_contact2, ipoint), &
2275 z_zero, self_energy_contacts(transm_contact2))
2279 self_energy_contacts(transm_contact2), &
2280 transm_coeff(ipoint))
2281 IF (sub_env%para_env%mepos /= 0) transm_coeff(ipoint) = 0.0_dp
2286 CALL sub_env%mpi_comm_global%sum(transm_coeff)
2291 IF (
ALLOCATED(g_ret_s_group))
THEN
2292 DO ipoint = npoints, 1, -1
2293 IF (sub_env%ngroups > 1 .OR. .NOT.
PRESENT(g_ret_s))
THEN
2297 DEALLOCATE (g_ret_s_group)
2300 IF (
ALLOCATED(gamma_contacts_group))
THEN
2301 DO ipoint = npoints, 1, -1
2302 DO icontact = ncontacts, 1, -1
2303 IF (sub_env%ngroups > 1 .OR. .NOT.
PRESENT(gamma_contacts))
THEN
2308 DEALLOCATE (gamma_contacts_group)
2311 IF (
ALLOCATED(gret_gamma_gadv_group))
THEN
2312 DO ipoint = npoints, 1, -1
2313 DO icontact = ncontacts, 1, -1
2314 IF (sub_env%ngroups > 1)
THEN
2319 DEALLOCATE (gret_gamma_gadv_group)
2322 IF (
ALLOCATED(self_energy_contacts))
THEN
2323 DO icontact = ncontacts, 1, -1
2326 DEALLOCATE (self_energy_contacts)
2329 IF (
ALLOCATED(zwork1_contacts))
THEN
2330 DO icontact = ncontacts, 1, -1
2333 DEALLOCATE (zwork1_contacts)
2336 IF (
ALLOCATED(zwork2_contacts))
THEN
2337 DO icontact = ncontacts, 1, -1
2340 DEALLOCATE (zwork2_contacts)
2343 CALL timestop(handle)
2344 END SUBROUTINE negf_retarded_green_function_batch
2354 PURE FUNCTION fermi_function(omega, temperature)
RESULT(val)
2355 COMPLEX(kind=dp),
INTENT(in) :: omega
2356 REAL(kind=
dp),
INTENT(in) :: temperature
2357 COMPLEX(kind=dp) :: val
2359 REAL(kind=
dp),
PARAMETER :: max_ln_omega_over_t = log(huge(0.0_dp))/16.0_dp
2361 IF (real(omega, kind=
dp) <= temperature*max_ln_omega_over_t)
THEN
2367 END FUNCTION fermi_function
2382 SUBROUTINE negf_init_rho_equiv_residuals(rho_ao_fm, v_shift, ignore_bias, negf_env, &
2383 negf_control, sub_env, ispin, base_contact, just_contact)
2385 REAL(kind=
dp),
INTENT(in) :: v_shift
2386 LOGICAL,
INTENT(in) :: ignore_bias
2390 INTEGER,
INTENT(in) :: ispin, base_contact
2391 INTEGER,
INTENT(in),
OPTIONAL :: just_contact
2393 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_init_rho_equiv_residuals'
2395 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: omega
2396 INTEGER :: handle, icontact, ipole, ncontacts, &
2398 REAL(kind=
dp) :: mu_base, pi_temperature, temperature, &
2400 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: g_ret_s
2405 CALL timeset(routinen, handle)
2407 temperature = negf_control%contacts(base_contact)%temperature
2408 IF (ignore_bias)
THEN
2409 mu_base = negf_control%contacts(base_contact)%fermi_level
2412 mu_base = negf_control%contacts(base_contact)%fermi_level - negf_control%contacts(base_contact)%v_external
2415 pi_temperature =
pi*temperature
2416 npoles = negf_control%delta_npoles
2418 ncontacts =
SIZE(negf_env%contacts)
2419 cpassert(base_contact <= ncontacts)
2420 IF (
PRESENT(just_contact))
THEN
2422 cpassert(just_contact == base_contact)
2425 IF (npoles > 0)
THEN
2426 CALL cp_fm_get_info(rho_ao_fm, para_env=para_env, matrix_struct=fm_struct)
2428 ALLOCATE (omega(npoles), g_ret_s(npoles))
2430 DO ipole = 1, npoles
2433 omega(ipole) = cmplx(mu_base, real(2*ipole - 1, kind=
dp)*pi_temperature, kind=
dp)
2438 IF (
PRESENT(just_contact))
THEN
2443 DO icontact = 1, ncontacts
2444 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
2446 h0=negf_env%contacts(just_contact)%h_00(ispin), &
2447 s0=negf_env%contacts(just_contact)%s_00, &
2448 h1=negf_env%contacts(just_contact)%h_01(ispin), &
2449 s1=negf_env%contacts(just_contact)%s_01, &
2450 sub_env=sub_env, v_external=0.0_dp, &
2451 conv=negf_control%conv_green, transp=(icontact == 1))
2454 DO icontact = 1, ncontacts
2455 IF (.NOT. ignore_bias) v_external = negf_control%contacts(icontact)%v_external
2457 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
2459 h0=negf_env%contacts(icontact)%h_00(ispin), &
2460 s0=negf_env%contacts(icontact)%s_00, &
2461 h1=negf_env%contacts(icontact)%h_01(ispin), &
2462 s1=negf_env%contacts(icontact)%s_01, &
2464 v_external=v_external, &
2465 conv=negf_control%conv_green, transp=.false.)
2469 CALL negf_retarded_green_function_batch(omega=omega(:), &
2471 ignore_bias=ignore_bias, &
2472 negf_env=negf_env, &
2473 negf_control=negf_control, &
2476 g_surf_contacts=g_surf_cache%g_surf_contacts, &
2478 just_contact=just_contact)
2482 DO ipole = 2, npoles
2490 DO ipole = npoles, 1, -1
2493 DEALLOCATE (g_ret_s, omega)
2496 CALL timestop(handle)
2497 END SUBROUTINE negf_init_rho_equiv_residuals
2518 SUBROUTINE negf_add_rho_equiv_low(rho_ao_fm, stats, v_shift, ignore_bias, negf_env, negf_control, sub_env, &
2519 ispin, base_contact, integr_lbound, integr_ubound, matrix_s_global, &
2520 is_circular, g_surf_cache, just_contact)
2522 TYPE(integration_status_type),
INTENT(inout) :: stats
2523 REAL(kind=
dp),
INTENT(in) :: v_shift
2524 LOGICAL,
INTENT(in) :: ignore_bias
2528 INTEGER,
INTENT(in) :: ispin, base_contact
2529 COMPLEX(kind=dp),
INTENT(in) :: integr_lbound, integr_ubound
2530 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_s_global
2531 LOGICAL,
INTENT(in) :: is_circular
2533 INTEGER,
INTENT(in),
OPTIONAL :: just_contact
2535 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_add_rho_equiv_low'
2537 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: xnodes, zscale
2538 INTEGER :: handle, icontact, interval_id, ipoint, max_points, min_points, ncontacts, &
2539 npoints, npoints_exist, npoints_tmp, npoints_total, shape_id
2540 LOGICAL :: do_surface_green
2541 REAL(kind=
dp) :: conv_integr, mu_base, temperature, &
2544 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: zdata, zdata_tmp
2550 CALL timeset(routinen, handle)
2554 conv_integr = 0.5_dp*negf_control%conv_density*
pi
2556 IF (ignore_bias)
THEN
2557 mu_base = negf_control%contacts(base_contact)%fermi_level
2560 mu_base = negf_control%contacts(base_contact)%fermi_level - negf_control%contacts(base_contact)%v_external
2563 min_points = negf_control%integr_min_points
2564 max_points = negf_control%integr_max_points
2565 temperature = negf_control%contacts(base_contact)%temperature
2567 ncontacts =
SIZE(negf_env%contacts)
2568 cpassert(base_contact <= ncontacts)
2569 IF (
PRESENT(just_contact))
THEN
2571 cpassert(just_contact == base_contact)
2574 do_surface_green = .NOT.
ALLOCATED(g_surf_cache%tnodes)
2576 IF (do_surface_green)
THEN
2577 npoints = min_points
2579 npoints =
SIZE(g_surf_cache%tnodes)
2583 CALL cp_fm_get_info(rho_ao_fm, para_env=para_env, matrix_struct=fm_struct)
2586 SELECT CASE (negf_control%integr_method)
2589 ALLOCATE (xnodes(npoints))
2591 IF (is_circular)
THEN
2599 IF (do_surface_green)
THEN
2600 CALL ccquad_init(cc_env, xnodes, npoints, integr_lbound, integr_ubound, &
2601 interval_id, shape_id, matrix_s_global)
2603 CALL ccquad_init(cc_env, xnodes, npoints, integr_lbound, integr_ubound, &
2604 interval_id, shape_id, matrix_s_global, tnodes_restart=g_surf_cache%tnodes)
2607 ALLOCATE (zdata(npoints))
2608 DO ipoint = 1, npoints
2613 IF (do_surface_green)
THEN
2616 IF (
PRESENT(just_contact))
THEN
2618 DO icontact = 1, ncontacts
2619 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, npoints_total + 1:), &
2620 omega=xnodes(1:npoints), &
2621 h0=negf_env%contacts(just_contact)%h_00(ispin), &
2622 s0=negf_env%contacts(just_contact)%s_00, &
2623 h1=negf_env%contacts(just_contact)%h_01(ispin), &
2624 s1=negf_env%contacts(just_contact)%s_01, &
2625 sub_env=sub_env, v_external=0.0_dp, &
2626 conv=negf_control%conv_green, transp=(icontact == 1))
2629 DO icontact = 1, ncontacts
2630 IF (.NOT. ignore_bias) v_external = negf_control%contacts(icontact)%v_external
2632 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, npoints_total + 1:), &
2633 omega=xnodes(1:npoints), &
2634 h0=negf_env%contacts(icontact)%h_00(ispin), &
2635 s0=negf_env%contacts(icontact)%s_00, &
2636 h1=negf_env%contacts(icontact)%h_01(ispin), &
2637 s1=negf_env%contacts(icontact)%s_01, &
2639 v_external=v_external, &
2640 conv=negf_control%conv_green, transp=.false.)
2645 ALLOCATE (zscale(npoints))
2647 IF (temperature >= 0.0_dp)
THEN
2648 DO ipoint = 1, npoints
2649 zscale(ipoint) = fermi_function(xnodes(ipoint) - mu_base, temperature)
2655 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints), &
2657 ignore_bias=ignore_bias, &
2658 negf_env=negf_env, &
2659 negf_control=negf_control, &
2662 g_surf_contacts=g_surf_cache%g_surf_contacts(:, npoints_total + 1:), &
2663 g_ret_s=zdata(1:npoints), &
2664 g_ret_scale=zscale(1:npoints), &
2665 just_contact=just_contact)
2667 DEALLOCATE (xnodes, zscale)
2668 npoints_total = npoints_total + npoints
2671 CALL move_alloc(zdata, zdata_tmp)
2675 IF (cc_env%error <= conv_integr)
EXIT
2676 IF (2*(npoints_total - 1) + 1 > max_points)
EXIT
2680 do_surface_green = .true.
2682 npoints_tmp = npoints
2684 npoints =
SIZE(xnodes)
2686 ALLOCATE (zdata(npoints))
2689 DO ipoint = 1, npoints_tmp
2690 IF (
ASSOCIATED(zdata_tmp(ipoint)%matrix_struct))
THEN
2691 npoints_exist = npoints_exist + 1
2692 zdata(npoints_exist) = zdata_tmp(ipoint)
2695 DEALLOCATE (zdata_tmp)
2697 DO ipoint = npoints_exist + 1, npoints
2703 stats%error = stats%error + cc_env%error/
pi
2705 DO ipoint =
SIZE(zdata_tmp), 1, -1
2708 DEALLOCATE (zdata_tmp)
2710 CALL cp_cfm_to_fm(cc_env%integral, mtargeti=integral_imag)
2713 IF (do_surface_green)
THEN
2720 ALLOCATE (xnodes(npoints), zdata(npoints), zscale(npoints))
2722 IF (is_circular)
THEN
2728 IF (do_surface_green)
THEN
2729 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2730 shape_id, conv_integr, matrix_s_global)
2732 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2733 shape_id, conv_integr, matrix_s_global, tnodes_restart=g_surf_cache%tnodes)
2736 DO WHILE (npoints > 0 .AND. npoints_total < max_points)
2737 DO ipoint = 1, npoints
2741 IF (do_surface_green)
THEN
2744 IF (
PRESENT(just_contact))
THEN
2746 DO icontact = 1, ncontacts
2747 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, npoints_total + 1:), &
2748 omega=xnodes(1:npoints), &
2749 h0=negf_env%contacts(just_contact)%h_00(ispin), &
2750 s0=negf_env%contacts(just_contact)%s_00, &
2751 h1=negf_env%contacts(just_contact)%h_01(ispin), &
2752 s1=negf_env%contacts(just_contact)%s_01, &
2753 sub_env=sub_env, v_external=0.0_dp, &
2754 conv=negf_control%conv_green, transp=(icontact == 1))
2757 DO icontact = 1, ncontacts
2758 IF (.NOT. ignore_bias) v_external = negf_control%contacts(icontact)%v_external
2760 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, npoints_total + 1:), &
2761 omega=xnodes(1:npoints), &
2762 h0=negf_env%contacts(icontact)%h_00(ispin), &
2763 s0=negf_env%contacts(icontact)%s_00, &
2764 h1=negf_env%contacts(icontact)%h_01(ispin), &
2765 s1=negf_env%contacts(icontact)%s_01, &
2767 v_external=v_external, &
2768 conv=negf_control%conv_green, transp=.false.)
2773 IF (temperature >= 0.0_dp)
THEN
2774 DO ipoint = 1, npoints
2775 zscale(ipoint) = fermi_function(xnodes(ipoint) - mu_base, temperature)
2781 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints), &
2783 ignore_bias=ignore_bias, &
2784 negf_env=negf_env, &
2785 negf_control=negf_control, &
2788 g_surf_contacts=g_surf_cache%g_surf_contacts(:, npoints_total + 1:), &
2789 g_ret_s=zdata(1:npoints), &
2790 g_ret_scale=zscale(1:npoints), &
2791 just_contact=just_contact)
2793 npoints_total = npoints_total + npoints
2797 IF (sr_env%error <= conv_integr)
EXIT
2802 do_surface_green = .true.
2804 npoints = max_points - npoints_total
2805 IF (npoints <= 0)
EXIT
2806 IF (npoints >
SIZE(xnodes)) npoints =
SIZE(xnodes)
2812 stats%error = stats%error + sr_env%error/
pi
2814 CALL cp_cfm_to_fm(sr_env%integral, mtargeti=integral_imag)
2817 IF (do_surface_green)
THEN
2822 DEALLOCATE (xnodes, zdata, zscale)
2825 cpabort(
"Unimplemented integration method")
2828 stats%npoints = stats%npoints + npoints_total
2833 CALL timestop(handle)
2834 END SUBROUTINE negf_add_rho_equiv_low
2850 SUBROUTINE negf_add_rho_nonequiv(rho_ao_fm, stats, v_shift, negf_env, negf_control, sub_env, &
2851 ispin, base_contact, matrix_s_global, g_surf_cache)
2853 TYPE(integration_status_type),
INTENT(inout) :: stats
2854 REAL(kind=
dp),
INTENT(in) :: v_shift
2858 INTEGER,
INTENT(in) :: ispin, base_contact
2859 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_s_global
2862 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_add_rho_nonequiv'
2864 COMPLEX(kind=dp) :: fermi_base, fermi_contact, &
2865 integr_lbound, integr_ubound
2866 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: xnodes
2867 INTEGER :: handle, icontact, ipoint, jcontact, &
2868 max_points, min_points, ncontacts, &
2869 npoints, npoints_total
2870 LOGICAL :: do_surface_green
2871 REAL(kind=
dp) :: conv_density, conv_integr, eta, &
2872 ln_conv_density, mu_base, mu_contact, &
2873 temperature_base, temperature_contact
2874 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:, :) :: zdata
2880 CALL timeset(routinen, handle)
2882 ncontacts =
SIZE(negf_env%contacts)
2883 cpassert(base_contact <= ncontacts)
2886 IF (ncontacts > 2)
THEN
2887 cpabort(
"Poisson solver does not support the general NEGF setup (>2 contacts).")
2890 mu_base = negf_control%contacts(base_contact)%fermi_level - negf_control%contacts(base_contact)%v_external
2891 min_points = negf_control%integr_min_points
2892 max_points = negf_control%integr_max_points
2893 temperature_base = negf_control%contacts(base_contact)%temperature
2894 eta = negf_control%eta
2895 conv_density = negf_control%conv_density
2896 ln_conv_density = log(conv_density)
2900 conv_integr = 0.5_dp*conv_density*
pi
2902 DO icontact = 1, ncontacts
2903 IF (icontact /= base_contact)
THEN
2904 mu_contact = negf_control%contacts(icontact)%fermi_level - negf_control%contacts(icontact)%v_external
2905 temperature_contact = negf_control%contacts(icontact)%temperature
2907 integr_lbound = cmplx(min(mu_base + ln_conv_density*temperature_base, &
2908 mu_contact + ln_conv_density*temperature_contact), eta, kind=
dp)
2909 integr_ubound = cmplx(max(mu_base - ln_conv_density*temperature_base, &
2910 mu_contact - ln_conv_density*temperature_contact), eta, kind=
dp)
2912 do_surface_green = .NOT.
ALLOCATED(g_surf_cache%tnodes)
2914 IF (do_surface_green)
THEN
2915 npoints = min_points
2917 npoints =
SIZE(g_surf_cache%tnodes)
2921 ALLOCATE (xnodes(npoints))
2922 CALL cp_fm_get_info(rho_ao_fm, para_env=para_env, matrix_struct=fm_struct)
2924 IF (do_surface_green)
THEN
2925 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2928 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2929 sr_shape_linear, conv_integr, matrix_s_global, tnodes_restart=g_surf_cache%tnodes)
2932 DO WHILE (npoints > 0 .AND. npoints_total < max_points)
2934 IF (do_surface_green)
THEN
2937 DO jcontact = 1, ncontacts
2938 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(jcontact, npoints_total + 1:), &
2939 omega=xnodes(1:npoints), &
2940 h0=negf_env%contacts(jcontact)%h_00(ispin), &
2941 s0=negf_env%contacts(jcontact)%s_00, &
2942 h1=negf_env%contacts(jcontact)%h_01(ispin), &
2943 s1=negf_env%contacts(jcontact)%s_01, &
2945 v_external=negf_control%contacts(jcontact)%v_external, &
2946 conv=negf_control%conv_green, transp=.false.)
2950 ALLOCATE (zdata(ncontacts, npoints))
2952 DO ipoint = 1, npoints
2957 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints), &
2959 ignore_bias=.false., &
2960 negf_env=negf_env, &
2961 negf_control=negf_control, &
2964 g_surf_contacts=g_surf_cache%g_surf_contacts(:, npoints_total + 1:), &
2965 gret_gamma_gadv=zdata(:, 1:npoints))
2967 DO ipoint = 1, npoints
2968 fermi_base = fermi_function(cmplx(real(xnodes(ipoint), kind=
dp) - mu_base, 0.0_dp, kind=
dp), &
2970 fermi_contact = fermi_function(cmplx(real(xnodes(ipoint), kind=
dp) - mu_contact, 0.0_dp, kind=
dp), &
2971 temperature_contact)
2972 CALL cp_cfm_scale(fermi_contact - fermi_base, zdata(icontact, ipoint))
2975 npoints_total = npoints_total + npoints
2979 DO ipoint = 1, npoints
2985 IF (sr_env%error <= conv_integr)
EXIT
2988 do_surface_green = .true.
2990 npoints = max_points - npoints_total
2991 IF (npoints <= 0)
EXIT
2992 IF (npoints >
SIZE(xnodes)) npoints =
SIZE(xnodes)
3000 CALL cp_cfm_to_fm(sr_env%integral, mtargetr=integral_real)
3007 stats%error = stats%error + sr_env%error*0.5_dp/
pi
3008 stats%npoints = stats%npoints + npoints_total
3011 IF (do_surface_green)
THEN
3019 CALL timestop(handle)
3020 END SUBROUTINE negf_add_rho_nonequiv
3027 ELEMENTAL SUBROUTINE integration_status_reset(stats)
3028 TYPE(integration_status_type),
INTENT(out) :: stats
3031 stats%error = 0.0_dp
3032 END SUBROUTINE integration_status_reset
3041 ELEMENTAL FUNCTION get_method_description_string(stats, integration_method)
RESULT(method_descr)
3042 TYPE(integration_status_type),
INTENT(in) :: stats
3043 INTEGER,
INTENT(in) :: integration_method
3044 CHARACTER(len=18) :: method_descr
3046 CHARACTER(len=2) :: method_abbr
3047 CHARACTER(len=6) :: npoints_str
3049 SELECT CASE (integration_method)
3060 WRITE (npoints_str,
'(I6)') stats%npoints
3061 WRITE (method_descr,
'(A2,T4,A,T11,ES8.2E2)') method_abbr, trim(adjustl(npoints_str)), stats%error
3062 END FUNCTION get_method_description_string
3077 FUNCTION negf_compute_current(contact_id1, contact_id2, v_shift, negf_env, negf_control, sub_env, ispin, &
3078 blacs_env_global)
RESULT(current)
3079 INTEGER,
INTENT(in) :: contact_id1, contact_id2
3080 REAL(kind=
dp),
INTENT(in) :: v_shift
3084 INTEGER,
INTENT(in) :: ispin
3086 REAL(kind=
dp) :: current
3088 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_compute_current'
3089 REAL(kind=
dp),
PARAMETER :: threshold = 16.0_dp*epsilon(0.0_dp)
3091 COMPLEX(kind=dp) :: fermi_contact1, fermi_contact2, &
3092 integr_lbound, integr_ubound
3093 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: transm_coeff, xnodes
3094 COMPLEX(kind=dp),
DIMENSION(1, 1) :: transmission
3095 INTEGER :: handle, icontact, ipoint, max_points, &
3096 min_points, ncontacts, npoints, &
3098 REAL(kind=
dp) :: conv_density, energy, eta, ln_conv_density, mu_contact1, mu_contact2, &
3099 temperature_contact1, temperature_contact2, v_contact1, v_contact2
3100 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: zdata
3108 IF (.NOT.
ASSOCIATED(negf_env%s_s))
RETURN
3110 CALL timeset(routinen, handle)
3112 ncontacts =
SIZE(negf_env%contacts)
3113 cpassert(contact_id1 <= ncontacts)
3114 cpassert(contact_id2 <= ncontacts)
3115 cpassert(contact_id1 /= contact_id2)
3117 v_contact1 = negf_control%contacts(contact_id1)%v_external
3118 mu_contact1 = negf_control%contacts(contact_id1)%fermi_level - v_contact1
3119 v_contact2 = negf_control%contacts(contact_id2)%v_external
3120 mu_contact2 = negf_control%contacts(contact_id2)%fermi_level - v_contact2
3122 IF (abs(mu_contact1 - mu_contact2) < threshold)
THEN
3123 CALL timestop(handle)
3127 min_points = negf_control%integr_min_points
3128 max_points = negf_control%integr_max_points
3129 temperature_contact1 = negf_control%contacts(contact_id1)%temperature
3130 temperature_contact2 = negf_control%contacts(contact_id2)%temperature
3131 eta = negf_control%eta
3132 conv_density = negf_control%conv_density
3133 ln_conv_density = log(conv_density)
3135 integr_lbound = cmplx(min(mu_contact1 + ln_conv_density*temperature_contact1, &
3136 mu_contact2 + ln_conv_density*temperature_contact2), eta, kind=
dp)
3137 integr_ubound = cmplx(max(mu_contact1 - ln_conv_density*temperature_contact1, &
3138 mu_contact2 - ln_conv_density*temperature_contact2), eta, kind=
dp)
3141 npoints = min_points
3143 NULLIFY (fm_struct_single)
3144 CALL cp_fm_struct_create(fm_struct_single, nrow_global=1, ncol_global=1, context=blacs_env_global)
3148 ALLOCATE (transm_coeff(npoints), xnodes(npoints), zdata(npoints))
3150 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
3153 DO WHILE (npoints > 0 .AND. npoints_total < max_points)
3156 DO icontact = 1, ncontacts
3157 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, 1:npoints), &
3158 omega=xnodes(1:npoints), &
3159 h0=negf_env%contacts(icontact)%h_00(ispin), &
3160 s0=negf_env%contacts(icontact)%s_00, &
3161 h1=negf_env%contacts(icontact)%h_01(ispin), &
3162 s1=negf_env%contacts(icontact)%s_01, &
3164 v_external=negf_control%contacts(icontact)%v_external, &
3165 conv=negf_control%conv_green, transp=.false.)
3168 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints), &
3170 ignore_bias=.false., &
3171 negf_env=negf_env, &
3172 negf_control=negf_control, &
3175 g_surf_contacts=g_surf_cache%g_surf_contacts(:, 1:npoints), &
3176 transm_coeff=transm_coeff(1:npoints), &
3177 transm_contact1=contact_id1, &
3178 transm_contact2=contact_id2)
3180 DO ipoint = 1, npoints
3183 energy = real(xnodes(ipoint), kind=
dp)
3184 fermi_contact1 = fermi_function(cmplx(energy - mu_contact1, 0.0_dp, kind=
dp), temperature_contact1)
3185 fermi_contact2 = fermi_function(cmplx(energy - mu_contact2, 0.0_dp, kind=
dp), temperature_contact2)
3187 transmission(1, 1) = transm_coeff(ipoint)*(fermi_contact1 - fermi_contact2)
3193 npoints_total = npoints_total + npoints
3197 IF (sr_env%error <= negf_control%conv_density)
EXIT
3199 npoints = max_points - npoints_total
3200 IF (npoints <= 0)
EXIT
3201 IF (npoints >
SIZE(xnodes)) npoints =
SIZE(xnodes)
3214 DEALLOCATE (transm_coeff, xnodes, zdata)
3216 CALL timestop(handle)
3217 END FUNCTION negf_compute_current
3237 SUBROUTINE negf_print_dos(log_unit, energy_min, energy_max, npoints, energy_unit, v_shift, &
3238 negf_env, negf_control, sub_env, base_contact, just_contact, volume)
3239 INTEGER,
INTENT(in) :: log_unit
3240 REAL(kind=
dp),
INTENT(in) :: energy_min, energy_max
3241 INTEGER,
INTENT(in) :: npoints, energy_unit
3242 REAL(kind=
dp),
INTENT(in) :: v_shift
3246 INTEGER,
INTENT(in) :: base_contact
3247 INTEGER,
INTENT(in),
OPTIONAL :: just_contact
3248 REAL(kind=
dp),
INTENT(in),
OPTIONAL :: volume
3250 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_print_dos'
3252 CHARACTER(len=15) :: units_str
3253 CHARACTER(LEN=4) :: string
3254 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: xnodes
3255 INTEGER :: handle, icontact, ipoint, ispin, &
3256 ncontacts, npoints_bundle, &
3257 npoints_remain, nspins
3258 REAL(kind=
dp) :: dos_scale, en_scale
3259 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: dos
3262 CALL timeset(routinen, handle)
3264 IF (
PRESENT(just_contact))
THEN
3265 nspins =
SIZE(negf_env%contacts(just_contact)%h_00)
3267 nspins =
SIZE(negf_env%h_s)
3270 IF (energy_unit == 2)
THEN
3280 IF (log_unit > 0)
THEN
3281 IF (
PRESENT(volume))
THEN
3282 units_str =
' (angstroms^-3)'
3287 IF (
PRESENT(just_contact))
THEN
3288 WRITE (log_unit,
'(3A,T70,I11)')
"# Density of states", trim(units_str),
" for the contact No. ", just_contact
3290 WRITE (log_unit,
'(3A)')
"# Density of states", trim(units_str),
" for the scattering region"
3292 IF (nspins > 1)
THEN
3293 WRITE (log_unit,
'(A,T10,A,T43,3A)')
"#",
"Energy ("//string//
")",
"Density of states [total, alpha, beta]"
3295 WRITE (log_unit,
'(A,T10,A,T43,3A)')
"#",
"Energy ("//string//
")",
"Density of states [total = alpha+beta]"
3297 WRITE (log_unit,
'("#", T3,98("-"))')
3300 ncontacts =
SIZE(negf_env%contacts)
3301 cpassert(base_contact <= ncontacts)
3302 IF (
PRESENT(just_contact))
THEN
3304 cpassert(just_contact == base_contact)
3306 mark_used(base_contact)
3308 npoints_bundle = 4*sub_env%ngroups
3309 IF (npoints_bundle > npoints) npoints_bundle = npoints
3311 ALLOCATE (dos(npoints_bundle, nspins), xnodes(npoints_bundle))
3313 npoints_remain = npoints
3314 DO WHILE (npoints_remain > 0)
3315 IF (npoints_bundle > npoints_remain) npoints_bundle = npoints_remain
3317 IF (npoints > 1)
THEN
3318 DO ipoint = 1, npoints_bundle
3319 xnodes(ipoint) = cmplx(energy_min + real(npoints - npoints_remain + ipoint - 1, kind=
dp)/ &
3320 REAL(npoints - 1, kind=
dp)*(energy_max - energy_min), negf_control%eta, kind=
dp)
3323 xnodes(ipoint) = cmplx(energy_min, negf_control%eta, kind=
dp)
3326 DO ispin = 1, nspins
3329 IF (
PRESENT(just_contact))
THEN
3330 DO icontact = 1, ncontacts
3331 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
3332 omega=xnodes(1:npoints_bundle), &
3333 h0=negf_env%contacts(just_contact)%h_00(ispin), &
3334 s0=negf_env%contacts(just_contact)%s_00, &
3335 h1=negf_env%contacts(just_contact)%h_01(ispin), &
3336 s1=negf_env%contacts(just_contact)%s_01, &
3337 sub_env=sub_env, v_external=0.0_dp, &
3338 conv=negf_control%conv_green, transp=(icontact == 1))
3341 DO icontact = 1, ncontacts
3342 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
3343 omega=xnodes(1:npoints_bundle), &
3344 h0=negf_env%contacts(icontact)%h_00(ispin), &
3345 s0=negf_env%contacts(icontact)%s_00, &
3346 h1=negf_env%contacts(icontact)%h_01(ispin), &
3347 s1=negf_env%contacts(icontact)%s_01, &
3349 v_external=negf_control%contacts(icontact)%v_external, &
3350 conv=negf_control%conv_green, transp=.false.)
3354 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints_bundle), &
3356 ignore_bias=.false., &
3357 negf_env=negf_env, &
3358 negf_control=negf_control, &
3361 g_surf_contacts=g_surf_cache%g_surf_contacts, &
3362 dos=dos(1:npoints_bundle, ispin), &
3363 just_contact=just_contact)
3368 IF (log_unit > 0)
THEN
3369 DO ipoint = 1, npoints_bundle
3370 IF (nspins > 1)
THEN
3372 WRITE (log_unit,
'(T2,F17.8,T18,3ES25.11E3)') real(xnodes(ipoint), kind=
dp)*en_scale, &
3373 (dos(ipoint, 1) + dos(ipoint, 2))*dos_scale, dos(ipoint, 1)*dos_scale, dos(ipoint, 2)*dos_scale
3376 WRITE (log_unit,
'(T2,F20.8,T43,ES25.11E3)') real(xnodes(ipoint), kind=
dp)*en_scale, &
3377 2.0_dp*dos(ipoint, 1)*dos_scale
3382 npoints_remain = npoints_remain - npoints_bundle
3385 DEALLOCATE (dos, xnodes)
3386 CALL timestop(handle)
3387 END SUBROUTINE negf_print_dos
3406 SUBROUTINE negf_print_transmission(log_unit, energy_min, energy_max, npoints, energy_unit, v_shift, &
3407 negf_env, negf_control, sub_env, contact_id1, contact_id2)
3408 INTEGER,
INTENT(in) :: log_unit
3409 REAL(kind=
dp),
INTENT(in) :: energy_min, energy_max
3410 INTEGER,
INTENT(in) :: npoints, energy_unit
3411 REAL(kind=
dp),
INTENT(in) :: v_shift
3415 INTEGER,
INTENT(in) :: contact_id1, contact_id2
3417 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_print_transmission'
3419 CHARACTER(LEN=4) :: string
3420 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: xnodes
3421 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:, :) :: transm_coeff
3422 INTEGER :: handle, icontact, ipoint, ispin, &
3423 ncontacts, npoints_bundle, &
3424 npoints_remain, nspins
3425 REAL(kind=
dp) :: en_scale, rscale
3428 CALL timeset(routinen, handle)
3430 nspins =
SIZE(negf_env%h_s)
3432 IF (energy_unit == 2)
THEN
3440 IF (log_unit > 0)
THEN
3441 WRITE (log_unit,
'(A)')
"# Transmission function (in units of G0 = 2 e^2/h) between left and right electrodes"
3442 IF (nspins > 1)
THEN
3443 WRITE (log_unit,
'(A,T10,A,T39,3A)')
"#",
"Energy ("//string//
")",
"Transmission function [total, alpha, beta]"
3445 WRITE (log_unit,
'(A,T10,A,T39,3A)')
"#",
"Energy ("//string//
")",
"Transmission function [total = alpha+beta]"
3447 WRITE (log_unit,
'("#", T3,98("-"))')
3450 ncontacts =
SIZE(negf_env%contacts)
3451 cpassert(contact_id1 <= ncontacts)
3452 cpassert(contact_id2 <= ncontacts)
3454 IF (nspins == 1)
THEN
3462 rscale = 0.5_dp*rscale
3464 npoints_bundle = 4*sub_env%ngroups
3465 IF (npoints_bundle > npoints) npoints_bundle = npoints
3467 ALLOCATE (transm_coeff(npoints_bundle, nspins), xnodes(npoints_bundle))
3469 npoints_remain = npoints
3470 DO WHILE (npoints_remain > 0)
3471 IF (npoints_bundle > npoints_remain) npoints_bundle = npoints_remain
3473 IF (npoints > 1)
THEN
3474 DO ipoint = 1, npoints_bundle
3475 xnodes(ipoint) = cmplx(energy_min + real(npoints - npoints_remain + ipoint - 1, kind=
dp)/ &
3476 REAL(npoints - 1, kind=
dp)*(energy_max - energy_min), negf_control%eta, kind=
dp)
3479 xnodes(ipoint) = cmplx(energy_min, negf_control%eta, kind=
dp)
3482 DO ispin = 1, nspins
3485 DO icontact = 1, ncontacts
3486 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
3487 omega=xnodes(1:npoints_bundle), &
3488 h0=negf_env%contacts(icontact)%h_00(ispin), &
3489 s0=negf_env%contacts(icontact)%s_00, &
3490 h1=negf_env%contacts(icontact)%h_01(ispin), &
3491 s1=negf_env%contacts(icontact)%s_01, &
3493 v_external=negf_control%contacts(icontact)%v_external, &
3494 conv=negf_control%conv_green, transp=.false.)
3497 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints_bundle), &
3499 ignore_bias=.false., &
3500 negf_env=negf_env, &
3501 negf_control=negf_control, &
3504 g_surf_contacts=g_surf_cache%g_surf_contacts, &
3505 transm_coeff=transm_coeff(1:npoints_bundle, ispin), &
3506 transm_contact1=contact_id1, &
3507 transm_contact2=contact_id2)
3512 IF (log_unit > 0)
THEN
3513 DO ipoint = 1, npoints_bundle
3514 IF (nspins > 1)
THEN
3516 WRITE (log_unit,
'(T2,F17.8,T18,3ES25.11E3)') real(xnodes(ipoint), kind=
dp)*en_scale, &
3517 rscale*real(transm_coeff(ipoint, 1), kind=
dp) + rscale*real(transm_coeff(ipoint, 2), kind=
dp), &
3518 rscale*real(transm_coeff(ipoint, 1:2), kind=
dp)
3521 WRITE (log_unit,
'(T2,F20.8,T43,ES25.11E3)') &
3522 REAL(xnodes(ipoint), kind=
dp)*en_scale, rscale*real(transm_coeff(ipoint, 1), kind=
dp)
3527 npoints_remain = npoints_remain - npoints_bundle
3530 DEALLOCATE (transm_coeff, xnodes)
3531 CALL timestop(handle)
3532 END SUBROUTINE negf_print_transmission
3546 SUBROUTINE negf_output_initial(log_unit, negf_env, sub_env, negf_control, dft_control, verbose_output, &
3548 INTEGER,
INTENT(in) :: log_unit
3553 LOGICAL,
INTENT(in) :: verbose_output, debug_output
3555 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_output_initial'
3557 CHARACTER(len=100) :: sfmt
3558 INTEGER :: handle, i, icontact, j, k, n, nrow
3559 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: target_m
3561 CALL timeset(routinen, handle)
3564 DO icontact = 1,
SIZE(negf_control%contacts)
3565 IF (log_unit > 0)
THEN
3566 WRITE (log_unit,
"(/,' The electrode',I5)") icontact
3567 WRITE (log_unit,
"( ' ------------------')")
3568 WRITE (log_unit,
"(' From the force environment:',I16)") negf_control%contacts(icontact)%force_env_index
3569 WRITE (log_unit,
"(' Number of atoms:',I27)")
SIZE(negf_control%contacts(icontact)%atomlist_bulk)
3570 IF (verbose_output)
WRITE (log_unit,
"(' Atoms belonging to a contact (from the entire system):')")
3571 IF (verbose_output)
WRITE (log_unit,
"(16I5)") negf_control%contacts(icontact)%atomlist_bulk
3572 WRITE (log_unit,
"(' Number of atoms in a primary unit cell:',I4)") &
3573 SIZE(negf_env%contacts(icontact)%atomlist_cell0)
3575 IF (log_unit > 0 .AND. verbose_output)
THEN
3576 WRITE (log_unit,
"(' Atoms belonging to a primary unit cell (from the entire system):')")
3577 WRITE (log_unit,
"(16I5)") negf_env%contacts(icontact)%atomlist_cell0
3578 WRITE (log_unit,
"(' Direction of an electrode: ',I16)") negf_env%contacts(icontact)%direction_axis
3581 IF (debug_output)
THEN
3582 CALL cp_fm_get_info(negf_env%contacts(icontact)%s_00, nrow_global=nrow)
3583 ALLOCATE (target_m(nrow, nrow))
3584 IF (log_unit > 0)
WRITE (log_unit,
"(' The number of atomic orbitals:',I13)") nrow
3585 DO k = 1, dft_control%nspins
3587 IF (log_unit > 0)
THEN
3588 WRITE (sfmt,
"('(',i0,'(E15.5))')") nrow
3589 WRITE (log_unit,
"(' The H_00 electrode Hamiltonian for spin',I2)") k
3591 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3595 IF (log_unit > 0)
THEN
3596 WRITE (log_unit,
"(' The H_01 electrode Hamiltonian for spin',I2)") k
3598 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3603 IF (log_unit > 0)
THEN
3604 WRITE (log_unit,
"(' The S_00 overlap matrix')")
3606 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3610 IF (log_unit > 0)
THEN
3611 WRITE (log_unit,
"(' The S_01 overlap matrix')")
3613 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3616 DEALLOCATE (target_m)
3621 IF (log_unit > 0)
THEN
3622 WRITE (log_unit,
"(/,' The full scattering region')")
3623 WRITE (log_unit,
"( ' --------------------------')")
3624 WRITE (log_unit,
"(' Number of atoms:',I27)")
SIZE(negf_control%atomlist_S_screening)
3625 IF (verbose_output)
WRITE (log_unit,
"(' Atoms belonging to a full scattering region:')")
3626 IF (verbose_output)
WRITE (log_unit,
"(16I5)") negf_control%atomlist_S_screening
3629 IF (debug_output)
THEN
3631 ALLOCATE (target_m(n, n))
3632 WRITE (sfmt,
"('(',i0,'(E15.5))')") n
3633 IF (log_unit > 0)
WRITE (log_unit,
"(' The number of atomic orbitals:',I14)") n
3634 DO k = 1, dft_control%nspins
3635 IF (log_unit > 0)
WRITE (log_unit,
"(' The H_s Hamiltonian for spin',I2)") k
3638 IF (log_unit > 0)
WRITE (log_unit, sfmt) (target_m(i, j), j=1, n)
3641 IF (log_unit > 0)
WRITE (log_unit,
"(' The S_s overlap matrix')")
3644 IF (log_unit > 0)
WRITE (log_unit, sfmt) (target_m(i, j), j=1, n)
3646 DEALLOCATE (target_m)
3647 IF (log_unit > 0)
WRITE (log_unit,
"(/,' Scattering region - electrode contacts')")
3648 IF (log_unit > 0)
WRITE (log_unit,
"( ' ---------------------------------------')")
3649 ALLOCATE (target_m(n, nrow))
3650 DO icontact = 1,
SIZE(negf_control%contacts)
3651 IF (log_unit > 0)
WRITE (log_unit,
"(/,' The contact',I5)") icontact
3652 IF (log_unit > 0)
WRITE (log_unit,
"( ' ----------------')")
3653 DO k = 1, dft_control%nspins
3655 IF (log_unit > 0)
THEN
3656 WRITE (log_unit,
"(' The H_sc Hamiltonian for spin',I2)") k
3658 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3663 IF (log_unit > 0)
THEN
3664 WRITE (log_unit,
"(' The S_sc overlap matrix')")
3666 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3670 DEALLOCATE (target_m)
3673 IF (log_unit > 0)
THEN
3674 WRITE (log_unit,
"(/,' NEGF| Number of MPI processes: ',I5)") sub_env%mpi_comm_global%num_pe
3675 WRITE (log_unit,
"(' NEGF| Maximal number of processes per energy point:',I5)") negf_control%nprocs
3676 WRITE (log_unit,
"(' NEGF| Number of parallel MPI (energy) groups: ',I5)") sub_env%ngroups
3679 CALL timestop(handle)
3680 END SUBROUTINE negf_output_initial
3690 SUBROUTINE negf_write_restart(filename, negf_env, negf_control)
3691 CHARACTER(LEN=*),
INTENT(IN) :: filename
3695 INTEGER :: icontact, ncontacts, print_unit
3697 CALL open_file(file_name=filename, file_status=
"REPLACE", &
3698 file_form=
"FORMATTED", file_action=
"WRITE", &
3699 file_position=
"REWIND", unit_number=print_unit)
3701 WRITE (print_unit, *)
'This file is created automatically with restart files.'
3702 WRITE (print_unit, *)
'Do not remove it if you use any of restart files!'
3704 ncontacts =
SIZE(negf_control%contacts)
3706 DO icontact = 1, ncontacts
3707 WRITE (print_unit, *)
'icontact', icontact,
' fermi_energy', negf_env%contacts(icontact)%fermi_energy
3708 WRITE (print_unit, *)
'icontact', icontact,
' nelectrons_qs_cell0', negf_env%contacts(icontact)%nelectrons_qs_cell0
3709 WRITE (print_unit, *)
'icontact', icontact,
' nelectrons_qs_cell1', negf_env%contacts(icontact)%nelectrons_qs_cell1
3712 WRITE (print_unit, *)
'nelectrons_ref', negf_env%nelectrons_ref
3713 WRITE (print_unit, *)
'nelectrons ', negf_env%nelectrons
3717 END SUBROUTINE negf_write_restart
3727 SUBROUTINE negf_read_restart(filename, negf_env, negf_control)
3728 CHARACTER(LEN=*),
INTENT(IN) :: filename
3733 INTEGER :: i, icontact, ncontacts, print_unit
3735 CALL open_file(file_name=filename, file_status=
"OLD", &
3736 file_form=
"FORMATTED", file_action=
"READ", &
3737 file_position=
"REWIND", unit_number=print_unit)
3739 READ (print_unit, *) a
3740 READ (print_unit, *) a
3742 ncontacts =
SIZE(negf_control%contacts)
3744 DO icontact = 1, ncontacts
3745 READ (print_unit, *) a, i, a, negf_env%contacts(icontact)%fermi_energy
3746 READ (print_unit, *) a, i, a, negf_env%contacts(icontact)%nelectrons_qs_cell0
3747 READ (print_unit, *) a, i, a, negf_env%contacts(icontact)%nelectrons_qs_cell1
3750 READ (print_unit, *) a, negf_env%nelectrons_ref
3751 READ (print_unit, *) a, negf_env%nelectrons
3755 END SUBROUTINE negf_read_restart
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public papior2017
integer, save, public bailey2006
methods related to the blacs parallel environment
Basic linear algebra operations for complex full matrices.
subroutine, public cp_cfm_scale_and_add(alpha, matrix_a, beta, matrix_b)
Scale and add two BLACS matrices (a = alpha*a + beta*b).
subroutine, public cp_cfm_trace(matrix_a, matrix_b, trace)
Returns the trace of matrix_a^T matrix_b, i.e sum_{i,j}(matrix_a(i,j)*matrix_b(i,j)) .
Represents a complex full matrix distributed on many processors.
subroutine, public cp_cfm_get_submatrix(fm, target_m, start_row, start_col, n_rows, n_cols, transpose)
Extract a sub-matrix from the full matrix: op(target_m)(1:n_rows,1:n_cols) = fm(start_row:start_row+n...
subroutine, public cp_cfm_release(matrix)
Releases a full matrix.
subroutine, public cp_cfm_start_copy_general(source, destination, para_env, info)
Initiate the copy operation: get distribution data, post MPI isend and irecvs.
subroutine, public cp_cfm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
Creates a new full matrix with the given structure.
subroutine, public cp_cfm_cleanup_copy_general(info)
Complete the copy operation: wait for comms clean up MPI state.
subroutine, public cp_cfm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, matrix_struct, para_env)
Returns information about a full matrix.
subroutine, public cp_cfm_set_submatrix(matrix, new_values, start_row, start_col, n_rows, n_cols, alpha, beta, transpose)
Set a sub-matrix of the full matrix: matrix(start_row:start_row+n_rows,start_col:start_col+n_cols) = ...
subroutine, public cp_cfm_to_fm(msource, mtargetr, mtargeti)
Copy real and imaginary parts of a complex full matrix into separate real-value full matrices.
subroutine, public cp_cfm_finish_copy_general(destination, info)
Complete the copy operation: wait for comms, unpack, clean up MPI state.
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_deallocate_matrix(matrix)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_init_p(matrix)
...
subroutine, public dbcsr_dot(matrix_a, matrix_b, trace)
Computes the dot product of two matrices, also known as the trace of their matrix product.
DBCSR operations in CP2K.
Utility routines to open and close files. Tracking of preconnections.
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_scale_and_add(alpha, matrix_a, beta, matrix_b)
calc A <- alpha*A + beta*B optimized for alpha == 1.0 (just add beta*B) and beta == 0....
subroutine, public cp_fm_scale(alpha, matrix_a)
scales a matrix matrix_a = alpha * matrix_b
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
subroutine, public cp_fm_copy_general(source, destination, para_env)
General copy of a fm matrix to another fm matrix. Uses non-blocking MPI rather than ScaLAPACK.
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_add_to_element(matrix, irow_global, icol_global, alpha)
...
subroutine, public cp_fm_set_submatrix(fm, new_values, start_row, start_col, n_rows, n_cols, alpha, beta, transpose)
sets a submatrix of a full matrix fm(start_row:start_row+n_rows,start_col:start_col+n_cols) = alpha*o...
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
creates a new full matrix with the given structure
subroutine, public cp_fm_get_submatrix(fm, target_m, start_row, start_col, n_rows, n_cols, transpose)
gets a submatrix of a full matrix op(target_m)(1:n_rows,1:n_cols) =fm(start_row:start_row+n_rows,...
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer, parameter, public debug_print_level
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
integer, parameter, public cp_p_file
integer, parameter, public high_print_level
subroutine, public cp_iterate(iteration_info, last, iter_nr, increment, iter_nr_out)
adds one to the actual iteration
subroutine, public cp_rm_iter_level(iteration_info, level_name, n_rlevel_att)
Removes an iteration level.
integer function, public cp_print_key_should_output(iteration_info, basis_section, print_key_path, used_print_key, first_time)
returns what should be done with the given property if btest(res,cp_p_store) then the property should...
subroutine, public cp_add_iter_level(iteration_info, level_name, n_rlevel_new)
Adds an iteration level.
types that represent a subsys, i.e. a part of the system
Interface for the force calculations.
recursive subroutine, public force_env_get(force_env, in_use, fist_env, qs_env, meta_env, fp_env, subsys, para_env, potential_energy, additional_potential, kinetic_energy, harmonic_shell, kinetic_shell, cell, sub_force_env, qmmm_env, qmmmx_env, eip_env, pwdft_env, globenv, input, force_env_section, method_name_id, root_section, mixed_env, nnp_env, embed_env, ipi_env)
returns various attributes about the force environment
Define type storing the global information of a run. Keep the amount of stored data small....
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
integer, parameter, public default_path_length
Types and basic routines needed for a kpoint calculation.
subroutine, public get_kpoint_info(kpoint, kp_scheme, nkp_grid, kp_shift, symmetry, verbose, full_grid, use_real_wfn, eps_geo, parallel_group_size, kp_range, nkp, xkp, wkp, para_env, blacs_env_all, para_env_kp, para_env_inter_kp, blacs_env, kp_env, kp_aux_env, mpools, iogrp, nkp_groups, kp_dist, cell_to_index, index_to_cell, sab_nl, sab_nl_nosym, inversion_symmetry_only, symmetry_backend, symmetry_reduction_method, gamma_centered, lattice_fft)
Retrieve information from a kpoint environment.
Machine interface based on Fortran 2003 and POSIX.
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
complex(kind=dp), parameter, public z_one
real(kind=dp), parameter, public twopi
complex(kind=dp), parameter, public z_zero
Interface to the message passing library MPI.
Input control types for NEGF based quantum transport calculations.
subroutine, public negf_control_create(negf_control)
allocate control options for Non-equilibrium Green's Function calculation
subroutine, public read_negf_control(negf_control, input, subsys)
Read NEGF input parameters.
subroutine, public negf_control_release(negf_control)
release memory allocated for NEGF control options
Environment for NEGF based quantum transport calculations.
subroutine, public negf_env_release(negf_env)
Release a NEGF environment variable.
subroutine, public negf_env_create(negf_env, sub_env, negf_control, force_env, negf_mixing_section, log_unit)
Create a new NEGF environment and compute the relevant Kohn-Sham matrices.
Storage to keep precomputed surface Green's functions.
subroutine, public green_functions_cache_reorder(cache, tnodes)
Sort cached items in ascending order.
subroutine, public green_functions_cache_release(cache)
Release storage.
subroutine, public green_functions_cache_expand(cache, ncontacts, nnodes_extra)
Reallocate storage so it can handle extra 'nnodes_extra' items for each contact.
Subroutines to compute Green functions.
subroutine, public sancho_work_matrices_create(work, fm_struct)
Create work matrices required for the Lopez-Sancho algorithm.
subroutine, public sancho_work_matrices_release(work)
Release work matrices.
subroutine, public negf_contact_self_energy(self_energy_c, omega, g_surf_c, h_sc0, s_sc0, zwork1, zwork2, transp)
Compute the contact self energy at point 'omega' as self_energy_C = [omega * S_SC0 - KS_SC0] * g_surf...
subroutine, public negf_contact_broadening_matrix(gamma_c, self_energy_c)
Compute contact broadening matrix as gamma_C = i (self_energy_c^{ret.} - (self_energy_c^{ret....
subroutine, public do_sancho(g_surf, omega, h0, s0, h1, s1, conv, transp, work)
Iterative method to compute a retarded surface Green's function at the point omega.
subroutine, public negf_retarded_green_function(g_ret_s, omega, self_energy_ret_sum, h_s, s_s, v_hartree_s)
Compute the retarded Green's function at point 'omega' as G_S^{ret.} = [ omega * S_S - KS_S - \sum_{c...
Adaptive Clenshaw-Curtis quadrature algorithm to integrate a complex-valued function in a complex pla...
integer, parameter, public cc_shape_linear
subroutine, public ccquad_refine_integral(cc_env)
Refine approximated integral.
integer, parameter, public cc_interval_full
subroutine, public ccquad_double_number_of_points(cc_env, xnodes_next)
Get the next set of points at which the integrand needs to be computed. These points are then can be ...
subroutine, public ccquad_release(cc_env)
Release a Clenshaw-Curtis quadrature environment variable.
integer, parameter, public cc_interval_half
subroutine, public ccquad_init(cc_env, xnodes, nnodes, a, b, interval_id, shape_id, weights, tnodes_restart)
Initialise a Clenshaw-Curtis quadrature environment variable.
integer, parameter, public cc_shape_arc
subroutine, public ccquad_reduce_and_append_zdata(cc_env, zdata_next)
Prepare Clenshaw-Curtis environment for the subsequent refinement of the integral.
Adaptive Simpson's rule algorithm to integrate a complex-valued function in a complex plane.
integer, parameter, public sr_shape_arc
subroutine, public simpsonrule_refine_integral(sr_env, zdata_next)
Compute integral using the simpson's rules.
subroutine, public simpsonrule_init(sr_env, xnodes, nnodes, a, b, shape_id, conv, weights, tnodes_restart)
Initialise a Simpson's rule environment variable.
subroutine, public simpsonrule_release(sr_env)
Release a Simpson's rule environment variable.
integer, parameter, public sr_shape_linear
subroutine, public simpsonrule_get_next_nodes(sr_env, xnodes_next, nnodes)
Get the next set of nodes where to compute integrand.
Routines for reading and writing NEGF restart files.
subroutine, public negf_restart_file_name(filename, exist, negf_section, logger, icontact, ispin, h00, h01, s00, s01, h, s, hc, sc, h_scf)
Checks if the restart file exists and returns the filename.
subroutine, public negf_read_matrix_from_file(filename, matrix)
Reads full matrix from a file.
Helper routines to manipulate with matrices.
subroutine, public invert_cell_to_index(cell_to_index, nimages, index_to_cell)
Invert cell_to_index mapping between unit cells and DBCSR matrix images.
subroutine, public negf_copy_fm_submat_to_dbcsr(fm, matrix, atomlist_row, atomlist_col, subsys)
Populate relevant blocks of the DBCSR matrix using data from a ScaLAPACK matrix. Irrelevant blocks of...
subroutine, public negf_copy_sym_dbcsr_to_fm_submat(matrix, fm, atomlist_row, atomlist_col, subsys, mpi_comm_global, do_upper_diag, do_lower)
Extract part of the DBCSR matrix based on selected atoms and copy it into a dense matrix.
NEGF based quantum transport calculations.
subroutine, public do_negf(force_env)
Perform NEGF calculation.
Environment for NEGF based quantum transport calculations.
subroutine, public negf_sub_env_release(sub_env)
Release a parallel (sub)group environment.
subroutine, public negf_sub_env_create(sub_env, negf_control, blacs_env_global, blacs_grid_layout, blacs_repeatable)
Split MPI communicator to create a set of parallel (sub)groups.
basic linear algebra operations for full matrixes
Definition of physical constants:
real(kind=dp), parameter, public e_charge
real(kind=dp), parameter, public kelvin
real(kind=dp), parameter, public seconds
real(kind=dp), parameter, public evolt
module that contains the definitions of the scf types
integer, parameter, public broyden_mixing_nr
integer, parameter, public modified_broyden_mixing_nr
integer, parameter, public direct_mixing_nr
integer, parameter, public multisecant_mixing_nr
integer, parameter, public pulay_mixing_nr
integer, parameter, public gspace_mixing_nr
Utilities for broadened DOS and PDOS output.
real(kind=dp) function, public dos_density_scale(energy_unit)
Return the DOS-density conversion factor for the selected energy unit.
Perform a QUICKSTEP wavefunction optimization (single point).
subroutine, public qs_energies(qs_env, consistent_energies, calc_forces)
Driver routine for QUICKSTEP single point wavefunction optimization.
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, matrix_vhxc, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
subroutine, public gspace_mixing(qs_env, mixing_method, mixing_store, rho, para_env, iter_count, auxiliary)
Driver for the g-space mixing, calls the proper routine given the requested method.
routines that build the Kohn-Sham matrix (i.e calculate the coulomb and xc parts
subroutine, public rebuild_ks_matrix(qs_env, calculate_forces, just_energy, print_active)
Constructs a new Khon-Sham matrix.
elemental subroutine, public charge_mixing_init(mixing_store)
initialiation needed when charge mixing is used
subroutine, public mixing_init(mixing_method, rho, mixing_store, para_env, rho_atom, auxiliary)
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.