51#if defined(HAVE_BERKELEYGW)
69 integer,
intent(in) :: nst
70 type(namespace_t),
intent(in) :: namespace
71 type(output_bgw_t),
intent(out) :: bgw
72 integer,
intent(in) :: periodic_dim
82#ifndef HAVE_BERKELEYGW
83 message(1) =
"Cannot do BerkeleyGW output: the library was not linked."
95 call parse_variable(namespace,
'BerkeleyGW_NumberBands', nst, bgw%nbands)
98 if (bgw%nbands > nst)
then
99 message(1) =
"BerkeleyGW_NumberBands must be <= number of states."
111 call parse_variable(namespace,
'BerkeleyGW_Vxc_diag_nmin', 1, bgw%vxc_diag_nmin)
113 if (bgw%vxc_diag_nmin > nst)
then
114 message(1) =
"BerkeleyGW_Vxc_diag_nmin must be <= number of states."
126 call parse_variable(namespace,
'BerkeleyGW_Vxc_diag_nmax', nst, bgw%vxc_diag_nmax)
128 if (bgw%vxc_diag_nmax > nst)
then
129 message(1) =
"BerkeleyGW_Vxc_diag_nmax must be <= number of states."
133 if (bgw%vxc_diag_nmin <= 0 .or. bgw%vxc_diag_nmax <= 0)
then
134 bgw%vxc_diag_nmin = 0
135 bgw%vxc_diag_nmax = 0
146 call parse_variable(namespace,
'BerkeleyGW_Vxc_offdiag_nmin', 1, bgw%vxc_offdiag_nmin)
148 if (bgw%vxc_offdiag_nmin > nst)
then
149 message(1) =
"BerkeleyGW_Vxc_offdiag_nmin must be <= number of states."
161 call parse_variable(namespace,
'BerkeleyGW_Vxc_offdiag_nmax', nst, bgw%vxc_offdiag_nmax)
163 if (bgw%vxc_offdiag_nmax > nst)
then
164 message(1) =
"BerkeleyGW_Vxc_offdiag_nmax must be <= number of states."
168 if (bgw%vxc_offdiag_nmin <= 0 .or. bgw%vxc_offdiag_nmax <= 0)
then
169 bgw%vxc_offdiag_nmin = 0
170 bgw%vxc_offdiag_nmax = 0
193 call parse_variable(namespace,
'BerkeleyGW_WFN_filename',
'WFN', bgw%wfn_filename)
204 call parse_variable(namespace,
'BerkeleyGW_CalcExchange', .false., bgw%calc_exchange)
219 call parse_variable(namespace,
'BerkeleyGW_CalcDipoleMtxels', .false., bgw%calc_vmtxel)
231 bgw%vmtxel_polarization(1:3) =
m_zero
232 bgw%vmtxel_polarization(1) =
m_one
234 if (bgw%calc_vmtxel .and.
parse_block(namespace,
'BerkeleyGW_VmtxelPolarization', blk) == 0)
then
238 if (idir <= periodic_dim .and. abs(bgw%vmtxel_polarization(idir)) >
m_epsilon)
then
239 message(1) =
"You cannot calculate vmtxel with polarization in a periodic direction. Use WFNq_fi instead."
244 norm = sum(abs(bgw%vmtxel_polarization(1:3))**2)
246 message(1) =
"A non-zero value must be set for BerkeleyGW_VmtxelPolarization when BerkeleyGW_CalcDipoleMtxels = yes."
249 bgw%vmtxel_polarization(1:3) = bgw%vmtxel_polarization(1:3) /
sqrt(norm)
261 if (bgw%calc_vmtxel)
call parse_variable(namespace,
'BerkeleyGW_VmtxelNumCondBands', 0, bgw%vmtxel_ncband)
273 if (bgw%calc_vmtxel)
call parse_variable(namespace,
'BerkeleyGW_VmtxelNumValBands', 0, bgw%vmtxel_nvband)
284 class(
space_t),
intent(in) :: space
285 character(len=*),
intent(in) :: dir
287 type(
grid_t),
target,
intent(in) :: gr
288 type(
v_ks_t),
intent(inout) :: ks
290 type(
ions_t),
intent(in) :: ions
292#ifdef HAVE_BERKELEYGW
293 integer :: ik, is, ikk, ist, itran, iunit, iatom, mtrx(3, 3, 48), fftgrid(3), ngkmax
294 integer,
pointer :: atyp(:)
295 integer,
allocatable :: ifmin(:,:), ifmax(:,:), ngk(:)
296 character(len=3) :: sheader
297 real(real64) :: adot(3,3), bdot(3,3), recvol, tnp(3, 48), ecutrho, ecutwfc
298 real(real64),
allocatable :: energies(:,:,:), occupations(:,:,:)
299 real(real64),
pointer :: apos(:,:)
300 real(real64),
allocatable :: vxc(:,:), dpsi(:,:)
301 complex(real64),
allocatable :: field_g(:,:), zpsi(:,:)
309 if (space%dim /= 3)
then
310 message(1) =
"BerkeleyGW output only available in 3D."
316 if (st%parallel_in_states)
call messages_not_implemented(
"BerkeleyGW output parallel in states", namespace=namespace)
326#ifdef HAVE_BERKELEYGW
328 safe_allocate(vxc(1:gr%np, 1:st%d%nspin))
331 call xc_get_vxc(gr, ks%xc, st, hm%kpoints, hm%psolver, namespace, space, st%rho, st%d%ispin, &
332 hm%ions%latt%rcell_volume, vxc)
334 message(1) =
"BerkeleyGW output: vxc.dat"
339 call dbgw_vxc_dat(bgw, namespace, space, dir, st, gr, hm, vxc)
341 call zbgw_vxc_dat(bgw, namespace, space, dir, st, gr, hm, vxc)
344 call cube_init(cube, gr%idx%ll, namespace, space, gr%spacing, gr%coord_system, &
347 if (any(gr%idx%ll(1:3) /= fftgrid(1:3)))
then
348 message(1) =
"Cannot do BerkeleyGW output: FFT grid has been modified."
356 ecutrho = shell_density%ekin_cutoff
357 safe_allocate(field_g(1:shell_density%ngvectors, 1:st%d%nspin))
359 call bgw_setup_header()
362 if (bgw%calc_vmtxel)
then
363 write(
message(1),
'(a,3f12.6)')
"BerkeleyGW output: vmtxel. Polarization = ", bgw%vmtxel_polarization(1:3)
367 call dbgw_vmtxel(bgw, namespace, dir, st, gr, ifmax)
369 call zbgw_vmtxel(bgw, namespace, dir, st, gr, ifmax)
373 message(1) =
"BerkeleyGW output: VXC"
377 if (st%system_grp%is_root())
then
378 iunit =
io_open(trim(dir) //
'VXC', namespace, form =
'unformatted', action =
'write')
379 call bgw_write_header(sheader, iunit)
382 vxc(:,:) = vxc(:,:) *
m_two / (product(cube%rs_n_global(1:3)) * gr%volume_element)
383 call dbgw_write_fs(namespace, iunit, vxc, field_g, shell_density, st%d%nspin, gr, cube, cf, is_wfn = .false., &
384 is_root=st%system_grp%is_root())
385 if (st%system_grp%is_root())
call io_close(iunit)
386 safe_deallocate_a(vxc)
389 message(1) =
"BerkeleyGW output: RHO"
393 if (st%system_grp%is_root())
then
394 iunit =
io_open(trim(dir) //
'RHO', namespace, form =
'unformatted', action =
'write')
395 call bgw_write_header(sheader, iunit)
397 call dbgw_write_fs(namespace, iunit, st%rho, field_g, shell_density, st%d%nspin, gr, cube, cf, is_wfn = .false., &
398 is_root=st%system_grp%is_root())
399 if (st%system_grp%is_root())
call io_close(iunit)
401 message(1) =
"BerkeleyGW output: WFN"
402 write(
message(2),
'(a,f12.6,a)')
"Wavefunction cutoff for BerkeleyGW: ", &
407 safe_allocate(dpsi(1:gr%np, 1:st%d%nspin))
409 safe_allocate(zpsi(1:gr%np, 1:st%d%nspin))
413 if (st%system_grp%is_root())
then
414 iunit =
io_open(trim(dir) // bgw%wfn_filename, namespace, form =
'unformatted', action =
'write')
415 call bgw_write_header(sheader, iunit)
421 do ik = st%d%kpt%start, st%d%kpt%end, st%d%nspin
422 call fourier_shell_init(shell_wfn, namespace, space, cube, gr, kk = hm%kpoints%reduced%red_point(:, ik))
424 if (st%system_grp%is_root())
then
425 call write_binary_gvectors(iunit, shell_wfn%ngvectors, shell_wfn%ngvectors, shell_wfn%red_gvec)
428 do is = 1, st%d%nspin
437 call dbgw_write_fs(namespace, iunit, dpsi, field_g, shell_wfn, st%d%nspin, gr, cube, cf, is_wfn = .
true., &
438 is_root=st%system_grp%is_root())
440 call zbgw_write_fs(namespace, iunit, zpsi, field_g, shell_wfn, st%d%nspin, gr, cube, cf, is_wfn = .
true., &
441 is_root=st%system_grp%is_root())
447 if (st%system_grp%is_root())
call io_close(iunit)
455 safe_deallocate_a(dpsi)
457 safe_deallocate_a(zpsi)
459 safe_deallocate_a(vxc)
460 safe_deallocate_a(field_g)
461 safe_deallocate_a(ifmin)
462 safe_deallocate_a(ifmax)
463 safe_deallocate_a(ngk)
464 safe_deallocate_a(energies)
465 safe_deallocate_a(occupations)
466 safe_deallocate_p(atyp)
467 safe_deallocate_p(apos)
470 message(1) =
"Cannot do BerkeleyGW output: the library was not linked."
476#ifdef HAVE_BERKELEYGW
479 subroutine bgw_setup_header()
482 if (space%periodic_dim /= 0 .and. space%periodic_dim /= 3)
then
483 message(1) =
"BerkeleyGW for mixed-periodicity is currently not implemented."
491 adot(1:3, 1:3) = matmul(ions%latt%rlattice(1:3, 1:3), ions%latt%rlattice(1:3, 1:3))
492 bdot(1:3, 1:3) = matmul(ions%latt%klattice(1:3, 1:3), ions%latt%klattice(1:3, 1:3))
493 recvol = (
m_two *
m_pi)**3 / ions%latt%rcell_volume
502 safe_allocate(ifmin(1:hm%kpoints%reduced%npoints, 1:st%d%nspin))
503 safe_allocate(ifmax(1:hm%kpoints%reduced%npoints, 1:st%d%nspin))
504 safe_allocate(energies(1:st%nst, 1:hm%kpoints%reduced%npoints, 1:st%d%nspin))
505 safe_allocate(occupations(1:st%nst, 1:hm%kpoints%reduced%npoints, 1:st%d%nspin))
513 is = st%d%get_spin_index(ik)
514 ikk = st%d%get_kpoint_index(ik)
515 energies(1:st%nst, ikk, is) = st%eigenval(1:st%nst,ik) *
m_two
516 occupations(1:st%nst, ikk, is) = st%occ(1:st%nst, ik) / st%smear%el_per_state
519 if (st%eigenval(ist, ik) < st%smear%e_fermi +
m_epsilon)
then
527 safe_allocate(ngk(1:hm%kpoints%reduced%npoints))
528 do ik = 1, st%nik, st%d%nspin
529 call fourier_shell_init(shell_wfn, namespace, space, cube, gr, kk = hm%kpoints%reduced%red_point(:, ik))
530 if (ik == 1) ecutwfc = shell_wfn%ekin_cutoff
531 ngk(ik) = shell_wfn%ngvectors
536 safe_allocate(atyp(1:ions%natoms))
537 safe_allocate(apos(1:3, 1:ions%natoms))
538 do iatom = 1, ions%natoms
539 atyp(iatom) = ions%atom(iatom)%species%get_index()
540 apos(1:3, iatom) = ions%pos(1:3, iatom)
543 if (any(hm%kpoints%nik_axis(1:3) == 0))
then
544 message(1) =
"KPointsGrid has a zero component. Set KPointsGrid appropriately,"
545 message(2) =
"or this WFN will only be usable in BerkeleyGW's inteqp."
550 end subroutine bgw_setup_header
553 subroutine bgw_write_header(sheader, iunit)
554 character(len=3),
intent(inout) :: sheader
555 integer,
intent(in) :: iunit
559 call write_binary_header(iunit, sheader, 2, st%d%nspin, shell_density%ngvectors, &
561 hm%kpoints%reduced%npoints, st%nst, ngkmax, ecutrho *
m_two, &
562 ecutwfc *
m_two, fftgrid, hm%kpoints%nik_axis, hm%kpoints%full%shifts, &
563 ions%latt%rcell_volume,
m_one, ions%latt%rlattice, adot, recvol, &
564 m_one, ions%latt%klattice, bdot, mtrx, tnp, atyp, &
565 apos, ngk, hm%kpoints%reduced%weight, hm%kpoints%reduced%red_point, &
566 ifmin, ifmax, energies, occupations, warn = .false.)
568 call write_binary_gvectors(iunit, shell_density%ngvectors, shell_density%ngvectors, shell_density%red_gvec)
571 end subroutine bgw_write_header
578#include "complex.F90"
579#ifdef HAVE_BERKELEYGW
580#include "output_berkeleygw_inc.F90"
585#ifdef HAVE_BERKELEYGW
586#include "output_berkeleygw_inc.F90"
double sqrt(double __x) __attribute__((__nothrow__
subroutine, public zcube_function_free_rs(cube, cf)
Deallocates the real space grid.
subroutine, public zcube_function_alloc_rs(cube, cf, in_device, force_alloc)
Allocates locally the real space grid, if PFFT library is not used. Otherwise, it assigns the PFFT re...
subroutine, public cube_init(cube, nn, namespace, space, spacing, coord_system, fft_type, fft_library, dont_optimize, nn_out, mpi_grp, need_partition, tp_enlarge, blocksize)
subroutine, public cube_end(cube)
subroutine, public cube_init_cube_map(cube, mesh)
integer, parameter, public spinors
Fast Fourier Transform module. This module provides a single interface that works with different FFT ...
integer, parameter, public fft_complex
real(real64) function, public fourier_shell_cutoff(space, cube, mesh, is_wfn, dg)
subroutine, public fourier_shell_init(this, namespace, space, cube, mesh, kk)
subroutine, public fourier_shell_end(this)
subroutine, public cube_function_free_fs(cube, cf)
Deallocates the Fourier space grid.
subroutine, public cube_function_alloc_fs(cube, cf, force_alloc)
Allocates locally the Fourier space grid, if PFFT library is not used. Otherwise, it assigns the PFFT...
real(real64), parameter, public m_two
real(real64), parameter, public m_zero
real(real64), parameter, public m_pi
some mathematical constants
integer, parameter, public hartree_fock
real(real64), parameter, public m_epsilon
real(real64), parameter, public m_one
integer, parameter, public hartree
This module implements the underlying real-space grid.
subroutine, public io_close(iunit, grp)
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
A module to handle KS potential, without the external potential.
This module defines various routines, operating on mesh functions.
subroutine, public messages_not_implemented(feature, namespace)
subroutine, public messages_warning(no_lines, all_nodes, namespace)
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_experimental(name, namespace)
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
subroutine, public output_berkeleygw(bgw, namespace, space, dir, st, gr, ks, hm, ions)
subroutine, public output_berkeleygw_init(nst, namespace, bgw, periodic_dim)
this module contains the low-level part of the output system
integer function, public parse_block(namespace, name, blk, check_varinfo_)
pure logical function, public states_are_real(st)
This module handles spin dimensions of the states and the k-point distribution.
real(real64) function, dimension(1:this%dim), public symm_op_translation_vector_red(this)
integer function, dimension(1:this%dim, 1:this%dim), public symm_op_rotation_matrix_red(this)
integer pure function, public symmetries_number(this)
logical pure function, public xc_is_orbital_dependent(xcs)
Is the xc family orbital dependent.
subroutine, public xc_get_vxc(gr, xcs, st, kpoints, psolver, namespace, space, rho, ispin, rcell_volume, vxc, ex, ec, deltaxc, vtau, ex_density, ec_density, stress_xc, force_orbitalfree)
Description of the grid, containing information on derivatives, stencil, and symmetries.
Output information for BerkeleyGW.
The states_elec_t class contains all electronic wave functions.