133#include "./base/base_uses.f90"
138 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'negf_methods'
139 LOGICAL,
PARAMETER,
PRIVATE :: debug_this_module = .true.
148 TYPE integration_status_type
149 INTEGER :: npoints = -1
150 REAL(kind=
dp) :: error = -1.0_dp
151 END TYPE integration_status_type
165 CHARACTER(LEN=*),
PARAMETER :: routinen =
'do_negf'
167 CHARACTER(len=default_string_length) :: contact_id_str, filename
168 INTEGER :: handle, icontact, ispin, log_unit, &
169 ncontacts, npoints, nspins, &
170 print_level, print_unit
171 LOGICAL :: debug_output, exist, should_output, &
173 REAL(kind=
dp) :: energy_max, energy_min
174 REAL(kind=
dp),
DIMENSION(2) :: current
187 negf_mixing_section, negf_section, &
188 print_section, root_section
190 CALL timeset(routinen, handle)
197 NULLIFY (blacs_env, cp_subsys, global_env, qs_env, root_section, sub_force_env)
198 CALL force_env_get(force_env, globenv=global_env, qs_env=qs_env, root_section=root_section, &
199 sub_force_env=sub_force_env, subsys=cp_subsys)
201 CALL get_qs_env(qs_env, blacs_env=blacs_env, para_env=para_env_global)
207 NULLIFY (negf_control)
210 CALL get_qs_env(qs_env, dft_control=dft_control)
213 log_unit =
cp_print_key_unit_nr(logger, negf_section,
"PRINT%PROGRAM_RUN_INFO", extension=
".Log")
215 IF (log_unit > 0)
THEN
216 WRITE (log_unit,
'(/,T2,79("-"))')
217 WRITE (log_unit,
'(T27,A,T62)')
"NEGF calculation is started"
218 WRITE (log_unit,
'(T2,79("-"))')
223 CALL section_vals_val_get(negf_section,
"PRINT%PROGRAM_RUN_INFO%PRINT_LEVEL", i_val=print_level)
224 SELECT CASE (print_level)
226 verbose_output = .true.
228 verbose_output = .true.
229 debug_output = .true.
231 verbose_output = .false.
232 debug_output = .false.
235 IF (log_unit > 0)
THEN
236 WRITE (log_unit,
"(/,' THE RELEVANT HAMILTONIAN AND OVERLAP MATRICES FROM DFT')")
237 WRITE (log_unit,
"( ' ------------------------------------------------------')")
240 CALL negf_sub_env_create(sub_env, negf_control, blacs_env, global_env%blacs_grid_layout, global_env%blacs_repeatable)
241 CALL negf_env_create(negf_env, sub_env, negf_control, force_env, negf_mixing_section, log_unit)
243 filename = trim(logger%iter_info%project_name)//
'-negf.restart'
244 INQUIRE (file=filename, exist=exist)
245 IF (exist)
CALL negf_read_restart(filename, negf_env, negf_control)
247 IF (log_unit > 0)
THEN
248 WRITE (log_unit,
"(/,' NEGF| The initial Hamiltonian and Overlap matrices are calculated.')")
251 CALL negf_output_initial(log_unit, negf_env, sub_env, negf_control, dft_control, verbose_output, debug_output)
258 ncontacts =
SIZE(negf_control%contacts)
259 DO icontact = 1, ncontacts
261 IF (negf_control%contacts(icontact)%force_env_index > 0)
THEN
262 CALL force_env_get(sub_force_env(negf_control%contacts(icontact)%force_env_index)%force_env, qs_env=qs_env)
267 CALL guess_fermi_level(icontact, negf_env, negf_control, sub_env, qs_env, log_unit)
272 IF (should_output)
THEN
280 middle_name=trim(adjustl(contact_id_str)), &
281 file_status=
"REPLACE")
282 CALL negf_print_dos(print_unit, energy_min, energy_max, npoints, &
283 v_shift=0.0_dp, negf_env=negf_env, negf_control=negf_control, &
284 sub_env=sub_env, base_contact=icontact, just_contact=icontact)
292 IF (ncontacts > 1)
THEN
297 CALL shift_potential(negf_env, negf_control, sub_env, qs_env, base_contact=1, log_unit=log_unit)
301 CALL converge_density(negf_env, negf_control, sub_env, negf_section, qs_env, negf_control%v_shift, &
302 base_contact=1, log_unit=log_unit)
307 IF (para_env_global%is_source() .AND. negf_control%write_common_restart_file)
THEN
308 CALL negf_write_restart(filename, negf_env, negf_control)
313 CALL get_qs_env(qs_env, dft_control=dft_control)
315 nspins = dft_control%nspins
317 cpassert(nspins <= 2)
323 current(ispin) = negf_compute_current(contact_id1=1, contact_id2=2, &
324 v_shift=negf_control%v_shift, &
326 negf_control=negf_control, &
329 blacs_env_global=blacs_env)
332 IF (log_unit > 0)
THEN
334 WRITE (log_unit,
'(/,T2,A,T60,ES20.7E2)')
"NEGF| Alpha-spin electric current (A)", current(1)
335 WRITE (log_unit,
'(T2,A,T60,ES20.7E2)')
"NEGF| Beta-spin electric current (A)", current(2)
337 WRITE (log_unit,
'(/,T2,A,T60,ES20.7E2)')
"NEGF| Electric current (A)", 2.0_dp*current(1)
346 IF (should_output)
THEN
354 middle_name=trim(adjustl(contact_id_str)), &
355 file_status=
"REPLACE")
357 CALL negf_print_dos(print_unit, energy_min, energy_max, npoints, negf_control%v_shift, &
358 negf_env=negf_env, negf_control=negf_control, &
359 sub_env=sub_env, base_contact=1)
368 IF (should_output)
THEN
375 extension=
".transm", &
376 middle_name=trim(adjustl(contact_id_str)), &
377 file_status=
"REPLACE")
379 CALL negf_print_transmission(print_unit, energy_min, energy_max, npoints, negf_control%v_shift, &
380 negf_env=negf_env, negf_control=negf_control, &
381 sub_env=sub_env, contact_id1=1, contact_id2=2)
388 IF (log_unit > 0)
THEN
389 WRITE (log_unit,
'(/,T2,79("-"))')
390 WRITE (log_unit,
'(T27,A,T62)')
"NEGF calculation is finished"
391 WRITE (log_unit,
'(T2,79("-"))')
397 CALL timestop(handle)
412 SUBROUTINE guess_fermi_level(contact_id, negf_env, negf_control, sub_env, qs_env, log_unit)
413 INTEGER,
INTENT(in) :: contact_id
418 INTEGER,
INTENT(in) :: log_unit
420 CHARACTER(LEN=*),
PARAMETER :: routinen =
'guess_fermi_level'
423 CHARACTER(len=default_string_length) :: temperature_str
424 COMPLEX(kind=dp) :: lbound_cpath, lbound_lpath, ubound_lpath
425 INTEGER :: direction_axis_abs, handle, image, &
426 ispin, nao, nimages, nspins, step
427 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: index_to_cell
428 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index
429 LOGICAL :: do_kpoints
430 REAL(kind=
dp) :: delta_au, delta_ef, energy_ubound_minus_fermi, fermi_level_guess, &
431 fermi_level_max, fermi_level_min, nelectrons_guess, nelectrons_max, nelectrons_min, &
432 nelectrons_qs_cell0, nelectrons_qs_cell1, offset_au, rscale, t1, t2, trace
437 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_s_kp, rho_ao_qs_kp
440 TYPE(integration_status_type) :: stats
447 CALL timeset(routinen, handle)
449 IF (log_unit > 0)
THEN
450 WRITE (temperature_str,
'(F11.3)') negf_control%contacts(contact_id)%temperature*
kelvin
451 WRITE (log_unit,
'(/,T2,A,I3)')
"FERMI LEVEL OF CONTACT ", contact_id
452 WRITE (log_unit,
"( ' --------------------------')")
453 WRITE (log_unit,
'(A)')
" Temperature "//trim(adjustl(temperature_str))//
" Kelvin"
456 IF (.NOT. negf_control%contacts(contact_id)%is_restart)
THEN
459 blacs_env=blacs_env_global, &
460 dft_control=dft_control, &
461 do_kpoints=do_kpoints, &
463 matrix_s_kp=matrix_s_kp, &
464 para_env=para_env_global, &
465 rho=rho_struct, subsys=subsys)
466 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_qs_kp)
468 nimages = dft_control%nimages
469 nspins = dft_control%nspins
470 direction_axis_abs = abs(negf_env%contacts(contact_id)%direction_axis)
472 cpassert(
SIZE(negf_env%contacts(contact_id)%h_00) == nspins)
474 IF (sub_env%ngroups > 1)
THEN
475 NULLIFY (matrix_s_fm, fm_struct)
477 CALL cp_fm_get_info(negf_env%contacts(contact_id)%s_00, nrow_global=nao)
478 CALL cp_fm_struct_create(fm_struct, nrow_global=nao, ncol_global=nao, context=blacs_env_global)
481 ALLOCATE (matrix_s_fm)
485 IF (sub_env%group_distribution(sub_env%mepos_global) == 0)
THEN
486 CALL cp_fm_copy_general(negf_env%contacts(contact_id)%s_00, matrix_s_fm, para_env_global)
491 matrix_s_fm => negf_env%contacts(contact_id)%s_00
499 ALLOCATE (cell_to_index(0:0, 0:0, 0:0))
500 cell_to_index(0, 0, 0) = 1
503 ALLOCATE (index_to_cell(3, nimages))
505 IF (.NOT. do_kpoints)
DEALLOCATE (cell_to_index)
507 IF (nspins == 1)
THEN
515 nelectrons_qs_cell0 = 0.0_dp
516 nelectrons_qs_cell1 = 0.0_dp
517 IF (negf_control%contacts(contact_id)%force_env_index > 0)
THEN
518 DO image = 1, nimages
519 IF (index_to_cell(direction_axis_abs, image) == 0)
THEN
521 CALL dbcsr_dot(rho_ao_qs_kp(ispin, image)%matrix, matrix_s_kp(1, image)%matrix, trace)
522 nelectrons_qs_cell0 = nelectrons_qs_cell0 + trace
524 ELSE IF (abs(index_to_cell(direction_axis_abs, image)) == 1)
THEN
526 CALL dbcsr_dot(rho_ao_qs_kp(ispin, image)%matrix, matrix_s_kp(1, image)%matrix, trace)
527 nelectrons_qs_cell1 = nelectrons_qs_cell1 + trace
531 negf_env%contacts(contact_id)%nelectrons_qs_cell0 = nelectrons_qs_cell0
532 negf_env%contacts(contact_id)%nelectrons_qs_cell1 = nelectrons_qs_cell1
533 ELSE IF (negf_control%contacts(contact_id)%force_env_index <= 0)
THEN
535 CALL cp_fm_trace(negf_env%contacts(contact_id)%rho_00(ispin), &
536 negf_env%contacts(contact_id)%s_00, trace)
537 nelectrons_qs_cell0 = nelectrons_qs_cell0 + trace
538 CALL cp_fm_trace(negf_env%contacts(contact_id)%rho_01(ispin), &
539 negf_env%contacts(contact_id)%s_01, trace)
540 nelectrons_qs_cell1 = nelectrons_qs_cell1 + 2.0_dp*trace
542 negf_env%contacts(contact_id)%nelectrons_qs_cell0 = nelectrons_qs_cell0
543 negf_env%contacts(contact_id)%nelectrons_qs_cell1 = nelectrons_qs_cell1
546 DEALLOCATE (index_to_cell)
548 IF (sub_env%ngroups > 1)
THEN
550 DEALLOCATE (matrix_s_fm)
556 nelectrons_qs_cell0 = negf_env%contacts(contact_id)%nelectrons_qs_cell0
557 nelectrons_qs_cell1 = negf_env%contacts(contact_id)%nelectrons_qs_cell1
561 IF (negf_control%contacts(contact_id)%compute_fermi_level)
THEN
564 blacs_env=blacs_env_global, &
565 dft_control=dft_control, &
566 do_kpoints=do_kpoints, &
568 matrix_s_kp=matrix_s_kp, &
569 para_env=para_env_global, &
570 rho=rho_struct, subsys=subsys)
571 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_qs_kp)
573 nimages = dft_control%nimages
574 nspins = dft_control%nspins
575 direction_axis_abs = abs(negf_env%contacts(contact_id)%direction_axis)
576 IF (nspins == 1)
THEN
583 cpassert(
SIZE(negf_env%contacts(contact_id)%h_00) == nspins)
585 IF (sub_env%ngroups > 1)
THEN
586 NULLIFY (matrix_s_fm, fm_struct)
588 CALL cp_fm_get_info(negf_env%contacts(contact_id)%s_00, nrow_global=nao)
589 CALL cp_fm_struct_create(fm_struct, nrow_global=nao, ncol_global=nao, context=blacs_env_global)
592 ALLOCATE (matrix_s_fm)
596 IF (sub_env%group_distribution(sub_env%mepos_global) == 0)
THEN
597 CALL cp_fm_copy_general(negf_env%contacts(contact_id)%s_00, matrix_s_fm, para_env_global)
602 matrix_s_fm => negf_env%contacts(contact_id)%s_00
607 IF (log_unit > 0)
THEN
608 WRITE (log_unit,
'(A)')
" Computing the Fermi level of bulk electrode"
609 WRITE (log_unit,
'(T2,A,T60,F20.10,/)')
"Electronic density of the electrode unit cell:", &
610 -1.0_dp*(nelectrons_qs_cell0 + nelectrons_qs_cell1)
611 WRITE (log_unit,
'(T3,A)')
"Step Integration method Time Fermi level Convergence (density)"
612 WRITE (log_unit,
'(T3,78("-"))')
618 negf_env%contacts(contact_id)%fermi_energy = energy%efermi
619 IF (negf_control%homo_lumo_gap > 0.0_dp)
THEN
620 IF (negf_control%contacts(contact_id)%refine_fermi_level)
THEN
621 fermi_level_min = negf_control%contacts(contact_id)%fermi_level
623 fermi_level_min = energy%efermi
625 fermi_level_max = fermi_level_min + negf_control%homo_lumo_gap
627 IF (negf_control%contacts(contact_id)%refine_fermi_level)
THEN
628 fermi_level_max = negf_control%contacts(contact_id)%fermi_level
630 fermi_level_max = energy%efermi
632 fermi_level_min = fermi_level_max + negf_control%homo_lumo_gap
636 lbound_cpath = cmplx(negf_control%energy_lbound, negf_control%eta, kind=
dp)
637 delta_au = real(negf_control%delta_npoles, kind=
dp)*
twopi*negf_control%contacts(contact_id)%temperature
638 offset_au = real(negf_control%gamma_kT, kind=
dp)*negf_control%contacts(contact_id)%temperature
639 energy_ubound_minus_fermi = -2.0_dp*log(negf_control%conv_density)*negf_control%contacts(contact_id)%temperature
647 fermi_level_guess = fermi_level_min
649 fermi_level_guess = fermi_level_max
651 fermi_level_guess = fermi_level_min - (nelectrons_min - nelectrons_qs_cell0)* &
652 (fermi_level_max - fermi_level_min)/(nelectrons_max - nelectrons_min)
655 negf_control%contacts(contact_id)%fermi_level = fermi_level_guess
656 nelectrons_guess = 0.0_dp
658 lbound_lpath = cmplx(fermi_level_guess - offset_au, delta_au, kind=
dp)
659 ubound_lpath = cmplx(fermi_level_guess + energy_ubound_minus_fermi, delta_au, kind=
dp)
661 CALL integration_status_reset(stats)
664 CALL negf_init_rho_equiv_residuals(rho_ao_fm=rho_ao_fm, &
666 ignore_bias=.true., &
668 negf_control=negf_control, &
671 base_contact=contact_id, &
672 just_contact=contact_id)
674 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_fm, &
677 ignore_bias=.true., &
679 negf_control=negf_control, &
682 base_contact=contact_id, &
683 integr_lbound=lbound_cpath, &
684 integr_ubound=lbound_lpath, &
685 matrix_s_global=matrix_s_fm, &
686 is_circular=.true., &
687 g_surf_cache=g_surf_cache, &
688 just_contact=contact_id)
691 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_fm, &
694 ignore_bias=.true., &
696 negf_control=negf_control, &
699 base_contact=contact_id, &
700 integr_lbound=lbound_lpath, &
701 integr_ubound=ubound_lpath, &
702 matrix_s_global=matrix_s_fm, &
703 is_circular=.false., &
704 g_surf_cache=g_surf_cache, &
705 just_contact=contact_id)
709 nelectrons_guess = nelectrons_guess + trace
712 nelectrons_guess = nelectrons_guess*rscale
716 IF (log_unit > 0)
THEN
717 WRITE (log_unit,
'(T2,I5,T12,A,T32,F8.1,T42,F15.8,T60,ES20.5E2)') &
718 step, get_method_description_string(stats, negf_control%integr_method), &
719 t2 - t1, fermi_level_guess, nelectrons_guess - nelectrons_qs_cell0
722 IF (abs(nelectrons_qs_cell0 - nelectrons_guess) < negf_control%conv_density)
EXIT
726 nelectrons_min = nelectrons_guess
728 nelectrons_max = nelectrons_guess
730 IF (fermi_level_guess < fermi_level_min)
THEN
731 fermi_level_max = fermi_level_min
732 nelectrons_max = nelectrons_min
733 fermi_level_min = fermi_level_guess
734 nelectrons_min = nelectrons_guess
735 ELSE IF (fermi_level_guess > fermi_level_max)
THEN
736 fermi_level_min = fermi_level_max
737 nelectrons_min = nelectrons_max
738 fermi_level_max = fermi_level_guess
739 nelectrons_max = nelectrons_guess
740 ELSE IF (fermi_level_max - fermi_level_guess < fermi_level_guess - fermi_level_min)
THEN
741 fermi_level_max = fermi_level_guess
742 nelectrons_max = nelectrons_guess
744 fermi_level_min = fermi_level_guess
745 nelectrons_min = nelectrons_guess
752 negf_control%contacts(contact_id)%fermi_level = fermi_level_guess
754 IF (sub_env%ngroups > 1)
THEN
756 DEALLOCATE (matrix_s_fm)
762 IF (negf_control%contacts(contact_id)%shift_fermi_level)
THEN
763 delta_ef = negf_control%contacts(contact_id)%fermi_level_shifted - negf_control%contacts(contact_id)%fermi_level
764 IF (log_unit > 0)
WRITE (log_unit,
"(/,' The energies are shifted by (a.u.):',F18.8)") delta_ef
765 IF (log_unit > 0)
WRITE (log_unit,
"(' (eV):',F18.8)") delta_ef*
evolt
766 negf_control%contacts(contact_id)%fermi_level = negf_control%contacts(contact_id)%fermi_level_shifted
767 CALL get_qs_env(qs_env, dft_control=dft_control)
768 nspins = dft_control%nspins
769 CALL cp_fm_get_info(negf_env%contacts(contact_id)%s_00, nrow_global=nao)
777 IF (log_unit > 0)
THEN
778 WRITE (temperature_str,
'(F11.3)') negf_control%contacts(contact_id)%temperature*
kelvin
779 WRITE (log_unit,
'(/,T2,A,I0)')
"NEGF| Contact No. ", contact_id
780 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| Fermi level at "//trim(adjustl(temperature_str))// &
781 " Kelvin (a.u.):", negf_control%contacts(contact_id)%fermi_level
782 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| (eV):", &
783 negf_control%contacts(contact_id)%fermi_level*
evolt
784 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| Electric potential (a.u.):", &
785 negf_control%contacts(contact_id)%v_external
786 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| (Volt):", &
787 negf_control%contacts(contact_id)%v_external*
evolt
788 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| Electro-chemical potential Ef-|e|V (a.u.):", &
789 (negf_control%contacts(contact_id)%fermi_level - negf_control%contacts(contact_id)%v_external)
790 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| (eV):", &
791 (negf_control%contacts(contact_id)%fermi_level - negf_control%contacts(contact_id)%v_external)*
evolt
794 CALL timestop(handle)
795 END SUBROUTINE guess_fermi_level
808 SUBROUTINE shift_potential(negf_env, negf_control, sub_env, qs_env, base_contact, log_unit)
813 INTEGER,
INTENT(in) :: base_contact, log_unit
815 CHARACTER(LEN=*),
PARAMETER :: routinen =
'shift_potential'
818 COMPLEX(kind=dp) :: lbound_cpath, ubound_cpath, ubound_lpath
819 INTEGER :: handle, ispin, iter_count, nao, &
821 LOGICAL :: do_kpoints
822 REAL(kind=
dp) :: mu_base, nelectrons_guess, nelectrons_max, nelectrons_min, nelectrons_ref, &
823 t1, t2, temperature, trace, v_shift_guess, v_shift_max, v_shift_min
826 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: rho_ao_fm
828 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: rho_ao_qs_kp
831 DIMENSION(:) :: g_surf_circular, g_surf_linear
832 TYPE(integration_status_type) :: stats
837 ncontacts =
SIZE(negf_control%contacts)
839 IF (.NOT. (
ALLOCATED(negf_env%h_s) .AND.
ALLOCATED(negf_env%h_sc) .AND. &
840 ASSOCIATED(negf_env%s_s) .AND.
ALLOCATED(negf_env%s_sc)))
RETURN
841 IF (ncontacts < 2)
RETURN
842 IF (negf_control%v_shift_maxiters == 0)
RETURN
844 CALL timeset(routinen, handle)
846 CALL get_qs_env(qs_env, blacs_env=blacs_env, do_kpoints=do_kpoints, dft_control=dft_control, &
847 para_env=para_env, rho=rho_struct, subsys=subsys)
848 cpassert(.NOT. do_kpoints)
854 IF (sub_env%ngroups > 1)
THEN
855 NULLIFY (matrix_s_fm, fm_struct)
860 ALLOCATE (matrix_s_fm)
864 IF (sub_env%group_distribution(sub_env%mepos_global) == 0)
THEN
870 matrix_s_fm => negf_env%s_s
875 nspins =
SIZE(negf_env%h_s)
877 mu_base = negf_control%contacts(base_contact)%fermi_level
880 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_qs_kp)
883 nelectrons_ref = 0.0_dp
884 ALLOCATE (rho_ao_fm(nspins))
888 IF (.NOT. negf_control%is_restart)
THEN
891 fm=rho_ao_fm(ispin), &
892 atomlist_row=negf_control%atomlist_S_screening, &
893 atomlist_col=negf_control%atomlist_S_screening, &
894 subsys=subsys, mpi_comm_global=para_env, &
895 do_upper_diag=.true., do_lower=.true.)
897 CALL cp_fm_trace(rho_ao_fm(ispin), matrix_s_fm, trace)
898 nelectrons_ref = nelectrons_ref + trace
900 negf_env%nelectrons_ref = nelectrons_ref
902 nelectrons_ref = negf_env%nelectrons_ref
905 IF (log_unit > 0)
THEN
906 WRITE (log_unit,
'(/,T2,A)')
"COMPUTE SHIFT IN HARTREE POTENTIAL"
907 WRITE (log_unit,
"( ' ----------------------------------')")
908 WRITE (log_unit,
'(/,T2,A,T55,F25.14,/)')
"Initial electronic density of the scattering region:", -1.0_dp*nelectrons_ref
909 WRITE (log_unit,
'(T3,A)')
"Step Integration method Time V shift Convergence (density)"
910 WRITE (log_unit,
'(T3,78("-"))')
913 temperature = negf_control%contacts(base_contact)%temperature
916 lbound_cpath = cmplx(negf_control%energy_lbound, negf_control%eta, kind=
dp)
917 ubound_cpath = cmplx(mu_base - real(negf_control%gamma_kT, kind=
dp)*temperature, &
918 REAL(negf_control%delta_npoles, kind=
dp)*
twopi*temperature, kind=
dp)
921 ubound_lpath = cmplx(mu_base - log(negf_control%conv_density)*temperature, &
922 REAL(negf_control%delta_npoles, kind=
dp)*
twopi*temperature, kind=
dp)
924 v_shift_min = negf_control%v_shift
925 v_shift_max = negf_control%v_shift + negf_control%v_shift_offset
927 ALLOCATE (g_surf_circular(nspins), g_surf_linear(nspins))
929 DO iter_count = 1, negf_control%v_shift_maxiters
930 SELECT CASE (iter_count)
932 v_shift_guess = v_shift_min
934 v_shift_guess = v_shift_max
936 v_shift_guess = v_shift_min - (nelectrons_min - nelectrons_ref)* &
937 (v_shift_max - v_shift_min)/(nelectrons_max - nelectrons_min)
941 CALL integration_status_reset(stats)
945 CALL negf_init_rho_equiv_residuals(rho_ao_fm=rho_ao_fm(ispin), &
946 v_shift=v_shift_guess, &
947 ignore_bias=.true., &
949 negf_control=negf_control, &
952 base_contact=base_contact)
955 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_fm(ispin), &
957 v_shift=v_shift_guess, &
958 ignore_bias=.true., &
960 negf_control=negf_control, &
963 base_contact=base_contact, &
964 integr_lbound=lbound_cpath, &
965 integr_ubound=ubound_cpath, &
966 matrix_s_global=matrix_s_fm, &
967 is_circular=.true., &
968 g_surf_cache=g_surf_circular(ispin))
969 IF (negf_control%disable_cache)
THEN
974 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_fm(ispin), &
976 v_shift=v_shift_guess, &
977 ignore_bias=.true., &
979 negf_control=negf_control, &
982 base_contact=base_contact, &
983 integr_lbound=ubound_cpath, &
984 integr_ubound=ubound_lpath, &
985 matrix_s_global=matrix_s_fm, &
986 is_circular=.false., &
987 g_surf_cache=g_surf_linear(ispin))
988 IF (negf_control%disable_cache)
THEN
1001 CALL cp_fm_trace(rho_ao_fm(1), matrix_s_fm, nelectrons_guess)
1005 IF (log_unit > 0)
THEN
1006 WRITE (log_unit,
'(T2,I5,T12,A,T32,F8.1,T42,F15.8,T60,ES20.5E2)') &
1007 iter_count, get_method_description_string(stats, negf_control%integr_method), &
1008 t2 - t1, v_shift_guess, nelectrons_guess - nelectrons_ref
1011 IF (abs(nelectrons_guess - nelectrons_ref) < negf_control%conv_scf)
EXIT
1014 SELECT CASE (iter_count)
1016 nelectrons_min = nelectrons_guess
1018 nelectrons_max = nelectrons_guess
1020 IF (v_shift_guess < v_shift_min)
THEN
1021 v_shift_max = v_shift_min
1022 nelectrons_max = nelectrons_min
1023 v_shift_min = v_shift_guess
1024 nelectrons_min = nelectrons_guess
1025 ELSE IF (v_shift_guess > v_shift_max)
THEN
1026 v_shift_min = v_shift_max
1027 nelectrons_min = nelectrons_max
1028 v_shift_max = v_shift_guess
1029 nelectrons_max = nelectrons_guess
1030 ELSE IF (v_shift_max - v_shift_guess < v_shift_guess - v_shift_min)
THEN
1031 v_shift_max = v_shift_guess
1032 nelectrons_max = nelectrons_guess
1034 v_shift_min = v_shift_guess
1035 nelectrons_min = nelectrons_guess
1042 negf_control%v_shift = v_shift_guess
1044 IF (log_unit > 0)
THEN
1045 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| Shift in Hartree potential (a.u.):", negf_control%v_shift
1046 WRITE (log_unit,
'(T2,A,T62,F18.8)')
"NEGF| (eV):", negf_control%v_shift*
evolt
1049 DO ispin = nspins, 1, -1
1053 DEALLOCATE (g_surf_circular, g_surf_linear)
1057 IF (sub_env%ngroups > 1 .AND.
ASSOCIATED(matrix_s_fm))
THEN
1059 DEALLOCATE (matrix_s_fm)
1062 CALL timestop(handle)
1063 END SUBROUTINE shift_potential
1079 SUBROUTINE converge_density(negf_env, negf_control, sub_env, negf_section, qs_env, v_shift, base_contact, log_unit)
1085 REAL(kind=
dp),
INTENT(in) :: v_shift
1086 INTEGER,
INTENT(in) :: base_contact, log_unit
1088 CHARACTER(LEN=*),
PARAMETER :: routinen =
'converge_density'
1089 REAL(kind=
dp),
PARAMETER :: threshold = 16.0_dp*epsilon(0.0_dp)
1092 CHARACTER(len=100) :: sfmt
1093 CHARACTER(LEN=default_path_length) :: filebase, filename
1094 COMPLEX(kind=dp) :: lbound_cpath, ubound_cpath, ubound_lpath
1095 INTEGER :: handle, i, icontact, image, ispin, &
1096 iter_count, j, nao, ncol, ncontacts, &
1097 nimages, nrow, nspins, print_unit
1098 LOGICAL :: do_kpoints, exist
1099 REAL(kind=
dp) :: delta, iter_delta, mu_base, nelectrons, &
1100 nelectrons_diff, t1, t2, temperature, &
1102 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: target_m
1105 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: rho_ao_delta_fm, rho_ao_new_fm
1108 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks_initial_kp, matrix_ks_qs_kp, &
1109 rho_ao_initial_kp, rho_ao_new_kp, &
1113 DIMENSION(:) :: g_surf_circular, g_surf_linear, &
1115 TYPE(integration_status_type) :: stats
1122 ncontacts =
SIZE(negf_control%contacts)
1124 IF (ncontacts > 2)
THEN
1125 cpabort(
"Poisson solver does not support the general NEGF setup (>2 contacts).")
1128 IF (.NOT. (
ALLOCATED(negf_env%h_s) .AND.
ALLOCATED(negf_env%h_sc) .AND. &
1129 ASSOCIATED(negf_env%s_s) .AND.
ALLOCATED(negf_env%s_sc)))
RETURN
1130 IF (ncontacts < 2)
RETURN
1131 IF (negf_control%max_scf == 0)
RETURN
1133 CALL timeset(routinen, handle)
1135 IF (log_unit > 0)
THEN
1136 WRITE (log_unit,
'(/,T2,A)')
"NEGF SELF-CONSISTENT PROCEDURE"
1137 WRITE (log_unit,
"( ' ------------------------------')")
1139 WRITE (log_unit,
'(T3,A)')
"Mixing method: Direct mixing of new and old density matrices"
1142 WRITE (log_unit,
'(T3,A)')
"Mixing method: Broyden mixing"
1145 WRITE (log_unit,
'(T3,A)')
"Mixing method: Modified Broyden mixing"
1148 WRITE (log_unit,
'(T3,A)')
"Mixing method: Pulay mixing"
1151 WRITE (log_unit,
'(T3,A)')
"Mixing method: Multisecant scheme for mixing"
1155 IF (negf_control%update_HS .AND. (.NOT. negf_control%is_dft_entire))
THEN
1156 CALL qs_energies(qs_env, consistent_energies=.false., calc_forces=.false.)
1159 CALL get_qs_env(qs_env, blacs_env=blacs_env, do_kpoints=do_kpoints, dft_control=dft_control, &
1160 matrix_ks_kp=matrix_ks_qs_kp, para_env=para_env, rho=rho_struct, subsys=subsys)
1161 cpassert(.NOT. do_kpoints)
1168 IF (sub_env%ngroups > 1)
THEN
1169 NULLIFY (matrix_s_fm, fm_struct)
1173 ALLOCATE (matrix_s_fm)
1177 IF (sub_env%group_distribution(sub_env%mepos_global) == 0)
THEN
1183 matrix_s_fm => negf_env%s_s
1188 nspins =
SIZE(negf_env%h_s)
1189 nimages = dft_control%nimages
1191 v_base = negf_control%contacts(base_contact)%v_external
1192 mu_base = negf_control%contacts(base_contact)%fermi_level - v_base
1195 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_qs_kp)
1197 ALLOCATE (target_m(nao, nao))
1198 ALLOCATE (rho_ao_delta_fm(nspins), rho_ao_new_fm(nspins))
1199 DO ispin = 1, nspins
1204 IF (negf_control%restart_scf)
THEN
1205 IF (para_env%is_source())
THEN
1208 CALL para_env%bcast(filebase)
1209 IF (nspins == 1)
THEN
1210 filename = trim(filebase)//
'.hs'
1211 INQUIRE (file=filename, exist=exist)
1212 IF (.NOT. exist)
THEN
1213 CALL cp_warn(__location__, &
1214 "User requested to read the KS matrix from the file named: "// &
1215 trim(filename)//
". This file does not exist. The initial KS matrix will be used.")
1218 CALL para_env%bcast(target_m)
1220 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
" H_s is read from "//trim(filename)
1222 filename = trim(filebase)//
'.rho'
1223 INQUIRE (file=filename, exist=exist)
1224 IF (.NOT. exist)
THEN
1225 CALL cp_warn(__location__, &
1226 "User requested to read the density matrix from the file named: "// &
1227 trim(filename)//
". This file does not exist. The initial density matrix will be used.")
1230 CALL para_env%bcast(target_m)
1232 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
" rho_s is read from "//trim(filename)
1234 matrix=rho_ao_qs_kp(1, 1)%matrix, &
1235 atomlist_row=negf_control%atomlist_S_screening, &
1236 atomlist_col=negf_control%atomlist_S_screening, &
1240 IF (nspins == 2)
THEN
1241 filename = trim(filebase)//
'-S1.hs'
1242 INQUIRE (file=filename, exist=exist)
1243 IF (.NOT. exist)
THEN
1244 CALL cp_warn(__location__, &
1245 "User requested to read the KS matrix from the file named: "// &
1246 trim(filename)//
". This file does not exist. The initial KS matrix will be used.")
1249 CALL para_env%bcast(target_m)
1251 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
" H_s is read from "//trim(filename)
1253 filename = trim(filebase)//
'-S2.hs'
1254 INQUIRE (file=filename, exist=exist)
1255 IF (.NOT. exist)
THEN
1256 CALL cp_warn(__location__, &
1257 "User requested to read the KS matrix from the file named: "// &
1258 trim(filename)//
". This file does not exist. The initial KS matrix will be used.")
1261 CALL para_env%bcast(target_m)
1263 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
" H_s is read from "//trim(filename)
1265 filename = trim(filebase)//
'-S1.rho'
1266 INQUIRE (file=filename, exist=exist)
1267 IF (.NOT. exist)
THEN
1268 CALL cp_warn(__location__, &
1269 "User requested to read the density matrix from the file named: "// &
1270 trim(filename)//
". This file does not exist. The initial density matrix will be used.")
1273 CALL para_env%bcast(target_m)
1275 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
" rho_s is read from "//trim(filename)
1277 matrix=rho_ao_qs_kp(1, 1)%matrix, &
1278 atomlist_row=negf_control%atomlist_S_screening, &
1279 atomlist_col=negf_control%atomlist_S_screening, &
1282 filename = trim(filebase)//
'-S2.rho'
1283 INQUIRE (file=filename, exist=exist)
1284 IF (.NOT. exist)
THEN
1285 CALL cp_warn(__location__, &
1286 "User requested to read the density matrix from the file named: "// &
1287 trim(filename)//
". This file does not exist. The initial density matrix will be used.")
1290 CALL para_env%bcast(target_m)
1292 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
" rho_s is read from "//trim(filename)
1294 matrix=rho_ao_qs_kp(2, 1)%matrix, &
1295 atomlist_row=negf_control%atomlist_S_screening, &
1296 atomlist_col=negf_control%atomlist_S_screening, &
1303 NULLIFY (matrix_ks_initial_kp, rho_ao_initial_kp, rho_ao_new_kp)
1308 DO image = 1, nimages
1309 DO ispin = 1, nspins
1310 CALL dbcsr_init_p(matrix_ks_initial_kp(ispin, image)%matrix)
1311 CALL dbcsr_copy(matrix_b=matrix_ks_initial_kp(ispin, image)%matrix, matrix_a=matrix_ks_qs_kp(ispin, image)%matrix)
1313 CALL dbcsr_init_p(rho_ao_initial_kp(ispin, image)%matrix)
1314 CALL dbcsr_copy(matrix_b=rho_ao_initial_kp(ispin, image)%matrix, matrix_a=rho_ao_qs_kp(ispin, image)%matrix)
1317 CALL dbcsr_copy(matrix_b=rho_ao_new_kp(ispin, image)%matrix, matrix_a=rho_ao_qs_kp(ispin, image)%matrix)
1323 DO ispin = 1, nspins
1325 fm=rho_ao_delta_fm(ispin), &
1326 atomlist_row=negf_control%atomlist_S_screening, &
1327 atomlist_col=negf_control%atomlist_S_screening, &
1328 subsys=subsys, mpi_comm_global=para_env, &
1329 do_upper_diag=.true., do_lower=.true.)
1331 CALL cp_fm_trace(rho_ao_delta_fm(ispin), matrix_s_fm, trace)
1332 nelectrons = nelectrons + trace
1334 negf_env%nelectrons = nelectrons
1338 CALL mixing_allocate(qs_env, negf_env%mixing_method, nspins=nspins, mixing_store=negf_env%mixing_storage)
1339 IF (dft_control%qs_control%dftb)
THEN
1340 cpabort(
'DFTB Code not available')
1341 ELSE IF (dft_control%qs_control%xtb)
THEN
1343 ELSE IF (dft_control%qs_control%semi_empirical)
THEN
1344 cpabort(
'SE Code not possible')
1346 CALL mixing_init(negf_env%mixing_method, rho_struct, negf_env%mixing_storage, para_env)
1350 IF (log_unit > 0)
THEN
1351 WRITE (log_unit,
'(/,T2,A,T55,F25.14,/)')
" Initial electronic density of the scattering region:", -1.0_dp*nelectrons
1352 WRITE (log_unit,
'(T3,A)')
"Step Integration method Time Electronic density Convergence"
1353 WRITE (log_unit,
'(T3,78("-"))')
1356 temperature = negf_control%contacts(base_contact)%temperature
1359 lbound_cpath = cmplx(negf_control%energy_lbound, negf_control%eta, kind=
dp)
1360 ubound_cpath = cmplx(mu_base - real(negf_control%gamma_kT, kind=
dp)*temperature, &
1361 REAL(negf_control%delta_npoles, kind=
dp)*
twopi*temperature, kind=
dp)
1364 ubound_lpath = cmplx(mu_base - log(negf_control%conv_density)*temperature, &
1365 REAL(negf_control%delta_npoles, kind=
dp)*
twopi*temperature, kind=
dp)
1367 ALLOCATE (g_surf_circular(nspins), g_surf_linear(nspins), g_surf_nonequiv(nspins))
1371 DO iter_count = 1, negf_control%max_scf
1373 CALL integration_status_reset(stats)
1374 CALL cp_iterate(logger%iter_info, last=.false., iter_nr=iter_count)
1376 DO ispin = 1, nspins
1378 CALL negf_init_rho_equiv_residuals(rho_ao_fm=rho_ao_new_fm(ispin), &
1380 ignore_bias=.false., &
1381 negf_env=negf_env, &
1382 negf_control=negf_control, &
1385 base_contact=base_contact)
1388 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_new_fm(ispin), &
1391 ignore_bias=.false., &
1392 negf_env=negf_env, &
1393 negf_control=negf_control, &
1396 base_contact=base_contact, &
1397 integr_lbound=lbound_cpath, &
1398 integr_ubound=ubound_cpath, &
1399 matrix_s_global=matrix_s_fm, &
1400 is_circular=.true., &
1401 g_surf_cache=g_surf_circular(ispin))
1402 IF (negf_control%disable_cache)
THEN
1407 CALL negf_add_rho_equiv_low(rho_ao_fm=rho_ao_new_fm(ispin), &
1410 ignore_bias=.false., &
1411 negf_env=negf_env, &
1412 negf_control=negf_control, &
1415 base_contact=base_contact, &
1416 integr_lbound=ubound_cpath, &
1417 integr_ubound=ubound_lpath, &
1418 matrix_s_global=matrix_s_fm, &
1419 is_circular=.false., &
1420 g_surf_cache=g_surf_linear(ispin))
1421 IF (negf_control%disable_cache)
THEN
1427 DO icontact = 1, ncontacts
1428 IF (icontact /= base_contact)
THEN
1429 delta = delta + abs(negf_control%contacts(icontact)%v_external - &
1430 negf_control%contacts(base_contact)%v_external) + &
1431 abs(negf_control%contacts(icontact)%fermi_level - &
1432 negf_control%contacts(base_contact)%fermi_level) + &
1433 abs(negf_control%contacts(icontact)%temperature - &
1434 negf_control%contacts(base_contact)%temperature)
1437 IF (delta >= threshold)
THEN
1438 CALL negf_add_rho_nonequiv(rho_ao_fm=rho_ao_new_fm(ispin), &
1441 negf_env=negf_env, &
1442 negf_control=negf_control, &
1445 base_contact=base_contact, &
1446 matrix_s_global=matrix_s_fm, &
1447 g_surf_cache=g_surf_nonequiv(ispin))
1448 IF (negf_control%disable_cache)
THEN
1454 IF (nspins == 1)
CALL cp_fm_scale(2.0_dp, rho_ao_new_fm(1))
1457 nelectrons_diff = 0.0_dp
1458 DO ispin = 1, nspins
1459 CALL cp_fm_trace(rho_ao_new_fm(ispin), matrix_s_fm, trace)
1460 nelectrons = nelectrons + trace
1464 CALL cp_fm_trace(rho_ao_delta_fm(ispin), matrix_s_fm, trace)
1465 nelectrons_diff = nelectrons_diff + trace
1468 CALL cp_fm_to_fm(rho_ao_new_fm(ispin), rho_ao_delta_fm(ispin))
1473 IF (log_unit > 0)
THEN
1474 WRITE (log_unit,
'(T2,I5,T12,A,T32,F8.1,T43,F20.8,T65,ES15.5E2)') &
1475 iter_count, get_method_description_string(stats, negf_control%integr_method), &
1476 t2 - t1, -1.0_dp*nelectrons, nelectrons_diff
1479 IF (abs(nelectrons_diff) < negf_control%conv_scf)
EXIT
1485 DO image = 1, nimages
1486 DO ispin = 1, nspins
1487 CALL dbcsr_copy(matrix_b=rho_ao_new_kp(ispin, image)%matrix, &
1488 matrix_a=rho_ao_initial_kp(ispin, image)%matrix)
1492 DO ispin = 1, nspins
1494 matrix=rho_ao_new_kp(ispin, 1)%matrix, &
1495 atomlist_row=negf_control%atomlist_S_screening, &
1496 atomlist_col=negf_control%atomlist_S_screening, &
1501 para_env, iter_delta, iter_count)
1503 DO image = 1, nimages
1504 DO ispin = 1, nspins
1505 CALL dbcsr_copy(rho_ao_qs_kp(ispin, image)%matrix, rho_ao_new_kp(ispin, image)%matrix)
1511 DO image = 1, nimages
1512 DO ispin = 1, nspins
1513 CALL dbcsr_copy(matrix_b=rho_ao_qs_kp(ispin, image)%matrix, &
1514 matrix_a=rho_ao_initial_kp(ispin, image)%matrix)
1518 DO ispin = 1, nspins
1520 matrix=rho_ao_qs_kp(ispin, 1)%matrix, &
1521 atomlist_row=negf_control%atomlist_S_screening, &
1522 atomlist_col=negf_control%atomlist_S_screening, &
1530 CALL gspace_mixing(qs_env, negf_env%mixing_method, negf_env%mixing_storage, &
1531 rho_struct, para_env, iter_count)
1535 IF (negf_control%update_HS)
THEN
1538 DO ispin = 1, nspins
1540 fm=negf_env%h_s(ispin), &
1541 atomlist_row=negf_control%atomlist_S_screening, &
1542 atomlist_col=negf_control%atomlist_S_screening, &
1543 subsys=subsys, mpi_comm_global=para_env, &
1544 do_upper_diag=.true., do_lower=.true.)
1549 IF (nspins == 1)
THEN
1552 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1554 extension=
".hs", file_status=
"REPLACE", file_action=
"WRITE", &
1555 do_backup=.true., file_form=
"FORMATTED")
1556 nrow =
SIZE(target_m, 1)
1557 ncol =
SIZE(target_m, 2)
1558 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1559 WRITE (print_unit, *) nrow, ncol
1561 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1566 IF (nspins == 2)
THEN
1569 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1571 extension=
"-S1.hs", file_status=
"REPLACE", file_action=
"WRITE", &
1572 do_backup=.true., file_form=
"FORMATTED")
1573 nrow =
SIZE(target_m, 1)
1574 ncol =
SIZE(target_m, 2)
1575 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1576 WRITE (print_unit, *) nrow, ncol
1578 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1584 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1586 extension=
"-S2.hs", file_status=
"REPLACE", file_action=
"WRITE", &
1587 do_backup=.true., file_form=
"FORMATTED")
1588 nrow =
SIZE(target_m, 1)
1589 ncol =
SIZE(target_m, 2)
1590 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1591 WRITE (print_unit, *) nrow, ncol
1593 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1600 IF (nspins == 1)
THEN
1603 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1605 extension=
".rho", file_status=
"REPLACE", file_action=
"WRITE", &
1606 do_backup=.true., file_form=
"FORMATTED")
1607 nrow =
SIZE(target_m, 1)
1608 ncol =
SIZE(target_m, 2)
1609 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1610 WRITE (print_unit, *) nrow, ncol
1612 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1617 IF (nspins == 2)
THEN
1620 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1622 extension=
"-S1.rho", file_status=
"REPLACE", file_action=
"WRITE", &
1623 do_backup=.true., file_form=
"FORMATTED")
1624 nrow =
SIZE(target_m, 1)
1625 ncol =
SIZE(target_m, 2)
1626 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1627 WRITE (print_unit, *) nrow, ncol
1629 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1635 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1637 extension=
"-S2.rho", file_status=
"REPLACE", file_action=
"WRITE", &
1638 do_backup=.true., file_form=
"FORMATTED")
1639 nrow =
SIZE(target_m, 1)
1640 ncol =
SIZE(target_m, 2)
1641 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1642 WRITE (print_unit, *) nrow, ncol
1644 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1653 CALL cp_iterate(logger%iter_info, last=.true., iter_nr=iter_count)
1654 IF (nspins == 1)
THEN
1657 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1659 extension=
".hs", file_status=
"REPLACE", file_action=
"WRITE", &
1660 do_backup=.true., file_form=
"FORMATTED")
1661 nrow =
SIZE(target_m, 1)
1662 ncol =
SIZE(target_m, 2)
1663 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1664 WRITE (print_unit, *) nrow, ncol
1666 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1671 IF (nspins == 2)
THEN
1674 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1676 extension=
"-S1.hs", file_status=
"REPLACE", file_action=
"WRITE", &
1677 do_backup=.true., file_form=
"FORMATTED")
1678 nrow =
SIZE(target_m, 1)
1679 ncol =
SIZE(target_m, 2)
1680 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1681 WRITE (print_unit, *) nrow, ncol
1683 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1689 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1691 extension=
"-S2.hs", file_status=
"REPLACE", file_action=
"WRITE", &
1692 do_backup=.true., file_form=
"FORMATTED")
1693 nrow =
SIZE(target_m, 1)
1694 ncol =
SIZE(target_m, 2)
1695 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1696 WRITE (print_unit, *) nrow, ncol
1698 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1705 IF (nspins == 1)
THEN
1708 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1710 extension=
".rho", file_status=
"REPLACE", file_action=
"WRITE", &
1711 do_backup=.true., file_form=
"FORMATTED")
1712 nrow =
SIZE(target_m, 1)
1713 ncol =
SIZE(target_m, 2)
1714 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1715 WRITE (print_unit, *) nrow, ncol
1717 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1722 IF (nspins == 2)
THEN
1725 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1727 extension=
"-S1.rho", file_status=
"REPLACE", file_action=
"WRITE", &
1728 do_backup=.true., file_form=
"FORMATTED")
1729 nrow =
SIZE(target_m, 1)
1730 ncol =
SIZE(target_m, 2)
1731 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1732 WRITE (print_unit, *) nrow, ncol
1734 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1740 negf_section,
'PRINT%RESTART'),
cp_p_file))
THEN
1742 extension=
"-S2.rho", file_status=
"REPLACE", file_action=
"WRITE", &
1743 do_backup=.true., file_form=
"FORMATTED")
1744 nrow =
SIZE(target_m, 1)
1745 ncol =
SIZE(target_m, 2)
1746 WRITE (sfmt,
"('(',i0,'(E15.5))')") ncol
1747 WRITE (print_unit, *) nrow, ncol
1749 WRITE (print_unit, sfmt) (target_m(i, j), j=1, ncol)
1755 DEALLOCATE (target_m)
1760 IF (log_unit > 0)
THEN
1761 IF (iter_count <= negf_control%max_scf)
THEN
1762 WRITE (log_unit,
'(/,T11,1X,A,I0,A)')
"*** NEGF run converged in ", iter_count,
" iteration(s) ***"
1764 WRITE (log_unit,
'(/,T11,1X,A,I0,A)')
"*** NEGF run did NOT converge after ", iter_count - 1,
" iteration(s) ***"
1768 DO ispin = nspins, 1, -1
1773 DEALLOCATE (g_surf_circular, g_surf_linear, g_surf_nonequiv)
1778 DO image = 1, nimages
1779 DO ispin = 1, nspins
1780 CALL dbcsr_copy(matrix_b=matrix_ks_qs_kp(ispin, image)%matrix, matrix_a=matrix_ks_initial_kp(ispin, image)%matrix)
1781 CALL dbcsr_copy(matrix_b=rho_ao_qs_kp(ispin, image)%matrix, matrix_a=rho_ao_initial_kp(ispin, image)%matrix)
1788 DEALLOCATE (matrix_ks_initial_kp, rho_ao_new_kp, rho_ao_initial_kp)
1790 IF (sub_env%ngroups > 1 .AND.
ASSOCIATED(matrix_s_fm))
THEN
1792 DEALLOCATE (matrix_s_fm)
1795 CALL timestop(handle)
1796 END SUBROUTINE converge_density
1813 SUBROUTINE negf_surface_green_function_batch(g_surf, omega, h0, s0, h1, s1, sub_env, v_external, conv, transp)
1814 TYPE(
cp_cfm_type),
DIMENSION(:),
INTENT(inout) :: g_surf
1815 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(in) :: omega
1816 TYPE(
cp_fm_type),
INTENT(IN) :: h0, s0, h1, s1
1818 REAL(kind=
dp),
INTENT(in) :: v_external, conv
1819 LOGICAL,
INTENT(in) :: transp
1821 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_surface_green_function_batch'
1824 INTEGER :: handle, igroup, ipoint, npoints
1828 CALL timeset(routinen, handle)
1829 npoints =
SIZE(omega)
1834 igroup = sub_env%group_distribution(sub_env%mepos_global)
1836 g_surf(1:npoints) = cfm_null
1838 DO ipoint = igroup + 1, npoints, sub_env%ngroups
1839 IF (debug_this_module)
THEN
1840 cpassert(.NOT.
ASSOCIATED(g_surf(ipoint)%matrix_struct))
1844 CALL do_sancho(g_surf(ipoint), omega(ipoint) + v_external, &
1845 h0, s0, h1, s1, conv, transp, work)
1849 CALL timestop(handle)
1850 END SUBROUTINE negf_surface_green_function_batch
1882 SUBROUTINE negf_retarded_green_function_batch(omega, v_shift, ignore_bias, negf_env, negf_control, sub_env, ispin, &
1884 g_ret_s, g_ret_scale, gamma_contacts, gret_gamma_gadv, dos, &
1885 transm_coeff, transm_contact1, transm_contact2, just_contact)
1886 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(in) :: omega
1887 REAL(kind=
dp),
INTENT(in) :: v_shift
1888 LOGICAL,
INTENT(in) :: ignore_bias
1892 INTEGER,
INTENT(in) :: ispin
1893 TYPE(
cp_cfm_type),
DIMENSION(:, :),
INTENT(in) :: g_surf_contacts
1896 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(in), &
1897 OPTIONAL :: g_ret_scale
1899 OPTIONAL :: gamma_contacts, gret_gamma_gadv
1900 REAL(kind=
dp),
DIMENSION(:),
INTENT(out),
OPTIONAL :: dos
1901 COMPLEX(kind=dp),
DIMENSION(:),
INTENT(out), &
1902 OPTIONAL :: transm_coeff
1903 INTEGER,
INTENT(in),
OPTIONAL :: transm_contact1, transm_contact2, &
1906 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_retarded_green_function_batch'
1908 INTEGER :: handle, icontact, igroup, ipoint, &
1909 ncontacts, npoints, nrows
1910 REAL(kind=
dp) :: v_external
1912 DIMENSION(:) :: info1
1914 DIMENSION(:, :) :: info2
1915 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: g_ret_s_group, self_energy_contacts, &
1916 zwork1_contacts, zwork2_contacts
1917 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:, :) :: gamma_contacts_group, &
1918 gret_gamma_gadv_group
1924 CALL timeset(routinen, handle)
1925 npoints =
SIZE(omega)
1926 ncontacts =
SIZE(negf_env%contacts)
1927 cpassert(
SIZE(negf_control%contacts) == ncontacts)
1929 IF (
PRESENT(just_contact))
THEN
1930 cpassert(just_contact <= ncontacts)
1934 cpassert(ncontacts >= 2)
1936 IF (ignore_bias) v_external = 0.0_dp
1938 IF (
PRESENT(transm_coeff) .OR.
PRESENT(transm_contact1) .OR.
PRESENT(transm_contact2))
THEN
1939 cpassert(
PRESENT(transm_coeff))
1940 cpassert(
PRESENT(transm_contact1))
1941 cpassert(
PRESENT(transm_contact2))
1942 cpassert(.NOT.
PRESENT(just_contact))
1945 ALLOCATE (self_energy_contacts(ncontacts), zwork1_contacts(ncontacts), zwork2_contacts(ncontacts))
1947 IF (
PRESENT(just_contact))
THEN
1948 CALL cp_fm_get_info(negf_env%contacts(just_contact)%s_01, matrix_struct=fm_struct)
1949 DO icontact = 1, ncontacts
1954 CALL cp_fm_get_info(negf_env%contacts(just_contact)%s_00, nrow_global=nrows, matrix_struct=fm_struct)
1955 DO icontact = 1, ncontacts
1956 CALL cp_cfm_create(self_energy_contacts(icontact), fm_struct)
1959 DO icontact = 1, ncontacts
1960 CALL cp_fm_get_info(negf_env%s_sc(icontact), matrix_struct=fm_struct)
1965 CALL cp_fm_get_info(negf_env%s_s, nrow_global=nrows, matrix_struct=fm_struct)
1966 DO icontact = 1, ncontacts
1967 CALL cp_cfm_create(self_energy_contacts(icontact), fm_struct)
1971 IF (
PRESENT(g_ret_s) .OR.
PRESENT(gret_gamma_gadv) .OR. &
1972 PRESENT(dos) .OR.
PRESENT(transm_coeff))
THEN
1973 ALLOCATE (g_ret_s_group(npoints))
1975 IF (sub_env%ngroups <= 1 .AND.
PRESENT(g_ret_s))
THEN
1976 g_ret_s_group(1:npoints) = g_ret_s(1:npoints)
1980 IF (
PRESENT(gamma_contacts) .OR.
PRESENT(gret_gamma_gadv) .OR.
PRESENT(transm_coeff))
THEN
1981 IF (debug_this_module .AND.
PRESENT(gamma_contacts))
THEN
1982 cpassert(
SIZE(gamma_contacts, 1) == ncontacts)
1985 ALLOCATE (gamma_contacts_group(ncontacts, npoints))
1986 IF (sub_env%ngroups <= 1 .AND.
PRESENT(gamma_contacts))
THEN
1987 gamma_contacts_group(1:ncontacts, 1:npoints) = gamma_contacts(1:ncontacts, 1:npoints)
1991 IF (
PRESENT(gret_gamma_gadv))
THEN
1992 IF (debug_this_module .AND.
PRESENT(gret_gamma_gadv))
THEN
1993 cpassert(
SIZE(gret_gamma_gadv, 1) == ncontacts)
1996 ALLOCATE (gret_gamma_gadv_group(ncontacts, npoints))
1997 IF (sub_env%ngroups <= 1)
THEN
1998 gret_gamma_gadv_group(1:ncontacts, 1:npoints) = gret_gamma_gadv(1:ncontacts, 1:npoints)
2002 igroup = sub_env%group_distribution(sub_env%mepos_global)
2004 DO ipoint = 1, npoints
2005 IF (
ASSOCIATED(g_surf_contacts(1, ipoint)%matrix_struct))
THEN
2006 IF (sub_env%ngroups > 1 .OR. .NOT.
PRESENT(g_ret_s))
THEN
2010 IF (
ALLOCATED(g_ret_s_group))
THEN
2015 IF (sub_env%ngroups > 1 .OR. .NOT.
PRESENT(gamma_contacts))
THEN
2016 IF (
ALLOCATED(gamma_contacts_group))
THEN
2017 DO icontact = 1, ncontacts
2018 CALL cp_cfm_create(gamma_contacts_group(icontact, ipoint), fm_struct)
2023 IF (sub_env%ngroups > 1)
THEN
2024 IF (
ALLOCATED(gret_gamma_gadv_group))
THEN
2025 DO icontact = 1, ncontacts
2026 IF (
ASSOCIATED(gret_gamma_gadv(icontact, ipoint)%matrix_struct))
THEN
2027 CALL cp_cfm_create(gret_gamma_gadv_group(icontact, ipoint), fm_struct)
2033 IF (
PRESENT(just_contact))
THEN
2035 DO icontact = 1, ncontacts
2037 omega=omega(ipoint), &
2038 g_surf_c=g_surf_contacts(icontact, ipoint), &
2039 h_sc0=negf_env%contacts(just_contact)%h_01(ispin), &
2040 s_sc0=negf_env%contacts(just_contact)%s_01, &
2041 zwork1=zwork1_contacts(icontact), &
2042 zwork2=zwork2_contacts(icontact), &
2043 transp=(icontact == 1))
2047 DO icontact = 1, ncontacts
2048 IF (.NOT. ignore_bias) v_external = negf_control%contacts(icontact)%v_external
2051 omega=omega(ipoint) + v_external, &
2052 g_surf_c=g_surf_contacts(icontact, ipoint), &
2053 h_sc0=negf_env%h_sc(ispin, icontact), &
2054 s_sc0=negf_env%s_sc(icontact), &
2055 zwork1=zwork1_contacts(icontact), &
2056 zwork2=zwork2_contacts(icontact), &
2062 IF (
ALLOCATED(gamma_contacts_group))
THEN
2063 DO icontact = 1, ncontacts
2065 self_energy_c=self_energy_contacts(icontact))
2069 IF (
ALLOCATED(g_ret_s_group))
THEN
2071 DO icontact = 2, ncontacts
2076 IF (
PRESENT(just_contact))
THEN
2078 omega=omega(ipoint) - v_shift, &
2079 self_energy_ret_sum=self_energy_contacts(1), &
2080 h_s=negf_env%contacts(just_contact)%h_00(ispin), &
2081 s_s=negf_env%contacts(just_contact)%s_00)
2082 ELSE IF (ignore_bias)
THEN
2084 omega=omega(ipoint) - v_shift, &
2085 self_energy_ret_sum=self_energy_contacts(1), &
2086 h_s=negf_env%h_s(ispin), &
2090 omega=omega(ipoint) - v_shift, &
2091 self_energy_ret_sum=self_energy_contacts(1), &
2092 h_s=negf_env%h_s(ispin), &
2094 v_hartree_s=negf_env%v_hartree_s)
2097 IF (
PRESENT(g_ret_scale))
THEN
2098 IF (g_ret_scale(ipoint) /=
z_one)
CALL cp_cfm_scale(g_ret_scale(ipoint), g_ret_s_group(ipoint))
2102 IF (
ALLOCATED(gret_gamma_gadv_group))
THEN
2105 DO icontact = 1, ncontacts
2106 IF (
ASSOCIATED(gret_gamma_gadv_group(icontact, ipoint)%matrix_struct))
THEN
2108 z_one, gamma_contacts_group(icontact, ipoint), &
2109 g_ret_s_group(ipoint), &
2110 z_zero, self_energy_contacts(icontact))
2112 z_one, g_ret_s_group(ipoint), &
2113 self_energy_contacts(icontact), &
2114 z_zero, gret_gamma_gadv_group(icontact, ipoint))
2122 IF (
PRESENT(g_ret_s))
THEN
2123 IF (sub_env%ngroups > 1)
THEN
2125 DO ipoint = 1, npoints
2126 IF (
ASSOCIATED(g_ret_s(ipoint)%matrix_struct))
THEN
2132 IF (
ASSOCIATED(para_env))
THEN
2133 ALLOCATE (info1(npoints))
2135 DO ipoint = 1, npoints
2138 para_env, info1(ipoint))
2141 DO ipoint = 1, npoints
2142 IF (
ASSOCIATED(g_ret_s(ipoint)%matrix_struct))
THEN
2144 IF (
ASSOCIATED(g_ret_s_group(ipoint)%matrix_struct))
THEN
2155 IF (
PRESENT(gamma_contacts))
THEN
2156 IF (sub_env%ngroups > 1)
THEN
2158 pnt1:
DO ipoint = 1, npoints
2159 DO icontact = 1, ncontacts
2160 IF (
ASSOCIATED(gamma_contacts(icontact, ipoint)%matrix_struct))
THEN
2161 CALL cp_cfm_get_info(gamma_contacts(icontact, ipoint), para_env=para_env)
2167 IF (
ASSOCIATED(para_env))
THEN
2168 ALLOCATE (info2(ncontacts, npoints))
2170 DO ipoint = 1, npoints
2171 DO icontact = 1, ncontacts
2173 gamma_contacts(icontact, ipoint), &
2174 para_env, info2(icontact, ipoint))
2178 DO ipoint = 1, npoints
2179 DO icontact = 1, ncontacts
2180 IF (
ASSOCIATED(gamma_contacts(icontact, ipoint)%matrix_struct))
THEN
2182 IF (
ASSOCIATED(gamma_contacts_group(icontact, ipoint)%matrix_struct))
THEN
2194 IF (
PRESENT(gret_gamma_gadv))
THEN
2195 IF (sub_env%ngroups > 1)
THEN
2197 pnt2:
DO ipoint = 1, npoints
2198 DO icontact = 1, ncontacts
2199 IF (
ASSOCIATED(gret_gamma_gadv(icontact, ipoint)%matrix_struct))
THEN
2200 CALL cp_cfm_get_info(gret_gamma_gadv(icontact, ipoint), para_env=para_env)
2206 IF (
ASSOCIATED(para_env))
THEN
2207 ALLOCATE (info2(ncontacts, npoints))
2209 DO ipoint = 1, npoints
2210 DO icontact = 1, ncontacts
2212 gret_gamma_gadv(icontact, ipoint), &
2213 para_env, info2(icontact, ipoint))
2217 DO ipoint = 1, npoints
2218 DO icontact = 1, ncontacts
2219 IF (
ASSOCIATED(gret_gamma_gadv(icontact, ipoint)%matrix_struct))
THEN
2221 IF (
ASSOCIATED(gret_gamma_gadv_group(icontact, ipoint)%matrix_struct))
THEN
2233 IF (
PRESENT(dos))
THEN
2236 IF (
PRESENT(just_contact))
THEN
2237 matrix_s => negf_env%contacts(just_contact)%s_00
2239 matrix_s => negf_env%s_s
2245 DO ipoint = 1, npoints
2246 IF (
ASSOCIATED(g_ret_s_group(ipoint)%matrix_struct))
THEN
2247 CALL cp_cfm_to_fm(g_ret_s_group(ipoint), mtargeti=g_ret_imag)
2248 CALL cp_fm_trace(g_ret_imag, matrix_s, dos(ipoint))
2249 IF (sub_env%para_env%mepos /= 0) dos(ipoint) = 0.0_dp
2255 CALL sub_env%mpi_comm_global%sum(dos)
2256 dos(:) = -1.0_dp/
pi*dos(:)
2259 IF (
PRESENT(transm_coeff))
THEN
2262 DO ipoint = 1, npoints
2263 IF (
ASSOCIATED(g_ret_s_group(ipoint)%matrix_struct))
THEN
2266 z_one, gamma_contacts_group(transm_contact1, ipoint), &
2267 g_ret_s_group(ipoint), &
2268 z_zero, self_energy_contacts(transm_contact1))
2270 z_one, self_energy_contacts(transm_contact1), &
2271 gamma_contacts_group(transm_contact2, ipoint), &
2272 z_zero, self_energy_contacts(transm_contact2))
2276 self_energy_contacts(transm_contact2), &
2277 transm_coeff(ipoint))
2278 IF (sub_env%para_env%mepos /= 0) transm_coeff(ipoint) = 0.0_dp
2283 CALL sub_env%mpi_comm_global%sum(transm_coeff)
2288 IF (
ALLOCATED(g_ret_s_group))
THEN
2289 DO ipoint = npoints, 1, -1
2290 IF (sub_env%ngroups > 1 .OR. .NOT.
PRESENT(g_ret_s))
THEN
2294 DEALLOCATE (g_ret_s_group)
2297 IF (
ALLOCATED(gamma_contacts_group))
THEN
2298 DO ipoint = npoints, 1, -1
2299 DO icontact = ncontacts, 1, -1
2300 IF (sub_env%ngroups > 1 .OR. .NOT.
PRESENT(gamma_contacts))
THEN
2305 DEALLOCATE (gamma_contacts_group)
2308 IF (
ALLOCATED(gret_gamma_gadv_group))
THEN
2309 DO ipoint = npoints, 1, -1
2310 DO icontact = ncontacts, 1, -1
2311 IF (sub_env%ngroups > 1)
THEN
2316 DEALLOCATE (gret_gamma_gadv_group)
2319 IF (
ALLOCATED(self_energy_contacts))
THEN
2320 DO icontact = ncontacts, 1, -1
2323 DEALLOCATE (self_energy_contacts)
2326 IF (
ALLOCATED(zwork1_contacts))
THEN
2327 DO icontact = ncontacts, 1, -1
2330 DEALLOCATE (zwork1_contacts)
2333 IF (
ALLOCATED(zwork2_contacts))
THEN
2334 DO icontact = ncontacts, 1, -1
2337 DEALLOCATE (zwork2_contacts)
2340 CALL timestop(handle)
2341 END SUBROUTINE negf_retarded_green_function_batch
2351 PURE FUNCTION fermi_function(omega, temperature)
RESULT(val)
2352 COMPLEX(kind=dp),
INTENT(in) :: omega
2353 REAL(kind=
dp),
INTENT(in) :: temperature
2354 COMPLEX(kind=dp) :: val
2356 REAL(kind=
dp),
PARAMETER :: max_ln_omega_over_t = log(huge(0.0_dp))/16.0_dp
2358 IF (real(omega, kind=
dp) <= temperature*max_ln_omega_over_t)
THEN
2364 END FUNCTION fermi_function
2379 SUBROUTINE negf_init_rho_equiv_residuals(rho_ao_fm, v_shift, ignore_bias, negf_env, &
2380 negf_control, sub_env, ispin, base_contact, just_contact)
2382 REAL(kind=
dp),
INTENT(in) :: v_shift
2383 LOGICAL,
INTENT(in) :: ignore_bias
2387 INTEGER,
INTENT(in) :: ispin, base_contact
2388 INTEGER,
INTENT(in),
OPTIONAL :: just_contact
2390 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_init_rho_equiv_residuals'
2392 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: omega
2393 INTEGER :: handle, icontact, ipole, ncontacts, &
2395 REAL(kind=
dp) :: mu_base, pi_temperature, temperature, &
2397 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: g_ret_s
2402 CALL timeset(routinen, handle)
2404 temperature = negf_control%contacts(base_contact)%temperature
2405 IF (ignore_bias)
THEN
2406 mu_base = negf_control%contacts(base_contact)%fermi_level
2409 mu_base = negf_control%contacts(base_contact)%fermi_level - negf_control%contacts(base_contact)%v_external
2412 pi_temperature =
pi*temperature
2413 npoles = negf_control%delta_npoles
2415 ncontacts =
SIZE(negf_env%contacts)
2416 cpassert(base_contact <= ncontacts)
2417 IF (
PRESENT(just_contact))
THEN
2419 cpassert(just_contact == base_contact)
2422 IF (npoles > 0)
THEN
2423 CALL cp_fm_get_info(rho_ao_fm, para_env=para_env, matrix_struct=fm_struct)
2425 ALLOCATE (omega(npoles), g_ret_s(npoles))
2427 DO ipole = 1, npoles
2430 omega(ipole) = cmplx(mu_base, real(2*ipole - 1, kind=
dp)*pi_temperature, kind=
dp)
2435 IF (
PRESENT(just_contact))
THEN
2440 DO icontact = 1, ncontacts
2441 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
2443 h0=negf_env%contacts(just_contact)%h_00(ispin), &
2444 s0=negf_env%contacts(just_contact)%s_00, &
2445 h1=negf_env%contacts(just_contact)%h_01(ispin), &
2446 s1=negf_env%contacts(just_contact)%s_01, &
2447 sub_env=sub_env, v_external=0.0_dp, &
2448 conv=negf_control%conv_green, transp=(icontact == 1))
2451 DO icontact = 1, ncontacts
2452 IF (.NOT. ignore_bias) v_external = negf_control%contacts(icontact)%v_external
2454 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
2456 h0=negf_env%contacts(icontact)%h_00(ispin), &
2457 s0=negf_env%contacts(icontact)%s_00, &
2458 h1=negf_env%contacts(icontact)%h_01(ispin), &
2459 s1=negf_env%contacts(icontact)%s_01, &
2461 v_external=v_external, &
2462 conv=negf_control%conv_green, transp=.false.)
2466 CALL negf_retarded_green_function_batch(omega=omega(:), &
2468 ignore_bias=ignore_bias, &
2469 negf_env=negf_env, &
2470 negf_control=negf_control, &
2473 g_surf_contacts=g_surf_cache%g_surf_contacts, &
2475 just_contact=just_contact)
2479 DO ipole = 2, npoles
2487 DO ipole = npoles, 1, -1
2490 DEALLOCATE (g_ret_s, omega)
2493 CALL timestop(handle)
2494 END SUBROUTINE negf_init_rho_equiv_residuals
2515 SUBROUTINE negf_add_rho_equiv_low(rho_ao_fm, stats, v_shift, ignore_bias, negf_env, negf_control, sub_env, &
2516 ispin, base_contact, integr_lbound, integr_ubound, matrix_s_global, &
2517 is_circular, g_surf_cache, just_contact)
2519 TYPE(integration_status_type),
INTENT(inout) :: stats
2520 REAL(kind=
dp),
INTENT(in) :: v_shift
2521 LOGICAL,
INTENT(in) :: ignore_bias
2525 INTEGER,
INTENT(in) :: ispin, base_contact
2526 COMPLEX(kind=dp),
INTENT(in) :: integr_lbound, integr_ubound
2527 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_s_global
2528 LOGICAL,
INTENT(in) :: is_circular
2530 INTEGER,
INTENT(in),
OPTIONAL :: just_contact
2532 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_add_rho_equiv_low'
2534 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: xnodes, zscale
2535 INTEGER :: handle, icontact, interval_id, ipoint, max_points, min_points, ncontacts, &
2536 npoints, npoints_exist, npoints_tmp, npoints_total, shape_id
2537 LOGICAL :: do_surface_green
2538 REAL(kind=
dp) :: conv_integr, mu_base, temperature, &
2541 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: zdata, zdata_tmp
2547 CALL timeset(routinen, handle)
2551 conv_integr = 0.5_dp*negf_control%conv_density*
pi
2553 IF (ignore_bias)
THEN
2554 mu_base = negf_control%contacts(base_contact)%fermi_level
2557 mu_base = negf_control%contacts(base_contact)%fermi_level - negf_control%contacts(base_contact)%v_external
2560 min_points = negf_control%integr_min_points
2561 max_points = negf_control%integr_max_points
2562 temperature = negf_control%contacts(base_contact)%temperature
2564 ncontacts =
SIZE(negf_env%contacts)
2565 cpassert(base_contact <= ncontacts)
2566 IF (
PRESENT(just_contact))
THEN
2568 cpassert(just_contact == base_contact)
2571 do_surface_green = .NOT.
ALLOCATED(g_surf_cache%tnodes)
2573 IF (do_surface_green)
THEN
2574 npoints = min_points
2576 npoints =
SIZE(g_surf_cache%tnodes)
2580 CALL cp_fm_get_info(rho_ao_fm, para_env=para_env, matrix_struct=fm_struct)
2583 SELECT CASE (negf_control%integr_method)
2586 ALLOCATE (xnodes(npoints))
2588 IF (is_circular)
THEN
2596 IF (do_surface_green)
THEN
2597 CALL ccquad_init(cc_env, xnodes, npoints, integr_lbound, integr_ubound, &
2598 interval_id, shape_id, matrix_s_global)
2600 CALL ccquad_init(cc_env, xnodes, npoints, integr_lbound, integr_ubound, &
2601 interval_id, shape_id, matrix_s_global, tnodes_restart=g_surf_cache%tnodes)
2604 ALLOCATE (zdata(npoints))
2605 DO ipoint = 1, npoints
2610 IF (do_surface_green)
THEN
2613 IF (
PRESENT(just_contact))
THEN
2615 DO icontact = 1, ncontacts
2616 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, npoints_total + 1:), &
2617 omega=xnodes(1:npoints), &
2618 h0=negf_env%contacts(just_contact)%h_00(ispin), &
2619 s0=negf_env%contacts(just_contact)%s_00, &
2620 h1=negf_env%contacts(just_contact)%h_01(ispin), &
2621 s1=negf_env%contacts(just_contact)%s_01, &
2622 sub_env=sub_env, v_external=0.0_dp, &
2623 conv=negf_control%conv_green, transp=(icontact == 1))
2626 DO icontact = 1, ncontacts
2627 IF (.NOT. ignore_bias) v_external = negf_control%contacts(icontact)%v_external
2629 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, npoints_total + 1:), &
2630 omega=xnodes(1:npoints), &
2631 h0=negf_env%contacts(icontact)%h_00(ispin), &
2632 s0=negf_env%contacts(icontact)%s_00, &
2633 h1=negf_env%contacts(icontact)%h_01(ispin), &
2634 s1=negf_env%contacts(icontact)%s_01, &
2636 v_external=v_external, &
2637 conv=negf_control%conv_green, transp=.false.)
2642 ALLOCATE (zscale(npoints))
2644 IF (temperature >= 0.0_dp)
THEN
2645 DO ipoint = 1, npoints
2646 zscale(ipoint) = fermi_function(xnodes(ipoint) - mu_base, temperature)
2652 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints), &
2654 ignore_bias=ignore_bias, &
2655 negf_env=negf_env, &
2656 negf_control=negf_control, &
2659 g_surf_contacts=g_surf_cache%g_surf_contacts(:, npoints_total + 1:), &
2660 g_ret_s=zdata(1:npoints), &
2661 g_ret_scale=zscale(1:npoints), &
2662 just_contact=just_contact)
2664 DEALLOCATE (xnodes, zscale)
2665 npoints_total = npoints_total + npoints
2668 CALL move_alloc(zdata, zdata_tmp)
2672 IF (cc_env%error <= conv_integr)
EXIT
2673 IF (2*(npoints_total - 1) + 1 > max_points)
EXIT
2677 do_surface_green = .true.
2679 npoints_tmp = npoints
2681 npoints =
SIZE(xnodes)
2683 ALLOCATE (zdata(npoints))
2686 DO ipoint = 1, npoints_tmp
2687 IF (
ASSOCIATED(zdata_tmp(ipoint)%matrix_struct))
THEN
2688 npoints_exist = npoints_exist + 1
2689 zdata(npoints_exist) = zdata_tmp(ipoint)
2692 DEALLOCATE (zdata_tmp)
2694 DO ipoint = npoints_exist + 1, npoints
2700 stats%error = stats%error + cc_env%error/
pi
2702 DO ipoint =
SIZE(zdata_tmp), 1, -1
2705 DEALLOCATE (zdata_tmp)
2707 CALL cp_cfm_to_fm(cc_env%integral, mtargeti=integral_imag)
2710 IF (do_surface_green)
THEN
2717 ALLOCATE (xnodes(npoints), zdata(npoints), zscale(npoints))
2719 IF (is_circular)
THEN
2725 IF (do_surface_green)
THEN
2726 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2727 shape_id, conv_integr, matrix_s_global)
2729 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2730 shape_id, conv_integr, matrix_s_global, tnodes_restart=g_surf_cache%tnodes)
2733 DO WHILE (npoints > 0 .AND. npoints_total < max_points)
2734 DO ipoint = 1, npoints
2738 IF (do_surface_green)
THEN
2741 IF (
PRESENT(just_contact))
THEN
2743 DO icontact = 1, ncontacts
2744 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, npoints_total + 1:), &
2745 omega=xnodes(1:npoints), &
2746 h0=negf_env%contacts(just_contact)%h_00(ispin), &
2747 s0=negf_env%contacts(just_contact)%s_00, &
2748 h1=negf_env%contacts(just_contact)%h_01(ispin), &
2749 s1=negf_env%contacts(just_contact)%s_01, &
2750 sub_env=sub_env, v_external=0.0_dp, &
2751 conv=negf_control%conv_green, transp=(icontact == 1))
2754 DO icontact = 1, ncontacts
2755 IF (.NOT. ignore_bias) v_external = negf_control%contacts(icontact)%v_external
2757 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, npoints_total + 1:), &
2758 omega=xnodes(1:npoints), &
2759 h0=negf_env%contacts(icontact)%h_00(ispin), &
2760 s0=negf_env%contacts(icontact)%s_00, &
2761 h1=negf_env%contacts(icontact)%h_01(ispin), &
2762 s1=negf_env%contacts(icontact)%s_01, &
2764 v_external=v_external, &
2765 conv=negf_control%conv_green, transp=.false.)
2770 IF (temperature >= 0.0_dp)
THEN
2771 DO ipoint = 1, npoints
2772 zscale(ipoint) = fermi_function(xnodes(ipoint) - mu_base, temperature)
2778 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints), &
2780 ignore_bias=ignore_bias, &
2781 negf_env=negf_env, &
2782 negf_control=negf_control, &
2785 g_surf_contacts=g_surf_cache%g_surf_contacts(:, npoints_total + 1:), &
2786 g_ret_s=zdata(1:npoints), &
2787 g_ret_scale=zscale(1:npoints), &
2788 just_contact=just_contact)
2790 npoints_total = npoints_total + npoints
2794 IF (sr_env%error <= conv_integr)
EXIT
2799 do_surface_green = .true.
2801 npoints = max_points - npoints_total
2802 IF (npoints <= 0)
EXIT
2803 IF (npoints >
SIZE(xnodes)) npoints =
SIZE(xnodes)
2809 stats%error = stats%error + sr_env%error/
pi
2811 CALL cp_cfm_to_fm(sr_env%integral, mtargeti=integral_imag)
2814 IF (do_surface_green)
THEN
2819 DEALLOCATE (xnodes, zdata, zscale)
2822 cpabort(
"Unimplemented integration method")
2825 stats%npoints = stats%npoints + npoints_total
2830 CALL timestop(handle)
2831 END SUBROUTINE negf_add_rho_equiv_low
2847 SUBROUTINE negf_add_rho_nonequiv(rho_ao_fm, stats, v_shift, negf_env, negf_control, sub_env, &
2848 ispin, base_contact, matrix_s_global, g_surf_cache)
2850 TYPE(integration_status_type),
INTENT(inout) :: stats
2851 REAL(kind=
dp),
INTENT(in) :: v_shift
2855 INTEGER,
INTENT(in) :: ispin, base_contact
2856 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_s_global
2859 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_add_rho_nonequiv'
2861 COMPLEX(kind=dp) :: fermi_base, fermi_contact, &
2862 integr_lbound, integr_ubound
2863 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: xnodes
2864 INTEGER :: handle, icontact, ipoint, jcontact, &
2865 max_points, min_points, ncontacts, &
2866 npoints, npoints_total
2867 LOGICAL :: do_surface_green
2868 REAL(kind=
dp) :: conv_density, conv_integr, eta, &
2869 ln_conv_density, mu_base, mu_contact, &
2870 temperature_base, temperature_contact
2871 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:, :) :: zdata
2877 CALL timeset(routinen, handle)
2879 ncontacts =
SIZE(negf_env%contacts)
2880 cpassert(base_contact <= ncontacts)
2883 IF (ncontacts > 2)
THEN
2884 cpabort(
"Poisson solver does not support the general NEGF setup (>2 contacts).")
2887 mu_base = negf_control%contacts(base_contact)%fermi_level - negf_control%contacts(base_contact)%v_external
2888 min_points = negf_control%integr_min_points
2889 max_points = negf_control%integr_max_points
2890 temperature_base = negf_control%contacts(base_contact)%temperature
2891 eta = negf_control%eta
2892 conv_density = negf_control%conv_density
2893 ln_conv_density = log(conv_density)
2897 conv_integr = 0.5_dp*conv_density*
pi
2899 DO icontact = 1, ncontacts
2900 IF (icontact /= base_contact)
THEN
2901 mu_contact = negf_control%contacts(icontact)%fermi_level - negf_control%contacts(icontact)%v_external
2902 temperature_contact = negf_control%contacts(icontact)%temperature
2904 integr_lbound = cmplx(min(mu_base + ln_conv_density*temperature_base, &
2905 mu_contact + ln_conv_density*temperature_contact), eta, kind=
dp)
2906 integr_ubound = cmplx(max(mu_base - ln_conv_density*temperature_base, &
2907 mu_contact - ln_conv_density*temperature_contact), eta, kind=
dp)
2909 do_surface_green = .NOT.
ALLOCATED(g_surf_cache%tnodes)
2911 IF (do_surface_green)
THEN
2912 npoints = min_points
2914 npoints =
SIZE(g_surf_cache%tnodes)
2918 ALLOCATE (xnodes(npoints))
2919 CALL cp_fm_get_info(rho_ao_fm, para_env=para_env, matrix_struct=fm_struct)
2921 IF (do_surface_green)
THEN
2922 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2925 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
2926 sr_shape_linear, conv_integr, matrix_s_global, tnodes_restart=g_surf_cache%tnodes)
2929 DO WHILE (npoints > 0 .AND. npoints_total < max_points)
2931 IF (do_surface_green)
THEN
2934 DO jcontact = 1, ncontacts
2935 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(jcontact, npoints_total + 1:), &
2936 omega=xnodes(1:npoints), &
2937 h0=negf_env%contacts(jcontact)%h_00(ispin), &
2938 s0=negf_env%contacts(jcontact)%s_00, &
2939 h1=negf_env%contacts(jcontact)%h_01(ispin), &
2940 s1=negf_env%contacts(jcontact)%s_01, &
2942 v_external=negf_control%contacts(jcontact)%v_external, &
2943 conv=negf_control%conv_green, transp=.false.)
2947 ALLOCATE (zdata(ncontacts, npoints))
2949 DO ipoint = 1, npoints
2954 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints), &
2956 ignore_bias=.false., &
2957 negf_env=negf_env, &
2958 negf_control=negf_control, &
2961 g_surf_contacts=g_surf_cache%g_surf_contacts(:, npoints_total + 1:), &
2962 gret_gamma_gadv=zdata(:, 1:npoints))
2964 DO ipoint = 1, npoints
2965 fermi_base = fermi_function(cmplx(real(xnodes(ipoint), kind=
dp) - mu_base, 0.0_dp, kind=
dp), &
2967 fermi_contact = fermi_function(cmplx(real(xnodes(ipoint), kind=
dp) - mu_contact, 0.0_dp, kind=
dp), &
2968 temperature_contact)
2969 CALL cp_cfm_scale(fermi_contact - fermi_base, zdata(icontact, ipoint))
2972 npoints_total = npoints_total + npoints
2976 DO ipoint = 1, npoints
2982 IF (sr_env%error <= conv_integr)
EXIT
2985 do_surface_green = .true.
2987 npoints = max_points - npoints_total
2988 IF (npoints <= 0)
EXIT
2989 IF (npoints >
SIZE(xnodes)) npoints =
SIZE(xnodes)
2997 CALL cp_cfm_to_fm(sr_env%integral, mtargetr=integral_real)
3004 stats%error = stats%error + sr_env%error*0.5_dp/
pi
3005 stats%npoints = stats%npoints + npoints_total
3008 IF (do_surface_green)
THEN
3016 CALL timestop(handle)
3017 END SUBROUTINE negf_add_rho_nonequiv
3024 ELEMENTAL SUBROUTINE integration_status_reset(stats)
3025 TYPE(integration_status_type),
INTENT(out) :: stats
3028 stats%error = 0.0_dp
3029 END SUBROUTINE integration_status_reset
3038 ELEMENTAL FUNCTION get_method_description_string(stats, integration_method)
RESULT(method_descr)
3039 TYPE(integration_status_type),
INTENT(in) :: stats
3040 INTEGER,
INTENT(in) :: integration_method
3041 CHARACTER(len=18) :: method_descr
3043 CHARACTER(len=2) :: method_abbr
3044 CHARACTER(len=6) :: npoints_str
3046 SELECT CASE (integration_method)
3057 WRITE (npoints_str,
'(I6)') stats%npoints
3058 WRITE (method_descr,
'(A2,T4,A,T11,ES8.2E2)') method_abbr, trim(adjustl(npoints_str)), stats%error
3059 END FUNCTION get_method_description_string
3074 FUNCTION negf_compute_current(contact_id1, contact_id2, v_shift, negf_env, negf_control, sub_env, ispin, &
3075 blacs_env_global)
RESULT(current)
3076 INTEGER,
INTENT(in) :: contact_id1, contact_id2
3077 REAL(kind=
dp),
INTENT(in) :: v_shift
3081 INTEGER,
INTENT(in) :: ispin
3083 REAL(kind=
dp) :: current
3085 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_compute_current'
3086 REAL(kind=
dp),
PARAMETER :: threshold = 16.0_dp*epsilon(0.0_dp)
3088 COMPLEX(kind=dp) :: fermi_contact1, fermi_contact2, &
3089 integr_lbound, integr_ubound
3090 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: transm_coeff, xnodes
3091 COMPLEX(kind=dp),
DIMENSION(1, 1) :: transmission
3092 INTEGER :: handle, icontact, ipoint, max_points, &
3093 min_points, ncontacts, npoints, &
3095 REAL(kind=
dp) :: conv_density, energy, eta, ln_conv_density, mu_contact1, mu_contact2, &
3096 temperature_contact1, temperature_contact2, v_contact1, v_contact2
3097 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: zdata
3105 IF (.NOT.
ASSOCIATED(negf_env%s_s))
RETURN
3107 CALL timeset(routinen, handle)
3109 ncontacts =
SIZE(negf_env%contacts)
3110 cpassert(contact_id1 <= ncontacts)
3111 cpassert(contact_id2 <= ncontacts)
3112 cpassert(contact_id1 /= contact_id2)
3114 v_contact1 = negf_control%contacts(contact_id1)%v_external
3115 mu_contact1 = negf_control%contacts(contact_id1)%fermi_level - v_contact1
3116 v_contact2 = negf_control%contacts(contact_id2)%v_external
3117 mu_contact2 = negf_control%contacts(contact_id2)%fermi_level - v_contact2
3119 IF (abs(mu_contact1 - mu_contact2) < threshold)
THEN
3120 CALL timestop(handle)
3124 min_points = negf_control%integr_min_points
3125 max_points = negf_control%integr_max_points
3126 temperature_contact1 = negf_control%contacts(contact_id1)%temperature
3127 temperature_contact2 = negf_control%contacts(contact_id2)%temperature
3128 eta = negf_control%eta
3129 conv_density = negf_control%conv_density
3130 ln_conv_density = log(conv_density)
3132 integr_lbound = cmplx(min(mu_contact1 + ln_conv_density*temperature_contact1, &
3133 mu_contact2 + ln_conv_density*temperature_contact2), eta, kind=
dp)
3134 integr_ubound = cmplx(max(mu_contact1 - ln_conv_density*temperature_contact1, &
3135 mu_contact2 - ln_conv_density*temperature_contact2), eta, kind=
dp)
3138 npoints = min_points
3140 NULLIFY (fm_struct_single)
3141 CALL cp_fm_struct_create(fm_struct_single, nrow_global=1, ncol_global=1, context=blacs_env_global)
3145 ALLOCATE (transm_coeff(npoints), xnodes(npoints), zdata(npoints))
3147 CALL simpsonrule_init(sr_env, xnodes, npoints, integr_lbound, integr_ubound, &
3150 DO WHILE (npoints > 0 .AND. npoints_total < max_points)
3153 DO icontact = 1, ncontacts
3154 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, 1:npoints), &
3155 omega=xnodes(1:npoints), &
3156 h0=negf_env%contacts(icontact)%h_00(ispin), &
3157 s0=negf_env%contacts(icontact)%s_00, &
3158 h1=negf_env%contacts(icontact)%h_01(ispin), &
3159 s1=negf_env%contacts(icontact)%s_01, &
3161 v_external=negf_control%contacts(icontact)%v_external, &
3162 conv=negf_control%conv_green, transp=.false.)
3165 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints), &
3167 ignore_bias=.false., &
3168 negf_env=negf_env, &
3169 negf_control=negf_control, &
3172 g_surf_contacts=g_surf_cache%g_surf_contacts(:, 1:npoints), &
3173 transm_coeff=transm_coeff(1:npoints), &
3174 transm_contact1=contact_id1, &
3175 transm_contact2=contact_id2)
3177 DO ipoint = 1, npoints
3180 energy = real(xnodes(ipoint), kind=
dp)
3181 fermi_contact1 = fermi_function(cmplx(energy - mu_contact1, 0.0_dp, kind=
dp), temperature_contact1)
3182 fermi_contact2 = fermi_function(cmplx(energy - mu_contact2, 0.0_dp, kind=
dp), temperature_contact2)
3184 transmission(1, 1) = transm_coeff(ipoint)*(fermi_contact1 - fermi_contact2)
3190 npoints_total = npoints_total + npoints
3194 IF (sr_env%error <= negf_control%conv_density)
EXIT
3196 npoints = max_points - npoints_total
3197 IF (npoints <= 0)
EXIT
3198 IF (npoints >
SIZE(xnodes)) npoints =
SIZE(xnodes)
3211 DEALLOCATE (transm_coeff, xnodes, zdata)
3213 CALL timestop(handle)
3214 END FUNCTION negf_compute_current
3231 SUBROUTINE negf_print_dos(log_unit, energy_min, energy_max, npoints, v_shift, negf_env, &
3232 negf_control, sub_env, base_contact, just_contact, volume)
3233 INTEGER,
INTENT(in) :: log_unit
3234 REAL(kind=
dp),
INTENT(in) :: energy_min, energy_max
3235 INTEGER,
INTENT(in) :: npoints
3236 REAL(kind=
dp),
INTENT(in) :: v_shift
3240 INTEGER,
INTENT(in) :: base_contact
3241 INTEGER,
INTENT(in),
OPTIONAL :: just_contact
3242 REAL(kind=
dp),
INTENT(in),
OPTIONAL :: volume
3244 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_print_dos'
3246 CHARACTER :: uks_str
3247 CHARACTER(len=15) :: units_str
3248 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: xnodes
3249 INTEGER :: handle, icontact, ipoint, ispin, &
3250 ncontacts, npoints_bundle, &
3251 npoints_remain, nspins
3252 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: dos
3255 CALL timeset(routinen, handle)
3257 IF (
PRESENT(just_contact))
THEN
3258 nspins =
SIZE(negf_env%contacts(just_contact)%h_00)
3260 nspins =
SIZE(negf_env%h_s)
3263 IF (log_unit > 0)
THEN
3264 IF (
PRESENT(volume))
THEN
3265 units_str =
' (angstroms^-3)'
3270 IF (nspins > 1)
THEN
3278 IF (
PRESENT(just_contact))
THEN
3279 WRITE (log_unit,
'(3A,T70,I11)')
"# Density of states", trim(units_str),
" for the contact No. ", just_contact
3281 WRITE (log_unit,
'(3A)')
"# Density of states", trim(units_str),
" for the scattering region"
3284 WRITE (log_unit,
'(A,T10,A,T43,3A)')
"#",
"Energy (a.u.)",
"Number of states [alpha ", uks_str,
" beta]"
3286 WRITE (log_unit,
'("#", T3,78("-"))')
3289 ncontacts =
SIZE(negf_env%contacts)
3290 cpassert(base_contact <= ncontacts)
3291 IF (
PRESENT(just_contact))
THEN
3293 cpassert(just_contact == base_contact)
3295 mark_used(base_contact)
3297 npoints_bundle = 4*sub_env%ngroups
3298 IF (npoints_bundle > npoints) npoints_bundle = npoints
3300 ALLOCATE (dos(npoints_bundle, nspins), xnodes(npoints_bundle))
3302 npoints_remain = npoints
3303 DO WHILE (npoints_remain > 0)
3304 IF (npoints_bundle > npoints_remain) npoints_bundle = npoints_remain
3306 IF (npoints > 1)
THEN
3307 DO ipoint = 1, npoints_bundle
3308 xnodes(ipoint) = cmplx(energy_min + real(npoints - npoints_remain + ipoint - 1, kind=
dp)/ &
3309 REAL(npoints - 1, kind=
dp)*(energy_max - energy_min), negf_control%eta, kind=
dp)
3312 xnodes(ipoint) = cmplx(energy_min, negf_control%eta, kind=
dp)
3315 DO ispin = 1, nspins
3318 IF (
PRESENT(just_contact))
THEN
3319 DO icontact = 1, ncontacts
3320 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
3321 omega=xnodes(1:npoints_bundle), &
3322 h0=negf_env%contacts(just_contact)%h_00(ispin), &
3323 s0=negf_env%contacts(just_contact)%s_00, &
3324 h1=negf_env%contacts(just_contact)%h_01(ispin), &
3325 s1=negf_env%contacts(just_contact)%s_01, &
3326 sub_env=sub_env, v_external=0.0_dp, &
3327 conv=negf_control%conv_green, transp=(icontact == 1))
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(icontact)%h_00(ispin), &
3334 s0=negf_env%contacts(icontact)%s_00, &
3335 h1=negf_env%contacts(icontact)%h_01(ispin), &
3336 s1=negf_env%contacts(icontact)%s_01, &
3338 v_external=negf_control%contacts(icontact)%v_external, &
3339 conv=negf_control%conv_green, transp=.false.)
3343 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints_bundle), &
3345 ignore_bias=.false., &
3346 negf_env=negf_env, &
3347 negf_control=negf_control, &
3350 g_surf_contacts=g_surf_cache%g_surf_contacts, &
3351 dos=dos(1:npoints_bundle, ispin), &
3352 just_contact=just_contact)
3357 IF (log_unit > 0)
THEN
3358 DO ipoint = 1, npoints_bundle
3359 IF (nspins > 1)
THEN
3361 WRITE (log_unit,
'(T2,F20.8,T30,2ES25.11E3)') real(xnodes(ipoint), kind=
dp), dos(ipoint, 1), dos(ipoint, 2)
3364 WRITE (log_unit,
'(T2,F20.8,T43,ES25.11E3)') real(xnodes(ipoint), kind=
dp), 2.0_dp*dos(ipoint, 1)
3369 npoints_remain = npoints_remain - npoints_bundle
3372 DEALLOCATE (dos, xnodes)
3373 CALL timestop(handle)
3374 END SUBROUTINE negf_print_dos
3390 SUBROUTINE negf_print_transmission(log_unit, energy_min, energy_max, npoints, v_shift, negf_env, &
3391 negf_control, sub_env, contact_id1, contact_id2)
3392 INTEGER,
INTENT(in) :: log_unit
3393 REAL(kind=
dp),
INTENT(in) :: energy_min, energy_max
3394 INTEGER,
INTENT(in) :: npoints
3395 REAL(kind=
dp),
INTENT(in) :: v_shift
3399 INTEGER,
INTENT(in) :: contact_id1, contact_id2
3401 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_print_transmission'
3403 CHARACTER :: uks_str
3404 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: xnodes
3405 COMPLEX(kind=dp),
ALLOCATABLE,
DIMENSION(:, :) :: transm_coeff
3406 INTEGER :: handle, icontact, ipoint, ispin, &
3407 ncontacts, npoints_bundle, &
3408 npoints_remain, nspins
3409 REAL(kind=
dp) :: rscale
3412 CALL timeset(routinen, handle)
3414 nspins =
SIZE(negf_env%h_s)
3416 IF (nspins > 1)
THEN
3424 IF (log_unit > 0)
THEN
3425 WRITE (log_unit,
'(A)')
"# Transmission coefficient (G0 = 2 e^2/h) for the scattering region"
3427 WRITE (log_unit,
'(A,T10,A,T39,3A)')
"#",
"Energy (a.u.)",
"Transmission coefficient [alpha ", uks_str,
" beta]"
3428 WRITE (log_unit,
'("#", T3,78("-"))')
3431 ncontacts =
SIZE(negf_env%contacts)
3432 cpassert(contact_id1 <= ncontacts)
3433 cpassert(contact_id2 <= ncontacts)
3435 IF (nspins == 1)
THEN
3443 rscale = 0.5_dp*rscale
3445 npoints_bundle = 4*sub_env%ngroups
3446 IF (npoints_bundle > npoints) npoints_bundle = npoints
3448 ALLOCATE (transm_coeff(npoints_bundle, nspins), xnodes(npoints_bundle))
3450 npoints_remain = npoints
3451 DO WHILE (npoints_remain > 0)
3452 IF (npoints_bundle > npoints_remain) npoints_bundle = npoints_remain
3454 IF (npoints > 1)
THEN
3455 DO ipoint = 1, npoints_bundle
3456 xnodes(ipoint) = cmplx(energy_min + real(npoints - npoints_remain + ipoint - 1, kind=
dp)/ &
3457 REAL(npoints - 1, kind=
dp)*(energy_max - energy_min), negf_control%eta, kind=
dp)
3460 xnodes(ipoint) = cmplx(energy_min, negf_control%eta, kind=
dp)
3463 DO ispin = 1, nspins
3466 DO icontact = 1, ncontacts
3467 CALL negf_surface_green_function_batch(g_surf=g_surf_cache%g_surf_contacts(icontact, :), &
3468 omega=xnodes(1:npoints_bundle), &
3469 h0=negf_env%contacts(icontact)%h_00(ispin), &
3470 s0=negf_env%contacts(icontact)%s_00, &
3471 h1=negf_env%contacts(icontact)%h_01(ispin), &
3472 s1=negf_env%contacts(icontact)%s_01, &
3474 v_external=negf_control%contacts(icontact)%v_external, &
3475 conv=negf_control%conv_green, transp=.false.)
3478 CALL negf_retarded_green_function_batch(omega=xnodes(1:npoints_bundle), &
3480 ignore_bias=.false., &
3481 negf_env=negf_env, &
3482 negf_control=negf_control, &
3485 g_surf_contacts=g_surf_cache%g_surf_contacts, &
3486 transm_coeff=transm_coeff(1:npoints_bundle, ispin), &
3487 transm_contact1=contact_id1, &
3488 transm_contact2=contact_id2)
3493 IF (log_unit > 0)
THEN
3494 DO ipoint = 1, npoints_bundle
3495 IF (nspins > 1)
THEN
3497 WRITE (log_unit,
'(T2,F20.8,T30,2ES25.11E3)') &
3498 REAL(xnodes(ipoint), kind=
dp), rscale*real(transm_coeff(ipoint, 1:2), kind=
dp)
3501 WRITE (log_unit,
'(T2,F20.8,T43,ES25.11E3)') &
3502 REAL(xnodes(ipoint), kind=
dp), rscale*real(transm_coeff(ipoint, 1), kind=
dp)
3507 npoints_remain = npoints_remain - npoints_bundle
3510 DEALLOCATE (transm_coeff, xnodes)
3511 CALL timestop(handle)
3512 END SUBROUTINE negf_print_transmission
3526 SUBROUTINE negf_output_initial(log_unit, negf_env, sub_env, negf_control, dft_control, verbose_output, &
3528 INTEGER,
INTENT(in) :: log_unit
3533 LOGICAL,
INTENT(in) :: verbose_output, debug_output
3535 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_output_initial'
3537 CHARACTER(len=100) :: sfmt
3538 INTEGER :: handle, i, icontact, j, k, n, nrow
3539 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: target_m
3541 CALL timeset(routinen, handle)
3544 DO icontact = 1,
SIZE(negf_control%contacts)
3545 IF (log_unit > 0)
THEN
3546 WRITE (log_unit,
"(/,' The electrode',I5)") icontact
3547 WRITE (log_unit,
"( ' ------------------')")
3548 WRITE (log_unit,
"(' From the force environment:',I16)") negf_control%contacts(icontact)%force_env_index
3549 WRITE (log_unit,
"(' Number of atoms:',I27)")
SIZE(negf_control%contacts(icontact)%atomlist_bulk)
3550 IF (verbose_output)
WRITE (log_unit,
"(' Atoms belonging to a contact (from the entire system):')")
3551 IF (verbose_output)
WRITE (log_unit,
"(16I5)") negf_control%contacts(icontact)%atomlist_bulk
3552 WRITE (log_unit,
"(' Number of atoms in a primary unit cell:',I4)") &
3553 SIZE(negf_env%contacts(icontact)%atomlist_cell0)
3555 IF (log_unit > 0 .AND. verbose_output)
THEN
3556 WRITE (log_unit,
"(' Atoms belonging to a primary unit cell (from the entire system):')")
3557 WRITE (log_unit,
"(16I5)") negf_env%contacts(icontact)%atomlist_cell0
3558 WRITE (log_unit,
"(' Direction of an electrode: ',I16)") negf_env%contacts(icontact)%direction_axis
3561 IF (debug_output)
THEN
3562 CALL cp_fm_get_info(negf_env%contacts(icontact)%s_00, nrow_global=nrow)
3563 ALLOCATE (target_m(nrow, nrow))
3564 IF (log_unit > 0)
WRITE (log_unit,
"(' The number of atomic orbitals:',I13)") nrow
3565 DO k = 1, dft_control%nspins
3567 IF (log_unit > 0)
THEN
3568 WRITE (sfmt,
"('(',i0,'(E15.5))')") nrow
3569 WRITE (log_unit,
"(' The H_00 electrode Hamiltonian for spin',I2)") k
3571 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3575 IF (log_unit > 0)
THEN
3576 WRITE (log_unit,
"(' The H_01 electrode Hamiltonian for spin',I2)") k
3578 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3583 IF (log_unit > 0)
THEN
3584 WRITE (log_unit,
"(' The S_00 overlap matrix')")
3586 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3590 IF (log_unit > 0)
THEN
3591 WRITE (log_unit,
"(' The S_01 overlap matrix')")
3593 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3596 DEALLOCATE (target_m)
3601 IF (log_unit > 0)
THEN
3602 WRITE (log_unit,
"(/,' The full scattering region')")
3603 WRITE (log_unit,
"( ' --------------------------')")
3604 WRITE (log_unit,
"(' Number of atoms:',I27)")
SIZE(negf_control%atomlist_S_screening)
3605 IF (verbose_output)
WRITE (log_unit,
"(' Atoms belonging to a full scattering region:')")
3606 IF (verbose_output)
WRITE (log_unit,
"(16I5)") negf_control%atomlist_S_screening
3609 IF (debug_output)
THEN
3611 ALLOCATE (target_m(n, n))
3612 WRITE (sfmt,
"('(',i0,'(E15.5))')") n
3613 IF (log_unit > 0)
WRITE (log_unit,
"(' The number of atomic orbitals:',I14)") n
3614 DO k = 1, dft_control%nspins
3615 IF (log_unit > 0)
WRITE (log_unit,
"(' The H_s Hamiltonian for spin',I2)") k
3618 IF (log_unit > 0)
WRITE (log_unit, sfmt) (target_m(i, j), j=1, n)
3621 IF (log_unit > 0)
WRITE (log_unit,
"(' The S_s overlap matrix')")
3624 IF (log_unit > 0)
WRITE (log_unit, sfmt) (target_m(i, j), j=1, n)
3626 DEALLOCATE (target_m)
3627 IF (log_unit > 0)
WRITE (log_unit,
"(/,' Scattering region - electrode contacts')")
3628 IF (log_unit > 0)
WRITE (log_unit,
"( ' ---------------------------------------')")
3629 ALLOCATE (target_m(n, nrow))
3630 DO icontact = 1,
SIZE(negf_control%contacts)
3631 IF (log_unit > 0)
WRITE (log_unit,
"(/,' The contact',I5)") icontact
3632 IF (log_unit > 0)
WRITE (log_unit,
"( ' ----------------')")
3633 DO k = 1, dft_control%nspins
3635 IF (log_unit > 0)
THEN
3636 WRITE (log_unit,
"(' The H_sc Hamiltonian for spin',I2)") k
3638 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3643 IF (log_unit > 0)
THEN
3644 WRITE (log_unit,
"(' The S_sc overlap matrix')")
3646 WRITE (log_unit, sfmt) (target_m(i, j), j=1, nrow)
3650 DEALLOCATE (target_m)
3653 IF (log_unit > 0)
THEN
3654 WRITE (log_unit,
"(/,' NEGF| Number of MPI processes: ',I5)") sub_env%mpi_comm_global%num_pe
3655 WRITE (log_unit,
"(' NEGF| Maximal number of processes per energy point:',I5)") negf_control%nprocs
3656 WRITE (log_unit,
"(' NEGF| Number of parallel MPI (energy) groups: ',I5)") sub_env%ngroups
3659 CALL timestop(handle)
3660 END SUBROUTINE negf_output_initial
3670 SUBROUTINE negf_write_restart(filename, negf_env, negf_control)
3671 CHARACTER(LEN=*),
INTENT(IN) :: filename
3675 INTEGER :: icontact, ncontacts, print_unit
3677 CALL open_file(file_name=filename, file_status=
"REPLACE", &
3678 file_form=
"FORMATTED", file_action=
"WRITE", &
3679 file_position=
"REWIND", unit_number=print_unit)
3681 WRITE (print_unit, *)
'This file is created automatically with restart files.'
3682 WRITE (print_unit, *)
'Do not remove it if you use any of restart files!'
3684 ncontacts =
SIZE(negf_control%contacts)
3686 DO icontact = 1, ncontacts
3687 WRITE (print_unit, *)
'icontact', icontact,
' fermi_energy', negf_env%contacts(icontact)%fermi_energy
3688 WRITE (print_unit, *)
'icontact', icontact,
' nelectrons_qs_cell0', negf_env%contacts(icontact)%nelectrons_qs_cell0
3689 WRITE (print_unit, *)
'icontact', icontact,
' nelectrons_qs_cell1', negf_env%contacts(icontact)%nelectrons_qs_cell1
3692 WRITE (print_unit, *)
'nelectrons_ref', negf_env%nelectrons_ref
3693 WRITE (print_unit, *)
'nelectrons ', negf_env%nelectrons
3697 END SUBROUTINE negf_write_restart
3707 SUBROUTINE negf_read_restart(filename, negf_env, negf_control)
3708 CHARACTER(LEN=*),
INTENT(IN) :: filename
3713 INTEGER :: i, icontact, ncontacts, print_unit
3715 CALL open_file(file_name=filename, file_status=
"OLD", &
3716 file_form=
"FORMATTED", file_action=
"READ", &
3717 file_position=
"REWIND", unit_number=print_unit)
3719 READ (print_unit, *) a
3720 READ (print_unit, *) a
3722 ncontacts =
SIZE(negf_control%contacts)
3724 DO icontact = 1, ncontacts
3725 READ (print_unit, *) a, i, a, negf_env%contacts(icontact)%fermi_energy
3726 READ (print_unit, *) a, i, a, negf_env%contacts(icontact)%nelectrons_qs_cell0
3727 READ (print_unit, *) a, i, a, negf_env%contacts(icontact)%nelectrons_qs_cell1
3730 READ (print_unit, *) a, negf_env%nelectrons_ref
3731 READ (print_unit, *) a, negf_env%nelectrons
3735 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)
Retrieve information from a kpoint environment.
Machine interface based on Fortran 2003 and POSIX.
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
complex(kind=dp), parameter, public z_one
real(kind=dp), parameter, public twopi
complex(kind=dp), parameter, public z_zero
Interface to the message passing library MPI.
Input control types for NEGF based quantum transport calculations.
subroutine, public negf_control_create(negf_control)
allocate control options for Non-equilibrium Green's Function calculation
subroutine, public read_negf_control(negf_control, input, subsys)
Read NEGF input parameters.
subroutine, public negf_control_release(negf_control)
release memory allocated for NEGF control options
Environment for NEGF based quantum transport calculations.
subroutine, public negf_env_release(negf_env)
Release a NEGF environment variable.
subroutine, public negf_env_create(negf_env, sub_env, negf_control, force_env, negf_mixing_section, log_unit)
Create a new NEGF environment and compute the relevant Kohn-Sham matrices.
Storage to keep precomputed surface Green's functions.
subroutine, public green_functions_cache_reorder(cache, tnodes)
Sort cached items in ascending order.
subroutine, public green_functions_cache_release(cache)
Release storage.
subroutine, public green_functions_cache_expand(cache, ncontacts, nnodes_extra)
Reallocate storage so it can handle extra 'nnodes_extra' items for each contact.
Subroutines to compute Green functions.
subroutine, public sancho_work_matrices_create(work, fm_struct)
Create work matrices required for the Lopez-Sancho algorithm.
subroutine, public sancho_work_matrices_release(work)
Release work matrices.
subroutine, public negf_contact_self_energy(self_energy_c, omega, g_surf_c, h_sc0, s_sc0, zwork1, zwork2, transp)
Compute the contact self energy at point 'omega' as self_energy_C = [omega * S_SC0 - KS_SC0] * g_surf...
subroutine, public negf_contact_broadening_matrix(gamma_c, self_energy_c)
Compute contact broadening matrix as gamma_C = i (self_energy_c^{ret.} - (self_energy_c^{ret....
subroutine, public do_sancho(g_surf, omega, h0, s0, h1, s1, conv, transp, work)
Iterative method to compute a retarded surface Green's function at the point omega.
subroutine, public negf_retarded_green_function(g_ret_s, omega, self_energy_ret_sum, h_s, s_s, v_hartree_s)
Compute the retarded Green's function at point 'omega' as G_S^{ret.} = [ omega * S_S - KS_S - \sum_{c...
Adaptive Clenshaw-Curtis quadrature algorithm to integrate a complex-valued function in a complex pla...
integer, parameter, public cc_shape_linear
subroutine, public ccquad_refine_integral(cc_env)
Refine approximated integral.
integer, parameter, public cc_interval_full
subroutine, public ccquad_double_number_of_points(cc_env, xnodes_next)
Get the next set of points at which the integrand needs to be computed. These points are then can be ...
subroutine, public ccquad_release(cc_env)
Release a Clenshaw-Curtis quadrature environment variable.
integer, parameter, public cc_interval_half
subroutine, public ccquad_init(cc_env, xnodes, nnodes, a, b, interval_id, shape_id, weights, tnodes_restart)
Initialise a Clenshaw-Curtis quadrature environment variable.
integer, parameter, public cc_shape_arc
subroutine, public ccquad_reduce_and_append_zdata(cc_env, zdata_next)
Prepare Clenshaw-Curtis environment for the subsequent refinement of the integral.
Adaptive Simpson's rule algorithm to integrate a complex-valued function in a complex plane.
integer, parameter, public sr_shape_arc
subroutine, public simpsonrule_refine_integral(sr_env, zdata_next)
Compute integral using the simpson's rules.
subroutine, public simpsonrule_init(sr_env, xnodes, nnodes, a, b, shape_id, conv, weights, tnodes_restart)
Initialise a Simpson's rule environment variable.
subroutine, public simpsonrule_release(sr_env)
Release a Simpson's rule environment variable.
integer, parameter, public sr_shape_linear
subroutine, public simpsonrule_get_next_nodes(sr_env, xnodes_next, nnodes)
Get the next set of nodes where to compute integrand.
Routines for reading and writing NEGF restart files.
subroutine, public negf_restart_file_name(filename, exist, negf_section, logger, icontact, ispin, h00, h01, s00, s01, h, s, hc, sc, h_scf)
Checks if the restart file exists and returns the filename.
subroutine, public negf_read_matrix_from_file(filename, matrix)
Reads full matrix from a file.
Helper routines to manipulate with matrices.
subroutine, public invert_cell_to_index(cell_to_index, nimages, index_to_cell)
Invert cell_to_index mapping between unit cells and DBCSR matrix images.
subroutine, public negf_copy_fm_submat_to_dbcsr(fm, matrix, atomlist_row, atomlist_col, subsys)
Populate relevant blocks of the DBCSR matrix using data from a ScaLAPACK matrix. Irrelevant blocks of...
subroutine, public negf_copy_sym_dbcsr_to_fm_submat(matrix, fm, atomlist_row, atomlist_col, subsys, mpi_comm_global, do_upper_diag, do_lower)
Extract part of the DBCSR matrix based on selected atoms and copy it into a dense matrix.
NEGF based quantum transport calculations.
subroutine, public do_negf(force_env)
Perform NEGF calculation.
Environment for NEGF based quantum transport calculations.
subroutine, public negf_sub_env_release(sub_env)
Release a parallel (sub)group environment.
subroutine, public negf_sub_env_create(sub_env, negf_control, blacs_env_global, blacs_grid_layout, blacs_repeatable)
Split MPI communicator to create a set of parallel (sub)groups.
basic linear algebra operations for full matrixes
Definition of physical constants:
real(kind=dp), parameter, public e_charge
real(kind=dp), parameter, public kelvin
real(kind=dp), parameter, public seconds
real(kind=dp), parameter, public evolt
module that contains the definitions of the scf types
integer, parameter, public broyden_mixing_nr
integer, parameter, public modified_broyden_mixing_nr
integer, parameter, public direct_mixing_nr
integer, parameter, public multisecant_mixing_nr
integer, parameter, public pulay_mixing_nr
integer, parameter, public gspace_mixing_nr
Perform a QUICKSTEP wavefunction optimization (single point)
subroutine, public qs_energies(qs_env, consistent_energies, calc_forces)
Driver routine for QUICKSTEP single point wavefunction optimization.
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, 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)
Driver for the g-space mixing, calls the proper routine given the requested method.
routines that build the Kohn-Sham matrix (i.e calculate the coulomb and xc parts
subroutine, public rebuild_ks_matrix(qs_env, calculate_forces, just_energy, print_active)
Constructs a new Khon-Sham matrix.
elemental subroutine, public charge_mixing_init(mixing_store)
initialiation needed when charge mixing is used
subroutine, public mixing_init(mixing_method, rho, mixing_store, para_env, rho_atom)
initialiation needed when gspace mixing is used
subroutine, public mixing_allocate(qs_env, mixing_method, p_mix_new, p_delta, nspins, mixing_store)
allocation needed when density mixing is used
methods of the rho structure (defined in qs_rho_types)
subroutine, public qs_rho_update_rho(rho_struct, qs_env, rho_xc_external, local_rho_set, task_list_external, task_list_external_soft, pw_env_external, para_env_external)
updates rho_r and rho_g to the rhorho_ao. if use_kinetic_energy_density also computes tau_r and tau_g...
superstucture that hold various representations of the density and keeps track of which ones are vali...
subroutine, public qs_rho_get(rho_struct, rho_ao, rho_ao_im, rho_ao_kp, rho_ao_im_kp, rho_r, drho_r, rho_g, drho_g, tau_r, tau_g, rho_r_valid, drho_r_valid, rho_g_valid, drho_g_valid, tau_r_valid, tau_g_valid, tot_rho_r, tot_rho_g, rho_r_sccs, soft_valid, complex_rho_ao)
returns info about the density described by this object. If some representation is not available an e...
groups fairly general SCF methods, so that modules other than qs_scf can use them too split off from ...
subroutine, public scf_env_density_mixing(p_mix_new, mixing_store, rho_ao, para_env, iter_delta, iter_count, diis, invert)
perform (if requested) a density mixing
types that represent a quickstep subsys
Utilities for string manipulations.
subroutine, public integer_to_string(inumber, string)
Converts an integer number to a string. The WRITE statement will return an error message,...
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
Stores the state of a copy between cp_cfm_start_copy_general and cp_cfm_finish_copy_general.
Represent a complex full matrix.
keeps the information about the structure of a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
represents a system: atoms, molecules, their pos,vel,...
allows for the creation of an array of force_env
wrapper to abstract the force evaluation of the various methods
contains the initially parsed file and the initial parallel environment
Contains information about kpoints.
stores all the informations relevant to an mpi environment
Input parameters related to the NEGF run.
Storage to keep surface Green's functions.
Adaptive Clenshaw-Curtis environment.
A structure to store data needed for adaptive Simpson's rule algorithm.
Parallel (sub)group environment.
keeps the density in various representations, keeping track of which ones are valid.