Octopus
zora.F90
Go to the documentation of this file.
1!! Copyright (C) 2023 L. Konecny, M. Lueders
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
23module zora_oct_m
24
25 use batch_oct_m
27 use debug_oct_m
29 use epot_oct_m
30 use global_oct_m
31 use grid_oct_m
33 use mesh_oct_m
39
40 implicit none
41
42 private
43 public :: zora_t
44
45 integer, parameter, public :: &
46 ZORA_NONE = 0, & !< no ZORA
49
51 !
52 type :: zora_t
53 private
54
55 real(real64), allocatable :: pot(:,:)
56 real(real64), allocatable :: grad_pot(:,:,:)
57 ! !! \f$ \nabla ( \frac{c^2}{2c^2 - V} ) \f$
58 real(real64), allocatable :: soc(:,:,:)
59 ! !! \f$ {\rm zora\%pref} * (\sigma \times {\nabla V}) \cdot p \f$
60
61 real(real64) :: so_strength = m_zero
62 real(real64) :: mass = m_zero
63
64 integer :: zora_level = zora_none
65
66 contains
67 procedure :: update => zora_update
68 procedure :: dapply_batch => dzora_apply_batch
69 procedure :: zapply_batch => zzora_apply_batch
70 final :: zora_finalize
71 end type
72
73 interface zora_t
74 procedure zora_constructor
75 end interface zora_t
76
77contains
78
82 !
83 function zora_constructor(namespace, der, st_d, ep, mass) result(this)
84 type(namespace_t), intent(in) :: namespace
85 type(derivatives_t), intent(in) :: der
86 type(states_elec_dim_t), intent(in) :: st_d
87 type(epot_t), intent(in) :: ep
88 real(real64), intent(in) :: mass
89 class(zora_t), pointer :: this
90
91 push_sub(zora_constructor)
92 safe_allocate(this)
93
94
95 this%so_strength = ep%so_strength
96 this%mass = mass
97
98 select case (ep%reltype)
100 this%zora_level = zora_scalar_relativistic
102 this%zora_level = zora_fully_relativistic
103 case default
104 this%zora_level = zora_none
105 pop_sub(zora_constructor)
106 return
107 end select
108
109 if (der%dim /= 3) then
110 call messages_not_implemented("ZORA for dimensions /= 3", namespace)
111 end if
112
113 safe_allocate(this%pot(1:der%mesh%np_part, 1:st_d%nspin))
114 safe_allocate(this%grad_pot(1:der%mesh%np, 1:st_d%nspin, 1:der%dim))
115
116 if(this%zora_level == zora_fully_relativistic) then
117
118 assert(st_d%nspin == 4)
119 safe_allocate(this%soc(1:der%mesh%np, 1:st_d%nspin, 1:der%dim))
120
121 end if
122
123 pop_sub(zora_constructor)
124 end function zora_constructor
125
126
128 subroutine zora_finalize(this)
129 type(zora_t), intent(inout) :: this
130
131 push_sub(zora_finalize)
132
133 safe_deallocate_a(this%pot)
134 safe_deallocate_a(this%grad_pot)
135 safe_deallocate_a(this%soc)
136
137 pop_sub(zora_finalize)
138 end subroutine zora_finalize
139
160 subroutine zora_update(this, der, potential)
161 class(zora_t), intent(inout) :: this
162 class(derivatives_t), intent(in) :: der
163 real(real64), contiguous, intent(in) :: potential(:, :)
165 real(real64), allocatable :: zora_scpot(:), grad_pot(:,:)
166 real(real64) :: prefactor, two_c2
167
168 integer :: ip, idir
169 integer :: nspin
170
171 push_sub(zora_update)
172
173 if (this%zora_level == zora_none) then
174 pop_sub(zora_update)
175 return
176 end if
177
178 nspin = size(this%pot, dim=2)
179 two_c2 = m_two * p_c**2
180
181 ! We need to copy the potential to an array, allocated to np_part for the application of the derivatives.
182
183 safe_allocate( zora_scpot(1:der%mesh%np_part) )
184 safe_allocate( grad_pot(1:der%mesh%np_part, 1:der%dim) )
185
186 !$omp parallel private(ip)
187 !$omp do simd schedule(static)
188 do ip = 1, der%mesh%np
189 ! zora_scpot = V
190 zora_scpot(ip) = potential(ip, 1)
191 ! zora_pot = \frac{c^2}{2 m c^2 - V}
192 ! included extra factor of 2 because of -1/2 in kinetic energy
193 this%pot(ip,1) = two_c2 / (this%mass * two_c2 - zora_scpot(ip) )
194 end do
195 !$omp end do simd
196
197 if (nspin > 1) then
198 !$omp do simd schedule(static)
199 do ip = 1, der%mesh%np
200 this%pot(ip,2) = this%pot(ip,1)
201 end do
202 !$omp end do simd
203 end if
204 if (nspin > 2) then
205 !$omp do simd schedule(static)
206 do ip = 1, der%mesh%np
207 this%pot(ip,3) = m_zero
208 this%pot(ip,4) = m_zero
209 end do
210 !$omp end do simd
211 end if
212 !$omp end parallel
213
214 ! zora_grad_pot = grad( \frac{c^2}{2 m c^2 - V} )
215
216 call dderivatives_grad(der, this%pot(:,1), grad_pot)
217
218 do idir=1, der%dim
219 !$omp parallel private(ip)
220 !$omp do simd schedule(static)
221 do ip = 1, der%mesh%np
222 this%grad_pot(ip, 1, idir)= grad_pot(ip,idir)
223 end do
224 !$omp end do simd
225
226 if (nspin > 1) then
227 !$omp do simd schedule(static)
228 do ip = 1, der%mesh%np
229 this%grad_pot(ip, 2, idir)= grad_pot(ip,idir)
230 end do
231 !$omp end do simd
232 end if
233
234 if (nspin > 2) then
235 !$omp do simd schedule(static)
236 do ip = 1, der%mesh%np
237 this%grad_pot(ip, 3, idir)= m_zero
238 this%grad_pot(ip, 4, idir)= m_zero
239 end do
240 !$omp end do simd
241 end if
242 !$omp end parallel
243
244 end do
245
246 ! spin-orbit relativistic ZORA contribution
247 if (this%zora_level == zora_fully_relativistic) then
249 end if
250
251 safe_deallocate_a( zora_scpot )
252 safe_deallocate_a( grad_pot )
253
254 pop_sub(zora_update)
256 contains
257
263
265
266 real(real64), allocatable :: grad_v(:,:)
267
269
270 safe_allocate(grad_v(1:der%mesh%np, 1:der%dim))
271
272
273 ! gradient of potenial, only consider scalar potential
274 call dderivatives_grad(der, zora_scpot(:), grad_v(:,:))
275
276 !$omp parallel private(ip, prefactor)
277 !$omp do simd schedule(static)
278 do ip = 1, der%mesh%np
279
280 ! added extra factor of 2 because of -1/2 in the gradient
281 prefactor = this%so_strength * two_c2 / (this%mass*two_c2 - zora_scpot(ip))**2
282
283 grad_v(ip, 1) = grad_v(ip, 1) * prefactor
284 grad_v(ip, 2) = grad_v(ip, 2) * prefactor
285 grad_v(ip, 3) = grad_v(ip, 3) * prefactor
286
287 ! sigma \times zora_grad_v
288 ! four-component vector has elements ( up-up, down-down, Re(up-down), Im(up-down) )
289 this%soc(ip, 1, 1) = -grad_v(ip, 2)
290 this%soc(ip, 2, 1) = grad_v(ip, 2)
291 this%soc(ip, 3, 1) = m_zero
292 this%soc(ip, 4, 1) = -grad_v(ip, 3)
293
294 this%soc(ip, 1, 2) = grad_v(ip, 1)
295 this%soc(ip, 2, 2) = -grad_v(ip, 1)
296 this%soc(ip, 3, 2) = -grad_v(ip, 3)
297 this%soc(ip, 4, 2) = m_zero
298
299 this%soc(ip, 1, 3) = m_zero
300 this%soc(ip, 2, 3) = m_zero
301 this%soc(ip, 3, 3) = grad_v(ip, 2)
302 this%soc(ip, 4, 3) = grad_v(ip, 1)
303
304 end do
305 !$omp end do simd
306 !$omp end parallel
307
308 safe_deallocate_a(grad_v)
309
311 end subroutine zora_update_fully_relativistic
312
313 end subroutine zora_update
314
315#include "undef.F90"
316#include "real.F90"
317#include "zora_inc.F90"
318
319#include "undef.F90"
320#include "complex.F90"
321#include "zora_inc.F90"
322
323
324end module zora_oct_m
This module implements batches of mesh functions.
Definition: batch.F90:135
This module implements common operations on batches of mesh functions.
Definition: batch_ops.F90:118
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
subroutine, public dderivatives_grad(der, ff, op_ff, ghost_update, set_bc, to_cartesian)
apply the gradient to a mesh function
integer, parameter, public scalar_relativistic_zora
Definition: epot.F90:169
integer, parameter, public fully_relativistic_zora
Definition: epot.F90:169
real(real64), parameter, public m_two
Definition: global.F90:202
real(real64), parameter, public m_zero
Definition: global.F90:200
real(real64), parameter, public p_c
Electron gyromagnetic ratio, see Phys. Rev. Lett. 130, 071801 (2023)
Definition: global.F90:242
This module implements the underlying real-space grid.
Definition: grid.F90:119
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1068
This module handles spin dimensions of the states and the k-point distribution.
This module implements the ZORA terms for the Hamoiltonian.
Definition: zora.F90:118
integer, parameter, public zora_scalar_relativistic
ZORA for scalar relativistic calculations.
Definition: zora.F90:140
subroutine zora_update(this, der, potential)
update the ZORA potentials
Definition: zora.F90:256
subroutine zzora_apply_batch(this, mesh, der, states_dim, psib, hpsib, set_bc)
apply the ZORA to a batch of states psib
Definition: zora.F90:628
class(zora_t) function, pointer zora_constructor(namespace, der, st_d, ep, mass)
initialize the ZORA
Definition: zora.F90:179
subroutine zora_finalize(this)
finalize the ZORA object and free memory
Definition: zora.F90:224
subroutine dzora_apply_batch(this, mesh, der, states_dim, psib, hpsib, set_bc)
apply the ZORA to a batch of states psib
Definition: zora.F90:489
integer, parameter, public zora_fully_relativistic
ZORA for fully relativistic calculations.
Definition: zora.F90:140
class representing derivatives
This class is responsible for calculating and applying the ZORA.
Definition: zora.F90:147
subroutine zora_update_fully_relativistic()
update quantities, necessary only for fully relativistic ZORA
Definition: zora.F90:360