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