70#include "./base/base_uses.f90"
75 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'negf_env_types'
76 LOGICAL,
PARAMETER,
PRIVATE :: debug_this_module = .true.
86 REAL(kind=
dp),
DIMENSION(3) :: direction_vector = -1.0_dp, origin = -1.0_dp
87 REAL(kind=
dp),
DIMENSION(3) :: direction_vector_bias = -1.0_dp, origin_bias = -1.0_dp
90 INTEGER :: direction_axis = -1
92 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atomlist_cell0
94 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atomlist_cell1
97 DIMENSION(:) :: atom_map_cell0, atom_map_cell1
99 REAL(kind=
dp) :: homo_energy = -1.0_dp
104 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: rho_00, rho_01
116 DIMENSION(:) :: contacts
130 INTEGER :: mixing_method = -1
137 TYPE negf_atom_map_contact_type
139 END TYPE negf_atom_map_contact_type
154 SUBROUTINE negf_env_create(negf_env, sub_env, negf_control, force_env, negf_mixing_section, log_unit)
160 INTEGER,
INTENT(in) :: log_unit
162 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_env_create'
164 CHARACTER(len=default_string_length) :: contact_str, force_env_str, &
166 INTEGER :: handle, icontact, in_use, n_force_env, &
168 LOGICAL :: do_kpoints
170 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks_kp, matrix_s_kp
173 TYPE(negf_atom_map_contact_type),
ALLOCATABLE, &
174 DIMENSION(:) :: map_contact
179 CALL timeset(routinen, handle)
182 NULLIFY (sub_force_env)
183 CALL force_env_get(force_env, in_use=in_use, qs_env=qs_env, sub_force_env=sub_force_env)
185 IF (
ASSOCIATED(sub_force_env))
THEN
186 n_force_env =
SIZE(sub_force_env)
192 DO icontact = 1, n_force_env
193 CALL force_env_get(sub_force_env(icontact)%force_env, in_use=in_use)
199 cpabort(
"Quickstep is required for NEGF run.")
203 ncontacts =
SIZE(negf_control%contacts)
205 DO icontact = 1, ncontacts
206 IF (negf_control%contacts(icontact)%force_env_index > n_force_env)
THEN
207 WRITE (contact_str,
'(I11)') icontact
208 WRITE (force_env_str,
'(I11)') negf_control%contacts(icontact)%force_env_index
209 WRITE (n_force_env_str,
'(I11)') n_force_env
211 CALL cp_abort(__location__, &
212 "Contact number "//trim(adjustl(contact_str))//
" is linked with the FORCE_EVAL section number "// &
213 trim(adjustl(force_env_str))//
", however only "//trim(adjustl(n_force_env_str))// &
214 " FORCE_EVAL sections have been found. Note that FORCE_EVAL sections are enumerated from 0"// &
215 " and that the primary (0-th) section must contain all the atoms.")
222 CALL get_qs_env(qs_env, blacs_env=blacs_env, do_kpoints=do_kpoints, &
223 matrix_s_kp=matrix_s_kp, matrix_ks_kp=matrix_ks_kp, &
224 subsys=subsys, v_hartree_rspace=v_hartree_rspace)
227 cpabort(
"k-points are currently not supported for device FORCE_EVAL")
231 ALLOCATE (negf_env%contacts(ncontacts))
232 ALLOCATE (map_contact(ncontacts))
234 DO icontact = 1, ncontacts
235 IF (negf_control%contacts(icontact)%force_env_index > 0)
THEN
236 CALL force_env_get(sub_force_env(negf_control%contacts(icontact)%force_env_index)%force_env, qs_env=qs_env_contact)
237 CALL get_qs_env(qs_env_contact, subsys=subsys_contact)
239 CALL negf_env_contact_init_maps(contact_env=negf_env%contacts(icontact), &
240 contact_control=negf_control%contacts(icontact), &
241 atom_map=map_contact(icontact)%atom_map, &
242 eps_geometry=negf_control%eps_geometry, &
243 subsys_device=subsys, &
244 subsys_contact=subsys_contact)
246 IF (negf_env%contacts(icontact)%direction_axis == 0)
THEN
247 WRITE (contact_str,
'(I11)') icontact
248 WRITE (force_env_str,
'(I11)') negf_control%contacts(icontact)%force_env_index
249 CALL cp_abort(__location__, &
250 "One lattice vector of the contact unit cell (FORCE_EVAL section "// &
251 trim(adjustl(force_env_str))//
") must be parallel to the direction of the contact "// &
252 trim(adjustl(contact_str))//
".")
258 DO icontact = 1, ncontacts
259 IF (negf_control%contacts(icontact)%force_env_index > 0)
THEN
261 WRITE (log_unit,
'(/,T2,A,T70,I11)')
"NEGF| Construct the Kohn-Sham matrix for the contact", icontact
263 CALL force_env_get(sub_force_env(negf_control%contacts(icontact)%force_env_index)%force_env, qs_env=qs_env_contact)
265 CALL qs_energies(qs_env_contact, consistent_energies=.false., calc_forces=.false.)
267 CALL negf_env_contact_init_matrices(contact_env=negf_env%contacts(icontact), sub_env=sub_env, &
268 qs_env_contact=qs_env_contact)
269 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,79("-"))')
275 WRITE (log_unit,
'(/,T2,A,T70)')
"NEGF| Construct the Kohn-Sham matrix for the entire system"
276 CALL qs_energies(qs_env, consistent_energies=.false., calc_forces=.false.)
277 IF (log_unit > 0)
WRITE (log_unit,
'(/,T2,79("-"))')
280 DO icontact = 1, ncontacts
281 IF (negf_control%contacts(icontact)%force_env_index <= 0)
THEN
282 CALL negf_env_contact_init_matrices_gamma(contact_env=negf_env%contacts(icontact), &
283 contact_control=negf_control%contacts(icontact), &
284 sub_env=sub_env, qs_env=qs_env, &
285 eps_geometry=negf_control%eps_geometry)
290 CALL negf_env_device_init_matrices(negf_env, negf_control, sub_env, qs_env)
294 NULLIFY (negf_env%mixing_storage)
297 CALL get_qs_env(qs_env, dft_control=dft_control)
298 ALLOCATE (negf_env%mixing_storage)
300 negf_env%mixing_method, dft_control%qs_control%cutoff)
302 CALL timestop(handle)
315 SUBROUTINE negf_env_contact_init_maps(contact_env, contact_control, atom_map, &
316 eps_geometry, subsys_device, subsys_contact)
320 DIMENSION(:),
INTENT(inout) :: atom_map
321 REAL(kind=
dp),
INTENT(in) :: eps_geometry
324 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_env_contact_init_maps'
326 INTEGER :: handle, natoms
328 CALL timeset(routinen, handle)
331 contact_env%direction_vector, &
332 contact_env%origin_bias, &
333 contact_env%direction_vector_bias, &
334 contact_control%atomlist_screening, &
335 contact_control%atomlist_bulk, &
338 contact_env%direction_axis = contact_direction_axis(contact_env%direction_vector, subsys_contact, eps_geometry)
340 IF (contact_env%direction_axis /= 0)
THEN
341 natoms =
SIZE(contact_control%atomlist_bulk)
342 ALLOCATE (atom_map(natoms))
346 atom_list=contact_control%atomlist_bulk, &
347 subsys_device=subsys_device, &
348 subsys_contact=subsys_contact, &
349 eps_geometry=eps_geometry)
353 CALL list_atoms_in_bulk_primary_unit_cell(atomlist_cell0=contact_env%atomlist_cell0, &
354 atom_map_cell0=contact_env%atom_map_cell0, &
355 atomlist_bulk=contact_control%atomlist_bulk, &
357 origin=contact_env%origin, &
358 direction_vector=contact_env%direction_vector, &
359 direction_axis=contact_env%direction_axis, &
360 subsys_device=subsys_device)
363 CALL list_atoms_in_bulk_secondary_unit_cell(atomlist_cell1=contact_env%atomlist_cell1, &
364 atom_map_cell1=contact_env%atom_map_cell1, &
365 atomlist_bulk=contact_control%atomlist_bulk, &
367 origin=contact_env%origin, &
368 direction_vector=contact_env%direction_vector, &
369 direction_axis=contact_env%direction_axis, &
370 subsys_device=subsys_device)
373 CALL timestop(handle)
374 END SUBROUTINE negf_env_contact_init_maps
386 SUBROUTINE negf_env_contact_init_matrices(contact_env, sub_env, qs_env_contact)
391 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_env_contact_init_matrices'
393 INTEGER :: handle, iatom, ispin, nao, natoms, &
395 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_list0, atom_list1
396 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: index_to_cell
397 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index
398 LOGICAL :: do_kpoints
401 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks_kp, matrix_s_kp, rho_ao_kp
408 CALL timeset(routinen, handle)
411 dft_control=dft_control, &
412 do_kpoints=do_kpoints, &
414 matrix_ks_kp=matrix_ks_kp, &
415 matrix_s_kp=matrix_s_kp, &
419 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_kp)
421 CALL negf_homo_energy_estimate(contact_env%homo_energy, qs_env_contact)
423 natoms =
SIZE(contact_env%atomlist_cell0)
424 ALLOCATE (atom_list0(natoms))
426 atom_list0(iatom) = contact_env%atom_map_cell0(iatom)%iatom
430 IF (sum(abs(contact_env%atom_map_cell0(iatom)%cell(:))) > 0)
THEN
431 cpabort(
"NEGF K-points are not currently supported")
435 cpassert(
SIZE(contact_env%atomlist_cell1) == natoms)
436 ALLOCATE (atom_list1(natoms))
438 atom_list1(iatom) = contact_env%atom_map_cell1(iatom)%iatom
441 nspins = dft_control%nspins
442 nimages = dft_control%nimages
447 ALLOCATE (cell_to_index(0:0, 0:0, 0:0))
448 cell_to_index(0, 0, 0) = 1
451 ALLOCATE (index_to_cell(3, nimages))
453 IF (.NOT. do_kpoints)
DEALLOCATE (cell_to_index)
457 CALL cp_fm_struct_create(fm_struct, nrow_global=nao, ncol_global=nao, context=sub_env%blacs_env)
460 ALLOCATE (contact_env%s_00, contact_env%s_01)
465 ALLOCATE (contact_env%h_00(nspins), contact_env%h_01(nspins))
466 ALLOCATE (contact_env%rho_00(nspins), contact_env%rho_01(nspins))
477 matkp => matrix_s_kp(1, :)
479 fm_cell1=contact_env%s_01, &
480 direction_axis=contact_env%direction_axis, &
482 atom_list0=atom_list0, atom_list1=atom_list1, &
483 subsys=subsys, mpi_comm_global=para_env, &
488 matkp => matrix_ks_kp(ispin, :)
490 fm_cell1=contact_env%h_01(ispin), &
491 direction_axis=contact_env%direction_axis, &
493 atom_list0=atom_list0, atom_list1=atom_list1, &
494 subsys=subsys, mpi_comm_global=para_env, &
497 matkp => rho_ao_kp(ispin, :)
499 fm_cell1=contact_env%rho_01(ispin), &
500 direction_axis=contact_env%direction_axis, &
502 atom_list0=atom_list0, atom_list1=atom_list1, &
503 subsys=subsys, mpi_comm_global=para_env, &
507 DEALLOCATE (atom_list0, atom_list1)
509 CALL timestop(handle)
510 END SUBROUTINE negf_env_contact_init_matrices
521 SUBROUTINE negf_env_contact_init_matrices_gamma(contact_env, contact_control, sub_env, qs_env, eps_geometry)
526 REAL(kind=
dp),
INTENT(in) :: eps_geometry
528 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_env_contact_init_matrices_gamma'
530 INTEGER :: handle, iatom, icell, ispin, nao_c, &
532 LOGICAL :: do_kpoints
533 REAL(kind=
dp),
DIMENSION(2) :: r2_origin_cell
534 REAL(kind=
dp),
DIMENSION(3) :: direction_vector, origin
536 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks_kp, matrix_s_kp, rho_ao_kp
543 CALL timeset(routinen, handle)
546 dft_control=dft_control, &
547 do_kpoints=do_kpoints, &
548 matrix_ks_kp=matrix_ks_kp, &
549 matrix_s_kp=matrix_s_kp, &
553 CALL qs_rho_get(rho_struct, rho_ao_kp=rho_ao_kp)
556 CALL cp_abort(__location__, &
557 "K-points in device region have not been implemented yet.")
560 nspins = dft_control%nspins
564 CALL cp_abort(__location__, &
565 "Primary and secondary bulk contact cells should be identical "// &
566 "in terms of the number of atoms of each kind, and their basis sets. "// &
567 "No single atom, however, can be shared between these two cells.")
570 contact_env%homo_energy = 0.0_dp
573 contact_env%direction_vector, &
574 contact_env%origin_bias, &
575 contact_env%direction_vector_bias, &
576 contact_control%atomlist_screening, &
577 contact_control%atomlist_bulk, &
580 contact_env%direction_axis = contact_direction_axis(contact_env%direction_vector, subsys, eps_geometry)
585 origin = particle_set(contact_control%atomlist_screening(1))%r
586 DO iatom = 2,
SIZE(contact_control%atomlist_screening)
587 origin = origin + particle_set(contact_control%atomlist_screening(iatom))%r
589 origin = origin/real(
SIZE(contact_control%atomlist_screening), kind=
dp)
592 direction_vector = particle_set(contact_control%atomlist_cell(icell)%vector(1))%r
593 DO iatom = 2,
SIZE(contact_control%atomlist_cell(icell)%vector)
594 direction_vector = direction_vector + particle_set(contact_control%atomlist_cell(icell)%vector(iatom))%r
596 direction_vector = direction_vector/real(
SIZE(contact_control%atomlist_cell(icell)%vector), kind=
dp)
597 direction_vector = direction_vector - origin
598 r2_origin_cell(icell) = dot_product(direction_vector, direction_vector)
601 IF (abs(r2_origin_cell(1) - r2_origin_cell(2)) < (eps_geometry*eps_geometry))
THEN
604 CALL cp_abort(__location__, &
605 "Primary and secondary bulk contact cells should not overlap ")
606 ELSE IF (r2_origin_cell(1) < r2_origin_cell(2))
THEN
607 ALLOCATE (contact_env%atomlist_cell0(
SIZE(contact_control%atomlist_cell(1)%vector)))
608 contact_env%atomlist_cell0(:) = contact_control%atomlist_cell(1)%vector(:)
609 ALLOCATE (contact_env%atomlist_cell1(
SIZE(contact_control%atomlist_cell(2)%vector)))
610 contact_env%atomlist_cell1(:) = contact_control%atomlist_cell(2)%vector(:)
612 ALLOCATE (contact_env%atomlist_cell0(
SIZE(contact_control%atomlist_cell(2)%vector)))
613 contact_env%atomlist_cell0(:) = contact_control%atomlist_cell(2)%vector(:)
614 ALLOCATE (contact_env%atomlist_cell1(
SIZE(contact_control%atomlist_cell(1)%vector)))
615 contact_env%atomlist_cell1(:) = contact_control%atomlist_cell(1)%vector(:)
619 CALL cp_fm_struct_create(fm_struct, nrow_global=nao_c, ncol_global=nao_c, context=sub_env%blacs_env)
620 ALLOCATE (contact_env%h_00(nspins), contact_env%h_01(nspins))
621 ALLOCATE (contact_env%rho_00(nspins), contact_env%rho_01(nspins))
628 ALLOCATE (contact_env%s_00, contact_env%s_01)
635 fm=contact_env%h_00(ispin), &
636 atomlist_row=contact_env%atomlist_cell0, &
637 atomlist_col=contact_env%atomlist_cell0, &
638 subsys=subsys, mpi_comm_global=para_env, &
639 do_upper_diag=.true., do_lower=.true.)
641 fm=contact_env%h_01(ispin), &
642 atomlist_row=contact_env%atomlist_cell0, &
643 atomlist_col=contact_env%atomlist_cell1, &
644 subsys=subsys, mpi_comm_global=para_env, &
645 do_upper_diag=.true., do_lower=.true.)
648 fm=contact_env%rho_00(ispin), &
649 atomlist_row=contact_env%atomlist_cell0, &
650 atomlist_col=contact_env%atomlist_cell0, &
651 subsys=subsys, mpi_comm_global=para_env, &
652 do_upper_diag=.true., do_lower=.true.)
654 fm=contact_env%rho_01(ispin), &
655 atomlist_row=contact_env%atomlist_cell0, &
656 atomlist_col=contact_env%atomlist_cell1, &
657 subsys=subsys, mpi_comm_global=para_env, &
658 do_upper_diag=.true., do_lower=.true.)
662 fm=contact_env%s_00, &
663 atomlist_row=contact_env%atomlist_cell0, &
664 atomlist_col=contact_env%atomlist_cell0, &
665 subsys=subsys, mpi_comm_global=para_env, &
666 do_upper_diag=.true., do_lower=.true.)
668 fm=contact_env%s_01, &
669 atomlist_row=contact_env%atomlist_cell0, &
670 atomlist_col=contact_env%atomlist_cell1, &
671 subsys=subsys, mpi_comm_global=para_env, &
672 do_upper_diag=.true., do_lower=.true.)
674 CALL timestop(handle)
675 END SUBROUTINE negf_env_contact_init_matrices_gamma
686 SUBROUTINE negf_env_device_init_matrices(negf_env, negf_control, sub_env, qs_env)
692 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_env_device_init_matrices'
694 INTEGER :: handle, icontact, ispin, nao_c, nao_s, &
696 LOGICAL :: do_kpoints
699 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks_kp, matrix_s_kp
707 CALL timeset(routinen, handle)
709 IF (
ALLOCATED(negf_control%atomlist_S_screening))
THEN
711 dft_control=dft_control, &
712 do_kpoints=do_kpoints, &
713 matrix_ks_kp=matrix_ks_kp, &
714 matrix_s_kp=matrix_s_kp, &
718 CALL pw_env_get(pw_env, auxbas_pw_pool=pw_pool)
721 CALL cp_abort(__location__, &
722 "K-points in device region have not been implemented yet.")
725 ncontacts =
SIZE(negf_control%contacts)
726 nspins = dft_control%nspins
732 NULLIFY (negf_env%s_s, negf_env%v_hartree_s, fm_struct)
733 ALLOCATE (negf_env%h_s(nspins))
735 CALL cp_fm_struct_create(fm_struct, nrow_global=nao_s, ncol_global=nao_s, context=sub_env%blacs_env)
736 ALLOCATE (negf_env%s_s)
741 ALLOCATE (negf_env%v_hartree_s)
746 ALLOCATE (negf_env%h_sc(nspins, ncontacts), negf_env%s_sc(ncontacts))
747 DO icontact = 1, ncontacts
749 CALL cp_fm_struct_create(fm_struct, nrow_global=nao_s, ncol_global=nao_c, context=sub_env%blacs_env)
754 CALL cp_fm_create(negf_env%h_sc(ispin, icontact), fm_struct)
763 fm=negf_env%h_s(ispin), &
764 atomlist_row=negf_control%atomlist_S_screening, &
765 atomlist_col=negf_control%atomlist_S_screening, &
766 subsys=subsys, mpi_comm_global=para_env, &
767 do_upper_diag=.true., do_lower=.true.)
772 atomlist_row=negf_control%atomlist_S_screening, &
773 atomlist_col=negf_control%atomlist_S_screening, &
774 subsys=subsys, mpi_comm_global=para_env, &
775 do_upper_diag=.true., do_lower=.true.)
778 NULLIFY (hmat%matrix)
780 CALL dbcsr_copy(matrix_b=hmat%matrix, matrix_a=matrix_s_kp(1, 1)%matrix)
783 CALL pw_pool%create_pw(v_hartree)
784 CALL negf_env_init_v_hartree(v_hartree, negf_env%contacts, negf_control%contacts)
786 CALL integrate_v_rspace(v_rspace=v_hartree, hmat=hmat, qs_env=qs_env, &
787 calculate_forces=.false., compute_tau=.false., gapw=.false.)
789 CALL pw_pool%give_back_pw(v_hartree)
792 fm=negf_env%v_hartree_s, &
793 atomlist_row=negf_control%atomlist_S_screening, &
794 atomlist_col=negf_control%atomlist_S_screening, &
795 subsys=subsys, mpi_comm_global=para_env, &
796 do_upper_diag=.true., do_lower=.true.)
801 DO icontact = 1, ncontacts
804 fm=negf_env%h_sc(ispin, icontact), &
805 atomlist_row=negf_control%atomlist_S_screening, &
806 atomlist_col=negf_env%contacts(icontact)%atomlist_cell0, &
807 subsys=subsys, mpi_comm_global=para_env, &
808 do_upper_diag=.true., do_lower=.true.)
812 fm=negf_env%s_sc(icontact), &
813 atomlist_row=negf_control%atomlist_S_screening, &
814 atomlist_col=negf_env%contacts(icontact)%atomlist_cell0, &
815 subsys=subsys, mpi_comm_global=para_env, &
816 do_upper_diag=.true., do_lower=.true.)
820 CALL timestop(handle)
821 END SUBROUTINE negf_env_device_init_matrices
830 SUBROUTINE negf_env_init_v_hartree(v_hartree, contact_env, contact_control)
833 INTENT(in) :: contact_env
835 INTENT(in) :: contact_control
837 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_env_init_v_hartree'
838 REAL(kind=
dp),
PARAMETER :: threshold = 16.0_dp*epsilon(0.0_dp)
840 INTEGER :: dx, dy, dz, handle, icontact, ix, iy, &
841 iz, lx, ly, lz, ncontacts, ux, uy, uz
842 REAL(kind=
dp) :: dvol, pot, proj, v1, v2
843 REAL(kind=
dp),
DIMENSION(3) :: dirvector_bias, point_coord, &
844 point_indices, vector
846 CALL timeset(routinen, handle)
848 ncontacts =
SIZE(contact_env)
849 cpassert(
SIZE(contact_control) == ncontacts)
850 cpassert(ncontacts == 2)
852 dirvector_bias = contact_env(2)%origin_bias - contact_env(1)%origin_bias
853 v1 = contact_control(1)%v_external
854 v2 = contact_control(2)%v_external
856 lx = v_hartree%pw_grid%bounds_local(1, 1)
857 ux = v_hartree%pw_grid%bounds_local(2, 1)
858 ly = v_hartree%pw_grid%bounds_local(1, 2)
859 uy = v_hartree%pw_grid%bounds_local(2, 2)
860 lz = v_hartree%pw_grid%bounds_local(1, 3)
861 uz = v_hartree%pw_grid%bounds_local(2, 3)
863 dx = v_hartree%pw_grid%npts(1)/2
864 dy = v_hartree%pw_grid%npts(2)/2
865 dz = v_hartree%pw_grid%npts(3)/2
867 dvol = v_hartree%pw_grid%dvol
870 point_indices(3) = real(iz + dz, kind=
dp)
872 point_indices(2) = real(iy + dy, kind=
dp)
875 point_indices(1) = real(ix + dx, kind=
dp)
876 point_coord(:) = matmul(v_hartree%pw_grid%dh, point_indices)
878 vector = point_coord - contact_env(1)%origin_bias
880 IF (proj + threshold >= 0.0_dp .AND. proj - threshold <= 1.0_dp)
THEN
884 IF (proj < 0.0_dp)
THEN
886 ELSE IF (proj > 1.0_dp)
THEN
889 pot = v1 + (v2 - v1)*proj
892 DO icontact = 1, ncontacts
893 vector = point_coord - contact_env(icontact)%origin_bias
896 IF (proj + threshold >= 0.0_dp .AND. proj - threshold <= 1.0_dp)
THEN
897 pot = contact_control(icontact)%v_external
903 v_hartree%array(ix, iy, iz) = pot*dvol
908 CALL timestop(handle)
909 END SUBROUTINE negf_env_init_v_hartree
920 FUNCTION contact_direction_axis(direction_vector, subsys_contact, eps_geometry)
RESULT(direction_axis)
921 REAL(kind=
dp),
DIMENSION(3),
INTENT(in) :: direction_vector
923 REAL(kind=
dp),
INTENT(in) :: eps_geometry
924 INTEGER :: direction_axis
927 REAL(kind=
dp),
DIMENSION(3) :: scaled
937 IF (abs(scaled(i)) > eps_geometry)
THEN
938 IF (scaled(i) > 0.0_dp)
THEN
948 IF (naxes /= 1) direction_axis = 0
949 END FUNCTION contact_direction_axis
958 SUBROUTINE negf_homo_energy_estimate(homo_energy, qs_env)
959 REAL(kind=
dp),
INTENT(out) :: homo_energy
962 CHARACTER(LEN=*),
PARAMETER :: routinen =
'negf_homo_energy_estimate'
963 INTEGER,
PARAMETER :: gamma_point = 1
965 INTEGER :: handle, homo, ikpgr, ikpoint, imo, &
966 ispin, kplocal, nmo, nspins
967 INTEGER,
DIMENSION(2) :: kp_range
968 LOGICAL :: do_kpoints
969 REAL(kind=
dp) :: my_homo_energy
970 REAL(kind=
dp),
DIMENSION(:),
POINTER :: eigenvalues
974 TYPE(
mo_set_type),
DIMENSION(:, :),
POINTER :: mos_kp
977 CALL timeset(routinen, handle)
978 my_homo_energy = 0.0_dp
980 CALL get_qs_env(qs_env, para_env=para_env, mos=mos, kpoints=kpoints, do_kpoints=do_kpoints)
983 CALL get_kpoint_info(kpoints, kp_env=kp_env, kp_range=kp_range, para_env_kp=para_env_kp)
986 IF (para_env_kp%mepos == 0 .AND. kp_range(1) <= gamma_point .AND. kp_range(2) >= gamma_point)
THEN
987 kplocal = kp_range(2) - kp_range(1) + 1
989 DO ikpgr = 1, kplocal
990 CALL get_kpoint_env(kp_env(ikpgr)%kpoint_env, nkpoint=ikpoint, mos=mos_kp)
992 IF (ikpoint == gamma_point)
THEN
994 CALL get_mo_set(mos_kp(1, 1), homo=homo, eigenvalues=eigenvalues)
996 my_homo_energy = eigenvalues(homo)
1002 CALL para_env%sum(my_homo_energy)
1009 cpabort(
"It is strongly advised to use k-points within all contact FORCE_EVAL-s")
1013 spin_loop:
DO ispin = 1, nspins
1014 CALL get_mo_set(mos(ispin), homo=homo, nmo=nmo, eigenvalues=eigenvalues)
1017 IF (eigenvalues(imo) /= 0.0_dp)
EXIT spin_loop
1022 cpabort(
"Orbital transformation (OT) for contact FORCE_EVAL-s is not supported")
1025 my_homo_energy = eigenvalues(homo)
1028 homo_energy = my_homo_energy
1029 CALL timestop(handle)
1030 END SUBROUTINE negf_homo_energy_estimate
1046 SUBROUTINE list_atoms_in_bulk_primary_unit_cell(atomlist_cell0, atom_map_cell0, atomlist_bulk, atom_map, &
1047 origin, direction_vector, direction_axis, subsys_device)
1048 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(inout) :: atomlist_cell0
1050 DIMENSION(:),
INTENT(inout) :: atom_map_cell0
1051 INTEGER,
DIMENSION(:),
INTENT(in) :: atomlist_bulk
1053 REAL(kind=
dp),
DIMENSION(3),
INTENT(in) :: origin, direction_vector
1054 INTEGER,
INTENT(in) :: direction_axis
1057 CHARACTER(LEN=*),
PARAMETER :: routinen =
'list_atoms_in_bulk_primary_unit_cell'
1059 INTEGER :: atom_min, dir_axis_min, &
1060 direction_axis_abs, handle, iatom, &
1061 natoms_bulk, natoms_cell0
1062 REAL(kind=
dp) :: proj, proj_min
1063 REAL(kind=
dp),
DIMENSION(3) :: vector
1066 CALL timeset(routinen, handle)
1067 CALL qs_subsys_get(subsys_device, particle_set=particle_set)
1069 natoms_bulk =
SIZE(atomlist_bulk)
1070 cpassert(
SIZE(atom_map, 1) == natoms_bulk)
1071 direction_axis_abs = abs(direction_axis)
1076 DO iatom = 1, natoms_bulk
1077 vector = particle_set(atomlist_bulk(iatom))%r - origin
1080 IF (proj < proj_min)
THEN
1086 dir_axis_min = atom_map(atom_min)%cell(direction_axis_abs)
1089 DO iatom = 1, natoms_bulk
1090 IF (atom_map(iatom)%cell(direction_axis_abs) == dir_axis_min) &
1091 natoms_cell0 = natoms_cell0 + 1
1094 ALLOCATE (atomlist_cell0(natoms_cell0))
1095 ALLOCATE (atom_map_cell0(natoms_cell0))
1098 DO iatom = 1, natoms_bulk
1099 IF (atom_map(iatom)%cell(direction_axis_abs) == dir_axis_min)
THEN
1100 natoms_cell0 = natoms_cell0 + 1
1101 atomlist_cell0(natoms_cell0) = atomlist_bulk(iatom)
1102 atom_map_cell0(natoms_cell0) = atom_map(iatom)
1106 CALL timestop(handle)
1107 END SUBROUTINE list_atoms_in_bulk_primary_unit_cell
1126 SUBROUTINE list_atoms_in_bulk_secondary_unit_cell(atomlist_cell1, atom_map_cell1, atomlist_bulk, atom_map, &
1127 origin, direction_vector, direction_axis, subsys_device)
1128 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(inout) :: atomlist_cell1
1130 DIMENSION(:),
INTENT(inout) :: atom_map_cell1
1131 INTEGER,
DIMENSION(:),
INTENT(in) :: atomlist_bulk
1133 REAL(kind=
dp),
DIMENSION(3),
INTENT(in) :: origin, direction_vector
1134 INTEGER,
INTENT(in) :: direction_axis
1137 CHARACTER(LEN=*),
PARAMETER :: routinen =
'list_atoms_in_bulk_secondary_unit_cell'
1139 INTEGER :: atom_min, dir_axis_min, &
1140 direction_axis_abs, handle, iatom, &
1141 natoms_bulk, natoms_cell1, offset
1142 REAL(kind=
dp) :: proj, proj_min
1143 REAL(kind=
dp),
DIMENSION(3) :: vector
1146 CALL timeset(routinen, handle)
1147 CALL qs_subsys_get(subsys_device, particle_set=particle_set)
1149 natoms_bulk =
SIZE(atomlist_bulk)
1150 cpassert(
SIZE(atom_map, 1) == natoms_bulk)
1151 direction_axis_abs = abs(direction_axis)
1152 offset = sign(1, direction_axis)
1157 DO iatom = 1, natoms_bulk
1158 vector = particle_set(atomlist_bulk(iatom))%r - origin
1161 IF (proj < proj_min)
THEN
1167 dir_axis_min = atom_map(atom_min)%cell(direction_axis_abs)
1170 DO iatom = 1, natoms_bulk
1171 IF (atom_map(iatom)%cell(direction_axis_abs) == dir_axis_min + offset) &
1172 natoms_cell1 = natoms_cell1 + 1
1175 ALLOCATE (atomlist_cell1(natoms_cell1))
1176 ALLOCATE (atom_map_cell1(natoms_cell1))
1179 DO iatom = 1, natoms_bulk
1180 IF (atom_map(iatom)%cell(direction_axis_abs) == dir_axis_min + offset)
THEN
1181 natoms_cell1 = natoms_cell1 + 1
1182 atomlist_cell1(natoms_cell1) = atomlist_bulk(iatom)
1183 atom_map_cell1(natoms_cell1) = atom_map(iatom)
1184 atom_map_cell1(natoms_cell1)%cell(direction_axis_abs) = dir_axis_min
1188 CALL timestop(handle)
1189 END SUBROUTINE list_atoms_in_bulk_secondary_unit_cell
1200 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_env_release'
1202 INTEGER :: handle, icontact
1204 CALL timeset(routinen, handle)
1206 IF (
ALLOCATED(negf_env%contacts))
THEN
1207 DO icontact =
SIZE(negf_env%contacts), 1, -1
1208 CALL negf_env_contact_release(negf_env%contacts(icontact))
1211 DEALLOCATE (negf_env%contacts)
1221 IF (
ASSOCIATED(negf_env%s_s))
THEN
1223 DEALLOCATE (negf_env%s_s)
1224 NULLIFY (negf_env%s_s)
1231 IF (
ASSOCIATED(negf_env%v_hartree_s))
THEN
1233 DEALLOCATE (negf_env%v_hartree_s)
1234 NULLIFY (negf_env%v_hartree_s)
1238 IF (
ASSOCIATED(negf_env%mixing_storage))
THEN
1240 DEALLOCATE (negf_env%mixing_storage)
1243 CALL timestop(handle)
1250 SUBROUTINE negf_env_contact_release(contact_env)
1253 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_env_contact_release'
1257 CALL timeset(routinen, handle)
1272 IF (
ASSOCIATED(contact_env%s_00))
THEN
1274 DEALLOCATE (contact_env%s_00)
1275 NULLIFY (contact_env%s_00)
1279 IF (
ASSOCIATED(contact_env%s_01))
THEN
1281 DEALLOCATE (contact_env%s_01)
1282 NULLIFY (contact_env%s_01)
1285 IF (
ALLOCATED(contact_env%atomlist_cell0))
DEALLOCATE (contact_env%atomlist_cell0)
1286 IF (
ALLOCATED(contact_env%atomlist_cell1))
DEALLOCATE (contact_env%atomlist_cell1)
1287 IF (
ALLOCATED(contact_env%atom_map_cell0))
DEALLOCATE (contact_env%atom_map_cell0)
1289 CALL timestop(handle)
1290 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)
...
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_create(matrix, matrix_struct, name, use_sp, nrow, ncol, set_zero)
creates a new full matrix with the given structure
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
Types and basic routines needed for a kpoint calculation.
subroutine, public get_kpoint_env(kpoint_env, nkpoint, wkp, xkp, is_local, mos)
Get information from a single kpoint environment.
subroutine, public get_kpoint_info(kpoint, kp_scheme, nkp_grid, kp_shift, symmetry, verbose, full_grid, use_real_wfn, eps_geo, parallel_group_size, kp_range, nkp, xkp, wkp, para_env, blacs_env_all, para_env_kp, para_env_inter_kp, blacs_env, kp_env, kp_aux_env, mpools, iogrp, nkp_groups, kp_dist, cell_to_index, index_to_cell, sab_nl, sab_nl_nosym)
Retrieve information from a kpoint environment.
Interface to the message passing library MPI.
Map atoms between various force environments.
subroutine, public negf_map_atomic_indices(atom_map, atom_list, subsys_device, subsys_contact, eps_geometry)
Map atoms in the cell 'subsys_device' listed in 'atom_list' with the corresponding atoms in the cell ...
Input control types for NEGF based quantum transport calculations.
Environment for NEGF based quantum transport calculations.
subroutine, public negf_env_release(negf_env)
Release a NEGF environment variable.
subroutine, public negf_env_create(negf_env, sub_env, negf_control, force_env, negf_mixing_section, log_unit)
Create a new NEGF environment and compute the relevant Kohn-Sham matrices.
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, 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, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Integrate single or product functions over a potential on a RS grid.
Definition and initialisation of the mo data type.
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kts, mu, flexible_electron_count)
Get the components of a MO set data structure.
superstucture that hold various representations of the density and keeps track of which ones are vali...
subroutine, public qs_rho_get(rho_struct, rho_ao, rho_ao_im, rho_ao_kp, rho_ao_im_kp, rho_r, drho_r, rho_g, drho_g, tau_r, tau_g, rho_r_valid, drho_r_valid, rho_g_valid, drho_g_valid, tau_r_valid, tau_g_valid, tot_rho_r, tot_rho_g, rho_r_sccs, soft_valid, complex_rho_ao)
returns info about the density described by this object. If some representation is not available an e...
types that represent a quickstep subsys
subroutine, public qs_subsys_get(subsys, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell, cell_ref, use_ref_cell, energy, force, qs_kind_set, cp_subsys, nelectron_total, nelectron_spin)
...
Type defining parameters related to the simulation cell.
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
keeps the information about the structure of a full matrix
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.