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 debug_oct_m
32 use energy_oct_m
37 use epot_oct_m
40 use global_oct_m
41 use grid_oct_m
45 use io_oct_m
46 use ions_oct_m
47 use kick_oct_m
48 use, intrinsic :: iso_fortran_env
52 use lasers_oct_m
54 use lda_u_oct_m
57 use math_oct_m
58 use mesh_oct_m
61 use mpi_oct_m
65 use nlcc_oct_m
69 use parser_oct_m
74 use pcm_oct_m
75 use phase_oct_m
78 use space_oct_m
86 use types_oct_m
87 use unit_oct_m
91 use xc_oct_m
92 use xc_cam_oct_m
93 use xc_f03_lib_m
97 use zora_oct_m
98
99 implicit none
100
101 private
102 public :: &
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 logical, private :: owns_ions = .false.
151 logical, private :: is_copy_snapshot = .false.
152 real(real64) :: exx_coef
153
154 type(poisson_t) :: psolver
155
157 logical :: self_induced_magnetic
158 real(real64), allocatable :: a_ind(:, :)
159 real(real64), allocatable :: b_ind(:, :)
160
161 integer :: theory_level
162 type(xc_t), pointer :: xc
163 type(xc_photons_t), pointer :: xc_photons
164
165 type(epot_t) :: ep
166 type(pcm_t) :: pcm
167
169 logical, private :: adjoint
170
172 real(real64), private :: mass
173
175 logical, private :: inh_term
176 type(states_elec_t) :: inh_st
177
180 type(oct_exchange_t) :: oct_exchange
181
182 type(scissor_t) :: scissor
183
184 real(real64) :: current_time
185 logical, private :: is_applied_packed
186
188 type(lda_u_t) :: lda_u
189 integer :: lda_u_level
190
191 logical, public :: time_zero
192
193 type(exchange_operator_t), public :: exxop
194
195 type(kpoints_t), pointer, public :: kpoints => null()
196
197 type(partner_list_t) :: external_potentials
198 real(real64), allocatable, public :: v_ext_pot(:)
199 real(real64), allocatable, public :: v_static(:)
200
201 type(ion_electron_local_potential_t) :: v_ie_loc
202 type(nlcc_t) :: nlcc
203
204 type(magnetic_constrain_t) :: magnetic_constrain
205
207 type(kick_t) :: kick
208
210 type(mxll_coupling_t) :: mxll
211 type(zora_t), pointer :: zora => null()
212
213 contains
214 procedure :: update => hamiltonian_elec_update
215 procedure :: apply_packed => hamiltonian_elec_apply_packed
216 procedure :: update_span => hamiltonian_elec_span
217 procedure :: dapply => dhamiltonian_elec_apply
218 procedure :: zapply => zhamiltonian_elec_apply
219 procedure :: is_hermitian => hamiltonian_elec_hermitian
220 procedure :: needs_mgga_term => hamiltonian_elec_needs_mgga_term
221 procedure :: set_mass => hamiltonian_elec_set_mass
222 end type hamiltonian_elec_t
223
224 integer, public, parameter :: &
225 LENGTH = 1, &
227
228
229contains
230
231 ! ---------------------------------------------------------
232 subroutine hamiltonian_elec_init(hm, namespace, space, gr, ions, ext_partners, st, theory_level, xc, &
233 mc, kpoints, need_exchange, xc_photons)
234 type(hamiltonian_elec_t), target, intent(inout) :: hm
235 type(namespace_t), intent(in) :: namespace
236 class(space_t), intent(in) :: space
237 type(grid_t), target, intent(inout) :: gr
238 type(ions_t), target, intent(inout) :: ions
239 type(partner_list_t), intent(inout) :: ext_partners
240 type(states_elec_t), target, intent(inout) :: st
241 integer, intent(in) :: theory_level
242 type(xc_t), target, intent(in) :: xc
243 type(multicomm_t), intent(in) :: mc
244 type(kpoints_t), target, intent(in) :: kpoints
245 logical, optional, intent(in) :: need_exchange
246 type(xc_photons_t), optional, target, intent(in) :: xc_photons
248
249 logical :: need_exchange_
250 real(real64) :: rashba_coupling
251
253 call profiling_in('HAMILTONIAN_ELEC_INIT')
255 ! make a couple of local copies
256 hm%space = space
257 hm%theory_level = theory_level
258 call states_elec_dim_copy(hm%d, st%d)
259
260 hm%kpoints => kpoints
262 !%Variable ParticleMass
263 !%Type float
264 !%Default 1.0
265 !%Section Hamiltonian
266 !%Description
267 !% It is possible to make calculations for a particle with a mass
268 !% different from one (atomic unit of mass, or mass of the electron).
269 !% This is useful to describe non-electronic systems, or for
270 !% esoteric purposes.
271 !%End
272 call parse_variable(namespace, 'ParticleMass', m_one, hm%mass)
273
274 !%Variable RashbaSpinOrbitCoupling
275 !%Type float
276 !%Default 0.0
277 !%Section Hamiltonian
278 !%Description
279 !% (Experimental.) For systems described in 2D (electrons confined to 2D in semiconductor structures), one
280 !% may add the Bychkov-Rashba spin-orbit coupling term [Bychkov and Rashba, <i>J. Phys. C: Solid
281 !% State Phys.</i> <b>17</b>, 6031 (1984)]. This variable determines the strength
282 !% of this perturbation, and has dimensions of energy times length.
283 !%End
284 call parse_variable(namespace, 'RashbaSpinOrbitCoupling', m_zero, rashba_coupling, units_inp%energy*units_inp%length)
285 if (parse_is_defined(namespace, 'RashbaSpinOrbitCoupling')) then
286 if (space%dim /= 2) then
287 write(message(1),'(a)') 'Rashba spin-orbit coupling can only be used for two-dimensional systems.'
288 call messages_fatal(1, namespace=namespace)
289 end if
290 call messages_experimental('RashbaSpinOrbitCoupling', namespace=namespace)
291 end if
293 call hm%hm_base%init(hm%d%nspin, hm%mass, rashba_coupling)
294 call hm%vnl%init()
295
296 assert(associated(gr%der%lapl))
297 hm%hm_base%kinetic => gr%der%lapl
298
299 safe_allocate(hm%energy)
300
301 !Keep pointers to derivatives, geometry and xc
302 hm%der => gr%der
303 hm%ions => ions
304 hm%owns_ions = .false.
305 hm%is_copy_snapshot = .false.
306 hm%xc => xc
307
308 if(present(xc_photons)) then
309 hm%xc_photons => xc_photons
310 else
311 hm%xc_photons => null()
312 end if
314 ! allocate potentials and density of the cores
315 ! In the case of spinors, vxc_11 = hm%vxc(:, 1), vxc_22 = hm%vxc(:, 2), Re(vxc_12) = hm%vxc(:. 3);
316 ! Im(vxc_12) = hm%vxc(:, 4)
317 call hm%ks_pot%init(gr%der, gr%np, gr%np_part, hm%d%nspin, hm%theory_level, family_is_mgga_with_exc(hm%xc))
318
319 !Initialize Poisson solvers
320 call poisson_init(hm%psolver, namespace, space, gr%der, mc, gr%stencil, st%qtot)
321
322 ! Initialize external potential
323 call epot_init(hm%ep, namespace, gr, hm%ions, hm%psolver, hm%d%ispin, hm%xc%family, hm%kpoints)
324 call kick_init(hm%kick, namespace, space, hm%kpoints, hm%d%ispin)
325
326 hm%zora => zora_t(namespace, hm%der, hm%d, hm%ep, hm%mass)
328 !Temporary construction of the ion-electron interactions
329 call hm%v_ie_loc%init(gr, hm%psolver, hm%ions, namespace)
330 if (hm%ep%nlcc) then
331 call hm%nlcc%init(gr, hm%ions)
332 safe_allocate(st%rho_core(1:gr%np))
333 st%rho_core(:) = m_zero
334 end if
335
336 !Static magnetic field or rashba spin-orbit interaction requires complex wavefunctions
337 if (parse_is_defined(namespace, 'StaticMagneticField') .or. list_has_gauge_field(ext_partners) .or. &
338 parse_is_defined(namespace, 'RashbaSpinOrbitCoupling')) then
339 call states_set_complex(st)
340 end if
341
342 !%Variable CalculateSelfInducedMagneticField
343 !%Type logical
344 !%Default no
345 !%Section Hamiltonian
346 !%Description
347 !% The existence of an electronic current implies the creation of a self-induced magnetic
348 !% field, which may in turn back-react on the system. Of course, a fully consistent treatment
349 !% of this kind of effect should be done in QED theory, but we will attempt a first
350 !% approximation to the problem by considering the lowest-order relativistic terms
351 !% plugged into the normal Hamiltonian equations (spin-other-orbit coupling terms, etc.).
352 !% For the moment being, none of this is done, but a first step is taken by calculating
353 !% the induced magnetic field of a system that has a current, by considering the magnetostatic
354 !% approximation and Biot-Savart law:
355 !%
356 !% <math> \nabla^2 \vec{A} + 4\pi\alpha \vec{J} = 0</math>
357 !%
358 !% <math> \vec{B} = \vec{\nabla} \times \vec{A}</math>
359 !%
360 !% If <tt>CalculateSelfInducedMagneticField</tt> is set to yes, this <i>B</i> field is
361 !% calculated at the end of a <tt>gs</tt> calculation (nothing is done -- yet -- in the <tt>td</tt>case)
362 !% and printed out, if the <tt>Output</tt> variable contains the <tt>potential</tt> keyword (the prefix
363 !% of the output files is <tt>Bind</tt>).
364 !%End
365 call parse_variable(namespace, 'CalculateSelfInducedMagneticField', .false., hm%self_induced_magnetic)
366 if (hm%self_induced_magnetic) then
367 safe_allocate(hm%a_ind(1:gr%np_part, 1:space%dim))
368 safe_allocate(hm%b_ind(1:gr%np_part, 1:space%dim))
369
370 !(for dim = we could save some memory, but it is better to keep it simple)
371 end if
372
373 ! Absorbing boundaries
374 call absorbing_boundaries_init(hm%abs_boundaries, namespace, space, gr)
375
376 hm%inh_term = .false.
377 call oct_exchange_remove(hm%oct_exchange)
378
379 hm%adjoint = .false.
380
381 call hm%phase%init(gr, hm%d%kpt, hm%kpoints, st%d, space)
382
383 !%Variable DFTULevel
384 !%Type integer
385 !%Default no
386 !%Section Hamiltonian::XC
387 !%Description
388 !% This variable selects which DFT+U expression is added to the Hamiltonian.
389 !%Option dft_u_none 0
390 !% No +U term is not applied.
391 !%Option dft_u_empirical 1
392 !% An empiricial Hubbard U is added on the orbitals specified in the block species
393 !% with hubbard_l and hubbard_u
394 !%Option dft_u_acbn0 2
395 !% Octopus determines the effective U term using the
396 !% ACBN0 functional as defined in PRX 5, 011006 (2015)
397 !%End
398 call parse_variable(namespace, 'DFTULevel', dft_u_none, hm%lda_u_level)
399 call messages_print_var_option('DFTULevel', hm%lda_u_level, namespace=namespace)
400 if (hm%lda_u_level /= dft_u_none) then
401 call lda_u_init(hm%lda_u, namespace, space, hm%lda_u_level, gr, ions, st, mc, hm%kpoints)
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 !%Variable TimeZero
437 !%Type logical
438 !%Default no
439 !%Section Hamiltonian
440 !%Description
441 !% (Experimental) If set to yes, the ground state and other time
442 !% dependent calculation will assume that they are done at time
443 !% zero, so that all time depedent field at that time will be
444 !% included.
445 !%End
446 call parse_variable(namespace, 'TimeZero', .false., hm%time_zero)
447 if (hm%time_zero) call messages_experimental('TimeZero', namespace=namespace)
448
449 !Cam parameters are irrelevant here and are updated later
450 need_exchange_ = optional_default(need_exchange, .false.)
451 if (hm%xc%compute_exchange(hm%theory_level) .or. need_exchange_) then
452 !We test Slater before OEP, as Slater is treated as OEP for the moment....
453 if (hm%xc%functional(func_x,1)%id == xc_oep_x_slater) then
454 call exchange_operator_init(hm%exxop, namespace, space, st, gr%der, mc, gr%stencil, &
455 hm%kpoints, cam_exact_exchange)
456 else if (bitand(hm%xc%family, xc_family_oep) /= 0 .or. hm%theory_level == rdmft) then
457 call exchange_operator_init(hm%exxop, namespace, space, st, gr%der, mc, gr%stencil, &
458 hm%kpoints, hm%xc%cam)
459 if (hm%theory_level == rdmft) hm%exxop%useACE = .false.
460 else
461 call exchange_operator_init(hm%exxop, namespace, space, st, gr%der, mc, gr%stencil, &
462 hm%kpoints, cam_exact_exchange)
463 end if
464 end if
465
466 if (hm%is_applied_packed .and. accel_is_enabled()) then
467 ! Check if we can actually apply the hamiltonian packed
468 if (gr%use_curvilinear) then
469 if (accel_allow_cpu_only()) then
470 hm%is_applied_packed = .false.
471 call messages_write('Cannot use GPUs as curvilinear coordinates are used.')
472 call messages_warning(namespace=namespace)
473 else
474 call messages_write('Cannot use GPUs as curvilinear coordinates are used.', new_line = .true.)
475 call messages_write('Calculation will not be continued. To force execution, set AllowCPUonly = yes.')
476 call messages_fatal(namespace=namespace)
477 end if
478 end if
479 end if
480
481 !We are building the list of external potentials
482 !This is done here at the moment, because we pass directly the mesh
483 !TODO: Once the abstract Hamiltonian knows about an abstract basis, we might move this to the
484 ! abstract Hamiltonian
485 call load_external_potentials(hm%external_potentials, namespace)
486
487 !Some checks which are electron specific, like k-points
489
490 !At the moment we do only have static external potential, so we never update them
492
493 !Build the resulting interactions
494 !TODO: This will be moved to the actual interactions
495 call build_interactions()
496
497 ! Constrained DFT for noncollinear magnetism
498 if (hm%theory_level /= independent_particles) then
499 call magnetic_constrain_init(hm%magnetic_constrain, namespace, gr, st%d, ions%natoms, ions%min_distance())
500 end if
501
502 ! init maxwell-electrons coupling
503 call mxll_coupling_init(hm%mxll, st%d, gr, namespace, hm%mass)
504
505 if (associated(hm%xc_photons)) then
506 if (hm%xc_photons%wants_to_renormalize_mass()) then
507 ! remornalize the electron mass due to light-matter interaction; here we only deal with it in free space
508 call hm%set_mass(namespace, hm%xc_photons%get_renormalized_mass())
509 end if
510 end if
511
512 if (hm%xc%compute_exchange(hm%theory_level) .or. need_exchange_) call hm%exxop%write_info(namespace)
513
514 call profiling_out('HAMILTONIAN_ELEC_INIT')
515 pop_sub(hamiltonian_elec_init)
516
517 contains
518
519 ! ---------------------------------------------------------
520 subroutine build_external_potentials()
521 type(list_iterator_t) :: iter
522 class(*), pointer :: potential
523 integer :: iop
524
526
527 safe_allocate(hm%v_ext_pot(1:gr%np))
528 hm%v_ext_pot(1:gr%np) = m_zero
529
530 call iter%start(hm%external_potentials)
531 do while (iter%has_next())
532 potential => iter%get_next()
533 select type (potential)
534 class is (external_potential_t)
535
536 call potential%allocate_memory(gr)
537 call potential%calculate(namespace, gr, hm%psolver)
538 !To preserve the old behavior, we are adding the various potentials
539 !to the corresponding arrays
540 select case (potential%type)
542 call lalg_axpy(gr%np, m_one, potential%pot, hm%v_ext_pot)
543
545 if (states_are_real(st)) then
546 message(1) = "Cannot use static magnetic field with real wavefunctions"
547 call messages_fatal(1, namespace=namespace)
548 end if
549
550 if (.not. allocated(hm%ep%b_field)) then
551 safe_allocate(hm%ep%b_field(1:3)) !Cannot be space%dim
552 hm%ep%b_field(1:3) = m_zero
553 end if
554 hm%ep%b_field(1:3) = hm%ep%b_field(1:3) + potential%b_field(1:3)
555
556 if (.not. allocated(hm%ep%a_static)) then
557 safe_allocate(hm%ep%a_static(1:gr%np, 1:space%dim))
558 hm%ep%a_static(1:gr%np, 1:space%dim) = m_zero
559 end if
560 call lalg_axpy(gr%np, space%dim, m_one, potential%a_static, hm%ep%a_static)
561
563 if (.not. allocated(hm%ep%e_field)) then
564 safe_allocate(hm%ep%e_field(1:space%dim))
565 hm%ep%e_field(1:space%dim) = m_zero
566 end if
567 hm%ep%e_field(1:space%dim) = hm%ep%e_field(1:space%dim) + potential%e_field(1:space%dim)
568
569 !In the fully periodic case, we use Berry phases
570 if (space%periodic_dim < space%dim) then
571 if (.not. allocated(hm%v_static)) then
572 safe_allocate(hm%v_static(1:gr%np))
573 hm%v_static(1:gr%np) = m_zero
574 end if
575 if (.not. allocated(hm%ep%v_ext)) then
576 safe_allocate(hm%ep%v_ext(1:gr%np_part))
577 hm%ep%v_ext(1:gr%np_part) = m_zero
578 end if
579 call lalg_axpy(gr%np, m_one, potential%pot, hm%v_static)
580 call lalg_axpy(gr%np, m_one, potential%v_ext, hm%ep%v_ext)
581 end if
582
583 if (hm%kpoints%use_symmetries) then
584 do iop = 1, symmetries_number(hm%kpoints%symm)
585 if (iop == symmetries_identity_index(hm%kpoints%symm)) cycle
586 if (.not. symm_op_invariant_cart(hm%kpoints%symm%ops(iop), hm%ep%e_field, 1e-5_real64)) then
587 message(1) = "The StaticElectricField breaks (at least) one of the symmetries used to reduce the k-points."
588 message(2) = "Set SymmetryBreakDir equal to StaticElectricField."
589 call messages_fatal(2, namespace=namespace)
590 end if
591 end do
592 end if
593
594 end select
595 call potential%deallocate_memory()
596
597 class default
598 assert(.false.)
599 end select
600 end do
601
603 end subroutine build_external_potentials
604
605 ! ---------------------------------------------------------
606 subroutine external_potentials_checks()
607 type(list_iterator_t) :: iter
608 class(*), pointer :: potential
609
611
612 call iter%start(hm%external_potentials)
613 do while (iter%has_next())
614 potential => iter%get_next()
615 select type (potential)
616 class is (external_potential_t)
617
618 if (potential%type == external_pot_static_efield .and. hm%kpoints%reduced%npoints > 1) then
619 message(1) = "Applying StaticElectricField in a periodic direction is only accurate for large supercells."
620 message(2) = "Single-point Berry phase is not appropriate when k-point sampling is needed."
621 call messages_warning(2, namespace=namespace)
622 end if
623
624 class default
625 assert(.false.)
626 end select
627 end do
628
630 end subroutine external_potentials_checks
631
632
633 !The code in this routines needs to know about the external potentials.
634 !This will be treated in the future by the interactions directly.
635 subroutine build_interactions()
636 logical :: external_potentials_present
637 logical :: kick_present
638
640
641 if (allocated(hm%ep%e_field) .and. space%is_periodic() .and. .not. list_has_gauge_field(ext_partners)) then
642 ! only need vberry if there is a field in a periodic direction
643 ! and we are not setting a gauge field
644 if (any(abs(hm%ep%e_field(1:space%periodic_dim)) > m_epsilon)) then
645 safe_allocate(hm%vberry(1:gr%np, 1:hm%d%nspin))
646 hm%vberry = m_zero
647 end if
648 end if
649
650 external_potentials_present = epot_have_external_potentials(hm%ep) .or. &
651 list_has_lasers(ext_partners) .or. allocated(hm%v_static)
652
653
654 kick_present = hamiltonian_elec_has_kick(hm)
655
656 call pcm_init(hm%pcm, namespace, space, ions, gr, st%qtot, st%val_charge, external_potentials_present, kick_present)
657 if (hm%pcm%run_pcm) then
658 if (hm%theory_level /= kohn_sham_dft) call messages_not_implemented("PCM for TheoryLevel /= kohn_sham", namespace=namespace)
659 end if
660
662
663 end subroutine build_interactions
664
665
666 end subroutine hamiltonian_elec_init
667
668
669
670
671 ! ---------------------------------------------------------
672 subroutine hamiltonian_elec_end(hm)
673 type(hamiltonian_elec_t), target, intent(inout) :: hm
674
675 type(partner_iterator_t) :: iter
676 class(interaction_partner_t), pointer :: potential
677
678 push_sub(hamiltonian_elec_end)
679
680 if (hm%is_copy_snapshot) then
681 ! release only pointer targets created by hamiltonian_elec_copy
683 pop_sub(hamiltonian_elec_end)
684 return
685 end if
686
687 call hm%hm_base%end()
688 call hm%vnl%end()
689
690 call hm%phase%end()
691
692 call hm%ks_pot%end()
693 safe_deallocate_a(hm%vberry)
694 safe_deallocate_a(hm%a_ind)
695 safe_deallocate_a(hm%b_ind)
696 safe_deallocate_a(hm%v_ext_pot)
697
698 safe_deallocate_p(hm%zora)
699
700 call poisson_end(hm%psolver)
702 nullify(hm%xc)
703
704 call kick_end(hm%kick)
705 call epot_end(hm%ep)
706 if (hm%owns_ions .and. associated(hm%ions)) then
707 ! ions_copy currently aliases species objects through species wrappers.
708 ! Detach wrapper storage to avoid double-finalizing shared species.
709 if (allocated(hm%ions%species)) then
710 safe_deallocate_a(hm%ions%species)
711 hm%ions%nspecies = 0
712 end if
713 safe_deallocate_p(hm%ions)
714 hm%owns_ions = .false.
715 else
716 nullify(hm%ions)
717 hm%owns_ions = .false.
718 end if
719
720 call absorbing_boundaries_end(hm%abs_boundaries)
721
722 call states_elec_dim_end(hm%d)
723
724 if (hm%scissor%apply) call scissor_end(hm%scissor)
725
726 call exchange_operator_end(hm%exxop)
727 call lda_u_end(hm%lda_u)
728
729 safe_deallocate_a(hm%energy)
731 if (hm%pcm%run_pcm) call pcm_end(hm%pcm)
732
733 call hm%v_ie_loc%end()
734 call hm%nlcc%end()
735
736 call iter%start(hm%external_potentials)
737 do while (iter%has_next())
738 potential => iter%get_next()
739 safe_deallocate_p(potential)
740 end do
741 call hm%external_potentials%empty()
742 safe_deallocate_a(hm%v_static)
743
744 call magnetic_constrain_end(hm%magnetic_constrain)
745
746 call mxll_coupling_end(hm%mxll)
747
748 hm%is_copy_snapshot = .false.
749
750 pop_sub(hamiltonian_elec_end)
751 end subroutine hamiltonian_elec_end
752
753 ! ---------------------------------------------------------
758 type(hamiltonian_elec_t), target, intent(inout) :: hm
759
760 type(partner_iterator_t) :: iter
761 class(interaction_partner_t), pointer :: potential
762
764
765 if (hm%owns_ions .and. associated(hm%ions)) then
766 if (allocated(hm%ions%species)) then
767 safe_deallocate_a(hm%ions%species)
768 hm%ions%nspecies = 0
769 end if
770 safe_deallocate_p(hm%ions)
771 hm%owns_ions = .false.
772 else
773 nullify(hm%ions)
774 hm%owns_ions = .false.
775 end if
776
777 if (associated(hm%zora)) then
778 safe_deallocate_p(hm%zora)
779 end if
780
781 call iter%start(hm%external_potentials)
782 do while (iter%has_next())
783 potential => iter%get_next()
784 safe_deallocate_p(potential)
785 end do
786 call hm%external_potentials%empty()
787
788 call hm%hm_base%end()
789 call hm%ks_pot%end()
790 call hm%phase%end()
791 call hm%vnl%end()
792 if (hm%lda_u_level /= dft_u_none) call lda_u_end(hm%lda_u)
793
794 hm%is_copy_snapshot = .false.
795
798
799 ! ---------------------------------------------------------
806 subroutine hamiltonian_elec_copy(hm_out, hm_in)
807 type(hamiltonian_elec_t), target, intent(out) :: hm_out
808 type(hamiltonian_elec_t), intent(inout) :: hm_in
809
810 type(ions_t), pointer :: ions_out
811 type(zora_t), pointer :: zora_out
812 type(partner_list_t) :: external_potentials_in
813 type(partner_list_t) :: external_potentials_out
814 type(list_iterator_t) :: iter
815 class(*), pointer :: ptr
816 class(external_potential_t), pointer :: ext_pot
817 logical :: runtime_initialized
818
819 push_sub(hamiltonian_elec_copy)
820
822 runtime_initialized = associated(hm_in%kpoints)
823
824 call iter%start(hm_in%external_potentials)
825 do while (iter%has_next())
826 ptr => iter%get_next()
827 select type (ptr)
828 class is (external_potential_t)
829 call external_potentials_in%add(ptr)
830 call external_potential_clone(ext_pot, ptr)
831 call external_potentials_out%add(ext_pot)
832 class default
833 call messages_not_implemented("hamiltonian_elec_copy with unsupported external potential partner")
834 end select
835 end do
836 call hm_in%external_potentials%empty()
837
838 hm_out = hm_in
839 hm_out%is_copy_snapshot = .true.
840
841 call epot_bind_poisson_solver(hm_out%ep, hm_out%psolver)
842 call nonlocal_pseudopotential_rebind_projectors(hm_out%vnl, hm_out%ep)
843
844 if (accel_is_enabled() .and. runtime_initialized .and. associated(hm_out%der)) then
845 call hamiltonian_elec_base_accel_rebuild(hm_out%hm_base, hm_out%der%mesh)
846 call ks_potential_accel_rebuild(hm_out%ks_pot)
847 call phase_accel_rebuild(hm_out%phase, hm_out%der%mesh, hm_out%d%kpt)
848 call nonlocal_pseudopotential_accel_rebuild(hm_out%vnl, hm_out%space, hm_out%der%mesh)
849 end if
850
851 call hm_out%external_potentials%empty()
852 call iter%start(external_potentials_out)
853 do while (iter%has_next())
854 ptr => iter%get_next()
855 select type (ptr)
856 class is (external_potential_t)
857 call hm_out%external_potentials%add(ptr)
858 class default
859 call messages_not_implemented("hamiltonian_elec_copy with unsupported external potential partner")
860 end select
861 end do
862 call iter%start(external_potentials_in)
863 do while (iter%has_next())
864 ptr => iter%get_next()
865 select type (ptr)
866 class is (external_potential_t)
867 call hm_in%external_potentials%add(ptr)
868 class default
869 call messages_not_implemented("hamiltonian_elec_copy with unsupported external potential partner")
870 end select
871 end do
872 call external_potentials_out%empty()
873 call external_potentials_in%empty()
874
875 if (runtime_initialized) then
876 call kick_end(hm_out%kick)
877 call kick_copy(hm_out%kick, hm_in%kick)
878
879 if (allocated(hm_in%energy)) then
880 if (.not. allocated(hm_out%energy)) safe_allocate(hm_out%energy)
881 call energy_copy(hm_in%energy, hm_out%energy)
882 else
883 safe_deallocate_a(hm_out%energy)
884 end if
885
886 call magnetic_constrain_copy(hm_out%magnetic_constrain, hm_in%magnetic_constrain)
887 call mxll_coupling_copy(hm_out%mxll, hm_in%mxll, hm_out%der)
888 end if
889
890 if (associated(hm_in%ions)) then
891 safe_allocate(ions_out)
892 ions_out = hm_in%ions
893 hm_out%ions => ions_out
894 hm_out%owns_ions = .true.
895 call hm_out%v_ie_loc%bind(hm_out%psolver, hm_out%ions)
896 call hm_out%nlcc%bind(hm_out%ions)
897 else
898 nullify(hm_out%ions)
899 hm_out%owns_ions = .false.
900 nullify(hm_out%v_ie_loc%atoms_dist)
901 nullify(hm_out%v_ie_loc%atom)
902 nullify(hm_out%v_ie_loc%pos)
903 nullify(hm_out%nlcc%atoms_dist)
904 nullify(hm_out%nlcc%atom)
905 nullify(hm_out%nlcc%pos)
906 end if
907
908 if (hm_out%lda_u_level /= dft_u_none .and. associated(hm_out%ions)) then
909 call lda_u_rebind_after_copy(hm_out%lda_u, hm_out%ions)
910 if (accel_is_enabled() .and. runtime_initialized) then
911 call lda_u_accel_rebuild(hm_out%lda_u, hm_out%d%kpt)
912 end if
913 end if
914
915 if (associated(hm_in%zora)) then
916 allocate(zora_out, source=hm_in%zora)
917 hm_out%zora => zora_out
918 else
919 nullify(hm_out%zora)
920 end if
921
922 pop_sub(hamiltonian_elec_copy)
923
924 end subroutine hamiltonian_elec_copy
925
926 ! ---------------------------------------------------------
929 type(hamiltonian_elec_t), intent(in) :: hm_in
930
931 logical :: runtime_initialized
932
934
935 runtime_initialized = associated(hm_in%kpoints)
936 if (.not. runtime_initialized) then
938 return
939 end if
940
941 if (hm_in%theory_level == hartree_fock .or. hm_in%theory_level == rdmft) then
942 call messages_not_implemented("hamiltonian_elec_copy with HF/RDMFT exchange operator paths")
943 end if
944
945 if (associated(hm_in%xc)) then
946 if (hm_in%xc%compute_exchange(hm_in%theory_level)) then
947 call messages_not_implemented("hamiltonian_elec_copy with hybrid/OEP exchange paths")
948 end if
949 end if
950
951 if (hamiltonian_elec_inh_term(hm_in)) then
952 call messages_not_implemented("hamiltonian_elec_copy with OCT inhomogeneous/source term")
953 end if
954
955 if (oct_exchange_enabled(hm_in%oct_exchange)) then
956 call messages_not_implemented("hamiltonian_elec_copy with OCT exchange term")
957 end if
958
959 if (hm_in%pcm%run_pcm) then
960 call messages_not_implemented("hamiltonian_elec_copy with PCM enabled")
961 end if
962
965
966
967 ! ---------------------------------------------------------
968 ! True if the Hamiltonian is Hermitian, false otherwise
969 logical function hamiltonian_elec_hermitian(hm)
970 class(hamiltonian_elec_t), intent(in) :: hm
971
973 hamiltonian_elec_hermitian = .not.((hm%abs_boundaries%abtype == imaginary_absorbing) .or. &
974 oct_exchange_enabled(hm%oct_exchange))
975
977 end function hamiltonian_elec_hermitian
978
979 ! ---------------------------------------------------------
980 ! True if the Hamiltonian needs to apply the mGGA term
981 pure logical function hamiltonian_elec_needs_mgga_term(hm, terms)
982 class(hamiltonian_elec_t), intent(in) :: hm
983 integer, intent(in) :: terms
984
986
987 if (bitand(term_mgga, terms) /= 0 .and. family_is_mgga_with_exc(hm%xc) &
988 .and. hm%theory_level == generalized_kohn_sham_dft) then
990 end if
991
992 !For OEP
993 if(terms == term_mgga .and. family_is_mgga_with_exc(hm%xc) .and. hm%theory_level == kohn_sham_dft) then
995 end if
996
998
999
1000
1001 ! ---------------------------------------------------------
1002 subroutine hamiltonian_elec_span(hm, delta, emin, namespace)
1003 class(hamiltonian_elec_t), intent(inout) :: hm
1004 real(real64), intent(in) :: delta(:)
1005 real(real64), intent(in) :: emin
1006 type(namespace_t), intent(in) :: namespace
1007
1008 real(real64) :: emax
1009
1010 push_sub(hamiltonian_elec_span)
1011
1012 ! estimate maximum energy of discrete kinetic operator
1013 ! this neglects possible contributions from the non-local part of the pseudopotentials
1015
1016 hm%spectral_middle_point = (emax + emin) / m_two
1017 hm%spectral_half_span = (emax - emin) / m_two
1018
1019 pop_sub(hamiltonian_elec_span)
1020 end subroutine hamiltonian_elec_span
1021
1022
1023 ! ---------------------------------------------------------
1024 pure logical function hamiltonian_elec_inh_term(hm) result(inh)
1025 type(hamiltonian_elec_t), intent(in) :: hm
1026
1027 inh = hm%inh_term
1028 end function hamiltonian_elec_inh_term
1029
1030
1031 ! ---------------------------------------------------------
1032 subroutine hamiltonian_elec_set_inh(hm, st)
1033 type(hamiltonian_elec_t), intent(inout) :: hm
1034 type(states_elec_t), intent(in) :: st
1035
1036 push_sub(hamiltonian_elec_set_inh)
1037
1038 if (hm%inh_term) call states_elec_end(hm%inh_st)
1039 call states_elec_copy(hm%inh_st, st)
1040 hm%inh_term = .true.
1041
1043 end subroutine hamiltonian_elec_set_inh
1044
1045
1046 ! ---------------------------------------------------------
1047 subroutine hamiltonian_elec_remove_inh(hm)
1048 type(hamiltonian_elec_t), intent(inout) :: hm
1049
1051
1052 if (hm%inh_term) then
1053 call states_elec_end(hm%inh_st)
1054 hm%inh_term = .false.
1055 end if
1056
1058 end subroutine hamiltonian_elec_remove_inh
1059
1060 ! ---------------------------------------------------------
1061 subroutine hamiltonian_elec_adjoint(hm)
1062 type(hamiltonian_elec_t), intent(inout) :: hm
1063
1065
1066 if (.not. hm%adjoint) then
1067 hm%adjoint = .true.
1068 if (hm%abs_boundaries%abtype == imaginary_absorbing) then
1069 hm%abs_boundaries%mf = -hm%abs_boundaries%mf
1070 end if
1071 end if
1072
1074 end subroutine hamiltonian_elec_adjoint
1075
1077 ! ---------------------------------------------------------
1078 subroutine hamiltonian_elec_not_adjoint(hm)
1079 type(hamiltonian_elec_t), intent(inout) :: hm
1080
1082
1083 if (hm%adjoint) then
1084 hm%adjoint = .false.
1085 if (hm%abs_boundaries%abtype == imaginary_absorbing) then
1086 hm%abs_boundaries%mf = -hm%abs_boundaries%mf
1087 end if
1088 end if
1089
1091 end subroutine hamiltonian_elec_not_adjoint
1092
1093
1094 ! ---------------------------------------------------------
1096 subroutine hamiltonian_elec_update(this, mesh, namespace, space, ext_partners, time)
1097 class(hamiltonian_elec_t), intent(inout) :: this
1098 class(mesh_t), intent(in) :: mesh
1099 type(namespace_t), intent(in) :: namespace
1100 class(space_t), intent(in) :: space
1101 type(partner_list_t), intent(in) :: ext_partners
1102 real(real64), optional, intent(in) :: time
1103
1104 integer :: ispin, ip, idir, iatom, ilaser
1105 real(real64) :: aa(space%dim), time_
1106 real(real64), allocatable :: vp(:,:)
1107 type(lasers_t), pointer :: lasers
1108 type(gauge_field_t), pointer :: gfield
1109 real(real64) :: am(space%dim)
1110
1111 push_sub(hamiltonian_elec_update)
1112 call profiling_in("HAMILTONIAN_ELEC_UPDATE")
1113
1114 this%current_time = m_zero
1115 if (present(time)) this%current_time = time
1116
1117 time_ = optional_default(time, 0.0_real64)
1118
1119 ! set everything to zero
1120 call this%hm_base%clear(mesh%np)
1121
1122 ! alllocate the scalar potential for the xc, hartree and external potentials
1123 call this%hm_base%allocate_field(mesh, field_potential, &
1124 complex_potential = this%abs_boundaries%abtype == imaginary_absorbing)
1125
1126 ! the lasers
1127 if (present(time) .or. this%time_zero) then
1128
1129 lasers => list_get_lasers(ext_partners)
1130 if(associated(lasers)) then
1131 do ilaser = 1, lasers%no_lasers
1132 select case (laser_kind(lasers%lasers(ilaser)))
1134 do ispin = 1, this%d%spin_channels
1135 call laser_potential(lasers%lasers(ilaser), mesh, &
1136 this%hm_base%potential(:, ispin), time_)
1137 end do
1138 case (e_field_magnetic)
1139 call this%hm_base%allocate_field(mesh, field_vector_potential + field_uniform_magnetic_field, &
1140 .false.)
1141 ! get the vector potential
1142 safe_allocate(vp(1:mesh%np, 1:space%dim))
1143 vp(1:mesh%np, 1:space%dim) = m_zero
1144 call laser_vector_potential(lasers%lasers(ilaser), mesh, vp, time_)
1145 !$omp parallel do private(idir) schedule(static)
1146 do ip = 1, mesh%np
1147 do idir = 1, space%dim
1148 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) + vp(ip, idir)/p_c
1149 end do
1150 end do
1151 ! and the magnetic field
1152 call laser_field(lasers%lasers(ilaser), this%hm_base%uniform_magnetic_field(1:space%dim), time_)
1153 safe_deallocate_a(vp)
1155 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
1156 ! get the uniform vector potential associated with a magnetic field
1157 aa = m_zero
1158 call laser_field(lasers%lasers(ilaser), aa, time_)
1159 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - aa/p_c
1160 end select
1161 end do
1162
1163 if (lasers_with_nondipole_field(lasers)) then
1164 assert( allocated(this%hm_base%uniform_vector_potential))
1165 call lasers_nondipole_laser_field_step(lasers, am, time_)
1166 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - am/p_c
1167 end if
1168 end if
1169
1170 ! the gauge field
1171 gfield => list_get_gauge_field(ext_partners)
1172 if (associated(gfield)) then
1173 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
1174 call gauge_field_get_vec_pot(gfield, aa)
1175 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - aa/p_c
1176 end if
1177
1178 ! the electric field for a periodic system through the gauge field
1179 if (allocated(this%ep%e_field) .and. associated(gfield)) then
1180 this%hm_base%uniform_vector_potential(1:space%periodic_dim) = &
1181 this%hm_base%uniform_vector_potential(1:space%periodic_dim) - time_*this%ep%e_field(1:space%periodic_dim)
1182 end if
1183
1184 ! add the photon-free mean-field vector potential
1185 if (associated(this%xc_photons)) then
1186 if(this%xc_photons%lpfmf .and. allocated(this%xc_photons%mf_vector_potential)) then
1187 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
1188 ! here we put a minus sign in front of the mean field term to get the right answer (need to check the formula)
1189 this%hm_base%uniform_vector_potential(1:space%dim) = &
1190 this%hm_base%uniform_vector_potential(1:space%dim) - this%xc_photons%mf_vector_potential(1:space%dim)/p_c
1191 end if
1192 end if
1193
1194 end if
1195
1196 ! the vector potential of a static magnetic field
1197 if (allocated(this%ep%a_static)) then
1198 call this%hm_base%allocate_field(mesh, field_vector_potential, .false.)
1199 !ep%a_static contains 1/c A(r)
1200 !$omp parallel do private(idir) schedule(static)
1201 do ip = 1, mesh%np
1202 do idir = 1, space%dim
1203 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) + this%ep%a_static(ip, idir)
1204 end do
1205 end do
1206 end if
1207
1208 ! add Maxwell coupling to Hamiltonian and sets the magnetic field for the Zeeman term added below
1209 call mxll_coupling_calc(this%mxll, this%hm_base, mesh, this%d, space)
1210
1211 !The electric field was added to the KS potential
1212 call this%hm_base%accel_copy_pot(mesh)
1213
1214 ! and the static magnetic field
1215 if (allocated(this%ep%b_field)) then
1216 call this%hm_base%allocate_field(mesh, field_uniform_magnetic_field, .false.)
1217 do idir = 1, 3
1218 this%hm_base%uniform_magnetic_field(idir) = this%hm_base%uniform_magnetic_field(idir) + this%ep%b_field(idir)
1219 end do
1220 end if
1221
1222 ! Combine the uniform and non-uniform fields and compute the Zeeman term
1223 call this%hm_base%update_magnetic_terms(mesh, this%ep%gyromagnetic_ratio, this%d%ispin)
1224
1225 ! This needs to be called at the end as the zeeman term enters the potential
1226 call hamiltonian_elec_update_pot(this, mesh, accumulate = .true.)
1227
1228 if (this%mxll%test_equad) then
1229 call set_electric_quadrupole_pot(this%mxll, mesh)
1230 end if
1231
1232 call build_phase()
1233
1234 call profiling_out("HAMILTONIAN_ELEC_UPDATE")
1236
1237 contains
1238
1239 subroutine build_phase()
1240 integer :: ik, imat, nmat, max_npoints, offset
1241 integer :: ip
1242 integer :: iphase, nphase
1243
1245
1246 if ((.not. this%kpoints%gamma_only()) .or. allocated(this%hm_base%uniform_vector_potential)) then
1247
1248 call profiling_in('UPDATE_PHASES')
1249 ! now regenerate the phases for the pseudopotentials
1250 do iatom = 1, this%ep%natoms
1251 call projector_init_phases(this%ep%proj(iatom), space%dim, this%d, this%der%boundaries, this%kpoints, &
1252 vec_pot = this%hm_base%uniform_vector_potential, vec_pot_var = this%hm_base%vector_potential)
1253 end do
1254
1255 call profiling_out('UPDATE_PHASES')
1256 end if
1257
1258 if (allocated(this%hm_base%uniform_vector_potential)) then
1259
1260 call this%phase%update(mesh, this%d%kpt, this%kpoints, this%d, space, this%hm_base%uniform_vector_potential)
1261
1262 ! We rebuild the phase for the orbital projection, similarly to the one of the pseudopotentials
1263 if (this%lda_u_level /= dft_u_none) then
1264 call lda_u_build_phase_correction(this%lda_u, space, this%d, this%der%boundaries, namespace, this%kpoints, &
1265 vec_pot = this%hm_base%uniform_vector_potential, vec_pot_var = this%hm_base%vector_potential)
1266 end if
1267 end if
1268
1269 max_npoints = this%vnl%max_npoints
1270 nmat = this%vnl%nprojector_matrices
1271
1272
1273 if (this%phase%is_allocated() .and. allocated(this%vnl%projector_matrices)) then
1274
1275 nphase = 1
1276 if (this%der%boundaries%spiralBC) nphase = 3
1277
1278 if (.not. allocated(this%vnl%projector_phases)) then
1279 safe_allocate(this%vnl%projector_phases(1:max_npoints, 1:nphase, nmat, this%d%kpt%start:this%d%kpt%end))
1280 if (accel_is_enabled()) then
1281 call accel_create_buffer(this%vnl%buff_projector_phases, accel_mem_read_only, &
1282 type_cmplx, this%vnl%total_points*nphase*this%d%kpt%nlocal())
1283 ! We need to save nphase, with which the array has been build,
1284 ! as the number might change throughout the run
1285 this%vnl%nphase = nphase
1286 end if
1287 end if
1288
1289 offset = 0
1290 do ik = this%d%kpt%start, this%d%kpt%end
1291 do imat = 1, this%vnl%nprojector_matrices
1292 iatom = this%vnl%projector_to_atom(imat)
1293 do iphase = 1, nphase
1294 !$omp parallel do simd schedule(static)
1295 do ip = 1, this%vnl%projector_matrices(imat)%npoints
1296 this%vnl%projector_phases(ip, iphase, imat, ik) = this%ep%proj(iatom)%phase(ip, iphase, ik)
1297 end do
1298
1299 if (accel_is_enabled() .and. this%vnl%projector_matrices(imat)%npoints > 0) then
1300 call accel_write_buffer(this%vnl%buff_projector_phases, &
1301 this%vnl%projector_matrices(imat)%npoints, this%vnl%projector_phases(1:, iphase, imat, ik), &
1302 offset = offset, async=.true.)
1303 end if
1304 offset = offset + this%vnl%projector_matrices(imat)%npoints
1305 end do
1306 end do
1307 end do
1308
1309 end if
1310
1311 call accel_finish()
1312
1314 end subroutine build_phase
1315
1316 end subroutine hamiltonian_elec_update
1317
1318
1319 !----------------------------------------------------------------
1322 ! TODO: See Issue #1064
1323 subroutine hamiltonian_elec_update_pot(this, mesh, accumulate)
1324 type(hamiltonian_elec_t), intent(inout) :: this
1325 class(mesh_t), intent(in) :: mesh
1326 logical, optional, intent(in) :: accumulate
1327
1328 integer :: ispin, ip
1329
1331
1332 ! By default we nullify first the result
1333 if (.not. optional_default(accumulate, .false.)) then
1334 !$omp parallel private(ip, ispin)
1335 do ispin = 1, this%d%nspin
1336 !$omp do simd schedule(static)
1337 do ip = 1, mesh%np
1338 this%hm_base%potential(ip, ispin) = m_zero
1339 end do
1340 end do
1341 !$omp end parallel
1342 if (this%abs_boundaries%abtype == imaginary_absorbing) then
1343 this%hm_base%Impotential = m_zero
1344 end if
1345 end if
1346
1347 !$omp parallel private(ip, ispin)
1348 do ispin = 1, this%d%nspin
1349 if (ispin <= 2) then
1350 !$omp do simd schedule(static)
1351 ! this%vhxc(ip, ispin) is added after the calculation of ZORA potential
1352 do ip = 1, mesh%np
1353 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + this%ep%vpsl(ip) + this%v_ext_pot(ip)
1354 end do
1355
1357 if (this%pcm%run_pcm) then
1358 if (this%pcm%solute) then
1359 !$omp do simd schedule(static)
1360 do ip = 1, mesh%np
1361 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + &
1362 this%pcm%v_e_rs(ip) + this%pcm%v_n_rs(ip)
1363 end do
1364 !$omp end do simd nowait
1365 end if
1366 if (this%pcm%localf) then
1367 !$omp do simd schedule(static)
1368 do ip = 1, mesh%np
1369 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + &
1370 this%pcm%v_ext_rs(ip)
1371 end do
1372 !$omp end do simd nowait
1373 end if
1374 end if
1375
1377 if (this%abs_boundaries%abtype == imaginary_absorbing) then
1378 !$omp do simd schedule(static)
1379 do ip = 1, mesh%np
1380 this%hm_base%Impotential(ip, ispin) = this%hm_base%Impotential(ip, ispin) + this%abs_boundaries%mf(ip)
1381 end do
1382 !$omp end do simd nowait
1383 end if
1384 end if
1385 end do
1386 !$omp end parallel
1387
1388 ! scalar relativistic ZORA contribution
1389 ! \boldsymbol{p} \frac{c^2}{2c^2 - V} \boldsymbol{p} \Phi^\mathrm{ZORA}
1390 ! Note that V here is the ionic plus external potential only: vHxc is added below, and is
1391 ! deliberately excluded from the ZORA prefactor. This makes it comparable to a one-electron
1392 ! X2C rather than to a full ZORA, and it is what allows zora_update to treat V as spin
1393 ! independent. Do not move this call after add_vhxc without revisiting zora_update.
1394 if (this%ep%reltype == scalar_relativistic_zora .or. this%ep%reltype == fully_relativistic_zora) then
1395 call this%zora%update(this%der, this%hm_base%potential)
1396 end if
1397
1398 !$omp parallel private(ip, ispin)
1399 do ispin = 1, this%d%nspin
1400 ! Adding Zeeman potential to hm_base%potential
1401 if (allocated(this%hm_base%zeeman_pot)) then
1402 !$omp do simd schedule(static)
1403 do ip = 1, mesh%np
1404 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + this%hm_base%zeeman_pot(ip, ispin)
1405 end do
1406 !$omp end do simd nowait
1407 end if
1408
1409 ! Adding Quadrupole potential from static E-field (test)
1410 if (this%mxll%test_equad) then
1411 !$omp do simd schedule(static)
1412 do ip = 1, mesh%np
1413 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + this%mxll%e_quadrupole_pot(ip)
1414 end do
1415 !$omp end do simd
1416 end if
1417 end do
1418 !$omp end parallel
1419
1420
1421 ! Add the Hartree and KS potential
1422 call this%ks_pot%add_vhxc(this%hm_base%potential)
1423
1424 call this%hm_base%accel_copy_pot(mesh)
1425
1427 end subroutine hamiltonian_elec_update_pot
1428
1429 ! ---------------------------------------------------------
1430 subroutine hamiltonian_elec_epot_generate(this, namespace, space, gr, ions, ext_partners, st, time)
1431 type(hamiltonian_elec_t), intent(inout) :: this
1432 type(namespace_t), intent(in) :: namespace
1433 class(electron_space_t), intent(in) :: space
1434 type(grid_t), intent(in) :: gr
1435 type(ions_t), target, intent(inout) :: ions
1436 type(partner_list_t), intent(in) :: ext_partners
1437 type(states_elec_t), intent(inout) :: st
1438 real(real64), optional, intent(in) :: time
1439
1441
1442 this%ions => ions
1443 call epot_generate(this%ep, namespace, gr, this%ions, this%d)
1444
1445 ! Interation terms are treated below
1446
1447 ! First we add the static electric field
1448 if (allocated(this%ep%e_field) .and. space%periodic_dim < space%dim) then
1449 call lalg_axpy(gr%np, m_one, this%v_static, this%ep%vpsl)
1450 end if
1451
1452 ! Here we need to pass this again, else test are failing.
1453 ! This is not a real problem, as the multisystem framework will indeed to this anyway
1454 this%v_ie_loc%atoms_dist => ions%atoms_dist
1455 this%v_ie_loc%atom => ions%atom
1456 call this%v_ie_loc%calculate()
1457
1458 ! At the moment we need to add this to ep%vpsl, to keep the behavior of the code
1459 call lalg_axpy(gr%np, m_one, this%v_ie_loc%potential(:,1), this%ep%vpsl)
1460
1461 ! Here we need to reinit the NLCC object
1462 ! This is not a real problem, as the multisystem framework will indeed to this anyway
1463 if (this%ep%nlcc) then
1464 call this%nlcc%end()
1465 call this%nlcc%init(gr, ions)
1466 call this%nlcc%calculate()
1467 call lalg_copy(gr%np, this%nlcc%density(:,1), st%rho_core)
1468 end if
1469
1470 call this%vnl%build(space, gr, this%ep)
1471 call hamiltonian_elec_update(this, gr, namespace, space, ext_partners, time)
1472
1473 ! Check if projectors are still compatible with apply_packed on GPU
1474 if (this%is_applied_packed .and. accel_is_enabled()) then
1475 if (this%ep%non_local .and. .not. this%vnl%apply_projector_matrices) then
1476 if (accel_allow_cpu_only()) then
1477 call messages_write('Relativistic pseudopotentials have not been fully implemented for GPUs.')
1478 call messages_warning(namespace=namespace)
1479 else
1480 call messages_write('Relativistic pseudopotentials have not been fully implemented for GPUs.',&
1481 new_line = .true.)
1482 call messages_write('Calculation will not be continued. To force execution, set AllowCPUonly = yes.')
1483 call messages_fatal(namespace=namespace)
1484 end if
1485 end if
1486
1487 end if
1488
1489 if (this%pcm%run_pcm) then
1492 if (this%pcm%solute) then
1493 call pcm_calc_pot_rs(this%pcm, gr, this%psolver, ions = ions)
1494 end if
1495
1498 ! Interpolation is needed, hence gr%np_part -> 1:gr%np
1499 if (this%pcm%localf .and. allocated(this%v_static)) then
1500 call pcm_calc_pot_rs(this%pcm, gr, this%psolver, v_ext = this%ep%v_ext(1:gr%np_part))
1501 end if
1502
1503 end if
1504
1505 call lda_u_update_basis(this%lda_u, space, gr, ions, st, this%psolver, namespace, this%kpoints, &
1506 this%phase%is_allocated())
1507
1509 end subroutine hamiltonian_elec_epot_generate
1510
1511 ! -----------------------------------------------------------------
1512
1513 real(real64) function hamiltonian_elec_get_time(this) result(time)
1514 type(hamiltonian_elec_t), intent(inout) :: this
1515
1516 time = this%current_time
1517 end function hamiltonian_elec_get_time
1518
1519 ! -----------------------------------------------------------------
1520
1521 pure logical function hamiltonian_elec_apply_packed(this) result(apply)
1522 class(hamiltonian_elec_t), intent(in) :: this
1523
1524 apply = this%is_applied_packed
1527
1528
1529 ! -----------------------------------------------------------------
1530 subroutine zhamiltonian_elec_apply_atom (hm, namespace, space, latt, species, pos, ia, mesh, psi, vpsi)
1531 type(hamiltonian_elec_t), intent(in) :: hm
1532 type(namespace_t), intent(in) :: namespace
1533 class(space_t), intent(in) :: space
1534 type(lattice_vectors_t), intent(in) :: latt
1535 class(species_t), intent(in) :: species
1536 real(real64), intent(in) :: pos(1:space%dim)
1537 integer, intent(in) :: ia
1538 class(mesh_t), intent(in) :: mesh
1539 complex(real64), intent(in) :: psi(:,:)
1540 complex(real64), intent(out) :: vpsi(:,:)
1541
1542 integer :: idim, ip
1543 real(real64), allocatable :: vlocal(:)
1545
1546 safe_allocate(vlocal(1:mesh%np_part))
1547 vlocal = m_zero
1548 call epot_local_potential(hm%ep, namespace, space, latt, mesh, species, pos, ia, vlocal)
1549
1550 !$omp parallel private(idim, ip)
1551 do idim = 1, hm%d%dim
1552 !$omp do
1553 do ip = 1, mesh%np
1554 vpsi(ip, idim) = vlocal(ip) * psi(ip, idim)
1555 end do
1556 end do
1557 !$omp end parallel
1558
1559 safe_deallocate_a(vlocal)
1561 end subroutine zhamiltonian_elec_apply_atom
1562
1563 ! ---------------------------------------------------------
1568 subroutine hamiltonian_elec_update_with_ext_pot(this, mesh, space, ext_partners, time, mu)
1569 type(hamiltonian_elec_t), intent(inout) :: this
1570 class(space_t), intent(in) :: space
1571 class(mesh_t), intent(in) :: mesh
1572 type(partner_list_t), intent(in) :: ext_partners
1573 real(real64), intent(in) :: time(1:2)
1574 real(real64), intent(in) :: mu(1:2)
1575
1576 integer :: ispin, ip, idir, iatom, ilaser, itime
1577 real(real64) :: aa(space%dim), bb(space%dim), time_
1578 real(real64), allocatable :: vp(:,:)
1579 real(real64), allocatable :: velectric(:)
1580 type(lasers_t), pointer :: lasers
1581 type(gauge_field_t), pointer :: gfield
1582
1584 call profiling_in("HAMILTONIAN_ELEC_UPDATE_EXT_POT")
1585
1586 this%current_time = m_zero
1587 this%current_time = time(1)
1588
1589 ! set everything to zero
1590 call this%hm_base%clear(mesh%np)
1591
1592 ! the xc, hartree and external potentials
1593 call this%hm_base%allocate_field(mesh, field_potential, &
1594 complex_potential = this%abs_boundaries%abtype == imaginary_absorbing)
1595
1596 do itime = 1, 2
1597 time_ = time(itime)
1598
1599 lasers => list_get_lasers(ext_partners)
1600 if(associated(lasers)) then
1601 do ilaser = 1, lasers%no_lasers
1602 select case (laser_kind(lasers%lasers(ilaser)))
1603 case (e_field_scalar_potential, e_field_electric)
1604 safe_allocate(velectric(1:mesh%np))
1605 do ispin = 1, this%d%spin_channels
1606 velectric = m_zero
1607 call laser_potential(lasers%lasers(ilaser), mesh, velectric, time_)
1608 !$omp parallel do simd schedule(static)
1609 do ip = 1, mesh%np
1610 this%hm_base%potential(ip, ispin) = this%hm_base%potential(ip, ispin) + mu(itime) * velectric(ip)
1611 end do
1612 end do
1613 safe_deallocate_a(velectric)
1614 case (e_field_magnetic)
1615 call this%hm_base%allocate_field(mesh, field_vector_potential + field_uniform_magnetic_field, .false.)
1616 ! get the vector potential
1617 safe_allocate(vp(1:mesh%np, 1:space%dim))
1618 vp(1:mesh%np, 1:space%dim) = m_zero
1619 call laser_vector_potential(lasers%lasers(ilaser), mesh, vp, time_)
1620 do idir = 1, space%dim
1621 !$omp parallel do schedule(static)
1622 do ip = 1, mesh%np
1623 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) &
1624 - mu(itime) * vp(ip, idir)/p_c
1625 end do
1626 end do
1627 ! and the magnetic field
1628 bb = m_zero
1629 call laser_field(lasers%lasers(ilaser), bb(1:space%dim), time_)
1630 this%hm_base%uniform_magnetic_field = this%hm_base%uniform_magnetic_field &
1631 - mu(itime) * bb
1632 safe_deallocate_a(vp)
1633 case (e_field_vector_potential)
1634 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
1635 ! get the uniform vector potential associated with a magnetic field
1636 aa = m_zero
1637 call laser_field(lasers%lasers(ilaser), aa, time_)
1638 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) &
1639 - mu(itime) * aa/p_c
1640 end select
1641 end do
1642 end if
1643
1644 ! the gauge field
1645 gfield => list_get_gauge_field(ext_partners)
1646 if (associated(gfield)) then
1647 call this%hm_base%allocate_field(mesh, field_uniform_vector_potential, .false.)
1648 call gauge_field_get_vec_pot(gfield, aa)
1649 this%hm_base%uniform_vector_potential(1:space%dim) = this%hm_base%uniform_vector_potential(1:space%dim) - aa/p_c
1650 end if
1651
1652 ! the electric field for a periodic system through the gauge field
1653 ! TODO: The condition is wrong here: the e_field should be in non-periodic dims as E field
1654 ! and as a gauge field in the periodic dim, unless we use a Bery phase, in which, we do not use it
1655 ! this way. But this is unrelated to the gauge field
1656 if (allocated(this%ep%e_field) .and. associated(gfield)) then
1657 this%hm_base%uniform_vector_potential(1:space%periodic_dim) = &
1658 this%hm_base%uniform_vector_potential(1:space%periodic_dim) - time_*this%ep%e_field(1:space%periodic_dim)
1659 end if
1660
1661 end do
1662
1663 ! the vector potential of a static magnetic field
1664 if (allocated(this%ep%a_static)) then
1665 call this%hm_base%allocate_field(mesh, field_vector_potential, .false.)
1666 !ep%a_static contains 1/c A(r)
1667 !$omp parallel do schedule(static) private(idir)
1668 do ip = 1, mesh%np
1669 do idir = 1, space%dim
1670 this%hm_base%vector_potential(idir, ip) = this%hm_base%vector_potential(idir, ip) + this%ep%a_static(ip, idir)
1671 end do
1672 end do
1673 end if
1674
1675 !The electric field is added to the KS potential
1676 call this%hm_base%accel_copy_pot(mesh)
1677
1678 ! and the static magnetic field
1679 if (allocated(this%ep%b_field)) then
1680 call this%hm_base%allocate_field(mesh, field_uniform_magnetic_field, .false.)
1681 do idir = 1, 3
1682 this%hm_base%uniform_magnetic_field(idir) = this%hm_base%uniform_magnetic_field(idir) + this%ep%b_field(idir)
1683 end do
1684 end if
1685
1686 call this%hm_base%update_magnetic_terms(mesh, this%ep%gyromagnetic_ratio, this%d%ispin)
1687
1688 call hamiltonian_elec_update_pot(this, mesh)
1689
1690 call build_phase()
1691
1692 call profiling_out("HAMILTONIAN_ELEC_UPDATE_EXT_POT")
1694
1695 contains
1696
1697 subroutine build_phase()
1698 integer :: ik, imat, nmat, max_npoints, offset, iphase, nphase
1699
1701
1702 if ((.not. this%kpoints%gamma_only()) .or. allocated(this%hm_base%uniform_vector_potential)) then
1703
1704 call profiling_in('UPDATE_PHASES')
1705 ! now regenerate the phases for the pseudopotentials
1706 do iatom = 1, this%ep%natoms
1707 call projector_init_phases(this%ep%proj(iatom), space%dim, this%d, this%der%boundaries, this%kpoints, &
1708 vec_pot = this%hm_base%uniform_vector_potential, vec_pot_var = this%hm_base%vector_potential)
1709 end do
1710
1711 call profiling_out('UPDATE_PHASES')
1712 end if
1713
1714 if (allocated(this%hm_base%uniform_vector_potential)) then
1715 call this%phase%update(mesh, this%d%kpt, this%kpoints, this%d, space, this%hm_base%uniform_vector_potential)
1716 end if
1717
1718 max_npoints = this%vnl%max_npoints
1719 nmat = this%vnl%nprojector_matrices
1720
1721
1722 if (this%phase%is_allocated() .and. allocated(this%vnl%projector_matrices)) then
1723
1724 nphase = 1
1725 if (this%der%boundaries%spiralBC) nphase = 3
1726
1727 if (.not. allocated(this%vnl%projector_phases)) then
1728 safe_allocate(this%vnl%projector_phases(1:max_npoints, nphase, nmat, this%d%kpt%start:this%d%kpt%end))
1729 if (accel_is_enabled()) then
1730 call accel_create_buffer(this%vnl%buff_projector_phases, accel_mem_read_only, &
1731 type_cmplx, this%vnl%total_points*nphase*this%d%kpt%nlocal())
1732 end if
1733 end if
1734
1735 offset = 0
1736 do ik = this%d%kpt%start, this%d%kpt%end
1737 do imat = 1, this%vnl%nprojector_matrices
1738 iatom = this%vnl%projector_to_atom(imat)
1739 do iphase = 1, nphase
1740 !$omp parallel do schedule(static)
1741 do ip = 1, this%vnl%projector_matrices(imat)%npoints
1742 this%vnl%projector_phases(ip, iphase, imat, ik) = this%ep%proj(iatom)%phase(ip, iphase, ik)
1743 end do
1744
1745 if (accel_is_enabled() .and. this%vnl%projector_matrices(imat)%npoints > 0) then
1746 call accel_write_buffer(this%vnl%buff_projector_phases, &
1747 this%vnl%projector_matrices(imat)%npoints, this%vnl%projector_phases(1:, iphase, imat, ik), &
1748 offset = offset)
1749 end if
1750 offset = offset + this%vnl%projector_matrices(imat)%npoints
1751 end do
1752 end do
1753 end do
1754
1755 end if
1756
1758 end subroutine build_phase
1759
1761
1762 logical function hamiltonian_elec_needs_current(hm, states_are_real)
1763 type(hamiltonian_elec_t), intent(in) :: hm
1764 logical, intent(in) :: states_are_real
1765
1767
1768 if (hm%self_induced_magnetic) then
1769 if (.not. states_are_real) then
1771 else
1772 message(1) = 'No current density for real states since it is identically zero.'
1773 call messages_warning(1)
1774 end if
1775 end if
1776
1778
1779 ! ---------------------------------------------------------
1780 subroutine zhamiltonian_elec_apply_all(hm, namespace, gr, st, hst)
1781 type(hamiltonian_elec_t), intent(inout) :: hm
1782 type(namespace_t), intent(in) :: namespace
1783 type(grid_t), intent(in) :: gr
1784 type(states_elec_t), intent(inout) :: st
1785 type(states_elec_t), intent(inout) :: hst
1786
1787 integer :: ik, ib, ist
1788 complex(real64), allocatable :: psi(:, :)
1789 complex(real64), allocatable :: psiall(:, :, :, :)
1790
1792
1793 do ik = st%d%kpt%start, st%d%kpt%end
1794 do ib = st%group%block_start, st%group%block_end
1795 call zhamiltonian_elec_apply_batch(hm, namespace, gr, st%group%psib(ib, ik), hst%group%psib(ib, ik))
1796 end do
1797 end do
1798
1799 if (oct_exchange_enabled(hm%oct_exchange)) then
1800
1801 safe_allocate(psiall(gr%np_part, 1:hst%d%dim, st%st_start:st%st_end, st%d%kpt%start:st%d%kpt%end))
1802
1803 call states_elec_get_state(st, gr, psiall)
1804
1805 call oct_exchange_prepare(hm%oct_exchange, gr, psiall, hm%xc, hm%psolver, namespace)
1806
1807 safe_deallocate_a(psiall)
1808
1809 safe_allocate(psi(gr%np_part, 1:hst%d%dim))
1810
1811 do ik = 1, st%nik
1812 do ist = 1, st%nst
1813 call states_elec_get_state(hst, gr, ist, ik, psi)
1814 call oct_exchange_operator(hm%oct_exchange, namespace, gr, psi, ist, ik)
1815 call states_elec_set_state(hst, gr, ist, ik, psi)
1816 end do
1817 end do
1818
1819 safe_deallocate_a(psi)
1820
1821 end if
1822
1824 end subroutine zhamiltonian_elec_apply_all
1825
1826 ! ---------------------------------------------------------
1827 logical function hamiltonian_elec_has_kick(hm)
1828 type(hamiltonian_elec_t), intent(in) :: hm
1829
1831
1832 hamiltonian_elec_has_kick = (abs(hm%kick%delta_strength) > m_epsilon)
1833
1835 end function hamiltonian_elec_has_kick
1836
1838 !
1839 subroutine hamiltonian_elec_set_mass(this, namespace, mass)
1840 class(hamiltonian_elec_t) , intent(inout) :: this
1841 type(namespace_t), intent(in) :: namespace
1842 real(real64), intent(in) :: mass
1843
1845
1846 if (parse_is_defined(namespace, 'ParticleMass')) then
1847 message(1) = 'Attempting to redefine a non-unit electron mass'
1848 call messages_fatal(1)
1849 else
1850 this%mass = mass
1851 end if
1852
1854 end subroutine hamiltonian_elec_set_mass
1855
1856 ! ---------------------------------------------------------
1857 subroutine hamiltonian_elec_diagonal (hm, mesh, diag, ik)
1858 type(hamiltonian_elec_t), intent(in) :: hm
1859 class(mesh_t), intent(in) :: mesh
1860 real(real64), contiguous, intent(out) :: diag(:,:)
1861 integer, intent(in) :: ik
1862
1863 integer :: idim, ip, ispin
1864
1865 real(real64), allocatable :: ldiag(:)
1866
1868
1869 safe_allocate(ldiag(1:mesh%np))
1870
1871 diag = m_zero
1872
1873 call derivatives_lapl_diag(hm%der, ldiag)
1874
1875 !$omp parallel private(idim, ip)
1876 do idim = 1, hm%d%dim
1877 !$omp do
1878 do ip = 1, mesh%np
1879 diag(ip, idim) = -m_half/hm%mass*ldiag(ip)
1880 end do
1881 end do
1882 !$omp end parallel
1883
1884 select case (hm%d%ispin)
1885
1886 case (unpolarized, spin_polarized)
1887 ispin = hm%d%get_spin_index(ik)
1888 !$omp parallel do
1889 do ip = 1, mesh%np
1890 diag(ip, 1) = diag(ip, 1) + hm%ep%vpsl(ip)
1891 end do
1892 !$omp end parallel do
1893
1894 case (spinors)
1895 do ip = 1, mesh%np
1896 diag(ip, 1) = diag(ip, 1) + hm%ep%vpsl(ip)
1897 diag(ip, 2) = diag(ip, 2) + hm%ep%vpsl(ip)
1898 end do
1899
1900 end select
1901
1902 call hm%ks_pot%add_vhxc(diag)
1903
1905 end subroutine hamiltonian_elec_diagonal
1906
1907
1908
1909#include "undef.F90"
1910#include "real.F90"
1911#include "hamiltonian_elec_inc.F90"
1912
1913#include "undef.F90"
1914#include "complex.F90"
1915#include "hamiltonian_elec_inc.F90"
1916
1917end module hamiltonian_elec_oct_m
1918
1919!! Local Variables:
1920!! mode: f90
1921!! coding: utf-8
1922!! End:
subroutine build_external_potentials()
subroutine build_phase()
subroutine external_potentials_checks()
subroutine build_interactions()
constant times a vector plus a vector
Definition: lalg_basic.F90:173
Copies a vector x, to a vector y.
Definition: lalg_basic.F90:188
integer, parameter, public imaginary_absorbing
subroutine, public absorbing_boundaries_end(this)
subroutine, public absorbing_boundaries_init(this, namespace, space, gr)
pure logical function, public accel_allow_cpu_only()
Definition: accel.F90:382
subroutine, public accel_finish()
Definition: accel.F90:1059
pure logical function, public accel_is_enabled()
Definition: accel.F90:372
integer, parameter, public accel_mem_read_only
Definition: accel.F90:185
This module implements batches of mesh functions.
Definition: batch.F90:135
This module implements common operations on batches of mesh functions.
Definition: batch_ops.F90:118
Module implementing boundary conditions in Octopus.
Definition: boundaries.F90:124
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
real(real64) function, public derivatives_lapl_get_max_eigenvalue(this)
Get maximum eigenvalue of discrete Laplacian. For the star and star_general stencils,...
subroutine, public energy_copy(ein, eout)
Definition: energy.F90:170
subroutine, public epot_bind_poisson_solver(ep, psolver)
Bind the Poisson solver if the potential manages a density. The Poisson solver pointer is aliased whe...
Definition: epot.F90:474
logical function, public epot_have_external_potentials(ep)
Definition: epot.F90:694
integer, parameter, public scalar_relativistic_zora
Definition: epot.F90:168
subroutine, public epot_end(ep)
Definition: epot.F90:435
integer, parameter, public fully_relativistic_zora
Definition: epot.F90:168
subroutine, public epot_init(ep, namespace, gr, ions, psolver, ispin, xc_family, kpoints)
Definition: epot.F90:226
subroutine, public epot_generate(ep, namespace, mesh, ions, st_d)
Definition: epot.F90:490
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 external_potential_clone(pot_out, pot_in)
Deep-clone an external potential instance.
subroutine, public gauge_field_get_vec_pot(this, vec_pot)
real(real64), parameter, public m_two
Definition: global.F90:202
real(real64), parameter, public m_zero
Definition: global.F90:200
integer, parameter, public rdmft
Definition: global.F90:250
integer, parameter, public hartree_fock
Definition: global.F90:250
integer, parameter, public independent_particles
Theory level.
Definition: global.F90:250
integer, parameter, public generalized_kohn_sham_dft
Definition: global.F90:250
integer, parameter, public kohn_sham_dft
Definition: global.F90:250
real(real64), parameter, public m_epsilon
Definition: global.F90:216
real(real64), parameter, public p_c
Electron gyromagnetic ratio, see Phys. Rev. Lett. 130, 071801 (2023)
Definition: global.F90:242
real(real64), parameter, public m_one
Definition: global.F90:201
This module implements the underlying real-space grid.
Definition: grid.F90:119
This module defines an abstract class for Hamiltonians.
integer, parameter, public field_uniform_magnetic_field
integer, parameter, public field_uniform_vector_potential
integer, parameter, public field_vector_potential
integer, parameter, public term_mgga
subroutine, public hamiltonian_elec_base_accel_rebuild(this, mesh)
Rebuild accelerator buffers after an intrinsic copy.
integer, parameter, public field_potential
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 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)
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 hamiltonian_elec_copy(hm_out, hm_in)
Deep-copy a hamiltonian_elec_t snapshot.
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, public zhamiltonian_elec_apply_atom(hm, namespace, space, latt, species, pos, ia, mesh, psi, vpsi)
subroutine hamiltonian_elec_release_copy_owned(hm)
Release owned pointer targets created by hamiltonian_elec_copy.
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 hamiltonian_elec_update(this, mesh, namespace, space, ext_partners, time)
(re-)build the Hamiltonian for the next application:
subroutine hamiltonian_elec_copy_guard_supported(hm_in)
Hard-fail guard matrix for unsupported hamiltonian snapshots.
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, public zhamiltonian_elec_external(this, mesh, psib, vpsib)
subroutine zhamiltonian_elec_apply(hm, namespace, mesh, psib, hpsib, terms, set_bc)
This module defines classes and functions for interaction partners.
Definition: io.F90:116
subroutine, public kick_copy(kick_out, kick_in)
Definition: kick.F90:753
integer, parameter, public kick_magnon_mode
Definition: kick.F90:165
subroutine, public kick_end(kick)
Definition: kick.F90:796
subroutine, public kick_init(kick, namespace, space, kpoints, nspin)
Definition: kick.F90:225
pure integer function, public kick_get_type(kick)
Definition: kick.F90:1365
A module to handle KS potential, without the external potential.
subroutine, public ks_potential_accel_rebuild(this)
Rebuild accelerator buffers after an intrinsic copy.
subroutine, public laser_vector_potential(laser, mesh, aa, time)
Definition: lasers.F90:1085
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:1157
logical function, public lasers_with_nondipole_field(lasers)
Check if a nondipole SFA correction should be computed for the given laser.
Definition: lasers.F90:744
integer, parameter, public e_field_electric
Definition: lasers.F90:180
integer, parameter, public e_field_vector_potential
Definition: lasers.F90:180
subroutine, public laser_potential(laser, mesh, pot, time)
Definition: lasers.F90:1050
integer, parameter, public e_field_scalar_potential
Definition: lasers.F90:180
integer pure elemental function, public laser_kind(laser)
Definition: lasers.F90:720
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:1122
integer, parameter, public e_field_magnetic
Definition: lasers.F90:180
integer, parameter, public dft_u_none
Definition: lda_u.F90:205
subroutine, public lda_u_init(this, namespace, space, level, gr, ions, st, mc, kpoints)
Definition: lda_u.F90:287
subroutine, public lda_u_update_basis(this, space, gr, ions, st, psolver, namespace, kpoints, has_phase)
Definition: lda_u.F90:793
subroutine, public lda_u_accel_rebuild(this, kpt)
Rebuild DFT+U accelerator buffers after intrinsic assignment.
Definition: lda_u.F90:750
subroutine, public lda_u_rebind_after_copy(this, ions)
Rebind non-owning pointers after intrinsic assignment of lda_u_t.
Definition: lda_u.F90:705
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:920
subroutine, public lda_u_end(this)
Definition: lda_u.F90:659
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_copy(this_out, this_in)
Deep-copy magnetic constrain data.
subroutine, public magnetic_constrain_end(this)
Releases memory of the magnetic constrain.
subroutine, public magnetic_constrain_init(this, namespace, mesh, std, natoms, min_dist)
Initilializes the magnetic_constrain_t object.
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:117
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1068
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:525
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:410
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1040
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
subroutine, public mxll_coupling_init(this, d, gr, namespace, mass)
Parse variables and initialize Maxwell coupling.
subroutine, public set_electric_quadrupole_pot(this, mesh)
Computes the electric quadrupole potential where .
subroutine, public mxll_coupling_end(this)
Finalize and deallocate Maxwell coupling arrays.
subroutine, public mxll_coupling_calc(this, hm_base, mesh, d, space)
Add the Maxwell coupling to the electronic Hamiltonian.
subroutine, public mxll_coupling_copy(this_out, this_in, der_target)
Deep-copy Maxwell-electron coupling data and rebind derivatives.
subroutine, public nonlocal_pseudopotential_accel_rebuild(this, space, mesh)
Rebuild accelerator buffers after an intrinsic copy.
subroutine, public nonlocal_pseudopotential_rebind_projectors(this, epot)
Rebind projector matrix pointers (map, position) to a target epot.
logical function, public oct_exchange_enabled(this)
subroutine, public oct_exchange_remove(this)
this module contains the low-level part of the output system
Definition: output_low.F90:117
Some general things and nomenclature:
Definition: par_vec.F90:173
logical function, public parse_is_defined(namespace, name)
Definition: parser.F90:463
subroutine, public pcm_calc_pot_rs(pcm, mesh, psolver, ions, v_h, v_ext, kick, time_present, kick_time)
Definition: pcm.F90:1217
subroutine, public pcm_end(pcm)
Definition: pcm.F90:3066
real(real64), dimension(:,:), allocatable delta
D_E matrix in JCP 139, 024105 (2013).
Definition: pcm.F90:270
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:296
subroutine, public phase_accel_rebuild(phase, mesh, kpt)
Rebuild phase accelerator buffers after an intrinsic copy.
Definition: phase.F90:538
subroutine, public poisson_init(this, namespace, space, der, mc, stencil, qtot, label, solver, verbose, force_serial, force_cmplx, fft_batch_size)
Definition: poisson.F90:236
subroutine, public poisson_end(this)
Definition: poisson.F90:692
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:631
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:554
subroutine, public projector_init_phases(this, dim, std, bnd, kpoints, vec_pot, vec_pot_var)
Definition: projector.F90:269
subroutine, public scissor_end(this)
Definition: scissor.F90:249
subroutine, public states_set_complex(st)
pure logical function, public states_are_real(st)
This module handles spin dimensions of the states and the k-point distribution.
subroutine, public states_elec_dim_copy(dout, din)
subroutine, public states_elec_dim_end(dim)
subroutine, public states_elec_end(st)
finalize the states_elec_t object
subroutine, public states_elec_copy(stout, stin, exclude_wfns, exclude_eigenval, special)
make a (selective) copy of a states_elec_t object
This module provides routines for communicating states when using states parallelization.
integer pure function, public symmetries_identity_index(this)
Definition: symmetries.F90:615
integer pure function, public symmetries_number(this)
Definition: symmetries.F90:569
type(type_t), parameter, public type_cmplx
Definition: types.F90:136
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:134
This module defines the unit system, used for input and output.
type(unit_system_t), public units_inp
the units systems for reading and writing
type(xc_cam_t), parameter, public cam_exact_exchange
Use only Hartree Fock exact exchange.
Definition: xc_cam.F90:155
integer, parameter, public xc_oep_x_slater
Slater approximation to the exact exchange.
integer, parameter, public func_x
Definition: xc.F90:120
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:734
logical pure function, public family_is_hybrid(xcs)
Returns true if the functional is an hybrid functional.
Definition: xc.F90:749
This module implements the "photon-free" electron-photon exchange-correlation functional.
Definition: xc_photons.F90:123
This module implements the ZORA terms for the Hamoiltonian.
Definition: zora.F90:118
Extension of space that contains the knowledge of the spin dimension.
Description of the grid, containing information on derivatives, stencil, and symmetries.
Definition: grid.F90:171
The abstract Hamiltonian class defines a skeleton for specific implementations.
abstract class for general interaction partners
Describes mesh distribution to nodes.
Definition: mesh.F90:187
Stores all communicators and groups.
Definition: multicomm.F90:208
The states_elec_t class contains all electronic wave functions.
This class described the 'photon-exchange' electron-photon xc functionals, based on QEDFT.
Definition: xc_photons.F90:160
This class is responsible for calculating and applying the ZORA.
Definition: zora.F90:147
int true(void)