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 real(real64), allocatable :: soc(:,:,:)
58
59 real(real64) :: so_strength = m_zero
60 real(real64) :: mass = m_zero
61
62 integer :: zora_level = zora_none
63
64 contains
65 procedure :: update => zora_update
66 procedure :: dapply_batch => dzora_apply_batch
67 procedure :: zapply_batch => zzora_apply_batch
68 final :: zora_finalize
69 end type
70
71 interface zora_t
72 procedure zora_constructor
73 end interface zora_t
74
75contains
76
80 !
81 function zora_constructor(namespace, der, st_d, ep, mass) result(this)
82 type(namespace_t), intent(in) :: namespace
83 type(derivatives_t), intent(in) :: der
84 type(states_elec_dim_t), intent(in) :: st_d
85 type(epot_t), intent(in) :: ep
86 real(real64), intent(in) :: mass
87 class(zora_t), pointer :: this
88
89 push_sub(zora_constructor)
90 safe_allocate(this)
91
92
93 this%so_strength = ep%so_strength
94 this%mass = mass
95
96 select case (ep%reltype)
98 this%zora_level = zora_scalar_relativistic
100 this%zora_level = zora_fully_relativistic
101 case default
102 this%zora_level = zora_none
103 pop_sub(zora_constructor)
104 return
105 end select
106
107 if (der%dim /= 3) then
108 call messages_not_implemented("ZORA for dimensions /= 3", namespace)
109 end if
110
111 safe_allocate(this%pot(1:der%mesh%np_part, 1:st_d%nspin))
112 safe_allocate(this%grad_pot(1:der%mesh%np, 1:st_d%nspin, 1:der%dim))
113
114 if(this%zora_level == zora_fully_relativistic) then
115
116 assert(st_d%nspin == 4)
117 safe_allocate(this%soc(1:der%mesh%np, 1:st_d%nspin, 1:der%dim))
118
119 end if
120
121 pop_sub(zora_constructor)
122 end function zora_constructor
123
124
126 !
127 subroutine zora_finalize(this)
128 type(zora_t), intent(inout) :: this
129
130 push_sub(zora_finalize)
131
132 safe_deallocate_a(this%pot)
133 safe_deallocate_a(this%grad_pot)
134 safe_deallocate_a(this%soc)
135
136 pop_sub(zora_finalize)
137 end subroutine zora_finalize
139
159 subroutine zora_update(this, der, potential)
160 class(zora_t), intent(inout) :: this
161 class(derivatives_t), intent(in) :: der
162 real(real64), contiguous, intent(in) :: potential(:, :)
163
164 real(real64), allocatable :: zora_scpot(:), grad_pot(:,:)
165 real(real64) :: prefactor, two_c2
166
167 integer :: ip, idir
168 integer :: nspin
169
170 push_sub(zora_update)
171
172 if (this%zora_level == zora_none) then
173 pop_sub(zora_update)
174 return
175 end if
176
177 nspin = size(this%pot, dim=2)
178 two_c2 = m_two * p_c**2
179
180 ! We need to copy the potential to an array, allocated to np_part for the application of the derivatives.
181
182 safe_allocate( zora_scpot(1:der%mesh%np_part) )
183 safe_allocate( grad_pot(1:der%mesh%np_part, 1:der%dim) )
184
185 !$omp parallel private(ip)
186 !$omp do simd schedule(static)
187 do ip = 1, der%mesh%np
188 ! zora_scpot = V
189 zora_scpot(ip) = potential(ip, 1)
190 ! zora_pot = \frac{c^2}{2 m c^2 - V}
191 ! included extra factor of 2 because of -1/2 in kinetic energy
192 this%pot(ip,1) = two_c2 / (this%mass * two_c2 - zora_scpot(ip) )
193 end do
194 !$omp end do simd
195
196 if (nspin > 1) then
197 !$omp do simd schedule(static)
198 do ip = 1, der%mesh%np
199 this%pot(ip,2) = this%pot(ip,1)
200 end do
201 !$omp end do simd
202 end if
203 if (nspin > 2) then
204 !$omp do simd schedule(static)
205 do ip = 1, der%mesh%np
206 this%pot(ip,3) = m_zero
207 this%pot(ip,4) = m_zero
208 end do
209 !$omp end do simd
210 end if
211 !$omp end parallel
212
213 ! zora_grad_pot = grad( \frac{c^2}{2 m c^2 - V} )
214
215 call dderivatives_grad(der, this%pot(:,1), grad_pot)
216
217 do idir=1, der%dim
218 !$omp parallel private(ip)
219 !$omp do simd schedule(static)
220 do ip = 1, der%mesh%np
221 this%grad_pot(ip, 1, idir)= grad_pot(ip,idir)
222 end do
223 !$omp end do simd
224
225 if (nspin > 1) then
226 !$omp do simd schedule(static)
227 do ip = 1, der%mesh%np
228 this%grad_pot(ip, 2, idir)= grad_pot(ip,idir)
229 end do
230 !$omp end do simd
231 end if
232
233 if (nspin > 2) then
234 !$omp do simd schedule(static)
235 do ip = 1, der%mesh%np
236 this%grad_pot(ip, 3, idir)= m_zero
237 this%grad_pot(ip, 4, idir)= m_zero
238 end do
239 !$omp end do simd
240 end if
241 !$omp end parallel
242
243 end do
244
245 ! spin-orbit relativistic ZORA contribution
246 if (this%zora_level == zora_fully_relativistic) then
248 end if
249
250 safe_deallocate_a( zora_scpot )
251 safe_deallocate_a( grad_pot )
253 pop_sub(zora_update)
254
255 contains
256
262
264
265 real(real64), allocatable :: grad_v(:,:)
266
268
269 safe_allocate(grad_v(1:der%mesh%np, 1:der%dim))
270
271
272 ! gradient of potenial, only consider scalar potential
273 call dderivatives_grad(der, zora_scpot(:), grad_v(:,:))
274
275 !$omp parallel private(ip, prefactor)
276 !$omp do simd schedule(static)
277 do ip = 1, der%mesh%np
278
279 ! added extra factor of 2 because of -1/2 in the gradient
280 prefactor = this%so_strength * two_c2 / (this%mass*two_c2 - zora_scpot(ip))**2
281
282 grad_v(ip, 1) = grad_v(ip, 1) * prefactor
283 grad_v(ip, 2) = grad_v(ip, 2) * prefactor
284 grad_v(ip, 3) = grad_v(ip, 3) * prefactor
285
286 ! sigma \times zora_grad_v
287 ! four-component vector has elements ( up-up, down-down, Re(up-down), Im(up-down) )
288 this%soc(ip, 1, 1) = -grad_v(ip, 2)
289 this%soc(ip, 2, 1) = grad_v(ip, 2)
290 this%soc(ip, 3, 1) = m_zero
291 this%soc(ip, 4, 1) = -grad_v(ip, 3)
292
293 this%soc(ip, 1, 2) = grad_v(ip, 1)
294 this%soc(ip, 2, 2) = -grad_v(ip, 1)
295 this%soc(ip, 3, 2) = -grad_v(ip, 3)
296 this%soc(ip, 4, 2) = m_zero
297
298 this%soc(ip, 1, 3) = m_zero
299 this%soc(ip, 2, 3) = m_zero
300 this%soc(ip, 3, 3) = grad_v(ip, 2)
301 this%soc(ip, 4, 3) = grad_v(ip, 1)
302
303 end do
304 !$omp end do simd
305 !$omp end parallel
306
307 safe_deallocate_a(grad_v)
308
310 end subroutine zora_update_fully_relativistic
311
312 end subroutine zora_update
313
314#include "undef.F90"
315#include "real.F90"
316#include "zora_inc.F90"
317
318#include "undef.F90"
319#include "complex.F90"
320#include "zora_inc.F90"
321
322
323end 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:189
real(real64), parameter, public m_zero
Definition: global.F90:187
real(real64), parameter, public p_c
Electron gyromagnetic ratio, see Phys. Rev. Lett. 130, 071801 (2023)
Definition: global.F90:223
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:1125
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
subroutine zzora_apply_batch(this, mesh, der, states_dim, psib, hpsib)
apply the ZORA to a batch of states psib
Definition: zora.F90:624
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:253
subroutine dzora_apply_batch(this, mesh, der, states_dim, psib, hpsib)
apply the ZORA to a batch of states psib
Definition: zora.F90:486
class(zora_t) function, pointer zora_constructor(namespace, der, st_d, ep, mass)
initialize the ZORA
Definition: zora.F90:175
subroutine zora_finalize(this)
finalize the ZORA object and free memory
Definition: zora.F90:221
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:357