Octopus
elf.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2011 M. Marques, A. Castro, A. Rubio, G. Bertsch, M. Oliveira
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
21module elf_oct_m
22 use debug_oct_m
26 use global_oct_m
27 use grid_oct_m
28 use, intrinsic :: iso_fortran_env
30 use mesh_oct_m
33 use parser_oct_m
35 use space_oct_m
38
39 implicit none
40
41 private
42 public :: &
43 elf_init, &
45
46 logical :: with_current_term = .true.
47
48contains
49
50 subroutine elf_init(namespace)
51 type(namespace_t), intent(in) :: namespace
52
53 push_sub(elf_init)
54
55 !%Variable ELFWithCurrentTerm
56 !%Type logical
57 !%Default true
58 !%Section Output
59 !%Description
60 !% The ELF, when calculated for complex wavefunctions, should contain
61 !% a term dependent on the current. This term is properly calculated by
62 !% default; however, for research purposes it may be useful not to add it.
63 !% If this feature proves to be useless, this option should go away.
64 !%End
65 call parse_variable(namespace, 'ELFWithCurrentTerm', .true., with_current_term)
66
67 pop_sub(elf_init)
68 end subroutine elf_init
69
70 ! ---------------------------------------------------------
72 ! ---------------------------------------------------------
73 subroutine elf_calc(space, st, gr, kpoints, elf, de)
74 class(space_t), intent(in) :: space
75 type(states_elec_t), intent(inout) :: st
76 type(grid_t), intent(in) :: gr
77 type(kpoints_t), intent(in) :: kpoints
82 real(real64), intent(inout) :: elf(:,:)
83 real(real64), optional, intent(inout):: de(:,:)
84
85 real(real64) :: factor, D0, dens
86 integer :: ip, is, nelfs
87 real(real64), allocatable :: rho(:,:), grho(:,:,:), jj(:,:,:)
88 real(real64), allocatable :: kappa(:,:)
89 real(real64), parameter :: dmin = 1e-10_real64
90
91 push_sub(elf_calc)
92
93 assert(space%dim == 2 .or. space%dim == 3)
94
95 ! We may or may not want the total ELF.
96 ! If we want it, the argument elf should have three components.
97 nelfs = size(elf, 2)
98
99 safe_allocate( rho(1:gr%np, 1:st%d%nspin))
100 safe_allocate(kappa(1:gr%np, 1:st%d%nspin))
101 rho = m_zero
102 kappa = m_zero
103 call density_calc(st, gr, rho)
104
105 safe_allocate(grho(1:gr%np, 1:space%dim, 1:st%d%nspin))
106 safe_allocate( jj(1:gr%np, 1:space%dim, 1:st%d%nspin))
107
108 call states_elec_calc_quantities(gr, st, kpoints, .false., kinetic_energy_density = kappa, &
109 paramagnetic_current = jj, density_gradient = grho)
110
111 ! spin-dependent quantities
112 if (st%d%ispin == unpolarized) then
113 rho = rho/m_two
114 kappa = kappa/m_two
115 jj = jj/m_two
116 grho = grho/m_two
117 end if
118
119 if (.not. with_current_term) jj = m_zero
120
121 ! kappa will contain rho * D
122 do_is: do is = 1, st%d%nspin
123 do ip = 1, gr%np
124 kappa(ip, is) = kappa(ip, is)*rho(ip, is) & ! + tau * rho
125 - m_fourth*sum(grho(ip, 1:space%dim, is)**2) & ! - | nabla rho |^2 / 4
126 - sum(jj(ip, 1:space%dim, is)**2) ! - j^2
127 end do
128
129 ! pass this information to the caller if requested
130 if (present(de)) de(1:gr%np,is) = kappa(1:gr%np,is)
131
132 end do do_is
133
134 safe_deallocate_a(grho)
135 safe_deallocate_a(jj) ! these are no longer needed
136
137 select case (space%dim)
138 case (3)
139 factor = m_three / m_five * (6.0_real64 * m_pi**2)**m_twothird
140 case (2)
141 factor = m_two * m_pi
142 end select
144 select case (st%d%ispin)
145 case (unpolarized)
146 do ip = 1, gr%np
147 if (rho(ip, 1) >= dmin) then
148 select case (space%dim)
149 case (3)
150 d0 = factor * rho(ip, 1)**(8.0_real64 / m_three)
151 case (2)
152 d0 = factor * rho(ip, 1)**3
153 end select
154 elf(ip, 1) = d0 * d0 / (d0 * d0 + kappa(ip, 1)**2)
155 else
156 elf(ip, 1) = m_zero
157 end if
158 end do
159
160 case (spin_polarized, spinors)
161 if (nelfs == 3) then
162 do ip = 1, gr%np
163 dens = rho(ip, 1) + rho(ip, 2)
164 if (dens >= dmin) then
165 select case (space%dim)
166 case (3)
167 d0 = factor * dens ** (m_five/m_three) * rho(ip, 1) * rho(ip, 2)
168 case (2)
169 d0 = factor * dens ** 2 * rho(ip, 1) * rho(ip, 2)
170 end select
171 elf(ip, 3) = d0 * d0 / (d0 * d0 + (kappa(ip, 1) * rho(ip, 2) + kappa(ip,2) * rho(ip, 1))**2)
172 else
173 elf(ip, 3) = m_zero
174 end if
175 end do
176 end if
177 do ip = 1, gr%np
178 do is = 1, st%d%spin_channels
179 if (rho(ip, is) >= dmin) then
180 select case (space%dim)
181 case (3)
182 d0 = factor * rho(ip, is)**(8.0_real64/m_three)
183 case (2)
184 d0 = factor * rho(ip, is)**3
185 end select
186 elf(ip, is) = d0 * d0 / (d0 * d0 + kappa(ip,is)**2)
187 else
188 elf(ip, is) = m_zero
189 end if
190 end do
191 end do
192 end select
193
194 safe_deallocate_a(rho)
195 safe_deallocate_a(kappa)
196
197 pop_sub(elf_calc)
198 end subroutine elf_calc
199
200end module elf_oct_m
201
202!! Local Variables:
203!! mode: f90
204!! coding: utf-8
205!! End:
This module implements a calculator for the density and defines related functions.
Definition: density.F90:120
subroutine, public density_calc(st, gr, density, istin)
Computes the density from the orbitals in st.
Definition: density.F90:608
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
integer, parameter, public unpolarized
Parameters...
integer, parameter, public spinors
integer, parameter, public spin_polarized
subroutine, public elf_calc(space, st, gr, kpoints, elf, de)
(time-dependent) electron localization function, (TD)ELF.
Definition: elf.F90:167
subroutine, public elf_init(namespace)
Definition: elf.F90:144
real(real64), parameter, public m_two
Definition: global.F90:189
real(real64), parameter, public m_zero
Definition: global.F90:187
real(real64), parameter, public m_pi
some mathematical constants
Definition: global.F90:185
real(real64), parameter, public m_fourth
Definition: global.F90:196
real(real64), parameter, public m_twothird
Definition: global.F90:195
real(real64), parameter, public m_three
Definition: global.F90:190
real(real64), parameter, public m_five
Definition: global.F90:192
This module implements the underlying real-space grid.
Definition: grid.F90:117
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:118
This module handles spin dimensions of the states and the k-point distribution.
subroutine, public states_elec_calc_quantities(gr, st, kpoints, nlcc, kinetic_energy_density, paramagnetic_current, density_gradient, density_laplacian, gi_kinetic_energy_density, st_end)
calculated selected quantities
int true(void)