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.)
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"
296 CALL force_env_get(sub_force_env(negf_control%contacts(icontact)%force_env_index)%force_env, qs_env=qs_env_contact)
297 CALL qs_energies(qs_env_contact, consistent_energies=.false., calc_forces=.false.)
298 CALL negf_env_contact_init_matrices(contact_env=negf_env%contacts(icontact), sub_env=sub_env, &
299 qs_env_contact=qs_env_contact)
300 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,79("-"))')
306 is_dft_entire = .false.
307 DO icontact = 1, ncontacts
308 IF (negf_control%contacts(icontact)%force_env_index <= 0)
THEN
309 IF (negf_control%contacts(icontact)%read_write_HS)
THEN
310 CALL negf_env_contact_init_matrices_gamma(contact_env=negf_env%contacts(icontact), &
311 contact_control=negf_control%contacts(icontact), &
312 sub_env=sub_env, qs_env=qs_env, &
313 eps_geometry=negf_control%eps_geometry)
314 CALL negf_env_contact_read_write_hs(icontact, force_env, para_env, negf_env, sub_env, negf_control, negf_section, &
315 log_unit, is_separate=.false., is_dft_entire=is_dft_entire)
318 WRITE (log_unit,
'(/,T2,A,T70,I11,/,A)')
"NEGF| Construct the Kohn-Sham matrix for the contact", icontact, &
319 " from the entire system bulk DFT calculation"
320 IF (.NOT. is_dft_entire)
CALL qs_energies(qs_env, consistent_energies=.false., calc_forces=.false.)
321 is_dft_entire = .true.
322 CALL negf_env_contact_init_matrices_gamma(contact_env=negf_env%contacts(icontact), &
323 contact_control=negf_control%contacts(icontact), &
324 sub_env=sub_env, qs_env=qs_env, &
325 eps_geometry=negf_control%eps_geometry)
326 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,79("-"))')
333 WRITE (log_unit,
'(/,T2,A,T70)')
"NEGF| Construct the Kohn-Sham matrix for the scattering region"
334 IF (negf_control%read_write_HS)
THEN
335 CALL negf_env_scatt_read_write_hs(force_env, para_env, negf_env, sub_env, negf_control, negf_section, log_unit, &
336 is_dft_entire=is_dft_entire)
338 IF (.NOT. is_dft_entire)
THEN
339 CALL qs_energies(qs_env, consistent_energies=.false., calc_forces=.false.)
340 is_dft_entire = .true.
343 CALL negf_env_device_init_matrices(negf_env, negf_control, sub_env, qs_env)
345 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,79("-"))')
347 negf_control%is_dft_entire = is_dft_entire
351 NULLIFY (negf_env%mixing_storage)
354 CALL get_qs_env(qs_env, dft_control=dft_control)
355 ALLOCATE (negf_env%mixing_storage)
357 negf_env%mixing_method, dft_control%qs_control%cutoff)
359 CALL timestop(handle)
372 SUBROUTINE negf_env_contact_init_maps(contact_env, contact_control, atom_map, &
373 eps_geometry, subsys_device, subsys_contact)
377 DIMENSION(:),
INTENT(inout) :: atom_map
378 REAL(kind=
dp),
INTENT(in) :: eps_geometry
381 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_env_contact_init_maps'
383 INTEGER :: handle, natoms
385 CALL timeset(routinen, handle)
388 contact_env%direction_vector, &
389 contact_env%origin_bias, &
390 contact_env%direction_vector_bias, &
391 contact_control%atomlist_screening, &
392 contact_control%atomlist_bulk, &
395 contact_env%direction_axis = contact_direction_axis(contact_env%direction_vector, subsys_contact, eps_geometry)
397 IF (contact_env%direction_axis /= 0)
THEN
398 natoms =
SIZE(contact_control%atomlist_bulk)
399 ALLOCATE (atom_map(natoms))
403 atom_list=contact_control%atomlist_bulk, &
404 subsys_device=subsys_device, &
405 subsys_contact=subsys_contact, &
406 eps_geometry=eps_geometry)
410 CALL list_atoms_in_bulk_primary_unit_cell(atomlist_cell0=contact_env%atomlist_cell0, &
411 atom_map_cell0=contact_env%atom_map_cell0, &
412 atomlist_bulk=contact_control%atomlist_bulk, &
414 origin=contact_env%origin, &
415 direction_vector=contact_env%direction_vector, &
416 direction_axis=contact_env%direction_axis, &
417 subsys_device=subsys_device)
420 CALL list_atoms_in_bulk_secondary_unit_cell(atomlist_cell1=contact_env%atomlist_cell1, &
421 atom_map_cell1=contact_env%atom_map_cell1, &
422 atomlist_bulk=contact_control%atomlist_bulk, &
424 origin=contact_env%origin, &
425 direction_vector=contact_env%direction_vector, &
426 direction_axis=contact_env%direction_axis, &
427 subsys_device=subsys_device)
430 CALL timestop(handle)
431 END SUBROUTINE negf_env_contact_init_maps
448 SUBROUTINE negf_env_contact_read_write_hs(icontact, el_force_env, para_env, negf_env, sub_env, negf_control, &
449 negf_section, log_unit, is_separate, is_dft_entire)
457 INTEGER,
INTENT(in) :: log_unit
458 LOGICAL,
INTENT(in) :: is_separate
459 LOGICAL,
INTENT(inout),
OPTIONAL :: is_dft_entire
461 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_env_contact_read_write_hs'
463 CHARACTER(len=default_path_length) :: filename_h00_1, filename_h00_2, &
464 filename_h01_1, filename_h01_2, &
465 filename_s00, filename_s01
466 INTEGER :: handle, ispin, ncol, nrow, nspins, &
468 LOGICAL :: exist, exist_all
469 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: target_m
476 CALL timeset(routinen, handle)
480 CALL get_qs_env(qs_env_contact, dft_control=dft_control, subsys=subsys)
481 nspins = dft_control%nspins
483 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,A,T70,I11)') &
484 "NEGF| Construct the Kohn-Sham matrix for the contact", icontact
489 IF (para_env%is_source())
THEN
491 IF (.NOT. exist)
THEN
492 CALL cp_warn(__location__, &
493 "User requested to read the overlap matrix from the file named: "// &
494 trim(filename_s00)//
". This file does not exist. The file will be created.")
498 IF (.NOT. exist)
THEN
499 CALL cp_warn(__location__, &
500 "User requested to read the overlap matrix from the file named: "// &
501 trim(filename_s01)//
". This file does not exist. The file will be created.")
504 IF (nspins == 1)
THEN
506 IF (.NOT. exist)
THEN
507 CALL cp_warn(__location__, &
508 "User requested to read the Hamiltonian matrix from the file named: "// &
509 trim(filename_h00_1)//
". This file does not exist. The file will be created.")
513 IF (.NOT. exist)
THEN
514 CALL cp_warn(__location__, &
515 "User requested to read the Hamiltonian matrix from the file named: "// &
516 trim(filename_h01_1)//
". This file does not exist. The file will be created.")
520 IF (nspins == 2)
THEN
522 IF (.NOT. exist)
THEN
523 CALL cp_warn(__location__, &
524 "User requested to read the Hamiltonian matrix from the file named: "// &
525 trim(filename_h00_1)//
". This file does not exist. The file will be created.")
529 IF (.NOT. exist)
THEN
530 CALL cp_warn(__location__, &
531 "User requested to read tthe Hamiltonian matrix from the file named: "// &
532 trim(filename_h01_1)//
". This file does not exist. The file will be created.")
536 IF (.NOT. exist)
THEN
537 CALL cp_warn(__location__, &
538 "User requested to read the Hamiltonian matrix from the file named: "// &
539 trim(filename_h00_2)//
". This file does not exist. The file will be created.")
543 IF (.NOT. exist)
THEN
544 CALL cp_warn(__location__, &
545 "User requested to read the Hamiltonian matrix from the file named: "// &
546 trim(filename_h01_2)//
". This file does not exist. The file will be created.")
551 CALL para_env%bcast(exist_all)
555 negf_control%contacts(icontact)%is_restart = .true.
556 IF (log_unit > 0)
THEN
557 WRITE (log_unit,
'(/,T2,A)')
"User requested to read the Hamiltonian and overlap matrices from files."
558 WRITE (log_unit,
'(T2,A)')
"All restart files exist."
562 IF (para_env%is_source())
THEN
563 CALL open_file(file_name=filename_s00, file_status=
"OLD", &
564 file_form=
"FORMATTED", file_action=
"READ", &
565 file_position=
"REWIND", unit_number=print_unit)
566 READ (print_unit, *) nrow, ncol
569 CALL para_env%bcast(nrow)
570 CALL para_env%bcast(ncol)
572 CALL cp_fm_struct_create(fm_struct, nrow_global=nrow, ncol_global=ncol, context=sub_env%blacs_env)
573 ALLOCATE (negf_env%contacts(icontact)%s_00, negf_env%contacts(icontact)%s_01)
574 CALL cp_fm_create(negf_env%contacts(icontact)%s_00, fm_struct)
575 CALL cp_fm_create(negf_env%contacts(icontact)%s_01, fm_struct)
576 ALLOCATE (negf_env%contacts(icontact)%h_00(nspins), negf_env%contacts(icontact)%h_01(nspins))
578 CALL cp_fm_create(negf_env%contacts(icontact)%h_00(ispin), fm_struct)
579 CALL cp_fm_create(negf_env%contacts(icontact)%h_01(ispin), fm_struct)
583 ALLOCATE (target_m(nrow, ncol))
585 CALL para_env%bcast(target_m)
587 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"S_00 is read from "//trim(filename_s00)
589 CALL para_env%bcast(target_m)
591 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"S_01 is read from "//trim(filename_s01)
592 IF (nspins == 1)
THEN
594 CALL para_env%bcast(target_m)
596 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_00 is read from "//trim(filename_h00_1)
598 CALL para_env%bcast(target_m)
600 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_01 is read from "//trim(filename_h01_1)
602 IF (nspins == 2)
THEN
604 CALL para_env%bcast(target_m)
606 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_00 is read from "//trim(filename_h00_1)//
" for spin 1"
608 CALL para_env%bcast(target_m)
610 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_01 is read from "//trim(filename_h01_1)//
" for spin 1"
612 CALL para_env%bcast(target_m)
614 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_00 is read from "//trim(filename_h00_2)//
" for spin 2"
616 CALL para_env%bcast(target_m)
618 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_01 is read from "//trim(filename_h01_2)//
" for spin 2"
620 DEALLOCATE (target_m)
624 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)') &
625 "Some restart files do not exist. ALL restart files will be recalculated!"
627 IF (is_separate)
THEN
628 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,A,T70,I11,/,A)') &
629 "Construct the Kohn-Sham matrix from from the separate bulk DFT calculation"
630 CALL qs_energies(qs_env_contact, consistent_energies=.false., calc_forces=.false.)
631 CALL negf_env_contact_init_matrices(contact_env=negf_env%contacts(icontact), sub_env=sub_env, &
632 qs_env_contact=qs_env_contact)
634 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,A,T70,I11,/,A)') &
635 "Construct the Kohn-Sham matrix from the entire system bulk DFT calculation"
636 negf_control%contacts(icontact)%read_write_HS = .false.
637 IF (.NOT. is_dft_entire)
CALL qs_energies(qs_env_contact, consistent_energies=.false., calc_forces=.false.)
638 CALL negf_env_contact_init_matrices_gamma(contact_env=negf_env%contacts(icontact), &
639 contact_control=negf_control%contacts(icontact), &
640 sub_env=sub_env, qs_env=qs_env_contact, &
641 eps_geometry=negf_control%eps_geometry)
642 negf_control%contacts(icontact)%read_write_HS = .true.
643 is_dft_entire = .true.
646 CALL cp_fm_get_info(negf_env%contacts(icontact)%s_00, nrow_global=nrow)
647 ALLOCATE (target_m(nrow, nrow))
650 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,A)')
"S_00 is saved to "//trim(filename_s00)
653 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"S_01 is saved to "//trim(filename_s01)
654 IF (nspins == 1)
THEN
657 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_00 is saved to "//trim(filename_h00_1)
660 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_01 is saved to "//trim(filename_h01_1)
662 IF (nspins == 2)
THEN
665 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_00 is saved to "//trim(filename_h00_1)//
" for spin 1"
668 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_01 is saved to "//trim(filename_h01_1)//
" for spin 1"
671 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_00 is saved to "//trim(filename_h00_2)//
" for spin 2"
674 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_01 is saved to "//trim(filename_h01_2)//
" for spin 2"
676 DEALLOCATE (target_m)
678 negf_control%write_common_restart_file = .true.
682 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,79("-"))')
684 CALL timestop(handle)
685 END SUBROUTINE negf_env_contact_read_write_hs
697 SUBROUTINE negf_env_contact_init_matrices(contact_env, sub_env, qs_env_contact)
702 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_env_contact_init_matrices'
704 INTEGER :: handle, iatom, ispin, nao, natoms, &
706 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_list0, atom_list1
707 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: index_to_cell
708 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index
709 LOGICAL :: do_kpoints
712 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks_kp, matrix_s_kp, rho_ao_kp
719 CALL timeset(routinen, handle)
722 dft_control=dft_control, &
723 do_kpoints=do_kpoints, &
725 matrix_ks_kp=matrix_ks_kp, &
726 matrix_s_kp=matrix_s_kp, &
730 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_kp)
732 CALL negf_homo_energy_estimate(contact_env%homo_energy, qs_env_contact)
734 natoms =
SIZE(contact_env%atomlist_cell0)
735 ALLOCATE (atom_list0(natoms))
737 atom_list0(iatom) = contact_env%atom_map_cell0(iatom)%iatom
741 IF (sum(abs(contact_env%atom_map_cell0(iatom)%cell(:))) > 0)
THEN
742 cpabort(
"NEGF K-points are not currently supported")
746 cpassert(
SIZE(contact_env%atomlist_cell1) == natoms)
747 ALLOCATE (atom_list1(natoms))
749 atom_list1(iatom) = contact_env%atom_map_cell1(iatom)%iatom
752 nspins = dft_control%nspins
753 nimages = dft_control%nimages
758 ALLOCATE (cell_to_index(0:0, 0:0, 0:0))
759 cell_to_index(0, 0, 0) = 1
762 ALLOCATE (index_to_cell(3, nimages))
764 IF (.NOT. do_kpoints)
DEALLOCATE (cell_to_index)
768 CALL cp_fm_struct_create(fm_struct, nrow_global=nao, ncol_global=nao, context=sub_env%blacs_env)
771 ALLOCATE (contact_env%s_00, contact_env%s_01)
776 ALLOCATE (contact_env%h_00(nspins), contact_env%h_01(nspins))
777 ALLOCATE (contact_env%rho_00(nspins), contact_env%rho_01(nspins))
788 matkp => matrix_s_kp(1, :)
790 fm_cell1=contact_env%s_01, &
791 direction_axis=contact_env%direction_axis, &
793 atom_list0=atom_list0, atom_list1=atom_list1, &
794 subsys=subsys, mpi_comm_global=para_env, &
799 matkp => matrix_ks_kp(ispin, :)
801 fm_cell1=contact_env%h_01(ispin), &
802 direction_axis=contact_env%direction_axis, &
804 atom_list0=atom_list0, atom_list1=atom_list1, &
805 subsys=subsys, mpi_comm_global=para_env, &
808 matkp => rho_ao_kp(ispin, :)
810 fm_cell1=contact_env%rho_01(ispin), &
811 direction_axis=contact_env%direction_axis, &
813 atom_list0=atom_list0, atom_list1=atom_list1, &
814 subsys=subsys, mpi_comm_global=para_env, &
818 DEALLOCATE (atom_list0, atom_list1)
820 CALL timestop(handle)
821 END SUBROUTINE negf_env_contact_init_matrices
832 SUBROUTINE negf_env_contact_init_matrices_gamma(contact_env, contact_control, sub_env, qs_env, eps_geometry)
837 REAL(kind=
dp),
INTENT(in) :: eps_geometry
839 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_env_contact_init_matrices_gamma'
841 INTEGER :: handle, iatom, icell, ispin, nao_c, &
843 LOGICAL :: do_kpoints
844 REAL(kind=
dp),
DIMENSION(2) :: r2_origin_cell
845 REAL(kind=
dp),
DIMENSION(3) :: direction_vector, origin
847 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks_kp, matrix_s_kp, rho_ao_kp
854 CALL timeset(routinen, handle)
857 dft_control=dft_control, &
858 do_kpoints=do_kpoints, &
859 matrix_ks_kp=matrix_ks_kp, &
860 matrix_s_kp=matrix_s_kp, &
864 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_kp)
867 CALL cp_abort(__location__, &
868 "K-points in device region have not been implemented yet.")
871 nspins = dft_control%nspins
875 CALL cp_abort(__location__, &
876 "Primary and secondary bulk contact cells should be identical "// &
877 "in terms of the number of atoms of each kind, and their basis sets. "// &
878 "No single atom, however, can be shared between these two cells.")
881 contact_env%homo_energy = 0.0_dp
884 contact_env%direction_vector, &
885 contact_env%origin_bias, &
886 contact_env%direction_vector_bias, &
887 contact_control%atomlist_screening, &
888 contact_control%atomlist_bulk, &
891 contact_env%direction_axis = contact_direction_axis(contact_env%direction_vector, subsys, eps_geometry)
896 origin = particle_set(contact_control%atomlist_screening(1))%r
897 DO iatom = 2,
SIZE(contact_control%atomlist_screening)
898 origin = origin + particle_set(contact_control%atomlist_screening(iatom))%r
900 origin = origin/real(
SIZE(contact_control%atomlist_screening), kind=
dp)
903 direction_vector = particle_set(contact_control%atomlist_cell(icell)%vector(1))%r
904 DO iatom = 2,
SIZE(contact_control%atomlist_cell(icell)%vector)
905 direction_vector = direction_vector + particle_set(contact_control%atomlist_cell(icell)%vector(iatom))%r
907 direction_vector = direction_vector/real(
SIZE(contact_control%atomlist_cell(icell)%vector), kind=
dp)
908 direction_vector = direction_vector - origin
909 r2_origin_cell(icell) = dot_product(direction_vector, direction_vector)
912 IF (abs(r2_origin_cell(1) - r2_origin_cell(2)) < (eps_geometry*eps_geometry))
THEN
915 CALL cp_abort(__location__, &
916 "Primary and secondary bulk contact cells should not overlap ")
917 ELSE IF (r2_origin_cell(1) < r2_origin_cell(2))
THEN
918 IF (.NOT.
ALLOCATED(contact_env%atomlist_cell0)) &
919 ALLOCATE (contact_env%atomlist_cell0(
SIZE(contact_control%atomlist_cell(1)%vector)))
920 contact_env%atomlist_cell0(:) = contact_control%atomlist_cell(1)%vector(:)
921 IF (.NOT.
ALLOCATED(contact_env%atomlist_cell1)) &
922 ALLOCATE (contact_env%atomlist_cell1(
SIZE(contact_control%atomlist_cell(2)%vector)))
923 contact_env%atomlist_cell1(:) = contact_control%atomlist_cell(2)%vector(:)
925 IF (.NOT.
ALLOCATED(contact_env%atomlist_cell0)) &
926 ALLOCATE (contact_env%atomlist_cell0(
SIZE(contact_control%atomlist_cell(2)%vector)))
927 contact_env%atomlist_cell0(:) = contact_control%atomlist_cell(2)%vector(:)
928 IF (.NOT.
ALLOCATED(contact_env%atomlist_cell1)) &
929 ALLOCATE (contact_env%atomlist_cell1(
SIZE(contact_control%atomlist_cell(1)%vector)))
930 contact_env%atomlist_cell1(:) = contact_control%atomlist_cell(1)%vector(:)
932 IF (.NOT. contact_control%read_write_HS)
THEN
934 CALL cp_fm_struct_create(fm_struct, nrow_global=nao_c, ncol_global=nao_c, context=sub_env%blacs_env)
935 ALLOCATE (contact_env%h_00(nspins), contact_env%h_01(nspins))
936 ALLOCATE (contact_env%rho_00(nspins), contact_env%rho_01(nspins))
943 ALLOCATE (contact_env%s_00, contact_env%s_01)
950 fm=contact_env%h_00(ispin), &
951 atomlist_row=contact_env%atomlist_cell0, &
952 atomlist_col=contact_env%atomlist_cell0, &
953 subsys=subsys, mpi_comm_global=para_env, &
954 do_upper_diag=.true., do_lower=.true.)
956 fm=contact_env%h_01(ispin), &
957 atomlist_row=contact_env%atomlist_cell0, &
958 atomlist_col=contact_env%atomlist_cell1, &
959 subsys=subsys, mpi_comm_global=para_env, &
960 do_upper_diag=.true., do_lower=.true.)
963 fm=contact_env%rho_00(ispin), &
964 atomlist_row=contact_env%atomlist_cell0, &
965 atomlist_col=contact_env%atomlist_cell0, &
966 subsys=subsys, mpi_comm_global=para_env, &
967 do_upper_diag=.true., do_lower=.true.)
969 fm=contact_env%rho_01(ispin), &
970 atomlist_row=contact_env%atomlist_cell0, &
971 atomlist_col=contact_env%atomlist_cell1, &
972 subsys=subsys, mpi_comm_global=para_env, &
973 do_upper_diag=.true., do_lower=.true.)
977 fm=contact_env%s_00, &
978 atomlist_row=contact_env%atomlist_cell0, &
979 atomlist_col=contact_env%atomlist_cell0, &
980 subsys=subsys, mpi_comm_global=para_env, &
981 do_upper_diag=.true., do_lower=.true.)
983 fm=contact_env%s_01, &
984 atomlist_row=contact_env%atomlist_cell0, &
985 atomlist_col=contact_env%atomlist_cell1, &
986 subsys=subsys, mpi_comm_global=para_env, &
987 do_upper_diag=.true., do_lower=.true.)
989 CALL timestop(handle)
990 END SUBROUTINE negf_env_contact_init_matrices_gamma
1005 SUBROUTINE negf_env_scatt_read_write_hs(force_env, para_env, negf_env, sub_env, negf_control, negf_section, &
1006 log_unit, is_dft_entire)
1013 INTEGER,
INTENT(in) :: log_unit
1014 LOGICAL,
INTENT(inout),
OPTIONAL :: is_dft_entire
1016 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_env_scatt_read_write_hs'
1018 CHARACTER(len=default_path_length) :: filename_h_1, filename_h_2, filename_s
1019 CHARACTER(len=default_path_length),
ALLOCATABLE, &
1020 DIMENSION(:) :: filename_hc_1, filename_hc_2, filename_sc
1021 INTEGER :: handle, icontact, ispin, ncol_s, &
1022 ncol_sc, ncontacts, nrow_s, nrow_sc, &
1024 LOGICAL :: exist, exist_all
1025 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: target_m
1032 CALL timeset(routinen, handle)
1036 CALL get_qs_env(qs_env, dft_control=dft_control, subsys=subsys)
1037 ncontacts =
SIZE(negf_control%contacts)
1038 nspins = dft_control%nspins
1039 ALLOCATE (filename_sc(ncontacts), filename_hc_1(ncontacts), filename_hc_2(ncontacts))
1044 IF (para_env%is_source())
THEN
1046 IF (.NOT. exist)
THEN
1047 CALL cp_warn(__location__, &
1048 "User requested to read the overlap matrix from the file named: "// &
1049 trim(filename_s)//
". This file does not exist. The file will be created.")
1052 IF (nspins == 1)
THEN
1054 IF (.NOT. exist)
THEN
1055 CALL cp_warn(__location__, &
1056 "User requested to read the Hamiltonian matrix from the file named: "// &
1057 trim(filename_h_1)//
". This file does not exist. The file will be created.")
1061 IF (nspins == 2)
THEN
1063 IF (.NOT. exist)
THEN
1064 CALL cp_warn(__location__, &
1065 "User requested to read the Hamiltonian matrix from the file named: "// &
1066 trim(filename_h_1)//
". This file does not exist. The file will be created.")
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_2)//
". This file does not exist. The file will be created.")
1077 DO icontact = 1, ncontacts
1078 CALL negf_restart_file_name(filename_sc(icontact), exist, negf_section, logger, icontact=icontact, sc=.true.)
1079 IF (.NOT. exist)
THEN
1080 CALL cp_warn(__location__, &
1081 "User requested to read the overlap matrix from the file named: "// &
1082 trim(filename_sc(icontact))//
". This file does not exist. The file will be created.")
1085 IF (nspins == 1)
THEN
1088 IF (.NOT. exist)
THEN
1089 CALL cp_warn(__location__, &
1090 "User requested to read the Hamiltonian matrix from the file named: "// &
1091 trim(filename_hc_1(icontact))//
". This file does not exist. The file will be created.")
1095 IF (nspins == 2)
THEN
1098 IF (.NOT. exist)
THEN
1099 CALL cp_warn(__location__, &
1100 "User requested to read the Hamiltonian matrix from the file named: "// &
1101 trim(filename_hc_1(icontact))//
". This file does not exist. The file will be created.")
1106 IF (.NOT. exist)
THEN
1107 CALL cp_warn(__location__, &
1108 "User requested to read the Hamiltonian matrix from the file named: "// &
1109 trim(filename_hc_2(icontact))//
". This file does not exist. The file will be created.")
1115 CALL para_env%bcast(exist_all)
1119 negf_control%is_restart = .true.
1121 IF (log_unit > 0)
THEN
1122 WRITE (log_unit,
'(/,T2,A)')
"User requested to read the Hamiltonian and overlap matrices from files."
1123 WRITE (log_unit,
'(T2,A)')
"All restart files exist."
1127 IF (para_env%is_source())
THEN
1128 CALL open_file(file_name=filename_s, file_status=
"OLD", &
1129 file_form=
"FORMATTED", file_action=
"READ", &
1130 file_position=
"REWIND", unit_number=print_unit)
1131 READ (print_unit, *) nrow_s, ncol_s
1134 CALL para_env%bcast(nrow_s)
1135 CALL para_env%bcast(ncol_s)
1137 CALL cp_fm_struct_create(fm_struct, nrow_global=nrow_s, ncol_global=ncol_s, context=sub_env%blacs_env)
1138 ALLOCATE (negf_env%s_s)
1140 ALLOCATE (negf_env%h_s(nspins))
1141 DO ispin = 1, nspins
1145 ALLOCATE (negf_env%s_sc(ncontacts))
1146 ALLOCATE (negf_env%h_sc(nspins, ncontacts))
1147 DO icontact = 1, ncontacts
1148 IF (para_env%is_source())
THEN
1149 CALL open_file(file_name=filename_sc(icontact), file_status=
"OLD", &
1150 file_form=
"FORMATTED", file_action=
"READ", &
1151 file_position=
"REWIND", unit_number=print_unit)
1152 READ (print_unit, *) nrow_sc, ncol_sc
1155 CALL para_env%bcast(nrow_sc)
1156 CALL para_env%bcast(ncol_sc)
1158 CALL cp_fm_struct_create(fm_struct, nrow_global=nrow_sc, ncol_global=ncol_sc, context=sub_env%blacs_env)
1160 DO ispin = 1, nspins
1161 CALL cp_fm_create(negf_env%h_sc(ispin, icontact), fm_struct)
1166 ALLOCATE (target_m(nrow_s, ncol_s))
1168 CALL para_env%bcast(target_m)
1170 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"S_s is read from "//trim(filename_s)
1171 IF (nspins == 1)
THEN
1173 CALL para_env%bcast(target_m)
1175 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_s is read from "//trim(filename_h_1)
1177 IF (nspins == 2)
THEN
1179 CALL para_env%bcast(target_m)
1181 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_s is read from "//trim(filename_h_1)//
" for spin 1"
1183 CALL para_env%bcast(target_m)
1185 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_s is read from "//trim(filename_h_2)//
" for spin 2"
1187 DEALLOCATE (target_m)
1189 DO icontact = 1, ncontacts
1190 ALLOCATE (target_m(nrow_s, ncol_sc))
1192 CALL para_env%bcast(target_m)
1194 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"S_sc is read from "//trim(filename_sc(icontact))
1195 IF (nspins == 1)
THEN
1197 CALL para_env%bcast(target_m)
1199 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_sc is read from "//trim(filename_hc_1(icontact))
1201 IF (nspins == 2)
THEN
1203 CALL para_env%bcast(target_m)
1205 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_sc is read from "//trim(filename_hc_1(icontact))//
" for spin 1"
1207 CALL para_env%bcast(target_m)
1209 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_sc is read from "//trim(filename_hc_2(icontact))//
" for spin 2"
1211 DEALLOCATE (target_m)
1217 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)') &
1218 "Some restart files do not exist. ALL restart files will be recalculated!"
1220 IF (.NOT. is_dft_entire)
CALL qs_energies(qs_env, consistent_energies=.false., calc_forces=.false.)
1222 CALL negf_env_device_init_matrices(negf_env, negf_control, sub_env, qs_env)
1223 is_dft_entire = .true.
1225 CALL cp_fm_get_info(negf_env%s_s, nrow_global=nrow_s, ncol_global=ncol_s)
1226 ALLOCATE (target_m(nrow_s, ncol_s))
1229 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,A)')
"S_s is saved to "//trim(filename_s)
1230 IF (nspins == 1)
THEN
1233 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_s is saved to "//trim(filename_h_1)
1235 IF (nspins == 2)
THEN
1238 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_s is saved to "//trim(filename_h_1)//
" for spin 1"
1241 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_s is saved to "//trim(filename_h_2)//
" for spin 2"
1243 DEALLOCATE (target_m)
1245 DO icontact = 1, ncontacts
1246 CALL cp_fm_get_info(negf_env%contacts(icontact)%s_00, nrow_global=nrow_sc, ncol_global=ncol_sc)
1247 ALLOCATE (target_m(nrow_s, ncol_sc))
1250 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A,I3)') &
1251 "S_sc is saved to "//trim(filename_sc(icontact))//
" for contact", icontact
1252 IF (nspins == 1)
THEN
1255 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_sc is saved to "//trim(filename_hc_1(icontact))
1257 IF (nspins == 2)
THEN
1260 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_sc is saved to "//trim(filename_hc_1(icontact))//
" for spin 1"
1263 IF (log_unit > 0)
WRITE (log_unit,
'(T2,A)')
"H_sc is saved to "//trim(filename_hc_2(icontact))//
" for spin 2"
1265 DEALLOCATE (target_m)
1268 negf_control%write_common_restart_file = .true.
1272 DEALLOCATE (filename_sc, filename_hc_1, filename_hc_2)
1273 CALL timestop(handle)
1274 END SUBROUTINE negf_env_scatt_read_write_hs
1285 SUBROUTINE negf_env_device_init_matrices(negf_env, negf_control, sub_env, qs_env)
1291 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_env_device_init_matrices'
1293 INTEGER :: handle, icontact, ispin, nao_c, nao_s, &
1295 LOGICAL :: do_kpoints
1298 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks_kp, matrix_s_kp
1306 CALL timeset(routinen, handle)
1308 IF (
ALLOCATED(negf_control%atomlist_S_screening))
THEN
1310 dft_control=dft_control, &
1311 do_kpoints=do_kpoints, &
1312 matrix_ks_kp=matrix_ks_kp, &
1313 matrix_s_kp=matrix_s_kp, &
1314 para_env=para_env, &
1318 CALL pw_env_get(pw_env, auxbas_pw_pool=pw_pool)
1320 IF (do_kpoints)
THEN
1321 CALL cp_abort(__location__, &
1322 "K-points in device region have not been implemented yet.")
1325 ncontacts =
SIZE(negf_control%contacts)
1326 nspins = dft_control%nspins
1332 NULLIFY (negf_env%s_s, negf_env%v_hartree_s, fm_struct)
1333 ALLOCATE (negf_env%h_s(nspins))
1335 CALL cp_fm_struct_create(fm_struct, nrow_global=nao_s, ncol_global=nao_s, context=sub_env%blacs_env)
1336 ALLOCATE (negf_env%s_s)
1338 DO ispin = 1, nspins
1341 ALLOCATE (negf_env%v_hartree_s)
1346 ALLOCATE (negf_env%h_sc(nspins, ncontacts), negf_env%s_sc(ncontacts))
1347 DO icontact = 1, ncontacts
1349 CALL cp_fm_struct_create(fm_struct, nrow_global=nao_s, ncol_global=nao_c, context=sub_env%blacs_env)
1353 DO ispin = 1, nspins
1354 CALL cp_fm_create(negf_env%h_sc(ispin, icontact), fm_struct)
1361 DO ispin = 1, nspins
1363 fm=negf_env%h_s(ispin), &
1364 atomlist_row=negf_control%atomlist_S_screening, &
1365 atomlist_col=negf_control%atomlist_S_screening, &
1366 subsys=subsys, mpi_comm_global=para_env, &
1367 do_upper_diag=.true., do_lower=.true.)
1372 atomlist_row=negf_control%atomlist_S_screening, &
1373 atomlist_col=negf_control%atomlist_S_screening, &
1374 subsys=subsys, mpi_comm_global=para_env, &
1375 do_upper_diag=.true., do_lower=.true.)
1378 NULLIFY (hmat%matrix)
1380 CALL dbcsr_copy(matrix_b=hmat%matrix, matrix_a=matrix_s_kp(1, 1)%matrix)
1383 CALL pw_pool%create_pw(v_hartree)
1384 CALL negf_env_init_v_hartree(v_hartree, negf_env%contacts, negf_control%contacts)
1386 CALL integrate_v_rspace(v_rspace=v_hartree, hmat=hmat, qs_env=qs_env, &
1387 calculate_forces=.false., compute_tau=.false., gapw=.false.)
1389 CALL pw_pool%give_back_pw(v_hartree)
1392 fm=negf_env%v_hartree_s, &
1393 atomlist_row=negf_control%atomlist_S_screening, &
1394 atomlist_col=negf_control%atomlist_S_screening, &
1395 subsys=subsys, mpi_comm_global=para_env, &
1396 do_upper_diag=.true., do_lower=.true.)
1401 DO icontact = 1, ncontacts
1402 DO ispin = 1, nspins
1404 fm=negf_env%h_sc(ispin, icontact), &
1405 atomlist_row=negf_control%atomlist_S_screening, &
1406 atomlist_col=negf_env%contacts(icontact)%atomlist_cell0, &
1407 subsys=subsys, mpi_comm_global=para_env, &
1408 do_upper_diag=.true., do_lower=.true.)
1412 fm=negf_env%s_sc(icontact), &
1413 atomlist_row=negf_control%atomlist_S_screening, &
1414 atomlist_col=negf_env%contacts(icontact)%atomlist_cell0, &
1415 subsys=subsys, mpi_comm_global=para_env, &
1416 do_upper_diag=.true., do_lower=.true.)
1420 CALL timestop(handle)
1421 END SUBROUTINE negf_env_device_init_matrices
1430 SUBROUTINE negf_env_init_v_hartree(v_hartree, contact_env, contact_control)
1433 INTENT(in) :: contact_env
1435 INTENT(in) :: contact_control
1437 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_env_init_v_hartree'
1438 REAL(kind=
dp),
PARAMETER :: threshold = 16.0_dp*epsilon(0.0_dp)
1440 INTEGER :: dx, dy, dz, handle, icontact, ix, iy, &
1441 iz, lx, ly, lz, ncontacts, ux, uy, uz
1442 REAL(kind=
dp) :: dvol, pot, proj, v1, v2
1443 REAL(kind=
dp),
DIMENSION(3) :: dirvector_bias, point_coord, &
1444 point_indices, vector
1446 CALL timeset(routinen, handle)
1448 ncontacts =
SIZE(contact_env)
1449 cpassert(
SIZE(contact_control) == ncontacts)
1450 cpassert(ncontacts == 2)
1452 dirvector_bias = contact_env(2)%origin_bias - contact_env(1)%origin_bias
1453 v1 = contact_control(1)%v_external
1454 v2 = contact_control(2)%v_external
1456 lx = v_hartree%pw_grid%bounds_local(1, 1)
1457 ux = v_hartree%pw_grid%bounds_local(2, 1)
1458 ly = v_hartree%pw_grid%bounds_local(1, 2)
1459 uy = v_hartree%pw_grid%bounds_local(2, 2)
1460 lz = v_hartree%pw_grid%bounds_local(1, 3)
1461 uz = v_hartree%pw_grid%bounds_local(2, 3)
1463 dx = v_hartree%pw_grid%npts(1)/2
1464 dy = v_hartree%pw_grid%npts(2)/2
1465 dz = v_hartree%pw_grid%npts(3)/2
1467 dvol = v_hartree%pw_grid%dvol
1470 point_indices(3) = real(iz + dz, kind=
dp)
1472 point_indices(2) = real(iy + dy, kind=
dp)
1475 point_indices(1) = real(ix + dx, kind=
dp)
1476 point_coord(:) = matmul(v_hartree%pw_grid%dh, point_indices)
1478 vector = point_coord - contact_env(1)%origin_bias
1480 IF (proj + threshold >= 0.0_dp .AND. proj - threshold <= 1.0_dp)
THEN
1484 IF (proj < 0.0_dp)
THEN
1486 ELSE IF (proj > 1.0_dp)
THEN
1489 pot = v1 + (v2 - v1)*proj
1492 DO icontact = 1, ncontacts
1493 vector = point_coord - contact_env(icontact)%origin_bias
1496 IF (proj + threshold >= 0.0_dp .AND. proj - threshold <= 1.0_dp)
THEN
1497 pot = contact_control(icontact)%v_external
1503 v_hartree%array(ix, iy, iz) = pot*dvol
1508 CALL timestop(handle)
1509 END SUBROUTINE negf_env_init_v_hartree
1520 FUNCTION contact_direction_axis(direction_vector, subsys_contact, eps_geometry)
RESULT(direction_axis)
1521 REAL(kind=
dp),
DIMENSION(3),
INTENT(in) :: direction_vector
1523 REAL(kind=
dp),
INTENT(in) :: eps_geometry
1524 INTEGER :: direction_axis
1527 REAL(kind=
dp),
DIMENSION(3) :: scaled
1537 IF (abs(scaled(i)) > eps_geometry)
THEN
1538 IF (scaled(i) > 0.0_dp)
THEN
1548 IF (naxes /= 1) direction_axis = 0
1549 END FUNCTION contact_direction_axis
1558 SUBROUTINE negf_homo_energy_estimate(homo_energy, qs_env)
1559 REAL(kind=
dp),
INTENT(out) :: homo_energy
1562 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_homo_energy_estimate'
1563 INTEGER,
PARAMETER :: gamma_point = 1
1565 INTEGER :: handle, homo, ikpgr, ikpoint, imo, &
1566 ispin, kplocal, nmo, nspins
1567 INTEGER,
DIMENSION(2) :: kp_range
1568 LOGICAL :: do_kpoints
1569 REAL(kind=
dp) :: my_homo_energy
1570 REAL(kind=
dp),
DIMENSION(:),
POINTER :: eigenvalues
1574 TYPE(
mo_set_type),
DIMENSION(:, :),
POINTER :: mos_kp
1577 CALL timeset(routinen, handle)
1578 my_homo_energy = 0.0_dp
1580 CALL get_qs_env(qs_env, para_env=para_env, mos=mos, kpoints=kpoints, do_kpoints=do_kpoints)
1582 IF (do_kpoints)
THEN
1583 CALL get_kpoint_info(kpoints, kp_env=kp_env, kp_range=kp_range, para_env_kp=para_env_kp)
1586 IF (para_env_kp%mepos == 0 .AND. kp_range(1) <= gamma_point .AND. kp_range(2) >= gamma_point)
THEN
1587 kplocal = kp_range(2) - kp_range(1) + 1
1589 DO ikpgr = 1, kplocal
1590 CALL get_kpoint_env(kp_env(ikpgr)%kpoint_env, nkpoint=ikpoint, mos=mos_kp)
1592 IF (ikpoint == gamma_point)
THEN
1594 CALL get_mo_set(mos_kp(1, 1), homo=homo, eigenvalues=eigenvalues)
1596 my_homo_energy = eigenvalues(homo)
1602 CALL para_env%sum(my_homo_energy)
1609 CALL cp_abort(__location__, &
1610 "It is necessary to use k-points along the transport direction "// &
1611 "for all contact FORCE_EVAL-s")
1616 spin_loop:
DO ispin = 1, nspins
1617 CALL get_mo_set(mos(ispin), homo=homo, nmo=nmo, eigenvalues=eigenvalues)
1620 IF (eigenvalues(imo) /= 0.0_dp)
EXIT spin_loop
1625 cpabort(
"Orbital transformation (OT) for contact FORCE_EVAL-s is not supported")
1628 my_homo_energy = eigenvalues(homo)
1631 homo_energy = my_homo_energy
1632 CALL timestop(handle)
1633 END SUBROUTINE negf_homo_energy_estimate
1649 SUBROUTINE list_atoms_in_bulk_primary_unit_cell(atomlist_cell0, atom_map_cell0, atomlist_bulk, atom_map, &
1650 origin, direction_vector, direction_axis, subsys_device)
1651 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(inout) :: atomlist_cell0
1653 DIMENSION(:),
INTENT(inout) :: atom_map_cell0
1654 INTEGER,
DIMENSION(:),
INTENT(in) :: atomlist_bulk
1656 REAL(kind=
dp),
DIMENSION(3),
INTENT(in) :: origin, direction_vector
1657 INTEGER,
INTENT(in) :: direction_axis
1660 CHARACTER(LEN=*),
PARAMETER :: routinen =
'list_atoms_in_bulk_primary_unit_cell'
1662 INTEGER :: atom_min, dir_axis_min, &
1663 direction_axis_abs, handle, iatom, &
1664 natoms_bulk, natoms_cell0
1665 REAL(kind=
dp) :: proj, proj_min
1666 REAL(kind=
dp),
DIMENSION(3) :: vector
1669 CALL timeset(routinen, handle)
1670 CALL qs_subsys_get(subsys_device, particle_set=particle_set)
1672 natoms_bulk =
SIZE(atomlist_bulk)
1673 cpassert(
SIZE(atom_map, 1) == natoms_bulk)
1674 direction_axis_abs = abs(direction_axis)
1679 DO iatom = 1, natoms_bulk
1680 vector = particle_set(atomlist_bulk(iatom))%r - origin
1683 IF (proj < proj_min)
THEN
1689 dir_axis_min = atom_map(atom_min)%cell(direction_axis_abs)
1692 DO iatom = 1, natoms_bulk
1693 IF (atom_map(iatom)%cell(direction_axis_abs) == dir_axis_min) &
1694 natoms_cell0 = natoms_cell0 + 1
1697 ALLOCATE (atomlist_cell0(natoms_cell0))
1698 ALLOCATE (atom_map_cell0(natoms_cell0))
1701 DO iatom = 1, natoms_bulk
1702 IF (atom_map(iatom)%cell(direction_axis_abs) == dir_axis_min)
THEN
1703 natoms_cell0 = natoms_cell0 + 1
1704 atomlist_cell0(natoms_cell0) = atomlist_bulk(iatom)
1705 atom_map_cell0(natoms_cell0) = atom_map(iatom)
1709 CALL timestop(handle)
1710 END SUBROUTINE list_atoms_in_bulk_primary_unit_cell
1729 SUBROUTINE list_atoms_in_bulk_secondary_unit_cell(atomlist_cell1, atom_map_cell1, atomlist_bulk, atom_map, &
1730 origin, direction_vector, direction_axis, subsys_device)
1731 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(inout) :: atomlist_cell1
1733 DIMENSION(:),
INTENT(inout) :: atom_map_cell1
1734 INTEGER,
DIMENSION(:),
INTENT(in) :: atomlist_bulk
1736 REAL(kind=
dp),
DIMENSION(3),
INTENT(in) :: origin, direction_vector
1737 INTEGER,
INTENT(in) :: direction_axis
1740 CHARACTER(LEN=*),
PARAMETER :: routinen =
'list_atoms_in_bulk_secondary_unit_cell'
1742 INTEGER :: atom_min, dir_axis_min, &
1743 direction_axis_abs, handle, iatom, &
1744 natoms_bulk, natoms_cell1, offset
1745 REAL(kind=
dp) :: proj, proj_min
1746 REAL(kind=
dp),
DIMENSION(3) :: vector
1749 CALL timeset(routinen, handle)
1750 CALL qs_subsys_get(subsys_device, particle_set=particle_set)
1752 natoms_bulk =
SIZE(atomlist_bulk)
1753 cpassert(
SIZE(atom_map, 1) == natoms_bulk)
1754 direction_axis_abs = abs(direction_axis)
1755 offset = sign(1, direction_axis)
1760 DO iatom = 1, natoms_bulk
1761 vector = particle_set(atomlist_bulk(iatom))%r - origin
1764 IF (proj < proj_min)
THEN
1770 dir_axis_min = atom_map(atom_min)%cell(direction_axis_abs)
1773 DO iatom = 1, natoms_bulk
1774 IF (atom_map(iatom)%cell(direction_axis_abs) == dir_axis_min + offset) &
1775 natoms_cell1 = natoms_cell1 + 1
1778 ALLOCATE (atomlist_cell1(natoms_cell1))
1779 ALLOCATE (atom_map_cell1(natoms_cell1))
1782 DO iatom = 1, natoms_bulk
1783 IF (atom_map(iatom)%cell(direction_axis_abs) == dir_axis_min + offset)
THEN
1784 natoms_cell1 = natoms_cell1 + 1
1785 atomlist_cell1(natoms_cell1) = atomlist_bulk(iatom)
1786 atom_map_cell1(natoms_cell1) = atom_map(iatom)
1787 atom_map_cell1(natoms_cell1)%cell(direction_axis_abs) = dir_axis_min
1791 CALL timestop(handle)
1792 END SUBROUTINE list_atoms_in_bulk_secondary_unit_cell
1803 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_env_release'
1805 INTEGER :: handle, icontact
1807 CALL timeset(routinen, handle)
1809 IF (
ALLOCATED(negf_env%contacts))
THEN
1810 DO icontact =
SIZE(negf_env%contacts), 1, -1
1811 CALL negf_env_contact_release(negf_env%contacts(icontact))
1814 DEALLOCATE (negf_env%contacts)
1824 IF (
ASSOCIATED(negf_env%s_s))
THEN
1826 DEALLOCATE (negf_env%s_s)
1827 NULLIFY (negf_env%s_s)
1834 IF (
ASSOCIATED(negf_env%v_hartree_s))
THEN
1836 DEALLOCATE (negf_env%v_hartree_s)
1837 NULLIFY (negf_env%v_hartree_s)
1841 IF (
ASSOCIATED(negf_env%mixing_storage))
THEN
1843 DEALLOCATE (negf_env%mixing_storage)
1846 CALL timestop(handle)
1853 SUBROUTINE negf_env_contact_release(contact_env)
1856 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_env_contact_release'
1860 CALL timeset(routinen, handle)
1875 IF (
ASSOCIATED(contact_env%s_00))
THEN
1877 DEALLOCATE (contact_env%s_00)
1878 NULLIFY (contact_env%s_00)
1882 IF (
ASSOCIATED(contact_env%s_01))
THEN
1884 DEALLOCATE (contact_env%s_01)
1885 NULLIFY (contact_env%s_01)
1888 IF (
ALLOCATED(contact_env%atomlist_cell0))
DEALLOCATE (contact_env%atomlist_cell0)
1889 IF (
ALLOCATED(contact_env%atomlist_cell1))
DEALLOCATE (contact_env%atomlist_cell1)
1890 IF (
ALLOCATED(contact_env%atom_map_cell0))
DEALLOCATE (contact_env%atom_map_cell0)
1892 CALL timestop(handle)
1893 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, inversion_symmetry_only, symmetry_backend, symmetry_reduction_method)
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, 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.