Octopus
hamiltonian_elec.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2020 M. Marques, A. Castro, A. Rubio, G. Bertsch,
2!! N. Tancogne-Dejean, M. Lueders
3!!
4!! This program is free software; you can redistribute it and/or modify
5!! it under the terms of the GNU General Public License as published by
6!! the Free Software Foundation; either version 2, or (at your option)
7!! any later version.
8!!
9!! This program is distributed in the hope that it will be useful,
10!! but WITHOUT ANY WARRANTY; without even the implied warranty of
11!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12!! GNU General Public License for more details.
13!!
14!! You should have received a copy of the GNU General Public License
15!! along with this program; if not, write to the Free Software
16!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17!! 02110-1301, USA.
18!!
19
20#include "global.h"
21
24 use accel_oct_m
26 use batch_oct_m
29 use comm_oct_m
30 use debug_oct_m
33 use energy_oct_m
38 use epot_oct_m
41 use global_oct_m
42 use grid_oct_m
46 use io_oct_m
47 use ions_oct_m
48 use kick_oct_m
49 use, intrinsic :: iso_fortran_env
53 use lasers_oct_m
55 use lda_u_oct_m
58 use math_oct_m
59 use mesh_oct_m
62 use mpi_oct_m
66 use nlcc_oct_m
70 use parser_oct_m
75 use pcm_oct_m
76 use phase_oct_m
79 use space_oct_m
87 use types_oct_m
88 use unit_oct_m
92 use xc_oct_m
93 use xc_cam_oct_m
94 use xc_f03_lib_m
98 use zora_oct_m
99
100 implicit none
101
102 private
103 public :: &
113 magnus, &
114 dvmask, &
115 zvmask, &
130
131
132 type, extends(hamiltonian_abst_t) :: hamiltonian_elec_t
133 ! Components are public by default
134
137 type(space_t), private :: space
138 type(states_elec_dim_t) :: d
139 type(hamiltonian_elec_base_t) :: hm_base
140 type(phase_t) :: phase
141 type(energy_t), allocatable :: energy
142 type(absorbing_boundaries_t) :: abs_boundaries
143 type(ks_potential_t) :: ks_pot
144 real(real64), allocatable :: vberry(:,:)
145
146 type(derivatives_t), pointer, private :: der
147
148 type(nonlocal_pseudopotential_t) :: vnl
149
150 type(ions_t), pointer :: ions
151 real(real64) :: exx_coef
152
153 type(poisson_t) :: psolver
154
156 logical :: self_induced_magnetic
157 real(real64), allocatable :: a_ind(:, :)
158 real(real64), allocatable :: b_ind(:, :)
159
160 integer :: theory_level
161 type(xc_t), pointer :: xc
162 type(xc_photons_t), pointer :: xc_photons
163
164 type(epot_t) :: ep
165 type(pcm_t) :: pcm
166
168 logical, private :: adjoint
169
171 real(real64), private :: mass
172
174 logical, private :: inh_term
175 type(states_elec_t) :: inh_st
176
179 type(oct_exchange_t) :: oct_exchange
180
181 type(scissor_t) :: scissor
182
183 real(real64) :: current_time
184 logical, private :: is_applied_packed
185
187 type(lda_u_t) :: lda_u
188 integer :: lda_u_level
189
190 logical, public :: time_zero
191
192 type(exchange_operator_t), public :: exxop
193
194 type(kpoints_t), pointer, public :: kpoints => null()
195
196 type(partner_list_t) :: external_potentials
197 real(real64), allocatable, public :: v_ext_pot(:)
198 real(real64), allocatable, public :: v_static(:)
199
200 type(ion_electron_local_potential_t) :: v_ie_loc
201 type(nlcc_t) :: nlcc
202
203 type(magnetic_constrain_t) :: magnetic_constrain
204
206 type(kick_t) :: kick
207
209 type(mxll_coupling_t) :: mxll
210 type(zora_t), pointer :: zora => null()
211
212 contains
213 procedure :: update => hamiltonian_elec_update
214 procedure :: apply_packed => hamiltonian_elec_apply_packed
215 procedure :: update_span => hamiltonian_elec_span
216 procedure :: dapply => dhamiltonian_elec_apply
217 procedure :: zapply => zhamiltonian_elec_apply
218 procedure :: dmagnus_apply => dhamiltonian_elec_magnus_apply
219 procedure :: zmagnus_apply => zhamiltonian_elec_magnus_apply
220 procedure :: is_hermitian => hamiltonian_elec_hermitian
221 procedure :: needs_mgga_term => hamiltonian_elec_needs_mgga_term
222 procedure :: set_mass => hamiltonian_elec_set_mass
223 end type hamiltonian_elec_t
224
225 integer, public, parameter :: &
226 LENGTH = 1, &
228
229
230contains
231
232 ! ---------------------------------------------------------
233 subroutine hamiltonian_elec_init(hm, namespace, space, gr, ions, ext_partners, st, theory_level, xc, &
234 mc, kpoints, need_exchange, xc_photons)
235 type(hamiltonian_elec_t), target, intent(inout) :: hm
236 type(namespace_t), intent(in) :: namespace
237 class(space_t), intent(in) :: space
238 type(grid_t), target, intent(inout) :: gr
239 type(ions_t), target, intent(inout) :: ions
240 type(partner_list_t), intent(inout) :: ext_partners
241 type(states_elec_t), target, intent(inout) :: st
242 integer, intent(in) :: theory_level
243 type(xc_t), target, intent(in) :: xc
244 type(multicomm_t), intent(in) :: mc
245 type(kpoints_t), target, intent(in) :: kpoints
246 logical, optional, intent(in) :: need_exchange
247 type(xc_photons_t), optional, target, intent(in) :: xc_photons
249
250 logical :: need_exchange_
251 real(real64) :: rashba_coupling
254 call profiling_in('HAMILTONIAN_ELEC_INIT')
256 ! make a couple of local copies
257 hm%space = space
258 hm%theory_level = theory_level
259 call states_elec_dim_copy(hm%d, st%d)
261 hm%kpoints => kpoints
262
263 !%Variable ParticleMass
264 !%Type float
265 !%Default 1.0
266 !%Section Hamiltonian
267 !%Description
268 !% It is possible to make calculations for a particle with a mass
269 !% different from one (atomic unit of mass, or mass of the electron).
270 !% This is useful to describe non-electronic systems, or for
271 !% esoteric purposes.
272 !%End
273 call parse_variable(namespace, 'ParticleMass', m_one, hm%mass)
275 !%Variable RashbaSpinOrbitCoupling
276 !%Type float
277 !%Default 0.0
278 !%Section Hamiltonian
279 !%Description
280 !% (Experimental.) For systems described in 2D (electrons confined to 2D in semiconductor structures), one
281 !% may add the Bychkov-Rashba spin-orbit coupling term [Bychkov and Rashba, <i>J. Phys. C: Solid
282 !% State Phys.</i> <b>17</b>, 6031 (1984)]. This variable determines the strength
283 !% of this perturbation, and has dimensions of energy times length.
284 !%End
285 call parse_variable(namespace, 'RashbaSpinOrbitCoupling', m_zero, rashba_coupling, units_inp%energy*units_inp%length)
286 if (parse_is_defined(namespace, 'RashbaSpinOrbitCoupling')) then
287 if (space%dim /= 2) then
288 write(message(1),'(a)') 'Rashba spin-orbit coupling can only be used for two-dimensional systems.'
289 call messages_fatal(1, namespace=namespace)
290 end if
291 call messages_experimental('RashbaSpinOrbitCoupling', namespace=namespace)
292 end if
294 call hm%hm_base%init(hm%d%nspin, hm%mass, rashba_coupling)
295 call hm%vnl%init()
297 assert(associated(gr%der%lapl))
298 hm%hm_base%kinetic => gr%der%lapl
299
300 safe_allocate(hm%energy)
302 !Keep pointers to derivatives, geometry and xc
303 hm%der => gr%der
304 hm%ions => ions
305 hm%xc => xc
306
307 if(present(xc_photons)) then
308 hm%xc_photons => xc_photons
309 else
310 hm%xc_photons => null()
311 end if
313 ! allocate potentials and density of the cores
314 ! In the case of spinors, vxc_11 = hm%vxc(:, 1), vxc_22 = hm%vxc(:, 2), Re(vxc_12) = hm%vxc(:. 3);
315 ! Im(vxc_12) = hm%vxc(:, 4)
316 call hm%ks_pot%init(gr%der, gr%np, gr%np_part, hm%d%nspin, hm%theory_level, family_is_mgga_with_exc(hm%xc))
318 !Initialize Poisson solvers
319 call poisson_init(hm%psolver, namespace, space, gr%der, mc, gr%stencil, st%qtot)
321 ! Initialize external potential
322 call epot_init(hm%ep, namespace, gr, hm%ions, hm%psolver, hm%d%ispin, hm%xc%family, hm%kpoints)
323 call kick_init(hm%kick, namespace, space, hm%kpoints, hm%d%ispin)
324
325 hm%zora => zora_t(namespace, hm%der, hm%d, hm%ep, hm%mass)
326
327 !Temporary construction of the ion-electron interactions
328 call hm%v_ie_loc%init(gr, hm%psolver, hm%ions, namespace)
329 if (hm%ep%nlcc) then
330 call hm%nlcc%init(gr, hm%ions)
331 safe_allocate(st%rho_core(1:gr%np))
332 st%rho_core(:) = m_zero
333 end if
334
335 !Static magnetic field or rashba spin-orbit interaction requires complex wavefunctions
336 if (parse_is_defined(namespace, 'StaticMagneticField') .or. list_has_gauge_field(ext_partners) .or. &
337 parse_is_defined(namespace, 'RashbaSpinOrbitCoupling')) then
338 call states_set_complex(st)
339 end if
340
341 !%Variable CalculateSelfInducedMagneticField
342 !%Type logical
343 !%Default no
344 !%Section Hamiltonian
345 !%Description
346 !% The existence of an electronic current implies the creation of a self-induced magnetic
347 !% field, which may in turn back-react on the system. Of course, a fully consistent treatment
348 !% of this kind of effect should be done in QED theory, but we will attempt a first
349 !% approximation to the problem by considering the lowest-order relativistic terms
350 !% plugged into the normal Hamiltonian equations (spin-other-orbit coupling terms, etc.).
351 !% For the moment being, none of this is done, but a first step is taken by calculating
352 !% the induced magnetic field of a system that has a current, by considering the magnetostatic
353 !% approximation and Biot-Savart law:
354 !%
355 !% <math> \nabla^2 \vec{A} + 4\pi\alpha \vec{J} = 0</math>
356 !%
357 !% <math> \vec{B} = \vec{\nabla} \times \vec{A}</math>
358 !%
359 !% If <tt>CalculateSelfInducedMagneticField</tt> is set to yes, this <i>B</i> field is
360 !% calculated at the end of a <tt>gs</tt> calculation (nothing is done -- yet -- in the <tt>td</tt>case)
361 !% and printed out, if the <tt>Output</tt> variable contains the <tt>potential</tt> keyword (the prefix
362 !% of the output files is <tt>Bind</tt>).
363 !%End
364 call parse_variable(namespace, 'CalculateSelfInducedMagneticField', .false., hm%self_induced_magnetic)
365 if (hm%self_induced_magnetic) then
366 safe_allocate(hm%a_ind(1:gr%np_part, 1:space%dim))
367 safe_allocate(hm%b_ind(1:gr%np_part, 1:space%dim))
368
369 !(for dim = we could save some memory, but it is better to keep it simple)
370 end if
371
372 ! Absorbing boundaries
373 call absorbing_boundaries_init(hm%abs_boundaries, namespace, space, gr)
374
375 hm%inh_term = .false.
376 call oct_exchange_remove(hm%oct_exchange)
377
378 hm%adjoint = .false.
379
380 call hm%phase%init(gr, hm%d%kpt, hm%kpoints, st%d, space)
381
382 !%Variable DFTULevel
383 !%Type integer
384 !%Default no
385 !%Section Hamiltonian::XC
386 !%Description
387 !% This variable selects which DFT+U expression is added to the Hamiltonian.
388 !%Option dft_u_none 0
389 !% No +U term is not applied.
390 !%Option dft_u_empirical 1
391 !% An empiricial Hubbard U is added on the orbitals specified in the block species
392 !% with hubbard_l and hubbard_u
393 !%Option dft_u_acbn0 2
394 !% Octopus determines the effective U term using the
395 !% ACBN0 functional as defined in PRX 5, 011006 (2015)
396 !%End
397 call parse_variable(namespace, 'DFTULevel', dft_u_none, hm%lda_u_level)
398 call messages_print_var_option('DFTULevel', hm%lda_u_level, namespace=namespace)
399 if (hm%lda_u_level /= dft_u_none) then
400 call lda_u_init(hm%lda_u, namespace, space, hm%lda_u_level, gr, ions, st, mc, &
401 hm%kpoints, hm%phase%is_allocated())
402
403 !In the present implementation of DFT+U, in case of spinors, we have off-diagonal terms
404 !in spin space which break the assumption of the generalized Bloch theorem
405 if (kick_get_type(hm%kick) == kick_magnon_mode .and. gr%der%boundaries%spiral) then
406 call messages_not_implemented("DFT+U with generalized Bloch theorem and magnon kick", namespace=namespace)
407 end if
408
409 ! We rebuild the phase for the orbital projection, similarly to the one of the pseudopotentials
410 if(hm%lda_u_level /= dft_u_none .and. hm%phase%is_allocated()) then
411 call lda_u_build_phase_correction(hm%lda_u, space, hm%d, gr%der%boundaries, namespace, hm%kpoints)
412 end if
413 end if
414
415 !%Variable HamiltonianApplyPacked
416 !%Type logical
417 !%Default yes
418 !%Section Execution::Optimization
419 !%Description
420 !% If set to yes (the default), Octopus will 'pack' the
421 !% wave-functions when operating with them. This might involve some
422 !% additional copying but makes operations more efficient.
423 !% See also the related <tt>StatesPack</tt> variable.
424 !%End
425 call parse_variable(namespace, 'HamiltonianApplyPacked', .true., hm%is_applied_packed)
426
427 if (hm%theory_level == hartree_fock .and. st%parallel_in_states) then
428 call messages_experimental('Hartree-Fock parallel in states', namespace=namespace)
429 end if
430
431 if (hm%theory_level == generalized_kohn_sham_dft .and. family_is_hybrid(hm%xc) &
432 .and. st%parallel_in_states) then
433 call messages_experimental('Hybrid functionals parallel in states', namespace=namespace)
434 end if
435
436
437 !%Variable TimeZero
438 !%Type logical
439 !%Default no
440 !%Section Hamiltonian
441 !%Description
442 !% (Experimental) If set to yes, the ground state and other time
443 !% dependent calculation will assume that they are done at time
444 !% zero, so that all time depedent field at that time will be
445 !% included.
446 !%End
447 call parse_variable(namespace, 'TimeZero', .false., hm%time_zero)
448 if (hm%time_zero) call messages_experimental('TimeZero', namespace=namespace)
449
450 !Cam parameters are irrelevant here and are updated later
451 need_exchange_ = optional_default(need_exchange, .false.)
452 if (hm%theory_level == hartree_fock .or. hm%theory_level == hartree &
453 .or. hm%theory_level == rdmft .or. need_exchange_ .or. &
454 (hm%theory_level == generalized_kohn_sham_dft .and. family_is_hybrid(hm%xc)) &
455 .or. hm%xc%functional(func_x,1)%id == xc_oep_x_slater &
456 .or. bitand(hm%xc%family, xc_family_oep) /= 0) then
457 !We test Slater before OEP, as Slater is treated as OEP for the moment....
458 if (hm%xc%functional(func_x,1)%id == xc_oep_x_slater) then
459 call exchange_operator_init(hm%exxop, namespace, space, st, gr%der, mc, gr%stencil, &
460 hm%kpoints, cam_exact_exchange)
461 else if (bitand(hm%xc%family, xc_family_oep) /= 0 .or. hm%theory_level == rdmft) then
462 call exchange_operator_init(hm%exxop, namespace, space, st, gr%der, mc, gr%stencil, &
463 hm%kpoints, hm%xc%cam)
464 if (hm%theory_level == rdmft) hm%exxop%useACE = .false.
465 else
466 call exchange_operator_init(hm%exxop, namespace, space, st, gr%der, mc, gr%stencil, &
467 hm%kpoints, cam_exact_exchange)
468 end if
469 end if
470
471 if (hm%is_applied_packed .and. accel_is_enabled()) then
472 ! Check if we can actually apply the hamiltonian packed
473 if (gr%use_curvilinear) then
474 if (accel_allow_cpu_only()) then
475 hm%is_applied_packed = .false.
476 call messages_write('Cannot use CUDA or OpenCL as curvilinear coordinates are used.')
477 call messages_warning(namespace=namespace)
478 else
479 call messages_write('Cannot use CUDA or OpenCL as curvilinear coordinates are used.', new_line = .true.)
480 call messages_write('Calculation will not be continued. To force execution, set AllowCPUonly = yes.')
481 call messages_fatal(namespace=namespace)
482 end if
483 end if
484 end if
485
486 !We are building the list of external potentials
487 !This is done here at the moment, because we pass directly the mesh
488 !TODO: Once the abstract Hamiltonian knows about an abstract basis, we might move this to the
489 ! abstract Hamiltonian
490 call load_external_potentials(hm%external_potentials, namespace)
491
492 !Some checks which are electron specific, like k-points
494
495 !At the moment we do only have static external potential, so we never update them
497
498 !Build the resulting interactions
499 !TODO: This will be moved to the actual interactions
500 call build_interactions()
501
502 ! Constrained DFT for noncollinear magnetism
503 if (hm%theory_level /= independent_particles) then
504 call magnetic_constrain_init(hm%magnetic_constrain, namespace, gr, st%d, ions%natoms, ions%min_distance())
505 end if
506
507 ! init maxwell-electrons coupling
508 call mxll_coupling_init(hm%mxll, st%d, gr, namespace, hm%mass)
509
510 if (associated(hm%xc_photons)) then
511 if (hm%xc_photons%wants_to_renormalize_mass()) then
512 ! remornalize the electron mass due to light-matter interaction; here we only deal with it in free space
513 call hm%set_mass(namespace, hm%xc_photons%get_renormalized_mass())
514 end if
515 end if
516
517
518 call profiling_out('HAMILTONIAN_ELEC_INIT')
519 pop_sub(hamiltonian_elec_init)
520
521 contains
522
523 ! ---------------------------------------------------------
524 subroutine build_external_potentials()
525 type(list_iterator_t) :: iter
526 class(*), pointer :: potential
527 integer :: iop
528
530
531 safe_allocate(hm%v_ext_pot(1:gr%np))
532 hm%v_ext_pot(1:gr%np) = m_zero
533
534 call iter%start(hm%external_potentials)
535 do while (iter%has_next())
536 potential => iter%get_next()
537 select type (potential)
538 class is (external_potential_t)
539
540 call potential%allocate_memory(gr)
541 call potential%calculate(namespace, gr, hm%psolver)
542 !To preserve the old behavior, we are adding the various potentials
543 !to the corresponding arrays
544 select case (potential%type)
546 call lalg_axpy(gr%np, m_one, potential%pot, hm%v_ext_pot)
547
549 if (states_are_real(st)) then
550 message(1) = "Cannot use static magnetic field with real wavefunctions"
551 call messages_fatal(1, namespace=namespace)
552 end if
553
554 if (.not. allocated(hm%ep%b_field)) then
555 safe_allocate(hm%ep%b_field(1:3)) !Cannot be space%dim
556 hm%ep%b_field(1:3) = m_zero
557 end if
558 hm%ep%b_field(1:3) = hm%ep%b_field(1:3) + potential%b_field(1:3)
559
560 if (.not. allocated(hm%ep%a_static)) then
561 safe_allocate(hm%ep%a_static(1:gr%np, 1:space%dim))
562 hm%ep%a_static(1:gr%np, 1:space%dim) = m_zero
563 end if
564 call lalg_axpy(gr%np, space%dim, m_one, potential%a_static, hm%ep%a_static)
565
567 if (.not. allocated(hm%ep%e_field)) then
568 safe_allocate(hm%ep%e_field(1:space%dim))
569 hm%ep%e_field(1:space%dim) = m_zero
570 end if
571 hm%ep%e_field(1:space%dim) = hm%ep%e_field(1:space%dim) + potential%e_field(1:space%dim)
572
573 !In the fully periodic case, we use Berry phases
574 if (space%periodic_dim < space%dim) then
575 if (.not. allocated(hm%v_static)) then
576 safe_allocate(hm%v_static(1:gr%np))
577 hm%v_static(1:gr%np) = m_zero
578 end if
579 if (.not. allocated(hm%ep%v_ext)) then
580 safe_allocate(hm%ep%v_ext(1:gr%np_part))
581 hm%ep%v_ext(1:gr%np_part) = m_zero
582 end if
583 call lalg_axpy(gr%np, m_one, potential%pot, hm%v_static)
584 call lalg_axpy(gr%np, m_one, potential%v_ext, hm%ep%v_ext)
585 end if
586
587 if (hm%kpoints%use_symmetries) then
588 do iop = 1, symmetries_number(hm%kpoints%symm)
589 if (iop == symmetries_identity_index(hm%kpoints%symm)) cycle
590 if (.not. symm_op_invariant_cart(hm%kpoints%symm%ops(iop), hm%ep%e_field, 1e-5_real64)) then
591 message(1) = "The StaticElectricField breaks (at least) one of the symmetries used to reduce the k-points."
592 message(2) = "Set SymmetryBreakDir equal to StaticElectricField."
593 call messages_fatal(2, namespace=namespace)
594 end if
595 end do
596 end if
597
598 end select
599 call potential%deallocate_memory()
600
601 class default
602 assert(.false.)
603 end select
604 end do
605
607 end subroutine build_external_potentials
608
609 ! ---------------------------------------------------------
610 subroutine external_potentials_checks()
611 type(list_iterator_t) :: iter
612 class(*), pointer :: potential
613
615
616 call iter%start(hm%external_potentials)
617 do while (iter%has_next())
618 potential => iter%get_next()
619 select type (potential)
620 class is (external_potential_t)
621
622 if (potential%type == external_pot_static_efield .and. hm%kpoints%reduced%npoints > 1) then
623 message(1) = "Applying StaticElectricField in a periodic direction is only accurate for large supercells."
624 message(2) = "Single-point Berry phase is not appropriate when k-point sampling is needed."
625 call messages_warning(2, namespace=namespace)
626 end if
627
628 class default
629 assert(.false.)
630 end select
631 end do
632
634 end subroutine external_potentials_checks
635
636
637 !The code in this routines needs to know about the external potentials.
638 !This will be treated in the future by the interactions directly.
639 subroutine build_interactions()
640 logical :: external_potentials_present
641 logical :: kick_present
642
644
645 if (allocated(hm%ep%e_field) .and. space%is_periodic() .and. .not. list_has_gauge_field(ext_partners)) then
646 ! only need vberry if there is a field in a periodic direction
647 ! and we are not setting a gauge field
648 if (any(abs(hm%ep%e_field(1:space%periodic_dim)) > m_epsilon)) then
649 safe_allocate(hm%vberry(1:gr%np, 1:hm%d%nspin))
650 hm%vberry = m_zero
651 end if
652 end if
653
654 external_potentials_present = epot_have_external_potentials(hm%ep) .or. &
655 list_has_lasers(ext_partners) .or. allocated(hm%v_static)
656
657
658 kick_present = hamiltonian_elec_has_kick(hm)
659
660 call pcm_init(hm%pcm, namespace, space, ions, gr, st%qtot, st%val_charge, external_potentials_present, kick_present)
661 if (hm%pcm%run_pcm) then
662 if (hm%theory_level /= kohn_sham_dft) call messages_not_implemented("PCM for TheoryLevel /= kohn_sham", namespace=namespace)
663 end if
664
666
667 end subroutine build_interactions
668
669
670 end subroutine hamiltonian_elec_init
671
672
673 ! ---------------------------------------------------------
674 subroutine hamiltonian_elec_end(hm)
675 type(hamiltonian_elec_t), target, intent(inout) :: hm
676
677 type(partner_iterator_t) :: iter
678 class(interaction_partner_t), pointer :: potential
679
680 push_sub(hamiltonian_elec_end)
681
682 call hm%hm_base%end()
683 call hm%vnl%end()
684
685 call hm%phase%end()
686
687 call hm%ks_pot%end()
688 safe_deallocate_a(hm%vberry)
689 safe_deallocate_a(hm%a_ind)
690 safe_deallocate_a(hm%b_ind)
691 safe_deallocate_a(hm%v_ext_pot)
692
693 safe_deallocate_p(hm%zora)
694
695 call poisson_end(hm%psolver)
696
697 nullify(hm%xc)
698
699 call kick_end(hm%kick)
700 call epot_end(hm%ep)
701 nullify(hm%ions)
702
703 call absorbing_boundaries_end(hm%abs_boundaries)
704
706
707 if (hm%scissor%apply) call scissor_end(hm%scissor)
708
709 call exchange_operator_end(hm%exxop)
710 call lda_u_end(hm%lda_u)
711
712 safe_deallocate_a(hm%energy)
713
714 if (hm%pcm%run_pcm) call pcm_end(hm%pcm)
715
716 call hm%v_ie_loc%end()
717 call hm%nlcc%end()
718
719 call iter%start(hm%external_potentials)
720 do while (iter%has_next())
721 potential => iter%get_next()
722 safe_deallocate_p(potential)
723 end do
724 call hm%external_potentials%empty()
725 safe_deallocate_a(hm%v_static)
726
727 call magnetic_constrain_end(hm%magnetic_constrain)
728
729 call mxll_coupling_end(hm%mxll)
730
731 pop_sub(hamiltonian_elec_end)
732 end subroutine hamiltonian_elec_end
733
735 ! ---------------------------------------------------------
736 ! True if the Hamiltonian is Hermitian, false otherwise
737 logical function hamiltonian_elec_hermitian(hm)
738 class(hamiltonian_elec_t), intent(in) :: hm
739
741 hamiltonian_elec_hermitian = .not.((hm%abs_boundaries%abtype == imaginary_absorbing) .or. &
742 oct_exchange_enabled(hm%oct_exchange))
743
745 end function hamiltonian_elec_hermitian
746
747 ! ---------------------------------------------------------
748 ! True if the Hamiltonian needs to apply the mGGA term
749 pure logical function hamiltonian_elec_needs_mgga_term(hm, terms)
750 class(hamiltonian_elec_t), intent(in) :: hm
751 integer, intent(in) :: terms
752
754
755 if (bitand(term_mgga, terms) /= 0 .and. family_is_mgga_with_exc(hm%xc) &
756 .and. hm%theory_level == generalized_kohn_sham_dft) then
758 end if
759
760 !For OEP
761 if(terms == term_mgga .and. family_is_mgga_with_exc(hm%xc) .and. hm%theory_level == kohn_sham_dft) then
763 end if
764
766
767
768
769 ! ---------------------------------------------------------
770 subroutine hamiltonian_elec_span(hm, delta, emin, namespace)
771 class(hamiltonian_elec_t), intent(inout) :: hm
772 real(real64), intent(in) :: delta(:)
773 real(real64), intent(in) :: emin
774 type(namespace_t), intent(in) :: namespace
775
776 real(real64) :: emax
777
778 push_sub(hamiltonian_elec_span)
779
780 ! estimate maximum energy of discrete kinetic operator
781 ! this neglects possible contributions from the non-local part of the pseudopotentials
783
784 hm%spectral_middle_point = (emax + emin) / m_two
785 hm%spectral_half_span = (emax - emin) / m_two
786
787 pop_sub(hamiltonian_elec_span)
788 end subroutine hamiltonian_elec_span
789
790
791 ! ---------------------------------------------------------
792 pure logical function hamiltonian_elec_inh_term(hm) result(inh)
793 type(hamiltonian_elec_t), intent(in) :: hm
794
795 inh = hm%inh_term
796 end function hamiltonian_elec_inh_term
797
798
799 ! ---------------------------------------------------------
800 subroutine hamiltonian_elec_set_inh(hm, st)
801 type(hamiltonian_elec_t), intent(inout) :: hm
802 type(states_elec_t), intent(in) :: st
803
805
806 if (hm%inh_term) call states_elec_end(hm%inh_st)
807 call states_elec_copy(hm%inh_st, st)
808 hm%inh_term = .true.
809
811 end subroutine hamiltonian_elec_set_inh
812
813
814 ! ---------------------------------------------------------
815 subroutine hamiltonian_elec_remove_inh(hm)
816 type(hamiltonian_elec_t), intent(inout) :: hm
817
819
820 if (hm%inh_term) then
821 call states_elec_end(hm%inh_st)
822 hm%inh_term = .false.
823 end if
824
826 end subroutine hamiltonian_elec_remove_inh
827
828 ! ---------------------------------------------------------
829 subroutine hamiltonian_elec_adjoint(hm)
830 type(hamiltonian_elec_t), intent(inout) :: hm
831
833
834 if (.not. hm%adjoint) then
835 hm%adjoint = .true.
836 if (hm%abs_boundaries%abtype == imaginary_absorbing) then
837 hm%abs_boundaries%mf = -hm%abs_boundaries%mf
838 end if
839 end if
840
842 end subroutine hamiltonian_elec_adjoint
843
845 ! ---------------------------------------------------------
846 subroutine hamiltonian_elec_not_adjoint(hm)
847 type(hamiltonian_elec_t), intent(inout) :: hm
848
850
851 if (hm%adjoint) then
852 hm%adjoint = .false.
853 if (hm%abs_boundaries%abtype == imaginary_absorbing) then
854 hm%abs_boundaries%mf = -hm%abs_boundaries%mf
855 end if
856 end if
857
859 end subroutine hamiltonian_elec_not_adjoint
860
861
862 ! ---------------------------------------------------------
864 subroutine hamiltonian_elec_update(this, mesh, namespace, space, ext_partners, time)
865 class(hamiltonian_elec_t), intent(inout) :: this
866 class(mesh_t), intent(in) :: mesh
867 type(namespace_t), intent(in) :: namespace
868 class(space_t), intent(in) :: space
869 type(partner_list_t), intent(in) :: ext_partners
870 real(real64), optional, intent(in) :: time
871
872 integer :: ispin, ip, idir, iatom, ilaser
873 real(real64) :: aa(space%dim), time_
874 real(real64), allocatable :: vp(:,:)
875 type(lasers_t), pointer :: lasers
876 type(gauge_field_t), pointer :: gfield
877 real(real64) :: am(space%dim)
878
880 call profiling_in("HAMILTONIAN_ELEC_UPDATE")
881
882 this%current_time = m_zero
883 if (present(time)) this%current_time = time
884
885 time_ = optional_default(time, 0.0_real64)
886
887 ! set everything to zero
888 call this%hm_base%clear(mesh%np)
889
890 ! alllocate the scalar potential for the xc, hartree and external potentials
891 call this%hm_base%allocate_field(mesh, field_potential, &
892 complex_potential = this%abs_boundaries%abtype == imaginary_absorbing)
893
894 ! the lasers
895 if (present(time) .or. this%time_zero) then
896
897 lasers => list_get_lasers(ext_partners)
898 if(associated(lasers)) then
899 do ilaser = 1, lasers%no_lasers
900 select case (laser_kind(lasers%lasers(ilaser)))
902 do ispin = 1, this%d%spin_channels
903 call laser_potential(lasers%lasers(ilaser), mesh, &
904 this%hm_base%potential(:, ispin), time_)
905 end do
906 case (e_field_magnetic)
907 call this%hm_base%allocate_field(mesh, field_vector_potential + field_uniform_magnetic_field, &
908 .false.)
909 ! get the vector potential
910 safe_allocate(vp(1:mesh%np, 1:space%dim))
911 vp(1:mesh%np, 1:space%dim) = m_zero
912 call laser_vector_potential(lasers%lasers(ilaser), mesh, vp, time_)
913 !$omp parallel do private(idir) schedule(static)
914 do ip = 1, mesh%np
915 do idir = 1, space%dim
916 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) + vp(ip, idir)/p_c
917 end do
918 end do
919 ! and the magnetic field
920 call laser_field(lasers%lasers(ilaser), this%hm_base%uniform_magnetic_field(1:space%dim), time_)
921 safe_deallocate_a(vp)
923 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
924 ! get the uniform vector potential associated with a magnetic field
925 aa = m_zero
926 call laser_field(lasers%lasers(ilaser), aa, time_)
927 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - aa/p_c
928 end select
929 end do
930
931 if (lasers_with_nondipole_field(lasers)) then
932 assert( allocated(this%hm_base%uniform_vector_potential))
933 call lasers_nondipole_laser_field_step(lasers, am, time_)
934 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - am/p_c
935 end if
936 end if
937
938 ! the gauge field
939 gfield => list_get_gauge_field(ext_partners)
940 if (associated(gfield)) then
941 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
942 call gauge_field_get_vec_pot(gfield, aa)
943 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - aa/p_c
944 end if
945
946 ! the electric field for a periodic system through the gauge field
947 if (allocated(this%ep%e_field) .and. associated(gfield)) then
948 this%hm_base%uniform_vector_potential(1:space%periodic_dim) = &
949 this%hm_base%uniform_vector_potential(1:space%periodic_dim) - time_*this%ep%e_field(1:space%periodic_dim)
950 end if
951
952 ! add the photon-free mean-field vector potential
953 if (associated(this%xc_photons)) then
954 if(this%xc_photons%lpfmf .and. allocated(this%xc_photons%mf_vector_potential)) then
955 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
956 ! here we put a minus sign in front of the mean field term to get the right answer (need to check the formula)
957 this%hm_base%uniform_vector_potential(1:space%dim) = &
958 this%hm_base%uniform_vector_potential(1:space%dim) - this%xc_photons%mf_vector_potential(1:space%dim)/p_c
959 end if
960 end if
961
962 end if
963
964 ! the vector potential of a static magnetic field
965 if (allocated(this%ep%a_static)) then
966 call this%hm_base%allocate_field(mesh, field_vector_potential, .false.)
967 !ep%a_static contains 1/c A(r)
968 !$omp parallel do private(idir) schedule(static)
969 do ip = 1, mesh%np
970 do idir = 1, space%dim
971 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) + this%ep%a_static(ip, idir)
972 end do
973 end do
974 end if
975
976 ! add Maxwell coupling to Hamiltonian and sets the magnetic field for the Zeeman term added below
977 call mxll_coupling_calc(this%mxll, this%hm_base, mesh, this%d, space)
978
979 !The electric field was added to the KS potential
980 call this%hm_base%accel_copy_pot(mesh)
981
982 ! and the static magnetic field
983 if (allocated(this%ep%b_field)) then
984 call this%hm_base%allocate_field(mesh, field_uniform_magnetic_field, .false.)
985 do idir = 1, 3
986 this%hm_base%uniform_magnetic_field(idir) = this%hm_base%uniform_magnetic_field(idir) + this%ep%b_field(idir)
987 end do
988 end if
989
990 ! Combine the uniform and non-uniform fields and compute the Zeeman term
991 call this%hm_base%update_magnetic_terms(mesh, this%ep%gyromagnetic_ratio, this%d%ispin)
992
993 ! This needs to be called at the end as the zeeman term enters the potential
994 call hamiltonian_elec_update_pot(this, mesh, accumulate = .true.)
995
996 if (this%mxll%test_equad) then
997 call set_electric_quadrupole_pot(this%mxll, mesh)
998 end if
999
1000 call build_phase()
1001
1002 call profiling_out("HAMILTONIAN_ELEC_UPDATE")
1004
1005 contains
1006
1007 subroutine build_phase()
1008 integer :: ik, imat, nmat, max_npoints, offset
1009 integer :: ip
1010 integer :: iphase, nphase
1011
1013
1014 if ((.not. this%kpoints%gamma_only()) .or. allocated(this%hm_base%uniform_vector_potential)) then
1015
1016 call profiling_in('UPDATE_PHASES')
1017 ! now regenerate the phases for the pseudopotentials
1018 do iatom = 1, this%ep%natoms
1019 call projector_init_phases(this%ep%proj(iatom), space%dim, this%d, this%der%boundaries, this%kpoints, &
1020 vec_pot = this%hm_base%uniform_vector_potential, vec_pot_var = this%hm_base%vector_potential)
1021 end do
1022
1023 call profiling_out('UPDATE_PHASES')
1024 end if
1025
1026 if (allocated(this%hm_base%uniform_vector_potential)) then
1027
1028 call this%phase%update(mesh, this%d%kpt, this%kpoints, this%d, space, this%hm_base%uniform_vector_potential)
1029
1030 ! We rebuild the phase for the orbital projection, similarly to the one of the pseudopotentials
1031 if (this%lda_u_level /= dft_u_none) then
1032 call lda_u_build_phase_correction(this%lda_u, space, this%d, this%der%boundaries, namespace, this%kpoints, &
1033 vec_pot = this%hm_base%uniform_vector_potential, vec_pot_var = this%hm_base%vector_potential)
1034 end if
1035 end if
1036
1037 max_npoints = this%vnl%max_npoints
1038 nmat = this%vnl%nprojector_matrices
1039
1040
1041 if (this%phase%is_allocated() .and. allocated(this%vnl%projector_matrices)) then
1042
1043 nphase = 1
1044 if (this%der%boundaries%spiralBC) nphase = 3
1045
1046 if (.not. allocated(this%vnl%projector_phases)) then
1047 safe_allocate(this%vnl%projector_phases(1:max_npoints, 1:nphase, nmat, this%d%kpt%start:this%d%kpt%end))
1048 if (accel_is_enabled()) then
1049 call accel_create_buffer(this%vnl%buff_projector_phases, accel_mem_read_only, &
1050 type_cmplx, this%vnl%total_points*nphase*this%d%kpt%nlocal)
1051 ! We need to save nphase, with which the array has been build,
1052 ! as the number might change throughout the run
1053 this%vnl%nphase = nphase
1054 end if
1055 end if
1056
1057 offset = 0
1058 do ik = this%d%kpt%start, this%d%kpt%end
1059 do imat = 1, this%vnl%nprojector_matrices
1060 iatom = this%vnl%projector_to_atom(imat)
1061 do iphase = 1, nphase
1062 !$omp parallel do simd schedule(static)
1063 do ip = 1, this%vnl%projector_matrices(imat)%npoints
1064 this%vnl%projector_phases(ip, iphase, imat, ik) = this%ep%proj(iatom)%phase(ip, iphase, ik)
1065 end do
1066
1067 if (accel_is_enabled() .and. this%vnl%projector_matrices(imat)%npoints > 0) then
1068 call accel_write_buffer(this%vnl%buff_projector_phases, &
1069 this%vnl%projector_matrices(imat)%npoints, this%vnl%projector_phases(1:, iphase, imat, ik), &
1070 offset = offset, async=.true.)
1071 end if
1072 offset = offset + this%vnl%projector_matrices(imat)%npoints
1073 end do
1074 end do
1075 end do
1076
1077 end if
1078
1079 call accel_finish()
1080
1082 end subroutine build_phase
1083
1084 end subroutine hamiltonian_elec_update
1085
1086
1087 !----------------------------------------------------------------
1090 ! TODO: See Issue #1064
1091 subroutine hamiltonian_elec_update_pot(this, mesh, accumulate)
1092 type(hamiltonian_elec_t), intent(inout) :: this
1093 class(mesh_t), intent(in) :: mesh
1094 logical, optional, intent(in) :: accumulate
1095
1096 integer :: ispin, ip
1097
1099
1100 ! By default we nullify first the result
1101 if (.not. optional_default(accumulate, .false.)) then
1102 !$omp parallel private(ip, ispin)
1103 do ispin = 1, this%d%nspin
1104 !$omp do simd schedule(static)
1105 do ip = 1, mesh%np
1106 this%hm_base%potential(ip, ispin) = m_zero
1107 end do
1108 end do
1109 !$omp end parallel
1110 end if
1111
1112 !$omp parallel private(ip, ispin)
1113 do ispin = 1, this%d%nspin
1114 if (ispin <= 2) then
1115 !$omp do simd schedule(static)
1116 ! this%vhxc(ip, ispin) is added after the calculation of ZORA potential
1117 do ip = 1, mesh%np
1118 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + this%ep%vpsl(ip) + this%v_ext_pot(ip)
1119 end do
1120
1122 if (this%pcm%run_pcm) then
1123 if (this%pcm%solute) then
1124 !$omp do simd schedule(static)
1125 do ip = 1, mesh%np
1126 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + &
1127 this%pcm%v_e_rs(ip) + this%pcm%v_n_rs(ip)
1128 end do
1129 !$omp end do simd nowait
1130 end if
1131 if (this%pcm%localf) then
1132 !$omp do simd schedule(static)
1133 do ip = 1, mesh%np
1134 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + &
1135 this%pcm%v_ext_rs(ip)
1136 end do
1137 !$omp end do simd nowait
1138 end if
1139 end if
1140
1142 if (this%abs_boundaries%abtype == imaginary_absorbing) then
1143 !$omp do simd schedule(static)
1144 do ip = 1, mesh%np
1145 this%hm_base%Impotential(ip, ispin) = this%hm_base%Impotential(ip, ispin) + this%abs_boundaries%mf(ip)
1146 end do
1147 !$omp end do simd nowait
1148 end if
1149 end if
1150 end do
1151 !$omp end parallel
1152
1153 ! scalar relativistic ZORA contribution
1154 ! \boldsymbol{p} \frac{c^2}{2c^2 - V} \boldsymbol{p} \Phi^\mathrm{ZORA}
1155 if (this%ep%reltype == scalar_relativistic_zora .or. this%ep%reltype == fully_relativistic_zora) then
1156 call this%zora%update(this%der, this%hm_base%potential)
1157 end if
1158
1159 !$omp parallel private(ip, ispin)
1160 do ispin = 1, this%d%nspin
1161 ! Adding Zeeman potential to hm_base%potential
1162 if (allocated(this%hm_base%zeeman_pot)) then
1163 !$omp do simd schedule(static)
1164 do ip = 1, mesh%np
1165 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + this%hm_base%zeeman_pot(ip, ispin)
1166 end do
1167 !$omp end do simd nowait
1168 end if
1169
1170 ! Adding Quadrupole potential from static E-field (test)
1171 if (this%mxll%test_equad) then
1172 !$omp do simd schedule(static)
1173 do ip = 1, mesh%np
1174 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + this%mxll%e_quadrupole_pot(ip)
1175 end do
1176 !$omp end do simd
1177 end if
1178 end do
1179 !$omp end parallel
1180
1181
1182 ! Add the Hartree and KS potential
1183 call this%ks_pot%add_vhxc(this%hm_base%potential)
1184
1185 call this%hm_base%accel_copy_pot(mesh)
1188 end subroutine hamiltonian_elec_update_pot
1189
1190 ! ---------------------------------------------------------
1191 subroutine hamiltonian_elec_epot_generate(this, namespace, space, gr, ions, ext_partners, st, time)
1192 type(hamiltonian_elec_t), intent(inout) :: this
1193 type(namespace_t), intent(in) :: namespace
1194 class(electron_space_t), intent(in) :: space
1195 type(grid_t), intent(in) :: gr
1196 type(ions_t), target, intent(inout) :: ions
1197 type(partner_list_t), intent(in) :: ext_partners
1198 type(states_elec_t), intent(inout) :: st
1199 real(real64), optional, intent(in) :: time
1200
1202
1203 this%ions => ions
1204 call epot_generate(this%ep, namespace, gr, this%ions, this%d)
1205
1206 ! Interation terms are treated below
1207
1208 ! First we add the static electric field
1209 if (allocated(this%ep%e_field) .and. space%periodic_dim < space%dim) then
1210 call lalg_axpy(gr%np, m_one, this%v_static, this%ep%vpsl)
1211 end if
1212
1213 ! Here we need to pass this again, else test are failing.
1214 ! This is not a real problem, as the multisystem framework will indeed to this anyway
1215 this%v_ie_loc%atoms_dist => ions%atoms_dist
1216 this%v_ie_loc%atom => ions%atom
1217 call this%v_ie_loc%calculate()
1218
1219 ! At the moment we need to add this to ep%vpsl, to keep the behavior of the code
1220 call lalg_axpy(gr%np, m_one, this%v_ie_loc%potential(:,1), this%ep%vpsl)
1221
1222 ! Here we need to pass this again, else test are failing.
1223 ! This is not a real problem, as the multisystem framework will indeed to this anyway
1224 if (this%ep%nlcc) then
1225 this%nlcc%atoms_dist => ions%atoms_dist
1226 this%nlcc%atom => ions%atom
1227 call this%nlcc%calculate()
1228 call lalg_copy(gr%np, this%nlcc%density(:,1), st%rho_core)
1229 end if
1230
1231 call this%vnl%build(space, gr, this%ep)
1232 call hamiltonian_elec_update(this, gr, namespace, space, ext_partners, time)
1233
1234 ! Check if projectors are still compatible with apply_packed on GPU
1235 if (this%is_applied_packed .and. accel_is_enabled()) then
1236 if (this%ep%non_local .and. .not. this%vnl%apply_projector_matrices) then
1237 if (accel_allow_cpu_only()) then
1238 call messages_write('Relativistic pseudopotentials have not been fully implemented for CUDA or OpenCL.')
1239 call messages_warning(namespace=namespace)
1240 else
1241 call messages_write('Relativistic pseudopotentials have not been fully implemented for CUDA or OpenCL.',&
1242 new_line = .true.)
1243 call messages_write('Calculation will not be continued. To force execution, set AllowCPUonly = yes.')
1244 call messages_fatal(namespace=namespace)
1245 end if
1246 end if
1247
1248 end if
1249
1250 if (this%pcm%run_pcm) then
1253 if (this%pcm%solute) then
1254 call pcm_calc_pot_rs(this%pcm, gr, this%psolver, ions = ions)
1255 end if
1256
1259 ! Interpolation is needed, hence gr%np_part -> 1:gr%np
1260 if (this%pcm%localf .and. allocated(this%v_static)) then
1261 call pcm_calc_pot_rs(this%pcm, gr, this%psolver, v_ext = this%ep%v_ext(1:gr%np_part))
1262 end if
1263
1264 end if
1265
1266 call lda_u_update_basis(this%lda_u, space, gr, ions, st, this%psolver, namespace, this%kpoints, &
1267 this%phase%is_allocated())
1268
1270 end subroutine hamiltonian_elec_epot_generate
1271
1272 ! -----------------------------------------------------------------
1273
1274 real(real64) function hamiltonian_elec_get_time(this) result(time)
1275 type(hamiltonian_elec_t), intent(inout) :: this
1276
1277 time = this%current_time
1278 end function hamiltonian_elec_get_time
1279
1280 ! -----------------------------------------------------------------
1281
1282 pure logical function hamiltonian_elec_apply_packed(this) result(apply)
1283 class(hamiltonian_elec_t), intent(in) :: this
1284
1285 apply = this%is_applied_packed
1288
1289
1290 ! -----------------------------------------------------------------
1291 subroutine zhamiltonian_elec_apply_atom (hm, namespace, space, latt, species, pos, ia, mesh, psi, vpsi)
1292 type(hamiltonian_elec_t), intent(in) :: hm
1293 type(namespace_t), intent(in) :: namespace
1294 class(space_t), intent(in) :: space
1295 type(lattice_vectors_t), intent(in) :: latt
1296 class(species_t), intent(in) :: species
1297 real(real64), intent(in) :: pos(1:space%dim)
1298 integer, intent(in) :: ia
1299 class(mesh_t), intent(in) :: mesh
1300 complex(real64), intent(in) :: psi(:,:)
1301 complex(real64), intent(out) :: vpsi(:,:)
1302
1303 integer :: idim
1304 real(real64), allocatable :: vlocal(:)
1306
1307 safe_allocate(vlocal(1:mesh%np_part))
1308 vlocal = m_zero
1309 call epot_local_potential(hm%ep, namespace, space, latt, mesh, species, pos, ia, vlocal)
1310
1311 do idim = 1, hm%d%dim
1312 vpsi(1:mesh%np, idim) = vlocal(1:mesh%np) * psi(1:mesh%np, idim)
1313 end do
1314
1315 safe_deallocate_a(vlocal)
1317 end subroutine zhamiltonian_elec_apply_atom
1318
1319 ! ---------------------------------------------------------
1324 subroutine hamiltonian_elec_update_with_ext_pot(this, mesh, space, ext_partners, time, mu)
1325 type(hamiltonian_elec_t), intent(inout) :: this
1326 class(space_t), intent(in) :: space
1327 class(mesh_t), intent(in) :: mesh
1328 type(partner_list_t), intent(in) :: ext_partners
1329 real(real64), intent(in) :: time(1:2)
1330 real(real64), intent(in) :: mu(1:2)
1331
1332 integer :: ispin, ip, idir, iatom, ilaser, itime
1333 real(real64) :: aa(space%dim), time_
1334 real(real64), allocatable :: vp(:,:)
1335 real(real64), allocatable :: velectric(:)
1336 type(lasers_t), pointer :: lasers
1337 type(gauge_field_t), pointer :: gfield
1338
1340 call profiling_in("HAMILTONIAN_ELEC_UPDATE_EXT_POT")
1341
1342 this%current_time = m_zero
1343 this%current_time = time(1)
1344
1345 ! set everything to zero
1346 call this%hm_base%clear(mesh%np)
1347
1348 ! the xc, hartree and external potentials
1349 call this%hm_base%allocate_field(mesh, field_potential, &
1350 complex_potential = this%abs_boundaries%abtype == imaginary_absorbing)
1351
1352 do itime = 1, 2
1353 time_ = time(itime)
1354
1355 lasers => list_get_lasers(ext_partners)
1356 if(associated(lasers)) then
1357 do ilaser = 1, lasers%no_lasers
1358 select case (laser_kind(lasers%lasers(ilaser)))
1359 case (e_field_scalar_potential, e_field_electric)
1360 safe_allocate(velectric(1:mesh%np))
1361 do ispin = 1, this%d%spin_channels
1362 velectric = m_zero
1363 call laser_potential(lasers%lasers(ilaser), mesh, velectric, time_)
1364 !$omp parallel do simd schedule(static)
1365 do ip = 1, mesh%np
1366 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + mu(itime) * velectric(ip)
1367 end do
1368 end do
1369 safe_deallocate_a(velectric)
1370 case (e_field_magnetic)
1371 call this%hm_base%allocate_field(mesh, field_vector_potential + field_uniform_magnetic_field, .false.)
1372 ! get the vector potential
1373 safe_allocate(vp(1:mesh%np, 1:space%dim))
1374 vp(1:mesh%np, 1:space%dim) = m_zero
1375 call laser_vector_potential(lasers%lasers(ilaser), mesh, vp, time_)
1376 do idir = 1, space%dim
1377 !$omp parallel do schedule(static)
1378 do ip = 1, mesh%np
1379 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) &
1380 - mu(itime) * vp(ip, idir)/p_c
1381 end do
1382 end do
1383 ! and the magnetic field
1384 call laser_field(lasers%lasers(ilaser), this%hm_base%uniform_magnetic_field(1:space%dim), time_)
1385 safe_deallocate_a(vp)
1386 case (e_field_vector_potential)
1387 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
1388 ! get the uniform vector potential associated with a magnetic field
1389 aa = m_zero
1390 call laser_field(lasers%lasers(ilaser), aa, time_)
1391 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) &
1392 - mu(itime) * aa/p_c
1393 end select
1394 end do
1395 end if
1396
1397 ! the gauge field
1398 gfield => list_get_gauge_field(ext_partners)
1399 if (associated(gfield)) then
1400 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
1401 call gauge_field_get_vec_pot(gfield, aa)
1402 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - aa/p_c
1403 end if
1404
1405 ! the electric field for a periodic system through the gauge field
1406 ! TODO: The condition is wrong here: the e_field should be in non-periodic dims as E field
1407 ! and as a gauge field in the periodic dim, unless we use a Bery phase, in which, we do not use it
1408 ! this way. But this is unrelated to the gauge field
1409 if (allocated(this%ep%e_field) .and. associated(gfield)) then
1410 this%hm_base%uniform_vector_potential(1:space%periodic_dim) = &
1411 this%hm_base%uniform_vector_potential(1:space%periodic_dim) - time_*this%ep%e_field(1:space%periodic_dim)
1412 end if
1413
1414 end do
1415
1416 ! the vector potential of a static magnetic field
1417 if (allocated(this%ep%a_static)) then
1418 call this%hm_base%allocate_field(mesh, field_vector_potential, .false.)
1419 !ep%a_static contains 1/c A(r)
1420 !$omp parallel do schedule(static) private(idir)
1421 do ip = 1, mesh%np
1422 do idir = 1, space%dim
1423 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) + this%ep%a_static(ip, idir)
1424 end do
1425 end do
1426 end if
1427
1428 !The electric field is added to the KS potential
1429 call this%hm_base%accel_copy_pot(mesh)
1430
1431 ! and the static magnetic field
1432 if (allocated(this%ep%b_field)) then
1433 call this%hm_base%allocate_field(mesh, field_uniform_magnetic_field, .false.)
1434 do idir = 1, 3
1435 this%hm_base%uniform_magnetic_field(idir) = this%hm_base%uniform_magnetic_field(idir) + this%ep%b_field(idir)
1436 end do
1437 end if
1438
1439 call this%hm_base%update_magnetic_terms(mesh, this%ep%gyromagnetic_ratio, this%d%ispin)
1440
1441 call hamiltonian_elec_update_pot(this, mesh)
1442
1443 call build_phase()
1444
1445 call profiling_out("HAMILTONIAN_ELEC_UPDATE_EXT_POT")
1447
1448 contains
1449
1450 subroutine build_phase()
1451 integer :: ik, imat, nmat, max_npoints, offset, iphase, nphase
1452
1454
1455 if ((.not. this%kpoints%gamma_only()) .or. allocated(this%hm_base%uniform_vector_potential)) then
1456
1457 call profiling_in('UPDATE_PHASES')
1458 ! now regenerate the phases for the pseudopotentials
1459 do iatom = 1, this%ep%natoms
1460 call projector_init_phases(this%ep%proj(iatom), space%dim, this%d, this%der%boundaries, this%kpoints, &
1461 vec_pot = this%hm_base%uniform_vector_potential, vec_pot_var = this%hm_base%vector_potential)
1462 end do
1463
1464 call profiling_out('UPDATE_PHASES')
1465 end if
1466
1467 if (allocated(this%hm_base%uniform_vector_potential)) then
1468 call this%phase%update(mesh, this%d%kpt, this%kpoints, this%d, space, this%hm_base%uniform_vector_potential)
1469 end if
1470
1471 max_npoints = this%vnl%max_npoints
1472 nmat = this%vnl%nprojector_matrices
1473
1474
1475 if (this%phase%is_allocated() .and. allocated(this%vnl%projector_matrices)) then
1476
1477 nphase = 1
1478 if (this%der%boundaries%spiralBC) nphase = 3
1479
1480 if (.not. allocated(this%vnl%projector_phases)) then
1481 safe_allocate(this%vnl%projector_phases(1:max_npoints, nphase, nmat, this%d%kpt%start:this%d%kpt%end))
1482 if (accel_is_enabled()) then
1483 call accel_create_buffer(this%vnl%buff_projector_phases, accel_mem_read_only, &
1484 type_cmplx, this%vnl%total_points*nphase*this%d%kpt%nlocal)
1485 end if
1486 end if
1487
1488 offset = 0
1489 do ik = this%d%kpt%start, this%d%kpt%end
1490 do imat = 1, this%vnl%nprojector_matrices
1491 iatom = this%vnl%projector_to_atom(imat)
1492 do iphase = 1, nphase
1493 !$omp parallel do schedule(static)
1494 do ip = 1, this%vnl%projector_matrices(imat)%npoints
1495 this%vnl%projector_phases(ip, imat, iphase, ik) = this%ep%proj(iatom)%phase(ip, iphase, ik)
1496 end do
1497
1498 if (accel_is_enabled() .and. this%vnl%projector_matrices(imat)%npoints > 0) then
1499 call accel_write_buffer(this%vnl%buff_projector_phases, &
1500 this%vnl%projector_matrices(imat)%npoints, this%vnl%projector_phases(1:, iphase, imat, ik), &
1501 offset = offset)
1502 end if
1503 offset = offset + this%vnl%projector_matrices(imat)%npoints
1504 end do
1505 end do
1506 end do
1507
1508 end if
1509
1511 end subroutine build_phase
1512
1514
1515 logical function hamiltonian_elec_needs_current(hm, states_are_real)
1516 type(hamiltonian_elec_t), intent(in) :: hm
1517 logical, intent(in) :: states_are_real
1518
1520
1521 if (hm%self_induced_magnetic) then
1522 if (.not. states_are_real) then
1524 else
1525 message(1) = 'No current density for real states since it is identically zero.'
1526 call messages_warning(1)
1527 end if
1528 end if
1529
1531
1532 ! ---------------------------------------------------------
1533 subroutine zhamiltonian_elec_apply_all(hm, namespace, gr, st, hst)
1534 type(hamiltonian_elec_t), intent(inout) :: hm
1535 type(namespace_t), intent(in) :: namespace
1536 type(grid_t), intent(in) :: gr
1537 type(states_elec_t), intent(inout) :: st
1538 type(states_elec_t), intent(inout) :: hst
1539
1540 integer :: ik, ib, ist
1541 complex(real64), allocatable :: psi(:, :)
1542 complex(real64), allocatable :: psiall(:, :, :, :)
1543
1545
1546 do ik = st%d%kpt%start, st%d%kpt%end
1547 do ib = st%group%block_start, st%group%block_end
1548 call zhamiltonian_elec_apply_batch(hm, namespace, gr, st%group%psib(ib, ik), hst%group%psib(ib, ik))
1549 end do
1550 end do
1551
1552 if (oct_exchange_enabled(hm%oct_exchange)) then
1553
1554 safe_allocate(psiall(gr%np_part, 1:hst%d%dim, st%st_start:st%st_end, st%d%kpt%start:st%d%kpt%end))
1555
1556 call states_elec_get_state(st, gr, psiall)
1557
1558 call oct_exchange_prepare(hm%oct_exchange, gr, psiall, hm%xc, hm%psolver, namespace)
1559
1560 safe_deallocate_a(psiall)
1561
1562 safe_allocate(psi(gr%np_part, 1:hst%d%dim))
1563
1564 do ik = 1, st%nik
1565 do ist = 1, st%nst
1566 call states_elec_get_state(hst, gr, ist, ik, psi)
1567 call oct_exchange_operator(hm%oct_exchange, namespace, gr, psi, ist, ik)
1568 call states_elec_set_state(hst, gr, ist, ik, psi)
1569 end do
1570 end do
1571
1572 safe_deallocate_a(psi)
1573
1574 end if
1575
1577 end subroutine zhamiltonian_elec_apply_all
1578
1579
1580 ! ---------------------------------------------------------
1581
1582 subroutine magnus(hm, namespace, mesh, psi, hpsi, ik, vmagnus, set_phase)
1583 type(hamiltonian_elec_t), intent(in) :: hm
1584 type(namespace_t), intent(in) :: namespace
1585 class(mesh_t), intent(in) :: mesh
1586 complex(real64), contiguous, intent(inout) :: psi(:,:)
1587 complex(real64), contiguous, intent(out) :: hpsi(:,:)
1588 integer, intent(in) :: ik
1589 real(real64), intent(in) :: vmagnus(:, :, :)
1590 logical, optional, intent(in) :: set_phase
1591
1592 complex(real64), allocatable :: auxpsi(:, :), aux2psi(:, :)
1593 integer :: idim, ispin
1594
1595 push_sub(magnus)
1596
1597 ! We will assume, for the moment, no spinors.
1598 if (hm%d%dim /= 1) then
1599 call messages_not_implemented("Magnus with spinors", namespace=namespace)
1600 end if
1601
1602 safe_allocate( auxpsi(1:mesh%np_part, 1:hm%d%dim))
1603 safe_allocate(aux2psi(1:mesh%np, 1:hm%d%dim))
1604
1605 ispin = hm%d%get_spin_index(ik)
1606
1607 ! Compute (T + Vnl)|psi> and store it
1608 call zhamiltonian_elec_apply_single(hm, namespace, mesh, psi, auxpsi, 1, ik, &
1609 terms = term_kinetic + term_non_local_potential, set_phase = set_phase)
1611 ! H|psi> = (T + Vnl)|psi> + Vpsl|psi> + Vmagnus(t2)|psi> + Vborders
1612 do idim = 1, hm%d%dim
1613 call lalg_copy(mesh%np, auxpsi(:, idim), hpsi(:, idim))
1614 hpsi(1:mesh%np, idim) = hpsi(1:mesh%np, idim) + hm%ep%Vpsl(1:mesh%np)*psi(1:mesh%np,idim)
1615 call vborders(mesh, hm, psi(:, idim), hpsi(:, idim))
1616 end do
1617 hpsi(1:mesh%np, 1) = hpsi(1:mesh%np, 1) + vmagnus(1:mesh%np, ispin, 2)*psi(1:mesh%np, 1)
1618
1619 ! Add first term of the commutator: - i Vmagnus(t1) (T + Vnl) |psi>
1620 hpsi(1:mesh%np, 1) = hpsi(1:mesh%np, 1) - m_zi*vmagnus(1:mesh%np, ispin, 1)*auxpsi(1:mesh%np, 1)
1621
1622 ! Add second term of commutator: i (T + Vnl) Vmagnus(t1) |psi>
1623 auxpsi(1:mesh%np, 1) = vmagnus(1:mesh%np, ispin, 1)*psi(1:mesh%np, 1)
1624 call zhamiltonian_elec_apply_single(hm, namespace, mesh, auxpsi, aux2psi, 1, ik, &
1625 terms = term_kinetic + term_non_local_potential, set_phase = set_phase)
1626 hpsi(1:mesh%np, 1) = hpsi(1:mesh%np, 1) + m_zi*aux2psi(1:mesh%np, 1)
1627
1628 safe_deallocate_a(auxpsi)
1629 safe_deallocate_a(aux2psi)
1630 pop_sub(magnus)
1631 end subroutine magnus
1632
1633 ! ---------------------------------------------------------
1634 subroutine vborders (mesh, hm, psi, hpsi)
1635 class(mesh_t), intent(in) :: mesh
1636 type(hamiltonian_elec_t), intent(in) :: hm
1637 complex(real64), intent(in) :: psi(:)
1638 complex(real64), intent(inout) :: hpsi(:)
1639
1640 integer :: ip
1641
1642 push_sub(vborders)
1643
1644 if (hm%abs_boundaries%abtype == imaginary_absorbing) then
1645 do ip = 1, mesh%np
1646 hpsi(ip) = hpsi(ip) + m_zi*hm%abs_boundaries%mf(ip)*psi(ip)
1647 end do
1648 end if
1649
1650 pop_sub(vborders)
1651 end subroutine vborders
1652
1653 ! ---------------------------------------------------------
1654 logical function hamiltonian_elec_has_kick(hm)
1655 type(hamiltonian_elec_t), intent(in) :: hm
1656
1658
1659 hamiltonian_elec_has_kick = (abs(hm%kick%delta_strength) > m_epsilon)
1660
1662 end function hamiltonian_elec_has_kick
1663
1665 !
1666 subroutine hamiltonian_elec_set_mass(this, namespace, mass)
1667 class(hamiltonian_elec_t) , intent(inout) :: this
1668 type(namespace_t), intent(in) :: namespace
1669 real(real64), intent(in) :: mass
1670
1672
1673 if (parse_is_defined(namespace, 'ParticleMass')) then
1674 message(1) = 'Attempting to redefine a non-unit electron mass'
1675 call messages_fatal(1)
1676 else
1677 this%mass = mass
1678 end if
1679
1681 end subroutine hamiltonian_elec_set_mass
1682
1683 !----------------------------------------------------------
1690 subroutine hamiltonian_elec_copy_and_set_phase(hm, gr, kpt, psib, psib_with_phase)
1691 type(hamiltonian_elec_t), intent(in) :: hm
1692 type(grid_t), intent(in) :: gr
1693 type(distributed_t), intent(in) :: kpt
1694 type(wfs_elec_t), intent(in) :: psib
1695 type(wfs_elec_t), intent(out) :: psib_with_phase
1696
1697 integer :: k_offset, n_boundary_points
1698
1700
1701 call psib%copy_to(psib_with_phase)
1702 if (hm%phase%is_allocated()) then
1703 call hm%phase%apply_to(gr, gr%np, conjugate = .false., psib = psib_with_phase, src = psib, async=.true.)
1704 ! apply phase correction while setting boundary -> memory needs to be
1705 ! accessed only once
1706 k_offset = psib%ik - kpt%start
1707 n_boundary_points = int(gr%np_part - gr%np)
1708 call boundaries_set(gr%der%boundaries, gr, psib_with_phase, phase_correction = hm%phase%phase_corr(:, psib%ik), &
1709 buff_phase_corr = hm%phase%buff_phase_corr, offset=k_offset*n_boundary_points, async=.true.)
1710 else
1711 call psib%copy_data_to(gr%np, psib_with_phase)
1712 call boundaries_set(gr%der%boundaries, gr, psib_with_phase)
1713 end if
1714
1715 call psib_with_phase%do_pack(copy = .true.)
1716
1719
1720 ! ---------------------------------------------------------
1721 subroutine hamiltonian_elec_diagonal (hm, mesh, diag, ik)
1722 type(hamiltonian_elec_t), intent(in) :: hm
1723 class(mesh_t), intent(in) :: mesh
1724 real(real64), contiguous, intent(out) :: diag(:,:)
1725 integer, intent(in) :: ik
1726
1727 integer :: idim, ip, ispin
1728
1729 real(real64), allocatable :: ldiag(:)
1730
1732
1733 safe_allocate(ldiag(1:mesh%np))
1734
1735 diag = m_zero
1736
1737 call derivatives_lapl_diag(hm%der, ldiag)
1738
1739 do idim = 1, hm%d%dim
1740 diag(1:mesh%np, idim) = -m_half/hm%mass*ldiag(1:mesh%np)
1741 end do
1742
1743 select case (hm%d%ispin)
1744
1745 case (unpolarized, spin_polarized)
1746 ispin = hm%d%get_spin_index(ik)
1747 diag(1:mesh%np, 1) = diag(1:mesh%np, 1) + hm%ep%vpsl(1:mesh%np)
1748
1749 case (spinors)
1750 do ip = 1, mesh%np
1751 diag(ip, 1) = diag(ip, 1) + hm%ep%vpsl(ip)
1752 diag(ip, 2) = diag(ip, 2) + hm%ep%vpsl(ip)
1753 end do
1754
1755 end select
1756
1757 call hm%ks_pot%add_vhxc(diag)
1758
1760 end subroutine hamiltonian_elec_diagonal
1762
1763
1764#include "undef.F90"
1765#include "real.F90"
1766#include "hamiltonian_elec_inc.F90"
1767
1768#include "undef.F90"
1769#include "complex.F90"
1770#include "hamiltonian_elec_inc.F90"
1771
1772end module hamiltonian_elec_oct_m
1773
1774!! Local Variables:
1775!! mode: f90
1776!! coding: utf-8
1777!! End:
subroutine build_external_potentials()
subroutine build_phase()
subroutine external_potentials_checks()
subroutine build_interactions()
constant times a vector plus a vector
Definition: lalg_basic.F90:173
Copies a vector x, to a vector y.
Definition: lalg_basic.F90:188
integer, parameter, public imaginary_absorbing
subroutine, public absorbing_boundaries_end(this)
subroutine, public absorbing_boundaries_init(this, namespace, space, gr)
pure logical function, public accel_allow_cpu_only()
Definition: accel.F90:428
subroutine, public accel_finish()
Definition: accel.F90:984
pure logical function, public accel_is_enabled()
Definition: accel.F90:418
integer, parameter, public accel_mem_read_only
Definition: accel.F90:195
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
Module implementing boundary conditions in Octopus.
Definition: boundaries.F90:124
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
real(real64) function, public derivatives_lapl_get_max_eigenvalue(this)
Get maximum eigenvalue of discrete Laplacian. For the star and star_general stencils,...
logical function, public epot_have_external_potentials(ep)
Definition: epot.F90:604
integer, parameter, public scalar_relativistic_zora
Definition: epot.F90:168
subroutine, public epot_end(ep)
Definition: epot.F90:383
integer, parameter, public fully_relativistic_zora
Definition: epot.F90:168
subroutine, public epot_init(ep, namespace, gr, ions, psolver, ispin, xc_family, kpoints)
Definition: epot.F90:220
subroutine, public epot_generate(ep, namespace, mesh, ions, st_d)
Definition: epot.F90:419
subroutine, public exchange_operator_init(this, namespace, space, st, der, mc, stencil, kpoints, cam)
subroutine, public exchange_operator_end(this)
logical function, public list_has_gauge_field(partners)
type(gauge_field_t) function, pointer, public list_get_gauge_field(partners)
logical function, public list_has_lasers(partners)
type(lasers_t) function, pointer, public list_get_lasers(partners)
integer, parameter, public external_pot_from_file
potential, defined in a file
subroutine, public load_external_potentials(external_potentials, namespace)
integer, parameter, public external_pot_charge_density
user-defined function for charge density
integer, parameter, public external_pot_usdef
user-defined function for local potential
integer, parameter, public external_pot_static_efield
Static electric field.
integer, parameter, public external_pot_static_bfield
Static magnetic field.
subroutine, public gauge_field_get_vec_pot(this, vec_pot)
real(real64), parameter, public m_two
Definition: global.F90:192
real(real64), parameter, public m_zero
Definition: global.F90:190
real(real64), parameter, public m_epsilon
Definition: global.F90:206
real(real64), parameter, public p_c
Electron gyromagnetic ratio, see Phys. Rev. Lett. 130, 071801 (2023)
Definition: global.F90:228
real(real64), parameter, public m_one
Definition: global.F90:191
This module implements the underlying real-space grid.
Definition: grid.F90:119
This module defines an abstract class for Hamiltonians.
integer, parameter, public field_uniform_magnetic_field
integer, parameter, public field_uniform_vector_potential
integer, parameter, public field_vector_potential
integer, parameter, public term_mgga
integer, parameter, public field_potential
subroutine vborders(mesh, hm, psi, hpsi)
pure logical function, public hamiltonian_elec_apply_packed(this)
subroutine, public hamiltonian_elec_set_inh(hm, st)
subroutine, public zvmask(mesh, hm, st)
subroutine, public zhamiltonian_elec_apply_batch(hm, namespace, mesh, psib, hpsib, terms, set_bc)
subroutine, public hamiltonian_elec_adjoint(hm)
subroutine, public hamiltonian_elec_end(hm)
subroutine, public hamiltonian_elec_copy_and_set_phase(hm, gr, kpt, psib, psib_with_phase)
Copy a batch to another batch and apply the Bloch phase to it.
subroutine, public zhamiltonian_elec_apply_single(hm, namespace, mesh, psi, hpsi, ist, ik, terms, set_bc, set_phase)
pure logical function hamiltonian_elec_needs_mgga_term(hm, terms)
logical function, public hamiltonian_elec_has_kick(hm)
subroutine, public magnus(hm, namespace, mesh, psi, hpsi, ik, vmagnus, set_phase)
logical function hamiltonian_elec_hermitian(hm)
subroutine, public dhamiltonian_elec_apply_single(hm, namespace, mesh, psi, hpsi, ist, ik, terms, set_bc, set_phase)
subroutine, public hamiltonian_elec_epot_generate(this, namespace, space, gr, ions, ext_partners, st, time)
real(real64) function, public hamiltonian_elec_get_time(this)
subroutine, public dvmask(mesh, hm, st)
logical function, public hamiltonian_elec_needs_current(hm, states_are_real)
subroutine, public hamiltonian_elec_remove_inh(hm)
subroutine zhamiltonian_elec_magnus_apply(hm, namespace, mesh, psib, hpsib, vmagnus)
subroutine, public zhamiltonian_elec_apply_atom(hm, namespace, space, latt, species, pos, ia, mesh, psi, vpsi)
subroutine, public zhamiltonian_elec_apply_all(hm, namespace, gr, st, hst)
subroutine, public hamiltonian_elec_diagonal(hm, mesh, diag, ik)
subroutine, public hamiltonian_elec_update_pot(this, mesh, accumulate)
Update the KS potential of the electronic Hamiltonian.
integer, parameter, public velocity
subroutine dhamiltonian_elec_magnus_apply(hm, namespace, mesh, psib, hpsib, vmagnus)
subroutine hamiltonian_elec_update(this, mesh, namespace, space, ext_partners, time)
(re-)build the Hamiltonian for the next application:
subroutine hamiltonian_elec_span(hm, delta, emin, namespace)
subroutine, public hamiltonian_elec_init(hm, namespace, space, gr, ions, ext_partners, st, theory_level, xc, mc, kpoints, need_exchange, xc_photons)
subroutine dhamiltonian_elec_apply(hm, namespace, mesh, psib, hpsib, terms, set_bc)
pure logical function, public hamiltonian_elec_inh_term(hm)
subroutine hamiltonian_elec_set_mass(this, namespace, mass)
set the effective electron mass, checking whether it was previously redefined.
subroutine, public dhamiltonian_elec_apply_batch(hm, namespace, mesh, psib, hpsib, terms, set_bc)
subroutine, public hamiltonian_elec_update_with_ext_pot(this, mesh, space, ext_partners, time, mu)
This is an extension of "hamiltonian_elec_update_pot" to be used by the CFM4 propagator....
subroutine, public hamiltonian_elec_not_adjoint(hm)
subroutine zhamiltonian_elec_apply(hm, namespace, mesh, psib, hpsib, terms, set_bc)
This module defines classes and functions for interaction partners.
Definition: io.F90:116
integer, parameter, public kick_magnon_mode
Definition: kick.F90:165
subroutine, public kick_end(kick)
Definition: kick.F90:796
subroutine, public kick_init(kick, namespace, space, kpoints, nspin)
Definition: kick.F90:225
pure integer function, public kick_get_type(kick)
Definition: kick.F90:1365
A module to handle KS potential, without the external potential.
integer, parameter, public rdmft
integer, parameter, public hartree
integer, parameter, public hartree_fock
integer, parameter, public independent_particles
integer, parameter, public generalized_kohn_sham_dft
integer, parameter, public kohn_sham_dft
subroutine, public laser_vector_potential(laser, mesh, aa, time)
Definition: lasers.F90:1080
subroutine, public lasers_nondipole_laser_field_step(this, field, time)
Retrieves the NDSFA vector_potential correction. The nondipole field is obtained for consecutive time...
Definition: lasers.F90:1152
logical function, public lasers_with_nondipole_field(lasers)
Check if a nondipole SFA correction should be computed for the given laser.
Definition: lasers.F90:741
integer, parameter, public e_field_electric
Definition: lasers.F90:179
integer, parameter, public e_field_vector_potential
Definition: lasers.F90:179
subroutine, public laser_potential(laser, mesh, pot, time)
Definition: lasers.F90:1045
integer, parameter, public e_field_scalar_potential
Definition: lasers.F90:179
integer pure elemental function, public laser_kind(laser)
Definition: lasers.F90:717
subroutine, public laser_field(laser, field, time)
Retrieves the value of either the electric or the magnetic field. If the laser is given by a scalar p...
Definition: lasers.F90:1117
integer, parameter, public e_field_magnetic
Definition: lasers.F90:179
integer, parameter, public dft_u_none
Definition: lda_u.F90:203
subroutine, public lda_u_update_basis(this, space, gr, ions, st, psolver, namespace, kpoints, has_phase)
Definition: lda_u.F90:699
subroutine, public lda_u_build_phase_correction(this, space, std, boundaries, namespace, kpoints, vec_pot, vec_pot_var)
Build the phase correction to the global phase for all orbitals.
Definition: lda_u.F90:827
subroutine, public lda_u_end(this)
Definition: lda_u.F90:657
subroutine, public lda_u_init(this, namespace, space, level, gr, ions, st, mc, kpoints, has_phase)
Definition: lda_u.F90:284
This module implements fully polymorphic linked lists, and some specializations thereof.
This modules implements the routines for doing constrain DFT for noncollinear magnetism.
subroutine, public magnetic_constrain_end(this)
Releases memory of the magnetic constrain.
subroutine, public magnetic_constrain_init(this, namespace, mesh, std, natoms, min_dist)
Initilializes the magnetic_constrain_t object.
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:117
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1097
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:531
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:416
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1069
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
subroutine, public mxll_coupling_init(this, d, gr, namespace, mass)
Parse variables and initialize Maxwell coupling.
subroutine, public set_electric_quadrupole_pot(this, mesh)
Computes the electric quadrupole potential where .
subroutine, public mxll_coupling_end(this)
Finalize and deallocate Maxwell coupling arrays.
subroutine, public mxll_coupling_calc(this, hm_base, mesh, d, space)
Add the Maxwell coupling to the electronic Hamiltonian.
logical function, public oct_exchange_enabled(this)
subroutine, public oct_exchange_remove(this)
this module contains the low-level part of the output system
Definition: output_low.F90:117
Some general things and nomenclature:
Definition: par_vec.F90:173
logical function, public parse_is_defined(namespace, name)
Definition: parser.F90:505
subroutine, public pcm_calc_pot_rs(pcm, mesh, psolver, ions, v_h, v_ext, kick, time_present, kick_time)
Definition: pcm.F90:1218
subroutine, public pcm_end(pcm)
Definition: pcm.F90:3073
real(real64), dimension(:,:), allocatable delta
D_E matrix in JCP 139, 024105 (2013).
Definition: pcm.F90:271
subroutine, public pcm_init(pcm, namespace, space, ions, grid, qtot, val_charge, external_potentials_present, kick_present)
Initializes the PCM calculation: reads the VdW molecular cavity and generates the PCM response matrix...
Definition: pcm.F90:297
subroutine, public poisson_init(this, namespace, space, der, mc, stencil, qtot, label, solver, verbose, force_serial, force_cmplx)
Definition: poisson.F90:236
subroutine, public poisson_end(this)
Definition: poisson.F90:688
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:625
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:554
subroutine, public projector_init_phases(this, dim, std, bnd, kpoints, vec_pot, vec_pot_var)
Definition: projector.F90:264
subroutine, public scissor_end(this)
Definition: scissor.F90:241
subroutine, public states_set_complex(st)
pure logical function, public states_are_real(st)
This module handles spin dimensions of the states and the k-point distribution.
subroutine, public states_elec_dim_copy(dout, din)
subroutine, public states_elec_dim_end(dim)
subroutine, public states_elec_end(st)
finalize the states_elec_t object
subroutine, public states_elec_copy(stout, stin, exclude_wfns, exclude_eigenval, special)
make a (selective) copy of a states_elec_t object
This module provides routines for communicating states when using states parallelization.
integer pure function, public symmetries_identity_index(this)
Definition: symmetries.F90:591
integer pure function, public symmetries_number(this)
Definition: symmetries.F90:545
type(type_t), public type_cmplx
Definition: types.F90:136
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.
type(unit_system_t), public units_inp
the units systems for reading and writing
type(xc_cam_t), parameter, public cam_exact_exchange
Use only Hartree Fock exact exchange.
Definition: xc_cam.F90:155
integer, parameter, public xc_oep_x_slater
Slater approximation to the exact exchange.
integer, parameter, public func_x
Definition: xc.F90:116
logical pure function, public family_is_mgga_with_exc(xcs)
Is the xc function part of the mGGA family with an energy functional.
Definition: xc.F90:586
logical pure function, public family_is_hybrid(xcs)
Returns true if the functional is an hybrid functional.
Definition: xc.F90:601
This module implements the "photon-free" electron-photon exchange-correlation functional.
Definition: xc_photons.F90:123
This module implements the ZORA terms for the Hamoiltonian.
Definition: zora.F90:118
Extension of space that contains the knowledge of the spin dimension.
Description of the grid, containing information on derivatives, stencil, and symmetries.
Definition: grid.F90:171
The abstract Hamiltonian class defines a skeleton for specific implementations.
abstract class for general interaction partners
Describes mesh distribution to nodes.
Definition: mesh.F90:188
Stores all communicators and groups.
Definition: multicomm.F90:208
The states_elec_t class contains all electronic wave functions.
This class described the 'photon-exchange' electron-photon xc functionals, based on QEDFT.
Definition: xc_photons.F90:159
This class is responsible for calculating and applying the ZORA.
Definition: zora.F90:147
int true(void)