35 use,
intrinsic :: iso_fortran_env
77 logical :: computepdos
79 integer :: ldos_nenergies = -1
80 real(real64),
allocatable :: ldos_energies(:)
82 integer(int64) :: method
90 subroutine dos_init(this, namespace, st, kpoints)
91 type(dos_t),
intent(out) :: this
92 type(namespace_t),
intent(in) :: namespace
93 type(states_elec_t),
intent(in) :: st
94 type(kpoints_t),
intent(in) :: kpoints
96 real(real64) :: evalmin, evalmax, eextend
104 npath = kpoints%nkpt_in_path()
105 if (st%nik > npath)
then
106 evalmin = minval(st%eigenval(1:st%nst, 1:(st%nik-npath)))
107 evalmax = maxval(st%eigenval(1:st%nst, 1:(st%nik-npath)))
109 evalmin = minval(st%eigenval(1:st%nst, 1:st%nik))
110 evalmax = maxval(st%eigenval(1:st%nst, 1:st%nik))
113 eextend = (evalmax - evalmin) /
m_four
128 call parse_variable(namespace,
'DOSMethod', option__dosmethod__smear, this%method)
157 call parse_variable(namespace,
'DOSEnergyPoints', 500, this%epoints)
182 call parse_variable(namespace,
'DOSComputePDOS', .false., this%computepdos)
185 this%de = (this%emax - this%emin) / (this%epoints - 1)
197 safe_allocate(this%ldos_energies(1:this%ldos_nenergies))
198 do ie = 1, this%ldos_nenergies
203 this%ldos_nenergies = -1
211 type(
dos_t),
intent(inout) :: this
215 safe_deallocate_a(this%ldos_energies)
216 this%ldos_nenergies = -1
223 subroutine dos_write_dos(this, dir, st, box, ions, mesh, hm, namespace)
224 type(
dos_t),
intent(in) :: this
225 character(len=*),
intent(in) :: dir
227 class(
box_t),
intent(in) :: box
228 type(
ions_t),
target,
intent(in) :: ions
229 class(
mesh_t),
intent(in) :: mesh
233 integer :: ie, ik, ist, is, ns, maxdos, ib, ind
234 integer,
allocatable :: iunit(:)
235 real(real64) :: energy
236 real(real64),
allocatable :: tdos(:)
237 real(real64),
allocatable :: dos(:,:,:)
238 character(len=64) :: filename,format_str
241 integer :: ii, ll, mm, nn, work, norb, work2
242 integer :: ia, iorb, idim
243 real(real64) :: threshold
244 real(real64),
allocatable :: ddot(:,:,:)
245 complex(real64),
allocatable :: zdot(:,:,:)
246 real(real64),
allocatable :: weight(:,:,:)
250 real(real64) :: e_simplex(4)
251 real(real64) :: dos_simplex
257 if (st%d%nspin == 2) ns = 2
261 safe_allocate(dos(1:this%epoints, 1:st%nst, 0:ns-1))
262 safe_allocate(iunit(0:ns-1))
269 write(filename,
'(a,i4.4,a,i1.1,a)')
'dos-', ist,
'-', is+1,
'.dat'
271 write(filename,
'(a,i4.4,a)')
'dos-', ist,
'.dat'
273 iunit(is) =
io_open(trim(dir)//
'/'//trim(filename), namespace, action=
'write')
278 do ie = 1, this%epoints
279 energy = this%emin + (ie - 1) * this%de
281 select case (this%method)
282 case (option__dosmethod__smear)
284 do ik = 1, st%nik, ns
286 dos(ie, ist, is) = dos(ie, ist, is) + st%kweights(ik+is) *
m_one/
m_pi * &
287 this%gamma / ((energy - st%eigenval(ist, ik+is))**2 + this%gamma**2)
290 case (option__dosmethod__tetrahedra)
292 assert(
associated(hm%kpoints%simplex))
294 do ii = 1, hm%kpoints%simplex%n_simplices
296 do ll = 1,
size(hm%kpoints%simplex%simplices, 2)
297 ik = hm%kpoints%simplex%simplices(ii, ll)
298 ik = ns * (ik - 1) + 1
299 e_simplex(ll) = st%eigenval(ist, ik+is)
302 dos(ie, ist, is) = dos(ie, ist, is) + dos_simplex / hm%kpoints%simplex%n_simplices
321 safe_allocate(tdos(1))
326 write(filename,
'(a,i1.1,a)')
'total-dos-', is+1,
'.dat'
327 iunit(is) =
io_open(trim(dir)//
'/'//trim(filename), namespace, action=
'write')
329 write(iunit(is),
'(3a)')
'# energy [', trim(
units_abbrev(
units_out%energy)),
'], total DOS (spin-resolved)'
331 do ie = 1, this%epoints
332 energy = this%emin + (ie - 1) * this%de
335 tdos(1) = tdos(1) + dos(ie, ist, is)
347 iunit(0) =
io_open(trim(dir)//
'/'//
'total-dos.dat', namespace, action=
'write')
351 do ie = 1, this%epoints
352 energy = this%emin + (ie - 1) * this%de
356 tdos(1) = tdos(1) + dos(ie, ist, is)
366 safe_deallocate_a(tdos)
370 iunit(0) =
io_open(trim(dir)//
'/'//
'total-dos-efermi.dat', namespace, action=
'write')
372 '] in a format compatible with total-dos.dat'
375 maxdos = st%smear%el_per_state * st%nst
385 if (this%computepdos)
then
388 call parse_variable(namespace,
'AOThreshold', 0.01_real64, threshold)
391 do ia = 1, ions%natoms
398 os%spec => ions%atom(ia)%species
402 do iorb = 1, os%spec%get_niwfs()
403 call os%spec%get_iwf_ilm(iorb, 1, ii, ll, mm)
404 call os%spec%get_iwf_n(iorb, 1, nn)
410 option__aotruncation__ao_full, threshold)
416 os%use_submesh = .false.
417 os%allocated_on_mesh = .
true.
418 os%spec => ions%atom(ia)%species
420 do work = 1, os%norbs
424 ions%atom(ia)%species, mesh, os%sphere, os%ii, os%ll, os%jj, &
425 os, work, os%radius, os%ndim, use_mesh=.not.os%use_submesh, &
426 normalize = normalize)
429 ions%atom(ia)%species, mesh, os%sphere, os%ii, os%ll, os%jj, &
430 os, work, os%radius, os%ndim, &
431 use_mesh = .not. hm%phase%is_allocated() .and. .not. os%use_submesh, &
432 normalize = normalize)
436 if (hm%phase%is_allocated())
then
438 safe_allocate(os%phase(1:os%sphere%np, st%d%kpt%start:st%d%kpt%end))
441 if (.not. os%use_submesh)
then
442 safe_allocate(os%eorb_mesh(1:mesh%np, 1:os%norbs, 1:os%ndim, st%d%kpt%start:st%d%kpt%end))
443 os%eorb_mesh(:,:,:,:) =
m_zero
445 safe_allocate(os%eorb_submesh(1:os%sphere%np, 1:os%ndim, 1:os%norbs, st%d%kpt%start:st%d%kpt%end))
446 os%eorb_submesh(:,:,:,:) =
m_zero
450 os%ldorbs_eorb = max(
pad_pow2(os%sphere%np), 1)
451 if(.not. os%use_submesh) os%ldorbs_eorb = max(
pad_pow2(os%sphere%mesh%np), 1)
453 safe_allocate(os%buff_eorb(st%d%kpt%start:st%d%kpt%end))
454 do ik= st%d%kpt%start, st%d%kpt%end
460 vec_pot = hm%hm_base%uniform_vector_potential, &
461 vec_pot_var = hm%hm_base%vector_potential)
472 write(filename,
'(a, i3.3, a1, a, i1.1, a1,a)')
'pdos-at', ia,
'-', trim(os%spec%get_label()), &
475 write(filename,
'(a, i3.3, a1, a, a1,a)')
'pdos-at', ia,
'-', trim(os%spec%get_label()), &
479 iunit(0) =
io_open(trim(dir)//
'/'//trim(filename), namespace, action=
'write')
482 '], projected DOS (total and orbital resolved)'
486 safe_allocate(ddot(1:st%d%dim, 1:os%norbs, 1:st%block_size))
488 safe_allocate(zdot(1:st%d%dim, 1:os%norbs, 1:st%block_size))
491 safe_allocate(weight(1:os%norbs,1:st%nik,1:st%nst))
492 weight(1:os%norbs,1:st%nik,1:st%nst) =
m_zero
494 do ik = st%d%kpt%start, st%d%kpt%end
495 do ib = st%group%block_start, st%group%block_end
497 if (hm%phase%is_allocated())
then
499 call st%group%psib(ib, ik)%copy_to(epsib)
500 call hm%phase%apply_to(mesh, mesh%np, .false., epsib, src = st%group%psib(ib, ik))
502 epsib => st%group%psib(ib, ik)
507 do ist = 1, st%group%psib(ib, ik)%nst
508 ind = st%group%psib(ib, ik)%ist(ist)
509 do iorb = 1, os%norbs
510 do idim = 1, st%d%dim
511 weight(iorb, ik, ind) = weight(iorb, ik, ind) + st%kweights(ik) * abs(ddot(idim, iorb, ist))**2
517 do ist = 1, st%group%psib(ib, ik)%nst
518 ind = st%group%psib(ib, ik)%ist(ist)
519 do iorb = 1, os%norbs
520 do idim = 1, st%d%dim
521 weight(iorb, ik, ind) = weight(iorb, ik, ind) + st%kweights(ik) * abs(zdot(idim, iorb, ist))**2
527 if (hm%phase%is_allocated())
then
528 call epsib%end(copy=.false.)
529 safe_deallocate_p(epsib)
535 if (st%parallel_in_states .or. st%d%kpt%parallel)
then
539 safe_deallocate_a(ddot)
540 safe_deallocate_a(zdot)
543 write(format_str,
'(a,i2,a)')
'(', os%norbs+2,
'f12.6)'
544 safe_allocate(tdos(1:os%norbs))
545 do ie = 1, this%epoints
546 energy = this%emin + (ie - 1) * this%de
547 do iorb = 1, os%norbs
551 tdos(iorb) = tdos(iorb) + weight(iorb,ik,ist) *
m_one/
m_pi * &
552 this%gamma / ((energy - st%eigenval(ist, ik))**2 + this%gamma**2)
561 safe_deallocate_a(tdos)
566 safe_deallocate_a(weight)
574 safe_deallocate_a(iunit)
575 safe_deallocate_a(dos)
583 type(
dos_t),
intent(in) :: this
584 character(len=*),
intent(in) :: dir
586 type(
ions_t),
target,
intent(in) :: ions
590 integer :: ie, ik, val, cond, is, ns
591 integer,
allocatable :: iunit(:)
592 real(real64) :: energy
593 real(real64) :: tjdos(1)
594 real(real64),
allocatable :: jdos(:,:)
595 character(len=64) :: filename
601 if (st%d%nspin == 2) ns = 2
605 safe_allocate(jdos(1:this%epoints, 0:ns-1))
606 safe_allocate(iunit(0:ns-1))
611 do cond = val, st%nst
612 do ik = 1, st%nik, ns
615 if(st%occ(cond, ik+is) >
m_epsilon) cycle
616 do ie = 1, this%epoints
617 energy = (ie - 1) * this%de
619 jdos(ie, is) = jdos(ie, is) + st%kweights(ik+is) *
m_one/
m_pi * &
620 this%gamma / ((energy - (st%eigenval(cond, ik+is)-st%eigenval(val, ik+is)))**2 + this%gamma**2)
628 if (st%d%nspin > 1)
then
630 write(filename,
'(a,i1.1,a)')
'total-jdos-', is+1,
'.dat'
631 iunit(is) =
io_open(trim(dir)//
'/'//trim(filename), namespace, action=
'write')
633 write(iunit(is),
'(3a)')
'# energy [', trim(
units_abbrev(
units_out%energy)),
'], total JDOS (spin-resolved)'
635 do ie = 1, this%epoints
636 energy = (ie - 1) * this%de
647 iunit(0) =
io_open(trim(dir)//
'/'//
'total-jdos.dat', namespace, action=
'write')
651 do ie = 1, this%epoints
652 energy = (ie - 1) * this%de
655 tjdos(1) = tjdos(1) + jdos(ie, is)
665 safe_deallocate_a(iunit)
666 safe_deallocate_a(jdos)
674 subroutine dos_write_ldos(this, dir, st, ions, mesh, how, namespace)
675 type(
dos_t),
intent(in) :: this
676 character(len=*),
intent(in) :: dir
678 type(
ions_t),
target,
intent(in) :: ions
679 class(
mesh_t),
intent(in) :: mesh
680 integer(int64),
intent(in) :: how
683 integer :: ie, ik, ist, is, ns, ip, ierr
684 character(len=MAX_PATH_LEN) :: fname, name
685 real(real64) :: weight
686 real(real64),
allocatable :: ldos(:,:,:), dpsi(:,:), abs_psi2(:)
687 complex(real64),
allocatable :: zpsi(:,:)
692 if (this%ldos_nenergies < 1)
then
693 message(1) =
"LDOSEnergies must be defined for Output=ldos"
699 if (st%d%nspin == 2) ns = 2
704 safe_allocate(ldos(1:mesh%np, 1:this%ldos_nenergies, 1:ns))
707 safe_allocate(abs_psi2(1:mesh%np))
709 safe_allocate(dpsi(1:mesh%np, 1:st%d%dim))
711 safe_allocate(zpsi(1:mesh%np, 1:st%d%dim))
715 do ik = st%d%kpt%start, st%d%kpt%end
716 is = st%d%get_spin_index(ik)
717 do ist = st%st_start, st%st_end
723 abs_psi2(ip) = dpsi(ip, 1)**2
725 if (st%d%dim > 1)
then
726 abs_psi2(ip) = abs_psi2(ip) + dpsi(ip, 2)**2
731 abs_psi2(ip) = real(conjg(zpsi(ip, 1)) * zpsi(ip, 1), real64)
733 if (st%d%dim > 1)
then
734 abs_psi2(ip) = abs_psi2(ip) + real(conjg(zpsi(ip, 2)) * zpsi(ip, 2), real64)
739 do ie = 1, this%ldos_nenergies
740 weight = st%kweights(ik) *
m_one/
m_pi * &
741 this%gamma / ((this%ldos_energies(ie) - st%eigenval(ist, ik))**2 + this%gamma**2)
743 call lalg_axpy(mesh%np, weight, abs_psi2, ldos(:, ie, is))
748 safe_deallocate_a(dpsi)
749 safe_deallocate_a(zpsi)
750 safe_deallocate_a(abs_psi2)
752 if (st%parallel_in_states .or. st%d%kpt%parallel)
then
757 do ie = 1, this%ldos_nenergies
758 write(name,
'(a,i3.3)')
'ldos_en-', ie
762 ldos(:, ie, is), fn_unit, ierr, pos=ions%pos, atoms=ions%atom, grp = st%dom_st_kpt_mpi_grp)
766 safe_deallocate_a(ldos)
constant times a vector plus a vector
pure logical function, public accel_is_enabled()
integer, parameter, public accel_mem_read_only
subroutine, public zget_atomic_orbital(namespace, space, latt, pos, species, mesh, sm, ii, ll, jj, os, orbind, radius, d_dim, use_mesh, normalize, index_shift)
This routine returns the atomic orbital basis – provided by the pseudopotential structure in geo.
character(len=1), dimension(0:3), parameter, public l_notation
real(real64) function, public atomic_orbital_get_radius(species, mesh, iorb, ispin, truncation, threshold)
subroutine, public dget_atomic_orbital(namespace, space, latt, pos, species, mesh, sm, ii, ll, jj, os, orbind, radius, d_dim, use_mesh, normalize, index_shift)
This routine returns the atomic orbital basis – provided by the pseudopotential structure in geo.
Module that handles computing and output of various density of states.
subroutine dos_end(this)
Finalizer for the dos_t object.
subroutine, public dos_write_dos(this, dir, st, box, ions, mesh, hm, namespace)
Computes and output the DOS and the projected DOS (PDOS)
subroutine, public dos_write_jdos(this, dir, st, ions, hm, namespace)
Computes and output the joint DOS (LDOS)
subroutine, public dos_init(this, namespace, st, kpoints)
Initializes the dot_t object.
subroutine, public dos_write_ldos(this, dir, st, ions, mesh, how, namespace)
Computes and output the local DOS (LDOS)
integer, parameter, public spin_polarized
real(real64), parameter, public m_zero
real(real64), parameter, public m_four
real(real64), parameter, public m_pi
some mathematical constants
real(real64), parameter, public m_epsilon
real(real64), parameter, public m_one
subroutine, public dio_function_output(how, dir, fname, namespace, space, mesh, ff, unit, ierr, pos, atoms, grp, root)
Top-level IO routine for functions defined on the mesh.
subroutine, public io_close(iunit, grp)
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
This module is intended to contain "only mathematical" functions and procedures.
integer pure function, public pad_pow2(size)
create array size, which is padded to powers of 2
This module defines the meshes, which are used in Octopus.
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
type(mpi_grp_t), public mpi_world
type(namespace_t), public global_namespace
subroutine, public orbitalset_init(this)
subroutine, public orbitalset_end(this)
subroutine, public dorbitalset_transfer_to_device(os, kpt, use_mesh)
Allocate and transfer the orbitals to the device.
subroutine, public orbitalset_update_phase(os, dim, kpt, kpoints, spin_polarized, vec_pot, vec_pot_var, kpt_max)
Build the phase correction to the global phase in case the orbital crosses the border of the simulato...
subroutine, public dorbitalset_get_coeff_batch(os, ndim, psib, dot, reduce)
subroutine, public zorbitalset_get_coeff_batch(os, ndim, psib, dot, reduce)
subroutine, public zorbitalset_transfer_to_device(os, kpt, use_mesh)
Allocate and transfer the orbitals to the device.
integer function, public orbitalset_utils_count(species, iselect)
Count the number of orbital sets we have for a given atom.
this module contains the low-level part of the output system
character(len=max_path_len) function, public get_filename_with_spin(output, nspin, spin_index)
Returns the filame as output, or output-spX is spin polarized.
integer function, public parse_block(namespace, name, blk, check_varinfo_)
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
subroutine, public simplex_dos_3d(etetra, eF, dos)
Get only the DOS contribution of a single tetrahedron.
pure logical function, public states_are_real(st)
type(type_t), public type_cmplx
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
character(len=20) pure function, public units_abbrev(this)
This module defines the unit system, used for input and output.
type(unit_system_t), public units_out
type(unit_system_t), public units_inp
the units systems for reading and writing
type(unit_t), public unit_one
some special units required for particular quantities
class to tell whether a point is inside or outside
Describes mesh distribution to nodes.
The states_elec_t class contains all electronic wave functions.
batches of electronic states