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 !
129 subroutine zora_finalize(this)
130 type(zora_t), intent(inout) :: this
131
132 push_sub(zora_finalize)
133
134 safe_deallocate_a(this%pot)
135 safe_deallocate_a(this%grad_pot)
136 safe_deallocate_a(this%soc)
137
139 end subroutine zora_finalize
140
141
161 subroutine zora_update(this, der, potential)
162 class(zora_t), intent(inout) :: this
163 class(derivatives_t), intent(in) :: der
164 real(real64), contiguous, intent(in) :: potential(:, :)
165
166 real(real64), allocatable :: zora_scpot(:), grad_pot(:,:)
167 real(real64) :: prefactor, two_c2
168
169 integer :: ip, idir
170 integer :: nspin
171
172 push_sub(zora_update)
173
174 if (this%zora_level == zora_none) then
175 pop_sub(zora_update)
176 return
177 end if
178
179 nspin = size(this%pot, dim=2)
180 two_c2 = m_two * p_c**2
181
182 ! We need to copy the potential to an array, allocated to np_part for the application of the derivatives.
183
184 safe_allocate( zora_scpot(1:der%mesh%np_part) )
185 safe_allocate( grad_pot(1:der%mesh%np_part, 1:der%dim) )
186
187 !$omp parallel private(ip)
188 !$omp do simd schedule(static)
189 do ip = 1, der%mesh%np
190 ! zora_scpot = V
191 zora_scpot(ip) = potential(ip, 1)
192 ! zora_pot = \frac{c^2}{2 m c^2 - V}
193 ! included extra factor of 2 because of -1/2 in kinetic energy
194 this%pot(ip,1) = two_c2 / (this%mass * two_c2 - zora_scpot(ip) )
195 end do
196 !$omp end do simd
197
198 if (nspin > 1) then
199 !$omp do simd schedule(static)
200 do ip = 1, der%mesh%np
201 this%pot(ip,2) = this%pot(ip,1)
202 end do
203 !$omp end do simd
204 end if
205 if (nspin > 2) then
206 !$omp do simd schedule(static)
207 do ip = 1, der%mesh%np
208 this%pot(ip,3) = m_zero
209 this%pot(ip,4) = m_zero
210 end do
211 !$omp end do simd
212 end if
213 !$omp end parallel
214
215 ! zora_grad_pot = grad( \frac{c^2}{2 m c^2 - V} )
216
217 call dderivatives_grad(der, this%pot(:,1), grad_pot)
218
219 do idir=1, der%dim
220 !$omp parallel private(ip)
221 !$omp do simd schedule(static)
222 do ip = 1, der%mesh%np
223 this%grad_pot(ip, 1, idir)= grad_pot(ip,idir)
224 end do
225 !$omp end do simd
226
227 if (nspin > 1) then
228 !$omp do simd schedule(static)
229 do ip = 1, der%mesh%np
230 this%grad_pot(ip, 2, idir)= grad_pot(ip,idir)
231 end do
232 !$omp end do simd
233 end if
234
235 if (nspin > 2) then
236 !$omp do simd schedule(static)
237 do ip = 1, der%mesh%np
238 this%grad_pot(ip, 3, idir)= m_zero
239 this%grad_pot(ip, 4, idir)= m_zero
240 end do
241 !$omp end do simd
242 end if
243 !$omp end parallel
244
245 end do
246
247 ! spin-orbit relativistic ZORA contribution
248 if (this%zora_level == zora_fully_relativistic) then
250 end if
251
252 safe_deallocate_a( zora_scpot )
253 safe_deallocate_a( grad_pot )
255 pop_sub(zora_update)
256
257 contains
258
264
266
267 real(real64), allocatable :: grad_v(:,:)
268
270
271 safe_allocate(grad_v(1:der%mesh%np, 1:der%dim))
272
273
274 ! gradient of potenial, only consider scalar potential
275 call dderivatives_grad(der, zora_scpot(:), grad_v(:,:))
276
277 !$omp parallel private(ip, prefactor)
278 !$omp do simd schedule(static)
279 do ip = 1, der%mesh%np
280
281 ! added extra factor of 2 because of -1/2 in the gradient
282 prefactor = this%so_strength * two_c2 / (this%mass*two_c2 - zora_scpot(ip))**2
283
284 grad_v(ip, 1) = grad_v(ip, 1) * prefactor
285 grad_v(ip, 2) = grad_v(ip, 2) * prefactor
286 grad_v(ip, 3) = grad_v(ip, 3) * prefactor
287
288 ! sigma \times zora_grad_v
289 ! four-component vector has elements ( up-up, down-down, Re(up-down), Im(up-down) )
290 this%soc(ip, 1, 1) = -grad_v(ip, 2)
291 this%soc(ip, 2, 1) = grad_v(ip, 2)
292 this%soc(ip, 3, 1) = m_zero
293 this%soc(ip, 4, 1) = -grad_v(ip, 3)
294
295 this%soc(ip, 1, 2) = grad_v(ip, 1)
296 this%soc(ip, 2, 2) = -grad_v(ip, 1)
297 this%soc(ip, 3, 2) = -grad_v(ip, 3)
298 this%soc(ip, 4, 2) = m_zero
299
300 this%soc(ip, 1, 3) = m_zero
301 this%soc(ip, 2, 3) = m_zero
302 this%soc(ip, 3, 3) = grad_v(ip, 2)
303 this%soc(ip, 4, 3) = grad_v(ip, 1)
304
305 end do
306 !$omp end do simd
307 !$omp end parallel
308
309 safe_deallocate_a(grad_v)
310
312 end subroutine zora_update_fully_relativistic
313
314 end subroutine zora_update
315
316#include "undef.F90"
317#include "real.F90"
318#include "zora_inc.F90"
319
320#include "undef.F90"
321#include "complex.F90"
322#include "zora_inc.F90"
323
324
325end module zora_oct_m
This module implements batches of mesh functions.
Definition: batch.F90:133
This module implements common operations on batches of mesh functions.
Definition: batch_ops.F90:116
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:166
integer, parameter, public fully_relativistic_zora
Definition: epot.F90:166
real(real64), parameter, public m_two
Definition: global.F90:190
real(real64), parameter, public m_zero
Definition: global.F90:188
real(real64), parameter, public p_c
Electron gyromagnetic ratio, see Phys. Rev. Lett. 130, 071801 (2023)
Definition: global.F90:224
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
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1113
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:116
integer, parameter, public zora_scalar_relativistic
ZORA for scalar relativistic calculations.
Definition: zora.F90:138
subroutine zora_update(this, der, potential)
update the ZORA potentials
Definition: zora.F90:255
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:627
class(zora_t) function, pointer zora_constructor(namespace, der, st_d, ep, mass)
initialize the ZORA
Definition: zora.F90:177
subroutine zora_finalize(this)
finalize the ZORA object and free memory
Definition: zora.F90:223
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:488
integer, parameter, public zora_fully_relativistic
ZORA for fully relativistic calculations.
Definition: zora.F90:138
class representing derivatives
This class is responsible for calculating and applying the ZORA.
Definition: zora.F90:145
subroutine zora_update_fully_relativistic()
update quantities, necessary only for fully relativistic ZORA
Definition: zora.F90:359