Octopus
v_ks_photon.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
31 use debug_oct_m
33 use global_oct_m
34 use grid_oct_m
36 use ions_oct_m
38 use, intrinsic :: iso_fortran_env
43 use parser_oct_m
49 use space_oct_m
53 use xc_oct_m
54 use xc_f03_lib_m
57 use xc_oep_oct_m
60
61 implicit none
62
63 private
64 public :: v_ks_photon_t
65
71 type v_ks_photon_t
72 private
73 integer :: xc_photon = 0
74 type(xc_photons_t) :: xc_photons
75 type(xc_oep_photon_t) :: oep_photon
76 logical :: has_photons = .false.
77 logical :: include_hartree = .true.
78 type(photon_mode_t), pointer :: pt => null()
79 type(mf_t) :: pt_mx
80 contains
81 procedure :: init => v_ks_photon_init
82 procedure :: init_xc => v_ks_photon_init_xc
83 procedure :: setup => v_ks_photon_setup
84 procedure :: end => v_ks_photon_end
85 procedure :: mf_calc => v_ks_photon_mf_calc
86 procedure :: add_px => v_ks_photon_add_px
87 procedure :: oep_calc => v_ks_photon_oep_calc
88 procedure :: add_mf_potential => v_ks_photon_add_mf_potential
89 procedure :: add_mean_field => v_ks_photon_add_mean_field
90 procedure :: restart_dump => v_ks_photon_restart_dump
91 procedure :: restart_load => v_ks_photon_restart_load
92 procedure :: write_info => v_ks_photon_write_info
93 procedure :: active => v_ks_photon_active
94 procedure :: set_active => v_ks_photon_set_active
95 procedure :: functional => v_ks_photon_functional
96 procedure :: includes_hartree => v_ks_photon_include_hartree
97 procedure :: nmodes => v_ks_photon_nmodes
98 procedure :: oep_full => v_ks_photon_oep_full
99 procedure :: correlator => v_ks_photon_correlator
100 procedure :: get_pt_mx => v_ks_photon_get_pt_mx
101 procedure :: get_xc_photons => v_ks_photon_get_xc_photons
102 end type v_ks_photon_t
103
104contains
105
106 ! ---------------------------------------------------------
108 subroutine v_ks_photon_init(this, namespace)
109 class(v_ks_photon_t), intent(inout) :: this
110 type(namespace_t), intent(in) :: namespace
111
112 push_sub(v_ks_photon_init)
113
114 this%oep_photon%level = oep_level_none
115
116 !%Variable XCPhotonFunctional
117 !%Type integer
118 !%Default 0
119 !%Section Hamiltonian::XC
120 !%Description
121 !% Defines the exchange and correlation functionals to be used for the QEDFT
122 !% description of the electron-photon system.
123 !%Option none 0
124 !% No functional is used
125 !%Option photon_x_lda 10
126 !% Exchange-only local density approcimation
127 !%Option photon_xc_lda 11
128 !% Exchange-correlation local density approcimation
129 !%Option photon_x_wfn 20
130 !% Exchange-only based on wave functions
131 !%Option photon_xc_wfn 21
132 !% Exchange-correlation based on wave functions
133 !%End
134 call parse_variable(namespace, 'XCPhotonFunctional', option__xcphotonfunctional__none, this%xc_photon)
135
136 !%Variable XCPhotonIncludeHartree
137 !%Type logical
138 !%Default yes
139 !%Section Hamiltonian::XC
140 !%Description
141 !% Use the Hartree potential and energy in calculations
142 !%End
143 call parse_variable(namespace, 'XCPhotonIncludeHartree', .true., this%include_hartree)
144
145 if (.not. this%include_hartree) then
146 call messages_write('turn off hartree potential and energy')
147 call messages_warning(namespace=namespace)
148 end if
149
150 pop_sub(v_ks_photon_init)
151 end subroutine v_ks_photon_init
152
153 ! ---------------------------------------------------------
155 subroutine v_ks_photon_init_xc(this, namespace, space, gr, st)
156 class(v_ks_photon_t), intent(inout) :: this
157 type(namespace_t), intent(in) :: namespace
158 class(space_t), intent(in) :: space
159 type(grid_t), intent(in) :: gr
160 type(states_elec_t), intent(in) :: st
161
162 push_sub(v_ks_photon_init_xc)
163
164 if (this%xc_photon /= 0) then
165 ! initialize the photon free variables
166 call this%xc_photons%init(namespace, this%xc_photon, space, gr, st)
167 this%oep_photon%level = oep_level_none
168 end if
171 end subroutine v_ks_photon_init_xc
173 ! ---------------------------------------------------------
175 subroutine v_ks_photon_setup(this, namespace, modes, gr, st, ions, mc, space, xc, xc_family, oep_level)
176 class(v_ks_photon_t), intent(inout) :: this
177 type(namespace_t), intent(in) :: namespace
178 type(photon_mode_t), target, intent(inout) :: modes
179 type(grid_t), intent(inout) :: gr
180 type(states_elec_t), intent(in) :: st
181 type(ions_t), intent(in) :: ions
182 type(multicomm_t), intent(in) :: mc
183 class(space_t), intent(in) :: space
184 type(xc_t), intent(in) :: xc
185 integer, intent(in) :: xc_family
186 integer, intent(in) :: oep_level
190 this%pt => modes
191 ! Temporary creation that should go in the system initialization later
192 call photon_mode_set_n_electrons(modes, st%qtot)
193 write(message(1), '(a,i5,a)') 'Happy to have ', modes%nmodes, ' photon modes with us.'
195 call mf_init(this%pt_mx, gr, st, ions, this%pt)
196 ! OEP for photons
197 if (bitand(xc_family, xc_family_oep) /= 0 .and. xc%functional(func_x, 1)%id == xc_oep_x) then
198 this%oep_photon%level = oep_level
199 call xc_oep_photon_init(this%oep_photon, namespace, xc_family, gr, st, mc, space)
200 else
201 this%oep_photon%level = oep_level_none
202 end if
204 pop_sub(v_ks_photon_setup)
205 end subroutine v_ks_photon_setup
206
207 ! ---------------------------------------------------------
209 subroutine v_ks_photon_end(this)
210 class(v_ks_photon_t), intent(inout) :: this
211
212 push_sub(v_ks_photon_end)
213
214 call xc_oep_photon_end(this%oep_photon)
215 if (this%has_photons) then
216 call mf_end(this%pt_mx)
217 end if
218 if (this%xc_photon /= 0) then
219 call this%xc_photons%end()
220 end if
221
222 pop_sub(v_ks_photon_end)
223 end subroutine v_ks_photon_end
224
225 ! ---------------------------------------------------------
227 subroutine v_ks_photon_mf_calc(this, gr, st, ions, time)
228 class(v_ks_photon_t), intent(inout) :: this
229 type(grid_t), intent(inout) :: gr
230 type(states_elec_t), intent(inout) :: st
231 type(ions_t), intent(in) :: ions
232 real(real64), intent(in) :: time
233
234 push_sub(v_ks_photon_mf_calc)
235
236 call mf_calc(this%pt_mx, gr, st, ions, this%pt, time)
237
238 pop_sub(v_ks_photon_mf_calc)
239 end subroutine v_ks_photon_mf_calc
240
241 ! ---------------------------------------------------------
243 subroutine v_ks_photon_add_px(this, namespace, total_density, gr, space, psolver, st, spin_channels, vxc, e_photon_exchange)
244 class(v_ks_photon_t), intent(inout) :: this
245 type(namespace_t), intent(in) :: namespace
246 real(real64), pointer, contiguous, intent(in) :: total_density(:)
247 type(grid_t), intent(in) :: gr
248 class(space_t), intent(in) :: space
249 type(poisson_t), intent(in) :: psolver
250 type(states_elec_t), intent(inout) :: st
251 integer, intent(in) :: spin_channels
252 real(real64), intent(inout) :: vxc(:, :)
253 real(real64), intent(out) :: e_photon_exchange
254
255 integer :: ispin
256
257 push_sub(v_ks_photon_add_px)
258
259 call this%xc_photons%v_ks(namespace, total_density, gr, space, psolver, st)
260
261 ! add the photon-free px potential into the xc potential
262 do ispin = 1, spin_channels
263 call lalg_axpy(gr%np, m_one, this%xc_photons%vpx(1:gr%np), vxc(1:gr%np, ispin))
264 end do
265
266 ! photon-exchange energy
267 e_photon_exchange = this%xc_photons%ex
268
269 pop_sub(v_ks_photon_add_px)
270 end subroutine v_ks_photon_add_px
271
272 ! ---------------------------------------------------------
277 subroutine v_ks_photon_oep_calc(this, namespace, xc, gr, hm, st, space, vxc)
278 class(v_ks_photon_t), intent(inout) :: this
279 type(namespace_t), intent(in) :: namespace
280 type(xc_t), intent(inout) :: xc
281 type(grid_t), intent(in) :: gr
282 type(hamiltonian_elec_t), intent(inout) :: hm
283 type(states_elec_t), intent(inout) :: st
284 class(space_t), intent(in) :: space
285 real(real64), contiguous, intent(inout) :: vxc(:, :)
286
287 push_sub(v_ks_photon_oep_calc)
288
289 if (this%oep_photon%level /= oep_level_none) then
290 if (states_are_real(st)) then
291 call dxc_oep_photon_calc(this%oep_photon, namespace, xc, gr, &
292 hm, st, space, hm%energy%exchange, hm%energy%correlation, vxc = vxc)
293 else
294 call zxc_oep_photon_calc(this%oep_photon, namespace, xc, gr, &
295 hm, st, space, hm%energy%exchange, hm%energy%correlation, vxc = vxc)
296 end if
297 hm%energy%photon_exchange = this%oep_photon%pt%ex
298 end if
299
300 pop_sub(v_ks_photon_oep_calc)
301 end subroutine v_ks_photon_oep_calc
302
303 ! ---------------------------------------------------------
305 subroutine v_ks_photon_add_mf_potential(this, gr, vhxc, ispin, photon_forces)
306 class(v_ks_photon_t), intent(in) :: this
307 type(grid_t), intent(in) :: gr
308 real(real64), intent(inout) :: vhxc(:, :)
309 integer, intent(in) :: ispin
310 real(real64), intent(out) :: photon_forces(:)
311
313
314 if (associated(this%pt_mx%vmf)) then
315 call lalg_axpy(gr%np, m_one, this%pt_mx%vmf, vhxc(:, 1))
316 if (ispin > unpolarized) then
317 call lalg_axpy(gr%np, m_one, this%pt_mx%vmf, vhxc(:, 2))
318 end if
319 end if
320 photon_forces(:) = this%pt_mx%fmf(1:size(photon_forces))
321
323 end subroutine v_ks_photon_add_mf_potential
324
325 ! ---------------------------------------------------------
327 subroutine v_ks_photon_add_mean_field(this, gr, space, kpoints, st, time, dt)
328 class(v_ks_photon_t), intent(inout) :: this
329 type(grid_t), intent(in) :: gr
330 class(space_t), intent(in) :: space
331 type(kpoints_t), intent(in) :: kpoints
332 type(states_elec_t), intent(inout) :: st
333 real(real64), intent(in) :: time
334 real(real64), intent(in) :: dt
335
337
338 if (this%xc_photon /= 0) then
339 call this%xc_photons%add_mean_field(gr, space, kpoints, st, time, dt)
340 end if
341
343 end subroutine v_ks_photon_add_mean_field
344
345 ! ---------------------------------------------------------
347 subroutine v_ks_photon_restart_dump(this, restart, gr, dt, ierr)
348 class(v_ks_photon_t), intent(in) :: this
349 type(restart_t), intent(in) :: restart
350 type(grid_t), intent(in) :: gr
351 real(real64), intent(in) :: dt
352 integer, intent(inout) :: ierr
353
354 integer :: err
355
357
358 if (this%has_photons) then
359 call mf_photons_dump(restart, this%pt_mx, gr, dt, this%pt, err)
360 if (err /= 0) ierr = ierr + 16
361 end if
362 if (this%xc_photon /= 0) then
363 ! photon-free mean field
364 call this%xc_photons%mf_dump(restart, err)
365 if (err /= 0) ierr = ierr + 32
366 end if
367
369 end subroutine v_ks_photon_restart_dump
370
371 ! ---------------------------------------------------------
373 subroutine v_ks_photon_restart_load(this, restart, gr, space, ierr)
374 class(v_ks_photon_t), intent(inout) :: this
375 type(restart_t), intent(in) :: restart
376 type(grid_t), intent(in) :: gr
377 class(space_t), intent(in) :: space
378 integer, intent(inout) :: ierr
379
380 integer :: err
381
383
384 if (this%has_photons) then
385 call mf_photons_load(restart, this%pt_mx, gr, err)
386 if (err /= 0) ierr = ierr + 16
387 end if
388 if (this%xc_photon /= 0) then
389 call this%xc_photons%mf_load(restart, space, err)
390 if (err /= 0) ierr = ierr + 32
391 end if
392
394 end subroutine v_ks_photon_restart_load
395
396 ! ---------------------------------------------------------
398 subroutine v_ks_photon_write_info(this, iunit)
399 class(v_ks_photon_t), intent(in) :: this
400 integer, intent(in) :: iunit
401
402 push_sub(v_ks_photon_write_info)
403
404 if (this%oep_photon%level == oep_level_full .or. this%oep_photon%level == oep_level_kli) then
405 write(iunit, '(a)') 'Photon observables:'
406 write(iunit, '(6x, a, es15.8,a,es15.8,a)') 'Photon number = ', this%oep_photon%pt%number(1)
407 write(iunit, '(6x, a, es15.8,a,es15.8,a)') 'Photon ex. = ', this%oep_photon%pt%ex
408 write(iunit, '(1x)')
409 end if
410
412 end subroutine v_ks_photon_write_info
413
414 ! ---------------------------------------------------------
416 logical pure function v_ks_photon_active(this)
417 class(v_ks_photon_t), intent(in) :: this
418 v_ks_photon_active = this%has_photons
419 end function v_ks_photon_active
420
421 ! ---------------------------------------------------------
423 subroutine v_ks_photon_set_active(this, val)
424 class(v_ks_photon_t), intent(inout) :: this
425 logical, intent(in) :: val
426 this%has_photons = val
427 end subroutine v_ks_photon_set_active
428
429 ! ---------------------------------------------------------
431 integer pure function v_ks_photon_functional(this)
432 class(v_ks_photon_t), intent(in) :: this
433 v_ks_photon_functional = this%xc_photon
434 end function v_ks_photon_functional
435
436 ! ---------------------------------------------------------
438 logical pure function v_ks_photon_include_hartree(this)
439 class(v_ks_photon_t), intent(in) :: this
440 v_ks_photon_include_hartree = this%include_hartree
441 end function v_ks_photon_include_hartree
443 ! ---------------------------------------------------------
445 integer pure function v_ks_photon_nmodes(this)
446 class(v_ks_photon_t), intent(in) :: this
447 v_ks_photon_nmodes = this%pt%nmodes
448 end function v_ks_photon_nmodes
449
450 ! ---------------------------------------------------------
452 logical pure function v_ks_photon_oep_full(this)
453 class(v_ks_photon_t), intent(in) :: this
454 v_ks_photon_oep_full = (this%oep_photon%level == oep_level_full)
455 end function v_ks_photon_oep_full
456
457 ! ---------------------------------------------------------
459 function v_ks_photon_correlator(this) result(corr)
460 class(v_ks_photon_t), target, intent(in) :: this
461 real(real64), pointer :: corr(:)
462 corr => this%oep_photon%pt%correlator(:, 1)
463 end function v_ks_photon_correlator
464
465 ! ---------------------------------------------------------
467 function v_ks_photon_get_pt_mx(this) result(pt_mx)
468 class(v_ks_photon_t), target, intent(in) :: this
469 type(mf_t), pointer :: pt_mx
470 pt_mx => this%pt_mx
471 end function v_ks_photon_get_pt_mx
472
473 ! ---------------------------------------------------------
475 function v_ks_photon_get_xc_photons(this) result(xcp)
476 class(v_ks_photon_t), target, intent(in) :: this
477 type(xc_photons_t), pointer :: xcp
478 xcp => this%xc_photons
479 end function v_ks_photon_get_xc_photons
480
481end module v_ks_photon_oct_m
482
483!! Local Variables:
484!! mode: f90
485!! coding: utf-8
486!! End:
constant times a vector plus a vector
Definition: lalg_basic.F90:173
integer, parameter, public unpolarized
Parameters...
real(real64), parameter, public m_one
Definition: global.F90:201
This module implements the underlying real-space grid.
Definition: grid.F90:119
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:525
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
subroutine, public mf_photons_load(restart, this, gr, ierr)
subroutine, public mf_init(this, gr, st, ions, pt_mode)
subroutine, public mf_photons_dump(restart, this, gr, dt, pt_mode, ierr)
subroutine, public mf_end(this)
subroutine, public mf_calc(this, gr, st, ions, pt_mode, time)
subroutine, public photon_mode_set_n_electrons(this, qtot)
pure logical function, public states_are_real(st)
This module handles spin dimensions of the states and the k-point distribution.
QEDFT / electron-photon (cavity) extension of the Kohn-Sham potential.
type(xc_photons_t) function, pointer v_ks_photon_get_xc_photons(this)
Pointer to the photon-free exchange object.
type(mf_t) function, pointer v_ks_photon_get_pt_mx(this)
Pointer to the mean-field photon object (for time-dependent output).
real(real64) function, dimension(:), pointer v_ks_photon_correlator(this)
Pointer to the photon correlator (for output).
subroutine v_ks_photon_oep_calc(this, namespace, xc, gr, hm, st, space, vxc)
Compute the photon OEP potential/energy contribution.
subroutine v_ks_photon_set_active(this, val)
Enable/disable photons (set before v_ks_init).
subroutine v_ks_photon_add_px(this, namespace, total_density, gr, space, psolver, st, spin_channels, vxc, e_photon_exchange)
Add the photon-free photon-exchange potential to vxc and return its energy.
integer pure function v_ks_photon_functional(this)
The selected QEDFT functional (0 = none).
subroutine v_ks_photon_end(this)
Finalize all photon objects.
subroutine v_ks_photon_add_mean_field(this, gr, space, kpoints, st, time, dt)
Add the photon mean field to the paramagnetic-current integral (time propagation).
subroutine v_ks_photon_mf_calc(this, gr, st, ions, time)
Update the mean-field photon quantities (time-dependent run, mean-field QEDFT).
subroutine v_ks_photon_add_mf_potential(this, gr, vhxc, ispin, photon_forces)
Add the mean-field photon potential to vhxc and set the photon forces.
subroutine v_ks_photon_init_xc(this, namespace, space, gr, st)
Initialize the photon-free exchange object when a QEDFT functional is selected.
subroutine v_ks_photon_setup(this, namespace, modes, gr, st, ions, mc, space, xc, xc_family, oep_level)
Set up the photon modes, mean-field object and photon OEP (called after v_ks_init).
integer pure function v_ks_photon_nmodes(this)
Number of photon modes.
subroutine v_ks_photon_restart_dump(this, restart, gr, dt, ierr)
Dump photon restart data; error bits added to ierr (16: mean field, 32: photon-free).
logical pure function v_ks_photon_oep_full(this)
Whether the photon OEP is at the FULL level (controls correlator output).
logical pure function v_ks_photon_active(this)
Whether photons are enabled in this v_ks.
subroutine v_ks_photon_init(this, namespace)
Parse the QEDFT input variables and set photon defaults.
subroutine v_ks_photon_restart_load(this, restart, gr, space, ierr)
Load photon restart data; error bits added to ierr (16: mean field, 32: photon-free).
subroutine v_ks_photon_write_info(this, iunit)
Write the photon observables (number, exchange) to the SCF info output.
logical pure function v_ks_photon_include_hartree(this)
Whether to include the Hartree term (QEDFT).
integer, parameter, public xc_oep_x
Exact exchange.
integer, parameter, public func_x
Definition: xc.F90:120
integer, parameter, public oep_level_none
the OEP levels
Definition: xc_oep.F90:174
integer, parameter, public oep_level_full
Definition: xc_oep.F90:174
integer, parameter, public oep_level_kli
Definition: xc_oep.F90:174
subroutine, public zxc_oep_photon_calc(oep, namespace, xcs, gr, hm, st, space, ex, ec, vxc)
This file handles the evaluation of the OEP potential, in the KLI or full OEP as described in S....
subroutine, public xc_oep_photon_init(oep, namespace, family, gr, st, mc, space)
subroutine, public xc_oep_photon_end(oep)
subroutine, public dxc_oep_photon_calc(oep, namespace, xcs, gr, hm, st, space, ex, ec, vxc)
This file handles the evaluation of the OEP potential, in the KLI or full OEP as described in S....
This module implements the "photon-free" electron-photon exchange-correlation functional.
Definition: xc_photons.F90:123
Description of the grid, containing information on derivatives, stencil, and symmetries.
Definition: grid.F90:171
Stores all communicators and groups.
Definition: multicomm.F90:208
The states_elec_t class contains all electronic wave functions.
Photon (QEDFT) part of v_ks_t.
int true(void)