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