32#include "./base/base_uses.f90"
37 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'negf_control_types'
38 LOGICAL,
PARAMETER,
PRIVATE :: debug_this_module = .true.
49 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atomlist_bulk, atomlist_screening
52 DIMENSION(:) :: atomlist_cell
54 INTEGER :: force_env_index = -1
56 LOGICAL :: compute_fermi_level = .false.
58 LOGICAL :: refine_fermi_level = .false.
60 LOGICAL :: shift_fermi_level = .false.
62 LOGICAL :: read_write_hs = .false.
64 LOGICAL :: is_restart = .false.
66 REAL(kind=
dp) :: fermi_level = -1.0_dp
68 REAL(kind=
dp) :: fermi_level_shifted = -1.0_dp
70 REAL(kind=
dp) :: temperature = -1.0_dp
72 REAL(kind=
dp) :: v_external = 0.0_dp
82 DIMENSION(:) :: contacts
84 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atomlist_s
87 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atomlist_s_screening
89 LOGICAL :: read_write_hs = .false.
91 LOGICAL :: update_hs = .true.
93 LOGICAL :: restart_scf = .true.
95 LOGICAL :: is_dft_entire = .false.
97 LOGICAL :: is_restart = .false.
99 LOGICAL :: write_common_restart_file = .false.
101 LOGICAL :: disable_cache = .false.
103 REAL(kind=
dp) :: conv_density = -1.0_dp
105 REAL(kind=
dp) :: conv_green = -1.0_dp
107 REAL(kind=
dp) :: conv_scf = -1.0_dp
109 REAL(kind=
dp) :: eps_geometry = -1.0_dp
111 REAL(kind=
dp) :: v_bias = -1.0_dp
113 REAL(kind=
dp) :: energy_lbound = -1.0_dp
115 REAL(kind=
dp) :: eta = -1.0_dp
117 REAL(kind=
dp) :: homo_lumo_gap = -1.0_dp
119 INTEGER :: delta_npoles = -1
121 INTEGER :: gamma_kt = -1
123 INTEGER :: integr_method = -1
125 INTEGER :: integr_min_points = -1
127 INTEGER :: integr_max_points = -1
129 INTEGER :: max_scf = -1
131 INTEGER :: nprocs = -1
133 REAL(kind=
dp) :: v_shift = -1.0_dp
135 REAL(kind=
dp) :: v_shift_offset = -1.0_dp
137 INTEGER :: v_shift_maxiters = -1
140 PRIVATE :: read_negf_atomlist
153 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_control_create'
157 cpassert(.NOT.
ASSOCIATED(negf_control))
158 CALL timeset(routinen, handle)
160 ALLOCATE (negf_control)
162 CALL timestop(handle)
174 CHARACTER(len=*),
PARAMETER :: routinen =
'negf_control_release'
176 INTEGER :: handle, i, j
178 CALL timeset(routinen, handle)
180 IF (
ASSOCIATED(negf_control))
THEN
181 IF (
ALLOCATED(negf_control%atomlist_S))
DEALLOCATE (negf_control%atomlist_S)
182 IF (
ALLOCATED(negf_control%atomlist_S_screening))
DEALLOCATE (negf_control%atomlist_S_screening)
184 IF (
ALLOCATED(negf_control%contacts))
THEN
185 DO i =
SIZE(negf_control%contacts), 1, -1
186 IF (
ALLOCATED(negf_control%contacts(i)%atomlist_bulk)) &
187 DEALLOCATE (negf_control%contacts(i)%atomlist_bulk)
189 IF (
ALLOCATED(negf_control%contacts(i)%atomlist_screening)) &
190 DEALLOCATE (negf_control%contacts(i)%atomlist_screening)
192 IF (
ALLOCATED(negf_control%contacts(i)%atomlist_cell))
THEN
193 DO j =
SIZE(negf_control%contacts(i)%atomlist_cell), 1, -1
194 IF (
ALLOCATED(negf_control%contacts(i)%atomlist_cell(j)%vector)) &
195 DEALLOCATE (negf_control%contacts(i)%atomlist_cell(j)%vector)
197 DEALLOCATE (negf_control%contacts(i)%atomlist_cell)
201 DEALLOCATE (negf_control%contacts)
204 DEALLOCATE (negf_control)
207 CALL timestop(handle)
221 CHARACTER(len=*),
PARAMETER :: routinen =
'read_negf_control'
223 CHARACTER(len=default_string_length) :: contact_id_str, eta_current_str, eta_max_str, &
224 npoles_current_str, npoles_min_str, temp_current_str, temp_min_str
225 INTEGER :: delta_npoles_min, handle, i2_rep, i_rep, &
226 n2_rep, n_rep, natoms_current, &
227 natoms_total, run_type
228 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: inds
229 LOGICAL :: do_negf, is_explicit
230 REAL(kind=
dp) :: eta_max, temp_current, temp_min
232 negf_section, region_section, &
235 CALL timeset(routinen, handle)
243 CALL section_vals_get(contact_section, n_repetition=n_rep, explicit=is_explicit)
244 IF ((.NOT. is_explicit) .AND. do_negf)
THEN
245 CALL cp_abort(__location__, &
246 "At least one contact is needed for NEGF calculation.")
249 ALLOCATE (negf_control%contacts(n_rep))
254 IF ((.NOT. is_explicit) .AND. do_negf)
THEN
255 WRITE (contact_id_str,
'(I11)') i_rep
256 CALL cp_abort(__location__, &
257 "The screening region must be defined for the contact "//trim(adjustl(contact_id_str))//
".")
260 IF (is_explicit)
THEN
261 CALL read_negf_atomlist(negf_control%contacts(i_rep)%atomlist_screening, region_section, 1, subsys)
268 IF ((.NOT. is_explicit) .AND. do_negf)
THEN
269 WRITE (contact_id_str,
'(I11)') i_rep
270 CALL cp_abort(__location__, &
271 "The bulk region must be defined for the contact "//trim(adjustl(contact_id_str))//
".")
274 IF (is_explicit)
THEN
275 CALL read_negf_atomlist(negf_control%contacts(i_rep)%atomlist_bulk, region_section, 1, subsys)
279 i_val=negf_control%contacts(i_rep)%force_env_index, &
283 CALL section_vals_get(cell_section, n_repetition=n2_rep, explicit=is_explicit)
285 IF (((.NOT. is_explicit) .OR. n2_rep /= 2) .AND. negf_control%contacts(i_rep)%force_env_index <= 0 .AND. do_negf)
THEN
286 WRITE (contact_id_str,
'(I11)') i_rep
287 CALL cp_abort(__location__, &
288 "You must either provide indices of atoms belonging to two adjacent bulk unit cells "// &
289 "(BULK_REGION/CELL) for the contact, or the index of the FORCE_EVAL section (FORCE_EVAL_SECTION) "// &
290 "which will be used to construct Kohn-Sham matrix for the bulk contact "// &
291 trim(adjustl(contact_id_str))//
".")
294 IF (is_explicit .AND. n2_rep > 0)
THEN
295 ALLOCATE (negf_control%contacts(i_rep)%atomlist_cell(n2_rep))
297 DO i2_rep = 1, n2_rep
298 CALL read_negf_atomlist(negf_control%contacts(i_rep)%atomlist_cell(i2_rep)%vector, cell_section, i2_rep, subsys)
303 l_val=negf_control%contacts(i_rep)%refine_fermi_level, &
307 r_val=negf_control%contacts(i_rep)%fermi_level, &
308 i_rep_section=i_rep, explicit=is_explicit)
309 IF (.NOT. is_explicit) negf_control%contacts(i_rep)%refine_fermi_level = .false.
310 negf_control%contacts(i_rep)%compute_fermi_level = (.NOT. is_explicit) .OR. &
311 negf_control%contacts(i_rep)%refine_fermi_level
314 r_val=negf_control%contacts(i_rep)%fermi_level_shifted, &
315 i_rep_section=i_rep, explicit=is_explicit)
316 IF (is_explicit) negf_control%contacts(i_rep)%shift_fermi_level = .true.
319 r_val=negf_control%contacts(i_rep)%temperature, &
321 IF (negf_control%contacts(i_rep)%temperature <= 0.0_dp)
THEN
322 CALL cp_abort(__location__,
"Electronic temperature must be > 0")
326 r_val=negf_control%contacts(i_rep)%v_external, &
332 l_val=negf_control%contacts(i_rep)%read_write_HS, &
333 explicit=is_explicit)
334 IF (is_explicit) negf_control%contacts(i_rep)%read_write_HS = .true.
340 IF (is_explicit)
THEN
341 CALL read_negf_atomlist(negf_control%atomlist_S, region_section, 1, subsys)
346 l_val=negf_control%read_write_HS, &
347 explicit=is_explicit)
348 IF (is_explicit) negf_control%read_write_HS = .true.
365 CALL section_vals_val_get(negf_section,
"INTEGRATION_MIN_POINTS", i_val=negf_control%integr_min_points)
366 CALL section_vals_val_get(negf_section,
"INTEGRATION_MAX_POINTS", i_val=negf_control%integr_max_points)
368 IF (negf_control%integr_max_points < negf_control%integr_min_points) &
369 negf_control%integr_max_points = negf_control%integr_min_points
377 CALL section_vals_val_get(negf_section,
"V_SHIFT_MAX_ITERS", i_val=negf_control%v_shift_maxiters)
383 IF (negf_control%eta < 0.0_dp)
THEN
384 CALL cp_abort(__location__,
"ETA must be >= 0")
388 delta_npoles_min = nint(0.5_dp*(negf_control%eta/(
pi*maxval(negf_control%contacts(:)%temperature)) + 1.0_dp))
393 IF (negf_control%delta_npoles < delta_npoles_min)
THEN
395 eta_max = real(2*negf_control%delta_npoles - 1, kind=
dp)*
pi*maxval(negf_control%contacts(:)%temperature)
396 temp_current = maxval(negf_control%contacts(:)%temperature)*
kelvin
397 temp_min = negf_control%eta/(
pi*real(2*negf_control%delta_npoles - 1, kind=
dp))*
kelvin
399 WRITE (eta_current_str,
'(ES11.4E2)') negf_control%eta
400 WRITE (eta_max_str,
'(ES11.4E2)') eta_max
401 WRITE (npoles_current_str,
'(I11)') negf_control%delta_npoles
402 WRITE (npoles_min_str,
'(I11)') delta_npoles_min
403 WRITE (temp_current_str,
'(F11.3)') temp_current
404 WRITE (temp_min_str,
'(F11.3)') temp_min
406 CALL cp_abort(__location__, &
407 "Parameter DELTA_NPOLES must be at least "//trim(adjustl(npoles_min_str))// &
408 " (instead of "//trim(adjustl(npoles_current_str))// &
409 ") for given TEMPERATURE ("//trim(adjustl(temp_current_str))// &
410 " K) and ETA ("//trim(adjustl(eta_current_str))// &
411 "). Alternatively you can increase TEMPERATURE above "//trim(adjustl(temp_min_str))// &
412 " K, or decrease ETA below "//trim(adjustl(eta_max_str))// &
413 ". Please keep in mind that very tight ETA may result in dramatical precision loss"// &
414 " due to inversion of ill-conditioned matrices.")
417 negf_control%delta_npoles = delta_npoles_min
422 n_rep =
SIZE(negf_control%contacts)
423 IF (
ALLOCATED(negf_control%atomlist_S))
THEN
424 natoms_total =
SIZE(negf_control%atomlist_S)
430 IF (
ALLOCATED(negf_control%contacts(i_rep)%atomlist_screening))
THEN
431 IF (
ALLOCATED(negf_control%contacts(i_rep)%atomlist_screening)) &
432 natoms_total = natoms_total +
SIZE(negf_control%contacts(i_rep)%atomlist_screening)
436 IF (natoms_total > 0)
THEN
437 ALLOCATE (negf_control%atomlist_S_screening(natoms_total))
438 IF (
ALLOCATED(negf_control%atomlist_S))
THEN
439 natoms_total =
SIZE(negf_control%atomlist_S)
440 negf_control%atomlist_S_screening(1:natoms_total) = negf_control%atomlist_S(1:natoms_total)
446 IF (
ALLOCATED(negf_control%contacts(i_rep)%atomlist_screening))
THEN
447 natoms_current =
SIZE(negf_control%contacts(i_rep)%atomlist_screening)
449 negf_control%atomlist_S_screening(natoms_total + 1:natoms_total + natoms_current) = &
450 negf_control%contacts(i_rep)%atomlist_screening(1:natoms_current)
452 natoms_total = natoms_total + natoms_current
457 ALLOCATE (inds(natoms_total))
458 CALL sort(negf_control%atomlist_S_screening, natoms_total, inds)
462 DO i_rep = natoms_current + 1, natoms_total
463 IF (negf_control%atomlist_S_screening(i_rep) /= negf_control%atomlist_S_screening(natoms_current))
THEN
464 natoms_current = natoms_current + 1
465 negf_control%atomlist_S_screening(natoms_current) = negf_control%atomlist_S_screening(i_rep)
469 IF (natoms_current < natoms_total)
THEN
470 CALL move_alloc(negf_control%atomlist_S_screening, inds)
472 ALLOCATE (negf_control%atomlist_S_screening(natoms_current))
473 negf_control%atomlist_S_screening(1:natoms_current) = inds(1:natoms_current)
478 IF (do_negf .AND.
SIZE(negf_control%contacts) > 2)
THEN
479 CALL cp_abort(__location__, &
480 "General case (> 2 contacts) has not been implemented yet")
483 CALL timestop(handle)
493 SUBROUTINE read_negf_atomlist(atomlist, input_section, i_rep_section, subsys)
494 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(out) :: atomlist
496 INTEGER,
INTENT(in) :: i_rep_section
499 CHARACTER(len=*),
PARAMETER :: routinen =
'read_negf_atomlist'
501 CHARACTER(len=default_string_length) :: index_str, natoms_str
502 CHARACTER(len=default_string_length), &
503 DIMENSION(:),
POINTER :: cptr
504 INTEGER :: first_atom, handle, iatom, ikind, imol, iname, irep, last_atom, natoms_current, &
505 natoms_max, natoms_total, nkinds, nmols, nnames, nrep_list, nrep_molname
506 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: inds
507 INTEGER,
DIMENSION(:),
POINTER :: iptr
508 LOGICAL :: is_list, is_molname
515 CALL timeset(routinen, handle)
518 molecule_set=molecule_set, &
519 molecule_kind_set=molecule_kind_set)
520 natoms_max =
SIZE(particle_set)
521 nkinds =
SIZE(molecule_kind_set)
524 n_rep_val=nrep_list, explicit=is_list)
526 n_rep_val=nrep_molname, explicit=is_molname)
530 IF (is_list .AND. nrep_list > 0)
THEN
531 DO irep = 1, nrep_list
532 CALL section_vals_val_get(input_section,
"LIST", i_rep_section=i_rep_section, i_rep_val=irep, i_vals=iptr)
534 natoms_current =
SIZE(iptr)
535 DO iatom = 1, natoms_current
536 IF (iptr(iatom) > natoms_max)
THEN
539 CALL cp_abort(__location__, &
540 "NEGF: Atomic index "//trim(index_str)//
" given in section "// &
541 trim(input_section%section%name)//
" exceeds the maximum number of atoms ("// &
542 trim(natoms_str)//
").")
546 natoms_total = natoms_total + natoms_current
550 IF (is_molname .AND. nrep_molname > 0)
THEN
551 DO irep = 1, nrep_molname
552 CALL section_vals_val_get(input_section,
"MOLNAME", i_rep_section=i_rep_section, i_rep_val=irep, c_vals=cptr)
557 IF (molecule_kind_set(ikind)%name == cptr(iname))
EXIT
560 IF (ikind <= nkinds)
THEN
561 molecule_kind => molecule_kind_set(ikind)
565 molecule => molecule_set(iptr(imol))
566 CALL get_molecule(molecule, first_atom=first_atom, last_atom=last_atom)
567 natoms_current = last_atom - first_atom + 1
568 natoms_total = natoms_total + natoms_current
571 CALL cp_abort(__location__, &
572 "NEGF: A molecule with the name '"//trim(cptr(iname))//
"' mentioned in section "// &
573 trim(input_section%section%name)//
" has not been defined. Note that names are case sensitive.")
580 IF (natoms_total > 0)
THEN
581 ALLOCATE (atomlist(natoms_total))
585 IF (is_list .AND. nrep_list > 0)
THEN
586 DO irep = 1, nrep_list
587 CALL section_vals_val_get(input_section,
"LIST", i_rep_section=i_rep_section, i_rep_val=irep, i_vals=iptr)
589 natoms_current =
SIZE(iptr)
590 atomlist(natoms_total + 1:natoms_total + natoms_current) = iptr(1:natoms_current)
591 natoms_total = natoms_total + natoms_current
595 IF (is_molname .AND. nrep_molname > 0)
THEN
596 DO irep = 1, nrep_molname
597 CALL section_vals_val_get(input_section,
"MOLNAME", i_rep_section=i_rep_section, i_rep_val=irep, c_vals=cptr)
602 IF (molecule_kind_set(ikind)%name == cptr(iname))
EXIT
605 IF (ikind <= nkinds)
THEN
606 molecule_kind => molecule_kind_set(ikind)
610 molecule => molecule_set(iptr(imol))
611 CALL get_molecule(molecule, first_atom=first_atom, last_atom=last_atom)
613 DO natoms_current = first_atom, last_atom
614 natoms_total = natoms_total + 1
615 atomlist(natoms_total) = natoms_current
624 ALLOCATE (inds(natoms_total))
625 CALL sort(atomlist, natoms_total, inds)
629 DO iatom = natoms_current + 1, natoms_total
630 IF (atomlist(iatom) /= atomlist(natoms_current))
THEN
631 natoms_current = natoms_current + 1
632 atomlist(natoms_current) = atomlist(iatom)
636 IF (natoms_current < natoms_total)
THEN
637 CALL move_alloc(atomlist, inds)
639 ALLOCATE (atomlist(natoms_current))
640 atomlist(1:natoms_current) = inds(1:natoms_current)
645 CALL timestop(handle)
646 END SUBROUTINE read_negf_atomlist
types that represent a subsys, i.e. a part of the system
subroutine, public cp_subsys_get(subsys, ref_count, 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)
returns information about various attributes of the given subsys
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
Define the molecule kind structure types and the corresponding functionality.
subroutine, public get_molecule_kind(molecule_kind, atom_list, bond_list, bend_list, ub_list, impr_list, opbend_list, colv_list, fixd_list, g3x3_list, g4x6_list, vsite_list, torsion_list, shell_list, name, mass, charge, kind_number, natom, nbend, nbond, nub, nimpr, nopbend, nconstraint, nconstraint_fixd, nfixd, ncolv, ng3x3, ng4x6, nvsite, nfixd_restraint, ng3x3_restraint, ng4x6_restraint, nvsite_restraint, nrestraints, nmolecule, nsgf, nshell, ntorsion, molecule_list, nelectron, nelectron_alpha, nelectron_beta, bond_kind_set, bend_kind_set, ub_kind_set, impr_kind_set, opbend_kind_set, torsion_kind_set, molname_generated)
Get informations about a molecule kind.
Define the data structure for the molecule information.
subroutine, public get_molecule(molecule, molecule_kind, lmi, lci, lg3x3, lg4x6, lcolv, first_atom, last_atom, first_shell, last_shell)
Get components from a molecule data set.
Allocatable vectors for NEGF based quantum transport calculations.
Input control types for NEGF based quantum transport calculations.
subroutine, public negf_control_create(negf_control)
allocate control options for Non-equilibrium Green's Function calculation
subroutine, public read_negf_control(negf_control, input, subsys)
Read NEGF input parameters.
subroutine, public negf_control_release(negf_control)
release memory allocated for NEGF control options
Define the data structure for the particle information.
Definition of physical constants:
real(kind=dp), parameter, public kelvin
Utilities for string manipulations.
subroutine, public integer_to_string(inumber, string)
Converts an integer number to a string. The WRITE statement will return an error message,...
All kind of helpful little routines.
represents a system: atoms, molecules, their pos,vel,...
Allocatable 1-D integer vector.
Input parameters related to the NEGF run.