Octopus
dos.F90
Go to the documentation of this file.
1!! Copyright (C) 2017 N. Tancogne-Dejean
2!! Copyright (C) 2025 N. Tancogne-Dejean
3!!
4!! This program is free software; you can redistribute it and/or modify
5!! it under the terms of the GNU General Public License as published by
6!! the Free Software Foundation; either version 2, or (at your option)
7!! any later version.
8!!
9!! This program is distributed in the hope that it will be useful,
10!! but WITHOUT ANY WARRANTY; without even the implied warranty of
11!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12!! GNU General Public License for more details.
13!!
14!! You should have received a copy of the GNU General Public License
15!! along with this program; if not, write to the Free Software
16!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17!! 02110-1301, USA.
18!!
19
20#include "global.h"
21
23module dos_oct_m
24 use accel_oct_m
26 use box_oct_m
27 use comm_oct_m
28 use debug_oct_m
30 use global_oct_m
33 use io_oct_m
35 use ions_oct_m
36 use, intrinsic :: iso_fortran_env
39 use math_oct_m
40 use mesh_oct_m
42 use mpi_oct_m
47 use parser_oct_m
55 use types_oct_m
56 use unit_oct_m
59
60 implicit none
61
62 private
63 public :: &
64 dos_t, &
65 dos_init, &
70
71 type dos_t
72 private
73 real(real64) :: emin
74 real(real64) :: emax
75 integer :: epoints
76 real(real64) :: de
77
78 real(real64) :: gamma
79
80 integer :: ldos_nenergies = -1
81 real(real64), allocatable :: ldos_energies(:)
82
83 integer(int64) :: method
84 integer :: smear_func
85 contains
86 final :: dos_end
87 end type dos_t
88
89contains
90
92 subroutine dos_init(this, namespace, st, kpoints)
93 type(dos_t), intent(out) :: this
94 type(namespace_t), intent(in) :: namespace
95 type(states_elec_t), intent(in) :: st
96 type(kpoints_t), intent(in) :: kpoints
97
98 real(real64) :: evalmin, evalmax, eextend
99 integer :: npath, ie
100 type(block_t) :: blk
101
102 push_sub(dos_init)
103
104 !The range of the dos is only calculated for physical points,
105 !without the one from a k-point path
106 npath = kpoints%nkpt_in_path()
107 if (st%nik > npath) then
108 evalmin = minval(st%eigenval(1:st%nst, 1:(st%nik-npath)))
109 evalmax = maxval(st%eigenval(1:st%nst, 1:(st%nik-npath)))
110 else !In case we only have a path, e.g., a bandstructure calculation
111 evalmin = minval(st%eigenval(1:st%nst, 1:st%nik))
112 evalmax = maxval(st%eigenval(1:st%nst, 1:st%nik))
113 end if
114 ! we extend the energy mesh by this amount
115 eextend = (evalmax - evalmin) / m_four
116
117 !%Variable DOSMethod
118 !%Type integer
119 !%Default smear
120 !%Section Output
121 !%Description
122 !% Selects the method that is used to calculate the DOS.
123 !%Option smear 0
124 !% Smearing with the smearing function selected by <tt>DOSSmearingFunction</tt>.
125 !%Option tetrahedra
126 !% Linear tetrahedron method as in P. E. Bloechl, et al., <i>Phys. Rev. B</i> <b>49</b>, 16223 (1994).
127 !% Requires a regular Monkhorst-Pack generated by Octopus.
128 !%Option tetrahedra_opt
129 !% Improved tetrahedron method as in M. Kawamura, et al., <i>Phys. Rev. B</i> <b>89</b>, 094515 (2014).
130 !% Requires a regular Monkhorst-Pack generated by Octopus.
131 !%End
132 call parse_variable(namespace, 'DOSMethod', option__dosmethod__smear, this%method)
133
134 !%Variable DOSSmearingFunction
135 !%Type integer
136 !%Default lorentzian_smearing
137 !%Section Output
138 !%Description
139 !% This is the function used to smear the energy levels in the DOS calculation.
140 !%Option fermi_dirac 2
141 !% Simple Fermi-Dirac distribution. In this case, <tt>DOSGamma</tt> has
142 !% the meaning of an electronic temperature. DN Mermin, <i>Phys. Rev.</i> <b>137</b>, A1441 (1965).
143 !%Option cold_smearing 3
144 !% N Marzari, D Vanderbilt, A De Vita, and MC Payne, <i>Phys. Rev. Lett.</i> <b>82</b>, 3296 (1999).
145 !%Option methfessel_paxton 4
146 !% M Methfessel and AT Paxton, <i>Phys. Rev. B</i> <b>40</b>, 3616 (1989).
147 !% The expansion order of the polynomial is fixed to 1.
148 !% Occupations may be negative.
149 !%Option spline_smearing 5
150 !% Nearly identical to Gaussian smearing.
151 !% JM Holender, MJ Gillan, MC Payne, and AD Simpson, <i>Phys. Rev. B</i> <b>52</b>, 967 (1995).
152 !%Option gaussian_smearing
153 !% Gaussian smearing.
154 !%Option lorentzian_smearing
155 !% Lorentzian smearing.
156 !%End
157 call parse_variable(namespace, 'DOSSmearingFunction', smear_lorentzian, this%smear_func)
158
159 !%Variable DOSEnergyMin
160 !%Type float
161 !%Section Output
162 !%Description
163 !% Lower bound for the energy mesh of the DOS.
164 !% The default is the lowest eigenvalue, minus a quarter of the total range of eigenvalues.
165 !% This is ignored for the joint density of states, and the minimal energy is always set to zero.
166 !%End
167 call parse_variable(namespace, 'DOSEnergyMin', evalmin - eextend, this%emin, units_inp%energy)
169 !%Variable DOSEnergyMax
170 !%Type float
171 !%Section Output
172 !%Description
173 !% Upper bound for the energy mesh of the DOS.
174 !% The default is the highest eigenvalue, plus a quarter of the total range of eigenvalues.
175 !%End
176 call parse_variable(namespace, 'DOSEnergyMax', evalmax + eextend, this%emax, units_inp%energy)
177
178 !%Variable DOSEnergyPoints
179 !%Type integer
180 !%Default 500
181 !%Section Output
182 !%Description
183 !% Determines how many energy points <tt>Octopus</tt> should use for
184 !% the DOS energy grid.
185 !%End
186 call parse_variable(namespace, 'DOSEnergyPoints', 500, this%epoints)
188 !%Variable DOSGamma
189 !%Type float
190 !%Default 0.008 Ha
191 !%Section Output
192 !%Description
193 !% Determines the width of the Lorentzian which is used for the DOS sum.
194 !%End
195 call parse_variable(namespace, 'DOSGamma', 0.008_real64, this%gamma)
196
197 ! DOSComputePDOS = yes -> Output = pdos
198 call messages_obsolete_variable(namespace, 'DOSComputePDOS' , 'Output')
199
200 ! spacing for energy mesh
201 this%de = (this%emax - this%emin) / (this%epoints - 1)
202
203 !%Variable LDOSEnergies
204 !%Type block
205 !%Section Output
206 !%Description
207 !% Specifies the energies at which the LDOS is computed.
208 !%End
209 if (parse_block(global_namespace, 'LDOSEnergies', blk) == 0) then
210 ! There is one high symmetry k-point per line
211 this%ldos_nenergies = parse_block_cols(blk, 0)
212
213 safe_allocate(this%ldos_energies(1:this%ldos_nenergies))
214 do ie = 1, this%ldos_nenergies
215 call parse_block_float(blk, 0, ie-1, this%ldos_energies(ie))
216 end do
217 call parse_block_end(blk)
218 else
219 this%ldos_nenergies = -1
220 end if
221
222 pop_sub(dos_init)
223 end subroutine dos_init
224
226 subroutine dos_end(this)
227 type(dos_t), intent(inout) :: this
228
229 push_sub(dos_end)
230
231 safe_deallocate_a(this%ldos_energies)
232 this%ldos_nenergies = -1
233
234 pop_sub(dos_end)
235 end subroutine
236
237 ! ---------------------------------------------------------
239 subroutine dos_write_dos(this, dir, st, box, ions, mesh, hm, namespace)
240 type(dos_t), intent(in) :: this
241 character(len=*), intent(in) :: dir
242 type(states_elec_t), target, intent(in) :: st
243 class(box_t), intent(in) :: box
244 type(ions_t), target, intent(in) :: ions
245 class(mesh_t), intent(in) :: mesh
246 type(hamiltonian_elec_t), intent(in) :: hm
247 type(namespace_t), intent(in) :: namespace
248
249 integer :: ie, ik, ist, is, ns, maxdos, nvertices
250 integer, allocatable :: iunit(:)
251 real(real64) :: energy
252 real(real64), allocatable :: tdos(:)
253 real(real64), allocatable :: dos(:,:,:)
254 character(len=64) :: filename
255
256 integer :: ii, ll
257
258 type(smear_t) :: smear
259 type(simplex_t), pointer :: simplex
260 real(real64) :: e_simplex(20)
261 real(real64), allocatable :: energies(:), dos_simplex_batch(:,:), dos_thread(:,:)
262
263 push_sub(dos_write_dos)
264
265 ! shortcuts
266 ns = 1
267 if (st%d%nspin == 2) ns = 2
268
269 ! set up smearing parameters
270 smear%method = this%smear_func
271 smear%MP_n = 1
272
273 if (st%system_grp%is_root()) then
274 ! space for state-dependent DOS
275 safe_allocate(dos(1:this%epoints, 1:st%nst, 0:ns-1))
276 dos(:, :, :) = m_zero
277 safe_allocate(iunit(0:ns-1))
278
279 ! compute band/spin-resolved density of states
280 do ist = 1, st%nst
281
282 do is = 0, ns-1
283 if (ns > 1) then
284 write(filename, '(a,i5.5,a,i1.1,a)') 'dos-', ist, '-', is+1,'.dat'
285 else
286 write(filename, '(a,i5.5,a)') 'dos-', ist, '.dat'
287 end if
288 iunit(is) = io_open(trim(dir)//'/'//trim(filename), namespace, action='write')
289 ! write header
290 write(iunit(is), '(3a)') '# energy [', trim(units_abbrev(units_out%energy)), '], band-resolved DOS'
291 end do
292
293 select case (this%method)
294 case (option__dosmethod__smear)
295 do ie = 1, this%epoints
296 energy = this%emin + (ie - 1) * this%de
297 ! sum up Lorentzians
298 do ik = 1, st%nik, ns
299 do is = 0, ns-1
300 dos(ie, ist, is) = dos(ie, ist, is) + st%kweights(ik+is) / this%gamma * &
301 smear_delta_function(smear, (energy - st%eigenval(ist, ik+is)) / this%gamma)
302 end do
303 end do
304 end do
305
306 case (option__dosmethod__tetrahedra, option__dosmethod__tetrahedra_opt)
307 assert(associated(hm%kpoints%reduced%simplex))
308 simplex => hm%kpoints%reduced%simplex
309 nvertices = simplex%rdim + 1
310 assert(nvertices <= 4)
311 call profiling_in("DOS_WRITE_TETRAHEDRA")
312 safe_allocate(energies(1:this%epoints))
313 do ie = 1, this%epoints
314 energies(ie) = this%emin + (ie - 1) * this%de
315 end do
316 !$omp parallel private(ii, is, ll, ik, ie, e_simplex, dos_simplex_batch, dos_thread)
317 safe_allocate(dos_simplex_batch(1:nvertices, 1:this%epoints))
318 safe_allocate(dos_thread(1:this%epoints, 0:ns-1))
319 dos_thread = m_zero
320 !$omp do schedule(static)
321 do ii = 1, simplex%n_simplices
322 do is = 0, ns - 1
323 do ll = 1, simplex%sdim
324 ik = simplex%simplices(ii, ll)
325 ik = ns * (ik - 1) + 1
326 e_simplex(ll) = st%eigenval(ist, ik+is)
327 end do
328
329 call simplex_dos(simplex%rdim, e_simplex(1:simplex%sdim), energies, dos_simplex_batch)
330
331 do ie = 1, this%epoints
332 dos_thread(ie, is) = dos_thread(ie, is) + sum(dos_simplex_batch(1:nvertices, ie)) / simplex%n_points
333 end do
334 end do
335 end do
336 !$omp end do
337 !$omp critical
338 dos(:, ist, :) = dos(:, ist, :) + dos_thread
339 !$omp end critical
340 safe_deallocate_a(dos_thread)
341 safe_deallocate_a(dos_simplex_batch)
342 !$omp end parallel
343 safe_deallocate_a(energies)
344 call profiling_out("DOS_WRITE_TETRAHEDRA")
345
346 case default
347 assert(.false.)
348 end select
349
350 do ie = 1, this%epoints
351 energy = this%emin + (ie - 1) * this%de
352 do is = 0, ns-1
353 write(message(1), '(2es25.16E3)') units_from_atomic(units_out%energy, energy), &
354 units_from_atomic(unit_one / units_out%energy, dos(ie, ist, is))
355 call messages_info(1, iunit(is))
356 end do
357 end do
358
359 do is = 0, ns-1
360 call io_close(iunit(is))
361 end do
362 end do
363
364 safe_allocate(tdos(1))
365
366 ! for spin-polarized calculations also output spin-resolved tDOS
367 if (st%d%nspin == spin_polarized) then
368 do is = 0, ns-1
369 write(filename, '(a,i1.1,a)') 'total-dos-', is+1,'.dat'
370 iunit(is) = io_open(trim(dir)//'/'//trim(filename), namespace, action='write')
371 ! write header
372 write(iunit(is), '(3a)') '# energy [', trim(units_abbrev(units_out%energy)), '], total DOS (spin-resolved)'
373
374 do ie = 1, this%epoints
375 energy = this%emin + (ie - 1) * this%de
376 tdos(1) = m_zero
377 do ist = 1, st%nst
378 tdos(1) = tdos(1) + dos(ie, ist, is)
379 end do
380 write(message(1), '(2es25.16E3)') units_from_atomic(units_out%energy, energy), &
381 units_from_atomic(unit_one / units_out%energy, tdos(1))
382 call messages_info(1, iunit(is))
383 end do
384
385 call io_close(iunit(is))
386 end do
387 end if
388
389
390 iunit(0) = io_open(trim(dir)//'/'//'total-dos.dat', namespace, action='write')
391 write(iunit(0), '(3a)') '# energy [', trim(units_abbrev(units_out%energy)), '], total DOS'
392
393 ! compute total density of states
394 do ie = 1, this%epoints
395 energy = this%emin + (ie - 1) * this%de
396 tdos(1) = m_zero
397 do ist = 1, st%nst
398 do is = 0, ns-1
399 tdos(1) = tdos(1) + dos(ie, ist, is)
400 end do
401 end do
402 write(message(1), '(2es25.16E3)') units_from_atomic(units_out%energy, energy), &
403 units_from_atomic(unit_one / units_out%energy, tdos(1))
404 call messages_info(1, iunit(0))
405 end do
406
407 call io_close(iunit(0))
408
409 safe_deallocate_a(tdos)
410
411
412 ! write Fermi file
413 iunit(0) = io_open(trim(dir)//'/'//'total-dos-efermi.dat', namespace, action='write')
414 write(message(1), '(3a)') '# Fermi energy [', trim(units_abbrev(units_out%energy)), &
415 '] in a format compatible with total-dos.dat'
416
417 ! this is the maximum that tdos can reach
418 maxdos = st%smear%el_per_state * st%nst
419
420 write(message(2), '(2es25.16E3)') units_from_atomic(units_out%energy, st%smear%e_fermi), m_zero
421 write(message(3), '(es25.16E3,i7)') units_from_atomic(units_out%energy, st%smear%e_fermi), maxdos
422
423 call messages_info(3, iunit(0))
424 call io_close(iunit(0))
425
426 end if
427
428
429 safe_deallocate_a(iunit)
430 safe_deallocate_a(dos)
431
432 pop_sub(dos_write_dos)
433 end subroutine dos_write_dos
434
435 ! ---------------------------------------------------------
437 subroutine dos_write_pdos(this, dir, st, box, ions, mesh, hm, namespace)
438 type(dos_t), intent(in) :: this
439 character(len=*), intent(in) :: dir
440 type(states_elec_t), target, intent(in) :: st
441 class(box_t), intent(in) :: box
442 type(ions_t), target, intent(in) :: ions
443 class(mesh_t), intent(in) :: mesh
444 type(hamiltonian_elec_t), intent(in) :: hm
445 type(namespace_t), intent(in) :: namespace
446
447 integer :: ie, ik, ist, is, ns, ib, ind, nvertices
448 integer :: iunit
449 real(real64) :: energy, threshold
450 character(len=64) :: filename, format_str
451 logical :: normalize
452
453 integer :: ii, ll, mm, nn, work, norb, work2
454 integer :: ia, iorb, idim
455 real(real64), allocatable :: ddot(:,:,:)
456 complex(real64), allocatable :: zdot(:,:,:)
457 real(real64), allocatable :: weight(:,:,:)
458 type(orbitalset_t) :: os
459 type(wfs_elec_t), pointer :: epsib
460
461 type(smear_t) :: smear
462 type(simplex_t), pointer :: simplex
463 real(real64) :: e_simplex(20), a_simplex(4)
464 real(real64), allocatable :: energies(:), dos_simplex_batch(:,:), pdos(:,:), pdos_thread(:,:)
465
466 push_sub(dos_write_pdos)
467
468 ! shortcuts
469 ns = 1
470 if (st%d%nspin == 2) ns = 2
471
472 ! set up smearing parameters
473 smear%method = this%smear_func
474 smear%MP_n = 1
475
476 !These variables are defined in basis_set/orbitalbasis.F90
477 call parse_variable(namespace, 'AOThreshold', 0.01_real64, threshold)
478 call parse_variable(namespace, 'AONormalize', .true., normalize)
479
480 do ia = 1, ions%natoms
481 !We first count how many orbital set we have
482 work = orbitalset_utils_count(ions%atom(ia)%species)
483
484 !We loop over the orbital sets of the atom ia
485 do norb = 1, work
486 call orbitalset_init(os)
487 os%spec => ions%atom(ia)%species
488
489 !We count the orbitals
490 work2 = 0
491 do iorb = 1, os%spec%get_niwfs()
492 call os%spec%get_iwf_ilm(iorb, 1, ii, ll, mm)
493 call os%spec%get_iwf_n(iorb, 1, nn)
494 if (ii == norb) then
495 os%ll = ll
496 os%nn = nn
497 os%ii = ii
498 os%radius = atomic_orbital_get_radius(os%spec, mesh, iorb, 1, &
499 option__aotruncation__ao_full, threshold)
500 work2 = work2 + 1
501 end if
502 end do
503 os%norbs = work2
504 os%ndim = 1
505 os%use_submesh = .false.
506 os%allocated_on_mesh = .true.
507 os%spec => ions%atom(ia)%species
508
509 do work = 1, os%norbs
510 ! We obtain the orbital
511 if (states_are_real(st)) then
512 call dget_atomic_orbital(namespace, ions%space, ions%latt, ions%pos(:,ia), &
513 ions%atom(ia)%species, mesh, os%sphere, os%ii, os%ll, os%jj, &
514 os, work, os%radius, os%ndim, use_mesh=.not.os%use_submesh, &
515 normalize = normalize)
516 else
517 call zget_atomic_orbital(namespace, ions%space, ions%latt, ions%pos(:,ia), &
518 ions%atom(ia)%species, mesh, os%sphere, os%ii, os%ll, os%jj, &
519 os, work, os%radius, os%ndim, &
520 use_mesh = .not. hm%phase%is_allocated() .and. .not. os%use_submesh, &
521 normalize = normalize)
522 end if
523 end do
524
525 if (hm%phase%is_allocated()) then
526 ! In case of complex wavefunction, we allocate the array for the phase correction
527 safe_allocate(os%phase(1:os%sphere%np, st%d%kpt%start:st%d%kpt%end))
528 os%phase(:,:) = m_zero
529
530 if (.not. os%use_submesh) then
531 safe_allocate(os%eorb_mesh(1:mesh%np, 1:os%norbs, 1:os%ndim, st%d%kpt%start:st%d%kpt%end))
532 os%eorb_mesh(:,:,:,:) = m_zero
533 else
534 safe_allocate(os%eorb_submesh(1:os%sphere%np, 1:os%ndim, 1:os%norbs, st%d%kpt%start:st%d%kpt%end))
535 os%eorb_submesh(:,:,:,:) = m_zero
536 end if
537
538 if (accel_is_enabled() .and. st%d%dim == 1) then
539 os%ldorbs_eorb = max(pad_pow2(os%sphere%np), 1)
540 if(.not. os%use_submesh) os%ldorbs_eorb = max(pad_pow2(os%sphere%mesh%np), 1)
541
542 safe_allocate(os%buff_eorb(st%d%kpt%start:st%d%kpt%end))
543 do ik= st%d%kpt%start, st%d%kpt%end
544 call accel_create_buffer(os%buff_eorb(ik), accel_mem_read_only, type_cmplx, os%ldorbs_eorb*os%norbs)
545 end do
546 end if
547
548 call orbitalset_update_phase(os, box%dim, st%d%kpt, hm%kpoints, (st%d%ispin==spin_polarized), &
549 vec_pot = hm%hm_base%uniform_vector_potential, &
550 vec_pot_var = hm%hm_base%vector_potential)
551 else
552 if (states_are_real(st)) then
553 call dorbitalset_transfer_to_device(os, st%d%kpt, .not. os%use_submesh)
554 else
555 call zorbitalset_transfer_to_device(os, st%d%kpt, .not. os%use_submesh)
556 end if
557 end if
558
559 if (st%system_grp%is_root()) then
560 if (os%nn /= 0) then
561 write(filename,'(a, i4.4, a1, a, i1.1, a1,a)') 'pdos-at', ia, '-', trim(os%spec%get_label()), &
562 os%nn, l_notation(os%ll), '.dat'
563 else
564 write(filename,'(a, i4.4, a1, a, a1,a)') 'pdos-at', ia, '-', trim(os%spec%get_label()), &
565 l_notation(os%ll), '.dat'
566 end if
567
568 iunit = io_open(trim(dir)//'/'//trim(filename), namespace, action='write')
569 ! write header
570 write(iunit, '(3a)') '# energy [', trim(units_abbrev(units_out%energy)), &
571 '], projected DOS (total and orbital resolved)'
572 end if
573
574 if (states_are_real(st)) then
575 safe_allocate(ddot(1:st%d%dim, 1:os%norbs, 1:st%block_size))
576 else
577 safe_allocate(zdot(1:st%d%dim, 1:os%norbs, 1:st%block_size))
578 end if
579
580 safe_allocate(weight(1:os%norbs,1:st%nik,1:st%nst))
581 weight(1:os%norbs,1:st%nik,1:st%nst) = m_zero
582
583 do ik = st%d%kpt%start, st%d%kpt%end
584 do ib = st%group%block_start, st%group%block_end
585
586 if (hm%phase%is_allocated()) then
587 safe_allocate(epsib)
588 call st%group%psib(ib, ik)%copy_to(epsib)
589 call hm%phase%apply_to(mesh, mesh%np, .false., epsib, src = st%group%psib(ib, ik))
590 else
591 epsib => st%group%psib(ib, ik)
592 end if
593
594 if (states_are_real(st)) then
595 call dorbitalset_get_coeff_batch(os, st%d%dim, epsib, ddot(:, :, :))
596 do ist = 1, st%group%psib(ib, ik)%nst
597 ind = st%group%psib(ib, ik)%ist(ist)
598 do iorb = 1, os%norbs
599 do idim = 1, st%d%dim
600 weight(iorb, ik, ind) = weight(iorb, ik, ind) + st%kweights(ik) * abs(ddot(idim, iorb, ist))**2
601 end do
602 end do
603 end do
604 else
605 call zorbitalset_get_coeff_batch(os, st%d%dim, epsib, zdot(:, :, :))
606 do ist = 1, st%group%psib(ib, ik)%nst
607 ind = st%group%psib(ib, ik)%ist(ist)
608 do iorb = 1, os%norbs
609 do idim = 1, st%d%dim
610 weight(iorb, ik, ind) = weight(iorb, ik, ind) + st%kweights(ik) * abs(zdot(idim, iorb, ist))**2
611 end do
612 end do
613 end do
614 end if
615
616 if (hm%phase%is_allocated()) then
617 call epsib%end(copy=.false.)
618 safe_deallocate_p(epsib)
619 end if
620
621 end do
622 end do
623
624 if (st%parallel_in_states .or. st%d%kpt%parallel) then
625 call comm_allreduce(st%st_kpt_mpi_grp, weight)
626 end if
627
628 safe_deallocate_a(ddot)
629 safe_deallocate_a(zdot)
630
631 if (st%system_grp%is_root()) then
632 write(format_str,'(a,i5,a)') '(', os%norbs+2, 'es25.16E3)'
633 safe_allocate(pdos(1:os%norbs, 1:this%epoints))
634 pdos = m_zero
635 select case (this%method)
636 case (option__dosmethod__smear)
637 do iorb = 1, os%norbs
638 do ist = 1, st%nst
639 do ik = 1, st%nik
640 do ie = 1, this%epoints
641 energy = this%emin + (ie - 1) * this%de
642 pdos(iorb, ie) = pdos(iorb, ie) + weight(iorb,ik,ist) / this%gamma * &
643 smear_delta_function(smear, (energy - st%eigenval(ist, ik))/this%gamma)
644 end do
645 end do
646 end do
647 end do
648 case (option__dosmethod__tetrahedra, option__dosmethod__tetrahedra_opt)
649 assert(associated(hm%kpoints%reduced%simplex))
650 simplex => hm%kpoints%reduced%simplex
651 nvertices = simplex%rdim + 1
652 assert(nvertices <= 4)
653 safe_allocate(energies(1:this%epoints))
654 do ie = 1, this%epoints
655 energies(ie) = this%emin + (ie - 1) * this%de
656 end do
657 call profiling_in("DOS_WRITE_PDOS_TETRAHEDRA")
658 !$omp parallel private(ist, ii, is, ll, ik, iorb, ie, e_simplex, a_simplex, dos_simplex_batch, pdos_thread)
659 safe_allocate(dos_simplex_batch(1:nvertices, 1:this%epoints))
660 safe_allocate(pdos_thread(1:os%norbs, 1:this%epoints))
661 pdos_thread = m_zero
662 !$omp do collapse(2) schedule(static)
663 do ist = 1, st%nst
664 do ii = 1, simplex%n_simplices
665 do is = 0, ns - 1
666 do ll = 1, simplex%sdim
667 ik = simplex%simplices(ii, ll)
668 ik = ns * (ik - 1) + 1
669 e_simplex(ll) = st%eigenval(ist, ik+is)
670 end do
671 call simplex_dos(simplex%rdim, e_simplex(1:simplex%sdim), energies, dos_simplex_batch)
672 do iorb = 1, os%norbs
673 do ll = 1, nvertices
674 ik = simplex%simplices(ii, ll)
675 ik = ns * (ik - 1) + 1
676 if (st%kweights(ik+is) > m_epsilon) then
677 a_simplex(ll) = weight(iorb, ik+is, ist) / st%kweights(ik+is)
678 else
679 a_simplex(ll) = m_zero
680 end if
681 end do
682 do ie = 1, this%epoints
683 pdos_thread(iorb, ie) = pdos_thread(iorb, ie) + &
684 sum(a_simplex(1:nvertices) * dos_simplex_batch(1:nvertices, ie)) / simplex%n_points
685 end do
686 end do
687 end do
688 end do
689 end do
690 !$omp end do
691 !$omp critical
692 pdos(:,:) = pdos(:,:) + pdos_thread(:,:)
693 !$omp end critical
694 safe_deallocate_a(pdos_thread)
695 safe_deallocate_a(dos_simplex_batch)
696 !$omp end parallel
697 call profiling_out("DOS_WRITE_PDOS_TETRAHEDRA")
698 safe_deallocate_a(energies)
699 case default
700 assert(.false.)
701 end select
702 do ie = 1, this%epoints
703 energy = this%emin + (ie - 1) * this%de
704 write(iunit, trim(format_str)) units_from_atomic(units_out%energy, energy), &
705 units_from_atomic(unit_one / units_out%energy, sum(pdos(:,ie))), &
706 (units_from_atomic(unit_one / units_out%energy, pdos(iorb,ie)), iorb=1,os%norbs)
707 end do
708 safe_deallocate_a(pdos)
709 call io_close(iunit)
710 end if
711
712 call orbitalset_end(os)
713 safe_deallocate_a(weight)
714
715 end do
716
717 end do
718
719 pop_sub(dos_write_pdos)
720 end subroutine dos_write_pdos
721
722 ! ---------------------------------------------------------
724 subroutine dos_write_jdos(this, dir, st, ions, hm, namespace)
725 type(dos_t), intent(in) :: this
726 character(len=*), intent(in) :: dir
727 type(states_elec_t), intent(in) :: st
728 type(ions_t), target, intent(in) :: ions
729 type(hamiltonian_elec_t), intent(in) :: hm
730 type(namespace_t), intent(in) :: namespace
731
732 integer :: ie, ik, val, cond, is, ns, ll, ii, nvertices
733 integer, allocatable :: iunit(:)
734 real(real64) :: energy
735 real(real64) :: tjdos(1), e_simplex(20), occ_simplex(4)
736 real(real64), allocatable :: jdos(:,:), energies(:), dos_simplex(:,:)
737 character(len=64) :: filename
738
739 type(smear_t) :: smear
740 type(simplex_t), pointer :: simplex
741
742 push_sub(dos_write_jdos)
743
744 ! shortcuts
745 ns = 1
746 if (st%d%nspin == 2) ns = 2
747
748 ! set up smearing parameters
749 smear%method = this%smear_func
750 smear%MP_n = 1
751
752 if (st%system_grp%is_root()) then
753 ! space for state-dependent DOS
754 safe_allocate(jdos(1:this%epoints, 0:ns-1))
755 safe_allocate(iunit(0:ns-1))
756 jdos = m_zero
757
758 select case (this%method)
759 case (option__dosmethod__smear)
760 ! compute band/spin-resolved density of states
761 do val = 1, st%nst
762 do cond = val, st%nst
763 do ik = 1, st%nik, ns
764 do is = 0, ns-1
765 if(st%occ(val, ik+is) < m_epsilon) cycle
766 if(st%occ(cond, ik+is) > m_epsilon) cycle
767 do ie = 1, this%epoints
768 energy = (ie - 1) * this%de
769 ! sum up Lorentzians
770 jdos(ie, is) = jdos(ie, is) + st%kweights(ik+is) / this%gamma * &
771 smear_delta_function(smear, (energy - (st%eigenval(cond, ik+is)-st%eigenval(val, ik+is)))/this%gamma)
772 end do
773 end do
774 end do
775 end do
776 end do
777 case (option__dosmethod__tetrahedra, option__dosmethod__tetrahedra_opt)
778 assert(associated(hm%kpoints%reduced%simplex))
779 simplex => hm%kpoints%reduced%simplex
780 nvertices = simplex%rdim + 1
781 assert(nvertices <= 4)
782 call profiling_in("DOS_WRITE_JDOS_TETRAHEDRA")
783 safe_allocate(energies(1:this%epoints))
784 do ie = 1, this%epoints
785 energies(ie) = (ie - 1) * this%de
786 end do
787 !$omp parallel reduction(+:jdos) &
788 !$omp private(val, cond, ie, ii, is, ll, ik, e_simplex, occ_simplex, dos_simplex)
789 safe_allocate(dos_simplex(1:nvertices, 1:this%epoints))
790 !$omp do collapse(3) schedule(dynamic)
791 do val = 1, st%nst
792 do cond = 1, st%nst
793 do ii = 1, simplex%n_simplices
794 if (cond < val) cycle
795 do is = 0, ns - 1
796 do ll = 1, simplex%sdim
797 ik = simplex%simplices(ii, ll)
798 ik = ns * (ik - 1) + 1
799 e_simplex(ll) = st%eigenval(cond, ik+is) - st%eigenval(val, ik+is)
800 end do
801
802 do ll = 1, nvertices
803 ik = simplex%simplices(ii, ll)
804 ik = ns * (ik - 1) + 1
805 if (st%occ(val, ik+is) > m_epsilon .and. st%occ(cond, ik+is) < m_epsilon) then
806 occ_simplex(ll) = m_one
807 else
808 occ_simplex(ll) = m_zero
809 end if
810 end do
811
812 ! use bitwise comparison for exact zero because direct comparison is forbidden by -Wcompare-reals
813 if (all(transfer(occ_simplex(1:nvertices), [0_int64]) == 0_int64)) cycle
814
815 call simplex_dos(simplex%rdim, e_simplex(1:simplex%sdim), energies, dos_simplex)
816 do ie = 1, this%epoints
817 jdos(ie, is) = jdos(ie, is) + sum(occ_simplex(1:nvertices) * dos_simplex(1:nvertices, ie)) / &
818 simplex%n_points
819 end do
820 end do
821 end do
822 end do
823 end do
824 !$omp end do
825 safe_deallocate_a(dos_simplex)
826 !$omp end parallel
827 safe_deallocate_a(energies)
828 call profiling_out("DOS_WRITE_JDOS_TETRAHEDRA")
829 case default
830 assert(.false.)
831 end select
832
833 ! for spin-polarized calculations also output spin-resolved tDOS
834 if (st%d%nspin > 1) then
835 do is = 0, ns-1
836 write(filename, '(a,i1.1,a)') 'total-jdos-', is+1,'.dat'
837 iunit(is) = io_open(trim(dir)//'/'//trim(filename), namespace, action='write')
838 ! write header
839 write(iunit(is), '(3a)') '# energy [', trim(units_abbrev(units_out%energy)), '], total JDOS (spin-resolved)'
840
841 do ie = 1, this%epoints
842 energy = (ie - 1) * this%de
843 write(message(1), '(2es25.16E3)') units_from_atomic(units_out%energy, energy), &
844 units_from_atomic(unit_one / units_out%energy, jdos(ie, is))
845 call messages_info(1, iunit(is))
846 end do
847
848 call io_close(iunit(is))
849 end do
850 end if
851
852
853 iunit(0) = io_open(trim(dir)//'/'//'total-jdos.dat', namespace, action='write')
854 write(iunit(0), '(3a)') '# energy [', trim(units_abbrev(units_out%energy)), '], total JDOS'
855
856 ! compute total joint density of states
857 do ie = 1, this%epoints
858 energy = (ie - 1) * this%de
859 tjdos(1) = m_zero
860 do is = 0, ns-1
861 tjdos(1) = tjdos(1) + jdos(ie, is)
862 end do
863 write(message(1), '(2es25.16E3)') units_from_atomic(units_out%energy, energy), &
864 units_from_atomic(unit_one / units_out%energy, tjdos(1))
865 call messages_info(1, iunit(0))
866 end do
867
868 call io_close(iunit(0))
869 end if
870
871 safe_deallocate_a(iunit)
872 safe_deallocate_a(jdos)
873
874 pop_sub(dos_write_jdos)
875 end subroutine dos_write_jdos
876
877
878 ! ---------------------------------------------------------
880 subroutine dos_write_ldos(this, dir, st, ions, gr, hm, how, namespace)
881 type(dos_t), intent(in) :: this
882 character(len=*), intent(in) :: dir
883 type(states_elec_t), intent(in) :: st
884 type(ions_t), target, intent(in) :: ions
885 type(grid_t), intent(in) :: gr
886 type(hamiltonian_elec_t), intent(in) :: hm
887 integer(int64), intent(in) :: how
888 type(namespace_t), intent(in) :: namespace
889
890 integer :: ie, ik, ist, is, ns, ip, ifull, ierr, ii, ll, nvertices, ikpoint
891 integer :: iop, iiop, nops, nops_max
892 character(len=MAX_PATH_LEN) :: fname, name
893 logical :: has_local_corner
894 real(real64) :: weight, e_simplex(20)
895 real(real64), allocatable :: ldos(:,:,:), dpsi(:,:), abs_psi2(:), abs_psi2_symm(:), ldos_weights(:,:,:)
896 real(real64), allocatable :: dos_simplex(:,:)
897 complex(real64), allocatable :: zpsi(:,:)
898 type(unit_t) :: fn_unit
899
900 type(smear_t) :: smear
901 type(simplex_t), pointer :: simplex
902
903 push_sub(dos_write_ldos)
904
905 if (this%ldos_nenergies < 1) then
906 message(1) = "LDOSEnergies must be defined for Output=ldos"
907 call messages_fatal(1, namespace=namespace)
908 end if
909
910 ! shortcuts
911 ns = 1
912 if (st%d%nspin == 2) ns = 2
913
914 ! set up smearing parameters
915 smear%method = this%smear_func
916 smear%MP_n = 1
917
918 fn_unit = units_out%length**(-ions%space%dim) / units_out%energy
919
920 ! space for state-dependent DOS
921 safe_allocate(ldos(1:gr%np, 1:this%ldos_nenergies, 1:ns))
922 ldos = m_zero
923
924 safe_allocate(abs_psi2(1:gr%np))
925 if (states_are_real(st)) then
926 safe_allocate(dpsi(1:gr%np, 1:st%d%dim))
927 else
928 safe_allocate(zpsi(1:gr%np, 1:st%d%dim))
929 end if
930
931 select case (this%method)
932 case (option__dosmethod__smear)
933 nops_max = 1
934 safe_allocate(ldos_weights(1:this%ldos_nenergies, st%d%kpt%start:st%d%kpt%end, 1:nops_max))
935 case (option__dosmethod__tetrahedra, option__dosmethod__tetrahedra_opt)
936 assert(associated(hm%kpoints%full%simplex))
937 simplex => hm%kpoints%full%simplex
938 nvertices = simplex%rdim + 1
939 assert(nvertices <= 4)
940 nops_max = 1
941 do ifull = 1, hm%kpoints%full%npoints
942 nops_max = max(nops_max, hm%kpoints%get_full_symmetry_op_index(ifull))
943 end do
944 safe_allocate(ldos_weights(1:this%ldos_nenergies, st%d%kpt%start:st%d%kpt%end, 1:nops_max))
945 safe_allocate(abs_psi2_symm(1:gr%np))
946 case default
947 assert(.false.)
948 end select
949
950 do ist = st%st_start, st%st_end
951 ldos_weights(:, :, :) = m_zero
952
953 select case (this%method)
954 case (option__dosmethod__smear)
955 do ik = st%d%kpt%start, st%d%kpt%end
956 do ie = 1, this%ldos_nenergies
957 ldos_weights(ie, ik, 1) = st%kweights(ik) / this%gamma * &
958 smear_delta_function(smear, (this%ldos_energies(ie) - st%eigenval(ist, ik))/this%gamma)
959 end do
960 end do
961 case (option__dosmethod__tetrahedra, option__dosmethod__tetrahedra_opt)
962 call profiling_in('DOS_WRITE_LDOS_TETRAHEDRA')
963 !$omp parallel reduction(+:ldos_weights) &
964 !$omp private(ii, is, ll, ik, ie, e_simplex, dos_simplex, ifull, iiop, has_local_corner)
965 safe_allocate(dos_simplex(1:nvertices, 1:this%ldos_nenergies))
966 !$omp do schedule(dynamic)
967 do ii = 1, simplex%n_simplices
968 do is = 0, ns - 1
969 has_local_corner = .false.
970 do ll = 1, simplex%sdim
971 ik = hm%kpoints%get_equiv(simplex%simplices(ii, ll))
972 ik = ns * (ik - 1) + 1 + is
973 e_simplex(ll) = st%eigenval(ist, ik)
974 if (ik >= st%d%kpt%start .and. ik <= st%d%kpt%end) has_local_corner = .true.
975 end do
976 if (.not. has_local_corner) cycle
977
978 call simplex_dos(simplex%rdim, e_simplex(1:simplex%sdim), this%ldos_energies, &
979 dos_simplex(1:nvertices, 1:this%ldos_nenergies))
980 do ie = 1, this%ldos_nenergies
981 do ll = 1, nvertices
982 ifull = simplex%simplices(ii, ll)
983 iiop = hm%kpoints%get_full_symmetry_op_index(ifull)
984 ik = hm%kpoints%get_equiv(ifull)
985 ik = ns * (ik - 1) + 1 + is
986 if (ik >= st%d%kpt%start .and. ik <= st%d%kpt%end) then
987 ldos_weights(ie, ik, iiop) = ldos_weights(ie, ik, iiop) + dos_simplex(ll, ie) / simplex%n_points
988 end if
989 end do
990 end do
991 end do
992 end do
993 !$omp end do
994 safe_deallocate_a(dos_simplex)
995 !$omp end parallel
996 call profiling_out('DOS_WRITE_LDOS_TETRAHEDRA')
997 case default
998 assert(.false.)
999 end select
1000
1001 do ik = st%d%kpt%start, st%d%kpt%end
1002 is = st%d%get_spin_index(ik)
1003
1004 if (states_are_real(st)) then
1005 call states_elec_get_state(st, gr, ist, ik, dpsi)
1006 do ip = 1, gr%np
1007 abs_psi2(ip) = dpsi(ip, 1)**2
1008 if (st%d%dim > 1) then
1009 abs_psi2(ip) = abs_psi2(ip) + dpsi(ip, 2)**2
1010 end if
1011 end do
1012 if (st%d%dim > 1) then
1013 do ip = 1, gr%np
1014 abs_psi2(ip) = abs_psi2(ip) + dpsi(ip, 2)**2
1015 end do
1016 end if
1017 else
1018 call states_elec_get_state(st, gr, ist, ik, zpsi)
1019 do ip = 1, gr%np
1020 abs_psi2(ip) = real(conjg(zpsi(ip, 1)) * zpsi(ip, 1), real64)
1021 if (st%d%dim > 1) then
1022 abs_psi2(ip) = abs_psi2(ip) + real(conjg(zpsi(ip, 2)) * zpsi(ip, 2), real64)
1023 end if
1024 end do
1025 if (st%d%dim > 1) then
1026 do ip = 1, gr%np
1027 end do
1028 end if
1029 end if
1030
1031 select case (this%method)
1032 case (option__dosmethod__smear)
1033 do ie = 1, this%ldos_nenergies
1034 weight = ldos_weights(ie, ik, 1)
1035 call lalg_axpy(gr%np, weight, abs_psi2, ldos(:, ie, is))
1036 end do
1037 case (option__dosmethod__tetrahedra, option__dosmethod__tetrahedra_opt)
1038 ikpoint = st%d%get_kpoint_index(ik)
1039 nops = kpoints_get_num_symmetry_ops(hm%kpoints, ikpoint)
1040 do iiop = 1, nops
1041 iop = abs(kpoints_get_symmetry_ops(hm%kpoints, ikpoint, iiop))
1042 call dgrid_symmetrize_single(gr, iop, abs_psi2, abs_psi2_symm)
1043 do ie = 1, this%ldos_nenergies
1044 weight = ldos_weights(ie, ik, iiop)
1045 call lalg_axpy(gr%np, weight, abs_psi2_symm, ldos(:, ie, is))
1046 end do
1047 end do
1048 case default
1049 assert(.false.)
1050 end select
1051 end do
1052 end do
1053
1054 safe_deallocate_a(ldos_weights)
1055 safe_deallocate_a(dpsi)
1056 safe_deallocate_a(zpsi)
1057 safe_deallocate_a(abs_psi2)
1058 safe_deallocate_a(abs_psi2_symm)
1059
1060 if (st%parallel_in_states .or. st%d%kpt%parallel) then
1061 call comm_allreduce(st%st_kpt_mpi_grp, ldos)
1062 end if
1063
1064 do is = 1, ns
1065 do ie = 1, this%ldos_nenergies
1066 write(name, '(a,i5.5)') 'ldos_en-', ie
1067 fname = get_filename_with_spin(name, st%d%nspin, is)
1068
1069 if (hm%kpoints%use_symmetries .and. &
1070 .not. (this%method == option__dosmethod__tetrahedra .or. this%method == option__dosmethod__tetrahedra_opt)) then
1071 call dgrid_symmetrize_scalar_field(gr, ldos(:, ie, is), suppress_warning = .true.)
1072 end if
1073 call dio_function_output(how, dir, fname, namespace, ions%space, gr, &
1074 ldos(:, ie, is), fn_unit, ierr, pos=ions%pos, atoms=ions%atom, grp = st%dom_st_kpt_mpi_grp)
1075 end do
1076 end do
1077
1078 safe_deallocate_a(ldos)
1079
1080 pop_sub(dos_write_ldos)
1081 end subroutine dos_write_ldos
1082
1083
1084end module dos_oct_m
1085
1086!! Local Variables:
1087!! mode: f90
1088!! coding: utf-8
1089!! End:
constant times a vector plus a vector
Definition: lalg_basic.F90:173
pure logical function, public accel_is_enabled()
Definition: accel.F90:403
integer, parameter, public accel_mem_read_only
Definition: accel.F90:186
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.
Definition: dos.F90:118
subroutine, public dos_write_pdos(this, dir, st, box, ions, mesh, hm, namespace)
Computes and output the projected DOS (PDOS)
Definition: dos.F90:533
subroutine dos_end(this)
Finalizer for the dos_t object.
Definition: dos.F90:322
subroutine, public dos_write_dos(this, dir, st, box, ions, mesh, hm, namespace)
Computes and output the DOS and the projected DOS (PDOS)
Definition: dos.F90:335
subroutine, public dos_write_jdos(this, dir, st, ions, hm, namespace)
Computes and output the joint DOS (JDOS)
Definition: dos.F90:820
subroutine, public dos_init(this, namespace, st, kpoints)
Initializes the dot_t object.
Definition: dos.F90:188
subroutine, public dos_write_ldos(this, dir, st, ions, gr, hm, how, namespace)
Computes and output the local DOS (LDOS)
Definition: dos.F90:976
integer, parameter, public spin_polarized
real(real64), parameter, public m_zero
Definition: global.F90:200
real(real64), parameter, public m_four
Definition: global.F90:204
real(real64), parameter, public m_epsilon
Definition: global.F90:216
real(real64), parameter, public m_one
Definition: global.F90:201
This module implements the underlying real-space grid.
Definition: grid.F90:119
subroutine, public dgrid_symmetrize_single(gr, iop, field, symm_field)
Definition: grid.F90:716
subroutine, public dgrid_symmetrize_scalar_field(gr, field, suppress_warning)
Definition: grid.F90:662
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.
Definition: io.F90:116
subroutine, public io_close(iunit, grp)
Definition: io.F90:467
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
Definition: io.F90:402
integer pure function, public kpoints_get_num_symmetry_ops(this, ik)
Definition: kpoints.F90:1730
integer pure function, public kpoints_get_symmetry_ops(this, ik, index)
Definition: kpoints.F90:1743
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:117
integer pure function, public pad_pow2(size)
create array size, which is padded to powers of 2
Definition: math.F90:846
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:1000
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:410
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
type(namespace_t), public global_namespace
Definition: namespace.F90:135
subroutine, public orbitalset_init(this)
Definition: orbitalset.F90:209
subroutine, public orbitalset_end(this)
Definition: orbitalset.F90:235
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...
Definition: orbitalset.F90:285
subroutine, public dorbitalset_get_coeff_batch(os, ndim, psib, dot, reduce)
Definition: orbitalset.F90:589
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
Definition: output_low.F90:117
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.
Definition: output_low.F90:233
integer function, public parse_block(namespace, name, blk, check_varinfo_)
Definition: parser.F90:623
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:631
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:554
real(real64) function, public smear_delta_function(this, xx)
Definition: smear.F90:832
integer, parameter, public smear_lorentzian
Definition: smear.F90:176
pure logical function, public states_are_real(st)
type(type_t), parameter, public type_cmplx
Definition: types.F90:136
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:134
character(len=20) pure function, public units_abbrev(this)
Definition: unit.F90:225
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
Definition: box.F90:143
Description of the grid, containing information on derivatives, stencil, and symmetries.
Definition: grid.F90:171
Describes mesh distribution to nodes.
Definition: mesh.F90:187
The states_elec_t class contains all electronic wave functions.
batches of electronic states
Definition: wfs_elec.F90:141
int true(void)