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