83#include "./base/base_uses.f90"
88 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'negf_env_types'
89 LOGICAL,
PARAMETER,
PRIVATE :: debug_this_module = .true.
99 REAL(kind=
dp),
DIMENSION(3) :: direction_vector = -1.0_dp, origin = -1.0_dp
100 REAL(kind=
dp),
DIMENSION(3) :: direction_vector_bias = -1.0_dp, origin_bias = -1.0_dp
103 INTEGER :: direction_axis = -1
105 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atomlist_cell0
107 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atomlist_cell1
110 DIMENSION(:) :: atom_map_cell0, atom_map_cell1
112 REAL(kind=
dp) :: fermi_energy = 0.0_dp
114 REAL(kind=
dp) :: homo_energy = -1.0_dp
116 REAL(kind=
dp) :: nelectrons_qs_cell0 = 0.0_dp
118 REAL(kind=
dp) :: nelectrons_qs_cell1 = 0.0_dp
123 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: rho_00, rho_01
135 DIMENSION(:) :: contacts
149 INTEGER :: mixing_method = -1
151 REAL(kind=
dp) :: nelectrons_ref = 0.0_dp
153 REAL(kind=
dp) :: nelectrons = 0.0_dp
160 TYPE negf_atom_map_contact_type
162 END TYPE negf_atom_map_contact_type
177 SUBROUTINE negf_env_create(negf_env, sub_env, negf_control, force_env, negf_mixing_section, log_unit)
183 INTEGER,
INTENT(in) :: log_unit
185 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_env_create'
187 CHARACTER(len=default_string_length) :: contact_str, force_env_str, &
189 INTEGER :: handle, icontact, in_use, n_force_env, &
191 LOGICAL :: do_kpoints, is_dft_entire
193 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks_kp, matrix_s_kp
197 TYPE(negf_atom_map_contact_type),
ALLOCATABLE, &
198 DIMENSION(:) :: map_contact
204 CALL timeset(routinen, handle)
207 NULLIFY (sub_force_env)
208 CALL force_env_get(force_env, in_use=in_use, qs_env=qs_env, root_section=root_section, &
209 sub_force_env=sub_force_env)
211 IF (
ASSOCIATED(sub_force_env))
THEN
212 n_force_env =
SIZE(sub_force_env)
218 DO icontact = 1, n_force_env
219 CALL force_env_get(sub_force_env(icontact)%force_env, in_use=in_use)
225 cpabort(
"Quickstep is required for NEGF run.")
229 ncontacts =
SIZE(negf_control%contacts)
231 DO icontact = 1, ncontacts
232 IF (negf_control%contacts(icontact)%force_env_index > n_force_env)
THEN
233 WRITE (contact_str,
'(I11)') icontact
234 WRITE (force_env_str,
'(I11)') negf_control%contacts(icontact)%force_env_index
235 WRITE (n_force_env_str,
'(I11)') n_force_env
237 CALL cp_abort(__location__, &
238 "Contact number "//trim(adjustl(contact_str))//
" is linked with the FORCE_EVAL section number "// &
239 trim(adjustl(force_env_str))//
", however only "//trim(adjustl(n_force_env_str))// &
240 " FORCE_EVAL sections have been found. Note that FORCE_EVAL sections are enumerated from 0"// &
241 " and that the primary (0-th) section must contain all the atoms.")
248 CALL get_qs_env(qs_env, blacs_env=blacs_env, do_kpoints=do_kpoints, &
249 matrix_s_kp=matrix_s_kp, matrix_ks_kp=matrix_ks_kp, &
250 para_env=para_env, subsys=subsys, v_hartree_rspace=v_hartree_rspace)
255 cpabort(
"k-points are currently not supported for device FORCE_EVAL")
259 ALLOCATE (negf_env%contacts(ncontacts))
260 ALLOCATE (map_contact(ncontacts))
262 DO icontact = 1, ncontacts
263 IF (negf_control%contacts(icontact)%force_env_index > 0)
THEN
264 CALL force_env_get(sub_force_env(negf_control%contacts(icontact)%force_env_index)%force_env, qs_env=qs_env_contact)
265 CALL get_qs_env(qs_env_contact, subsys=subsys_contact)
267 CALL negf_env_contact_init_maps(contact_env=negf_env%contacts(icontact), &
268 contact_control=negf_control%contacts(icontact), &
269 atom_map=map_contact(icontact)%atom_map, &
270 eps_geometry=negf_control%eps_geometry, &
271 subsys_device=subsys, &
272 subsys_contact=subsys_contact)
274 IF (negf_env%contacts(icontact)%direction_axis == 0)
THEN
275 WRITE (contact_str,
'(I11)') icontact
276 WRITE (force_env_str,
'(I11)') negf_control%contacts(icontact)%force_env_index
277 CALL cp_abort(__location__, &
278 "One lattice vector of the contact unit cell (FORCE_EVAL section "// &
279 trim(adjustl(force_env_str))//
") must be parallel to the direction of the contact "// &
280 trim(adjustl(contact_str))//
".")
286 DO icontact = 1, ncontacts
287 IF (negf_control%contacts(icontact)%force_env_index > 0)
THEN
288 IF (negf_control%contacts(icontact)%read_write_HS)
THEN
289 CALL negf_env_contact_read_write_hs &
290 (icontact, sub_force_env(negf_control%contacts(icontact)%force_env_index)%force_env, &
291 para_env, negf_env, sub_env, negf_control, negf_section, log_unit, is_separate=.true.)
293 IF (log_unit > 0)
THEN
294 WRITE (log_unit,
'(/,T2,A,T70,I11,/,A)')
"NEGF| Construct the Kohn-Sham matrix for the contact", icontact, &
295 " from the separate bulk DFT calculation"
297 CALL force_env_get(sub_force_env(negf_control%contacts(icontact)%force_env_index)%force_env, qs_env=qs_env_contact)
298 CALL qs_energies(qs_env_contact, consistent_energies=.false., calc_forces=.false.)
299 CALL negf_env_contact_init_matrices(contact_env=negf_env%contacts(icontact), sub_env=sub_env, &
300 qs_env_contact=qs_env_contact)
301 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,79("-"))')
307 is_dft_entire = .false.
308 DO icontact = 1, ncontacts
309 IF (negf_control%contacts(icontact)%force_env_index <= 0)
THEN
310 IF (negf_control%contacts(icontact)%read_write_HS)
THEN
311 CALL negf_env_contact_init_matrices_gamma(contact_env=negf_env%contacts(icontact), &
312 contact_control=negf_control%contacts(icontact), &
313 sub_env=sub_env, qs_env=qs_env, &
314 eps_geometry=negf_control%eps_geometry)
315 CALL negf_env_contact_read_write_hs(icontact, force_env, para_env, negf_env, sub_env, negf_control, negf_section, &
316 log_unit, is_separate=.false., is_dft_entire=is_dft_entire)
318 IF (log_unit > 0)
THEN
319 WRITE (log_unit,
'(/,T2,A,T70,I11,/,A)')
"NEGF| Construct the Kohn-Sham matrix for the contact", icontact, &
320 " from the entire system bulk DFT calculation"
322 IF (.NOT. is_dft_entire)
CALL qs_energies(qs_env, consistent_energies=.false., calc_forces=.false.)
323 is_dft_entire = .true.
324 CALL negf_env_contact_init_matrices_gamma(contact_env=negf_env%contacts(icontact), &
325 contact_control=negf_control%contacts(icontact), &
326 sub_env=sub_env, qs_env=qs_env, &
327 eps_geometry=negf_control%eps_geometry)
328 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,79("-"))')
334 IF (log_unit > 0)
THEN
335 WRITE (log_unit,
'(/,T2,A,T70)')
"NEGF| Construct the Kohn-Sham matrix for the scattering region"
337 IF (negf_control%read_write_HS)
THEN
338 CALL negf_env_scatt_read_write_hs(force_env, para_env, negf_env, sub_env, negf_control, negf_section, log_unit, &
339 is_dft_entire=is_dft_entire)
341 IF (.NOT. is_dft_entire)
THEN
342 CALL qs_energies(qs_env, consistent_energies=.false., calc_forces=.false.)
343 is_dft_entire = .true.
346 CALL negf_env_device_init_matrices(negf_env, negf_control, sub_env, qs_env)
348 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,79("-"))')
350 negf_control%is_dft_entire = is_dft_entire
354 NULLIFY (negf_env%mixing_storage)
357 CALL get_qs_env(qs_env, dft_control=dft_control)
358 ALLOCATE (negf_env%mixing_storage)
360 negf_env%mixing_method, dft_control%qs_control%cutoff)
362 CALL timestop(handle)
375 SUBROUTINE negf_env_contact_init_maps(contact_env, contact_control, atom_map, &
376 eps_geometry, subsys_device, subsys_contact)
380 DIMENSION(:),
INTENT(inout) :: atom_map
381 REAL(kind=
dp),
INTENT(in) :: eps_geometry
384 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_env_contact_init_maps'
386 INTEGER :: handle, natoms
388 CALL timeset(routinen, handle)
391 contact_env%direction_vector, &
392 contact_env%origin_bias, &
393 contact_env%direction_vector_bias, &
394 contact_control%atomlist_screening, &
395 contact_control%atomlist_bulk, &
398 contact_env%direction_axis = contact_direction_axis(contact_env%direction_vector, subsys_contact, eps_geometry)
400 IF (contact_env%direction_axis /= 0)
THEN
401 natoms =
SIZE(contact_control%atomlist_bulk)
402 ALLOCATE (atom_map(natoms))
406 atom_list=contact_control%atomlist_bulk, &
407 subsys_device=subsys_device, &
408 subsys_contact=subsys_contact, &
409 eps_geometry=eps_geometry)
413 CALL list_atoms_in_bulk_primary_unit_cell(atomlist_cell0=contact_env%atomlist_cell0, &
414 atom_map_cell0=contact_env%atom_map_cell0, &
415 atomlist_bulk=contact_control%atomlist_bulk, &
417 origin=contact_env%origin, &
418 direction_vector=contact_env%direction_vector, &
419 direction_axis=contact_env%direction_axis, &
420 subsys_device=subsys_device)
423 CALL list_atoms_in_bulk_secondary_unit_cell(atomlist_cell1=contact_env%atomlist_cell1, &
424 atom_map_cell1=contact_env%atom_map_cell1, &
425 atomlist_bulk=contact_control%atomlist_bulk, &
427 origin=contact_env%origin, &
428 direction_vector=contact_env%direction_vector, &
429 direction_axis=contact_env%direction_axis, &
430 subsys_device=subsys_device)
433 CALL timestop(handle)
434 END SUBROUTINE negf_env_contact_init_maps
451 SUBROUTINE negf_env_contact_read_write_hs(icontact, el_force_env, para_env, negf_env, sub_env, negf_control, &
452 negf_section, log_unit, is_separate, is_dft_entire)
460 INTEGER,
INTENT(in) :: log_unit
461 LOGICAL,
INTENT(in) :: is_separate
462 LOGICAL,
INTENT(inout),
OPTIONAL :: is_dft_entire
464 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_env_contact_read_write_hs'
466 CHARACTER(len=default_path_length) :: filename_h00_1, filename_h00_2, &
467 filename_h01_1, filename_h01_2, &
468 filename_s00, filename_s01
469 INTEGER :: handle, ispin, ncol, nrow, nspins, &
471 LOGICAL :: exist, exist_all
472 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: target_m
479 CALL timeset(routinen, handle)
483 CALL get_qs_env(qs_env_contact, dft_control=dft_control, subsys=subsys)
484 nspins = dft_control%nspins
486 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,A,T70,I11)') &
487 "NEGF| Construct the Kohn-Sham matrix for the contact", icontact
492 IF (para_env%is_source())
THEN
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_s00)//
". This file does not exist. The file will be created.")
501 IF (.NOT. exist)
THEN
502 CALL cp_warn(__location__, &
503 "User requested to read the overlap matrix from the file named: "// &
504 trim(filename_s01)//
". This file does not exist. The file will be created.")
507 IF (nspins == 1)
THEN
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_h00_1)//
". This file does not exist. The file will be created.")
516 IF (.NOT. exist)
THEN
517 CALL cp_warn(__location__, &
518 "User requested to read the Hamiltonian matrix from the file named: "// &
519 trim(filename_h01_1)//
". This file does not exist. The file will be created.")
523 IF (nspins == 2)
THEN
525 IF (.NOT. exist)
THEN
526 CALL cp_warn(__location__, &
527 "User requested to read the Hamiltonian matrix from the file named: "// &
528 trim(filename_h00_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 tthe Hamiltonian matrix from the file named: "// &
535 trim(filename_h01_1)//
". 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_h00_2)//
". This file does not exist. The file will be created.")
546 IF (.NOT. exist)
THEN
547 CALL cp_warn(__location__, &
548 "User requested to read the Hamiltonian matrix from the file named: "// &
549 trim(filename_h01_2)//
". This file does not exist. The file will be created.")
554 CALL para_env%bcast(exist_all)
558 negf_control%contacts(icontact)%is_restart = .true.
559 IF (log_unit > 0)
THEN
560 WRITE (log_unit,
'(/,T2,A)')
"User requested to read the Hamiltonian and overlap matrices from files."
561 WRITE (log_unit,
'(T2,A)')
"All restart files exist."
565 IF (para_env%is_source())
THEN
566 CALL open_file(file_name=filename_s00, file_status=
"OLD", &
567 file_form=
"FORMATTED", file_action=
"READ", &
568 file_position=
"REWIND", unit_number=print_unit)
569 READ (print_unit, *) nrow, ncol
572 CALL para_env%bcast(nrow)
573 CALL para_env%bcast(ncol)
575 CALL cp_fm_struct_create(fm_struct, nrow_global=nrow, ncol_global=ncol, context=sub_env%blacs_env)
576 ALLOCATE (negf_env%contacts(icontact)%s_00, negf_env%contacts(icontact)%s_01)
577 CALL cp_fm_create(negf_env%contacts(icontact)%s_00, fm_struct)
578 CALL cp_fm_create(negf_env%contacts(icontact)%s_01, fm_struct)
579 ALLOCATE (negf_env%contacts(icontact)%h_00(nspins), negf_env%contacts(icontact)%h_01(nspins))
581 CALL cp_fm_create(negf_env%contacts(icontact)%h_00(ispin), fm_struct)
582 CALL cp_fm_create(negf_env%contacts(icontact)%h_01(ispin), fm_struct)
586 ALLOCATE (target_m(nrow, ncol))
588 CALL para_env%bcast(target_m)
590 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"S_00 is read from "//trim(filename_s00)
592 CALL para_env%bcast(target_m)
594 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"S_01 is read from "//trim(filename_s01)
595 IF (nspins == 1)
THEN
597 CALL para_env%bcast(target_m)
599 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_00 is read from "//trim(filename_h00_1)
601 CALL para_env%bcast(target_m)
603 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_01 is read from "//trim(filename_h01_1)
605 IF (nspins == 2)
THEN
607 CALL para_env%bcast(target_m)
609 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_00 is read from "//trim(filename_h00_1)//
" for spin 1"
611 CALL para_env%bcast(target_m)
613 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_01 is read from "//trim(filename_h01_1)//
" for spin 1"
615 CALL para_env%bcast(target_m)
617 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_00 is read from "//trim(filename_h00_2)//
" for spin 2"
619 CALL para_env%bcast(target_m)
621 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_01 is read from "//trim(filename_h01_2)//
" for spin 2"
623 DEALLOCATE (target_m)
627 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)') &
628 "Some restart files do not exist. ALL restart files will be recalculated!"
630 IF (is_separate)
THEN
631 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,A,T70,I11,/,A)') &
632 "Construct the Kohn-Sham matrix from from the separate bulk DFT calculation"
633 CALL qs_energies(qs_env_contact, consistent_energies=.false., calc_forces=.false.)
634 CALL negf_env_contact_init_matrices(contact_env=negf_env%contacts(icontact), sub_env=sub_env, &
635 qs_env_contact=qs_env_contact)
637 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,A,T70,I11,/,A)') &
638 "Construct the Kohn-Sham matrix from the entire system bulk DFT calculation"
639 negf_control%contacts(icontact)%read_write_HS = .false.
640 IF (.NOT. is_dft_entire)
CALL qs_energies(qs_env_contact, consistent_energies=.false., calc_forces=.false.)
641 CALL negf_env_contact_init_matrices_gamma(contact_env=negf_env%contacts(icontact), &
642 contact_control=negf_control%contacts(icontact), &
643 sub_env=sub_env, qs_env=qs_env_contact, &
644 eps_geometry=negf_control%eps_geometry)
645 negf_control%contacts(icontact)%read_write_HS = .true.
646 is_dft_entire = .true.
649 CALL cp_fm_get_info(negf_env%contacts(icontact)%s_00, nrow_global=nrow)
650 ALLOCATE (target_m(nrow, nrow))
653 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,A)')
"S_00 is saved to "//trim(filename_s00)
656 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"S_01 is saved to "//trim(filename_s01)
657 IF (nspins == 1)
THEN
660 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_00 is saved to "//trim(filename_h00_1)
663 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_01 is saved to "//trim(filename_h01_1)
665 IF (nspins == 2)
THEN
668 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_00 is saved to "//trim(filename_h00_1)//
" for spin 1"
671 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_01 is saved to "//trim(filename_h01_1)//
" for spin 1"
674 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_00 is saved to "//trim(filename_h00_2)//
" for spin 2"
677 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_01 is saved to "//trim(filename_h01_2)//
" for spin 2"
679 DEALLOCATE (target_m)
681 negf_control%write_common_restart_file = .true.
685 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,79("-"))')
687 CALL timestop(handle)
688 END SUBROUTINE negf_env_contact_read_write_hs
700 SUBROUTINE negf_env_contact_init_matrices(contact_env, sub_env, qs_env_contact)
705 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_env_contact_init_matrices'
707 INTEGER :: handle, iatom, ispin, nao, natoms, &
709 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_list0, atom_list1
710 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: index_to_cell
711 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index
712 LOGICAL :: do_kpoints
715 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks_kp, matrix_s_kp, rho_ao_kp
722 CALL timeset(routinen, handle)
725 dft_control=dft_control, &
726 do_kpoints=do_kpoints, &
728 matrix_ks_kp=matrix_ks_kp, &
729 matrix_s_kp=matrix_s_kp, &
733 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_kp)
735 CALL negf_homo_energy_estimate(contact_env%homo_energy, qs_env_contact)
737 natoms =
SIZE(contact_env%atomlist_cell0)
738 ALLOCATE (atom_list0(natoms))
740 atom_list0(iatom) = contact_env%atom_map_cell0(iatom)%iatom
744 IF (sum(abs(contact_env%atom_map_cell0(iatom)%cell(:))) > 0)
THEN
745 cpabort(
"NEGF K-points are not currently supported")
749 cpassert(
SIZE(contact_env%atomlist_cell1) == natoms)
750 ALLOCATE (atom_list1(natoms))
752 atom_list1(iatom) = contact_env%atom_map_cell1(iatom)%iatom
755 nspins = dft_control%nspins
756 nimages = dft_control%nimages
761 ALLOCATE (cell_to_index(0:0, 0:0, 0:0))
762 cell_to_index(0, 0, 0) = 1
765 ALLOCATE (index_to_cell(3, nimages))
767 IF (.NOT. do_kpoints)
DEALLOCATE (cell_to_index)
771 CALL cp_fm_struct_create(fm_struct, nrow_global=nao, ncol_global=nao, context=sub_env%blacs_env)
774 ALLOCATE (contact_env%s_00, contact_env%s_01)
779 ALLOCATE (contact_env%h_00(nspins), contact_env%h_01(nspins))
780 ALLOCATE (contact_env%rho_00(nspins), contact_env%rho_01(nspins))
791 matkp => matrix_s_kp(1, :)
793 fm_cell1=contact_env%s_01, &
794 direction_axis=contact_env%direction_axis, &
796 atom_list0=atom_list0, atom_list1=atom_list1, &
797 subsys=subsys, mpi_comm_global=para_env, &
802 matkp => matrix_ks_kp(ispin, :)
804 fm_cell1=contact_env%h_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, &
811 matkp => rho_ao_kp(ispin, :)
813 fm_cell1=contact_env%rho_01(ispin), &
814 direction_axis=contact_env%direction_axis, &
816 atom_list0=atom_list0, atom_list1=atom_list1, &
817 subsys=subsys, mpi_comm_global=para_env, &
821 DEALLOCATE (atom_list0, atom_list1)
823 CALL timestop(handle)
824 END SUBROUTINE negf_env_contact_init_matrices
835 SUBROUTINE negf_env_contact_init_matrices_gamma(contact_env, contact_control, sub_env, qs_env, eps_geometry)
840 REAL(kind=
dp),
INTENT(in) :: eps_geometry
842 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_env_contact_init_matrices_gamma'
844 INTEGER :: handle, iatom, icell, ispin, nao_c, &
846 LOGICAL :: do_kpoints
847 REAL(kind=
dp),
DIMENSION(2) :: r2_origin_cell
848 REAL(kind=
dp),
DIMENSION(3) :: direction_vector, origin
850 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks_kp, matrix_s_kp, rho_ao_kp
857 CALL timeset(routinen, handle)
860 dft_control=dft_control, &
861 do_kpoints=do_kpoints, &
862 matrix_ks_kp=matrix_ks_kp, &
863 matrix_s_kp=matrix_s_kp, &
867 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_kp)
870 CALL cp_abort(__location__, &
871 "K-points in device region have not been implemented yet.")
874 nspins = dft_control%nspins
878 CALL cp_abort(__location__, &
879 "Primary and secondary bulk contact cells should be identical "// &
880 "in terms of the number of atoms of each kind, and their basis sets. "// &
881 "No single atom, however, can be shared between these two cells.")
884 contact_env%homo_energy = 0.0_dp
887 contact_env%direction_vector, &
888 contact_env%origin_bias, &
889 contact_env%direction_vector_bias, &
890 contact_control%atomlist_screening, &
891 contact_control%atomlist_bulk, &
894 contact_env%direction_axis = contact_direction_axis(contact_env%direction_vector, subsys, eps_geometry)
899 origin = particle_set(contact_control%atomlist_screening(1))%r
900 DO iatom = 2,
SIZE(contact_control%atomlist_screening)
901 origin = origin + particle_set(contact_control%atomlist_screening(iatom))%r
903 origin = origin/real(
SIZE(contact_control%atomlist_screening), kind=
dp)
906 direction_vector = particle_set(contact_control%atomlist_cell(icell)%vector(1))%r
907 DO iatom = 2,
SIZE(contact_control%atomlist_cell(icell)%vector)
908 direction_vector = direction_vector + particle_set(contact_control%atomlist_cell(icell)%vector(iatom))%r
910 direction_vector = direction_vector/real(
SIZE(contact_control%atomlist_cell(icell)%vector), kind=
dp)
911 direction_vector = direction_vector - origin
912 r2_origin_cell(icell) = dot_product(direction_vector, direction_vector)
915 IF (abs(r2_origin_cell(1) - r2_origin_cell(2)) < (eps_geometry*eps_geometry))
THEN
918 CALL cp_abort(__location__, &
919 "Primary and secondary bulk contact cells should not overlap ")
920 ELSE IF (r2_origin_cell(1) < r2_origin_cell(2))
THEN
921 IF (.NOT.
ALLOCATED(contact_env%atomlist_cell0))
THEN
922 ALLOCATE (contact_env%atomlist_cell0(
SIZE(contact_control%atomlist_cell(1)%vector)))
924 contact_env%atomlist_cell0(:) = contact_control%atomlist_cell(1)%vector(:)
925 IF (.NOT.
ALLOCATED(contact_env%atomlist_cell1))
THEN
926 ALLOCATE (contact_env%atomlist_cell1(
SIZE(contact_control%atomlist_cell(2)%vector)))
928 contact_env%atomlist_cell1(:) = contact_control%atomlist_cell(2)%vector(:)
930 IF (.NOT.
ALLOCATED(contact_env%atomlist_cell0))
THEN
931 ALLOCATE (contact_env%atomlist_cell0(
SIZE(contact_control%atomlist_cell(2)%vector)))
933 contact_env%atomlist_cell0(:) = contact_control%atomlist_cell(2)%vector(:)
934 IF (.NOT.
ALLOCATED(contact_env%atomlist_cell1))
THEN
935 ALLOCATE (contact_env%atomlist_cell1(
SIZE(contact_control%atomlist_cell(1)%vector)))
937 contact_env%atomlist_cell1(:) = contact_control%atomlist_cell(1)%vector(:)
939 IF (.NOT. contact_control%read_write_HS)
THEN
941 CALL cp_fm_struct_create(fm_struct, nrow_global=nao_c, ncol_global=nao_c, context=sub_env%blacs_env)
942 ALLOCATE (contact_env%h_00(nspins), contact_env%h_01(nspins))
943 ALLOCATE (contact_env%rho_00(nspins), contact_env%rho_01(nspins))
950 ALLOCATE (contact_env%s_00, contact_env%s_01)
957 fm=contact_env%h_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%h_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.)
970 fm=contact_env%rho_00(ispin), &
971 atomlist_row=contact_env%atomlist_cell0, &
972 atomlist_col=contact_env%atomlist_cell0, &
973 subsys=subsys, mpi_comm_global=para_env, &
974 do_upper_diag=.true., do_lower=.true.)
976 fm=contact_env%rho_01(ispin), &
977 atomlist_row=contact_env%atomlist_cell0, &
978 atomlist_col=contact_env%atomlist_cell1, &
979 subsys=subsys, mpi_comm_global=para_env, &
980 do_upper_diag=.true., do_lower=.true.)
984 fm=contact_env%s_00, &
985 atomlist_row=contact_env%atomlist_cell0, &
986 atomlist_col=contact_env%atomlist_cell0, &
987 subsys=subsys, mpi_comm_global=para_env, &
988 do_upper_diag=.true., do_lower=.true.)
990 fm=contact_env%s_01, &
991 atomlist_row=contact_env%atomlist_cell0, &
992 atomlist_col=contact_env%atomlist_cell1, &
993 subsys=subsys, mpi_comm_global=para_env, &
994 do_upper_diag=.true., do_lower=.true.)
996 CALL timestop(handle)
997 END SUBROUTINE negf_env_contact_init_matrices_gamma
1012 SUBROUTINE negf_env_scatt_read_write_hs(force_env, para_env, negf_env, sub_env, negf_control, negf_section, &
1013 log_unit, is_dft_entire)
1020 INTEGER,
INTENT(in) :: log_unit
1021 LOGICAL,
INTENT(inout),
OPTIONAL :: is_dft_entire
1023 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_env_scatt_read_write_hs'
1025 CHARACTER(len=default_path_length) :: filename_h_1, filename_h_2, filename_s
1026 CHARACTER(len=default_path_length),
ALLOCATABLE, &
1027 DIMENSION(:) :: filename_hc_1, filename_hc_2, filename_sc
1028 INTEGER :: handle, icontact, ispin, ncol_s, &
1029 ncol_sc, ncontacts, nrow_s, nrow_sc, &
1031 LOGICAL :: exist, exist_all
1032 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: target_m
1039 CALL timeset(routinen, handle)
1043 CALL get_qs_env(qs_env, dft_control=dft_control, subsys=subsys)
1044 ncontacts =
SIZE(negf_control%contacts)
1045 nspins = dft_control%nspins
1046 ALLOCATE (filename_sc(ncontacts), filename_hc_1(ncontacts), filename_hc_2(ncontacts))
1051 IF (para_env%is_source())
THEN
1053 IF (.NOT. exist)
THEN
1054 CALL cp_warn(__location__, &
1055 "User requested to read the overlap matrix from the file named: "// &
1056 trim(filename_s)//
". This file does not exist. The file will be created.")
1059 IF (nspins == 1)
THEN
1061 IF (.NOT. exist)
THEN
1062 CALL cp_warn(__location__, &
1063 "User requested to read the Hamiltonian matrix from the file named: "// &
1064 trim(filename_h_1)//
". This file does not exist. The file will be created.")
1068 IF (nspins == 2)
THEN
1070 IF (.NOT. exist)
THEN
1071 CALL cp_warn(__location__, &
1072 "User requested to read the Hamiltonian matrix from the file named: "// &
1073 trim(filename_h_1)//
". This file does not exist. The file will be created.")
1077 IF (.NOT. exist)
THEN
1078 CALL cp_warn(__location__, &
1079 "User requested to read the Hamiltonian matrix from the file named: "// &
1080 trim(filename_h_2)//
". This file does not exist. The file will be created.")
1084 DO icontact = 1, ncontacts
1085 CALL negf_restart_file_name(filename_sc(icontact), exist, negf_section, logger, icontact=icontact, sc=.true.)
1086 IF (.NOT. exist)
THEN
1087 CALL cp_warn(__location__, &
1088 "User requested to read the overlap matrix from the file named: "// &
1089 trim(filename_sc(icontact))//
". This file does not exist. The file will be created.")
1092 IF (nspins == 1)
THEN
1095 IF (.NOT. exist)
THEN
1096 CALL cp_warn(__location__, &
1097 "User requested to read the Hamiltonian matrix from the file named: "// &
1098 trim(filename_hc_1(icontact))//
". This file does not exist. The file will be created.")
1102 IF (nspins == 2)
THEN
1105 IF (.NOT. exist)
THEN
1106 CALL cp_warn(__location__, &
1107 "User requested to read the Hamiltonian matrix from the file named: "// &
1108 trim(filename_hc_1(icontact))//
". This file does not exist. The file will be created.")
1113 IF (.NOT. exist)
THEN
1114 CALL cp_warn(__location__, &
1115 "User requested to read the Hamiltonian matrix from the file named: "// &
1116 trim(filename_hc_2(icontact))//
". This file does not exist. The file will be created.")
1122 CALL para_env%bcast(exist_all)
1126 negf_control%is_restart = .true.
1128 IF (log_unit > 0)
THEN
1129 WRITE (log_unit,
'(/,T2,A)')
"User requested to read the Hamiltonian and overlap matrices from files."
1130 WRITE (log_unit,
'(T2,A)')
"All restart files exist."
1134 IF (para_env%is_source())
THEN
1135 CALL open_file(file_name=filename_s, file_status=
"OLD", &
1136 file_form=
"FORMATTED", file_action=
"READ", &
1137 file_position=
"REWIND", unit_number=print_unit)
1138 READ (print_unit, *) nrow_s, ncol_s
1141 CALL para_env%bcast(nrow_s)
1142 CALL para_env%bcast(ncol_s)
1144 CALL cp_fm_struct_create(fm_struct, nrow_global=nrow_s, ncol_global=ncol_s, context=sub_env%blacs_env)
1145 ALLOCATE (negf_env%s_s)
1147 ALLOCATE (negf_env%h_s(nspins))
1148 DO ispin = 1, nspins
1152 ALLOCATE (negf_env%s_sc(ncontacts))
1153 ALLOCATE (negf_env%h_sc(nspins, ncontacts))
1154 DO icontact = 1, ncontacts
1155 IF (para_env%is_source())
THEN
1156 CALL open_file(file_name=filename_sc(icontact), file_status=
"OLD", &
1157 file_form=
"FORMATTED", file_action=
"READ", &
1158 file_position=
"REWIND", unit_number=print_unit)
1159 READ (print_unit, *) nrow_sc, ncol_sc
1162 CALL para_env%bcast(nrow_sc)
1163 CALL para_env%bcast(ncol_sc)
1165 CALL cp_fm_struct_create(fm_struct, nrow_global=nrow_sc, ncol_global=ncol_sc, context=sub_env%blacs_env)
1167 DO ispin = 1, nspins
1168 CALL cp_fm_create(negf_env%h_sc(ispin, icontact), fm_struct)
1173 ALLOCATE (target_m(nrow_s, ncol_s))
1175 CALL para_env%bcast(target_m)
1177 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"S_s is read from "//trim(filename_s)
1178 IF (nspins == 1)
THEN
1180 CALL para_env%bcast(target_m)
1182 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_s is read from "//trim(filename_h_1)
1184 IF (nspins == 2)
THEN
1186 CALL para_env%bcast(target_m)
1188 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_s is read from "//trim(filename_h_1)//
" for spin 1"
1190 CALL para_env%bcast(target_m)
1192 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_s is read from "//trim(filename_h_2)//
" for spin 2"
1194 DEALLOCATE (target_m)
1196 DO icontact = 1, ncontacts
1197 ALLOCATE (target_m(nrow_s, ncol_sc))
1199 CALL para_env%bcast(target_m)
1201 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"S_sc is read from "//trim(filename_sc(icontact))
1202 IF (nspins == 1)
THEN
1204 CALL para_env%bcast(target_m)
1206 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_sc is read from "//trim(filename_hc_1(icontact))
1208 IF (nspins == 2)
THEN
1210 CALL para_env%bcast(target_m)
1212 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_sc is read from "//trim(filename_hc_1(icontact))//
" for spin 1"
1214 CALL para_env%bcast(target_m)
1216 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_sc is read from "//trim(filename_hc_2(icontact))//
" for spin 2"
1218 DEALLOCATE (target_m)
1224 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)') &
1225 "Some restart files do not exist. ALL restart files will be recalculated!"
1227 IF (.NOT. is_dft_entire)
CALL qs_energies(qs_env, consistent_energies=.false., calc_forces=.false.)
1229 CALL negf_env_device_init_matrices(negf_env, negf_control, sub_env, qs_env)
1230 is_dft_entire = .true.
1232 CALL cp_fm_get_info(negf_env%s_s, nrow_global=nrow_s, ncol_global=ncol_s)
1233 ALLOCATE (target_m(nrow_s, ncol_s))
1236 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,A)')
"S_s is saved to "//trim(filename_s)
1237 IF (nspins == 1)
THEN
1240 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_s is saved to "//trim(filename_h_1)
1242 IF (nspins == 2)
THEN
1245 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_s is saved to "//trim(filename_h_1)//
" for spin 1"
1248 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_s is saved to "//trim(filename_h_2)//
" for spin 2"
1250 DEALLOCATE (target_m)
1252 DO icontact = 1, ncontacts
1253 CALL cp_fm_get_info(negf_env%contacts(icontact)%s_00, nrow_global=nrow_sc, ncol_global=ncol_sc)
1254 ALLOCATE (target_m(nrow_s, ncol_sc))
1257 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A,I3)') &
1258 "S_sc is saved to "//trim(filename_sc(icontact))//
" for contact", icontact
1259 IF (nspins == 1)
THEN
1262 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_sc is saved to "//trim(filename_hc_1(icontact))
1264 IF (nspins == 2)
THEN
1267 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_sc is saved to "//trim(filename_hc_1(icontact))//
" for spin 1"
1270 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_sc is saved to "//trim(filename_hc_2(icontact))//
" for spin 2"
1272 DEALLOCATE (target_m)
1275 negf_control%write_common_restart_file = .true.
1279 DEALLOCATE (filename_sc, filename_hc_1, filename_hc_2)
1280 CALL timestop(handle)
1281 END SUBROUTINE negf_env_scatt_read_write_hs
1292 SUBROUTINE negf_env_device_init_matrices(negf_env, negf_control, sub_env, qs_env)
1298 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_env_device_init_matrices'
1300 INTEGER :: handle, icontact, ispin, nao_c, nao_s, &
1302 LOGICAL :: do_kpoints
1305 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks_kp, matrix_s_kp
1313 CALL timeset(routinen, handle)
1315 IF (
ALLOCATED(negf_control%atomlist_S_screening))
THEN
1317 dft_control=dft_control, &
1318 do_kpoints=do_kpoints, &
1319 matrix_ks_kp=matrix_ks_kp, &
1320 matrix_s_kp=matrix_s_kp, &
1321 para_env=para_env, &
1325 CALL pw_env_get(pw_env, auxbas_pw_pool=pw_pool)
1327 IF (do_kpoints)
THEN
1328 CALL cp_abort(__location__, &
1329 "K-points in device region have not been implemented yet.")
1332 ncontacts =
SIZE(negf_control%contacts)
1333 nspins = dft_control%nspins
1339 NULLIFY (negf_env%s_s, negf_env%v_hartree_s, fm_struct)
1340 ALLOCATE (negf_env%h_s(nspins))
1342 CALL cp_fm_struct_create(fm_struct, nrow_global=nao_s, ncol_global=nao_s, context=sub_env%blacs_env)
1343 ALLOCATE (negf_env%s_s)
1345 DO ispin = 1, nspins
1348 ALLOCATE (negf_env%v_hartree_s)
1353 ALLOCATE (negf_env%h_sc(nspins, ncontacts), negf_env%s_sc(ncontacts))
1354 DO icontact = 1, ncontacts
1356 CALL cp_fm_struct_create(fm_struct, nrow_global=nao_s, ncol_global=nao_c, context=sub_env%blacs_env)
1360 DO ispin = 1, nspins
1361 CALL cp_fm_create(negf_env%h_sc(ispin, icontact), fm_struct)
1368 DO ispin = 1, nspins
1370 fm=negf_env%h_s(ispin), &
1371 atomlist_row=negf_control%atomlist_S_screening, &
1372 atomlist_col=negf_control%atomlist_S_screening, &
1373 subsys=subsys, mpi_comm_global=para_env, &
1374 do_upper_diag=.true., do_lower=.true.)
1379 atomlist_row=negf_control%atomlist_S_screening, &
1380 atomlist_col=negf_control%atomlist_S_screening, &
1381 subsys=subsys, mpi_comm_global=para_env, &
1382 do_upper_diag=.true., do_lower=.true.)
1385 NULLIFY (hmat%matrix)
1387 CALL dbcsr_copy(matrix_b=hmat%matrix, matrix_a=matrix_s_kp(1, 1)%matrix)
1390 CALL pw_pool%create_pw(v_hartree)
1391 CALL negf_env_init_v_hartree(v_hartree, negf_env%contacts, negf_control%contacts)
1393 CALL integrate_v_rspace(v_rspace=v_hartree, hmat=hmat, qs_env=qs_env, &
1394 calculate_forces=.false., compute_tau=.false., gapw=.false.)
1396 CALL pw_pool%give_back_pw(v_hartree)
1399 fm=negf_env%v_hartree_s, &
1400 atomlist_row=negf_control%atomlist_S_screening, &
1401 atomlist_col=negf_control%atomlist_S_screening, &
1402 subsys=subsys, mpi_comm_global=para_env, &
1403 do_upper_diag=.true., do_lower=.true.)
1408 DO icontact = 1, ncontacts
1409 DO ispin = 1, nspins
1411 fm=negf_env%h_sc(ispin, icontact), &
1412 atomlist_row=negf_control%atomlist_S_screening, &
1413 atomlist_col=negf_env%contacts(icontact)%atomlist_cell0, &
1414 subsys=subsys, mpi_comm_global=para_env, &
1415 do_upper_diag=.true., do_lower=.true.)
1419 fm=negf_env%s_sc(icontact), &
1420 atomlist_row=negf_control%atomlist_S_screening, &
1421 atomlist_col=negf_env%contacts(icontact)%atomlist_cell0, &
1422 subsys=subsys, mpi_comm_global=para_env, &
1423 do_upper_diag=.true., do_lower=.true.)
1427 CALL timestop(handle)
1428 END SUBROUTINE negf_env_device_init_matrices
1437 SUBROUTINE negf_env_init_v_hartree(v_hartree, contact_env, contact_control)
1440 INTENT(in) :: contact_env
1442 INTENT(in) :: contact_control
1444 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_env_init_v_hartree'
1445 REAL(kind=
dp),
PARAMETER :: threshold = 16.0_dp*epsilon(0.0_dp)
1447 INTEGER :: dx, dy, dz, handle, icontact, ix, iy, &
1448 iz, lx, ly, lz, ncontacts, ux, uy, uz
1449 REAL(kind=
dp) :: dvol, pot, proj, v1, v2
1450 REAL(kind=
dp),
DIMENSION(3) :: dirvector_bias, point_coord, &
1451 point_indices, vector
1453 CALL timeset(routinen, handle)
1455 ncontacts =
SIZE(contact_env)
1456 cpassert(
SIZE(contact_control) == ncontacts)
1457 cpassert(ncontacts == 2)
1459 dirvector_bias = contact_env(2)%origin_bias - contact_env(1)%origin_bias
1460 v1 = contact_control(1)%v_external
1461 v2 = contact_control(2)%v_external
1463 lx = v_hartree%pw_grid%bounds_local(1, 1)
1464 ux = v_hartree%pw_grid%bounds_local(2, 1)
1465 ly = v_hartree%pw_grid%bounds_local(1, 2)
1466 uy = v_hartree%pw_grid%bounds_local(2, 2)
1467 lz = v_hartree%pw_grid%bounds_local(1, 3)
1468 uz = v_hartree%pw_grid%bounds_local(2, 3)
1470 dx = v_hartree%pw_grid%npts(1)/2
1471 dy = v_hartree%pw_grid%npts(2)/2
1472 dz = v_hartree%pw_grid%npts(3)/2
1474 dvol = v_hartree%pw_grid%dvol
1477 point_indices(3) = real(iz + dz, kind=
dp)
1479 point_indices(2) = real(iy + dy, kind=
dp)
1482 point_indices(1) = real(ix + dx, kind=
dp)
1483 point_coord(:) = matmul(v_hartree%pw_grid%dh, point_indices)
1485 vector = point_coord - contact_env(1)%origin_bias
1487 IF (proj + threshold >= 0.0_dp .AND. proj - threshold <= 1.0_dp)
THEN
1491 IF (proj < 0.0_dp)
THEN
1493 ELSE IF (proj > 1.0_dp)
THEN
1496 pot = v1 + (v2 - v1)*proj
1499 DO icontact = 1, ncontacts
1500 vector = point_coord - contact_env(icontact)%origin_bias
1503 IF (proj + threshold >= 0.0_dp .AND. proj - threshold <= 1.0_dp)
THEN
1504 pot = contact_control(icontact)%v_external
1510 v_hartree%array(ix, iy, iz) = pot*dvol
1515 CALL timestop(handle)
1516 END SUBROUTINE negf_env_init_v_hartree
1527 FUNCTION contact_direction_axis(direction_vector, subsys_contact, eps_geometry)
RESULT(direction_axis)
1528 REAL(kind=
dp),
DIMENSION(3),
INTENT(in) :: direction_vector
1530 REAL(kind=
dp),
INTENT(in) :: eps_geometry
1531 INTEGER :: direction_axis
1534 REAL(kind=
dp),
DIMENSION(3) :: scaled
1544 IF (abs(scaled(i)) > eps_geometry)
THEN
1545 IF (scaled(i) > 0.0_dp)
THEN
1555 IF (naxes /= 1) direction_axis = 0
1556 END FUNCTION contact_direction_axis
1565 SUBROUTINE negf_homo_energy_estimate(homo_energy, qs_env)
1566 REAL(kind=
dp),
INTENT(out) :: homo_energy
1569 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_homo_energy_estimate'
1570 INTEGER,
PARAMETER :: gamma_point = 1
1572 INTEGER :: handle, homo, ikpgr, ikpoint, imo, &
1573 ispin, kplocal, nmo, nspins
1574 INTEGER,
DIMENSION(2) :: kp_range
1575 LOGICAL :: do_kpoints
1576 REAL(kind=
dp) :: my_homo_energy
1577 REAL(kind=
dp),
DIMENSION(:),
POINTER :: eigenvalues
1581 TYPE(
mo_set_type),
DIMENSION(:, :),
POINTER :: mos_kp
1584 CALL timeset(routinen, handle)
1585 my_homo_energy = 0.0_dp
1587 CALL get_qs_env(qs_env, para_env=para_env, mos=mos, kpoints=kpoints, do_kpoints=do_kpoints)
1589 IF (do_kpoints)
THEN
1590 CALL get_kpoint_info(kpoints, kp_env=kp_env, kp_range=kp_range, para_env_kp=para_env_kp)
1593 IF (para_env_kp%mepos == 0 .AND. kp_range(1) <= gamma_point .AND. kp_range(2) >= gamma_point)
THEN
1594 kplocal = kp_range(2) - kp_range(1) + 1
1596 DO ikpgr = 1, kplocal
1597 CALL get_kpoint_env(kp_env(ikpgr)%kpoint_env, nkpoint=ikpoint, mos=mos_kp)
1599 IF (ikpoint == gamma_point)
THEN
1601 CALL get_mo_set(mos_kp(1, 1), homo=homo, eigenvalues=eigenvalues)
1603 my_homo_energy = eigenvalues(homo)
1609 CALL para_env%sum(my_homo_energy)
1616 CALL cp_abort(__location__, &
1617 "It is necessary to use k-points along the transport direction "// &
1618 "for all contact FORCE_EVAL-s")
1623 spin_loop:
DO ispin = 1, nspins
1624 CALL get_mo_set(mos(ispin), homo=homo, nmo=nmo, eigenvalues=eigenvalues)
1627 IF (eigenvalues(imo) /= 0.0_dp)
EXIT spin_loop
1632 cpabort(
"Orbital transformation (OT) for contact FORCE_EVAL-s is not supported")
1635 my_homo_energy = eigenvalues(homo)
1638 homo_energy = my_homo_energy
1639 CALL timestop(handle)
1640 END SUBROUTINE negf_homo_energy_estimate
1656 SUBROUTINE list_atoms_in_bulk_primary_unit_cell(atomlist_cell0, atom_map_cell0, atomlist_bulk, atom_map, &
1657 origin, direction_vector, direction_axis, subsys_device)
1658 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(inout) :: atomlist_cell0
1660 DIMENSION(:),
INTENT(inout) :: atom_map_cell0
1661 INTEGER,
DIMENSION(:),
INTENT(in) :: atomlist_bulk
1663 REAL(kind=
dp),
DIMENSION(3),
INTENT(in) :: origin, direction_vector
1664 INTEGER,
INTENT(in) :: direction_axis
1667 CHARACTER(LEN=*),
PARAMETER :: routinen =
'list_atoms_in_bulk_primary_unit_cell'
1669 INTEGER :: atom_min, dir_axis_min, &
1670 direction_axis_abs, handle, iatom, &
1671 natoms_bulk, natoms_cell0
1672 REAL(kind=
dp) :: proj, proj_min
1673 REAL(kind=
dp),
DIMENSION(3) :: vector
1676 CALL timeset(routinen, handle)
1677 CALL qs_subsys_get(subsys_device, particle_set=particle_set)
1679 natoms_bulk =
SIZE(atomlist_bulk)
1680 cpassert(
SIZE(atom_map, 1) == natoms_bulk)
1681 direction_axis_abs = abs(direction_axis)
1686 DO iatom = 1, natoms_bulk
1687 vector = particle_set(atomlist_bulk(iatom))%r - origin
1690 IF (proj < proj_min)
THEN
1696 dir_axis_min = atom_map(atom_min)%cell(direction_axis_abs)
1699 DO iatom = 1, natoms_bulk
1700 IF (atom_map(iatom)%cell(direction_axis_abs) == dir_axis_min)
THEN
1701 natoms_cell0 = natoms_cell0 + 1
1705 ALLOCATE (atomlist_cell0(natoms_cell0))
1706 ALLOCATE (atom_map_cell0(natoms_cell0))
1709 DO iatom = 1, natoms_bulk
1710 IF (atom_map(iatom)%cell(direction_axis_abs) == dir_axis_min)
THEN
1711 natoms_cell0 = natoms_cell0 + 1
1712 atomlist_cell0(natoms_cell0) = atomlist_bulk(iatom)
1713 atom_map_cell0(natoms_cell0) = atom_map(iatom)
1717 CALL timestop(handle)
1718 END SUBROUTINE list_atoms_in_bulk_primary_unit_cell
1737 SUBROUTINE list_atoms_in_bulk_secondary_unit_cell(atomlist_cell1, atom_map_cell1, atomlist_bulk, atom_map, &
1738 origin, direction_vector, direction_axis, subsys_device)
1739 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(inout) :: atomlist_cell1
1741 DIMENSION(:),
INTENT(inout) :: atom_map_cell1
1742 INTEGER,
DIMENSION(:),
INTENT(in) :: atomlist_bulk
1744 REAL(kind=
dp),
DIMENSION(3),
INTENT(in) :: origin, direction_vector
1745 INTEGER,
INTENT(in) :: direction_axis
1748 CHARACTER(LEN=*),
PARAMETER :: routinen =
'list_atoms_in_bulk_secondary_unit_cell'
1750 INTEGER :: atom_min, dir_axis_min, &
1751 direction_axis_abs, handle, iatom, &
1752 natoms_bulk, natoms_cell1, offset
1753 REAL(kind=
dp) :: proj, proj_min
1754 REAL(kind=
dp),
DIMENSION(3) :: vector
1757 CALL timeset(routinen, handle)
1758 CALL qs_subsys_get(subsys_device, particle_set=particle_set)
1760 natoms_bulk =
SIZE(atomlist_bulk)
1761 cpassert(
SIZE(atom_map, 1) == natoms_bulk)
1762 direction_axis_abs = abs(direction_axis)
1763 offset = sign(1, direction_axis)
1768 DO iatom = 1, natoms_bulk
1769 vector = particle_set(atomlist_bulk(iatom))%r - origin
1772 IF (proj < proj_min)
THEN
1778 dir_axis_min = atom_map(atom_min)%cell(direction_axis_abs)
1781 DO iatom = 1, natoms_bulk
1782 IF (atom_map(iatom)%cell(direction_axis_abs) == dir_axis_min + offset)
THEN
1783 natoms_cell1 = natoms_cell1 + 1
1787 ALLOCATE (atomlist_cell1(natoms_cell1))
1788 ALLOCATE (atom_map_cell1(natoms_cell1))
1791 DO iatom = 1, natoms_bulk
1792 IF (atom_map(iatom)%cell(direction_axis_abs) == dir_axis_min + offset)
THEN
1793 natoms_cell1 = natoms_cell1 + 1
1794 atomlist_cell1(natoms_cell1) = atomlist_bulk(iatom)
1795 atom_map_cell1(natoms_cell1) = atom_map(iatom)
1796 atom_map_cell1(natoms_cell1)%cell(direction_axis_abs) = dir_axis_min
1800 CALL timestop(handle)
1801 END SUBROUTINE list_atoms_in_bulk_secondary_unit_cell
1812 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_env_release'
1814 INTEGER :: handle, icontact
1816 CALL timeset(routinen, handle)
1818 IF (
ALLOCATED(negf_env%contacts))
THEN
1819 DO icontact =
SIZE(negf_env%contacts), 1, -1
1820 CALL negf_env_contact_release(negf_env%contacts(icontact))
1823 DEALLOCATE (negf_env%contacts)
1833 IF (
ASSOCIATED(negf_env%s_s))
THEN
1835 DEALLOCATE (negf_env%s_s)
1836 NULLIFY (negf_env%s_s)
1843 IF (
ASSOCIATED(negf_env%v_hartree_s))
THEN
1845 DEALLOCATE (negf_env%v_hartree_s)
1846 NULLIFY (negf_env%v_hartree_s)
1850 IF (
ASSOCIATED(negf_env%mixing_storage))
THEN
1852 DEALLOCATE (negf_env%mixing_storage)
1855 CALL timestop(handle)
1862 SUBROUTINE negf_env_contact_release(contact_env)
1865 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_env_contact_release'
1869 CALL timeset(routinen, handle)
1884 IF (
ASSOCIATED(contact_env%s_00))
THEN
1886 DEALLOCATE (contact_env%s_00)
1887 NULLIFY (contact_env%s_00)
1891 IF (
ASSOCIATED(contact_env%s_01))
THEN
1893 DEALLOCATE (contact_env%s_01)
1894 NULLIFY (contact_env%s_01)
1897 IF (
ALLOCATED(contact_env%atomlist_cell0))
DEALLOCATE (contact_env%atomlist_cell0)
1898 IF (
ALLOCATED(contact_env%atomlist_cell1))
DEALLOCATE (contact_env%atomlist_cell1)
1899 IF (
ALLOCATED(contact_env%atom_map_cell0))
DEALLOCATE (contact_env%atom_map_cell0)
1901 CALL timestop(handle)
1902 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_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_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 ...
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, inversion_symmetry_only, symmetry_backend, symmetry_reduction_method, gamma_centered)
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, h_scf)
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, 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.
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...
Does all kind of post scf calculations for DFTB.
subroutine, public rebuild_pw_env(qs_env)
...
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.