82#include "./base/base_uses.f90"
87 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'negf_env_types'
88 LOGICAL,
PARAMETER,
PRIVATE :: debug_this_module = .true.
98 REAL(kind=
dp),
DIMENSION(3) :: direction_vector = -1.0_dp, origin = -1.0_dp
99 REAL(kind=
dp),
DIMENSION(3) :: direction_vector_bias = -1.0_dp, origin_bias = -1.0_dp
102 INTEGER :: direction_axis = -1
104 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atomlist_cell0
106 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atomlist_cell1
109 DIMENSION(:) :: atom_map_cell0, atom_map_cell1
111 REAL(kind=
dp) :: fermi_energy = 0.0_dp
113 REAL(kind=
dp) :: homo_energy = -1.0_dp
115 REAL(kind=
dp) :: nelectrons_qs_cell0
117 REAL(kind=
dp) :: nelectrons_qs_cell1
122 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: rho_00, rho_01
134 DIMENSION(:) :: contacts
148 INTEGER :: mixing_method = -1
150 REAL(kind=
dp) :: nelectrons_ref
152 REAL(kind=
dp) :: nelectrons
159 TYPE negf_atom_map_contact_type
161 END TYPE negf_atom_map_contact_type
176 SUBROUTINE negf_env_create(negf_env, sub_env, negf_control, force_env, negf_mixing_section, log_unit)
182 INTEGER,
INTENT(in) :: log_unit
184 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_env_create'
186 CHARACTER(len=default_string_length) :: contact_str, force_env_str, &
188 INTEGER :: handle, icontact, in_use, n_force_env, &
190 LOGICAL :: do_kpoints, is_dft_entire
192 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks_kp, matrix_s_kp
196 TYPE(negf_atom_map_contact_type),
ALLOCATABLE, &
197 DIMENSION(:) :: map_contact
203 CALL timeset(routinen, handle)
206 NULLIFY (sub_force_env)
207 CALL force_env_get(force_env, in_use=in_use, qs_env=qs_env, root_section=root_section, &
208 sub_force_env=sub_force_env)
210 IF (
ASSOCIATED(sub_force_env))
THEN
211 n_force_env =
SIZE(sub_force_env)
217 DO icontact = 1, n_force_env
218 CALL force_env_get(sub_force_env(icontact)%force_env, in_use=in_use)
224 cpabort(
"Quickstep is required for NEGF run.")
228 ncontacts =
SIZE(negf_control%contacts)
230 DO icontact = 1, ncontacts
231 IF (negf_control%contacts(icontact)%force_env_index > n_force_env)
THEN
232 WRITE (contact_str,
'(I11)') icontact
233 WRITE (force_env_str,
'(I11)') negf_control%contacts(icontact)%force_env_index
234 WRITE (n_force_env_str,
'(I11)') n_force_env
236 CALL cp_abort(__location__, &
237 "Contact number "//trim(adjustl(contact_str))//
" is linked with the FORCE_EVAL section number "// &
238 trim(adjustl(force_env_str))//
", however only "//trim(adjustl(n_force_env_str))// &
239 " FORCE_EVAL sections have been found. Note that FORCE_EVAL sections are enumerated from 0"// &
240 " and that the primary (0-th) section must contain all the atoms.")
247 CALL get_qs_env(qs_env, blacs_env=blacs_env, do_kpoints=do_kpoints, &
248 matrix_s_kp=matrix_s_kp, matrix_ks_kp=matrix_ks_kp, &
249 para_env=para_env, subsys=subsys, v_hartree_rspace=v_hartree_rspace)
254 cpabort(
"k-points are currently not supported for device FORCE_EVAL")
258 ALLOCATE (negf_env%contacts(ncontacts))
259 ALLOCATE (map_contact(ncontacts))
261 DO icontact = 1, ncontacts
262 IF (negf_control%contacts(icontact)%force_env_index > 0)
THEN
263 CALL force_env_get(sub_force_env(negf_control%contacts(icontact)%force_env_index)%force_env, qs_env=qs_env_contact)
264 CALL get_qs_env(qs_env_contact, subsys=subsys_contact)
266 CALL negf_env_contact_init_maps(contact_env=negf_env%contacts(icontact), &
267 contact_control=negf_control%contacts(icontact), &
268 atom_map=map_contact(icontact)%atom_map, &
269 eps_geometry=negf_control%eps_geometry, &
270 subsys_device=subsys, &
271 subsys_contact=subsys_contact)
273 IF (negf_env%contacts(icontact)%direction_axis == 0)
THEN
274 WRITE (contact_str,
'(I11)') icontact
275 WRITE (force_env_str,
'(I11)') negf_control%contacts(icontact)%force_env_index
276 CALL cp_abort(__location__, &
277 "One lattice vector of the contact unit cell (FORCE_EVAL section "// &
278 trim(adjustl(force_env_str))//
") must be parallel to the direction of the contact "// &
279 trim(adjustl(contact_str))//
".")
285 DO icontact = 1, ncontacts
286 IF (negf_control%contacts(icontact)%force_env_index > 0)
THEN
287 IF (negf_control%contacts(icontact)%read_write_HS)
THEN
288 CALL negf_env_contact_read_write_hs &
289 (icontact, sub_force_env(negf_control%contacts(icontact)%force_env_index)%force_env, &
290 para_env, negf_env, sub_env, negf_control, negf_section, log_unit, is_separate=.true.)
293 WRITE (log_unit,
'(/,T2,A,T70,I11,/,A)')
"NEGF| Construct the Kohn-Sham matrix for the contact", icontact, &
294 " from the separate bulk DFT calculation"
295 CALL force_env_get(sub_force_env(negf_control%contacts(icontact)%force_env_index)%force_env, qs_env=qs_env_contact)
296 CALL qs_energies(qs_env_contact, consistent_energies=.false., calc_forces=.false.)
297 CALL negf_env_contact_init_matrices(contact_env=negf_env%contacts(icontact), sub_env=sub_env, &
298 qs_env_contact=qs_env_contact)
299 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,79("-"))')
305 is_dft_entire = .false.
306 DO icontact = 1, ncontacts
307 IF (negf_control%contacts(icontact)%force_env_index <= 0)
THEN
308 IF (negf_control%contacts(icontact)%read_write_HS)
THEN
309 CALL negf_env_contact_init_matrices_gamma(contact_env=negf_env%contacts(icontact), &
310 contact_control=negf_control%contacts(icontact), &
311 sub_env=sub_env, qs_env=qs_env, &
312 eps_geometry=negf_control%eps_geometry)
313 CALL negf_env_contact_read_write_hs(icontact, force_env, para_env, negf_env, sub_env, negf_control, negf_section, &
314 log_unit, is_separate=.false., is_dft_entire=is_dft_entire)
317 WRITE (log_unit,
'(/,T2,A,T70,I11,/,A)')
"NEGF| Construct the Kohn-Sham matrix for the contact", icontact, &
318 " from the entire system bulk DFT calculation"
319 IF (.NOT. is_dft_entire)
CALL qs_energies(qs_env, consistent_energies=.false., calc_forces=.false.)
320 is_dft_entire = .true.
321 CALL negf_env_contact_init_matrices_gamma(contact_env=negf_env%contacts(icontact), &
322 contact_control=negf_control%contacts(icontact), &
323 sub_env=sub_env, qs_env=qs_env, &
324 eps_geometry=negf_control%eps_geometry)
325 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,79("-"))')
332 WRITE (log_unit,
'(/,T2,A,T70)')
"NEGF| Construct the Kohn-Sham matrix for the scattering region"
333 IF (negf_control%read_write_HS)
THEN
334 CALL negf_env_scatt_read_write_hs(force_env, para_env, negf_env, sub_env, negf_control, negf_section, log_unit, &
335 is_dft_entire=is_dft_entire)
337 IF (.NOT. is_dft_entire)
CALL qs_energies(qs_env, consistent_energies=.false., calc_forces=.false.)
339 CALL negf_env_device_init_matrices(negf_env, negf_control, sub_env, qs_env)
341 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,79("-"))')
343 negf_control%is_dft_entire = is_dft_entire
347 NULLIFY (negf_env%mixing_storage)
350 CALL get_qs_env(qs_env, dft_control=dft_control)
351 ALLOCATE (negf_env%mixing_storage)
353 negf_env%mixing_method, dft_control%qs_control%cutoff)
355 CALL timestop(handle)
368 SUBROUTINE negf_env_contact_init_maps(contact_env, contact_control, atom_map, &
369 eps_geometry, subsys_device, subsys_contact)
373 DIMENSION(:),
INTENT(inout) :: atom_map
374 REAL(kind=
dp),
INTENT(in) :: eps_geometry
377 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_env_contact_init_maps'
379 INTEGER :: handle, natoms
381 CALL timeset(routinen, handle)
384 contact_env%direction_vector, &
385 contact_env%origin_bias, &
386 contact_env%direction_vector_bias, &
387 contact_control%atomlist_screening, &
388 contact_control%atomlist_bulk, &
391 contact_env%direction_axis = contact_direction_axis(contact_env%direction_vector, subsys_contact, eps_geometry)
393 IF (contact_env%direction_axis /= 0)
THEN
394 natoms =
SIZE(contact_control%atomlist_bulk)
395 ALLOCATE (atom_map(natoms))
399 atom_list=contact_control%atomlist_bulk, &
400 subsys_device=subsys_device, &
401 subsys_contact=subsys_contact, &
402 eps_geometry=eps_geometry)
406 CALL list_atoms_in_bulk_primary_unit_cell(atomlist_cell0=contact_env%atomlist_cell0, &
407 atom_map_cell0=contact_env%atom_map_cell0, &
408 atomlist_bulk=contact_control%atomlist_bulk, &
410 origin=contact_env%origin, &
411 direction_vector=contact_env%direction_vector, &
412 direction_axis=contact_env%direction_axis, &
413 subsys_device=subsys_device)
416 CALL list_atoms_in_bulk_secondary_unit_cell(atomlist_cell1=contact_env%atomlist_cell1, &
417 atom_map_cell1=contact_env%atom_map_cell1, &
418 atomlist_bulk=contact_control%atomlist_bulk, &
420 origin=contact_env%origin, &
421 direction_vector=contact_env%direction_vector, &
422 direction_axis=contact_env%direction_axis, &
423 subsys_device=subsys_device)
426 CALL timestop(handle)
427 END SUBROUTINE negf_env_contact_init_maps
444 SUBROUTINE negf_env_contact_read_write_hs(icontact, el_force_env, para_env, negf_env, sub_env, negf_control, &
445 negf_section, log_unit, is_separate, is_dft_entire)
453 INTEGER,
INTENT(in) :: log_unit
454 LOGICAL,
INTENT(in) :: is_separate
455 LOGICAL,
INTENT(inout),
OPTIONAL :: is_dft_entire
457 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_env_contact_read_write_hs'
459 CHARACTER(len=default_path_length) :: filename_h00_1, filename_h00_2, &
460 filename_h01_1, filename_h01_2, &
461 filename_s00, filename_s01
462 INTEGER :: handle, ispin, ncol, nrow, nspins, &
464 LOGICAL :: exist, exist_all
465 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: target_m
472 CALL timeset(routinen, handle)
476 CALL get_qs_env(qs_env_contact, dft_control=dft_control, subsys=subsys)
477 nspins = dft_control%nspins
479 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,A,T70,I11)') &
480 "NEGF| Construct the Kohn-Sham matrix for the contact", icontact
485 IF (para_env%is_source())
THEN
487 IF (.NOT. exist)
THEN
488 CALL cp_warn(__location__, &
489 "User requested to read the overlap matrix from the file named: "// &
490 trim(filename_s00)//
". This file does not exist. The file will be created.")
494 IF (.NOT. exist)
THEN
495 CALL cp_warn(__location__, &
496 "User requested to read the overlap matrix from the file named: "// &
497 trim(filename_s01)//
". This file does not exist. The file will be created.")
500 IF (nspins == 1)
THEN
502 IF (.NOT. exist)
THEN
503 CALL cp_warn(__location__, &
504 "User requested to read the Hamiltonian matrix from the file named: "// &
505 trim(filename_h00_1)//
". This file does not exist. The file will be created.")
509 IF (.NOT. exist)
THEN
510 CALL cp_warn(__location__, &
511 "User requested to read the Hamiltonian matrix from the file named: "// &
512 trim(filename_h01_1)//
". This file does not exist. The file will be created.")
516 IF (nspins == 2)
THEN
518 IF (.NOT. exist)
THEN
519 CALL cp_warn(__location__, &
520 "User requested to read the Hamiltonian matrix from the file named: "// &
521 trim(filename_h00_1)//
". This file does not exist. The file will be created.")
525 IF (.NOT. exist)
THEN
526 CALL cp_warn(__location__, &
527 "User requested to read tthe Hamiltonian matrix from the file named: "// &
528 trim(filename_h01_1)//
". This file does not exist. The file will be created.")
532 IF (.NOT. exist)
THEN
533 CALL cp_warn(__location__, &
534 "User requested to read the Hamiltonian matrix from the file named: "// &
535 trim(filename_h00_2)//
". This file does not exist. The file will be created.")
539 IF (.NOT. exist)
THEN
540 CALL cp_warn(__location__, &
541 "User requested to read the Hamiltonian matrix from the file named: "// &
542 trim(filename_h01_2)//
". This file does not exist. The file will be created.")
547 CALL para_env%bcast(exist_all)
551 negf_control%contacts(icontact)%is_restart = .true.
553 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,A)')
"All restart files exist."
556 IF (para_env%is_source())
THEN
557 CALL open_file(file_name=filename_s00, file_status=
"OLD", &
558 file_form=
"FORMATTED", file_action=
"READ", &
559 file_position=
"REWIND", unit_number=print_unit)
560 READ (print_unit, *) nrow, ncol
563 CALL para_env%bcast(nrow)
564 CALL para_env%bcast(ncol)
566 CALL cp_fm_struct_create(fm_struct, nrow_global=nrow, ncol_global=ncol, context=sub_env%blacs_env)
567 ALLOCATE (negf_env%contacts(icontact)%s_00, negf_env%contacts(icontact)%s_01)
568 CALL cp_fm_create(negf_env%contacts(icontact)%s_00, fm_struct)
569 CALL cp_fm_create(negf_env%contacts(icontact)%s_01, fm_struct)
570 ALLOCATE (negf_env%contacts(icontact)%h_00(nspins), negf_env%contacts(icontact)%h_01(nspins))
572 CALL cp_fm_create(negf_env%contacts(icontact)%h_00(ispin), fm_struct)
573 CALL cp_fm_create(negf_env%contacts(icontact)%h_01(ispin), fm_struct)
577 ALLOCATE (target_m(nrow, ncol))
579 CALL para_env%bcast(target_m)
581 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"S_00 is read from "//trim(filename_s00)
583 CALL para_env%bcast(target_m)
585 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"S_01 is read from "//trim(filename_s01)
586 IF (nspins == 1)
THEN
588 CALL para_env%bcast(target_m)
590 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_00 is read from "//trim(filename_h00_1)
592 CALL para_env%bcast(target_m)
594 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_01 is read from "//trim(filename_h01_1)
596 IF (nspins == 2)
THEN
598 CALL para_env%bcast(target_m)
600 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_00 is read from "//trim(filename_h00_1)//
" for spin 1"
602 CALL para_env%bcast(target_m)
604 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_01 is read from "//trim(filename_h01_1)//
" for spin 1"
606 CALL para_env%bcast(target_m)
608 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_00 is read from "//trim(filename_h00_2)//
" for spin 2"
610 CALL para_env%bcast(target_m)
612 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_01 is read from "//trim(filename_h01_2)//
" for spin 2"
614 DEALLOCATE (target_m)
618 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)') &
619 "Some restart files do not exist. ALL restart files will be recalculated!"
621 IF (is_separate)
THEN
622 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,A,T70,I11,/,A)') &
623 "Construct the Kohn-Sham matrix from from the separate bulk DFT calculation"
624 CALL qs_energies(qs_env_contact, consistent_energies=.false., calc_forces=.false.)
625 CALL negf_env_contact_init_matrices(contact_env=negf_env%contacts(icontact), sub_env=sub_env, &
626 qs_env_contact=qs_env_contact)
628 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,A,T70,I11,/,A)') &
629 "Construct the Kohn-Sham matrix from the entire system bulk DFT calculation"
630 negf_control%contacts(icontact)%read_write_HS = .false.
631 IF (.NOT. is_dft_entire)
CALL qs_energies(qs_env_contact, consistent_energies=.false., calc_forces=.false.)
632 CALL negf_env_contact_init_matrices_gamma(contact_env=negf_env%contacts(icontact), &
633 contact_control=negf_control%contacts(icontact), &
634 sub_env=sub_env, qs_env=qs_env_contact, &
635 eps_geometry=negf_control%eps_geometry)
636 negf_control%contacts(icontact)%read_write_HS = .true.
637 is_dft_entire = .true.
640 CALL cp_fm_get_info(negf_env%contacts(icontact)%s_00, nrow_global=nrow)
641 ALLOCATE (target_m(nrow, nrow))
644 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,A)')
"S_00 is saved to "//trim(filename_s00)
647 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"S_01 is saved to "//trim(filename_s01)
648 IF (nspins == 1)
THEN
651 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_00 is saved to "//trim(filename_h00_1)
654 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_01 is saved to "//trim(filename_h01_1)
656 IF (nspins == 2)
THEN
659 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_00 is saved to "//trim(filename_h00_1)//
" for spin 1"
662 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_01 is saved to "//trim(filename_h01_1)//
" for spin 1"
665 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_00 is saved to "//trim(filename_h00_2)//
" for spin 2"
668 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_01 is saved to "//trim(filename_h01_2)//
" for spin 2"
670 DEALLOCATE (target_m)
672 negf_control%write_common_restart_file = .true.
676 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,79("-"))')
678 CALL timestop(handle)
679 END SUBROUTINE negf_env_contact_read_write_hs
691 SUBROUTINE negf_env_contact_init_matrices(contact_env, sub_env, qs_env_contact)
696 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_env_contact_init_matrices'
698 INTEGER :: handle, iatom, ispin, nao, natoms, &
700 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_list0, atom_list1
701 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: index_to_cell
702 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index
703 LOGICAL :: do_kpoints
706 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks_kp, matrix_s_kp, rho_ao_kp
713 CALL timeset(routinen, handle)
716 dft_control=dft_control, &
717 do_kpoints=do_kpoints, &
719 matrix_ks_kp=matrix_ks_kp, &
720 matrix_s_kp=matrix_s_kp, &
724 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_kp)
726 CALL negf_homo_energy_estimate(contact_env%homo_energy, qs_env_contact)
728 natoms =
SIZE(contact_env%atomlist_cell0)
729 ALLOCATE (atom_list0(natoms))
731 atom_list0(iatom) = contact_env%atom_map_cell0(iatom)%iatom
735 IF (sum(abs(contact_env%atom_map_cell0(iatom)%cell(:))) > 0)
THEN
736 cpabort(
"NEGF K-points are not currently supported")
740 cpassert(
SIZE(contact_env%atomlist_cell1) == natoms)
741 ALLOCATE (atom_list1(natoms))
743 atom_list1(iatom) = contact_env%atom_map_cell1(iatom)%iatom
746 nspins = dft_control%nspins
747 nimages = dft_control%nimages
752 ALLOCATE (cell_to_index(0:0, 0:0, 0:0))
753 cell_to_index(0, 0, 0) = 1
756 ALLOCATE (index_to_cell(3, nimages))
758 IF (.NOT. do_kpoints)
DEALLOCATE (cell_to_index)
762 CALL cp_fm_struct_create(fm_struct, nrow_global=nao, ncol_global=nao, context=sub_env%blacs_env)
765 ALLOCATE (contact_env%s_00, contact_env%s_01)
770 ALLOCATE (contact_env%h_00(nspins), contact_env%h_01(nspins))
771 ALLOCATE (contact_env%rho_00(nspins), contact_env%rho_01(nspins))
782 matkp => matrix_s_kp(1, :)
784 fm_cell1=contact_env%s_01, &
785 direction_axis=contact_env%direction_axis, &
787 atom_list0=atom_list0, atom_list1=atom_list1, &
788 subsys=subsys, mpi_comm_global=para_env, &
793 matkp => matrix_ks_kp(ispin, :)
795 fm_cell1=contact_env%h_01(ispin), &
796 direction_axis=contact_env%direction_axis, &
798 atom_list0=atom_list0, atom_list1=atom_list1, &
799 subsys=subsys, mpi_comm_global=para_env, &
802 matkp => rho_ao_kp(ispin, :)
804 fm_cell1=contact_env%rho_01(ispin), &
805 direction_axis=contact_env%direction_axis, &
807 atom_list0=atom_list0, atom_list1=atom_list1, &
808 subsys=subsys, mpi_comm_global=para_env, &
812 DEALLOCATE (atom_list0, atom_list1)
814 CALL timestop(handle)
815 END SUBROUTINE negf_env_contact_init_matrices
826 SUBROUTINE negf_env_contact_init_matrices_gamma(contact_env, contact_control, sub_env, qs_env, eps_geometry)
831 REAL(kind=
dp),
INTENT(in) :: eps_geometry
833 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_env_contact_init_matrices_gamma'
835 INTEGER :: handle, iatom, icell, ispin, nao_c, &
837 LOGICAL :: do_kpoints
838 REAL(kind=
dp),
DIMENSION(2) :: r2_origin_cell
839 REAL(kind=
dp),
DIMENSION(3) :: direction_vector, origin
841 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks_kp, matrix_s_kp, rho_ao_kp
848 CALL timeset(routinen, handle)
851 dft_control=dft_control, &
852 do_kpoints=do_kpoints, &
853 matrix_ks_kp=matrix_ks_kp, &
854 matrix_s_kp=matrix_s_kp, &
858 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_kp)
861 CALL cp_abort(__location__, &
862 "K-points in device region have not been implemented yet.")
865 nspins = dft_control%nspins
869 CALL cp_abort(__location__, &
870 "Primary and secondary bulk contact cells should be identical "// &
871 "in terms of the number of atoms of each kind, and their basis sets. "// &
872 "No single atom, however, can be shared between these two cells.")
875 contact_env%homo_energy = 0.0_dp
878 contact_env%direction_vector, &
879 contact_env%origin_bias, &
880 contact_env%direction_vector_bias, &
881 contact_control%atomlist_screening, &
882 contact_control%atomlist_bulk, &
885 contact_env%direction_axis = contact_direction_axis(contact_env%direction_vector, subsys, eps_geometry)
890 origin = particle_set(contact_control%atomlist_screening(1))%r
891 DO iatom = 2,
SIZE(contact_control%atomlist_screening)
892 origin = origin + particle_set(contact_control%atomlist_screening(iatom))%r
894 origin = origin/real(
SIZE(contact_control%atomlist_screening), kind=
dp)
897 direction_vector = particle_set(contact_control%atomlist_cell(icell)%vector(1))%r
898 DO iatom = 2,
SIZE(contact_control%atomlist_cell(icell)%vector)
899 direction_vector = direction_vector + particle_set(contact_control%atomlist_cell(icell)%vector(iatom))%r
901 direction_vector = direction_vector/real(
SIZE(contact_control%atomlist_cell(icell)%vector), kind=
dp)
902 direction_vector = direction_vector - origin
903 r2_origin_cell(icell) = dot_product(direction_vector, direction_vector)
906 IF (abs(r2_origin_cell(1) - r2_origin_cell(2)) < (eps_geometry*eps_geometry))
THEN
909 CALL cp_abort(__location__, &
910 "Primary and secondary bulk contact cells should not overlap ")
911 ELSE IF (r2_origin_cell(1) < r2_origin_cell(2))
THEN
912 IF (.NOT.
ALLOCATED(contact_env%atomlist_cell0)) &
913 ALLOCATE (contact_env%atomlist_cell0(
SIZE(contact_control%atomlist_cell(1)%vector)))
914 contact_env%atomlist_cell0(:) = contact_control%atomlist_cell(1)%vector(:)
915 IF (.NOT.
ALLOCATED(contact_env%atomlist_cell1)) &
916 ALLOCATE (contact_env%atomlist_cell1(
SIZE(contact_control%atomlist_cell(2)%vector)))
917 contact_env%atomlist_cell1(:) = contact_control%atomlist_cell(2)%vector(:)
919 IF (.NOT.
ALLOCATED(contact_env%atomlist_cell0)) &
920 ALLOCATE (contact_env%atomlist_cell0(
SIZE(contact_control%atomlist_cell(2)%vector)))
921 contact_env%atomlist_cell0(:) = contact_control%atomlist_cell(2)%vector(:)
922 IF (.NOT.
ALLOCATED(contact_env%atomlist_cell1)) &
923 ALLOCATE (contact_env%atomlist_cell1(
SIZE(contact_control%atomlist_cell(1)%vector)))
924 contact_env%atomlist_cell1(:) = contact_control%atomlist_cell(1)%vector(:)
926 IF (.NOT. contact_control%read_write_HS)
THEN
928 CALL cp_fm_struct_create(fm_struct, nrow_global=nao_c, ncol_global=nao_c, context=sub_env%blacs_env)
929 ALLOCATE (contact_env%h_00(nspins), contact_env%h_01(nspins))
930 ALLOCATE (contact_env%rho_00(nspins), contact_env%rho_01(nspins))
937 ALLOCATE (contact_env%s_00, contact_env%s_01)
944 fm=contact_env%h_00(ispin), &
945 atomlist_row=contact_env%atomlist_cell0, &
946 atomlist_col=contact_env%atomlist_cell0, &
947 subsys=subsys, mpi_comm_global=para_env, &
948 do_upper_diag=.true., do_lower=.true.)
950 fm=contact_env%h_01(ispin), &
951 atomlist_row=contact_env%atomlist_cell0, &
952 atomlist_col=contact_env%atomlist_cell1, &
953 subsys=subsys, mpi_comm_global=para_env, &
954 do_upper_diag=.true., do_lower=.true.)
957 fm=contact_env%rho_00(ispin), &
958 atomlist_row=contact_env%atomlist_cell0, &
959 atomlist_col=contact_env%atomlist_cell0, &
960 subsys=subsys, mpi_comm_global=para_env, &
961 do_upper_diag=.true., do_lower=.true.)
963 fm=contact_env%rho_01(ispin), &
964 atomlist_row=contact_env%atomlist_cell0, &
965 atomlist_col=contact_env%atomlist_cell1, &
966 subsys=subsys, mpi_comm_global=para_env, &
967 do_upper_diag=.true., do_lower=.true.)
971 fm=contact_env%s_00, &
972 atomlist_row=contact_env%atomlist_cell0, &
973 atomlist_col=contact_env%atomlist_cell0, &
974 subsys=subsys, mpi_comm_global=para_env, &
975 do_upper_diag=.true., do_lower=.true.)
977 fm=contact_env%s_01, &
978 atomlist_row=contact_env%atomlist_cell0, &
979 atomlist_col=contact_env%atomlist_cell1, &
980 subsys=subsys, mpi_comm_global=para_env, &
981 do_upper_diag=.true., do_lower=.true.)
983 CALL timestop(handle)
984 END SUBROUTINE negf_env_contact_init_matrices_gamma
999 SUBROUTINE negf_env_scatt_read_write_hs(force_env, para_env, negf_env, sub_env, negf_control, negf_section, &
1000 log_unit, is_dft_entire)
1007 INTEGER,
INTENT(in) :: log_unit
1008 LOGICAL,
INTENT(inout),
OPTIONAL :: is_dft_entire
1010 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_env_scatt_read_write_hs'
1012 CHARACTER(len=default_path_length) :: filename_h_1, filename_h_2, filename_s
1013 CHARACTER(len=default_path_length),
ALLOCATABLE, &
1014 DIMENSION(:) :: filename_hc_1, filename_hc_2, filename_sc
1015 INTEGER :: handle, icontact, ispin, ncol_s, &
1016 ncol_sc, ncontacts, nrow_s, nrow_sc, &
1018 LOGICAL :: exist, exist_all
1019 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: target_m
1026 CALL timeset(routinen, handle)
1030 CALL get_qs_env(qs_env, dft_control=dft_control, subsys=subsys)
1031 ncontacts =
SIZE(negf_control%contacts)
1032 nspins = dft_control%nspins
1033 ALLOCATE (filename_sc(ncontacts), filename_hc_1(ncontacts), filename_hc_2(ncontacts))
1038 IF (para_env%is_source())
THEN
1040 IF (.NOT. exist)
THEN
1041 CALL cp_warn(__location__, &
1042 "User requested to read the overlap matrix from the file named: "// &
1043 trim(filename_s)//
". This file does not exist. The file will be created.")
1046 IF (nspins == 1)
THEN
1048 IF (.NOT. exist)
THEN
1049 CALL cp_warn(__location__, &
1050 "User requested to read the Hamiltonian matrix from the file named: "// &
1051 trim(filename_h_1)//
". This file does not exist. The file will be created.")
1055 IF (nspins == 2)
THEN
1057 IF (.NOT. exist)
THEN
1058 CALL cp_warn(__location__, &
1059 "User requested to read the Hamiltonian matrix from the file named: "// &
1060 trim(filename_h_1)//
". This file does not exist. The file will be created.")
1064 IF (.NOT. exist)
THEN
1065 CALL cp_warn(__location__, &
1066 "User requested to read the Hamiltonian matrix from the file named: "// &
1067 trim(filename_h_2)//
". This file does not exist. The file will be created.")
1071 DO icontact = 1, ncontacts
1072 CALL negf_restart_file_name(filename_sc(icontact), exist, negf_section, logger, icontact=icontact, sc=.true.)
1073 IF (.NOT. exist)
THEN
1074 CALL cp_warn(__location__, &
1075 "User requested to read the overlap matrix from the file named: "// &
1076 trim(filename_sc(icontact))//
". This file does not exist. The file will be created.")
1079 IF (nspins == 1)
THEN
1082 IF (.NOT. exist)
THEN
1083 CALL cp_warn(__location__, &
1084 "User requested to read the Hamiltonian matrix from the file named: "// &
1085 trim(filename_hc_1(icontact))//
". This file does not exist. The file will be created.")
1089 IF (nspins == 2)
THEN
1092 IF (.NOT. exist)
THEN
1093 CALL cp_warn(__location__, &
1094 "User requested to read the Hamiltonian matrix from the file named: "// &
1095 trim(filename_hc_1(icontact))//
". This file does not exist. The file will be created.")
1100 IF (.NOT. exist)
THEN
1101 CALL cp_warn(__location__, &
1102 "User requested to read the Hamiltonian matrix from the file named: "// &
1103 trim(filename_hc_2(icontact))//
". This file does not exist. The file will be created.")
1109 CALL para_env%bcast(exist_all)
1113 negf_control%is_restart = .true.
1115 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,A)')
"All restart files exist."
1118 IF (para_env%is_source())
THEN
1119 CALL open_file(file_name=filename_s, file_status=
"OLD", &
1120 file_form=
"FORMATTED", file_action=
"READ", &
1121 file_position=
"REWIND", unit_number=print_unit)
1122 READ (print_unit, *) nrow_s, ncol_s
1125 CALL para_env%bcast(nrow_s)
1126 CALL para_env%bcast(ncol_s)
1128 CALL cp_fm_struct_create(fm_struct, nrow_global=nrow_s, ncol_global=ncol_s, context=sub_env%blacs_env)
1129 ALLOCATE (negf_env%s_s)
1131 ALLOCATE (negf_env%h_s(nspins))
1132 DO ispin = 1, nspins
1136 ALLOCATE (negf_env%s_sc(ncontacts))
1137 ALLOCATE (negf_env%h_sc(nspins, ncontacts))
1138 DO icontact = 1, ncontacts
1139 IF (para_env%is_source())
THEN
1140 CALL open_file(file_name=filename_sc(icontact), file_status=
"OLD", &
1141 file_form=
"FORMATTED", file_action=
"READ", &
1142 file_position=
"REWIND", unit_number=print_unit)
1143 READ (print_unit, *) nrow_sc, ncol_sc
1146 CALL para_env%bcast(nrow_sc)
1147 CALL para_env%bcast(ncol_sc)
1149 CALL cp_fm_struct_create(fm_struct, nrow_global=nrow_sc, ncol_global=ncol_sc, context=sub_env%blacs_env)
1151 DO ispin = 1, nspins
1152 CALL cp_fm_create(negf_env%h_sc(ispin, icontact), fm_struct)
1157 ALLOCATE (target_m(nrow_s, ncol_s))
1159 CALL para_env%bcast(target_m)
1161 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"S_s is read from "//trim(filename_s)
1162 IF (nspins == 1)
THEN
1164 CALL para_env%bcast(target_m)
1166 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_s is read from "//trim(filename_h_1)
1168 IF (nspins == 2)
THEN
1170 CALL para_env%bcast(target_m)
1172 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_s is read from "//trim(filename_h_1)//
" for spin 1"
1174 CALL para_env%bcast(target_m)
1176 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_s is read from "//trim(filename_h_2)//
" for spin 2"
1178 DEALLOCATE (target_m)
1180 DO icontact = 1, ncontacts
1181 ALLOCATE (target_m(nrow_s, ncol_sc))
1183 CALL para_env%bcast(target_m)
1185 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"S_sc is read from "//trim(filename_sc(icontact))
1186 IF (nspins == 1)
THEN
1188 CALL para_env%bcast(target_m)
1190 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_sc is read from "//trim(filename_hc_1(icontact))
1192 IF (nspins == 2)
THEN
1194 CALL para_env%bcast(target_m)
1196 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_sc is read from "//trim(filename_hc_1(icontact))//
" for spin 1"
1198 CALL para_env%bcast(target_m)
1200 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_sc is read from "//trim(filename_hc_2(icontact))//
" for spin 2"
1202 DEALLOCATE (target_m)
1208 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)') &
1209 "Some restart files do not exist. ALL restart files will be recalculated!"
1211 IF (.NOT. is_dft_entire)
CALL qs_energies(qs_env, consistent_energies=.false., calc_forces=.false.)
1213 CALL negf_env_device_init_matrices(negf_env, negf_control, sub_env, qs_env)
1214 is_dft_entire = .true.
1216 CALL cp_fm_get_info(negf_env%s_s, nrow_global=nrow_s, ncol_global=ncol_s)
1217 ALLOCATE (target_m(nrow_s, ncol_s))
1220 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,A)')
"S_s is saved to "//trim(filename_s)
1221 IF (nspins == 1)
THEN
1224 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_s is saved to "//trim(filename_h_1)
1226 IF (nspins == 2)
THEN
1229 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_s is saved to "//trim(filename_h_1)//
" for spin 1"
1232 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_s is saved to "//trim(filename_h_2)//
" for spin 2"
1234 DEALLOCATE (target_m)
1236 DO icontact = 1, ncontacts
1237 CALL cp_fm_get_info(negf_env%contacts(icontact)%s_00, nrow_global=nrow_sc, ncol_global=ncol_sc)
1238 ALLOCATE (target_m(nrow_s, ncol_sc))
1241 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A,I3)') &
1242 "S_sc is saved to "//trim(filename_sc(icontact))//
" for contact", icontact
1243 IF (nspins == 1)
THEN
1246 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_sc is saved to "//trim(filename_hc_1(icontact))
1248 IF (nspins == 2)
THEN
1251 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_sc is saved to "//trim(filename_hc_1(icontact))//
" for spin 1"
1254 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_sc is saved to "//trim(filename_hc_2(icontact))//
" for spin 2"
1256 DEALLOCATE (target_m)
1259 negf_control%write_common_restart_file = .true.
1263 DEALLOCATE (filename_sc, filename_hc_1, filename_hc_2)
1264 CALL timestop(handle)
1265 END SUBROUTINE negf_env_scatt_read_write_hs
1276 SUBROUTINE negf_env_device_init_matrices(negf_env, negf_control, sub_env, qs_env)
1282 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_env_device_init_matrices'
1284 INTEGER :: handle, icontact, ispin, nao_c, nao_s, &
1286 LOGICAL :: do_kpoints
1289 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks_kp, matrix_s_kp
1297 CALL timeset(routinen, handle)
1299 IF (
ALLOCATED(negf_control%atomlist_S_screening))
THEN
1301 dft_control=dft_control, &
1302 do_kpoints=do_kpoints, &
1303 matrix_ks_kp=matrix_ks_kp, &
1304 matrix_s_kp=matrix_s_kp, &
1305 para_env=para_env, &
1308 CALL pw_env_get(pw_env, auxbas_pw_pool=pw_pool)
1310 IF (do_kpoints)
THEN
1311 CALL cp_abort(__location__, &
1312 "K-points in device region have not been implemented yet.")
1315 ncontacts =
SIZE(negf_control%contacts)
1316 nspins = dft_control%nspins
1322 NULLIFY (negf_env%s_s, negf_env%v_hartree_s, fm_struct)
1323 ALLOCATE (negf_env%h_s(nspins))
1325 CALL cp_fm_struct_create(fm_struct, nrow_global=nao_s, ncol_global=nao_s, context=sub_env%blacs_env)
1326 ALLOCATE (negf_env%s_s)
1328 DO ispin = 1, nspins
1331 ALLOCATE (negf_env%v_hartree_s)
1336 ALLOCATE (negf_env%h_sc(nspins, ncontacts), negf_env%s_sc(ncontacts))
1337 DO icontact = 1, ncontacts
1339 CALL cp_fm_struct_create(fm_struct, nrow_global=nao_s, ncol_global=nao_c, context=sub_env%blacs_env)
1343 DO ispin = 1, nspins
1344 CALL cp_fm_create(negf_env%h_sc(ispin, icontact), fm_struct)
1351 DO ispin = 1, nspins
1353 fm=negf_env%h_s(ispin), &
1354 atomlist_row=negf_control%atomlist_S_screening, &
1355 atomlist_col=negf_control%atomlist_S_screening, &
1356 subsys=subsys, mpi_comm_global=para_env, &
1357 do_upper_diag=.true., do_lower=.true.)
1362 atomlist_row=negf_control%atomlist_S_screening, &
1363 atomlist_col=negf_control%atomlist_S_screening, &
1364 subsys=subsys, mpi_comm_global=para_env, &
1365 do_upper_diag=.true., do_lower=.true.)
1368 NULLIFY (hmat%matrix)
1370 CALL dbcsr_copy(matrix_b=hmat%matrix, matrix_a=matrix_s_kp(1, 1)%matrix)
1373 CALL pw_pool%create_pw(v_hartree)
1374 CALL negf_env_init_v_hartree(v_hartree, negf_env%contacts, negf_control%contacts)
1376 CALL integrate_v_rspace(v_rspace=v_hartree, hmat=hmat, qs_env=qs_env, &
1377 calculate_forces=.false., compute_tau=.false., gapw=.false.)
1379 CALL pw_pool%give_back_pw(v_hartree)
1382 fm=negf_env%v_hartree_s, &
1383 atomlist_row=negf_control%atomlist_S_screening, &
1384 atomlist_col=negf_control%atomlist_S_screening, &
1385 subsys=subsys, mpi_comm_global=para_env, &
1386 do_upper_diag=.true., do_lower=.true.)
1391 DO icontact = 1, ncontacts
1392 DO ispin = 1, nspins
1394 fm=negf_env%h_sc(ispin, icontact), &
1395 atomlist_row=negf_control%atomlist_S_screening, &
1396 atomlist_col=negf_env%contacts(icontact)%atomlist_cell0, &
1397 subsys=subsys, mpi_comm_global=para_env, &
1398 do_upper_diag=.true., do_lower=.true.)
1402 fm=negf_env%s_sc(icontact), &
1403 atomlist_row=negf_control%atomlist_S_screening, &
1404 atomlist_col=negf_env%contacts(icontact)%atomlist_cell0, &
1405 subsys=subsys, mpi_comm_global=para_env, &
1406 do_upper_diag=.true., do_lower=.true.)
1410 CALL timestop(handle)
1411 END SUBROUTINE negf_env_device_init_matrices
1420 SUBROUTINE negf_env_init_v_hartree(v_hartree, contact_env, contact_control)
1423 INTENT(in) :: contact_env
1425 INTENT(in) :: contact_control
1427 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_env_init_v_hartree'
1428 REAL(kind=
dp),
PARAMETER :: threshold = 16.0_dp*epsilon(0.0_dp)
1430 INTEGER :: dx, dy, dz, handle, icontact, ix, iy, &
1431 iz, lx, ly, lz, ncontacts, ux, uy, uz
1432 REAL(kind=
dp) :: dvol, pot, proj, v1, v2
1433 REAL(kind=
dp),
DIMENSION(3) :: dirvector_bias, point_coord, &
1434 point_indices, vector
1436 CALL timeset(routinen, handle)
1438 ncontacts =
SIZE(contact_env)
1439 cpassert(
SIZE(contact_control) == ncontacts)
1440 cpassert(ncontacts == 2)
1442 dirvector_bias = contact_env(2)%origin_bias - contact_env(1)%origin_bias
1443 v1 = contact_control(1)%v_external
1444 v2 = contact_control(2)%v_external
1446 lx = v_hartree%pw_grid%bounds_local(1, 1)
1447 ux = v_hartree%pw_grid%bounds_local(2, 1)
1448 ly = v_hartree%pw_grid%bounds_local(1, 2)
1449 uy = v_hartree%pw_grid%bounds_local(2, 2)
1450 lz = v_hartree%pw_grid%bounds_local(1, 3)
1451 uz = v_hartree%pw_grid%bounds_local(2, 3)
1453 dx = v_hartree%pw_grid%npts(1)/2
1454 dy = v_hartree%pw_grid%npts(2)/2
1455 dz = v_hartree%pw_grid%npts(3)/2
1457 dvol = v_hartree%pw_grid%dvol
1460 point_indices(3) = real(iz + dz, kind=
dp)
1462 point_indices(2) = real(iy + dy, kind=
dp)
1465 point_indices(1) = real(ix + dx, kind=
dp)
1466 point_coord(:) = matmul(v_hartree%pw_grid%dh, point_indices)
1468 vector = point_coord - contact_env(1)%origin_bias
1470 IF (proj + threshold >= 0.0_dp .AND. proj - threshold <= 1.0_dp)
THEN
1474 IF (proj < 0.0_dp)
THEN
1476 ELSE IF (proj > 1.0_dp)
THEN
1479 pot = v1 + (v2 - v1)*proj
1482 DO icontact = 1, ncontacts
1483 vector = point_coord - contact_env(icontact)%origin_bias
1486 IF (proj + threshold >= 0.0_dp .AND. proj - threshold <= 1.0_dp)
THEN
1487 pot = contact_control(icontact)%v_external
1493 v_hartree%array(ix, iy, iz) = pot*dvol
1498 CALL timestop(handle)
1499 END SUBROUTINE negf_env_init_v_hartree
1510 FUNCTION contact_direction_axis(direction_vector, subsys_contact, eps_geometry)
RESULT(direction_axis)
1511 REAL(kind=
dp),
DIMENSION(3),
INTENT(in) :: direction_vector
1513 REAL(kind=
dp),
INTENT(in) :: eps_geometry
1514 INTEGER :: direction_axis
1517 REAL(kind=
dp),
DIMENSION(3) :: scaled
1527 IF (abs(scaled(i)) > eps_geometry)
THEN
1528 IF (scaled(i) > 0.0_dp)
THEN
1538 IF (naxes /= 1) direction_axis = 0
1539 END FUNCTION contact_direction_axis
1548 SUBROUTINE negf_homo_energy_estimate(homo_energy, qs_env)
1549 REAL(kind=
dp),
INTENT(out) :: homo_energy
1552 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_homo_energy_estimate'
1553 INTEGER,
PARAMETER :: gamma_point = 1
1555 INTEGER :: handle, homo, ikpgr, ikpoint, imo, &
1556 ispin, kplocal, nmo, nspins
1557 INTEGER,
DIMENSION(2) :: kp_range
1558 LOGICAL :: do_kpoints
1559 REAL(kind=
dp) :: my_homo_energy
1560 REAL(kind=
dp),
DIMENSION(:),
POINTER :: eigenvalues
1564 TYPE(
mo_set_type),
DIMENSION(:, :),
POINTER :: mos_kp
1567 CALL timeset(routinen, handle)
1568 my_homo_energy = 0.0_dp
1570 CALL get_qs_env(qs_env, para_env=para_env, mos=mos, kpoints=kpoints, do_kpoints=do_kpoints)
1572 IF (do_kpoints)
THEN
1573 CALL get_kpoint_info(kpoints, kp_env=kp_env, kp_range=kp_range, para_env_kp=para_env_kp)
1576 IF (para_env_kp%mepos == 0 .AND. kp_range(1) <= gamma_point .AND. kp_range(2) >= gamma_point)
THEN
1577 kplocal = kp_range(2) - kp_range(1) + 1
1579 DO ikpgr = 1, kplocal
1580 CALL get_kpoint_env(kp_env(ikpgr)%kpoint_env, nkpoint=ikpoint, mos=mos_kp)
1582 IF (ikpoint == gamma_point)
THEN
1584 CALL get_mo_set(mos_kp(1, 1), homo=homo, eigenvalues=eigenvalues)
1586 my_homo_energy = eigenvalues(homo)
1592 CALL para_env%sum(my_homo_energy)
1599 CALL cp_abort(__location__, &
1600 "It is necessary to use k-points along the transport direction "// &
1601 "for all contact FORCE_EVAL-s")
1606 spin_loop:
DO ispin = 1, nspins
1607 CALL get_mo_set(mos(ispin), homo=homo, nmo=nmo, eigenvalues=eigenvalues)
1610 IF (eigenvalues(imo) /= 0.0_dp)
EXIT spin_loop
1615 cpabort(
"Orbital transformation (OT) for contact FORCE_EVAL-s is not supported")
1618 my_homo_energy = eigenvalues(homo)
1621 homo_energy = my_homo_energy
1622 CALL timestop(handle)
1623 END SUBROUTINE negf_homo_energy_estimate
1639 SUBROUTINE list_atoms_in_bulk_primary_unit_cell(atomlist_cell0, atom_map_cell0, atomlist_bulk, atom_map, &
1640 origin, direction_vector, direction_axis, subsys_device)
1641 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(inout) :: atomlist_cell0
1643 DIMENSION(:),
INTENT(inout) :: atom_map_cell0
1644 INTEGER,
DIMENSION(:),
INTENT(in) :: atomlist_bulk
1646 REAL(kind=
dp),
DIMENSION(3),
INTENT(in) :: origin, direction_vector
1647 INTEGER,
INTENT(in) :: direction_axis
1650 CHARACTER(LEN=*),
PARAMETER :: routinen =
'list_atoms_in_bulk_primary_unit_cell'
1652 INTEGER :: atom_min, dir_axis_min, &
1653 direction_axis_abs, handle, iatom, &
1654 natoms_bulk, natoms_cell0
1655 REAL(kind=
dp) :: proj, proj_min
1656 REAL(kind=
dp),
DIMENSION(3) :: vector
1659 CALL timeset(routinen, handle)
1660 CALL qs_subsys_get(subsys_device, particle_set=particle_set)
1662 natoms_bulk =
SIZE(atomlist_bulk)
1663 cpassert(
SIZE(atom_map, 1) == natoms_bulk)
1664 direction_axis_abs = abs(direction_axis)
1669 DO iatom = 1, natoms_bulk
1670 vector = particle_set(atomlist_bulk(iatom))%r - origin
1673 IF (proj < proj_min)
THEN
1679 dir_axis_min = atom_map(atom_min)%cell(direction_axis_abs)
1682 DO iatom = 1, natoms_bulk
1683 IF (atom_map(iatom)%cell(direction_axis_abs) == dir_axis_min) &
1684 natoms_cell0 = natoms_cell0 + 1
1687 ALLOCATE (atomlist_cell0(natoms_cell0))
1688 ALLOCATE (atom_map_cell0(natoms_cell0))
1691 DO iatom = 1, natoms_bulk
1692 IF (atom_map(iatom)%cell(direction_axis_abs) == dir_axis_min)
THEN
1693 natoms_cell0 = natoms_cell0 + 1
1694 atomlist_cell0(natoms_cell0) = atomlist_bulk(iatom)
1695 atom_map_cell0(natoms_cell0) = atom_map(iatom)
1699 CALL timestop(handle)
1700 END SUBROUTINE list_atoms_in_bulk_primary_unit_cell
1719 SUBROUTINE list_atoms_in_bulk_secondary_unit_cell(atomlist_cell1, atom_map_cell1, atomlist_bulk, atom_map, &
1720 origin, direction_vector, direction_axis, subsys_device)
1721 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(inout) :: atomlist_cell1
1723 DIMENSION(:),
INTENT(inout) :: atom_map_cell1
1724 INTEGER,
DIMENSION(:),
INTENT(in) :: atomlist_bulk
1726 REAL(kind=
dp),
DIMENSION(3),
INTENT(in) :: origin, direction_vector
1727 INTEGER,
INTENT(in) :: direction_axis
1730 CHARACTER(LEN=*),
PARAMETER :: routinen =
'list_atoms_in_bulk_secondary_unit_cell'
1732 INTEGER :: atom_min, dir_axis_min, &
1733 direction_axis_abs, handle, iatom, &
1734 natoms_bulk, natoms_cell1, offset
1735 REAL(kind=
dp) :: proj, proj_min
1736 REAL(kind=
dp),
DIMENSION(3) :: vector
1739 CALL timeset(routinen, handle)
1740 CALL qs_subsys_get(subsys_device, particle_set=particle_set)
1742 natoms_bulk =
SIZE(atomlist_bulk)
1743 cpassert(
SIZE(atom_map, 1) == natoms_bulk)
1744 direction_axis_abs = abs(direction_axis)
1745 offset = sign(1, direction_axis)
1750 DO iatom = 1, natoms_bulk
1751 vector = particle_set(atomlist_bulk(iatom))%r - origin
1754 IF (proj < proj_min)
THEN
1760 dir_axis_min = atom_map(atom_min)%cell(direction_axis_abs)
1763 DO iatom = 1, natoms_bulk
1764 IF (atom_map(iatom)%cell(direction_axis_abs) == dir_axis_min + offset) &
1765 natoms_cell1 = natoms_cell1 + 1
1768 ALLOCATE (atomlist_cell1(natoms_cell1))
1769 ALLOCATE (atom_map_cell1(natoms_cell1))
1772 DO iatom = 1, natoms_bulk
1773 IF (atom_map(iatom)%cell(direction_axis_abs) == dir_axis_min + offset)
THEN
1774 natoms_cell1 = natoms_cell1 + 1
1775 atomlist_cell1(natoms_cell1) = atomlist_bulk(iatom)
1776 atom_map_cell1(natoms_cell1) = atom_map(iatom)
1777 atom_map_cell1(natoms_cell1)%cell(direction_axis_abs) = dir_axis_min
1781 CALL timestop(handle)
1782 END SUBROUTINE list_atoms_in_bulk_secondary_unit_cell
1793 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_env_release'
1795 INTEGER :: handle, icontact
1797 CALL timeset(routinen, handle)
1799 IF (
ALLOCATED(negf_env%contacts))
THEN
1800 DO icontact =
SIZE(negf_env%contacts), 1, -1
1801 CALL negf_env_contact_release(negf_env%contacts(icontact))
1804 DEALLOCATE (negf_env%contacts)
1814 IF (
ASSOCIATED(negf_env%s_s))
THEN
1816 DEALLOCATE (negf_env%s_s)
1817 NULLIFY (negf_env%s_s)
1824 IF (
ASSOCIATED(negf_env%v_hartree_s))
THEN
1826 DEALLOCATE (negf_env%v_hartree_s)
1827 NULLIFY (negf_env%v_hartree_s)
1831 IF (
ASSOCIATED(negf_env%mixing_storage))
THEN
1833 DEALLOCATE (negf_env%mixing_storage)
1836 CALL timestop(handle)
1843 SUBROUTINE negf_env_contact_release(contact_env)
1846 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_env_contact_release'
1850 CALL timeset(routinen, handle)
1865 IF (
ASSOCIATED(contact_env%s_00))
THEN
1867 DEALLOCATE (contact_env%s_00)
1868 NULLIFY (contact_env%s_00)
1872 IF (
ASSOCIATED(contact_env%s_01))
THEN
1874 DEALLOCATE (contact_env%s_01)
1875 NULLIFY (contact_env%s_01)
1878 IF (
ALLOCATED(contact_env%atomlist_cell0))
DEALLOCATE (contact_env%atomlist_cell0)
1879 IF (
ALLOCATED(contact_env%atomlist_cell1))
DEALLOCATE (contact_env%atomlist_cell1)
1880 IF (
ALLOCATED(contact_env%atom_map_cell0))
DEALLOCATE (contact_env%atom_map_cell0)
1882 CALL timestop(handle)
1883 END SUBROUTINE negf_env_contact_release
Handles all functions related to the CELL.
subroutine, public real_to_scaled(s, r, cell)
Transform real to scaled cell coordinates. s=h_inv*r.
methods related to the blacs parallel environment
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_set(matrix, alpha)
...
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.
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_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp, nrow, ncol, set_zero)
creates a new full matrix with the given structure
subroutine, public cp_fm_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_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 ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
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
integer, parameter, public use_qs_force
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_env(kpoint_env, nkpoint, wkp, xkp, is_local, mos)
Get information from a single kpoint environment.
subroutine, public get_kpoint_info(kpoint, kp_scheme, nkp_grid, kp_shift, symmetry, verbose, full_grid, use_real_wfn, eps_geo, parallel_group_size, kp_range, nkp, xkp, wkp, para_env, blacs_env_all, para_env_kp, para_env_inter_kp, blacs_env, kp_env, kp_aux_env, mpools, iogrp, nkp_groups, kp_dist, cell_to_index, index_to_cell, sab_nl, sab_nl_nosym)
Retrieve information from a kpoint environment.
Interface to the message passing library MPI.
Map atoms between various force environments.
subroutine, public negf_map_atomic_indices(atom_map, atom_list, subsys_device, subsys_contact, eps_geometry)
Map atoms in the cell 'subsys_device' listed in 'atom_list' with the corresponding atoms in the cell ...
Input control types for NEGF based quantum transport calculations.
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.
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)
Checks if the restart file exists and returns the filename.
subroutine, public negf_print_matrix_to_file(filename, matrix)
Prints full matrix to a file.
subroutine, public negf_read_matrix_from_file(filename, matrix)
Reads full matrix from a file.
Helper routines to manipulate with matrices.
integer function, public number_of_atomic_orbitals(subsys, atom_list)
Compute the number of atomic orbitals of the given set of atoms.
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_contact_matrix(fm_cell0, fm_cell1, direction_axis, matrix_kp, atom_list0, atom_list1, subsys, mpi_comm_global, kpoints)
Driver routine to extract diagonal and off-diagonal blocks from a symmetric DBCSR matrix.
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.
Environment for NEGF based quantum transport calculations.
Routines to deal with vectors in 3-D real space.
pure real(kind=dp) function, public projection_on_direction_vector(vector, vector0)
project the 'vector' onto the direction 'vector0'. Both vectors should have the same origin.
subroutine, public contact_direction_vector(origin, direction_vector, origin_bias, direction_vector_bias, atomlist_screening, atomlist_bulk, subsys)
compute direction vector of the given contact
Define the data structure for the particle information.
container for various plainwaves related things
subroutine, public pw_env_get(pw_env, pw_pools, cube_info, gridlevel_info, auxbas_pw_pool, auxbas_grid, auxbas_rs_desc, auxbas_rs_grid, rs_descs, rs_grids, xc_pw_pool, vdw_pw_pool, poisson_env, interp_section)
returns the various attributes of the pw env
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
module that contains the definitions of the scf types
subroutine, public mixing_storage_release(mixing_store)
releases a mixing_storage
subroutine, public mixing_storage_create(mixing_store, mixing_section, mixing_method, ecut)
creates a mixing_storage
Utility subroutine for qs energy calculation.
subroutine, public qs_energies_init(qs_env, calc_forces)
Refactoring of qs_energies_scf. Driver routine for the initial setup and calculations for a qs energy...
Perform a QUICKSTEP wavefunction optimization (single point)
subroutine, public qs_energies(qs_env, consistent_energies, calc_forces)
Driver routine for QUICKSTEP single point wavefunction optimization.
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Integrate single or product functions over a potential on a RS grid.
Definition and initialisation of the mo data type.
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kts, mu, flexible_electron_count)
Get the components of a MO set data structure.
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...
types that represent a quickstep subsys
subroutine, public qs_subsys_get(subsys, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell, cell_ref, use_ref_cell, energy, force, qs_kind_set, cp_subsys, nelectron_total, nelectron_spin)
...
Type defining parameters related to the simulation cell.
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
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...
allows for the creation of an array of force_env
wrapper to abstract the force evaluation of the various methods
Contains information about kpoints.
stores all the informations relevant to an mpi environment
Structure that maps the given atom in the sourse FORCE_EVAL section with another atom from the target...
Input parameters related to the NEGF run.
Parallel (sub)group environment.
contained for different pw related things
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
keeps the density in various representations, keeping track of which ones are valid.