40#include "./base/base_uses.f90"
46 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qs_dos'
65 SUBROUTINE calculate_dos(mos, dft_section, unoccupied_evals, smearing_enabled)
70 POINTER :: unoccupied_evals
71 LOGICAL,
INTENT(IN),
OPTIONAL :: smearing_enabled
73 CHARACTER(len=*),
PARAMETER :: routinen =
'calculate_dos'
75 CHARACTER(LEN=16) :: energy_label
76 CHARACTER(LEN=20) :: fmtstr_data
77 CHARACTER(LEN=32) :: zero_label
78 CHARACTER(LEN=default_string_length) :: my_act, my_pos
79 INTEGER :: broaden_type, energy_unit, energy_zero, handle, i, iounit, ispin, iterstep, iv, &
80 iw, ndigits, nhist, nmo(2), nspins, nstates(2), nvirt(2), resolved_energy_zero
81 LOGICAL :: append, do_broaden, &
82 fractional_occupation, ionode, &
83 should_output, smear_on
84 REAL(kind=
dp) :: broaden_cutoff, broaden_width, de, density_factor, e1, e2, e_fermi(2), &
85 emax, emin, energy_factor, energy_ref(2), ev_factor, eval, hoco(2), out_density, out_occ, &
87 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: ehist, hist, occval
88 REAL(kind=
dp),
DIMENSION(:),
POINTER :: eigenvalues, occupation_numbers
94 ionode = logger%para_env%is_source()
98 IF ((.NOT. should_output))
RETURN
100 CALL timeset(routinen, handle)
101 iterstep = logger%iter_info%iteration(logger%iter_info%n_rlevel)
103 IF (iounit > 0)
WRITE (unit=iounit, fmt=
'(/,(T3,A,T61,I10))') &
104 " Calculate DOS at iteration step ", iterstep
114 IF (append .AND. iterstep > 1)
THEN
119 ndigits = min(max(ndigits, 1), 10)
120 do_broaden = (broaden_width > 0.0_dp)
121 IF (do_broaden) de = max(de, 0.00001_dp)
129 hoco(:) = -huge(0.0_dp)
130 fractional_occupation = .false.
132 IF (
PRESENT(smearing_enabled)) smear_on = smearing_enabled
136 CALL get_mo_set(mo_set=mo_set, nmo=nmo(ispin), mu=e_fermi(ispin))
137 eigenvalues => mo_set%eigenvalues
138 occupation_numbers => mo_set%occupation_numbers
140 IF (occupation_numbers(i) > 1.0e-10_dp) hoco(ispin) = max(hoco(ispin), eigenvalues(i))
141 IF (abs(occupation_numbers(i) - real(nint(occupation_numbers(i)), kind=
dp)) > &
142 1.0e-8_dp) fractional_occupation = .true.
144 IF (hoco(ispin) < -0.5_dp*huge(0.0_dp)) hoco(ispin) = e_fermi(ispin)
145 IF (
PRESENT(unoccupied_evals))
THEN
146 IF (
ASSOCIATED(unoccupied_evals(ispin)%array)) nvirt(ispin) =
SIZE(unoccupied_evals(ispin)%array)
148 nstates(ispin) = nmo(ispin) + nvirt(ispin)
149 e1 = minval(eigenvalues(1:nmo(ispin)))
150 e2 = maxval(eigenvalues(1:nmo(ispin)))
151 IF (nvirt(ispin) > 0)
THEN
152 e1 = min(e1, minval(unoccupied_evals(ispin)%array(1:nvirt(ispin))))
153 e2 = max(e2, maxval(unoccupied_evals(ispin)%array(1:nvirt(ispin))))
161 emin = emin - broaden_cutoff
162 emax = emax + broaden_cutoff
163 nhist = nint((emax - emin)/de) + 1
164 ALLOCATE (hist(nhist, nspins), occval(nhist, nspins), ehist(nhist, nspins))
170 occupation_numbers => mo_set%occupation_numbers
171 eigenvalues => mo_set%eigenvalues
174 occupation_numbers(i), 1.0_dp, broaden_type, broaden_width, &
177 DO i = 1, nvirt(ispin)
179 unoccupied_evals(ispin)%array(i), 0.0_dp, 1.0_dp, &
180 broaden_type, broaden_width, voigt_mixing)
184 ehist(i, 1:nspins) = emin + (i - 1)*de
186 ELSE IF (de > 0.0_dp)
THEN
187 nhist = nint((emax - emin)/de) + 1
188 ALLOCATE (hist(nhist, nspins), occval(nhist, nspins), ehist(nhist, nspins))
194 occupation_numbers => mo_set%occupation_numbers
195 eigenvalues => mo_set%eigenvalues
197 eval = eigenvalues(i) - emin
198 iv = nint(eval/de) + 1
199 cpassert((iv > 0) .AND. (iv <= nhist))
200 hist(iv, ispin) = hist(iv, ispin) + 1.0_dp
201 occval(iv, ispin) = occval(iv, ispin) + occupation_numbers(i)
203 DO i = 1, nvirt(ispin)
204 eval = unoccupied_evals(ispin)%array(i) - emin
205 iv = nint(eval/de) + 1
206 cpassert((iv > 0) .AND. (iv <= nhist))
207 hist(iv, ispin) = hist(iv, ispin) + 1.0_dp
209 hist(:, ispin) = hist(:, ispin)/real(nstates(ispin), kind=
dp)
212 ehist(i, 1:nspins) = emin + (i - 1)*de
215 nhist = maxval(nstates)
216 ALLOCATE (hist(nhist, nspins), occval(nhist, nspins), ehist(nhist, nspins))
222 occupation_numbers => mo_set%occupation_numbers
223 eigenvalues => mo_set%eigenvalues
225 ehist(i, ispin) = eigenvalues(i)
226 hist(i, ispin) = 1.0_dp
227 occval(i, ispin) = occupation_numbers(i)
229 DO i = 1, nvirt(ispin)
230 ehist(nmo(ispin) + i, ispin) = unoccupied_evals(ispin)%array(i)
231 hist(nmo(ispin) + i, ispin) = 1.0_dp
233 hist(:, ispin) = hist(:, ispin)/real(nstates(ispin), kind=
dp)
238 SELECT CASE (resolved_energy_zero)
240 energy_ref(:) = 0.0_dp
242 energy_ref(:) = hoco(:)
244 energy_ref(:) = e_fermi(:)
255 extension=
".dos", file_position=my_pos, file_action=my_act, &
256 file_form=
"FORMATTED")
258 WRITE (unit=iw, fmt=
"(A,I0)")
"# DOS at iteration step i = ", iterstep
259 IF (nspins == 2)
THEN
260 WRITE (unit=iw, fmt=
"(A,2F12.6,A,2F12.6,A)") &
261 "# E(Fermi) = ", e_fermi(1:2),
" a.u. = ", e_fermi(1:2)*ev_factor,
" eV"
262 WRITE (unit=iw, fmt=
"(A,2F12.6,A,2F12.6,A)") &
263 "# E(HOCO) = ", hoco(1:2),
" a.u. = ", hoco(1:2)*ev_factor,
" eV"
264 WRITE (unit=iw, fmt=
"(A,A)")
"# Energy zero: ", trim(zero_label)
266 WRITE (unit=iw, fmt=
"(T2,A,A,A)")
"# "//trim(energy_label)//
" Alpha_Density Occupation", &
267 " "//trim(energy_label),
" Beta_Density Occupation"
269 WRITE (unit=fmtstr_data, fmt=
"(A,I0,A)")
"(2(F15.8,2F20.", ndigits,
"))"
271 WRITE (unit=iw, fmt=
"(A,F12.6,A,F12.6,A)") &
272 "# E(Fermi) = ", e_fermi(1),
" a.u. = ", e_fermi(1)*ev_factor,
" eV"
273 WRITE (unit=iw, fmt=
"(A,F12.6,A,F12.6,A)") &
274 "# E(HOCO) = ", hoco(1),
" a.u. = ", hoco(1)*ev_factor,
" eV"
275 WRITE (unit=iw, fmt=
"(A,A)")
"# Energy zero: ", trim(zero_label)
277 WRITE (unit=iw, fmt=
"(A,A)")
"# "//trim(energy_label),
" Density Occupation"
279 WRITE (unit=fmtstr_data, fmt=
"(A,I0,A)")
"(F15.8,2F20.", ndigits,
")"
282 IF (nspins == 2)
THEN
283 e1 = (ehist(i, 1) - energy_ref(1))*energy_factor
284 e2 = (ehist(i, 2) - energy_ref(2))*energy_factor
287 WRITE (unit=iw, fmt=fmtstr_data) e1, hist(i, 1)*density_factor, &
288 occval(i, 1)*density_factor, e2, hist(i, 2)*density_factor, &
289 occval(i, 2)*density_factor
291 WRITE (unit=iw, fmt=fmtstr_data) e1, hist(i, 1), occval(i, 1), &
292 e2, hist(i, 2), occval(i, 2)
295 eval = (ehist(i, 1) - energy_ref(1))*energy_factor
298 out_density = hist(i, 1)*density_factor
299 out_occ = occval(i, 1)*density_factor
301 out_density = hist(i, 1)
302 out_occ = occval(i, 1)
304 WRITE (unit=iw, fmt=fmtstr_data) eval, out_density, out_occ
309 DEALLOCATE (hist, occval, ehist)
311 CALL timestop(handle)
329 CHARACTER(len=*),
PARAMETER :: routinen =
'calculate_dos_kp'
331 CHARACTER(LEN=16) :: energy_label, fmtstr_data
332 CHARACTER(LEN=32) :: zero_label
333 CHARACTER(LEN=default_string_length) :: my_act, my_pos
334 INTEGER :: broaden_type, energy_unit, energy_zero, fractional_occupation_int, handle, i, ik, &
335 iounit, ispin, iterstep, iv, iw, ndigits, nhist, nmo(2), nmo_kp, nspins, &
337 INTEGER,
DIMENSION(:),
POINTER :: nkp_grid
338 LOGICAL :: append, do_broaden, explicit, &
339 fractional_occupation, ionode, &
341 REAL(kind=
dp) :: broaden_cutoff, broaden_width, de, density_factor, e1, e2, e_fermi(2), &
342 emax, emin, energy_factor, energy_ref(2), ev_factor, eval, hoco(2), out_density, out_occ, &
344 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: ehist, hist, occval
345 REAL(kind=
dp),
DIMENSION(:),
POINTER :: eigenvalues, occupation_numbers
353 NULLIFY (logger, kpoints)
355 ionode = logger%para_env%is_source()
359 IF ((.NOT. should_output))
RETURN
361 CALL timeset(routinen, handle)
362 iterstep = logger%iter_info%iteration(logger%iter_info%n_rlevel)
370 IF (nkp_grid(i) < 1)
THEN
371 WRITE (unit=iounit, fmt=
'(T4,A,I3,A,I1)') &
372 "Invalid kpoint grid for DOS ", nkp_grid(i),
" in dimension ", i
383 IF (iounit > 0)
WRITE (unit=iounit, fmt=
'(/,(T3,A,T61,I10))') &
384 " Calculate DOS at iteration step ", iterstep
385 IF (iounit > 0)
WRITE (unit=iounit, fmt=
'((T3,A,3I3,A))') &
386 " Using a", kpoints%nkp_grid(:),
' '//trim(kpoints%kp_scheme)//
' grid'
397 de = max(de, 0.00001_dp)
398 IF (append .AND. iterstep > 1)
THEN
403 ndigits = min(max(ndigits, 1), 10)
404 do_broaden = (broaden_width > 0.0_dp)
406 CALL get_qs_env(qs_env, dft_control=dft_control)
407 nspins = dft_control%nspins
408 para_env => kpoints%para_env_inter_kp
414 hoco(:) = -huge(0.0_dp)
415 fractional_occupation = .false.
416 IF (kpoints%nkp /= 0)
THEN
417 DO ik = 1,
SIZE(kpoints%kp_env)
418 mos => kpoints%kp_env(ik)%kpoint_env%mos
419 cpassert(
ASSOCIATED(mos))
421 mo_set => mos(1, ispin)
422 CALL get_mo_set(mo_set=mo_set, nmo=nmo_kp, mu=e_fermi(ispin))
423 eigenvalues => mo_set%eigenvalues
424 occupation_numbers => mo_set%occupation_numbers
426 IF (occupation_numbers(i) > 1.0e-10_dp) hoco(ispin) = max(hoco(ispin), eigenvalues(i))
427 IF (abs(occupation_numbers(i) - real(nint(occupation_numbers(i)), kind=
dp)) > &
428 1.0e-8_dp) fractional_occupation = .true.
430 e1 = minval(eigenvalues(1:nmo_kp))
431 e2 = maxval(eigenvalues(1:nmo_kp))
434 nmo(ispin) = max(nmo(ispin), nmo_kp)
438 CALL para_env%min(emin)
439 CALL para_env%max(emax)
440 CALL para_env%max(nmo)
441 CALL para_env%max(e_fermi)
442 CALL para_env%max(hoco)
443 fractional_occupation_int = merge(1, 0, fractional_occupation)
444 CALL para_env%max(fractional_occupation_int)
445 fractional_occupation = (fractional_occupation_int /= 0)
447 IF (hoco(ispin) < -0.5_dp*huge(0.0_dp)) hoco(ispin) = e_fermi(ispin)
452 emin = emin - broaden_cutoff
453 emax = emax + broaden_cutoff
455 nhist = nint((emax - emin)/de) + 1
456 ALLOCATE (hist(nhist, nspins), occval(nhist, nspins), ehist(nhist, nspins))
461 IF (kpoints%nkp /= 0)
THEN
462 DO ik = 1,
SIZE(kpoints%kp_env)
463 mos => kpoints%kp_env(ik)%kpoint_env%mos
464 wkp = kpoints%kp_env(ik)%kpoint_env%wkp
466 mo_set => mos(1, ispin)
467 occupation_numbers => mo_set%occupation_numbers
468 eigenvalues => mo_set%eigenvalues
472 occupation_numbers(i), wkp, broaden_type, broaden_width, &
477 eval = eigenvalues(i) - emin
478 iv = nint(eval/de) + 1
479 cpassert((iv > 0) .AND. (iv <= nhist))
480 hist(iv, ispin) = hist(iv, ispin) + wkp
481 occval(iv, ispin) = occval(iv, ispin) + wkp*occupation_numbers(i)
487 CALL para_env%sum(hist)
488 CALL para_env%sum(occval)
489 IF (.NOT. do_broaden)
THEN
491 hist(:, ispin) = hist(:, ispin)/real(nmo(ispin), kind=
dp)
495 ehist(i, 1:nspins) = emin + (i - 1)*de
499 SELECT CASE (resolved_energy_zero)
501 energy_ref(:) = 0.0_dp
503 energy_ref(:) = hoco(:)
505 energy_ref(:) = e_fermi(:)
516 extension=
".dos", file_position=my_pos, file_action=my_act, &
517 file_form=
"FORMATTED")
519 WRITE (unit=iw, fmt=
"(A,I0)")
"# DOS at iteration step i = ", iterstep
520 IF (nspins == 2)
THEN
521 WRITE (unit=iw, fmt=
"(A,2F12.6,A,2F12.6,A)") &
522 "# E(Fermi) = ", e_fermi(1:2),
" a.u. = ", e_fermi(1:2)*ev_factor,
" eV"
523 WRITE (unit=iw, fmt=
"(A,2F12.6,A,2F12.6,A)") &
524 "# E(HOCO) = ", hoco(1:2),
" a.u. = ", hoco(1:2)*ev_factor,
" eV"
525 WRITE (unit=iw, fmt=
"(A,A)")
"# Energy zero: ", trim(zero_label)
527 WRITE (unit=iw, fmt=
"(A,A)")
"# "//trim(energy_label)//
" Alpha_Density Occupation", &
528 " Beta_Density Occupation"
530 WRITE (unit=fmtstr_data, fmt=
"(A,I0,A)")
"(F15.8,4F20.", ndigits,
")"
532 WRITE (unit=iw, fmt=
"(A,F12.6,A,F12.6,A)") &
533 "# E(Fermi) = ", e_fermi(1),
" a.u. = ", e_fermi(1)*ev_factor,
" eV"
534 WRITE (unit=iw, fmt=
"(A,F12.6,A,F12.6,A)") &
535 "# E(HOCO) = ", hoco(1),
" a.u. = ", hoco(1)*ev_factor,
" eV"
536 WRITE (unit=iw, fmt=
"(A,A)")
"# Energy zero: ", trim(zero_label)
538 WRITE (unit=iw, fmt=
"(A,A)")
"# "//trim(energy_label),
" Density Occupation"
540 WRITE (unit=fmtstr_data, fmt=
"(A,I0,A)")
"(F15.8,2F20.", ndigits,
")"
543 eval = (ehist(i, 1) - energy_ref(1))*energy_factor
544 IF (nspins == 2)
THEN
547 WRITE (unit=iw, fmt=fmtstr_data) eval, hist(i, 1)*density_factor, &
548 occval(i, 1)*density_factor, hist(i, 2)*density_factor, occval(i, 2)*density_factor
550 WRITE (unit=iw, fmt=fmtstr_data) eval, hist(i, 1), occval(i, 1), &
551 hist(i, 2), occval(i, 2)
556 out_density = hist(i, 1)*density_factor
557 out_occ = occval(i, 1)*density_factor
559 out_density = hist(i, 1)
560 out_occ = occval(i, 1)
562 WRITE (unit=iw, fmt=fmtstr_data) eval, out_density, out_occ
567 DEALLOCATE (hist, occval, ehist)
574 CALL timestop(handle)
various utilities that regard array of different kinds: output, allocation,... maybe it is not a good...
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
integer, parameter, public cp_p_file
integer function, public cp_print_key_should_output(iteration_info, basis_section, print_key_path, used_print_key, first_time)
returns what should be done with the given property if btest(res,cp_p_store) then the property should...
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 kpoint_release(kpoint)
Release a kpoint environment, deallocate all data.
Interface to the message passing library MPI.
Calculation of band structures.
subroutine, public calculate_kp_orbitals(qs_env, kpoint, scheme, nadd, mp_grid, kpgeneral, group_size_ext, kp_shift, gamma_centered)
diagonalize KS matrices at a set of kpoints
Utilities for broadened DOS and PDOS output.
subroutine, public add_broadened_peak(dos, occ_dos, emin, de, eig, occ, weight, broaden_type, broaden_width, voigt_mixing)
Add a broadened spectral line to a DOS curve.
subroutine, public write_broadening_info(iw, broaden_type, broaden_width, voigt_mixing)
Write broadening metadata.
integer, parameter, public dos_energy_zero_hoco
integer, parameter, public dos_energy_zero_auto
integer, parameter, public dos_energy_unit_ev
character(len=16) function, public dos_energy_label(energy_unit)
Return the energy-column label for DOS-like output.
integer function, public dos_resolve_energy_zero(energy_zero, smearing_enabled, fractional_occupation)
Resolve AUTO energy-zero selection for DOS-like output.
real(kind=dp) function, public dos_energy_scale(energy_unit)
Return the conversion factor from internal energy units to the selected DOS energy unit.
integer, parameter, public dos_energy_zero_absolute
pure real(kind=dp) function, public broadening_cutoff(broaden_type, broaden_width)
Broadening cutoff used for numerical accumulation.
real(kind=dp) function, public dos_density_scale(energy_unit)
Return the DOS-density conversion factor for the selected energy unit.
character(len=16) function, public dos_energy_zero_label(energy_zero)
Return the label for the selected DOS energy zero.
Calculation and writing of density of states.
subroutine, public calculate_dos(mos, dft_section, unoccupied_evals, smearing_enabled)
Compute and write density of states.
subroutine, public calculate_dos_kp(qs_env, dft_section)
Compute and write density of states (kpoints)
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
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.
represent a pointer to a 1d array
type of a logger, at the moment it contains just a print level starting at which level it should be l...
Contains information about kpoints.
stores all the informations relevant to an mpi environment