Octopus
xc_interaction.F90
Go to the documentation of this file.
1!! Copyright (C) 2021 Nicolas Tancogne-Dejean
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
22 use comm_oct_m
23 use debug_oct_m
26 use global_oct_m
29 use, intrinsic :: iso_fortran_env
30 use mesh_oct_m
37 use space_oct_m
39 use xc_f03_lib_m
41
42 implicit none
43
44 private
45 public :: &
50
52 private
53
54 contains
55 procedure :: init => xc_interaction_init
56 procedure :: calculate => xc_interaction_calculate
57 procedure :: calculate_energy => xc_interaction_calculate_energy
58 procedure :: end => xc_interaction_end
60 end type xc_interaction_t
61
62 interface xc_interaction_t
63 module procedure xc_interaction_constructor
64 end interface xc_interaction_t
65
66 integer, public, parameter :: &
67 FUNC_X = 1, &
68 func_c = 2
69
70
71contains
72
73 ! ---------------------------------------------------------
74 function xc_interaction_constructor(partner) result(this)
75 class(interaction_partner_t), target, intent(inout) :: partner
76 class(xc_interaction_t), pointer :: this
77
79
80 allocate(this)
81
82 this%label = "exchange-correlation interaction"
83
84 this%partner => partner
85
88
89 ! ---------------------------------------------------------
90 subroutine xc_interaction_init(this)
91 class(xc_interaction_t), intent(inout) :: this
92
93 push_sub(xc_interaction_init)
94
95 pop_sub(xc_interaction_init)
96 end subroutine xc_interaction_init
97
98 ! ---------------------------------------------------------
99 subroutine xc_interaction_calculate(this)
100 class(xc_interaction_t), intent(inout) :: this
101
103
104 this%density = m_zero
105
107 end subroutine xc_interaction_calculate
108
109 ! ---------------------------------------------------------
110 subroutine xc_interaction_calculate_energy(this)
111 class(xc_interaction_t), intent(inout) :: this
112
115 this%energy = m_zero
116
119
120
121 ! ---------------------------------------------------------
122 subroutine xc_interaction_compute(this)
123 class(xc_interaction_t), intent(inout) :: this
124 push_sub(xc_interaction_compute)
125
126 this%density = m_zero
127
129 end subroutine xc_interaction_compute
130
131 ! ---------------------------------------------------------
132 subroutine xc_interaction_end(this)
133 class(xc_interaction_t), intent(inout) :: this
134
135 push_sub(xc_interaction_end)
136
137 safe_deallocate_a(this%density)
138
139 call interaction_end(this)
140
141 pop_sub(xc_interaction_end)
142 end subroutine xc_interaction_end
143
145 ! ---------------------------------------------------------
146 subroutine xc_interaction_finalize(this)
147 type(xc_interaction_t), intent(inout) :: this
154 end subroutine xc_interaction_finalize
155
156 ! -----------------------------------------------------
157 subroutine calc_tb09_c(mesh, space, functl, dens, gdens, ispin, rcell_volume)
158 class(mesh_t), intent(in) :: mesh
159 class(space_t), intent(in) :: space
160 type(xc_functional_t), intent(inout) :: functl(:)
161 real(real64), intent(in) :: dens(:,:)
162 real(real64), intent(in) :: gdens(:,:,:)
163 integer, intent(in) :: ispin
164 real(real64), intent(in) :: rcell_volume
165
166 real(real64), allocatable :: gnon(:)
167 real(real64) :: gn(space%dim), n, parameters(1)
168 integer :: ii
169
170 push_sub(calc_tb09_c)
171
172 safe_allocate(gnon(1:mesh%np))
173
174 do ii = 1, mesh%np
175 if (ispin == unpolarized) then
176 n = dens(ii, 1)
177 gn(1:space%dim) = gdens(ii, 1:space%dim, 1)
178 else
179 n = dens(ii, 1) + dens(ii, 2)
180 gn(1:space%dim) = gdens(ii, 1:space%dim, 1) + gdens(ii, 1:space%dim, 2)
181 end if
182
183 if (n <= 1e-7_real64) then
184 gnon(ii) = m_zero
185 else
186 gnon(ii) = sqrt(sum((gn(1:space%dim)/n)**2))
187 end if
188 end do
189
190 parameters(1) = -0.012_real64 + 1.023_real64*sqrt(dmf_integrate(mesh, gnon)/rcell_volume)
191
192 call xc_f03_func_set_ext_params(functl(1)%conf, parameters)
193
194 safe_deallocate_a(gnon)
195
196 pop_sub(calc_tb09_c)
197 end subroutine calc_tb09_c
198
199 ! ---------------------------------------------------------
200 subroutine calc_mvorb_alpha(mesh, namespace, space, functl, dens, gdens, ispin, rcell_volume, &
201 cam_alpha, cam_beta, cam_omega)
202 class(mesh_t), intent(in) :: mesh
203 type(namespace_t), intent(in) :: namespace
204 class(space_t), intent(in) :: space
205 type(xc_functional_t), intent(inout) :: functl(:)
206 real(real64), intent(in) :: dens(:,:)
207 real(real64), intent(in) :: gdens(:,:,:)
208 integer, intent(in) :: ispin
209 real(real64), intent(in) :: rcell_volume
210 real(real64), intent(inout) :: cam_alpha, cam_beta, cam_omega
211
212 real(real64), allocatable :: gnon(:)
213 real(real64) :: tb09_c, alpha
214 real(real64) :: gn(space%dim), n
215 integer :: ii
216 real(real64) :: parameters(3)
217
218 push_sub(calc_mvorb_alpha)
219
220 safe_allocate(gnon(1:mesh%np))
221
222 do ii = 1, mesh%np
223 if (ispin == unpolarized) then
224 n = dens(ii, 1)
225 gn(1:space%dim) = gdens(ii, 1:space%dim, 1)
226 else
227 n = dens(ii, 1) + dens(ii, 2)
228 gn(1:space%dim) = gdens(ii, 1:space%dim, 1) + gdens(ii, 1:space%dim, 2)
229 end if
230
231 if (n <= 1e-7_real64) then
232 gnon(ii) = m_zero
233 else
234 gnon(ii) = sqrt(sum((gn(1:space%dim)/n)**2))
235 gnon(ii) = sqrt(gnon(ii))
236 end if
237 end do
238
239 tb09_c = dmf_integrate(mesh, gnon)/rcell_volume
240
241 safe_deallocate_a(gnon)
242
243 select case (functl(func_c)%id)
245 alpha = 0.121983_real64+0.130711_real64*tb09_c**4
246
247 if (alpha > 1) then
248 write(message(1), '(a,f6.3,a)') 'MVORB mixing parameter bigger than one (' , alpha ,').'
249 call messages_warning(1, namespace=namespace)
250 alpha = 0.25_real64
251 end if
252
253
254 parameters(1) = alpha
255 parameters(2) = cam_omega
256 parameters(3) = cam_omega
257 call xc_f03_func_set_ext_params(functl(func_c)%conf, parameters)
258 !The name is confusing. Here alpha is the beta of hybrids in functionals,
259 !but is called alpha in the original paper.
260 cam_beta = alpha
261
263 alpha = -1.00778_real64+1.10507_real64*tb09_c
264
265 if (alpha > 1) then
266 write(message(1), '(a,f6.3,a)') 'MVORB mixing parameter bigger than one (' , alpha ,').'
267 call messages_warning(1, namespace=namespace)
268 alpha = 0.25_real64
269 end if
270 if (alpha < 0) then
271 write(message(1), '(a,f6.3,a)') 'MVORB mixing parameter smaller than zero (' , alpha ,').'
272 call messages_warning(1, namespace=namespace)
273 alpha = 0.25_real64
274 end if
275
276 parameters(1) = alpha
277 call xc_f03_func_set_ext_params(functl(func_c)%conf, parameters)
278 cam_alpha = alpha
279 case default
280 call messages_not_implemented("MVORB density-based mixing for functionals other than PBE0 and HSE06", namespace=namespace)
281 end select
282
283 pop_sub(calc_mvorb_alpha)
284 end subroutine calc_mvorb_alpha
285
286
287end module xc_interaction_oct_m
288
289!! Local Variables:
290!! mode: f90
291!! coding: utf-8
292!! End:
double sqrt(double __x) __attribute__((__nothrow__
integer, parameter, public unpolarized
Parameters...
real(real64), parameter, public m_zero
Definition: global.F90:187
This module defines the abstract interaction_t class, and some auxiliary classes for interactions.
subroutine, public interaction_end(this)
This module defines classes and functions for interaction partners.
This module defines various routines, operating on mesh functions.
real(real64) function, public dmf_integrate(mesh, ff, mask, reduce)
Integrate a function on the mesh.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:118
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1125
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:543
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:160
This module defines the quantity_t class and the IDs for quantities, which can be exposed by a system...
Definition: quantity.F90:137
This module handles spin dimensions of the states and the k-point distribution.
integer, parameter, public xc_hyb_gga_xc_mvorb_pbeh
Density-based mixing parameter of PBE0.
integer, parameter, public xc_hyb_gga_xc_mvorb_hse06
Density-based mixing parameter of HSE06.
subroutine xc_interaction_finalize(this)
class(xc_interaction_t) function, pointer xc_interaction_constructor(partner)
subroutine, public calc_mvorb_alpha(mesh, namespace, space, functl, dens, gdens, ispin, rcell_volume, cam_alpha, cam_beta, cam_omega)
subroutine, public xc_interaction_compute(this)
subroutine xc_interaction_end(this)
subroutine, public calc_tb09_c(mesh, space, functl, dens, gdens, ispin, rcell_volume)
integer, parameter, public func_c
subroutine xc_interaction_init(this)
subroutine xc_interaction_calculate(this)
subroutine xc_interaction_calculate_energy(this)
Describes mesh distribution to nodes.
Definition: mesh.F90:186