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, &
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, &
227 velocity = 2
228
229
230contains
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
248
250 logical :: need_exchange_
251 real(real64) :: rashba_coupling
252
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)
260
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
300 safe_allocate(hm%energy)
301
302 !Keep pointers to derivatives, geometry and xc
303 hm%der => gr%der
304 hm%ions => ions
305 hm%xc => xc
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))
317
318 !Initialize Poisson solvers
319 call poisson_init(hm%psolver, namespace, space, gr%der, mc, gr%stencil, st%qtot)
320
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)
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 (.not. allocated(hm%ep%b_field)) then
550 safe_allocate(hm%ep%b_field(1:3)) !Cannot be space%dim
551 hm%ep%b_field(1:3) = m_zero
552 end if
553 hm%ep%b_field(1:3) = hm%ep%b_field(1:3) + potential%b_field(1:3)
554
555 if (.not. allocated(hm%ep%a_static)) then
556 safe_allocate(hm%ep%a_static(1:gr%np, 1:space%dim))
557 hm%ep%a_static(1:gr%np, 1:space%dim) = m_zero
558 end if
559 call lalg_axpy(gr%np, space%dim, m_one, potential%a_static, hm%ep%a_static)
560
562 if (.not. allocated(hm%ep%e_field)) then
563 safe_allocate(hm%ep%e_field(1:space%dim))
564 hm%ep%e_field(1:space%dim) = m_zero
565 end if
566 hm%ep%e_field(1:space%dim) = hm%ep%e_field(1:space%dim) + potential%e_field(1:space%dim)
567
568 !In the fully periodic case, we use Berry phases
569 if (space%periodic_dim < space%dim) then
570 if (.not. allocated(hm%v_static)) then
571 safe_allocate(hm%v_static(1:gr%np))
572 hm%v_static(1:gr%np) = m_zero
573 end if
574 if (.not. allocated(hm%ep%v_ext)) then
575 safe_allocate(hm%ep%v_ext(1:gr%np_part))
576 hm%ep%v_ext(1:gr%np_part) = m_zero
577 end if
578 call lalg_axpy(gr%np, m_one, potential%pot, hm%v_static)
579 call lalg_axpy(gr%np, m_one, potential%v_ext, hm%ep%v_ext)
580 end if
581
582 if (hm%kpoints%use_symmetries) then
583 do iop = 1, symmetries_number(hm%kpoints%symm)
584 if (iop == symmetries_identity_index(hm%kpoints%symm)) cycle
585 if (.not. symm_op_invariant_cart(hm%kpoints%symm%ops(iop), hm%ep%e_field, 1e-5_real64)) then
586 message(1) = "The StaticElectricField breaks (at least) one of the symmetries used to reduce the k-points."
587 message(2) = "Set SymmetryBreakDir equal to StaticElectricField."
588 call messages_fatal(2, namespace=namespace)
589 end if
590 end do
591 end if
592
593 end select
594 call potential%deallocate_memory()
595
596 class default
597 assert(.false.)
598 end select
599 end do
600
602 end subroutine build_external_potentials
603
604 ! ---------------------------------------------------------
605 subroutine external_potentials_checks()
606 type(list_iterator_t) :: iter
607 class(*), pointer :: potential
608
610
611 call iter%start(hm%external_potentials)
612 do while (iter%has_next())
613 potential => iter%get_next()
614 select type (potential)
615 class is (external_potential_t)
616
617 if (potential%type == external_pot_static_efield .and. hm%kpoints%reduced%npoints > 1) then
618 message(1) = "Applying StaticElectricField in a periodic direction is only accurate for large supercells."
619 message(2) = "Single-point Berry phase is not appropriate when k-point sampling is needed."
620 call messages_warning(2, namespace=namespace)
621 end if
622
623 class default
624 assert(.false.)
625 end select
626 end do
627
629 end subroutine external_potentials_checks
630
631
632 !The code in this routines needs to know about the external potentials.
633 !This will be treated in the future by the interactions directly.
634 subroutine build_interactions()
635 logical :: external_potentials_present
636 logical :: kick_present
637
639
640 if (allocated(hm%ep%e_field) .and. space%is_periodic() .and. .not. list_has_gauge_field(ext_partners)) then
641 ! only need vberry if there is a field in a periodic direction
642 ! and we are not setting a gauge field
643 if (any(abs(hm%ep%e_field(1:space%periodic_dim)) > m_epsilon)) then
644 safe_allocate(hm%vberry(1:gr%np, 1:hm%d%nspin))
645 hm%vberry = m_zero
646 end if
647 end if
648
649 external_potentials_present = epot_have_external_potentials(hm%ep) .or. &
650 list_has_lasers(ext_partners) .or. allocated(hm%v_static)
651
652
653 kick_present = hamiltonian_elec_has_kick(hm)
654
655 call pcm_init(hm%pcm, namespace, space, ions, gr, st%qtot, st%val_charge, external_potentials_present, kick_present)
656 if (hm%pcm%run_pcm) then
657 if (hm%theory_level /= kohn_sham_dft) call messages_not_implemented("PCM for TheoryLevel /= kohn_sham", namespace=namespace)
658 end if
659
661
662 end subroutine build_interactions
663
664
665 end subroutine hamiltonian_elec_init
666
667
668 ! ---------------------------------------------------------
669 subroutine hamiltonian_elec_end(hm)
670 type(hamiltonian_elec_t), target, intent(inout) :: hm
671
672 type(partner_iterator_t) :: iter
673 class(interaction_partner_t), pointer :: potential
674
675 push_sub(hamiltonian_elec_end)
676
677 call hm%hm_base%end()
678 call hm%vnl%end()
679
680 call hm%phase%end()
681
682 call hm%ks_pot%end()
683 safe_deallocate_a(hm%vberry)
684 safe_deallocate_a(hm%a_ind)
685 safe_deallocate_a(hm%b_ind)
686 safe_deallocate_a(hm%v_ext_pot)
687
688 safe_deallocate_p(hm%zora)
689
690 call poisson_end(hm%psolver)
691
692 nullify(hm%xc)
693
694 call kick_end(hm%kick)
695 call epot_end(hm%ep)
696 nullify(hm%ions)
697
698 call absorbing_boundaries_end(hm%abs_boundaries)
699
700 call states_elec_dim_end(hm%d)
701
702 if (hm%scissor%apply) call scissor_end(hm%scissor)
703
704 call exchange_operator_end(hm%exxop)
705 call lda_u_end(hm%lda_u)
706
707 safe_deallocate_a(hm%energy)
708
709 if (hm%pcm%run_pcm) call pcm_end(hm%pcm)
710
711 call hm%v_ie_loc%end()
712 call hm%nlcc%end()
713
714 call iter%start(hm%external_potentials)
715 do while (iter%has_next())
716 potential => iter%get_next()
717 safe_deallocate_p(potential)
718 end do
719 call hm%external_potentials%empty()
720 safe_deallocate_a(hm%v_static)
721
722 call magnetic_constrain_end(hm%magnetic_constrain)
723
724 call mxll_coupling_end(hm%mxll)
725
726 pop_sub(hamiltonian_elec_end)
727 end subroutine hamiltonian_elec_end
728
729
730 ! ---------------------------------------------------------
731 ! True if the Hamiltonian is Hermitian, false otherwise
732 logical function hamiltonian_elec_hermitian(hm)
733 class(hamiltonian_elec_t), intent(in) :: hm
734
736 hamiltonian_elec_hermitian = .not.((hm%abs_boundaries%abtype == imaginary_absorbing) .or. &
737 oct_exchange_enabled(hm%oct_exchange))
738
740 end function hamiltonian_elec_hermitian
741
742 ! ---------------------------------------------------------
743 ! True if the Hamiltonian needs to apply the mGGA term
744 pure logical function hamiltonian_elec_needs_mgga_term(hm, terms)
745 class(hamiltonian_elec_t), intent(in) :: hm
746 integer, intent(in) :: terms
747
749
750 if (bitand(term_mgga, terms) /= 0 .and. family_is_mgga_with_exc(hm%xc) &
751 .and. hm%theory_level == generalized_kohn_sham_dft) then
753 end if
754
755 !For OEP
756 if(terms == term_mgga .and. family_is_mgga_with_exc(hm%xc) .and. hm%theory_level == kohn_sham_dft) then
758 end if
759
761
763
764 ! ---------------------------------------------------------
765 subroutine hamiltonian_elec_span(hm, delta, emin, namespace)
766 class(hamiltonian_elec_t), intent(inout) :: hm
767 real(real64), intent(in) :: delta(:)
768 real(real64), intent(in) :: emin
769 type(namespace_t), intent(in) :: namespace
770
771 real(real64) :: emax
772
773 push_sub(hamiltonian_elec_span)
774
775 ! estimate maximum energy of discrete kinetic operator
776 ! this neglects possible contributions from the non-local part of the pseudopotentials
778
779 hm%spectral_middle_point = (emax + emin) / m_two
780 hm%spectral_half_span = (emax - emin) / m_two
781
782 pop_sub(hamiltonian_elec_span)
783 end subroutine hamiltonian_elec_span
784
785
786 ! ---------------------------------------------------------
787 pure logical function hamiltonian_elec_inh_term(hm) result(inh)
788 type(hamiltonian_elec_t), intent(in) :: hm
789
790 inh = hm%inh_term
791 end function hamiltonian_elec_inh_term
792
793
794 ! ---------------------------------------------------------
795 subroutine hamiltonian_elec_set_inh(hm, st)
796 type(hamiltonian_elec_t), intent(inout) :: hm
797 type(states_elec_t), intent(in) :: st
798
800
801 if (hm%inh_term) call states_elec_end(hm%inh_st)
802 call states_elec_copy(hm%inh_st, st)
803 hm%inh_term = .true.
804
806 end subroutine hamiltonian_elec_set_inh
807
808
809 ! ---------------------------------------------------------
810 subroutine hamiltonian_elec_remove_inh(hm)
811 type(hamiltonian_elec_t), intent(inout) :: hm
812
814
815 if (hm%inh_term) then
816 call states_elec_end(hm%inh_st)
817 hm%inh_term = .false.
818 end if
819
821 end subroutine hamiltonian_elec_remove_inh
822
823 ! ---------------------------------------------------------
824 subroutine hamiltonian_elec_adjoint(hm)
825 type(hamiltonian_elec_t), intent(inout) :: hm
826
828
829 if (.not. hm%adjoint) then
830 hm%adjoint = .true.
831 if (hm%abs_boundaries%abtype == imaginary_absorbing) then
832 hm%abs_boundaries%mf = -hm%abs_boundaries%mf
833 end if
834 end if
835
838
839
840 ! ---------------------------------------------------------
841 subroutine hamiltonian_elec_not_adjoint(hm)
842 type(hamiltonian_elec_t), intent(inout) :: hm
843
845
846 if (hm%adjoint) then
847 hm%adjoint = .false.
848 if (hm%abs_boundaries%abtype == imaginary_absorbing) then
849 hm%abs_boundaries%mf = -hm%abs_boundaries%mf
850 end if
851 end if
852
854 end subroutine hamiltonian_elec_not_adjoint
855
856
857 ! ---------------------------------------------------------
859 subroutine hamiltonian_elec_update(this, mesh, namespace, space, ext_partners, time)
860 class(hamiltonian_elec_t), intent(inout) :: this
861 class(mesh_t), intent(in) :: mesh
862 type(namespace_t), intent(in) :: namespace
863 class(space_t), intent(in) :: space
864 type(partner_list_t), intent(in) :: ext_partners
865 real(real64), optional, intent(in) :: time
866
867 integer :: ispin, ip, idir, iatom, ilaser
868 real(real64) :: aa(space%dim), time_
869 real(real64), allocatable :: vp(:,:)
870 type(lasers_t), pointer :: lasers
871 type(gauge_field_t), pointer :: gfield
872 real(real64) :: am(space%dim)
873
875 call profiling_in("HAMILTONIAN_ELEC_UPDATE")
876
877 this%current_time = m_zero
878 if (present(time)) this%current_time = time
879
880 time_ = optional_default(time, 0.0_real64)
881
882 ! set everything to zero
883 call this%hm_base%clear(mesh%np)
884
885 ! alllocate the scalar potential for the xc, hartree and external potentials
886 call this%hm_base%allocate_field(mesh, field_potential, &
887 complex_potential = this%abs_boundaries%abtype == imaginary_absorbing)
889 ! the lasers
890 if (present(time) .or. this%time_zero) then
891
892 lasers => list_get_lasers(ext_partners)
893 if(associated(lasers)) then
894 do ilaser = 1, lasers%no_lasers
895 select case (laser_kind(lasers%lasers(ilaser)))
897 do ispin = 1, this%d%spin_channels
898 call laser_potential(lasers%lasers(ilaser), mesh, &
899 this%hm_base%potential(:, ispin), time_)
900 end do
901 case (e_field_magnetic)
902 call this%hm_base%allocate_field(mesh, field_vector_potential + field_uniform_magnetic_field, &
903 .false.)
904 ! get the vector potential
905 safe_allocate(vp(1:mesh%np, 1:space%dim))
906 vp(1:mesh%np, 1:space%dim) = m_zero
907 call laser_vector_potential(lasers%lasers(ilaser), mesh, vp, time_)
908 !$omp parallel do private(idir) schedule(static)
909 do ip = 1, mesh%np
910 do idir = 1, space%dim
911 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) + vp(ip, idir)/p_c
912 end do
913 end do
914 ! and the magnetic field
915 call laser_field(lasers%lasers(ilaser), this%hm_base%uniform_magnetic_field(1:space%dim), time_)
916 safe_deallocate_a(vp)
918 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
919 ! get the uniform vector potential associated with a magnetic field
920 aa = m_zero
921 call laser_field(lasers%lasers(ilaser), aa, time_)
922 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - aa/p_c
923 end select
924 end do
925
926 if (lasers_with_nondipole_field(lasers)) then
927 assert( allocated(this%hm_base%uniform_vector_potential))
928 call lasers_nondipole_laser_field_step(lasers, am, time_)
929 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - am/p_c
930 end if
931 end if
932
933 ! the gauge field
934 gfield => list_get_gauge_field(ext_partners)
935 if (associated(gfield)) then
936 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
937 call gauge_field_get_vec_pot(gfield, aa)
938 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - aa/p_c
939 end if
940
941 ! the electric field for a periodic system through the gauge field
942 if (allocated(this%ep%e_field) .and. associated(gfield)) then
943 this%hm_base%uniform_vector_potential(1:space%periodic_dim) = &
944 this%hm_base%uniform_vector_potential(1:space%periodic_dim) - time_*this%ep%e_field(1:space%periodic_dim)
945 end if
946
947 ! add the photon-free mean-field vector potential
948 if (associated(this%xc_photons)) then
949 if(this%xc_photons%lpfmf .and. allocated(this%xc_photons%mf_vector_potential)) then
950 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
951 ! here we put a minus sign in front of the mean field term to get the right answer (need to check the formula)
952 this%hm_base%uniform_vector_potential(1:space%dim) = &
953 this%hm_base%uniform_vector_potential(1:space%dim) - this%xc_photons%mf_vector_potential(1:space%dim)/p_c
954 end if
955 end if
956
957 end if
958
959 ! the vector potential of a static magnetic field
960 if (allocated(this%ep%a_static)) then
961 call this%hm_base%allocate_field(mesh, field_vector_potential, .false.)
962 !ep%a_static contains 1/c A(r)
963 !$omp parallel do private(idir) schedule(static)
964 do ip = 1, mesh%np
965 do idir = 1, space%dim
966 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) + this%ep%a_static(ip, idir)
967 end do
968 end do
969 end if
970
971 ! add Maxwell coupling to Hamiltonian and sets the magnetic field for the Zeeman term added below
972 call mxll_coupling_calc(this%mxll, this%hm_base, mesh, this%d, space)
973
974 !The electric field was added to the KS potential
975 call this%hm_base%accel_copy_pot(mesh)
976
977 ! and the static magnetic field
978 if (allocated(this%ep%b_field)) then
979 call this%hm_base%allocate_field(mesh, field_uniform_magnetic_field, .false.)
980 do idir = 1, 3
981 this%hm_base%uniform_magnetic_field(idir) = this%hm_base%uniform_magnetic_field(idir) + this%ep%b_field(idir)
982 end do
983 end if
984
985 ! Combine the uniform and non-uniform fields and compute the Zeeman term
986 call this%hm_base%update_magnetic_terms(mesh, this%ep%gyromagnetic_ratio, this%d%ispin)
987
988 ! This needs to be called at the end as the zeeman term enters the potential
989 call hamiltonian_elec_update_pot(this, mesh, accumulate = .true.)
990
991 if (this%mxll%test_equad) then
992 call set_electric_quadrupole_pot(this%mxll, mesh)
993 end if
994
995 call build_phase()
996
997 call profiling_out("HAMILTONIAN_ELEC_UPDATE")
999
1000 contains
1001
1002 subroutine build_phase()
1003 integer :: ik, imat, nmat, max_npoints, offset
1004 integer :: ip
1005 integer :: iphase, nphase
1006
1008
1009 if ((.not. this%kpoints%gamma_only()) .or. allocated(this%hm_base%uniform_vector_potential)) then
1010
1011 call profiling_in('UPDATE_PHASES')
1012 ! now regenerate the phases for the pseudopotentials
1013 do iatom = 1, this%ep%natoms
1014 call projector_init_phases(this%ep%proj(iatom), space%dim, this%d, this%der%boundaries, this%kpoints, &
1015 vec_pot = this%hm_base%uniform_vector_potential, vec_pot_var = this%hm_base%vector_potential)
1016 end do
1017
1018 call profiling_out('UPDATE_PHASES')
1019 end if
1020
1021 if (allocated(this%hm_base%uniform_vector_potential)) then
1022
1023 call this%phase%update(mesh, this%d%kpt, this%kpoints, this%d, space, this%hm_base%uniform_vector_potential)
1024
1025 ! We rebuild the phase for the orbital projection, similarly to the one of the pseudopotentials
1026 if (this%lda_u_level /= dft_u_none) then
1027 call lda_u_build_phase_correction(this%lda_u, space, this%d, this%der%boundaries, namespace, this%kpoints, &
1028 vec_pot = this%hm_base%uniform_vector_potential, vec_pot_var = this%hm_base%vector_potential)
1029 end if
1030 end if
1031
1032 max_npoints = this%vnl%max_npoints
1033 nmat = this%vnl%nprojector_matrices
1034
1035
1036 if (this%phase%is_allocated() .and. allocated(this%vnl%projector_matrices)) then
1037
1038 nphase = 1
1039 if (this%der%boundaries%spiralBC) nphase = 3
1040
1041 if (.not. allocated(this%vnl%projector_phases)) then
1042 safe_allocate(this%vnl%projector_phases(1:max_npoints, 1:nphase, nmat, this%d%kpt%start:this%d%kpt%end))
1043 if (accel_is_enabled()) then
1044 call accel_create_buffer(this%vnl%buff_projector_phases, accel_mem_read_only, &
1045 type_cmplx, this%vnl%total_points*nphase*this%d%kpt%nlocal)
1046 ! We need to save nphase, with which the array has been build,
1047 ! as the number might change throughout the run
1048 this%vnl%nphase = nphase
1049 end if
1050 end if
1051
1052 offset = 0
1053 do ik = this%d%kpt%start, this%d%kpt%end
1054 do imat = 1, this%vnl%nprojector_matrices
1055 iatom = this%vnl%projector_to_atom(imat)
1056 do iphase = 1, nphase
1057 !$omp parallel do simd schedule(static)
1058 do ip = 1, this%vnl%projector_matrices(imat)%npoints
1059 this%vnl%projector_phases(ip, iphase, imat, ik) = this%ep%proj(iatom)%phase(ip, iphase, ik)
1060 end do
1061
1062 if (accel_is_enabled() .and. this%vnl%projector_matrices(imat)%npoints > 0) then
1063 call accel_write_buffer(this%vnl%buff_projector_phases, &
1064 this%vnl%projector_matrices(imat)%npoints, this%vnl%projector_phases(1:, iphase, imat, ik), &
1065 offset = offset, async=.true.)
1066 end if
1067 offset = offset + this%vnl%projector_matrices(imat)%npoints
1068 end do
1069 end do
1070 end do
1071
1072 end if
1073
1074 call accel_finish()
1075
1077 end subroutine build_phase
1078
1079 end subroutine hamiltonian_elec_update
1080
1081
1082 !----------------------------------------------------------------
1085 ! TODO: See Issue #1064
1086 subroutine hamiltonian_elec_update_pot(this, mesh, accumulate)
1087 type(hamiltonian_elec_t), intent(inout) :: this
1088 class(mesh_t), intent(in) :: mesh
1089 logical, optional, intent(in) :: accumulate
1090
1091 integer :: ispin, ip
1092
1094
1095 ! By default we nullify first the result
1096 if (.not. optional_default(accumulate, .false.)) then
1097 !$omp parallel private(ip, ispin)
1098 do ispin = 1, this%d%nspin
1099 !$omp do simd schedule(static)
1100 do ip = 1, mesh%np
1101 this%hm_base%potential(ip, ispin) = m_zero
1102 end do
1103 end do
1104 !$omp end parallel
1105 end if
1106
1107 !$omp parallel private(ip, ispin)
1108 do ispin = 1, this%d%nspin
1109 if (ispin <= 2) then
1110 !$omp do simd schedule(static)
1111 ! this%vhxc(ip, ispin) is added after the calculation of ZORA potential
1112 do ip = 1, mesh%np
1113 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + this%ep%vpsl(ip) + this%v_ext_pot(ip)
1114 end do
1115
1117 if (this%pcm%run_pcm) then
1118 if (this%pcm%solute) then
1119 !$omp do simd schedule(static)
1120 do ip = 1, mesh%np
1121 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + &
1122 this%pcm%v_e_rs(ip) + this%pcm%v_n_rs(ip)
1123 end do
1124 !$omp end do simd nowait
1125 end if
1126 if (this%pcm%localf) then
1127 !$omp do simd schedule(static)
1128 do ip = 1, mesh%np
1129 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + &
1130 this%pcm%v_ext_rs(ip)
1131 end do
1132 !$omp end do simd nowait
1133 end if
1134 end if
1135
1137 if (this%abs_boundaries%abtype == imaginary_absorbing) then
1138 !$omp do simd schedule(static)
1139 do ip = 1, mesh%np
1140 this%hm_base%Impotential(ip, ispin) = this%hm_base%Impotential(ip, ispin) + this%abs_boundaries%mf(ip)
1141 end do
1142 !$omp end do simd nowait
1143 end if
1144 end if
1145 end do
1146 !$omp end parallel
1147
1148 ! scalar relativistic ZORA contribution
1149 ! \boldsymbol{p} \frac{c^2}{2c^2 - V} \boldsymbol{p} \Phi^\mathrm{ZORA}
1150 if (this%ep%reltype == scalar_relativistic_zora .or. this%ep%reltype == fully_relativistic_zora) then
1151 call this%zora%update(this%der, this%hm_base%potential)
1152 end if
1153
1154 !$omp parallel private(ip, ispin)
1155 do ispin = 1, this%d%nspin
1156 ! Adding Zeeman potential to hm_base%potential
1157 if (allocated(this%hm_base%zeeman_pot)) then
1158 !$omp do simd schedule(static)
1159 do ip = 1, mesh%np
1160 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + this%hm_base%zeeman_pot(ip, ispin)
1161 end do
1162 !$omp end do simd nowait
1163 end if
1164
1165 ! Adding Quadrupole potential from static E-field (test)
1166 if (this%mxll%test_equad) then
1167 !$omp do simd schedule(static)
1168 do ip = 1, mesh%np
1169 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + this%mxll%e_quadrupole_pot(ip)
1170 end do
1171 !$omp end do simd
1172 end if
1173 end do
1174 !$omp end parallel
1175
1176
1177 ! Add the Hartree and KS potential
1178 call this%ks_pot%add_vhxc(this%hm_base%potential)
1180 call this%hm_base%accel_copy_pot(mesh)
1181
1183 end subroutine hamiltonian_elec_update_pot
1184
1185 ! ---------------------------------------------------------
1186 subroutine hamiltonian_elec_epot_generate(this, namespace, space, gr, ions, ext_partners, st, time)
1187 type(hamiltonian_elec_t), intent(inout) :: this
1188 type(namespace_t), intent(in) :: namespace
1189 class(electron_space_t), intent(in) :: space
1190 type(grid_t), intent(in) :: gr
1191 type(ions_t), target, intent(inout) :: ions
1192 type(partner_list_t), intent(in) :: ext_partners
1193 type(states_elec_t), intent(inout) :: st
1194 real(real64), optional, intent(in) :: time
1195
1197
1198 this%ions => ions
1199 call epot_generate(this%ep, namespace, gr, this%ions, this%d)
1200
1201 ! Interation terms are treated below
1202
1203 ! First we add the static electric field
1204 if (allocated(this%ep%e_field) .and. space%periodic_dim < space%dim) then
1205 call lalg_axpy(gr%np, m_one, this%v_static, this%ep%vpsl)
1206 end if
1207
1208 ! Here we need to pass this again, else test are failing.
1209 ! This is not a real problem, as the multisystem framework will indeed to this anyway
1210 this%v_ie_loc%atoms_dist => ions%atoms_dist
1211 this%v_ie_loc%atom => ions%atom
1212 call this%v_ie_loc%calculate()
1213
1214 ! At the moment we need to add this to ep%vpsl, to keep the behavior of the code
1215 call lalg_axpy(gr%np, m_one, this%v_ie_loc%potential(:,1), this%ep%vpsl)
1216
1217 ! Here we need to pass this again, else test are failing.
1218 ! This is not a real problem, as the multisystem framework will indeed to this anyway
1219 if (this%ep%nlcc) then
1220 this%nlcc%atoms_dist => ions%atoms_dist
1221 this%nlcc%atom => ions%atom
1222 call this%nlcc%calculate()
1223 call lalg_copy(gr%np, this%nlcc%density(:,1), st%rho_core)
1224 end if
1225
1226 call this%vnl%build(space, gr, this%ep)
1227 call hamiltonian_elec_update(this, gr, namespace, space, ext_partners, time)
1228
1229 ! Check if projectors are still compatible with apply_packed on GPU
1230 if (this%is_applied_packed .and. accel_is_enabled()) then
1231 if (this%ep%non_local .and. .not. this%vnl%apply_projector_matrices) then
1232 if (accel_allow_cpu_only()) then
1233 call messages_write('Relativistic pseudopotentials have not been fully implemented for CUDA or OpenCL.')
1234 call messages_warning(namespace=namespace)
1235 else
1236 call messages_write('Relativistic pseudopotentials have not been fully implemented for CUDA or OpenCL.',&
1237 new_line = .true.)
1238 call messages_write('Calculation will not be continued. To force execution, set AllowCPUonly = yes.')
1239 call messages_fatal(namespace=namespace)
1240 end if
1241 end if
1242
1243 end if
1244
1245 if (this%pcm%run_pcm) then
1248 if (this%pcm%solute) then
1249 call pcm_calc_pot_rs(this%pcm, gr, this%psolver, ions = ions)
1250 end if
1251
1254 ! Interpolation is needed, hence gr%np_part -> 1:gr%np
1255 if (this%pcm%localf .and. allocated(this%v_static)) then
1256 call pcm_calc_pot_rs(this%pcm, gr, this%psolver, v_ext = this%ep%v_ext(1:gr%np_part))
1257 end if
1258
1259 end if
1260
1261 call lda_u_update_basis(this%lda_u, space, gr, ions, st, this%psolver, namespace, this%kpoints, &
1262 this%phase%is_allocated())
1263
1265 end subroutine hamiltonian_elec_epot_generate
1266
1267 ! -----------------------------------------------------------------
1268
1269 real(real64) function hamiltonian_elec_get_time(this) result(time)
1270 type(hamiltonian_elec_t), intent(inout) :: this
1271
1272 time = this%current_time
1273 end function hamiltonian_elec_get_time
1274
1275 ! -----------------------------------------------------------------
1276
1277 pure logical function hamiltonian_elec_apply_packed(this) result(apply)
1278 class(hamiltonian_elec_t), intent(in) :: this
1280 apply = this%is_applied_packed
1281
1283
1284
1285 ! -----------------------------------------------------------------
1286 subroutine zhamiltonian_elec_apply_atom (hm, namespace, space, latt, species, pos, ia, mesh, psi, vpsi)
1287 type(hamiltonian_elec_t), intent(in) :: hm
1288 type(namespace_t), intent(in) :: namespace
1289 class(space_t), intent(in) :: space
1290 type(lattice_vectors_t), intent(in) :: latt
1291 class(species_t), intent(in) :: species
1292 real(real64), intent(in) :: pos(1:space%dim)
1293 integer, intent(in) :: ia
1294 class(mesh_t), intent(in) :: mesh
1295 complex(real64), intent(in) :: psi(:,:)
1296 complex(real64), intent(out) :: vpsi(:,:)
1297
1298 integer :: idim
1299 real(real64), allocatable :: vlocal(:)
1301
1302 safe_allocate(vlocal(1:mesh%np_part))
1303 vlocal = m_zero
1304 call epot_local_potential(hm%ep, namespace, space, latt, mesh, species, pos, ia, vlocal)
1305
1306 do idim = 1, hm%d%dim
1307 vpsi(1:mesh%np, idim) = vlocal(1:mesh%np) * psi(1:mesh%np, idim)
1308 end do
1309
1310 safe_deallocate_a(vlocal)
1312 end subroutine zhamiltonian_elec_apply_atom
1313
1314 ! ---------------------------------------------------------
1319 subroutine hamiltonian_elec_update_with_ext_pot(this, mesh, space, ext_partners, time, mu)
1320 type(hamiltonian_elec_t), intent(inout) :: this
1321 class(space_t), intent(in) :: space
1322 class(mesh_t), intent(in) :: mesh
1323 type(partner_list_t), intent(in) :: ext_partners
1324 real(real64), intent(in) :: time(1:2)
1325 real(real64), intent(in) :: mu(1:2)
1326
1327 integer :: ispin, ip, idir, iatom, ilaser, itime
1328 real(real64) :: aa(space%dim), time_
1329 real(real64), allocatable :: vp(:,:)
1330 real(real64), allocatable :: velectric(:)
1331 type(lasers_t), pointer :: lasers
1332 type(gauge_field_t), pointer :: gfield
1333
1335 call profiling_in("HAMILTONIAN_ELEC_UPDATE_EXT_POT")
1336
1337 this%current_time = m_zero
1338 this%current_time = time(1)
1339
1340 ! set everything to zero
1341 call this%hm_base%clear(mesh%np)
1342
1343 ! the xc, hartree and external potentials
1344 call this%hm_base%allocate_field(mesh, field_potential, &
1345 complex_potential = this%abs_boundaries%abtype == imaginary_absorbing)
1346
1347 do itime = 1, 2
1348 time_ = time(itime)
1349
1350 lasers => list_get_lasers(ext_partners)
1351 if(associated(lasers)) then
1352 do ilaser = 1, lasers%no_lasers
1353 select case (laser_kind(lasers%lasers(ilaser)))
1354 case (e_field_scalar_potential, e_field_electric)
1355 safe_allocate(velectric(1:mesh%np))
1356 do ispin = 1, this%d%spin_channels
1357 velectric = m_zero
1358 call laser_potential(lasers%lasers(ilaser), mesh, velectric, time_)
1359 !$omp parallel do simd schedule(static)
1360 do ip = 1, mesh%np
1361 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + mu(itime) * velectric(ip)
1362 end do
1363 end do
1364 safe_deallocate_a(velectric)
1365 case (e_field_magnetic)
1366 call this%hm_base%allocate_field(mesh, field_vector_potential + field_uniform_magnetic_field, .false.)
1367 ! get the vector potential
1368 safe_allocate(vp(1:mesh%np, 1:space%dim))
1369 vp(1:mesh%np, 1:space%dim) = m_zero
1370 call laser_vector_potential(lasers%lasers(ilaser), mesh, vp, time_)
1371 do idir = 1, space%dim
1372 !$omp parallel do schedule(static)
1373 do ip = 1, mesh%np
1374 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) &
1375 - mu(itime) * vp(ip, idir)/p_c
1376 end do
1377 end do
1378 ! and the magnetic field
1379 call laser_field(lasers%lasers(ilaser), this%hm_base%uniform_magnetic_field(1:space%dim), time_)
1380 safe_deallocate_a(vp)
1381 case (e_field_vector_potential)
1382 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
1383 ! get the uniform vector potential associated with a magnetic field
1384 aa = m_zero
1385 call laser_field(lasers%lasers(ilaser), aa, time_)
1386 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) &
1387 - mu(itime) * aa/p_c
1388 end select
1389 end do
1390 end if
1391
1392 ! the gauge field
1393 gfield => list_get_gauge_field(ext_partners)
1394 if (associated(gfield)) then
1395 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
1396 call gauge_field_get_vec_pot(gfield, aa)
1397 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - aa/p_c
1398 end if
1399
1400 ! the electric field for a periodic system through the gauge field
1401 ! TODO: The condition is wrong here: the e_field should be in non-periodic dims as E field
1402 ! and as a gauge field in the periodic dim, unless we use a Bery phase, in which, we do not use it
1403 ! this way. But this is unrelated to the gauge field
1404 if (allocated(this%ep%e_field) .and. associated(gfield)) then
1405 this%hm_base%uniform_vector_potential(1:space%periodic_dim) = &
1406 this%hm_base%uniform_vector_potential(1:space%periodic_dim) - time_*this%ep%e_field(1:space%periodic_dim)
1407 end if
1408
1409 end do
1410
1411 ! the vector potential of a static magnetic field
1412 if (allocated(this%ep%a_static)) then
1413 call this%hm_base%allocate_field(mesh, field_vector_potential, .false.)
1414 !ep%a_static contains 1/c A(r)
1415 !$omp parallel do schedule(static) private(idir)
1416 do ip = 1, mesh%np
1417 do idir = 1, space%dim
1418 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) + this%ep%a_static(ip, idir)
1419 end do
1420 end do
1421 end if
1422
1423 !The electric field is added to the KS potential
1424 call this%hm_base%accel_copy_pot(mesh)
1425
1426 ! and the static magnetic field
1427 if (allocated(this%ep%b_field)) then
1428 call this%hm_base%allocate_field(mesh, field_uniform_magnetic_field, .false.)
1429 do idir = 1, 3
1430 this%hm_base%uniform_magnetic_field(idir) = this%hm_base%uniform_magnetic_field(idir) + this%ep%b_field(idir)
1431 end do
1432 end if
1433
1434 call this%hm_base%update_magnetic_terms(mesh, this%ep%gyromagnetic_ratio, this%d%ispin)
1435
1436 call hamiltonian_elec_update_pot(this, mesh)
1437
1438 call build_phase()
1439
1440 call profiling_out("HAMILTONIAN_ELEC_UPDATE_EXT_POT")
1442
1443 contains
1444
1445 subroutine build_phase()
1446 integer :: ik, imat, nmat, max_npoints, offset, iphase, nphase
1447
1449
1450 if ((.not. this%kpoints%gamma_only()) .or. allocated(this%hm_base%uniform_vector_potential)) then
1451
1452 call profiling_in('UPDATE_PHASES')
1453 ! now regenerate the phases for the pseudopotentials
1454 do iatom = 1, this%ep%natoms
1455 call projector_init_phases(this%ep%proj(iatom), space%dim, this%d, this%der%boundaries, this%kpoints, &
1456 vec_pot = this%hm_base%uniform_vector_potential, vec_pot_var = this%hm_base%vector_potential)
1457 end do
1458
1459 call profiling_out('UPDATE_PHASES')
1460 end if
1461
1462 if (allocated(this%hm_base%uniform_vector_potential)) then
1463 call this%phase%update(mesh, this%d%kpt, this%kpoints, this%d, space, this%hm_base%uniform_vector_potential)
1464 end if
1465
1466 max_npoints = this%vnl%max_npoints
1467 nmat = this%vnl%nprojector_matrices
1468
1469
1470 if (this%phase%is_allocated() .and. allocated(this%vnl%projector_matrices)) then
1471
1472 nphase = 1
1473 if (this%der%boundaries%spiralBC) nphase = 3
1474
1475 if (.not. allocated(this%vnl%projector_phases)) then
1476 safe_allocate(this%vnl%projector_phases(1:max_npoints, nphase, nmat, this%d%kpt%start:this%d%kpt%end))
1477 if (accel_is_enabled()) then
1478 call accel_create_buffer(this%vnl%buff_projector_phases, accel_mem_read_only, &
1479 type_cmplx, this%vnl%total_points*nphase*this%d%kpt%nlocal)
1480 end if
1481 end if
1482
1483 offset = 0
1484 do ik = this%d%kpt%start, this%d%kpt%end
1485 do imat = 1, this%vnl%nprojector_matrices
1486 iatom = this%vnl%projector_to_atom(imat)
1487 do iphase = 1, nphase
1488 !$omp parallel do schedule(static)
1489 do ip = 1, this%vnl%projector_matrices(imat)%npoints
1490 this%vnl%projector_phases(ip, imat, iphase, ik) = this%ep%proj(iatom)%phase(ip, iphase, ik)
1491 end do
1492
1493 if (accel_is_enabled() .and. this%vnl%projector_matrices(imat)%npoints > 0) then
1494 call accel_write_buffer(this%vnl%buff_projector_phases, &
1495 this%vnl%projector_matrices(imat)%npoints, this%vnl%projector_phases(1:, iphase, imat, ik), &
1496 offset = offset)
1497 end if
1498 offset = offset + this%vnl%projector_matrices(imat)%npoints
1499 end do
1500 end do
1501 end do
1502
1503 end if
1504
1506 end subroutine build_phase
1507
1509
1510 logical function hamiltonian_elec_needs_current(hm, states_are_real)
1511 type(hamiltonian_elec_t), intent(in) :: hm
1512 logical, intent(in) :: states_are_real
1513
1515
1516 if (hm%self_induced_magnetic) then
1517 if (.not. states_are_real) then
1519 else
1520 message(1) = 'No current density for real states since it is identically zero.'
1521 call messages_warning(1)
1522 end if
1523 end if
1524
1526
1527 ! ---------------------------------------------------------
1528 subroutine zhamiltonian_elec_apply_all(hm, namespace, gr, st, hst)
1529 type(hamiltonian_elec_t), intent(inout) :: hm
1530 type(namespace_t), intent(in) :: namespace
1531 type(grid_t), intent(in) :: gr
1532 type(states_elec_t), intent(inout) :: st
1533 type(states_elec_t), intent(inout) :: hst
1534
1535 integer :: ik, ib, ist
1536 complex(real64), allocatable :: psi(:, :)
1537 complex(real64), allocatable :: psiall(:, :, :, :)
1538
1540
1541 do ik = st%d%kpt%start, st%d%kpt%end
1542 do ib = st%group%block_start, st%group%block_end
1543 call zhamiltonian_elec_apply_batch(hm, namespace, gr, st%group%psib(ib, ik), hst%group%psib(ib, ik))
1544 end do
1545 end do
1546
1547 if (oct_exchange_enabled(hm%oct_exchange)) then
1548
1549 safe_allocate(psiall(gr%np_part, 1:hst%d%dim, st%st_start:st%st_end, st%d%kpt%start:st%d%kpt%end))
1550
1551 call states_elec_get_state(st, gr, psiall)
1552
1553 call oct_exchange_prepare(hm%oct_exchange, gr, psiall, hm%xc, hm%psolver, namespace)
1554
1555 safe_deallocate_a(psiall)
1556
1557 safe_allocate(psi(gr%np_part, 1:hst%d%dim))
1558
1559 do ik = 1, st%nik
1560 do ist = 1, st%nst
1561 call states_elec_get_state(hst, gr, ist, ik, psi)
1562 call oct_exchange_operator(hm%oct_exchange, namespace, gr, psi, ist, ik)
1563 call states_elec_set_state(hst, gr, ist, ik, psi)
1564 end do
1565 end do
1566
1567 safe_deallocate_a(psi)
1568
1569 end if
1570
1572 end subroutine zhamiltonian_elec_apply_all
1573
1574
1575 ! ---------------------------------------------------------
1576
1577 subroutine magnus(hm, namespace, mesh, psi, hpsi, ik, vmagnus, set_phase)
1578 type(hamiltonian_elec_t), intent(in) :: hm
1579 type(namespace_t), intent(in) :: namespace
1580 class(mesh_t), intent(in) :: mesh
1581 complex(real64), contiguous, intent(inout) :: psi(:,:)
1582 complex(real64), contiguous, intent(out) :: hpsi(:,:)
1583 integer, intent(in) :: ik
1584 real(real64), intent(in) :: vmagnus(:, :, :)
1585 logical, optional, intent(in) :: set_phase
1586
1587 complex(real64), allocatable :: auxpsi(:, :), aux2psi(:, :)
1588 integer :: idim, ispin
1589
1590 push_sub(magnus)
1591
1592 ! We will assume, for the moment, no spinors.
1593 if (hm%d%dim /= 1) then
1594 call messages_not_implemented("Magnus with spinors", namespace=namespace)
1595 end if
1596
1597 safe_allocate( auxpsi(1:mesh%np_part, 1:hm%d%dim))
1598 safe_allocate(aux2psi(1:mesh%np, 1:hm%d%dim))
1599
1600 ispin = hm%d%get_spin_index(ik)
1601
1602 ! Compute (T + Vnl)|psi> and store it
1603 call zhamiltonian_elec_apply_single(hm, namespace, mesh, psi, auxpsi, 1, ik, &
1604 terms = term_kinetic + term_non_local_potential, set_phase = set_phase)
1605
1606 ! H|psi> = (T + Vnl)|psi> + Vpsl|psi> + Vmagnus(t2)|psi> + Vborders
1607 do idim = 1, hm%d%dim
1608 call lalg_copy(mesh%np, auxpsi(:, idim), hpsi(:, idim))
1609 hpsi(1:mesh%np, idim) = hpsi(1:mesh%np, idim) + hm%ep%Vpsl(1:mesh%np)*psi(1:mesh%np,idim)
1610 call vborders(mesh, hm, psi(:, idim), hpsi(:, idim))
1611 end do
1612 hpsi(1:mesh%np, 1) = hpsi(1:mesh%np, 1) + vmagnus(1:mesh%np, ispin, 2)*psi(1:mesh%np, 1)
1613
1614 ! Add first term of the commutator: - i Vmagnus(t1) (T + Vnl) |psi>
1615 hpsi(1:mesh%np, 1) = hpsi(1:mesh%np, 1) - m_zi*vmagnus(1:mesh%np, ispin, 1)*auxpsi(1:mesh%np, 1)
1616
1617 ! Add second term of commutator: i (T + Vnl) Vmagnus(t1) |psi>
1618 auxpsi(1:mesh%np, 1) = vmagnus(1:mesh%np, ispin, 1)*psi(1:mesh%np, 1)
1619 call zhamiltonian_elec_apply_single(hm, namespace, mesh, auxpsi, aux2psi, 1, ik, &
1620 terms = term_kinetic + term_non_local_potential, set_phase = set_phase)
1621 hpsi(1:mesh%np, 1) = hpsi(1:mesh%np, 1) + m_zi*aux2psi(1:mesh%np, 1)
1622
1623 safe_deallocate_a(auxpsi)
1624 safe_deallocate_a(aux2psi)
1625 pop_sub(magnus)
1626 end subroutine magnus
1627
1628 ! ---------------------------------------------------------
1629 subroutine vborders (mesh, hm, psi, hpsi)
1630 class(mesh_t), intent(in) :: mesh
1631 type(hamiltonian_elec_t), intent(in) :: hm
1632 complex(real64), intent(in) :: psi(:)
1633 complex(real64), intent(inout) :: hpsi(:)
1634
1635 integer :: ip
1636
1637 push_sub(vborders)
1638
1639 if (hm%abs_boundaries%abtype == imaginary_absorbing) then
1640 do ip = 1, mesh%np
1641 hpsi(ip) = hpsi(ip) + m_zi*hm%abs_boundaries%mf(ip)*psi(ip)
1642 end do
1643 end if
1644
1645 pop_sub(vborders)
1646 end subroutine vborders
1647
1648 ! ---------------------------------------------------------
1649 logical function hamiltonian_elec_has_kick(hm)
1650 type(hamiltonian_elec_t), intent(in) :: hm
1651
1653
1654 hamiltonian_elec_has_kick = (abs(hm%kick%delta_strength) > m_epsilon)
1655
1657 end function hamiltonian_elec_has_kick
1658
1660 !
1661 subroutine hamiltonian_elec_set_mass(this, namespace, mass)
1662 class(hamiltonian_elec_t) , intent(inout) :: this
1663 type(namespace_t), intent(in) :: namespace
1664 real(real64), intent(in) :: mass
1665
1667
1668 if (parse_is_defined(namespace, 'ParticleMass')) then
1669 message(1) = 'Attempting to redefine a non-unit electron mass'
1670 call messages_fatal(1)
1671 else
1672 this%mass = mass
1673 end if
1674
1676 end subroutine hamiltonian_elec_set_mass
1677
1678 !----------------------------------------------------------
1685 subroutine hamiltonian_elec_copy_and_set_phase(hm, gr, kpt, psib, psib_with_phase)
1686 type(hamiltonian_elec_t), intent(in) :: hm
1687 type(grid_t), intent(in) :: gr
1688 type(distributed_t), intent(in) :: kpt
1689 type(wfs_elec_t), intent(in) :: psib
1690 type(wfs_elec_t), intent(out) :: psib_with_phase
1691
1692 integer :: k_offset, n_boundary_points
1693
1695
1696 call psib%copy_to(psib_with_phase)
1697 if (hm%phase%is_allocated()) then
1698 call hm%phase%apply_to(gr, gr%np, conjugate = .false., psib = psib_with_phase, src = psib, async=.true.)
1699 ! apply phase correction while setting boundary -> memory needs to be
1700 ! accessed only once
1701 k_offset = psib%ik - kpt%start
1702 n_boundary_points = int(gr%np_part - gr%np)
1703 call boundaries_set(gr%der%boundaries, gr, psib_with_phase, phase_correction = hm%phase%phase_corr(:, psib%ik), &
1704 buff_phase_corr = hm%phase%buff_phase_corr, offset=k_offset*n_boundary_points, async=.true.)
1705 else
1706 call psib%copy_data_to(gr%np, psib_with_phase)
1707 call boundaries_set(gr%der%boundaries, gr, psib_with_phase)
1708 end if
1709
1710 call psib_with_phase%do_pack(copy = .true.)
1711
1714
1715 ! ---------------------------------------------------------
1716 subroutine hamiltonian_elec_diagonal (hm, mesh, diag, ik)
1717 type(hamiltonian_elec_t), intent(in) :: hm
1718 class(mesh_t), intent(in) :: mesh
1719 real(real64), contiguous, intent(out) :: diag(:,:)
1720 integer, intent(in) :: ik
1721
1722 integer :: idim, ip, ispin
1723
1724 real(real64), allocatable :: ldiag(:)
1725
1727
1728 safe_allocate(ldiag(1:mesh%np))
1729
1730 diag = m_zero
1731
1732 call derivatives_lapl_diag(hm%der, ldiag)
1733
1734 do idim = 1, hm%d%dim
1735 diag(1:mesh%np, idim) = -m_half/hm%mass*ldiag(1:mesh%np)
1736 end do
1737
1738 select case (hm%d%ispin)
1739
1740 case (unpolarized, spin_polarized)
1741 ispin = hm%d%get_spin_index(ik)
1742 diag(1:mesh%np, 1) = diag(1:mesh%np, 1) + hm%ep%vpsl(1:mesh%np)
1743
1744 case (spinors)
1745 do ip = 1, mesh%np
1746 diag(ip, 1) = diag(ip, 1) + hm%ep%vpsl(ip)
1747 diag(ip, 2) = diag(ip, 2) + hm%ep%vpsl(ip)
1748 end do
1749
1750 end select
1751
1752 call hm%ks_pot%add_vhxc(diag)
1753
1755 end subroutine hamiltonian_elec_diagonal
1756
1757
1758
1759#include "undef.F90"
1760#include "real.F90"
1761#include "hamiltonian_elec_inc.F90"
1762
1763#include "undef.F90"
1764#include "complex.F90"
1765#include "hamiltonian_elec_inc.F90"
1766
1767end module hamiltonian_elec_oct_m
1768
1769!! Local Variables:
1770!! mode: f90
1771!! coding: utf-8
1772!! 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:437
subroutine, public accel_finish()
Definition: accel.F90:1407
pure logical function, public accel_is_enabled()
Definition: accel.F90:427
integer, parameter, public accel_mem_read_only
Definition: accel.F90:187
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, 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: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 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: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:234
subroutine, public poisson_end(this)
Definition: poisson.F90:710
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
type(xc_cam_t), parameter, public cam_exact_exchange
Use only Hartree Fock exact exchange.
Definition: xc_cam.F90:153
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:584
logical pure function, public family_is_hybrid(xcs)
Returns true if the functional is an hybrid functional.
Definition: xc.F90:599
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)