Octopus
epot.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
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 epot_oct_m
22 use debug_oct_m
26 use global_oct_m
27 use grid_oct_m
29 use ions_oct_m
31 use, intrinsic :: iso_fortran_env
34 use mesh_oct_m
36 use mpi_oct_m
39 use parser_oct_m
43 use ps_oct_m
45 use space_oct_m
54 use unit_oct_m
57 use xc_oct_m
58
59 implicit none
60
61 private
62 public :: &
63 epot_t, &
64 epot_init, &
65 epot_end, &
72
73 integer, public, parameter :: &
74 NOREL = 0, &
75 spin_orbit = 1, &
78
79 type epot_t
80 ! Components are public by default
81
82 ! Ions
83 real(real64), allocatable :: vpsl(:)
84 ! !< plus the potential from static electric fields
85 type(projector_t), allocatable :: proj(:)
86 logical :: non_local
87 integer :: natoms
88
89 ! External e-m fields
90 real(real64), allocatable :: e_field(:)
91 real(real64), allocatable :: v_ext(:)
92 real(real64), allocatable :: b_field(:)
93 real(real64), allocatable :: a_static(:,:)
94 integer :: reltype
95
98 real(real64) :: gyromagnetic_ratio
99
101 real(real64) :: so_strength
102
104 real(real64) :: eii
105 real(real64), allocatable :: fii(:, :)
106 real(real64), allocatable :: vdw_forces(:, :)
107 real(real64), allocatable :: photon_forces(:)
108
110 real(real64) :: vdw_stress(3, 3)
111
112 real(real64), allocatable, private :: local_potential(:,:)
113 logical, private :: local_potential_precalculated
114
115 logical, private :: have_density
116 type(poisson_t), pointer, private :: poisson_solver
117
119 logical, private :: proj_check_done = .false.
120
121 logical :: nlcc = .false.
122 end type epot_t
123
124contains
125
126 ! ---------------------------------------------------------
127 subroutine epot_init(ep, namespace, gr, ions, psolver, ispin, xc_family, kpoints)
128 type(epot_t), intent(out) :: ep
129 type(namespace_t), intent(in) :: namespace
130 type(grid_t), intent(in) :: gr
131 type(ions_t), intent(inout) :: ions
132 type(poisson_t), target, intent(in) :: psolver
133 integer, intent(in) :: ispin
134 integer, intent(in) :: xc_family
135 type(kpoints_t), intent(in) :: kpoints
136
137
138 integer :: ispec, ia
139 integer :: filter
140
141 push_sub(epot_init)
142
143 !%Variable FilterPotentials
144 !%Type integer
145 !%Default filter_ts
146 !%Section Hamiltonian
147 !%Description
148 !% <tt>Octopus</tt> can filter the pseudopotentials so that they no
149 !% longer contain Fourier components larger than the mesh itself. This is
150 !% very useful to decrease the egg-box effect, and so should be used in
151 !% all instances where atoms move (<i>e.g.</i> geometry optimization,
152 !% molecular dynamics, and vibrational modes).
153 !% No filtering is applied to HGH pseudopotentials, as these are already
154 !% smooth, analytical potentials in both real and Fourier space.
155 !%Option filter_none 0
156 !% Do not filter.
157 !%Option filter_TS 2
158 !% The filter of M. Tafipolsky and R. Schmid, <i>J. Chem. Phys.</i> <b>124</b>, 174102 (2006).
159 !%Option filter_BSB 3
160 !% The filter of E. L. Briggs, D. J. Sullivan, and J. Bernholc, <i>Phys. Rev. B</i> <b>54</b>, 14362 (1996).
161 !%End
162 call parse_variable(namespace, 'FilterPotentials', ps_filter_ts, filter)
163 if (.not. varinfo_valid_option('FilterPotentials', filter)) call messages_input_error(namespace, 'FilterPotentials')
164 call messages_print_var_option("FilterPotentials", filter, namespace=namespace)
165
166 if (family_is_mgga(xc_family) .and. filter /= ps_filter_none) then
167 call messages_not_implemented("FilterPotentials different from filter_none with MGGA", namespace=namespace)
168 end if
169
170 if (filter == ps_filter_ts) call spline_filter_mask_init()
171 do ispec = 1, ions%nspecies
172 call ions%species(ispec)%s%init_potential(namespace, mesh_gcutoff(gr), filter)
173 end do
175 safe_allocate(ep%vpsl(1:gr%np))
176
177 ep%vpsl(1:gr%np) = m_zero
179 ! No more "UserDefinedTDPotential" from this version on.
180 call messages_obsolete_variable(namespace, 'UserDefinedTDPotential', 'TDExternalFields')
182 call messages_obsolete_variable(namespace, 'ClassicalPotential')
183
184 !%Variable GyromagneticRatio
185 !%Type float
186 !%Default 2.0023193043768
187 !%Section Hamiltonian
188 !%Description
189 !% The gyromagnetic ratio of the electron. This is of course a physical
190 !% constant, and the default value is the exact one that you should not
191 !% touch, unless:
192 !% (i) You want to disconnect the anomalous Zeeman term in the Hamiltonian
193 !% (then set it to zero; this number only affects that term);
194 !% (ii) You are using an effective Hamiltonian, as is the case when
195 !% you calculate a 2D electron gas, in which case you have an effective
196 !% gyromagnetic factor that depends on the material.
197 !%End
198 call parse_variable(namespace, 'GyromagneticRatio', p_g, ep%gyromagnetic_ratio)
200 !%Variable RelativisticCorrection
201 !%Type integer
202 !%Default non_relativistic
203 !%Section Hamiltonian
204 !%Description
205 !% The default value means that <i>no</i> relativistic correction is used. To
206 !% include spin-orbit coupling turn <tt>RelativisticCorrection</tt> to <tt>spin_orbit</tt>
207 !% (this will only work if <tt>SpinComponents</tt> has been set to <tt>non_collinear</tt>, which ensures
208 !% the use of spinors).
209 !%Option non_relativistic 0
210 !% No relativistic corrections.
211 !%Option spin_orbit 1
212 !% Spin-orbit.
213 !%Option scalar_relativistic_zora 2
214 !% scalar relativistic ZORA Hamiltonian
215 !%Option fully_relativistic_zora 3
216 !% fully relativistic spin-orbit ZORA Hamiltonian
217 !% including SR and SO terms
218 !%End
219 call parse_variable(namespace, 'RelativisticCorrection', norel, ep%reltype)
220 if (.not. varinfo_valid_option('RelativisticCorrection', ep%reltype)) then
221 call messages_input_error(namespace, 'RelativisticCorrection')
222 end if
223 if (ispin /= spinors .and. ( ep%reltype == spin_orbit .or. ep%reltype == fully_relativistic_zora ) ) then
224 message(1) = "The spin-orbit term can only be applied when using spinors."
225 call messages_fatal(1, namespace=namespace)
226 end if
227
228 if((ep%reltype == spin_orbit .or. ep%reltype == fully_relativistic_zora) .and. kpoints%use_symmetries) then
229 call messages_not_implemented("Spin-orbit coupling and k-point symmetries", namespace=namespace)
230 end if
231
232 call messages_print_var_option("RelativisticCorrection", ep%reltype, namespace=namespace)
233
234 !%Variable SOStrength
235 !%Type float
236 !%Default 1.0
237 !%Section Hamiltonian
238 !%Description
239 !% Tuning of the spin-orbit coupling strength: setting this value to zero turns off spin-orbit terms in
240 !% the Hamiltonian, and setting it to one corresponds to full spin-orbit.
241 !%End
242 if (ep%reltype == spin_orbit .or. ep%reltype == fully_relativistic_zora) then
243 call parse_variable(namespace, 'SOStrength', m_one, ep%so_strength)
244 else
245 ep%so_strength = m_one
246 end if
247
248 safe_allocate(ep%proj(1:ions%natoms))
249
250 ep%natoms = ions%natoms
251 ep%non_local = .false.
252
253 ep%eii = m_zero
254 safe_allocate(ep%fii(1:ions%space%dim, 1:ions%natoms))
255 ep%fii = m_zero
256
257 safe_allocate(ep%vdw_forces(1:ions%space%dim, 1:ions%natoms))
258 ep%vdw_forces = m_zero
259
260 safe_allocate(ep%photon_forces(1:ions%space%dim))
261 ep%photon_forces = m_zero
262
263 ep%local_potential_precalculated = .false.
264
265
266 ep%have_density = .false.
267 do ia = 1, ions%nspecies
268 if (local_potential_has_density(ions%space, ions%species(ia)%s)) then
269 ep%have_density = .true.
270 exit
271 end if
272 end do
273
274 if (ep%have_density) then
275 ep%poisson_solver => psolver
276 else
277 nullify(ep%poisson_solver)
278 end if
279
280 ! find out if we need non-local core corrections
281 ep%nlcc = .false.
282 do ia = 1, ions%nspecies
283 ep%nlcc = (ep%nlcc .or. ions%species(ia)%s%is_ps_with_nlcc())
284 end do
285
286 pop_sub(epot_init)
287 end subroutine epot_init
288
289 ! ---------------------------------------------------------
290 subroutine epot_end(ep)
291 type(epot_t), intent(inout) :: ep
292
293 integer :: iproj
294
295 push_sub(epot_end)
296
297 if (ep%have_density) then
298 nullify(ep%poisson_solver)
299 end if
300
301 safe_deallocate_a(ep%local_potential)
302 safe_deallocate_a(ep%fii)
303 safe_deallocate_a(ep%vdw_forces)
304 safe_deallocate_a(ep%vpsl)
305 safe_deallocate_a(ep%photon_forces)
306
307 ! the macroscopic fields
308 safe_deallocate_a(ep%e_field)
309 safe_deallocate_a(ep%v_ext)
310 safe_deallocate_a(ep%b_field)
311 safe_deallocate_a(ep%a_static)
312
313 do iproj = 1, ep%natoms
314 if (projector_is_null(ep%proj(iproj))) cycle
315 call projector_end(ep%proj(iproj))
316 end do
317
318 assert(allocated(ep%proj))
319 safe_deallocate_a(ep%proj)
320
321 pop_sub(epot_end)
322
323 end subroutine epot_end
324
325 ! ---------------------------------------------------------
329 subroutine epot_bind_poisson_solver(ep, psolver)
330 type(epot_t), intent(inout) :: ep
331 type(poisson_t), target, intent(in) :: psolver
332
334
335 if (ep%have_density) then
336 ep%poisson_solver => psolver
337 else
338 nullify(ep%poisson_solver)
339 end if
340
342 end subroutine epot_bind_poisson_solver
343
344 ! ---------------------------------------------------------
345 subroutine epot_generate(ep, namespace, mesh, ions, st_d)
346 type(epot_t), intent(inout) :: ep
347 type(namespace_t), intent(in) :: namespace
348 class(mesh_t), target, intent(in) :: mesh
349 type(ions_t), target, intent(inout) :: ions
350 type(states_elec_dim_t), intent(inout) :: st_d
351
352 integer :: ia
353 type(ps_t), pointer :: ps
354 logical, allocatable :: spec_checked(:)
355
356 call profiling_in("EPOT_GENERATE")
357 push_sub(epot_generate)
358
359 ! Local part
360 ep%vpsl = m_zero
361
362 ! we assume that we need to recalculate the ion-ion energy
363 call ion_interaction_calculate(ions%ion_interaction, ions%space, ions%latt, ions%atom, &
364 ions%natoms, ions%pos, mesh%box%bounding_box_l, ep%eii, ep%fii)
365
366 ! the pseudopotential part.
367 do ia = 1, ions%natoms
368 select type(spec=>ions%atom(ia)%species)
369 type is(pseudopotential_t)
370 call projector_end(ep%proj(ia))
371 call projector_init(ep%proj(ia), spec, namespace, st_d%dim, ep%reltype)
372 end select
373 end do
374
375 do ia = ions%atoms_dist%start, ions%atoms_dist%end
376 if (ep%proj(ia)%type == proj_none) cycle
377 select type(spec=>ions%atom(ia)%species)
378 type is(pseudopotential_t)
379 ps => spec%ps
380 call submesh_init(ep%proj(ia)%sphere, ions%space, mesh, ions%latt, ions%pos(:, ia), ps%rc_max)
381 end select
382 end do
383
384 if (ions%atoms_dist%parallel) then
385 do ia = 1, ions%natoms
386 if (ep%proj(ia)%type == proj_none) cycle
387 select type(spec=>ions%atom(ia)%species)
388 type is(pseudopotential_t)
389 ps => spec%ps
390 call submesh_broadcast(ep%proj(ia)%sphere, ions%space, mesh, ions%pos(:, ia), ps%rc_max, &
391 ions%atoms_dist%node(ia), ions%atoms_dist%mpi_grp)
392 end select
393 end do
394 end if
395
396 do ia = 1, ions%natoms
397 select type(spec=>ions%atom(ia)%species)
398 type is(pseudopotential_t)
399 call projector_build(ep%proj(ia), spec, ep%so_strength)
400 if (.not. projector_is(ep%proj(ia), proj_none)) ep%non_local = .true.
401 end select
402 end do
403
404 ! Check once, for one atom of each species, that the projectors are properly
405 ! resolved on the grid, to warn about possible spurious (ghost) states
406 if (.not. ep%proj_check_done) then
407 safe_allocate(spec_checked(1:ions%nspecies))
408 spec_checked = .false.
409 do ia = 1, ions%natoms
410 if (ep%proj(ia)%type == proj_none) cycle
411 if (spec_checked(ions%atom(ia)%species%get_index())) cycle
412 select type(spec=>ions%atom(ia)%species)
413 type is(pseudopotential_t)
414 call projector_check_discretization(spec, ep%proj(ia)%sphere, namespace)
415 spec_checked(ions%atom(ia)%species%get_index()) = .true.
416 end select
417 end do
418 safe_deallocate_a(spec_checked)
419 ep%proj_check_done = .true.
420 end if
421
422 pop_sub(epot_generate)
423 call profiling_out("EPOT_GENERATE")
424 end subroutine epot_generate
425
426 ! ---------------------------------------------------------
427
428 logical pure function local_potential_has_density(space, species) result(has_density)
429 class(space_t), intent(in) :: space
430 class(species_t), intent(in) :: species
431
432 has_density = species%has_density .or. (species%is_ps() .and. space%is_periodic())
433
434 end function local_potential_has_density
435
436 ! ---------------------------------------------------------
437 subroutine epot_local_potential(ep, namespace, space, latt, mesh, species, pos, iatom, vpsl)
438 type(epot_t), intent(in) :: ep
439 type(namespace_t), intent(in) :: namespace
440 class(space_t), intent(in) :: space
441 type(lattice_vectors_t), intent(in) :: latt
442 class(mesh_t), intent(in) :: mesh
443 class(species_t), target, intent(in) :: species
444 real(real64), intent(in) :: pos(1:space%dim)
445 integer, intent(in) :: iatom
446 real(real64), contiguous, intent(inout) :: vpsl(:)
447
448 integer :: ip
449 real(real64) :: radius
450 real(real64), allocatable :: vl(:), rho(:)
451 type(submesh_t) :: sphere
452 type(ps_t), pointer :: ps
453
454 push_sub(epot_local_potential)
455 call profiling_in("EPOT_LOCAL")
456
457 if (ep%local_potential_precalculated) then
458
459 call lalg_axpy(mesh%np, m_one, ep%local_potential(:, iatom), vpsl)
460
461 else
462
463 !Local potential, we can get it by solving the Poisson equation
464 !(for all-electron species or pseudopotentials in periodic
465 !systems) or by applying it directly to the grid
466 safe_allocate(vl(1:mesh%np))
467
468 if (local_potential_has_density(space, species)) then
469 safe_allocate(rho(1:mesh%np))
470
471 call species_get_long_range_density(species, namespace, space, latt, pos, mesh, rho, sphere)
472
473 call dpoisson_solve(ep%poisson_solver, namespace, vl, rho, all_nodes = .false.)
474
475 safe_deallocate_a(rho)
476
477 else
478
479 call species_get_local(species, namespace, space, latt, pos, mesh, vl)
480
481 end if
482
483 call lalg_axpy(mesh%np, m_one, vl, vpsl)
484 safe_deallocate_a(vl)
485
486 !the localized part
487 select type(species)
488 class is(pseudopotential_t)
489
490 ps => species%ps
491
492 radius = min(ps%vl%x_threshold*1.05_real64, spline_range_max(ps%vl))
493 if (.not. submesh_compatible(sphere, radius, pos, minval(mesh%spacing(1:space%dim)))) then
494 call submesh_end(sphere)
495 call submesh_init(sphere, space, mesh, latt, pos, radius)
496 end if
497 safe_allocate(vl(1:sphere%np))
498 vl = m_zero
499
500 do ip = 1, sphere%np
501 if(sphere%r(ip) <= radius) then
502 vl(ip) = spline_eval(ps%vl, sphere%r(ip))
503 end if
504 end do
505
506 call submesh_add_to_mesh(sphere, vl, vpsl)
507
508 safe_deallocate_a(vl)
509 nullify(ps)
510
511 end select
512 call submesh_end(sphere)
513
514 end if
515
516 call profiling_out("EPOT_LOCAL")
517 pop_sub(epot_local_potential)
518 end subroutine epot_local_potential
519
520 ! ---------------------------------------------------------
521 subroutine epot_precalc_local_potential(ep, namespace, gr, ions)
522 type(epot_t), intent(inout) :: ep
523 type(namespace_t), intent(in) :: namespace
524 type(grid_t), intent(in) :: gr
525 type(ions_t), intent(in) :: ions
526
527 integer :: iatom
528
530
531 if (.not. allocated(ep%local_potential)) then
532 safe_allocate(ep%local_potential(1:gr%np, 1:ions%natoms))
533 end if
534
535 ep%local_potential_precalculated = .false.
536
537 do iatom = 1, ions%natoms
538 ep%local_potential(1:gr%np, iatom) = m_zero
539 call epot_local_potential(ep, namespace, ions%space, ions%latt, gr, ions%atom(iatom)%species, &
540 ions%pos(:, iatom), iatom, ep%local_potential(1:gr%np, iatom))!, time)
541 end do
542 ep%local_potential_precalculated = .true.
543
545 end subroutine epot_precalc_local_potential
546
547 ! ---------------------------------------------------------
548
549 logical function epot_have_external_potentials(ep)
550 type(epot_t), intent(in) :: ep
551
553
554 epot_have_external_potentials = allocated(ep%e_field)
555
557
559
560end module epot_oct_m
561
562!! Local Variables:
563!! mode: f90
564!! coding: utf-8
565!! End:
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
integer, parameter, public spinors
subroutine, public epot_bind_poisson_solver(ep, psolver)
Bind the Poisson solver if the potential manages a density. The Poisson solver pointer is aliased whe...
Definition: epot.F90:425
logical function, public epot_have_external_potentials(ep)
Definition: epot.F90:645
logical pure function, public local_potential_has_density(space, species)
Definition: epot.F90:524
integer, parameter, public spin_orbit
Definition: epot.F90:168
integer, parameter, public scalar_relativistic_zora
Definition: epot.F90:168
subroutine, public epot_end(ep)
Definition: epot.F90:386
integer, parameter, public fully_relativistic_zora
Definition: epot.F90:168
subroutine, public epot_precalc_local_potential(ep, namespace, gr, ions)
Definition: epot.F90:617
subroutine, public epot_local_potential(ep, namespace, space, latt, mesh, species, pos, iatom, vpsl)
Definition: epot.F90:533
subroutine, public epot_init(ep, namespace, gr, ions, psolver, ispin, xc_family, kpoints)
Definition: epot.F90:223
subroutine, public epot_generate(ep, namespace, mesh, ions, st_d)
Definition: epot.F90:441
real(real64), parameter, public p_g
Definition: global.F90:244
real(real64), parameter, public m_zero
Definition: global.F90:200
real(real64), parameter, public m_one
Definition: global.F90:201
This module implements the underlying real-space grid.
Definition: grid.F90:119
subroutine, public ion_interaction_calculate(this, space, latt, atom, natoms, pos, lsize, energy, force, energy_components, force_components)
Top level routine for computing electrostatic energies and forces between ions.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
real(real64) function, public mesh_gcutoff(mesh)
mesh_gcutoff returns the "natural" band limitation of the grid mesh, in terms of the maximum G vector...
Definition: mesh.F90:451
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1068
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:1000
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:410
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:691
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:631
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:554
subroutine, public projector_build(p, ps, so_strength)
Definition: projector.F90:346
logical elemental function, public projector_is(p, type)
Definition: projector.F90:211
subroutine, public projector_init(p, pseudo, namespace, dim, reltype)
Definition: projector.F90:218
subroutine, public projector_end(p)
Definition: projector.F90:468
subroutine, public projector_check_discretization(pseudo, sm, namespace)
Check how well the nonlocal projectors are resolved on the real-space grid.
Definition: projector.F90:401
logical elemental function, public projector_is_null(p)
Definition: projector.F90:204
Definition: ps.F90:116
integer, parameter, public ps_filter_ts
Definition: ps.F90:166
integer, parameter, public ps_filter_none
Definition: ps.F90:166
integer, parameter, public proj_none
Definition: ps.F90:171
subroutine, public spline_filter_mask_init()
This module handles spin dimensions of the states and the k-point distribution.
subroutine, public submesh_broadcast(this, space, mesh, center, radius, root, mpi_grp)
Definition: submesh.F90:602
subroutine, public submesh_init(this, space, mesh, latt, center, rc)
Definition: submesh.F90:226
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:134
This module defines the unit system, used for input and output.
Definition: xc.F90:120
pure logical function, public family_is_mgga(family, only_collinear)
Is the xc function part of the mGGA family.
Definition: xc.F90:702
Describes mesh distribution to nodes.
Definition: mesh.F90:187
A type storing the information and data about a pseudopotential.
Definition: ps.F90:188
An abstract class for species. Derived classes include jellium, all electron, and pseudopotential spe...
Definition: species.F90:147
class for organizing spins and k-points
int true(void)